summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKinsey Moore <kinsey.moore@oarcorp.com>2022-07-22 13:49:03 -0500
committerKinsey Moore <kinsey.moore@oarcorp.com>2022-09-06 13:46:39 -0500
commitebf143484247438a5696804a3e981ab3c06050d7 (patch)
tree77eea9f5e8e23a530e64aa141b4d30736064249d
parentInitial Commit (diff)
downloadrtems-net-services-ebf143484247438a5696804a3e981ab3c06050d7.tar.bz2
sebhbsd: Import NTP sources
These were retrieved from git hash 8dd5badffc37c674d664d06887976bce44dda5f6 of the repository.
-rw-r--r--COPYING.sebhbsd28
-rw-r--r--ORIGIN.sebhbsd2
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ascii.h96
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/audio.h14
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/binio.h86
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/config.h1854
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/declcond.h21
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/icom.h87
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ieee754io.h78
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/intreswork.h29
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/iosignal.h58
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/isc/mem.h68
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/l_stdlib.h224
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/lib_strbuf.h32
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/libntp.h16
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/libssl_compat.h119
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/mbg_gps166.h1015
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/namespace.h902
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntp.h944
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntp_assert.h104
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntp_calendar.h472
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntp_cmdargs.h1
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntp_config.h338
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntp_control.h192
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntp_crypto.h191
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntp_debug.h27
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntp_filegen.h56
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntp_fp.h424
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntp_if.h27
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntp_intres.h51
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntp_io.h99
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntp_keyacc.h25
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntp_libopts.h14
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntp_lists.h443
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntp_machine.h297
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntp_malloc.h61
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntp_md5.h49
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntp_net.h238
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntp_prio_q.h83
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntp_proto.h6
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntp_random.h17
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntp_refclock.h240
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntp_request.h955
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntp_rfc2553.h253
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntp_select.h35
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntp_stdlib.h298
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntp_string.h37
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntp_syscall.h56
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntp_syslog.h86
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntp_tty.h103
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntp_types.h302
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntp_unixtime.h47
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntp_worker.h197
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntp_workimpl.h30
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntpd.h585
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/ntpsim.h146
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/parse.h431
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/rc_cmdlength.h2
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/recvbuff.h124
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/refclock_atom.h15
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/refidsmear.h3
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/safecast.h34
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/timespecops.h393
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/timetoa.h83
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/timevalops.h446
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/trimble.h160
-rw-r--r--sebhbsd/freebsd/contrib/ntp/include/vint64ops.h28
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/assertions.c147
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/error.c108
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/hmacsha.c596
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/app.h375
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/assertions.h126
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/backtrace.h131
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/base32.h128
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/base64.h99
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/bind9.h30
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/bitstring.h157
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/boolean.h31
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/buffer.h904
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/bufferlist.h86
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/commandline.h50
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/entropy.h314
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/error.h63
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/event.h121
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/eventclass.h53
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/file.h304
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/formatcheck.h40
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/fsaccess.h178
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/hash.h185
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/heap.h170
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/hex.h98
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/hmacmd5.h72
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/hmacsha.h169
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/httpd.h64
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/interfaceiter.h138
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/ipv6.h148
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/iterated_hash.h47
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/lang.h33
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/lex.h431
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/lfsr.h130
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/lib.h50
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/list.h197
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/log.h914
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/magic.h41
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/md5.h83
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/msgcat.h131
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/msgs.h195
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/mutexblock.h71
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/namespace.h171
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/netaddr.h180
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/netscope.h43
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/ondestroy.h116
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/os.h38
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/parseint.h64
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/platform.h40
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/portset.h141
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/print.h87
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/queue.h100
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/quota.h119
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/radix.h240
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/random.h62
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/ratelimiter.h134
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/refcount.h233
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/region.h99
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/resource.h97
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/result.h109
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/resultclass.h51
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/rwlock.h135
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/serial.h75
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/sha1.h68
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/sha2.h145
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/sockaddr.h241
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/socket.h1168
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/stats.h121
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/stdio.h77
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/stdlib.h40
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/string.h249
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/symtab.h139
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/task.h796
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/taskpool.h157
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/timer.h431
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/types.h129
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/util.h238
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/version.h28
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/xml.h41
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/iterated_hash.c50
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/lib.c105
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/log.c1769
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/netaddr.c437
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/nls/msgcat.c133
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/pthreads/include/isc/mutex.h145
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/pthreads/include/isc/once.h50
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/pthreads/mutex.c286
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/result.c216
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/sha1.c356
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/sockaddr.c512
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/tsmemcmp.c57
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/unix/dir.c258
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/unix/errno2result.c124
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/unix/errno2result.h41
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/unix/file.c546
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/unix/ifiter_getifaddrs.c283
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/unix/ifiter_ioctl.c1034
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/unix/include/isc/dir.h94
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/unix/include/isc/int.h55
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/unix/include/isc/keyboard.h52
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/unix/include/isc/net.h364
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/unix/include/isc/offset.h46
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/unix/include/isc/stat.h52
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/unix/include/isc/stdtime.h64
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/unix/include/isc/strerror.h45
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/unix/include/isc/time.h334
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/unix/interfaceiter.c329
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/unix/net.c525
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/unix/stdio.c131
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/unix/strerror.c78
-rw-r--r--sebhbsd/freebsd/contrib/ntp/lib/isc/unix/time.c422
-rw-r--r--sebhbsd/freebsd/contrib/ntp/libntp/a_md5encrypt.c287
-rw-r--r--sebhbsd/freebsd/contrib/ntp/libntp/atoint.c53
-rw-r--r--sebhbsd/freebsd/contrib/ntp/libntp/authkeys.c931
-rw-r--r--sebhbsd/freebsd/contrib/ntp/libntp/authreadkeys.c409
-rw-r--r--sebhbsd/freebsd/contrib/ntp/libntp/clocktypes.c125
-rw-r--r--sebhbsd/freebsd/contrib/ntp/libntp/decodenetnum.c88
-rw-r--r--sebhbsd/freebsd/contrib/ntp/libntp/dolfptoa.c176
-rw-r--r--sebhbsd/freebsd/contrib/ntp/libntp/emalloc.c152
-rw-r--r--sebhbsd/freebsd/contrib/ntp/libntp/findconfig.c76
-rw-r--r--sebhbsd/freebsd/contrib/ntp/libntp/humandate.c62
-rw-r--r--sebhbsd/freebsd/contrib/ntp/libntp/is_ip_address.c91
-rw-r--r--sebhbsd/freebsd/contrib/ntp/libntp/lib_strbuf.c41
-rw-r--r--sebhbsd/freebsd/contrib/ntp/libntp/machines.c535
-rw-r--r--sebhbsd/freebsd/contrib/ntp/libntp/modetoa.c37
-rw-r--r--sebhbsd/freebsd/contrib/ntp/libntp/msyslog.c586
-rw-r--r--sebhbsd/freebsd/contrib/ntp/libntp/netof.c57
-rw-r--r--sebhbsd/freebsd/contrib/ntp/libntp/ntp_calendar.c1977
-rw-r--r--sebhbsd/freebsd/contrib/ntp/libntp/ntp_intres.c1156
-rw-r--r--sebhbsd/freebsd/contrib/ntp/libntp/ntp_libopts.c60
-rw-r--r--sebhbsd/freebsd/contrib/ntp/libntp/ntp_random.c501
-rw-r--r--sebhbsd/freebsd/contrib/ntp/libntp/ntp_rfc2553.c580
-rw-r--r--sebhbsd/freebsd/contrib/ntp/libntp/ntp_worker.c374
-rw-r--r--sebhbsd/freebsd/contrib/ntp/libntp/numtoa.c61
-rw-r--r--sebhbsd/freebsd/contrib/ntp/libntp/prettydate.c238
-rw-r--r--sebhbsd/freebsd/contrib/ntp/libntp/recvbuff.c330
-rw-r--r--sebhbsd/freebsd/contrib/ntp/libntp/refidsmear.c60
-rw-r--r--sebhbsd/freebsd/contrib/ntp/libntp/refnumtoa.c38
-rw-r--r--sebhbsd/freebsd/contrib/ntp/libntp/socket.c220
-rw-r--r--sebhbsd/freebsd/contrib/ntp/libntp/socktoa.c172
-rw-r--r--sebhbsd/freebsd/contrib/ntp/libntp/statestr.c512
-rw-r--r--sebhbsd/freebsd/contrib/ntp/libntp/systime.c685
-rw-r--r--sebhbsd/freebsd/contrib/ntp/libntp/vint64ops.c286
-rw-r--r--sebhbsd/freebsd/contrib/ntp/libntp/work_fork.c619
-rw-r--r--sebhbsd/freebsd/contrib/ntp/libntp/work_thread.c945
-rw-r--r--sebhbsd/freebsd/contrib/ntp/libntp/xsbprintf.c77
-rw-r--r--sebhbsd/freebsd/contrib/ntp/ntpd/cmd_args.c207
-rw-r--r--sebhbsd/freebsd/contrib/ntp/ntpd/jupiter.h255
-rw-r--r--sebhbsd/freebsd/contrib/ntp/ntpd/ntp_config.c5493
-rw-r--r--sebhbsd/freebsd/contrib/ntp/ntpd/ntp_control.c5297
-rw-r--r--sebhbsd/freebsd/contrib/ntp/ntpd/ntp_crypto.c4174
-rw-r--r--sebhbsd/freebsd/contrib/ntp/ntpd/ntp_filegen.c647
-rw-r--r--sebhbsd/freebsd/contrib/ntp/ntpd/ntp_io.c4870
-rw-r--r--sebhbsd/freebsd/contrib/ntp/ntpd/ntp_keyword.h1164
-rw-r--r--sebhbsd/freebsd/contrib/ntp/ntpd/ntp_leapsec.c1198
-rw-r--r--sebhbsd/freebsd/contrib/ntp/ntpd/ntp_leapsec.h276
-rw-r--r--sebhbsd/freebsd/contrib/ntp/ntpd/ntp_loopfilter.c1397
-rw-r--r--sebhbsd/freebsd/contrib/ntp/ntpd/ntp_monitor.c502
-rw-r--r--sebhbsd/freebsd/contrib/ntp/ntpd/ntp_parser.c3747
-rw-r--r--sebhbsd/freebsd/contrib/ntp/ntpd/ntp_parser.h489
-rw-r--r--sebhbsd/freebsd/contrib/ntp/ntpd/ntp_peer.c1119
-rw-r--r--sebhbsd/freebsd/contrib/ntp/ntpd/ntp_proto.c5219
-rw-r--r--sebhbsd/freebsd/contrib/ntp/ntpd/ntp_refclock.c1382
-rw-r--r--sebhbsd/freebsd/contrib/ntp/ntpd/ntp_request.c2789
-rw-r--r--sebhbsd/freebsd/contrib/ntp/ntpd/ntp_restrict.c804
-rw-r--r--sebhbsd/freebsd/contrib/ntp/ntpd/ntp_scanner.c937
-rw-r--r--sebhbsd/freebsd/contrib/ntp/ntpd/ntp_scanner.h142
-rw-r--r--sebhbsd/freebsd/contrib/ntp/ntpd/ntp_signd.c242
-rw-r--r--sebhbsd/freebsd/contrib/ntp/ntpd/ntp_timer.c712
-rw-r--r--sebhbsd/freebsd/contrib/ntp/ntpd/ntp_util.c1047
-rw-r--r--sebhbsd/freebsd/contrib/ntp/ntpd/ntpd-opts.c1986
-rw-r--r--sebhbsd/freebsd/contrib/ntp/ntpd/ntpd-opts.h465
-rw-r--r--sebhbsd/freebsd/contrib/ntp/ntpd/ntpd.c1804
-rw-r--r--sebhbsd/freebsd/contrib/ntp/ntpd/ntpsim.c660
-rw-r--r--sebhbsd/freebsd/contrib/ntp/ntpd/ppsapi_timepps.h26
-rw-r--r--sebhbsd/freebsd/contrib/ntp/ntpd/rc_cmdlength.c40
-rw-r--r--sebhbsd/freebsd/contrib/ntp/ntpd/refclock_palisade.h202
-rw-r--r--sebhbsd/freebsd/contrib/ntp/ntpd/version.c5
-rw-r--r--sebhbsd/freebsd/contrib/ntp/ntpdc/ntpdc.h67
-rw-r--r--sebhbsd/freebsd/contrib/ntp/ntpdc/ntpdc_ops.c3153
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/ag-char-map.h526
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/alias.c116
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/ao-strs.c374
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/ao-strs.h330
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/autoopts.c397
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/autoopts.h484
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/autoopts/options.h1261
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/autoopts/project.h77
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/autoopts/usage-txt.h657
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/boolean.c95
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/check.c177
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/compat/compat.h383
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/compat/pathfind.c294
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/configfile.c1381
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/cook.c325
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/enum.c652
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/env.c267
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/file.c201
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/find.c780
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/genshell.c847
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/genshell.h209
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/gettext.h288
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/init.c293
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/intprops.h320
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/libopts.c50
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/load.c588
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/makeshell.c956
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/nested.c938
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/numeric.c179
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/option-value-type.c156
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/option-value-type.h60
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/option-xat-attribute.c148
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/option-xat-attribute.h57
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/parse-duration.c610
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/parse-duration.h90
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/pgusage.c187
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/proto.h146
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/putshell.c511
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/reset.c141
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/restore.c223
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/save.c809
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/sort.c340
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/stack.c267
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/streqvcmp.c284
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/text_mmap.c379
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/time.c143
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/tokenize.c339
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/usage.c1336
-rw-r--r--sebhbsd/freebsd/contrib/ntp/sntp/libopts/version.c237
-rw-r--r--sebhbsd/rtemsbsd/include/machine/rtems-bsd-program.h212
-rw-r--r--sebhbsd/rtemsbsd/include/rtems/ntpd.h62
-rw-r--r--sebhbsd/rtemsbsd/rtems/program-internal.h84
-rw-r--r--sebhbsd/rtemsbsd/rtems/rtems-program-socket.c79
-rw-r--r--sebhbsd/rtemsbsd/rtems/rtems-program.c680
300 files changed, 122919 insertions, 0 deletions
diff --git a/COPYING.sebhbsd b/COPYING.sebhbsd
new file mode 100644
index 0000000..ff638ef
--- /dev/null
+++ b/COPYING.sebhbsd
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
diff --git a/ORIGIN.sebhbsd b/ORIGIN.sebhbsd
new file mode 100644
index 0000000..43caff1
--- /dev/null
+++ b/ORIGIN.sebhbsd
@@ -0,0 +1,2 @@
+The files under the sebhbsd/ directory are sourced from:
+https://github.com/sebhub/rtems-libbsd.git
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ascii.h b/sebhbsd/freebsd/contrib/ntp/include/ascii.h
new file mode 100644
index 0000000..a789091
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ascii.h
@@ -0,0 +1,96 @@
+/*
+ * /src/NTP/ntp4-dev/include/ascii.h,v 4.4 2005/04/16 17:32:10 kardel RELEASE_20050508_A
+ *
+ * ascii.h,v 4.4 2005/04/16 17:32:10 kardel RELEASE_20050508_A
+ *
+ * $Created: Sun Jul 20 11:42:53 1997 $
+ *
+ * Copyright (c) 1997-2005 by Frank Kardel <kardel <AT> ntp.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED 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.
+ *
+ */
+#ifndef ASCII_H
+#define ASCII_H
+
+/*
+ * just name the common ASCII control codes
+ */
+#define NUL 0
+#define SOH 1
+#define STX 2
+#define ETX 3
+#define EOT 4
+#define ENQ 5
+#define ACK 6
+#define BEL 7
+#define BS 8
+#define HT 9
+#define NL 10
+#define VT 11
+#define NP 12
+#define CR 13
+#define SO 14
+#define SI 15
+#define DLE 16
+#define DC1 17
+#define DC2 18
+#define DC3 19
+#define DC4 20
+#define NAK 21
+#define SYN 22
+#define ETB 23
+#define CAN 24
+#define EM 25
+#define SUB 26
+#define ESC 27
+#define FS 28
+#define GS 29
+#define RS 30
+#define US 31
+#define SP 32
+#define DEL 127
+
+#endif
+/*
+ * History:
+ *
+ * ascii.h,v
+ * Revision 4.4 2005/04/16 17:32:10 kardel
+ * update copyright
+ *
+ * Revision 4.3 2004/11/14 15:29:41 kardel
+ * support PPSAPI, upgrade Copyright to Berkeley style
+ *
+ * Revision 4.1 1998/07/11 10:05:22 kardel
+ * Release 4.0.73d reconcilation
+ *
+ * Revision 4.0 1998/04/10 19:50:38 kardel
+ * Start 4.0 release version numbering
+ *
+ * Revision 4.0 1998/04/10 19:50:38 kardel
+ * Start 4.0 release version numbering
+ *
+ */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/audio.h b/sebhbsd/freebsd/contrib/ntp/include/audio.h
new file mode 100644
index 0000000..0d74226
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/audio.h
@@ -0,0 +1,14 @@
+/*
+ * Header file for audio drivers
+ */
+#include "ntp_types.h"
+
+#define MAXGAIN 255 /* max codec gain */
+#define MONGAIN 127 /* codec monitor gain */
+
+/*
+ * Function prototypes
+ */
+int audio_init (const char *, int, int);
+int audio_gain (int, int, int);
+void audio_show (void);
diff --git a/sebhbsd/freebsd/contrib/ntp/include/binio.h b/sebhbsd/freebsd/contrib/ntp/include/binio.h
new file mode 100644
index 0000000..cf98633
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/binio.h
@@ -0,0 +1,86 @@
+/*
+ * /src/NTP/ntp4-dev/include/binio.h,v 4.5 2005/04/16 17:32:10 kardel RELEASE_20050508_A
+ *
+ * binio.h,v 4.5 2005/04/16 17:32:10 kardel RELEASE_20050508_A
+ *
+ * $Created: Sun Jul 20 13:03:05 1997 $
+ *
+ * Copyright (c) 1997-2005 by Frank Kardel <kardel <AT> ntp.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED 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.
+ *
+ */
+#ifndef BINIO_H
+#define BINIO_H
+
+#include "ntp_stdlib.h"
+
+long get_lsb_short (unsigned char **);
+void put_lsb_short (unsigned char **, long);
+long get_lsb_long (unsigned char **);
+void put_lsb_long (unsigned char **, long);
+
+#define get_lsb_int16( _x_ ) ((int16_t) get_lsb_short( _x_ ))
+#define get_lsb_uint16( _x_ ) ((uint16_t) get_lsb_short( _x_ ))
+#define get_lsb_int32( _x_ ) ((int32_t) get_lsb_long( _x_ ))
+#define get_lsb_uint32( _x_ ) ((uint32_t) get_lsb_long( _x_ ))
+
+long get_msb_short (unsigned char **);
+void put_msb_short (unsigned char **, long);
+long get_msb_long (unsigned char **);
+void put_msb_long (unsigned char **, long);
+
+#define get_msb_int16( _x_ ) ((int16_t) get_msb_short( _x_ ))
+#define get_msb_uint16( _x_ ) ((uint16_t) get_msb_short( _x_ ))
+#define get_msb_int32( _x_ ) ((int32_t) get_msb_long( _x_ ))
+#define get_msb_uint32( _x_ ) ((uint32_t) get_msb_long( _x_ ))
+
+#endif
+/*
+ * History:
+ *
+ * binio.h,v
+ * Revision 4.5 2005/04/16 17:32:10 kardel
+ * update copyright
+ *
+ * Revision 4.4 2004/11/14 15:29:41 kardel
+ * support PPSAPI, upgrade Copyright to Berkeley style
+ *
+ * Revision 4.2 1998/06/28 16:52:15 kardel
+ * added binio MSB prototypes for {get,put}_msb_{short,long}
+ *
+ * Revision 4.1 1998/06/12 15:07:40 kardel
+ * fixed prototyping
+ *
+ * Revision 4.0 1998/04/10 19:50:38 kardel
+ * Start 4.0 release version numbering
+ *
+ * Revision 1.1 1998/04/10 19:27:32 kardel
+ * initial NTP VERSION 4 integration of PARSE with GPS166 binary support
+ *
+ * Revision 1.1 1997/10/06 20:55:37 kardel
+ * new parse structure
+ *
+ */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/config.h b/sebhbsd/freebsd/contrib/ntp/include/config.h
new file mode 100644
index 0000000..0cd7aba
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/config.h
@@ -0,0 +1,1854 @@
+/* config.h. Generated from config.h.in by configure. */
+/* config.h.in. Generated from configure.ac by autoheader. */
+/* $FreeBSD$ */
+
+#define RTEMS_BSD_PROGRAM_NO_MALLOC_WRAP
+#define RTEMS_BSD_PROGRAM_NO_CALLOC_WRAP
+#define RTEMS_BSD_PROGRAM_NO_REALLOC_WRAP
+#define RTEMS_BSD_PROGRAM_NO_STRDUP_WRAP
+#define RTEMS_BSD_PROGRAM_NO_STRNDUP_WRAP
+#define RTEMS_BSD_PROGRAM_NO_VASPRINTF_WRAP
+#define RTEMS_BSD_PROGRAM_NO_ASPRINTF_WRAP
+#define RTEMS_BSD_PROGRAM_NO_FREE_WRAP
+
+#include <machine/rtems-bsd-program.h>
+
+#include "namespace.h"
+
+/* Define if building universal (internal helper macro) */
+/* #undef AC_APPLE_UNIVERSAL_BUILD */
+
+/* Is adjtime() accurate? */
+/* #undef ADJTIME_IS_ACCURATE */
+
+/* Support NTP Autokey protocol? */
+/* #define AUTOKEY 1 */
+
+/* why not HAVE_P_S? */
+/* #undef CALL_PTHREAD_SETCONCURRENCY */
+
+/* ACTS modem service */
+#define CLOCK_ACTS 1
+
+/* Arbiter 1088A/B GPS receiver */
+#define CLOCK_ARBITER 1
+
+/* ARCRON support? */
+#define CLOCK_ARCRON_MSF 1
+
+/* Austron 2200A/2201A GPS receiver? */
+#define CLOCK_AS2201 1
+
+/* PPS interface? */
+#define CLOCK_ATOM 1
+
+/* Datum/Bancomm bc635/VME interface? */
+/* #undef CLOCK_BANC */
+
+/* Chronolog K-series WWVB receiver? */
+#define CLOCK_CHRONOLOG 1
+
+/* CHU modem/decoder */
+#define CLOCK_CHU 1
+
+/* Diems Computime Radio Clock? */
+/* #undef CLOCK_COMPUTIME */
+
+/* Datum Programmable Time System? */
+#define CLOCK_DATUM 1
+
+/* ELV/DCF7000 clock? */
+/* #undef CLOCK_DCF7000 */
+
+/* Dumb generic hh:mm:ss local clock? */
+#define CLOCK_DUMBCLOCK 1
+
+/* Forum Graphic GPS datating station driver? */
+#define CLOCK_FG 1
+
+/* GPSD JSON receiver */
+#define CLOCK_GPSDJSON 1
+
+/* TrueTime GPS receiver/VME interface? */
+/* #undef CLOCK_GPSVME */
+
+/* Heath GC-1000 WWV/WWVH receiver? */
+#define CLOCK_HEATH 1
+
+/* HOPF 6021 clock? */
+/* #undef CLOCK_HOPF6021 */
+
+/* HOPF PCI clock device? */
+#define CLOCK_HOPF_PCI 1
+
+/* HOPF serial clock device? */
+#define CLOCK_HOPF_SERIAL 1
+
+/* HP 58503A GPS receiver? */
+#define CLOCK_HPGPS 1
+
+/* IRIG audio decoder? */
+#define CLOCK_IRIG 1
+
+/* JJY receiver? */
+#define CLOCK_JJY 1
+
+/* Rockwell Jupiter GPS clock? */
+#define CLOCK_JUPITER 1
+
+/* Leitch CSD 5300 Master Clock System Driver? */
+#define CLOCK_LEITCH 1
+
+/* local clock reference? */
+#define CLOCK_LOCAL 1
+
+/* Meinberg clocks */
+#define CLOCK_MEINBERG 1
+
+/* Magnavox MX4200 GPS receiver */
+/* #undef CLOCK_MX4200 */
+
+/* NeoClock4X */
+#define CLOCK_NEOCLOCK4X 1
+
+/* NMEA GPS receiver */
+#define CLOCK_NMEA 1
+
+/* Motorola UT Oncore GPS */
+#define CLOCK_ONCORE 1
+
+/* Palisade clock */
+#define CLOCK_PALISADE 1
+
+/* PARSE driver interface */
+#define CLOCK_PARSE 1
+
+/* Conrad parallel port radio clock */
+#define CLOCK_PCF 1
+
+/* PCL 720 clock support */
+/* #undef CLOCK_PPS720 */
+
+/* PST/Traconex 1020 WWV/WWVH receiver */
+#define CLOCK_PST 1
+
+/* DCF77 raw time code */
+#define CLOCK_RAWDCF 1
+
+/* RCC 8000 clock */
+/* #undef CLOCK_RCC8000 */
+
+/* RIPE NCC Trimble clock */
+/* #undef CLOCK_RIPENCC */
+
+/* Schmid DCF77 clock */
+/* #undef CLOCK_SCHMID */
+
+/* SEL240X protocol */
+/* #undef CLOCK_SEL240X */
+
+/* clock thru shared memory */
+#define CLOCK_SHM 1
+
+/* Spectracom 8170/Netclock/2 WWVB receiver */
+#define CLOCK_SPECTRACOM 1
+
+/* KSI/Odetics TPRO/S GPS receiver/IRIG interface */
+/* #undef CLOCK_TPRO */
+
+/* Trimble GPS receiver/TAIP protocol */
+/* #undef CLOCK_TRIMTAIP */
+
+/* Trimble GPS receiver/TSIP protocol */
+/* #undef CLOCK_TRIMTSIP */
+
+/* Kinemetrics/TrueTime receivers */
+#define CLOCK_TRUETIME 1
+
+/* Spectracom TSYNC timing board */
+/* #undef CLOCK_TSYNCPCI */
+
+/* TrueTime 560 IRIG-B decoder? */
+/* #undef CLOCK_TT560 */
+
+/* Ultralink M320 WWVB receiver? */
+#define CLOCK_ULINK 1
+
+/* VARITEXT clock */
+/* #undef CLOCK_VARITEXT */
+
+/* WHARTON 400A Series clock */
+/* #undef CLOCK_WHARTON_400A */
+
+/* WWV audio driver */
+#define CLOCK_WWV 1
+
+/* Zyfer GPStarplus */
+#define CLOCK_ZYFER 1
+
+/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
+ systems. This function is required for `alloca.c' support on those systems.
+ */
+/* #undef CRAY_STACKSEG_END */
+
+/* Define to 1 if using `alloca.c'. */
+/* #undef C_ALLOCA */
+
+/* Enable debugging code? */
+/* #undef DEBUG */
+
+/* Enable processing time debugging? */
+/* #undef DEBUG_TIMING */
+
+/* Declaration style */
+/* #undef DECL_ADJTIME_0 */
+
+/* Declaration style */
+/* #undef DECL_BCOPY_0 */
+
+/* Declaration style */
+/* #undef DECL_BZERO_0 */
+
+/* Declaration style */
+/* #undef DECL_CFSETISPEED_0 */
+
+/* Declare errno? */
+/* #undef DECL_ERRNO */
+
+/* Declaration style */
+/* #undef DECL_HSTRERROR_0 */
+
+/* Declare h_errno? */
+#define DECL_H_ERRNO 1
+
+/* Declaration style */
+/* #undef DECL_INET_NTOA_0 */
+
+/* Declaration style */
+/* #undef DECL_IOCTL_0 */
+
+/* Declaration style */
+/* #undef DECL_IPC_0 */
+
+/* Declaration style */
+/* #undef DECL_MEMMOVE_0 */
+
+/* Declaration style */
+/* #undef DECL_MKSTEMP_0 */
+
+/* Declaration style */
+/* #undef DECL_MKTEMP_0 */
+
+/* Declaration style */
+/* #undef DECL_NLIST_0 */
+
+/* Declaration style */
+/* #undef DECL_PLOCK_0 */
+
+/* Declaration style */
+/* #undef DECL_RENAME_0 */
+
+/* Declaration style */
+/* #undef DECL_SELECT_0 */
+
+/* Declaration style */
+/* #undef DECL_SETITIMER_0 */
+
+/* Declaration style */
+/* #undef DECL_SETPRIORITY_0 */
+
+/* Declaration style */
+/* #undef DECL_SETPRIORITY_1 */
+
+/* Declaration style */
+/* #undef DECL_SIGVEC_0 */
+
+/* Declaration style */
+/* #undef DECL_STDIO_0 */
+
+/* Declaration style */
+/* #undef DECL_STIME_0 */
+
+/* Declaration style */
+/* #undef DECL_STIME_1 */
+
+/* Declaration style */
+/* #undef DECL_STRERROR_0 */
+
+/* Declaration style */
+/* #undef DECL_STRTOL_0 */
+
+/* Declare syscall()? */
+/* #undef DECL_SYSCALL */
+
+/* Declaration style */
+/* #undef DECL_SYSLOG_0 */
+
+/* Declaration style */
+/* #undef DECL_TIMEOFDAY_0 */
+
+/* Declaration style */
+/* #undef DECL_TIME_0 */
+
+/* Declaration style */
+/* #undef DECL_TOLOWER_0 */
+
+/* Declaration style */
+/* #undef DECL_TOUPPER_0 */
+
+/* What is the fallback value for HZ? */
+#define DEFAULT_HZ 100
+
+/* Default number of megabytes for RLIMIT_MEMLOCK */
+#define DFLT_RLIMIT_MEMLOCK -1
+
+/* Default number of 4k pages for RLIMIT_STACK */
+#define DFLT_RLIMIT_STACK 50
+
+/* Directory separator character, usually / or \\ */
+#define DIR_SEP '/'
+
+/* use old autokey session key behavior? */
+/* #undef DISABLE_BUG1243_FIX */
+
+/* synch TODR hourly? */
+/* #undef DOSYNCTODR */
+
+/* The number of minutes in a DST adjustment */
+#define DSTMINUTES 60
+
+/* support dynamic interleave? */
+#define DYNAMIC_INTERLEAVE 0
+
+/* number of args to el_init() */
+#define EL_INIT_ARGS 4
+
+/* Provide the explicit 127.0.0.0/8 martian filter? */
+#define ENABLE_BUG3020_FIX 1
+
+/* Enable CMAC support? */
+#define ENABLE_CMAC 1
+
+/* nls support in libopts */
+/* #undef ENABLE_NLS */
+
+/* force ntpdate to step the clock if !defined(STEP_SLEW) ? */
+/* #undef FORCE_NTPDATE_STEP */
+
+/* What is getsockname()'s socklen type? */
+#define GETSOCKNAME_SOCKLEN_TYPE socklen_t
+
+/* Do we have a routing socket (rt_msghdr or rtattr)? */
+#define HAS_ROUTING_SOCKET 1
+
+/* via __adjtimex */
+/* #undef HAVE_ADJTIMEX */
+
+/* Define to 1 if you have `alloca', as a function or macro. */
+#define HAVE_ALLOCA 1
+
+/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
+ */
+/* #undef HAVE_ALLOCA_H */
+
+/* Define to 1 if you have the `arc4random_buf' function. */
+#define HAVE_ARC4RANDOM_BUF 1
+
+/* Define to 1 if you have the <arpa/nameser.h> header file. */
+#define HAVE_ARPA_NAMESER_H 1
+
+/* Define to 1 if you have the `atomic_thread_fence' function. */
+/* #undef HAVE_ATOMIC_THREAD_FENCE */
+
+/* Do we have audio support? */
+#define HAVE_AUDIO /**/
+
+/* Define to 1 if you have the <bstring.h> header file. */
+/* #undef HAVE_BSTRING_H */
+
+/* Define to 1 if you have the `canonicalize_file_name' function. */
+/* #undef HAVE_CANONICALIZE_FILE_NAME */
+
+/* Define to 1 if you have the `chmod' function. */
+#define HAVE_CHMOD 1
+
+/* Do we have the CIOGETEV ioctl (SunOS, Linux)? */
+/* #undef HAVE_CIOGETEV */
+
+/* Define to 1 if you have the `clock_getres' function. */
+#define HAVE_CLOCK_GETRES 1
+
+/* Define to 1 if you have the `clock_gettime' function. */
+#define HAVE_CLOCK_GETTIME 1
+
+/* Define to 1 if you have the `clock_settime' function. */
+#define HAVE_CLOCK_SETTIME 1
+
+/* Define to 1 if you have the <cthreads.h> header file. */
+/* #undef HAVE_CTHREADS_H */
+
+/* Define to 1 if you have the `daemon' function. */
+#define HAVE_DAEMON 1
+
+/* Define to 1 if you have the declaration of `siglongjmp', and to 0 if you
+ don't. */
+#define HAVE_DECL_SIGLONGJMP 1
+
+/* Define to 1 if you have the declaration of `sigsetjmp', and to 0 if you
+ don't. */
+#define HAVE_DECL_SIGSETJMP 1
+
+/* Define to 1 if you have the declaration of `strerror_r', and to 0 if you
+ don't. */
+#define HAVE_DECL_STRERROR_R 1
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
+ */
+#define HAVE_DIRENT_H 1
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Use Rendezvous/DNS-SD registration */
+/* #undef HAVE_DNSREGISTRATION */
+
+/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
+/* #undef HAVE_DOPRNT */
+
+/* Can we drop root privileges? */
+/* #undef HAVE_DROPROOT */
+
+/* Define to 1 if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define to 1 if you have the `EVP_MD_do_all_sorted' function. */
+#define HAVE_EVP_MD_DO_ALL_SORTED 1
+
+/* Define to 1 if you have the `fchmod' function. */
+#define HAVE_FCHMOD 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if you have the `finite' function. */
+/* #undef HAVE_FINITE */
+
+/* Define to 1 if you have the `fnmatch' function. */
+#define HAVE_FNMATCH 1
+
+/* Define to 1 if you have the <fnmatch.h> header file. */
+#define HAVE_FNMATCH_H 1
+
+/* Define to 1 if you have the `fork' function. */
+/* #undef HAVE_FORK */
+
+/* Define to 1 if you have the `fstat' function. */
+#define HAVE_FSTAT 1
+
+/* Define to 1 if you have the `getbootfile' function. */
+#define HAVE_GETBOOTFILE 1
+
+/* Define to 1 if you have the `getclock' function. */
+/* #undef HAVE_GETCLOCK */
+
+/* Define to 1 if you have the `getdtablesize' function. */
+#define HAVE_GETDTABLESIZE 1
+
+/* Define to 1 if you have the `getifaddrs' function. */
+#define HAVE_GETIFADDRS 1
+
+/* Define to 1 if you have the `getpassphrase' function. */
+/* #undef HAVE_GETPASSPHRASE */
+
+/* Define to 1 if you have the `getrusage' function. */
+#define HAVE_GETRUSAGE 1
+
+/* Define to 1 if you have the `getuid' function. */
+#define HAVE_GETUID 1
+
+/* if you have GNU Pth */
+/* #undef HAVE_GNU_PTH */
+
+/* Define to 1 if you have the <histedit.h> header file. */
+#define HAVE_HISTEDIT_H 1
+
+/* Define to 1 if you have the <history.h> header file. */
+/* #undef HAVE_HISTORY_H */
+
+/* Obvious */
+#define HAVE_HZ_IN_STRUCT_CLOCKINFO 1
+
+/* Define to 1 if you have the <ieeefp.h> header file. */
+#define HAVE_IEEEFP_H 1
+
+/* have iflist_sysctl? */
+#define HAVE_IFLIST_SYSCTL 1
+
+/* Define to 1 if you have the `if_nametoindex' function. */
+#define HAVE_IF_NAMETOINDEX 1
+
+/* inline keyword or macro available */
+#define HAVE_INLINE 1
+
+/* Define to 1 if the system has the type `int16_t'. */
+#define HAVE_INT16_T 1
+
+/* Define to 1 if the system has the type `int32'. */
+/* #undef HAVE_INT32 */
+
+/* int32 type in DNS headers, not others. */
+/* #undef HAVE_INT32_ONLY_WITH_DNS */
+
+/* Define to 1 if the system has the type `int32_t'. */
+#define HAVE_INT32_T 1
+
+/* Define to 1 if the system has the type `int8_t'. */
+#define HAVE_INT8_T 1
+
+/* Define to 1 if the system has the type `intmax_t'. */
+/* #undef HAVE_INTMAX_T */
+
+/* Define to 1 if the system has the type `intptr_t'. */
+#define HAVE_INTPTR_T 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the `isfinite' function. */
+#define HAVE_ISFINITE 1
+
+/* Define to 1 if you have the <kvm.h> header file. */
+#define HAVE_KVM_H 1
+
+/* Define to 1 if you have the `kvm_open' function. */
+/* #undef HAVE_KVM_OPEN */
+
+/* Define to 1 if you have the `gen' library (-lgen). */
+/* #undef HAVE_LIBGEN */
+
+/* Define to 1 if you have the <libgen.h> header file. */
+#define HAVE_LIBGEN_H 1
+
+/* Define to 1 if you have the `intl' library (-lintl). */
+/* #undef HAVE_LIBINTL */
+
+/* Define to 1 if you have the <libintl.h> header file. */
+/* #undef HAVE_LIBINTL_H */
+
+/* Define to 1 if you have the <libscf.h> header file. */
+/* #undef HAVE_LIBSCF_H */
+
+/* Define to 1 if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* using Linux pthread? */
+/* #undef HAVE_LINUXTHREADS */
+
+/* Do we have Linux capabilities? */
+/* #undef HAVE_LINUX_CAPABILITIES */
+
+/* Define to 1 if you have the <linux/if_addr.h> header file. */
+/* #undef HAVE_LINUX_IF_ADDR_H */
+
+/* if you have LinuxThreads */
+/* #undef HAVE_LINUX_THREADS */
+
+/* Define to 1 if you have the `localeconv' function. */
+/* #undef HAVE_LOCALECONV */
+
+/* Define to 1 if you have the <locale.h> header file. */
+/* #undef HAVE_LOCALE_H */
+
+/* Define to 1 if the system has the type `long double'. */
+/* #undef HAVE_LONG_DOUBLE */
+
+/* Define to 1 if the system has the type `long long'. */
+#define HAVE_LONG_LONG 1
+
+/* Define to 1 if the system has the type `long long int'. */
+/* #undef HAVE_LONG_LONG_INT */
+
+/* if you have SunOS LWP package */
+/* #undef HAVE_LWP */
+
+/* Define to 1 if you have the <lwp/lwp.h> header file. */
+/* #undef HAVE_LWP_LWP_H */
+
+/* Define to 1 if you have the <machine/inline.h> header file. */
+/* #undef HAVE_MACHINE_INLINE_H */
+
+/* Define to 1 if you have the <machine/soundcard.h> header file. */
+/* #undef HAVE_MACHINE_SOUNDCARD_H */
+
+/* define if you have Mach Cthreads */
+/* #undef HAVE_MACH_CTHREADS */
+
+/* Define to 1 if you have the <mach/cthreads.h> header file. */
+/* #undef HAVE_MACH_CTHREADS_H */
+
+/* Define to 1 if you have the <math.h> header file. */
+#define HAVE_MATH_H 1
+
+/* Define to 1 if you have the `MD5Init' function. */
+#define HAVE_MD5INIT 1
+
+/* Define to 1 if you have the <md5.h> header file. */
+#define HAVE_MD5_H 1
+
+/* Define to 1 if you have the `memlk' function. */
+/* #undef HAVE_MEMLK */
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `mkstemp' function. */
+#define HAVE_MKSTEMP 1
+
+/* Define to 1 if you have the `mktime' function. */
+#define HAVE_MKTIME 1
+
+/* Define to 1 if you have the `mlockall' function. */
+/* #undef HAVE_MLOCKALL */
+
+/* Define to 1 if you have the `mmap' function. */
+/* #undef HAVE_MMAP */
+
+/* Define to 1 if you have the `nanosleep' function. */
+#define HAVE_NANOSLEEP 1
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+/* #undef HAVE_NDIR_H */
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#define HAVE_NETDB_H 1
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#define HAVE_NETINET_IN_H 1
+
+/* Define to 1 if you have the <netinet/in_system.h> header file. */
+/* #undef HAVE_NETINET_IN_SYSTEM_H */
+
+/* Define to 1 if you have the <netinet/in_systm.h> header file. */
+#define HAVE_NETINET_IN_SYSTM_H 1
+
+/* Define to 1 if you have the <netinet/in_var.h> header file. */
+#define HAVE_NETINET_IN_VAR_H 1
+
+/* Define to 1 if you have the <netinet/ip.h> header file. */
+#define HAVE_NETINET_IP_H 1
+
+/* NetInfo support? */
+/* #undef HAVE_NETINFO */
+
+/* Define to 1 if you have the <netinfo/ni.h> header file. */
+/* #undef HAVE_NETINFO_NI_H */
+
+/* Define to 1 if you have the <net/if6.h> header file. */
+/* #undef HAVE_NET_IF6_H */
+
+/* Define to 1 if you have the <net/if.h> header file. */
+#define HAVE_NET_IF_H 1
+
+/* Define to 1 if you have the <net/if_var.h> header file. */
+#define HAVE_NET_IF_VAR_H 1
+
+/* Define to 1 if you have the <net/route.h> header file. */
+#define HAVE_NET_ROUTE_H 1
+
+/* Define to 1 if you have the `nice' function. */
+/* #undef HAVE_NICE */
+#define HAVE_NO_NICE 1
+
+/* Define to 1 if you have the <nlist.h> header file. */
+#define HAVE_NLIST_H 1
+
+/* via __adjtimex */
+#define HAVE_NTP_ADJTIME 1
+
+/* via __ntp_gettime */
+#define HAVE_NTP_GETTIME 1
+
+/* Do we want support for Samba's signing daemon? */
+#define HAVE_NTP_SIGND 1
+
+/* if you have NT Event Log */
+/* #undef HAVE_NT_EVENT_LOG */
+
+/* if you have NT Service Manager */
+/* #undef HAVE_NT_SERVICE_MANAGER */
+
+/* if you have NT Threads */
+/* #undef HAVE_NT_THREADS */
+
+/* Define to 1 if you have the <openssl/cmac.h> header file. */
+#define HAVE_OPENSSL_CMAC_H 1
+
+/* Define to 1 if you have the <openssl/hmac.h> header file. */
+#define HAVE_OPENSSL_HMAC_H 1
+
+/* Define to 1 if the system has the type `pid_t'. */
+#define HAVE_PID_T 1
+
+/* Define to 1 if you have the `plock' function. */
+/* #undef HAVE_PLOCK */
+
+/* Define to 1 if you have the <poll.h> header file. */
+#define HAVE_POLL_H 1
+
+/* Do we have the PPS API per the Draft RFC? */
+#define HAVE_PPSAPI 1
+
+/* Define to 1 if you have the <priv.h> header file. */
+/* #undef HAVE_PRIV_H */
+
+/* Define if you have POSIX threads libraries and header files. */
+/* #undef HAVE_PTHREAD */
+
+/* define to pthreads API spec revision */
+#define HAVE_PTHREADS 10
+
+/* Define to 1 if you have the `pthread_attr_getstacksize' function. */
+#define HAVE_PTHREAD_ATTR_GETSTACKSIZE 1
+
+/* Define to 1 if you have the `pthread_attr_setstacksize' function. */
+#define HAVE_PTHREAD_ATTR_SETSTACKSIZE 1
+
+/* define if you have pthread_detach function */
+#define HAVE_PTHREAD_DETACH 1
+
+/* Define to 1 if you have the `pthread_getconcurrency' function. */
+#define HAVE_PTHREAD_GETCONCURRENCY 1
+
+/* Define to 1 if you have the <pthread.h> header file. */
+#define HAVE_PTHREAD_H 1
+
+/* Define to 1 if you have the `pthread_kill' function. */
+#define HAVE_PTHREAD_KILL 1
+
+/* Define to 1 if you have the `pthread_kill_other_threads_np' function. */
+/* #undef HAVE_PTHREAD_KILL_OTHER_THREADS_NP */
+
+/* define if you have pthread_rwlock_destroy function */
+#define HAVE_PTHREAD_RWLOCK_DESTROY 1
+
+/* Define to 1 if you have the `pthread_setconcurrency' function. */
+#define HAVE_PTHREAD_SETCONCURRENCY 1
+
+/* Define to 1 if you have the `pthread_yield' function. */
+#define HAVE_PTHREAD_YIELD 1
+
+/* Define to 1 if you have the <pth.h> header file. */
+/* #undef HAVE_PTH_H */
+
+/* Define to 1 if the system has the type `ptrdiff_t'. */
+#define HAVE_PTRDIFF_T 1
+
+/* Define to 1 if you have the `pututline' function. */
+/* #undef HAVE_PUTUTLINE */
+
+/* Define to 1 if you have the `pututxline' function. */
+#define HAVE_PUTUTXLINE 1
+
+/* Define to 1 if you have the `RAND_bytes' function. */
+#define HAVE_RAND_BYTES 1
+
+/* Define to 1 if you have the `RAND_poll' function. */
+#define HAVE_RAND_POLL 1
+
+/* Define to 1 if you have the <readline.h> header file. */
+/* #undef HAVE_READLINE_H */
+
+/* Define if your readline library has \`add_history' */
+#define HAVE_READLINE_HISTORY 1
+
+/* Define to 1 if you have the <readline/history.h> header file. */
+#define HAVE_READLINE_HISTORY_H 1
+
+/* Define to 1 if you have the <readline/readline.h> header file. */
+#define HAVE_READLINE_READLINE_H 1
+
+/* Define to 1 if you have the `readlink' function. */
+#define HAVE_READLINK 1
+
+/* Define to 1 if you have the `recvmsg' function. */
+#define HAVE_RECVMSG 1
+
+/* Define to 1 if you have the <resolv.h> header file. */
+#define HAVE_RESOLV_H 1
+
+/* Define to 1 if you have the `res_init' function. */
+#define HAVE_RES_INIT 1
+
+/* Do we have Linux routing socket? */
+/* #undef HAVE_RTNETLINK */
+
+/* Define to 1 if you have the `rtprio' function. */
+/* #undef HAVE_RTPRIO */
+
+/* Define to 1 if you have the <runetype.h> header file. */
+#define HAVE_RUNETYPE_H 1
+
+/* Obvious */
+#define HAVE_SA_SIGACTION_IN_STRUCT_SIGACTION 1
+
+/* Define to 1 if you have the <sched.h> header file. */
+#define HAVE_SCHED_H 1
+
+/* Define to 1 if you have the `sched_setscheduler' function. */
+#define HAVE_SCHED_SETSCHEDULER 1
+
+/* Define to 1 if you have the `sched_yield' function. */
+#define HAVE_SCHED_YIELD 1
+
+/* Define to 1 if you have the <semaphore.h> header file. */
+#define HAVE_SEMAPHORE_H 1
+
+/* Define to 1 if you have the `sem_timedwait' function. */
+#define HAVE_SEM_TIMEDWAIT 1
+
+/* Define to 1 if you have the <setjmp.h> header file. */
+#define HAVE_SETJMP_H 1
+
+/* Define to 1 if you have the `setlinebuf' function. */
+#define HAVE_SETLINEBUF 1
+
+/* Define to 1 if you have the `setpgid' function. */
+/* #undef HAVE_SETPGID */
+
+/* define if setpgrp takes 0 arguments */
+#define HAVE_SETPGRP_0 1
+
+/* Define to 1 if you have the `setpriority' function. */
+/* #undef HAVE_SETPRIORITY */
+
+/* Define to 1 if you have the `setrlimit' function. */
+/* #undef HAVE_SETRLIMIT */
+
+/* Define to 1 if you have the `setsid' function. */
+/* #undef HAVE_SETSID */
+
+/* Define to 1 if you have the `settimeofday' function. */
+/* #undef HAVE_SETTIMEOFDAY */
+
+/* Define to 1 if you have the `setvbuf' function. */
+#define HAVE_SETVBUF 1
+
+/* Define to 1 if you have the <sgtty.h> header file. */
+/* #undef HAVE_SGTTY_H */
+
+/* Define to 1 if you have the `sigaction' function. */
+#define HAVE_SIGACTION 1
+
+/* Can we use SIGIO for tcp and udp IO? */
+/* #undef HAVE_SIGNALED_IO */
+
+/* Define to 1 if you have the `sigset' function. */
+#define HAVE_SIGSET 1
+
+/* Define to 1 if you have the `sigvec' function. */
+#define HAVE_SIGVEC 1
+
+/* sigwait() available? */
+#define HAVE_SIGWAIT 1
+
+/* Define to 1 if the system has the type `size_t'. */
+#define HAVE_SIZE_T 1
+
+/* Define if C99-compliant `snprintf' is available. */
+#define HAVE_SNPRINTF 1
+
+/* Define to 1 if you have the `socketpair' function. */
+#define HAVE_SOCKETPAIR 1
+
+/* Are Solaris privileges available? */
+/* #undef HAVE_SOLARIS_PRIVS */
+
+/* Define to 1 if you have the <stdarg.h> header file. */
+#define HAVE_STDARG_H 1
+
+/* Define to 1 if you have the <stdatomic.h> header file. */
+#define HAVE_STDATOMIC_H 1
+
+/* Define to 1 if stdbool.h conforms to C99. */
+#define HAVE_STDBOOL_H 1
+
+/* Define to 1 if you have the <stddef.h> header file. */
+/* #undef HAVE_STDDEF_H */
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the `stime' function. */
+/* #undef HAVE_STIME */
+
+/* Define to 1 if you have the `strchr' function. */
+#define HAVE_STRCHR 1
+
+/* Define to 1 if you have the `strdup' function. */
+#define HAVE_STRDUP 1
+
+/* Define to 1 if you have the `strerror' function. */
+#define HAVE_STRERROR 1
+
+/* Define to 1 if you have the `strerror_r' function. */
+#define HAVE_STRERROR_R 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strlcat' function. */
+#define HAVE_STRLCAT 1
+
+/* Define to 1 if you have the `strlcpy' function. */
+#define HAVE_STRLCPY 1
+
+/* Define to 1 if you have the <stropts.h> header file. */
+/* #undef HAVE_STROPTS_H */
+
+/* Define to 1 if you have the `strrchr' function. */
+#define HAVE_STRRCHR 1
+
+/* Define to 1 if you have the `strsignal' function. */
+#define HAVE_STRSIGNAL 1
+
+/* Define to 1 if you have the `strtoll' function. */
+#define HAVE_STRTOLL 1
+
+/* Define to 1 if `decimal_point' is a member of `struct lconv'. */
+/* #undef HAVE_STRUCT_LCONV_DECIMAL_POINT */
+
+/* Define to 1 if `thousands_sep' is a member of `struct lconv'. */
+/* #undef HAVE_STRUCT_LCONV_THOUSANDS_SEP */
+
+/* Do we have struct ntptimeval? */
+#define HAVE_STRUCT_NTPTIMEVAL 1
+
+/* Define to 1 if `time.tv_nsec' is a member of `struct ntptimeval'. */
+#define HAVE_STRUCT_NTPTIMEVAL_TIME_TV_NSEC 1
+
+/* Does a system header define struct ppsclockev? */
+/* #undef HAVE_STRUCT_PPSCLOCKEV */
+
+/* Do we have struct snd_size? */
+#define HAVE_STRUCT_SND_SIZE 1
+
+/* Does a system header define struct sockaddr_storage? */
+#define HAVE_STRUCT_SOCKADDR_STORAGE 1
+
+/* struct timespec declared? */
+#define HAVE_STRUCT_TIMESPEC 1
+
+/* Define to 1 if you have the <sun/audioio.h> header file. */
+/* #undef HAVE_SUN_AUDIOIO_H */
+
+/* Define to 1 if you have the <synch.h> header file. */
+/* #undef HAVE_SYNCH_H */
+
+/* Define to 1 if you have the `sysconf' function. */
+#define HAVE_SYSCONF 1
+
+/* Define to 1 if you have the <sysexits.h> header file. */
+#define HAVE_SYSEXITS_H 1
+
+/* */
+#define HAVE_SYSLOG_FACILITYNAMES 1
+
+/* Define to 1 if you have the <sys/audioio.h> header file. */
+/* #undef HAVE_SYS_AUDIOIO_H */
+
+/* Define to 1 if you have the <sys/capability.h> header file. */
+#define HAVE_SYS_CAPABILITY_H 1
+
+/* Define to 1 if you have the <sys/clockctl.h> header file. */
+/* #undef HAVE_SYS_CLOCKCTL_H */
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+ */
+/* #undef HAVE_SYS_DIR_H */
+
+/* Define to 1 if you have the <sys/file.h> header file. */
+#define HAVE_SYS_FILE_H 1
+
+/* Define to 1 if you have the <sys/i8253.h> header file. */
+/* #undef HAVE_SYS_I8253_H */
+
+/* Define to 1 if you have the <sys/ioctl.h> header file. */
+#define HAVE_SYS_IOCTL_H 1
+
+/* Define to 1 if you have the <sys/ipc.h> header file. */
+#define HAVE_SYS_IPC_H 1
+
+/* Define to 1 if you have the <sys/limits.h> header file. */
+/* #undef HAVE_SYS_LIMITS_H */
+
+/* Define to 1 if you have the <sys/lock.h> header file. */
+#define HAVE_SYS_LOCK_H 1
+
+/* Define to 1 if you have the <sys/mac.h> header file. */
+#define HAVE_SYS_MAC_H 1
+
+/* Define to 1 if you have the <sys/mman.h> header file. */
+#define HAVE_SYS_MMAN_H 1
+
+/* Define to 1 if you have the <sys/modem.h> header file. */
+/* #undef HAVE_SYS_MODEM_H */
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+ */
+/* #undef HAVE_SYS_NDIR_H */
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define to 1 if you have the <sys/pcl720.h> header file. */
+/* #undef HAVE_SYS_PCL720_H */
+
+/* Define to 1 if you have the <sys/poll.h> header file. */
+#define HAVE_SYS_POLL_H 1
+
+/* Define to 1 if you have the <sys/ppsclock.h> header file. */
+/* #undef HAVE_SYS_PPSCLOCK_H */
+
+/* Define to 1 if you have the <sys/ppstime.h> header file. */
+/* #undef HAVE_SYS_PPSTIME_H */
+
+/* Define to 1 if you have the <sys/prctl.h> header file. */
+/* #undef HAVE_SYS_PRCTL_H */
+
+/* Define to 1 if you have the <sys/procset.h> header file. */
+/* #undef HAVE_SYS_PROCSET_H */
+
+/* Define to 1 if you have the <sys/proc.h> header file. */
+#define HAVE_SYS_PROC_H 1
+
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#define HAVE_SYS_RESOURCE_H 1
+
+/* Define to 1 if you have the <sys/sched.h> header file. */
+/* #undef HAVE_SYS_SCHED_H */
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#define HAVE_SYS_SELECT_H 1
+
+/* Define to 1 if you have the <sys/shm.h> header file. */
+#define HAVE_SYS_SHM_H 1
+
+/* Define to 1 if you have the <sys/signal.h> header file. */
+#define HAVE_SYS_SIGNAL_H 1
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#define HAVE_SYS_SOCKET_H 1
+
+/* Define to 1 if you have the <sys/sockio.h> header file. */
+#define HAVE_SYS_SOCKIO_H 1
+
+/* Define to 1 if you have the <sys/soundcard.h> header file. */
+#define HAVE_SYS_SOUNDCARD_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/stream.h> header file. */
+/* #undef HAVE_SYS_STREAM_H */
+
+/* Define to 1 if you have the <sys/stropts.h> header file. */
+/* #undef HAVE_SYS_STROPTS_H */
+
+/* Define to 1 if you have the <sys/sysctl.h> header file. */
+#define HAVE_SYS_SYSCTL_H 1
+
+/* Define to 1 if you have the <sys/syssgi.h> header file. */
+/* #undef HAVE_SYS_SYSSGI_H */
+
+/* Define to 1 if you have the <sys/systune.h> header file. */
+/* #undef HAVE_SYS_SYSTUNE_H */
+
+/* Define to 1 if you have the <sys/termios.h> header file. */
+#define HAVE_SYS_TERMIOS_H 1
+
+/* Define to 1 if you have the <sys/timepps.h> header file. */
+#define HAVE_SYS_TIMEPPS_H 1
+
+/* Define to 1 if you have the <sys/timers.h> header file. */
+#define HAVE_SYS_TIMERS_H 1
+
+/* Define to 1 if you have the <sys/timex.h> header file. */
+#define HAVE_SYS_TIMEX_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/tpro.h> header file. */
+/* #undef HAVE_SYS_TPRO_H */
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Use sys/uio.h for struct iovec help */
+/* #undef HAVE_SYS_UIO_H */
+
+/* Define to 1 if you have the <sys/un.h> header file. */
+#define HAVE_SYS_UN_H 1
+
+/* Define to 1 if you have the <sys/var.h> header file. */
+/* #undef HAVE_SYS_VAR_H */
+
+/* Define to 1 if you have the <sys/wait.h> header file. */
+#define HAVE_SYS_WAIT_H 1
+
+/* Define to 1 if the system has the type `s_char'. */
+/* #undef HAVE_S_CHAR */
+
+/* Define to 1 if you have the <termios.h> header file. */
+#define HAVE_TERMIOS_H 1
+
+/* Define to 1 if you have the <termio.h> header file. */
+/* #undef HAVE_TERMIO_H */
+
+/* if you have Solaris LWP (thr) package */
+/* #undef HAVE_THR */
+
+/* Define to 1 if you have the <thread.h> header file. */
+/* #undef HAVE_THREAD_H */
+
+/* Define to 1 if you have the `thr_getconcurrency' function. */
+/* #undef HAVE_THR_GETCONCURRENCY */
+
+/* Define to 1 if you have the `thr_setconcurrency' function. */
+/* #undef HAVE_THR_SETCONCURRENCY */
+
+/* Define to 1 if you have the `thr_yield' function. */
+/* #undef HAVE_THR_YIELD */
+
+/* Obvious */
+#define HAVE_TICKADJ_IN_STRUCT_CLOCKINFO 1
+
+/* Define to 1 if you have the `timegm' function. */
+#define HAVE_TIMEGM 1
+
+/* Define to 1 if you have the <timepps.h> header file. */
+/* #undef HAVE_TIMEPPS_H */
+
+/* Define to 1 if you have the `timer_create' function. */
+/* #undef HAVE_TIMER_CREATE */
+
+/* Define to 1 if you have the <timex.h> header file. */
+/* #undef HAVE_TIMEX_H */
+
+/* Define to 1 if you have the <time.h> header file. */
+#define HAVE_TIME_H 1
+
+/* Do we have the TIOCGPPSEV ioctl (Solaris)? */
+/* #undef HAVE_TIOCGPPSEV */
+
+/* Do we have the TIOCSPPS ioctl (Solaris)? */
+/* #undef HAVE_TIOCSPPS */
+
+/* Do we have the TIO serial stuff? */
+/* #undef HAVE_TIO_SERIAL_STUFF */
+
+/* Are TrustedBSD MAC policy privileges available? */
+#define HAVE_TRUSTEDBSD_MAC 1
+
+/* Define to 1 if the system has the type `uint16_t'. */
+#define HAVE_UINT16_T 1
+
+/* Define to 1 if the system has the type `uint32_t'. */
+#define HAVE_UINT32_T 1
+
+/* Define to 1 if the system has the type `uint8_t'. */
+#define HAVE_UINT8_T 1
+
+/* Define to 1 if the system has the type `uintmax_t'. */
+/* #undef HAVE_UINTMAX_T */
+
+/* Define to 1 if the system has the type `uintptr_t'. */
+#define HAVE_UINTPTR_T 1
+
+/* Define to 1 if the system has the type `uint_t'. */
+/* #undef HAVE_UINT_T */
+
+/* Define to 1 if you have the `umask' function. */
+/* #undef HAVE_UMASK */
+
+/* Define to 1 if you have the `uname' function. */
+#define HAVE_UNAME 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* deviant sigwait? */
+/* #undef HAVE_UNIXWARE_SIGWAIT */
+
+/* Define to 1 if the system has the type `unsigned long long int'. */
+#define HAVE_UNSIGNED_LONG_LONG_INT 1
+
+/* Define to 1 if you have the `updwtmp' function. */
+/* #undef HAVE_UPDWTMP */
+
+/* Define to 1 if you have the `updwtmpx' function. */
+/* #undef HAVE_UPDWTMPX */
+
+/* Define to 1 if you have the <utime.h> header file. */
+#define HAVE_UTIME_H 1
+
+/* Define to 1 if you have the <utmpx.h> header file. */
+/* #undef HAVE_UTMPX_H */
+
+/* Define to 1 if you have the <utmp.h> header file. */
+/* #undef HAVE_UTMP_H */
+
+/* Define to 1 if the system has the type `u_int32'. */
+/* #undef HAVE_U_INT32 */
+
+/* u_int32 type in DNS headers, not others. */
+/* #undef HAVE_U_INT32_ONLY_WITH_DNS */
+
+/* Define to 1 if you have the <values.h> header file. */
+/* #undef HAVE_VALUES_H */
+
+/* Define to 1 if you have the <varargs.h> header file. */
+/* #undef HAVE_VARARGS_H */
+
+/* Define to 1 if you have the `vfork' function. */
+#define HAVE_VFORK 1
+
+/* Define to 1 if you have the <vfork.h> header file. */
+/* #undef HAVE_VFORK_H */
+
+/* Define to 1 if you have the `vprintf' function. */
+#define HAVE_VPRINTF 1
+
+/* Define if C99-compliant `vsnprintf' is available. */
+#define HAVE_VSNPRINTF 1
+
+/* Define to 1 if you have the <wchar.h> header file. */
+#define HAVE_WCHAR_H 1
+
+/* Define to 1 if the system has the type `wchar_t'. */
+#define HAVE_WCHAR_T 1
+
+/* Define to 1 if the system has the type `wint_t'. */
+#define HAVE_WINT_T 1
+
+/* Define to 1 if `fork' works. */
+/* #undef HAVE_WORKING_FORK */
+
+/* Define to 1 if `vfork' works. */
+/* #undef HAVE_WORKING_VFORK */
+
+/* define if select implicitly yields */
+#define HAVE_YIELDING_SELECT 1
+
+/* Define to 1 if the system has the type `_Bool'. */
+#define HAVE__BOOL 1
+
+/* Define to 1 if you have the `_exit' function. */
+#define HAVE__EXIT 1
+
+/* Define to 1 if you have the </sys/sync/queue.h> header file. */
+/* #undef HAVE__SYS_SYNC_QUEUE_H */
+
+/* Define to 1 if you have the </sys/sync/sema.h> header file. */
+/* #undef HAVE__SYS_SYNC_SEMA_H */
+
+/* Define to 1 if you have the `__adjtimex' function. */
+/* #undef HAVE___ADJTIMEX */
+
+/* defined if C compiler supports __attribute__((...)) */
+#define HAVE___ATTRIBUTE__ /**/
+
+
+ /* define away __attribute__() if unsupported */
+ #ifndef HAVE___ATTRIBUTE__
+ # define __attribute__(x) /* empty */
+ #endif
+ #define ISC_PLATFORM_NORETURN_PRE
+ #define ISC_PLATFORM_NORETURN_POST __attribute__((__noreturn__))
+
+
+
+/* Define to 1 if you have the `__ntp_gettime' function. */
+/* #undef HAVE___NTP_GETTIME */
+
+/* Define to 1 if you have the `__res_init' function. */
+/* #undef HAVE___RES_INIT */
+
+/* Does struct sockaddr_storage have __ss_family? */
+/* #undef HAVE___SS_FAMILY_IN_SS */
+
+
+ /* Handle sockaddr_storage.__ss_family */
+ #ifdef HAVE___SS_FAMILY_IN_SS
+ # define ss_family __ss_family
+ #endif /* HAVE___SS_FAMILY_IN_SS */
+
+
+
+/* Define to provide `rpl_snprintf' function. */
+/* #undef HW_WANT_RPL_SNPRINTF */
+
+/* Define to provide `rpl_vsnprintf' function. */
+/* #undef HW_WANT_RPL_VSNPRINTF */
+
+/* Retry queries on _any_ DNS error? */
+/* #undef IGNORE_DNS_ERRORS */
+
+/* Should we use the IRIG sawtooth filter? */
+/* #undef IRIG_SUCKS */
+
+/* Enclose PTHREAD_ONCE_INIT in extra braces? */
+/* #undef ISC_PLATFORM_BRACEPTHREADONCEINIT */
+
+/* Do we need to fix in6isaddr? */
+/* #undef ISC_PLATFORM_FIXIN6ISADDR */
+
+/* ISC: do we have if_nametoindex()? */
+#define ISC_PLATFORM_HAVEIFNAMETOINDEX 1
+
+/* have struct if_laddrconf? */
+/* #undef ISC_PLATFORM_HAVEIF_LADDRCONF */
+
+/* have struct if_laddrreq? */
+/* #undef ISC_PLATFORM_HAVEIF_LADDRREQ */
+
+/* have struct in6_pktinfo? */
+#define ISC_PLATFORM_HAVEIN6PKTINFO 1
+
+/* have IPv6? */
+#define ISC_PLATFORM_HAVEIPV6 1
+
+/* struct sockaddr has sa_len? */
+#define ISC_PLATFORM_HAVESALEN 1
+
+/* sin6_scope_id? */
+#define ISC_PLATFORM_HAVESCOPEID 1
+
+/* missing in6addr_any? */
+/* #undef ISC_PLATFORM_NEEDIN6ADDRANY */
+
+/* Do we need netinet6/in6.h? */
+/* #undef ISC_PLATFORM_NEEDNETINET6IN6H */
+
+/* ISC: provide inet_ntop() */
+/* #undef ISC_PLATFORM_NEEDNTOP */
+
+/* Declare in_port_t? */
+/* #undef ISC_PLATFORM_NEEDPORTT */
+
+/* ISC: provide inet_pton() */
+/* #undef ISC_PLATFORM_NEEDPTON */
+
+/* enable libisc thread support? */
+#define ISC_PLATFORM_USETHREADS 1
+
+/* Does the kernel have an FLL bug? */
+/* #undef KERNEL_FLL_BUG */
+
+/* Does the kernel support precision time discipline? */
+#define KERNEL_PLL 1
+
+/* Define to use libseccomp system call filtering. */
+/* #undef KERN_SECCOMP */
+
+/* What is (probably) the name of DOSYNCTODR in the kernel? */
+#define K_DOSYNCTODR_NAME "_dosynctodr"
+
+/* What is (probably) the name of NOPRINTF in the kernel? */
+#define K_NOPRINTF_NAME "_noprintf"
+
+/* What is the name of TICKADJ in the kernel? */
+#define K_TICKADJ_NAME "_tickadj"
+
+/* What is the name of TICK in the kernel? */
+#define K_TICK_NAME "_tick"
+
+/* define to 1 if library is thread safe */
+#define LDAP_API_FEATURE_X_OPENLDAP_THREAD_SAFE 1
+
+/* leap smear mechanism */
+#define LEAP_SMEAR 1
+
+/* Define to any value to include libseccomp sandboxing. */
+/* #undef LIBSECCOMP */
+
+/* Should we align with the NIST lockclock scheme? */
+/* #undef LOCKCLOCK */
+
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
+#define LT_OBJDIR ".libs/"
+
+/* Does the target support multicast IP? */
+#define MCAST 1
+
+/* Should we recommend a minimum value for tickadj? */
+/* #undef MIN_REC_TICKADJ */
+
+/* Define to 1 if the compiler does not support C99's structure
+ initialization. */
+/* #undef MISSING_C99_STRUCT_INIT */
+
+/* having to fork the DNS worker early when doing chroot? */
+/* #undef NEED_EARLY_FORK */
+
+/* Do we need HPUX adjtime() library support? */
+/* #undef NEED_HPUX_ADJTIME */
+
+/* Do we want the HPUX FindConfig()? */
+/* #undef NEED_HPUX_FINDCONFIG */
+
+/* We need to provide netsnmp_daemonize() */
+/* #undef NEED_NETSNMP_DAEMONIZE */
+
+/* pthread_init() required? */
+/* #undef NEED_PTHREAD_INIT */
+
+/* use PTHREAD_SCOPE_SYSTEM? */
+/* #undef NEED_PTHREAD_SCOPE_SYSTEM */
+
+/* Do we need the qnx adjtime call? */
+/* #undef NEED_QNX_ADJTIME */
+
+/* Do we need extra room for SO_RCVBUF? (HPUX < 8) */
+/* #undef NEED_RCVBUF_SLOP */
+
+/* Do we need an s_char typedef? */
+#define NEED_S_CHAR_TYPEDEF 1
+
+/* Might nlist() values require an extra level of indirection (AIX)? */
+/* #undef NLIST_EXTRA_INDIRECTION */
+
+/* does struct nlist use a name union? */
+/* #undef NLIST_NAME_UNION */
+
+/* nlist stuff */
+#define NLIST_STRUCT 1
+
+/* Should we NOT read /dev/kmem? */
+#define NOKMEM 1
+
+/* Should we avoid #warning on option name collisions? */
+/* #undef NO_OPTION_NAME_WARNINGS */
+
+/* Is there a problem using PARENB and IGNPAR? */
+/* #undef NO_PARENB_IGNPAR */
+
+/* define if you have (or want) no threads */
+/* #undef NO_THREADS */
+
+/* Default location of crypto key info */
+#define NTP_KEYSDIR "/etc/ntp"
+
+/* Path to sign daemon rendezvous socket */
+#define NTP_SIGND_PATH "/var/run/ntp_signd"
+
+/* Do we have ntp_{adj,get}time in libc? */
+#define NTP_SYSCALLS_LIBC 1
+
+/* Do we have ntp_{adj,get}time in the kernel? */
+/* #undef NTP_SYSCALLS_STD */
+
+/* Do we have support for SHMEM_STATUS? */
+#define ONCORE_SHMEM_STATUS 1
+
+/* Use OpenSSL? */
+/* #define OPENSSL */
+
+/* Should we open the broadcast socket? */
+#define OPEN_BCAST_SOCKET 1
+
+/* need to recreate sockets on changed routing? */
+/* #undef OS_MISSES_SPECIFIC_ROUTE_UPDATES */
+
+/* wildcard socket needs REUSEADDR to bind interface addresses */
+/* #undef OS_NEEDS_REUSEADDR_FOR_IFADDRBIND */
+
+/* Do we need to override the system's idea of HZ? */
+#define OVERRIDE_HZ 1
+
+/* Name of package */
+#define PACKAGE "ntp"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "http://bugs.ntp.org./"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "ntp"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "ntp 4.2.8p12"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "ntp"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL "http://www.ntp.org./"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "4.2.8p13"
+
+/* data dir */
+#define PERLLIBDIR "/usr/share/ntp/lib"
+
+/* define to a working POSIX compliant shell */
+#define POSIX_SHELL "/bin/sh"
+
+/* PARSE kernel PLL PPS support */
+/* #undef PPS_SYNC */
+
+/* Preset a value for 'tick'? */
+#define PRESET_TICK 1000000L/hz
+
+/* Preset a value for 'tickadj'? */
+#define PRESET_TICKADJ 500/hz
+
+/* Should we not IGNPAR (Linux)? */
+/* #undef RAWDCF_NO_IGNPAR */
+
+/* enable thread safety */
+#define REENTRANT 1
+
+/* Basic refclock support? */
+/* #undef REFCLOCK 1 */
+
+/* Do we want the ReliantUNIX clock hacks? */
+/* #undef RELIANTUNIX_CLOCK */
+
+/* define if sched_yield yields the entire process */
+/* #undef REPLACE_BROKEN_YIELD */
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#define RETSIGTYPE void
+
+/* saveconfig mechanism */
+#define SAVECONFIG 1
+
+/* Do we want the SCO clock hacks? */
+/* #undef SCO5_CLOCK */
+
+/* The size of `char *', as computed by sizeof. */
+#ifdef __LP64__
+#define SIZEOF_CHARP 8
+#else
+#define SIZEOF_CHARP 4
+#endif
+
+/* The size of `int', as computed by sizeof. */
+#define SIZEOF_INT 4
+
+/* The size of `long', as computed by sizeof. */
+#ifdef __LP64__
+#define SIZEOF_LONG 8
+#else
+#define SIZEOF_LONG 4
+#endif
+
+/* The size of `long long', as computed by sizeof. */
+#define SIZEOF_LONG_LONG 8
+
+/* The size of `pthread_t', as computed by sizeof. */
+#define SIZEOF_PTHREAD_T 8
+
+/* The size of `short', as computed by sizeof. */
+#define SIZEOF_SHORT 2
+
+/* The size of `signed char', as computed by sizeof. */
+#define SIZEOF_SIGNED_CHAR 1
+
+/* The size of `time_t', as computed by sizeof. */
+#if defined(__i386__) || defined(__powerpc__)
+#define SIZEOF_TIME_T 4
+#else
+#define SIZEOF_TIME_T 8
+#endif
+
+/* Does SIOCGIFCONF return size in the buffer? */
+/* #undef SIZE_RETURNED_IN_BUFFER */
+
+/* Slew always? */
+/* #undef SLEWALWAYS */
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at runtime.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown */
+/* #undef STACK_DIRECTION */
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Step, then slew the clock? */
+/* #undef STEP_SLEW */
+
+/* Define to 1 if strerror_r returns char *. */
+/* #undef STRERROR_R_CHAR_P */
+
+/* canonical system (cpu-vendor-os) of where we should run */
+#if defined(__alpha__)
+#define STR_SYSTEM "alpha-undermydesk-freebsd"
+#elif defined(__sparc64__)
+#define STR_SYSTEM "sparc64-undermydesk-freebsd"
+#elif defined(__amd64__)
+#define STR_SYSTEM "amd64-undermydesk-freebsd"
+#elif defined(__powerpc64__)
+#define STR_SYSTEM "powerpc64-undermydesk-freebsd"
+#elif defined(__powerpc__)
+#define STR_SYSTEM "powerpc-undermydesk-freebsd"
+#elif defined(__mips64)
+#define STR_SYSTEM "mips64-undermydesk-freebsd"
+#elif defined(__mips__)
+#define STR_SYSTEM "mips-undermydesk-freebsd"
+#elif defined(__aarch64__)
+#define STR_SYSTEM "arm64-undermydesk-freebsd"
+#elif defined(__arm__)
+#define STR_SYSTEM "arm-undermydesk-freebsd"
+#elif defined(__sparc64__)
+#define STR_SYSTEM "sparc64-undermydesk-freebsd"
+#elif defined(__sparc__)
+#define STR_SYSTEM "sparc-undermydesk-freebsd"
+#elif defined(__ia64__)
+#define STR_SYSTEM "ia64-undermydesk-freebsd"
+#else
+#define STR_SYSTEM "i386-undermydesk-freebsd"
+#endif
+
+/* Does Xettimeofday take 1 arg? */
+/* #undef SYSV_TIMEOFDAY */
+
+/* Do we need to #define _SVID3 when we #include <termios.h>? */
+/* #undef TERMIOS_NEEDS__SVID3 */
+
+/* enable thread safety */
+#define THREADSAFE 1
+
+/* enable thread safety */
+#define THREAD_SAFE 1
+
+/* Is K_TICKADJ_NAME in nanoseconds? */
+/* #undef TICKADJ_NANO */
+
+/* Is K_TICK_NAME in nanoseconds? */
+/* #undef TICK_NANO */
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#define TIME_WITH_SYS_TIME 1
+
+/* Define to 1 if your <sys/time.h> declares `struct tm'. */
+/* #undef TM_IN_SYS_TIME */
+
+/* Provide a typedef for uintptr_t? */
+#ifndef HAVE_UINTPTR_T
+typedef unsigned int uintptr_t;
+#define HAVE_UINTPTR_T 1
+#endif
+
+/* What type to use for setsockopt */
+#define TYPEOF_IP_MULTICAST_LOOP u_char
+
+/* Do we set process groups with -pid? */
+/* #undef UDP_BACKWARDS_SETOWN */
+
+/* Must we have a CTTY for fsetown? */
+#define USE_FSETOWNCTTY 1
+
+/* Use OpenSSL's crypto random functions */
+/* #define USE_OPENSSL_CRYPTO_RAND 1 */
+
+/* OK to use snprintb()? */
+/* #undef USE_SNPRINTB */
+
+/* Can we use SIGPOLL for tty IO? */
+/* #undef USE_TTY_SIGPOLL */
+
+/* Can we use SIGPOLL for UDP? */
+/* #undef USE_UDP_SIGPOLL */
+
+/* Version number of package */
+#define VERSION "4.2.8p12"
+
+/* vsnprintf expands "%m" to strerror(errno) */
+#define VSNPRINTF_PERCENT_M 1
+
+/* configure --enable-ipv6 */
+#define WANT_IPV6 1
+
+#include <machine/_endian.h>
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+ significant byte first (like Motorola and SPARC, unlike Intel). */
+#if _BYTE_ORDER == _BIG_ENDIAN
+#define WORDS_BIGENDIAN 1
+#endif
+
+/* routine worker child proc uses to exit. */
+#define WORKER_CHILD_EXIT exit
+
+/* Define to 1 if on MINIX. */
+/* #undef _MINIX */
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+ this defined. */
+/* #undef _POSIX_1_SOURCE */
+
+/* Define to 1 if you need to in order for `stat' and other things to work. */
+/* #undef _POSIX_SOURCE */
+
+/* enable thread safety */
+#define _REENTRANT 1
+
+/* enable thread safety */
+#define _SGI_MP_SOURCE 1
+
+/* enable thread safety */
+#define _THREADSAFE 1
+
+/* enable thread safety */
+#define _THREAD_SAFE 1
+
+/* Define to 500 only on HP-UX. */
+/* #undef _XOPEN_SOURCE */
+
+/* Are we _special_? */
+/* #undef __APPLE_USE_RFC_3542 */
+
+/* Define to 1 if type `char' is unsigned and you are not using gcc. */
+#ifndef __CHAR_UNSIGNED__
+/* # undef __CHAR_UNSIGNED__ */
+#endif
+
+/* Enable extensions on AIX 3, Interix. */
+#ifndef _ALL_SOURCE
+# define _ALL_SOURCE 1
+#endif
+/* Enable GNU extensions on systems that have them. */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE 1
+#endif
+/* Enable threading extensions on Solaris. */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# define _POSIX_PTHREAD_SEMANTICS 1
+#endif
+/* Enable extensions on HP NonStop. */
+#ifndef _TANDEM_SOURCE
+# define _TANDEM_SOURCE 1
+#endif
+/* Enable general extensions on Solaris. */
+#ifndef __EXTENSIONS__
+# define __EXTENSIONS__ 1
+#endif
+
+
+/* deviant */
+/* #undef adjtimex */
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+/* #undef gid_t */
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+ calls it, or to nothing if 'inline' is not supported under any name. */
+#ifndef __cplusplus
+/* #undef inline */
+#endif
+
+/* Define to the widest signed integer type if <stdint.h> and <inttypes.h> do
+ not define. */
+/* #undef intmax_t */
+
+/* deviant */
+/* #undef ntp_adjtime */
+
+/* deviant */
+/* #undef ntp_gettime */
+
+/* Define to `long int' if <sys/types.h> does not define. */
+/* #undef off_t */
+
+/* Define to `int' if <sys/types.h> does not define. */
+/* #undef pid_t */
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef size_t */
+
+
+ #if !defined(_KERNEL) && !defined(PARSESTREAM)
+ /*
+ * stdio.h must be included after _GNU_SOURCE is defined
+ * but before #define snprintf rpl_snprintf
+ */
+ # include <stdio.h>
+ #endif
+
+
+/* Define to rpl_snprintf if the replacement function should be used. */
+/* #undef snprintf */
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+/* #undef uid_t */
+
+/* Define to the widest unsigned integer type if <stdint.h> and <inttypes.h>
+ do not define. */
+/* #undef uintmax_t */
+
+/* Define to the type of an unsigned integer type wide enough to hold a
+ pointer, if such a type exists, and if the system does not define it. */
+/* #undef uintptr_t */
+
+/* Define as `fork' if `vfork' does not work. */
+/* #undef vfork */
+
+/* Define to empty if the keyword `volatile' does not work. Warning: valid
+ code using `volatile' can become incorrect without. Disable with care. */
+/* #undef volatile */
+
+/* Define to rpl_vsnprintf if the replacement function should be used. */
+/* #undef vsnprintf */
+
+
+#ifndef MPINFOU_PREDECLARED
+# define MPINFOU_PREDECLARED
+typedef union mpinfou {
+ struct pdk_mpinfo *pdkptr;
+ struct mpinfo *pikptr;
+} mpinfou_t;
+#endif
+
+
+
+ #if !defined(_KERNEL) && !defined(PARSESTREAM)
+ # if defined(HW_WANT_RPL_VSNPRINTF)
+ # if defined(__cplusplus)
+ extern "C" {
+ # endif
+ # include <stdarg.h>
+ int rpl_vsnprintf(char *, size_t, const char *, va_list);
+ # if defined(__cplusplus)
+ }
+ # endif
+ # endif
+ # if defined(HW_WANT_RPL_SNPRINTF)
+ # if defined(__cplusplus)
+ extern "C" {
+ # endif
+ int rpl_snprintf(char *, size_t, const char *, ...);
+ # if defined(__cplusplus)
+ }
+ # endif
+ # endif
+ #endif /* !defined(_KERNEL) && !defined(PARSESTREAM) */
+
+/*
+ * FreeBSD specific: Explicitly specify date/time for reproducible build.
+ */
+#define MKREPRO_DATE "Aug 19 2018"
+#define MKREPRO_TIME "01:24:29"
diff --git a/sebhbsd/freebsd/contrib/ntp/include/declcond.h b/sebhbsd/freebsd/contrib/ntp/include/declcond.h
new file mode 100644
index 0000000..751eff9
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/declcond.h
@@ -0,0 +1,21 @@
+/*
+ * declcond.h - declarations conditionalized for ntpd
+ *
+ * The NTP reference implementation distribution includes two distinct
+ * declcond.h files, one in ntpd/ used only by ntpd, and another in
+ * include/ used by libntp and utilities. This relies on the source
+ * file's directory being ahead of include/ in the include search.
+ *
+ * The ntpd variant of declcond.h declares "debug" only #ifdef DEBUG,
+ * as the --disable-debugging version of ntpd should not reference
+ * "debug". The libntp and utilities variant always declares debug,
+ * as it is used in those codebases even without DEBUG defined.
+ */
+#ifndef DECLCOND_H
+#define DECLCOND_H
+
+/* #ifdef DEBUG */ /* uncommented in ntpd/declcond.h */
+extern int debug;
+/* #endif */ /* uncommented in ntpd/declcond.h */
+
+#endif /* DECLCOND_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/icom.h b/sebhbsd/freebsd/contrib/ntp/include/icom.h
new file mode 100644
index 0000000..b271afb
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/icom.h
@@ -0,0 +1,87 @@
+/*
+ * Header file for ICOM radios
+ */
+#include "ntp_types.h"
+
+/*
+ * Common definitions
+ */
+#define P_ERMSG 0x1 /* trace bus error messages */
+#define P_TRACE 0x2 /* trace CI-V messges */
+#define RETRY 3 /* max packet retries */
+#define IBAUD B1200 /* autotune port speed */
+
+/*
+ * Radio identifier codes
+ */
+#define IC1271 0x24
+#define IC1275 0x18
+#define IC271 0x20
+#define IC275 0x10
+#define IC375 0x12
+#define IC471 0x22
+#define IC475 0x14
+#define IC575 0x16
+#define IC725 0x28
+#define IC726 0x30
+#define IC735 0x04
+#define IC751 0x1c
+#define IC761 0x1e
+#define IC765 0x2c
+#define IC775 0x46
+#define IC781 0x26
+#define IC970 0x2e
+#define R7000 0x08
+#define R71 0x1a
+#define R7100 0x34
+#define R72 0x32
+#define R8500 0x4a
+#define R9000 0x2a
+
+/*
+ * CI-V frame codes
+ */
+#define PR 0xfe /* preamble */
+#define TX 0xe0 /* controller address */
+#define FI 0xfd /* end of message */
+#define ACK 0xfb /* controller normal reply */
+#define NAK 0xfa /* controller error reply */
+#define PAD 0xff /* transmit padding */
+
+/*
+ * CI-V controller commands
+ */
+#define V_FREQT 0x00 /* freq set (transceive) */
+#define V_MODET 0x01 /* set mode (transceive) */
+#define V_RBAND 0x02 /* read band edge */
+#define V_RFREQ 0x03 /* read frequency */
+#define V_RMODE 0x04 /* read mode */
+#define V_SFREQ 0x05 /* set frequency */
+#define V_SMODE 0x06 /* set mode */
+#define V_SVFO 0x07 /* select vfo */
+#define V_SMEM 0x08 /* select channel/bank */
+#define V_WRITE 0x09 /* write channel */
+#define V_VFOM 0x0a /* memory -> vfo */
+#define V_CLEAR 0x0b /* clear channel */
+#define V_ROFFS 0x0c /* read tx offset */
+#define V_SOFFS 0x0d /* write tx offset */
+#define V_SCAN 0x0e /* scan control */
+#define V_SPLIT 0x0f /* split control */
+#define V_DIAL 0x10 /* set dial tuning step */
+#define V_ATTEN 0x11 /* set attenuator */
+#define V_SANT 0x12 /* select antenna */
+#define V_ANNC 0x13 /* announce control */
+#define V_WRCTL 0x14 /* write controls */
+#define V_RDCTL 0x15 /* read controls */
+#define V_TOGL 0x16 /* set switches */
+#define V_ASCII 0x17 /* send CW message */
+#define V_POWER 0x18 /* power control */
+#define V_RDID 0x19 /* read model ID */
+#define V_SETW 0x1a /* read/write channel/bank data */
+#define V_CTRL 0x7f /* miscellaneous control */
+
+/*
+ * Function prototypes
+ */
+int icom_init (const char *, int, int);
+int icom_freq (int, int, double);
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ieee754io.h b/sebhbsd/freebsd/contrib/ntp/include/ieee754io.h
new file mode 100644
index 0000000..73e7f79
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ieee754io.h
@@ -0,0 +1,78 @@
+/*
+ * /src/NTP/ntp4-dev/include/ieee754io.h,v 4.3 2005/04/16 17:32:10 kardel RELEASE_20050508_A
+ *
+ * ieee754io.h,v 4.3 2005/04/16 17:32:10 kardel RELEASE_20050508_A
+ *
+ * $Created: Sun Jul 13 12:22:11 1997 $
+ *
+ * Copyright (c) 1997-2005 by Frank Kardel <kardel <AT> ntp.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED 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.
+ *
+ */
+#ifndef IEEE754IO_H
+#define IEEE754IO_H
+
+#define IEEE_SINGLE 1
+#define IEEE_DOUBLE 2
+
+#define IEEE_MSB 1
+#define IEEE_LSB 2
+
+#define IEEE_OK 0 /* conversion ok */
+#define IEEE_BADCALL 1 /* bad call parameters */
+#define IEEE_NAN 2 /* found an NaN */
+#define IEEE_POSINFINITY 3 /* positive infinity */
+#define IEEE_NEGINFINITY 4 /* negative infinity */
+#define IEEE_POSOVERFLOW 5 /* positive overflow */
+#define IEEE_NEGOVERFLOW 6 /* negative overflow */
+
+#define IEEE_OFFSETS 8 /* number of byte positions */
+typedef unsigned char offsets_t[IEEE_OFFSETS];
+
+int fetch_ieee754 (unsigned char **bufp, int size, l_fp *lfpp, offsets_t offsets);
+int put_ieee754 (unsigned char **bufpp, int size, l_fp *lfpp, offsets_t offsets);
+
+#endif
+/*
+ * History:
+ *
+ * ieee754io.h,v
+ * Revision 4.3 2005/04/16 17:32:10 kardel
+ * update copyright
+ *
+ * Revision 4.2 2004/11/14 15:29:41 kardel
+ * support PPSAPI, upgrade Copyright to Berkeley style
+ *
+ * Revision 4.0 1998/04/10 19:50:40 kardel
+ * Start 4.0 release version numbering
+ *
+ * Revision 1.1 1998/04/10 19:27:33 kardel
+ * initial NTP VERSION 4 integration of PARSE with GPS166 binary support
+ *
+ * Revision 1.1 1997/10/06 20:55:37 kardel
+ * new parse structure
+ *
+ */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/intreswork.h b/sebhbsd/freebsd/contrib/ntp/include/intreswork.h
new file mode 100644
index 0000000..c343ac0
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/intreswork.h
@@ -0,0 +1,29 @@
+/*
+ * intreswork.h -- declarations private to ntp_intres.c, ntp_worker.c.
+ */
+#ifndef INTRESWORK_H
+#define INTRESWORK_H
+
+#include "ntp_worker.h"
+
+#ifdef WORKER
+
+extern int blocking_getaddrinfo(blocking_child *,
+ blocking_pipe_header *);
+extern int blocking_getnameinfo(blocking_child *,
+ blocking_pipe_header *);
+
+#ifdef TEST_BLOCKING_WORKER
+extern void gai_test_callback(int rescode, int gai_errno,
+ void *context, const char *name,
+ const char *service,
+ const struct addrinfo *hints,
+ const struct addrinfo *ai_res);
+extern void gni_test_callback(int rescode, int gni_errno,
+ sockaddr_u *psau, int flags,
+ const char *host,
+ const char *service, void *context);
+#endif /* TEST_BLOCKING_WORKER */
+#endif /* WORKER */
+
+#endif /* INTRESWORK_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/iosignal.h b/sebhbsd/freebsd/contrib/ntp/include/iosignal.h
new file mode 100644
index 0000000..406804e
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/iosignal.h
@@ -0,0 +1,58 @@
+#ifndef IOSIGNAL_H
+#define IOSIGNAL_H
+
+#include "ntp_refclock.h"
+
+ /*
+ * Some systems (MOST) define SIGPOLL == SIGIO, others SIGIO == SIGPOLL, and
+ * a few have separate SIGIO and SIGPOLL signals. This code checks for the
+ * SIGIO == SIGPOLL case at compile time.
+ * Do not define USE_SIGPOLL or USE_SIGIO.
+ * these are interal only to iosignal.c and ntpd/work_fork.c!
+ */
+#if defined(USE_SIGPOLL)
+# undef USE_SIGPOLL
+#endif
+#if defined(USE_SIGIO)
+# undef USE_SIGIO
+#endif
+
+/* type of input handler function - only shared between iosignal.c and ntp_io.c */
+typedef void (input_handler_t)(l_fp *);
+
+#if defined(HAVE_SIGNALED_IO)
+# if defined(USE_TTY_SIGPOLL) || defined(USE_UDP_SIGPOLL)
+# define USE_SIGPOLL
+# endif
+
+# if !defined(USE_TTY_SIGPOLL) || !defined(USE_UDP_SIGPOLL)
+# define USE_SIGIO
+# endif
+
+# if defined(USE_SIGIO) && defined(USE_SIGPOLL)
+# if SIGIO == SIGPOLL
+# define USE_SIGIO
+# undef USE_SIGPOLL
+# endif /* SIGIO == SIGPOLL */
+# endif /* USE_SIGIO && USE_SIGPOLL */
+
+#define USING_SIGIO() using_sigio
+
+extern int using_sigio;
+
+extern void block_sigio (void);
+extern void unblock_sigio (void);
+extern int init_clock_sig (struct refclockio *);
+extern void init_socket_sig (int);
+extern void set_signal (input_handler_t *);
+
+# define BLOCKIO() block_sigio()
+# define UNBLOCKIO() unblock_sigio()
+
+#else /* !HAVE_SIGNALED_IO follows */
+# define BLOCKIO() do {} while (0)
+# define UNBLOCKIO() do {} while (0)
+# define USING_SIGIO() FALSE
+#endif
+
+#endif /* IOSIGNAL_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/isc/mem.h b/sebhbsd/freebsd/contrib/ntp/include/isc/mem.h
new file mode 100644
index 0000000..ba1bfeb
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/isc/mem.h
@@ -0,0 +1,68 @@
+/*
+ * libntp local override of isc/mem.h to stub it out.
+ *
+ * include/isc is searched before any of the lib/isc include
+ * directories and should be used only for replacement NTP headers
+ * overriding headers of the same name under lib/isc.
+ *
+ * NOTE: this assumes the system malloc is thread-safe and does
+ * not use any normal lib/isc locking.
+ */
+
+/*
+ * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1997-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: mem.h,v 1.78.120.3 2009/02/11 03:07:01 jinmei Exp $ */
+
+#ifndef ISC_MEM_H
+#define ISC_MEM_H 1
+
+#include <stdio.h>
+
+#include <isc/lang.h>
+#include <isc/mutex.h>
+#include <isc/platform.h>
+#include <isc/types.h>
+#include <isc/xml.h>
+
+#include <ntp_stdlib.h>
+
+
+#define ISC_MEM_UNUSED_ARG(a) ((void)(a))
+
+#define isc_mem_allocate(c, cnt) isc_mem_get(c, cnt)
+#define isc_mem_get(c, cnt) \
+ ( ISC_MEM_UNUSED_ARG(c), emalloc(cnt) )
+
+#define isc_mem_reallocate(c, mem, cnt) \
+ ( ISC_MEM_UNUSED_ARG(c), erealloc((mem), cnt) )
+
+#define isc_mem_put(c, mem, cnt) \
+ ( ISC_MEM_UNUSED_ARG(cnt), isc_mem_free(c, (mem)) )
+
+#define isc_mem_free(c, mem) \
+ ( ISC_MEM_UNUSED_ARG(c), free(mem) )
+
+#define isc_mem_strdup(c, str) \
+ ( ISC_MEM_UNUSED_ARG(c), estrdup(str) )
+
+#define isc__mem_attach(src, ptgt) do { *(ptgt) = (src); } while (0)
+#define isc__mem_detach(c) ISC_MEM_UNUSED_ARG(c)
+#define isc__mem_printallactive(s) fprintf((s), \
+ "isc_mem_printallactive() stubbed.\n")
+
+#endif /* ISC_MEM_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/l_stdlib.h b/sebhbsd/freebsd/contrib/ntp/include/l_stdlib.h
new file mode 100644
index 0000000..073ea46
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/l_stdlib.h
@@ -0,0 +1,224 @@
+/*
+ * Proto types for machines that are not ANSI and POSIX compliant.
+ * This is optional
+ */
+
+#ifndef L_STDLIB_H
+#define L_STDLIB_H
+
+#ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+#endif
+
+#include <stdarg.h>
+#include <sys/types.h>
+
+/* Needed for speed_t. */
+#ifdef HAVE_TERMIOS_H
+# include <termios.h>
+#endif
+
+#ifdef HAVE_ERRNO_H
+# include <errno.h>
+#endif
+
+#include "ntp_types.h"
+#include "ntp_proto.h"
+
+/* Let's try to keep this more or less alphabetized... */
+
+#ifdef DECL_ADJTIME_0
+struct timeval;
+extern int adjtime (struct timeval *, struct timeval *);
+#endif
+
+#ifdef DECL_BCOPY_0
+#ifndef bcopy
+extern void bcopy (const char *, char *, int);
+#endif
+#endif
+
+#ifdef DECL_BZERO_0
+#ifndef bzero
+extern void bzero (char *, int);
+#endif
+#endif
+
+#ifdef DECL_CFSETISPEED_0
+struct termios;
+extern int cfsetispeed (struct termios *, speed_t);
+extern int cfsetospeed (struct termios *, speed_t);
+#endif
+
+extern char * getpass (const char *);
+
+#ifdef DECL_HSTRERROR_0
+extern const char * hstrerror (int);
+#endif
+
+#ifdef DECL_INET_NTOA_0
+struct in_addr;
+extern char * inet_ntoa (struct in_addr);
+#endif
+
+#ifdef DECL_IOCTL_0
+extern int ioctl (int, u_long, char *);
+#endif
+
+#ifdef DECL_IPC_0
+struct sockaddr;
+extern int bind (int, struct sockaddr *, int);
+extern int connect (int, struct sockaddr *, int);
+extern int recv (int, char *, int, int);
+extern int recvfrom (int, char *, int, int, struct sockaddr *, int *);
+extern int send (int, char *, int, int);
+extern int sendto (int, char *, int, int, struct sockaddr *, int);
+extern int setsockopt (int, int, int, char *, int);
+extern int socket (int, int, int);
+#endif
+
+#ifdef DECL_MEMMOVE_0
+extern void * memmove (void *, const void *, size_t);
+#endif
+
+#ifdef DECL_MEMSET_0
+extern char * memset (char *, int, int);
+#endif
+
+#ifdef DECL_MKSTEMP_0
+extern int mkstemp (char *);
+#endif
+
+#ifdef DECL_MKTEMP_0
+extern char *mktemp (char *);
+#endif
+
+#ifdef DECL_NLIST_0
+struct nlist;
+extern int nlist (const char *, struct nlist *);
+#endif
+
+#ifdef DECL_PLOCK_0
+extern int plock (int);
+#endif
+
+#ifdef DECL_RENAME_0
+extern int rename (const char *, const char *);
+#endif
+
+#ifdef DECL_SELECT_0
+#ifdef NTP_SELECT_H
+extern int select (int, fd_set *, fd_set *, fd_set *, struct timeval *);
+#endif
+#endif
+
+#ifdef DECL_SETITIMER_0
+struct itimerval;
+extern int setitimer (int , struct itimerval *, struct itimerval *);
+#endif
+
+#ifdef PRIO_PROCESS
+#ifdef DECL_SETPRIORITY_0
+extern int setpriority (int, int, int);
+#endif
+#ifdef DECL_SETPRIORITY_1
+extern int setpriority (int, id_t, int);
+#endif
+#endif
+
+#ifdef DECL_SIGVEC_0
+struct sigvec;
+extern int sigvec (int, struct sigvec *, struct sigvec *);
+#endif
+
+#ifdef DECL_STDIO_0
+#if defined(FILE) || defined(BUFSIZ)
+extern int _flsbuf (int, FILE *);
+extern int _filbuf (FILE *);
+extern int fclose (FILE *);
+extern int fflush (FILE *);
+extern int fprintf (FILE *, const char *, ...);
+extern int fscanf (FILE *, const char *, ...);
+extern int fputs (const char *, FILE *);
+extern int fputc (int, FILE *);
+extern int fread (char *, int, int, FILE *);
+extern void perror (const char *);
+extern int printf (const char *, ...);
+extern int setbuf (FILE *, char *);
+# ifdef HAVE_SETLINEBUF
+extern int setlinebuf (FILE *);
+# endif
+extern int setvbuf (FILE *, char *, int, int);
+extern int scanf (const char *, ...);
+extern int sscanf (const char *, const char *, ...);
+extern int vfprintf (FILE *, const char *, ...);
+extern int vsprintf (char *, const char *, ...);
+#endif
+#endif
+
+#ifdef DECL_STIME_0
+extern int stime (const time_t *);
+#endif
+
+#ifdef DECL_STIME_1
+extern int stime (long *);
+#endif
+
+#ifdef DECL_STRERROR_0
+extern char * strerror (int errnum);
+#endif
+
+#ifdef DECL_STRTOL_0
+extern long strtol (const char *, char **, int);
+#endif
+
+#ifdef DECL_SYSCALL
+extern int syscall (int, ...);
+#endif
+
+#ifdef DECL_SYSLOG_0
+extern void closelog (void);
+#ifndef LOG_DAEMON
+extern void openlog (const char *, int);
+#else
+extern void openlog (const char *, int, int);
+#endif
+extern int setlogmask (int);
+extern void syslog (int, const char *, ...);
+#endif
+
+#ifdef DECL_TIME_0
+extern time_t time (time_t *);
+#endif
+
+#ifdef DECL_TIMEOFDAY_0
+#ifdef SYSV_TIMEOFDAY
+extern int gettimeofday (struct timeval *);
+extern int settimeofday (struct timeval *);
+#else /* not SYSV_TIMEOFDAY */
+struct timezone;
+extern int gettimeofday (struct timeval *, struct timezone *);
+extern int settimeofday (struct timeval *, void *);
+#endif /* not SYSV_TIMEOFDAY */
+#endif
+
+#ifdef DECL_TOLOWER_0
+extern int tolower (int);
+#endif
+
+#ifdef DECL_TOUPPER_0
+extern int toupper (int);
+#endif
+
+/*
+ * Necessary variable declarations.
+ */
+#ifdef DECL_ERRNO
+extern int errno;
+#endif
+
+#if defined(DECL_H_ERRNO) && !defined(h_errno)
+extern int h_errno;
+#endif
+
+#endif /* L_STDLIB_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/lib_strbuf.h b/sebhbsd/freebsd/contrib/ntp/include/lib_strbuf.h
new file mode 100644
index 0000000..5ee92d6
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/lib_strbuf.h
@@ -0,0 +1,32 @@
+/*
+ * lib_strbuf.h - definitions for routines which use the common string buffers
+ */
+#ifndef LIB_STRBUF_H
+#define LIB_STRBUF_H
+
+#include <ntp_types.h>
+#include <ntp_malloc.h> /* for ZERO() */
+
+/*
+ * Sizes of things
+ */
+#define LIB_NUMBUF 16
+#define LIB_BUFLENGTH 128
+
+typedef char libbufstr[LIB_BUFLENGTH];
+extern libbufstr lib_stringbuf[LIB_NUMBUF];
+extern int lib_nextbuf;
+extern int lib_inited;
+
+
+/*
+ * Macro to get a pointer to the next buffer
+ */
+#define LIB_GETBUF(bufp) \
+ do { \
+ ZERO(lib_stringbuf[lib_nextbuf]); \
+ (bufp) = &lib_stringbuf[lib_nextbuf++][0]; \
+ lib_nextbuf %= COUNTOF(lib_stringbuf); \
+ } while (FALSE)
+
+#endif /* LIB_STRBUF_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/libntp.h b/sebhbsd/freebsd/contrib/ntp/include/libntp.h
new file mode 100644
index 0000000..8d87c02
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/libntp.h
@@ -0,0 +1,16 @@
+/* libntp.h */
+
+#if defined(HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
+#define GETDTABLESIZE() ((int)sysconf(_SC_OPEN_MAX))
+#elif defined(HAVE_GETDTABLESIZE)
+#define GETDTABLESIZE getdtablesize
+#else
+/*
+ * if we have no idea about the max fd value set up things
+ * so we will start at FOPEN_MAX
+ */
+#define GETDTABLESIZE() (FOPEN_MAX + FD_CHUNK)
+#endif
+
+extern void make_socket_nonblocking( SOCKET fd );
+extern SOCKET move_fd( SOCKET fd );
diff --git a/sebhbsd/freebsd/contrib/ntp/include/libssl_compat.h b/sebhbsd/freebsd/contrib/ntp/include/libssl_compat.h
new file mode 100644
index 0000000..2a3697c
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/libssl_compat.h
@@ -0,0 +1,119 @@
+/*
+ * libssl_compat.h -- OpenSSL v1.1 compatibility shims
+ *
+ * ---------------------------------------------------------------------
+ *
+ * Written by Juergen Perlinger <perlinger@ntp.org> for the NTP project
+ *
+ * Based on an idea by Kurt Roeckx <kurt@roeckx.be>
+ *
+ * ---------------------------------------------------------------------
+ * This is a clean room implementation of shim functions that have
+ * counterparts in the OpenSSL v1.1 API but not in earlier versions.
+ *
+ * If the OpenSSL version used for compilation needs the shims (that is,
+ * does not provide the new functions) the names of these functions are
+ * redirected to our shims.
+ * ---------------------------------------------------------------------
+ */
+
+#ifndef NTP_LIBSSL_COMPAT_H
+#define NTP_LIBSSL_COMPAT_H
+
+#include "openssl/evp.h"
+#include "openssl/dsa.h"
+#include "openssl/rsa.h"
+
+#ifndef OPENSSL_VERSION_NUMBER
+#define OPENSSL_VERSION_NUMBER SSLEAY_VERSION_NUMBER
+#endif
+
+#ifndef OPENSSL_VERSION_TEXT
+#define OPENSSL_VERSION_TEXT SSLEAY_VERSION_TEXT
+#endif
+
+#ifndef OPENSSL_VERSION
+#define OPENSSL_VERSION SSLEAY_VERSION
+#endif
+
+/* ----------------------------------------------------------------- */
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+/* ----------------------------------------------------------------- */
+
+# include <openssl/objects.h>
+# include <openssl/x509.h>
+
+/* shim the new-style API on an old-style OpenSSL */
+
+extern BN_GENCB* sslshimBN_GENCB_new(void);
+extern void sslshimBN_GENCB_free(BN_GENCB*);
+
+extern EVP_MD_CTX* sslshim_EVP_MD_CTX_new(void);
+extern void sslshim_EVP_MD_CTX_free(EVP_MD_CTX *ctx);
+
+extern int sslshim_EVP_PKEY_id(const EVP_PKEY * pkey);
+extern int sslshim_EVP_PKEY_base_id(const EVP_PKEY * pkey);
+extern RSA* sslshim_EVP_PKEY_get0_RSA(EVP_PKEY * pkey);
+extern DSA* sslshim_EVP_PKEY_get0_DSA(EVP_PKEY * pkey);
+
+extern void sslshim_RSA_get0_key(const RSA *prsa, const BIGNUM **pn,
+ const BIGNUM **pe, const BIGNUM **pd);
+extern int sslshim_RSA_set0_key(RSA *prsa, BIGNUM *n,
+ BIGNUM *e, BIGNUM *d);
+extern void sslshim_RSA_get0_factors(const RSA *prsa, const BIGNUM **pp,
+ const BIGNUM **pq);
+extern int sslshim_RSA_set0_factors(RSA *prsar, BIGNUM *p, BIGNUM *q);
+extern int sslshim_RSA_set0_crt_params(RSA *prsa, BIGNUM *dmp1,
+ BIGNUM *dmq1, BIGNUM *iqmp);
+
+extern void sslshim_DSA_SIG_get0(const DSA_SIG *psig, const BIGNUM **pr,
+ const BIGNUM **ps);
+extern int sslshim_DSA_SIG_set0(DSA_SIG *psig, BIGNUM *r, BIGNUM *s);
+extern void sslshim_DSA_get0_pqg(const DSA *pdsa, const BIGNUM **pp,
+ const BIGNUM **pq, const BIGNUM **pg);
+extern int sslshim_DSA_set0_pqg(DSA *pdsa, BIGNUM *p, BIGNUM *q, BIGNUM *g);
+extern void sslshim_DSA_get0_key(const DSA *pdsa, const BIGNUM **ppub_key,
+ const BIGNUM **ppriv_key);
+extern int sslshim_DSA_set0_key(DSA *pdsa, BIGNUM *pub_key,
+ BIGNUM *priv_key);
+
+extern int sslshim_X509_get_signature_nid(const X509 *x);
+
+#define BN_GENCB_new sslshimBN_GENCB_new
+#define BN_GENCB_free sslshimBN_GENCB_free
+
+#define EVP_MD_CTX_new sslshim_EVP_MD_CTX_new
+#define EVP_MD_CTX_free sslshim_EVP_MD_CTX_free
+
+#define EVP_PKEY_id sslshim_EVP_PKEY_id
+#define EVP_PKEY_base_id sslshim_EVP_PKEY_base_id
+#define EVP_PKEY_get0_RSA sslshim_EVP_PKEY_get0_RSA
+#define EVP_PKEY_get0_DSA sslshim_EVP_PKEY_get0_DSA
+
+#define RSA_get0_key sslshim_RSA_get0_key
+#define RSA_set0_key sslshim_RSA_set0_key
+#define RSA_get0_factors sslshim_RSA_get0_factors
+#define RSA_set0_factors sslshim_RSA_set0_factors
+#define RSA_set0_crt_params sslshim_RSA_set0_crt_params
+
+#define DSA_SIG_get0 sslshim_DSA_SIG_get0
+#define DSA_SIG_set0 sslshim_DSA_SIG_set0
+#define DSA_get0_pqg sslshim_DSA_get0_pqg
+#define DSA_set0_pqg sslshim_DSA_set0_pqg
+#define DSA_get0_key sslshim_DSA_get0_key
+#define DSA_set0_key sslshim_DSA_set0_key
+
+#define X509_get_signature_nid sslshim_X509_get_signature_nid
+
+#define OpenSSL_version_num SSLeay
+#define OpenSSL_version SSLeay_version
+#define X509_get0_notBefore X509_get_notBefore
+#define X509_getm_notBefore X509_get_notBefore
+#define X509_get0_notAfter X509_get_notAfter
+#define X509_getm_notAfter X509_get_notAfter
+
+/* ----------------------------------------------------------------- */
+#endif /* OPENSSL_VERSION_NUMBER < v1.1.0 */
+/* ----------------------------------------------------------------- */
+
+#endif /* NTP_LIBSSL_COMPAT_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/mbg_gps166.h b/sebhbsd/freebsd/contrib/ntp/include/mbg_gps166.h
new file mode 100644
index 0000000..b9b3d77
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/mbg_gps166.h
@@ -0,0 +1,1015 @@
+/*
+ * /src/NTP/REPOSITORY/ntp4-dev/include/mbg_gps166.h,v 4.7 2006/06/22 18:41:43 kardel RELEASE_20060622_A
+ *
+ * mbg_gps166.h,v 4.7 2006/06/22 18:41:43 kardel RELEASE_20060622_A
+ *
+ * $Created: Sun Jul 20 09:20:50 1997 $
+ *
+ * File GPSSERIO.H Copyright (c) by Meinberg Funkuhren (www.meinberg.de)
+ *
+ * Linkage to PARSE:
+ * Copyright (c) 1997-2005 by Frank Kardel <kardel <AT> ntp.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED 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.
+ *
+ */
+#ifndef MBG_GPS166_H
+#define MBG_GPS166_H
+
+
+/***************************************************************************
+ *
+ * Definitions taken from Meinberg's gpsserio.h and gpsdefs.h files.
+ *
+ * Author: Martin Burnicki, Meinberg Funkuhren
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Structures and codes to be used to access Meinberg GPS clocks via
+ * their serial interface COM0. COM0 should be set to a high baud rate,
+ * default is 19200.
+ *
+ * Standard Meinberg GPS serial operation is to send the Meinberg
+ * standard time string automatically once per second, once per
+ * minute, or on request per ASCII '?'.
+ *
+ * GPS parameter setup or parameter readout uses blocks of binary
+ * data which have to be isolated from the standard string. A block
+ * of data starts with a SOH code (ASCII Start Of Header, 0x01)
+ * followed by a message header with constant length and a block of
+ * data with variable length.
+ *
+ * The first field (cmd) of the message header holds the command
+ * code resp. the type of data to be transmitted. The next field (len)
+ * gives the number of data bytes that follow the header. This number
+ * ranges from 0 to sizeof( MSG_DATA ). The third field (data_csum)
+ * holds a checksum of all data bytes and the last field of the header
+ * finally holds the checksum of the header itself.
+ *
+ ***************************************************************************/
+
+/**
+ * @brief GPS epoch bias from ordinary time_t epoch
+ *
+ * The Unix time_t epoch is usually 1970-01-01 00:00 whereas
+ * the GPS epoch is 1980-01-06 00:00, so the difference is 10 years,
+ * plus 2 days due to leap years (1972 and 1976), plus the difference
+ * of the day-of-month (6 - 1), so:<br>
+ *
+ * time_t t = ( gps_week * ::SECS_PER_WEEK ) + sec_of_week + ::GPS_SEC_BIAS
+ */
+#define GPS_SEC_BIAS 315964800UL // ( ( ( 10UL * 365UL ) + 2 + 5 ) * SECS_PER_DAY )
+
+
+#ifndef _COM_HS_DEFINED
+ /**
+ * @brief Enumeration of handshake modes
+ */
+ enum COM_HANSHAKE_MODES { HS_NONE, HS_XONXOFF, HS_RTSCTS, N_COM_HS };
+ #define _COM_HS_DEFINED
+#endif
+
+#ifndef _COM_PARM_DEFINED
+ /**
+ * @brief A data type to configure a serial port's baud rate
+ *
+ * @see ::MBG_BAUD_RATES
+ */
+ typedef int32_t BAUD_RATE;
+
+ /**
+ * @brief Indices used to identify a parameter in the framing string
+ *
+ * @see ::MBG_FRAMING_STRS
+ */
+ enum MBG_FRAMING_STR_IDXS { F_DBITS, F_PRTY, F_STBITS };
+
+ /**
+ * @brief A structure to store the configuration of a serial port
+ */
+ typedef struct
+ {
+ BAUD_RATE baud_rate; ///< transmission speed, e.g. 19200L, see ::MBG_BAUD_RATES
+ char framing[4]; ///< ASCIIZ framing string, e.g. "8N1" or "7E2", see ::MBG_FRAMING_STRS
+ int16_t handshake; ///< handshake mode, yet only ::HS_NONE supported
+
+ } COM_PARM;
+
+ #define _COM_PARM_DEFINED
+#endif
+
+
+/**
+ * @brief Enumeration of modes supported for time string transmission
+ *
+ * This determines e.g. at which point in time a string starts
+ * to be transmitted via the serial port.
+ * Used with ::PORT_SETTINGS::mode.
+ *
+ * @see ::STR_MODE_MASKS
+ */
+enum STR_MODES
+{
+ STR_ON_REQ, ///< transmission on request by received '?' character only
+ STR_PER_SEC, ///< transmission automatically if second changes
+ STR_PER_MIN, ///< transmission automatically if minute changes
+ STR_AUTO, ///< transmission automatically if required, e.g. on capture event
+ STR_ON_REQ_SEC, ///< transmission if second changes and a request has been received before
+ N_STR_MODE ///< the number of known modes
+};
+
+
+/**
+ * The number of serial ports which are at least available
+ * even with very old GPS receiver models. For devices providing
+ * a ::RECEIVER_INFO structure the number of provided COM ports
+ * is available in ::RECEIVER_INFO::n_com_ports.
+ */
+#define DEFAULT_N_COM 2
+
+
+/**
+ * @brief A The structure used to store the configuration of two serial ports
+ *
+ * @deprecated This structure is deprecated, ::PORT_SETTINGS and related structures
+ * should be used instead, if supported by the device.
+ */
+typedef struct
+{
+ COM_PARM com[DEFAULT_N_COM]; ///< COM0 and COM1 settings
+ uint8_t mode[DEFAULT_N_COM]; ///< COM0 and COM1 output mode
+
+} PORT_PARM;
+
+
+/**
+ * @brief The type of a GPS command code
+ *
+ * @see ::GPS_CMD_CODES
+ */
+typedef uint16_t GPS_CMD;
+
+
+/**
+ * @brief Control codes to be or'ed with a particular command/type code
+ */
+enum GPS_CMD_CTRL_CODES
+{
+ GPS_REQACK = 0x8000, ///< to device: request acknowledge
+ GPS_ACK = 0x4000, ///< from device: acknowledge a command
+ GPS_NACK = 0x2000, ///< from device: error evaluating a command
+};
+
+#define GPS_CTRL_MSK 0xF000 ///< bit mask of all ::GPS_CMD_CTRL_CODES
+
+
+/**
+ * @brief Command codes for the binary protocol
+ *
+ * These codes specify commands and associated data types used by Meinberg's
+ * binary protocol to exchange data with a device via serial port, direct USB,
+ * or socket I/O.
+ *
+ * Some commands and associated data structures can be read (r) from a device, others
+ * can be written (w) to the device, and some can also be sent automatically (a) by
+ * a device after a ::GPS_AUTO_ON command has been sent to the device.
+ * The individual command codes are marked with (rwa) accordingly, where '-' is used
+ * to indicate that a particular mode is not supported.
+ *
+ * @note Not all command code are supported by all devices.
+ * See the hints for a particular command.
+ *
+ * @note If ::GPS_ALM, ::GPS_EPH or a code named ..._IDX is sent to retrieve
+ * some data from a device then an uint16_t parameter must be also supplied
+ * in order to specify the index number of the data set to be returned.
+ * The valid index range depends on the command code.
+ * For ::GPS_ALM and ::GPS_EPH the index is the SV number which may be 0 or
+ * ::MIN_SVNO_GPS to ::MAX_SVNO_GPS. If the number is 0 then all ::N_SVNO_GPS
+ * almanacs or ephemeris data structures are returned.
+ *
+ * @see ::GPS_CMD_CODES_TABLE
+ */
+enum GPS_CMD_CODES
+{ /* system data */
+ GPS_AUTO_ON = 0x000, ///< (-w-) no data, enable auto-msgs from device
+ GPS_AUTO_OFF, ///< (-w-) no data, disable auto-msgs from device
+ GPS_SW_REV, ///< (r--) deprecated, ::SW_REV, software revision, use only if ::GPS_RECEIVER_INFO not supp.
+ GPS_BVAR_STAT, ///< (r--) ::BVAR_STAT, status of buffered variables, only if ::GPS_MODEL_HAS_BVAR_STAT
+ GPS_TIME, ///< (-wa) ::TTM, current time or capture, or init board time
+ GPS_POS_XYZ, ///< (rw-) ::XYZ, current position in ECEF coordinates, only if ::GPS_MODEL_HAS_POS_XYZ
+ GPS_POS_LLA, ///< (rw-) ::LLA, current position in geographic coordinates, only if ::GPS_MODEL_HAS_POS_LLA
+ GPS_TZDL, ///< (rw-) ::TZDL, time zone / daylight saving, only if ::GPS_MODEL_HAS_TZDL
+ GPS_PORT_PARM, ///< (rw-) deprecated, ::PORT_PARM, use ::PORT_SETTINGS etc. if ::GPS_RECEIVER_INFO supported
+ GPS_SYNTH, ///< (rw-) ::SYNTH, synthesizer settings, only if ::GPS_HAS_SYNTH
+ GPS_ANT_INFO, ///< (r-a) ::ANT_INFO, time diff after antenna disconnect, only if ::GPS_MODEL_HAS_ANT_INFO
+ GPS_UCAP, ///< (r-a) ::TTM, user capture events, only if ::RECEIVER_INFO::n_ucaps > 0
+
+ /* GPS data */
+ GPS_CFGH = 0x100, ///< (rw-) ::CFGH, SVs' configuration and health codes
+ GPS_ALM, ///< (rw-) req: uint16_t SV num, ::SV_ALM, one SV's almanac
+ GPS_EPH, ///< (rw-) req: uint16_t SV num, ::SV_EPH, one SV's ephemeris
+ GPS_UTC, ///< (rw-) ::UTC, GPS %UTC correction parameters
+ GPS_IONO, ///< (rw-) ::IONO, GPS ionospheric correction parameters
+ GPS_ASCII_MSG ///< (r--) ::ASCII_MSG, the GPS ASCII message
+};
+
+
+#ifndef _CSUM_DEFINED
+ typedef uint16_t CSUM; /* checksum used by some structures stored in non-volatile memory */
+ #define _CSUM_DEFINED
+#endif
+
+
+/**
+ * @brief The header of a binary message.
+ */
+typedef struct
+{
+ GPS_CMD cmd; ///< see ::GPS_CMD_CODES
+ uint16_t len; ///< length of the data portion appended after the header
+ CSUM data_csum; ///< checksum of the data portion appended after the header
+ CSUM hdr_csum; ///< checksum of the preceding header bytes
+
+} GPS_MSG_HDR;
+
+
+#define GPS_ID_STR_LEN 16
+#define GPS_ID_STR_SIZE ( GPS_ID_STR_LEN + 1 )
+
+/**
+ * @brief Software revision information
+ *
+ * Contains a software revision code, plus an optional
+ * identifier for a customized version.
+ */
+typedef struct
+{
+ uint16_t code; ///< Version number, e.g. 0x0120 means v1.20
+ char name[GPS_ID_STR_SIZE]; ///< Optional string identifying a customized version
+ uint8_t reserved; ///< Reserved field to yield even structure size
+
+} SW_REV;
+
+
+/**
+ * @brief GNSS satellite numbers
+ *
+ * @todo: Check if MAX_SVNO_GLN is 94 instead of 95, and thus
+ * N_SVNO_GLN is 30 instead of 31, as reported by Wikipedia.
+ */
+enum GNSS_SVNOS
+{
+ MIN_SVNO_GPS = 1, ///< min. GPS satellite PRN number
+ MAX_SVNO_GPS = 32, ///< max. GPS satellite PRN number
+ N_SVNO_GPS = 32, ///< max. number of active GPS satellites
+
+ MIN_SVNO_WAAS = 33, ///< min. WAAS satellite number
+ MAX_SVNO_WAAS = 64, ///< max. WAAS satellite number
+ N_SVNO_WAAS = 32, ///< max. number of active WAAS satellites
+
+ MIN_SVNO_GLONASS = 65, ///< min. Glonass satellite number (64 + sat slot ID)
+ MAX_SVNO_GLONASS = 95, ///< max. Glonass satellite number (64 + sat slot ID)
+ N_SVNO_GLONASS = 31 ///< max. number of active Glonass satellites
+};
+
+
+typedef uint16_t SVNO; ///< the number of an SV (Space Vehicle, i.e. satellite)
+typedef uint16_t HEALTH; ///< an SV's 6 bit health code
+typedef uint16_t CFG; ///< an SV's 4 bit configuration code
+typedef uint16_t IOD; ///< Issue-Of-Data code
+
+
+/**
+ * @brief Status flags of battery buffered data
+ *
+ * Related to data received from the satellites, or data derived thereof.
+ *
+ * All '0' means OK, single bits set to '1' indicate
+ * the associated type of GPS data is not available.
+ *
+ * @see ::BVAR_FLAGS
+ */
+typedef uint16_t BVAR_STAT;
+
+#define _mbg_swab_bvar_stat( _p ) _mbg_swab16( (_p) )
+
+
+/**
+ * @brief Enumeration of flag bits used to define ::BVAR_FLAGS
+ *
+ * For each bit which is set this means the associated data set in
+ * non-volatile memory is not available, or incomplete.
+ * Most data sets will just be re-collected from the data streams sent
+ * by the satellites. However, the receiver position has usually been
+ * computed earlier during normal operation, and will be re-computed
+ * when a sufficient number of satellites can be received.
+ *
+ * @see ::BVAR_STAT
+ * @see ::BVAR_FLAGS
+ * @see ::BVAR_FLAG_NAMES
+ */
+enum BVAR_FLAG_BITS
+{
+ BVAR_BIT_CFGH_INVALID, ///< Satellite configuration and health parameters incomplete
+ BVAR_BIT_ALM_NOT_COMPLETE, ///< Almanac parameters incomplete
+ BVAR_BIT_UTC_INVALID, ///< %UTC offset parameters incomplete
+ BVAR_BIT_IONO_INVALID, ///< Ionospheric correction parameters incomplete
+ BVAR_BIT_RCVR_POS_INVALID, ///< No valid receiver position available
+ N_BVAR_BIT ///< number of defined ::BVAR_STAT bits
+};
+
+
+/**
+ * @brief Bit masks associated with ::BVAR_FLAG_BITS
+ *
+ * Used with ::BVAR_STAT.
+ *
+ * @see ::BVAR_STAT
+ * @see ::BVAR_FLAG_BITS
+ * @see ::BVAR_FLAG_NAMES
+ */
+enum BVAR_FLAGS
+{
+ BVAR_CFGH_INVALID = ( 1UL << BVAR_BIT_CFGH_INVALID ), ///< see ::BVAR_BIT_CFGH_INVALID
+ BVAR_ALM_NOT_COMPLETE = ( 1UL << BVAR_BIT_ALM_NOT_COMPLETE ), ///< see ::BVAR_BIT_ALM_NOT_COMPLETE
+ BVAR_UTC_INVALID = ( 1UL << BVAR_BIT_UTC_INVALID ), ///< see ::BVAR_BIT_UTC_INVALID
+ BVAR_IONO_INVALID = ( 1UL << BVAR_BIT_IONO_INVALID ), ///< see ::BVAR_BIT_IONO_INVALID
+ BVAR_RCVR_POS_INVALID = ( 1UL << BVAR_BIT_RCVR_POS_INVALID ), ///< see ::BVAR_BIT_RCVR_POS_INVALID
+};
+
+
+/**
+ * @brief A structure used to hold time in GPS format
+ *
+ * Date and time refer to the linear time scale defined by GPS, with
+ * the epoch starting at %UTC midnight at the beginning of January 6, 1980.
+ *
+ * GPS time is counted by the week numbers since the epoch, plus second
+ * of the week, plus fraction of the second. The week number transmitted
+ * by the satellites rolls over from 1023 to 0, but Meinberg devices
+ * just continue to count the weeks beyond the 1024 week limit to keep
+ * the receiver's internal time.
+ *
+ * %UTC time differs from GPS time since a number of leap seconds have
+ * been inserted in the %UTC time scale after the GPS epoche. The number
+ * of leap seconds is disseminated by the satellites using the ::UTC
+ * parameter set, which also provides info on pending leap seconds.
+ */
+typedef struct
+{
+ uint16_t wn; ///< the week number since GPS has been installed
+ uint32_t sec; ///< the second of that week
+ uint32_t tick; ///< fractions of a second, 1/::RECEIVER_INFO::ticks_per_sec units
+
+} T_GPS;
+
+
+/**
+ * @brief Local date and time computed from GPS time
+ *
+ * The current number of leap seconds have to be added to get %UTC
+ * from GPS time. Additional corrections could have been made according
+ * to the time zone/daylight saving parameters ::TZDL defined by the user.
+ * The status field can be checked to see which corrections
+ * have actually been applied.
+ *
+ * @note Conversion from GPS time to %UTC and/or local time can only be
+ * done if some valid ::UTC correction parameters are available in the
+ * receiver's non-volatile memory.
+ */
+typedef struct
+{
+ int16_t year; ///< year number, 0..9999
+ int8_t month; ///< month, 1..12
+ int8_t mday; ///< day of month, 1..31
+ int16_t yday; ///< day of year, 1..365, or 366 in case of leap year
+ int8_t wday; ///< day of week, 0..6 == Sun..Sat
+ int8_t hour; ///< hours, 0..23
+ int8_t min; ///< minutes, 0..59
+ int8_t sec; ///< seconds, 0..59, or 60 in case of inserted leap second
+ int32_t frac; ///< fractions of a second, 1/::RECEIVER_INFO::ticks_per_sec units
+ int32_t offs_from_utc; ///< local time offset from %UTC [sec]
+ uint16_t status; ///< status flags, see ::TM_GPS_STATUS_BIT_MASKS
+
+} TM_GPS;
+
+
+
+/**
+ * @brief Status flag bits used to define ::TM_GPS_STATUS_BIT_MASKS
+ *
+ * These bits report info on the time conversion from GPS time to %UTC
+ * and/or local time as well as device status info.
+ *
+ * @see ::TM_GPS_STATUS_BIT_MASKS
+ */
+enum TM_GPS_STATUS_BITS
+{
+ TM_BIT_UTC, ///< %UTC correction has been made
+ TM_BIT_LOCAL, ///< %UTC has been converted to local time according to ::TZDL settings
+ TM_BIT_DL_ANN, ///< state of daylight saving is going to change
+ TM_BIT_DL_ENB, ///< daylight saving is in effect
+ TM_BIT_LS_ANN, ///< leap second pending
+ TM_BIT_LS_ENB, ///< current second is leap second
+ TM_BIT_LS_ANN_NEG, ///< set in addition to ::TM_BIT_LS_ANN if leap sec is negative
+ TM_BIT_INVT, ///< invalid time, e.g. if RTC battery bas been empty
+
+ TM_BIT_EXT_SYNC, ///< synchronized externally
+ TM_BIT_HOLDOVER, ///< in holdover mode after previous synchronization
+ TM_BIT_ANT_SHORT, ///< antenna cable short circuited
+ TM_BIT_NO_WARM, ///< OCXO has not warmed up
+ TM_BIT_ANT_DISCONN, ///< antenna currently disconnected
+ TM_BIT_SYN_FLAG, ///< TIME_SYN output is low
+ TM_BIT_NO_SYNC, ///< time sync actually not verified
+ TM_BIT_NO_POS ///< position actually not verified, LOCK LED off
+};
+
+
+/**
+ * @brief Status flag masks used with ::TM_GPS::status
+ *
+ * These bits report info on the time conversion from GPS time to %UTC
+ * and/or local time as well as device status info.
+ *
+ * @see ::TM_GPS_STATUS_BITS
+ */
+enum TM_GPS_STATUS_BIT_MASKS
+{
+ TM_UTC = ( 1UL << TM_BIT_UTC ), ///< see ::TM_BIT_UTC
+ TM_LOCAL = ( 1UL << TM_BIT_LOCAL ), ///< see ::TM_BIT_LOCAL
+ TM_DL_ANN = ( 1UL << TM_BIT_DL_ANN ), ///< see ::TM_BIT_DL_ANN
+ TM_DL_ENB = ( 1UL << TM_BIT_DL_ENB ), ///< see ::TM_BIT_DL_ENB
+ TM_LS_ANN = ( 1UL << TM_BIT_LS_ANN ), ///< see ::TM_BIT_LS_ANN
+ TM_LS_ENB = ( 1UL << TM_BIT_LS_ENB ), ///< see ::TM_BIT_LS_ENB
+ TM_LS_ANN_NEG = ( 1UL << TM_BIT_LS_ANN_NEG ), ///< see ::TM_BIT_LS_ANN_NEG
+ TM_INVT = ( 1UL << TM_BIT_INVT ), ///< see ::TM_BIT_INVT
+
+ TM_EXT_SYNC = ( 1UL << TM_BIT_EXT_SYNC ), ///< see ::TM_BIT_EXT_SYNC
+ TM_HOLDOVER = ( 1UL << TM_BIT_HOLDOVER ), ///< see ::TM_BIT_HOLDOVER
+ TM_ANT_SHORT = ( 1UL << TM_BIT_ANT_SHORT ), ///< see ::TM_BIT_ANT_SHORT
+ TM_NO_WARM = ( 1UL << TM_BIT_NO_WARM ), ///< see ::TM_BIT_NO_WARM
+ TM_ANT_DISCONN = ( 1UL << TM_BIT_ANT_DISCONN ), ///< see ::TM_BIT_ANT_DISCONN
+ TM_SYN_FLAG = ( 1UL << TM_BIT_SYN_FLAG ), ///< see ::TM_BIT_SYN_FLAG
+ TM_NO_SYNC = ( 1UL << TM_BIT_NO_SYNC ), ///< see ::TM_BIT_NO_SYNC
+ TM_NO_POS = ( 1UL << TM_BIT_NO_POS ) ///< see ::TM_BIT_NO_POS
+};
+
+
+/**
+ * @brief A structure used to transmit information on date and time
+ *
+ * This structure can be used to transfer the current time, in which
+ * case the channel field has to be set to -1, or an event capture time
+ * retrieved from the on-board FIFO, in which case the channel field
+ * contains the index of the time capture input, e.g. 0 or 1.
+ */
+typedef struct
+{
+ int16_t channel; ///< -1: the current on-board time; >= 0 the capture channel number
+ T_GPS t; ///< time in GPS scale and format
+ TM_GPS tm; ///< time converted to %UTC and/or local time according to ::TZDL settings
+
+} TTM;
+
+
+
+/* Two types of variables used to store a position. Type XYZ is */
+/* used with a position in earth centered, earth fixed (ECEF) */
+/* coordinates whereas type LLA holds such a position converted */
+/* to geographic coordinates as defined by WGS84 (World Geodetic */
+/* System from 1984). */
+
+/**
+ * @brief Sequence and number of components of a cartesian position
+ */
+enum XYZ_FIELDS { XP, YP, ZP, N_XYZ }; // x, y, z
+
+/**
+ * @brief A position in cartesian coordinates
+ *
+ * Usually earth centered, earth fixed (ECEF) coordinates,
+ * in [m].
+ *
+ * @note In the original code this is an array of double.
+ *
+ * @see ::XYZ_FIELDS
+ */
+typedef l_fp XYZ[N_XYZ];
+
+
+/**
+ * @brief Sequence and number of components of a geographic position
+ */
+enum LLA_FIELDS { LAT, LON, ALT, N_LLA }; /* latitude, longitude, altitude */
+
+/**
+ * @brief A geographic position based on latitude, longitude, and altitude
+ *
+ * The geographic position associated to specific cartesian coordinates
+ * depends on the characteristics of the ellipsoid used for the computation,
+ * the so-called geographic datum. GPS uses the WGS84 (World Geodetic System
+ * from 1984) ellipsoid by default.
+ *
+ * lon, lat in [rad], alt in [m]
+ *
+ * @note In the original code this is an array of double.
+ *
+ * @see ::LLA_FIELDS
+ */
+typedef l_fp LLA[N_LLA];
+
+
+/**
+ * @defgroup group_synth Synthesizer parameters
+ *
+ * Synthesizer frequency is expressed as a
+ * four digit decimal number (freq) to be multiplied by 0.1 Hz and an
+ * base 10 exponent (range). If the effective frequency is less than
+ * 10 kHz its phase is synchronized corresponding to the variable phase.
+ * Phase may be in a range from -360 deg to +360 deg with a resolution
+ * of 0.1 deg, so the resulting numbers to be stored are in a range of
+ * -3600 to +3600.
+ *
+ * Example:<br>
+ * Assume the value of freq is 2345 (decimal) and the value of phase is 900.
+ * If range == 0 the effective frequency is 234.5 Hz with a phase of +90 deg.
+ * If range == 1 the synthesizer will generate a 2345 Hz output frequency
+ * and so on.
+ *
+ * Limitations:<br>
+ * If freq == 0 the synthesizer is disabled. If range == 0 the least
+ * significant digit of freq is limited to 0, 3, 5 or 6. The resulting
+ * frequency is shown in the examples below:
+ * - freq == 1230 --> 123.0 Hz
+ * - freq == 1233 --> 123 1/3 Hz (real 1/3 Hz, NOT 123.3 Hz)
+ * - freq == 1235 --> 123.5 Hz
+ * - freq == 1236 --> 123 2/3 Hz (real 2/3 Hz, NOT 123.6 Hz)
+ *
+ * If range == ::MAX_SYNTH_RANGE the value of freq must not exceed 1000, so
+ * the output frequency is limited to 10 MHz (see ::MAX_SYNTH_FREQ_VAL).
+ *
+ * @{ */
+
+#define N_SYNTH_FREQ_DIGIT 4 ///< number of digits to edit
+#define MAX_SYNTH_FREQ 1000 ///< if range == ::MAX_SYNTH_RANGE
+
+#define MIN_SYNTH_RANGE 0
+#define MAX_SYNTH_RANGE 5
+#define N_SYNTH_RANGE ( MAX_SYNTH_RANGE - MIN_SYNTH_RANGE + 1 )
+
+#define N_SYNTH_PHASE_DIGIT 4
+#define MAX_SYNTH_PHASE 3600
+
+
+#define MAX_SYNTH_FREQ_EDIT 9999 ///< max sequence of digits when editing
+
+
+/**
+ * @brief The maximum frequency that can be configured for the synthesizer
+ */
+#define MAX_SYNTH_FREQ_VAL 10000000UL ///< 10 MHz
+/* == MAX_SYNTH_FREQ * 10^(MAX_SYNTH_RANGE-1) */
+
+/**
+ * @brief The synthesizer's phase is only be synchronized if the frequency is below this limit
+ */
+#define SYNTH_PHASE_SYNC_LIMIT 10000UL ///< 10 kHz
+
+/**
+ * A Macro used to determine the position of the decimal point
+ * when printing the synthesizer frequency as 4 digit value
+ */
+#define _synth_dp_pos_from_range( _r ) \
+ ( ( ( N_SYNTH_RANGE - (_r) ) % ( N_SYNTH_FREQ_DIGIT - 1 ) ) + 1 )
+
+/**
+ * @brief Synthesizer frequency units
+ *
+ * An initializer for commonly displayed synthesizer frequency units
+ * (::N_SYNTH_RANGE strings)
+ */
+#define DEFAULT_FREQ_RANGES \
+{ \
+ "Hz", \
+ "kHz", \
+ "kHz", \
+ "kHz", \
+ "MHz", \
+ "MHz", \
+}
+
+
+
+/**
+ * @brief Synthesizer configuration parameters
+ */
+typedef struct
+{
+ int16_t freq; ///< four digits used; scale: 0.1 Hz; e.g. 1234 -> 123.4 Hz
+ int16_t range; ///< scale factor for freq; 0..::MAX_SYNTH_RANGE
+ int16_t phase; ///< -::MAX_SYNTH_PHASE..+::MAX_SYNTH_PHASE; >0 -> pulses later
+
+} SYNTH;
+
+#define _mbg_swab_synth( _p ) \
+{ \
+ _mbg_swab16( &(_p)->freq ); \
+ _mbg_swab16( &(_p)->range ); \
+ _mbg_swab16( &(_p)->phase ); \
+}
+
+
+/**
+ * @brief Enumeration of synthesizer states
+ */
+enum SYNTH_STATES
+{
+ SYNTH_DISABLED, ///< disbled by cfg, i.e. freq == 0.0
+ SYNTH_OFF, ///< not enabled after power-up
+ SYNTH_FREE, ///< enabled, but not synchronized
+ SYNTH_DRIFTING, ///< has initially been sync'd, but now running free
+ SYNTH_SYNC, ///< fully synchronized
+ N_SYNTH_STATE ///< the number of known states
+};
+
+
+/**
+ * @brief A structure used to report the synthesizer state
+ */
+typedef struct
+{
+ uint8_t state; ///< state code as enumerated in ::SYNTH_STATES
+ uint8_t flags; ///< reserved, currently always 0
+
+} SYNTH_STATE;
+
+#define _mbg_swab_synth_state( _p ) _nop_macro_fnc()
+
+#define SYNTH_FLAG_PHASE_IGNORED 0x01
+
+/** @} defgroup group_synth */
+
+
+
+/**
+ * @defgroup group_tzdl Time zone / daylight saving parameters
+ *
+ * Example: <br>
+ * For automatic daylight saving enable/disable in Central Europe,
+ * the variables are to be set as shown below: <br>
+ * - offs = 3600L one hour from %UTC
+ * - offs_dl = 3600L one additional hour if daylight saving enabled
+ * - tm_on = first Sunday from March 25, 02:00:00h ( year |= ::DL_AUTO_FLAG )
+ * - tm_off = first Sunday from October 25, 03:00:00h ( year |= ::DL_AUTO_FLAG )
+ * - name[0] == "CET " name if daylight saving not enabled
+ * - name[1] == "CEST " name if daylight saving is enabled
+ *
+ * @{ */
+
+/**
+ * @brief The name of a time zone
+ *
+ * @note Up to 5 printable characters, plus trailing zero
+ */
+typedef char TZ_NAME[6];
+
+/**
+ * @brief Time zone / daylight saving parameters
+ *
+ * This structure is used to specify how a device converts on-board %UTC
+ * to local time, including computation of beginning and end of daylight
+ * saving time (DST), if required.
+ *
+ * @note The ::TZDL structure contains members of type ::TM_GPS to specify
+ * the times for beginning and end of DST. However, the ::TM_GPS::frac,
+ * ::TM_GPS::offs_from_utc, and ::TM_GPS::status fields of these ::TZDL::tm_on
+ * and ::TZDL::tm_off members are ignored for the conversion to local time,
+ * and thus should be 0.
+ */
+typedef struct
+{
+ int32_t offs; ///< standard offset from %UTC to local time [sec]
+ int32_t offs_dl; ///< additional offset if daylight saving enabled [sec]
+ TM_GPS tm_on; ///< date/time when daylight saving starts
+ TM_GPS tm_off; ///< date/time when daylight saving ends
+ TZ_NAME name[2]; ///< names without and with daylight saving enabled
+
+} TZDL;
+
+/**
+ * @brief A flag indicating automatic computation of DST
+ *
+ * If this flag is or'ed to the year numbers in ::TZDL::tm_on and ::TZDL::tm_off
+ * then daylight saving is computed automatically year by year.
+ */
+#define DL_AUTO_FLAG 0x8000
+
+/** @} defgroup group_tzdl */
+
+
+
+/**
+ * @brief Antenna status and error at reconnect information
+ *
+ * The structure below reflects the status of the antenna,
+ * the times of last disconnect/reconnect, and the board's
+ * clock offset when it has synchronized again after the
+ * disconnection interval.
+ *
+ * @note ::ANT_INFO::status changes back to ::ANT_RECONN only
+ * after the antenna has been reconnected <b>and</b> the
+ * receiver has re-synchronized to the satellite signal.
+ * In this case ::ANT_INFO::delta_t reports the time offset
+ * before resynchronization, i.e. how much the internal
+ * time has drifted while the antenna was disconnected.
+ */
+typedef struct
+{
+ int16_t status; ///< current status of antenna, see ::ANT_STATUS_CODES
+ TM_GPS tm_disconn; ///< time of antenna disconnect
+ TM_GPS tm_reconn; ///< time of antenna reconnect
+ int32_t delta_t; ///< clock offs at reconn. time in 1/::RECEIVER_INFO::ticks_per_sec units
+
+} ANT_INFO;
+
+
+/**
+ * @brief Status code used with ::ANT_INFO::status
+ */
+enum ANT_STATUS_CODES
+{
+ ANT_INVALID, ///< No other fields valid since antenna has not yet been disconnected
+ ANT_DISCONN, ///< Antenna is disconnected, tm_reconn and delta_t not yet set
+ ANT_RECONN, ///< Antenna has been disconnect, and receiver sync. after reconnect, so all fields valid
+ N_ANT_STATUS_CODES ///< the number of known status codes
+};
+
+
+
+/**
+ * @brief Summary of configuration and health data of all satellites
+ */
+typedef struct
+{
+ CSUM csum; ///< checksum of the remaining bytes
+ int16_t valid; ///< flag data are valid
+
+ T_GPS tot_51; ///< time of transmission, page 51
+ T_GPS tot_63; ///< time of transmission, page 63
+ T_GPS t0a; ///< complete reference time almanac
+
+ CFG cfg[N_SVNO_GPS]; ///< 4 bit SV configuration code from page 63
+ HEALTH health[N_SVNO_GPS]; ///< 6 bit SV health codes from pages 51, 63
+
+} CFGH;
+
+
+
+/**
+ * @brief GPS %UTC correction parameters
+ *
+ * %UTC correction parameters basically as sent by the GPS satellites.
+ *
+ * The csum field is only used by the card's firmware to check the
+ * consistency of the structure in non-volatile memory.
+ *
+ * The field labeled valid indicates if the parameter set is valid, i.e.
+ * if it contains data received from the satellites.
+ *
+ * t0t, A0 and A1 contain fractional correction parameters for the current
+ * GPS-%UTC time offset in addition to the whole seconds. This is evaluated
+ * by the receivers' firmware to convert GPS time to %UTC time.
+ *
+ * The delta_tls field contains the current full seconds offset between
+ * GPS time and %UTC, which corresponds to the number of leap seconds inserted
+ * into the %UTC time scale since GPS was put into operation in January 1980.
+ *
+ * delta_tlfs holds the number of "future" leap seconds, i.e. the %UTC offset
+ * after the next leap second event defined by WNlsf and DNt.
+ *
+ * The fields WNlsf and DNt specify the GPS week number and the day number
+ * in that week for the end of which a leap second has been scheduled.
+ *
+ * @note: The satellites transmit WNlsf only as a signed 8 bit value, so it
+ * can only define a point in time which is +/- 127 weeks off the current time.
+ * The firmware tries to expand this based on the current week number, but
+ * the result is ambiguous if the leap second occurs or occurred more
+ * than 127 weeks in the future or past.
+ *
+ * So the leap second date should <b>only</b> be evaluated and displayed
+ * in a user interface if the fields delta_tls and delta_tlsf have
+ * different values, in which case there is indeed a leap second announcement
+ * inside the +/- 127 week range.
+ *
+ * @note In the original code the type of A0 and A1 is double.
+ */
+typedef struct
+{
+ CSUM csum; ///< Checksum of the remaining bytes
+ int16_t valid; ///< Flag indicating %UTC parameters are valid
+
+ T_GPS t0t; ///< Reference Time %UTC Parameters [wn|sec]
+ l_fp A0; ///< +- Clock Correction Coefficient 0 [sec]
+ l_fp A1; ///< +- Clock Correction Coefficient 1 [sec/sec]
+
+ uint16_t WNlsf; ///< Week number of nearest leap second
+ int16_t DNt; ///< The day number at the end of which a leap second occurs
+ int8_t delta_tls; ///< Current %UTC offset to GPS system time [sec]
+ int8_t delta_tlsf; ///< Future %UTC offset to GPS system time after next leap second transition [sec]
+
+} UTC;
+
+
+/**
+ * @brief GPS ASCII message
+ */
+typedef struct
+{
+ CSUM csum; ///< checksum of the remaining bytes */
+ int16_t valid; ///< flag data are valid
+ char s[23]; ///< 22 chars GPS ASCII message plus trailing zero
+
+} ASCII_MSG;
+
+
+/**
+ * @brief Ephemeris parameters of one specific satellite
+ *
+ * Needed to compute the position of a satellite at a given time with
+ * high precision. Valid for an interval of 4 to 6 hours from start
+ * of transmission.
+ */
+typedef struct
+{
+ CSUM csum; ///< checksum of the remaining bytes
+ int16_t valid; ///< flag data are valid
+
+ HEALTH health; ///< health indication of transmitting SV [---]
+ IOD IODC; ///< Issue Of Data, Clock
+ IOD IODE2; ///< Issue of Data, Ephemeris (Subframe 2)
+ IOD IODE3; ///< Issue of Data, Ephemeris (Subframe 3)
+ T_GPS tt; ///< time of transmission
+ T_GPS t0c; ///< Reference Time Clock [---]
+ T_GPS t0e; ///< Reference Time Ephemeris [---]
+
+ l_fp sqrt_A; ///< Square Root of semi-major Axis [sqrt(m)]
+ l_fp e; ///< Eccentricity [---]
+ l_fp M0; ///< +- Mean Anomaly at Ref. Time [rad]
+ l_fp omega; ///< +- Argument of Perigee [rad]
+ l_fp OMEGA0; ///< +- Longit. of Asc. Node of orbit plane [rad]
+ l_fp OMEGADOT; ///< +- Rate of Right Ascension [rad/sec]
+ l_fp deltan; ///< +- Mean Motion Diff. from computed value [rad/sec]
+ l_fp i0; ///< +- Inclination Angle [rad]
+ l_fp idot; ///< +- Rate of Inclination Angle [rad/sec]
+ l_fp crc; ///< +- Cosine Corr. Term to Orbit Radius [m]
+ l_fp crs; ///< +- Sine Corr. Term to Orbit Radius [m]
+ l_fp cuc; ///< +- Cosine Corr. Term to Arg. of Latitude [rad]
+ l_fp cus; ///< +- Sine Corr. Term to Arg. of Latitude [rad]
+ l_fp cic; ///< +- Cosine Corr. Term to Inclination Angle [rad]
+ l_fp cis; ///< +- Sine Corr. Term to Inclination Angle [rad]
+
+ l_fp af0; ///< +- Clock Correction Coefficient 0 [sec]
+ l_fp af1; ///< +- Clock Correction Coefficient 1 [sec/sec]
+ l_fp af2; ///< +- Clock Correction Coefficient 2 [sec/sec^2]
+ l_fp tgd; ///< +- estimated group delay differential [sec]
+
+ uint16_t URA; ///< predicted User Range Accuracy
+
+ uint8_t L2code; ///< code on L2 channel [---]
+ uint8_t L2flag; ///< L2 P data flag [---]
+
+} EPH;
+
+
+
+/**
+ * @brief Almanac parameters of one specific satellite
+ *
+ * A reduced precision set of parameters used to check if a satellite
+ * is in view at a given time. Valid for an interval of more than 7 days
+ * from start of transmission.
+ */
+typedef struct
+{
+ CSUM csum; ///< checksum of the remaining bytes
+ int16_t valid; ///< flag data are valid
+
+ HEALTH health; ///< [---]
+ T_GPS t0a; ///< Reference Time Almanac [sec]
+
+ l_fp sqrt_A; ///< Square Root of semi-major Axis [sqrt(m)]
+ l_fp e; ///< Eccentricity [---]
+
+ l_fp M0; ///< +- Mean Anomaly at Ref. Time [rad]
+ l_fp omega; ///< +- Argument of Perigee [rad]
+ l_fp OMEGA0; ///< +- Longit. of Asc. Node of orbit plane [rad]
+ l_fp OMEGADOT; ///< +- Rate of Right Ascension [rad/sec]
+ l_fp deltai; ///< +- [rad]
+ l_fp af0; ///< +- Clock Correction Coefficient 0 [sec]
+ l_fp af1; ///< +- Clock Correction Coefficient 1 [sec/sec]
+
+} ALM;
+
+
+
+/**
+ * @brief Ionospheric correction parameters
+ */
+typedef struct
+{
+ CSUM csum; ///< checksum of the remaining bytes
+ int16_t valid; ///< flag data are valid
+
+ l_fp alpha_0; ///< Ionosph. Corr. Coeff. Alpha 0 [sec]
+ l_fp alpha_1; ///< Ionosph. Corr. Coeff. Alpha 1 [sec/deg]
+ l_fp alpha_2; ///< Ionosph. Corr. Coeff. Alpha 2 [sec/deg^2]
+ l_fp alpha_3; ///< Ionosph. Corr. Coeff. Alpha 3 [sec/deg^3]
+
+ l_fp beta_0; ///< Ionosph. Corr. Coeff. Beta 0 [sec]
+ l_fp beta_1; ///< Ionosph. Corr. Coeff. Beta 1 [sec/deg]
+ l_fp beta_2; ///< Ionosph. Corr. Coeff. Beta 2 [sec/deg^2]
+ l_fp beta_3; ///< Ionosph. Corr. Coeff. Beta 3 [sec/deg^3]
+
+} IONO;
+
+
+
+void mbg_tm_str (char **, TM_GPS *, int, int);
+void mbg_tgps_str (char **, T_GPS *, int);
+void get_mbg_header (unsigned char **, GPS_MSG_HDR *);
+void put_mbg_header (unsigned char **, GPS_MSG_HDR *);
+void get_mbg_sw_rev (unsigned char **, SW_REV *);
+void get_mbg_ascii_msg (unsigned char **, ASCII_MSG *);
+void get_mbg_svno (unsigned char **, SVNO *);
+void get_mbg_health (unsigned char **, HEALTH *);
+void get_mbg_cfg (unsigned char **, CFG *);
+void get_mbg_tgps (unsigned char **, T_GPS *);
+void get_mbg_tm (unsigned char **, TM_GPS *);
+void get_mbg_ttm (unsigned char **, TTM *);
+void get_mbg_synth (unsigned char **, SYNTH *);
+void get_mbg_tzdl (unsigned char **, TZDL *);
+void get_mbg_antinfo (unsigned char **, ANT_INFO *);
+void get_mbg_cfgh (unsigned char **, CFGH *);
+void get_mbg_utc (unsigned char **, UTC *);
+void get_mbg_lla (unsigned char **, LLA);
+void get_mbg_xyz (unsigned char **, XYZ);
+void get_mbg_portparam (unsigned char **, PORT_PARM *);
+void get_mbg_eph (unsigned char **, EPH *);
+void get_mbg_alm (unsigned char **, ALM *);
+void get_mbg_iono (unsigned char **, IONO *);
+
+CSUM mbg_csum (unsigned char *, unsigned int);
+
+#endif
+/*
+ * History:
+ *
+ * mbg_gps166.h,v
+ * Revision 4.7 2006/06/22 18:41:43 kardel
+ * clean up signedness (gcc 4)
+ *
+ * Revision 4.6 2005/10/07 22:11:56 kardel
+ * bounded buffer implementation
+ *
+ * Revision 4.5.2.1 2005/09/25 10:23:48 kardel
+ * support bounded buffers
+ *
+ * Revision 4.5 2005/06/25 10:58:45 kardel
+ * add missing log keywords
+ *
+ * Revision 4.1 1998/06/12 15:07:30 kardel
+ * fixed prototyping
+ *
+ * Revision 4.0 1998/04/10 19:50:42 kardel
+ * Start 4.0 release version numbering
+ *
+ * Revision 1.1 1998/04/10 19:27:34 kardel
+ * initial NTP VERSION 4 integration of PARSE with GPS166 binary support
+ *
+ * Revision 1.1 1997/10/06 20:55:38 kardel
+ * new parse structure
+ *
+ */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/namespace.h b/sebhbsd/freebsd/contrib/ntp/include/namespace.h
new file mode 100644
index 0000000..f5653fc
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/namespace.h
@@ -0,0 +1,902 @@
+#define addremove_io_fd _ntp_addremove_io_fd
+#define alarm_flag _ntp_alarm_flag
+#define alarm_overflow _ntp_alarm_overflow
+#define allow_panic _ntp_allow_panic
+#define any6_interface _ntp_any6_interface
+#define any_interface _ntp_any_interface
+#define assoc_hash _ntp_assoc_hash
+#define assoc_hash_count _ntp_assoc_hash_count
+#define assocpeer_calls _ntp_assocpeer_calls
+#define asyncio_reader_list _ntp_asyncio_reader_list
+#define authdecryptions _ntp_authdecryptions
+#define authencryptions _ntp_authencryptions
+#define authfreekeys _ntp_authfreekeys
+#define authhashdisabled _ntp_authhashdisabled
+#define authkeyexpired _ntp_authkeyexpired
+#define authkeylookups _ntp_authkeylookups
+#define authkeynotfound _ntp_authkeynotfound
+#define authkeyuncached _ntp_authkeyuncached
+#define authnokey _ntp_authnokey
+#define authnumfreekeys _ntp_authnumfreekeys
+#define authnumkeys _ntp_authnumkeys
+#define auth_timereset _ntp_auth_timereset
+#define blocking_child_ready_done _ntp_blocking_child_ready_done
+#define blocking_child_ready_seen _ntp_blocking_child_ready_seen
+#define blocking_children _ntp_blocking_children
+#define blocking_children_alloc _ntp_blocking_children_alloc
+#define broadcast_client_enabled _ntp_broadcast_client_enabled
+#define cache_flags _ntp_cache_flags
+#define cache_keyacclist _ntp_cache_keyacclist
+#define cache_keyid _ntp_cache_keyid
+#define cache_secret _ntp_cache_secret
+#define cache_secretsize _ntp_cache_secretsize
+#define cache_type _ntp_cache_type
+#define cfgt _ntp_cfgt
+#define cfg_tree_history _ntp_cfg_tree_history
+#define clock_codec _ntp_clock_codec
+#define clock_jitter _ntp_clock_jitter
+#define clock_stability _ntp_clock_stability
+#define cmdline_server_count _ntp_cmdline_server_count
+#define cmdline_servers _ntp_cmdline_servers
+#define conf_file_sum _ntp_conf_file_sum
+#define config_file _ntp_config_file
+#define config_priority _ntp_config_priority
+#define config_priority_override _ntp_config_priority_override
+#define cryptosw _ntp_cryptosw
+#define ctl_auth_keyid _ntp_ctl_auth_keyid
+#define ctltimereset _ntp_ctltimereset
+#define ctl_traps _ntp_ctl_traps
+#define current_time _ntp_current_time
+#define debug _ntp_debug
+#define disable_dynamic_updates _ntp_disable_dynamic_updates
+#define dnschild_contexts _ntp_dnschild_contexts
+#define dnschild_contexts_alloc _ntp_dnschild_contexts_alloc
+#define dnsworker_contexts _ntp_dnsworker_contexts
+#define dnsworker_contexts_alloc _ntp_dnsworker_contexts_alloc
+#define drift_comp _ntp_drift_comp
+#define dynamic_interleave _ntp_dynamic_interleave
+#define ep_list _ntp_ep_list
+#define errorcounter _ntp_errorcounter
+#define ext_enable _ntp_ext_enable
+#define fd_list _ntp_fd_list
+#define findpeer_calls _ntp_findpeer_calls
+#define force_step_once _ntp_force_step_once
+#define freq_cnt _ntp_freq_cnt
+#define freq_set _ntp_freq_set
+#define handler_calls _ntp_handler_calls
+#define handler_pkts _ntp_handler_pkts
+#define hardpps_enable _ntp_hardpps_enable
+#define info_auth_keyid _ntp_info_auth_keyid
+#define initializing _ntp_initializing
+#define interface_interval _ntp_interface_interval
+#define intres_req_pending _ntp_intres_req_pending
+#define io_timereset _ntp_io_timereset
+#define ipv4_works _ntp_ipv4_works
+#define ipv6_works _ntp_ipv6_works
+#define isc_lctx _ntp_isc_lctx
+#define isc_msgcat _ntp_isc_msgcat
+#define itimer _ntp_itimer
+#define kernel_status _ntp_kernel_status
+#define key_hash _ntp_key_hash
+#define key_listhead _ntp_key_listhead
+#define last_offset _ntp_last_offset
+#define leapdif _ntp_leapdif
+#define leapsec _ntp_leapsec
+#define leap_sec_in_progress _ntp_leap_sec_in_progress
+#define leap_smear _ntp_leap_smear
+#define leap_smear_intv _ntp_leap_smear_intv
+#define lib_inited _ntp_lib_inited
+#define lib_nextbuf _ntp_lib_nextbuf
+#define lib_stringbuf _ntp_lib_stringbuf
+#define loopback_interface _ntp_loopback_interface
+#define mc4_list _ntp_mc4_list
+#define mc6_list _ntp_mc6_list
+#define measured_tick _ntp_measured_tick
+#define mode_ntpdate _ntp_mode_ntpdate
+#define mon_enabled _ntp_mon_enabled
+#define mon_hash _ntp_mon_hash
+#define mon_hash_bits _ntp_mon_hash_bits
+#define mon_mru_list _ntp_mon_mru_list
+#define mru_alloc _ntp_mru_alloc
+#define mru_entries _ntp_mru_entries
+#define mru_peakentries _ntp_mru_peakentries
+#define msyslog_term _ntp_msyslog_term
+#define nic_rule_list _ntp_nic_rule_list
+#define ninterfaces _ntp_ninterfaces
+#define nofork _ntp_nofork
+#define ntp_crypto_bs_pubkey _ntp_ntp_crypto_bs_pubkey
+#define ntp_mode7 _ntp_ntp_mode7
+#define numasyncmsgs _ntp_numasyncmsgs
+#define numctlbadoffset _ntp_numctlbadoffset
+#define numctlbadop _ntp_numctlbadop
+#define numctlbadpkts _ntp_numctlbadpkts
+#define numctlbadversion _ntp_numctlbadversion
+#define numctldatatooshort _ntp_numctldatatooshort
+#define numctlerrors _ntp_numctlerrors
+#define numctlfrags _ntp_numctlfrags
+#define numctlinputerr _ntp_numctlinputerr
+#define numctlinputfrag _ntp_numctlinputfrag
+#define numctlinputresp _ntp_numctlinputresp
+#define numctlreq _ntp_numctlreq
+#define numctlresponses _ntp_numctlresponses
+#define numctltooshort _ntp_numctltooshort
+#define num_ctl_traps _ntp_num_ctl_traps
+#define numrequests _ntp_numrequests
+#define numresppkts _ntp_numresppkts
+#define optionParseShellOptions _ntp_optionParseShellOptions
+#define option_usage_fp _ntp_option_usage_fp
+#define orphwait _ntp_orphwait
+#define packets_dropped _ntp_packets_dropped
+#define packets_ignored _ntp_packets_ignored
+#define packets_notsent _ntp_packets_notsent
+#define packets_received _ntp_packets_received
+#define packets_sent _ntp_packets_sent
+#define peer_allocations _ntp_peer_allocations
+#define peer_associations _ntp_peer_associations
+#define peer_demobilizations _ntp_peer_demobilizations
+#define peer_free_count _ntp_peer_free_count
+#define peer_hash _ntp_peer_hash
+#define peer_hash_count _ntp_peer_hash_count
+#define peer_list _ntp_peer_list
+#define peer_ntpdate _ntp_peer_ntpdate
+#define peer_preempt _ntp_peer_preempt
+#define peer_timereset _ntp_peer_timereset
+#define pll_control _ntp_pll_control
+#define pll_status _ntp_pll_status
+#define pps_stratum _ntp_pps_stratum
+#define progname _ntp_progname
+#define remoteaddr_list _ntp_remoteaddr_list
+#define remote_config _ntp_remote_config
+#define restrictlist4 _ntp_restrictlist4
+#define restrictlist6 _ntp_restrictlist6
+#define saveconfigdir _ntp_saveconfigdir
+#define saved_argc _ntp_saved_argc
+#define saved_argv _ntp_saved_argv
+#define set_tod_using _ntp_set_tod_using
+#define state _ntp_state
+#define stats_control _ntp_stats_control
+#define stats_drift_file _ntp_stats_drift_file
+#define step_callback _ntp_step_callback
+#define sys_authdelay _ntp_sys_authdelay
+#define sys_authenticate _ntp_sys_authenticate
+#define sys_badauth _ntp_sys_badauth
+#define sys_badlength _ntp_sys_badlength
+#define sys_bclient _ntp_sys_bclient
+#define sys_bcpollbstep _ntp_sys_bcpollbstep
+#define sys_bdelay _ntp_sys_bdelay
+#define sys_cohort _ntp_sys_cohort
+#define sys_declined _ntp_sys_declined
+#define sys_epoch _ntp_sys_epoch
+#define sys_floor _ntp_sys_floor
+#define sys_fuzz _ntp_sys_fuzz
+#define sys_fuzz_nsec _ntp_sys_fuzz_nsec
+#define sys_ident _ntp_sys_ident
+#define sys_ifnum _ntp_sys_ifnum
+#define sys_jitter _ntp_sys_jitter
+#define sys_kodsent _ntp_sys_kodsent
+#define sys_lamport _ntp_sys_lamport
+#define sys_leap _ntp_sys_leap
+#define sys_limitrejected _ntp_sys_limitrejected
+#define syslog_abs_fname _ntp_syslog_abs_fname
+#define syslog_file _ntp_syslog_file
+#define syslog_fname _ntp_syslog_fname
+#define sys_manycastserver _ntp_sys_manycastserver
+#define sys_newversion _ntp_sys_newversion
+#define sys_offset _ntp_sys_offset
+#define sys_oldversion _ntp_sys_oldversion
+#define sys_peer _ntp_sys_peer
+#define sys_phone _ntp_sys_phone
+#define sys_poll _ntp_sys_poll
+#define sys_precision _ntp_sys_precision
+#define sys_private _ntp_sys_private
+#define sys_processed _ntp_sys_processed
+#define sys_received _ntp_sys_received
+#define sys_refid _ntp_sys_refid
+#define sys_reftime _ntp_sys_reftime
+#define sys_residual _ntp_sys_residual
+#define sys_restricted _ntp_sys_restricted
+#define sys_rootdelay _ntp_sys_rootdelay
+#define sys_rootdisp _ntp_sys_rootdisp
+#define sys_stattime _ntp_sys_stattime
+#define sys_stratum _ntp_sys_stratum
+#define sys_survivors _ntp_sys_survivors
+#define sys_tai _ntp_sys_tai
+#define sys_tick _ntp_sys_tick
+#define sys_tsrounding _ntp_sys_tsrounding
+#define sys_ttl _ntp_sys_ttl
+#define sys_ttlmax _ntp_sys_ttlmax
+#define tc_counter _ntp_tc_counter
+#define timer_overflows _ntp_timer_overflows
+#define timer_timereset _ntp_timer_timereset
+#define timer_xmtcalls _ntp_timer_xmtcalls
+#define total_peer_structs _ntp_total_peer_structs
+#define trunc_os_clock _ntp_trunc_os_clock
+#define unexpected_error_cnt _ntp_unexpected_error_cnt
+#define was_alarmed _ntp_was_alarmed
+#define worker_per_query _ntp_worker_per_query
+#define work_fork_nonempty_compilation_unit _ntp_work_fork_nonempty_compilation_unit
+#define xmt_leap _ntp_xmt_leap
+#define yychar _ntp_yychar
+#define yydebug _ntp_yydebug
+#define yylval _ntp_yylval
+#define yynerrs _ntp_yynerrs
+#define yytext _ntp_yytext
+#define allan_xpt _ntp_allan_xpt
+#define AM _ntp_AM
+#define authhashbuckets _ntp_authhashbuckets
+#define authhashmask _ntp_authhashmask
+#define clktypes _ntp_clktypes
+#define clock_max_back _ntp_clock_max_back
+#define clock_max_fwd _ntp_clock_max_fwd
+#define clock_minstep _ntp_clock_minstep
+#define clock_panic _ntp_clock_panic
+#define clock_phi _ntp_clock_phi
+#define cur_memlock _ntp_cur_memlock
+#define default_keysdir _ntp_default_keysdir
+#define enable_panic_check _ntp_enable_panic_check
+#define genshelloptOptions _ntp_genshelloptOptions
+#define isc_categories _ntp_isc_categories
+#define isc_interval_zero _ntp_isc_interval_zero
+#define isc_modules _ntp_isc_modules
+#define isc_time_epoch _ntp_isc_time_epoch
+#define kern_enable _ntp_kern_enable
+#define keysdir _ntp_keysdir
+#define listen_to_virtual_ips _ntp_listen_to_virtual_ips
+#define mon_age _ntp_mon_age
+#define mru_incalloc _ntp_mru_incalloc
+#define mru_initalloc _ntp_mru_initalloc
+#define mru_maxage _ntp_mru_maxage
+#define mru_maxdepth _ntp_mru_maxdepth
+#define mru_mindepth _ntp_mru_mindepth
+#define msyslog_include_timestamp _ntp_msyslog_include_timestamp
+#define msyslog_term_pid _ntp_msyslog_term_pid
+#define ntpdOptions _ntp_ntpdOptions
+#define ntp_enable _ntp_ntp_enable
+#define ntp_minpkt _ntp_ntp_minpkt
+#define ntp_minpoll _ntp_ntp_minpoll
+#define ntp_signd_socket _ntp_ntp_signd_socket
+#define ntp_syslogmask _ntp_ntp_syslogmask
+#define old_config_style _ntp_old_config_style
+#define opcmds _ntp_opcmds
+#define option_xlateable_txt _ntp_option_xlateable_txt
+#define peer_clear_digest_early _ntp_peer_clear_digest_early
+#define priority_done _ntp_priority_done
+#define qos _ntp_qos
+#define reset_entries _ntp_reset_entries
+#define sreset _ntp_sreset
+#define statsdir _ntp_statsdir
+#define sys_beacon _ntp_sys_beacon
+#define sys_ceiling _ntp_sys_ceiling
+#define syslogit _ntp_syslogit
+#define sys_maxclock _ntp_sys_maxclock
+#define sys_maxdist _ntp_sys_maxdist
+#define sys_minclock _ntp_sys_minclock
+#define sys_mindisp _ntp_sys_mindisp
+#define sys_minsane _ntp_sys_minsane
+#define sys_orphan _ntp_sys_orphan
+#define sys_orphwait _ntp_sys_orphwait
+#define unpeer_crypto_early _ntp_unpeer_crypto_early
+#define unpeer_crypto_nak_early _ntp_unpeer_crypto_nak_early
+#define unpeer_digest_early _ntp_unpeer_digest_early
+#define Version _ntp_Version
+#define wander_threshold _ntp_wander_threshold
+#define accept_wildcard_if_for_winnt _ntp_accept_wildcard_if_for_winnt
+#define ao_strs_strtable _ntp_ao_strs_strtable
+#define daynames _ntp_daynames
+#define keyword_text _ntp_keyword_text
+#define months _ntp_months
+#define option_lib_text _ntp_option_lib_text
+#define set_tod_used _ntp_set_tod_used
+#define special_chars _ntp_special_chars
+#define sst _ntp_sst
+#define add_full_recv_buffer _ntp_add_full_recv_buffer
+#define add_nic_rule _ntp_add_nic_rule
+#define addr2refid _ntp_addr2refid
+#define addto_syslog _ntp_addto_syslog
+#define addv64 _ntp_addv64
+#define addv64i32 _ntp_addv64i32
+#define addv64u32 _ntp_addv64u32
+#define add_var _ntp_add_var
+#define adj_host_clock _ntp_adj_host_clock
+#define adj_systime _ntp_adj_systime
+#define amtoa _ntp_amtoa
+#define ao_string_cook _ntp_ao_string_cook
+#define ao_string_cook_escape_char _ntp_ao_string_cook_escape_char
+#define ao_string_tokenize _ntp_ao_string_tokenize
+#define append_gen_fifo _ntp_append_gen_fifo
+#define atoint _ntp_atoint
+#define auth_agekeys _ntp_auth_agekeys
+#define authdecrypt _ntp_authdecrypt
+#define auth_delkeys _ntp_auth_delkeys
+#define authencrypt _ntp_authencrypt
+#define auth_findkey _ntp_auth_findkey
+#define auth_havekey _ntp_auth_havekey
+#define authhavekey _ntp_authhavekey
+#define authistrusted _ntp_authistrusted
+#define authistrustedip _ntp_authistrustedip
+#define auth_moremem _ntp_auth_moremem
+#define auth_prealloc_symkeys _ntp_auth_prealloc_symkeys
+#define authreadkeys _ntp_authreadkeys
+#define authtrust _ntp_authtrust
+#define available_blocking_child_slot _ntp_available_blocking_child_slot
+#define basedate_eval_buildstamp _ntp_basedate_eval_buildstamp
+#define basedate_eval_string _ntp_basedate_eval_string
+#define basedate_expand_gpsweek _ntp_basedate_expand_gpsweek
+#define basedate_get_day _ntp_basedate_get_day
+#define basedate_get_erabase _ntp_basedate_get_erabase
+#define basedate_get_eracenter _ntp_basedate_get_eracenter
+#define basedate_get_gpsweek _ntp_basedate_get_gpsweek
+#define basedate_set_day _ntp_basedate_set_day
+#define blocking_child_common _ntp_blocking_child_common
+#define blocking_getaddrinfo _ntp_blocking_getaddrinfo
+#define blocking_getnameinfo _ntp_blocking_getnameinfo
+#define blocking_thread _ntp_blocking_thread
+#define build_iflags _ntp_build_iflags
+#define build_mflags _ntp_build_mflags
+#define build_rflags _ntp_build_rflags
+#define ceventstr _ntp_ceventstr
+#define change_logfile _ntp_change_logfile
+#define check_leap_file _ntp_check_leap_file
+#define clamp_systime _ntp_clamp_systime
+#define clear_all _ntp_clear_all
+#define clock_filter _ntp_clock_filter
+#define clockname _ntp_clockname
+#define clock_select _ntp_clock_select
+#define close_all_beyond _ntp_close_all_beyond
+#define close_all_except _ntp_close_all_except
+#define concat_gen_fifos _ntp_concat_gen_fifos
+#define configFileLoad _ntp_configFileLoad
+#define config_remotely _ntp_config_remotely
+#define convertLFPToRefID _ntp_convertLFPToRefID
+#define convertRefIDToLFP _ntp_convertRefIDToLFP
+#define copy_addrinfo_common _ntp_copy_addrinfo_common
+#define copy_addrinfo_impl _ntp_copy_addrinfo_impl
+#define copy_addrinfo_list_impl _ntp_copy_addrinfo_list_impl
+#define create_address_node _ntp_create_address_node
+#define create_addr_opts_node _ntp_create_addr_opts_node
+#define create_attr_dval _ntp_create_attr_dval
+#define create_attr_ival _ntp_create_attr_ival
+#define create_attr_rangeval _ntp_create_attr_rangeval
+#define create_attr_sval _ntp_create_attr_sval
+#define create_attr_uval _ntp_create_attr_uval
+#define create_filegen_node _ntp_create_filegen_node
+#define create_int_node _ntp_create_int_node
+#define create_nic_rule_node _ntp_create_nic_rule_node
+#define create_peer_node _ntp_create_peer_node
+#define create_restrict_node _ntp_create_restrict_node
+#define create_setvar_node _ntp_create_setvar_node
+#define create_sim_node _ntp_create_sim_node
+#define create_string_node _ntp_create_string_node
+#define create_unpeer_node _ntp_create_unpeer_node
+#define ctl_clr_stats _ntp_ctl_clr_stats
+#define ctlclrtrap _ntp_ctlclrtrap
+#define ctlpeerstatus _ntp_ctlpeerstatus
+#define ctlsettrap _ntp_ctlsettrap
+#define ctlsysstatus _ntp_ctlsysstatus
+#define decodenetnum _ntp_decodenetnum
+#define destroy_address_node _ntp_destroy_address_node
+#define destroy_attr_val _ntp_destroy_attr_val
+#define destroy_gen_fifo _ntp_destroy_gen_fifo
+#define dolfptoa _ntp_dolfptoa
+#define dump_all_config_trees _ntp_dump_all_config_trees
+#define dump_config_tree _ntp_dump_config_tree
+#define dump_restricts _ntp_dump_restricts
+#define enable_broadcast _ntp_enable_broadcast
+#define enable_multicast_if _ntp_enable_multicast_if
+#define ereallocz _ntp_ereallocz
+#define errno_to_str _ntp_errno_to_str
+#define estrdup_impl _ntp_estrdup_impl
+#define eventstr _ntp_eventstr
+#define exit_worker _ntp_exit_worker
+#define filegen_config _ntp_filegen_config
+#define filegen_get _ntp_filegen_get
+#define filegen_register _ntp_filegen_register
+#define filegen_setup _ntp_filegen_setup
+#define filegen_statsdir _ntp_filegen_statsdir
+#define findbcastinter _ntp_findbcastinter
+#define FindConfig _ntp_FindConfig
+#define findexistingpeer _ntp_findexistingpeer
+#define findinterface _ntp_findinterface
+#define findmanycastpeer _ntp_findmanycastpeer
+#define find_option_value_type_cmd _ntp_find_option_value_type_cmd
+#define find_option_xat_attribute_cmd _ntp_find_option_xat_attribute_cmd
+#define findpeer _ntp_findpeer
+#define findpeerbyassoc _ntp_findpeerbyassoc
+#define freerecvbuf _ntp_freerecvbuf
+#define free_recvbuffs _ntp_free_recvbuffs
+#define free_varlist _ntp_free_varlist
+#define fstostr _ntp_fstostr
+#define full_recvbuffs _ntp_full_recvbuffs
+#define genshelloptUsage _ntp_genshelloptUsage
+#define getaddrinfo_sometime _ntp_getaddrinfo_sometime
+#define getaddrinfo_sometime_ex _ntp_getaddrinfo_sometime_ex
+#define getauthkeys _ntp_getauthkeys
+#define get_broadcastclient_flag _ntp_get_broadcastclient_flag
+#define getCmdOpts _ntp_getCmdOpts
+#define getconfig _ntp_getconfig
+#define get_ext_sys_var _ntp_get_ext_sys_var
+#define get_free_recv_buffer _ntp_get_free_recv_buffer
+#define get_full_recv_buffer _ntp_get_full_recv_buffer
+#define getinterface _ntp_getinterface
+#define getnameinfo_sometime _ntp_getnameinfo_sometime
+#define get_packet_mode _ntp_get_packet_mode
+#define get_systime _ntp_get_systime
+#define gmprettydate _ntp_gmprettydate
+#define hack_restrict _ntp_hack_restrict
+#define harvest_blocking_responses _ntp_harvest_blocking_responses
+#define has_full_recv_buffer _ntp_has_full_recv_buffer
+#define huffpuff _ntp_huffpuff
+#define humanlogtime _ntp_humanlogtime
+#define humantime _ntp_humantime
+#define icmpv64 _ntp_icmpv64
+#define init_auth _ntp_init_auth
+#define init_control _ntp_init_control
+#define init_io _ntp_init_io
+#define init_lib _ntp_init_lib
+#define init_logging _ntp_init_logging
+#define init_loopfilter _ntp_init_loopfilter
+#define init_mon _ntp_init_mon
+#define init_peer _ntp_init_peer
+#define init_proto _ntp_init_proto
+#define init_recvbuff _ntp_init_recvbuff
+#define init_request _ntp_init_request
+#define init_restrict _ntp_init_restrict
+#define init_systime _ntp_init_systime
+#define init_timer _ntp_init_timer
+#define init_util _ntp_init_util
+#define interface_enumerate _ntp_interface_enumerate
+#define interface_update _ntp_interface_update
+#define interrupt_worker_sleep _ntp_interrupt_worker_sleep
+#define intres_timeout_req _ntp_intres_timeout_req
+#define io_clr_stats _ntp_io_clr_stats
+#define io_handler _ntp_io_handler
+#define io_multicast_add _ntp_io_multicast_add
+#define io_multicast_del _ntp_io_multicast_del
+#define io_open_sockets _ntp_io_open_sockets
+#define io_setbclient _ntp_io_setbclient
+#define io_unsetbclient _ntp_io_unsetbclient
+#define isc_assertion_failed _ntp_isc_assertion_failed
+#define isc_assertion_setcallback _ntp_isc_assertion_setcallback
+#define isc_assertion_typetotext _ntp_isc_assertion_typetotext
+#define isc_dir_chdir _ntp_isc_dir_chdir
+#define isc_dir_chroot _ntp_isc_dir_chroot
+#define isc_dir_close _ntp_isc_dir_close
+#define isc_dir_createunique _ntp_isc_dir_createunique
+#define isc_dir_init _ntp_isc_dir_init
+#define isc_dir_open _ntp_isc_dir_open
+#define isc_dir_read _ntp_isc_dir_read
+#define isc_dir_reset _ntp_isc_dir_reset
+#define isc___errno2result _ntp_isc___errno2result
+#define isc_error_fatal _ntp_isc_error_fatal
+#define isc_error_runtimecheck _ntp_isc_error_runtimecheck
+#define isc_error_setfatal _ntp_isc_error_setfatal
+#define isc_error_setunexpected _ntp_isc_error_setunexpected
+#define isc_error_unexpected _ntp_isc_error_unexpected
+#define isc_file_absolutepath _ntp_isc_file_absolutepath
+#define isc_file_basename _ntp_isc_file_basename
+#define isc_file_exists _ntp_isc_file_exists
+#define isc_file_getmodtime _ntp_isc_file_getmodtime
+#define isc_file_isabsolute _ntp_isc_file_isabsolute
+#define isc_file_ischdiridempotent _ntp_isc_file_ischdiridempotent
+#define isc_file_iscurrentdir _ntp_isc_file_iscurrentdir
+#define isc_file_isplainfile _ntp_isc_file_isplainfile
+#define isc_file_mktemplate _ntp_isc_file_mktemplate
+#define isc_file_openunique _ntp_isc_file_openunique
+#define isc_file_openuniquemode _ntp_isc_file_openuniquemode
+#define isc_file_openuniqueprivate _ntp_isc_file_openuniqueprivate
+#define isc_file_progname _ntp_isc_file_progname
+#define isc_file_remove _ntp_isc_file_remove
+#define isc_file_rename _ntp_isc_file_rename
+#define isc_file_renameunique _ntp_isc_file_renameunique
+#define isc_file_safecreate _ntp_isc_file_safecreate
+#define isc_file_settime _ntp_isc_file_settime
+#define isc_file_splitpath _ntp_isc_file_splitpath
+#define isc_file_template _ntp_isc_file_template
+#define isc_file_truncate _ntp_isc_file_truncate
+#define isc_hmacsha1_init _ntp_isc_hmacsha1_init
+#define isc_hmacsha1_invalidate _ntp_isc_hmacsha1_invalidate
+#define isc_hmacsha1_sign _ntp_isc_hmacsha1_sign
+#define isc_hmacsha1_update _ntp_isc_hmacsha1_update
+#define isc_hmacsha1_verify _ntp_isc_hmacsha1_verify
+#define isc_hmacsha224_init _ntp_isc_hmacsha224_init
+#define isc_hmacsha224_invalidate _ntp_isc_hmacsha224_invalidate
+#define isc_hmacsha224_sign _ntp_isc_hmacsha224_sign
+#define isc_hmacsha224_update _ntp_isc_hmacsha224_update
+#define isc_hmacsha224_verify _ntp_isc_hmacsha224_verify
+#define isc_hmacsha256_init _ntp_isc_hmacsha256_init
+#define isc_hmacsha256_invalidate _ntp_isc_hmacsha256_invalidate
+#define isc_hmacsha256_sign _ntp_isc_hmacsha256_sign
+#define isc_hmacsha256_update _ntp_isc_hmacsha256_update
+#define isc_hmacsha256_verify _ntp_isc_hmacsha256_verify
+#define isc_hmacsha384_init _ntp_isc_hmacsha384_init
+#define isc_hmacsha384_invalidate _ntp_isc_hmacsha384_invalidate
+#define isc_hmacsha384_sign _ntp_isc_hmacsha384_sign
+#define isc_hmacsha384_update _ntp_isc_hmacsha384_update
+#define isc_hmacsha384_verify _ntp_isc_hmacsha384_verify
+#define isc_hmacsha512_init _ntp_isc_hmacsha512_init
+#define isc_hmacsha512_invalidate _ntp_isc_hmacsha512_invalidate
+#define isc_hmacsha512_sign _ntp_isc_hmacsha512_sign
+#define isc_hmacsha512_update _ntp_isc_hmacsha512_update
+#define isc_hmacsha512_verify _ntp_isc_hmacsha512_verify
+#define isc_interfaceiter_create _ntp_isc_interfaceiter_create
+#define isc_interfaceiter_current _ntp_isc_interfaceiter_current
+#define isc_interfaceiter_destroy _ntp_isc_interfaceiter_destroy
+#define isc_interfaceiter_first _ntp_isc_interfaceiter_first
+#define isc_interfaceiter_next _ntp_isc_interfaceiter_next
+#define isc_interval_iszero _ntp_isc_interval_iszero
+#define isc_interval_set _ntp_isc_interval_set
+#define isc_iterated_hash _ntp_isc_iterated_hash
+#define isc_lib_initmsgcat _ntp_isc_lib_initmsgcat
+#define isc_log_categorybyname _ntp_isc_log_categorybyname
+#define isc_log_closefilelogs _ntp_isc_log_closefilelogs
+#define isc_logconfig_create _ntp_isc_logconfig_create
+#define isc_logconfig_destroy _ntp_isc_logconfig_destroy
+#define isc_logconfig_get _ntp_isc_logconfig_get
+#define isc_logconfig_use _ntp_isc_logconfig_use
+#define isc_log_create _ntp_isc_log_create
+#define isc_log_createchannel _ntp_isc_log_createchannel
+#define isc_log_destroy _ntp_isc_log_destroy
+#define isc_log_getdebuglevel _ntp_isc_log_getdebuglevel
+#define isc_log_getduplicateinterval _ntp_isc_log_getduplicateinterval
+#define isc_log_gettag _ntp_isc_log_gettag
+#define isc_log_ivwrite _ntp_isc_log_ivwrite
+#define isc_log_ivwrite1 _ntp_isc_log_ivwrite1
+#define isc_log_iwrite _ntp_isc_log_iwrite
+#define isc_log_iwrite1 _ntp_isc_log_iwrite1
+#define isc_log_modulebyname _ntp_isc_log_modulebyname
+#define isc_log_opensyslog _ntp_isc_log_opensyslog
+#define isc_log_registercategories _ntp_isc_log_registercategories
+#define isc_log_registermodules _ntp_isc_log_registermodules
+#define isc_log_setcontext _ntp_isc_log_setcontext
+#define isc_log_setdebuglevel _ntp_isc_log_setdebuglevel
+#define isc_log_setduplicateinterval _ntp_isc_log_setduplicateinterval
+#define isc_log_settag _ntp_isc_log_settag
+#define isc_log_usechannel _ntp_isc_log_usechannel
+#define isc_log_vwrite _ntp_isc_log_vwrite
+#define isc_log_vwrite1 _ntp_isc_log_vwrite1
+#define isc_log_wouldlog _ntp_isc_log_wouldlog
+#define isc_log_write _ntp_isc_log_write
+#define isc_log_write1 _ntp_isc_log_write1
+#define isc_msgcat_close _ntp_isc_msgcat_close
+#define isc_msgcat_get _ntp_isc_msgcat_get
+#define isc_msgcat_open _ntp_isc_msgcat_open
+#define isc__mutex_init _ntp_isc__mutex_init
+#define isc_netaddr_any _ntp_isc_netaddr_any
+#define isc_netaddr_any6 _ntp_isc_netaddr_any6
+#define isc_netaddr_eqprefix _ntp_isc_netaddr_eqprefix
+#define isc_netaddr_equal _ntp_isc_netaddr_equal
+#define isc_netaddr_format _ntp_isc_netaddr_format
+#define isc_netaddr_fromin _ntp_isc_netaddr_fromin
+#define isc_netaddr_fromin6 _ntp_isc_netaddr_fromin6
+#define isc_netaddr_frompath _ntp_isc_netaddr_frompath
+#define isc_netaddr_fromsockaddr _ntp_isc_netaddr_fromsockaddr
+#define isc_netaddr_fromv4mapped _ntp_isc_netaddr_fromv4mapped
+#define isc_netaddr_getzone _ntp_isc_netaddr_getzone
+#define isc_netaddr_isexperimental _ntp_isc_netaddr_isexperimental
+#define isc_netaddr_islinklocal _ntp_isc_netaddr_islinklocal
+#define isc_netaddr_ismulticast _ntp_isc_netaddr_ismulticast
+#define isc_netaddr_issitelocal _ntp_isc_netaddr_issitelocal
+#define isc_netaddr_masktoprefixlen _ntp_isc_netaddr_masktoprefixlen
+#define isc_netaddr_prefixok _ntp_isc_netaddr_prefixok
+#define isc_netaddr_setzone _ntp_isc_netaddr_setzone
+#define isc_netaddr_totext _ntp_isc_netaddr_totext
+#define isc_net_disableipv4 _ntp_isc_net_disableipv4
+#define isc_net_disableipv6 _ntp_isc_net_disableipv6
+#define isc_net_enableipv4 _ntp_isc_net_enableipv4
+#define isc_net_enableipv6 _ntp_isc_net_enableipv6
+#define isc_net_getudpportrange _ntp_isc_net_getudpportrange
+#define isc_net_probeipv4 _ntp_isc_net_probeipv4
+#define isc_net_probeipv6 _ntp_isc_net_probeipv6
+#define isc_net_probe_ipv6only _ntp_isc_net_probe_ipv6only
+#define isc_net_probe_ipv6pktinfo _ntp_isc_net_probe_ipv6pktinfo
+#define isc_net_probeunix _ntp_isc_net_probeunix
+#define isc_result_register _ntp_isc_result_register
+#define isc_result_totext _ntp_isc_result_totext
+#define isc_sha1_final _ntp_isc_sha1_final
+#define isc_sha1_init _ntp_isc_sha1_init
+#define isc_sha1_invalidate _ntp_isc_sha1_invalidate
+#define isc_sha1_update _ntp_isc_sha1_update
+#define isc_sockaddr_any _ntp_isc_sockaddr_any
+#define isc_sockaddr_any6 _ntp_isc_sockaddr_any6
+#define isc_sockaddr_anyofpf _ntp_isc_sockaddr_anyofpf
+#define isc_sockaddr_compare _ntp_isc_sockaddr_compare
+#define isc_sockaddr_eqaddr _ntp_isc_sockaddr_eqaddr
+#define isc_sockaddr_eqaddrprefix _ntp_isc_sockaddr_eqaddrprefix
+#define isc_sockaddr_equal _ntp_isc_sockaddr_equal
+#define isc_sockaddr_format _ntp_isc_sockaddr_format
+#define isc_sockaddr_fromin _ntp_isc_sockaddr_fromin
+#define isc_sockaddr_fromin6 _ntp_isc_sockaddr_fromin6
+#define isc_sockaddr_fromnetaddr _ntp_isc_sockaddr_fromnetaddr
+#define isc_sockaddr_frompath _ntp_isc_sockaddr_frompath
+#define isc_sockaddr_getport _ntp_isc_sockaddr_getport
+#define isc_sockaddr_hash _ntp_isc_sockaddr_hash
+#define isc_sockaddr_isexperimental _ntp_isc_sockaddr_isexperimental
+#define isc_sockaddr_islinklocal _ntp_isc_sockaddr_islinklocal
+#define isc_sockaddr_ismulticast _ntp_isc_sockaddr_ismulticast
+#define isc_sockaddr_issitelocal _ntp_isc_sockaddr_issitelocal
+#define isc_sockaddr_pf _ntp_isc_sockaddr_pf
+#define isc_sockaddr_setport _ntp_isc_sockaddr_setport
+#define isc_sockaddr_totext _ntp_isc_sockaddr_totext
+#define isc_sockaddr_v6fromin _ntp_isc_sockaddr_v6fromin
+#define isc_stdio_close _ntp_isc_stdio_close
+#define isc_stdio_flush _ntp_isc_stdio_flush
+#define isc_stdio_open _ntp_isc_stdio_open
+#define isc_stdio_read _ntp_isc_stdio_read
+#define isc_stdio_seek _ntp_isc_stdio_seek
+#define isc_stdio_sync _ntp_isc_stdio_sync
+#define isc_stdio_write _ntp_isc_stdio_write
+#define isc__strerror _ntp_isc__strerror
+#define isc_time_add _ntp_isc_time_add
+#define isc_time_compare _ntp_isc_time_compare
+#define isc_time_formathttptimestamp _ntp_isc_time_formathttptimestamp
+#define isc_time_formatISO8601 _ntp_isc_time_formatISO8601
+#define isc_time_formattimestamp _ntp_isc_time_formattimestamp
+#define isc_time_isepoch _ntp_isc_time_isepoch
+#define isc_time_microdiff _ntp_isc_time_microdiff
+#define isc_time_nanoseconds _ntp_isc_time_nanoseconds
+#define isc_time_now _ntp_isc_time_now
+#define isc_time_nowplusinterval _ntp_isc_time_nowplusinterval
+#define isc_time_seconds _ntp_isc_time_seconds
+#define isc_time_secondsastimet _ntp_isc_time_secondsastimet
+#define isc_time_set _ntp_isc_time_set
+#define isc_time_settoepoch _ntp_isc_time_settoepoch
+#define isc_time_subtract _ntp_isc_time_subtract
+#define isc_tsmemcmp _ntp_isc_tsmemcmp
+#define is_ip_address _ntp_is_ip_address
+#define isocal_date_to_ntp _ntp_isocal_date_to_ntp
+#define isocal_date_to_ntp64 _ntp_isocal_date_to_ntp64
+#define isocal_ntp64_to_date _ntp_isocal_ntp64_to_date
+#define isocal_ntp_to_date _ntp_isocal_ntp_to_date
+#define isocal_split_eraweeks _ntp_isocal_split_eraweeks
+#define isocal_weeks_in_years _ntp_isocal_weeks_in_years
+#define is_safe_filename _ntp_is_safe_filename
+#define keyacc_all_free _ntp_keyacc_all_free
+#define keyacc_amatch _ntp_keyacc_amatch
+#define keyacc_contains _ntp_keyacc_contains
+#define keyacc_new_push _ntp_keyacc_new_push
+#define keyacc_pop_free _ntp_keyacc_pop_free
+#define keyword _ntp_keyword
+#define kill_asyncio _ntp_kill_asyncio
+#define kiss_code_check _ntp_kiss_code_check
+#define k_st_flags _ntp_k_st_flags
+#define leapsec_add_dyn _ntp_leapsec_add_dyn
+#define leapsec_autokey_tai _ntp_leapsec_autokey_tai
+#define leapsec_clear _ntp_leapsec_clear
+#define leapsec_daystolive _ntp_leapsec_daystolive
+#define leapsec_dump _ntp_leapsec_dump
+#define leapsec_electric _ntp_leapsec_electric
+#define leapsec_expired _ntp_leapsec_expired
+#define leapsec_frame _ntp_leapsec_frame
+#define leapsec_getsig _ntp_leapsec_getsig
+#define leapsec_get_table _ntp_leapsec_get_table
+#define leapsec_load _ntp_leapsec_load
+#define leapsec_load_file _ntp_leapsec_load_file
+#define leapsec_load_stream _ntp_leapsec_load_stream
+#define leapsec_query _ntp_leapsec_query
+#define leapsec_query_era _ntp_leapsec_query_era
+#define leapsec_reset_frame _ntp_leapsec_reset_frame
+#define leapsec_set_table _ntp_leapsec_set_table
+#define leapsec_ut_pristine _ntp_leapsec_ut_pristine
+#define leapsec_validate _ntp_leapsec_validate
+#define lex_current _ntp_lex_current
+#define lex_drop_stack _ntp_lex_drop_stack
+#define lex_flush_stack _ntp_lex_flush_stack
+#define lex_from_file _ntp_lex_from_file
+#define lex_init_stack _ntp_lex_init_stack
+#define lex_level _ntp_lex_level
+#define lex_pop_file _ntp_lex_pop_file
+#define lex_push_file _ntp_lex_push_file
+#define localaddrtoa _ntp_localaddrtoa
+#define local_clock _ntp_local_clock
+#define loop_config _ntp_loop_config
+#define lowater_additions _ntp_lowater_additions
+#define maintain_activefds _ntp_maintain_activefds
+#define make_socket_nonblocking _ntp_make_socket_nonblocking
+#define MD5authdecrypt _ntp_MD5authdecrypt
+#define MD5authencrypt _ntp_MD5authencrypt
+#define MD5auth_setkey _ntp_MD5auth_setkey
+#define mfprintf _ntp_mfprintf
+#define mfptoa _ntp_mfptoa
+#define mfptoms _ntp_mfptoms
+#define modetoa _ntp_modetoa
+#define mon_clearinterface _ntp_mon_clearinterface
+#define mon_start _ntp_mon_start
+#define mon_stop _ntp_mon_stop
+#define move_fd _ntp_move_fd
+#define mprintf _ntp_mprintf
+#define mprintf_clock_stats _ntp_mprintf_clock_stats
+#define mprintf_event _ntp_mprintf_event
+#define msnprintf _ntp_msnprintf
+#define msyslog _ntp_msyslog
+#define mvfprintf _ntp_mvfprintf
+#define mvsnprintf _ntp_mvsnprintf
+#define mvsyslog _ntp_mvsyslog
+#define netof _ntp_netof
+#define newpeer _ntp_newpeer
+#define ntp2unix_tm _ntp_ntp2unix_tm
+#define ntpcal_date_to_daysec _ntp_ntpcal_date_to_daysec
+#define ntpcal_date_to_ntp _ntp_ntpcal_date_to_ntp
+#define ntpcal_date_to_ntp64 _ntp_ntpcal_date_to_ntp64
+#define ntpcal_date_to_rd _ntp_ntpcal_date_to_rd
+#define ntpcal_date_to_time _ntp_ntpcal_date_to_time
+#define ntpcal_dayjoin _ntp_ntpcal_dayjoin
+#define ntpcal_daysec_to_date _ntp_ntpcal_daysec_to_date
+#define ntpcal_daysec_to_tm _ntp_ntpcal_daysec_to_tm
+#define ntpcal_days_in_months _ntp_ntpcal_days_in_months
+#define ntpcal_days_in_years _ntp_ntpcal_days_in_years
+#define ntpcal_daysplit _ntp_ntpcal_daysplit
+#define ntpcal_daysplit_to_date _ntp_ntpcal_daysplit_to_date
+#define ntpcal_daysplit_to_tm _ntp_ntpcal_daysplit_to_tm
+#define ntpcal_edate_to_eradays _ntp_ntpcal_edate_to_eradays
+#define ntpcal_edate_to_yeardays _ntp_ntpcal_edate_to_yeardays
+#define ntpcal_etime_to_seconds _ntp_ntpcal_etime_to_seconds
+#define ntpcal_get_build_date _ntp_ntpcal_get_build_date
+#define ntpcal_leapyears_in_years _ntp_ntpcal_leapyears_in_years
+#define ntpcal_ntp64_to_date _ntp_ntpcal_ntp64_to_date
+#define ntpcal_ntp_to_date _ntp_ntpcal_ntp_to_date
+#define ntpcal_ntp_to_ntp _ntp_ntpcal_ntp_to_ntp
+#define ntpcal_ntp_to_time _ntp_ntpcal_ntp_to_time
+#define ntpcal_periodic_extend _ntp_ntpcal_periodic_extend
+#define ntpcal_rd_to_date _ntp_ntpcal_rd_to_date
+#define ntpcal_rd_to_mstart _ntp_ntpcal_rd_to_mstart
+#define ntpcal_rd_to_tm _ntp_ntpcal_rd_to_tm
+#define ntpcal_rd_to_ystart _ntp_ntpcal_rd_to_ystart
+#define ntpcal_set_timefunc _ntp_ntpcal_set_timefunc
+#define ntpcal_split_eradays _ntp_ntpcal_split_eradays
+#define ntpcal_split_yeardays _ntp_ntpcal_split_yeardays
+#define ntpcal_time_to_date _ntp_ntpcal_time_to_date
+#define ntpcal_tm_to_daysec _ntp_ntpcal_tm_to_daysec
+#define ntpcal_tm_to_rd _ntp_ntpcal_tm_to_rd
+#define ntpcal_weekday_close _ntp_ntpcal_weekday_close
+#define ntpcal_weekday_ge _ntp_ntpcal_weekday_ge
+#define ntpcal_weekday_gt _ntp_ntpcal_weekday_gt
+#define ntpcal_weekday_le _ntp_ntpcal_weekday_le
+#define ntpcal_weekday_lt _ntp_ntpcal_weekday_lt
+#define ntpcal_year_to_ystart _ntp_ntpcal_year_to_ystart
+#define ntpd_time_stepped _ntp_ntpd_time_stepped
+#define ntp_monitor _ntp_ntp_monitor
+#define ntpOptionPrintVersion _ntp_ntpOptionPrintVersion
+#define ntpOptionProcess _ntp_ntpOptionProcess
+#define ntp_random _ntp_ntp_random
+#define ntp_set_tod _ntp_ntp_set_tod
+#define ntp_srandom _ntp_ntp_srandom
+#define numtoa _ntp_numtoa
+#define optionAlias _ntp_optionAlias
+#define optionBooleanVal _ntp_optionBooleanVal
+#define optionEnumerationVal _ntp_optionEnumerationVal
+#define optionFileCheck _ntp_optionFileCheck
+#define optionFileLoad _ntp_optionFileLoad
+#define optionFindNextValue _ntp_optionFindNextValue
+#define optionFindValue _ntp_optionFindValue
+#define optionFree _ntp_optionFree
+#define optionGetValue _ntp_optionGetValue
+#define optionKeywordName _ntp_optionKeywordName
+#define optionLoadLine _ntp_optionLoadLine
+#define optionLoadOpt _ntp_optionLoadOpt
+#define optionMakePath _ntp_optionMakePath
+#define optionMemberList _ntp_optionMemberList
+#define optionNestedVal _ntp_optionNestedVal
+#define optionNextValue _ntp_optionNextValue
+#define optionNumericVal _ntp_optionNumericVal
+#define optionOnlyUsage _ntp_optionOnlyUsage
+#define optionPagedUsage _ntp_optionPagedUsage
+#define option_parse_duration _ntp_option_parse_duration
+#define optionParseShell _ntp_optionParseShell
+#define optionPrintParagraphs _ntp_optionPrintParagraphs
+#define optionPrintVersion _ntp_optionPrintVersion
+#define optionPrintVersionAndReturn _ntp_optionPrintVersionAndReturn
+#define optionProcess _ntp_optionProcess
+#define optionPutShell _ntp_optionPutShell
+#define optionQuoteString _ntp_optionQuoteString
+#define optionResetOpt _ntp_optionResetOpt
+#define optionRestore _ntp_optionRestore
+#define optionSaveFile _ntp_optionSaveFile
+#define optionSaveState _ntp_optionSaveState
+#define optionSetMembers _ntp_optionSetMembers
+#define optionShowRange _ntp_optionShowRange
+#define optionStackArg _ntp_optionStackArg
+#define option_strequate _ntp_option_strequate
+#define option_streqvcmp _ntp_option_streqvcmp
+#define option_streqvmap _ntp_option_streqvmap
+#define option_strneqvcmp _ntp_option_strneqvcmp
+#define option_strtransform _ntp_option_strtransform
+#define optionTimeDate _ntp_optionTimeDate
+#define optionTimeVal _ntp_optionTimeVal
+#define optionUnloadNested _ntp_optionUnloadNested
+#define optionUnstackArg _ntp_optionUnstackArg
+#define optionUsage _ntp_optionUsage
+#define optionVendorOption _ntp_optionVendorOption
+#define optionVersion _ntp_optionVersion
+#define optionVersionStderr _ntp_optionVersionStderr
+#define oreallocarrayxz _ntp_oreallocarrayxz
+#define parse_cmdline_opts _ntp_parse_cmdline_opts
+#define peer_all_reset _ntp_peer_all_reset
+#define peer_cleanup _ntp_peer_cleanup
+#define peer_clear _ntp_peer_clear
+#define peer_clr_stats _ntp_peer_clr_stats
+#define peer_config _ntp_peer_config
+#define peer_reset _ntp_peer_reset
+#define pipe_socketpair _ntp_pipe_socketpair
+#define poll_update _ntp_poll_update
+#define pool_name_resolved _ntp_pool_name_resolved
+#define prettydate _ntp_prettydate
+#define process_blocking_resp _ntp_process_blocking_resp
+#define process_control _ntp_process_control
+#define process_packet _ntp_process_packet
+#define process_private _ntp_process_private
+#define proto_clr_stats _ntp_proto_clr_stats
+#define proto_config _ntp_proto_config
+#define purge_recv_buffers_for_fd _ntp_purge_recv_buffers_for_fd
+#define queue_blocking_request _ntp_queue_blocking_request
+#define queue_blocking_response _ntp_queue_blocking_response
+#define quote_if_needed _ntp_quote_if_needed
+#define receive _ntp_receive
+#define receive_blocking_req_internal _ntp_receive_blocking_req_internal
+#define receive_blocking_resp_internal _ntp_receive_blocking_resp_internal
+#define record_clock_stats _ntp_record_clock_stats
+#define record_loop_stats _ntp_record_loop_stats
+#define record_peer_stats _ntp_record_peer_stats
+#define record_proto_stats _ntp_record_proto_stats
+#define record_raw_stats _ntp_record_raw_stats
+#define refid_str _ntp_refid_str
+#define refnumtoa _ntp_refnumtoa
+#define refresh_all_peerinterfaces _ntp_refresh_all_peerinterfaces
+#define reinit_timer _ntp_reinit_timer
+#define remoteconfig_cmdlength _ntp_remoteconfig_cmdlength
+#define report_event _ntp_report_event
+#define req_child_exit _ntp_req_child_exit
+#define rereadkeys _ntp_rereadkeys
+#define res_access_flags _ntp_res_access_flags
+#define reset_auth_stats _ntp_reset_auth_stats
+#define res_match_flags _ntp_res_match_flags
+#define restrictions _ntp_restrictions
+#define restrict_source _ntp_restrict_source
+#define sau_from_netaddr _ntp_sau_from_netaddr
+#define score_all _ntp_score_all
+#define select_loop _ntp_select_loop
+#define select_peerinterface _ntp_select_peerinterface
+#define send_blocking_req_internal _ntp_send_blocking_req_internal
+#define send_blocking_resp_internal _ntp_send_blocking_resp_internal
+#define sendpkt _ntp_sendpkt
+#define send_via_ntp_signd _ntp_send_via_ntp_signd
+#define set_peerdstadr _ntp_set_peerdstadr
+#define set_sys_fuzz _ntp_set_sys_fuzz
+#define set_sys_leap _ntp_set_sys_leap
+#define set_sys_tick_precision _ntp_set_sys_tick_precision
+#define set_sys_var _ntp_set_sys_var
+#define set_timer_or_die _ntp_set_timer_or_die
+#define setup_logfile _ntp_setup_logfile
+#define set_var _ntp_set_var
+#define sockaddr_masktoprefixlen _ntp_sockaddr_masktoprefixlen
+#define sock_hash _ntp_sock_hash
+#define sockporttoa _ntp_sockporttoa
+#define socktoa _ntp_socktoa
+#define stats_config _ntp_stats_config
+#define statustoa _ntp_statustoa
+#define step_systime _ntp_step_systime
+#define strtouv64 _ntp_strtouv64
+#define subv64 _ntp_subv64
+#define subv64i32 _ntp_subv64i32
+#define subv64u32 _ntp_subv64u32
+#define text_mmap _ntp_text_mmap
+#define text_munmap _ntp_text_munmap
+#define timer _ntp_timer
+#define timer_clr_stats _ntp_timer_clr_stats
+#define timer_interfacetimeout _ntp_timer_interfacetimeout
+#define time_to_vint64 _ntp_time_to_vint64
+#define token_name _ntp_token_name
+#define total_recvbuffs _ntp_total_recvbuffs
+#define transmit _ntp_transmit
+#define ucmpv64 _ntp_ucmpv64
+#define unpeer _ntp_unpeer
+#define valid_NAK _ntp_valid_NAK
+#define vint64_to_time _ntp_vint64_to_time
+#define worker_global_lock _ntp_worker_global_lock
+#define worker_idle_timer_fired _ntp_worker_idle_timer_fired
+#define worker_sleep _ntp_worker_sleep
+#define write_stats _ntp_write_stats
+#define xsbprintf _ntp_xsbprintf
+#define xvsbprintf _ntp_xvsbprintf
+#define yyerror _ntp_yyerror
+#define yylex _ntp_yylex
+#define yyparse _ntp_yyparse
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntp.h b/sebhbsd/freebsd/contrib/ntp/include/ntp.h
new file mode 100644
index 0000000..cfbb7d2
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntp.h
@@ -0,0 +1,944 @@
+/*
+ * ntp.h - NTP definitions for the masses
+ */
+#ifndef NTP_H
+#define NTP_H
+
+#include <stddef.h>
+#include <math.h>
+
+#include <ntp_fp.h>
+#include <ntp_types.h>
+#include <ntp_lists.h>
+#include <ntp_stdlib.h>
+#include <ntp_crypto.h>
+#include <ntp_random.h>
+#include <ntp_net.h>
+
+#include <isc/boolean.h>
+
+/*
+ * Calendar arithmetic - contributed by G. Healton
+ */
+#define YEAR_BREAK 500 /* years < this are tm_year values:
+ * Break < AnyFourDigitYear && Break >
+ * Anytm_yearYear */
+
+#define YEAR_PIVOT 98 /* 97/98: years < this are year 2000+
+ * FYI: official UNIX pivot year is
+ * 68/69 */
+
+/*
+ * Number of Days since 1 BC Gregorian to 1 January of given year
+ */
+#define julian0(year) (((year) * 365 ) + ((year) > 0 ? (((year) + 3) \
+ / 4 - ((year - 1) / 100) + ((year - 1) / \
+ 400)) : 0))
+
+/*
+ * Number of days since start of NTP time to 1 January of given year
+ */
+#define ntp0(year) (julian0(year) - julian0(1900))
+
+/*
+ * Number of days since start of UNIX time to 1 January of given year
+ */
+#define unix0(year) (julian0(year) - julian0(1970))
+
+/*
+ * LEAP YEAR test for full 4-digit years (e.g, 1999, 2010)
+ */
+#define isleap_4(y) ((y) % 4 == 0 && !((y) % 100 == 0 && !(y % \
+ 400 == 0)))
+
+/*
+ * LEAP YEAR test for tm_year (struct tm) years (e.g, 99, 110)
+ */
+#define isleap_tm(y) ((y) % 4 == 0 && !((y) % 100 == 0 && !(((y) \
+ + 1900) % 400 == 0)))
+
+/*
+ * to convert simple two-digit years to tm_year style years:
+ *
+ * if (year < YEAR_PIVOT)
+ * year += 100;
+ *
+ * to convert either two-digit OR tm_year years to four-digit years:
+ *
+ * if (year < YEAR_PIVOT)
+ * year += 100;
+ *
+ * if (year < YEAR_BREAK)
+ * year += 1900;
+ */
+
+/*
+ * How to get signed characters. On machines where signed char works,
+ * use it. On machines where signed char doesn't work, char had better
+ * be signed.
+ */
+#ifdef NEED_S_CHAR_TYPEDEF
+# if SIZEOF_SIGNED_CHAR
+typedef signed char s_char;
+# else
+typedef char s_char;
+# endif
+ /* XXX: Why is this sequent bit INSIDE this test? */
+# ifdef sequent
+# undef SO_RCVBUF
+# undef SO_SNDBUF
+# endif
+#endif
+
+/*
+ * NTP protocol parameters. See section 3.2.6 of the specification.
+ */
+#define NTP_VERSION ((u_char)4) /* current version number */
+#define NTP_OLDVERSION ((u_char)1) /* oldest credible version */
+#define NTP_PORT 123 /* included for non-unix machines */
+
+/*
+ * Poll interval parameters
+ */
+#define NTP_UNREACH 10 /* poll unreach threshold */
+#define NTP_MINPOLL 3 /* log2 min poll interval (8 s) */
+#define NTP_MINDPOLL 6 /* log2 default min poll (64 s) */
+#define NTP_MAXDPOLL 10 /* log2 default max poll (~17 m) */
+#define NTP_MAXPOLL 17 /* log2 max poll interval (~36 h) */
+#define NTP_RETRY 3 /* max packet retries */
+#define NTP_MINPKT 2 /* guard time (s) */
+
+/*
+ * Clock filter algorithm tuning parameters
+ */
+#define MAXDISPERSE 16. /* max dispersion */
+#define NTP_SHIFT 8 /* clock filter stages */
+#define NTP_FWEIGHT .5 /* clock filter weight */
+
+/*
+ * Selection algorithm tuning parameters
+ */
+#define NTP_MINCLOCK 3 /* min survivors */
+#define NTP_MAXCLOCK 10 /* max candidates */
+#define MINDISPERSE .001 /* min distance */
+#define MAXDISTANCE 1.5 /* max root distance (select threshold) */
+#define CLOCK_SGATE 3. /* popcorn spike gate */
+#define HUFFPUFF 900 /* huff-n'-puff sample interval (s) */
+#define MAXHOP 2 /* anti-clockhop threshold */
+#define MAX_TTL 8 /* max ttl mapping vector size */
+#define BEACON 7200 /* manycast beacon interval */
+#define NTP_MAXEXTEN 2048 /* max extension field size */
+#define NTP_ORPHWAIT 300 /* orphan wair (s) */
+
+/*
+ * Miscellaneous stuff
+ */
+#define NTP_MAXKEY 65535 /* max authentication key number */
+#define KEY_TYPE_MD5 NID_md5 /* MD5 digest NID */
+/*
+ * Limits of things
+ */
+#define MAXFILENAME 256 /* max length of file name */
+#define MAXHOSTNAME 512 /* max length of host/node name */
+#define NTP_MAXSTRLEN 256 /* max string length */
+
+/*
+ * Operations for jitter calculations (these use doubles).
+ *
+ * Note that we carefully separate the jitter component from the
+ * dispersion component (frequency error plus precision). The frequency
+ * error component is computed as CLOCK_PHI times the difference between
+ * the epoch of the time measurement and the reference time. The
+ * precision component is computed as the square root of the mean of the
+ * squares of a zero-mean, uniform distribution of unit maximum
+ * amplitude. Whether this makes statistical sense may be arguable.
+ */
+#define SQUARE(x) ((x) * (x))
+#define SQRT(x) (sqrt(x))
+#define DIFF(x, y) (SQUARE((x) - (y)))
+#define LOGTOD(a) ldexp(1., (int)(a)) /* log2 to double */
+#define UNIVAR(x) (SQUARE(.28867513 * LOGTOD(x))) /* std uniform distr */
+#define ULOGTOD(a) ldexp(1., (int)(a)) /* ulog2 to double */
+
+#define EVENT_TIMEOUT 0 /* one second, that is */
+
+
+/*
+ * The interface structure is used to hold the addresses and socket
+ * numbers of each of the local network addresses we are using.
+ * Because "interface" is a reserved word in C++ and has so many
+ * varied meanings, a change to "endpt" (via typedef) is under way.
+ * Eventually the struct tag will change from interface to endpt_tag.
+ * endpt is unrelated to the select algorithm's struct endpoint.
+ */
+typedef struct interface endpt;
+struct interface {
+ endpt * elink; /* endpt list link */
+ endpt * mclink; /* per-AF_* multicast list */
+ void * ioreg_ctx; /* IO registration context */
+ SOCKET fd; /* socket descriptor */
+ SOCKET bfd; /* for receiving broadcasts */
+ u_int32 ifnum; /* endpt instance count */
+ sockaddr_u sin; /* unicast address */
+ sockaddr_u mask; /* subnet mask */
+ sockaddr_u bcast; /* broadcast address */
+ char name[32]; /* name of interface */
+ u_short family; /* AF_INET/AF_INET6 */
+ u_short phase; /* phase in update cycle */
+ u_int32 flags; /* interface flags */
+ int last_ttl; /* last TTL specified */
+ u_int32 addr_refid; /* IPv4 addr or IPv6 hash */
+ int num_mcast; /* mcast addrs enabled */
+ u_long starttime; /* current_time at creation */
+ volatile long received; /* number of incoming packets */
+ long sent; /* number of outgoing packets */
+ long notsent; /* number of send failures */
+ u_int ifindex; /* for IPV6_MULTICAST_IF */
+ isc_boolean_t ignore_packets; /* listen-read-drop this? */
+ struct peer * peers; /* list of peers using endpt */
+ u_int peercnt; /* count of same */
+};
+
+/*
+ * Flags for interfaces
+ */
+#define INT_UP 0x001 /* Interface is up */
+#define INT_PPP 0x002 /* Point-to-point interface */
+#define INT_LOOPBACK 0x004 /* the loopback interface */
+#define INT_BROADCAST 0x008 /* can broadcast out this interface */
+#define INT_MULTICAST 0x010 /* can multicast out this interface */
+#define INT_BCASTOPEN 0x020 /* broadcast receive socket is open */
+#define INT_MCASTOPEN 0x040 /* multicasting enabled */
+#define INT_WILDCARD 0x080 /* wildcard interface - usually skipped */
+#define INT_MCASTIF 0x100 /* bound directly to MCAST address */
+#define INT_PRIVACY 0x200 /* RFC 4941 IPv6 privacy address */
+#define INT_BCASTXMIT 0x400 /* socket setup to allow broadcasts */
+
+/*
+ * Define flasher bits (tests 1 through 11 in packet procedure)
+ * These reveal the state at the last grumble from the peer and are
+ * most handy for diagnosing problems, even if not strictly a state
+ * variable in the spec. These are recorded in the peer structure.
+ *
+ * Packet errors
+ */
+#define TEST1 0X0001 /* duplicate packet */
+#define TEST2 0x0002 /* bogus packet */
+#define TEST3 0x0004 /* protocol unsynchronized */
+#define TEST4 0x0008 /* access denied */
+#define TEST5 0x0010 /* bad authentication */
+#define TEST6 0x0020 /* bad synch or stratum */
+#define TEST7 0x0040 /* bad header */
+#define TEST8 0x0080 /* bad autokey */
+#define TEST9 0x0100 /* bad crypto */
+#define PKT_TEST_MASK (TEST1 | TEST2 | TEST3 | TEST4 | TEST5 |\
+ TEST6 | TEST7 | TEST8 | TEST9)
+/*
+ * Peer errors
+ */
+#define TEST10 0x0200 /* peer bad synch or stratum */
+#define TEST11 0x0400 /* peer distance exceeded */
+#define TEST12 0x0800 /* peer synchronization loop */
+#define TEST13 0x1000 /* peer unreacable */
+#define PEER_TEST_MASK (TEST10 | TEST11 | TEST12 | TEST13)
+
+/*
+ * Unused flags
+ */
+#define TEST14 0x2000
+#define TEST15 0x4000
+#define TEST16 0x8000
+
+/*
+ * The peer structure. Holds state information relating to the guys
+ * we are peering with. Most of this stuff is from section 3.2 of the
+ * spec.
+ */
+struct peer {
+ struct peer *p_link; /* link pointer in free & peer lists */
+ struct peer *adr_link; /* link pointer in address hash */
+ struct peer *aid_link; /* link pointer in associd hash */
+ struct peer *ilink; /* list of peers for interface */
+ sockaddr_u srcadr; /* address of remote host */
+ char * hostname; /* if non-NULL, remote name */
+ struct addrinfo *addrs; /* hostname query result */
+ struct addrinfo *ai; /* position within addrs */
+ endpt * dstadr; /* local address */
+ associd_t associd; /* association ID */
+ u_char version; /* version number */
+ u_char hmode; /* local association mode */
+ u_char hpoll; /* local poll interval */
+ u_char minpoll; /* min poll interval */
+ u_char maxpoll; /* max poll interval */
+ u_int flags; /* association flags */
+ u_char cast_flags; /* additional flags */
+ u_char last_event; /* last peer error code */
+ u_char num_events; /* number of error events */
+ u_int32 ttl; /* ttl/refclock mode */
+ char *ident; /* group identifier name */
+
+ /*
+ * Variables used by reference clock support
+ */
+#ifdef REFCLOCK
+ struct refclockproc *procptr; /* refclock structure pointer */
+ u_char refclktype; /* reference clock type */
+ u_char refclkunit; /* reference clock unit number */
+ u_char sstclktype; /* clock type for system status word */
+#endif /* REFCLOCK */
+
+ /*
+ * Variables set by received packet
+ */
+ u_char leap; /* local leap indicator */
+ u_char pmode; /* remote association mode */
+ u_char stratum; /* remote stratum */
+ u_char ppoll; /* remote poll interval */
+ s_char precision; /* remote clock precision */
+ double rootdelay; /* roundtrip delay to primary source */
+ double rootdisp; /* dispersion to primary source */
+ u_int32 refid; /* remote reference ID */
+ l_fp reftime; /* update epoch */
+
+ /*
+ * Variables used by authenticated client
+ */
+ keyid_t keyid; /* current key ID */
+#ifdef AUTOKEY
+#define clear_to_zero opcode
+ u_int32 opcode; /* last request opcode */
+ associd_t assoc; /* peer association ID */
+ u_int32 crypto; /* peer status word */
+ EVP_PKEY *pkey; /* public key */
+ const EVP_MD *digest; /* message digest algorithm */
+ char *subject; /* certificate subject name */
+ char *issuer; /* certificate issuer name */
+ struct cert_info *xinfo; /* issuer certificate */
+ keyid_t pkeyid; /* previous key ID */
+ keyid_t hcookie; /* host cookie */
+ keyid_t pcookie; /* peer cookie */
+ const struct pkey_info *ident_pkey; /* identity key */
+ BIGNUM *iffval; /* identity challenge (IFF, GQ, MV) */
+ const BIGNUM *grpkey; /* identity challenge key (GQ) */
+ struct value cookval; /* receive cookie values */
+ struct value recval; /* receive autokey values */
+ struct exten *cmmd; /* extension pointer */
+ u_long refresh; /* next refresh epoch */
+
+ /*
+ * Variables used by authenticated server
+ */
+ keyid_t *keylist; /* session key ID list */
+ int keynumber; /* current key number */
+ struct value encrypt; /* send encrypt values */
+ struct value sndval; /* send autokey values */
+#else /* !AUTOKEY follows */
+#define clear_to_zero status
+#endif /* !AUTOKEY */
+
+ /*
+ * Ephemeral state variables
+ */
+ u_char status; /* peer status */
+ u_char new_status; /* under-construction status */
+ u_char reach; /* reachability register */
+ int flash; /* protocol error test tally bits */
+ u_long epoch; /* reference epoch */
+ int burst; /* packets remaining in burst */
+ int retry; /* retry counter */
+ int flip; /* interleave mode control */
+ int filter_nextpt; /* index into filter shift register */
+ double filter_delay[NTP_SHIFT]; /* delay shift register */
+ double filter_offset[NTP_SHIFT]; /* offset shift register */
+ double filter_disp[NTP_SHIFT]; /* dispersion shift register */
+ u_long filter_epoch[NTP_SHIFT]; /* epoch shift register */
+ u_char filter_order[NTP_SHIFT]; /* filter sort index */
+ l_fp rec; /* receive time stamp */
+ l_fp xmt; /* transmit time stamp */
+ l_fp dst; /* destination timestamp */
+ l_fp aorg; /* origin timestamp */
+ l_fp borg; /* alternate origin timestamp */
+ l_fp bxmt; /* most recent broadcast transmit timestamp */
+ double offset; /* peer clock offset */
+ double delay; /* peer roundtrip delay */
+ double jitter; /* peer jitter (squares) */
+ double disp; /* peer dispersion */
+ double xleave; /* interleave delay */
+ double bias; /* programmed offset bias */
+
+ /*
+ * Variables used to correct for packet length and asymmetry.
+ */
+ double t21; /* outbound packet delay */
+ int t21_bytes; /* outbound packet length */
+ int t21_last; /* last outbound packet length */
+ double r21; /* outbound data rate */
+ double t34; /* inbound packet delay */
+ int t34_bytes; /* inbound packet length */
+ double r34; /* inbound data rate */
+
+ /*
+ * End of clear-to-zero area
+ */
+ u_long update; /* receive epoch */
+#define end_clear_to_zero update
+ int unreach; /* watchdog counter */
+ int throttle; /* rate control */
+ u_long outdate; /* send time last packet */
+ u_long nextdate; /* send time next packet */
+
+ /*
+ * Statistic counters
+ */
+ u_long timereset; /* time stat counters were reset */
+ u_long timelastrec; /* last packet received time, incl. trash */
+ u_long timereceived; /* last (clean) packet received time */
+ u_long timereachable; /* last reachable/unreachable time */
+
+ u_long sent; /* packets sent */
+ u_long received; /* packets received */
+ u_long processed; /* packets processed */
+ u_long badauth; /* bad authentication (TEST5) */
+ u_long badNAK; /* invalid crypto-NAK */
+ u_long bogusorg; /* bogus origin (TEST2, TEST3) */
+ u_long oldpkt; /* old duplicate (TEST1) */
+ u_long seldisptoolarge; /* bad header (TEST6, TEST7) */
+ u_long selbroken; /* KoD received */
+};
+
+/*
+ * Values for peer.leap, sys_leap
+ */
+#define LEAP_NOWARNING 0x0 /* normal, no leap second warning */
+#define LEAP_ADDSECOND 0x1 /* last minute of day has 61 seconds */
+#define LEAP_DELSECOND 0x2 /* last minute of day has 59 seconds */
+#define LEAP_NOTINSYNC 0x3 /* overload, clock is free running */
+
+/*
+ * Values for peer mode and packet mode. Only the modes through
+ * MODE_BROADCAST and MODE_BCLIENT appear in the transition
+ * function. MODE_CONTROL and MODE_PRIVATE can appear in packets,
+ * but those never survive to the transition function.
+ */
+#define MODE_UNSPEC 0 /* unspecified (old version) */
+#define MODE_ACTIVE 1 /* symmetric active mode */
+#define MODE_PASSIVE 2 /* symmetric passive mode */
+#define MODE_CLIENT 3 /* client mode */
+#define MODE_SERVER 4 /* server mode */
+#define MODE_BROADCAST 5 /* broadcast mode */
+/*
+ * These can appear in packets
+ */
+#define MODE_CONTROL 6 /* control mode */
+#define MODE_PRIVATE 7 /* private mode */
+/*
+ * This is a made-up mode for broadcast client.
+ */
+#define MODE_BCLIENT 6 /* broadcast client mode */
+
+/*
+ * Values for peer.stratum, sys_stratum
+ */
+#define STRATUM_REFCLOCK ((u_char)0) /* default stratum */
+/* A stratum of 0 in the packet is mapped to 16 internally */
+#define STRATUM_PKT_UNSPEC ((u_char)0) /* unspecified in packet */
+#define STRATUM_UNSPEC ((u_char)16) /* unspecified */
+
+/*
+ * Values for peer.flags (u_int)
+ */
+#define FLAG_CONFIG 0x0001 /* association was configured */
+#define FLAG_PREEMPT 0x0002 /* preemptable association */
+#define FLAG_AUTHENTIC 0x0004 /* last message was authentic */
+#define FLAG_REFCLOCK 0x0008 /* this is actually a reference clock */
+#define FLAG_BC_VOL 0x0010 /* broadcast client volleying */
+#define FLAG_PREFER 0x0020 /* prefer peer */
+#define FLAG_BURST 0x0040 /* burst mode */
+#define FLAG_PPS 0x0080 /* steered by PPS */
+#define FLAG_IBURST 0x0100 /* initial burst mode */
+#define FLAG_NOSELECT 0x0200 /* never select */
+#define FLAG_TRUE 0x0400 /* force truechimer */
+#define FLAG_SKEY 0x0800 /* autokey authentication */
+#define FLAG_XLEAVE 0x1000 /* interleaved protocol */
+#define FLAG_XB 0x2000 /* interleaved broadcast */
+#define FLAG_XBOGUS 0x4000 /* interleaved bogus packet */
+#ifdef OPENSSL
+# define FLAG_ASSOC 0x8000 /* autokey request */
+#endif /* OPENSSL */
+#define FLAG_TSTAMP_PPS 0x10000 /* PPS source provides absolute timestamp */
+
+/*
+ * Definitions for the clear() routine. We use memset() to clear
+ * the parts of the peer structure which go to zero. These are
+ * used to calculate the start address and length of the area.
+ */
+#define CLEAR_TO_ZERO(p) ((char *)&((p)->clear_to_zero))
+#define END_CLEAR_TO_ZERO(p) ((char *)&((p)->end_clear_to_zero))
+#define LEN_CLEAR_TO_ZERO(p) (END_CLEAR_TO_ZERO(p) - CLEAR_TO_ZERO(p))
+#define CRYPTO_TO_ZERO(p) ((char *)&((p)->clear_to_zero))
+#define END_CRYPTO_TO_ZERO(p) ((char *)&((p)->end_clear_to_zero))
+#define LEN_CRYPTO_TO_ZERO (END_CRYPTO_TO_ZERO((struct peer *)0) \
+ - CRYPTO_TO_ZERO((struct peer *)0))
+
+/*
+ * Reference clock types. Added as necessary.
+ */
+#define REFCLK_NONE 0 /* unknown or missing */
+#define REFCLK_LOCALCLOCK 1 /* external (e.g., lockclock) */
+#define REFCLK_GPS_TRAK 2 /* TRAK 8810 GPS Receiver */
+#define REFCLK_WWV_PST 3 /* PST/Traconex 1020 WWV/H */
+#define REFCLK_SPECTRACOM 4 /* Spectracom (generic) Receivers */
+#define REFCLK_TRUETIME 5 /* TrueTime (generic) Receivers */
+#define REFCLK_IRIG_AUDIO 6 /* IRIG-B/W audio decoder */
+#define REFCLK_CHU_AUDIO 7 /* CHU audio demodulator/decoder */
+#define REFCLK_PARSE 8 /* generic driver (usually DCF77,GPS,MSF) */
+#define REFCLK_GPS_MX4200 9 /* Magnavox MX4200 GPS */
+#define REFCLK_GPS_AS2201 10 /* Austron 2201A GPS */
+#define REFCLK_GPS_ARBITER 11 /* Arbiter 1088A/B/ GPS */
+#define REFCLK_IRIG_TPRO 12 /* KSI/Odetics TPRO-S IRIG */
+#define REFCLK_ATOM_LEITCH 13 /* Leitch CSD 5300 Master Clock */
+#define REFCLK_MSF_EES 14 /* EES M201 MSF Receiver */
+#define REFCLK_GPSTM_TRUE 15 /* OLD TrueTime GPS/TM-TMD Receiver */
+#define REFCLK_IRIG_BANCOMM 16 /* Bancomm GPS/IRIG Interface */
+#define REFCLK_GPS_DATUM 17 /* Datum Programmable Time System */
+#define REFCLK_ACTS 18 /* Generic Auto Computer Time Service */
+#define REFCLK_WWV_HEATH 19 /* Heath GC1000 WWV/WWVH Receiver */
+#define REFCLK_GPS_NMEA 20 /* NMEA based GPS clock */
+#define REFCLK_GPS_VME 21 /* TrueTime GPS-VME Interface */
+#define REFCLK_ATOM_PPS 22 /* 1-PPS Clock Discipline */
+#define REFCLK_PTB_ACTS 23 /* replaced by REFCLK_ACTS */
+#define REFCLK_USNO 24 /* replaced by REFCLK_ACTS */
+#define REFCLK_GPS_HP 26 /* HP 58503A Time/Frequency Receiver */
+#define REFCLK_ARCRON_MSF 27 /* ARCRON MSF radio clock. */
+#define REFCLK_SHM 28 /* clock attached thru shared memory */
+#define REFCLK_PALISADE 29 /* Trimble Navigation Palisade GPS */
+#define REFCLK_ONCORE 30 /* Motorola UT Oncore GPS */
+#define REFCLK_GPS_JUPITER 31 /* Rockwell Jupiter GPS receiver */
+#define REFCLK_CHRONOLOG 32 /* Chrono-log K WWVB receiver */
+#define REFCLK_DUMBCLOCK 33 /* Dumb localtime clock */
+#define REFCLK_ULINK 34 /* Ultralink M320 WWVB receiver */
+#define REFCLK_PCF 35 /* Conrad parallel port radio clock */
+#define REFCLK_WWV_AUDIO 36 /* WWV/H audio demodulator/decoder */
+#define REFCLK_FG 37 /* Forum Graphic GPS */
+#define REFCLK_HOPF_SERIAL 38 /* hopf DCF77/GPS serial receiver */
+#define REFCLK_HOPF_PCI 39 /* hopf DCF77/GPS PCI receiver */
+#define REFCLK_JJY 40 /* JJY receiver */
+#define REFCLK_TT560 41 /* TrueTime 560 IRIG-B decoder */
+#define REFCLK_ZYFER 42 /* Zyfer GPStarplus receiver */
+#define REFCLK_RIPENCC 43 /* RIPE NCC Trimble driver */
+#define REFCLK_NEOCLOCK4X 44 /* NeoClock4X DCF77 or TDF receiver */
+#define REFCLK_TSYNCPCI 45 /* Spectracom TSYNC PCI timing board */
+#define REFCLK_GPSDJSON 46
+#define REFCLK_MAX 46
+
+
+/*
+ * NTP packet format. The mac field is optional. It isn't really
+ * an l_fp either, but for now declaring it that way is convenient.
+ * See Appendix A in the specification.
+ *
+ * Note that all u_fp and l_fp values arrive in network byte order
+ * and must be converted (except the mac, which isn't, really).
+ */
+struct pkt {
+ u_char li_vn_mode; /* peer leap indicator */
+ u_char stratum; /* peer stratum */
+ u_char ppoll; /* peer poll interval */
+ s_char precision; /* peer clock precision */
+ u_fp rootdelay; /* roundtrip delay to primary source */
+ u_fp rootdisp; /* dispersion to primary source*/
+ u_int32 refid; /* reference id */
+ l_fp reftime; /* last update time */
+ l_fp org; /* originate time stamp */
+ l_fp rec; /* receive time stamp */
+ l_fp xmt; /* transmit time stamp */
+
+#define MIN_V4_PKT_LEN (12 * sizeof(u_int32)) /* min header length */
+#define LEN_PKT_NOMAC (12 * sizeof(u_int32)) /* min header length */
+#define MIN_MAC_LEN (1 * sizeof(u_int32)) /* crypto_NAK */
+#define MAX_MD5_LEN (5 * sizeof(u_int32)) /* MD5 */
+#define MAX_MAC_LEN (6 * sizeof(u_int32)) /* SHA */
+#define KEY_MAC_LEN sizeof(u_int32) /* key ID in MAC */
+#define MAX_MDG_LEN (MAX_MAC_LEN-KEY_MAC_LEN) /* max. digest len */
+
+ /*
+ * The length of the packet less MAC must be a multiple of 64
+ * with an RSA modulus and Diffie-Hellman prime of 256 octets
+ * and maximum host name of 128 octets, the maximum autokey
+ * command is 152 octets and maximum autokey response is 460
+ * octets. A packet can contain no more than one command and one
+ * response, so the maximum total extension field length is 864
+ * octets. But, to handle humungus certificates, the bank must
+ * be broke.
+ *
+ * The different definitions of the 'exten' field are here for
+ * the benefit of applications that want to send a packet from
+ * an auto variable in the stack - not using the AUTOKEY version
+ * saves 2KB of stack space. The receive buffer should ALWAYS be
+ * big enough to hold a full extended packet if the extension
+ * fields have to be parsed or skipped.
+ */
+#ifdef AUTOKEY
+ u_int32 exten[(NTP_MAXEXTEN + MAX_MAC_LEN) / sizeof(u_int32)];
+#else /* !AUTOKEY follows */
+ u_int32 exten[(MAX_MAC_LEN) / sizeof(u_int32)];
+#endif /* !AUTOKEY */
+};
+
+/*
+ * Stuff for extracting things from li_vn_mode
+ */
+#define PKT_MODE(li_vn_mode) ((u_char)((li_vn_mode) & 0x7))
+#define PKT_VERSION(li_vn_mode) ((u_char)(((li_vn_mode) >> 3) & 0x7))
+#define PKT_LEAP(li_vn_mode) ((u_char)(((li_vn_mode) >> 6) & 0x3))
+
+/*
+ * Stuff for putting things back into li_vn_mode in packets and vn_mode
+ * in ntp_monitor.c's mon_entry.
+ */
+#define VN_MODE(v, m) ((((v) & 7) << 3) | ((m) & 0x7))
+#define PKT_LI_VN_MODE(l, v, m) ((((l) & 3) << 6) | VN_MODE((v), (m)))
+
+
+/*
+ * Dealing with stratum. 0 gets mapped to 16 incoming, and back to 0
+ * on output.
+ */
+#define PKT_TO_STRATUM(s) ((u_char)(((s) == (STRATUM_PKT_UNSPEC)) ?\
+ (STRATUM_UNSPEC) : (s)))
+
+#define STRATUM_TO_PKT(s) ((u_char)(((s) == (STRATUM_UNSPEC)) ?\
+ (STRATUM_PKT_UNSPEC) : (s)))
+
+
+/*
+ * A test to determine if the refid should be interpreted as text string.
+ * This is usually the case for a refclock, which has stratum 0 internally,
+ * which results in sys_stratum 1 if the refclock becomes system peer, or
+ * in case of a kiss-of-death (KoD) packet that has STRATUM_PKT_UNSPEC (==0)
+ * in the packet which is converted to STRATUM_UNSPEC when the packet
+ * is evaluated.
+ */
+#define REFID_ISTEXT(s) (((s) <= 1) || ((s) >= STRATUM_UNSPEC))
+
+
+/*
+ * Event codes. Used for reporting errors/events to the control module
+ */
+#define PEER_EVENT 0x080 /* this is a peer event */
+#define CRPT_EVENT 0x100 /* this is a crypto event */
+
+/*
+ * System event codes
+ */
+#define EVNT_UNSPEC 0 /* unspecified */
+#define EVNT_NSET 1 /* freq not set */
+#define EVNT_FSET 2 /* freq set */
+#define EVNT_SPIK 3 /* spike detect */
+#define EVNT_FREQ 4 /* freq mode */
+#define EVNT_SYNC 5 /* clock sync */
+#define EVNT_SYSRESTART 6 /* restart */
+#define EVNT_SYSFAULT 7 /* panic stop */
+#define EVNT_NOPEER 8 /* no sys peer */
+#define EVNT_ARMED 9 /* leap armed */
+#define EVNT_DISARMED 10 /* leap disarmed */
+#define EVNT_LEAP 11 /* leap event */
+#define EVNT_CLOCKRESET 12 /* clock step */
+#define EVNT_KERN 13 /* kernel event */
+#define EVNT_TAI 14 /* TAI */
+#define EVNT_LEAPVAL 15 /* stale leapsecond values */
+
+/*
+ * Peer event codes
+ */
+#define PEVNT_MOBIL (1 | PEER_EVENT) /* mobilize */
+#define PEVNT_DEMOBIL (2 | PEER_EVENT) /* demobilize */
+#define PEVNT_UNREACH (3 | PEER_EVENT) /* unreachable */
+#define PEVNT_REACH (4 | PEER_EVENT) /* reachable */
+#define PEVNT_RESTART (5 | PEER_EVENT) /* restart */
+#define PEVNT_REPLY (6 | PEER_EVENT) /* no reply */
+#define PEVNT_RATE (7 | PEER_EVENT) /* rate exceeded */
+#define PEVNT_DENY (8 | PEER_EVENT) /* access denied */
+#define PEVNT_ARMED (9 | PEER_EVENT) /* leap armed */
+#define PEVNT_NEWPEER (10 | PEER_EVENT) /* sys peer */
+#define PEVNT_CLOCK (11 | PEER_EVENT) /* clock event */
+#define PEVNT_AUTH (12 | PEER_EVENT) /* bad auth */
+#define PEVNT_POPCORN (13 | PEER_EVENT) /* popcorn */
+#define PEVNT_XLEAVE (14 | PEER_EVENT) /* interleave mode */
+#define PEVNT_XERR (15 | PEER_EVENT) /* interleave error */
+
+/*
+ * Clock event codes
+ */
+#define CEVNT_NOMINAL 0 /* unspecified */
+#define CEVNT_TIMEOUT 1 /* no reply */
+#define CEVNT_BADREPLY 2 /* bad format */
+#define CEVNT_FAULT 3 /* fault */
+#define CEVNT_PROP 4 /* bad signal */
+#define CEVNT_BADDATE 5 /* bad date */
+#define CEVNT_BADTIME 6 /* bad time */
+#define CEVNT_MAX CEVNT_BADTIME
+
+/*
+ * Very misplaced value. Default port through which we send traps.
+ */
+#define TRAPPORT 18447
+
+
+/*
+ * To speed lookups, peers are hashed by the low order bits of the
+ * remote IP address. These definitions relate to that.
+ */
+#define NTP_HASH_SIZE 128
+#define NTP_HASH_MASK (NTP_HASH_SIZE-1)
+#define NTP_HASH_ADDR(src) (sock_hash(src) & NTP_HASH_MASK)
+
+/*
+ * min, min3 and max. Makes it easier to transliterate the spec without
+ * thinking about it.
+ */
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+#define min3(a,b,c) min(min((a),(b)), (c))
+
+
+/*
+ * Configuration items. These are for the protocol module (proto_config())
+ */
+#define PROTO_BROADCLIENT 1
+#define PROTO_PRECISION 2 /* (not used) */
+#define PROTO_AUTHENTICATE 3
+#define PROTO_BROADDELAY 4
+#define PROTO_AUTHDELAY 5 /* (not used) */
+#define PROTO_MULTICAST_ADD 6
+#define PROTO_MULTICAST_DEL 7
+#define PROTO_NTP 8
+#define PROTO_KERNEL 9
+#define PROTO_MONITOR 10
+#define PROTO_FILEGEN 11
+#define PROTO_PPS 12
+#define PROTO_CAL 13
+#define PROTO_MINCLOCK 14
+#define PROTO_MAXCLOCK 15
+#define PROTO_MINSANE 16
+#define PROTO_FLOOR 17
+#define PROTO_CEILING 18
+#define PROTO_COHORT 19
+#define PROTO_CALLDELAY 20
+#define PROTO_MINDISP 21
+#define PROTO_MAXDIST 22
+ /* available 23 */
+#define PROTO_MAXHOP 24
+#define PROTO_BEACON 25
+#define PROTO_ORPHAN 26
+#define PROTO_ORPHWAIT 27
+#define PROTO_MODE7 28
+#define PROTO_UECRYPTO 29
+#define PROTO_UECRYPTONAK 30
+#define PROTO_UEDIGEST 31
+#define PROTO_PCEDIGEST 32
+#define PROTO_BCPOLLBSTEP 33
+
+/*
+ * Configuration items for the loop filter
+ */
+#define LOOP_DRIFTINIT 1 /* iniitialize frequency */
+#define LOOP_KERN_CLEAR 2 /* set initial frequency offset */
+#define LOOP_MAX 3 /* set both step offsets */
+#define LOOP_MAX_BACK 4 /* set backward-step offset */
+#define LOOP_MAX_FWD 5 /* set forward-step offset */
+#define LOOP_PANIC 6 /* set panic offseet */
+#define LOOP_PHI 7 /* set dispersion rate */
+#define LOOP_MINSTEP 8 /* set step timeout */
+#define LOOP_MINPOLL 9 /* set min poll interval (log2 s) */
+#define LOOP_ALLAN 10 /* set minimum Allan intercept */
+#define LOOP_HUFFPUFF 11 /* set huff-n'-puff filter length */
+#define LOOP_FREQ 12 /* set initial frequency */
+#define LOOP_CODEC 13 /* set audio codec frequency */
+#define LOOP_LEAP 14 /* insert leap after second 23:59 */
+#define LOOP_TICK 15 /* sim. low precision clock */
+
+/*
+ * Configuration items for the stats printer
+ */
+#define STATS_FREQ_FILE 1 /* configure drift file */
+#define STATS_STATSDIR 2 /* directory prefix for stats files */
+#define STATS_PID_FILE 3 /* configure ntpd PID file */
+#define STATS_LEAP_FILE 4 /* configure ntpd leapseconds file */
+
+#define MJD_1900 15020 /* MJD for 1 Jan 1900 */
+
+/*
+ * Default parameters. We use these in the absence of something better.
+ */
+#define INADDR_NTP 0xe0000101 /* NTP multicast address 224.0.1.1 */
+
+/*
+ * Structure used optionally for monitoring when this is turned on.
+ */
+typedef struct mon_data mon_entry;
+struct mon_data {
+ mon_entry * hash_next; /* next structure in hash list */
+ DECL_DLIST_LINK(mon_entry, mru);/* MRU list link pointers */
+ struct interface * lcladr; /* address on which this arrived */
+ l_fp first; /* first time seen */
+ l_fp last; /* last time seen */
+ int leak; /* leaky bucket accumulator */
+ int count; /* total packet count */
+ u_short flags; /* restrict flags */
+ u_char vn_mode; /* packet mode & version */
+ u_char cast_flags; /* flags MDF_?CAST */
+ sockaddr_u rmtadr; /* address of remote host */
+};
+
+/*
+ * Values for cast_flags in mon_entry and struct peer. mon_entry uses
+ * only the first three, MDF_UCAST, MDF_MCAST, and MDF_BCAST.
+ */
+#define MDF_UCAST 0x01 /* unicast client */
+#define MDF_MCAST 0x02 /* multicast server */
+#define MDF_BCAST 0x04 /* broadcast server */
+#define MDF_POOL 0x08 /* pool client solicitor */
+#define MDF_ACAST 0x10 /* manycast client solicitor */
+#define MDF_BCLNT 0x20 /* eph. broadcast/multicast client */
+#define MDF_UCLNT 0x40 /* preemptible manycast or pool client */
+/*
+ * In the context of struct peer in ntpd, three of the cast_flags bits
+ * represent configured associations which never receive packets, and
+ * whose reach is always 0: MDF_BCAST, MDF_MCAST, and MDF_ACAST. The
+ * last can be argued as responses are received, but those responses do
+ * not affect the MDF_ACAST association's reach register, rather they
+ * (may) result in mobilizing ephemeral MDF_ACLNT associations.
+ */
+#define MDF_TXONLY_MASK (MDF_BCAST | MDF_MCAST | MDF_ACAST | MDF_POOL)
+/*
+ * manycastclient-like solicitor association cast_flags bits
+ */
+#define MDF_SOLICIT_MASK (MDF_ACAST | MDF_POOL)
+/*
+ * Values used with mon_enabled to indicate reason for enabling monitoring
+ */
+#define MON_OFF 0x00 /* no monitoring */
+#define MON_ON 0x01 /* monitoring explicitly enabled */
+#define MON_RES 0x02 /* implicit monitoring for RES_LIMITED */
+/*
+ * Structure used for restrictlist entries
+ */
+typedef struct res_addr4_tag {
+ u_int32 addr; /* IPv4 addr (host order) */
+ u_int32 mask; /* IPv4 mask (host order) */
+} res_addr4;
+
+typedef struct res_addr6_tag {
+ struct in6_addr addr; /* IPv6 addr (net order) */
+ struct in6_addr mask; /* IPv6 mask (net order) */
+} res_addr6;
+
+typedef struct restrict_u_tag restrict_u;
+struct restrict_u_tag {
+ restrict_u * link; /* link to next entry */
+ u_int32 count; /* number of packets matched */
+ u_short rflags; /* restrict (accesslist) flags */
+ u_short mflags; /* match flags */
+ short ippeerlimit; /* IP peer limit */
+ u_long expire; /* valid until time */
+ union { /* variant starting here */
+ res_addr4 v4;
+ res_addr6 v6;
+ } u;
+};
+#define V4_SIZEOF_RESTRICT_U (offsetof(restrict_u, u) \
+ + sizeof(res_addr4))
+#define V6_SIZEOF_RESTRICT_U (offsetof(restrict_u, u) \
+ + sizeof(res_addr6))
+
+typedef struct r4addr_tag r4addr;
+struct r4addr_tag {
+ u_short rflags; /* match flags */
+ short ippeerlimit; /* IP peer limit */
+};
+
+char *build_iflags(u_int32 flags);
+char *build_mflags(u_short mflags);
+char *build_rflags(u_short rflags);
+
+/*
+ * Restrict (Access) flags (rflags)
+ */
+#define RES_IGNORE 0x0001 /* ignore packet */
+#define RES_DONTSERVE 0x0002 /* access denied */
+#define RES_DONTTRUST 0x0004 /* authentication required */
+#define RES_VERSION 0x0008 /* version mismatch */
+#define RES_NOPEER 0x0010 /* new association denied */
+#define RES_NOEPEER 0x0020 /* new ephemeral association denied */
+#define RES_LIMITED 0x0040 /* packet rate exceeded */
+#define RES_FLAGS (RES_IGNORE | RES_DONTSERVE |\
+ RES_DONTTRUST | RES_VERSION |\
+ RES_NOPEER | RES_NOEPEER | RES_LIMITED)
+
+#define RES_NOQUERY 0x0080 /* mode 6/7 packet denied */
+#define RES_NOMODIFY 0x0100 /* mode 6/7 modify denied */
+#define RES_NOTRAP 0x0200 /* mode 6/7 set trap denied */
+#define RES_LPTRAP 0x0400 /* mode 6/7 low priority trap */
+
+#define RES_KOD 0x0800 /* send kiss of death packet */
+#define RES_MSSNTP 0x1000 /* enable MS-SNTP authentication */
+#define RES_FLAKE 0x2000 /* flakeway - drop 10% */
+#define RES_NOMRULIST 0x4000 /* mode 6 mrulist denied */
+#define RES_UNUSED 0x8000 /* Unused flag bits */
+
+#define RES_ALLFLAGS (RES_FLAGS | RES_NOQUERY | \
+ RES_NOMODIFY | RES_NOTRAP | \
+ RES_LPTRAP | RES_KOD | \
+ RES_MSSNTP | RES_FLAKE | \
+ RES_NOMRULIST)
+
+/*
+ * Match flags (mflags)
+ */
+#define RESM_INTERFACE 0x1000 /* this is an interface */
+#define RESM_NTPONLY 0x2000 /* match source port 123 */
+#define RESM_SOURCE 0x4000 /* from "restrict source" */
+
+/*
+ * Restriction configuration ops
+ */
+typedef enum
+restrict_ops {
+ RESTRICT_FLAGS = 1, /* add rflags to restrict entry */
+ RESTRICT_UNFLAG, /* remove rflags from restrict entry */
+ RESTRICT_REMOVE, /* remove a restrict entry */
+ RESTRICT_REMOVEIF, /* remove an interface restrict entry */
+} restrict_op;
+
+/*
+ * Endpoint structure for the select algorithm
+ */
+struct endpoint {
+ double val; /* offset of endpoint */
+ int type; /* interval entry/exit */
+};
+
+/*
+ * Association matching AM[] return codes
+ */
+#define AM_ERR -1 /* error */
+#define AM_NOMATCH 0 /* no match */
+#define AM_PROCPKT 1 /* server/symmetric packet */
+#define AM_BCST 2 /* broadcast packet */
+#define AM_FXMIT 3 /* client packet */
+#define AM_MANYCAST 4 /* manycast or pool */
+#define AM_NEWPASS 5 /* new passive */
+#define AM_NEWBCL 6 /* new broadcast */
+#define AM_POSSBCL 7 /* discard broadcast */
+
+/* NetInfo configuration locations */
+#ifdef HAVE_NETINFO
+#define NETINFO_CONFIG_DIR "/config/ntp"
+#endif
+
+/* ntpq -c mrulist rows per request limit in ntpd */
+#define MRU_ROW_LIMIT 256
+/* similar datagrams per response limit for ntpd */
+#define MRU_FRAGS_LIMIT 128
+#endif /* NTP_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntp_assert.h b/sebhbsd/freebsd/contrib/ntp/include/ntp_assert.h
new file mode 100644
index 0000000..42d78ac
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntp_assert.h
@@ -0,0 +1,104 @@
+/*
+ * ntp_assert.h - design by contract stuff
+ *
+ * example:
+ *
+ * int foo(char *a) {
+ * int result;
+ * int value;
+ *
+ * REQUIRE(a != NULL);
+ * ...
+ * bar(&value);
+ * INSIST(value > 2);
+ * ...
+ *
+ * ENSURE(result != 12);
+ * return result;
+ * }
+ *
+ * open question: when would we use INVARIANT()?
+ *
+ * For cases where the overhead for non-debug builds is deemed too high,
+ * use DEBUG_REQUIRE(), DEBUG_INSIST(), DEBUG_ENSURE(), and/or
+ * DEBUG_INVARIANT().
+ */
+
+#ifndef NTP_ASSERT_H
+#define NTP_ASSERT_H
+
+# ifdef CALYSTO
+/* see: http://www.domagoj-babic.com/index.php/ResearchProjects/Calysto */
+
+extern void calysto_assume(unsigned char cnd); /* assume this always holds */
+extern void calysto_assert(unsigned char cnd); /* check whether this holds */
+#define ALWAYS_REQUIRE(x) calysto_assert(x)
+#define ALWAYS_INSIST(x) calysto_assume(x) /* DLH calysto_assert()? */
+#define ALWAYS_INVARIANT(x) calysto_assume(x)
+#define ALWAYS_ENSURE(x) calysto_assert(x)
+
+/* # elif defined(__COVERITY__) */
+/*
+ * DH: try letting coverity scan our actual assertion macros, now that
+ * isc_assertioncallback_t is marked __attribute__ __noreturn__.
+ */
+
+/*
+ * Coverity has special knowledge that assert(x) terminates the process
+ * if x is not true. Rather than teach it about our assertion macros,
+ * just use the one it knows about for Coverity Prevent scans. This
+ * means our assertion code (and ISC's) escapes Coverity analysis, but
+ * that seems to be a reasonable trade-off.
+ */
+
+/*
+#define ALWAYS_REQUIRE(x) assert(x)
+#define ALWAYS_INSIST(x) assert(x)
+#define ALWAYS_INVARIANT(x) assert(x)
+#define ALWAYS_ENSURE(x) assert(x)
+*/
+
+
+#elif defined(__FLEXELINT__)
+
+#include <assert.h>
+
+#define ALWAYS_REQUIRE(x) assert(x)
+#define ALWAYS_INSIST(x) assert(x)
+#define ALWAYS_INVARIANT(x) assert(x)
+#define ALWAYS_ENSURE(x) assert(x)
+
+# else /* neither Calysto, Coverity or FlexeLint */
+
+#include "isc/assertions.h"
+
+#define ALWAYS_REQUIRE(x) ISC_REQUIRE(x)
+#define ALWAYS_INSIST(x) ISC_INSIST(x)
+#define ALWAYS_INVARIANT(x) ISC_INVARIANT(x)
+#define ALWAYS_ENSURE(x) ISC_ENSURE(x)
+
+# endif /* neither Coverity nor Calysto */
+
+#define REQUIRE(x) ALWAYS_REQUIRE(x)
+#define INSIST(x) ALWAYS_INSIST(x)
+#define INVARIANT(x) ALWAYS_INVARIANT(x)
+#define ENSURE(x) ALWAYS_ENSURE(x)
+
+/*
+ * We initially used NTP_REQUIRE() instead of REQUIRE() etc, but that
+ * is unneccesarily verbose, as libisc use of REQUIRE() etc shows.
+ */
+
+# ifdef DEBUG
+#define DEBUG_REQUIRE(x) REQUIRE(x)
+#define DEBUG_INSIST(x) INSIST(x)
+#define DEBUG_INVARIANT(x) INVARIANT(x)
+#define DEBUG_ENSURE(x) ENSURE(x)
+# else
+#define DEBUG_REQUIRE(x) do {} while (FALSE)
+#define DEBUG_INSIST(x) do {} while (FALSE)
+#define DEBUG_INVARIANT(x) do {} while (FALSE)
+#define DEBUG_ENSURE(x) do {} while (FALSE)
+# endif
+
+#endif /* NTP_ASSERT_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntp_calendar.h b/sebhbsd/freebsd/contrib/ntp/include/ntp_calendar.h
new file mode 100644
index 0000000..0b1f20d
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntp_calendar.h
@@ -0,0 +1,472 @@
+/*
+ * ntp_calendar.h - definitions for the calendar time-of-day routine
+ */
+#ifndef NTP_CALENDAR_H
+#define NTP_CALENDAR_H
+
+#include <time.h>
+
+#include "ntp_types.h"
+
+/* gregorian calendar date */
+struct calendar {
+ uint16_t year; /* year (A.D.) */
+ uint16_t yearday; /* day of year, 1 = January 1 */
+ uint8_t month; /* month, 1 = January */
+ uint8_t monthday; /* day of month */
+ uint8_t hour; /* hour of day, midnight = 0 */
+ uint8_t minute; /* minute of hour */
+ uint8_t second; /* second of minute */
+ uint8_t weekday; /* 0..7, 0=Sunday */
+};
+
+/* ISO week calendar date */
+struct isodate {
+ uint16_t year; /* year (A.D.) */
+ uint8_t week; /* 1..53, week in year */
+ uint8_t weekday; /* 1..7, 1=Monday */
+ uint8_t hour; /* hour of day, midnight = 0 */
+ uint8_t minute; /* minute of hour */
+ uint8_t second; /* second of minute */
+};
+
+/* general split representation */
+typedef struct {
+ int32_t hi;
+ int32_t lo;
+} ntpcal_split;
+
+typedef time_t (*systime_func_ptr)(time_t *);
+
+/*
+ * set the function for getting the system time. This is mostly used for
+ * unit testing to provide a fixed / shifted time stamp. Setting the
+ * value to NULL restores the original function, that is, 'time()',
+ * which is also the automatic default.
+ */
+extern systime_func_ptr ntpcal_set_timefunc(systime_func_ptr);
+
+/*
+ * days-of-week
+ */
+#define CAL_SUNDAY 0
+#define CAL_MONDAY 1
+#define CAL_TUESDAY 2
+#define CAL_WEDNESDAY 3
+#define CAL_THURSDAY 4
+#define CAL_FRIDAY 5
+#define CAL_SATURDAY 6
+#define CAL_SUNDAY7 7 /* also sunday */
+
+/*
+ * Days in each month. 30 days hath September...
+ */
+#define JAN 31
+#define FEB 28
+#define FEBLEAP 29
+#define MAR 31
+#define APR 30
+#define MAY 31
+#define JUN 30
+#define JUL 31
+#define AUG 31
+#define SEP 30
+#define OCT 31
+#define NOV 30
+#define DEC 31
+
+/*
+ * We deal in a 4 year cycle starting at March 1, 1900. We assume
+ * we will only want to deal with dates since then, and not to exceed
+ * the rollover day in 2036.
+ */
+#define SECSPERMIN (60) /* seconds per minute */
+#define MINSPERHR (60) /* minutes per hour */
+#define HRSPERDAY (24) /* hours per day */
+#define DAYSPERWEEK (7) /* days per week */
+#define DAYSPERYEAR (365) /* days per year */
+
+#define SECSPERHR (SECSPERMIN * MINSPERHR)
+#define SECSPERDAY (SECSPERHR * HRSPERDAY)
+#define SECSPERWEEK (DAYSPERWEEK * SECSPERDAY)
+#define SECSPERYEAR (365 * SECSPERDAY) /* regular year */
+#define SECSPERLEAPYEAR (366 * SECSPERDAY) /* leap year */
+#define SECSPERAVGYEAR 31556952 /* mean year length over 400yrs */
+
+#define GPSWEEKS 1024 /* GPS week cycle */
+/*
+ * Gross hacks. I have illicit knowlege that there won't be overflows
+ * here, the compiler often can't tell this.
+ */
+#define TIMES60(val) ((((val)<<4) - (val))<<2) /* *(16 - 1) * 4 */
+#define TIMES24(val) (((val)<<4) + ((val)<<3)) /* *16 + *8 */
+#define TIMES7(val) (((val)<<3) - (val)) /* *8 - *1 */
+#define TIMESDPERC(val) (((val)<<10) + ((val)<<8) \
+ + ((val)<<7) + ((val)<<5) \
+ + ((val)<<4) + ((val)<<2) + (val)) /* *big* hack */
+
+
+extern const char * const months[12];
+extern const char * const daynames[7];
+
+extern void caljulian (uint32_t, struct calendar *);
+extern uint32_t caltontp (const struct calendar *);
+
+/*
+ * Convert between 'time_t' and 'vint64'
+ */
+extern vint64 time_to_vint64(const time_t *);
+extern time_t vint64_to_time(const vint64 *);
+
+/*
+ * Get the build date & time. ATTENTION: The time zone is not specified!
+ * This depends entirely on the C compilers' capabilities to properly
+ * expand the '__TIME__' and '__DATE__' macros, as required by the C
+ * standard.
+ */
+extern int
+ntpcal_get_build_date(struct calendar * /* jd */);
+
+/*
+ * Convert a timestamp in NTP scale to a time_t value in the UN*X
+ * scale with proper epoch unfolding around a given pivot or the
+ * current system time.
+ */
+extern vint64
+ntpcal_ntp_to_time(uint32_t /* ntp */, const time_t * /* pivot */);
+
+/*
+ * Convert a timestamp in NTP scale to a 64bit seconds value in the NTP
+ * scale with proper epoch unfolding around a given pivot or the current
+ * system time.
+ * Note: The pivot must be given in UN*X time scale!
+ */
+extern vint64
+ntpcal_ntp_to_ntp(uint32_t /* ntp */, const time_t * /* pivot */);
+
+/*
+ * Split a time stamp in seconds into elapsed days and elapsed seconds
+ * since midnight.
+ */
+extern ntpcal_split
+ntpcal_daysplit(const vint64 *);
+
+/*
+ * Merge a number of days and a number of seconds into seconds,
+ * expressed in 64 bits to avoid overflow.
+ */
+extern vint64
+ntpcal_dayjoin(int32_t /* days */, int32_t /* seconds */);
+
+/* Get the number of leap years since epoch for the number of elapsed
+ * full years
+ */
+extern int32_t
+ntpcal_leapyears_in_years(int32_t /* years */);
+
+/*
+ * Convert elapsed years in Era into elapsed days in Era.
+ */
+extern int32_t
+ntpcal_days_in_years(int32_t /* years */);
+
+/*
+ * Convert a number of elapsed month in a year into elapsed days
+ * in year.
+ *
+ * The month will be normalized, and 'res.hi' will contain the
+ * excessive years that must be considered when converting the years,
+ * while 'res.lo' will contain the days since start of the
+ * year. (Expect the resulting days to be negative, with a positive
+ * excess! But then, we need no leap year flag, either...)
+ */
+extern ntpcal_split
+ntpcal_days_in_months(int32_t /* months */);
+
+/*
+ * Convert ELAPSED years/months/days of gregorian calendar to elapsed
+ * days in Gregorian epoch. No range checks done here!
+ */
+extern int32_t
+ntpcal_edate_to_eradays(int32_t /* years */, int32_t /* months */, int32_t /* mdays */);
+
+/*
+ * Convert a time spec to seconds. No range checks done here!
+ */
+extern int32_t
+ntpcal_etime_to_seconds(int32_t /* hours */, int32_t /* minutes */, int32_t /* seconds */);
+
+/*
+ * Convert ELAPSED years/months/days of gregorian calendar to elapsed
+ * days in year.
+ *
+ * Note: This will give the true difference to the start of the given year,
+ * even if months & days are off-scale.
+ */
+extern int32_t
+ntpcal_edate_to_yeardays(int32_t /* years */, int32_t /* months */, int32_t /* mdays */);
+
+/*
+ * Convert the date part of a 'struct tm' (that is, year, month,
+ * day-of-month) into the RataDie of that day.
+ */
+extern int32_t
+ntpcal_tm_to_rd(const struct tm * /* utm */);
+
+/*
+ * Convert the date part of a 'struct calendar' (that is, year, month,
+ * day-of-month) into the RataDie of that day.
+ */
+extern int32_t
+ntpcal_date_to_rd(const struct calendar * /* jt */);
+
+/*
+ * Given the number of elapsed days in the calendar era, split this
+ * number into the number of elapsed years in 'res.quot' and the
+ * number of elapsed days of that year in 'res.rem'.
+ *
+ * if 'isleapyear' is not NULL, it will receive an integer that is 0
+ * for regular years and a non-zero value for leap years.
+ *
+ * The input is limited to [-2^30, 2^30-1]. If the days exceed this
+ * range, errno is set to EDOM and the result is saturated.
+ */
+extern ntpcal_split
+ntpcal_split_eradays(int32_t /* days */, int/*BOOL*/ * /* isleapyear */);
+
+/*
+ * Given a number of elapsed days in a year and a leap year indicator,
+ * split the number of elapsed days into the number of elapsed months
+ * in 'res.quot' and the number of elapsed days of that month in
+ * 'res.rem'.
+ */
+extern ntpcal_split
+ntpcal_split_yeardays(int32_t /* eyd */, int/*BOOL*/ /* isleapyear */);
+
+/*
+ * Convert a RataDie number into the date part of a 'struct
+ * calendar'. Return 0 if the year is regular year, !0 if the year is
+ * a leap year.
+ */
+extern int/*BOOL*/
+ntpcal_rd_to_date(struct calendar * /* jt */, int32_t /* rd */);
+
+/*
+ * Convert a RataDie number into the date part of a 'struct
+ * tm'. Return 0 if the year is regular year, !0 if the year is a leap
+ * year.
+ */
+extern int/*BOOL*/
+ntpcal_rd_to_tm(struct tm * /* utm */, int32_t /* rd */);
+
+/*
+ * Take a value of seconds since midnight and split it into hhmmss in
+ * a 'struct calendar'. Return excessive days.
+ */
+extern int32_t
+ntpcal_daysec_to_date(struct calendar * /* jt */, int32_t /* secs */);
+
+/*
+ * Take the time part of a 'struct calendar' and return the seconds
+ * since midnight.
+ */
+extern int32_t
+ntpcal_date_to_daysec(const struct calendar *);
+
+/*
+ * Take a value of seconds since midnight and split it into hhmmss in
+ * a 'struct tm'. Return excessive days.
+ */
+extern int32_t
+ntpcal_daysec_to_tm(struct tm * /* utm */, int32_t /* secs */);
+
+extern int32_t
+ntpcal_tm_to_daysec(const struct tm * /* utm */);
+
+/*
+ * convert a year number to rata die of year start
+ */
+extern int32_t
+ntpcal_year_to_ystart(int32_t /* year */);
+
+/*
+ * For a given RataDie, get the RataDie of the associated year start,
+ * that is, the RataDie of the last January,1st on or before that day.
+ */
+extern int32_t
+ntpcal_rd_to_ystart(int32_t /* rd */);
+
+/*
+ * convert a RataDie to the RataDie of start of the calendar month.
+ */
+extern int32_t
+ntpcal_rd_to_mstart(int32_t /* year */);
+
+
+extern int
+ntpcal_daysplit_to_date(struct calendar * /* jt */,
+ const ntpcal_split * /* ds */, int32_t /* dof */);
+
+extern int
+ntpcal_daysplit_to_tm(struct tm * /* utm */, const ntpcal_split * /* ds */,
+ int32_t /* dof */);
+
+extern int
+ntpcal_time_to_date(struct calendar * /* jd */, const vint64 * /* ts */);
+
+extern int32_t
+ntpcal_periodic_extend(int32_t /* pivot */, int32_t /* value */,
+ int32_t /* cycle */);
+
+extern int
+ntpcal_ntp64_to_date(struct calendar * /* jd */, const vint64 * /* ntp */);
+
+extern int
+ntpcal_ntp_to_date(struct calendar * /* jd */, uint32_t /* ntp */,
+ const time_t * /* pivot */);
+
+extern vint64
+ntpcal_date_to_ntp64(const struct calendar * /* jd */);
+
+extern uint32_t
+ntpcal_date_to_ntp(const struct calendar * /* jd */);
+
+extern time_t
+ntpcal_date_to_time(const struct calendar * /* jd */);
+
+/*
+ * ISO week-calendar conversions
+ */
+extern int32_t
+isocal_weeks_in_years(int32_t /* years */);
+
+/*
+ * The input is limited to [-2^30, 2^30-1]. If the weeks exceed this
+ * range, errno is set to EDOM and the result is saturated.
+ */
+extern ntpcal_split
+isocal_split_eraweeks(int32_t /* weeks */);
+
+extern int
+isocal_ntp64_to_date(struct isodate * /* id */, const vint64 * /* ntp */);
+
+extern int
+isocal_ntp_to_date(struct isodate * /* id */, uint32_t /* ntp */,
+ const time_t * /* pivot */);
+
+extern vint64
+isocal_date_to_ntp64(const struct isodate * /* id */);
+
+extern uint32_t
+isocal_date_to_ntp(const struct isodate * /* id */);
+
+
+/*
+ * day-of-week calculations
+ *
+ * Given a RataDie and a day-of-week, calculate a RDN that is reater-than,
+ * greater-or equal, closest, less-or-equal or less-than the given RDN
+ * and denotes the given day-of-week
+ */
+extern int32_t
+ntpcal_weekday_gt(int32_t /* rdn */, int32_t /* dow */);
+
+extern int32_t
+ntpcal_weekday_ge(int32_t /* rdn */, int32_t /* dow */);
+
+extern int32_t
+ntpcal_weekday_close(int32_t /* rdn */, int32_t /* dow */);
+
+extern int32_t
+ntpcal_weekday_le(int32_t /* rdn */, int32_t /* dow */);
+
+extern int32_t
+ntpcal_weekday_lt(int32_t /* rdn */, int32_t /* dow */);
+
+
+/*
+ * handling of base date spec
+ */
+extern int32_t
+basedate_eval_buildstamp(void);
+
+extern int32_t
+basedate_eval_string(const char *str);
+
+extern int32_t
+basedate_set_day(int32_t dayno);
+
+extern uint32_t
+basedate_get_day(void);
+
+extern time_t
+basedate_get_eracenter(void);
+
+extern time_t
+basedate_get_erabase(void);
+
+extern uint32_t
+basedate_get_gpsweek(void);
+
+extern uint32_t
+basedate_expand_gpsweek(unsigned short weekno);
+
+/*
+ * Additional support stuff for Ed Rheingold's calendrical calculations
+ */
+
+/*
+ * Start day of NTP time as days past 0000-12-31 in the proleptic
+ * Gregorian calendar. (So 0001-01-01 is day number 1; this is the Rata
+ * Die counting scheme used by Ed Rheingold in his book "Calendrical
+ * Calculations".)
+ */
+#define DAY_NTP_STARTS 693596
+
+/*
+ * Start day of the UNIX epoch. This is the Rata Die of 1970-01-01.
+ */
+#define DAY_UNIX_STARTS 719163
+
+/*
+ * Start day of the GPS epoch. This is the Rata Die of 1980-01-06
+ */
+#define DAY_GPS_STARTS 722819
+
+/*
+ * Difference between UN*X and NTP epoch (25567).
+ */
+#define NTP_TO_UNIX_DAYS (DAY_UNIX_STARTS - DAY_NTP_STARTS)
+
+/*
+ * Difference between GPS and NTP epoch (29224)
+ */
+#define NTP_TO_GPS_DAYS (DAY_GPS_STARTS - DAY_NTP_STARTS)
+
+/*
+ * Days in a normal 4 year leap year calendar cycle (1461).
+ */
+#define GREGORIAN_NORMAL_LEAP_CYCLE_DAYS (4 * 365 + 1)
+
+/*
+ * Days in a normal 100 year leap year calendar (36524). We lose a
+ * leap day in years evenly divisible by 100 but not by 400.
+ */
+#define GREGORIAN_NORMAL_CENTURY_DAYS \
+ (25 * GREGORIAN_NORMAL_LEAP_CYCLE_DAYS - 1)
+
+/*
+ * The Gregorian calendar is based on a 400 year cycle. This is the
+ * number of days in each cycle (146097). We gain a leap day in years
+ * divisible by 400 relative to the "normal" century.
+ */
+#define GREGORIAN_CYCLE_DAYS (4 * GREGORIAN_NORMAL_CENTURY_DAYS + 1)
+
+/*
+ * Number of weeks in 400 years (20871).
+ */
+#define GREGORIAN_CYCLE_WEEKS (GREGORIAN_CYCLE_DAYS / 7)
+
+#define is_leapyear(y) (!((y) % 4) && !(!((y) % 100) && (y) % 400))
+
+#endif
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntp_cmdargs.h b/sebhbsd/freebsd/contrib/ntp/include/ntp_cmdargs.h
new file mode 100644
index 0000000..de45d8d
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntp_cmdargs.h
@@ -0,0 +1 @@
+extern void getCmdOpts(int, char **);
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntp_config.h b/sebhbsd/freebsd/contrib/ntp/include/ntp_config.h
new file mode 100644
index 0000000..dac933a
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntp_config.h
@@ -0,0 +1,338 @@
+#ifndef NTP_CONFIG_H
+#define NTP_CONFIG_H
+
+#ifdef HAVE_SYS_RESOURCE_H
+# include <sys/resource.h>
+#endif /* HAVE_SYS_RESOURCE_H */
+
+#include "ntp_machine.h"
+#include "ntpsim.h"
+
+
+/*
+ * Configuration file name
+ */
+#ifndef CONFIG_FILE
+# ifndef SYS_WINNT
+# define CONFIG_FILE "/etc/ntp.conf"
+# else /* SYS_WINNT */
+# define CONFIG_FILE "%windir%\\system32\\drivers\\etc\\ntp.conf"
+# define ALT_CONFIG_FILE "%windir%\\ntp.conf"
+# define NTP_KEYSDIR "%windir%\\system32\\drivers\\etc"
+# endif /* SYS_WINNT */
+#endif /* not CONFIG_FILE */
+
+
+/*
+ * We keep config trees around for possible saveconfig use. When
+ * built with configure --disable-saveconfig, and when built with
+ * debugging enabled, include the free_config_*() routines. In the
+ * DEBUG case, they are used in an atexit() cleanup routine to make
+ * postmortem leak check reports more interesting.
+ */
+#if !defined(FREE_CFG_T) && (!defined(SAVECONFIG) || defined(DEBUG))
+#define FREE_CFG_T
+#endif
+
+/* Limits */
+#define MAXLINE 1024
+
+/* Configuration sources */
+
+#define CONF_SOURCE_FILE 0
+#define CONF_SOURCE_NTPQ 1
+
+/* list of servers from command line for config_peers() */
+extern int cmdline_server_count;
+extern char ** cmdline_servers;
+
+/* set to zero if we're not locking memory */
+extern int cur_memlock;
+
+typedef struct int_range_tag {
+ int first;
+ int last;
+} int_range;
+
+/* generic list node */
+typedef struct any_node_tag any_node;
+struct any_node_tag {
+ any_node * link;
+};
+
+typedef DECL_FIFO_ANCHOR(any_node) any_node_fifo;
+
+/* Structure for storing an attribute-value pair */
+typedef struct attr_val_tag attr_val;
+struct attr_val_tag {
+ attr_val * link;
+ int attr;
+ int type; /* T_String, T_Integer, ... */
+ union val {
+ int i;
+ u_int u;
+ int_range r;
+ double d;
+ char * s;
+ } value;
+};
+
+typedef DECL_FIFO_ANCHOR(attr_val) attr_val_fifo;
+
+/* Structure for nodes on the syntax tree */
+typedef struct address_node_tag address_node;
+struct address_node_tag {
+ address_node * link;
+ char * address;
+ u_short type; /* family, AF_UNSPEC (0), AF_INET[6] */
+};
+
+typedef DECL_FIFO_ANCHOR(address_node) address_fifo;
+
+typedef struct int_node_tag int_node;
+struct int_node_tag {
+ int_node * link;
+ int i;
+};
+
+typedef DECL_FIFO_ANCHOR(int_node) int_fifo;
+
+typedef struct string_node_tag string_node;
+struct string_node_tag {
+ string_node * link;
+ char * s;
+};
+
+typedef DECL_FIFO_ANCHOR(string_node) string_fifo;
+
+typedef struct restrict_node_tag restrict_node;
+struct restrict_node_tag {
+ restrict_node * link;
+ address_node * addr;
+ address_node * mask;
+ int_fifo * flag_tok_fifo;
+ int line_no;
+ short ippeerlimit;
+};
+
+typedef DECL_FIFO_ANCHOR(restrict_node) restrict_fifo;
+
+typedef struct peer_node_tag peer_node;
+struct peer_node_tag {
+ peer_node * link;
+ int host_mode;
+ address_node * addr;
+ attr_val_fifo * peerflags;
+ u_char minpoll;
+ u_char maxpoll;
+ u_int32 ttl;
+ u_char peerversion;
+ keyid_t peerkey;
+ char * group;
+};
+
+typedef DECL_FIFO_ANCHOR(peer_node) peer_fifo;
+
+typedef struct unpeer_node_tag unpeer_node;
+struct unpeer_node_tag {
+ unpeer_node * link;
+ associd_t assocID;
+ address_node * addr;
+};
+
+typedef DECL_FIFO_ANCHOR(unpeer_node) unpeer_fifo;
+
+typedef struct auth_node_tag auth_node;
+struct auth_node_tag {
+ int control_key;
+ int cryptosw;
+ attr_val_fifo * crypto_cmd_list;
+ char * keys;
+ char * keysdir;
+ int request_key;
+ int revoke;
+ attr_val_fifo * trusted_key_list;
+ char * ntp_signd_socket;
+};
+
+typedef struct filegen_node_tag filegen_node;
+struct filegen_node_tag {
+ filegen_node * link;
+ int filegen_token;
+ attr_val_fifo * options;
+};
+
+typedef DECL_FIFO_ANCHOR(filegen_node) filegen_fifo;
+
+typedef struct setvar_node_tag setvar_node;
+struct setvar_node_tag {
+ setvar_node * link;
+ char * var;
+ char * val;
+ int isdefault;
+};
+
+typedef DECL_FIFO_ANCHOR(setvar_node) setvar_fifo;
+
+typedef struct nic_rule_node_tag nic_rule_node;
+struct nic_rule_node_tag {
+ nic_rule_node * link;
+ int match_class;
+ char * if_name; /* or numeric address */
+ int action;
+};
+
+typedef DECL_FIFO_ANCHOR(nic_rule_node) nic_rule_fifo;
+
+typedef struct addr_opts_node_tag addr_opts_node;
+struct addr_opts_node_tag {
+ addr_opts_node *link;
+ address_node * addr;
+ attr_val_fifo * options;
+};
+
+typedef DECL_FIFO_ANCHOR(addr_opts_node) addr_opts_fifo;
+
+typedef struct sim_node_tag sim_node;
+struct sim_node_tag {
+ sim_node * link;
+ attr_val_fifo * init_opts;
+ server_info_fifo * servers;
+};
+
+typedef DECL_FIFO_ANCHOR(sim_node) sim_fifo;
+
+/* The syntax tree */
+typedef struct config_tree_tag config_tree;
+struct config_tree_tag {
+ config_tree * link;
+
+ attr_val source;
+ time_t timestamp;
+
+ peer_fifo * peers;
+ unpeer_fifo * unpeers;
+
+ /* Other Modes */
+ int broadcastclient;
+ address_fifo * manycastserver;
+ address_fifo * multicastclient;
+
+ attr_val_fifo * orphan_cmds; /* s/b renamed tos_options */
+
+ /* Monitoring Configuration */
+ int_fifo * stats_list;
+ char * stats_dir;
+ filegen_fifo * filegen_opts;
+
+ /* Access Control Configuration */
+ attr_val_fifo * discard_opts;
+ attr_val_fifo * mru_opts;
+ restrict_fifo * restrict_opts;
+
+ addr_opts_fifo *fudge;
+ attr_val_fifo * rlimit;
+ attr_val_fifo * tinker;
+ attr_val_fifo * enable_opts;
+ attr_val_fifo * disable_opts;
+
+ auth_node auth;
+
+ attr_val_fifo * logconfig;
+ string_fifo * phone;
+ setvar_fifo * setvar;
+ int_fifo * ttl;
+ addr_opts_fifo *trap;
+ attr_val_fifo * vars;
+ nic_rule_fifo * nic_rules;
+ int_fifo * reset_counters;
+
+ sim_fifo * sim_details;
+ int mdnstries;
+};
+
+
+/* Structure for holding a remote configuration command */
+struct REMOTE_CONFIG_INFO {
+ char buffer[MAXLINE];
+ char err_msg[MAXLINE];
+ int pos;
+ int err_pos;
+ int no_errors;
+};
+
+
+/*
+ * context for trap_name_resolved() to call ctlsettrap() once the
+ * name->address resolution completes.
+ */
+typedef struct settrap_parms_tag {
+ sockaddr_u ifaddr;
+ int ifaddr_nonnull;
+} settrap_parms;
+
+
+/* get text from T_ tokens */
+const char * token_name(int token);
+
+/* generic fifo routines for structs linked by 1st member */
+typedef void (*fifo_deleter)(void*);
+void * destroy_gen_fifo(void *fifo, fifo_deleter func);
+void * append_gen_fifo(void *fifo, void *entry);
+void * concat_gen_fifos(void *first, void *second);
+#define DESTROY_G_FIFO(pf, func) \
+ ((pf) = destroy_gen_fifo((pf), (fifo_deleter)(func)))
+#define APPEND_G_FIFO(pf, pe) \
+ ((pf) = append_gen_fifo((pf), (pe)))
+#define CONCAT_G_FIFOS(first, second) \
+ ((first) = concat_gen_fifos((first), (second)))
+#define HEAD_PFIFO(pf) \
+ (((pf) != NULL) \
+ ? HEAD_FIFO(*(pf)) \
+ : NULL)
+
+peer_node *create_peer_node(int hmode, address_node *addr,
+ attr_val_fifo *options);
+unpeer_node *create_unpeer_node(address_node *addr);
+address_node *create_address_node(char *addr, int type);
+void destroy_address_node(address_node *my_node);
+attr_val *create_attr_dval(int attr, double value);
+attr_val *create_attr_ival(int attr, int value);
+attr_val *create_attr_uval(int attr, u_int value);
+attr_val *create_attr_rangeval(int attr, int first, int last);
+attr_val *create_attr_sval(int attr, const char *s);
+void destroy_attr_val(attr_val *node);
+filegen_node *create_filegen_node(int filegen_token,
+ attr_val_fifo *options);
+string_node *create_string_node(char *str);
+restrict_node *create_restrict_node(address_node *addr,
+ address_node *mask,
+ short ippeerlimit,
+ int_fifo *flags, int line_no);
+int_node *create_int_node(int val);
+addr_opts_node *create_addr_opts_node(address_node *addr,
+ attr_val_fifo *options);
+sim_node *create_sim_node(attr_val_fifo *init_opts,
+ server_info_fifo *servers);
+setvar_node *create_setvar_node(char *var, char *val, int isdefault);
+nic_rule_node *create_nic_rule_node(int match_class, char *if_name,
+ int action);
+
+script_info *create_sim_script_info(double duration,
+ attr_val_fifo *script_queue);
+server_info *create_sim_server(address_node *addr, double server_offset,
+ script_info_fifo *script);
+
+extern struct REMOTE_CONFIG_INFO remote_config;
+void config_remotely(sockaddr_u *);
+
+#ifdef SAVECONFIG
+int dump_config_tree(config_tree *ptree, FILE *df, int comment);
+int dump_all_config_trees(FILE *df, int comment);
+#endif
+
+#if defined(HAVE_SETRLIMIT)
+void ntp_rlimit(int, rlim_t, int, const char *);
+#endif
+
+#endif /* !defined(NTP_CONFIG_H) */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntp_control.h b/sebhbsd/freebsd/contrib/ntp/include/ntp_control.h
new file mode 100644
index 0000000..85f4105
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntp_control.h
@@ -0,0 +1,192 @@
+/*
+ * ntp_control.h - definitions related to NTP mode 6 control messages
+ */
+
+#include "ntp_types.h"
+
+typedef union ctl_pkt_u_tag {
+ u_char data[480 + MAX_MAC_LEN]; /* data + auth */
+ u_int32 u32[(480 + MAX_MAC_LEN) / sizeof(u_int32)];
+} ctl_pkt_u;
+
+struct ntp_control {
+ u_char li_vn_mode; /* leap, version, mode */
+ u_char r_m_e_op; /* response, more, error, opcode */
+ u_short sequence; /* sequence number of request */
+ u_short status; /* status word for association */
+ associd_t associd; /* association ID */
+ u_short offset; /* offset of this batch of data */
+ u_short count; /* count of data in this packet */
+ ctl_pkt_u u;
+};
+
+/*
+ * Length of the control header, in octets
+ */
+#define CTL_HEADER_LEN (offsetof(struct ntp_control, u))
+#define CTL_MAX_DATA_LEN 468
+
+
+/*
+ * Limits and things
+ */
+#define CTL_MAXTRAPS 3 /* maximum number of traps we allow */
+#define CTL_TRAPTIME (60*60) /* time out traps in 1 hour */
+#define CTL_MAXAUTHSIZE 64 /* maximum size of an authen'ed req */
+
+/*
+ * Decoding for the r_m_e_op field
+ */
+#define CTL_RESPONSE 0x80
+#define CTL_ERROR 0x40
+#define CTL_MORE 0x20
+#define CTL_OP_MASK 0x1f
+
+#define CTL_ISRESPONSE(r_m_e_op) ((CTL_RESPONSE & (r_m_e_op)) != 0)
+#define CTL_ISMORE(r_m_e_op) ((CTL_MORE & (r_m_e_op)) != 0)
+#define CTL_ISERROR(r_m_e_op) ((CTL_ERROR & (r_m_e_op)) != 0)
+#define CTL_OP(r_m_e_op) (CTL_OP_MASK & (r_m_e_op))
+
+/*
+ * Opcodes
+ */
+#define CTL_OP_UNSPEC 0 /* unspeciffied */
+#define CTL_OP_READSTAT 1 /* read status */
+#define CTL_OP_READVAR 2 /* read variables */
+#define CTL_OP_WRITEVAR 3 /* write variables */
+#define CTL_OP_READCLOCK 4 /* read clock variables */
+#define CTL_OP_WRITECLOCK 5 /* write clock variables */
+#define CTL_OP_SETTRAP 6 /* set trap address */
+#define CTL_OP_ASYNCMSG 7 /* asynchronous message */
+#define CTL_OP_CONFIGURE 8 /* runtime configuration */
+#define CTL_OP_SAVECONFIG 9 /* save config to file */
+#define CTL_OP_READ_MRU 10 /* retrieve MRU (mrulist) */
+#define CTL_OP_READ_ORDLIST_A 11 /* ordered list req. auth. */
+#define CTL_OP_REQ_NONCE 12 /* request a client nonce */
+#define CTL_OP_UNSETTRAP 31 /* unset trap */
+
+/*
+ * {En,De}coding of the system status word
+ */
+#define CTL_SST_TS_UNSPEC 0 /* unspec */
+#define CTL_SST_TS_ATOM 1 /* pps */
+#define CTL_SST_TS_LF 2 /* lf radio */
+#define CTL_SST_TS_HF 3 /* hf radio */
+#define CTL_SST_TS_UHF 4 /* uhf radio */
+#define CTL_SST_TS_LOCAL 5 /* local */
+#define CTL_SST_TS_NTP 6 /* ntp */
+#define CTL_SST_TS_UDPTIME 7 /* other */
+#define CTL_SST_TS_WRSTWTCH 8 /* wristwatch */
+#define CTL_SST_TS_TELEPHONE 9 /* telephone */
+
+#define CTL_SYS_MAXEVENTS 15
+
+#define CTL_SYS_STATUS(li, source, nevnt, evnt) \
+ (((((unsigned short)(li))<< 14)&0xc000) | \
+ (((source)<<8)&0x3f00) | \
+ (((nevnt)<<4)&0x00f0) | \
+ ((evnt)&0x000f))
+
+#define CTL_SYS_LI(status) (((status)>>14) & 0x3)
+#define CTL_SYS_SOURCE(status) (((status)>>8) & 0x3f)
+#define CTL_SYS_NEVNT(status) (((status)>>4) & 0xf)
+#define CTL_SYS_EVENT(status) ((status) & 0xf)
+
+/*
+ * {En,De}coding of the peer status word
+ */
+#define CTL_PST_CONFIG 0x80
+#define CTL_PST_AUTHENABLE 0x40
+#define CTL_PST_AUTHENTIC 0x20
+#define CTL_PST_REACH 0x10
+#define CTL_PST_BCAST 0x08
+
+#define CTL_PST_SEL_REJECT 0 /* reject */
+#define CTL_PST_SEL_SANE 1 /* x falsetick */
+#define CTL_PST_SEL_CORRECT 2 /* . excess */
+#define CTL_PST_SEL_SELCAND 3 /* - outlier */
+#define CTL_PST_SEL_SYNCCAND 4 /* + candidate */
+#define CTL_PST_SEL_EXCESS 5 /* # backup */
+#define CTL_PST_SEL_SYSPEER 6 /* * sys.peer */
+#define CTL_PST_SEL_PPS 7 /* o pps.peer */
+
+#define CTL_PEER_MAXEVENTS 15
+
+#define CTL_PEER_STATUS(status, nevnt, evnt) \
+ ((((status)<<8) & 0xff00) | \
+ (((nevnt)<<4) & 0x00f0) | \
+ ((evnt) & 0x000f))
+
+#define CTL_PEER_STATVAL(status)(((status)>>8) & 0xff)
+#define CTL_PEER_NEVNT(status) (((status)>>4) & 0xf)
+#define CTL_PEER_EVENT(status) ((status) & 0xf)
+
+/*
+ * {En,De}coding of the clock status word
+ */
+#define CTL_CLK_OKAY 0
+#define CTL_CLK_NOREPLY 1
+#define CTL_CLK_BADFORMAT 2
+#define CTL_CLK_FAULT 3
+#define CTL_CLK_PROPAGATION 4
+#define CTL_CLK_BADDATE 5
+#define CTL_CLK_BADTIME 6
+
+#define CTL_CLK_STATUS(status, event) \
+ ((((status)<<8) & 0xff00) | \
+ ((event) & 0x00ff))
+
+/*
+ * Error code responses returned when the E bit is set.
+ */
+#define CERR_UNSPEC 0
+#define CERR_PERMISSION 1
+#define CERR_BADFMT 2
+#define CERR_BADOP 3
+#define CERR_BADASSOC 4
+#define CERR_UNKNOWNVAR 5
+#define CERR_BADVALUE 6
+#define CERR_RESTRICT 7
+
+#define CERR_NORESOURCE CERR_PERMISSION /* wish there was a different code */
+
+
+/*
+ * Definition of the structure used internally to hold trap information.
+ * ntp_request.c wants to see this.
+ */
+struct ctl_trap {
+ sockaddr_u tr_addr; /* address of trap recipient */
+ struct interface *tr_localaddr; /* interface to send this through */
+ u_long tr_settime; /* time trap was set */
+ u_long tr_count; /* async messages sent to this guy */
+ u_long tr_origtime; /* time trap was originally set */
+ u_long tr_resets; /* count of resets for this trap */
+ u_short tr_sequence; /* trap sequence id */
+ u_char tr_flags; /* trap flags */
+ u_char tr_version; /* version number of trapper */
+};
+extern struct ctl_trap ctl_traps[CTL_MAXTRAPS];
+
+/*
+ * Flag bits
+ */
+#define TRAP_INUSE 0x1 /* this trap is active */
+#define TRAP_NONPRIO 0x2 /* this trap is non-priority */
+#define TRAP_CONFIGURED 0x4 /* this trap was configured */
+
+/*
+ * Types of things we may deal with
+ * shared between ntpq and library
+ */
+#define TYPE_SYS 1
+#define TYPE_PEER 2
+#define TYPE_CLOCK 3
+
+/*
+ * IFSTATS_FIELDS is the number of fields ntpd supplies for each ifstats
+ * row. Similarly RESLIST_FIELDS for reslist.
+ */
+#define IFSTATS_FIELDS 12
+#define RESLIST_FIELDS 4
+
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntp_crypto.h b/sebhbsd/freebsd/contrib/ntp/include/ntp_crypto.h
new file mode 100644
index 0000000..32134a8
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntp_crypto.h
@@ -0,0 +1,191 @@
+/*
+ * ntp_crypto.h - definitions for cryptographic operations
+ */
+#ifndef NTP_CRYPTO_H
+#define NTP_CRYPTO_H
+
+/*
+ * Configuration codes (also needed for parser without AUTOKEY)
+ */
+#define CRYPTO_CONF_NONE 0 /* nothing doing */
+#define CRYPTO_CONF_PRIV 1 /* host name */
+#define CRYPTO_CONF_IDENT 2 /* group name */
+#define CRYPTO_CONF_CERT 3 /* certificate file name */
+#define CRYPTO_CONF_RAND 4 /* random seed file name */
+#define CRYPTO_CONF_IFFPAR 5 /* IFF parameters file name */
+#define CRYPTO_CONF_GQPAR 6 /* GQ parameters file name */
+#define CRYPTO_CONF_MVPAR 7 /* MV parameters file name */
+#define CRYPTO_CONF_PW 8 /* private key password */
+#define CRYPTO_CONF_NID 9 /* specify digest name */
+
+#ifdef AUTOKEY
+#ifndef OPENSSL
+#error AUTOKEY should be defined only if OPENSSL is.
+invalidsyntax: AUTOKEY should be defined only if OPENSSL is.
+#endif
+
+#include "openssl/bn.h"
+#include "openssl/evp.h"
+#include "ntp_calendar.h" /* for fields in the cert_info structure */
+
+
+/*
+ * The following bits are set by the CRYPTO_ASSOC message from
+ * the server and are not modified by the client.
+ */
+#define CRYPTO_FLAG_ENAB 0x0001 /* crypto enable */
+#define CRYPTO_FLAG_TAI 0x0002 /* leapseconds table */
+
+#define CRYPTO_FLAG_PRIV 0x0010 /* PC identity scheme */
+#define CRYPTO_FLAG_IFF 0x0020 /* IFF identity scheme */
+#define CRYPTO_FLAG_GQ 0x0040 /* GQ identity scheme */
+#define CRYPTO_FLAG_MV 0x0080 /* MV identity scheme */
+#define CRYPTO_FLAG_MASK 0x00f0 /* identity scheme mask */
+
+/*
+ * The following bits are used by the client during the protocol
+ * exchange.
+ */
+#define CRYPTO_FLAG_CERT 0x0100 /* public key verified */
+#define CRYPTO_FLAG_VRFY 0x0200 /* identity verified */
+#define CRYPTO_FLAG_PROV 0x0400 /* signature verified */
+#define CRYPTO_FLAG_COOK 0x0800 /* cookie verifed */
+#define CRYPTO_FLAG_AUTO 0x1000 /* autokey verified */
+#define CRYPTO_FLAG_SIGN 0x2000 /* certificate signed */
+#define CRYPTO_FLAG_LEAP 0x4000 /* leapsecond values verified */
+#define CRYPTO_FLAG_ALL 0x7f00 /* all mask */
+
+/*
+ * Flags used for certificate management
+ */
+#define CERT_TRUST 0x01 /* certificate is trusted */
+#define CERT_SIGN 0x02 /* certificate is signed */
+#define CERT_VALID 0x04 /* certificate is valid */
+#define CERT_PRIV 0x08 /* certificate is private */
+#define CERT_ERROR 0x80 /* certificate has errors */
+
+/*
+ * Extension field definitions
+ */
+#define CRYPTO_MAXLEN 1024 /* max extension field length */
+#define CRYPTO_VN 2 /* current protocol version number */
+#define CRYPTO_CMD(x) (((CRYPTO_VN << 8) | (x)) << 16)
+#define CRYPTO_NULL CRYPTO_CMD(0) /* no operation */
+#define CRYPTO_ASSOC CRYPTO_CMD(1) /* association */
+#define CRYPTO_CERT CRYPTO_CMD(2) /* certificate */
+#define CRYPTO_COOK CRYPTO_CMD(3) /* cookie value */
+#define CRYPTO_AUTO CRYPTO_CMD(4) /* autokey values */
+#define CRYPTO_LEAP CRYPTO_CMD(5) /* leapsecond values */
+#define CRYPTO_SIGN CRYPTO_CMD(6) /* certificate sign */
+#define CRYPTO_IFF CRYPTO_CMD(7) /* IFF identity scheme */
+#define CRYPTO_GQ CRYPTO_CMD(8) /* GQ identity scheme */
+#define CRYPTO_MV CRYPTO_CMD(9) /* MV identity scheme */
+#define CRYPTO_RESP 0x80000000 /* response */
+#define CRYPTO_ERROR 0x40000000 /* error */
+
+/*
+ * Autokey event codes
+ */
+#define XEVNT_CMD(x) (CRPT_EVENT | (x))
+#define XEVNT_OK XEVNT_CMD(0) /* success */
+#define XEVNT_LEN XEVNT_CMD(1) /* bad field format or length */
+#define XEVNT_TSP XEVNT_CMD(2) /* bad timestamp */
+#define XEVNT_FSP XEVNT_CMD(3) /* bad filestamp */
+#define XEVNT_PUB XEVNT_CMD(4) /* bad or missing public key */
+#define XEVNT_MD XEVNT_CMD(5) /* unsupported digest type */
+#define XEVNT_KEY XEVNT_CMD(6) /* unsupported identity type */
+#define XEVNT_SGL XEVNT_CMD(7) /* bad signature length */
+#define XEVNT_SIG XEVNT_CMD(8) /* signature not verified */
+#define XEVNT_VFY XEVNT_CMD(9) /* certificate not verified */
+#define XEVNT_PER XEVNT_CMD(10) /* host certificate expired */
+#define XEVNT_CKY XEVNT_CMD(11) /* bad or missing cookie */
+#define XEVNT_DAT XEVNT_CMD(12) /* bad or missing leapseconds */
+#define XEVNT_CRT XEVNT_CMD(13) /* bad or missing certificate */
+#define XEVNT_ID XEVNT_CMD(14) /* bad or missing group key */
+#define XEVNT_ERR XEVNT_CMD(15) /* protocol error */
+
+/*
+ * Miscellaneous crypto stuff
+ */
+#define NTP_MAXSESSION 100 /* maximum session key list entries */
+#define NTP_MAXEXTEN 2048 /* maximum extension field size */
+#define NTP_AUTOMAX 12 /* default key list timeout (log2 s) */
+#define KEY_REVOKE 17 /* default key revoke timeout (log2 s) */
+#define NTP_REFRESH 19 /* default restart timeout (log2 s) */
+#define NTP_MAXKEY 65535 /* maximum symmetric key ID */
+
+/*
+ * The autokey structure holds the values used to authenticate key IDs.
+ */
+struct autokey { /* network byte order */
+ keyid_t key; /* key ID */
+ int32 seq; /* key number */
+};
+
+/*
+ * The value structure holds variable length data such as public
+ * key, agreement parameters, public valule and leapsecond table.
+ * They are in network byte order.
+ */
+struct value { /* network byte order */
+ tstamp_t tstamp; /* timestamp */
+ tstamp_t fstamp; /* filestamp */
+ u_int32 vallen; /* value length */
+ void *ptr; /* data pointer (various) */
+ u_int32 siglen; /* signature length */
+ u_char *sig; /* signature */
+};
+
+/*
+ * The packet extension field structures are used to hold values
+ * and signatures in network byte order.
+ */
+struct exten {
+ u_int32 opcode; /* opcode */
+ u_int32 associd; /* association ID */
+ u_int32 tstamp; /* timestamp */
+ u_int32 fstamp; /* filestamp */
+ u_int32 vallen; /* value length */
+ u_int32 pkt[1]; /* start of value field */
+};
+
+
+/*
+ * The certificate info/value structure
+ */
+struct cert_info {
+ struct cert_info *link; /* forward link */
+ u_int flags; /* flags that wave */
+ EVP_PKEY *pkey; /* generic key */
+ long version; /* X509 version */
+ int nid; /* signature/digest ID */
+ const EVP_MD *digest; /* message digest algorithm */
+ u_long serial; /* serial number */
+ struct calendar first; /* not valid before */
+ struct calendar last; /* not valid after */
+ char *subject; /* subject common name */
+ char *issuer; /* issuer common name */
+ BIGNUM *grpkey; /* GQ group key */
+ struct value cert; /* certificate/value */
+};
+
+/*
+ * The keys info/value structure
+ */
+struct pkey_info {
+ struct pkey_info *link; /* forward link */
+ EVP_PKEY *pkey; /* generic key */
+ char *name; /* file name */
+ tstamp_t fstamp; /* filestamp */
+};
+
+/*
+ * Cryptographic values
+ */
+extern u_int crypto_flags; /* status word */
+extern int crypto_nid; /* digest nid */
+extern struct value hostval; /* host name/value */
+extern struct cert_info *cinfo; /* host certificate information */
+extern struct value tai_leap; /* leapseconds table */
+#endif /* AUTOKEY */
+#endif /* NTP_CRYPTO_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntp_debug.h b/sebhbsd/freebsd/contrib/ntp/include/ntp_debug.h
new file mode 100644
index 0000000..b0e846e
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntp_debug.h
@@ -0,0 +1,27 @@
+/*
+ * $Header$
+ *
+ * $Created: Sat Aug 20 14:23:01 2005 $
+ *
+ * Copyright (C) 2005 by Frank Kardel
+ */
+#ifndef NTP_DEBUG_H
+#define NTP_DEBUG_H
+
+/*
+ * macro for debugging output - cut down on #ifdef pollution.
+ *
+ * TRACE() is similar to ntpd's DPRINTF() for utilities and libntp.
+ * Uses mprintf() and so supports %m, replaced by strerror(errno).
+ *
+ * The calling convention is not attractive:
+ * TRACE(debuglevel, (fmt, ...));
+ * TRACE(2, ("this will appear on stdout if debug >= %d\n", 2));
+ */
+#define TRACE(lvl, arg) \
+ do { \
+ if (debug >= (lvl)) \
+ mprintf arg; \
+ } while (0)
+
+#endif /* NTP_DEBUG_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntp_filegen.h b/sebhbsd/freebsd/contrib/ntp/include/ntp_filegen.h
new file mode 100644
index 0000000..549bedb
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntp_filegen.h
@@ -0,0 +1,56 @@
+/*
+ * ntp_filegen.h,v 3.9 1996/12/01 16:02:45 kardel Exp
+ *
+ * definitions for NTP file generations support
+ *
+ *
+ * Copyright (C) 1992, 1996 by Rainer Pruy
+ * Friedrich-Alexander Universitaet Erlangen-Nuernberg, Germany
+ *
+ * This code may be modified and used freely
+ * provided the credits remain intact.
+ */
+
+#include "ntp_types.h"
+
+/*
+ * supported file generation types
+ */
+
+#define FILEGEN_NONE 255 /* no generations - use plain file name */
+#define FILEGEN_PID 1 /* one filegen per process incarnation */
+#define FILEGEN_DAY 2 /* one filegen per day */
+#define FILEGEN_WEEK 3 /* one filegen per week */
+#define FILEGEN_MONTH 4 /* one filegen per month */
+#define FILEGEN_YEAR 5 /* one filegen per year */
+#define FILEGEN_AGE 6 /* change filegen each FG_AGE_SECS */
+
+/*
+ * supported file generation flags
+ */
+
+#define FGEN_FLAG_LINK 0x01 /* make a link to base name */
+
+#define FGEN_FLAG_ENABLED 0x80 /* set this to really create files */
+ /* without this, open is suppressed */
+
+typedef struct filegen_tag {
+ FILE * fp; /* file referring to current generation */
+ char * dir; /* currently always statsdir */
+ char * fname; /* filename prefix of generation file */
+ /* must be malloced, will be fed to free() */
+ u_long id_lo; /* lower bound of ident value */
+ u_long id_hi; /* upper bound of ident value */
+ u_char type; /* type of file generation */
+ u_char flag; /* flags modifying processing of file generation */
+} FILEGEN;
+
+extern void filegen_setup (FILEGEN *, u_int32);
+extern void filegen_config (FILEGEN *, const char *, const char *,
+ u_int, u_int);
+extern void filegen_statsdir(void);
+extern FILEGEN *filegen_get (const char *);
+extern void filegen_register (const char *, const char *, FILEGEN *);
+#ifdef DEBUG
+extern void filegen_unregister(const char *);
+#endif
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntp_fp.h b/sebhbsd/freebsd/contrib/ntp/include/ntp_fp.h
new file mode 100644
index 0000000..2782ebf
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntp_fp.h
@@ -0,0 +1,424 @@
+/*
+ * ntp_fp.h - definitions for NTP fixed/floating-point arithmetic
+ */
+
+#ifndef NTP_FP_H
+#define NTP_FP_H
+
+#include "ntp_types.h"
+
+/*
+ * NTP uses two fixed point formats. The first (l_fp) is the "long"
+ * format and is 64 bits long with the decimal between bits 31 and 32.
+ * This is used for time stamps in the NTP packet header (in network
+ * byte order) and for internal computations of offsets (in local host
+ * byte order). We use the same structure for both signed and unsigned
+ * values, which is a big hack but saves rewriting all the operators
+ * twice. Just to confuse this, we also sometimes just carry the
+ * fractional part in calculations, in both signed and unsigned forms.
+ * Anyway, an l_fp looks like:
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Integral Part |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Fractional Part |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+typedef struct {
+ union {
+ u_int32 Xl_ui;
+ int32 Xl_i;
+ } Ul_i;
+ u_int32 l_uf;
+} l_fp;
+
+#define l_ui Ul_i.Xl_ui /* unsigned integral part */
+#define l_i Ul_i.Xl_i /* signed integral part */
+
+/*
+ * Fractional precision (of an l_fp) is actually the number of
+ * bits in a long.
+ */
+#define FRACTION_PREC (32)
+
+
+/*
+ * The second fixed point format is 32 bits, with the decimal between
+ * bits 15 and 16. There is a signed version (s_fp) and an unsigned
+ * version (u_fp). This is used to represent synchronizing distance
+ * and synchronizing dispersion in the NTP packet header (again, in
+ * network byte order) and internally to hold both distance and
+ * dispersion values (in local byte order). In network byte order
+ * it looks like:
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Integer Part | Fraction Part |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+typedef int32 s_fp;
+typedef u_int32 u_fp;
+
+/*
+ * A unit second in fp format. Actually 2**(half_the_bits_in_a_long)
+ */
+#define FP_SECOND (0x10000)
+
+/*
+ * Byte order conversions
+ */
+#define HTONS_FP(x) (htonl(x))
+#define NTOHS_FP(x) (ntohl(x))
+
+#define NTOHL_MFP(ni, nf, hi, hf) \
+ do { \
+ (hi) = ntohl(ni); \
+ (hf) = ntohl(nf); \
+ } while (FALSE)
+
+#define HTONL_MFP(hi, hf, ni, nf) \
+ do { \
+ (ni) = htonl(hi); \
+ (nf) = htonl(hf); \
+ } while (FALSE)
+
+#define HTONL_FP(h, n) \
+ HTONL_MFP((h)->l_ui, (h)->l_uf, (n)->l_ui, (n)->l_uf)
+
+#define NTOHL_FP(n, h) \
+ NTOHL_MFP((n)->l_ui, (n)->l_uf, (h)->l_ui, (h)->l_uf)
+
+/* Convert unsigned ts fraction to net order ts */
+#define HTONL_UF(uf, nts) \
+ do { \
+ (nts)->l_ui = 0; \
+ (nts)->l_uf = htonl(uf); \
+ } while (FALSE)
+
+/*
+ * Conversions between the two fixed point types
+ */
+#define MFPTOFP(x_i, x_f) (((x_i) >= 0x00010000) ? 0x7fffffff : \
+ (((x_i) <= -0x00010000) ? 0x80000000 : \
+ (((x_i)<<16) | (((x_f)>>16)&0xffff))))
+#define LFPTOFP(v) MFPTOFP((v)->l_i, (v)->l_uf)
+
+#define UFPTOLFP(x, v) ((v)->l_ui = (u_fp)(x)>>16, (v)->l_uf = (x)<<16)
+#define FPTOLFP(x, v) (UFPTOLFP((x), (v)), (x) < 0 ? (v)->l_ui -= 0x10000 : 0)
+
+#define MAXLFP(v) ((v)->l_ui = 0x7fffffffu, (v)->l_uf = 0xffffffffu)
+#define MINLFP(v) ((v)->l_ui = 0x80000000u, (v)->l_uf = 0u)
+
+/*
+ * Primitive operations on long fixed point values. If these are
+ * reminiscent of assembler op codes it's only because some may
+ * be replaced by inline assembler for particular machines someday.
+ * These are the (kind of inefficient) run-anywhere versions.
+ */
+#define M_NEG(v_i, v_f) /* v = -v */ \
+ do { \
+ (v_f) = ~(v_f) + 1u; \
+ (v_i) = ~(v_i) + ((v_f) == 0); \
+ } while (FALSE)
+
+#define M_NEGM(r_i, r_f, a_i, a_f) /* r = -a */ \
+ do { \
+ (r_f) = ~(a_f) + 1u; \
+ (r_i) = ~(a_i) + ((r_f) == 0); \
+ } while (FALSE)
+
+#define M_ADD(r_i, r_f, a_i, a_f) /* r += a */ \
+ do { \
+ u_int32 add_t = (r_f); \
+ (r_f) += (a_f); \
+ (r_i) += (a_i) + ((u_int32)(r_f) < add_t); \
+ } while (FALSE)
+
+#define M_ADD3(r_o, r_i, r_f, a_o, a_i, a_f) /* r += a, three word */ \
+ do { \
+ u_int32 add_t, add_c; \
+ add_t = (r_f); \
+ (r_f) += (a_f); \
+ add_c = ((u_int32)(r_f) < add_t); \
+ (r_i) += add_c; \
+ add_c = ((u_int32)(r_i) < add_c); \
+ add_t = (r_i); \
+ (r_i) += (a_i); \
+ add_c |= ((u_int32)(r_i) < add_t); \
+ (r_o) += (a_o) + add_c; \
+ } while (FALSE)
+
+#define M_SUB(r_i, r_f, a_i, a_f) /* r -= a */ \
+ do { \
+ u_int32 sub_t = (r_f); \
+ (r_f) -= (a_f); \
+ (r_i) -= (a_i) + ((u_int32)(r_f) > sub_t); \
+ } while (FALSE)
+
+#define M_RSHIFTU(v_i, v_f) /* v >>= 1, v is unsigned */ \
+ do { \
+ (v_f) = ((u_int32)(v_f) >> 1) | ((u_int32)(v_i) << 31); \
+ (v_i) = ((u_int32)(v_i) >> 1); \
+ } while (FALSE)
+
+#define M_RSHIFT(v_i, v_f) /* v >>= 1, v is signed */ \
+ do { \
+ (v_f) = ((u_int32)(v_f) >> 1) | ((u_int32)(v_i) << 31); \
+ (v_i) = ((u_int32)(v_i) >> 1) | ((u_int32)(v_i) & 0x80000000); \
+ } while (FALSE)
+
+#define M_LSHIFT(v_i, v_f) /* v <<= 1 */ \
+ do { \
+ (v_i) = ((u_int32)(v_i) << 1) | ((u_int32)(v_f) >> 31); \
+ (v_f) = ((u_int32)(v_f) << 1); \
+ } while (FALSE)
+
+#define M_LSHIFT3(v_o, v_i, v_f) /* v <<= 1, with overflow */ \
+ do { \
+ (v_o) = ((u_int32)(v_o) << 1) | ((u_int32)(v_i) >> 31); \
+ (v_i) = ((u_int32)(v_i) << 1) | ((u_int32)(v_f) >> 31); \
+ (v_f) = ((u_int32)(v_f) << 1); \
+ } while (FALSE)
+
+#define M_ADDUF(r_i, r_f, uf) /* r += uf, uf is u_int32 fraction */ \
+ M_ADD((r_i), (r_f), 0, (uf)) /* let optimizer worry about it */
+
+#define M_SUBUF(r_i, r_f, uf) /* r -= uf, uf is u_int32 fraction */ \
+ M_SUB((r_i), (r_f), 0, (uf)) /* let optimizer worry about it */
+
+#define M_ADDF(r_i, r_f, f) /* r += f, f is a int32 fraction */ \
+ do { \
+ int32 add_f = (int32)(f); \
+ if (add_f >= 0) \
+ M_ADD((r_i), (r_f), 0, (uint32)( add_f)); \
+ else \
+ M_SUB((r_i), (r_f), 0, (uint32)(-add_f)); \
+ } while(0)
+
+#define M_ISNEG(v_i) /* v < 0 */ \
+ (((v_i) & 0x80000000) != 0)
+
+#define M_ISGT(a_i, a_f, b_i, b_f) /* a > b signed */ \
+ (((u_int32)((a_i) ^ 0x80000000) > (u_int32)((b_i) ^ 0x80000000)) || \
+ ((a_i) == (b_i) && ((u_int32)(a_f)) > ((u_int32)(b_f))))
+
+#define M_ISGTU(a_i, a_f, b_i, b_f) /* a > b unsigned */ \
+ (((u_int32)(a_i)) > ((u_int32)(b_i)) || \
+ ((a_i) == (b_i) && ((u_int32)(a_f)) > ((u_int32)(b_f))))
+
+#define M_ISHIS(a_i, a_f, b_i, b_f) /* a >= b unsigned */ \
+ (((u_int32)(a_i)) > ((u_int32)(b_i)) || \
+ ((a_i) == (b_i) && ((u_int32)(a_f)) >= ((u_int32)(b_f))))
+
+#define M_ISGEQ(a_i, a_f, b_i, b_f) /* a >= b signed */ \
+ (((u_int32)((a_i) ^ 0x80000000) > (u_int32)((b_i) ^ 0x80000000)) || \
+ ((a_i) == (b_i) && (u_int32)(a_f) >= (u_int32)(b_f)))
+
+#define M_ISEQU(a_i, a_f, b_i, b_f) /* a == b unsigned */ \
+ ((u_int32)(a_i) == (u_int32)(b_i) && (u_int32)(a_f) == (u_int32)(b_f))
+
+/*
+ * Operations on the long fp format
+ */
+#define L_ADD(r, a) M_ADD((r)->l_ui, (r)->l_uf, (a)->l_ui, (a)->l_uf)
+#define L_SUB(r, a) M_SUB((r)->l_ui, (r)->l_uf, (a)->l_ui, (a)->l_uf)
+#define L_NEG(v) M_NEG((v)->l_ui, (v)->l_uf)
+#define L_ADDUF(r, uf) M_ADDUF((r)->l_ui, (r)->l_uf, (uf))
+#define L_SUBUF(r, uf) M_SUBUF((r)->l_ui, (r)->l_uf, (uf))
+#define L_ADDF(r, f) M_ADDF((r)->l_ui, (r)->l_uf, (f))
+#define L_RSHIFT(v) M_RSHIFT((v)->l_i, (v)->l_uf)
+#define L_RSHIFTU(v) M_RSHIFTU((v)->l_ui, (v)->l_uf)
+#define L_LSHIFT(v) M_LSHIFT((v)->l_ui, (v)->l_uf)
+#define L_CLR(v) ((v)->l_ui = (v)->l_uf = 0)
+
+#define L_ISNEG(v) M_ISNEG((v)->l_ui)
+#define L_ISZERO(v) (((v)->l_ui | (v)->l_uf) == 0)
+#define L_ISGT(a, b) M_ISGT((a)->l_i, (a)->l_uf, (b)->l_i, (b)->l_uf)
+#define L_ISGTU(a, b) M_ISGTU((a)->l_ui, (a)->l_uf, (b)->l_ui, (b)->l_uf)
+#define L_ISHIS(a, b) M_ISHIS((a)->l_ui, (a)->l_uf, (b)->l_ui, (b)->l_uf)
+#define L_ISGEQ(a, b) M_ISGEQ((a)->l_ui, (a)->l_uf, (b)->l_ui, (b)->l_uf)
+#define L_ISEQU(a, b) M_ISEQU((a)->l_ui, (a)->l_uf, (b)->l_ui, (b)->l_uf)
+
+/*
+ * s_fp/double and u_fp/double conversions
+ */
+#define FRIC 65536.0 /* 2^16 as a double */
+#define DTOFP(r) ((s_fp)((r) * FRIC))
+#define DTOUFP(r) ((u_fp)((r) * FRIC))
+#define FPTOD(r) ((double)(r) / FRIC)
+
+/*
+ * l_fp/double conversions
+ */
+#define FRAC 4294967296.0 /* 2^32 as a double */
+
+/*
+ * Use 64 bit integers if available. Solaris on SPARC has a problem
+ * compiling parsesolaris.c if ntp_fp.h includes math.h, due to
+ * archaic gets() and printf() prototypes used in Solaris kernel
+ * headers. So far the problem has only been seen with gcc, but it
+ * may also affect Sun compilers, in which case the defined(__GNUC__)
+ * term should be removed.
+ * XSCALE also generates bad code for these, at least with GCC 3.3.5.
+ * This is unrelated to math.h, but the same solution applies.
+ */
+#if defined(HAVE_U_INT64) && \
+ !(defined(__SVR4) && defined(__sun) && \
+ defined(sparc) && defined(__GNUC__) || \
+ defined(__arm__) && defined(__XSCALE__) && defined(__GNUC__))
+
+#include <math.h> /* ldexp() */
+
+#define M_DTOLFP(d, r_ui, r_uf) /* double to l_fp */ \
+ do { \
+ double d_tmp; \
+ u_int64 q_tmp; \
+ int M_isneg; \
+ \
+ d_tmp = (d); \
+ M_isneg = (d_tmp < 0.); \
+ if (M_isneg) { \
+ d_tmp = -d_tmp; \
+ } \
+ q_tmp = (u_int64)ldexp(d_tmp, 32); \
+ if (M_isneg) { \
+ q_tmp = ~q_tmp + 1; \
+ } \
+ (r_uf) = (u_int32)q_tmp; \
+ (r_ui) = (u_int32)(q_tmp >> 32); \
+ } while (FALSE)
+
+#define M_LFPTOD(r_ui, r_uf, d) /* l_fp to double */ \
+ do { \
+ double d_tmp; \
+ u_int64 q_tmp; \
+ int M_isneg; \
+ \
+ q_tmp = ((u_int64)(r_ui) << 32) + (r_uf); \
+ M_isneg = M_ISNEG(r_ui); \
+ if (M_isneg) { \
+ q_tmp = ~q_tmp + 1; \
+ } \
+ d_tmp = ldexp((double)q_tmp, -32); \
+ if (M_isneg) { \
+ d_tmp = -d_tmp; \
+ } \
+ (d) = d_tmp; \
+ } while (FALSE)
+
+#else /* use only 32 bit unsigned values */
+
+#define M_DTOLFP(d, r_ui, r_uf) /* double to l_fp */ \
+ do { \
+ double d_tmp; \
+ if ((d_tmp = (d)) < 0) { \
+ (r_ui) = (u_int32)(-d_tmp); \
+ (r_uf) = (u_int32)(-(d_tmp + (double)(r_ui)) * FRAC); \
+ M_NEG((r_ui), (r_uf)); \
+ } else { \
+ (r_ui) = (u_int32)d_tmp; \
+ (r_uf) = (u_int32)((d_tmp - (double)(r_ui)) * FRAC); \
+ } \
+ } while (0)
+#define M_LFPTOD(r_ui, r_uf, d) /* l_fp to double */ \
+ do { \
+ u_int32 l_thi, l_tlo; \
+ l_thi = (r_ui); l_tlo = (r_uf); \
+ if (M_ISNEG(l_thi)) { \
+ M_NEG(l_thi, l_tlo); \
+ (d) = -((double)l_thi + (double)l_tlo / FRAC); \
+ } else { \
+ (d) = (double)l_thi + (double)l_tlo / FRAC; \
+ } \
+ } while (0)
+#endif
+
+#define DTOLFP(d, v) M_DTOLFP((d), (v)->l_ui, (v)->l_uf)
+#define LFPTOD(v, d) M_LFPTOD((v)->l_ui, (v)->l_uf, (d))
+
+/*
+ * Prototypes
+ */
+extern char * dofptoa (u_fp, int, short, int);
+extern char * dolfptoa (u_int32, u_int32, int, short, int);
+
+extern int atolfp (const char *, l_fp *);
+extern int buftvtots (const char *, l_fp *);
+extern char * fptoa (s_fp, short);
+extern char * fptoms (s_fp, short);
+extern int hextolfp (const char *, l_fp *);
+extern void gpstolfp (u_int, u_int, unsigned long, l_fp *);
+extern int mstolfp (const char *, l_fp *);
+extern char * prettydate (l_fp *);
+extern char * gmprettydate (l_fp *);
+extern char * uglydate (l_fp *);
+extern void mfp_mul (int32 *, u_int32 *, int32, u_int32, int32, u_int32);
+
+extern void set_sys_fuzz (double);
+extern void init_systime (void);
+extern void get_systime (l_fp *);
+extern int step_systime (double);
+extern int adj_systime (double);
+extern int clamp_systime (void);
+
+extern struct tm * ntp2unix_tm (u_int32 ntp, int local);
+
+#define lfptoa(fpv, ndec) mfptoa((fpv)->l_ui, (fpv)->l_uf, (ndec))
+#define lfptoms(fpv, ndec) mfptoms((fpv)->l_ui, (fpv)->l_uf, (ndec))
+
+#define stoa(addr) socktoa(addr)
+#define ntoa(addr) stoa(addr)
+#define sptoa(addr) sockporttoa(addr)
+#define stohost(addr) socktohost(addr)
+
+#define ufptoa(fpv, ndec) dofptoa((fpv), 0, (ndec), 0)
+#define ufptoms(fpv, ndec) dofptoa((fpv), 0, (ndec), 1)
+#define ulfptoa(fpv, ndec) dolfptoa((fpv)->l_ui, (fpv)->l_uf, 0, (ndec), 0)
+#define ulfptoms(fpv, ndec) dolfptoa((fpv)->l_ui, (fpv)->l_uf, 0, (ndec), 1)
+#define umfptoa(fpi, fpf, ndec) dolfptoa((fpi), (fpf), 0, (ndec), 0)
+
+/*
+ * Optional callback from libntp step_systime() to ntpd. Optional
+* because other libntp clients like ntpdate don't use it.
+ */
+typedef void (*time_stepped_callback)(void);
+extern time_stepped_callback step_callback;
+
+/*
+ * Multi-thread locking for get_systime()
+ *
+ * On most systems, get_systime() is used solely by the main ntpd
+ * thread, but on Windows it's also used by the dedicated I/O thread.
+ * The [Bug 2037] changes to get_systime() have it keep state between
+ * calls to ensure time moves in only one direction, which means its
+ * use on Windows needs to be protected against simultaneous execution
+ * to avoid falsely detecting Lamport violations by ensuring only one
+ * thread at a time is in get_systime().
+ */
+#ifdef SYS_WINNT
+extern CRITICAL_SECTION get_systime_cs;
+# define INIT_GET_SYSTIME_CRITSEC() \
+ InitializeCriticalSection(&get_systime_cs)
+# define ENTER_GET_SYSTIME_CRITSEC() \
+ EnterCriticalSection(&get_systime_cs)
+# define LEAVE_GET_SYSTIME_CRITSEC() \
+ LeaveCriticalSection(&get_systime_cs)
+# define INIT_WIN_PRECISE_TIME() \
+ init_win_precise_time()
+#else /* !SYS_WINNT follows */
+# define INIT_GET_SYSTIME_CRITSEC() \
+ do {} while (FALSE)
+# define ENTER_GET_SYSTIME_CRITSEC() \
+ do {} while (FALSE)
+# define LEAVE_GET_SYSTIME_CRITSEC() \
+ do {} while (FALSE)
+# define INIT_WIN_PRECISE_TIME() \
+ do {} while (FALSE)
+#endif
+
+#endif /* NTP_FP_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntp_if.h b/sebhbsd/freebsd/contrib/ntp/include/ntp_if.h
new file mode 100644
index 0000000..3af5865
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntp_if.h
@@ -0,0 +1,27 @@
+/*
+ * Sockets are not standard.
+ * So hide uglyness in include file.
+ */
+/* was: defined(SYS_CONVEXOS9) */
+#if defined(HAVE__SYS_SYNC_QUEUE_H) && defined(HAVE__SYS_SYNC_SEMA_H)
+# include "/sys/sync/queue.h"
+# include "/sys/sync/sema.h"
+#endif
+
+/* was: (defined(SYS_SOLARIS) && !defined(bsd)) || defined(SYS_SUNOS4) */
+/* was: defined(SYS_UNIXWARE1) */
+#ifdef HAVE_SYS_SOCKIO_H
+# include <sys/sockio.h>
+#endif
+
+/* was: #if defined(SYS_PTX) || defined(SYS_SINIXM) */
+#ifdef HAVE_SYS_STREAM_H
+# include <sys/stream.h>
+#endif
+#ifdef HAVE_SYS_STROPTS_H
+# include <sys/stropts.h>
+#endif
+
+#ifdef HAVE_NET_IF_H
+# include <net/if.h>
+#endif /* HAVE_NET_IF_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntp_intres.h b/sebhbsd/freebsd/contrib/ntp/include/ntp_intres.h
new file mode 100644
index 0000000..1109130
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntp_intres.h
@@ -0,0 +1,51 @@
+/*
+ * ntp_intres.h - client interface to blocking-worker name resolution.
+ */
+#ifndef NTP_INTRES_H
+#define NTP_INTRES_H
+
+#include <ntp_worker.h>
+
+#ifdef WORKER
+#define INITIAL_DNS_RETRY 2 /* seconds between queries */
+
+/* flags for extended addrinfo version */
+#define GAIR_F_IGNDNSERR 0x0001 /* ignore DNS errors */
+
+/*
+ * you call getaddrinfo_sometime(name, service, &hints, retry, callback_func, context);
+ * later (*callback_func)(rescode, gai_errno, context, name, service, hints, ai_result) is called.
+ */
+typedef void (*gai_sometime_callback)
+ (int, int, void *, const char *, const char *,
+ const struct addrinfo *, const struct addrinfo *);
+extern int getaddrinfo_sometime(const char *, const char *,
+ const struct addrinfo *, int,
+ gai_sometime_callback, void *);
+extern int getaddrinfo_sometime_ex(const char *, const char *,
+ const struct addrinfo *, int,
+ gai_sometime_callback, void *, u_int);
+/*
+ * In gai_sometime_callback routines, the resulting addrinfo list is
+ * only available until the callback returns. To hold on to the list
+ * of addresses after the callback returns, use copy_addrinfo_list():
+ *
+ * struct addrinfo *copy_addrinfo_list(const struct addrinfo *);
+ */
+
+
+/*
+ * you call getnameinfo_sometime(sockaddr, namelen, servlen, flags, callback_func, context);
+ * later (*callback_func)(rescode, gni_errno, sockaddr, flags, name, service, context) is called.
+ */
+typedef void (*gni_sometime_callback)
+ (int, int, sockaddr_u *, int, const char *,
+ const char *, void *);
+extern int getnameinfo_sometime(sockaddr_u *, size_t, size_t, int,
+ gni_sometime_callback, void *);
+#endif /* WORKER */
+
+/* intres_timeout_req() is provided by the client, ntpd or sntp. */
+extern void intres_timeout_req(u_int);
+
+#endif /* NTP_INTRES_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntp_io.h b/sebhbsd/freebsd/contrib/ntp/include/ntp_io.h
new file mode 100644
index 0000000..d34d60a
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntp_io.h
@@ -0,0 +1,99 @@
+#ifndef NTP_IO_H
+#define NTP_IO_H
+
+#include "ntp_workimpl.h"
+
+/*
+ * POSIX says use <fnct.h> to get O_* symbols and
+ * SEEK_SET symbol form <unistd.h>.
+ */
+#include <sys/types.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#include <stdio.h>
+#ifdef HAVE_SYS_FILE_H
+# include <sys/file.h>
+#endif
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+#if !defined(SEEK_SET) && defined(L_SET)
+# define SEEK_SET L_SET
+#endif
+
+#ifdef SYS_WINNT
+# include <io.h>
+# include "win32_io.h"
+#endif
+
+#include <isc/boolean.h>
+#include <isc/netaddr.h>
+
+#if defined(HAVE_NETINET_IN_H) && defined(HAVE_NETINET_IP_H)
+# include <netinet/in.h>
+# ifdef HAVE_NETINET_IN_SYSTM_H
+# include <netinet/in_systm.h>
+# endif
+# include <netinet/ip.h>
+#endif
+
+#include "libntp.h" /* This needs Something above for GETDTABLESIZE */
+
+#include "ntp_keyacc.h"
+
+/*
+ * Define FNDELAY and FASYNC using O_NONBLOCK and O_ASYNC if we need
+ * to (and can). This is here initially for QNX, but may help for
+ * others as well...
+ */
+#ifndef FNDELAY
+# ifdef O_NONBLOCK
+# define FNDELAY O_NONBLOCK
+# endif
+#endif
+
+#ifndef FASYNC
+# ifdef O_ASYNC
+# define FASYNC O_ASYNC
+# endif
+#endif
+
+
+/*
+ * NIC rule match types
+ */
+typedef enum {
+ MATCH_ALL,
+ MATCH_IPV4,
+ MATCH_IPV6,
+ MATCH_WILDCARD,
+ MATCH_IFNAME,
+ MATCH_IFADDR
+} nic_rule_match;
+
+/*
+ * NIC rule actions
+ */
+typedef enum {
+ ACTION_LISTEN,
+ ACTION_IGNORE,
+ ACTION_DROP
+} nic_rule_action;
+
+
+extern int qos;
+SOCKET move_fd(SOCKET fd);
+isc_boolean_t get_broadcastclient_flag(void);
+extern void sau_from_netaddr(sockaddr_u *, const isc_netaddr_t *);
+extern void add_nic_rule(nic_rule_match match_type,
+ const char *if_name, int prefixlen,
+ nic_rule_action action);
+#ifndef HAVE_IO_COMPLETION_PORT
+extern void maintain_activefds(int fd, int closing);
+#else
+#define maintain_activefds(f, c) do {} while (0)
+#endif
+
+
+#endif /* NTP_IO_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntp_keyacc.h b/sebhbsd/freebsd/contrib/ntp/include/ntp_keyacc.h
new file mode 100644
index 0000000..f497b62
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntp_keyacc.h
@@ -0,0 +1,25 @@
+/*
+ * ntp_keyacc.h - key access stuff
+ */
+#ifndef NTP_KEYACC_H
+#define NTP_KEYACC_H
+
+typedef struct keyaccess KeyAccT;
+struct keyaccess {
+ KeyAccT * next;
+ sockaddr_u addr;
+ unsigned int subnetbits;
+};
+
+extern KeyAccT* keyacc_new_push(KeyAccT *head, const sockaddr_u *addr,
+ unsigned int subnetbits);
+extern KeyAccT* keyacc_pop_free(KeyAccT *head);
+extern KeyAccT* keyacc_all_free(KeyAccT *head);
+extern int keyacc_contains(const KeyAccT *head, const sockaddr_u *addr,
+ int res_on_empty_list);
+/* public for testability: */
+extern int keyacc_amatch(const sockaddr_u *,const sockaddr_u *,
+ unsigned int mbits);
+
+
+#endif /* NTP_KEYACC_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntp_libopts.h b/sebhbsd/freebsd/contrib/ntp/include/ntp_libopts.h
new file mode 100644
index 0000000..b03b2f6
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntp_libopts.h
@@ -0,0 +1,14 @@
+/*
+ * ntp_libopts.h
+ *
+ * Common code interfacing with Autogen's libopts command-line option
+ * processing.
+ */
+#ifndef NTP_LIBOPTS_H
+# define NTP_LIBOPTS_H
+# include "autoopts/options.h"
+
+extern int ntpOptionProcess(tOptions *pOpts, int argc,
+ char ** argv);
+extern void ntpOptionPrintVersion(tOptions *, tOptDesc *);
+#endif
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntp_lists.h b/sebhbsd/freebsd/contrib/ntp/include/ntp_lists.h
new file mode 100644
index 0000000..d741974
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntp_lists.h
@@ -0,0 +1,443 @@
+/*
+ * ntp_lists.h - linked lists common code
+ *
+ * SLIST: singly-linked lists
+ * ==========================
+ *
+ * These macros implement a simple singly-linked list template. Both
+ * the listhead and per-entry next fields are declared as pointers to
+ * the list entry struct type. Initialization to NULL is typically
+ * implicit (for globals and statics) or handled by zeroing of the
+ * containing structure.
+ *
+ * The name of the next link field is passed as an argument to allow
+ * membership in several lists at once using multiple next link fields.
+ *
+ * When possible, placing the link field first in the entry structure
+ * allows slightly smaller code to be generated on some platforms.
+ *
+ * LINK_SLIST(listhead, pentry, nextlink)
+ * add entry at head
+ *
+ * LINK_TAIL_SLIST(listhead, pentry, nextlink, entrytype)
+ * add entry at tail. This is O(n), if this is a common
+ * operation the FIFO template may be more appropriate.
+ *
+ * LINK_SORT_SLIST(listhead, pentry, beforecur, nextlink, entrytype)
+ * add entry in sorted order. beforecur is an expression comparing
+ * pentry with the current list entry. The current entry can be
+ * referenced within beforecur as L_S_S_CUR(), which is short for
+ * LINK_SORT_SLIST_CUR(). beforecur is nonzero if pentry sorts
+ * before L_S_S_CUR().
+ *
+ * UNLINK_HEAD_SLIST(punlinked, listhead, nextlink)
+ * unlink first entry and point punlinked to it, or set punlinked
+ * to NULL if the list is empty.
+ *
+ * UNLINK_SLIST(punlinked, listhead, ptounlink, nextlink, entrytype)
+ * unlink entry pointed to by ptounlink. punlinked is set to NULL
+ * if the entry is not found on the list, otherwise it is set to
+ * ptounlink.
+ *
+ * UNLINK_EXPR_SLIST(punlinked, listhead, expr, nextlink, entrytype)
+ * unlink entry where expression expr is nonzero. expr can refer
+ * to the entry being tested using UNLINK_EXPR_SLIST_CURRENT(),
+ * alias U_E_S_CUR(). See the implementation of UNLINK_SLIST()
+ * below for an example. U_E_S_CUR() is NULL iff the list is empty.
+ * punlinked is pointed to the removed entry or NULL if none
+ * satisfy expr.
+ *
+ * FIFO: singly-linked lists plus tail pointer
+ * ===========================================
+ *
+ * This is the same as FreeBSD's sys/queue.h STAILQ -- a singly-linked
+ * list implementation with tail-pointer maintenance, so that adding
+ * at the tail for first-in, first-out access is O(1).
+ *
+ * DECL_FIFO_ANCHOR(entrytype)
+ * provides the type specification portion of the declaration for
+ * a variable to refer to a FIFO queue (similar to listhead). The
+ * anchor contains the head and indirect tail pointers. Example:
+ *
+ * #include "ntp_lists.h"
+ *
+ * typedef struct myentry_tag myentry;
+ * struct myentry_tag {
+ * myentry *next_link;
+ * ...
+ * };
+ *
+ * DECL_FIFO_ANCHOR(myentry) my_fifo;
+ *
+ * void somefunc(myentry *pentry)
+ * {
+ * LINK_FIFO(my_fifo, pentry, next_link);
+ * }
+ *
+ * If DECL_FIFO_ANCHOR is used with stack or heap storage, it
+ * should be initialized to NULL pointers using a = { NULL };
+ * initializer or memset.
+ *
+ * HEAD_FIFO(anchor)
+ * TAIL_FIFO(anchor)
+ * Pointer to first/last entry, NULL if FIFO is empty.
+ *
+ * LINK_FIFO(anchor, pentry, nextlink)
+ * add entry at tail.
+ *
+ * UNLINK_FIFO(punlinked, anchor, nextlink)
+ * unlink head entry and point punlinked to it, or set punlinked
+ * to NULL if the list is empty.
+ *
+ * CONCAT_FIFO(q1, q2, nextlink)
+ * empty fifoq q2 moving its nodes to q1 following q1's existing
+ * nodes.
+ *
+ * DLIST: doubly-linked lists
+ * ==========================
+ *
+ * Elements on DLISTs always have non-NULL forward and back links,
+ * because both link chains are circular. The beginning/end is marked
+ * by the listhead, which is the same type as elements for simplicity.
+ * An empty list's listhead has both links set to its own address.
+ *
+ *
+ */
+#ifndef NTP_LISTS_H
+#define NTP_LISTS_H
+
+#include "ntp_types.h" /* TRUE and FALSE */
+#include "ntp_assert.h"
+
+#ifdef DEBUG
+# define NTP_DEBUG_LISTS_H
+#endif
+
+/*
+ * If list debugging is not enabled, save a little time by not clearing
+ * an entry's link pointer when it is unlinked, as the stale pointer
+ * is harmless as long as it is ignored when the entry is not in a
+ * list.
+ */
+#ifndef NTP_DEBUG_LISTS_H
+#define MAYBE_Z_LISTS(p) do { } while (FALSE)
+#else
+#define MAYBE_Z_LISTS(p) (p) = NULL
+#endif
+
+#define LINK_SLIST(listhead, pentry, nextlink) \
+do { \
+ (pentry)->nextlink = (listhead); \
+ (listhead) = (pentry); \
+} while (FALSE)
+
+#define LINK_TAIL_SLIST(listhead, pentry, nextlink, entrytype) \
+do { \
+ entrytype **pptail; \
+ \
+ pptail = &(listhead); \
+ while (*pptail != NULL) \
+ pptail = &((*pptail)->nextlink); \
+ \
+ (pentry)->nextlink = NULL; \
+ *pptail = (pentry); \
+} while (FALSE)
+
+#define LINK_SORT_SLIST_CURRENT() (*ppentry)
+#define L_S_S_CUR() LINK_SORT_SLIST_CURRENT()
+
+#define LINK_SORT_SLIST(listhead, pentry, beforecur, nextlink, \
+ entrytype) \
+do { \
+ entrytype **ppentry; \
+ \
+ ppentry = &(listhead); \
+ while (TRUE) { \
+ if (NULL == *ppentry || (beforecur)) { \
+ (pentry)->nextlink = *ppentry; \
+ *ppentry = (pentry); \
+ break; \
+ } \
+ ppentry = &((*ppentry)->nextlink); \
+ if (NULL == *ppentry) { \
+ (pentry)->nextlink = NULL; \
+ *ppentry = (pentry); \
+ break; \
+ } \
+ } \
+} while (FALSE)
+
+#define UNLINK_HEAD_SLIST(punlinked, listhead, nextlink) \
+do { \
+ (punlinked) = (listhead); \
+ if (NULL != (punlinked)) { \
+ (listhead) = (punlinked)->nextlink; \
+ MAYBE_Z_LISTS((punlinked)->nextlink); \
+ } \
+} while (FALSE)
+
+#define UNLINK_EXPR_SLIST_CURRENT() (*ppentry)
+#define U_E_S_CUR() UNLINK_EXPR_SLIST_CURRENT()
+
+#define UNLINK_EXPR_SLIST(punlinked, listhead, expr, nextlink, \
+ entrytype) \
+do { \
+ entrytype **ppentry; \
+ \
+ ppentry = &(listhead); \
+ \
+ while (!(expr)) \
+ if (*ppentry != NULL && \
+ (*ppentry)->nextlink != NULL) { \
+ ppentry = &((*ppentry)->nextlink); \
+ } else { \
+ ppentry = NULL; \
+ break; \
+ } \
+ \
+ if (ppentry != NULL) { \
+ (punlinked) = *ppentry; \
+ *ppentry = (punlinked)->nextlink; \
+ MAYBE_Z_LISTS((punlinked)->nextlink); \
+ } else { \
+ (punlinked) = NULL; \
+ } \
+} while (FALSE)
+
+#define UNLINK_SLIST(punlinked, listhead, ptounlink, nextlink, \
+ entrytype) \
+ UNLINK_EXPR_SLIST(punlinked, listhead, (ptounlink) == \
+ U_E_S_CUR(), nextlink, entrytype)
+
+#define CHECK_SLIST(listhead, nextlink, entrytype) \
+do { \
+ entrytype *pentry; \
+ \
+ for (pentry = (listhead); \
+ pentry != NULL; \
+ pentry = pentry->nextlink) { \
+ INSIST(pentry != pentry->nextlink); \
+ INSIST((listhead) != pentry->nextlink); \
+ } \
+} while (FALSE)
+
+/*
+ * FIFO
+ */
+
+#define DECL_FIFO_ANCHOR(entrytype) \
+struct { \
+ entrytype * phead; /* NULL if list empty */ \
+ entrytype ** pptail; /* NULL if list empty */ \
+}
+
+#define HEAD_FIFO(anchor) ((anchor).phead)
+#define TAIL_FIFO(anchor) ((NULL == (anchor).pptail) \
+ ? NULL \
+ : *((anchor).pptail))
+
+/*
+ * For DEBUG builds only, verify both or neither of the anchor pointers
+ * are NULL with each operation.
+ */
+#if !defined(NTP_DEBUG_LISTS_H)
+#define CHECK_FIFO_CONSISTENCY(anchor) do { } while (FALSE)
+#else
+#define CHECK_FIFO_CONSISTENCY(anchor) \
+ check_gen_fifo_consistency(&(anchor))
+void check_gen_fifo_consistency(void *fifo);
+#endif
+
+/*
+ * generic FIFO element used to access any FIFO where each element
+ * begins with the link pointer
+ */
+typedef struct gen_node_tag gen_node;
+struct gen_node_tag {
+ gen_node * link;
+};
+
+/* generic FIFO */
+typedef DECL_FIFO_ANCHOR(gen_node) gen_fifo;
+
+
+#define LINK_FIFO(anchor, pentry, nextlink) \
+do { \
+ CHECK_FIFO_CONSISTENCY(anchor); \
+ \
+ (pentry)->nextlink = NULL; \
+ if (NULL != (anchor).pptail) { \
+ (*((anchor).pptail))->nextlink = (pentry); \
+ (anchor).pptail = \
+ &(*((anchor).pptail))->nextlink; \
+ } else { \
+ (anchor).phead = (pentry); \
+ (anchor).pptail = &(anchor).phead; \
+ } \
+ \
+ CHECK_FIFO_CONSISTENCY(anchor); \
+} while (FALSE)
+
+#define UNLINK_FIFO(punlinked, anchor, nextlink) \
+do { \
+ CHECK_FIFO_CONSISTENCY(anchor); \
+ \
+ (punlinked) = (anchor).phead; \
+ if (NULL != (punlinked)) { \
+ (anchor).phead = (punlinked)->nextlink; \
+ if (NULL == (anchor).phead) \
+ (anchor).pptail = NULL; \
+ else if ((anchor).pptail == \
+ &(punlinked)->nextlink) \
+ (anchor).pptail = &(anchor).phead; \
+ MAYBE_Z_LISTS((punlinked)->nextlink); \
+ CHECK_FIFO_CONSISTENCY(anchor); \
+ } \
+} while (FALSE)
+
+#define UNLINK_MID_FIFO(punlinked, anchor, tounlink, nextlink, \
+ entrytype) \
+do { \
+ entrytype **ppentry; \
+ \
+ CHECK_FIFO_CONSISTENCY(anchor); \
+ \
+ ppentry = &(anchor).phead; \
+ \
+ while ((tounlink) != *ppentry) \
+ if ((*ppentry)->nextlink != NULL) { \
+ ppentry = &((*ppentry)->nextlink); \
+ } else { \
+ ppentry = NULL; \
+ break; \
+ } \
+ \
+ if (ppentry != NULL) { \
+ (punlinked) = *ppentry; \
+ *ppentry = (punlinked)->nextlink; \
+ if (NULL == *ppentry) \
+ (anchor).pptail = NULL; \
+ else if ((anchor).pptail == \
+ &(punlinked)->nextlink) \
+ (anchor).pptail = &(anchor).phead; \
+ MAYBE_Z_LISTS((punlinked)->nextlink); \
+ CHECK_FIFO_CONSISTENCY(anchor); \
+ } else { \
+ (punlinked) = NULL; \
+ } \
+} while (FALSE)
+
+#define CONCAT_FIFO(f1, f2, nextlink) \
+do { \
+ CHECK_FIFO_CONSISTENCY(f1); \
+ CHECK_FIFO_CONSISTENCY(f2); \
+ \
+ if ((f2).pptail != NULL) { \
+ if ((f1).pptail != NULL) { \
+ (*(f1).pptail)->nextlink = (f2).phead; \
+ if ((f2).pptail == &(f2).phead) \
+ (f1).pptail = \
+ &(*(f1).pptail)->nextlink; \
+ else \
+ (f1).pptail = (f2).pptail; \
+ CHECK_FIFO_CONSISTENCY(f1); \
+ } else { \
+ (f1) = (f2); \
+ } \
+ MAYBE_Z_LISTS((f2).phead); \
+ MAYBE_Z_LISTS((f2).pptail); \
+ } \
+} while (FALSE)
+
+/*
+ * DLIST
+ */
+#define DECL_DLIST_LINK(entrytype, link) \
+struct { \
+ entrytype * b; \
+ entrytype * f; \
+} link
+
+#define INIT_DLIST(listhead, link) \
+do { \
+ (listhead).link.f = &(listhead); \
+ (listhead).link.b = &(listhead); \
+} while (FALSE)
+
+#define HEAD_DLIST(listhead, link) \
+ ( \
+ (&(listhead) != (listhead).link.f) \
+ ? (listhead).link.f \
+ : NULL \
+ )
+
+#define TAIL_DLIST(listhead, link) \
+ ( \
+ (&(listhead) != (listhead).link.b) \
+ ? (listhead).link.b \
+ : NULL \
+ )
+
+#define NEXT_DLIST(listhead, entry, link) \
+ ( \
+ (&(listhead) != (entry)->link.f) \
+ ? (entry)->link.f \
+ : NULL \
+ )
+
+#define PREV_DLIST(listhead, entry, link) \
+ ( \
+ (&(listhead) != (entry)->link.b) \
+ ? (entry)->link.b \
+ : NULL \
+ )
+
+#define LINK_DLIST(listhead, pentry, link) \
+do { \
+ (pentry)->link.f = (listhead).link.f; \
+ (pentry)->link.b = &(listhead); \
+ (listhead).link.f->link.b = (pentry); \
+ (listhead).link.f = (pentry); \
+} while (FALSE)
+
+#define LINK_TAIL_DLIST(listhead, pentry, link) \
+do { \
+ (pentry)->link.b = (listhead).link.b; \
+ (pentry)->link.f = &(listhead); \
+ (listhead).link.b->link.f = (pentry); \
+ (listhead).link.b = (pentry); \
+} while (FALSE)
+
+#define UNLINK_DLIST(ptounlink, link) \
+do { \
+ (ptounlink)->link.b->link.f = (ptounlink)->link.f; \
+ (ptounlink)->link.f->link.b = (ptounlink)->link.b; \
+ MAYBE_Z_LISTS((ptounlink)->link.b); \
+ MAYBE_Z_LISTS((ptounlink)->link.f); \
+} while (FALSE)
+
+#define ITER_DLIST_BEGIN(listhead, iter, link, entrytype) \
+{ \
+ entrytype *i_dl_nextiter; \
+ \
+ for ((iter) = (listhead).link.f; \
+ (iter) != &(listhead) \
+ && ((i_dl_nextiter = (iter)->link.f), TRUE); \
+ (iter) = i_dl_nextiter) {
+#define ITER_DLIST_END() \
+ } \
+}
+
+#define REV_ITER_DLIST_BEGIN(listhead, iter, link, entrytype) \
+{ \
+ entrytype *i_dl_nextiter; \
+ \
+ for ((iter) = (listhead).link.b; \
+ (iter) != &(listhead) \
+ && ((i_dl_nextiter = (iter)->link.b), TRUE); \
+ (iter) = i_dl_nextiter) {
+#define REV_ITER_DLIST_END() \
+ } \
+}
+
+#endif /* NTP_LISTS_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntp_machine.h b/sebhbsd/freebsd/contrib/ntp/include/ntp_machine.h
new file mode 100644
index 0000000..c5e7248
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntp_machine.h
@@ -0,0 +1,297 @@
+/*
+ * ntp_machine.h
+ *
+ * Collect all machine dependent idiosyncrasies in one place.
+ *
+ * The functionality formerly in this file is mostly handled by
+ * Autoconf these days.
+ */
+
+#ifndef NTP_MACHINE_H
+#define NTP_MACHINE_H
+
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+#include <time.h>
+
+#include "ntp_proto.h"
+
+/*
+
+ HEY! CHECK THIS OUT!
+
+ The per-system SYS_* #defins ARE NO LONGER USED, with the temporary
+ exception of SYS_WINNT.
+
+ If you find a hunk of code that is bracketed by a SYS_* macro and you
+ *know* that it is still needed, please let us know. In many cases the
+ code fragment is now handled somewhere else by autoconf choices.
+
+*/
+
+/*
+
+HOW TO GET IP INTERFACE INFORMATION
+
+ Some UNIX V.4 machines implement a sockets library on top of
+ streams. For these systems, you must use send the SIOCGIFCONF down
+ the stream in an I_STR ioctl. This ususally also implies
+ USE_STREAMS_DEVICE FOR IF_CONFIG. Dell UNIX is a notable exception.
+
+WHAT DOES IOCTL(SIOCGIFCONF) RETURN IN THE BUFFER
+
+ UNIX V.4 machines implement a sockets library on top of streams.
+ When requesting the IP interface configuration with an ioctl(2) calll,
+ an array of ifreq structures are placed in the provided buffer. Some
+ implementations also place the length of the buffer information in
+ the first integer position of the buffer.
+
+ SIZE_RETURNED_IN_BUFFER - size integer is in the buffer
+
+WILL IOCTL(SIOCGIFCONF) WORK ON A SOCKET
+
+ Some UNIX V.4 machines do not appear to support ioctl() requests for the
+ IP interface configuration on a socket. They appear to require the use
+ of the streams device instead.
+
+ USE_STREAMS_DEVICE_FOR_IF_CONFIG - use the /dev/ip device for configuration
+
+MISC
+
+ DOSYNCTODR - Resync TODR clock every hour.
+ RETSIGTYPE - Define signal function type.
+ NO_SIGNED_CHAR_DECL - No "signed char" see include/ntp.h
+ LOCK_PROCESS - Have plock.
+*/
+
+int ntp_set_tod (struct timeval *tvp, void *tzp);
+
+/*casey Tue May 27 15:45:25 SAT 1997*/
+#ifdef SYS_VXWORKS
+
+/* casey's new defines */
+#define NO_MAIN_ALLOWED 1
+#define NO_NETDB 1
+#define NO_RENAME 1
+
+/* in vxWorks we use FIONBIO, but the others are defined for old systems, so
+ * all hell breaks loose if we leave them defined we define USE_FIONBIO to
+ * undefine O_NONBLOCK FNDELAY O_NDELAY where necessary.
+ */
+#define USE_FIONBIO 1
+/* end my new defines */
+
+#define TIMEOFDAY 0x0 /* system wide realtime clock */
+#define HAVE_GETCLOCK 1 /* configure does not set this ... */
+#define HAVE_NO_NICE 1 /* configure does not set this ... */
+#define HAVE_RANDOM 1 /* configure does not set this ... */
+#define HAVE_SRANDOM 1 /* configure does not set this ... */
+
+/* vxWorks specific additions to take care of its
+ * unix (non)complicance
+ */
+
+#include "vxWorks.h"
+#include "ioLib.h"
+#include "taskLib.h"
+#include "time.h"
+
+extern int sysClkRateGet ();
+
+/* usrtime.h
+ * Bob Herlien's excellent time code find it at:
+ * ftp://ftp.atd.ucar.edu/pub/vxworks/vx/usrTime.shar
+ * I would recommend this instead of clock_[g|s]ettime() plus you get
+ * adjtime() too ... casey
+ */
+/*
+extern int gettimeofday ( struct timeval *tp, struct timezone *tzp );
+extern int settimeofday (struct timeval *, struct timezone *);
+extern int adjtime ( struct timeval *delta, struct timeval *olddelta );
+ */
+
+/* in machines.c */
+extern void sleep (int seconds);
+extern void alarm (int seconds);
+/* machines.c */
+
+
+/* this is really this */
+#define getpid taskIdSelf
+#define getclock clock_gettime
+#define fcntl ioctl
+#define _getch getchar
+
+/* define this away for vxWorks */
+#define openlog(x,y)
+/* use local defines for these */
+#undef min
+#undef max
+
+#endif /* SYS_VXWORKS */
+
+#ifdef NO_NETDB
+/* These structures are needed for gethostbyname() etc... */
+/* structures used by netdb.h */
+struct hostent {
+ char *h_name; /* official name of host */
+ char **h_aliases; /* alias list */
+ int h_addrtype; /* host address type */
+ int h_length; /* length of address */
+ char **h_addr_list; /* list of addresses from name server */
+#define h_addr h_addr_list[0] /* address, for backward compatibility */
+};
+
+struct servent {
+ char *s_name; /* official service name */
+ char **s_aliases; /* alias list */
+ int s_port; /* port # */
+ char *s_proto; /* protocol to use */
+};
+extern int h_errno;
+
+#define TRY_AGAIN 2
+
+struct hostent *gethostbyname (char * netnum);
+struct hostent *gethostbyaddr (char * netnum, int size, int addr_type);
+/* type is the protocol */
+struct servent *getservbyname (char *name, char *type);
+#endif /* NO_NETDB */
+
+#ifdef NO_MAIN_ALLOWED
+/* we have no main routines so lets make a plan */
+#define CALL(callname, progname, callmain) \
+ extern int callmain (int,char**); \
+ void callname (a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) \
+ char *a0; \
+ char *a1; \
+ char *a2; \
+ char *a3; \
+ char *a4; \
+ char *a5; \
+ char *a6; \
+ char *a7; \
+ char *a8; \
+ char *a9; \
+ char *a10; \
+ { \
+ char *x[11]; \
+ int argc; \
+ char *argv[] = {progname,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}; \
+ int i; \
+ for (i=0;i<11;i++) \
+ x[i] = NULL; \
+ x[0] = a0; \
+ x[1] = a1; \
+ x[2] = a2; \
+ x[3] = a3; \
+ x[4] = a4; \
+ x[5] = a5; \
+ x[6] = a6; \
+ x[7] = a7; \
+ x[8] = a8; \
+ x[9] = a9; \
+ x[10] = a10; \
+ argc=1; \
+ for (i=0; i<11;i++) \
+ if (x[i]) \
+ { \
+ argv[argc++] = x[i]; \
+ } \
+ callmain(argc,argv); \
+ }
+#endif /* NO_MAIN_ALLOWED */
+/*casey Tue May 27 15:45:25 SAT 1997*/
+
+/*
+ * Here's where autoconfig starts to take over
+ */
+#ifdef HAVE_SYS_STROPTS_H
+# ifdef HAVE_SYS_STREAM_H
+# define STREAM
+# endif
+#endif
+
+#ifndef RETSIGTYPE
+# if defined(NTP_POSIX_SOURCE)
+# define RETSIGTYPE void
+# else
+# define RETSIGTYPE int
+# endif
+#endif
+
+#ifdef NTP_SYSCALLS_STD
+# ifndef NTP_SYSCALL_GET
+# define NTP_SYSCALL_GET 235
+# endif
+# ifndef NTP_SYSCALL_ADJ
+# define NTP_SYSCALL_ADJ 236
+# endif
+#endif /* NTP_SYSCALLS_STD */
+
+#ifdef MPE
+# include <sys/types.h>
+# include <netinet/in.h>
+# include <stdio.h>
+# include <time.h>
+
+/* missing functions that are easily renamed */
+
+# define _getch getchar
+
+/* special functions that require MPE-specific wrappers */
+
+# define bind __ntp_mpe_bind
+# define fcntl __ntp_mpe_fcntl
+
+/* standard macros missing from MPE include files */
+
+# define IN_CLASSD(i) ((((long)(i))&0xf0000000)==0xe0000000)
+# define IN_MULTICAST IN_CLASSD
+# define ITIMER_REAL 0
+
+/* standard structures missing from MPE include files */
+
+struct itimerval {
+ struct timeval it_interval; /* timer interval */
+ struct timeval it_value; /* current value */
+};
+
+/* various declarations to make gcc stop complaining */
+
+extern int __filbuf(FILE *);
+extern int __flsbuf(int, FILE *);
+extern int gethostname(char *, int);
+extern unsigned long inet_addr(char *);
+extern char *strdup(const char *);
+
+/* miscellaneous NTP macros */
+
+# define HAVE_NO_NICE
+#endif /* MPE */
+
+#ifdef HAVE_RTPRIO
+# define HAVE_NO_NICE
+#else
+# ifdef HAVE_SETPRIORITY
+# define HAVE_BSD_NICE
+# else
+# ifdef HAVE_NICE
+# define HAVE_ATT_NICE
+# endif
+# endif
+#endif
+
+#if !defined(HAVE_ATT_NICE) \
+ && !defined(HAVE_BSD_NICE) \
+ && !defined(HAVE_NO_NICE)
+#include "ERROR: You must define one of the HAVE_xx_NICE defines!"
+#endif
+
+#ifndef HAVE_TIMEGM
+extern time_t timegm (struct tm *);
+#endif
+
+
+#endif /* NTP_MACHINE_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntp_malloc.h b/sebhbsd/freebsd/contrib/ntp/include/ntp_malloc.h
new file mode 100644
index 0000000..4cde62e
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntp_malloc.h
@@ -0,0 +1,61 @@
+/*
+ * Define malloc and friends.
+ */
+#ifndef NTP_MALLOC_H
+#define NTP_MALLOC_H
+
+#ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+#else
+# ifdef HAVE_MALLOC_H
+# include <malloc.h>
+# endif
+#endif
+
+/*
+ * Deal with platform differences declaring alloca()
+ * This comes nearly verbatim from:
+ *
+ * http://www.gnu.org/software/autoconf/manual/autoconf.html#Particular-Functions
+ *
+ * The only modifications were to remove C++ support and guard against
+ * redefining alloca.
+ */
+#ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+#elif defined __GNUC__
+# ifndef alloca
+# define alloca __builtin_alloca
+# endif
+#elif defined _AIX
+# ifndef alloca
+# define alloca __alloca
+# endif
+#elif defined _MSC_VER
+# include <malloc.h>
+# ifndef alloca
+# define alloca _alloca
+# endif
+#else
+# include <stddef.h>
+void * alloca(size_t);
+#endif
+
+#ifdef EREALLOC_IMPL
+# define EREALLOC_CALLSITE /* preserve __FILE__ and __LINE__ */
+#else
+# define EREALLOC_IMPL(ptr, newsz, filenm, loc) \
+ realloc(ptr, (newsz))
+#endif
+
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+# define zero_mem(p, s) bzero(p, s)
+#endif
+
+#ifndef zero_mem
+# define zero_mem(p, s) memset(p, 0, s)
+#endif
+#define ZERO(var) zero_mem(&(var), sizeof(var))
+
+#endif /* NTP_MALLOC_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntp_md5.h b/sebhbsd/freebsd/contrib/ntp/include/ntp_md5.h
new file mode 100644
index 0000000..06c90b2
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntp_md5.h
@@ -0,0 +1,49 @@
+/*
+ * ntp_md5.h: deal with md5.h headers
+ *
+ * Use the system MD5 if available, otherwise libisc's.
+ */
+#ifndef NTP_MD5_H
+#define NTP_MD5_H
+
+#ifdef OPENSSL
+# include <openssl/evp.h>
+# include "libssl_compat.h"
+# ifdef HAVE_OPENSSL_CMAC_H
+# include <openssl/cmac.h>
+# define CMAC "AES128CMAC"
+# define AES_128_KEY_SIZE 16
+# endif /*HAVE_OPENSSL_CMAC_H*/
+#else /* !OPENSSL follows */
+/*
+ * Provide OpenSSL-alike MD5 API if we're not using OpenSSL
+ */
+# if defined HAVE_MD5_H && defined HAVE_MD5INIT
+# include <md5.h>
+# else
+# include "isc/md5.h"
+ typedef isc_md5_t MD5_CTX;
+# define MD5Init(c) isc_md5_init(c)
+# define MD5Update(c, p, s) isc_md5_update(c, p, s)
+# define MD5Final(d, c) isc_md5_final((c), (d)) /* swapped */
+# endif
+
+ typedef MD5_CTX EVP_MD_CTX;
+
+# define EVP_MD_CTX_free(c) free(c)
+# define EVP_MD_CTX_new() calloc(1, sizeof(MD5_CTX))
+# define EVP_get_digestbynid(t) NULL
+# define EVP_md5() NULL
+# define EVP_MD_CTX_init(c)
+# define EVP_MD_CTX_set_flags(c, f)
+# define EVP_DigestInit(c, dt) (MD5Init(c), 1)
+# define EVP_DigestInit_ex(c, dt, i) (MD5Init(c), 1)
+# define EVP_DigestUpdate(c, p, s) MD5Update(c, (const void *)(p), \
+ s)
+# define EVP_DigestFinal(c, d, pdl) \
+ do { \
+ MD5Final((d), (c)); \
+ *(pdl) = 16; \
+ } while (0)
+# endif /* !OPENSSL */
+#endif /* NTP_MD5_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntp_net.h b/sebhbsd/freebsd/contrib/ntp/include/ntp_net.h
new file mode 100644
index 0000000..0577402
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntp_net.h
@@ -0,0 +1,238 @@
+/*
+ * ntp_net.h - definitions for NTP network stuff
+ */
+
+#ifndef NTP_NET_H
+#define NTP_NET_H
+
+#include <sys/types.h>
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NET_IF_VAR_H
+#include <net/if_var.h>
+#endif
+#ifdef HAVE_NETINET_IN_VAR_H
+#include <netinet/in_var.h>
+#endif
+
+#include "ntp_rfc2553.h"
+#include "ntp_malloc.h"
+
+typedef union {
+ struct sockaddr sa;
+ struct sockaddr_in sa4;
+ struct sockaddr_in6 sa6;
+} sockaddr_u;
+
+/*
+ * Utilities for manipulating sockaddr_u v4/v6 unions
+ */
+#define SOCK_ADDR4(psau) ((psau)->sa4.sin_addr)
+#define SOCK_ADDR6(psau) ((psau)->sa6.sin6_addr)
+
+#define PSOCK_ADDR4(psau) (&SOCK_ADDR4(psau))
+#define PSOCK_ADDR6(psau) (&SOCK_ADDR6(psau))
+
+#define AF(psau) ((psau)->sa.sa_family)
+
+#define IS_IPV4(psau) (AF_INET == AF(psau))
+#define IS_IPV6(psau) (AF_INET6 == AF(psau))
+
+/* sockaddr_u v4 address in network byte order */
+#define NSRCADR(psau) (SOCK_ADDR4(psau).s_addr)
+
+/* sockaddr_u v4 address in host byte order */
+#define SRCADR(psau) (ntohl(NSRCADR(psau)))
+
+/* sockaddr_u v6 address in network byte order */
+#define NSRCADR6(psau) (SOCK_ADDR6(psau).s6_addr)
+
+/* assign sockaddr_u v4 address from host byte order */
+#define SET_ADDR4(psau, addr4) (NSRCADR(psau) = htonl(addr4))
+
+/* assign sockaddr_u v4 address from network byte order */
+#define SET_ADDR4N(psau, addr4n) (NSRCADR(psau) = (addr4n));
+
+/* assign sockaddr_u v6 address from network byte order */
+#define SET_ADDR6N(psau, s6_addr) \
+ (SOCK_ADDR6(psau) = (s6_addr))
+
+/* sockaddr_u v4/v6 port in network byte order */
+#define NSRCPORT(psau) ((psau)->sa4.sin_port)
+
+/* sockaddr_u v4/v6 port in host byte order */
+#define SRCPORT(psau) (ntohs(NSRCPORT(psau)))
+
+/* assign sockaddr_u v4/v6 port from host byte order */
+#define SET_PORT(psau, port) (NSRCPORT(psau) = htons(port))
+
+/* sockaddr_u v6 scope */
+#define SCOPE_VAR(psau) ((psau)->sa6.sin6_scope_id)
+
+#ifdef ISC_PLATFORM_HAVESCOPEID
+/* v4/v6 scope (always zero for v4) */
+# define SCOPE(psau) (IS_IPV4(psau) \
+ ? 0 \
+ : SCOPE_VAR(psau))
+
+/* are two v6 sockaddr_u scopes equal? */
+# define SCOPE_EQ(psau1, psau2) \
+ (SCOPE_VAR(psau1) == SCOPE_VAR(psau2))
+
+/* assign scope if supported */
+# define SET_SCOPE(psau, s) \
+ do \
+ if (IS_IPV6(psau)) \
+ SCOPE_VAR(psau) = (s); \
+ while (0)
+#else /* ISC_PLATFORM_HAVESCOPEID not defined */
+# define SCOPE(psau) (0)
+# define SCOPE_EQ(psau1, psau2) (1)
+# define SET_SCOPE(psau, s) do { } while (0)
+#endif /* ISC_PLATFORM_HAVESCOPEID */
+
+/* v4/v6 is multicast address */
+#define IS_MCAST(psau) \
+ (IS_IPV4(psau) \
+ ? IN_CLASSD(SRCADR(psau)) \
+ : IN6_IS_ADDR_MULTICAST(PSOCK_ADDR6(psau)))
+
+/* v6 is interface ID scope universal, as with MAC-derived addresses */
+#define IS_IID_UNIV(psau) \
+ (!!(0x02 & NSRCADR6(psau)[8]))
+
+#define SIZEOF_INADDR(fam) \
+ ((AF_INET == (fam)) \
+ ? sizeof(struct in_addr) \
+ : sizeof(struct in6_addr))
+
+#define SIZEOF_SOCKADDR(fam) \
+ ((AF_INET == (fam)) \
+ ? sizeof(struct sockaddr_in) \
+ : sizeof(struct sockaddr_in6))
+
+#define SOCKLEN(psau) \
+ (IS_IPV4(psau) \
+ ? sizeof((psau)->sa4) \
+ : sizeof((psau)->sa6))
+
+#define ZERO_SOCK(psau) \
+ ZERO(*(psau))
+
+/* blast a byte value across sockaddr_u v6 address */
+#define MEMSET_ADDR6(psau, v) \
+ memset((psau)->sa6.sin6_addr.s6_addr, (v), \
+ sizeof((psau)->sa6.sin6_addr.s6_addr))
+
+#define SET_ONESMASK(psau) \
+ do { \
+ if (IS_IPV6(psau)) \
+ MEMSET_ADDR6((psau), 0xff); \
+ else \
+ NSRCADR(psau) = 0xffffffff; \
+ } while(0)
+
+/* zero sockaddr_u, fill in family and all-ones (host) mask */
+#define SET_HOSTMASK(psau, family) \
+ do { \
+ ZERO_SOCK(psau); \
+ AF(psau) = (family); \
+ SET_ONESMASK(psau); \
+ } while (0)
+
+/*
+ * compare two in6_addr returning negative, 0, or positive.
+ * ADDR6_CMP is negative if *pin6A is lower than *pin6B, zero if they
+ * are equal, positive if *pin6A is higher than *pin6B. IN6ADDR_ANY
+ * is the lowest address (128 zero bits).
+ */
+#define ADDR6_CMP(pin6A, pin6B) \
+ memcmp((pin6A)->s6_addr, (pin6B)->s6_addr, \
+ sizeof(pin6A)->s6_addr)
+
+/* compare two in6_addr for equality only */
+#if !defined(SYS_WINNT) || !defined(in_addr6)
+#define ADDR6_EQ(pin6A, pin6B) \
+ (!ADDR6_CMP(pin6A, pin6B))
+#else
+#define ADDR6_EQ(pin6A, pin6B) \
+ IN6_ADDR_EQUAL(pin6A, pin6B)
+#endif
+
+/* compare a in6_addr with socket address */
+#define S_ADDR6_EQ(psau, pin6) \
+ ADDR6_EQ(&(psau)->sa6.sin6_addr, pin6)
+
+/* are two sockaddr_u's addresses equal? (port excluded) */
+#define SOCK_EQ(psau1, psau2) \
+ ((AF(psau1) != AF(psau2)) \
+ ? 0 \
+ : IS_IPV4(psau1) \
+ ? (NSRCADR(psau1) == NSRCADR(psau2)) \
+ : (S_ADDR6_EQ((psau1), PSOCK_ADDR6(psau2)) \
+ && SCOPE_EQ((psau1), (psau2))))
+
+/* are two sockaddr_u's addresses and ports equal? */
+#define ADDR_PORT_EQ(psau1, psau2) \
+ ((NSRCPORT(psau1) != NSRCPORT(psau2) \
+ ? 0 \
+ : SOCK_EQ((psau1), (psau2))))
+
+/* is sockaddr_u address unspecified? */
+#define SOCK_UNSPEC(psau) \
+ (IS_IPV4(psau) \
+ ? !NSRCADR(psau) \
+ : IN6_IS_ADDR_UNSPECIFIED(PSOCK_ADDR6(psau)))
+
+/* just how unspecified do you mean? (scope 0/unspec too) */
+#define SOCK_UNSPEC_S(psau) \
+ (SOCK_UNSPEC(psau) && !SCOPE(psau))
+
+/* choose a default net interface (struct interface) for v4 or v6 */
+#define ANY_INTERFACE_BYFAM(family) \
+ ((AF_INET == family) \
+ ? any_interface \
+ : any6_interface)
+
+/* choose a default interface for addresses' protocol (addr family) */
+#define ANY_INTERFACE_CHOOSE(psau) \
+ ANY_INTERFACE_BYFAM(AF(psau))
+
+
+/*
+ * We tell reference clocks from real peers by giving the reference
+ * clocks an address of the form 127.127.t.u, where t is the type and
+ * u is the unit number. We define some of this here since we will need
+ * some sanity checks to make sure this address isn't interpretted as
+ * that of a normal peer.
+ */
+#define REFCLOCK_ADDR 0x7f7f0000 /* 127.127.0.0 */
+#define REFCLOCK_MASK 0xffff0000 /* 255.255.0.0 */
+
+#define ISREFCLOCKADR(srcadr) \
+ (IS_IPV4(srcadr) && \
+ (SRCADR(srcadr) & REFCLOCK_MASK) == REFCLOCK_ADDR)
+
+/*
+ * Macro for checking for invalid addresses. This is really, really
+ * gross, but is needed so no one configures a host on net 127 now that
+ * we're encouraging it the the configuration file.
+ */
+#define LOOPBACKADR 0x7f000001
+#define LOOPNETMASK 0xff000000
+
+#define ISBADADR(srcadr) \
+ (IS_IPV4(srcadr) \
+ && ((SRCADR(srcadr) & LOOPNETMASK) \
+ == (LOOPBACKADR & LOOPNETMASK)) \
+ && SRCADR(srcadr) != LOOPBACKADR)
+
+
+#endif /* NTP_NET_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntp_prio_q.h b/sebhbsd/freebsd/contrib/ntp/include/ntp_prio_q.h
new file mode 100644
index 0000000..4b5ffca
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntp_prio_q.h
@@ -0,0 +1,83 @@
+/* ntp_prio_q.h
+ *
+ * This file contains the structures and function prototypes for the
+ * priority queue implementation used by the discrete event simulator.
+ *
+ * Written By: Sachin Kamboj
+ * University of Delaware
+ * Newark, DE 19711
+ * Copyright (c) 2006
+ */
+
+#ifndef NTP_PRIO_Q_H
+#define NTP_PRIO_Q_H
+
+#include <stddef.h> /* size_t */
+
+/* Structures for storing a priority queue
+ * ---------------------------------------
+ */
+
+typedef struct node {
+ union {
+ struct node *next;
+ double d;
+ } nodeu;
+} node;
+#define node_next nodeu.next
+
+typedef int (*q_order_func)(const void *, const void *);
+
+typedef struct Queue {
+ q_order_func get_order;
+ node * front;
+ int no_of_elements;
+} queue;
+
+
+/* FUNCTION PROTOTYPES
+ * -------------------
+ */
+/* Define a function to create a FIFO queue */
+#define create_queue() create_priority_queue(&get_fifo_order)
+
+void destroy_queue(queue *my_queue);
+void free_node(void *my_node);
+void *next_node(void *my_node);
+int empty(queue *my_queue);
+void *queue_head(queue *my_queue);
+queue *enqueue(queue *my_queue, void *my_node);
+void append_queue(queue *q1, queue *q2);
+void *dequeue(queue *my_queue);
+int get_no_of_elements(queue *my_queue);
+int get_fifo_order(const void *el1, const void *el2);
+
+/*
+ * Preserve original callsite __FILE__ and __LINE__ for these
+ * malloc-like funcs when using MS C runtime debug heap.
+ */
+#ifdef _CRTDBG_MAP_ALLOC
+# define create_priority_queue(order) debug_create_priority_queue(order, __FILE__, __LINE__)
+# define get_node(size) debug_get_node(size, __FILE__, __LINE__)
+#else
+# define create_priority_queue(order) debug_create_priority_queue(order)
+# define get_node(size) debug_get_node(size)
+#endif
+
+queue *debug_create_priority_queue(
+ q_order_func get_order
+#ifdef _CRTDBG_MAP_ALLOC
+ , const char * sourcefile
+ , int line_num
+#endif
+ );
+
+void *debug_get_node(
+ size_t size
+#ifdef _CRTDBG_MAP_ALLOC
+ , const char * sourcefile
+ , int line_num
+#endif
+ );
+
+#endif /* NTP_PRIO_Q_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntp_proto.h b/sebhbsd/freebsd/contrib/ntp/include/ntp_proto.h
new file mode 100644
index 0000000..1d04b78
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntp_proto.h
@@ -0,0 +1,6 @@
+#ifndef NTP_PROTO_H
+#define NTP_PROTO_H
+
+#define NTP_MAXFREQ 500e-6
+
+#endif /* NTP_PROTO_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntp_random.h b/sebhbsd/freebsd/contrib/ntp/include/ntp_random.h
new file mode 100644
index 0000000..fa77f65
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntp_random.h
@@ -0,0 +1,17 @@
+
+#include <ntp_types.h>
+
+void ntp_crypto_srandom(void);
+int ntp_crypto_random_buf(void *buf, size_t nbytes);
+
+long ntp_random (void);
+void ntp_srandom (unsigned long);
+void ntp_srandomdev (void);
+char * ntp_initstate (unsigned long, /* seed for R.N.G. */
+ char *, /* pointer to state array */
+ long /* # bytes of state info */
+ );
+char * ntp_setstate (char *); /* pointer to state array */
+
+
+
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntp_refclock.h b/sebhbsd/freebsd/contrib/ntp/include/ntp_refclock.h
new file mode 100644
index 0000000..4b807e5
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntp_refclock.h
@@ -0,0 +1,240 @@
+/*
+ * ntp_refclock.h - definitions for reference clock support
+ */
+
+#ifndef NTP_REFCLOCK_H
+#define NTP_REFCLOCK_H
+
+#if defined(HAVE_SYS_MODEM_H)
+#include <sys/modem.h>
+#endif
+
+#include "ntp_types.h"
+#include "ntp_tty.h"
+#include "recvbuff.h"
+
+
+#define SAMPLE(x) pp->coderecv = (pp->coderecv + 1) % MAXSTAGE; \
+ pp->filter[pp->coderecv] = (x); \
+ if (pp->coderecv == pp->codeproc) \
+ pp->codeproc = (pp->codeproc + 1) % MAXSTAGE;
+
+/*
+ * Macros to determine the clock type and unit numbers from a
+ * 127.127.t.u address
+ */
+#define REFCLOCKTYPE(srcadr) ((SRCADR(srcadr) >> 8) & 0xff)
+#define REFCLOCKUNIT(srcadr) (SRCADR(srcadr) & 0xff)
+
+/*
+ * List of reference clock names and descriptions. These must agree with
+ * lib/clocktypes.c and ntpd/refclock_conf.c.
+ */
+struct clktype {
+ int code; /* driver "major" number */
+ const char *clocktype; /* long description */
+ const char *abbrev; /* short description */
+};
+extern struct clktype clktypes[];
+
+/*
+ * Configuration flag values
+ */
+#define CLK_HAVETIME1 0x1
+#define CLK_HAVETIME2 0x2
+#define CLK_HAVEVAL1 0x4
+#define CLK_HAVEVAL2 0x8
+
+#define CLK_FLAG1 0x1
+#define CLK_FLAG2 0x2
+#define CLK_FLAG3 0x4
+#define CLK_FLAG4 0x8
+
+#define CLK_HAVEFLAG1 0x10
+#define CLK_HAVEFLAG2 0x20
+#define CLK_HAVEFLAG3 0x40
+#define CLK_HAVEFLAG4 0x80
+
+/*
+ * Constant for disabling event reporting in
+ * refclock_receive. ORed in leap
+ * parameter
+ */
+#define REFCLOCK_OWN_STATES 0x80
+
+/*
+ * Structure for returning clock status
+ */
+struct refclockstat {
+ u_char type; /* clock type */
+ u_char flags; /* clock flags */
+ u_char haveflags; /* bit array of valid flags */
+ u_short lencode; /* length of last timecode */
+ const char *p_lastcode; /* last timecode received */
+ u_int32 polls; /* transmit polls */
+ u_int32 noresponse; /* no response to poll */
+ u_int32 badformat; /* bad format timecode received */
+ u_int32 baddata; /* invalid data timecode received */
+ u_int32 timereset; /* driver resets */
+ const char *clockdesc; /* ASCII description */
+ double fudgetime1; /* configure fudge time1 */
+ double fudgetime2; /* configure fudge time2 */
+ int32 fudgeval1; /* configure fudge value1 */
+ u_int32 fudgeval2; /* configure fudge value2 */
+ u_char currentstatus; /* clock status */
+ u_char lastevent; /* last exception event */
+ u_char leap; /* leap bits */
+ struct ctl_var *kv_list; /* additional variables */
+};
+
+/*
+ * Reference clock I/O structure. Used to provide an interface between
+ * the reference clock drivers and the I/O module.
+ */
+struct refclockio {
+ struct refclockio *next; /* link to next structure */
+ void (*clock_recv) (struct recvbuf *); /* completion routine */
+ int (*io_input) (struct recvbuf *); /* input routine -
+ to avoid excessive buffer use
+ due to small bursts
+ of refclock input data */
+ struct peer *srcclock; /* refclock peer */
+ int datalen; /* length of data */
+ int fd; /* file descriptor */
+ u_long recvcount; /* count of receive completions */
+ int active; /* nonzero when in use */
+
+#ifdef HAVE_IO_COMPLETION_PORT
+ void * ioreg_ctx; /* IO registration context */
+ void * device_ctx; /* device-related data for i/o subsystem */
+#endif
+};
+
+/*
+ * Structure for returning debugging info
+ */
+#define NCLKBUGVALUES 16
+#define NCLKBUGTIMES 32
+
+struct refclockbug {
+ u_char nvalues; /* values following */
+ u_char ntimes; /* times following */
+ u_short svalues; /* values format sign array */
+ u_int32 stimes; /* times format sign array */
+ u_int32 values[NCLKBUGVALUES]; /* real values */
+ l_fp times[NCLKBUGTIMES]; /* real times */
+};
+
+#ifdef HAVE_IO_COMPLETION_PORT
+extern HANDLE WaitableIoEventHandle;
+#endif
+
+/*
+ * Structure interface between the reference clock support
+ * ntp_refclock.c and the driver utility routines
+ */
+#define MAXSTAGE 60 /* max median filter stages */
+#define NSTAGE 5 /* default median filter stages */
+#define BMAX 128 /* max timecode length */
+#define GMT 0 /* I hope nobody sees this */
+#define MAXDIAL 60 /* max length of modem dial strings */
+
+
+struct refclockproc {
+ void * unitptr; /* pointer to unit structure */
+ struct refclock * conf; /* refclock_conf[type] */
+ struct refclockio io; /* I/O handler structure */
+ u_char leap; /* leap/synchronization code */
+ u_char currentstatus; /* clock status */
+ u_char lastevent; /* last exception event */
+ u_char type; /* clock type */
+ const char *clockdesc; /* clock description */
+ u_long nextaction; /* local activity timeout */
+ void (*action)(struct peer *); /* timeout callback */
+
+ char a_lastcode[BMAX]; /* last timecode received */
+ int lencode; /* length of last timecode */
+
+ int year; /* year of eternity */
+ int day; /* day of year */
+ int hour; /* hour of day */
+ int minute; /* minute of hour */
+ int second; /* second of minute */
+ long nsec; /* nanosecond of second */
+ u_long yearstart; /* beginning of year */
+ int coderecv; /* put pointer */
+ int codeproc; /* get pointer */
+ l_fp lastref; /* reference timestamp */
+ l_fp lastrec; /* receive timestamp */
+ double offset; /* mean offset */
+ double disp; /* sample dispersion */
+ double jitter; /* jitter (mean squares) */
+ double filter[MAXSTAGE]; /* median filter */
+
+ /*
+ * Configuration data
+ */
+ double fudgetime1; /* fudge time1 */
+ double fudgetime2; /* fudge time2 */
+ u_char stratum; /* server stratum */
+ u_int32 refid; /* reference identifier */
+ u_char sloppyclockflag; /* fudge flags */
+
+ /*
+ * Status tallies
+ */
+ u_long timestarted; /* time we started this */
+ u_long polls; /* polls sent */
+ u_long noreply; /* no replies to polls */
+ u_long badformat; /* bad format reply */
+ u_long baddata; /* bad data reply */
+};
+
+/*
+ * Structure interface between the reference clock support
+ * ntp_refclock.c and particular clock drivers. This must agree with the
+ * structure defined in the driver.
+ */
+#define noentry 0 /* flag for null routine */
+#define NOFLAGS 0 /* flag for null flags */
+
+struct refclock {
+ int (*clock_start) (int, struct peer *);
+ void (*clock_shutdown) (int, struct peer *);
+ void (*clock_poll) (int, struct peer *);
+ void (*clock_control) (int, const struct refclockstat *,
+ struct refclockstat *, struct peer *);
+ void (*clock_init) (void);
+ void (*clock_buginfo) (int, struct refclockbug *, struct peer *);
+ void (*clock_timer) (int, struct peer *);
+};
+
+/*
+ * Function prototypes
+ */
+extern int io_addclock (struct refclockio *);
+extern void io_closeclock (struct refclockio *);
+
+#ifdef REFCLOCK
+extern void refclock_buginfo(sockaddr_u *,
+ struct refclockbug *);
+extern void refclock_control(sockaddr_u *,
+ const struct refclockstat *,
+ struct refclockstat *);
+extern int refclock_open (const char *, u_int, u_int);
+extern int refclock_setup (int, u_int, u_int);
+extern void refclock_timer (struct peer *);
+extern void refclock_transmit(struct peer *);
+extern int refclock_process(struct refclockproc *);
+extern int refclock_process_f(struct refclockproc *, double);
+extern void refclock_process_offset(struct refclockproc *, l_fp,
+ l_fp, double);
+extern void refclock_report (struct peer *, int);
+extern int refclock_gtlin (struct recvbuf *, char *, int, l_fp *);
+extern int refclock_gtraw (struct recvbuf *, char *, int, l_fp *);
+extern int indicate_refclock_packet(struct refclockio *,
+ struct recvbuf *);
+extern void process_refclock_packet(struct recvbuf *);
+#endif /* REFCLOCK */
+
+#endif /* NTP_REFCLOCK_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntp_request.h b/sebhbsd/freebsd/contrib/ntp/include/ntp_request.h
new file mode 100644
index 0000000..d05a67f
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntp_request.h
@@ -0,0 +1,955 @@
+/*
+ * ntp_request.h - definitions for the ntpd remote query facility
+ */
+
+#ifndef NTP_REQUEST_H
+#define NTP_REQUEST_H
+
+#include "stddef.h"
+#include "ntp_types.h"
+#include "recvbuff.h"
+
+/*
+ * A mode 7 packet is used exchanging data between an NTP server
+ * and a client for purposes other than time synchronization, e.g.
+ * monitoring, statistics gathering and configuration. A mode 7
+ * packet has the following format:
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |R|M| VN | Mode|A| Sequence | Implementation| Req Code |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Err | Number of data items | MBZ | Size of data item |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | |
+ * | Data (Minimum 0 octets, maximum 500 octets) |
+ * | |
+ * [...]
+ * | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Encryption Keyid (when A bit set) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | |
+ * | Message Authentication Code (when A bit set) |
+ * | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * where the fields are (note that the client sends requests, the server
+ * responses):
+ *
+ * Response Bit: This packet is a response (if clear, packet is a request).
+ *
+ * More Bit: Set for all packets but the last in a response which
+ * requires more than one packet.
+ *
+ * Version Number: 2 for current version
+ *
+ * Mode: Always 7
+ *
+ * Authenticated bit: If set, this packet is authenticated.
+ *
+ * Sequence number: For a multipacket response, contains the sequence
+ * number of this packet. 0 is the first in the sequence,
+ * 127 (or less) is the last. The More Bit must be set in
+ * all packets but the last.
+ *
+ * Implementation number: The number of the implementation this request code
+ * is defined by. An implementation number of zero is used
+ * for requst codes/data formats which all implementations
+ * agree on. Implementation number 255 is reserved (for
+ * extensions, in case we run out).
+ *
+ * Request code: An implementation-specific code which specifies the
+ * operation to be (which has been) performed and/or the
+ * format and semantics of the data included in the packet.
+ *
+ * Err: Must be 0 for a request. For a response, holds an error
+ * code relating to the request. If nonzero, the operation
+ * requested wasn't performed.
+ *
+ * 0 - no error
+ * 1 - incompatible implementation number
+ * 2 - unimplemented request code
+ * 3 - format error (wrong data items, data size, packet size etc.)
+ * 4 - no data available (e.g. request for details on unknown peer)
+ * 5-6 I don't know
+ * 7 - authentication failure (i.e. permission denied)
+ *
+ * Number of data items: number of data items in packet. 0 to 500
+ *
+ * MBZ: A reserved data field, must be zero in requests and responses.
+ *
+ * Size of data item: size of each data item in packet. 0 to 500
+ *
+ * Data: Variable sized area containing request/response data. For
+ * requests and responses the size in octets must be greater
+ * than or equal to the product of the number of data items
+ * and the size of a data item. For requests the data area
+ * must be exactly 40 octets in length. For responses the
+ * data area may be any length between 0 and 500 octets
+ * inclusive.
+ *
+ * Message Authentication Code: Same as NTP spec, in definition and function.
+ * May optionally be included in requests which require
+ * authentication, is never included in responses.
+ *
+ * The version number, mode and keyid have the same function and are
+ * in the same location as a standard NTP packet. The request packet
+ * is the same size as a standard NTP packet to ease receive buffer
+ * management, and to allow the same encryption procedure to be used
+ * both on mode 7 and standard NTP packets. The mac is included when
+ * it is required that a request be authenticated, the keyid should be
+ * zero in requests in which the mac is not included.
+ *
+ * The data format depends on the implementation number/request code pair
+ * and whether the packet is a request or a response. The only requirement
+ * is that data items start in the octet immediately following the size
+ * word and that data items be concatenated without padding between (i.e.
+ * if the data area is larger than data_items*size, all padding is at
+ * the end). Padding is ignored, other than for encryption purposes.
+ * Implementations using encryption might want to include a time stamp
+ * or other data in the request packet padding. The key used for requests
+ * is implementation defined, but key 15 is suggested as a default.
+ */
+
+/*
+ * union of raw addresses to save space
+ */
+union addrun {
+ struct in6_addr addr6;
+ struct in_addr addr;
+};
+
+#define MODE7_PAYLOAD_LIM 176
+
+typedef union req_data_u_tag {
+ u_int32 u32[MODE7_PAYLOAD_LIM / sizeof(u_int32)];
+ char data[MODE7_PAYLOAD_LIM]; /* data area (176 byte max) */
+} req_data_u; /* struct conf_peer must fit */
+
+/*
+ * A request packet. These are almost a fixed length.
+ */
+struct req_pkt {
+ u_char rm_vn_mode; /* response, more, version, mode */
+ u_char auth_seq; /* key, sequence number */
+ u_char implementation; /* implementation number */
+ u_char request; /* request number */
+ u_short err_nitems; /* error code/number of data items */
+ u_short mbz_itemsize; /* item size */
+ req_data_u u; /* data area */
+ l_fp tstamp; /* time stamp, for authentication */
+ keyid_t keyid; /* (optional) encryption key */
+ char mac[MAX_MDG_LEN]; /* (optional) auth code */
+};
+
+/*
+ * The req_pkt_tail structure is used by ntpd to adjust for different
+ * packet sizes that may arrive.
+ */
+struct req_pkt_tail {
+ l_fp tstamp; /* time stamp, for authentication */
+ keyid_t keyid; /* (optional) encryption key */
+ char mac[MAX_MDG_LEN]; /* (optional) auth code */
+};
+
+/* MODE_PRIVATE request packet header length before optional items. */
+#define REQ_LEN_HDR (offsetof(struct req_pkt, u))
+/* MODE_PRIVATE request packet fixed length without MAC. */
+#define REQ_LEN_NOMAC (offsetof(struct req_pkt, keyid))
+/* MODE_PRIVATE req_pkt_tail minimum size (16 octet digest) */
+#define REQ_TAIL_MIN \
+ (sizeof(struct req_pkt_tail) - (MAX_MAC_LEN - MAX_MD5_LEN))
+
+/*
+ * A MODE_PRIVATE response packet. The length here is variable, this
+ * is a maximally sized one. Note that this implementation doesn't
+ * authenticate responses.
+ */
+#define RESP_HEADER_SIZE (offsetof(struct resp_pkt, u))
+#define RESP_DATA_SIZE 500
+
+typedef union resp_pkt_u_tag {
+ char data[RESP_DATA_SIZE];
+ u_int32 u32[RESP_DATA_SIZE / sizeof(u_int32)];
+} resp_pkt_u;
+
+struct resp_pkt {
+ u_char rm_vn_mode; /* response, more, version, mode */
+ u_char auth_seq; /* key, sequence number */
+ u_char implementation; /* implementation number */
+ u_char request; /* request number */
+ u_short err_nitems; /* error code/number of data items */
+ u_short mbz_itemsize; /* item size */
+ resp_pkt_u u; /* data area */
+};
+
+
+/*
+ * Information error codes
+ */
+#define INFO_OKAY 0
+#define INFO_ERR_IMPL 1 /* incompatible implementation */
+#define INFO_ERR_REQ 2 /* unknown request code */
+#define INFO_ERR_FMT 3 /* format error */
+#define INFO_ERR_NODATA 4 /* no data for this request */
+#define INFO_ERR_AUTH 7 /* authentication failure */
+#define MAX_INFO_ERR INFO_ERR_AUTH
+
+/*
+ * Maximum sequence number.
+ */
+#define MAXSEQ 127
+
+
+/*
+ * Bit setting macros for multifield items.
+ */
+#define RESP_BIT 0x80
+#define MORE_BIT 0x40
+
+#define ISRESPONSE(rm_vn_mode) (((rm_vn_mode)&RESP_BIT)!=0)
+#define ISMORE(rm_vn_mode) (((rm_vn_mode)&MORE_BIT)!=0)
+#define INFO_VERSION(rm_vn_mode) ((u_char)(((rm_vn_mode)>>3)&0x7))
+#define INFO_MODE(rm_vn_mode) ((rm_vn_mode)&0x7)
+
+#define RM_VN_MODE(resp, more, version) \
+ ((u_char)(((resp)?RESP_BIT:0)\
+ |((more)?MORE_BIT:0)\
+ |((version?version:(NTP_OLDVERSION+1))<<3)\
+ |(MODE_PRIVATE)))
+
+#define INFO_IS_AUTH(auth_seq) (((auth_seq) & 0x80) != 0)
+#define INFO_SEQ(auth_seq) ((auth_seq)&0x7f)
+#define AUTH_SEQ(auth, seq) ((u_char)((((auth)!=0)?0x80:0)|((seq)&0x7f)))
+
+#define INFO_ERR(err_nitems) ((u_short)((ntohs(err_nitems)>>12)&0xf))
+#define INFO_NITEMS(err_nitems) ((u_short)(ntohs(err_nitems)&0xfff))
+#define ERR_NITEMS(err, nitems) (htons((u_short)((((u_short)(err)<<12)&0xf000)\
+ |((u_short)(nitems)&0xfff))))
+
+#define INFO_MBZ(mbz_itemsize) ((ntohs(mbz_itemsize)>>12)&0xf)
+#define INFO_ITEMSIZE(mbz_itemsize) ((u_short)(ntohs(mbz_itemsize)&0xfff))
+#define MBZ_ITEMSIZE(itemsize) (htons((u_short)(itemsize)))
+
+
+/*
+ * Implementation numbers. One for universal use and one for ntpd.
+ */
+#define IMPL_UNIV 0
+#define IMPL_XNTPD_OLD 2 /* Used by pre ipv6 ntpdc */
+#define IMPL_XNTPD 3 /* Used by post ipv6 ntpdc */
+
+/*
+ * Some limits related to authentication. Frames which are
+ * authenticated must include a time stamp which differs from
+ * the receive time stamp by no more than 10 seconds.
+ */
+#define INFO_TS_MAXSKEW 10.
+
+/*
+ * Universal request codes go here. There aren't any.
+ */
+
+/*
+ * ntpdc -> ntpd request codes go here.
+ */
+#define REQ_PEER_LIST 0 /* return list of peers */
+#define REQ_PEER_LIST_SUM 1 /* return summary info for all peers */
+#define REQ_PEER_INFO 2 /* get standard information on peer */
+#define REQ_PEER_STATS 3 /* get statistics for peer */
+#define REQ_SYS_INFO 4 /* get system information */
+#define REQ_SYS_STATS 5 /* get system stats */
+#define REQ_IO_STATS 6 /* get I/O stats */
+#define REQ_MEM_STATS 7 /* stats related to peer list maint */
+#define REQ_LOOP_INFO 8 /* info from the loop filter */
+#define REQ_TIMER_STATS 9 /* get timer stats */
+#define REQ_CONFIG 10 /* configure a new peer */
+#define REQ_UNCONFIG 11 /* unconfigure an existing peer */
+#define REQ_SET_SYS_FLAG 12 /* set system flags */
+#define REQ_CLR_SYS_FLAG 13 /* clear system flags */
+#define REQ_MONITOR 14 /* (not used) */
+#define REQ_NOMONITOR 15 /* (not used) */
+#define REQ_GET_RESTRICT 16 /* return restrict list */
+#define REQ_RESADDFLAGS 17 /* add flags to restrict list */
+#define REQ_RESSUBFLAGS 18 /* remove flags from restrict list */
+#define REQ_UNRESTRICT 19 /* remove entry from restrict list */
+#define REQ_MON_GETLIST 20 /* return data collected by monitor */
+#define REQ_RESET_STATS 21 /* reset stat counters */
+#define REQ_RESET_PEER 22 /* reset peer stat counters */
+#define REQ_REREAD_KEYS 23 /* reread the encryption key file */
+#define REQ_DO_DIRTY_HACK 24 /* (not used) */
+#define REQ_DONT_DIRTY_HACK 25 /* (not used) */
+#define REQ_TRUSTKEY 26 /* add a trusted key */
+#define REQ_UNTRUSTKEY 27 /* remove a trusted key */
+#define REQ_AUTHINFO 28 /* return authentication info */
+#define REQ_TRAPS 29 /* return currently set traps */
+#define REQ_ADD_TRAP 30 /* add a trap */
+#define REQ_CLR_TRAP 31 /* clear a trap */
+#define REQ_REQUEST_KEY 32 /* define a new request keyid */
+#define REQ_CONTROL_KEY 33 /* define a new control keyid */
+#define REQ_GET_CTLSTATS 34 /* get stats from the control module */
+#define REQ_GET_LEAPINFO 35 /* (not used) */
+#define REQ_GET_CLOCKINFO 36 /* get clock information */
+#define REQ_SET_CLKFUDGE 37 /* set clock fudge factors */
+#define REQ_GET_KERNEL 38 /* get kernel pll/pps information */
+#define REQ_GET_CLKBUGINFO 39 /* get clock debugging info */
+#define REQ_SET_PRECISION 41 /* (not used) */
+#define REQ_MON_GETLIST_1 42 /* return collected v1 monitor data */
+#define REQ_HOSTNAME_ASSOCID 43 /* Here is a hostname + assoc_id */
+#define REQ_IF_STATS 44 /* get interface statistics */
+#define REQ_IF_RELOAD 45 /* reload interface list */
+
+/* Determine size of pre-v6 version of structures */
+#define v4sizeof(type) offsetof(type, v6_flag)
+
+/*
+ * Flags in the peer information returns
+ */
+#define INFO_FLAG_CONFIG 0x1
+#define INFO_FLAG_SYSPEER 0x2
+#define INFO_FLAG_BURST 0x4
+#define INFO_FLAG_REFCLOCK 0x8
+#define INFO_FLAG_PREFER 0x10
+#define INFO_FLAG_AUTHENABLE 0x20
+#define INFO_FLAG_SEL_CANDIDATE 0x40
+#define INFO_FLAG_SHORTLIST 0x80
+#define INFO_FLAG_IBURST 0x100
+
+/*
+ * Flags in the system information returns
+ */
+#define INFO_FLAG_BCLIENT 0x1
+#define INFO_FLAG_AUTHENTICATE 0x2
+#define INFO_FLAG_NTP 0x4
+#define INFO_FLAG_KERNEL 0x8
+#define INFO_FLAG_MONITOR 0x40
+#define INFO_FLAG_FILEGEN 0x80
+#define INFO_FLAG_CAL 0x10
+#define INFO_FLAG_PPS_SYNC 0x20
+
+/*
+ * Peer list structure. Used to return raw lists of peers. It goes
+ * without saying that everything returned is in network byte order.
+ * Well, it *would* have gone without saying, but somebody said it.
+ */
+struct info_peer_list {
+ u_int32 addr; /* address of peer */
+ u_short port; /* port number of peer */
+ u_char hmode; /* mode for this peer */
+ u_char flags; /* flags (from above) */
+ u_int v6_flag; /* is this v6 or not */
+ u_int unused1; /* (unused) padding for addr6 */
+ struct in6_addr addr6; /* v6 address of peer */
+};
+
+
+/*
+ * Peer summary structure. Sort of the info that ntpdc returns by default.
+ */
+struct info_peer_summary {
+ u_int32 dstadr; /* local address (zero for undetermined) */
+ u_int32 srcadr; /* source address */
+ u_short srcport; /* source port */
+ u_char stratum; /* stratum of peer */
+ s_char hpoll; /* host polling interval */
+ s_char ppoll; /* peer polling interval */
+ u_char reach; /* reachability register */
+ u_char flags; /* flags, from above */
+ u_char hmode; /* peer mode */
+ s_fp delay; /* peer.estdelay */
+ l_fp offset; /* peer.estoffset */
+ u_fp dispersion; /* peer.estdisp */
+ u_int v6_flag; /* is this v6 or not */
+ u_int unused1; /* (unused) padding for dstadr6 */
+ struct in6_addr dstadr6; /* local address (v6) */
+ struct in6_addr srcadr6; /* source address (v6) */
+};
+
+
+/*
+ * Peer information structure.
+ */
+struct info_peer {
+ u_int32 dstadr; /* local address */
+ u_int32 srcadr; /* source address */
+ u_short srcport; /* remote port */
+ u_char flags; /* peer flags */
+ u_char leap; /* peer.leap */
+ u_char hmode; /* peer.hmode */
+ u_char pmode; /* peer.pmode */
+ u_char stratum; /* peer.stratum */
+ u_char ppoll; /* peer.ppoll */
+ u_char hpoll; /* peer.hpoll */
+ s_char precision; /* peer.precision */
+ u_char version; /* peer.version */
+ u_char unused8;
+ u_char reach; /* peer.reach */
+ u_char unreach; /* peer.unreach */
+ u_char flash; /* old peer.flash */
+ u_char ttl; /* peer.ttl */
+ u_short flash2; /* new peer.flash */
+ associd_t associd; /* association ID */
+ keyid_t keyid; /* peer.keyid */
+ u_int32 pkeyid; /* unused */
+ u_int32 refid; /* peer.refid */
+ u_int32 timer; /* peer.timer */
+ s_fp rootdelay; /* peer.delay */
+ u_fp rootdispersion; /* peer.dispersion */
+ l_fp reftime; /* peer.reftime */
+ l_fp org; /* peer.org */
+ l_fp rec; /* peer.rec */
+ l_fp xmt; /* peer.xmt */
+ s_fp filtdelay[NTP_SHIFT]; /* delay shift register */
+ l_fp filtoffset[NTP_SHIFT]; /* offset shift register */
+ u_char order[NTP_SHIFT]; /* order of peers from last filter */
+ s_fp delay; /* peer.estdelay */
+ u_fp dispersion; /* peer.estdisp */
+ l_fp offset; /* peer.estoffset */
+ u_fp selectdisp; /* peer select dispersion */
+ int32 unused1; /* (obsolete) */
+ int32 unused2;
+ int32 unused3;
+ int32 unused4;
+ int32 unused5;
+ int32 unused6;
+ int32 unused7;
+ s_fp estbdelay; /* broadcast offset */
+ u_int v6_flag; /* is this v6 or not */
+ u_int unused9; /* (unused) padding for dstadr6 */
+ struct in6_addr dstadr6; /* local address (v6-like) */
+ struct in6_addr srcadr6; /* sources address (v6-like) */
+};
+
+
+/*
+ * Peer statistics structure
+ */
+struct info_peer_stats {
+ u_int32 dstadr; /* local address */
+ u_int32 srcadr; /* remote address */
+ u_short srcport; /* remote port */
+ u_short flags; /* peer flags */
+ u_int32 timereset; /* time counters were reset */
+ u_int32 timereceived; /* time since a packet received */
+ u_int32 timetosend; /* time until a packet sent */
+ u_int32 timereachable; /* time peer has been reachable */
+ u_int32 sent; /* number sent */
+ u_int32 unused1; /* (unused) */
+ u_int32 processed; /* number processed */
+ u_int32 unused2; /* (unused) */
+ u_int32 badauth; /* bad authentication */
+ u_int32 bogusorg; /* bogus origin */
+ u_int32 oldpkt; /* duplicate */
+ u_int32 unused3; /* (unused) */
+ u_int32 unused4; /* (unused) */
+ u_int32 seldisp; /* bad dispersion */
+ u_int32 selbroken; /* bad reference time */
+ u_int32 unused5; /* (unused) */
+ u_char candidate; /* select order */
+ u_char unused6; /* (unused) */
+ u_char unused7; /* (unused) */
+ u_char unused8; /* (unused) */
+ u_int v6_flag; /* is this v6 or not */
+ u_int unused9; /* (unused) padding for dstadr6 */
+ struct in6_addr dstadr6; /* local address */
+ struct in6_addr srcadr6; /* remote address */
+};
+
+
+/*
+ * Loop filter variables
+ */
+struct info_loop {
+ l_fp last_offset;
+ l_fp drift_comp;
+ u_int32 compliance;
+ u_int32 watchdog_timer;
+};
+
+
+/*
+ * System info. Mostly the sys.* variables, plus a few unique to
+ * the implementation.
+ */
+struct info_sys {
+ u_int32 peer; /* system peer address (v4) */
+ u_char peer_mode; /* mode we are syncing to peer in */
+ u_char leap; /* system leap bits */
+ u_char stratum; /* our stratum */
+ s_char precision; /* local clock precision */
+ s_fp rootdelay; /* delay from sync source */
+ u_fp rootdispersion; /* dispersion from sync source */
+ u_int32 refid; /* reference ID of sync source */
+ l_fp reftime; /* system reference time */
+ u_int32 poll; /* system poll interval */
+ u_char flags; /* system flags */
+ u_char unused1; /* unused */
+ u_char unused2; /* unused */
+ u_char unused3; /* unused */
+ s_fp bdelay; /* default broadcast offset */
+ s_fp frequency; /* frequency residual (scaled ppm) */
+ l_fp authdelay; /* default authentication delay */
+ u_fp stability; /* clock stability (scaled ppm) */
+ u_int v6_flag; /* is this v6 or not */
+ u_int unused4; /* unused, padding for peer6 */
+ struct in6_addr peer6; /* system peer address (v6) */
+};
+
+
+/*
+ * System stats. These are collected in the protocol module
+ */
+struct info_sys_stats {
+ u_int32 timeup; /* time since restart */
+ u_int32 timereset; /* time since reset */
+ u_int32 denied; /* access denied */
+ u_int32 oldversionpkt; /* recent version */
+ u_int32 newversionpkt; /* current version */
+ u_int32 unknownversion; /* bad version */
+ u_int32 badlength; /* bad length or format */
+ u_int32 processed; /* packets processed */
+ u_int32 badauth; /* bad authentication */
+ u_int32 received; /* packets received */
+ u_int32 limitrejected; /* rate exceeded */
+ u_int32 lamport; /* Lamport violations */
+ u_int32 tsrounding; /* Timestamp rounding errors */
+};
+
+
+/*
+ * System stats - old version
+ */
+struct old_info_sys_stats {
+ u_int32 timeup; /* time since restart */
+ u_int32 timereset; /* time since reset */
+ u_int32 denied; /* access denied */
+ u_int32 oldversionpkt; /* recent version */
+ u_int32 newversionpkt; /* current version */
+ u_int32 unknownversion; /* bad version */
+ u_int32 badlength; /* bad length or format */
+ u_int32 processed; /* packets processed */
+ u_int32 badauth; /* bad authentication */
+ u_int32 wanderhold; /* (not used) */
+};
+
+
+/*
+ * Peer memory statistics. Collected in the peer module.
+ */
+struct info_mem_stats {
+ u_int32 timereset; /* time since reset */
+ u_short totalpeermem;
+ u_short freepeermem;
+ u_int32 findpeer_calls;
+ u_int32 allocations;
+ u_int32 demobilizations;
+ u_char hashcount[NTP_HASH_SIZE];
+};
+
+
+/*
+ * I/O statistics. Collected in the I/O module
+ */
+struct info_io_stats {
+ u_int32 timereset; /* time since reset */
+ u_short totalrecvbufs; /* total receive bufs */
+ u_short freerecvbufs; /* free buffers */
+ u_short fullrecvbufs; /* full buffers */
+ u_short lowwater; /* number of times we've added buffers */
+ u_int32 dropped; /* dropped packets */
+ u_int32 ignored; /* ignored packets */
+ u_int32 received; /* received packets */
+ u_int32 sent; /* packets sent */
+ u_int32 notsent; /* packets not sent */
+ u_int32 interrupts; /* interrupts we've handled */
+ u_int32 int_received; /* received by interrupt handler */
+};
+
+
+/*
+ * Timer stats. Guess where from.
+ */
+struct info_timer_stats {
+ u_int32 timereset; /* time since reset */
+ u_int32 alarms; /* alarms we've handled */
+ u_int32 overflows; /* timer overflows */
+ u_int32 xmtcalls; /* calls to xmit */
+};
+
+
+/*
+ * Structure for passing peer configuration information
+ */
+struct old_conf_peer {
+ u_int32 peeraddr; /* address to poll */
+ u_char hmode; /* mode, either broadcast, active or client */
+ u_char version; /* version number to poll with */
+ u_char minpoll; /* min host poll interval */
+ u_char maxpoll; /* max host poll interval */
+ u_char flags; /* flags for this request */
+ u_char ttl; /* time to live (multicast) or refclock mode */
+ u_short unused; /* unused */
+ keyid_t keyid; /* key to use for this association */
+};
+
+struct conf_peer {
+ u_int32 peeraddr; /* address to poll */
+ u_char hmode; /* mode, either broadcast, active or client */
+ u_char version; /* version number to poll with */
+ u_char minpoll; /* min host poll interval */
+ u_char maxpoll; /* max host poll interval */
+ u_char flags; /* flags for this request */
+ u_char ttl; /* time to live (multicast) or refclock mode */
+ u_short unused1; /* unused */
+ keyid_t keyid; /* key to use for this association */
+ char keystr[128]; /* public key file name */
+ u_int v6_flag; /* is this v6 or not */
+ u_int unused2; /* unused, padding for peeraddr6 */
+ struct in6_addr peeraddr6; /* ipv6 address to poll */
+};
+
+#define CONF_FLAG_AUTHENABLE 0x01
+#define CONF_FLAG_PREFER 0x02
+#define CONF_FLAG_BURST 0x04
+#define CONF_FLAG_IBURST 0x08
+#define CONF_FLAG_NOSELECT 0x10
+#define CONF_FLAG_SKEY 0x20
+
+/*
+ * Structure for passing peer deletion information. Currently
+ * we only pass the address and delete all configured peers with
+ * this addess.
+ */
+struct conf_unpeer {
+ u_int32 peeraddr; /* address of peer */
+ u_int v6_flag; /* is this v6 or not */
+ struct in6_addr peeraddr6; /* address of peer (v6) */
+};
+
+/*
+ * Structure for carrying system flags.
+ */
+struct conf_sys_flags {
+ u_int32 flags;
+};
+
+/*
+ * System flags we can set/clear
+ */
+#define SYS_FLAG_BCLIENT 0x01
+#define SYS_FLAG_PPS 0x02
+#define SYS_FLAG_NTP 0x04
+#define SYS_FLAG_KERNEL 0x08
+#define SYS_FLAG_MONITOR 0x10
+#define SYS_FLAG_FILEGEN 0x20
+#define SYS_FLAG_AUTH 0x40
+#define SYS_FLAG_CAL 0x80
+
+/*
+ * Structure used for returning restrict entries
+ */
+struct info_restrict {
+ u_int32 addr; /* match address */
+ u_int32 mask; /* match mask */
+ u_int32 count; /* number of packets matched */
+ u_short rflags; /* restrict flags */
+ u_short mflags; /* match flags */
+ u_int v6_flag; /* is this v6 or not */
+ u_int unused1; /* unused, padding for addr6 */
+ struct in6_addr addr6; /* match address (v6) */
+ struct in6_addr mask6; /* match mask (v6) */
+};
+
+
+/*
+ * Structure used for specifying restrict entries
+ */
+struct conf_restrict {
+ u_int32 addr; /* match address */
+ u_int32 mask; /* match mask */
+ short ippeerlimit; /* ip peer limit */
+ u_short flags; /* restrict flags */
+ u_short mflags; /* match flags */
+ u_int v6_flag; /* is this v6 or not */
+ struct in6_addr addr6; /* match address (v6) */
+ struct in6_addr mask6; /* match mask (v6) */
+};
+
+
+/*
+ * Structure used for returning monitor data
+ */
+struct info_monitor_1 {
+ u_int32 avg_int; /* avg s between packets from this host */
+ u_int32 last_int; /* s since we last received a packet */
+ u_int32 restr; /* restrict bits (was named lastdrop) */
+ u_int32 count; /* count of packets received */
+ u_int32 addr; /* host address V4 style */
+ u_int32 daddr; /* destination host address */
+ u_int32 flags; /* flags about destination */
+ u_short port; /* port number of last reception */
+ u_char mode; /* mode of last packet */
+ u_char version; /* version number of last packet */
+ u_int v6_flag; /* is this v6 or not */
+ u_int unused1; /* unused, padding for addr6 */
+ struct in6_addr addr6; /* host address V6 style */
+ struct in6_addr daddr6; /* host address V6 style */
+};
+
+
+/*
+ * Structure used for returning monitor data
+ */
+struct info_monitor {
+ u_int32 avg_int; /* avg s between packets from this host */
+ u_int32 last_int; /* s since we last received a packet */
+ u_int32 restr; /* restrict bits (was named lastdrop) */
+ u_int32 count; /* count of packets received */
+ u_int32 addr; /* host address */
+ u_short port; /* port number of last reception */
+ u_char mode; /* mode of last packet */
+ u_char version; /* version number of last packet */
+ u_int v6_flag; /* is this v6 or not */
+ u_int unused1; /* unused, padding for addr6 */
+ struct in6_addr addr6; /* host v6 address */
+};
+
+/*
+ * Structure used for returning monitor data (old format)
+ */
+struct old_info_monitor {
+ u_int32 lasttime; /* last packet from this host */
+ u_int32 firsttime; /* first time we received a packet */
+ u_int32 count; /* count of packets received */
+ u_int32 addr; /* host address */
+ u_short port; /* port number of last reception */
+ u_char mode; /* mode of last packet */
+ u_char version; /* version number of last packet */
+ u_int v6_flag; /* is this v6 or not */
+ struct in6_addr addr6; /* host address (v6)*/
+};
+
+/*
+ * Structure used for passing indication of flags to clear
+ */
+struct reset_flags {
+ u_int32 flags;
+};
+
+#define RESET_FLAG_ALLPEERS 0x01
+#define RESET_FLAG_IO 0x02
+#define RESET_FLAG_SYS 0x04
+#define RESET_FLAG_MEM 0x08
+#define RESET_FLAG_TIMER 0x10
+#define RESET_FLAG_AUTH 0x20
+#define RESET_FLAG_CTL 0x40
+
+#define RESET_ALLFLAGS ( \
+ RESET_FLAG_ALLPEERS | \
+ RESET_FLAG_IO | \
+ RESET_FLAG_SYS | \
+ RESET_FLAG_MEM | \
+ RESET_FLAG_TIMER | \
+ RESET_FLAG_AUTH | \
+ RESET_FLAG_CTL \
+)
+
+/*
+ * Structure used to return information concerning the authentication
+ * module.
+ */
+struct info_auth {
+ u_int32 timereset; /* time counters were reset */
+ u_int32 numkeys; /* number of keys we know */
+ u_int32 numfreekeys; /* number of free keys */
+ u_int32 keylookups; /* calls to authhavekey() */
+ u_int32 keynotfound; /* requested key unknown */
+ u_int32 encryptions; /* number of encryptions */
+ u_int32 decryptions; /* number of decryptions */
+ u_int32 expired; /* number of expired keys */
+ u_int32 keyuncached; /* calls to encrypt/decrypt with uncached key */
+};
+
+
+/*
+ * Structure used to pass trap information to the client
+ */
+struct info_trap {
+ u_int32 local_address; /* local interface addres (v4) */
+ u_int32 trap_address; /* remote client's addres (v4) */
+ u_short trap_port; /* remote port number */
+ u_short sequence; /* sequence number */
+ u_int32 settime; /* time trap last set */
+ u_int32 origtime; /* time trap originally set */
+ u_int32 resets; /* number of resets on this trap */
+ u_int32 flags; /* trap flags, as defined in ntp_control.h */
+ u_int v6_flag; /* is this v6 or not */
+ struct in6_addr local_address6; /* local interface address (v6) */
+ struct in6_addr trap_address6; /* remote client's address (v6) */
+};
+
+/*
+ * Structure used to pass add/clear trap information to the client
+ */
+struct conf_trap {
+ u_int32 local_address; /* remote client's address */
+ u_int32 trap_address; /* local interface address */
+ u_short trap_port; /* remote client's port */
+ u_short unused; /* (unused) */
+ u_int v6_flag; /* is this v6 or not */
+ struct in6_addr local_address6; /* local interface address (v6) */
+ struct in6_addr trap_address6; /* remote client's address (v6) */
+};
+
+
+/*
+ * Structure used to return statistics from the control module
+ */
+struct info_control {
+ u_int32 ctltimereset;
+ u_int32 numctlreq; /* number of requests we've received */
+ u_int32 numctlbadpkts; /* number of bad control packets */
+ u_int32 numctlresponses; /* # resp packets sent */
+ u_int32 numctlfrags; /* # of fragments sent */
+ u_int32 numctlerrors; /* number of error responses sent */
+ u_int32 numctltooshort; /* number of too short input packets */
+ u_int32 numctlinputresp; /* number of responses on input */
+ u_int32 numctlinputfrag; /* number of fragments on input */
+ u_int32 numctlinputerr; /* # input pkts with err bit set */
+ u_int32 numctlbadoffset; /* # input pkts with nonzero offset */
+ u_int32 numctlbadversion; /* # input pkts with unknown version */
+ u_int32 numctldatatooshort; /* data too short for count */
+ u_int32 numctlbadop; /* bad op code found in packet */
+ u_int32 numasyncmsgs; /* # async messages we've sent */
+};
+
+
+/*
+ * Structure used to return clock information
+ */
+struct info_clock {
+ u_int32 clockadr;
+ u_char type;
+ u_char flags;
+ u_char lastevent;
+ u_char currentstatus;
+ u_int32 polls;
+ u_int32 noresponse;
+ u_int32 badformat;
+ u_int32 baddata;
+ u_int32 timestarted;
+ l_fp fudgetime1;
+ l_fp fudgetime2;
+ int32 fudgeval1;
+ u_int32 fudgeval2;
+};
+
+
+/*
+ * Structure used for setting clock fudge factors
+ */
+struct conf_fudge {
+ u_int32 clockadr;
+ u_int32 which;
+ l_fp fudgetime;
+ u_int32 fudgeval_flags;
+};
+
+#define FUDGE_TIME1 1
+#define FUDGE_TIME2 2
+#define FUDGE_VAL1 3
+#define FUDGE_VAL2 4
+#define FUDGE_FLAGS 5
+
+
+/*
+ * Structure used for returning clock debugging info
+ */
+#define NUMCBUGVALUES 16
+#define NUMCBUGTIMES 32
+
+struct info_clkbug {
+ u_int32 clockadr;
+ u_char nvalues;
+ u_char ntimes;
+ u_short svalues;
+ u_int32 stimes;
+ u_int32 values[NUMCBUGVALUES];
+ l_fp times[NUMCBUGTIMES];
+};
+
+/*
+ * Structure used for returning kernel pll/PPS information
+ */
+struct info_kernel {
+ int32 offset;
+ int32 freq;
+ int32 maxerror;
+ int32 esterror;
+ u_short status;
+ u_short shift;
+ int32 constant;
+ int32 precision;
+ int32 tolerance;
+
+/*
+ * Variables used only if PPS signal discipline is implemented
+ */
+ int32 ppsfreq;
+ int32 jitter;
+ int32 stabil;
+ int32 jitcnt;
+ int32 calcnt;
+ int32 errcnt;
+ int32 stbcnt;
+};
+
+/*
+ * interface statistics
+ */
+struct info_if_stats {
+ union addrun unaddr; /* address */
+ union addrun unbcast; /* broadcast */
+ union addrun unmask; /* mask */
+ u_int32 v6_flag; /* is this v6 */
+ char name[32]; /* name of interface */
+ int32 flags; /* interface flags */
+ int32 last_ttl; /* last TTL specified */
+ int32 num_mcast; /* No. of IP addresses in multicast socket */
+ int32 received; /* number of incoming packets */
+ int32 sent; /* number of outgoing packets */
+ int32 notsent; /* number of send failures */
+ int32 uptime; /* number of seconds this interface was active */
+ u_int32 scopeid; /* Scope used for Multicasting */
+ u_int32 ifindex; /* interface index - from system */
+ u_int32 ifnum; /* sequential interface number */
+ u_int32 peercnt; /* number of peers referencinf this interface - informational only */
+ u_short family; /* Address family */
+ u_char ignore_packets; /* Specify whether the packet should be ignored */
+ u_char action; /* reason the item is listed */
+ int32 _filler0; /* pad to a 64 bit size boundary */
+};
+
+#define IFS_EXISTS 1 /* just exists */
+#define IFS_CREATED 2 /* was just created */
+#define IFS_DELETED 3 /* was just delete */
+
+/*
+ * Info returned with IP -> hostname lookup
+ */
+/* 144 might need to become 32, matching data[] member of req_pkt */
+#define NTP_MAXHOSTNAME (32 - sizeof(u_int32) - sizeof(u_short))
+struct info_dns_assoc {
+ u_int32 peeraddr; /* peer address (HMS: being careful...) */
+ associd_t associd; /* association ID */
+ char hostname[NTP_MAXHOSTNAME]; /* hostname */
+};
+
+/*
+ * function declarations
+ */
+int get_packet_mode(struct recvbuf *rbufp); /* Return packet mode */
+
+#endif /* NTP_REQUEST_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntp_rfc2553.h b/sebhbsd/freebsd/contrib/ntp/include/ntp_rfc2553.h
new file mode 100644
index 0000000..08ccbc4
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntp_rfc2553.h
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)in.h 8.3 (Berkeley) 1/3/94
+ */
+
+/*
+ * Compatability shims with the rfc2553 API to simplify ntp.
+ */
+#ifndef NTP_RFC2553_H
+#define NTP_RFC2553_H
+
+#include <netdb.h>
+#include <isc/net.h>
+
+#include "ntp_types.h"
+#include "ntp_malloc.h"
+
+struct addrinfo *copy_addrinfo_impl(const struct addrinfo *
+#ifdef EREALLOC_CALLSITE /* from ntp_malloc.h */
+ ,
+ const char *, int
+#endif
+ );
+struct addrinfo *copy_addrinfo_list_impl(const struct addrinfo *
+#ifdef EREALLOC_CALLSITE /* from ntp_malloc.h */
+ ,
+ const char *, int
+#endif
+ );
+#ifdef EREALLOC_CALLSITE
+# define copy_addrinfo(l) \
+ copy_addrinfo_impl((l), __FILE__, __LINE__)
+# define copy_addrinfo_list(l) \
+ copy_addrinfo_list_impl((l), __FILE__, __LINE__)
+#else
+# define copy_addrinfo(l) copy_addrinfo_impl(l)
+# define copy_addrinfo_list(l) copy_addrinfo_list_impl(l)
+#endif
+
+/*
+ * If various macros are not defined we need to define them
+ */
+
+#ifndef AF_INET6
+# define AF_INET6 AF_MAX
+# define PF_INET6 AF_INET6
+#endif
+
+#if !defined(_SS_MAXSIZE) && !defined(_SS_ALIGNSIZE)
+
+# define _SS_MAXSIZE 128
+# define _SS_ALIGNSIZE (sizeof(ntp_uint64_t))
+# ifdef ISC_PLATFORM_HAVESALEN
+# define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(u_char) - sizeof(ntp_u_int8_t))
+# define _SS_PAD2SIZE (_SS_MAXSIZE - sizeof(u_char) - sizeof(ntp_u_int8_t) - \
+ _SS_PAD1SIZE - _SS_ALIGNSIZE)
+# else
+# define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(short))
+# define _SS_PAD2SIZE (_SS_MAXSIZE - sizeof(short) - \
+ _SS_PAD1SIZE - _SS_ALIGNSIZE)
+# endif /* ISC_PLATFORM_HAVESALEN */
+#endif
+
+#ifndef INET6_ADDRSTRLEN
+# define INET6_ADDRSTRLEN 46 /* max len of IPv6 addr in ascii */
+#endif
+
+/*
+ * If we don't have the sockaddr_storage structure
+ * we need to define it
+ */
+
+#ifndef HAVE_STRUCT_SOCKADDR_STORAGE
+struct sockaddr_storage {
+#ifdef ISC_PLATFORM_HAVESALEN
+ ntp_u_int8_t ss_len; /* address length */
+ ntp_u_int8_t ss_family; /* address family */
+#else
+ short ss_family; /* address family */
+#endif
+ char __ss_pad1[_SS_PAD1SIZE];
+ ntp_uint64_t __ss_align; /* force desired structure storage alignment */
+ char __ss_pad2[_SS_PAD2SIZE];
+};
+#endif
+
+/*
+ * Finally if the platform doesn't support IPv6 we need some
+ * additional definitions
+ */
+
+/*
+ * Flag values for getaddrinfo()
+ */
+#ifndef AI_PASSIVE
+#define AI_PASSIVE 0x00000001 /* get address to use bind() */
+#define AI_CANONNAME 0x00000002 /* fill ai_canonname */
+#define AI_NUMERICHOST 0x00000004 /* prevent name resolution */
+/* valid flags for addrinfo */
+#define AI_MASK \
+ (AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST | AI_ADDRCONFIG)
+
+#define AI_ADDRCONFIG 0x00000400 /* only if any address is assigned */
+#endif /* !AI_PASSIVE */
+
+#ifndef AI_NUMERICHOST /* such as AIX 4.3 */
+# define Z_AI_NUMERICHOST 0
+#else
+# define Z_AI_NUMERICHOST AI_NUMERICHOST
+#endif
+
+#ifndef AI_NUMERICSERV /* not in RFC 2553 */
+# define Z_AI_NUMERICSERV 0
+#else
+# define Z_AI_NUMERICSERV AI_NUMERICSERV
+#endif
+
+#ifndef ISC_PLATFORM_HAVEIPV6
+
+#ifdef SYS_WINNT
+# define in6_addr in_addr6
+#endif
+
+struct addrinfo {
+ int ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
+ int ai_family; /* PF_xxx */
+ int ai_socktype; /* SOCK_xxx */
+ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
+ size_t ai_addrlen; /* length of ai_addr */
+ char *ai_canonname; /* canonical name for hostname */
+ struct sockaddr *ai_addr; /* binary address */
+ struct addrinfo *ai_next; /* next structure in linked list */
+};
+
+/*
+ * Error return codes from getaddrinfo()
+ */
+#define EAI_ADDRFAMILY 1 /* address family for hostname not supported */
+#define EAI_AGAIN 2 /* temporary failure in name resolution */
+#define EAI_BADFLAGS 3 /* invalid value for ai_flags */
+#define EAI_FAIL 4 /* non-recoverable failure in name resolution */
+#define EAI_FAMILY 5 /* ai_family not supported */
+#define EAI_MEMORY 6 /* memory allocation failure */
+#define EAI_NODATA 7 /* no address associated with hostname */
+#define EAI_NONAME 8 /* hostname nor servname provided, or not known */
+#define EAI_SERVICE 9 /* servname not supported for ai_socktype */
+#define EAI_SOCKTYPE 10 /* ai_socktype not supported */
+#define EAI_SYSTEM 11 /* system error returned in errno */
+#define EAI_BADHINTS 12
+#define EAI_PROTOCOL 13
+#define EAI_MAX 14
+
+
+int getaddrinfo (const char *, const char *,
+ const struct addrinfo *, struct addrinfo **);
+int getnameinfo (const struct sockaddr *, u_int, char *,
+ size_t, char *, size_t, int);
+void freeaddrinfo (struct addrinfo *);
+char *gai_strerror (int);
+
+/*
+ * Constants for getnameinfo()
+ */
+#ifndef NI_MAXHOST
+#define NI_MAXHOST 1025
+#define NI_MAXSERV 32
+#endif
+
+/*
+ * Flag values for getnameinfo()
+ */
+#ifndef NI_NUMERICHOST
+#define NI_NOFQDN 0x00000001
+#define NI_NUMERICHOST 0x00000002
+#define NI_NAMEREQD 0x00000004
+#define NI_NUMERICSERV 0x00000008
+#define NI_DGRAM 0x00000010
+#define NI_WITHSCOPEID 0x00000020
+#endif
+
+#endif /* !ISC_PLATFORM_HAVEIPV6 */
+
+/*
+ * Set up some macros to look for IPv6 and IPv6 multicast
+ */
+
+#if defined(ISC_PLATFORM_HAVEIPV6) && defined(WANT_IPV6)
+# define INCLUDE_IPV6_SUPPORT
+# if defined(IPV6_JOIN_GROUP) && defined(IPV6_LEAVE_GROUP)
+# define INCLUDE_IPV6_MULTICAST_SUPPORT
+# endif /* IPV6 Multicast Support */
+#endif /* IPv6 Support */
+
+#endif /* !NTP_RFC2553_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntp_select.h b/sebhbsd/freebsd/contrib/ntp/include/ntp_select.h
new file mode 100644
index 0000000..2c0fbee
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntp_select.h
@@ -0,0 +1,35 @@
+/*
+ * Not all machines define FD_SET in sys/types.h
+ */
+#ifndef NTP_SELECT_H
+#define NTP_SELECT_H /* note: tested by include/l_stdlib.h */
+
+/* Was: (defined(RS6000)||defined(SYS_PTX))&&!defined(_BSD) */
+/* Could say: !defined(FD_SET) && defined(HAVE_SYS_SELECT_H) */
+/* except FD_SET can legitimately be a typedef... */
+#if defined(HAVE_SYS_SELECT_H) && !defined(_BSD)
+# ifndef SYS_VXWORKS
+# include <sys/select.h>
+# else
+# include <sockLib.h>
+extern int select(int width, fd_set *pReadFds, fd_set *pWriteFds,
+ fd_set *pExceptFds, struct timeval *pTimeOut);
+# endif
+#endif
+
+#if !defined(FD_SET)
+# define NFDBITS 32
+# define FD_SETSIZE 32
+# define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+# define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+# define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+# define FD_ZERO(p) memset((p), 0, sizeof(*(p)))
+#endif
+
+#if defined(VMS)
+typedef struct {
+ unsigned int fds_bits[1];
+} fd_set;
+#endif
+
+#endif /* NTP_SELECT_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntp_stdlib.h b/sebhbsd/freebsd/contrib/ntp/include/ntp_stdlib.h
new file mode 100644
index 0000000..fa0afb8
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntp_stdlib.h
@@ -0,0 +1,298 @@
+/*
+ * ntp_stdlib.h - Prototypes for NTP lib.
+ */
+#ifndef NTP_STDLIB_H
+#define NTP_STDLIB_H
+
+#include <sys/types.h>
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+#include "declcond.h" /* ntpd uses ntpd/declcond.h, others include/ */
+#include "l_stdlib.h"
+#include "ntp_net.h"
+#include "ntp_debug.h"
+#include "ntp_malloc.h"
+#include "ntp_string.h"
+#include "ntp_syslog.h"
+#include "ntp_keyacc.h"
+
+#ifdef __GNUC__
+#define NTP_PRINTF(fmt, args) __attribute__((__format__(__printf__, fmt, args)))
+#else
+#define NTP_PRINTF(fmt, args)
+#endif
+
+extern int mprintf(const char *, ...) NTP_PRINTF(1, 2);
+extern int mfprintf(FILE *, const char *, ...) NTP_PRINTF(2, 3);
+extern int mvfprintf(FILE *, const char *, va_list) NTP_PRINTF(2, 0);
+extern int mvsnprintf(char *, size_t, const char *, va_list)
+ NTP_PRINTF(3, 0);
+extern int msnprintf(char *, size_t, const char *, ...)
+ NTP_PRINTF(3, 4);
+extern void msyslog(int, const char *, ...) NTP_PRINTF(2, 3);
+extern void mvsyslog(int, const char *, va_list) NTP_PRINTF(2, 0);
+extern void init_logging (const char *, u_int32, int);
+extern int change_logfile (const char *, int);
+extern void setup_logfile (const char *);
+#ifndef errno_to_str
+extern void errno_to_str(int, char *, size_t);
+#endif
+
+extern int xvsbprintf(char**, char* const, char const*, va_list) NTP_PRINTF(3, 0);
+extern int xsbprintf(char**, char* const, char const*, ...) NTP_PRINTF(3, 4);
+
+/*
+ * When building without OpenSSL, use a few macros of theirs to
+ * minimize source differences in NTP.
+ */
+#ifndef OPENSSL
+#define NID_md5 4 /* from openssl/objects.h */
+/* from openssl/evp.h */
+#define EVP_MAX_MD_SIZE 64 /* longest known is SHA512 */
+#endif
+
+#define SAVE_ERRNO(stmt) \
+ { \
+ int preserved_errno; \
+ \
+ preserved_errno = socket_errno(); \
+ { \
+ stmt \
+ } \
+ errno = preserved_errno; \
+ }
+
+typedef void (*ctrl_c_fn)(void);
+
+/* authkeys.c */
+extern void auth_delkeys (void);
+extern int auth_havekey (keyid_t);
+extern int authdecrypt (keyid_t, u_int32 *, size_t, size_t);
+extern size_t authencrypt (keyid_t, u_int32 *, size_t);
+extern int authhavekey (keyid_t);
+extern int authistrusted (keyid_t);
+extern int authistrustedip (keyid_t, sockaddr_u *);
+extern int authreadkeys (const char *);
+extern void authtrust (keyid_t, u_long);
+extern int authusekey (keyid_t, int, const u_char *);
+
+/*
+ * Based on the NTP timestamp, calculate the NTP timestamp of
+ * the corresponding calendar unit. Use the pivot time to unfold
+ * the NTP timestamp properly, or the current system time if the
+ * pivot pointer is NULL.
+ */
+extern u_int32 calyearstart (u_int32 ntptime, const time_t *pivot);
+extern u_int32 calmonthstart (u_int32 ntptime, const time_t *pivot);
+extern u_int32 calweekstart (u_int32 ntptime, const time_t *pivot);
+extern u_int32 caldaystart (u_int32 ntptime, const time_t *pivot);
+
+extern const char *clockname (int);
+extern int clocktime (int, int, int, int, int, u_int32, u_long *, u_int32 *);
+extern int ntp_getopt (int, char **, const char *);
+extern void init_auth (void);
+extern void init_lib (void);
+extern struct savekey *auth_findkey (keyid_t);
+extern void auth_moremem (int);
+extern void auth_prealloc_symkeys(int);
+extern int ymd2yd (int, int, int);
+
+/* a_md5encrypt.c */
+extern int MD5authdecrypt (int, const u_char *, size_t, u_int32 *, size_t, size_t);
+extern size_t MD5authencrypt (int, const u_char *, size_t, u_int32 *, size_t);
+extern void MD5auth_setkey (keyid_t, int, const u_char *, size_t, KeyAccT *c);
+extern u_int32 addr2refid (sockaddr_u *);
+
+/* emalloc.c */
+#ifndef EREALLOC_CALLSITE /* ntp_malloc.h defines */
+extern void * ereallocz (void *, size_t, size_t, int);
+extern void * oreallocarrayxz (void *optr, size_t nmemb, size_t size, size_t extra);
+#define erealloczsite(p, n, o, z, f, l) ereallocz((p), (n), (o), (z))
+#define emalloc(n) ereallocz(NULL, (n), 0, FALSE)
+#define emalloc_zero(c) ereallocz(NULL, (c), 0, TRUE)
+#define erealloc(p, c) ereallocz((p), (c), 0, FALSE)
+#define erealloc_zero(p, n, o) ereallocz((p), (n), (o), TRUE)
+#define ereallocarray(p, n, s) oreallocarrayxz((p), (n), (s), 0)
+#define eallocarray(n, s) oreallocarrayxz(NULL, (n), (s), 0)
+#define ereallocarrayxz(p, n, s, x) oreallocarrayxz((p), (n), (s), (x))
+#define eallocarrayxz(n, s, x) oreallocarrayxz(NULL, (n), (s), (x))
+extern char * estrdup_impl(const char *);
+#define estrdup(s) estrdup_impl(s)
+#else
+extern void * ereallocz (void *, size_t, size_t, int,
+ const char *, int);
+extern void * oreallocarrayxz (void *optr, size_t nmemb, size_t size,
+ size_t extra, const char *, int);
+#define erealloczsite ereallocz
+#define emalloc(c) ereallocz(NULL, (c), 0, FALSE, \
+ __FILE__, __LINE__)
+#define emalloc_zero(c) ereallocz(NULL, (c), 0, TRUE, \
+ __FILE__, __LINE__)
+#define erealloc(p, c) ereallocz((p), (c), 0, FALSE, \
+ __FILE__, __LINE__)
+#define erealloc_zero(p, n, o) ereallocz((p), (n), (o), TRUE, \
+ __FILE__, __LINE__)
+#define ereallocarray(p, n, s) oreallocarrayxz((p), (n), (s), 0, \
+ __FILE__, __LINE__)
+#define eallocarray(n, s) oreallocarrayxz(NULL, (n), (s), 0, \
+ __FILE__, __LINE__)
+#define ereallocarrayxz(p, n, s, x) oreallocarrayxz((p), (n), (s), (x), \
+ __FILE__, __LINE__)
+#define eallocarrayxz(n, s, x) oreallocarrayxz(NULL, (n), (s), (x), \
+ __FILE__, __LINE__)
+extern char * estrdup_impl(const char *, const char *, int);
+#define estrdup(s) estrdup_impl((s), __FILE__, __LINE__)
+#endif
+
+
+extern int atoint (const char *, long *);
+extern int atouint (const char *, u_long *);
+extern int hextoint (const char *, u_long *);
+extern const char * humanlogtime (void);
+extern const char * humantime (time_t);
+extern int is_ip_address (const char *, u_short, sockaddr_u *);
+extern char * mfptoa (u_int32, u_int32, short);
+extern char * mfptoms (u_int32, u_int32, short);
+extern const char * modetoa (size_t);
+extern const char * eventstr (int);
+extern const char * ceventstr (int);
+extern const char * res_match_flags(u_short);
+extern const char * res_access_flags(u_short);
+#ifdef KERNEL_PLL
+extern const char * k_st_flags (u_int32);
+#endif
+extern char * statustoa (int, int);
+extern sockaddr_u * netof (sockaddr_u *);
+extern char * numtoa (u_int32);
+extern char * numtohost (u_int32);
+extern const char * socktoa (const sockaddr_u *);
+extern const char * sockporttoa(const sockaddr_u *);
+extern u_short sock_hash (const sockaddr_u *);
+extern int sockaddr_masktoprefixlen(const sockaddr_u *);
+extern const char * socktohost (const sockaddr_u *);
+extern int octtoint (const char *, u_long *);
+extern u_long ranp2 (int);
+extern const char *refnumtoa (sockaddr_u *);
+extern const char *refid_str (u_int32, int);
+
+extern int decodenetnum (const char *, sockaddr_u *);
+
+extern const char * FindConfig (const char *);
+
+#ifndef __rtems__
+extern void signal_no_reset (int, RETSIGTYPE (*func)(int));
+#else /* __rtems__ */
+static inline void
+signal_no_reset(int sig, RETSIGTYPE (*func)(int))
+{
+ (void)sig;
+ (void)func;
+}
+#endif /* __rtems__ */
+extern void set_ctrl_c_hook (ctrl_c_fn);
+
+extern void getauthkeys (const char *);
+extern void auth_agekeys (void);
+extern void rereadkeys (void);
+
+/*
+ * Variable declarations for libntp.
+ */
+
+/* authkeys.c */
+extern u_long authkeynotfound; /* keys not found */
+extern u_long authkeylookups; /* calls to lookup keys */
+extern u_long authnumkeys; /* number of active keys */
+extern u_long authkeyexpired; /* key lifetime expirations */
+extern u_long authkeyuncached; /* cache misses */
+extern u_long authencryptions; /* calls to encrypt */
+extern u_long authdecryptions; /* calls to decrypt */
+
+extern int authnumfreekeys;
+
+/*
+ * The key cache. We cache the last key we looked at here.
+ */
+extern keyid_t cache_keyid; /* key identifier */
+extern int cache_type; /* key type */
+extern u_char * cache_secret; /* secret */
+extern size_t cache_secretsize; /* secret octets */
+extern u_short cache_flags; /* KEY_ bit flags */
+
+/* getopt.c */
+extern char * ntp_optarg; /* global argument pointer */
+extern int ntp_optind; /* global argv index */
+
+/* lib_strbuf.c */
+extern int ipv4_works;
+extern int ipv6_works;
+
+/* machines.c */
+typedef void (*pset_tod_using)(const char *);
+extern pset_tod_using set_tod_using;
+
+/* ssl_init.c */
+#ifdef OPENSSL
+extern void ssl_init (void);
+extern void ssl_check_version (void);
+extern int ssl_init_done;
+#define INIT_SSL() \
+ do { \
+ if (!ssl_init_done) \
+ ssl_init(); \
+ } while (0)
+#else /* !OPENSSL follows */
+#define INIT_SSL() do {} while (0)
+#endif
+extern int keytype_from_text (const char *, size_t *);
+extern const char *keytype_name (int);
+extern char * getpass_keytype (int);
+
+/* strl-obsd.c */
+#ifndef HAVE_STRLCPY /* + */
+/*
+ * Copy src to string dst of size siz. At most siz-1 characters
+ * will be copied. Always NUL terminates (unless siz == 0).
+ * Returns strlen(src); if retval >= siz, truncation occurred.
+ */
+extern size_t strlcpy(char *dst, const char *src, size_t siz);
+#endif
+#ifndef HAVE_STRLCAT /* + */
+/*
+ * Appends src to string dst of size siz (unlike strncat, siz is the
+ * full size of dst, not space left). At most siz-1 characters
+ * will be copied. Always NUL terminates (unless siz <= strlen(dst)).
+ * Returns strlen(src) + MIN(siz, strlen(initial dst)).
+ * If retval >= siz, truncation occurred.
+ */
+extern size_t strlcat(char *dst, const char *src, size_t siz);
+#endif
+
+
+
+/* lib/isc/win32/strerror.c
+ *
+ * To minimize Windows-specific changes to the rest of the NTP code,
+ * particularly reference clocks, we hijack calls to strerror() to deal
+ * with our mixture of error codes from the C runtime (open, write)
+ * and Windows (sockets, serial ports). This is an ugly hack because
+ * both use the lowest values differently, but particularly for ntpd,
+ * it's not a problem.
+ */
+#ifdef NTP_REDEFINE_STRERROR
+#define strerror(e) ntp_strerror(e)
+extern char * ntp_strerror (int e);
+#endif
+
+/* systime.c */
+extern double sys_tick; /* tick size or time to read */
+extern double measured_tick; /* non-overridable sys_tick */
+extern double sys_fuzz; /* min clock read latency */
+extern int trunc_os_clock; /* sys_tick > measured_tick */
+
+/* version.c */
+extern const char *Version; /* version declaration */
+
+#endif /* NTP_STDLIB_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntp_string.h b/sebhbsd/freebsd/contrib/ntp/include/ntp_string.h
new file mode 100644
index 0000000..9b62ec2
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntp_string.h
@@ -0,0 +1,37 @@
+/*
+ * Define string ops: strchr strrchr memcmp memmove memset
+ */
+
+#ifndef NTP_STRING_H
+#define NTP_STRING_H
+
+#ifdef HAVE_MEMORY_H
+# include <memory.h>
+#endif
+
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif
+
+#ifdef HAVE_BSTRING_H
+# include <bstring.h>
+#endif
+
+#ifdef NTP_NEED_BOPS
+
+#ifdef HAVE_STRINGS_H
+# include <strings.h> /* bcmp, bcopy, bzero */
+#endif
+
+void ntp_memset (char *, int, int);
+
+#define memcmp(a, b, c) bcmp(a, b, (int)(c))
+#define memmove(t, f, c) bcopy(f, t, (int)(c))
+#define memcpy(t, f, c) bcopy(f, t, (int)(c))
+#define memset(a, x, c) if (0 == (x)) \
+ bzero(a, (int)(c)); \
+ else \
+ ntp_memset((char *)(a), x, c)
+#endif /* NTP_NEED_BOPS */
+
+#endif /* NTP_STRING_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntp_syscall.h b/sebhbsd/freebsd/contrib/ntp/include/ntp_syscall.h
new file mode 100644
index 0000000..d1ce03e
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntp_syscall.h
@@ -0,0 +1,56 @@
+/*
+ * ntp_syscall.h - various ways to perform the ntp_adjtime() and ntp_gettime()
+ * system calls.
+ */
+
+#ifndef NTP_SYSCALL_H
+#define NTP_SYSCALL_H
+
+#ifdef HAVE_SYS_TIMEX_H
+# include <sys/timex.h>
+#endif
+
+#ifndef NTP_SYSCALLS_LIBC
+# ifdef NTP_SYSCALLS_STD
+# define ntp_adjtime(t) syscall(SYS_ntp_adjtime, (t))
+# define ntp_gettime(t) syscall(SYS_ntp_gettime, (t))
+# else /* !NTP_SYSCALLS_STD */
+# ifdef HAVE_NTP_ADJTIME
+extern int ntp_adjtime (struct timex *);
+
+# ifndef HAVE_STRUCT_NTPTIMEVAL
+struct ntptimeval
+{
+ struct timeval time; /* current time (ro) */
+ long int maxerror; /* maximum error (us) (ro) */
+ long int esterror; /* estimated error (us) (ro) */
+};
+# endif
+
+# ifndef HAVE_NTP_GETTIME
+static inline int
+ntp_gettime(
+ struct ntptimeval *ntv
+ )
+{
+ struct timex tntx;
+ int result;
+
+ ZERO(tntx);
+ result = ntp_adjtime(&tntx);
+ ntv->time = tntx.time;
+ ntv->maxerror = tntx.maxerror;
+ ntv->esterror = tntx.esterror;
+# ifdef NTP_API
+# if NTP_API > 3
+ ntv->tai = tntx.tai;
+# endif
+# endif
+ return result;
+}
+# endif /* !HAVE_NTP_GETTIME */
+# endif /* !HAVE_NTP_ADJTIME */
+# endif /* !NTP_SYSCALLS_STD */
+#endif /* !NTP_SYSCALLS_LIBC */
+
+#endif /* NTP_SYSCALL_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntp_syslog.h b/sebhbsd/freebsd/contrib/ntp/include/ntp_syslog.h
new file mode 100644
index 0000000..ecc6346
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntp_syslog.h
@@ -0,0 +1,86 @@
+/*
+ * A hack for platforms which require specially built syslog facilities
+ */
+
+#ifndef NTP_SYSLOG_H
+#define NTP_SYSLOG_H
+
+#include <ntp_types.h> /* u_int32 type */
+
+#ifdef VMS
+extern void msyslog();
+extern void mvsyslog();
+#else
+# ifndef SYS_VXWORKS
+# include <syslog.h>
+# endif
+#endif /* VMS */
+#include <stdio.h>
+
+extern int syslogit;
+extern int msyslog_term; /* duplicate to stdout/err */
+extern int msyslog_term_pid;
+extern int msyslog_include_timestamp;
+extern FILE * syslog_file; /* if syslogit is FALSE, log to
+ this file and not syslog */
+extern char * syslog_fname;
+extern char * syslog_abs_fname;
+
+#if defined(VMS) || defined (SYS_VXWORKS)
+#define LOG_EMERG 0 /* system is unusable */
+#define LOG_ALERT 1 /* action must be taken immediately */
+#define LOG_CRIT 2 /* critical conditions */
+#define LOG_ERR 3 /* error conditions */
+#define LOG_WARNING 4 /* warning conditions */
+#define LOG_NOTICE 5 /* normal but signification condition */
+#define LOG_INFO 6 /* informational */
+#define LOG_DEBUG 7 /* debug-level messages */
+#endif /* VMS || VXWORKS */
+
+/*
+ * syslog output control
+ */
+#define NLOG_INFO 0x00000001
+#define NLOG_EVENT 0x00000002
+#define NLOG_STATUS 0x00000004
+#define NLOG_STATIST 0x00000008
+
+#define NLOG_OSYS 0 /* offset for system flags */
+#define NLOG_SYSMASK 0x0000000F /* system log events */
+#define NLOG_SYSINFO 0x00000001 /* system info log events */
+#define NLOG_SYSEVENT 0x00000002 /* system events */
+#define NLOG_SYSSTATUS 0x00000004 /* system status (sync/unsync) */
+#define NLOG_SYSSTATIST 0x00000008 /* system statistics output */
+
+#define NLOG_OPEER 4 /* offset for peer flags */
+#define NLOG_PEERMASK 0x000000F0 /* peer log events */
+#define NLOG_PEERINFO 0x00000010 /* peer info log events */
+#define NLOG_PEEREVENT 0x00000020 /* peer events */
+#define NLOG_PEERSTATUS 0x00000040 /* peer status (sync/unsync) */
+#define NLOG_PEERSTATIST 0x00000080 /* peer statistics output */
+
+#define NLOG_OCLOCK 8 /* offset for clock flags */
+#define NLOG_CLOCKMASK 0x00000F00 /* clock log events */
+#define NLOG_CLOCKINFO 0x00000100 /* clock info log events */
+#define NLOG_CLOCKEVENT 0x00000200 /* clock events */
+#define NLOG_CLOCKSTATUS 0x00000400 /* clock status (sync/unsync) */
+#define NLOG_CLOCKSTATIST 0x00000800 /* clock statistics output */
+
+#define NLOG_OSYNC 12 /* offset for sync flags */
+#define NLOG_SYNCMASK 0x0000F000 /* sync log events */
+#define NLOG_SYNCINFO 0x00001000 /* sync info log events */
+#define NLOG_SYNCEVENT 0x00002000 /* sync events */
+#define NLOG_SYNCSTATUS 0x00004000 /* sync status (sync/unsync) */
+#define NLOG_SYNCSTATIST 0x00008000 /* sync statistics output */
+
+extern u_int32 ntp_syslogmask;
+
+#define NLOG(bits) if (ntp_syslogmask & (bits))
+
+#define LOGIF(nlog_suffix, msl_args) \
+do { \
+ NLOG(NLOG_##nlog_suffix) /* like "if (...) */ \
+ msyslog msl_args; \
+} while (FALSE)
+
+#endif /* NTP_SYSLOG_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntp_tty.h b/sebhbsd/freebsd/contrib/ntp/include/ntp_tty.h
new file mode 100644
index 0000000..6dc48b6
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntp_tty.h
@@ -0,0 +1,103 @@
+/*
+ * ntp_tty.h - header file for serial lines handling
+ */
+#ifndef NTP_TTY_H
+#define NTP_TTY_H
+
+/*
+ * use only one tty model - no use in initialising
+ * a tty in three ways
+ * HAVE_TERMIOS is preferred over HAVE_SYSV_TTYS over HAVE_BSD_TTYS
+ */
+
+#if defined(HAVE_TERMIOS_H) || defined(HAVE_SYS_TERMIOS_H)
+# define HAVE_TERMIOS
+#elif defined(HAVE_TERMIO_H)
+# define HAVE_SYSV_TTYS
+#elif defined(HAVE_SGTTY_H)
+# define HAVE_BSD_TTYS
+#endif
+
+#if !defined(VMS) && !defined(SYS_VXWORKS)
+# if !defined(HAVE_SYSV_TTYS) \
+ && !defined(HAVE_BSD_TTYS) \
+ && !defined(HAVE_TERMIOS)
+#include "ERROR: no tty type defined!"
+# endif
+#endif /* !VMS && !SYS_VXWORKS*/
+
+#if defined(HAVE_BSD_TTYS)
+#include <sgtty.h>
+#define TTY struct sgttyb
+#endif /* HAVE_BSD_TTYS */
+
+#if defined(HAVE_SYSV_TTYS)
+#include <termio.h>
+#define TTY struct termio
+#ifndef tcsetattr
+#define tcsetattr(fd, cmd, arg) ioctl(fd, cmd, arg)
+#endif
+#ifndef TCSANOW
+#define TCSANOW TCSETA
+#endif
+#ifndef TCIFLUSH
+#define TCIFLUSH 0
+#endif
+#ifndef TCOFLUSH
+#define TCOFLUSH 1
+#endif
+#ifndef TCIOFLUSH
+#define TCIOFLUSH 2
+#endif
+#ifndef tcflush
+#define tcflush(fd, arg) ioctl(fd, TCFLSH, arg)
+#endif
+#endif /* HAVE_SYSV_TTYS */
+
+#if defined(HAVE_TERMIOS)
+# if defined(HAVE_TERMIOS_H)
+# ifdef TERMIOS_NEEDS__SVID3
+# define _SVID3
+# endif
+# include <termios.h>
+# ifdef TERMIOS_NEEDS__SVID3
+# undef _SVID3
+# endif
+# elif defined(HAVE_SYS_TERMIOS_H)
+# include <sys/termios.h>
+# endif
+# define TTY struct termios
+#endif
+
+#if defined(HAVE_SYS_MODEM_H)
+#include <sys/modem.h>
+#endif
+
+/*
+ * Line discipline flags. The depredated ones required line discipline
+ * or streams modules to be installed/loaded in the kernel and are now
+ * ignored. Leave the LDISC_CLK and other deprecated symbols defined
+ * until 2013 or 2014 to avoid complicating the use of newer drivers on
+ * older ntpd, which is often as easy as dropping in the refclock *.c.
+ */
+#define LDISC_STD 0x000 /* standard */
+#define LDISC_CLK 0x001 /* depredated tty_clk \n */
+#define LDISC_CLKPPS 0x002 /* depredated tty_clk \377 */
+#define LDISC_ACTS 0x004 /* depredated tty_clk #* */
+#define LDISC_CHU 0x008 /* depredated */
+#define LDISC_PPS 0x010 /* depredated */
+#define LDISC_RAW 0x020 /* raw binary */
+#define LDISC_ECHO 0x040 /* enable echo */
+#define LDISC_REMOTE 0x080 /* remote mode */
+#define LDISC_7O1 0x100 /* 7-bit, odd parity for Z3801A */
+
+/* function prototypes for ntp_tty.c */
+#if !defined(SYS_VXWORKS) && !defined(SYS_WINNT)
+# if defined(HAVE_TERMIOS) || defined(HAVE_SYSV_TTYS) || \
+ defined(HAVE_BSD_TTYS)
+extern int ntp_tty_setup(int, u_int, u_int);
+extern int ntp_tty_ioctl(int, u_int);
+# endif
+#endif
+
+#endif /* NTP_TTY_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntp_types.h b/sebhbsd/freebsd/contrib/ntp/include/ntp_types.h
new file mode 100644
index 0000000..969b325
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntp_types.h
@@ -0,0 +1,302 @@
+/*
+ * ntp_types.h - defines how int32 and u_int32 are treated.
+ *
+ * New style: Make sure C99 fixed width integer types are available:
+ * intN_t and uintN_t
+
+ * Old style: defines how int32 and u_int32 are treated.
+ * For 64 bit systems like the DEC Alpha, they have to be defined
+ * as int and u_int.
+ * For 32 bit systems, define them as long and u_long
+ */
+#ifndef NTP_TYPES_H
+#define NTP_TYPES_H
+
+#include <sys/types.h>
+#if defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#endif
+#if defined(HAVE_STDINT_H)
+# include <stdint.h>
+#endif
+
+/* Bug 2813 */
+#ifdef HAVE_LIMITS_H
+# include <limits.h>
+#endif
+
+#include "ntp_machine.h"
+
+
+#ifndef TRUE
+# define TRUE 1
+#endif
+#ifndef FALSE
+# define FALSE 0
+#endif
+
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+typedef int bool; /* Can't use enum TRUE/FALSE because of above */
+#endif
+
+
+/*
+ * This is another naming conflict.
+ * On NetBSD for MAC the macro "mac" is defined as 1
+ * this is fun for us as a packet structure contains an
+ * optional "mac" member - severe confusion results 8-)
+ * As we hopefully do not have to rely on that macro we
+ * just undefine that.
+ */
+#ifdef mac
+#undef mac
+#endif
+
+/*
+ * used to quiet compiler warnings
+ */
+#ifndef UNUSED_ARG
+#define UNUSED_ARG(arg) ((void)(arg))
+#endif
+#ifndef UNUSED_LOCAL
+#define UNUSED_LOCAL(arg) ((void)(arg))
+#endif
+
+/*
+ * COUNTOF(array) - size of array in elements
+ */
+#define COUNTOF(arr) (sizeof(arr) / sizeof((arr)[0]))
+
+/*
+ * VMS DECC (v4.1), {u_char,u_short,u_long} are only in SOCKET.H,
+ * and u_int isn't defined anywhere
+ */
+#if defined(VMS)
+#include <socket.h>
+typedef unsigned int u_int;
+#endif /* VMS */
+
+#ifdef HAVE_UINT32_T
+# ifndef HAVE_INT32
+ typedef int32_t int32;
+# endif
+# ifndef HAVE_U_INT32
+ typedef uint32_t u_int32;
+# if defined(UINT32_MAX) && !defined(U_INT32_MAX)
+# define U_INT32_MAX UINT32_MAX
+# endif
+# endif
+#elif (SIZEOF_INT == 4)
+# if !defined(HAVE_INT32) && !defined(int32)
+ typedef int int32;
+# ifndef INT32_MIN
+# define INT32_MIN INT_MIN
+# endif
+# ifndef INT32_MAX
+# define INT32_MAX INT_MAX
+# endif
+# endif
+# if !defined(HAVE_U_INT32) && !defined(u_int32)
+ typedef unsigned u_int32;
+# if defined(UINT_MAX) && !defined(U_INT32_MAX)
+# define U_INT32_MAX UINT_MAX
+# endif
+# endif
+#else /* SIZEOF_INT != 4 */
+# if (SIZEOF_LONG == 4)
+# if !defined(HAVE_INT32) && !defined(int32)
+ typedef long int32;
+# ifndef INT32_MIN
+# define INT32_MIN LONG_MIN
+# endif
+# ifndef INT32_MAX
+# define INT32_MAX LONG_MAX
+# endif
+# endif
+# if !defined(HAVE_U_INT32) && !defined(u_int32)
+ typedef unsigned long u_int32;
+# if defined(ULONG_MAX) && !defined(U_INT32_MAX)
+# define U_INT32_MAX ULONG_MAX
+# endif
+# endif
+# else /* SIZEOF_LONG != 4 */
+# include "Bletch: what's 32 bits on this machine?"
+# endif
+#endif /* !HAVE_UINT32_T && SIZEOF_INT != 4 */
+
+#ifndef U_INT32_MAX
+# define U_INT32_MAX 0xffffffff
+#endif
+
+
+/*
+ * Ugly dance to find out if we have 64bit integer type.
+ */
+#if !defined(HAVE_INT64)
+
+/* assume best for now, fix if frustrated later. */
+# define HAVE_INT64
+# define HAVE_U_INT64
+
+/* now check the cascade. Feel free to add things. */
+# ifdef INT64_MAX
+
+typedef int64_t int64;
+typedef uint64_t u_int64;
+
+# elif SIZEOF_LONG == 8
+
+typedef long int64;
+typedef unsigned long u_int64;
+
+# elif SIZEOF_LONG_LONG == 8
+
+typedef long long int64;
+typedef unsigned long long u_int64;
+
+# else
+
+/* no 64bit scalar, give it up. */
+# undef HAVE_INT64
+# undef HAVE_U_INT64
+
+# endif
+
+#endif
+
+/*
+ * and here the trouble starts: We need a representation with more than
+ * 64 bits. If a scalar of that size is not available, we need a struct
+ * that holds the value in split representation.
+ *
+ * To ease the usage a bit, we alwys use a union that is in processor
+ * byte order and might or might not contain a 64bit scalar.
+ */
+
+#if SIZEOF_SHORT != 2
+# error short is not 2 bytes -- what is 16 bit integer on this target?
+#endif
+
+typedef union {
+# ifdef WORDS_BIGENDIAN
+ struct {
+ int16_t hh; uint16_t hl; uint16_t lh; uint16_t ll;
+ } w_s;
+ struct {
+ uint16_t hh; uint16_t hl; uint16_t lh; uint16_t ll;
+ } W_s;
+ struct {
+ int32 hi; u_int32 lo;
+ } d_s;
+ struct {
+ u_int32 hi; u_int32 lo;
+ } D_s;
+# else
+ struct {
+ uint16_t ll; uint16_t lh; uint16_t hl; int16_t hh;
+ } w_s;
+ struct {
+ uint16_t ll; uint16_t lh; uint16_t hl; uint16_t hh;
+ } W_s;
+ struct {
+ u_int32 lo; int32 hi;
+ } d_s;
+ struct {
+ u_int32 lo; u_int32 hi;
+ } D_s;
+# endif
+
+# ifdef HAVE_INT64
+ int64 q_s; /* signed quad scalar */
+ u_int64 Q_s; /* unsigned quad scalar */
+# endif
+} vint64; /* variant int 64 */
+
+
+typedef uint8_t ntp_u_int8_t;
+typedef uint16_t ntp_u_int16_t;
+typedef uint32_t ntp_u_int32_t;
+
+typedef struct ntp_uint64_t { u_int32 val[2]; } ntp_uint64_t;
+
+typedef uint16_t associd_t; /* association ID */
+#define ASSOCID_MAX USHRT_MAX
+typedef u_int32 keyid_t; /* cryptographic key ID */
+#define KEYID_T_MAX (0xffffffff)
+
+typedef u_int32 tstamp_t; /* NTP seconds timestamp */
+
+/*
+ * Cloning malloc()'s behavior of always returning pointers suitably
+ * aligned for the strictest alignment requirement of any type is not
+ * easy to do portably, as the maximum alignment required is not
+ * exposed. Use the size of a union of the types known to represent the
+ * strictest alignment on some platform.
+ */
+typedef union max_alignment_tag {
+ double d;
+} max_alignment;
+
+#define MAXALIGN sizeof(max_alignment)
+#define ALIGN_UNITS(sz) (((sz) + MAXALIGN - 1) / MAXALIGN)
+#define ALIGNED_SIZE(sz) (MAXALIGN * ALIGN_UNITS(sz))
+#define INC_ALIGNED_PTR(b, m) ((void *)aligned_ptr((void *)(b), m))
+
+static inline
+max_alignment *
+aligned_ptr(
+ max_alignment * base,
+ size_t minsize
+ )
+{
+ return base + ALIGN_UNITS((minsize < 1) ? 1 : minsize);
+}
+
+/*
+ * Macro to use in otherwise-empty source files to comply with ANSI C
+ * requirement that each translation unit (source file) contain some
+ * declaration. This has commonly been done by declaring an unused
+ * global variable of type int or char. An extern reference to exit()
+ * serves the same purpose without bloat.
+ */
+#define NONEMPTY_TRANSLATION_UNIT extern void exit(int);
+
+/*
+ * On Unix struct sock_timeval is equivalent to struct timeval.
+ * On Windows built with 64-bit time_t, sock_timeval.tv_sec is a long
+ * as required by Windows' socket() interface timeout argument, while
+ * timeval.tv_sec is time_t for the more common use as a UTC time
+ * within NTP.
+ */
+#ifndef SYS_WINNT
+#define sock_timeval timeval
+#endif
+
+/*
+ * On Unix open() works for tty (serial) devices just fine, while on
+ * Windows refclock serial devices are opened using CreateFile, a lower
+ * level than the CRT-provided descriptors, because the C runtime lacks
+ * tty APIs. For refclocks which wish to use open() as well as or
+ * instead of refclock_open(), tty_open() is equivalent to open() on
+ * Unix and implemented in the Windows port similarly to
+ * refclock_open().
+ * Similarly, the termios emulation in the Windows code needs to know
+ * about serial ports being closed, while the Posix systems do not.
+ */
+#ifndef SYS_WINNT
+# define tty_open(f, a, m) open(f, a, m)
+# define closeserial(fd) close(fd)
+# define closesocket(fd) close(fd)
+typedef int SOCKET;
+# define INVALID_SOCKET (-1)
+# define SOCKET_ERROR (-1)
+# define socket_errno() (errno)
+#else /* SYS_WINNT follows */
+# define socket_errno() (errno = WSAGetLastError())
+#endif
+
+
+
+#endif /* NTP_TYPES_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntp_unixtime.h b/sebhbsd/freebsd/contrib/ntp/include/ntp_unixtime.h
new file mode 100644
index 0000000..eaa8b1e
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntp_unixtime.h
@@ -0,0 +1,47 @@
+/*
+ * ntp_unixtime.h - much of what was here is now in timevalops.h
+ */
+
+#ifndef NTP_UNIXTIME_H
+#define NTP_UNIXTIME_H
+
+#include "ntp_types.h" /* picks up time.h via ntp_machine.h */
+#include "ntp_calendar.h"
+
+#ifdef SIM
+# define GETTIMEOFDAY(a, b) (node_gettime(&ntp_node, a))
+# define SETTIMEOFDAY(a, b) (node_settime(&ntp_node, a))
+# define ADJTIMEOFDAY(a, b) (node_adjtime(&ntp_node, a, b))
+#else
+# define ADJTIMEOFDAY(a, b) (adjtime(a, b))
+/* gettimeofday() takes two args in BSD and only one in SYSV */
+# if defined(HAVE_SYS_TIMERS_H) && defined(HAVE_GETCLOCK)
+# include <sys/timers.h>
+int getclock (int clock_type, struct timespec *tp);
+# define GETTIMEOFDAY(a, b) (gettimeofday(a, b))
+# define SETTIMEOFDAY(a, b) (settimeofday(a, b))
+# else /* not (HAVE_SYS_TIMERS_H && HAVE_GETCLOCK) */
+# ifdef SYSV_TIMEOFDAY
+# define GETTIMEOFDAY(a, b) (gettimeofday(a))
+# define SETTIMEOFDAY(a, b) (settimeofday(a))
+# else /* ! SYSV_TIMEOFDAY */
+#if defined SYS_CYGWIN32
+# define GETTIMEOFDAY(a, b) (gettimeofday(a, b))
+# define SETTIMEOFDAY(a, b) (settimeofday_NT(a))
+#else
+# define GETTIMEOFDAY(a, b) (gettimeofday(a, b))
+# define SETTIMEOFDAY(a, b) (settimeofday(a, b))
+#endif
+# endif /* SYSV_TIMEOFDAY */
+# endif /* not (HAVE_SYS_TIMERS_H && HAVE_GETCLOCK) */
+#endif /* SIM */
+
+/*
+ * Time of day conversion constant. Ntp's time scale starts in 1900,
+ * Unix in 1970. The value is 1970 - 1900 in seconds, 0x83aa7e80 or
+ * 2208988800. This is larger than 32-bit INT_MAX, so unsigned
+ * type is forced.
+ */
+#define JAN_1970 ((u_int)NTP_TO_UNIX_DAYS * (u_int)SECSPERDAY)
+
+#endif /* !defined(NTP_UNIXTIME_H) */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntp_worker.h b/sebhbsd/freebsd/contrib/ntp/include/ntp_worker.h
new file mode 100644
index 0000000..49ffef4
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntp_worker.h
@@ -0,0 +1,197 @@
+/*
+ * ntp_worker.h
+ */
+
+#ifndef NTP_WORKER_H
+#define NTP_WORKER_H
+
+#include "ntp_workimpl.h"
+
+#ifdef WORKER
+# if defined(WORK_THREAD) && defined(WORK_PIPE)
+# ifdef HAVE_SEMAPHORE_H
+# include <semaphore.h>
+# endif
+# endif
+#include "ntp_stdlib.h"
+
+/* #define TEST_BLOCKING_WORKER */ /* ntp_config.c ntp_intres.c */
+
+typedef enum blocking_work_req_tag {
+ BLOCKING_GETNAMEINFO,
+ BLOCKING_GETADDRINFO,
+} blocking_work_req;
+
+typedef void (*blocking_work_callback)(blocking_work_req, void *, size_t, void *);
+
+typedef enum blocking_magic_sig_e {
+ BLOCKING_REQ_MAGIC = 0x510c7ecf,
+ BLOCKING_RESP_MAGIC = 0x510c7e54,
+} blocking_magic_sig;
+
+/*
+ * The same header is used for both requests to and responses from
+ * the child. In the child, done_func and context are opaque.
+ */
+typedef struct blocking_pipe_header_tag {
+ size_t octets;
+ blocking_magic_sig magic_sig;
+ blocking_work_req rtype;
+ u_int child_idx;
+ blocking_work_callback done_func;
+ void * context;
+} blocking_pipe_header;
+
+# ifdef WORK_THREAD
+# ifdef SYS_WINNT
+typedef struct { HANDLE thnd; } thread_type;
+typedef struct { HANDLE shnd; } sema_type;
+# else
+typedef pthread_t thread_type;
+typedef sem_t sema_type;
+# endif
+typedef thread_type *thr_ref;
+typedef sema_type *sem_ref;
+# endif
+
+/*
+ *
+ */
+#if defined(WORK_FORK)
+
+typedef struct blocking_child_tag {
+ int reusable;
+ int pid;
+ int req_write_pipe; /* parent */
+ int resp_read_pipe;
+ void * resp_read_ctx;
+ int req_read_pipe; /* child */
+ int resp_write_pipe;
+ int ispipe;
+ volatile u_int resp_ready_seen; /* signal/scan */
+ volatile u_int resp_ready_done; /* consumer/mainloop */
+} blocking_child;
+
+#elif defined(WORK_THREAD)
+
+typedef struct blocking_child_tag {
+ /*
+ * blocking workitems and blocking_responses are
+ * dynamically-sized one-dimensional arrays of pointers to
+ * blocking worker requests and responses.
+ *
+ * IMPORTANT: This structure is shared between threads, and all
+ * access that is not atomic (especially queue operations) must
+ * hold the 'accesslock' semaphore to avoid data races.
+ *
+ * The resource management (thread/semaphore
+ * creation/destruction) functions and functions just testing a
+ * handle are safe because these are only changed by the main
+ * thread when no worker is running on the same data structure.
+ */
+ int reusable;
+ sem_ref accesslock; /* shared access lock */
+ thr_ref thread_ref; /* thread 'handle' */
+
+ /* the reuest queue */
+ blocking_pipe_header ** volatile
+ workitems;
+ volatile size_t workitems_alloc;
+ size_t head_workitem; /* parent */
+ size_t tail_workitem; /* child */
+ sem_ref workitems_pending; /* signalling */
+
+ /* the response queue */
+ blocking_pipe_header ** volatile
+ responses;
+ volatile size_t responses_alloc;
+ size_t head_response; /* child */
+ size_t tail_response; /* parent */
+
+ /* event handles / sem_t pointers */
+ sem_ref wake_scheduled_sleep;
+
+ /* some systems use a pipe for notification, others a semaphore.
+ * Both employ the queue above for the actual data transfer.
+ */
+#ifdef WORK_PIPE
+ int resp_read_pipe; /* parent */
+ int resp_write_pipe; /* child */
+ int ispipe;
+ void * resp_read_ctx; /* child */
+#else
+ sem_ref responses_pending; /* signalling */
+#endif
+ volatile u_int resp_ready_seen; /* signal/scan */
+ volatile u_int resp_ready_done; /* consumer/mainloop */
+ sema_type sem_table[4];
+ thread_type thr_table[1];
+} blocking_child;
+
+#endif /* WORK_THREAD */
+
+/* we need some global tag to indicate any blocking child may be ready: */
+extern volatile u_int blocking_child_ready_seen;/* signal/scan */
+extern volatile u_int blocking_child_ready_done;/* consumer/mainloop */
+
+extern blocking_child ** blocking_children;
+extern size_t blocking_children_alloc;
+extern int worker_per_query; /* boolean */
+extern int intres_req_pending;
+
+extern u_int available_blocking_child_slot(void);
+extern int queue_blocking_request(blocking_work_req, void *,
+ size_t, blocking_work_callback,
+ void *);
+extern int queue_blocking_response(blocking_child *,
+ blocking_pipe_header *, size_t,
+ const blocking_pipe_header *);
+extern void process_blocking_resp(blocking_child *);
+extern void harvest_blocking_responses(void);
+extern int send_blocking_req_internal(blocking_child *,
+ blocking_pipe_header *,
+ void *);
+extern int send_blocking_resp_internal(blocking_child *,
+ blocking_pipe_header *);
+extern blocking_pipe_header *
+ receive_blocking_req_internal(blocking_child *);
+extern blocking_pipe_header *
+ receive_blocking_resp_internal(blocking_child *);
+extern int blocking_child_common(blocking_child *);
+extern void exit_worker(int)
+ __attribute__ ((__noreturn__));
+extern int worker_sleep(blocking_child *, time_t);
+extern void worker_idle_timer_fired(void);
+extern void interrupt_worker_sleep(void);
+extern int req_child_exit(blocking_child *);
+#ifndef HAVE_IO_COMPLETION_PORT
+extern int pipe_socketpair(int fds[2], int *is_pipe);
+extern void close_all_beyond(int);
+extern void close_all_except(int);
+extern void kill_asyncio (int);
+#endif
+
+extern void worker_global_lock(int inOrOut);
+
+# ifdef WORK_PIPE
+typedef void (*addremove_io_fd_func)(int, int, int);
+extern addremove_io_fd_func addremove_io_fd;
+# else
+extern void handle_blocking_resp_sem(void *);
+typedef void (*addremove_io_semaphore_func)(sem_ref, int);
+extern addremove_io_semaphore_func addremove_io_semaphore;
+# endif
+
+# ifdef WORK_FORK
+extern int worker_process;
+# endif
+
+#endif /* WORKER */
+
+#if defined(HAVE_DROPROOT) && defined(WORK_FORK)
+extern void fork_deferred_worker(void);
+#else
+# define fork_deferred_worker() do {} while (0)
+#endif
+
+#endif /* !NTP_WORKER_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntp_workimpl.h b/sebhbsd/freebsd/contrib/ntp/include/ntp_workimpl.h
new file mode 100644
index 0000000..a86c2cd
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntp_workimpl.h
@@ -0,0 +1,30 @@
+/*
+ * ntp_workimpl.h - selects worker child implementation
+ */
+#ifndef NTP_WORKIMPL_H
+#define NTP_WORKIMPL_H
+
+/*
+ * Some systems do not support fork() and don't have an alternate
+ * threads implementation of ntp_intres. Such systems are limited
+ * to using numeric IP addresses.
+ */
+#if defined(SYS_WINNT)
+# define WORK_THREAD
+#elif defined(ISC_PLATFORM_USETHREADS) && \
+ defined(HAVE_SEM_TIMEDWAIT) && \
+ (defined(HAVE_GETCLOCK) || defined(HAVE_CLOCK_GETTIME))
+# define WORK_THREAD
+# define WORK_PIPE
+#elif defined(VMS) || defined(SYS_VXWORKS)
+ /* empty */
+#elif defined(HAVE_WORKING_FORK)
+# define WORK_FORK
+# define WORK_PIPE
+#endif
+
+#if defined(WORK_FORK) || defined(WORK_THREAD)
+# define WORKER
+#endif
+
+#endif /* !NTP_WORKIMPL_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntpd.h b/sebhbsd/freebsd/contrib/ntp/include/ntpd.h
new file mode 100644
index 0000000..ead0c2c
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntpd.h
@@ -0,0 +1,585 @@
+/*
+ * ntpd.h - Prototypes and external variables for ntpd.
+ *
+ * Note the first half is primarily function prototypes, type
+ * declarations, and preprocessor macros, with variables declared
+ * primarily in the second half.
+ *
+ * Each half is further divided into sections for each source file.
+ */
+
+#include "ntp.h"
+#include "ntp_stdlib.h"
+#include "ntp_syslog.h"
+#include "ntp_debug.h"
+#include "ntp_syslog.h"
+#include "ntp_select.h"
+#include "ntp_malloc.h"
+#include "ntp_refclock.h"
+#include "ntp_intres.h"
+#include "recvbuff.h"
+
+/*
+ * First half: ntpd types, functions, macros
+ * -----------------------------------------
+ */
+
+/*
+ * macro for debugging output - cut down on #ifdef pollution.
+ *
+ * DPRINTF() is for use by ntpd only, and compiles away to nothing
+ * without DEBUG (configure --disable-debugging).
+ *
+ * TRACE() is similar for libntp and utilities, which retain full
+ * debug capability even when compiled without DEBUG.
+ *
+ * The calling convention is not attractive:
+ * DPRINTF(debuglevel, (fmt, ...));
+ * DPRINTF(2, ("shows #ifdef DEBUG and if debug >= %d\n", 2));
+ */
+#ifdef DEBUG
+# define DPRINTF(lvl, arg) \
+ do { \
+ if (debug >= (lvl)) \
+ mprintf arg; \
+ } while (0)
+#else
+# define DPRINTF(lvl, arg) do {} while (0)
+#endif
+
+
+/* nt_clockstuff.c */
+#ifdef SYS_WINNT
+extern void win_time_stepped(void);
+#endif
+
+/* ntp_config.c */
+#define TAI_1972 10 /* initial TAI offset (s) */
+extern char *keysdir; /* crypto keys and leaptable directory */
+extern char * saveconfigdir; /* ntpq saveconfig output directory */
+
+extern void getconfig (int, char **);
+extern void ctl_clr_stats (void);
+extern int ctlclrtrap (sockaddr_u *, struct interface *, int);
+extern u_short ctlpeerstatus (struct peer *);
+extern int ctlsettrap (sockaddr_u *, struct interface *, int, int);
+extern u_short ctlsysstatus (void);
+extern void init_control (void);
+extern void process_control (struct recvbuf *, int);
+extern void report_event (int, struct peer *, const char *);
+extern int mprintf_event (int, struct peer *, const char *, ...)
+ NTP_PRINTF(3, 4);
+
+/* ntp_control.c */
+/*
+ * Structure for translation tables between internal system
+ * variable indices and text format.
+ */
+struct ctl_var {
+ u_short code;
+ u_short flags;
+ const char *text;
+};
+/*
+ * Flag values
+ */
+#define CAN_READ 0x01
+#define CAN_WRITE 0x02
+
+#define DEF 0x20
+#define PADDING 0x40
+#define EOV 0x80
+
+#define RO (CAN_READ)
+#define WO (CAN_WRITE)
+#define RW (CAN_READ|CAN_WRITE)
+
+extern char * add_var (struct ctl_var **, u_long, u_short);
+extern void free_varlist (struct ctl_var *);
+extern void set_var (struct ctl_var **, const char *, u_long, u_short);
+extern void set_sys_var (const char *, u_long, u_short);
+extern const char * get_ext_sys_var(const char *tag);
+
+/* ntp_io.c */
+typedef struct interface_info {
+ endpt * ep;
+ u_char action;
+} interface_info_t;
+
+typedef void (*interface_receiver_t) (void *, interface_info_t *);
+
+extern void interface_enumerate (interface_receiver_t, void *);
+extern endpt * getinterface (sockaddr_u *, u_int32);
+extern endpt * select_peerinterface (struct peer *, sockaddr_u *,
+ endpt *);
+extern endpt * findinterface (sockaddr_u *);
+extern endpt * findbcastinter (sockaddr_u *);
+extern void enable_broadcast (endpt *, sockaddr_u *);
+extern void enable_multicast_if (endpt *, sockaddr_u *);
+extern void interface_update (interface_receiver_t, void *);
+#ifndef HAVE_IO_COMPLETION_PORT
+extern void io_handler (void);
+#endif
+extern void init_io (void);
+extern void io_open_sockets (void);
+extern void io_clr_stats (void);
+extern void io_setbclient (void);
+extern void io_unsetbclient (void);
+extern void io_multicast_add(sockaddr_u *);
+extern void io_multicast_del(sockaddr_u *);
+extern void sendpkt (sockaddr_u *, struct interface *, int, struct pkt *, int);
+#ifdef DEBUG
+extern void collect_timing (struct recvbuf *, const char *, int, l_fp *);
+#endif
+#ifdef HAVE_SIGNALED_IO
+extern void wait_for_signal (void);
+extern void unblock_io_and_alarm (void);
+extern void block_io_and_alarm (void);
+# define UNBLOCK_IO_AND_ALARM() unblock_io_and_alarm()
+# define BLOCK_IO_AND_ALARM() block_io_and_alarm()
+#else
+# define UNBLOCK_IO_AND_ALARM() do {} while (0)
+# define BLOCK_IO_AND_ALARM() do {} while (0)
+#endif
+#define latoa(pif) localaddrtoa(pif)
+extern const char * localaddrtoa(endpt *);
+
+/* ntp_loopfilter.c */
+extern void init_loopfilter(void);
+extern int local_clock(struct peer *, double);
+extern void adj_host_clock(void);
+extern void loop_config(int, double);
+extern void select_loop(int);
+extern void huffpuff(void);
+extern u_long sys_clocktime;
+extern u_int sys_tai;
+extern int freq_cnt;
+
+/* ntp_monitor.c */
+#define MON_HASH_SIZE ((size_t)1U << mon_hash_bits)
+#define MON_HASH_MASK (MON_HASH_SIZE - 1)
+#define MON_HASH(addr) (sock_hash(addr) & MON_HASH_MASK)
+extern void init_mon (void);
+extern void mon_start (int);
+extern void mon_stop (int);
+extern u_short ntp_monitor (struct recvbuf *, u_short);
+extern void mon_clearinterface(endpt *interface);
+
+/* ntp_peer.c */
+extern void init_peer (void);
+extern struct peer *findexistingpeer(sockaddr_u *, const char *,
+ struct peer *, int, u_char, int *);
+extern struct peer *findpeer (struct recvbuf *, int, int *);
+extern struct peer *findpeerbyassoc(associd_t);
+extern void set_peerdstadr (struct peer *, endpt *);
+extern struct peer *newpeer (sockaddr_u *, const char *, endpt *,
+ int, u_char, u_char, u_char, u_char,
+ u_int, u_char, u_int32,
+ keyid_t, const char *);
+extern void peer_all_reset (void);
+extern void peer_clr_stats (void);
+extern struct peer *peer_config(sockaddr_u *, const char *, endpt *,
+ int, u_char, u_char, u_char, u_char,
+ u_int, u_int32,
+ keyid_t, const char *);
+extern void peer_reset (struct peer *);
+extern void refresh_all_peerinterfaces(void);
+extern void unpeer (struct peer *);
+extern void clear_all (void);
+extern int score_all (struct peer *);
+extern struct peer *findmanycastpeer(struct recvbuf *);
+extern void peer_cleanup (void);
+
+/* ntp_crypto.c */
+#ifdef AUTOKEY
+extern int crypto_recv (struct peer *, struct recvbuf *);
+extern int crypto_xmit (struct peer *, struct pkt *,
+ struct recvbuf *, int,
+ struct exten *, keyid_t);
+extern keyid_t session_key (sockaddr_u *, sockaddr_u *, keyid_t,
+ keyid_t, u_long);
+extern int make_keylist (struct peer *, struct interface *);
+extern void key_expire (struct peer *);
+extern void crypto_update (void);
+extern void crypto_update_taichange(void);
+extern void crypto_config (int, char *);
+extern void crypto_setup (void);
+extern u_int crypto_ident (struct peer *);
+extern struct exten *crypto_args (struct peer *, u_int, associd_t, char *);
+extern int crypto_public (struct peer *, u_char *, u_int);
+extern void value_free (struct value *);
+extern char *iffpar_file;
+extern EVP_PKEY *iffpar_pkey;
+extern char *gqpar_file;
+extern EVP_PKEY *gqpar_pkey;
+extern char *mvpar_file;
+extern EVP_PKEY *mvpar_pkey;
+extern struct value tai_leap;
+#endif /* AUTOKEY */
+
+/* ntp_proto.c */
+extern void transmit (struct peer *);
+extern void receive (struct recvbuf *);
+extern void peer_clear (struct peer *, const char *);
+extern void process_packet (struct peer *, struct pkt *, u_int);
+extern void clock_select (void);
+extern void set_sys_leap (u_char);
+
+extern u_long leapsec; /* seconds to next leap (proximity class) */
+extern int leapdif; /* TAI difference step at next leap second*/
+extern int sys_orphan;
+extern double sys_mindisp;
+extern double sys_maxdist;
+
+extern char *sys_ident; /* identity scheme */
+extern void poll_update (struct peer *, u_char);
+
+extern void clear (struct peer *);
+extern void clock_filter (struct peer *, double, double, double);
+extern void init_proto (void);
+extern void set_sys_tick_precision(double);
+extern void proto_config (int, u_long, double, sockaddr_u *);
+extern void proto_clr_stats (void);
+
+/* ntp_refclock.c */
+#ifdef REFCLOCK
+extern int refclock_newpeer (struct peer *);
+extern void refclock_unpeer (struct peer *);
+extern void refclock_receive (struct peer *);
+extern void refclock_transmit (struct peer *);
+extern void init_refclock (void);
+#endif /* REFCLOCK */
+
+/* ntp_request.c */
+extern void init_request (void);
+extern void process_private (struct recvbuf *, int);
+extern void reset_auth_stats(void);
+
+/* ntp_restrict.c */
+extern void init_restrict (void);
+extern void restrictions (sockaddr_u *, r4addr *);
+extern void hack_restrict (restrict_op, sockaddr_u *, sockaddr_u *,
+ short, u_short, u_short, u_long);
+extern void restrict_source (sockaddr_u *, int, u_long);
+extern void dump_restricts (void);
+
+/* ntp_timer.c */
+extern void init_timer (void);
+extern void reinit_timer (void);
+extern void timer (void);
+extern void timer_clr_stats (void);
+extern void timer_interfacetimeout (u_long);
+extern volatile int interface_interval;
+extern u_long orphwait; /* orphan wait time */
+#ifdef AUTOKEY
+extern char *sys_hostname; /* host name */
+extern char *sys_groupname; /* group name */
+extern char *group_name; /* group name */
+extern u_char sys_revoke; /* keys revoke timeout */
+extern u_char sys_automax; /* session key timeout */
+#endif /* AUTOKEY */
+
+/* ntp_util.c */
+extern void init_util (void);
+extern void write_stats (void);
+extern void stats_config (int, const char *);
+extern void record_peer_stats (sockaddr_u *, int, double, double, double, double);
+extern void record_proto_stats (char *);
+extern void record_loop_stats (double, double, double, double, int);
+extern void record_clock_stats (sockaddr_u *, const char *);
+extern int mprintf_clock_stats(sockaddr_u *, const char *, ...)
+ NTP_PRINTF(2, 3);
+extern void record_raw_stats (sockaddr_u *srcadr, sockaddr_u *dstadr, l_fp *t1, l_fp *t2, l_fp *t3, l_fp *t4, int leap, int version, int mode, int stratum, int ppoll, int precision, double root_delay, double root_dispersion, u_int32 refid, int len, u_char *extra);
+extern void check_leap_file (int is_daily_check, u_int32 ntptime, const time_t * systime);
+extern void record_crypto_stats (sockaddr_u *, const char *);
+#ifdef DEBUG
+extern void record_timing_stats (const char *);
+#endif
+extern char * fstostr(time_t); /* NTP timescale seconds */
+
+/* ntpd.c */
+extern void parse_cmdline_opts(int *, char ***);
+/*
+ * Signals we catch for debugging.
+ */
+#define MOREDEBUGSIG SIGUSR1
+#define LESSDEBUGSIG SIGUSR2
+/*
+ * Signals which terminate us gracefully.
+ */
+#ifndef SYS_WINNT
+# define SIGDIE1 SIGHUP
+# define SIGDIE2 SIGINT
+# define SIGDIE3 SIGQUIT
+# define SIGDIE4 SIGTERM
+#endif /* SYS_WINNT */
+
+
+/*
+ * Last half: ntpd variables
+ * -------------------------
+ */
+
+/* ntp_config.c */
+extern char const * progname;
+extern int saved_argc;
+extern char **saved_argv;
+extern char *sys_phone[]; /* ACTS phone numbers */
+#if defined(HAVE_SCHED_SETSCHEDULER)
+extern int config_priority_override;
+extern int config_priority;
+#endif
+extern char *ntp_signd_socket;
+extern struct config_tree_tag *cfg_tree_history;
+
+#ifdef BC_LIST_FRAMEWORK_NOT_YET_USED
+/*
+ * backwards compatibility flags
+ */
+typedef struct bc_entry_tag {
+ int token;
+ int enabled;
+} bc_entry;
+
+extern bc_entry bc_list[];
+#endif
+
+/* ntp_control.c */
+extern int num_ctl_traps;
+extern keyid_t ctl_auth_keyid; /* keyid used for authenticating write requests */
+
+/*
+ * Statistic counters to keep track of requests and responses.
+ */
+extern u_long ctltimereset; /* time stats reset */
+extern u_long numctlreq; /* number of requests we've received */
+extern u_long numctlbadpkts; /* number of bad control packets */
+extern u_long numctlresponses; /* number of resp packets sent with data */
+extern u_long numctlfrags; /* number of fragments sent */
+extern u_long numctlerrors; /* number of error responses sent */
+extern u_long numctltooshort; /* number of too short input packets */
+extern u_long numctlinputresp; /* number of responses on input */
+extern u_long numctlinputfrag; /* number of fragments on input */
+extern u_long numctlinputerr; /* number of input pkts with err bit set */
+extern u_long numctlbadoffset; /* number of input pkts with nonzero offset */
+extern u_long numctlbadversion; /* number of input pkts with unknown version */
+extern u_long numctldatatooshort; /* data too short for count */
+extern u_long numctlbadop; /* bad op code found in packet */
+extern u_long numasyncmsgs; /* number of async messages we've sent */
+
+/*
+ * Other statistics of possible interest
+ */
+extern volatile u_long packets_dropped; /* total number of packets dropped on reception */
+extern volatile u_long packets_ignored; /* packets received on wild card interface */
+extern volatile u_long packets_received;/* total number of packets received */
+extern u_long packets_sent; /* total number of packets sent */
+extern u_long packets_notsent; /* total number of packets which couldn't be sent */
+
+extern volatile u_long handler_calls; /* number of calls to interrupt handler */
+extern volatile u_long handler_pkts; /* number of pkts received by handler */
+extern u_long io_timereset; /* time counters were reset */
+
+/* ntp_io.c */
+extern int disable_dynamic_updates;
+extern u_int sys_ifnum; /* next .ifnum to assign */
+extern endpt * any_interface; /* IPv4 wildcard */
+extern endpt * any6_interface; /* IPv6 wildcard */
+extern endpt * loopback_interface; /* IPv4 loopback for refclocks */
+extern endpt * ep_list; /* linked list */
+
+/* ntp_loopfilter.c */
+extern double drift_comp; /* clock frequency (s/s) */
+extern double clock_stability; /* clock stability (s/s) */
+extern double clock_max_back; /* max backward offset before step (s) */
+extern double clock_max_fwd; /* max forward offset before step (s) */
+extern double clock_panic; /* max offset before panic (s) */
+extern double clock_phi; /* dispersion rate (s/s) */
+extern double clock_minstep; /* step timeout (s) */
+extern double clock_codec; /* codec frequency */
+#ifdef KERNEL_PLL
+extern int pll_status; /* status bits for kernel pll */
+#endif /* KERNEL_PLL */
+
+/*
+ * Clock state machine control flags
+ */
+extern int ntp_enable; /* clock discipline enabled */
+extern int pll_control; /* kernel support available */
+extern int kern_enable; /* kernel support enabled */
+extern int hardpps_enable; /* kernel PPS discipline enabled */
+extern int ext_enable; /* external clock enabled */
+extern int cal_enable; /* refclock calibrate enable */
+extern int allow_panic; /* allow panic correction (-g) */
+extern int enable_panic_check; /* Can we check allow_panic's state? */
+extern int force_step_once; /* always step time once at startup (-G) */
+extern int mode_ntpdate; /* exit on first clock set (-q) */
+extern int peer_ntpdate; /* count of ntpdate peers */
+
+/*
+ * Clock state machine variables
+ */
+extern u_char sys_poll; /* system poll interval (log2 s) */
+extern int state; /* clock discipline state */
+extern int tc_counter; /* poll-adjust counter */
+extern u_long last_time; /* time of last clock update (s) */
+extern double last_offset; /* last clock offset (s) */
+extern u_char allan_xpt; /* Allan intercept (log2 s) */
+extern double clock_jitter; /* clock jitter (s) */
+extern double sys_offset; /* system offset (s) */
+extern double sys_jitter; /* system jitter (s) */
+
+/* ntp_monitor.c */
+extern u_char mon_hash_bits; /* log2 size of hash table */
+extern mon_entry ** mon_hash; /* MRU hash table */
+extern mon_entry mon_mru_list; /* mru listhead */
+extern u_int mon_enabled; /* MON_OFF (0) or other MON_* */
+extern u_int mru_alloc; /* mru list + free list count */
+extern u_int mru_entries; /* mru list count */
+extern u_int mru_peakentries; /* highest mru_entries */
+extern u_int mru_initalloc; /* entries to preallocate */
+extern u_int mru_incalloc; /* allocation batch factor */
+extern u_int mru_mindepth; /* preempt above this */
+extern int mru_maxage; /* for entries older than */
+extern u_int mru_maxdepth; /* MRU size hard limit */
+extern int mon_age; /* preemption limit */
+
+/* ntp_peer.c */
+extern struct peer *peer_hash[NTP_HASH_SIZE]; /* peer hash table */
+extern int peer_hash_count[NTP_HASH_SIZE]; /* count of in each bucket */
+extern struct peer *assoc_hash[NTP_HASH_SIZE]; /* association ID hash table */
+extern int assoc_hash_count[NTP_HASH_SIZE];/* count of in each bucket */
+extern struct peer *peer_list; /* peer structures list */
+extern int peer_count; /* count in peer_list */
+extern int peer_free_count; /* count in peer_free */
+
+/*
+ * Miscellaneous statistic counters which may be queried.
+ */
+extern u_long peer_timereset; /* time stat counters were zeroed */
+extern u_long findpeer_calls; /* number of calls to findpeer */
+extern u_long assocpeer_calls; /* number of calls to findpeerbyassoc */
+extern u_long peer_allocations; /* number of allocations from the free list */
+extern u_long peer_demobilizations; /* number of structs freed to free list */
+extern int total_peer_structs; /* number of peer structs in circulation */
+extern int peer_associations; /* mobilized associations */
+extern int peer_preempt; /* preemptable associations */
+
+/* ntp_proto.c */
+/*
+ * System variables are declared here. See Section 3.2 of the
+ * specification.
+ */
+extern u_char sys_leap; /* system leap indicator */
+extern u_char sys_stratum; /* system stratum */
+extern s_char sys_precision; /* local clock precision */
+extern double sys_rootdelay; /* roundtrip delay to primary source */
+extern double sys_rootdisp; /* dispersion to primary source */
+extern u_int32 sys_refid; /* reference id */
+extern l_fp sys_reftime; /* last update time */
+extern struct peer *sys_peer; /* current peer */
+
+/*
+ * Nonspecified system state variables.
+ */
+extern int sys_bclient; /* we set our time to broadcasts */
+extern double sys_bdelay; /* broadcast client default delay */
+extern int sys_authenticate; /* requre authentication for config */
+extern l_fp sys_authdelay; /* authentication delay */
+extern u_char sys_bcpollbstep; /* broadcast poll backstep gate */
+extern u_long sys_epoch; /* last clock update time */
+extern keyid_t sys_private; /* private value for session seed */
+extern int sys_manycastserver; /* respond to manycast client pkts */
+extern int sys_maxclock; /* maximum survivors */
+extern int sys_minclock; /* minimum survivors */
+extern int sys_minsane; /* minimum candidates */
+extern int sys_floor; /* cluster stratum floor */
+extern int sys_ceiling; /* cluster stratum ceiling */
+extern u_char sys_ttl[MAX_TTL]; /* ttl mapping vector */
+extern u_int sys_ttlmax; /* max ttl mapping vector index */
+
+/*
+ * Statistics counters
+ */
+extern u_long sys_badauth; /* bad authentication */
+extern u_long sys_badlength; /* bad length or format */
+extern u_long sys_declined; /* declined */
+extern u_long sys_kodsent; /* KoD sent */
+extern u_long sys_lamport; /* Lamport violation */
+extern u_long sys_limitrejected; /* rate exceeded */
+extern u_long sys_newversion; /* current version */
+extern u_long sys_oldversion; /* old version */
+extern u_long sys_processed; /* packets for this host */
+extern u_long sys_received; /* packets received */
+extern u_long sys_restricted; /* access denied */
+extern u_long sys_stattime; /* time since reset */
+extern u_long sys_tsrounding; /* timestamp rounding errors */
+
+/* ntp_request.c */
+extern keyid_t info_auth_keyid; /* keyid used to authenticate requests */
+extern u_long auth_timereset;
+
+/* ntp_restrict.c */
+extern restrict_u * restrictlist4; /* IPv4 restriction list */
+extern restrict_u * restrictlist6; /* IPv6 restriction list */
+extern int ntp_minpkt;
+extern u_char ntp_minpoll;
+
+/* ntp_scanner.c */
+extern u_int32 conf_file_sum; /* Simple sum of characters */
+
+/* ntp_signd.c */
+#ifdef HAVE_NTP_SIGND
+extern void send_via_ntp_signd(struct recvbuf *, int, keyid_t, int,
+ struct pkt *);
+#endif
+
+/* ntp_timer.c */
+extern volatile int alarm_flag; /* alarm flag */
+extern volatile u_long alarm_overflow;
+extern u_long current_time; /* seconds since startup */
+extern u_long timer_timereset;
+extern u_long timer_overflows;
+extern u_long timer_xmtcalls;
+extern int leap_sec_in_progress;
+#ifdef LEAP_SMEAR
+extern struct leap_smear_info leap_smear;
+extern int leap_smear_intv;
+#endif
+#ifdef SYS_WINNT
+HANDLE WaitableTimerHandle;
+#endif
+
+/* ntp_util.c */
+extern char statsdir[MAXFILENAME];
+extern int stats_control; /* write stats to fileset? */
+extern int stats_write_period; /* # of seconds between writes. */
+extern double stats_write_tolerance;
+extern double wander_threshold;
+
+/* ntpd.c */
+extern int nofork; /* no-fork flag */
+extern int initializing; /* initializing flag */
+#ifdef HAVE_DROPROOT
+extern int droproot; /* flag: try to drop root privileges after startup */
+extern int root_dropped; /* root has been dropped */
+extern char *user; /* user to switch to */
+extern char *group; /* group to switch to */
+extern const char *chrootdir; /* directory to chroot() to */
+#endif
+#ifdef HAVE_WORKING_FORK
+extern int waitsync_fd_to_close; /* -w/--wait-sync */
+#endif
+
+/* ntservice.c */
+#ifdef SYS_WINNT
+extern int accept_wildcard_if_for_winnt;
+#endif
+
+/* refclock_conf.c */
+#ifdef REFCLOCK
+/* refclock configuration table */
+extern struct refclock * const refclock_conf[];
+extern u_char num_refclock_conf;
+#endif
+
diff --git a/sebhbsd/freebsd/contrib/ntp/include/ntpsim.h b/sebhbsd/freebsd/contrib/ntp/include/ntpsim.h
new file mode 100644
index 0000000..b270ce6
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/ntpsim.h
@@ -0,0 +1,146 @@
+/* ntpsim.h
+ *
+ * The header file for the ntp discrete event simulator.
+ *
+ * Written By: Sachin Kamboj
+ * University of Delaware
+ * Newark, DE 19711
+ * Copyright (c) 2006
+ */
+
+#ifndef NTPSIM_H
+#define NTPSIM_H
+
+#include <stdio.h>
+#include <math.h>
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#include <arpa/inet.h>
+#include "ntp_syslog.h"
+#include "ntp_fp.h"
+#include "ntp.h"
+#include "ntp_select.h"
+#include "ntp_malloc.h"
+#include "ntp_refclock.h"
+#include "recvbuff.h"
+#include "ntp_io.h"
+#include "ntp_stdlib.h"
+#include "ntp_prio_q.h"
+
+/* CONSTANTS */
+
+#ifdef PI
+# undef PI
+#endif
+#define PI 3.1415926535 /* The world's most famous constant */
+#define SIM_TIME 86400 /* end simulation time */
+#define NET_DLY .001 /* network delay */
+#define PROC_DLY .001 /* processing delay */
+#define BEEP_DLY 3600 /* beep interval (s) */
+
+
+/* Discrete Event Queue
+ * --------------------
+ * The NTP simulator is a discrete event simulator.
+ *
+ * Central to this simulator is an event queue which is a priority queue
+ * in which the "priority" is given by the time of arrival of the event.
+ *
+ * A discrete set of events can happen and are stored in the queue to arrive
+ * at a particular time.
+ */
+
+/* Possible Discrete Events */
+
+typedef enum {
+ BEEP, /* Event to record simulator stats */
+ CLOCK, /* Event to advance the clock to the specified time */
+ TIMER, /* Event that designates a timer interrupt. */
+ PACKET /* Event that designates arrival of a packet */
+} funcTkn;
+
+
+/* Event information */
+
+typedef struct {
+ double time; /* Time at which event occurred */
+ funcTkn function; /* Type of event that occured */
+ union {
+ struct pkt evnt_pkt;
+ struct recvbuf evnt_buf;
+ } buffer; /* Other data associated with the event */
+#define ntp_pkt buffer.evnt_pkt
+#define rcv_buf buffer.evnt_buf
+} Event;
+
+
+/* Server Script Information */
+typedef struct script_info_tag script_info;
+struct script_info_tag {
+ script_info * link;
+ double duration;
+ double freq_offset;
+ double wander;
+ double jitter;
+ double prop_delay;
+ double proc_delay;
+};
+
+typedef DECL_FIFO_ANCHOR(script_info) script_info_fifo;
+
+
+/* Server Structures */
+
+typedef struct server_info_tag server_info;
+struct server_info_tag {
+ server_info * link;
+ double server_time;
+ sockaddr_u * addr;
+ script_info_fifo * script;
+ script_info * curr_script;
+};
+
+typedef DECL_FIFO_ANCHOR(server_info) server_info_fifo;
+
+
+/* Simulation control information */
+
+typedef struct Sim_Info {
+ double sim_time; /* Time in the simulation */
+ double end_time; /* Time at which simulation needs to be ended */
+ double beep_delay; /* Delay between simulation "beeps" at which
+ simulation stats are recorded. */
+ int num_of_servers; /* Number of servers in the simulation */
+ server_info *servers; /* Pointer to array of servers */
+} sim_info;
+
+
+/* Local Clock (Client) Variables */
+
+typedef struct Local_Clock_Info {
+ double local_time; /* Client disciplined time */
+ double adj; /* Remaining time correction */
+ double slew; /* Correction Slew Rate */
+ double last_read_time; /* Last time the clock was read */
+} local_clock_info;
+
+extern local_clock_info simclock; /* Local Clock Variables */
+extern sim_info simulation; /* Simulation Control Variables */
+
+/* Function Prototypes */
+
+int ntpsim (int argc, char *argv[]);
+Event *event (double t, funcTkn f);
+void sim_event_timer (Event *e);
+int simulate_server (sockaddr_u *serv_addr, endpt *inter,
+ struct pkt *rpkt);
+void sim_update_clocks (Event *e);
+void sim_event_recv_packet (Event *e);
+void sim_event_beep (Event *e);
+void abortsim (char *errmsg);
+double gauss (double, double);
+double poisson (double, double);
+void create_server_associations(void);
+
+#endif /* NTPSIM_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/parse.h b/sebhbsd/freebsd/contrib/ntp/include/parse.h
new file mode 100644
index 0000000..e2caa52
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/parse.h
@@ -0,0 +1,431 @@
+/*
+ * /src/NTP/REPOSITORY/ntp4-dev/include/parse.h,v 4.12 2007/01/14 08:36:03 kardel RELEASE_20070114_A
+ *
+ * parse.h,v 4.12 2007/01/14 08:36:03 kardel RELEASE_20070114_A
+ *
+ * Copyright (c) 1995-2015 by Frank Kardel <kardel <AT> ntp.org>
+ * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universitaet Erlangen-Nuernberg, Germany
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED 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.
+ *
+ */
+
+#ifndef __PARSE_H__
+#define __PARSE_H__
+#if !(defined(lint) || defined(__GNUC__))
+ static char parsehrcsid[]="parse.h,v 4.12 2007/01/14 08:36:03 kardel RELEASE_20070114_A";
+#endif
+
+#include "ntp_types.h"
+
+#include "parse_conf.h"
+
+/*
+ * we use the following datastructures in two modes
+ * either in the NTP itself where we use NTP time stamps at some places
+ * or in the kernel, where only struct timeval will be used.
+ */
+#undef PARSEKERNEL
+#if defined(KERNEL) || defined(_KERNEL)
+#ifndef PARSESTREAM
+#define PARSESTREAM
+#endif
+#endif
+#if defined(PARSESTREAM) && defined(HAVE_SYS_STREAM_H)
+#define PARSEKERNEL
+#endif
+#ifdef PARSEKERNEL
+#ifndef _KERNEL
+extern caddr_t kmem_alloc (unsigned int);
+extern caddr_t kmem_free (caddr_t, unsigned int);
+extern unsigned int splx (unsigned int);
+extern unsigned int splhigh (void);
+extern unsigned int splclock (void);
+#define MALLOC(_X_) (char *)kmem_alloc(_X_)
+#define FREE(_X_, _Y_) kmem_free((caddr_t)_X_, _Y_)
+#else
+#include <sys/kmem.h>
+#define MALLOC(_X_) (char *)kmem_alloc(_X_, KM_SLEEP)
+#define FREE(_X_, _Y_) kmem_free((caddr_t)_X_, _Y_)
+#endif
+#else
+#define MALLOC(_X_) malloc(_X_)
+#define FREE(_X_, _Y_) free(_X_)
+#endif
+
+#if defined(PARSESTREAM) && defined(HAVE_SYS_STREAM_H)
+#include <sys/stream.h>
+#include <sys/stropts.h>
+#else /* STREAM */
+#include <stdio.h>
+#include "ntp_syslog.h"
+#ifdef DEBUG
+#define DD_PARSE 5
+#define DD_RAWDCF 4
+#define parseprintf(LEVEL, ARGS) if (debug > LEVEL) printf ARGS
+#else /* DEBUG */
+#define parseprintf(LEVEL, ARGS)
+#endif /* DEBUG */
+#endif /* PARSESTREAM */
+
+#if defined(timercmp) && defined(__GNUC__)
+#undef timercmp
+#endif
+
+#if !defined(timercmp)
+#define timercmp(tvp, uvp, cmp) \
+ ((tvp)->tv_sec cmp (uvp)->tv_sec || \
+ ((tvp)->tv_sec == (uvp)->tv_sec && (tvp)->tv_usec cmp (uvp)->tv_usec))
+#endif
+
+#ifndef TIMES10
+#define TIMES10(_X_) (((_X_) << 3) + ((_X_) << 1))
+#endif
+
+/*
+ * some constants useful for GPS time conversion
+ */
+#define GPSORIGIN 2524953600UL /* NTP origin - GPS origin in seconds */
+#define GPSWEEKS 1024 /* number of weeks until the GPS epch rolls over */
+
+/*
+ * state flags
+ */
+#define PARSEB_POWERUP 0x00000001 /* no synchronisation */
+#define PARSEB_NOSYNC 0x00000002 /* timecode currently not confirmed */
+
+/*
+ * time zone information
+ */
+#define PARSEB_ANNOUNCE 0x00000010 /* switch time zone warning (DST switch) */
+#define PARSEB_DST 0x00000020 /* DST in effect */
+#define PARSEB_UTC 0x00000040 /* UTC time */
+
+/*
+ * leap information
+ */
+#define PARSEB_LEAPDEL 0x00000100 /* LEAP deletion warning */
+#define PARSEB_LEAPADD 0x00000200 /* LEAP addition warning */
+#define PARSEB_LEAPS 0x00000300 /* LEAP warnings */
+#define PARSEB_LEAPSECOND 0x00000400 /* actual leap second */
+/*
+ * optional status information
+ */
+#define PARSEB_CALLBIT 0x00001000 /* "call bit" used to signalize irregularities in the control facilities */
+#define PARSEB_POSITION 0x00002000 /* position available */
+#define PARSEB_MESSAGE 0x00004000 /* addtitional message data */
+/*
+ * feature information
+ */
+#define PARSEB_S_LEAP 0x00010000 /* supports LEAP */
+#define PARSEB_S_CALLBIT 0x00020000 /* supports callbit information */
+#define PARSEB_S_PPS 0x00040000 /* supports PPS time stamping */
+#define PARSEB_S_POSITION 0x00080000 /* supports position information (GPS) */
+
+/*
+ * time stamp availability
+ */
+#define PARSEB_TIMECODE 0x10000000 /* valid time code sample */
+#define PARSEB_PPS 0x20000000 /* valid PPS sample */
+
+#define PARSE_TCINFO (PARSEB_ANNOUNCE|PARSEB_POWERUP|PARSEB_NOSYNC|PARSEB_DST|\
+ PARSEB_UTC|PARSEB_LEAPS|PARSEB_CALLBIT|PARSEB_S_LEAP|\
+ PARSEB_S_LOCATION|PARSEB_TIMECODE|PARSEB_MESSAGE)
+
+#define PARSE_POWERUP(x) ((x) & PARSEB_POWERUP)
+#define PARSE_NOSYNC(x) (((x) & (PARSEB_POWERUP|PARSEB_NOSYNC)) == PARSEB_NOSYNC)
+#define PARSE_SYNC(x) (((x) & (PARSEB_POWERUP|PARSEB_NOSYNC)) == 0)
+#define PARSE_ANNOUNCE(x) ((x) & PARSEB_ANNOUNCE)
+#define PARSE_DST(x) ((x) & PARSEB_DST)
+#define PARSE_UTC(x) ((x) & PARSEB_UTC)
+#define PARSE_LEAPADD(x) (PARSE_SYNC(x) && (((x) & PARSEB_LEAPS) == PARSEB_LEAPADD))
+#define PARSE_LEAPDEL(x) (PARSE_SYNC(x) && (((x) & PARSEB_LEAPS) == PARSEB_LEAPDEL))
+#define PARSE_CALLBIT(x) ((x) & PARSEB_CALLBIT)
+#define PARSE_LEAPSECOND(x) (PARSE_SYNC(x) && ((x) & PARSEB_LEAP_SECOND))
+
+#define PARSE_S_LEAP(x) ((x) & PARSEB_S_LEAP)
+#define PARSE_S_CALLBIT(x) ((x) & PARSEB_S_CALLBIT)
+#define PARSE_S_PPS(x) ((x) & PARSEB_S_PPS)
+#define PARSE_S_POSITION(x) ((x) & PARSEB_S_POSITION)
+
+#define PARSE_TIMECODE(x) ((x) & PARSEB_TIMECODE)
+#define PARSE_PPS(x) ((x) & PARSEB_PPS)
+#define PARSE_POSITION(x) ((x) & PARSEB_POSITION)
+#define PARSE_MESSAGE(x) ((x) & PARSEB_MESSAGE)
+
+/*
+ * operation flags - lower nibble contains fudge flags
+ */
+#define PARSE_TRUSTTIME CLK_FLAG1 /* use flag1 to indicate the time2 references mean the trust time */
+#define PARSE_CLEAR CLK_FLAG2 /* use flag2 to control pps on assert */
+#define PARSE_PPSKERNEL CLK_FLAG3 /* use flag3 to bind PPS to kernel */
+#define PARSE_LEAP_DELETE CLK_FLAG4 /* use flag4 to force leap deletion - only necessary when earth slows down */
+
+#define PARSE_FIXED_FMT 0x10 /* fixed format */
+#define PARSE_PPSCLOCK 0x20 /* try to get PPS time stamp via ppsclock ioctl */
+
+/*
+ * size of buffers
+ */
+#define PARSE_TCMAX 400 /* maximum addition data size */
+
+typedef union
+{
+ struct timeval tv; /* timeval - kernel view */
+ l_fp fp; /* fixed point - ntp view */
+} timestamp_t;
+
+/*
+ * standard time stamp structure
+ */
+struct parsetime
+{
+ u_long parse_status; /* data status - CVT_OK, CVT_NONE, CVT_FAIL ... */
+ timestamp_t parse_time; /* PARSE timestamp */
+ timestamp_t parse_stime; /* telegram sample timestamp */
+ timestamp_t parse_ptime; /* PPS time stamp */
+ long parse_usecerror; /* sampled usec error */
+ u_long parse_state; /* current receiver state */
+ unsigned short parse_format; /* format code */
+ unsigned short parse_msglen; /* length of message */
+ unsigned char parse_msg[PARSE_TCMAX]; /* original messages */
+};
+
+typedef struct parsetime parsetime_t;
+
+/*---------- STREAMS interface ----------*/
+
+#ifdef HAVE_SYS_STREAM_H
+/*
+ * ioctls
+ */
+#define PARSEIOC_ENABLE (('D'<<8) + 'E')
+#define PARSEIOC_DISABLE (('D'<<8) + 'D')
+#define PARSEIOC_SETFMT (('D'<<8) + 'f')
+#define PARSEIOC_GETFMT (('D'<<8) + 'F')
+#define PARSEIOC_SETCS (('D'<<8) + 'C')
+#define PARSEIOC_TIMECODE (('D'<<8) + 'T')
+
+#endif
+
+/*------ IO handling flags (sorry) ------*/
+
+#define PARSE_IO_CSIZE 0x00000003
+#define PARSE_IO_CS5 0x00000000
+#define PARSE_IO_CS6 0x00000001
+#define PARSE_IO_CS7 0x00000002
+#define PARSE_IO_CS8 0x00000003
+
+/*
+ * ioctl structure
+ */
+union parsectl
+{
+ struct parsegettc
+ {
+ u_long parse_state; /* last state */
+ u_long parse_badformat; /* number of bad packets since last query */
+ unsigned short parse_format;/* last decoded format */
+ unsigned short parse_count; /* count of valid time code bytes */
+ char parse_buffer[PARSE_TCMAX+1]; /* timecode buffer */
+ } parsegettc;
+
+ struct parseformat
+ {
+ unsigned short parse_format;/* number of examined format */
+ unsigned short parse_count; /* count of valid string bytes */
+ char parse_buffer[PARSE_TCMAX+1]; /* format code string */
+ } parseformat;
+
+ struct parsesetcs
+ {
+ u_long parse_cs; /* character size (needed for stripping) */
+ } parsesetcs;
+};
+
+typedef union parsectl parsectl_t;
+
+/*------ for conversion routines --------*/
+
+struct parse /* parse module local data */
+{
+ int parse_flags; /* operation and current status flags */
+
+ int parse_ioflags; /* io handling flags (5-8 Bit control currently) */
+
+ /*
+ * private data - fixed format only
+ */
+ unsigned short parse_plen; /* length of private data */
+ void *parse_pdata; /* private data pointer */
+
+ /*
+ * time code input buffer (from RS232 or PPS)
+ */
+ unsigned short parse_index; /* current buffer index */
+ char *parse_data; /* data buffer */
+ unsigned short parse_dsize; /* size of data buffer */
+ unsigned short parse_lformat; /* last format used */
+ u_long parse_lstate; /* last state code */
+ char *parse_ldata; /* last data buffer */
+ unsigned short parse_ldsize; /* last data buffer length */
+ u_long parse_badformat; /* number of unparsable pakets */
+
+ timestamp_t parse_lastchar; /* last time a character was received */
+ parsetime_t parse_dtime; /* external data prototype */
+};
+
+typedef struct parse parse_t;
+
+struct clocktime /* clock time broken up from time code */
+{
+ long day;
+ long month;
+ long year;
+ long hour;
+ long minute;
+ long second;
+ long usecond;
+ long utcoffset; /* in seconds */
+ time_t utctime; /* the actual time - alternative to date/time */
+ u_long flags; /* current clock status */
+};
+
+typedef struct clocktime clocktime_t;
+
+/*
+ * parser related return/error codes
+ */
+#define CVT_MASK (unsigned)0x0000000F /* conversion exit code */
+#define CVT_NONE (unsigned)0x00000001 /* format not applicable */
+#define CVT_FAIL (unsigned)0x00000002 /* conversion failed - error code returned */
+#define CVT_OK (unsigned)0x00000004 /* conversion succeeded */
+#define CVT_SKIP (unsigned)0x00000008 /* conversion succeeded */
+#define CVT_ADDITIONAL (unsigned)0x00000010 /* additional data is available */
+#define CVT_BADFMT (unsigned)0x00000100 /* general format error - (unparsable) */
+#define CVT_BADDATE (unsigned)0x00000200 /* date field incorrect */
+#define CVT_BADTIME (unsigned)0x00000400 /* time field incorrect */
+
+/*
+ * return codes used by special input parsers
+ */
+#define PARSE_INP_SKIP 0x00 /* discard data - may have been consumed */
+#define PARSE_INP_TIME 0x01 /* time code assembled */
+#define PARSE_INP_PARSE 0x02 /* parse data using normal algorithm */
+#define PARSE_INP_DATA 0x04 /* additional data to pass up */
+#define PARSE_INP_SYNTH 0x08 /* just pass up synthesized time */
+
+/*
+ * PPS edge info
+ */
+#define SYNC_ZERO 0x00
+#define SYNC_ONE 0x01
+
+typedef u_long parse_inp_fnc_t(parse_t *, char, timestamp_t *);
+typedef u_long parse_cvt_fnc_t(unsigned char *, int, struct format *, clocktime_t *, void *);
+typedef u_long parse_pps_fnc_t(parse_t *, int, timestamp_t *);
+
+struct clockformat
+{
+ /* special input protocol - implies fixed format */
+ parse_inp_fnc_t *input;
+ /* conversion routine */
+ parse_cvt_fnc_t *convert;
+ /* routine for handling RS232 sync events (time stamps) */
+ /* PPS input routine */
+ parse_pps_fnc_t *syncpps;
+ /* time code synthesizer */
+
+ void *data; /* local parameters */
+ const char *name; /* clock format name */
+ unsigned short length; /* maximum length of data packet */
+ unsigned short plen; /* length of private data - implies fixed format */
+};
+
+typedef struct clockformat clockformat_t;
+
+/*
+ * parse interface
+ */
+extern int parse_ioinit (parse_t *);
+extern void parse_ioend (parse_t *);
+extern int parse_ioread (parse_t *, char, timestamp_t *);
+extern int parse_iopps (parse_t *, int, timestamp_t *);
+extern void parse_iodone (parse_t *);
+extern int parse_timecode (parsectl_t *, parse_t *);
+extern int parse_getfmt (parsectl_t *, parse_t *);
+extern int parse_setfmt (parsectl_t *, parse_t *);
+extern int parse_setcs (parsectl_t *, parse_t *);
+
+extern unsigned int parse_restart (parse_t *, char);
+extern unsigned int parse_addchar (parse_t *, char);
+extern unsigned int parse_end (parse_t *);
+
+extern int Strok (const unsigned char *, const unsigned char *);
+extern int Stoi (const unsigned char *, long *, int);
+
+extern time_t parse_to_unixtime (clocktime_t *, u_long *);
+extern u_long updatetimeinfo (parse_t *, u_long);
+extern void syn_simple (parse_t *, timestamp_t *, struct format *, u_long);
+extern parse_pps_fnc_t pps_simple;
+extern parse_pps_fnc_t pps_one;
+extern parse_pps_fnc_t pps_zero;
+extern int parse_timedout (parse_t *, timestamp_t *, struct timeval *);
+
+#endif
+
+/*
+ * History:
+ *
+ * parse.h,v
+ * Revision 4.12 2007/01/14 08:36:03 kardel
+ * make timestamp union anonymous to avoid conflicts with
+ * some OSes that choose to create a nameing conflic here.
+ *
+ * Revision 4.11 2005/06/25 10:58:45 kardel
+ * add missing log keywords
+ *
+ * Revision 4.5 1998/08/09 22:23:32 kardel
+ * 4.0.73e2 adjustments
+ *
+ * Revision 4.4 1998/06/14 21:09:27 kardel
+ * Sun acc cleanup
+ *
+ * Revision 4.3 1998/06/13 11:49:25 kardel
+ * STREAM macro gone in favor of HAVE_SYS_STREAM_H
+ *
+ * Revision 4.2 1998/06/12 15:14:25 kardel
+ * fixed prototypes
+ *
+ * Revision 4.1 1998/05/24 10:07:59 kardel
+ * removed old data structure cruft (new input model)
+ * new PARSE_INP* macros for input handling
+ * removed old SYNC_* macros from old input model
+ * (struct clockformat): removed old parse functions in favor of the
+ * new input model
+ * updated prototypes
+ *
+ * form V3 3.31 - log info deleted 1998/04/11 kardel
+ */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/rc_cmdlength.h b/sebhbsd/freebsd/contrib/ntp/include/rc_cmdlength.h
new file mode 100644
index 0000000..8794757
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/rc_cmdlength.h
@@ -0,0 +1,2 @@
+
+extern size_t remoteconfig_cmdlength( const char *src_buf, const char *src_end );
diff --git a/sebhbsd/freebsd/contrib/ntp/include/recvbuff.h b/sebhbsd/freebsd/contrib/ntp/include/recvbuff.h
new file mode 100644
index 0000000..4259715
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/recvbuff.h
@@ -0,0 +1,124 @@
+#ifndef RECVBUFF_H
+#define RECVBUFF_H
+
+#include "ntp.h"
+#include "ntp_net.h"
+#include "ntp_lists.h"
+
+#include <isc/result.h>
+
+/*
+ * recvbuf memory management
+ */
+#define RECV_INIT 10 /* 10 buffers initially */
+#define RECV_LOWAT 3 /* when we're down to three buffers get more */
+#define RECV_INC 5 /* get 5 more at a time */
+#define RECV_TOOMANY 40 /* this is way too many buffers */
+
+#if defined HAVE_IO_COMPLETION_PORT
+# include "ntp_iocompletionport.h"
+# include "ntp_timer.h"
+
+# define RECV_BLOCK_IO() EnterCriticalSection(&RecvCritSection)
+# define RECV_UNBLOCK_IO() LeaveCriticalSection(&RecvCritSection)
+
+/* Return the event which is set when items are added to the full list
+ */
+extern HANDLE get_recv_buff_event(void);
+#else
+# define RECV_BLOCK_IO()
+# define RECV_UNBLOCK_IO()
+#endif
+
+
+/*
+ * Format of a recvbuf. These are used by the asynchronous receive
+ * routine to store incoming packets and related information.
+ */
+
+/*
+ * the maximum length NTP packet contains the NTP header, one Autokey
+ * request, one Autokey response and the MAC. Assuming certificates don't
+ * get too big, the maximum packet length is set arbitrarily at 1200.
+ * (was 1000, but that bumps on 2048 RSA keys)
+ */
+#define RX_BUFF_SIZE 1200 /* hail Mary */
+
+
+typedef struct recvbuf recvbuf_t;
+
+struct recvbuf {
+ recvbuf_t * link; /* next in list */
+ union {
+ sockaddr_u X_recv_srcadr;
+ caddr_t X_recv_srcclock;
+ struct peer * X_recv_peer;
+ } X_from_where;
+#define recv_srcadr X_from_where.X_recv_srcadr
+#define recv_srcclock X_from_where.X_recv_srcclock
+#define recv_peer X_from_where.X_recv_peer
+#ifndef HAVE_IO_COMPLETION_PORT
+ sockaddr_u srcadr; /* where packet came from */
+#else
+ int recv_srcadr_len;/* filled in on completion */
+#endif
+ endpt * dstadr; /* address pkt arrived on */
+ SOCKET fd; /* fd on which it was received */
+ int msg_flags; /* Flags received about the packet */
+ l_fp recv_time; /* time of arrival */
+ void (*receiver)(struct recvbuf *); /* callback */
+ int recv_length; /* number of octets received */
+ union {
+ struct pkt X_recv_pkt;
+ u_char X_recv_buffer[RX_BUFF_SIZE];
+ } recv_space;
+#define recv_pkt recv_space.X_recv_pkt
+#define recv_buffer recv_space.X_recv_buffer
+ int used; /* reference count */
+};
+
+extern void init_recvbuff(int);
+
+/* freerecvbuf - make a single recvbuf available for reuse
+ */
+extern void freerecvbuf(struct recvbuf *);
+
+/* Get a free buffer (typically used so an async
+ * read can directly place data into the buffer
+ *
+ * The buffer is removed from the free list. Make sure
+ * you put it back with freerecvbuf() or
+ */
+
+/* signal safe - no malloc */
+extern struct recvbuf *get_free_recv_buffer(void);
+/* signal unsafe - may malloc, never returs NULL */
+extern struct recvbuf *get_free_recv_buffer_alloc(void);
+
+/* Add a buffer to the full list
+ */
+extern void add_full_recv_buffer(struct recvbuf *);
+
+/* number of recvbufs on freelist */
+extern u_long free_recvbuffs(void);
+extern u_long full_recvbuffs(void);
+extern u_long total_recvbuffs(void);
+extern u_long lowater_additions(void);
+
+/* Returns the next buffer in the full list.
+ *
+ */
+extern struct recvbuf *get_full_recv_buffer(void);
+
+/*
+ * purge_recv_buffers_for_fd() - purges any previously-received input
+ * from a given file descriptor.
+ */
+extern void purge_recv_buffers_for_fd(int);
+
+/*
+ * Checks to see if there are buffers to process
+ */
+extern isc_boolean_t has_full_recv_buffer(void);
+
+#endif /* RECVBUFF_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/refclock_atom.h b/sebhbsd/freebsd/contrib/ntp/include/refclock_atom.h
new file mode 100644
index 0000000..452e933
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/refclock_atom.h
@@ -0,0 +1,15 @@
+/*
+ * Definitions for the atom driver and its friends
+ */
+#undef NANOSECOND /* some systems define it differently */
+#define NANOSECOND 1000000000 /* one second (ns) */
+
+struct refclock_atom {
+ pps_handle_t handle;
+ pps_params_t pps_params;
+ struct timespec ts;
+};
+
+extern int refclock_ppsapi(int, struct refclock_atom *);
+extern int refclock_params(int, struct refclock_atom *);
+extern int refclock_pps(struct peer *, struct refclock_atom *, int);
diff --git a/sebhbsd/freebsd/contrib/ntp/include/refidsmear.h b/sebhbsd/freebsd/contrib/ntp/include/refidsmear.h
new file mode 100644
index 0000000..9c0f245
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/refidsmear.h
@@ -0,0 +1,3 @@
+
+extern l_fp convertRefIDToLFP(uint32_t r);
+extern uint32_t convertLFPToRefID(l_fp num);
diff --git a/sebhbsd/freebsd/contrib/ntp/include/safecast.h b/sebhbsd/freebsd/contrib/ntp/include/safecast.h
new file mode 100644
index 0000000..9300463
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/safecast.h
@@ -0,0 +1,34 @@
+#ifndef SAFECAST_H
+#define SAFECAST_H
+
+#include <limits.h>
+static inline int size2int_chk(size_t v)
+{
+ if (v > INT_MAX)
+ abort();
+ return (int)(v);
+}
+
+static inline int size2int_sat(size_t v)
+{
+ return (v > INT_MAX) ? INT_MAX : (int)v;
+}
+
+/* Compilers can emit warning about increased alignment requirements
+ * when casting pointers. The impact is tricky: on machines where
+ * alignment is just a performance issue (x86,x64,...) this might just
+ * cause a performance penalty. On others, an address error can occur
+ * and the process dies...
+ *
+ * Still, there are many cases where the pointer arithmetic and the
+ * buffer alignment make sure this does not happen. OTOH, the compiler
+ * doesn't know this and still emits warnings.
+ *
+ * The following cast macros are going through void pointers to tell
+ * the compiler that there is no alignment requirement to watch.
+ */
+#define UA_PTR(ptype,pval) ((ptype *)(void*)(pval))
+#define UAC_PTR(ptype,pval) ((const ptype *)(const void*)(pval))
+#define UAV_PTR(ptype,pval) ((volatile ptype *)(volatile void*)(pval))
+
+#endif
diff --git a/sebhbsd/freebsd/contrib/ntp/include/timespecops.h b/sebhbsd/freebsd/contrib/ntp/include/timespecops.h
new file mode 100644
index 0000000..fa32e42
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/timespecops.h
@@ -0,0 +1,393 @@
+/*
+ * timespecops.h -- calculations on 'struct timespec' values
+ *
+ * Written by Juergen Perlinger (perlinger@ntp.org) for the NTP project.
+ * The contents of 'html/copyright.html' apply.
+ *
+ * Rationale
+ * ---------
+ *
+ * Doing basic arithmetic on a 'struct timespec' is not exceedingly
+ * hard, but it requires tedious and repetitive code to keep the result
+ * normalised. We consider a timespec normalised when the nanosecond
+ * fraction is in the interval [0 .. 10^9[ ; there are multiple value
+ * pairs of seconds and nanoseconds that denote the same time interval,
+ * but the normalised representation is unique. No two different
+ * intervals can have the same normalised representation.
+ *
+ * Another topic is the representation of negative time intervals.
+ * There's more than one way to this, since both the seconds and the
+ * nanoseconds of a timespec are signed values. IMHO, the easiest way is
+ * to use a complement representation where the nanoseconds are still
+ * normalised, no matter what the sign of the seconds value. This makes
+ * normalisation easier, since the sign of the integer part is
+ * irrelevant, and it removes several sign decision cases during the
+ * calculations.
+ *
+ * As long as no signed integer overflow can occur with the nanosecond
+ * part of the operands, all operations work as expected and produce a
+ * normalised result.
+ *
+ * The exception to this are functions fix a '_fast' suffix, which do no
+ * normalisation on input data and therefore expect the input data to be
+ * normalised.
+ *
+ * Input and output operands may overlap; all input is consumed before
+ * the output is written to.
+ */
+#ifndef TIMESPECOPS_H
+#define TIMESPECOPS_H
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <math.h>
+
+#include "ntp.h"
+#include "timetoa.h"
+
+
+/* nanoseconds per second */
+#define NANOSECONDS 1000000000
+
+/* predicate: returns TRUE if the nanoseconds are in nominal range */
+#define timespec_isnormal(x) \
+ ((x)->tv_nsec >= 0 && (x)->tv_nsec < NANOSECONDS)
+
+/* predicate: returns TRUE if the nanoseconds are out-of-bounds */
+#define timespec_isdenormal(x) (!timespec_isnormal(x))
+
+/* conversion between l_fp fractions and nanoseconds */
+#ifdef HAVE_U_INT64
+# define FTOTVN(tsf) \
+ ((int32) \
+ (((u_int64)(tsf) * NANOSECONDS + 0x80000000) >> 32))
+# define TVNTOF(tvu) \
+ ((u_int32) \
+ ((((u_int64)(tvu) << 32) + NANOSECONDS / 2) / \
+ NANOSECONDS))
+#else
+# define NSECFRAC (FRAC / NANOSECONDS)
+# define FTOTVN(tsf) \
+ ((int32)((tsf) / NSECFRAC + 0.5))
+# define TVNTOF(tvu) \
+ ((u_int32)((tvu) * NSECFRAC + 0.5))
+#endif
+
+
+
+/* make sure nanoseconds are in nominal range */
+static inline struct timespec
+normalize_tspec(
+ struct timespec x
+ )
+{
+#if SIZEOF_LONG > 4
+ long z;
+
+ /*
+ * tv_nsec is of type 'long', and on a 64-bit machine using only
+ * loops becomes prohibitive once the upper 32 bits get
+ * involved. On the other hand, division by constant should be
+ * fast enough; so we do a division of the nanoseconds in that
+ * case. The floor adjustment step follows with the standard
+ * normalisation loops. And labs() is intentionally not used
+ * here: it has implementation-defined behaviour when applied
+ * to LONG_MIN.
+ */
+ if (x.tv_nsec < -3l * NANOSECONDS ||
+ x.tv_nsec > 3l * NANOSECONDS) {
+ z = x.tv_nsec / NANOSECONDS;
+ x.tv_nsec -= z * NANOSECONDS;
+ x.tv_sec += z;
+ }
+#endif
+ /* since 10**9 is close to 2**32, we don't divide but do a
+ * normalisation in a loop; this takes 3 steps max, and should
+ * outperform a division even if the mul-by-inverse trick is
+ * employed. */
+ if (x.tv_nsec < 0)
+ do {
+ x.tv_nsec += NANOSECONDS;
+ x.tv_sec--;
+ } while (x.tv_nsec < 0);
+ else if (x.tv_nsec >= NANOSECONDS)
+ do {
+ x.tv_nsec -= NANOSECONDS;
+ x.tv_sec++;
+ } while (x.tv_nsec >= NANOSECONDS);
+
+ return x;
+}
+
+/* x = a + b */
+static inline struct timespec
+add_tspec(
+ struct timespec a,
+ struct timespec b
+ )
+{
+ struct timespec x;
+
+ x = a;
+ x.tv_sec += b.tv_sec;
+ x.tv_nsec += b.tv_nsec;
+
+ return normalize_tspec(x);
+}
+
+/* x = a + b, b is fraction only */
+static inline struct timespec
+add_tspec_ns(
+ struct timespec a,
+ long b
+ )
+{
+ struct timespec x;
+
+ x = a;
+ x.tv_nsec += b;
+
+ return normalize_tspec(x);
+}
+
+/* x = a - b */
+static inline struct timespec
+sub_tspec(
+ struct timespec a,
+ struct timespec b
+ )
+{
+ struct timespec x;
+
+ x = a;
+ x.tv_sec -= b.tv_sec;
+ x.tv_nsec -= b.tv_nsec;
+
+ return normalize_tspec(x);
+}
+
+/* x = a - b, b is fraction only */
+static inline struct timespec
+sub_tspec_ns(
+ struct timespec a,
+ long b
+ )
+{
+ struct timespec x;
+
+ x = a;
+ x.tv_nsec -= b;
+
+ return normalize_tspec(x);
+}
+
+/* x = -a */
+static inline struct timespec
+neg_tspec(
+ struct timespec a
+ )
+{
+ struct timespec x;
+
+ x.tv_sec = -a.tv_sec;
+ x.tv_nsec = -a.tv_nsec;
+
+ return normalize_tspec(x);
+}
+
+/* x = abs(a) */
+static inline struct timespec
+abs_tspec(
+ struct timespec a
+ )
+{
+ struct timespec c;
+
+ c = normalize_tspec(a);
+ if (c.tv_sec < 0) {
+ if (c.tv_nsec != 0) {
+ c.tv_sec = -c.tv_sec - 1;
+ c.tv_nsec = NANOSECONDS - c.tv_nsec;
+ } else {
+ c.tv_sec = -c.tv_sec;
+ }
+ }
+
+ return c;
+}
+
+/*
+ * compare previously-normalised a and b
+ * return 1 / 0 / -1 if a < / == / > b
+ */
+static inline int
+cmp_tspec(
+ struct timespec a,
+ struct timespec b
+ )
+{
+ int r;
+
+ r = (a.tv_sec > b.tv_sec) - (a.tv_sec < b.tv_sec);
+ if (0 == r)
+ r = (a.tv_nsec > b.tv_nsec) -
+ (a.tv_nsec < b.tv_nsec);
+
+ return r;
+}
+
+/*
+ * compare possibly-denormal a and b
+ * return 1 / 0 / -1 if a < / == / > b
+ */
+static inline int
+cmp_tspec_denorm(
+ struct timespec a,
+ struct timespec b
+ )
+{
+ return cmp_tspec(normalize_tspec(a), normalize_tspec(b));
+}
+
+/*
+ * test previously-normalised a
+ * return 1 / 0 / -1 if a < / == / > 0
+ */
+static inline int
+test_tspec(
+ struct timespec a
+ )
+{
+ int r;
+
+ r = (a.tv_sec > 0) - (a.tv_sec < 0);
+ if (r == 0)
+ r = (a.tv_nsec > 0);
+
+ return r;
+}
+
+/*
+ * test possibly-denormal a
+ * return 1 / 0 / -1 if a < / == / > 0
+ */
+static inline int
+test_tspec_denorm(
+ struct timespec a
+ )
+{
+ return test_tspec(normalize_tspec(a));
+}
+
+/* return LIB buffer ptr to string rep */
+static inline const char *
+tspectoa(
+ struct timespec x
+ )
+{
+ return format_time_fraction(x.tv_sec, x.tv_nsec, 9);
+}
+
+/*
+ * convert to l_fp type, relative and absolute
+ */
+
+/* convert from timespec duration to l_fp duration */
+static inline l_fp
+tspec_intv_to_lfp(
+ struct timespec x
+ )
+{
+ struct timespec v;
+ l_fp y;
+
+ v = normalize_tspec(x);
+ y.l_uf = TVNTOF(v.tv_nsec);
+ y.l_i = (int32)v.tv_sec;
+
+ return y;
+}
+
+/* x must be UN*X epoch, output will be in NTP epoch */
+static inline l_fp
+tspec_stamp_to_lfp(
+ struct timespec x
+ )
+{
+ l_fp y;
+
+ y = tspec_intv_to_lfp(x);
+ y.l_ui += JAN_1970;
+
+ return y;
+}
+
+/* convert from l_fp type, relative signed/unsigned and absolute */
+static inline struct timespec
+lfp_intv_to_tspec(
+ l_fp x
+ )
+{
+ struct timespec out;
+ l_fp absx;
+ int neg;
+
+ neg = L_ISNEG(&x);
+ absx = x;
+ if (neg) {
+ L_NEG(&absx);
+ }
+ out.tv_nsec = FTOTVN(absx.l_uf);
+ out.tv_sec = absx.l_i;
+ if (neg) {
+ out.tv_sec = -out.tv_sec;
+ out.tv_nsec = -out.tv_nsec;
+ out = normalize_tspec(out);
+ }
+
+ return out;
+}
+
+static inline struct timespec
+lfp_uintv_to_tspec(
+ l_fp x
+ )
+{
+ struct timespec out;
+
+ out.tv_nsec = FTOTVN(x.l_uf);
+ out.tv_sec = x.l_ui;
+
+ return out;
+}
+
+/*
+ * absolute (timestamp) conversion. Input is time in NTP epoch, output
+ * is in UN*X epoch. The NTP time stamp will be expanded around the
+ * pivot time *p or the current time, if p is NULL.
+ */
+static inline struct timespec
+lfp_stamp_to_tspec(
+ l_fp x,
+ const time_t * p
+ )
+{
+ struct timespec out;
+ vint64 sec;
+
+ sec = ntpcal_ntp_to_time(x.l_ui, p);
+ out.tv_nsec = FTOTVN(x.l_uf);
+
+ /* copying a vint64 to a time_t needs some care... */
+#if SIZEOF_TIME_T <= 4
+ out.tv_sec = (time_t)sec.d_s.lo;
+#elif defined(HAVE_INT64)
+ out.tv_sec = (time_t)sec.q_s;
+#else
+ out.tv_sec = ((time_t)sec.d_s.hi << 32) | sec.d_s.lo;
+#endif
+
+ return out;
+}
+
+#endif /* TIMESPECOPS_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/timetoa.h b/sebhbsd/freebsd/contrib/ntp/include/timetoa.h
new file mode 100644
index 0000000..2599449
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/timetoa.h
@@ -0,0 +1,83 @@
+/*
+ * timetoa.h -- time_t related string formatting
+ *
+ * Written by Juergen Perlinger (perlinger@ntp.org) for the NTP project.
+ * The contents of 'html/copyright.html' apply.
+ *
+ * Printing a 'time_t' has some portability pitfalls, due to it's opaque
+ * base type. The only requirement imposed by the standard is that it
+ * must be a numeric type. For all practical purposes it's a signed int,
+ * and 32 bits are common.
+ *
+ * Since the UN*X time epoch will cause a signed integer overflow for
+ * 32-bit signed int values in the year 2038, implementations slowly
+ * move to 64bit base types for time_t, even in 32-bit environments. In
+ * such an environment sizeof(time_t) could be bigger than sizeof(long)
+ * and the commonly used idiom of casting to long leads to truncation.
+ *
+ * As the printf() family has no standardised type specifier for time_t,
+ * guessing the right output format specifier is a bit troublesome and
+ * best done with the help of the preprocessor and "config.h".
+ */
+#ifndef TIMETOA_H
+#define TIMETOA_H
+
+#include "ntp_fp.h"
+#include "ntp_stdlib.h"
+#include "ntp_unixtime.h"
+
+/*
+ * Given the size of time_t, guess what can be used as an unsigned value
+ * to hold a time_t and the printf() format specifcation.
+ *
+ * These should be used with the string constant concatenation feature
+ * of the compiler like this:
+ *
+ * printf("a time stamp: %" TIME_FORMAT " and more\n", a_time_t_value);
+ *
+ * It's not exactly nice, but there's not much leeway once we want to
+ * use the printf() family on time_t values.
+ */
+
+#if SIZEOF_TIME_T <= SIZEOF_INT
+
+typedef unsigned int u_time;
+#define TIME_FORMAT "d"
+#define UTIME_FORMAT "u"
+
+#elif SIZEOF_TIME_T <= SIZEOF_LONG
+
+typedef unsigned long u_time;
+#define TIME_FORMAT "ld"
+#define UTIME_FORMAT "lu"
+
+#elif defined(SIZEOF_LONG_LONG) && SIZEOF_TIME_T <= SIZEOF_LONG_LONG
+
+typedef unsigned long long u_time;
+#define TIME_FORMAT "lld"
+#define UTIME_FORMAT "llu"
+
+#else
+#include "GRONK: what size has a time_t here?"
+#endif
+
+/*
+ * general fractional time stamp formatting.
+ *
+ * secs - integral seconds of time stamp
+ * frac - fractional units
+ * prec - log10 of units per second (3=milliseconds, 6=microseconds,..)
+ * or in other words: the count of decimal digits required.
+ * If prec is < 0, abs(prec) is taken for the precision and secs
+ * is treated as an unsigned value.
+ *
+ * The function will eventually normalise the fraction and adjust the
+ * seconds accordingly.
+ *
+ * This function uses the string buffer library for the return value,
+ * so do not keep the resulting pointers around.
+ */
+extern const char *
+format_time_fraction(time_t secs, long frac, int prec);
+
+#endif /* !defined(TIMETOA_H) */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/timevalops.h b/sebhbsd/freebsd/contrib/ntp/include/timevalops.h
new file mode 100644
index 0000000..e873b8b
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/timevalops.h
@@ -0,0 +1,446 @@
+/*
+ * timevalops.h -- calculations on 'struct timeval' values
+ *
+ * Written by Juergen Perlinger (perlinger@ntp.org) for the NTP project.
+ * The contents of 'html/copyright.html' apply.
+ *
+ * For a rationale look at 'timespecops.h'; we do the same here, but the
+ * normalisation keeps the microseconds in [0 .. 10^6[, of course.
+ */
+#ifndef TIMEVALOPS_H
+#define TIMEVALOPS_H
+
+#include <sys/types.h>
+#include <stdio.h>
+
+#include "ntp.h"
+#include "timetoa.h"
+
+
+/* microseconds per second */
+#define MICROSECONDS 1000000
+
+#ifndef HAVE_U_INT64
+# define USE_TSF_USEC_TABLES
+#endif
+
+/*
+ * Convert usec to a time stamp fraction.
+ */
+#ifdef USE_TSF_USEC_TABLES
+extern const u_int32 ustotslo[];
+extern const u_int32 ustotsmid[];
+extern const u_int32 ustotshi[];
+
+# define TVUTOTSF(tvu, tsf) \
+ ((tsf) = ustotslo[(tvu) & 0xff] \
+ + ustotsmid[((tvu) >> 8) & 0xff] \
+ + ustotshi[((tvu) >> 16) & 0xf])
+#else
+# define TVUTOTSF(tvu, tsf) \
+ ((tsf) = (u_int32) \
+ ((((u_int64)(tvu) << 32) + MICROSECONDS / 2) / \
+ MICROSECONDS))
+#endif
+
+/*
+ * Convert a time stamp fraction to microseconds. The time stamp
+ * fraction is assumed to be unsigned.
+ */
+#ifdef USE_TSF_USEC_TABLES
+extern const u_int32 tstouslo[256];
+extern const u_int32 tstousmid[256];
+extern const u_int32 tstoushi[128];
+
+/*
+ * TV_SHIFT is used to turn the table result into a usec value. To
+ * round, add in TV_ROUNDBIT before shifting.
+ */
+#define TV_SHIFT 3
+#define TV_ROUNDBIT 0x4
+
+# define TSFTOTVU(tsf, tvu) \
+ ((tvu) = (tstoushi[((tsf) >> 24) & 0xff] \
+ + tstousmid[((tsf) >> 16) & 0xff] \
+ + tstouslo[((tsf) >> 9) & 0x7f] \
+ + TV_ROUNDBIT) >> TV_SHIFT)
+#else
+# define TSFTOTVU(tsf, tvu) \
+ ((tvu) = (int32) \
+ (((u_int64)(tsf) * MICROSECONDS + 0x80000000) >> 32))
+#endif
+
+/*
+ * Convert a struct timeval to a time stamp.
+ */
+#define TVTOTS(tv, ts) \
+ do { \
+ (ts)->l_ui = (u_long)(tv)->tv_sec; \
+ TVUTOTSF((tv)->tv_usec, (ts)->l_uf); \
+ } while (FALSE)
+
+#define sTVTOTS(tv, ts) \
+ do { \
+ int isneg = 0; \
+ long usec; \
+ (ts)->l_ui = (tv)->tv_sec; \
+ usec = (tv)->tv_usec; \
+ if (((tv)->tv_sec < 0) || ((tv)->tv_usec < 0)) { \
+ usec = -usec; \
+ (ts)->l_ui = -(ts)->l_ui; \
+ isneg = 1; \
+ } \
+ TVUTOTSF(usec, (ts)->l_uf); \
+ if (isneg) { \
+ L_NEG((ts)); \
+ } \
+ } while (FALSE)
+
+/*
+ * Convert a time stamp to a struct timeval. The time stamp
+ * has to be positive.
+ */
+#define TSTOTV(ts, tv) \
+ do { \
+ (tv)->tv_sec = (ts)->l_ui; \
+ TSFTOTVU((ts)->l_uf, (tv)->tv_usec); \
+ if ((tv)->tv_usec == 1000000) { \
+ (tv)->tv_sec++; \
+ (tv)->tv_usec = 0; \
+ } \
+ } while (FALSE)
+
+
+/*
+ * predicate: returns TRUE if the microseconds are in nominal range
+ * use like: int timeval_isnormal(const struct timeval *x)
+ */
+#define timeval_isnormal(x) \
+ ((x)->tv_usec >= 0 && (x)->tv_usec < MICROSECONDS)
+
+/*
+ * Convert milliseconds to a time stamp fraction. Unused except for
+ * refclock_leitch.c, so accompanying lookup tables were removed in
+ * favor of reusing the microseconds conversion tables.
+ */
+#define MSUTOTSF(msu, tsf) TVUTOTSF((msu) * 1000, tsf)
+
+/*
+ * predicate: returns TRUE if the microseconds are out-of-bounds
+ * use like: int timeval_isdenormal(const struct timeval *x)
+ */
+#define timeval_isdenormal(x) (!timeval_isnormal(x))
+
+/* make sure microseconds are in nominal range */
+static inline struct timeval
+normalize_tval(
+ struct timeval x
+ )
+{
+ long z;
+
+ /*
+ * If the fraction becomes excessive denormal, we use division
+ * to do first partial normalisation. The normalisation loops
+ * following will do the remaining cleanup. Since the size of
+ * tv_usec has a peculiar definition by the standard the range
+ * check is coded manually. And labs() is intentionally not used
+ * here: it has implementation-defined behaviour when applied
+ * to LONG_MIN.
+ */
+ if (x.tv_usec < -3l * MICROSECONDS ||
+ x.tv_usec > 3l * MICROSECONDS ) {
+ z = x.tv_usec / MICROSECONDS;
+ x.tv_usec -= z * MICROSECONDS;
+ x.tv_sec += z;
+ }
+
+ /*
+ * Do any remaining normalisation steps in loops. This takes 3
+ * steps max, and should outperform a division even if the
+ * mul-by-inverse trick is employed. (It also does the floor
+ * division adjustment if the above division was executed.)
+ */
+ if (x.tv_usec < 0)
+ do {
+ x.tv_usec += MICROSECONDS;
+ x.tv_sec--;
+ } while (x.tv_usec < 0);
+ else if (x.tv_usec >= MICROSECONDS)
+ do {
+ x.tv_usec -= MICROSECONDS;
+ x.tv_sec++;
+ } while (x.tv_usec >= MICROSECONDS);
+
+ return x;
+}
+
+/* x = a + b */
+static inline struct timeval
+add_tval(
+ struct timeval a,
+ struct timeval b
+ )
+{
+ struct timeval x;
+
+ x = a;
+ x.tv_sec += b.tv_sec;
+ x.tv_usec += b.tv_usec;
+
+ return normalize_tval(x);
+}
+
+/* x = a + b, b is fraction only */
+static inline struct timeval
+add_tval_us(
+ struct timeval a,
+ long b
+ )
+{
+ struct timeval x;
+
+ x = a;
+ x.tv_usec += b;
+
+ return normalize_tval(x);
+}
+
+/* x = a - b */
+static inline struct timeval
+sub_tval(
+ struct timeval a,
+ struct timeval b
+ )
+{
+ struct timeval x;
+
+ x = a;
+ x.tv_sec -= b.tv_sec;
+ x.tv_usec -= b.tv_usec;
+
+ return normalize_tval(x);
+}
+
+/* x = a - b, b is fraction only */
+static inline struct timeval
+sub_tval_us(
+ struct timeval a,
+ long b
+ )
+{
+ struct timeval x;
+
+ x = a;
+ x.tv_usec -= b;
+
+ return normalize_tval(x);
+}
+
+/* x = -a */
+static inline struct timeval
+neg_tval(
+ struct timeval a
+ )
+{
+ struct timeval x;
+
+ x.tv_sec = -a.tv_sec;
+ x.tv_usec = -a.tv_usec;
+
+ return normalize_tval(x);
+}
+
+/* x = abs(a) */
+static inline struct timeval
+abs_tval(
+ struct timeval a
+ )
+{
+ struct timeval c;
+
+ c = normalize_tval(a);
+ if (c.tv_sec < 0) {
+ if (c.tv_usec != 0) {
+ c.tv_sec = -c.tv_sec - 1;
+ c.tv_usec = MICROSECONDS - c.tv_usec;
+ } else {
+ c.tv_sec = -c.tv_sec;
+ }
+ }
+
+ return c;
+}
+
+/*
+ * compare previously-normalised a and b
+ * return 1 / 0 / -1 if a < / == / > b
+ */
+static inline int
+cmp_tval(
+ struct timeval a,
+ struct timeval b
+ )
+{
+ int r;
+
+ r = (a.tv_sec > b.tv_sec) - (a.tv_sec < b.tv_sec);
+ if (0 == r)
+ r = (a.tv_usec > b.tv_usec) -
+ (a.tv_usec < b.tv_usec);
+
+ return r;
+}
+
+/*
+ * compare possibly-denormal a and b
+ * return 1 / 0 / -1 if a < / == / > b
+ */
+static inline int
+cmp_tval_denorm(
+ struct timeval a,
+ struct timeval b
+ )
+{
+ return cmp_tval(normalize_tval(a), normalize_tval(b));
+}
+
+/*
+ * test previously-normalised a
+ * return 1 / 0 / -1 if a < / == / > 0
+ */
+static inline int
+test_tval(
+ struct timeval a
+ )
+{
+ int r;
+
+ r = (a.tv_sec > 0) - (a.tv_sec < 0);
+ if (r == 0)
+ r = (a.tv_usec > 0);
+
+ return r;
+}
+
+/*
+ * test possibly-denormal a
+ * return 1 / 0 / -1 if a < / == / > 0
+ */
+static inline int
+test_tval_denorm(
+ struct timeval a
+ )
+{
+ return test_tval(normalize_tval(a));
+}
+
+/* return LIB buffer ptr to string rep */
+static inline const char *
+tvaltoa(
+ struct timeval x
+ )
+{
+ return format_time_fraction(x.tv_sec, x.tv_usec, 6);
+}
+
+/* convert from timeval duration to l_fp duration */
+static inline l_fp
+tval_intv_to_lfp(
+ struct timeval x
+ )
+{
+ struct timeval v;
+ l_fp y;
+
+ v = normalize_tval(x);
+ TVUTOTSF(v.tv_usec, y.l_uf);
+ y.l_i = (int32)v.tv_sec;
+
+ return y;
+}
+
+/* x must be UN*X epoch, output *y will be in NTP epoch */
+static inline l_fp
+tval_stamp_to_lfp(
+ struct timeval x
+ )
+{
+ l_fp y;
+
+ y = tval_intv_to_lfp(x);
+ y.l_ui += JAN_1970;
+
+ return y;
+}
+
+/* convert to l_fp type, relative signed/unsigned and absolute */
+static inline struct timeval
+lfp_intv_to_tval(
+ l_fp x
+ )
+{
+ struct timeval out;
+ l_fp absx;
+ int neg;
+
+ neg = L_ISNEG(&x);
+ absx = x;
+ if (neg) {
+ L_NEG(&absx);
+ }
+ TSFTOTVU(absx.l_uf, out.tv_usec);
+ out.tv_sec = absx.l_i;
+ if (neg) {
+ out.tv_sec = -out.tv_sec;
+ out.tv_usec = -out.tv_usec;
+ out = normalize_tval(out);
+ }
+
+ return out;
+}
+
+static inline struct timeval
+lfp_uintv_to_tval(
+ l_fp x
+ )
+{
+ struct timeval out;
+
+ TSFTOTVU(x.l_uf, out.tv_usec);
+ out.tv_sec = x.l_ui;
+
+ return out;
+}
+
+/*
+ * absolute (timestamp) conversion. Input is time in NTP epoch, output
+ * is in UN*X epoch. The NTP time stamp will be expanded around the
+ * pivot time *p or the current time, if p is NULL.
+ */
+static inline struct timeval
+lfp_stamp_to_tval(
+ l_fp x,
+ const time_t * p
+ )
+{
+ struct timeval out;
+ vint64 sec;
+
+ sec = ntpcal_ntp_to_time(x.l_ui, p);
+ TSFTOTVU(x.l_uf, out.tv_usec);
+
+ /* copying a vint64 to a time_t needs some care... */
+#if SIZEOF_TIME_T <= 4
+ out.tv_sec = (time_t)sec.d_s.lo;
+#elif defined(HAVE_INT64)
+ out.tv_sec = (time_t)sec.q_s;
+#else
+ out.tv_sec = ((time_t)sec.d_s.hi << 32) | sec.d_s.lo;
+#endif
+ out = normalize_tval(out);
+
+ return out;
+}
+
+#endif /* TIMEVALOPS_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/trimble.h b/sebhbsd/freebsd/contrib/ntp/include/trimble.h
new file mode 100644
index 0000000..aaa5baa
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/trimble.h
@@ -0,0 +1,160 @@
+/*
+ * /src/NTP/ntp4-dev/include/trimble.h,v 4.6 2005/04/16 17:32:10 kardel RELEASE_20050508_A
+ *
+ * trimble.h,v 4.6 2005/04/16 17:32:10 kardel RELEASE_20050508_A
+ *
+ * $Created: Sun Aug 2 16:16:49 1998 $
+ *
+ * Copyright (c) 1998-2005 by Frank Kardel <kardel <AT> ntp.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED 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.
+ *
+ */
+#ifndef TRIMBLE_H
+#define TRIMBLE_H
+
+/*
+ * Trimble packet command codes - commands being sent/received
+ * keep comments formatted as shown - they are used to generate
+ * translation tables
+ */
+#define CMD_CCLROSC 0x1D /* clear oscillator offset */
+#define CMD_CCLRRST 0x1E /* clear battery backup and RESET */
+#define CMD_CVERSION 0x1F /* return software version */
+#define CMD_CALMANAC 0x20 /* almanac */
+#define CMD_CCURTIME 0x21 /* current time */
+#define CMD_CMODESEL 0x22 /* mode select (2-d, 3-D, auto) */
+#define CMD_CINITPOS 0x23 /* initial position */
+#define CMD_CRECVPOS 0x24 /* receiver position fix mode */
+#define CMD_CRESET 0x25 /* soft reset & selftest */
+#define CMD_CRECVHEALTH 0x26 /* receiver health */
+#define CMD_CSIGNALLV 0x27 /* signal levels */
+#define CMD_CMESSAGE 0x28 /* GPS system message */
+#define CMD_CALMAHEALTH 0x29 /* almanac healt page */
+#define CMD_C2DALTITUDE 0x2A /* altitude for 2-D mode */
+#define CMD_CINITPOSLLA 0x2B /* initial position LLA */
+#define CMD_COPERPARAM 0x2C /* operating parameters */
+#define CMD_COSCOFFSET 0x2D /* oscillator offset */
+#define CMD_CSETGPSTIME 0x2E /* set GPS time */
+#define CMD_CUTCPARAM 0x2F /* UTC parameters */
+#define CMD_CACCPOSXYZ 0x31 /* accurate initial position (XYZ/ECEF) */
+#define CMD_CACCPOS 0x32 /* accurate initial position */
+#define CMD_CANALOGDIG 0x33 /* analog to digital */
+#define CMD_CSAT1SAT 0x34 /* satellite for 1-Sat mode */
+#define CMD_CIOOPTIONS 0x35 /* I/O options */
+#define CMD_CVELOCAID 0x36 /* velocity aiding of acquisition */
+#define CMD_CSTATLSTPOS 0x37 /* status and values of last pos. and vel. */
+#define CMD_CLOADSSATDT 0x38 /* load satellite system data */
+#define CMD_CSATDISABLE 0x39 /* satellite disable */
+#define CMD_CLASTRAW 0x3A /* last raw measurement */
+#define CMD_CSTATSATEPH 0x3B /* satellite ephemeris status */
+#define CMD_CSTATTRACK 0x3C /* tracking status */
+#define CMD_CCHANADGPS 0x3D /* configure channel A for differential GPS */
+#define CMD_CADDITFIX 0x3E /* additional fix data */
+#define CMD_CDGPSFIXMD 0x62 /* set/request differential GPS position fix mode */
+#define CMD_CDGPSCORR 0x65 /* differential correction status */
+#define CMD_CPOSFILT 0x71 /* position filter parameters */
+#define CMD_CHEIGHTFILT 0x73 /* height filter control */
+#define CMD_CHIGH8CNT 0x75 /* high-8 (best 4) / high-6 (overdetermined) control */
+#define CMD_CMAXDGPSCOR 0x77 /* maximum rate of DGPS corrections */
+#define CMD_CSUPER 0x8E /* super paket */
+
+#define CMD_RDATAA 0x3D /* data channel A configuration:trimble_channelA:RO */
+#define CMD_RALMANAC 0x40 /* almanac data for sat:gps_almanac:RO */
+#define CMD_RCURTIME 0x41 /* GPS time:gps_time:RO */
+#define CMD_RSPOSXYZ 0x42 /* single precision XYZ position:gps_position(XYZ):RO|DEF */
+#define CMD_RVELOXYZ 0x43 /* velocity fix (XYZ ECEF):gps_velocity(XYZ):RO|DEF */
+#define CMD_RBEST4 0x44 /* best 4 satellite selection:trimble_best4:RO|DEF */
+#define CMD_RVERSION 0x45 /* software version:trimble_version:RO|DEF */
+#define CMD_RRECVHEALTH 0x46 /* receiver health:trimble_receiver_health:RO|DEF */
+#define CMD_RSIGNALLV 0x47 /* signal levels of all satellites:trimble_signal_levels:RO */
+#define CMD_RMESSAGE 0x48 /* GPS system message:gps-message:RO|DEF */
+#define CMD_RALMAHEALTH 0x49 /* almanac health page for all satellites:gps_almanac_health:RO */
+#define CMD_RSLLAPOS 0x4A /* single LLA position:gps_position(LLA):RO|DEF */
+#define CMD_RMACHSTAT 0x4B /* machine code / status:trimble_status:RO|DEF */
+#define CMD_ROPERPARAM 0x4C /* operating parameters:trimble_opparam:RO */
+#define CMD_ROSCOFFSET 0x4D /* oscillator offset:trimble_oscoffset:RO */
+#define CMD_RSETGPSTIME 0x4E /* response to set GPS time:trimble_setgpstime:RO */
+#define CMD_RUTCPARAM 0x4F /* UTC parameters:gps_utc_correction:RO|DEF */
+#define CMD_RANALOGDIG 0x53 /* analog to digital:trimble_analogdigital:RO */
+#define CMD_RSAT1BIAS 0x54 /* one-satellite bias & bias rate:trimble_sat1bias:RO */
+#define CMD_RIOOPTIONS 0x55 /* I/O options:trimble_iooptions:RO */
+#define CMD_RVELOCFIX 0x56 /* velocity fix (ENU):trimble_velocfix */
+#define CMD_RSTATLSTFIX 0x57 /* status and values of last pos. and vel.:trimble_status_lastpos:RO */
+#define CMD_RLOADSSATDT 0x58 /* response to load satellite system data:trimble_loaddata:RO */
+#define CMD_RSATDISABLE 0x59 /* satellite disable:trimble_satdisble:RO */
+#define CMD_RLASTRAW 0x5A /* last raw measurement:trimble_lastraw:RO */
+#define CMD_RSTATSATEPH 0x5B /* satellite ephemeris status:trimble_ephstatus:RO */
+#define CMD_RSTATTRACK 0x5C /* tracking status:trimble_tracking_status:RO|DEF */
+#define CMD_RADDITFIX 0x5E /* additional fix data:trimble_addfix:RO */
+#define CMD_RALLINVIEW 0x6D /* all in view satellite selection:trimble_satview:RO|DEF */
+#define CMD_RPOSFILT 0x72 /* position filter parameters:trimble_posfilt:RO */
+#define CMD_RHEIGHTFILT 0x74 /* height filter control:trimble_heightfilt:RO */
+#define CMD_RHIGH8CNT 0x76 /* high-8 (best 4) / high-6 (overdetermined) control:trimble_high8control:RO */
+#define CMD_RMAXAGE 0x78 /* DC MaxAge:trimble_dgpsmaxage:RO */
+#define CMD_RDGPSFIX 0x82 /* differential position fix mode:trimble_dgpsfixmode:RO */
+#define CMD_RDOUBLEXYZ 0x83 /* double precision XYZ:gps_position_ext(XYZ):RO|DEF */
+#define CMD_RDOUBLELLA 0x84 /* double precision LLA:gps_position_ext(LLA):RO|DEF */
+#define CMD_RDGPSSTAT 0x85 /* differential correction status:trimble_dgpsstatus:RO */
+#define CMD_RSUPER 0x8F /* super paket::0 */
+
+typedef struct cmd_info
+{
+ unsigned char cmd; /* command code */
+ const char *cmdname; /* command name */
+ const char *cmddesc; /* command description */
+ const char *varname; /* name of variable */
+ int varmode; /* mode of variable */
+} cmd_info_t;
+
+extern cmd_info_t trimble_rcmds[];
+extern cmd_info_t trimble_scmds[];
+
+extern cmd_info_t *trimble_convert (unsigned int cmd, cmd_info_t *tbl);
+
+#endif
+/*
+ * History:
+ *
+ * trimble.h,v
+ * Revision 4.6 2005/04/16 17:32:10 kardel
+ * update copyright
+ *
+ * Revision 4.5 2004/11/14 15:29:41 kardel
+ * support PPSAPI, upgrade Copyright to Berkeley style
+ *
+ * Revision 4.4 1999/02/28 11:41:11 kardel
+ * (CMD_RUTCPARAM): control variable name unification
+ *
+ * Revision 4.3 1998/12/20 23:45:25 kardel
+ * fix types and warnings
+ *
+ * Revision 4.2 1998/08/16 18:45:05 kardel
+ * (CMD_RSTATTRACK): renamed mode 6 variable name
+ *
+ * Revision 4.1 1998/08/09 22:24:35 kardel
+ * Trimble TSIP support
+ *
+ */
diff --git a/sebhbsd/freebsd/contrib/ntp/include/vint64ops.h b/sebhbsd/freebsd/contrib/ntp/include/vint64ops.h
new file mode 100644
index 0000000..2c3deff
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/include/vint64ops.h
@@ -0,0 +1,28 @@
+/*
+ * vint64ops.h - operations on 'vint64' values
+ *
+ * Written by Juergen Perlinger (perlinger@ntp.org) for the NTP project.
+ * The contents of 'html/copyright.html' apply.
+ * ----------------------------------------------------------------------
+ * This is an attempt to get the vint64 calculations stuff centralised.
+ */
+#ifndef VINT64OPS_H
+#define VINT64OPS_H
+
+/* signed/unsigned compare. returns 1/0/-1 if lhs >/=/< rhs */
+extern int icmpv64(const vint64 * lhs, const vint64 * rhs);
+extern int ucmpv64(const vint64 * lhs, const vint64 * rhs);
+
+/* add / subtract */
+extern vint64 addv64(const vint64 *lhs, const vint64 *rhs);
+extern vint64 addv64i32(const vint64 * lhs, int32_t rhs);
+extern vint64 addv64u32(const vint64 * lhs, uint32_t rhs);
+
+extern vint64 subv64(const vint64 *lhs, const vint64 *rhs);
+extern vint64 subv64i32(const vint64 * lhs, int32_t rhs);
+extern vint64 subv64u32(const vint64 * lhs, uint32_t rhs);
+
+/* parsing. works like strtoul() or strtoull() */
+extern vint64 strtouv64(const char * begp, char ** endp, int base);
+
+#endif /*!defined(VINT64OPS_H)*/
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/assertions.c b/sebhbsd/freebsd/contrib/ntp/lib/isc/assertions.c
new file mode 100644
index 0000000..e3786a6
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/assertions.c
@@ -0,0 +1,147 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1997-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: assertions.c,v 1.26 2009/09/29 15:06:07 fdupont Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <isc/assertions.h>
+#include <isc/backtrace.h>
+#include <isc/msgs.h>
+#include <isc/result.h>
+
+/*
+ * The maximum number of stack frames to dump on assertion failure.
+ */
+#ifndef BACKTRACE_MAXFRAME
+#define BACKTRACE_MAXFRAME 128
+#endif
+
+/*%
+ * Forward.
+ */
+static void
+default_callback(const char *, int, isc_assertiontype_t, const char *);
+
+static isc_assertioncallback_t isc_assertion_failed_cb = default_callback;
+
+/*%
+ * Public.
+ */
+
+/*% assertion failed handler */
+/* coverity[+kill] */
+void
+isc_assertion_failed(const char *file, int line, isc_assertiontype_t type,
+ const char *cond)
+{
+ isc_assertion_failed_cb(file, line, type, cond);
+ abort();
+ /* NOTREACHED */
+}
+
+/*% Set callback. */
+void
+isc_assertion_setcallback(isc_assertioncallback_t cb) {
+ if (cb == NULL)
+ isc_assertion_failed_cb = default_callback;
+ else
+ isc_assertion_failed_cb = cb;
+}
+
+/*% Type to Text */
+const char *
+isc_assertion_typetotext(isc_assertiontype_t type) {
+ const char *result;
+
+ /*
+ * These strings have purposefully not been internationalized
+ * because they are considered to essentially be keywords of
+ * the ISC development environment.
+ */
+ switch (type) {
+ case isc_assertiontype_require:
+ result = "REQUIRE";
+ break;
+ case isc_assertiontype_ensure:
+ result = "ENSURE";
+ break;
+ case isc_assertiontype_insist:
+ result = "INSIST";
+ break;
+ case isc_assertiontype_invariant:
+ result = "INVARIANT";
+ break;
+ default:
+ result = NULL;
+ }
+ return (result);
+}
+
+/*
+ * Private.
+ */
+
+static void
+default_callback(const char *file, int line, isc_assertiontype_t type,
+ const char *cond)
+{
+#ifndef __rtems__
+ void *tracebuf[BACKTRACE_MAXFRAME];
+ int i, nframes;
+#endif /* __rtems__ */
+ const char *logsuffix = ".";
+#ifndef __rtems__
+ const char *fname;
+ isc_result_t result;
+
+ result = isc_backtrace_gettrace(tracebuf, BACKTRACE_MAXFRAME, &nframes);
+ if (result == ISC_R_SUCCESS && nframes > 0)
+ logsuffix = ", back trace";
+#endif /* __rtems__ */
+
+ fprintf(stderr, "%s:%d: %s(%s) %s%s\n",
+ file, line, isc_assertion_typetotext(type), cond,
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
+ ISC_MSG_FAILED, "failed"), logsuffix);
+#ifndef __rtems__
+ if (result == ISC_R_SUCCESS) {
+ for (i = 0; i < nframes; i++) {
+ unsigned long offset;
+
+ fname = NULL;
+ result = isc_backtrace_getsymbol(tracebuf[i], &fname,
+ &offset);
+ if (result == ISC_R_SUCCESS) {
+ fprintf(stderr, "#%d %p in %s()+0x%lx\n", i,
+ tracebuf[i], fname, offset);
+ } else {
+ fprintf(stderr, "#%d %p in ??\n", i,
+ tracebuf[i]);
+ }
+ }
+ }
+#endif /* __rtems__ */
+ fflush(stderr);
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/error.c b/sebhbsd/freebsd/contrib/ntp/lib/isc/error.c
new file mode 100644
index 0000000..94a3c07
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/error.c
@@ -0,0 +1,108 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: error.c,v 1.21 2007/06/19 23:47:17 tbox Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <isc/error.h>
+#include <isc/msgs.h>
+
+/*% Default unexpected callback. */
+static void
+default_unexpected_callback(const char *, int, const char *, va_list)
+ ISC_FORMAT_PRINTF(3, 0);
+
+/*% Default fatal callback. */
+static void
+default_fatal_callback(const char *, int, const char *, va_list)
+ ISC_FORMAT_PRINTF(3, 0);
+
+/*% unexpected_callback */
+static isc_errorcallback_t unexpected_callback = default_unexpected_callback;
+static isc_errorcallback_t fatal_callback = default_fatal_callback;
+
+void
+isc_error_setunexpected(isc_errorcallback_t cb) {
+ if (cb == NULL)
+ unexpected_callback = default_unexpected_callback;
+ else
+ unexpected_callback = cb;
+}
+
+void
+isc_error_setfatal(isc_errorcallback_t cb) {
+ if (cb == NULL)
+ fatal_callback = default_fatal_callback;
+ else
+ fatal_callback = cb;
+}
+
+void
+isc_error_unexpected(const char *file, int line, const char *format, ...) {
+ va_list args;
+
+ va_start(args, format);
+ (unexpected_callback)(file, line, format, args);
+ va_end(args);
+}
+
+void
+isc_error_fatal(const char *file, int line, const char *format, ...) {
+ va_list args;
+
+ va_start(args, format);
+ (fatal_callback)(file, line, format, args);
+ va_end(args);
+ abort();
+}
+
+void
+isc_error_runtimecheck(const char *file, int line, const char *expression) {
+ isc_error_fatal(file, line, "RUNTIME_CHECK(%s) %s", expression,
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
+ ISC_MSG_FAILED, "failed"));
+}
+
+static void
+default_unexpected_callback(const char *file, int line, const char *format,
+ va_list args)
+{
+ fprintf(stderr, "%s:%d: ", file, line);
+ vfprintf(stderr, format, args);
+ fprintf(stderr, "\n");
+ fflush(stderr);
+}
+
+static void
+default_fatal_callback(const char *file, int line, const char *format,
+ va_list args)
+{
+ fprintf(stderr, "%s:%d: %s: ", file, line,
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
+ ISC_MSG_FATALERROR, "fatal error"));
+ vfprintf(stderr, format, args);
+ fprintf(stderr, "\n");
+ fflush(stderr);
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/hmacsha.c b/sebhbsd/freebsd/contrib/ntp/lib/isc/hmacsha.c
new file mode 100644
index 0000000..e0f72c6
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/hmacsha.c
@@ -0,0 +1,596 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (C) 2005-2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+/*
+ * This code implements the HMAC-SHA1, HMAC-SHA224, HMAC-SHA256, HMAC-SHA384
+ * and HMAC-SHA512 keyed hash algorithm described in RFC 2104 and
+ * draft-ietf-dnsext-tsig-sha-01.txt.
+ */
+
+#include "config.h"
+
+#include <isc/assertions.h>
+#include <isc/hmacsha.h>
+#include <isc/platform.h>
+#include <isc/sha1.h>
+#include <isc/sha2.h>
+#include <isc/string.h>
+#include <isc/types.h>
+#include <isc/util.h>
+
+#ifdef ISC_PLATFORM_OPENSSLHASH
+
+void
+isc_hmacsha1_init(isc_hmacsha1_t *ctx, const unsigned char *key,
+ unsigned int len)
+{
+ HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha1());
+}
+
+void
+isc_hmacsha1_invalidate(isc_hmacsha1_t *ctx) {
+ HMAC_CTX_cleanup(ctx);
+}
+
+void
+isc_hmacsha1_update(isc_hmacsha1_t *ctx, const unsigned char *buf,
+ unsigned int len)
+{
+ HMAC_Update(ctx, buf, (int) len);
+}
+
+void
+isc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) {
+ unsigned char newdigest[ISC_SHA1_DIGESTLENGTH];
+
+ REQUIRE(len <= ISC_SHA1_DIGESTLENGTH);
+
+ HMAC_Final(ctx, newdigest, NULL);
+ HMAC_CTX_cleanup(ctx);
+ memcpy(digest, newdigest, len);
+ memset(newdigest, 0, sizeof(newdigest));
+}
+
+void
+isc_hmacsha224_init(isc_hmacsha224_t *ctx, const unsigned char *key,
+ unsigned int len)
+{
+ HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha224());
+}
+
+void
+isc_hmacsha224_invalidate(isc_hmacsha224_t *ctx) {
+ HMAC_CTX_cleanup(ctx);
+}
+
+void
+isc_hmacsha224_update(isc_hmacsha224_t *ctx, const unsigned char *buf,
+ unsigned int len)
+{
+ HMAC_Update(ctx, buf, (int) len);
+}
+
+void
+isc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) {
+ unsigned char newdigest[ISC_SHA224_DIGESTLENGTH];
+
+ REQUIRE(len <= ISC_SHA224_DIGESTLENGTH);
+
+ HMAC_Final(ctx, newdigest, NULL);
+ HMAC_CTX_cleanup(ctx);
+ memcpy(digest, newdigest, len);
+ memset(newdigest, 0, sizeof(newdigest));
+}
+
+void
+isc_hmacsha256_init(isc_hmacsha256_t *ctx, const unsigned char *key,
+ unsigned int len)
+{
+ HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha256());
+}
+
+void
+isc_hmacsha256_invalidate(isc_hmacsha256_t *ctx) {
+ HMAC_CTX_cleanup(ctx);
+}
+
+void
+isc_hmacsha256_update(isc_hmacsha256_t *ctx, const unsigned char *buf,
+ unsigned int len)
+{
+ HMAC_Update(ctx, buf, (int) len);
+}
+
+void
+isc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) {
+ unsigned char newdigest[ISC_SHA256_DIGESTLENGTH];
+
+ REQUIRE(len <= ISC_SHA256_DIGESTLENGTH);
+
+ HMAC_Final(ctx, newdigest, NULL);
+ HMAC_CTX_cleanup(ctx);
+ memcpy(digest, newdigest, len);
+ memset(newdigest, 0, sizeof(newdigest));
+}
+
+void
+isc_hmacsha384_init(isc_hmacsha384_t *ctx, const unsigned char *key,
+ unsigned int len)
+{
+ HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha384());
+}
+
+void
+isc_hmacsha384_invalidate(isc_hmacsha384_t *ctx) {
+ HMAC_CTX_cleanup(ctx);
+}
+
+void
+isc_hmacsha384_update(isc_hmacsha384_t *ctx, const unsigned char *buf,
+ unsigned int len)
+{
+ HMAC_Update(ctx, buf, (int) len);
+}
+
+void
+isc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) {
+ unsigned char newdigest[ISC_SHA384_DIGESTLENGTH];
+
+ REQUIRE(len <= ISC_SHA384_DIGESTLENGTH);
+
+ HMAC_Final(ctx, newdigest, NULL);
+ HMAC_CTX_cleanup(ctx);
+ memcpy(digest, newdigest, len);
+ memset(newdigest, 0, sizeof(newdigest));
+}
+
+void
+isc_hmacsha512_init(isc_hmacsha512_t *ctx, const unsigned char *key,
+ unsigned int len)
+{
+ HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha512());
+}
+
+void
+isc_hmacsha512_invalidate(isc_hmacsha512_t *ctx) {
+ HMAC_CTX_cleanup(ctx);
+}
+
+void
+isc_hmacsha512_update(isc_hmacsha512_t *ctx, const unsigned char *buf,
+ unsigned int len)
+{
+ HMAC_Update(ctx, buf, (int) len);
+}
+
+void
+isc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) {
+ unsigned char newdigest[ISC_SHA512_DIGESTLENGTH];
+
+ REQUIRE(len <= ISC_SHA512_DIGESTLENGTH);
+
+ HMAC_Final(ctx, newdigest, NULL);
+ HMAC_CTX_cleanup(ctx);
+ memcpy(digest, newdigest, len);
+ memset(newdigest, 0, sizeof(newdigest));
+}
+
+#else
+
+#define IPAD 0x36
+#define OPAD 0x5C
+
+/*
+ * Start HMAC-SHA1 process. Initialize an sha1 context and digest the key.
+ */
+void
+isc_hmacsha1_init(isc_hmacsha1_t *ctx, const unsigned char *key,
+ unsigned int len)
+{
+ unsigned char ipad[ISC_SHA1_BLOCK_LENGTH];
+ unsigned int i;
+
+ memset(ctx->key, 0, sizeof(ctx->key));
+ if (len > sizeof(ctx->key)) {
+ isc_sha1_t sha1ctx;
+ isc_sha1_init(&sha1ctx);
+ isc_sha1_update(&sha1ctx, key, len);
+ isc_sha1_final(&sha1ctx, ctx->key);
+ } else
+ memcpy(ctx->key, key, len);
+
+ isc_sha1_init(&ctx->sha1ctx);
+ memset(ipad, IPAD, sizeof(ipad));
+ for (i = 0; i < ISC_SHA1_BLOCK_LENGTH; i++)
+ ipad[i] ^= ctx->key[i];
+ isc_sha1_update(&ctx->sha1ctx, ipad, sizeof(ipad));
+}
+
+void
+isc_hmacsha1_invalidate(isc_hmacsha1_t *ctx) {
+ isc_sha1_invalidate(&ctx->sha1ctx);
+ memset(ctx, 0, sizeof(*ctx));
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void
+isc_hmacsha1_update(isc_hmacsha1_t *ctx, const unsigned char *buf,
+ unsigned int len)
+{
+ isc_sha1_update(&ctx->sha1ctx, buf, len);
+}
+
+/*
+ * Compute signature - finalize SHA1 operation and reapply SHA1.
+ */
+void
+isc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) {
+ unsigned char opad[ISC_SHA1_BLOCK_LENGTH];
+ unsigned char newdigest[ISC_SHA1_DIGESTLENGTH];
+ unsigned int i;
+
+ REQUIRE(len <= ISC_SHA1_DIGESTLENGTH);
+ isc_sha1_final(&ctx->sha1ctx, newdigest);
+
+ memset(opad, OPAD, sizeof(opad));
+ for (i = 0; i < ISC_SHA1_BLOCK_LENGTH; i++)
+ opad[i] ^= ctx->key[i];
+
+ isc_sha1_init(&ctx->sha1ctx);
+ isc_sha1_update(&ctx->sha1ctx, opad, sizeof(opad));
+ isc_sha1_update(&ctx->sha1ctx, newdigest, ISC_SHA1_DIGESTLENGTH);
+ isc_sha1_final(&ctx->sha1ctx, newdigest);
+ isc_hmacsha1_invalidate(ctx);
+ memcpy(digest, newdigest, len);
+ memset(newdigest, 0, sizeof(newdigest));
+}
+
+/*
+ * Start HMAC-SHA224 process. Initialize an sha224 context and digest the key.
+ */
+void
+isc_hmacsha224_init(isc_hmacsha224_t *ctx, const unsigned char *key,
+ unsigned int len)
+{
+ unsigned char ipad[ISC_SHA224_BLOCK_LENGTH];
+ unsigned int i;
+
+ memset(ctx->key, 0, sizeof(ctx->key));
+ if (len > sizeof(ctx->key)) {
+ isc_sha224_t sha224ctx;
+ isc_sha224_init(&sha224ctx);
+ isc_sha224_update(&sha224ctx, key, len);
+ isc_sha224_final(ctx->key, &sha224ctx);
+ } else
+ memcpy(ctx->key, key, len);
+
+ isc_sha224_init(&ctx->sha224ctx);
+ memset(ipad, IPAD, sizeof(ipad));
+ for (i = 0; i < ISC_SHA224_BLOCK_LENGTH; i++)
+ ipad[i] ^= ctx->key[i];
+ isc_sha224_update(&ctx->sha224ctx, ipad, sizeof(ipad));
+}
+
+void
+isc_hmacsha224_invalidate(isc_hmacsha224_t *ctx) {
+ memset(ctx, 0, sizeof(*ctx));
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void
+isc_hmacsha224_update(isc_hmacsha224_t *ctx, const unsigned char *buf,
+ unsigned int len)
+{
+ isc_sha224_update(&ctx->sha224ctx, buf, len);
+}
+
+/*
+ * Compute signature - finalize SHA224 operation and reapply SHA224.
+ */
+void
+isc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) {
+ unsigned char opad[ISC_SHA224_BLOCK_LENGTH];
+ unsigned char newdigest[ISC_SHA224_DIGESTLENGTH];
+ unsigned int i;
+
+ REQUIRE(len <= ISC_SHA224_DIGESTLENGTH);
+ isc_sha224_final(newdigest, &ctx->sha224ctx);
+
+ memset(opad, OPAD, sizeof(opad));
+ for (i = 0; i < ISC_SHA224_BLOCK_LENGTH; i++)
+ opad[i] ^= ctx->key[i];
+
+ isc_sha224_init(&ctx->sha224ctx);
+ isc_sha224_update(&ctx->sha224ctx, opad, sizeof(opad));
+ isc_sha224_update(&ctx->sha224ctx, newdigest, ISC_SHA224_DIGESTLENGTH);
+ isc_sha224_final(newdigest, &ctx->sha224ctx);
+ memcpy(digest, newdigest, len);
+ memset(newdigest, 0, sizeof(newdigest));
+}
+
+/*
+ * Start HMAC-SHA256 process. Initialize an sha256 context and digest the key.
+ */
+void
+isc_hmacsha256_init(isc_hmacsha256_t *ctx, const unsigned char *key,
+ unsigned int len)
+{
+ unsigned char ipad[ISC_SHA256_BLOCK_LENGTH];
+ unsigned int i;
+
+ memset(ctx->key, 0, sizeof(ctx->key));
+ if (len > sizeof(ctx->key)) {
+ isc_sha256_t sha256ctx;
+ isc_sha256_init(&sha256ctx);
+ isc_sha256_update(&sha256ctx, key, len);
+ isc_sha256_final(ctx->key, &sha256ctx);
+ } else
+ memcpy(ctx->key, key, len);
+
+ isc_sha256_init(&ctx->sha256ctx);
+ memset(ipad, IPAD, sizeof(ipad));
+ for (i = 0; i < ISC_SHA256_BLOCK_LENGTH; i++)
+ ipad[i] ^= ctx->key[i];
+ isc_sha256_update(&ctx->sha256ctx, ipad, sizeof(ipad));
+}
+
+void
+isc_hmacsha256_invalidate(isc_hmacsha256_t *ctx) {
+ memset(ctx, 0, sizeof(*ctx));
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void
+isc_hmacsha256_update(isc_hmacsha256_t *ctx, const unsigned char *buf,
+ unsigned int len)
+{
+ isc_sha256_update(&ctx->sha256ctx, buf, len);
+}
+
+/*
+ * Compute signature - finalize SHA256 operation and reapply SHA256.
+ */
+void
+isc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) {
+ unsigned char opad[ISC_SHA256_BLOCK_LENGTH];
+ unsigned char newdigest[ISC_SHA256_DIGESTLENGTH];
+ unsigned int i;
+
+ REQUIRE(len <= ISC_SHA256_DIGESTLENGTH);
+ isc_sha256_final(newdigest, &ctx->sha256ctx);
+
+ memset(opad, OPAD, sizeof(opad));
+ for (i = 0; i < ISC_SHA256_BLOCK_LENGTH; i++)
+ opad[i] ^= ctx->key[i];
+
+ isc_sha256_init(&ctx->sha256ctx);
+ isc_sha256_update(&ctx->sha256ctx, opad, sizeof(opad));
+ isc_sha256_update(&ctx->sha256ctx, newdigest, ISC_SHA256_DIGESTLENGTH);
+ isc_sha256_final(newdigest, &ctx->sha256ctx);
+ memcpy(digest, newdigest, len);
+ memset(newdigest, 0, sizeof(newdigest));
+}
+
+/*
+ * Start HMAC-SHA384 process. Initialize an sha384 context and digest the key.
+ */
+void
+isc_hmacsha384_init(isc_hmacsha384_t *ctx, const unsigned char *key,
+ unsigned int len)
+{
+ unsigned char ipad[ISC_SHA384_BLOCK_LENGTH];
+ unsigned int i;
+
+ memset(ctx->key, 0, sizeof(ctx->key));
+ if (len > sizeof(ctx->key)) {
+ isc_sha384_t sha384ctx;
+ isc_sha384_init(&sha384ctx);
+ isc_sha384_update(&sha384ctx, key, len);
+ isc_sha384_final(ctx->key, &sha384ctx);
+ } else
+ memcpy(ctx->key, key, len);
+
+ isc_sha384_init(&ctx->sha384ctx);
+ memset(ipad, IPAD, sizeof(ipad));
+ for (i = 0; i < ISC_SHA384_BLOCK_LENGTH; i++)
+ ipad[i] ^= ctx->key[i];
+ isc_sha384_update(&ctx->sha384ctx, ipad, sizeof(ipad));
+}
+
+void
+isc_hmacsha384_invalidate(isc_hmacsha384_t *ctx) {
+ memset(ctx, 0, sizeof(*ctx));
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void
+isc_hmacsha384_update(isc_hmacsha384_t *ctx, const unsigned char *buf,
+ unsigned int len)
+{
+ isc_sha384_update(&ctx->sha384ctx, buf, len);
+}
+
+/*
+ * Compute signature - finalize SHA384 operation and reapply SHA384.
+ */
+void
+isc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) {
+ unsigned char opad[ISC_SHA384_BLOCK_LENGTH];
+ unsigned char newdigest[ISC_SHA384_DIGESTLENGTH];
+ unsigned int i;
+
+ REQUIRE(len <= ISC_SHA384_DIGESTLENGTH);
+ isc_sha384_final(newdigest, &ctx->sha384ctx);
+
+ memset(opad, OPAD, sizeof(opad));
+ for (i = 0; i < ISC_SHA384_BLOCK_LENGTH; i++)
+ opad[i] ^= ctx->key[i];
+
+ isc_sha384_init(&ctx->sha384ctx);
+ isc_sha384_update(&ctx->sha384ctx, opad, sizeof(opad));
+ isc_sha384_update(&ctx->sha384ctx, newdigest, ISC_SHA384_DIGESTLENGTH);
+ isc_sha384_final(newdigest, &ctx->sha384ctx);
+ memcpy(digest, newdigest, len);
+ memset(newdigest, 0, sizeof(newdigest));
+}
+
+/*
+ * Start HMAC-SHA512 process. Initialize an sha512 context and digest the key.
+ */
+void
+isc_hmacsha512_init(isc_hmacsha512_t *ctx, const unsigned char *key,
+ unsigned int len)
+{
+ unsigned char ipad[ISC_SHA512_BLOCK_LENGTH];
+ unsigned int i;
+
+ memset(ctx->key, 0, sizeof(ctx->key));
+ if (len > sizeof(ctx->key)) {
+ isc_sha512_t sha512ctx;
+ isc_sha512_init(&sha512ctx);
+ isc_sha512_update(&sha512ctx, key, len);
+ isc_sha512_final(ctx->key, &sha512ctx);
+ } else
+ memcpy(ctx->key, key, len);
+
+ isc_sha512_init(&ctx->sha512ctx);
+ memset(ipad, IPAD, sizeof(ipad));
+ for (i = 0; i < ISC_SHA512_BLOCK_LENGTH; i++)
+ ipad[i] ^= ctx->key[i];
+ isc_sha512_update(&ctx->sha512ctx, ipad, sizeof(ipad));
+}
+
+void
+isc_hmacsha512_invalidate(isc_hmacsha512_t *ctx) {
+ memset(ctx, 0, sizeof(*ctx));
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void
+isc_hmacsha512_update(isc_hmacsha512_t *ctx, const unsigned char *buf,
+ unsigned int len)
+{
+ isc_sha512_update(&ctx->sha512ctx, buf, len);
+}
+
+/*
+ * Compute signature - finalize SHA512 operation and reapply SHA512.
+ */
+void
+isc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) {
+ unsigned char opad[ISC_SHA512_BLOCK_LENGTH];
+ unsigned char newdigest[ISC_SHA512_DIGESTLENGTH];
+ unsigned int i;
+
+ REQUIRE(len <= ISC_SHA512_DIGESTLENGTH);
+ isc_sha512_final(newdigest, &ctx->sha512ctx);
+
+ memset(opad, OPAD, sizeof(opad));
+ for (i = 0; i < ISC_SHA512_BLOCK_LENGTH; i++)
+ opad[i] ^= ctx->key[i];
+
+ isc_sha512_init(&ctx->sha512ctx);
+ isc_sha512_update(&ctx->sha512ctx, opad, sizeof(opad));
+ isc_sha512_update(&ctx->sha512ctx, newdigest, ISC_SHA512_DIGESTLENGTH);
+ isc_sha512_final(newdigest, &ctx->sha512ctx);
+ memcpy(digest, newdigest, len);
+ memset(newdigest, 0, sizeof(newdigest));
+}
+#endif /* !ISC_PLATFORM_OPENSSLHASH */
+
+/*
+ * Verify signature - finalize SHA1 operation and reapply SHA1, then
+ * compare to the supplied digest.
+ */
+isc_boolean_t
+isc_hmacsha1_verify(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) {
+ unsigned char newdigest[ISC_SHA1_DIGESTLENGTH];
+
+ REQUIRE(len <= ISC_SHA1_DIGESTLENGTH);
+ isc_hmacsha1_sign(ctx, newdigest, ISC_SHA1_DIGESTLENGTH);
+ return (ISC_TF(isc_tsmemcmp(digest, newdigest, len) == 0));
+}
+
+/*
+ * Verify signature - finalize SHA224 operation and reapply SHA224, then
+ * compare to the supplied digest.
+ */
+isc_boolean_t
+isc_hmacsha224_verify(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) {
+ unsigned char newdigest[ISC_SHA224_DIGESTLENGTH];
+
+ REQUIRE(len <= ISC_SHA224_DIGESTLENGTH);
+ isc_hmacsha224_sign(ctx, newdigest, ISC_SHA224_DIGESTLENGTH);
+ return (ISC_TF(isc_tsmemcmp(digest, newdigest, len) == 0));
+}
+
+/*
+ * Verify signature - finalize SHA256 operation and reapply SHA256, then
+ * compare to the supplied digest.
+ */
+isc_boolean_t
+isc_hmacsha256_verify(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) {
+ unsigned char newdigest[ISC_SHA256_DIGESTLENGTH];
+
+ REQUIRE(len <= ISC_SHA256_DIGESTLENGTH);
+ isc_hmacsha256_sign(ctx, newdigest, ISC_SHA256_DIGESTLENGTH);
+ return (ISC_TF(isc_tsmemcmp(digest, newdigest, len) == 0));
+}
+
+/*
+ * Verify signature - finalize SHA384 operation and reapply SHA384, then
+ * compare to the supplied digest.
+ */
+isc_boolean_t
+isc_hmacsha384_verify(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) {
+ unsigned char newdigest[ISC_SHA384_DIGESTLENGTH];
+
+ REQUIRE(len <= ISC_SHA384_DIGESTLENGTH);
+ isc_hmacsha384_sign(ctx, newdigest, ISC_SHA384_DIGESTLENGTH);
+ return (ISC_TF(isc_tsmemcmp(digest, newdigest, len) == 0));
+}
+
+/*
+ * Verify signature - finalize SHA512 operation and reapply SHA512, then
+ * compare to the supplied digest.
+ */
+isc_boolean_t
+isc_hmacsha512_verify(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) {
+ unsigned char newdigest[ISC_SHA512_DIGESTLENGTH];
+
+ REQUIRE(len <= ISC_SHA512_DIGESTLENGTH);
+ isc_hmacsha512_sign(ctx, newdigest, ISC_SHA512_DIGESTLENGTH);
+ return (ISC_TF(isc_tsmemcmp(digest, newdigest, len) == 0));
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/app.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/app.h
new file mode 100644
index 0000000..e0be790
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/app.h
@@ -0,0 +1,375 @@
+/*
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: app.h,v 1.11 2009/09/02 23:48:03 tbox Exp $ */
+
+#ifndef ISC_APP_H
+#define ISC_APP_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file isc/app.h
+ * \brief ISC Application Support
+ *
+ * Dealing with program termination can be difficult, especially in a
+ * multithreaded program. The routines in this module help coordinate
+ * the shutdown process. They are used as follows by the initial (main)
+ * thread of the application:
+ *
+ *\li isc_app_start(); Call very early in main(), before
+ * any other threads have been created.
+ *
+ *\li isc_app_run(); This will post any on-run events,
+ * and then block until application
+ * shutdown is requested. A shutdown
+ * request is made by calling
+ * isc_app_shutdown(), or by sending
+ * SIGINT or SIGTERM to the process.
+ * After isc_app_run() returns, the
+ * application should shutdown itself.
+ *
+ *\li isc_app_finish(); Call very late in main().
+ *
+ * Applications that want to use SIGHUP/isc_app_reload() to trigger reloading
+ * should check the result of isc_app_run() and call the reload routine if
+ * the result is ISC_R_RELOAD. They should then call isc_app_run() again
+ * to resume waiting for reload or termination.
+ *
+ * Use of this module is not required. In particular, isc_app_start() is
+ * NOT an ISC library initialization routine.
+ *
+ * This module also supports per-thread 'application contexts'. With this
+ * mode, a thread-based application will have a separate context, in which
+ * it uses other ISC library services such as tasks or timers. Signals are
+ * not caught in this mode, so that the application can handle the signals
+ * in its preferred way.
+ *
+ * \li MP:
+ * Clients must ensure that isc_app_start(), isc_app_run(), and
+ * isc_app_finish() are called at most once. isc_app_shutdown()
+ * is safe to use by any thread (provided isc_app_start() has been
+ * called previously).
+ *
+ * The same note applies to isc_app_ctxXXX() functions, but in this case
+ * it's a per-thread restriction. For example, a thread with an
+ * application context must ensure that isc_app_ctxstart() with the
+ * context is called at most once.
+ *
+ * \li Reliability:
+ * No anticipated impact.
+ *
+ * \li Resources:
+ * None.
+ *
+ * \li Security:
+ * No anticipated impact.
+ *
+ * \li Standards:
+ * None.
+ */
+
+#include <isc/eventclass.h>
+#include <isc/lang.h>
+#include <isc/magic.h>
+#include <isc/result.h>
+
+/***
+ *** Types
+ ***/
+
+typedef isc_event_t isc_appevent_t;
+
+#define ISC_APPEVENT_FIRSTEVENT (ISC_EVENTCLASS_APP + 0)
+#define ISC_APPEVENT_SHUTDOWN (ISC_EVENTCLASS_APP + 1)
+#define ISC_APPEVENT_LASTEVENT (ISC_EVENTCLASS_APP + 65535)
+
+/*%
+ * app module methods. Only app driver implementations use this structure.
+ * Other clients should use the top-level interfaces (i.e., isc_app_xxx
+ * functions). magic must be ISCAPI_APPMETHODS_MAGIC.
+ */
+typedef struct isc_appmethods {
+ void (*ctxdestroy)(isc_appctx_t **ctxp);
+ isc_result_t (*ctxstart)(isc_appctx_t *ctx);
+ isc_result_t (*ctxrun)(isc_appctx_t *ctx);
+ isc_result_t (*ctxsuspend)(isc_appctx_t *ctx);
+ isc_result_t (*ctxshutdown)(isc_appctx_t *ctx);
+ void (*ctxfinish)(isc_appctx_t *ctx);
+ void (*settaskmgr)(isc_appctx_t *ctx,
+ isc_taskmgr_t *timermgr);
+ void (*setsocketmgr)(isc_appctx_t *ctx,
+ isc_socketmgr_t *timermgr);
+ void (*settimermgr)(isc_appctx_t *ctx,
+ isc_timermgr_t *timermgr);
+} isc_appmethods_t;
+
+/*%
+ * This structure is actually just the common prefix of an application context
+ * implementation's version of an isc_appctx_t.
+ * \brief
+ * Direct use of this structure by clients is forbidden. app implementations
+ * may change the structure. 'magic' must be ISCAPI_APPCTX_MAGIC for any
+ * of the isc_app_ routines to work. app implementations must maintain
+ * all app context invariants.
+ */
+struct isc_appctx {
+ unsigned int impmagic;
+ unsigned int magic;
+ isc_appmethods_t *methods;
+};
+
+#define ISCAPI_APPCTX_MAGIC ISC_MAGIC('A','a','p','c')
+#define ISCAPI_APPCTX_VALID(c) ((c) != NULL && \
+ (c)->magic == ISCAPI_APPCTX_MAGIC)
+
+ISC_LANG_BEGINDECLS
+
+isc_result_t
+isc_app_ctxstart(isc_appctx_t *ctx);
+
+isc_result_t
+isc_app_start(void);
+/*!<
+ * \brief Start an ISC library application.
+ *
+ * Notes:
+ * This call should be made before any other ISC library call, and as
+ * close to the beginning of the application as possible.
+ *
+ * Requires:
+ * 'ctx' is a valid application context (for app_ctxstart()).
+ */
+
+isc_result_t
+isc_app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action,
+ void *arg);
+/*!<
+ * \brief Request delivery of an event when the application is run.
+ *
+ * Requires:
+ *\li isc_app_start() has been called.
+ *
+ * Returns:
+ * ISC_R_SUCCESS
+ * ISC_R_NOMEMORY
+ */
+
+isc_result_t
+isc_app_ctxrun(isc_appctx_t *ctx);
+
+isc_result_t
+isc_app_run(void);
+/*!<
+ * \brief Run an ISC library application.
+ *
+ * Notes:
+ *\li The caller (typically the initial thread of an application) will
+ * block until shutdown is requested. When the call returns, the
+ * caller should start shutting down the application.
+ *
+ * Requires:
+ *\li isc_app_[ctx]start() has been called.
+ *
+ * Ensures:
+ *\li Any events requested via isc_app_onrun() will have been posted (in
+ * FIFO order) before isc_app_run() blocks.
+ *\li 'ctx' is a valid application context (for app_ctxrun()).
+ *
+ * Returns:
+ *\li ISC_R_SUCCESS Shutdown has been requested.
+ *\li ISC_R_RELOAD Reload has been requested.
+ */
+
+isc_result_t
+isc_app_ctxshutdown(isc_appctx_t *ctx);
+
+isc_result_t
+isc_app_shutdown(void);
+/*!<
+ * \brief Request application shutdown.
+ *
+ * Notes:
+ *\li It is safe to call isc_app_shutdown() multiple times. Shutdown will
+ * only be triggered once.
+ *
+ * Requires:
+ *\li isc_app_[ctx]run() has been called.
+ *\li 'ctx' is a valid application context (for app_ctxshutdown()).
+ *
+ * Returns:
+ *\li ISC_R_SUCCESS
+ *\li ISC_R_UNEXPECTED
+ */
+
+isc_result_t
+isc_app_ctxsuspend(isc_appctx_t *ctx);
+/*!<
+ * \brief This has the same behavior as isc_app_ctxsuspend().
+ */
+
+isc_result_t
+isc_app_reload(void);
+/*!<
+ * \brief Request application reload.
+ *
+ * Requires:
+ *\li isc_app_run() has been called.
+ *
+ * Returns:
+ *\li ISC_R_SUCCESS
+ *\li ISC_R_UNEXPECTED
+ */
+
+void
+isc_app_ctxfinish(isc_appctx_t *ctx);
+
+void
+isc_app_finish(void);
+/*!<
+ * \brief Finish an ISC library application.
+ *
+ * Notes:
+ *\li This call should be made at or near the end of main().
+ *
+ * Requires:
+ *\li isc_app_start() has been called.
+ *\li 'ctx' is a valid application context (for app_ctxfinish()).
+ *
+ * Ensures:
+ *\li Any resources allocated by isc_app_start() have been released.
+ */
+
+void
+isc_app_block(void);
+/*!<
+ * \brief Indicate that a blocking operation will be performed.
+ *
+ * Notes:
+ *\li If a blocking operation is in process, a call to isc_app_shutdown()
+ * or an external signal will abort the program, rather than allowing
+ * clean shutdown. This is primarily useful for reading user input.
+ *
+ * Requires:
+ * \li isc_app_start() has been called.
+ * \li No other blocking operations are in progress.
+ */
+
+void
+isc_app_unblock(void);
+/*!<
+ * \brief Indicate that a blocking operation is complete.
+ *
+ * Notes:
+ * \li When a blocking operation has completed, return the program to a
+ * state where a call to isc_app_shutdown() or an external signal will
+ * shutdown normally.
+ *
+ * Requires:
+ * \li isc_app_start() has been called.
+ * \li isc_app_block() has been called by the same thread.
+ */
+
+isc_result_t
+isc_appctx_create(isc_mem_t *mctx, isc_appctx_t **ctxp);
+/*!<
+ * \brief Create an application context.
+ *
+ * Requires:
+ *\li 'mctx' is a valid memory context.
+ *\li 'ctxp' != NULL && *ctxp == NULL.
+ */
+
+void
+isc_appctx_destroy(isc_appctx_t **ctxp);
+/*!<
+ * \brief Destroy an application context.
+ *
+ * Requires:
+ *\li '*ctxp' is a valid application context.
+ *
+ * Ensures:
+ *\li *ctxp == NULL.
+ */
+
+void
+isc_appctx_settaskmgr(isc_appctx_t *ctx, isc_taskmgr_t *taskmgr);
+/*!<
+ * \brief Associate a task manager with an application context.
+ *
+ * This must be done before running tasks within the application context.
+ *
+ * Requires:
+ *\li 'ctx' is a valid application context.
+ *\li 'taskmgr' is a valid task manager.
+ */
+
+void
+isc_appctx_setsocketmgr(isc_appctx_t *ctx, isc_socketmgr_t *socketmgr);
+/*!<
+ * \brief Associate a socket manager with an application context.
+ *
+ * This must be done before handling socket events within the application
+ * context.
+ *
+ * Requires:
+ *\li 'ctx' is a valid application context.
+ *\li 'socketmgr' is a valid socket manager.
+ */
+
+void
+isc_appctx_settimermgr(isc_appctx_t *ctx, isc_timermgr_t *timermgr);
+/*!<
+ * \brief Associate a socket timer with an application context.
+ *
+ * This must be done before handling timer events within the application
+ * context.
+ *
+ * Requires:
+ *\li 'ctx' is a valid application context.
+ *\li 'timermgr' is a valid timer manager.
+ */
+
+#ifdef USE_APPIMPREGISTER
+/*%<
+ * See isc_appctx_create() above.
+ */
+typedef isc_result_t
+(*isc_appctxcreatefunc_t)(isc_mem_t *mctx, isc_appctx_t **ctxp);
+
+isc_result_t
+isc_app_register(isc_appctxcreatefunc_t createfunc);
+/*%<
+ * Register a new application implementation and add it to the list of
+ * supported implementations. This function must be called when a different
+ * event library is used than the one contained in the ISC library.
+ */
+
+isc_result_t
+isc__app_register(void);
+/*%<
+ * A short cut function that specifies the application module in the ISC
+ * library for isc_app_register(). An application that uses the ISC library
+ * usually do not have to care about this function: it would call
+ * isc_lib_register(), which internally calls this function.
+ */
+#endif /* USE_APPIMPREGISTER */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_APP_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/assertions.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/assertions.h
new file mode 100644
index 0000000..2c81b1a
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/assertions.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1997-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * $Id: assertions.h,v 1.28 2009/09/29 23:48:04 tbox Exp $
+ */
+/*! \file isc/assertions.h
+ */
+
+#ifndef ISC_ASSERTIONS_H
+#define ISC_ASSERTIONS_H 1
+
+#include <isc/lang.h>
+#include <isc/platform.h>
+
+ISC_LANG_BEGINDECLS
+
+/*% isc assertion type */
+typedef enum {
+ isc_assertiontype_require,
+ isc_assertiontype_ensure,
+ isc_assertiontype_insist,
+ isc_assertiontype_invariant
+} isc_assertiontype_t;
+
+typedef void (*isc_assertioncallback_t)(const char *, int, isc_assertiontype_t,
+ const char *);
+
+/* coverity[+kill] */
+ISC_PLATFORM_NORETURN_PRE
+void isc_assertion_failed(const char *, int, isc_assertiontype_t,
+ const char *) ISC_PLATFORM_NORETURN_POST;
+
+void
+isc_assertion_setcallback(isc_assertioncallback_t);
+
+const char *
+isc_assertion_typetotext(isc_assertiontype_t type);
+
+#if defined(ISC_CHECK_ALL) || defined(__COVERITY__)
+#define ISC_CHECK_REQUIRE 1
+#define ISC_CHECK_ENSURE 1
+#define ISC_CHECK_INSIST 1
+#define ISC_CHECK_INVARIANT 1
+#endif
+
+#if defined(ISC_CHECK_NONE) && !defined(__COVERITY__)
+#define ISC_CHECK_REQUIRE 0
+#define ISC_CHECK_ENSURE 0
+#define ISC_CHECK_INSIST 0
+#define ISC_CHECK_INVARIANT 0
+#endif
+
+#ifndef ISC_CHECK_REQUIRE
+#define ISC_CHECK_REQUIRE 1
+#endif
+
+#ifndef ISC_CHECK_ENSURE
+#define ISC_CHECK_ENSURE 1
+#endif
+
+#ifndef ISC_CHECK_INSIST
+#define ISC_CHECK_INSIST 1
+#endif
+
+#ifndef ISC_CHECK_INVARIANT
+#define ISC_CHECK_INVARIANT 1
+#endif
+
+#if ISC_CHECK_REQUIRE != 0
+#define ISC_REQUIRE(cond) \
+ ((void) ((cond) || \
+ ((isc_assertion_failed)(__FILE__, __LINE__, \
+ isc_assertiontype_require, \
+ #cond), 0)))
+#else
+#define ISC_REQUIRE(cond) ((void) 0)
+#endif /* ISC_CHECK_REQUIRE */
+
+#if ISC_CHECK_ENSURE != 0
+#define ISC_ENSURE(cond) \
+ ((void) ((cond) || \
+ ((isc_assertion_failed)(__FILE__, __LINE__, \
+ isc_assertiontype_ensure, \
+ #cond), 0)))
+#else
+#define ISC_ENSURE(cond) ((void) 0)
+#endif /* ISC_CHECK_ENSURE */
+
+#if ISC_CHECK_INSIST != 0
+#define ISC_INSIST(cond) \
+ ((void) ((cond) || \
+ ((isc_assertion_failed)(__FILE__, __LINE__, \
+ isc_assertiontype_insist, \
+ #cond), 0)))
+#else
+#define ISC_INSIST(cond) ((void) 0)
+#endif /* ISC_CHECK_INSIST */
+
+#if ISC_CHECK_INVARIANT != 0
+#define ISC_INVARIANT(cond) \
+ ((void) ((cond) || \
+ ((isc_assertion_failed)(__FILE__, __LINE__, \
+ isc_assertiontype_invariant, \
+ #cond), 0)))
+#else
+#define ISC_INVARIANT(cond) ((void) 0)
+#endif /* ISC_CHECK_INVARIANT */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_ASSERTIONS_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/backtrace.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/backtrace.h
new file mode 100644
index 0000000..7d7fc32
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/backtrace.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: backtrace.h,v 1.2 2009/09/01 18:40:25 jinmei Exp $ */
+
+/*! \file isc/backtrace.h
+ * \brief provide a back trace of the running process to help debug problems.
+ *
+ * This module tries to get a back trace of the process using some platform
+ * dependent way when available. It also manages an internal symbol table
+ * that maps function addresses used in the process to their textual symbols.
+ * This module is expected to be used to help debug when some fatal error
+ * happens.
+ *
+ * IMPORTANT NOTE: since the (major) intended use case of this module is
+ * dumping a back trace on a fatal error, normally followed by self termination,
+ * functions defined in this module generally doesn't employ assertion checks
+ * (if it did, a program bug could cause infinite recursive calls to a
+ * backtrace function). These functions still perform minimal checks and return
+ * ISC_R_FAILURE if they detect an error, but the caller should therefore be
+ * very careful about the use of these functions, and generally discouraged to
+ * use them except in an exit path. The exception is
+ * isc_backtrace_getsymbolfromindex(), which is expected to be used in a
+ * non-error-handling context and validates arguments with assertion checks.
+ */
+
+#ifndef ISC_BACKTRACE_H
+#define ISC_BACKTRACE_H 1
+
+/***
+ *** Imports
+ ***/
+
+#include <isc/types.h>
+
+/***
+ *** Types
+ ***/
+struct isc_backtrace_symmap {
+ void *addr;
+ const char *symbol;
+};
+
+extern const int isc__backtrace_nsymbols;
+extern const isc_backtrace_symmap_t isc__backtrace_symtable[];
+
+/***
+ *** Functions
+ ***/
+
+ISC_LANG_BEGINDECLS
+isc_result_t
+isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes);
+/*%<
+ * Get a back trace of the running process above this function itself. On
+ * success, addrs[i] will store the address of the call point of the i-th
+ * stack frame (addrs[0] is the caller of this function). *nframes will store
+ * the total number of frames.
+ *
+ * Requires (note that these are not ensured by assertion checks, see above):
+ *
+ *\li 'addrs' is a valid array containing at least 'maxaddrs' void * entries.
+ *
+ *\li 'nframes' must be non NULL.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_FAILURE
+ *\li #ISC_R_NOTFOUND
+ *\li #ISC_R_NOTIMPLEMENTED
+ */
+
+isc_result_t
+isc_backtrace_getsymbolfromindex(int idx, const void **addrp,
+ const char **symbolp);
+/*%<
+ * Returns the content of the internal symbol table of the given index.
+ * On success, *addrsp and *symbolp point to the address and the symbol of
+ * the 'index'th entry of the table, respectively. If 'idx' is not in the
+ * range of the symbol table, ISC_R_RANGE will be returned.
+ *
+ * Requires
+ *
+ *\li 'addrp' must be non NULL && '*addrp' == NULL.
+ *
+ *\li 'symbolp' must be non NULL && '*symbolp' == NULL.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_RANGE
+ */
+
+isc_result_t
+isc_backtrace_getsymbol(const void *addr, const char **symbolp,
+ unsigned long *offsetp);
+/*%<
+ * Searches the internal symbol table for the symbol that most matches the
+ * given 'addr'. On success, '*symbolp' will point to the name of function
+ * to which the address 'addr' belong, and '*offsetp' will store the offset
+ * from the function's entry address to 'addr'.
+ *
+ * Requires (note that these are not ensured by assertion checks, see above):
+ *
+ *\li 'symbolp' must be non NULL && '*symbolp' == NULL.
+ *
+ *\li 'offsetp' must be non NULL.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_FAILURE
+ *\li #ISC_R_NOTFOUND
+ */
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_BACKTRACE_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/base32.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/base32.h
new file mode 100644
index 0000000..978a8db
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/base32.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2008 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: base32.h,v 1.3 2008/09/25 04:02:39 tbox Exp $ */
+
+#ifndef ISC_BASE32_H
+#define ISC_BASE32_H 1
+
+/*! \file */
+
+/*
+ * Routines for manipulating base 32 and base 32 hex encoded data.
+ * Based on RFC 4648.
+ *
+ * Base 32 hex preserves the sort order of data when it is encoded /
+ * decoded.
+ */
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+ISC_LANG_BEGINDECLS
+
+/***
+ *** Functions
+ ***/
+
+isc_result_t
+isc_base32_totext(isc_region_t *source, int wordlength,
+ const char *wordbreak, isc_buffer_t *target);
+isc_result_t
+isc_base32hex_totext(isc_region_t *source, int wordlength,
+ const char *wordbreak, isc_buffer_t *target);
+/*!<
+ * \brief Convert data into base32 encoded text.
+ *
+ * Notes:
+ *\li The base32 encoded text in 'target' will be divided into
+ * words of at most 'wordlength' characters, separated by
+ * the 'wordbreak' string. No parentheses will surround
+ * the text.
+ *
+ * Requires:
+ *\li 'source' is a region containing binary data
+ *\li 'target' is a text buffer containing available space
+ *\li 'wordbreak' points to a null-terminated string of
+ * zero or more whitespace characters
+ *
+ * Ensures:
+ *\li target will contain the base32 encoded version of the data
+ * in source. The 'used' pointer in target will be advanced as
+ * necessary.
+ */
+
+isc_result_t
+isc_base32_decodestring(const char *cstr, isc_buffer_t *target);
+isc_result_t
+isc_base32hex_decodestring(const char *cstr, isc_buffer_t *target);
+/*!<
+ * \brief Decode a null-terminated base32 string.
+ *
+ * Requires:
+ *\li 'cstr' is non-null.
+ *\li 'target' is a valid buffer.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS -- the entire decoded representation of 'cstring'
+ * fit in 'target'.
+ *\li #ISC_R_BADBASE32 -- 'cstr' is not a valid base32 encoding.
+ *
+ * Other error returns are any possible error code from:
+ *\li isc_lex_create(),
+ *\li isc_lex_openbuffer(),
+ *\li isc_base32_tobuffer().
+ */
+
+isc_result_t
+isc_base32_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length);
+isc_result_t
+isc_base32hex_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length);
+/*!<
+ * \brief Convert base32 encoded text from a lexer context into data.
+ *
+ * Requires:
+ *\li 'lex' is a valid lexer context
+ *\li 'target' is a buffer containing binary data
+ *\li 'length' is an integer
+ *
+ * Ensures:
+ *\li target will contain the data represented by the base32 encoded
+ * string parsed by the lexer. No more than length bytes will be read,
+ * if length is positive. The 'used' pointer in target will be
+ * advanced as necessary.
+ */
+
+isc_result_t
+isc_base32_decoderegion(isc_region_t *source, isc_buffer_t *target);
+isc_result_t
+isc_base32hex_decoderegion(isc_region_t *source, isc_buffer_t *target);
+/*!<
+ * \brief Decode a packed (no white space permitted) base32 region.
+ *
+ * Requires:
+ *\li 'source' is a valid region.
+ *\li 'target' is a valid buffer.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS -- the entire decoded representation of 'cstring'
+ * fit in 'target'.
+ *\li #ISC_R_BADBASE32 -- 'source' is not a valid base32 encoding.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_BASE32_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/base64.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/base64.h
new file mode 100644
index 0000000..e48ef2a
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/base64.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: base64.h,v 1.22 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_BASE64_H
+#define ISC_BASE64_H 1
+
+/*! \file isc/base64.h */
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+ISC_LANG_BEGINDECLS
+
+/***
+ *** Functions
+ ***/
+
+isc_result_t
+isc_base64_totext(isc_region_t *source, int wordlength,
+ const char *wordbreak, isc_buffer_t *target);
+/*!<
+ * \brief Convert data into base64 encoded text.
+ *
+ * Notes:
+ *\li The base64 encoded text in 'target' will be divided into
+ * words of at most 'wordlength' characters, separated by
+ * the 'wordbreak' string. No parentheses will surround
+ * the text.
+ *
+ * Requires:
+ *\li 'source' is a region containing binary data
+ *\li 'target' is a text buffer containing available space
+ *\li 'wordbreak' points to a null-terminated string of
+ * zero or more whitespace characters
+ *
+ * Ensures:
+ *\li target will contain the base64 encoded version of the data
+ * in source. The 'used' pointer in target will be advanced as
+ * necessary.
+ */
+
+isc_result_t
+isc_base64_decodestring(const char *cstr, isc_buffer_t *target);
+/*!<
+ * \brief Decode a null-terminated base64 string.
+ *
+ * Requires:
+ *\li 'cstr' is non-null.
+ *\li 'target' is a valid buffer.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS -- the entire decoded representation of 'cstring'
+ * fit in 'target'.
+ *\li #ISC_R_BADBASE64 -- 'cstr' is not a valid base64 encoding.
+ *
+ * Other error returns are any possible error code from:
+ *\li isc_lex_create(),
+ *\li isc_lex_openbuffer(),
+ *\li isc_base64_tobuffer().
+ */
+
+isc_result_t
+isc_base64_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length);
+/*!<
+ * \brief Convert base64 encoded text from a lexer context into data.
+ *
+ * Requires:
+ *\li 'lex' is a valid lexer context
+ *\li 'target' is a buffer containing binary data
+ *\li 'length' is an integer
+ *
+ * Ensures:
+ *\li target will contain the data represented by the base64 encoded
+ * string parsed by the lexer. No more than length bytes will be read,
+ * if length is positive. The 'used' pointer in target will be
+ * advanced as necessary.
+ */
+
+
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_BASE64_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/bind9.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/bind9.h
new file mode 100644
index 0000000..00bcb24
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/bind9.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: bind9.h,v 1.2 2009/12/05 23:31:41 each Exp $ */
+
+#ifndef ISC_BIND9_H
+#define ISC_BIND9_H 1
+
+/*
+ * This determines whether we are building BIND9 or using the exported
+ * libisc/libdns libraries. The version of this file included in the
+ * standard BIND9 build defines BIND9; the version included with the
+ * exportable libraries does not.
+ */
+#define BIND9 1
+
+#endif /* ISC_BIND9_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/bitstring.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/bitstring.h
new file mode 100644
index 0000000..252d111
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/bitstring.h
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: bitstring.h,v 1.14 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_BITSTRING_H
+#define ISC_BITSTRING_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file isc/bitstring.h
+ *
+ * \brief Bitstring manipulation functions.
+ *
+ * A bitstring is a packed array of bits, stored in a contiguous
+ * sequence of octets. The "most significant bit" (msb) of a bitstring
+ * is the high bit of the first octet. The "least significant bit" of a
+ * bitstring is the low bit of the last octet.
+ *
+ * Two bit numbering schemes are supported, "msb0" and "lsb0".
+ *
+ * In the "msb0" scheme, bit number 0 designates the most significant bit,
+ * and any padding bits required to make the bitstring a multiple of 8 bits
+ * long are added to the least significant end of the last octet.
+ *
+ * In the "lsb0" scheme, bit number 0 designates the least significant bit,
+ * and any padding bits required to make the bitstring a multiple of 8 bits
+ * long are added to the most significant end of the first octet.
+ *
+ * E.g., consider the bitstring "11010001111". This bitstring is 11 bits
+ * long and will take two octets. Let "p" denote a pad bit. In the msb0
+ * encoding, it would be
+ *
+ * \verbatim
+ * Octet 0 Octet 1
+ * |
+ * 1 1 0 1 0 0 0 1 | 1 1 1 p p p p p
+ * ^ | ^
+ * | |
+ * bit 0 bit 15
+ * \endverbatim
+ *
+ * In the lsb0 encoding, it would be
+ *
+ * \verbatim
+ * Octet 0 Octet 1
+ * |
+ * p p p p p 1 1 0 | 1 0 0 0 1 1 1 1
+ * ^ | ^
+ * | |
+ * bit 15 bit 0
+ * \endverbatim
+ */
+
+/***
+ *** Imports
+ ***/
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+ISC_LANG_BEGINDECLS
+
+/***
+ *** Types
+ ***/
+
+struct isc_bitstring {
+ unsigned int magic;
+ unsigned char * data;
+ unsigned int length;
+ unsigned int size;
+ isc_boolean_t lsb0;
+};
+
+/***
+ *** Functions
+ ***/
+
+void
+isc_bitstring_init(isc_bitstring_t *bitstring, unsigned char *data,
+ unsigned int length, unsigned int size, isc_boolean_t lsb0);
+/*!<
+ * \brief Make 'bitstring' refer to the bitstring of 'size' bits starting
+ * at 'data'. 'length' bits of the bitstring are valid. If 'lsb0'
+ * is set then, bit 0 refers to the least significant bit of the
+ * bitstring. Otherwise bit 0 is the most significant bit.
+ *
+ * Requires:
+ *
+ *\li 'bitstring' points to a isc_bitstring_t.
+ *
+ *\li 'data' points to an array of unsigned char large enough to hold
+ * 'size' bits.
+ *
+ *\li 'length' <= 'size'.
+ *
+ * Ensures:
+ *
+ *\li 'bitstring' is a valid bitstring.
+ */
+
+void
+isc_bitstring_invalidate(isc_bitstring_t *bitstring);
+/*!<
+ * \brief Invalidate 'bitstring'.
+ *
+ * Requires:
+ *
+ *\li 'bitstring' is a valid bitstring.
+ *
+ * Ensures:
+ *
+ *\li 'bitstring' is not a valid bitstring.
+ */
+
+void
+isc_bitstring_copy(isc_bitstring_t *source, unsigned int sbitpos,
+ isc_bitstring_t *target, unsigned int tbitpos,
+ unsigned int n);
+/*!<
+ * \brief Starting at bit 'sbitpos', copy 'n' bits from 'source' to
+ * the 'n' bits of 'target' starting at 'tbitpos'.
+ *
+ * Requires:
+ *
+ *\li 'source' and target are valid bitstrings with the same lsb0 setting.
+ *
+ *\li 'sbitpos' + 'n' is less than or equal to the length of 'source'.
+ *
+ *\li 'tbitpos' + 'n' is less than or equal to the size of 'target'.
+ *
+ * Ensures:
+ *
+ *\li The specified bits have been copied, and the length of 'target'
+ * adjusted (if required).
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_BITSTRING_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/boolean.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/boolean.h
new file mode 100644
index 0000000..348b096
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/boolean.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: boolean.h,v 1.19 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_BOOLEAN_H
+#define ISC_BOOLEAN_H 1
+
+/*! \file isc/boolean.h */
+
+typedef enum { isc_boolean_false = 0, isc_boolean_true = 1 } isc_boolean_t;
+
+#define ISC_FALSE isc_boolean_false
+#define ISC_TRUE isc_boolean_true
+#define ISC_TF(x) ((x) ? ISC_TRUE : ISC_FALSE)
+
+#endif /* ISC_BOOLEAN_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/buffer.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/buffer.h
new file mode 100644
index 0000000..ae7e4c3
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/buffer.h
@@ -0,0 +1,904 @@
+/*
+ * Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: buffer.h,v 1.55 2010/12/20 23:47:21 tbox Exp $ */
+
+#ifndef ISC_BUFFER_H
+#define ISC_BUFFER_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file isc/buffer.h
+ *
+ * \brief A buffer is a region of memory, together with a set of related subregions.
+ * Buffers are used for parsing and I/O operations.
+ *
+ * The 'used region' and the 'available' region are disjoint, and their
+ * union is the buffer's region. The used region extends from the beginning
+ * of the buffer region to the last used byte. The available region
+ * extends from one byte greater than the last used byte to the end of the
+ * buffer's region. The size of the used region can be changed using various
+ * buffer commands. Initially, the used region is empty.
+ *
+ * The used region is further subdivided into two disjoint regions: the
+ * 'consumed region' and the 'remaining region'. The union of these two
+ * regions is the used region. The consumed region extends from the beginning
+ * of the used region to the byte before the 'current' offset (if any). The
+ * 'remaining' region the current pointer to the end of the used
+ * region. The size of the consumed region can be changed using various
+ * buffer commands. Initially, the consumed region is empty.
+ *
+ * The 'active region' is an (optional) subregion of the remaining region.
+ * It extends from the current offset to an offset in the remaining region
+ * that is selected with isc_buffer_setactive(). Initially, the active region
+ * is empty. If the current offset advances beyond the chosen offset, the
+ * active region will also be empty.
+ *
+ * \verbatim
+ * /------------entire length---------------\
+ * /----- used region -----\/-- available --\
+ * +----------------------------------------+
+ * | consumed | remaining | |
+ * +----------------------------------------+
+ * a b c d e
+ *
+ * a == base of buffer.
+ * b == current pointer. Can be anywhere between a and d.
+ * c == active pointer. Meaningful between b and d.
+ * d == used pointer.
+ * e == length of buffer.
+ *
+ * a-e == entire length of buffer.
+ * a-d == used region.
+ * a-b == consumed region.
+ * b-d == remaining region.
+ * b-c == optional active region.
+ *\endverbatim
+ *
+ * The following invariants are maintained by all routines:
+ *
+ *\code
+ * length > 0
+ *
+ * base is a valid pointer to length bytes of memory
+ *
+ * 0 <= used <= length
+ *
+ * 0 <= current <= used
+ *
+ * 0 <= active <= used
+ * (although active < current implies empty active region)
+ *\endcode
+ *
+ * \li MP:
+ * Buffers have no synchronization. Clients must ensure exclusive
+ * access.
+ *
+ * \li Reliability:
+ * No anticipated impact.
+ *
+ * \li Resources:
+ * Memory: 1 pointer + 6 unsigned integers per buffer.
+ *
+ * \li Security:
+ * No anticipated impact.
+ *
+ * \li Standards:
+ * None.
+ */
+
+/***
+ *** Imports
+ ***/
+
+#include <isc/lang.h>
+#include <isc/magic.h>
+#include <isc/types.h>
+
+/*!
+ * To make many functions be inline macros (via \#define) define this.
+ * If it is undefined, a function will be used.
+ */
+/* #define ISC_BUFFER_USEINLINE */
+
+ISC_LANG_BEGINDECLS
+
+/*@{*/
+/*!
+ *** Magic numbers
+ ***/
+#define ISC_BUFFER_MAGIC 0x42756621U /* Buf!. */
+#define ISC_BUFFER_VALID(b) ISC_MAGIC_VALID(b, ISC_BUFFER_MAGIC)
+/*@}*/
+
+/*
+ * The following macros MUST be used only on valid buffers. It is the
+ * caller's responsibility to ensure this by using the ISC_BUFFER_VALID
+ * check above, or by calling another isc_buffer_*() function (rather than
+ * another macro.)
+ */
+
+/*@{*/
+/*!
+ * Fundamental buffer elements. (A through E in the introductory comment.)
+ */
+#define isc_buffer_base(b) ((void *)(b)->base) /*a*/
+#define isc_buffer_current(b) \
+ ((void *)((unsigned char *)(b)->base + (b)->current)) /*b*/
+#define isc_buffer_active(b) \
+ ((void *)((unsigned char *)(b)->base + (b)->active)) /*c*/
+#define isc_buffer_used(b) \
+ ((void *)((unsigned char *)(b)->base + (b)->used)) /*d*/
+#define isc_buffer_length(b) ((b)->length) /*e*/
+/*@}*/
+
+/*@{*/
+/*!
+ * Derived lengths. (Described in the introductory comment.)
+ */
+#define isc_buffer_usedlength(b) ((b)->used) /* d-a */
+#define isc_buffer_consumedlength(b) ((b)->current) /* b-a */
+#define isc_buffer_remaininglength(b) ((b)->used - (b)->current) /* d-b */
+#define isc_buffer_activelength(b) ((b)->active - (b)->current) /* c-b */
+#define isc_buffer_availablelength(b) ((b)->length - (b)->used) /* e-d */
+/*@}*/
+
+/*!
+ * Note that the buffer structure is public. This is principally so buffer
+ * operations can be implemented using macros. Applications are strongly
+ * discouraged from directly manipulating the structure.
+ */
+
+struct isc_buffer {
+ unsigned int magic;
+ void *base;
+ /*@{*/
+ /*! The following integers are byte offsets from 'base'. */
+ unsigned int length;
+ unsigned int used;
+ unsigned int current;
+ unsigned int active;
+ /*@}*/
+ /*! linkable */
+ ISC_LINK(isc_buffer_t) link;
+ /*! private internal elements */
+ isc_mem_t *mctx;
+};
+
+/***
+ *** Functions
+ ***/
+
+isc_result_t
+isc_buffer_allocate(isc_mem_t *mctx, isc_buffer_t **dynbuffer,
+ unsigned int length);
+/*!<
+ * \brief Allocate a dynamic linkable buffer which has "length" bytes in the
+ * data region.
+ *
+ * Requires:
+ *\li "mctx" is valid.
+ *
+ *\li "dynbuffer" is non-NULL, and "*dynbuffer" is NULL.
+ *
+ * Returns:
+ *\li ISC_R_SUCCESS - success
+ *\li ISC_R_NOMEMORY - no memory available
+ *
+ * Note:
+ *\li Changing the buffer's length field is not permitted.
+ */
+
+void
+isc_buffer_free(isc_buffer_t **dynbuffer);
+/*!<
+ * \brief Release resources allocated for a dynamic buffer.
+ *
+ * Requires:
+ *\li "dynbuffer" is not NULL.
+ *
+ *\li "*dynbuffer" is a valid dynamic buffer.
+ *
+ * Ensures:
+ *\li "*dynbuffer" will be NULL on return, and all memory associated with
+ * the dynamic buffer is returned to the memory context used in
+ * isc_buffer_allocate().
+ */
+
+void
+isc__buffer_init(isc_buffer_t *b, const void *base, unsigned int length);
+/*!<
+ * \brief Make 'b' refer to the 'length'-byte region starting at base.
+ *
+ * Requires:
+ *
+ *\li 'length' > 0
+ *
+ *\li 'base' is a pointer to a sequence of 'length' bytes.
+ *
+ */
+
+void
+isc__buffer_initnull(isc_buffer_t *b);
+/*!<
+ *\brief Initialize a buffer 'b' with a null data and zero length/
+ */
+
+void
+isc_buffer_reinit(isc_buffer_t *b, void *base, unsigned int length);
+/*!<
+ * \brief Make 'b' refer to the 'length'-byte region starting at base.
+ * Any existing data will be copied.
+ *
+ * Requires:
+ *
+ *\li 'length' > 0 AND length >= previous length
+ *
+ *\li 'base' is a pointer to a sequence of 'length' bytes.
+ *
+ */
+
+void
+isc__buffer_invalidate(isc_buffer_t *b);
+/*!<
+ * \brief Make 'b' an invalid buffer.
+ *
+ * Requires:
+ *\li 'b' is a valid buffer.
+ *
+ * Ensures:
+ *\li If assertion checking is enabled, future attempts to use 'b' without
+ * calling isc_buffer_init() on it will cause an assertion failure.
+ */
+
+void
+isc__buffer_region(isc_buffer_t *b, isc_region_t *r);
+/*!<
+ * \brief Make 'r' refer to the region of 'b'.
+ *
+ * Requires:
+ *
+ *\li 'b' is a valid buffer.
+ *
+ *\li 'r' points to a region structure.
+ */
+
+void
+isc__buffer_usedregion(isc_buffer_t *b, isc_region_t *r);
+/*!<
+ * \brief Make 'r' refer to the used region of 'b'.
+ *
+ * Requires:
+ *
+ *\li 'b' is a valid buffer.
+ *
+ *\li 'r' points to a region structure.
+ */
+
+void
+isc__buffer_availableregion(isc_buffer_t *b, isc_region_t *r);
+/*!<
+ * \brief Make 'r' refer to the available region of 'b'.
+ *
+ * Requires:
+ *
+ *\li 'b' is a valid buffer.
+ *
+ *\li 'r' points to a region structure.
+ */
+
+void
+isc__buffer_add(isc_buffer_t *b, unsigned int n);
+/*!<
+ * \brief Increase the 'used' region of 'b' by 'n' bytes.
+ *
+ * Requires:
+ *
+ *\li 'b' is a valid buffer
+ *
+ *\li used + n <= length
+ *
+ */
+
+void
+isc__buffer_subtract(isc_buffer_t *b, unsigned int n);
+/*!<
+ * \brief Decrease the 'used' region of 'b' by 'n' bytes.
+ *
+ * Requires:
+ *
+ *\li 'b' is a valid buffer
+ *
+ *\li used >= n
+ *
+ */
+
+void
+isc__buffer_clear(isc_buffer_t *b);
+/*!<
+ * \brief Make the used region empty.
+ *
+ * Requires:
+ *
+ *\li 'b' is a valid buffer
+ *
+ * Ensures:
+ *
+ *\li used = 0
+ *
+ */
+
+void
+isc__buffer_consumedregion(isc_buffer_t *b, isc_region_t *r);
+/*!<
+ * \brief Make 'r' refer to the consumed region of 'b'.
+ *
+ * Requires:
+ *
+ *\li 'b' is a valid buffer.
+ *
+ *\li 'r' points to a region structure.
+ */
+
+void
+isc__buffer_remainingregion(isc_buffer_t *b, isc_region_t *r);
+/*!<
+ * \brief Make 'r' refer to the remaining region of 'b'.
+ *
+ * Requires:
+ *
+ *\li 'b' is a valid buffer.
+ *
+ *\li 'r' points to a region structure.
+ */
+
+void
+isc__buffer_activeregion(isc_buffer_t *b, isc_region_t *r);
+/*!<
+ * \brief Make 'r' refer to the active region of 'b'.
+ *
+ * Requires:
+ *
+ *\li 'b' is a valid buffer.
+ *
+ *\li 'r' points to a region structure.
+ */
+
+void
+isc__buffer_setactive(isc_buffer_t *b, unsigned int n);
+/*!<
+ * \brief Sets the end of the active region 'n' bytes after current.
+ *
+ * Requires:
+ *
+ *\li 'b' is a valid buffer.
+ *
+ *\li current + n <= used
+ */
+
+void
+isc__buffer_first(isc_buffer_t *b);
+/*!<
+ * \brief Make the consumed region empty.
+ *
+ * Requires:
+ *
+ *\li 'b' is a valid buffer
+ *
+ * Ensures:
+ *
+ *\li current == 0
+ *
+ */
+
+void
+isc__buffer_forward(isc_buffer_t *b, unsigned int n);
+/*!<
+ * \brief Increase the 'consumed' region of 'b' by 'n' bytes.
+ *
+ * Requires:
+ *
+ *\li 'b' is a valid buffer
+ *
+ *\li current + n <= used
+ *
+ */
+
+void
+isc__buffer_back(isc_buffer_t *b, unsigned int n);
+/*!<
+ * \brief Decrease the 'consumed' region of 'b' by 'n' bytes.
+ *
+ * Requires:
+ *
+ *\li 'b' is a valid buffer
+ *
+ *\li n <= current
+ *
+ */
+
+void
+isc_buffer_compact(isc_buffer_t *b);
+/*!<
+ * \brief Compact the used region by moving the remaining region so it occurs
+ * at the start of the buffer. The used region is shrunk by the size of
+ * the consumed region, and the consumed region is then made empty.
+ *
+ * Requires:
+ *
+ *\li 'b' is a valid buffer
+ *
+ * Ensures:
+ *
+ *\li current == 0
+ *
+ *\li The size of the used region is now equal to the size of the remaining
+ * region (as it was before the call). The contents of the used region
+ * are those of the remaining region (as it was before the call).
+ */
+
+isc_uint8_t
+isc_buffer_getuint8(isc_buffer_t *b);
+/*!<
+ * \brief Read an unsigned 8-bit integer from 'b' and return it.
+ *
+ * Requires:
+ *
+ *\li 'b' is a valid buffer.
+ *
+ *\li The length of the available region of 'b' is at least 1.
+ *
+ * Ensures:
+ *
+ *\li The current pointer in 'b' is advanced by 1.
+ *
+ * Returns:
+ *
+ *\li A 8-bit unsigned integer.
+ */
+
+void
+isc__buffer_putuint8(isc_buffer_t *b, isc_uint8_t val);
+/*!<
+ * \brief Store an unsigned 8-bit integer from 'val' into 'b'.
+ *
+ * Requires:
+ *\li 'b' is a valid buffer.
+ *
+ *\li The length of the unused region of 'b' is at least 1.
+ *
+ * Ensures:
+ *\li The used pointer in 'b' is advanced by 1.
+ */
+
+isc_uint16_t
+isc_buffer_getuint16(isc_buffer_t *b);
+/*!<
+ * \brief Read an unsigned 16-bit integer in network byte order from 'b', convert
+ * it to host byte order, and return it.
+ *
+ * Requires:
+ *
+ *\li 'b' is a valid buffer.
+ *
+ *\li The length of the available region of 'b' is at least 2.
+ *
+ * Ensures:
+ *
+ *\li The current pointer in 'b' is advanced by 2.
+ *
+ * Returns:
+ *
+ *\li A 16-bit unsigned integer.
+ */
+
+void
+isc__buffer_putuint16(isc_buffer_t *b, isc_uint16_t val);
+/*!<
+ * \brief Store an unsigned 16-bit integer in host byte order from 'val'
+ * into 'b' in network byte order.
+ *
+ * Requires:
+ *\li 'b' is a valid buffer.
+ *
+ *\li The length of the unused region of 'b' is at least 2.
+ *
+ * Ensures:
+ *\li The used pointer in 'b' is advanced by 2.
+ */
+
+isc_uint32_t
+isc_buffer_getuint32(isc_buffer_t *b);
+/*!<
+ * \brief Read an unsigned 32-bit integer in network byte order from 'b', convert
+ * it to host byte order, and return it.
+ *
+ * Requires:
+ *
+ *\li 'b' is a valid buffer.
+ *
+ *\li The length of the available region of 'b' is at least 4.
+ *
+ * Ensures:
+ *
+ *\li The current pointer in 'b' is advanced by 4.
+ *
+ * Returns:
+ *
+ *\li A 32-bit unsigned integer.
+ */
+
+void
+isc__buffer_putuint32(isc_buffer_t *b, isc_uint32_t val);
+/*!<
+ * \brief Store an unsigned 32-bit integer in host byte order from 'val'
+ * into 'b' in network byte order.
+ *
+ * Requires:
+ *\li 'b' is a valid buffer.
+ *
+ *\li The length of the unused region of 'b' is at least 4.
+ *
+ * Ensures:
+ *\li The used pointer in 'b' is advanced by 4.
+ */
+
+isc_uint64_t
+isc_buffer_getuint48(isc_buffer_t *b);
+/*!<
+ * \brief Read an unsigned 48-bit integer in network byte order from 'b',
+ * convert it to host byte order, and return it.
+ *
+ * Requires:
+ *
+ *\li 'b' is a valid buffer.
+ *
+ *\li The length of the available region of 'b' is at least 6.
+ *
+ * Ensures:
+ *
+ *\li The current pointer in 'b' is advanced by 6.
+ *
+ * Returns:
+ *
+ *\li A 48-bit unsigned integer (stored in a 64-bit integer).
+ */
+
+void
+isc__buffer_putuint48(isc_buffer_t *b, isc_uint64_t val);
+/*!<
+ * \brief Store an unsigned 48-bit integer in host byte order from 'val'
+ * into 'b' in network byte order.
+ *
+ * Requires:
+ *\li 'b' is a valid buffer.
+ *
+ *\li The length of the unused region of 'b' is at least 6.
+ *
+ * Ensures:
+ *\li The used pointer in 'b' is advanced by 6.
+ */
+
+void
+isc__buffer_putuint24(isc_buffer_t *b, isc_uint32_t val);
+/*!<
+ * Store an unsigned 24-bit integer in host byte order from 'val'
+ * into 'b' in network byte order.
+ *
+ * Requires:
+ *\li 'b' is a valid buffer.
+ *
+ * The length of the unused region of 'b' is at least 3.
+ *
+ * Ensures:
+ *\li The used pointer in 'b' is advanced by 3.
+ */
+
+void
+isc__buffer_putmem(isc_buffer_t *b, const unsigned char *base,
+ unsigned int length);
+/*!<
+ * \brief Copy 'length' bytes of memory at 'base' into 'b'.
+ *
+ * Requires:
+ *\li 'b' is a valid buffer.
+ *
+ *\li 'base' points to 'length' bytes of valid memory.
+ *
+ */
+
+void
+isc__buffer_putstr(isc_buffer_t *b, const char *source);
+/*!<
+ * \brief Copy 'source' into 'b', not including terminating NUL.
+ *
+ * Requires:
+ *\li 'b' is a valid buffer.
+ *
+ *\li 'source' to be a valid NULL terminated string.
+ *
+ *\li strlen(source) <= isc_buffer_available(b)
+ */
+
+isc_result_t
+isc_buffer_copyregion(isc_buffer_t *b, const isc_region_t *r);
+/*!<
+ * \brief Copy the contents of 'r' into 'b'.
+ *
+ * Requires:
+ *\li 'b' is a valid buffer.
+ *
+ *\li 'r' is a valid region.
+ *
+ * Returns:
+ *
+ *\li ISC_R_SUCCESS
+ *\li ISC_R_NOSPACE The available region of 'b' is not
+ * big enough.
+ */
+
+ISC_LANG_ENDDECLS
+
+/*
+ * Inline macro versions of the functions. These should never be called
+ * directly by an application, but will be used by the functions within
+ * buffer.c. The callers should always use "isc_buffer_*()" names, never
+ * ones beginning with "isc__"
+ */
+
+/*! \note
+ * XXXDCL Something more could be done with initializing buffers that
+ * point to const data. For example, a new function, isc_buffer_initconst,
+ * could be used, and a new boolean flag in the buffer structure could
+ * indicate whether the buffer was initialized with that function.
+ * (isc_bufer_init itself would be reprototyped to *not* have its "base"
+ * parameter be const.) Then if the boolean were true, the isc_buffer_put*
+ * functions could assert a contractual requirement for a non-const buffer.
+ * One drawback is that the isc_buffer_* functions (macros) that return
+ * pointers would still need to return non-const pointers to avoid compiler
+ * warnings, so it would be up to code that uses them to have to deal
+ * with the possibility that the buffer was initialized as const --
+ * a problem that they *already* have to deal with but have absolutely
+ * no ability to. With a new isc_buffer_isconst() function returning
+ * true/false, they could at least assert a contractual requirement for
+ * non-const buffers when needed.
+ */
+#define ISC__BUFFER_INIT(_b, _base, _length) \
+ do { \
+ union { \
+ const void * konst; \
+ void * var; \
+ } _u; \
+ _u.konst = (_base); \
+ (_b)->base = _u.var; \
+ (_b)->length = (_length); \
+ (_b)->used = 0; \
+ (_b)->current = 0; \
+ (_b)->active = 0; \
+ (_b)->mctx = NULL; \
+ ISC_LINK_INIT(_b, link); \
+ (_b)->magic = ISC_BUFFER_MAGIC; \
+ } while (0)
+
+#define ISC__BUFFER_INITNULL(_b) ISC__BUFFER_INIT(_b, NULL, 0)
+
+#define ISC__BUFFER_INVALIDATE(_b) \
+ do { \
+ (_b)->magic = 0; \
+ (_b)->base = NULL; \
+ (_b)->length = 0; \
+ (_b)->used = 0; \
+ (_b)->current = 0; \
+ (_b)->active = 0; \
+ } while (0)
+
+#define ISC__BUFFER_REGION(_b, _r) \
+ do { \
+ (_r)->base = (_b)->base; \
+ (_r)->length = (_b)->length; \
+ } while (0)
+
+#define ISC__BUFFER_USEDREGION(_b, _r) \
+ do { \
+ (_r)->base = (_b)->base; \
+ (_r)->length = (_b)->used; \
+ } while (0)
+
+#define ISC__BUFFER_AVAILABLEREGION(_b, _r) \
+ do { \
+ (_r)->base = isc_buffer_used(_b); \
+ (_r)->length = isc_buffer_availablelength(_b); \
+ } while (0)
+
+#define ISC__BUFFER_ADD(_b, _n) \
+ do { \
+ (_b)->used += (_n); \
+ } while (0)
+
+#define ISC__BUFFER_SUBTRACT(_b, _n) \
+ do { \
+ (_b)->used -= (_n); \
+ if ((_b)->current > (_b)->used) \
+ (_b)->current = (_b)->used; \
+ if ((_b)->active > (_b)->used) \
+ (_b)->active = (_b)->used; \
+ } while (0)
+
+#define ISC__BUFFER_CLEAR(_b) \
+ do { \
+ (_b)->used = 0; \
+ (_b)->current = 0; \
+ (_b)->active = 0; \
+ } while (0)
+
+#define ISC__BUFFER_CONSUMEDREGION(_b, _r) \
+ do { \
+ (_r)->base = (_b)->base; \
+ (_r)->length = (_b)->current; \
+ } while (0)
+
+#define ISC__BUFFER_REMAININGREGION(_b, _r) \
+ do { \
+ (_r)->base = isc_buffer_current(_b); \
+ (_r)->length = isc_buffer_remaininglength(_b); \
+ } while (0)
+
+#define ISC__BUFFER_ACTIVEREGION(_b, _r) \
+ do { \
+ if ((_b)->current < (_b)->active) { \
+ (_r)->base = isc_buffer_current(_b); \
+ (_r)->length = isc_buffer_activelength(_b); \
+ } else { \
+ (_r)->base = NULL; \
+ (_r)->length = 0; \
+ } \
+ } while (0)
+
+#define ISC__BUFFER_SETACTIVE(_b, _n) \
+ do { \
+ (_b)->active = (_b)->current + (_n); \
+ } while (0)
+
+#define ISC__BUFFER_FIRST(_b) \
+ do { \
+ (_b)->current = 0; \
+ } while (0)
+
+#define ISC__BUFFER_FORWARD(_b, _n) \
+ do { \
+ (_b)->current += (_n); \
+ } while (0)
+
+#define ISC__BUFFER_BACK(_b, _n) \
+ do { \
+ (_b)->current -= (_n); \
+ } while (0)
+
+#define ISC__BUFFER_PUTMEM(_b, _base, _length) \
+ do { \
+ memcpy(isc_buffer_used(_b), (_base), (_length)); \
+ (_b)->used += (_length); \
+ } while (0)
+
+#define ISC__BUFFER_PUTSTR(_b, _source) \
+ do { \
+ unsigned int _length; \
+ unsigned char *_cp; \
+ _length = strlen(_source); \
+ _cp = isc_buffer_used(_b); \
+ memcpy(_cp, (_source), _length); \
+ (_b)->used += (_length); \
+ } while (0)
+
+#define ISC__BUFFER_PUTUINT8(_b, _val) \
+ do { \
+ unsigned char *_cp; \
+ isc_uint8_t _val2 = (_val); \
+ _cp = isc_buffer_used(_b); \
+ (_b)->used++; \
+ _cp[0] = _val2 & 0x00ff; \
+ } while (0)
+
+#define ISC__BUFFER_PUTUINT16(_b, _val) \
+ do { \
+ unsigned char *_cp; \
+ isc_uint16_t _val2 = (_val); \
+ _cp = isc_buffer_used(_b); \
+ (_b)->used += 2; \
+ _cp[0] = (unsigned char)((_val2 & 0xff00U) >> 8); \
+ _cp[1] = (unsigned char)(_val2 & 0x00ffU); \
+ } while (0)
+
+#define ISC__BUFFER_PUTUINT24(_b, _val) \
+ do { \
+ unsigned char *_cp; \
+ isc_uint32_t _val2 = (_val); \
+ _cp = isc_buffer_used(_b); \
+ (_b)->used += 3; \
+ _cp[0] = (unsigned char)((_val2 & 0xff0000U) >> 16); \
+ _cp[1] = (unsigned char)((_val2 & 0xff00U) >> 8); \
+ _cp[2] = (unsigned char)(_val2 & 0x00ffU); \
+ } while (0)
+
+#define ISC__BUFFER_PUTUINT32(_b, _val) \
+ do { \
+ unsigned char *_cp; \
+ isc_uint32_t _val2 = (_val); \
+ _cp = isc_buffer_used(_b); \
+ (_b)->used += 4; \
+ _cp[0] = (unsigned char)((_val2 & 0xff000000) >> 24); \
+ _cp[1] = (unsigned char)((_val2 & 0x00ff0000) >> 16); \
+ _cp[2] = (unsigned char)((_val2 & 0x0000ff00) >> 8); \
+ _cp[3] = (unsigned char)((_val2 & 0x000000ff)); \
+ } while (0)
+
+#if defined(ISC_BUFFER_USEINLINE)
+#define isc_buffer_init ISC__BUFFER_INIT
+#define isc_buffer_initnull ISC__BUFFER_INITNULL
+#define isc_buffer_invalidate ISC__BUFFER_INVALIDATE
+#define isc_buffer_region ISC__BUFFER_REGION
+#define isc_buffer_usedregion ISC__BUFFER_USEDREGION
+#define isc_buffer_availableregion ISC__BUFFER_AVAILABLEREGION
+#define isc_buffer_add ISC__BUFFER_ADD
+#define isc_buffer_subtract ISC__BUFFER_SUBTRACT
+#define isc_buffer_clear ISC__BUFFER_CLEAR
+#define isc_buffer_consumedregion ISC__BUFFER_CONSUMEDREGION
+#define isc_buffer_remainingregion ISC__BUFFER_REMAININGREGION
+#define isc_buffer_activeregion ISC__BUFFER_ACTIVEREGION
+#define isc_buffer_setactive ISC__BUFFER_SETACTIVE
+#define isc_buffer_first ISC__BUFFER_FIRST
+#define isc_buffer_forward ISC__BUFFER_FORWARD
+#define isc_buffer_back ISC__BUFFER_BACK
+#define isc_buffer_putmem ISC__BUFFER_PUTMEM
+#define isc_buffer_putstr ISC__BUFFER_PUTSTR
+#define isc_buffer_putuint8 ISC__BUFFER_PUTUINT8
+#define isc_buffer_putuint16 ISC__BUFFER_PUTUINT16
+#define isc_buffer_putuint24 ISC__BUFFER_PUTUINT24
+#define isc_buffer_putuint32 ISC__BUFFER_PUTUINT32
+#else
+#define isc_buffer_init isc__buffer_init
+#define isc_buffer_initnull isc__buffer_initnull
+#define isc_buffer_invalidate isc__buffer_invalidate
+#define isc_buffer_region isc__buffer_region
+#define isc_buffer_usedregion isc__buffer_usedregion
+#define isc_buffer_availableregion isc__buffer_availableregion
+#define isc_buffer_add isc__buffer_add
+#define isc_buffer_subtract isc__buffer_subtract
+#define isc_buffer_clear isc__buffer_clear
+#define isc_buffer_consumedregion isc__buffer_consumedregion
+#define isc_buffer_remainingregion isc__buffer_remainingregion
+#define isc_buffer_activeregion isc__buffer_activeregion
+#define isc_buffer_setactive isc__buffer_setactive
+#define isc_buffer_first isc__buffer_first
+#define isc_buffer_forward isc__buffer_forward
+#define isc_buffer_back isc__buffer_back
+#define isc_buffer_putmem isc__buffer_putmem
+#define isc_buffer_putstr isc__buffer_putstr
+#define isc_buffer_putuint8 isc__buffer_putuint8
+#define isc_buffer_putuint16 isc__buffer_putuint16
+#define isc_buffer_putuint24 isc__buffer_putuint24
+#define isc_buffer_putuint32 isc__buffer_putuint32
+#endif
+
+/*
+ * No inline method for this one (yet).
+ */
+#define isc_buffer_putuint48 isc__buffer_putuint48
+
+#endif /* ISC_BUFFER_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/bufferlist.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/bufferlist.h
new file mode 100644
index 0000000..54e00c7
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/bufferlist.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: bufferlist.h,v 1.17 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_BUFFERLIST_H
+#define ISC_BUFFERLIST_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file isc/bufferlist.h
+ *
+ *
+ *\brief Buffer lists have no synchronization. Clients must ensure exclusive
+ * access.
+ *
+ * \li Reliability:
+ * No anticipated impact.
+
+ * \li Security:
+ * No anticipated impact.
+ *
+ * \li Standards:
+ * None.
+ */
+
+/***
+ *** Imports
+ ***/
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+ISC_LANG_BEGINDECLS
+
+/***
+ *** Functions
+ ***/
+
+unsigned int
+isc_bufferlist_usedcount(isc_bufferlist_t *bl);
+/*!<
+ * \brief Return the length of the sum of all used regions of all buffers in
+ * the buffer list 'bl'
+ *
+ * Requires:
+ *
+ *\li 'bl' is not NULL.
+ *
+ * Returns:
+ *\li sum of all used regions' lengths.
+ */
+
+unsigned int
+isc_bufferlist_availablecount(isc_bufferlist_t *bl);
+/*!<
+ * \brief Return the length of the sum of all available regions of all buffers in
+ * the buffer list 'bl'
+ *
+ * Requires:
+ *
+ *\li 'bl' is not NULL.
+ *
+ * Returns:
+ *\li sum of all available regions' lengths.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_BUFFERLIST_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/commandline.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/commandline.h
new file mode 100644
index 0000000..384640a
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/commandline.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: commandline.h,v 1.16 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_COMMANDLINE_H
+#define ISC_COMMANDLINE_H 1
+
+/*! \file isc/commandline.h */
+
+#include <isc/boolean.h>
+#include <isc/lang.h>
+#include <isc/platform.h>
+
+/*% Index into parent argv vector. */
+LIBISC_EXTERNAL_DATA extern int isc_commandline_index;
+/*% Character checked for validity. */
+LIBISC_EXTERNAL_DATA extern int isc_commandline_option;
+/*% Argument associated with option. */
+LIBISC_EXTERNAL_DATA extern char *isc_commandline_argument;
+/*% For printing error messages. */
+LIBISC_EXTERNAL_DATA extern char *isc_commandline_progname;
+/*% Print error message. */
+LIBISC_EXTERNAL_DATA extern isc_boolean_t isc_commandline_errprint;
+/*% Reset getopt. */
+LIBISC_EXTERNAL_DATA extern isc_boolean_t isc_commandline_reset;
+
+ISC_LANG_BEGINDECLS
+
+/*% parse command line */
+int
+isc_commandline_parse(int argc, char * const *argv, const char *options);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_COMMANDLINE_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/entropy.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/entropy.h
new file mode 100644
index 0000000..d28f29a
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/entropy.h
@@ -0,0 +1,314 @@
+/*
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: entropy.h,v 1.35 2009/10/19 02:37:08 marka Exp $ */
+
+#ifndef ISC_ENTROPY_H
+#define ISC_ENTROPY_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file isc/entropy.h
+ * \brief The entropy API
+ *
+ * \li MP:
+ * The entropy object is locked internally. All callbacks into
+ * application-provided functions (for setup, gathering, and
+ * shutdown of sources) are guaranteed to be called with the
+ * entropy API lock held. This means these functions are
+ * not permitted to call back into the entropy API.
+ *
+ * \li Reliability:
+ * No anticipated impact.
+ *
+ * \li Resources:
+ * A buffer, used as an entropy pool.
+ *
+ * \li Security:
+ * While this code is believed to implement good entropy gathering
+ * and distribution, it has not been reviewed by a cryptographic
+ * expert.
+ * Since the added entropy is only as good as the sources used,
+ * this module could hand out bad data and never know it.
+ *
+ * \li Standards:
+ * None.
+ */
+
+/***
+ *** Imports
+ ***/
+
+#include <stdio.h>
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+/*@{*/
+/*% Entropy callback function. */
+typedef isc_result_t (*isc_entropystart_t)(isc_entropysource_t *source,
+ void *arg, isc_boolean_t blocking);
+typedef isc_result_t (*isc_entropyget_t)(isc_entropysource_t *source,
+ void *arg, isc_boolean_t blocking);
+typedef void (*isc_entropystop_t)(isc_entropysource_t *source, void *arg);
+/*@}*/
+
+/***
+ *** Flags.
+ ***/
+
+/*!
+ * \brief
+ * Extract only "good" data; return failure if there is not enough
+ * data available and there are no sources which we can poll to get
+ * data, or those sources are empty.
+ *
+ *
+ */
+#define ISC_ENTROPY_GOODONLY 0x00000001U
+/*!
+ * \brief
+ * Extract as much good data as possible, but if there isn't enough
+ * at hand, return what is available. This flag only makes sense
+ * when used with _GOODONLY.
+ */
+#define ISC_ENTROPY_PARTIAL 0x00000002U
+/*!
+ * \brief
+ * Block the task until data is available. This is contrary to the
+ * ISC task system, where tasks should never block. However, if
+ * this is a special purpose application where blocking a task is
+ * acceptable (say, an offline zone signer) this flag may be set.
+ * This flag only makes sense when used with _GOODONLY, and will
+ * block regardless of the setting for _PARTIAL.
+ */
+#define ISC_ENTROPY_BLOCKING 0x00000004U
+
+/*!
+ * \brief
+ * Estimate the amount of entropy contained in the sample pool.
+ * If this is not set, the source will be gathered and periodically
+ * mixed into the entropy pool, but no increment in contained entropy
+ * will be assumed. This flag only makes sense on sample sources.
+ */
+#define ISC_ENTROPYSOURCE_ESTIMATE 0x00000001U
+
+/*
+ * For use with isc_entropy_usebestsource().
+ */
+/*!
+ * \brief
+ * Use the keyboard as the only entropy source.
+ */
+#define ISC_ENTROPY_KEYBOARDYES 1
+/*!
+ * \brief
+ * Never use the keyboard as an entropy source.
+ */
+#define ISC_ENTROPY_KEYBOARDNO 2
+/*!
+ * \brief
+ * Use the keyboard as an entropy source only if opening the
+ * random device fails.
+ */
+#define ISC_ENTROPY_KEYBOARDMAYBE 3
+
+ISC_LANG_BEGINDECLS
+
+/***
+ *** Functions
+ ***/
+
+isc_result_t
+isc_entropy_create(isc_mem_t *mctx, isc_entropy_t **entp);
+/*!<
+ * \brief Create a new entropy object.
+ */
+
+void
+isc_entropy_attach(isc_entropy_t *ent, isc_entropy_t **entp);
+/*!<
+ * Attaches to an entropy object.
+ */
+
+void
+isc_entropy_detach(isc_entropy_t **entp);
+/*!<
+ * \brief Detaches from an entropy object.
+ */
+
+isc_result_t
+isc_entropy_createfilesource(isc_entropy_t *ent, const char *fname);
+/*!<
+ * \brief Create a new entropy source from a file.
+ *
+ * The file is assumed to contain good randomness, and will be mixed directly
+ * into the pool with every byte adding 8 bits of entropy.
+ *
+ * The file will be put into non-blocking mode, so it may be a device file,
+ * such as /dev/random. /dev/urandom should not be used here if it can
+ * be avoided, since it will always provide data even if it isn't good.
+ * We will make as much pseudorandom data as we need internally if our
+ * caller asks for it.
+ *
+ * If we hit end-of-file, we will stop reading from this source. Callers
+ * who require strong random data will get failure when our pool drains.
+ * The file will never be opened/read again once EOF is reached.
+ */
+
+void
+isc_entropy_destroysource(isc_entropysource_t **sourcep);
+/*!<
+ * \brief Removes an entropy source from the entropy system.
+ */
+
+isc_result_t
+isc_entropy_createsamplesource(isc_entropy_t *ent,
+ isc_entropysource_t **sourcep);
+/*!<
+ * \brief Create an entropy source that consists of samples. Each sample is
+ * added to the source via isc_entropy_addsamples(), below.
+ */
+
+isc_result_t
+isc_entropy_createcallbacksource(isc_entropy_t *ent,
+ isc_entropystart_t start,
+ isc_entropyget_t get,
+ isc_entropystop_t stop,
+ void *arg,
+ isc_entropysource_t **sourcep);
+/*!<
+ * \brief Create an entropy source that is polled via a callback.
+ *
+ * This would
+ * be used when keyboard input is used, or a GUI input method. It can
+ * also be used to hook in any external entropy source.
+ *
+ * Samples are added via isc_entropy_addcallbacksample(), below.
+ * _addcallbacksample() is the only function which may be called from
+ * within an entropy API callback function.
+ */
+
+void
+isc_entropy_stopcallbacksources(isc_entropy_t *ent);
+/*!<
+ * \brief Call the stop functions for callback sources that have had their
+ * start functions called.
+ */
+
+/*@{*/
+isc_result_t
+isc_entropy_addcallbacksample(isc_entropysource_t *source, isc_uint32_t sample,
+ isc_uint32_t extra);
+isc_result_t
+isc_entropy_addsample(isc_entropysource_t *source, isc_uint32_t sample,
+ isc_uint32_t extra);
+/*!<
+ * \brief Add a sample to the sample source.
+ *
+ * The sample MUST be a timestamp
+ * that increases over time, with the exception of wrap-around for
+ * extremely high resolution timers which will quickly wrap-around
+ * a 32-bit integer.
+ *
+ * The "extra" parameter is used only to add a bit more unpredictable
+ * data. It is not used other than included in the hash of samples.
+ *
+ * When in an entropy API callback function, _addcallbacksource() must be
+ * used. At all other times, _addsample() must be used.
+ */
+/*@}*/
+
+isc_result_t
+isc_entropy_getdata(isc_entropy_t *ent, void *data, unsigned int length,
+ unsigned int *returned, unsigned int flags);
+/*!<
+ * \brief Extract data from the entropy pool. This may load the pool from various
+ * sources.
+ *
+ * Do this by stiring the pool and returning a part of hash as randomness.
+ * Note that no secrets are given away here since parts of the hash are
+ * xored together before returned.
+ *
+ * Honor the request from the caller to only return good data, any data,
+ * etc.
+ */
+
+void
+isc_entropy_putdata(isc_entropy_t *ent, void *data, unsigned int length,
+ isc_uint32_t entropy);
+/*!<
+ * \brief Add "length" bytes in "data" to the entropy pool, incrementing the
+ * pool's entropy count by "entropy."
+ *
+ * These bytes will prime the pseudorandom portion even if no entropy is
+ * actually added.
+ */
+
+void
+isc_entropy_stats(isc_entropy_t *ent, FILE *out);
+/*!<
+ * \brief Dump some (trivial) stats to the stdio stream "out".
+ */
+
+unsigned int
+isc_entropy_status(isc_entropy_t *end);
+/*
+ * Returns the number of bits the pool currently contains. This is just
+ * an estimate.
+ */
+
+isc_result_t
+isc_entropy_usebestsource(isc_entropy_t *ectx, isc_entropysource_t **source,
+ const char *randomfile, int use_keyboard);
+/*!<
+ * \brief Use whatever source of entropy is best.
+ *
+ * Notes:
+ *\li If "randomfile" is not NULL, open it with
+ * isc_entropy_createfilesource().
+ *
+ *\li If "randomfile" is NULL and the system's random device was detected
+ * when the program was configured and built, open that device with
+ * isc_entropy_createfilesource().
+ *
+ *\li If "use_keyboard" is #ISC_ENTROPY_KEYBOARDYES, then always open
+ * the keyboard as an entropy source (possibly in addition to
+ * "randomfile" or the random device).
+ *
+ *\li If "use_keyboard" is #ISC_ENTROPY_KEYBOARDMAYBE, open the keyboard only
+ * if opening the random file/device fails. A message will be
+ * printed describing the need for keyboard input.
+ *
+ *\li If "use_keyboard" is #ISC_ENTROPY_KEYBOARDNO, the keyboard will
+ * never be opened.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS if at least one source of entropy could be started.
+ *
+ *\li #ISC_R_NOENTROPY if use_keyboard is #ISC_ENTROPY_KEYBOARDNO and
+ * there is no random device pathname compiled into the program.
+ *
+ *\li A return code from isc_entropy_createfilesource() or
+ * isc_entropy_createcallbacksource().
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_ENTROPY_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/error.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/error.h
new file mode 100644
index 0000000..e0cdfa8
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/error.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: error.h,v 1.22 2009/09/29 23:48:04 tbox Exp $ */
+
+#ifndef ISC_ERROR_H
+#define ISC_ERROR_H 1
+
+/*! \file isc/error.h */
+
+#include <stdarg.h>
+
+#include <isc/formatcheck.h>
+#include <isc/lang.h>
+#include <isc/platform.h>
+
+ISC_LANG_BEGINDECLS
+
+typedef void (*isc_errorcallback_t)(const char *, int, const char *, va_list);
+
+/*% set unexpected error */
+void
+isc_error_setunexpected(isc_errorcallback_t);
+
+/*% set fatal error */
+void
+isc_error_setfatal(isc_errorcallback_t);
+
+/*% unexpected error */
+void
+isc_error_unexpected(const char *, int, const char *, ...)
+ ISC_FORMAT_PRINTF(3, 4);
+
+/*% fatal error */
+ISC_PLATFORM_NORETURN_PRE void
+isc_error_fatal(const char *, int, const char *, ...)
+ISC_FORMAT_PRINTF(3, 4) ISC_PLATFORM_NORETURN_POST;
+
+/*% runtimecheck error */
+void
+isc_error_runtimecheck(const char *, int, const char *);
+
+#define ISC_ERROR_RUNTIMECHECK(cond) \
+ ((void) ((cond) || \
+ ((isc_error_runtimecheck)(__FILE__, __LINE__, #cond), 0)))
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_ERROR_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/event.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/event.h
new file mode 100644
index 0000000..68fabb2
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/event.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: event.h,v 1.34 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_EVENT_H
+#define ISC_EVENT_H 1
+
+/*! \file isc/event.h */
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+/*****
+ ***** Events.
+ *****/
+
+typedef void (*isc_eventdestructor_t)(isc_event_t *);
+
+#define ISC_EVENT_COMMON(ltype) \
+ size_t ev_size; \
+ unsigned int ev_attributes; \
+ void * ev_tag; \
+ isc_eventtype_t ev_type; \
+ isc_taskaction_t ev_action; \
+ void * ev_arg; \
+ void * ev_sender; \
+ isc_eventdestructor_t ev_destroy; \
+ void * ev_destroy_arg; \
+ ISC_LINK(ltype) ev_link
+
+/*%
+ * Attributes matching a mask of 0x000000ff are reserved for the task library's
+ * definition. Attributes of 0xffffff00 may be used by the application
+ * or non-ISC libraries.
+ */
+#define ISC_EVENTATTR_NOPURGE 0x00000001
+
+/*%
+ * The ISC_EVENTATTR_CANCELED attribute is intended to indicate
+ * that an event is delivered as a result of a canceled operation
+ * rather than successful completion, by mutual agreement
+ * between the sender and receiver. It is not set or used by
+ * the task system.
+ */
+#define ISC_EVENTATTR_CANCELED 0x00000002
+
+#define ISC_EVENT_INIT(event, sz, at, ta, ty, ac, ar, sn, df, da) \
+do { \
+ (event)->ev_size = (sz); \
+ (event)->ev_attributes = (at); \
+ (event)->ev_tag = (ta); \
+ (event)->ev_type = (ty); \
+ (event)->ev_action = (ac); \
+ (event)->ev_arg = (ar); \
+ (event)->ev_sender = (sn); \
+ (event)->ev_destroy = (df); \
+ (event)->ev_destroy_arg = (da); \
+ ISC_LINK_INIT((event), ev_link); \
+} while (0)
+
+/*%
+ * This structure is public because "subclassing" it may be useful when
+ * defining new event types.
+ */
+struct isc_event {
+ ISC_EVENT_COMMON(struct isc_event);
+};
+
+#define ISC_EVENTTYPE_FIRSTEVENT 0x00000000
+#define ISC_EVENTTYPE_LASTEVENT 0xffffffff
+
+#define ISC_EVENT_PTR(p) ((isc_event_t **)(void *)(p))
+
+ISC_LANG_BEGINDECLS
+
+isc_event_t *
+isc_event_allocate(isc_mem_t *mctx, void *sender, isc_eventtype_t type,
+ isc_taskaction_t action, const void *arg, size_t size);
+/*%<
+ * Allocate an event structure.
+ *
+ * Allocate and initialize in a structure with initial elements
+ * defined by:
+ *
+ * \code
+ * struct {
+ * ISC_EVENT_COMMON(struct isc_event);
+ * ...
+ * };
+ * \endcode
+ *
+ * Requires:
+ *\li 'size' >= sizeof(struct isc_event)
+ *\li 'action' to be non NULL
+ *
+ * Returns:
+ *\li a pointer to a initialized structure of the requested size.
+ *\li NULL if unable to allocate memory.
+ */
+
+void
+isc_event_free(isc_event_t **);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_EVENT_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/eventclass.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/eventclass.h
new file mode 100644
index 0000000..9e6c145
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/eventclass.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: eventclass.h,v 1.18 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_EVENTCLASS_H
+#define ISC_EVENTCLASS_H 1
+
+/*! \file isc/eventclass.h
+ ***** Registry of Predefined Event Type Classes
+ *****/
+
+/*%
+ * An event class is an unsigned 16 bit number. Each class may contain up
+ * to 65536 events. An event type is formed by adding the event number
+ * within the class to the class number.
+ *
+ */
+
+#define ISC_EVENTCLASS(eclass) ((eclass) << 16)
+
+/*@{*/
+/*!
+ * Classes < 1024 are reserved for ISC use.
+ * Event classes >= 1024 and <= 65535 are reserved for application use.
+ */
+
+#define ISC_EVENTCLASS_TASK ISC_EVENTCLASS(0)
+#define ISC_EVENTCLASS_TIMER ISC_EVENTCLASS(1)
+#define ISC_EVENTCLASS_SOCKET ISC_EVENTCLASS(2)
+#define ISC_EVENTCLASS_FILE ISC_EVENTCLASS(3)
+#define ISC_EVENTCLASS_DNS ISC_EVENTCLASS(4)
+#define ISC_EVENTCLASS_APP ISC_EVENTCLASS(5)
+#define ISC_EVENTCLASS_OMAPI ISC_EVENTCLASS(6)
+#define ISC_EVENTCLASS_RATELIMITER ISC_EVENTCLASS(7)
+#define ISC_EVENTCLASS_ISCCC ISC_EVENTCLASS(8)
+/*@}*/
+
+#endif /* ISC_EVENTCLASS_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/file.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/file.h
new file mode 100644
index 0000000..5db506a
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/file.h
@@ -0,0 +1,304 @@
+/*
+ * Copyright (C) 2004-2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+#ifndef ISC_FILE_H
+#define ISC_FILE_H 1
+
+/*! \file isc/file.h */
+
+#include <stdio.h>
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+ISC_LANG_BEGINDECLS
+
+isc_result_t
+isc_file_settime(const char *file, isc_time_t *itime);
+
+isc_result_t
+isc_file_getmodtime(const char *file, isc_time_t *itime);
+/*!<
+ * \brief Get the time of last modification of a file.
+ *
+ * Notes:
+ *\li The time that is set is relative to the (OS-specific) epoch, as are
+ * all isc_time_t structures.
+ *
+ * Requires:
+ *\li file != NULL.
+ *\li time != NULL.
+ *
+ * Ensures:
+ *\li If the file could not be accessed, 'time' is unchanged.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ * Success.
+ *\li #ISC_R_NOTFOUND
+ * No such file exists.
+ *\li #ISC_R_INVALIDFILE
+ * The path specified was not usable by the operating system.
+ *\li #ISC_R_NOPERM
+ * The file's metainformation could not be retrieved because
+ * permission was denied to some part of the file's path.
+ *\li #ISC_R_EIO
+ * Hardware error interacting with the filesystem.
+ *\li #ISC_R_UNEXPECTED
+ * Something totally unexpected happened.
+ *
+ */
+
+isc_result_t
+isc_file_mktemplate(const char *path, char *buf, size_t buflen);
+/*!<
+ * \brief Generate a template string suitable for use with isc_file_openunique().
+ *
+ * Notes:
+ *\li This function is intended to make creating temporary files
+ * portable between different operating systems.
+ *
+ *\li The path is prepended to an implementation-defined string and
+ * placed into buf. The string has no path characters in it,
+ * and its maximum length is 14 characters plus a NUL. Thus
+ * buflen should be at least strlen(path) + 15 characters or
+ * an error will be returned.
+ *
+ * Requires:
+ *\li buf != NULL.
+ *
+ * Ensures:
+ *\li If result == #ISC_R_SUCCESS:
+ * buf contains a string suitable for use as the template argument
+ * to isc_file_openunique().
+ *
+ *\li If result != #ISC_R_SUCCESS:
+ * buf is unchanged.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS Success.
+ *\li #ISC_R_NOSPACE buflen indicates buf is too small for the catenation
+ * of the path with the internal template string.
+ */
+
+
+isc_result_t
+isc_file_openunique(char *templet, FILE **fp);
+isc_result_t
+isc_file_openuniqueprivate(char *templet, FILE **fp);
+isc_result_t
+isc_file_openuniquemode(char *templet, int mode, FILE **fp);
+/*!<
+ * \brief Create and open a file with a unique name based on 'templet'.
+ *
+ * Notes:
+ *\li 'template' is a reserved work in C++. If you want to complain
+ * about the spelling of 'templet', first look it up in the
+ * Merriam-Webster English dictionary. (http://www.m-w.com/)
+ *
+ *\li This function works by using the template to generate file names.
+ * The template must be a writable string, as it is modified in place.
+ * Trailing X characters in the file name (full file name on Unix,
+ * basename on Win32 -- eg, tmp-XXXXXX vs XXXXXX.tmp, respectively)
+ * are replaced with ASCII characters until a non-existent filename
+ * is found. If the template does not include pathname information,
+ * the files in the working directory of the program are searched.
+ *
+ *\li isc_file_mktemplate is a good, portable way to get a template.
+ *
+ * Requires:
+ *\li 'fp' is non-NULL and '*fp' is NULL.
+ *
+ *\li 'template' is non-NULL, and of a form suitable for use by
+ * the system as described above.
+ *
+ * Ensures:
+ *\li If result is #ISC_R_SUCCESS:
+ * *fp points to an stream opening in stdio's "w+" mode.
+ *
+ *\li If result is not #ISC_R_SUCCESS:
+ * *fp is NULL.
+ *
+ * No file is open. Even if one was created (but unable
+ * to be reopened as a stdio FILE pointer) then it has been
+ * removed.
+ *
+ *\li This function does *not* ensure that the template string has not been
+ * modified, even if the operation was unsuccessful.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ * Success.
+ *\li #ISC_R_EXISTS
+ * No file with a unique name could be created based on the
+ * template.
+ *\li #ISC_R_INVALIDFILE
+ * The path specified was not usable by the operating system.
+ *\li #ISC_R_NOPERM
+ * The file could not be created because permission was denied
+ * to some part of the file's path.
+ *\li #ISC_R_IOERROR
+ * Hardware error interacting with the filesystem.
+ *\li #ISC_R_UNEXPECTED
+ * Something totally unexpected happened.
+ */
+
+isc_result_t
+isc_file_remove(const char *filename);
+/*!<
+ * \brief Remove the file named by 'filename'.
+ */
+
+isc_result_t
+isc_file_rename(const char *oldname, const char *newname);
+/*!<
+ * \brief Rename the file 'oldname' to 'newname'.
+ */
+
+isc_boolean_t
+isc_file_exists(const char *pathname);
+/*!<
+ * \brief Return #ISC_TRUE if the calling process can tell that the given file exists.
+ * Will not return true if the calling process has insufficient privileges
+ * to search the entire path.
+ */
+
+isc_boolean_t
+isc_file_isabsolute(const char *filename);
+/*!<
+ * \brief Return #ISC_TRUE if the given file name is absolute.
+ */
+
+isc_result_t
+isc_file_isplainfile(const char *name);
+/*!<
+ * \brief Check that the file is a plain file
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ * Success. The file is a plain file.
+ *\li #ISC_R_INVALIDFILE
+ * The path specified was not usable by the operating system.
+ *\li #ISC_R_FILENOTFOUND
+ * The file does not exist. This return code comes from
+ * errno=ENOENT when stat returns -1. This code is mentioned
+ * here, because in logconf.c, it is the one rcode that is
+ * permitted in addition to ISC_R_SUCCESS. This is done since
+ * the next call in logconf.c is to isc_stdio_open(), which
+ * will create the file if it can.
+ *\li #other ISC_R_* errors translated from errno
+ * These occur when stat returns -1 and an errno.
+ */
+
+isc_boolean_t
+isc_file_iscurrentdir(const char *filename);
+/*!<
+ * \brief Return #ISC_TRUE if the given file name is the current directory (".").
+ */
+
+isc_boolean_t
+isc_file_ischdiridempotent(const char *filename);
+/*%<
+ * Return #ISC_TRUE if calling chdir(filename) multiple times will give
+ * the same result as calling it once.
+ */
+
+const char *
+isc_file_basename(const char *filename);
+/*%<
+ * Return the final component of the path in the file name.
+ */
+
+isc_result_t
+isc_file_progname(const char *filename, char *buf, size_t buflen);
+/*!<
+ * \brief Given an operating system specific file name "filename"
+ * referring to a program, return the canonical program name.
+ *
+ *
+ * Any directory prefix or executable file name extension (if
+ * used on the OS in case) is stripped. On systems where program
+ * names are case insensitive, the name is canonicalized to all
+ * lower case. The name is written to 'buf', an array of 'buflen'
+ * chars, and null terminated.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOSPACE The name did not fit in 'buf'.
+ */
+
+isc_result_t
+isc_file_template(const char *path, const char *templet, char *buf,
+ size_t buflen);
+/*%<
+ * Create an OS specific template using 'path' to define the directory
+ * 'templet' to describe the filename and store the result in 'buf'
+ * such that path can be renamed to buf atomically.
+ */
+
+isc_result_t
+isc_file_renameunique(const char *file, char *templet);
+/*%<
+ * Rename 'file' using 'templet' as a template for the new file name.
+ */
+
+isc_result_t
+isc_file_absolutepath(const char *filename, char *path, size_t pathlen);
+/*%<
+ * Given a file name, return the fully qualified path to the file.
+ */
+
+/*
+ * XXX We should also have a isc_file_writeeopen() function
+ * for safely open a file in a publicly writable directory
+ * (see write_open() in BIND 8's ns_config.c).
+ */
+
+isc_result_t
+isc_file_truncate(const char *filename, isc_offset_t size);
+/*%<
+ * Truncate/extend the file specified to 'size' bytes.
+ */
+
+isc_result_t
+isc_file_safecreate(const char *filename, FILE **fp);
+/*%<
+ * Open 'filename' for writing, truncating if necessary. Ensure that
+ * if it existed it was a normal file. If creating the file, ensure
+ * that only the owner can read/write it.
+ */
+
+isc_result_t
+isc_file_splitpath(isc_mem_t *mctx, char *path,
+ char **dirname, char **basename);
+/*%<
+ * Split a path into dirname and basename. If 'path' contains no slash
+ * (or, on windows, backslash), then '*dirname' is set to ".".
+ *
+ * Allocates memory for '*dirname', which can be freed with isc_mem_free().
+ *
+ * Returns:
+ * - ISC_R_SUCCESS on success
+ * - ISC_R_INVALIDFILE if 'path' is empty or ends with '/'
+ * - ISC_R_NOMEMORY if unable to allocate memory
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_FILE_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/formatcheck.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/formatcheck.h
new file mode 100644
index 0000000..51ce3ca
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/formatcheck.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: formatcheck.h,v 1.13 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_FORMATCHECK_H
+#define ISC_FORMATCHECK_H 1
+
+/*! \file isc/formatcheck.h */
+
+/*%
+ * ISC_FORMAT_PRINTF().
+ *
+ * \li fmt is the location of the format string parameter.
+ * \li args is the location of the first argument (or 0 for no argument checking).
+ *
+ * Note:
+ * \li The first parameter is 1, not 0.
+ */
+#ifdef __GNUC__
+#define ISC_FORMAT_PRINTF(fmt, args) __attribute__((__format__(__printf__, fmt, args)))
+#else
+#define ISC_FORMAT_PRINTF(fmt, args)
+#endif
+
+#endif /* ISC_FORMATCHECK_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/fsaccess.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/fsaccess.h
new file mode 100644
index 0000000..7962bbe
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/fsaccess.h
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: fsaccess.h,v 1.16 2009/01/17 23:47:43 tbox Exp $ */
+
+#ifndef ISC_FSACCESS_H
+#define ISC_FSACCESS_H 1
+
+/*! \file isc/fsaccess.h
+ * \brief The ISC filesystem access module encapsulates the setting of file
+ * and directory access permissions into one API that is meant to be
+ * portable to multiple operating systems.
+ *
+ * The two primary operating system flavors that are initially accommodated
+ * are POSIX and Windows NT 4.0 and later. The Windows NT access model is
+ * considerable more flexible than POSIX's model (as much as I am loathe to
+ * admit it), and so the ISC API has a higher degree of complexity than would
+ * be needed to simply address POSIX's needs.
+ *
+ * The full breadth of NT's flexibility is not available either, for the
+ * present time. Much of it is to provide compatibility with what Unix
+ * programmers are expecting. This is also due to not yet really needing all
+ * of the functionality of an NT system (or, for that matter, a POSIX system)
+ * in BIND9, and so resolving how to handle the various incompatibilities has
+ * been a purely theoretical exercise with no operational experience to
+ * indicate how flawed the thinking may be.
+ *
+ * Some of the more notable dumbing down of NT for this API includes:
+ *
+ *\li Each of FILE_READ_DATA and FILE_READ_EA are set with #ISC_FSACCESS_READ.
+ *
+ * \li All of FILE_WRITE_DATA, FILE_WRITE_EA and FILE_APPEND_DATA are
+ * set with #ISC_FSACCESS_WRITE. FILE_WRITE_ATTRIBUTES is not set
+ * so as to be consistent with Unix, where only the owner of the file
+ * or the superuser can change the attributes/mode of a file.
+ *
+ * \li Both of FILE_ADD_FILE and FILE_ADD_SUBDIRECTORY are set with
+ * #ISC_FSACCESS_CREATECHILD. This is similar to setting the WRITE
+ * permission on a Unix directory.
+ *
+ * \li SYNCHRONIZE is always set for files and directories, unless someone
+ * can give me a reason why this is a bad idea.
+ *
+ * \li READ_CONTROL and FILE_READ_ATTRIBUTES are always set; this is
+ * consistent with Unix, where any file or directory can be stat()'d
+ * unless the directory path disallows complete access somewhere along
+ * the way.
+ *
+ * \li WRITE_DAC is only set for the owner. This too is consistent with
+ * Unix, and is tighter security than allowing anyone else to be
+ * able to set permissions.
+ *
+ * \li DELETE is only set for the owner. On Unix the ability to delete
+ * a file is controlled by the directory permissions, but it isn't
+ * currently clear to me what happens on NT if the directory has
+ * FILE_DELETE_CHILD set but a file within it does not have DELETE
+ * set. Always setting DELETE on the file/directory for the owner
+ * gives maximum flexibility to the owner without exposing the
+ * file to deletion by others.
+ *
+ * \li WRITE_OWNER is never set. This too is consistent with Unix,
+ * and is also tighter security than allowing anyone to change the
+ * ownership of the file apart from the superu..ahem, Administrator.
+ *
+ * \li Inheritance is set to NO_INHERITANCE.
+ *
+ * Unix's dumbing down includes:
+ *
+ * \li The sticky bit cannot be set.
+ *
+ * \li setuid and setgid cannot be set.
+ *
+ * \li Only regular files and directories can be set.
+ *
+ * The rest of this comment discusses a few of the incompatibilities
+ * between the two systems that need more thought if this API is to
+ * be extended to accommodate them.
+ *
+ * The Windows standard access right "DELETE" doesn't have a direct
+ * equivalent in the Unix world, so it isn't clear what should be done
+ * with it.
+ *
+ * The Unix sticky bit is not supported. While NT does have a concept
+ * of allowing users to create files in a directory but not delete or
+ * rename them, it does not have a concept of allowing them to be deleted
+ * if they are owned by the user trying to delete/rename. While it is
+ * probable that something could be cobbled together in NT 5 with inheritance,
+ * it can't really be done in NT 4 as a single property that you could
+ * set on a directory. You'd need to coordinate something with file creation
+ * so that every file created had DELETE set for the owner but noone else.
+ *
+ * On Unix systems, setting #ISC_FSACCESS_LISTDIRECTORY sets READ.
+ * ... setting either #ISC_FSACCESS_CREATECHILD or #ISC_FSACCESS_DELETECHILD
+ * sets WRITE.
+ * ... setting #ISC_FSACCESS_ACCESSCHILD sets EXECUTE.
+ *
+ * On NT systems, setting #ISC_FSACCESS_LISTDIRECTORY sets FILE_LIST_DIRECTORY.
+ * ... setting #ISC_FSACCESS_CREATECHILD sets FILE_CREATE_CHILD independently.
+ * ... setting #ISC_FSACCESS_DELETECHILD sets FILE_DELETE_CHILD independently.
+ * ... setting #ISC_FSACCESS_ACCESSCHILD sets FILE_TRAVERSE.
+ *
+ * Unresolved: XXXDCL
+ * \li What NT access right controls the ability to rename a file?
+ * \li How does DELETE work? If a directory has FILE_DELETE_CHILD but a
+ * file or directory within it does not have DELETE, is that file
+ * or directory deletable?
+ * \li To implement isc_fsaccess_get(), mapping an existing Unix permission
+ * mode_t back to an isc_fsaccess_t is pretty trivial; however, mapping
+ * an NT DACL could be impossible to do in a responsible way.
+ * \li Similarly, trying to implement the functionality of being able to
+ * say "add group writability to whatever permissions already exist"
+ * could be tricky on NT because of the order-of-entry issue combined
+ * with possibly having one or more matching ACEs already explicitly
+ * granting or denying access. Because this functionality is
+ * not yet needed by the ISC, no code has been written to try to
+ * solve this problem.
+ */
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+/*
+ * Trustees.
+ */
+#define ISC_FSACCESS_OWNER 0x1 /*%< User account. */
+#define ISC_FSACCESS_GROUP 0x2 /*%< Primary group owner. */
+#define ISC_FSACCESS_OTHER 0x4 /*%< Not the owner or the group owner. */
+#define ISC_FSACCESS_WORLD 0x7 /*%< User, Group, Other. */
+
+/*
+ * Types of permission.
+ */
+#define ISC_FSACCESS_READ 0x00000001 /*%< File only. */
+#define ISC_FSACCESS_WRITE 0x00000002 /*%< File only. */
+#define ISC_FSACCESS_EXECUTE 0x00000004 /*%< File only. */
+#define ISC_FSACCESS_CREATECHILD 0x00000008 /*%< Dir only. */
+#define ISC_FSACCESS_DELETECHILD 0x00000010 /*%< Dir only. */
+#define ISC_FSACCESS_LISTDIRECTORY 0x00000020 /*%< Dir only. */
+#define ISC_FSACCESS_ACCESSCHILD 0x00000040 /*%< Dir only. */
+
+/*%
+ * Adding any permission bits beyond 0x200 would mean typedef'ing
+ * isc_fsaccess_t as isc_uint64_t, and redefining this value to
+ * reflect the new range of permission types, Probably to 21 for
+ * maximum flexibility. The number of bits has to accommodate all of
+ * the permission types, and three full sets of them have to fit
+ * within an isc_fsaccess_t.
+ */
+#define ISC__FSACCESS_PERMISSIONBITS 10
+
+ISC_LANG_BEGINDECLS
+
+void
+isc_fsaccess_add(int trustee, int permission, isc_fsaccess_t *access);
+
+void
+isc_fsaccess_remove(int trustee, int permission, isc_fsaccess_t *access);
+
+isc_result_t
+isc_fsaccess_set(const char *path, isc_fsaccess_t access);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_FSACCESS_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/hash.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/hash.h
new file mode 100644
index 0000000..ca04b4e
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/hash.h
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: hash.h,v 1.12 2009/01/17 23:47:43 tbox Exp $ */
+
+#ifndef ISC_HASH_H
+#define ISC_HASH_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file isc/hash.h
+ *
+ * \brief The hash API
+ * provides an unpredictable hash value for variable length data.
+ * A hash object contains a random vector (which is hidden from clients
+ * of this API) to make the actual hash value unpredictable.
+ *
+ * The algorithm used in the API guarantees the probability of hash
+ * collision; in the current implementation, as long as the values stored
+ * in the random vector are unpredictable, the probability of hash
+ * collision between arbitrary two different values is at most 1/2^16.
+ *
+ * Although the API is generic about the hash keys, it mainly expects
+ * DNS names (and sometimes IPv4/v6 addresses) as inputs. It has an
+ * upper limit of the input length, and may run slow to calculate the
+ * hash values for large inputs.
+ *
+ * This API is designed to be general so that it can provide multiple
+ * different hash contexts that have different random vectors. However,
+ * it should be typical to have a single context for an entire system.
+ * To support such cases, the API also provides a single-context mode.
+ *
+ * \li MP:
+ * The hash object is almost read-only. Once the internal random vector
+ * is initialized, no write operation will occur, and there will be no
+ * need to lock the object to calculate actual hash values.
+ *
+ * \li Reliability:
+ * In some cases this module uses low-level data copy to initialize the
+ * random vector. Errors in this part are likely to crash the server or
+ * corrupt memory.
+ *
+ * \li Resources:
+ * A buffer, used as a random vector for calculating hash values.
+ *
+ * \li Security:
+ * This module intends to provide unpredictable hash values in
+ * adversarial environments in order to avoid denial of service attacks
+ * to hash buckets.
+ * Its unpredictability relies on the quality of entropy to build the
+ * random vector.
+ *
+ * \li Standards:
+ * None.
+ */
+
+/***
+ *** Imports
+ ***/
+
+#include <isc/types.h>
+
+/***
+ *** Functions
+ ***/
+ISC_LANG_BEGINDECLS
+
+isc_result_t
+isc_hash_ctxcreate(isc_mem_t *mctx, isc_entropy_t *entropy, unsigned int limit,
+ isc_hash_t **hctx);
+isc_result_t
+isc_hash_create(isc_mem_t *mctx, isc_entropy_t *entropy, size_t limit);
+/*!<
+ * \brief Create a new hash object.
+ *
+ * isc_hash_ctxcreate() creates a different object.
+ *
+ * isc_hash_create() creates a module-internal object to support the
+ * single-context mode. It should be called only once.
+ *
+ * 'entropy' must be NULL or a valid entropy object. If 'entropy' is NULL,
+ * pseudo random values will be used to build the random vector, which may
+ * weaken security.
+ *
+ * 'limit' specifies the maximum number of hash keys. If it is too large,
+ * these functions may fail.
+ */
+
+void
+isc_hash_ctxattach(isc_hash_t *hctx, isc_hash_t **hctxp);
+/*!<
+ * \brief Attach to a hash object.
+ *
+ * This function is only necessary for the multiple-context mode.
+ */
+
+void
+isc_hash_ctxdetach(isc_hash_t **hctxp);
+/*!<
+ * \brief Detach from a hash object.
+ *
+ * This function is for the multiple-context mode, and takes a valid
+ * hash object as an argument.
+ */
+
+void
+isc_hash_destroy(void);
+/*!<
+ * \brief This function is for the single-context mode, and is expected to be used
+ * as a counterpart of isc_hash_create().
+ *
+ * A valid module-internal hash object must have been created, and this
+ * function should be called only once.
+ */
+
+/*@{*/
+void
+isc_hash_ctxinit(isc_hash_t *hctx);
+void
+isc_hash_init(void);
+/*!<
+ * \brief Initialize a hash object.
+ *
+ * It fills in the random vector with a proper
+ * source of entropy, which is typically from the entropy object specified
+ * at the creation. Thus, it is desirable to call these functions after
+ * initializing the entropy object with some good entropy sources.
+ *
+ * These functions should be called before the first hash calculation.
+ *
+ * isc_hash_ctxinit() is for the multiple-context mode, and takes a valid hash
+ * object as an argument.
+ *
+ * isc_hash_init() is for the single-context mode. A valid module-internal
+ * hash object must have been created, and this function should be called only
+ * once.
+ */
+/*@}*/
+
+/*@{*/
+unsigned int
+isc_hash_ctxcalc(isc_hash_t *hctx, const unsigned char *key,
+ unsigned int keylen, isc_boolean_t case_sensitive);
+unsigned int
+isc_hash_calc(const unsigned char *key, unsigned int keylen,
+ isc_boolean_t case_sensitive);
+/*!<
+ * \brief Calculate a hash value.
+ *
+ * isc_hash_ctxinit() is for the multiple-context mode, and takes a valid hash
+ * object as an argument.
+ *
+ * isc_hash_init() is for the single-context mode. A valid module-internal
+ * hash object must have been created.
+ *
+ * 'key' is the hash key, which is a variable length buffer.
+ *
+ * 'keylen' specifies the key length, which must not be larger than the limit
+ * specified for the corresponding hash object.
+ *
+ * 'case_sensitive' specifies whether the hash key should be treated as
+ * case_sensitive values. It should typically be ISC_FALSE if the hash key
+ * is a DNS name.
+ */
+/*@}*/
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_HASH_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/heap.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/heap.h
new file mode 100644
index 0000000..77bf07c
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/heap.h
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1997-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: heap.h,v 1.26 2009/01/17 23:47:43 tbox Exp $ */
+
+#ifndef ISC_HEAP_H
+#define ISC_HEAP_H 1
+
+/*! \file isc/heap.h */
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+ISC_LANG_BEGINDECLS
+
+/*%
+ * The comparison function returns ISC_TRUE if the first argument has
+ * higher priority than the second argument, and ISC_FALSE otherwise.
+ */
+typedef isc_boolean_t (*isc_heapcompare_t)(void *, void *);
+
+/*%
+ * The index function allows the client of the heap to receive a callback
+ * when an item's index number changes. This allows it to maintain
+ * sync with its external state, but still delete itself, since deletions
+ * from the heap require the index be provided.
+ */
+typedef void (*isc_heapindex_t)(void *, unsigned int);
+
+/*%
+ * The heapaction function is used when iterating over the heap.
+ *
+ * NOTE: The heap structure CANNOT BE MODIFIED during the call to
+ * isc_heap_foreach().
+ */
+typedef void (*isc_heapaction_t)(void *, void *);
+
+typedef struct isc_heap isc_heap_t;
+
+isc_result_t
+isc_heap_create(isc_mem_t *mctx, isc_heapcompare_t compare,
+ isc_heapindex_t index, unsigned int size_increment,
+ isc_heap_t **heapp);
+/*!<
+ * \brief Create a new heap. The heap is implemented using a space-efficient
+ * storage method. When the heap elements are deleted space is not freed
+ * but will be reused when new elements are inserted.
+ *
+ * Requires:
+ *\li "mctx" is valid.
+ *\li "compare" is a function which takes two void * arguments and
+ * returns ISC_TRUE if the first argument has a higher priority than
+ * the second, and ISC_FALSE otherwise.
+ *\li "index" is a function which takes a void *, and an unsigned int
+ * argument. This function will be called whenever an element's
+ * index value changes, so it may continue to delete itself from the
+ * heap. This option may be NULL if this functionality is unneeded.
+ *\li "size_increment" is a hint about how large the heap should grow
+ * when resizing is needed. If this is 0, a default size will be
+ * used, which is currently 1024, allowing space for an additional 1024
+ * heap elements to be inserted before adding more space.
+ *\li "heapp" is not NULL, and "*heap" is NULL.
+ *
+ * Returns:
+ *\li ISC_R_SUCCESS - success
+ *\li ISC_R_NOMEMORY - insufficient memory
+ */
+
+void
+isc_heap_destroy(isc_heap_t **heapp);
+/*!<
+ * \brief Destroys a heap.
+ *
+ * Requires:
+ *\li "heapp" is not NULL and "*heap" points to a valid isc_heap_t.
+ */
+
+isc_result_t
+isc_heap_insert(isc_heap_t *heap, void *elt);
+/*!<
+ * \brief Inserts a new element into a heap.
+ *
+ * Requires:
+ *\li "heapp" is not NULL and "*heap" points to a valid isc_heap_t.
+ */
+
+void
+isc_heap_delete(isc_heap_t *heap, unsigned int index);
+/*!<
+ * \brief Deletes an element from a heap, by element index.
+ *
+ * Requires:
+ *\li "heapp" is not NULL and "*heap" points to a valid isc_heap_t.
+ *\li "index" is a valid element index, as provided by the "index" callback
+ * provided during heap creation.
+ */
+
+void
+isc_heap_increased(isc_heap_t *heap, unsigned int index);
+/*!<
+ * \brief Indicates to the heap that an element's priority has increased.
+ * This function MUST be called whenever an element has increased in priority.
+ *
+ * Requires:
+ *\li "heapp" is not NULL and "*heap" points to a valid isc_heap_t.
+ *\li "index" is a valid element index, as provided by the "index" callback
+ * provided during heap creation.
+ */
+
+void
+isc_heap_decreased(isc_heap_t *heap, unsigned int index);
+/*!<
+ * \brief Indicates to the heap that an element's priority has decreased.
+ * This function MUST be called whenever an element has decreased in priority.
+ *
+ * Requires:
+ *\li "heapp" is not NULL and "*heap" points to a valid isc_heap_t.
+ *\li "index" is a valid element index, as provided by the "index" callback
+ * provided during heap creation.
+ */
+
+void *
+isc_heap_element(isc_heap_t *heap, unsigned int index);
+/*!<
+ * \brief Returns the element for a specific element index.
+ *
+ * Requires:
+ *\li "heapp" is not NULL and "*heap" points to a valid isc_heap_t.
+ *\li "index" is a valid element index, as provided by the "index" callback
+ * provided during heap creation.
+ *
+ * Returns:
+ *\li A pointer to the element for the element index.
+ */
+
+void
+isc_heap_foreach(isc_heap_t *heap, isc_heapaction_t action, void *uap);
+/*!<
+ * \brief Iterate over the heap, calling an action for each element. The
+ * order of iteration is not sorted.
+ *
+ * Requires:
+ *\li "heapp" is not NULL and "*heap" points to a valid isc_heap_t.
+ *\li "action" is not NULL, and is a function which takes two arguments.
+ * The first is a void *, representing the element, and the second is
+ * "uap" as provided to isc_heap_foreach.
+ *\li "uap" is a caller-provided argument, and may be NULL.
+ *
+ * Note:
+ *\li The heap structure CANNOT be modified during this iteration. The only
+ * safe function to call while iterating the heap is isc_heap_element().
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_HEAP_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/hex.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/hex.h
new file mode 100644
index 0000000..a5e2f53
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/hex.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: hex.h,v 1.13 2008/09/25 04:02:39 tbox Exp $ */
+
+#ifndef ISC_HEX_H
+#define ISC_HEX_H 1
+
+/*! \file isc/hex.h */
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+ISC_LANG_BEGINDECLS
+
+/***
+ *** Functions
+ ***/
+
+isc_result_t
+isc_hex_totext(isc_region_t *source, int wordlength,
+ const char *wordbreak, isc_buffer_t *target);
+/*!<
+ * \brief Convert data into hex encoded text.
+ *
+ * Notes:
+ *\li The hex encoded text in 'target' will be divided into
+ * words of at most 'wordlength' characters, separated by
+ * the 'wordbreak' string. No parentheses will surround
+ * the text.
+ *
+ * Requires:
+ *\li 'source' is a region containing binary data
+ *\li 'target' is a text buffer containing available space
+ *\li 'wordbreak' points to a null-terminated string of
+ * zero or more whitespace characters
+ *
+ * Ensures:
+ *\li target will contain the hex encoded version of the data
+ * in source. The 'used' pointer in target will be advanced as
+ * necessary.
+ */
+
+isc_result_t
+isc_hex_decodestring(const char *cstr, isc_buffer_t *target);
+/*!<
+ * \brief Decode a null-terminated hex string.
+ *
+ * Requires:
+ *\li 'cstr' is non-null.
+ *\li 'target' is a valid buffer.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS -- the entire decoded representation of 'cstring'
+ * fit in 'target'.
+ *\li #ISC_R_BADHEX -- 'cstr' is not a valid hex encoding.
+ *
+ * Other error returns are any possible error code from:
+ * isc_lex_create(),
+ * isc_lex_openbuffer(),
+ * isc_hex_tobuffer().
+ */
+
+isc_result_t
+isc_hex_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length);
+/*!<
+ * \brief Convert hex encoded text from a lexer context into data.
+ *
+ * Requires:
+ *\li 'lex' is a valid lexer context
+ *\li 'target' is a buffer containing binary data
+ *\li 'length' is an integer
+ *
+ * Ensures:
+ *\li target will contain the data represented by the hex encoded
+ * string parsed by the lexer. No more than length bytes will be read,
+ * if length is positive. The 'used' pointer in target will be
+ * advanced as necessary.
+ */
+
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_HEX_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/hmacmd5.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/hmacmd5.h
new file mode 100644
index 0000000..9ecad45
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/hmacmd5.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: hmacmd5.h,v 1.14 2009/02/06 23:47:42 tbox Exp $ */
+
+/*! \file isc/hmacmd5.h
+ * \brief This is the header file for the HMAC-MD5 keyed hash algorithm
+ * described in RFC2104.
+ */
+
+#ifndef ISC_HMACMD5_H
+#define ISC_HMACMD5_H 1
+
+#include <isc/lang.h>
+#include <isc/md5.h>
+#include <isc/platform.h>
+#include <isc/types.h>
+
+#define ISC_HMACMD5_KEYLENGTH 64
+
+#ifdef ISC_PLATFORM_OPENSSLHASH
+#include <openssl/hmac.h>
+
+typedef HMAC_CTX isc_hmacmd5_t;
+
+#else
+
+typedef struct {
+ isc_md5_t md5ctx;
+ unsigned char key[ISC_HMACMD5_KEYLENGTH];
+} isc_hmacmd5_t;
+#endif
+
+ISC_LANG_BEGINDECLS
+
+void
+isc_hmacmd5_init(isc_hmacmd5_t *ctx, const unsigned char *key,
+ unsigned int len);
+
+void
+isc_hmacmd5_invalidate(isc_hmacmd5_t *ctx);
+
+void
+isc_hmacmd5_update(isc_hmacmd5_t *ctx, const unsigned char *buf,
+ unsigned int len);
+
+void
+isc_hmacmd5_sign(isc_hmacmd5_t *ctx, unsigned char *digest);
+
+isc_boolean_t
+isc_hmacmd5_verify(isc_hmacmd5_t *ctx, unsigned char *digest);
+
+isc_boolean_t
+isc_hmacmd5_verify2(isc_hmacmd5_t *ctx, unsigned char *digest, size_t len);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_HMACMD5_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/hmacsha.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/hmacsha.h
new file mode 100644
index 0000000..1d0e184
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/hmacsha.h
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2005-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: hmacsha.h,v 1.9 2009/02/06 23:47:42 tbox Exp $ */
+
+/*! \file isc/hmacsha.h
+ * This is the header file for the HMAC-SHA1, HMAC-SHA224, HMAC-SHA256,
+ * HMAC-SHA334 and HMAC-SHA512 hash algorithm described in RFC 2104.
+ */
+
+#ifndef ISC_HMACSHA_H
+#define ISC_HMACSHA_H 1
+
+#include <isc/lang.h>
+#include <isc/platform.h>
+#include <isc/sha1.h>
+#include <isc/sha2.h>
+#include <isc/types.h>
+
+#define ISC_HMACSHA1_KEYLENGTH ISC_SHA1_BLOCK_LENGTH
+#define ISC_HMACSHA224_KEYLENGTH ISC_SHA224_BLOCK_LENGTH
+#define ISC_HMACSHA256_KEYLENGTH ISC_SHA256_BLOCK_LENGTH
+#define ISC_HMACSHA384_KEYLENGTH ISC_SHA384_BLOCK_LENGTH
+#define ISC_HMACSHA512_KEYLENGTH ISC_SHA512_BLOCK_LENGTH
+
+#ifdef ISC_PLATFORM_OPENSSLHASH
+#include <openssl/hmac.h>
+
+typedef HMAC_CTX isc_hmacsha1_t;
+typedef HMAC_CTX isc_hmacsha224_t;
+typedef HMAC_CTX isc_hmacsha256_t;
+typedef HMAC_CTX isc_hmacsha384_t;
+typedef HMAC_CTX isc_hmacsha512_t;
+
+#else
+
+typedef struct {
+ isc_sha1_t sha1ctx;
+ unsigned char key[ISC_HMACSHA1_KEYLENGTH];
+} isc_hmacsha1_t;
+
+typedef struct {
+ isc_sha224_t sha224ctx;
+ unsigned char key[ISC_HMACSHA224_KEYLENGTH];
+} isc_hmacsha224_t;
+
+typedef struct {
+ isc_sha256_t sha256ctx;
+ unsigned char key[ISC_HMACSHA256_KEYLENGTH];
+} isc_hmacsha256_t;
+
+typedef struct {
+ isc_sha384_t sha384ctx;
+ unsigned char key[ISC_HMACSHA384_KEYLENGTH];
+} isc_hmacsha384_t;
+
+typedef struct {
+ isc_sha512_t sha512ctx;
+ unsigned char key[ISC_HMACSHA512_KEYLENGTH];
+} isc_hmacsha512_t;
+#endif
+
+ISC_LANG_BEGINDECLS
+
+void
+isc_hmacsha1_init(isc_hmacsha1_t *ctx, const unsigned char *key,
+ unsigned int len);
+
+void
+isc_hmacsha1_invalidate(isc_hmacsha1_t *ctx);
+
+void
+isc_hmacsha1_update(isc_hmacsha1_t *ctx, const unsigned char *buf,
+ unsigned int len);
+
+void
+isc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len);
+
+isc_boolean_t
+isc_hmacsha1_verify(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len);
+
+
+void
+isc_hmacsha224_init(isc_hmacsha224_t *ctx, const unsigned char *key,
+ unsigned int len);
+
+void
+isc_hmacsha224_invalidate(isc_hmacsha224_t *ctx);
+
+void
+isc_hmacsha224_update(isc_hmacsha224_t *ctx, const unsigned char *buf,
+ unsigned int len);
+
+void
+isc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len);
+
+isc_boolean_t
+isc_hmacsha224_verify(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len);
+
+
+void
+isc_hmacsha256_init(isc_hmacsha256_t *ctx, const unsigned char *key,
+ unsigned int len);
+
+void
+isc_hmacsha256_invalidate(isc_hmacsha256_t *ctx);
+
+void
+isc_hmacsha256_update(isc_hmacsha256_t *ctx, const unsigned char *buf,
+ unsigned int len);
+
+void
+isc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len);
+
+isc_boolean_t
+isc_hmacsha256_verify(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len);
+
+
+void
+isc_hmacsha384_init(isc_hmacsha384_t *ctx, const unsigned char *key,
+ unsigned int len);
+
+void
+isc_hmacsha384_invalidate(isc_hmacsha384_t *ctx);
+
+void
+isc_hmacsha384_update(isc_hmacsha384_t *ctx, const unsigned char *buf,
+ unsigned int len);
+
+void
+isc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len);
+
+isc_boolean_t
+isc_hmacsha384_verify(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len);
+
+
+void
+isc_hmacsha512_init(isc_hmacsha512_t *ctx, const unsigned char *key,
+ unsigned int len);
+
+void
+isc_hmacsha512_invalidate(isc_hmacsha512_t *ctx);
+
+void
+isc_hmacsha512_update(isc_hmacsha512_t *ctx, const unsigned char *buf,
+ unsigned int len);
+
+void
+isc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len);
+
+isc_boolean_t
+isc_hmacsha512_verify(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_HMACSHA_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/httpd.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/httpd.h
new file mode 100644
index 0000000..ba7f900
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/httpd.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2006-2008 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: httpd.h,v 1.9 2008/08/08 05:06:49 marka Exp $ */
+
+#ifndef ISC_HTTPD_H
+#define ISC_HTTPD_H 1
+
+/*! \file */
+
+#include <isc/event.h>
+#include <isc/eventclass.h>
+#include <isc/types.h>
+#include <isc/mutex.h>
+#include <isc/task.h>
+
+#define HTTPD_EVENTCLASS ISC_EVENTCLASS(4300)
+#define HTTPD_SHUTDOWN (HTTPD_EVENTCLASS + 0x0001)
+
+#define ISC_HTTPDMGR_FLAGSHUTTINGDOWN 0x00000001
+
+/*
+ * Create a new http daemon which will send, once every time period,
+ * a http-like header followed by HTTP data.
+ */
+isc_result_t
+isc_httpdmgr_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task,
+ isc_httpdclientok_t *client_ok,
+ isc_httpdondestroy_t *ondestory, void *cb_arg,
+ isc_timermgr_t *tmgr, isc_httpdmgr_t **httpdp);
+
+void
+isc_httpdmgr_shutdown(isc_httpdmgr_t **httpdp);
+
+isc_result_t
+isc_httpdmgr_addurl(isc_httpdmgr_t *httpdmgr, const char *url,
+ isc_httpdaction_t *func, void *arg);
+
+isc_result_t
+isc_httpd_response(isc_httpd_t *httpd);
+
+isc_result_t
+isc_httpd_addheader(isc_httpd_t *httpd, const char *name,
+ const char *val);
+
+isc_result_t
+isc_httpd_addheaderuint(isc_httpd_t *httpd, const char *name, int val);
+
+isc_result_t isc_httpd_endheaders(isc_httpd_t *httpd);
+
+#endif /* ISC_HTTPD_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/interfaceiter.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/interfaceiter.h
new file mode 100644
index 0000000..544f54b
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/interfaceiter.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: interfaceiter.h,v 1.17 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_INTERFACEITER_H
+#define ISC_INTERFACEITER_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file isc/interfaceiter.h
+ * \brief Iterates over the list of network interfaces.
+ *
+ * Interfaces whose address family is not supported are ignored and never
+ * returned by the iterator. Interfaces whose netmask, interface flags,
+ * or similar cannot be obtained are also ignored, and the failure is logged.
+ *
+ * Standards:
+ * The API for scanning varies greatly among operating systems.
+ * This module attempts to hide the differences.
+ */
+
+/***
+ *** Imports
+ ***/
+
+#include <isc/lang.h>
+#include <isc/netaddr.h>
+#include <isc/types.h>
+
+/*!
+ * \brief Public structure describing a network interface.
+ */
+
+struct isc_interface {
+ char name[32]; /*%< Interface name, null-terminated. */
+ unsigned int af; /*%< Address family. */
+ isc_netaddr_t address; /*%< Local address. */
+ isc_netaddr_t netmask; /*%< Network mask. */
+ isc_netaddr_t broadcast; /*&< Broadcast address. */
+ isc_netaddr_t dstaddress; /*%< Destination address (point-to-point only). */
+ isc_uint32_t flags; /*%< Flags; see INTERFACE flags. */
+ unsigned int ifindex; /*%< Interface index for IP(V6)_MULTICAST_IF. */
+};
+
+/*@{*/
+/*! Interface flags. */
+
+#define INTERFACE_F_UP 0x00000001U
+#define INTERFACE_F_POINTTOPOINT 0x00000002U
+#define INTERFACE_F_LOOPBACK 0x00000004U
+#define INTERFACE_F_BROADCAST 0x00000008U
+#define INTERFACE_F_MULTICAST 0x00000010U
+#define INTERFACE_F_PRIVACY 0x00000020U /* RFC 4941 */
+/*@}*/
+
+/***
+ *** Functions
+ ***/
+
+ISC_LANG_BEGINDECLS
+
+isc_result_t
+isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp);
+/*!<
+ * \brief Create an iterator for traversing the operating system's list
+ * of network interfaces.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ * \li #ISC_R_NOMEMORY
+ *\li Various network-related errors
+ */
+
+isc_result_t
+isc_interfaceiter_first(isc_interfaceiter_t *iter);
+/*!<
+ * \brief Position the iterator on the first interface.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS Success.
+ *\li #ISC_R_NOMORE There are no interfaces.
+ */
+
+isc_result_t
+isc_interfaceiter_current(isc_interfaceiter_t *iter,
+ isc_interface_t *ifdata);
+/*!<
+ * \brief Get information about the interface the iterator is currently
+ * positioned at and store it at *ifdata.
+ *
+ * Requires:
+ *\li The iterator has been successfully positioned using
+ * isc_interface_iter_first() / isc_interface_iter_next().
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS Success.
+ */
+
+isc_result_t
+isc_interfaceiter_next(isc_interfaceiter_t *iter);
+/*!<
+ * \brief Position the iterator on the next interface.
+ *
+ * Requires:
+ * \li The iterator has been successfully positioned using
+ * isc_interface_iter_first() / isc_interface_iter_next().
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS Success.
+ *\li #ISC_R_NOMORE There are no more interfaces.
+ */
+
+void
+isc_interfaceiter_destroy(isc_interfaceiter_t **iterp);
+/*!<
+ * \brief Destroy the iterator.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_INTERFACEITER_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/ipv6.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/ipv6.h
new file mode 100644
index 0000000..8054c9e
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/ipv6.h
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: ipv6.h,v 1.24 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_IPV6_H
+#define ISC_IPV6_H 1
+
+/*!
+ * Also define LWRES_IPV6_H to keep it from being included if liblwres is
+ * being used, or redefinition errors will occur.
+ */
+#define LWRES_IPV6_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file isc/ipv6.h
+ * \brief IPv6 definitions for systems which do not support IPv6.
+ *
+ * \li MP:
+ * No impact.
+ *
+ * \li Reliability:
+ * No anticipated impact.
+ *
+ * \li Resources:
+ * N/A.
+ *
+ * \li Security:
+ * No anticipated impact.
+ *
+ * \li Standards:
+ * RFC2553.
+ */
+
+/***
+ *** Imports.
+ ***/
+
+#include <isc/int.h>
+#include <isc/platform.h>
+
+/***
+ *** Types.
+ ***/
+
+struct in6_addr {
+ union {
+ isc_uint8_t _S6_u8[16];
+ isc_uint16_t _S6_u16[8];
+ isc_uint32_t _S6_u32[4];
+ } _S6_un;
+};
+#define s6_addr _S6_un._S6_u8
+#define s6_addr8 _S6_un._S6_u8
+#define s6_addr16 _S6_un._S6_u16
+#define s6_addr32 _S6_un._S6_u32
+
+#define IN6ADDR_ANY_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }}}
+#define IN6ADDR_LOOPBACK_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }}}
+
+LIBISC_EXTERNAL_DATA extern const struct in6_addr in6addr_any;
+LIBISC_EXTERNAL_DATA extern const struct in6_addr in6addr_loopback;
+
+struct sockaddr_in6 {
+#ifdef ISC_PLATFORM_HAVESALEN
+ isc_uint8_t sin6_len;
+ isc_uint8_t sin6_family;
+#else
+ isc_uint16_t sin6_family;
+#endif
+ isc_uint16_t sin6_port;
+ isc_uint32_t sin6_flowinfo;
+ struct in6_addr sin6_addr;
+ isc_uint32_t sin6_scope_id;
+};
+
+#ifdef ISC_PLATFORM_HAVESALEN
+#define SIN6_LEN 1
+#endif
+
+/*%
+ * Unspecified
+ */
+#define IN6_IS_ADDR_UNSPECIFIED(a) \
+ (((a)->s6_addr32[0] == 0) && \
+ ((a)->s6_addr32[1] == 0) && \
+ ((a)->s6_addr32[2] == 0) && \
+ ((a)->s6_addr32[3] == 0))
+
+/*%
+ * Loopback
+ */
+#define IN6_IS_ADDR_LOOPBACK(a) \
+ (((a)->s6_addr32[0] == 0) && \
+ ((a)->s6_addr32[1] == 0) && \
+ ((a)->s6_addr32[2] == 0) && \
+ ((a)->s6_addr32[3] == htonl(1)))
+
+/*%
+ * IPv4 compatible
+ */
+#define IN6_IS_ADDR_V4COMPAT(a) \
+ (((a)->s6_addr32[0] == 0) && \
+ ((a)->s6_addr32[1] == 0) && \
+ ((a)->s6_addr32[2] == 0) && \
+ ((a)->s6_addr32[3] != 0) && \
+ ((a)->s6_addr32[3] != htonl(1)))
+
+/*%
+ * Mapped
+ */
+#define IN6_IS_ADDR_V4MAPPED(a) \
+ (((a)->s6_addr32[0] == 0) && \
+ ((a)->s6_addr32[1] == 0) && \
+ ((a)->s6_addr32[2] == htonl(0x0000ffff)))
+
+/*%
+ * Multicast
+ */
+#define IN6_IS_ADDR_MULTICAST(a) \
+ ((a)->s6_addr8[0] == 0xffU)
+
+/*%
+ * Unicast link / site local.
+ */
+#define IN6_IS_ADDR_LINKLOCAL(a) \
+ (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0x80))
+#define IN6_IS_ADDR_SITELOCAL(a) \
+ (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0xc0))
+
+#endif /* ISC_IPV6_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/iterated_hash.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/iterated_hash.h
new file mode 100644
index 0000000..a8173f0
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/iterated_hash.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: iterated_hash.h,v 1.3 2008/09/25 04:02:39 tbox Exp $ */
+
+#ifndef ISC_ITERATED_HASH_H
+#define ISC_ITERATED_HASH_H 1
+
+#include <isc/lang.h>
+#include <isc/sha1.h>
+
+/*
+ * The maximal hash length that can be encoded it a name
+ * using base32hex. floor(255/8)*5
+ */
+#define NSEC3_MAX_HASH_LENGTH 155
+
+/*
+ * The maximum has that can be encoded in a single label using
+ * base32hex. floor(63/8)*5
+ */
+#define NSEC3_MAX_LABEL_HASH 35
+
+ISC_LANG_BEGINDECLS
+
+int isc_iterated_hash(unsigned char out[NSEC3_MAX_HASH_LENGTH],
+ unsigned int hashalg, int iterations,
+ const unsigned char *salt, int saltlength,
+ const unsigned char *in, int inlength);
+
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_ITERATED_HASH_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/lang.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/lang.h
new file mode 100644
index 0000000..8c60866
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/lang.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: lang.h,v 1.13 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_LANG_H
+#define ISC_LANG_H 1
+
+/*! \file isc/lang.h */
+
+#ifdef __cplusplus
+#define ISC_LANG_BEGINDECLS extern "C" {
+#define ISC_LANG_ENDDECLS }
+#else
+#define ISC_LANG_BEGINDECLS
+#define ISC_LANG_ENDDECLS
+#endif
+
+#endif /* ISC_LANG_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/lex.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/lex.h
new file mode 100644
index 0000000..8612150
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/lex.h
@@ -0,0 +1,431 @@
+/*
+ * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: lex.h,v 1.37 2008/05/30 23:47:01 tbox Exp $ */
+
+#ifndef ISC_LEX_H
+#define ISC_LEX_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file isc/lex.h
+ * \brief The "lex" module provides a lightweight tokenizer. It can operate
+ * on files or buffers, and can handle "include". It is designed for
+ * parsing of DNS master files and the BIND configuration file, but
+ * should be general enough to tokenize other things, e.g. HTTP.
+ *
+ * \li MP:
+ * No synchronization is provided. Clients must ensure exclusive
+ * access.
+ *
+ * \li Reliability:
+ * No anticipated impact.
+ *
+ * \li Resources:
+ * TBS
+ *
+ * \li Security:
+ * No anticipated impact.
+ *
+ * \li Standards:
+ * None.
+ */
+
+/***
+ *** Imports
+ ***/
+
+#include <stdio.h>
+
+#include <isc/lang.h>
+#include <isc/region.h>
+#include <isc/types.h>
+
+ISC_LANG_BEGINDECLS
+
+/***
+ *** Options
+ ***/
+
+/*@{*/
+/*!
+ * Various options for isc_lex_gettoken().
+ */
+
+#define ISC_LEXOPT_EOL 0x01 /*%< Want end-of-line token. */
+#define ISC_LEXOPT_EOF 0x02 /*%< Want end-of-file token. */
+#define ISC_LEXOPT_INITIALWS 0x04 /*%< Want initial whitespace. */
+#define ISC_LEXOPT_NUMBER 0x08 /*%< Recognize numbers. */
+#define ISC_LEXOPT_QSTRING 0x10 /*%< Recognize qstrings. */
+/*@}*/
+
+/*@{*/
+/*!
+ * The ISC_LEXOPT_DNSMULTILINE option handles the processing of '(' and ')' in
+ * the DNS master file format. If this option is set, then the
+ * ISC_LEXOPT_INITIALWS and ISC_LEXOPT_EOL options will be ignored when
+ * the paren count is > 0. To use this option, '(' and ')' must be special
+ * characters.
+ */
+#define ISC_LEXOPT_DNSMULTILINE 0x20 /*%< Handle '(' and ')'. */
+#define ISC_LEXOPT_NOMORE 0x40 /*%< Want "no more" token. */
+
+#define ISC_LEXOPT_CNUMBER 0x80 /*%< Recognize octal and hex. */
+#define ISC_LEXOPT_ESCAPE 0x100 /*%< Recognize escapes. */
+#define ISC_LEXOPT_QSTRINGMULTILINE 0x200 /*%< Allow multiline "" strings */
+#define ISC_LEXOPT_OCTAL 0x400 /*%< Expect a octal number. */
+/*@}*/
+/*@{*/
+/*!
+ * Various commenting styles, which may be changed at any time with
+ * isc_lex_setcomments().
+ */
+
+#define ISC_LEXCOMMENT_C 0x01
+#define ISC_LEXCOMMENT_CPLUSPLUS 0x02
+#define ISC_LEXCOMMENT_SHELL 0x04
+#define ISC_LEXCOMMENT_DNSMASTERFILE 0x08
+/*@}*/
+
+/***
+ *** Types
+ ***/
+
+/*! Lex */
+
+typedef char isc_lexspecials_t[256];
+
+/* Tokens */
+
+typedef enum {
+ isc_tokentype_unknown = 0,
+ isc_tokentype_string = 1,
+ isc_tokentype_number = 2,
+ isc_tokentype_qstring = 3,
+ isc_tokentype_eol = 4,
+ isc_tokentype_eof = 5,
+ isc_tokentype_initialws = 6,
+ isc_tokentype_special = 7,
+ isc_tokentype_nomore = 8
+} isc_tokentype_t;
+
+typedef union {
+ char as_char;
+ unsigned long as_ulong;
+ isc_region_t as_region;
+ isc_textregion_t as_textregion;
+ void * as_pointer;
+} isc_tokenvalue_t;
+
+typedef struct isc_token {
+ isc_tokentype_t type;
+ isc_tokenvalue_t value;
+} isc_token_t;
+
+/***
+ *** Functions
+ ***/
+
+isc_result_t
+isc_lex_create(isc_mem_t *mctx, size_t max_token, isc_lex_t **lexp);
+/*%<
+ * Create a lexer.
+ *
+ * 'max_token' is a hint of the number of bytes in the largest token.
+ *
+ * Requires:
+ *\li '*lexp' is a valid lexer.
+ *
+ *\li max_token > 0.
+ *
+ * Ensures:
+ *\li On success, *lexp is attached to the newly created lexer.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOMEMORY
+ */
+
+void
+isc_lex_destroy(isc_lex_t **lexp);
+/*%<
+ * Destroy the lexer.
+ *
+ * Requires:
+ *\li '*lexp' is a valid lexer.
+ *
+ * Ensures:
+ *\li *lexp == NULL
+ */
+
+unsigned int
+isc_lex_getcomments(isc_lex_t *lex);
+/*%<
+ * Return the current lexer commenting styles.
+ *
+ * Requires:
+ *\li 'lex' is a valid lexer.
+ *
+ * Returns:
+ *\li The commenting sytles which are currently allowed.
+ */
+
+void
+isc_lex_setcomments(isc_lex_t *lex, unsigned int comments);
+/*%<
+ * Set allowed lexer commenting styles.
+ *
+ * Requires:
+ *\li 'lex' is a valid lexer.
+ *
+ *\li 'comments' has meaningful values.
+ */
+
+void
+isc_lex_getspecials(isc_lex_t *lex, isc_lexspecials_t specials);
+/*%<
+ * Put the current list of specials into 'specials'.
+ *
+ * Requires:
+ *\li 'lex' is a valid lexer.
+ */
+
+void
+isc_lex_setspecials(isc_lex_t *lex, isc_lexspecials_t specials);
+/*!<
+ * The characters in 'specials' are returned as tokens. Along with
+ * whitespace, they delimit strings and numbers.
+ *
+ * Note:
+ *\li Comment processing takes precedence over special character
+ * recognition.
+ *
+ * Requires:
+ *\li 'lex' is a valid lexer.
+ */
+
+isc_result_t
+isc_lex_openfile(isc_lex_t *lex, const char *filename);
+/*%<
+ * Open 'filename' and make it the current input source for 'lex'.
+ *
+ * Requires:
+ *\li 'lex' is a valid lexer.
+ *
+ *\li filename is a valid C string.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOMEMORY Out of memory
+ *\li #ISC_R_NOTFOUND File not found
+ *\li #ISC_R_NOPERM No permission to open file
+ *\li #ISC_R_FAILURE Couldn't open file, not sure why
+ *\li #ISC_R_UNEXPECTED
+ */
+
+isc_result_t
+isc_lex_openstream(isc_lex_t *lex, FILE *stream);
+/*%<
+ * Make 'stream' the current input source for 'lex'.
+ *
+ * Requires:
+ *\li 'lex' is a valid lexer.
+ *
+ *\li 'stream' is a valid C stream.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOMEMORY Out of memory
+ */
+
+isc_result_t
+isc_lex_openbuffer(isc_lex_t *lex, isc_buffer_t *buffer);
+/*%<
+ * Make 'buffer' the current input source for 'lex'.
+ *
+ * Requires:
+ *\li 'lex' is a valid lexer.
+ *
+ *\li 'buffer' is a valid buffer.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOMEMORY Out of memory
+ */
+
+isc_result_t
+isc_lex_close(isc_lex_t *lex);
+/*%<
+ * Close the most recently opened object (i.e. file or buffer).
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOMORE No more input sources
+ */
+
+isc_result_t
+isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp);
+/*%<
+ * Get the next token.
+ *
+ * Requires:
+ *\li 'lex' is a valid lexer.
+ *
+ *\li 'lex' has an input source.
+ *
+ *\li 'options' contains valid options.
+ *
+ *\li '*tokenp' is a valid pointer.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_UNEXPECTEDEND
+ *\li #ISC_R_NOMEMORY
+ *
+ * These two results are returned only if their corresponding lexer
+ * options are not set.
+ *
+ *\li #ISC_R_EOF End of input source
+ *\li #ISC_R_NOMORE No more input sources
+ */
+
+isc_result_t
+isc_lex_getmastertoken(isc_lex_t *lex, isc_token_t *token,
+ isc_tokentype_t expect, isc_boolean_t eol);
+/*%<
+ * Get the next token from a DNS master file type stream. This is a
+ * convenience function that sets appropriate options and handles quoted
+ * strings and end of line correctly for master files. It also ungets
+ * unexpected tokens.
+ *
+ * Requires:
+ *\li 'lex' is a valid lexer.
+ *
+ *\li 'token' is a valid pointer
+ *
+ * Returns:
+ *
+ * \li any return code from isc_lex_gettoken().
+ */
+
+isc_result_t
+isc_lex_getoctaltoken(isc_lex_t *lex, isc_token_t *token, isc_boolean_t eol);
+/*%<
+ * Get the next token from a DNS master file type stream. This is a
+ * convenience function that sets appropriate options and handles end
+ * of line correctly for master files. It also ungets unexpected tokens.
+ *
+ * Requires:
+ *\li 'lex' is a valid lexer.
+ *
+ *\li 'token' is a valid pointer
+ *
+ * Returns:
+ *
+ * \li any return code from isc_lex_gettoken().
+ */
+
+void
+isc_lex_ungettoken(isc_lex_t *lex, isc_token_t *tokenp);
+/*%<
+ * Unget the current token.
+ *
+ * Requires:
+ *\li 'lex' is a valid lexer.
+ *
+ *\li 'lex' has an input source.
+ *
+ *\li 'tokenp' points to a valid token.
+ *
+ *\li There is no ungotten token already.
+ */
+
+void
+isc_lex_getlasttokentext(isc_lex_t *lex, isc_token_t *tokenp, isc_region_t *r);
+/*%<
+ * Returns a region containing the text of the last token returned.
+ *
+ * Requires:
+ *\li 'lex' is a valid lexer.
+ *
+ *\li 'lex' has an input source.
+ *
+ *\li 'tokenp' points to a valid token.
+ *
+ *\li A token has been gotten and not ungotten.
+ */
+
+char *
+isc_lex_getsourcename(isc_lex_t *lex);
+/*%<
+ * Return the input source name.
+ *
+ * Requires:
+ *\li 'lex' is a valid lexer.
+ *
+ * Returns:
+ * \li source name or NULL if no current source.
+ *\li result valid while current input source exists.
+ */
+
+
+unsigned long
+isc_lex_getsourceline(isc_lex_t *lex);
+/*%<
+ * Return the input source line number.
+ *
+ * Requires:
+ *\li 'lex' is a valid lexer.
+ *
+ * Returns:
+ *\li Current line number or 0 if no current source.
+ */
+
+isc_result_t
+isc_lex_setsourcename(isc_lex_t *lex, const char *name);
+/*%<
+ * Assigns a new name to the input source.
+ *
+ * Requires:
+ *
+ * \li 'lex' is a valid lexer.
+ *
+ * Returns:
+ * \li #ISC_R_SUCCESS
+ * \li #ISC_R_NOMEMORY
+ * \li #ISC_R_NOTFOUND - there are no sources.
+ */
+
+isc_boolean_t
+isc_lex_isfile(isc_lex_t *lex);
+/*%<
+ * Return whether the current input source is a file.
+ *
+ * Requires:
+ *\li 'lex' is a valid lexer.
+ *
+ * Returns:
+ * \li #ISC_TRUE if the current input is a file,
+ *\li #ISC_FALSE otherwise.
+ */
+
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_LEX_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/lfsr.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/lfsr.h
new file mode 100644
index 0000000..d4d9707
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/lfsr.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: lfsr.h,v 1.17 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_LFSR_H
+#define ISC_LFSR_H 1
+
+/*! \file isc/lfsr.h */
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+typedef struct isc_lfsr isc_lfsr_t;
+
+/*%
+ * This function is called when reseeding is needed. It is allowed to
+ * modify any state in the LFSR in any way it sees fit OTHER THAN "bits".
+ *
+ * It MUST set "count" to a new value or the lfsr will never reseed again.
+ *
+ * Also, a reseed will never occur in the middle of an extraction. This
+ * is purely an optimization, and is probably what one would want.
+ */
+typedef void (*isc_lfsrreseed_t)(isc_lfsr_t *, void *);
+
+/*%
+ * The members of this structure can be used by the application, but care
+ * needs to be taken to not change state once the lfsr is in operation.
+ */
+struct isc_lfsr {
+ isc_uint32_t state; /*%< previous state */
+ unsigned int bits; /*%< length */
+ isc_uint32_t tap; /*%< bit taps */
+ unsigned int count; /*%< reseed count (in BITS!) */
+ isc_lfsrreseed_t reseed; /*%< reseed function */
+ void *arg; /*%< reseed function argument */
+};
+
+ISC_LANG_BEGINDECLS
+
+
+void
+isc_lfsr_init(isc_lfsr_t *lfsr, isc_uint32_t state, unsigned int bits,
+ isc_uint32_t tap, unsigned int count,
+ isc_lfsrreseed_t reseed, void *arg);
+/*%<
+ * Initialize an LFSR.
+ *
+ * Note:
+ *
+ *\li Putting untrusted values into this function will cause the LFSR to
+ * generate (perhaps) non-maximal length sequences.
+ *
+ * Requires:
+ *
+ *\li lfsr != NULL
+ *
+ *\li 8 <= bits <= 32
+ *
+ *\li tap != 0
+ */
+
+void
+isc_lfsr_generate(isc_lfsr_t *lfsr, void *data, unsigned int count);
+/*%<
+ * Returns "count" bytes of data from the LFSR.
+ *
+ * Requires:
+ *
+ *\li lfsr be valid.
+ *
+ *\li data != NULL.
+ *
+ *\li count > 0.
+ */
+
+void
+isc_lfsr_skip(isc_lfsr_t *lfsr, unsigned int skip);
+/*%<
+ * Skip "skip" states.
+ *
+ * Requires:
+ *
+ *\li lfsr be valid.
+ */
+
+isc_uint32_t
+isc_lfsr_generate32(isc_lfsr_t *lfsr1, isc_lfsr_t *lfsr2);
+/*%<
+ * Given two LFSRs, use the current state from each to skip entries in the
+ * other. The next states are then xor'd together and returned.
+ *
+ * WARNING:
+ *
+ *\li This function is used only for very, very low security data, such
+ * as DNS message IDs where it is desired to have an unpredictable
+ * stream of bytes that are harder to predict than a simple flooding
+ * attack.
+ *
+ * Notes:
+ *
+ *\li Since the current state from each of the LFSRs is used to skip
+ * state in the other, it is important that no state be leaked
+ * from either LFSR.
+ *
+ * Requires:
+ *
+ *\li lfsr1 and lfsr2 be valid.
+ *
+ *\li 1 <= skipbits <= 31
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_LFSR_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/lib.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/lib.h
new file mode 100644
index 0000000..f24fef8
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/lib.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: lib.h,v 1.16 2009/09/02 23:48:03 tbox Exp $ */
+
+#ifndef ISC_LIB_H
+#define ISC_LIB_H 1
+
+/*! \file isc/lib.h */
+
+#include <isc/types.h>
+#include <isc/lang.h>
+
+ISC_LANG_BEGINDECLS
+
+LIBISC_EXTERNAL_DATA extern isc_msgcat_t *isc_msgcat;
+
+void
+isc_lib_initmsgcat(void);
+/*!<
+ * \brief Initialize the ISC library's message catalog, isc_msgcat, if it
+ * has not already been initialized.
+ */
+
+void
+isc_lib_register(void);
+/*!<
+ * \brief Register the ISC library implementations for some base services
+ * such as memory or event management and handling socket or timer events.
+ * An external application that wants to use the ISC library must call this
+ * function very early in main().
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_LIB_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/list.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/list.h
new file mode 100644
index 0000000..c9bdfc7
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/list.h
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2004, 2006, 2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1997-2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+#ifndef ISC_LIST_H
+#define ISC_LIST_H 1
+#include <isc/boolean.h>
+#include <isc/assertions.h>
+
+#ifdef ISC_LIST_CHECKINIT
+#define ISC_LINK_INSIST(x) ISC_INSIST(x)
+#else
+#define ISC_LINK_INSIST(x)
+#endif
+
+#define ISC_LIST(type) struct { type *head, *tail; }
+#define ISC_LIST_INIT(list) \
+ do { (list).head = NULL; (list).tail = NULL; } while (0)
+
+#define ISC_LINK(type) struct { type *prev, *next; }
+#define ISC_LINK_INIT_TYPE(elt, link, type) \
+ do { \
+ (elt)->link.prev = (type *)(-1); \
+ (elt)->link.next = (type *)(-1); \
+ } while (0)
+#define ISC_LINK_INIT(elt, link) \
+ ISC_LINK_INIT_TYPE(elt, link, void)
+#define ISC_LINK_LINKED(elt, link) ((void *)((elt)->link.prev) != (void *)(-1))
+
+#define ISC_LIST_HEAD(list) ((list).head)
+#define ISC_LIST_TAIL(list) ((list).tail)
+#define ISC_LIST_EMPTY(list) ISC_TF((list).head == NULL)
+
+#define __ISC_LIST_PREPENDUNSAFE(list, elt, link) \
+ do { \
+ if ((list).head != NULL) \
+ (list).head->link.prev = (elt); \
+ else \
+ (list).tail = (elt); \
+ (elt)->link.prev = NULL; \
+ (elt)->link.next = (list).head; \
+ (list).head = (elt); \
+ } while (0)
+
+#define ISC_LIST_PREPEND(list, elt, link) \
+ do { \
+ ISC_LINK_INSIST(!ISC_LINK_LINKED(elt, link)); \
+ __ISC_LIST_PREPENDUNSAFE(list, elt, link); \
+ } while (0)
+
+#define ISC_LIST_INITANDPREPEND(list, elt, link) \
+ __ISC_LIST_PREPENDUNSAFE(list, elt, link)
+
+#define __ISC_LIST_APPENDUNSAFE(list, elt, link) \
+ do { \
+ if ((list).tail != NULL) \
+ (list).tail->link.next = (elt); \
+ else \
+ (list).head = (elt); \
+ (elt)->link.prev = (list).tail; \
+ (elt)->link.next = NULL; \
+ (list).tail = (elt); \
+ } while (0)
+
+#define ISC_LIST_APPEND(list, elt, link) \
+ do { \
+ ISC_LINK_INSIST(!ISC_LINK_LINKED(elt, link)); \
+ __ISC_LIST_APPENDUNSAFE(list, elt, link); \
+ } while (0)
+
+#define ISC_LIST_INITANDAPPEND(list, elt, link) \
+ __ISC_LIST_APPENDUNSAFE(list, elt, link)
+
+#define __ISC_LIST_UNLINKUNSAFE_TYPE(list, elt, link, type) \
+ do { \
+ if ((elt)->link.next != NULL) \
+ (elt)->link.next->link.prev = (elt)->link.prev; \
+ else { \
+ ISC_INSIST((list).tail == (elt)); \
+ (list).tail = (elt)->link.prev; \
+ } \
+ if ((elt)->link.prev != NULL) \
+ (elt)->link.prev->link.next = (elt)->link.next; \
+ else { \
+ ISC_INSIST((list).head == (elt)); \
+ (list).head = (elt)->link.next; \
+ } \
+ (elt)->link.prev = (type *)(-1); \
+ (elt)->link.next = (type *)(-1); \
+ } while (0)
+
+#define __ISC_LIST_UNLINKUNSAFE(list, elt, link) \
+ __ISC_LIST_UNLINKUNSAFE_TYPE(list, elt, link, void)
+
+#define ISC_LIST_UNLINK_TYPE(list, elt, link, type) \
+ do { \
+ ISC_LINK_INSIST(ISC_LINK_LINKED(elt, link)); \
+ __ISC_LIST_UNLINKUNSAFE_TYPE(list, elt, link, type); \
+ } while (0)
+#define ISC_LIST_UNLINK(list, elt, link) \
+ ISC_LIST_UNLINK_TYPE(list, elt, link, void)
+
+#define ISC_LIST_PREV(elt, link) ((elt)->link.prev)
+#define ISC_LIST_NEXT(elt, link) ((elt)->link.next)
+
+#define __ISC_LIST_INSERTBEFOREUNSAFE(list, before, elt, link) \
+ do { \
+ if ((before)->link.prev == NULL) \
+ ISC_LIST_PREPEND(list, elt, link); \
+ else { \
+ (elt)->link.prev = (before)->link.prev; \
+ (before)->link.prev = (elt); \
+ (elt)->link.prev->link.next = (elt); \
+ (elt)->link.next = (before); \
+ } \
+ } while (0)
+
+#define ISC_LIST_INSERTBEFORE(list, before, elt, link) \
+ do { \
+ ISC_LINK_INSIST(ISC_LINK_LINKED(before, link)); \
+ ISC_LINK_INSIST(!ISC_LINK_LINKED(elt, link)); \
+ __ISC_LIST_INSERTBEFOREUNSAFE(list, before, elt, link); \
+ } while (0)
+
+#define __ISC_LIST_INSERTAFTERUNSAFE(list, after, elt, link) \
+ do { \
+ if ((after)->link.next == NULL) \
+ ISC_LIST_APPEND(list, elt, link); \
+ else { \
+ (elt)->link.next = (after)->link.next; \
+ (after)->link.next = (elt); \
+ (elt)->link.next->link.prev = (elt); \
+ (elt)->link.prev = (after); \
+ } \
+ } while (0)
+
+#define ISC_LIST_INSERTAFTER(list, after, elt, link) \
+ do { \
+ ISC_LINK_INSIST(ISC_LINK_LINKED(after, link)); \
+ ISC_LINK_INSIST(!ISC_LINK_LINKED(elt, link)); \
+ __ISC_LIST_INSERTAFTERUNSAFE(list, after, elt, link); \
+ } while (0)
+
+#define ISC_LIST_APPENDLIST(list1, list2, link) \
+ do { \
+ if (ISC_LIST_EMPTY(list1)) \
+ (list1) = (list2); \
+ else if (!ISC_LIST_EMPTY(list2)) { \
+ (list1).tail->link.next = (list2).head; \
+ (list2).head->link.prev = (list1).tail; \
+ (list1).tail = (list2).tail; \
+ } \
+ (list2).head = NULL; \
+ (list2).tail = NULL; \
+ } while (0)
+
+#define ISC_LIST_PREPENDLIST(list1, list2, link) \
+ do { \
+ if (ISC_LIST_EMPTY(list1)) \
+ (list1) = (list2); \
+ else if (!ISC_LIST_EMPTY(list2)) { \
+ (list2).tail->link.next = (list1).head; \
+ (list1).head->link.prev = (list2).tail; \
+ (list1).head = (list2).head; \
+ } \
+ (list2).head = NULL; \
+ (list2).tail = NULL; \
+ } while (0)
+
+#define ISC_LIST_ENQUEUE(list, elt, link) ISC_LIST_APPEND(list, elt, link)
+#define __ISC_LIST_ENQUEUEUNSAFE(list, elt, link) \
+ __ISC_LIST_APPENDUNSAFE(list, elt, link)
+#define ISC_LIST_DEQUEUE(list, elt, link) \
+ ISC_LIST_UNLINK_TYPE(list, elt, link, void)
+#define ISC_LIST_DEQUEUE_TYPE(list, elt, link, type) \
+ ISC_LIST_UNLINK_TYPE(list, elt, link, type)
+#define __ISC_LIST_DEQUEUEUNSAFE(list, elt, link) \
+ __ISC_LIST_UNLINKUNSAFE_TYPE(list, elt, link, void)
+#define __ISC_LIST_DEQUEUEUNSAFE_TYPE(list, elt, link, type) \
+ __ISC_LIST_UNLINKUNSAFE_TYPE(list, elt, link, type)
+
+#endif /* ISC_LIST_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/log.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/log.h
new file mode 100644
index 0000000..741c532
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/log.h
@@ -0,0 +1,914 @@
+/*
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: log.h,v 1.59 2009/02/16 02:01:16 marka Exp $ */
+
+#ifndef ISC_LOG_H
+#define ISC_LOG_H 1
+
+/*! \file isc/log.h */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <syslog.h> /* XXXDCL NT */
+
+#include <isc/formatcheck.h>
+#include <isc/lang.h>
+#include <isc/platform.h>
+#include <isc/types.h>
+
+/*@{*/
+/*!
+ * \brief Severity levels, patterned after Unix's syslog levels.
+ *
+ */
+#define ISC_LOG_DEBUG(level) (level)
+/*!
+ * #ISC_LOG_DYNAMIC can only be used for defining channels with
+ * isc_log_createchannel(), not to specify a level in isc_log_write().
+ */
+#define ISC_LOG_DYNAMIC 0
+#define ISC_LOG_INFO (-1)
+#define ISC_LOG_NOTICE (-2)
+#define ISC_LOG_WARNING (-3)
+#define ISC_LOG_ERROR (-4)
+#define ISC_LOG_CRITICAL (-5)
+/*@}*/
+
+/*@{*/
+/*!
+ * \brief Destinations.
+ */
+#define ISC_LOG_TONULL 1
+#define ISC_LOG_TOSYSLOG 2
+#define ISC_LOG_TOFILE 3
+#define ISC_LOG_TOFILEDESC 4
+/*@}*/
+
+/*@{*/
+/*%
+ * Channel flags.
+ */
+#define ISC_LOG_PRINTTIME 0x0001
+#define ISC_LOG_PRINTLEVEL 0x0002
+#define ISC_LOG_PRINTCATEGORY 0x0004
+#define ISC_LOG_PRINTMODULE 0x0008
+#define ISC_LOG_PRINTTAG 0x0010
+#define ISC_LOG_PRINTALL 0x001F
+#define ISC_LOG_DEBUGONLY 0x1000
+#define ISC_LOG_OPENERR 0x8000 /* internal */
+/*@}*/
+
+/*@{*/
+/*!
+ * \brief Other options.
+ *
+ * XXXDCL INFINITE doesn't yet work. Arguably it isn't needed, but
+ * since I am intend to make large number of versions work efficiently,
+ * INFINITE is going to be trivial to add to that.
+ */
+#define ISC_LOG_ROLLINFINITE (-1)
+#define ISC_LOG_ROLLNEVER (-2)
+/*@}*/
+
+/*!
+ * \brief Used to name the categories used by a library.
+ *
+ * An array of isc_logcategory
+ * structures names each category, and the id value is initialized by calling
+ * isc_log_registercategories.
+ */
+struct isc_logcategory {
+ const char *name;
+ unsigned int id;
+};
+
+/*%
+ * Similar to isc_logcategory, but for all the modules a library defines.
+ */
+struct isc_logmodule {
+ const char *name;
+ unsigned int id;
+};
+
+/*%
+ * The isc_logfile structure is initialized as part of an isc_logdestination
+ * before calling isc_log_createchannel().
+ *
+ * When defining an #ISC_LOG_TOFILE
+ * channel the name, versions and maximum_size should be set before calling
+ * isc_log_createchannel(). To define an #ISC_LOG_TOFILEDESC channel set only
+ * the stream before the call.
+ *
+ * Setting maximum_size to zero implies no maximum.
+ */
+typedef struct isc_logfile {
+ FILE *stream; /*%< Initialized to NULL for #ISC_LOG_TOFILE. */
+ const char *name; /*%< NULL for #ISC_LOG_TOFILEDESC. */
+ int versions; /* >= 0, #ISC_LOG_ROLLNEVER, #ISC_LOG_ROLLINFINITE. */
+ /*%
+ * stdio's ftell is standardized to return a long, which may well not
+ * be big enough for the largest file supportable by the operating
+ * system (though it is _probably_ big enough for the largest log
+ * anyone would want). st_size returned by fstat should be typedef'd
+ * to a size large enough for the largest possible file on a system.
+ */
+ isc_offset_t maximum_size;
+ isc_boolean_t maximum_reached; /*%< Private. */
+} isc_logfile_t;
+
+/*%
+ * Passed to isc_log_createchannel to define the attributes of either
+ * a stdio or a syslog log.
+ */
+typedef union isc_logdestination {
+ isc_logfile_t file;
+ int facility; /* XXXDCL NT */
+} isc_logdestination_t;
+
+/*@{*/
+/*%
+ * The built-in categories of libisc.
+ *
+ * Each library registering categories should provide library_LOGCATEGORY_name
+ * definitions with indexes into its isc_logcategory structure corresponding to
+ * the order of the names.
+ */
+LIBISC_EXTERNAL_DATA extern isc_logcategory_t isc_categories[];
+LIBISC_EXTERNAL_DATA extern isc_log_t *isc_lctx;
+LIBISC_EXTERNAL_DATA extern isc_logmodule_t isc_modules[];
+/*@}*/
+
+/*@{*/
+/*%
+ * Do not log directly to DEFAULT. Use another category. When in doubt,
+ * use GENERAL.
+ */
+#define ISC_LOGCATEGORY_DEFAULT (&isc_categories[0])
+#define ISC_LOGCATEGORY_GENERAL (&isc_categories[1])
+/*@}*/
+
+#define ISC_LOGMODULE_SOCKET (&isc_modules[0])
+#define ISC_LOGMODULE_TIME (&isc_modules[1])
+#define ISC_LOGMODULE_INTERFACE (&isc_modules[2])
+#define ISC_LOGMODULE_TIMER (&isc_modules[3])
+#define ISC_LOGMODULE_FILE (&isc_modules[4])
+
+ISC_LANG_BEGINDECLS
+
+isc_result_t
+isc_log_create(isc_mem_t *mctx, isc_log_t **lctxp, isc_logconfig_t **lcfgp);
+/*%<
+ * Establish a new logging context, with default channels.
+ *
+ * Notes:
+ *\li isc_log_create() calls isc_logconfig_create(), so see its comment
+ * below for more information.
+ *
+ * Requires:
+ *\li mctx is a valid memory context.
+ *\li lctxp is not null and *lctxp is null.
+ *\li lcfgp is null or lcfgp is not null and *lcfgp is null.
+ *
+ * Ensures:
+ *\li *lctxp will point to a valid logging context if all of the necessary
+ * memory was allocated, or NULL otherwise.
+ *\li *lcfgp will point to a valid logging configuration if all of the
+ * necessary memory was allocated, or NULL otherwise.
+ *\li On failure, no additional memory is allocated.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS Success
+ *\li #ISC_R_NOMEMORY Resource limit: Out of memory
+ */
+
+isc_result_t
+isc_logconfig_create(isc_log_t *lctx, isc_logconfig_t **lcfgp);
+/*%<
+ * Create the data structure that holds all of the configurable information
+ * about where messages are actually supposed to be sent -- the information
+ * that could changed based on some configuration file, as opposed to the
+ * the category/module specification of isc_log_[v]write[1] that is compiled
+ * into a program, or the debug_level which is dynamic state information.
+ *
+ * Notes:
+ *\li It is necessary to specify the logging context the configuration
+ * will be used with because the number of categories and modules
+ * needs to be known in order to set the configuration. However,
+ * the configuration is not used by the logging context until the
+ * isc_logconfig_use function is called.
+ *
+ *\li The memory context used for operations that allocate memory for
+ * the configuration is that of the logging context, as specified
+ * in the isc_log_create call.
+ *
+ *\li Four default channels are established:
+ *\verbatim
+ * default_syslog
+ * - log to syslog's daemon facility #ISC_LOG_INFO or higher
+ * default_stderr
+ * - log to stderr #ISC_LOG_INFO or higher
+ * default_debug
+ * - log to stderr #ISC_LOG_DEBUG dynamically
+ * null
+ * - log nothing
+ *\endverbatim
+ *
+ * Requires:
+ *\li lctx is a valid logging context.
+ *\li lcftp is not null and *lcfgp is null.
+ *
+ * Ensures:
+ *\li *lcfgp will point to a valid logging context if all of the necessary
+ * memory was allocated, or NULL otherwise.
+ *\li On failure, no additional memory is allocated.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS Success
+ *\li #ISC_R_NOMEMORY Resource limit: Out of memory
+ */
+
+isc_logconfig_t *
+isc_logconfig_get(isc_log_t *lctx);
+/*%<
+ * Returns a pointer to the configuration currently in use by the log context.
+ *
+ * Requires:
+ *\li lctx is a valid context.
+ *
+ * Ensures:
+ *\li The configuration pointer is non-null.
+ *
+ * Returns:
+ *\li The configuration pointer.
+ */
+
+isc_result_t
+isc_logconfig_use(isc_log_t *lctx, isc_logconfig_t *lcfg);
+/*%<
+ * Associate a new configuration with a logging context.
+ *
+ * Notes:
+ *\li This is thread safe. The logging context will lock a mutex
+ * before attempting to swap in the new configuration, and isc_log_doit
+ * (the internal function used by all of isc_log_[v]write[1]) locks
+ * the same lock for the duration of its use of the configuration.
+ *
+ * Requires:
+ *\li lctx is a valid logging context.
+ *\li lcfg is a valid logging configuration.
+ *\li lctx is the same configuration given to isc_logconfig_create
+ * when the configuration was created.
+ *
+ * Ensures:
+ *\li Future calls to isc_log_write will use the new configuration.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS Success
+ *\li #ISC_R_NOMEMORY Resource limit: Out of memory
+ */
+
+void
+isc_log_destroy(isc_log_t **lctxp);
+/*%<
+ * Deallocate the memory associated with a logging context.
+ *
+ * Requires:
+ *\li *lctx is a valid logging context.
+ *
+ * Ensures:
+ *\li All of the memory associated with the logging context is returned
+ * to the free memory pool.
+ *
+ *\li Any open files are closed.
+ *
+ *\li The logging context is marked as invalid.
+ */
+
+void
+isc_logconfig_destroy(isc_logconfig_t **lcfgp);
+/*%<
+ * Destroy a logging configuration.
+ *
+ * Notes:
+ *\li This function cannot be used directly with the return value of
+ * isc_logconfig_get, because a logging context must always have
+ * a valid configuration associated with it.
+ *
+ * Requires:
+ *\li lcfgp is not null and *lcfgp is a valid logging configuration.
+ *\li The logging configuration is not in use by an existing logging context.
+ *
+ * Ensures:
+ *\li All memory allocated for the configuration is freed.
+ *
+ *\li The configuration is marked as invalid.
+ */
+
+void
+isc_log_registercategories(isc_log_t *lctx, isc_logcategory_t categories[]);
+/*%<
+ * Identify logging categories a library will use.
+ *
+ * Notes:
+ *\li A category should only be registered once, but no mechanism enforces
+ * this rule.
+ *
+ *\li The end of the categories array is identified by a NULL name.
+ *
+ *\li Because the name is used by #ISC_LOG_PRINTCATEGORY, it should not
+ * be altered or destroyed after isc_log_registercategories().
+ *
+ *\li Because each element of the categories array is used by
+ * isc_log_categorybyname, it should not be altered or destroyed
+ * after registration.
+ *
+ *\li The value of the id integer in each structure is overwritten
+ * by this function, and so id need not be initialized to any particular
+ * value prior to the function call.
+ *
+ *\li A subsequent call to isc_log_registercategories with the same
+ * logging context (but new categories) will cause the last
+ * element of the categories array from the prior call to have
+ * its "name" member changed from NULL to point to the new
+ * categories array, and its "id" member set to UINT_MAX.
+ *
+ * Requires:
+ *\li lctx is a valid logging context.
+ *\li categories != NULL.
+ *\li categories[0].name != NULL.
+ *
+ * Ensures:
+ * \li There are references to each category in the logging context,
+ * so they can be used with isc_log_usechannel() and isc_log_write().
+ */
+
+void
+isc_log_registermodules(isc_log_t *lctx, isc_logmodule_t modules[]);
+/*%<
+ * Identify logging categories a library will use.
+ *
+ * Notes:
+ *\li A module should only be registered once, but no mechanism enforces
+ * this rule.
+ *
+ *\li The end of the modules array is identified by a NULL name.
+ *
+ *\li Because the name is used by #ISC_LOG_PRINTMODULE, it should not
+ * be altered or destroyed after isc_log_registermodules().
+ *
+ *\li Because each element of the modules array is used by
+ * isc_log_modulebyname, it should not be altered or destroyed
+ * after registration.
+ *
+ *\li The value of the id integer in each structure is overwritten
+ * by this function, and so id need not be initialized to any particular
+ * value prior to the function call.
+ *
+ *\li A subsequent call to isc_log_registermodules with the same
+ * logging context (but new modules) will cause the last
+ * element of the modules array from the prior call to have
+ * its "name" member changed from NULL to point to the new
+ * modules array, and its "id" member set to UINT_MAX.
+ *
+ * Requires:
+ *\li lctx is a valid logging context.
+ *\li modules != NULL.
+ *\li modules[0].name != NULL;
+ *
+ * Ensures:
+ *\li Each module has a reference in the logging context, so they can be
+ * used with isc_log_usechannel() and isc_log_write().
+ */
+
+isc_result_t
+isc_log_createchannel(isc_logconfig_t *lcfg, const char *name,
+ unsigned int type, int level,
+ const isc_logdestination_t *destination,
+ unsigned int flags);
+/*%<
+ * Specify the parameters of a logging channel.
+ *
+ * Notes:
+ *\li The name argument is copied to memory in the logging context, so
+ * it can be altered or destroyed after isc_log_createchannel().
+ *
+ *\li Defining a very large number of channels will have a performance
+ * impact on isc_log_usechannel(), since the names are searched
+ * linearly until a match is made. This same issue does not affect
+ * isc_log_write, however.
+ *
+ *\li Channel names can be redefined; this is primarily useful for programs
+ * that want their own definition of default_syslog, default_debug
+ * and default_stderr.
+ *
+ *\li Any channel that is redefined will not affect logging that was
+ * already directed to its original definition, _except_ for the
+ * default_stderr channel. This case is handled specially so that
+ * the default logging category can be changed by redefining
+ * default_stderr. (XXXDCL Though now that I think of it, the default
+ * logging category can be changed with only one additional function
+ * call by defining a new channel and then calling isc_log_usechannel()
+ * for #ISC_LOGCATEGORY_DEFAULT.)
+ *
+ *\li Specifying #ISC_LOG_PRINTTIME or #ISC_LOG_PRINTTAG for syslog is allowed,
+ * but probably not what you wanted to do.
+ *
+ * #ISC_LOG_DEBUGONLY will mark the channel as usable only when the
+ * debug level of the logging context (see isc_log_setdebuglevel)
+ * is non-zero.
+ *
+ * Requires:
+ *\li lcfg is a valid logging configuration.
+ *
+ *\li name is not NULL.
+ *
+ *\li type is #ISC_LOG_TOSYSLOG, #ISC_LOG_TOFILE, #ISC_LOG_TOFILEDESC or
+ * #ISC_LOG_TONULL.
+ *
+ *\li destination is not NULL unless type is #ISC_LOG_TONULL.
+ *
+ *\li level is >= #ISC_LOG_CRITICAL (the most negative logging level).
+ *
+ *\li flags does not include any bits aside from the ISC_LOG_PRINT* bits
+ * or #ISC_LOG_DEBUGONLY.
+ *
+ * Ensures:
+ *\li #ISC_R_SUCCESS
+ * A channel with the given name is usable with
+ * isc_log_usechannel().
+ *
+ *\li #ISC_R_NOMEMORY or #ISC_R_UNEXPECTED
+ * No additional memory is being used by the logging context.
+ * Any channel that previously existed with the given name
+ * is not redefined.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS Success
+ *\li #ISC_R_NOMEMORY Resource limit: Out of memory
+ *\li #ISC_R_UNEXPECTED type was out of range and REQUIRE()
+ * was disabled.
+ */
+
+isc_result_t
+isc_log_usechannel(isc_logconfig_t *lcfg, const char *name,
+ const isc_logcategory_t *category,
+ const isc_logmodule_t *module);
+/*%<
+ * Associate a named logging channel with a category and module that
+ * will use it.
+ *
+ * Notes:
+ *\li The name is searched for linearly in the set of known channel names
+ * until a match is found. (Note the performance impact of a very large
+ * number of named channels.) When multiple channels of the same
+ * name are defined, the most recent definition is found.
+ *
+ *\li Specifying a very large number of channels for a category will have
+ * a moderate impact on performance in isc_log_write(), as each
+ * call looks up the category for the start of a linked list, which
+ * it follows all the way to the end to find matching modules. The
+ * test for matching modules is integral, though.
+ *
+ *\li If category is NULL, then the channel is associated with the indicated
+ * module for all known categories (including the "default" category).
+ *
+ *\li If module is NULL, then the channel is associated with every module
+ * that uses that category.
+ *
+ *\li Passing both category and module as NULL would make every log message
+ * use the indicated channel.
+ *
+ * \li Specifying a channel that is #ISC_LOG_TONULL for a category/module pair
+ * has no effect on any other channels associated with that pair,
+ * regardless of ordering. Thus you cannot use it to "mask out" one
+ * category/module pair when you have specified some other channel that
+ * is also used by that category/module pair.
+ *
+ * Requires:
+ *\li lcfg is a valid logging configuration.
+ *
+ *\li category is NULL or has an id that is in the range of known ids.
+ *
+ * module is NULL or has an id that is in the range of known ids.
+ *
+ * Ensures:
+ *\li #ISC_R_SUCCESS
+ * The channel will be used by the indicated category/module
+ * arguments.
+ *
+ *\li #ISC_R_NOMEMORY
+ * If assignment for a specific category has been requested,
+ * the channel has not been associated with the indicated
+ * category/module arguments and no additional memory is
+ * used by the logging context.
+ * If assignment for all categories has been requested
+ * then _some_ may have succeeded (starting with category
+ * "default" and progressing through the order of categories
+ * passed to isc_log_registercategories()) and additional memory
+ * is being used by whatever assignments succeeded.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS Success
+ *\li #ISC_R_NOMEMORY Resource limit: Out of memory
+ */
+
+/* Attention: next four comments PRECEED code */
+/*!
+ * \brief
+ * Write a message to the log channels.
+ *
+ * Notes:
+ *\li Log messages containing natural language text should be logged with
+ * isc_log_iwrite() to allow for localization.
+ *
+ *\li lctx can be NULL; this is allowed so that programs which use
+ * libraries that use the ISC logging system are not required to
+ * also use it.
+ *
+ *\li The format argument is a printf(3) string, with additional arguments
+ * as necessary.
+ *
+ * Requires:
+ *\li lctx is a valid logging context.
+ *
+ *\li The category and module arguments must have ids that are in the
+ * range of known ids, as established by isc_log_registercategories()
+ * and isc_log_registermodules().
+ *
+ *\li level != #ISC_LOG_DYNAMIC. ISC_LOG_DYNAMIC is used only to define
+ * channels, and explicit debugging level must be identified for
+ * isc_log_write() via ISC_LOG_DEBUG(level).
+ *
+ *\li format != NULL.
+ *
+ * Ensures:
+ *\li The log message is written to every channel associated with the
+ * indicated category/module pair.
+ *
+ * Returns:
+ *\li Nothing. Failure to log a message is not construed as a
+ * meaningful error.
+ */
+void
+isc_log_write(isc_log_t *lctx, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level,
+ const char *format, ...)
+
+ISC_FORMAT_PRINTF(5, 6);
+
+/*%
+ * Write a message to the log channels.
+ *
+ * Notes:
+ *\li lctx can be NULL; this is allowed so that programs which use
+ * libraries that use the ISC logging system are not required to
+ * also use it.
+ *
+ *\li The format argument is a printf(3) string, with additional arguments
+ * as necessary.
+ *
+ * Requires:
+ *\li lctx is a valid logging context.
+ *
+ *\li The category and module arguments must have ids that are in the
+ * range of known ids, as established by isc_log_registercategories()
+ * and isc_log_registermodules().
+ *
+ *\li level != #ISC_LOG_DYNAMIC. ISC_LOG_DYNAMIC is used only to define
+ * channels, and explicit debugging level must be identified for
+ * isc_log_write() via ISC_LOG_DEBUG(level).
+ *
+ *\li format != NULL.
+ *
+ * Ensures:
+ *\li The log message is written to every channel associated with the
+ * indicated category/module pair.
+ *
+ * Returns:
+ *\li Nothing. Failure to log a message is not construed as a
+ * meaningful error.
+ */
+void
+isc_log_vwrite(isc_log_t *lctx, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level,
+ const char *format, va_list args)
+
+ISC_FORMAT_PRINTF(5, 0);
+
+/*%
+ * Write a message to the log channels, pruning duplicates that occur within
+ * a configurable amount of seconds (see isc_log_[sg]etduplicateinterval).
+ * This function is otherwise identical to isc_log_write().
+ */
+void
+isc_log_write1(isc_log_t *lctx, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level, const char *format, ...)
+
+ISC_FORMAT_PRINTF(5, 6);
+
+/*%
+ * Write a message to the log channels, pruning duplicates that occur within
+ * a configurable amount of seconds (see isc_log_[sg]etduplicateinterval).
+ * This function is otherwise identical to isc_log_vwrite().
+ */
+void
+isc_log_vwrite1(isc_log_t *lctx, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level, const char *format,
+ va_list args)
+
+ISC_FORMAT_PRINTF(5, 0);
+
+/*%
+ * These are four internationalized versions of the isc_log_[v]write[1]
+ * functions.
+ *
+ * The only difference is that they take arguments for a message
+ * catalog, message set, and message number, all immediately preceding the
+ * format argument. The format argument becomes the default text, a la
+ * isc_msgcat_get. If the message catalog is NULL, no lookup is attempted
+ * for a message -- which makes the message set and message number irrelevant,
+ * and the non-internationalized call should have probably been used instead.
+ *
+ * Yes, that means there are now *eight* interfaces to logging a message.
+ * Sheesh. Make the madness stop!
+ */
+/*@{*/
+void
+isc_log_iwrite(isc_log_t *lctx, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level,
+ isc_msgcat_t *msgcat, int msgset, int message,
+ const char *format, ...)
+ISC_FORMAT_PRINTF(8, 9);
+
+void
+isc_log_ivwrite(isc_log_t *lctx, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level,
+ isc_msgcat_t *msgcat, int msgset, int message,
+ const char *format, va_list args)
+ISC_FORMAT_PRINTF(8, 0);
+
+void
+isc_log_iwrite1(isc_log_t *lctx, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level,
+ isc_msgcat_t *msgcat, int msgset, int message,
+ const char *format, ...)
+ISC_FORMAT_PRINTF(8, 9);
+
+void
+isc_log_ivwrite1(isc_log_t *lctx, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level,
+ isc_msgcat_t *msgcat, int msgset, int message,
+ const char *format, va_list args)
+ISC_FORMAT_PRINTF(8, 0);
+/*@}*/
+
+void
+isc_log_setdebuglevel(isc_log_t *lctx, unsigned int level);
+/*%<
+ * Set the debugging level used for logging.
+ *
+ * Notes:
+ *\li Setting the debugging level to 0 disables debugging log messages.
+ *
+ * Requires:
+ *\li lctx is a valid logging context.
+ *
+ * Ensures:
+ *\li The debugging level is set to the requested value.
+ */
+
+unsigned int
+isc_log_getdebuglevel(isc_log_t *lctx);
+/*%<
+ * Get the current debugging level.
+ *
+ * Notes:
+ *\li This is provided so that a program can have a notion of
+ * "increment debugging level" or "decrement debugging level"
+ * without needing to keep track of what the current level is.
+ *
+ *\li A return value of 0 indicates that debugging messages are disabled.
+ *
+ * Requires:
+ *\li lctx is a valid logging context.
+ *
+ * Ensures:
+ *\li The current logging debugging level is returned.
+ */
+
+isc_boolean_t
+isc_log_wouldlog(isc_log_t *lctx, int level);
+/*%<
+ * Determine whether logging something to 'lctx' at 'level' would
+ * actually cause something to be logged somewhere.
+ *
+ * If #ISC_FALSE is returned, it is guaranteed that nothing would
+ * be logged, allowing the caller to omit unnecessary
+ * isc_log_write() calls and possible message preformatting.
+ */
+
+void
+isc_log_setduplicateinterval(isc_logconfig_t *lcfg, unsigned int interval);
+/*%<
+ * Set the interval over which duplicate log messages will be ignored
+ * by isc_log_[v]write1(), in seconds.
+ *
+ * Notes:
+ *\li Increasing the duplicate interval from X to Y will not necessarily
+ * filter out duplicates of messages logged in Y - X seconds since the
+ * increase. (Example: Message1 is logged at midnight. Message2
+ * is logged at 00:01:00, when the interval is only 30 seconds, causing
+ * Message1 to be expired from the log message history. Then the interval
+ * is increased to 3000 (five minutes) and at 00:04:00 Message1 is logged
+ * again. It will appear the second time even though less than five
+ * passed since the first occurrence.
+ *
+ * Requires:
+ *\li lctx is a valid logging context.
+ */
+
+unsigned int
+isc_log_getduplicateinterval(isc_logconfig_t *lcfg);
+/*%<
+ * Get the current duplicate filtering interval.
+ *
+ * Requires:
+ *\li lctx is a valid logging context.
+ *
+ * Returns:
+ *\li The current duplicate filtering interval.
+ */
+
+isc_result_t
+isc_log_settag(isc_logconfig_t *lcfg, const char *tag);
+/*%<
+ * Set the program name or other identifier for #ISC_LOG_PRINTTAG.
+ *
+ * Requires:
+ *\li lcfg is a valid logging configuration.
+ *
+ * Notes:
+ *\li If this function has not set the tag to a non-NULL, non-empty value,
+ * then the #ISC_LOG_PRINTTAG channel flag will not print anything.
+ * Unlike some implementations of syslog on Unix systems, you *must* set
+ * the tag in order to get it logged. It is not implicitly derived from
+ * the program name (which is pretty impossible to infer portably).
+ *
+ *\li Setting the tag to NULL or the empty string will also cause the
+ * #ISC_LOG_PRINTTAG channel flag to not print anything. If tag equals the
+ * empty string, calls to isc_log_gettag will return NULL.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS Success
+ *\li #ISC_R_NOMEMORY Resource Limit: Out of memory
+ *
+ * XXXDCL when creating a new isc_logconfig_t, it might be nice if the tag
+ * of the currently active isc_logconfig_t was inherited. this does not
+ * currently happen.
+ */
+
+char *
+isc_log_gettag(isc_logconfig_t *lcfg);
+/*%<
+ * Get the current identifier printed with #ISC_LOG_PRINTTAG.
+ *
+ * Requires:
+ *\li lcfg is a valid logging configuration.
+ *
+ * Notes:
+ *\li Since isc_log_settag() will not associate a zero-length string
+ * with the logging configuration, attempts to do so will cause
+ * this function to return NULL. However, a determined programmer
+ * will observe that (currently) a tag of length greater than zero
+ * could be set, and then modified to be zero length.
+ *
+ * Returns:
+ *\li A pointer to the current identifier, or NULL if none has been set.
+ */
+
+void
+isc_log_opensyslog(const char *tag, int options, int facility);
+/*%<
+ * Initialize syslog logging.
+ *
+ * Notes:
+ *\li XXXDCL NT
+ * This is currently equivalent to openlog(), but is not going to remain
+ * that way. In the meantime, the arguments are all identical to
+ * those used by openlog(3), as follows:
+ *
+ * \code
+ * tag: The string to use in the position of the program
+ * name in syslog messages. Most (all?) syslogs
+ * will use basename(argv[0]) if tag is NULL.
+ *
+ * options: LOG_CONS, LOG_PID, LOG_NDELAY ... whatever your
+ * syslog supports.
+ *
+ * facility: The default syslog facility. This is irrelevant
+ * since isc_log_write will ALWAYS use the channel's
+ * declared facility.
+ * \endcode
+ *
+ *\li Zero effort has been made (yet) to accommodate systems with openlog()
+ * that only takes two arguments, or to identify valid syslog
+ * facilities or options for any given architecture.
+ *
+ *\li It is necessary to call isc_log_opensyslog() to initialize
+ * syslogging on machines which do not support network connections to
+ * syslogd because they require a Unix domain socket to be used. Since
+ * this is a chore to determine at run-time, it is suggested that it
+ * always be called by programs using the ISC logging system.
+ *
+ * Requires:
+ *\li Nothing.
+ *
+ * Ensures:
+ *\li openlog() is called to initialize the syslog system.
+ */
+
+void
+isc_log_closefilelogs(isc_log_t *lctx);
+/*%<
+ * Close all open files used by #ISC_LOG_TOFILE channels.
+ *
+ * Notes:
+ *\li This function is provided for programs that want to use their own
+ * log rolling mechanism rather than the one provided internally.
+ * For example, a program that wanted to keep daily logs would define
+ * a channel which used #ISC_LOG_ROLLNEVER, then once a day would
+ * rename the log file and call isc_log_closefilelogs().
+ *
+ *\li #ISC_LOG_TOFILEDESC channels are unaffected.
+ *
+ * Requires:
+ *\li lctx is a valid context.
+ *
+ * Ensures:
+ *\li The open files are closed and will be reopened when they are
+ * next needed.
+ */
+
+isc_logcategory_t *
+isc_log_categorybyname(isc_log_t *lctx, const char *name);
+/*%<
+ * Find a category by its name.
+ *
+ * Notes:
+ *\li The string name of a category is not required to be unique.
+ *
+ * Requires:
+ *\li lctx is a valid context.
+ *\li name is not NULL.
+ *
+ * Returns:
+ *\li A pointer to the _first_ isc_logcategory_t structure used by "name".
+ *
+ *\li NULL if no category exists by that name.
+ */
+
+isc_logmodule_t *
+isc_log_modulebyname(isc_log_t *lctx, const char *name);
+/*%<
+ * Find a module by its name.
+ *
+ * Notes:
+ *\li The string name of a module is not required to be unique.
+ *
+ * Requires:
+ *\li lctx is a valid context.
+ *\li name is not NULL.
+ *
+ * Returns:
+ *\li A pointer to the _first_ isc_logmodule_t structure used by "name".
+ *
+ *\li NULL if no module exists by that name.
+ */
+
+void
+isc_log_setcontext(isc_log_t *lctx);
+/*%<
+ * Sets the context used by the libisc for logging.
+ *
+ * Requires:
+ *\li lctx be a valid context.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_LOG_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/magic.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/magic.h
new file mode 100644
index 0000000..073de90
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/magic.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: magic.h,v 1.18 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_MAGIC_H
+#define ISC_MAGIC_H 1
+
+/*! \file isc/magic.h */
+
+typedef struct {
+ unsigned int magic;
+} isc__magic_t;
+
+
+/*%
+ * To use this macro the magic number MUST be the first thing in the
+ * structure, and MUST be of type "unsigned int".
+ * The intent of this is to allow magic numbers to be checked even though
+ * the object is otherwise opaque.
+ */
+#define ISC_MAGIC_VALID(a,b) (((a) != NULL) && \
+ (((const isc__magic_t *)(a))->magic == (b)))
+
+#define ISC_MAGIC(a, b, c, d) ((a) << 24 | (b) << 16 | (c) << 8 | (d))
+
+#endif /* ISC_MAGIC_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/md5.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/md5.h
new file mode 100644
index 0000000..dfa586d
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/md5.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2004-2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: md5.h,v 1.20 2010/01/07 23:48:54 tbox Exp $ */
+
+/*! \file isc/md5.h
+ * \brief This is the header file for the MD5 message-digest algorithm.
+ *
+ * The algorithm is due to Ron Rivest. This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ *
+ * Changed so as no longer to depend on Colin Plumb's `usual.h'
+ * header definitions; now uses stuff from dpkg's config.h
+ * - Ian Jackson <ijackson@nyx.cs.du.edu>.
+ * Still in the public domain.
+ */
+
+#ifndef ISC_MD5_H
+#define ISC_MD5_H 1
+
+#include <isc/lang.h>
+#include <isc/platform.h>
+#include <isc/types.h>
+
+#define ISC_MD5_DIGESTLENGTH 16U
+#define ISC_MD5_BLOCK_LENGTH 64U
+
+#ifdef ISC_PLATFORM_OPENSSLHASH
+#include <openssl/evp.h>
+
+typedef EVP_MD_CTX isc_md5_t;
+
+#else
+
+typedef struct {
+ isc_uint32_t buf[4];
+ isc_uint32_t bytes[2];
+ isc_uint32_t in[16];
+} isc_md5_t;
+#endif
+
+ISC_LANG_BEGINDECLS
+
+void
+isc_md5_init(isc_md5_t *ctx);
+
+void
+isc_md5_invalidate(isc_md5_t *ctx);
+
+void
+isc_md5_update(isc_md5_t *ctx, const unsigned char *buf, unsigned int len);
+
+void
+isc_md5_final(isc_md5_t *ctx, unsigned char *digest);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_MD5_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/msgcat.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/msgcat.h
new file mode 100644
index 0000000..fe3d336
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/msgcat.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: msgcat.h,v 1.13 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_MSGCAT_H
+#define ISC_MSGCAT_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file isc/msgcat.h
+ * \brief The ISC Message Catalog
+ * aids internationalization of applications by allowing
+ * messages to be retrieved from locale-specific files instead of
+ * hardwiring them into the application. This allows translations of
+ * messages appropriate to the locale to be supplied without recompiling
+ * the application.
+ *
+ * Notes:
+ *\li It's very important that message catalogs work, even if only the
+ * default_text can be used.
+ *
+ * MP:
+ *\li The caller must ensure appropriate synchronization of
+ * isc_msgcat_open() and isc_msgcat_close(). isc_msgcat_get()
+ * ensures appropriate synchronization.
+ *
+ * Reliability:
+ *\li No anticipated impact.
+ *
+ * Resources:
+ *\li TBS
+ *
+ * \li Security:
+ * No anticipated impact.
+ *
+ * \li Standards:
+ * None.
+ */
+
+/*****
+ ***** Imports
+ *****/
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+ISC_LANG_BEGINDECLS
+
+/*****
+ ***** Methods
+ *****/
+
+void
+isc_msgcat_open(const char *name, isc_msgcat_t **msgcatp);
+/*%<
+ * Open a message catalog.
+ *
+ * Notes:
+ *
+ *\li If memory cannot be allocated or other failures occur, *msgcatp
+ * will be set to NULL. If a NULL msgcat is given to isc_msgcat_get(),
+ * the default_text will be returned, ensuring that some message text
+ * will be available, no matter what's going wrong.
+ *
+ * Requires:
+ *
+ *\li 'name' is a valid string.
+ *
+ *\li msgcatp != NULL && *msgcatp == NULL
+ */
+
+void
+isc_msgcat_close(isc_msgcat_t **msgcatp);
+/*%<
+ * Close a message catalog.
+ *
+ * Notes:
+ *
+ *\li Any string pointers returned by prior calls to isc_msgcat_get() are
+ * invalid after isc_msgcat_close() has been called and must not be
+ * used.
+ *
+ * Requires:
+ *
+ *\li *msgcatp is a valid message catalog or is NULL.
+ *
+ * Ensures:
+ *
+ *\li All resources associated with the message catalog are released.
+ *
+ *\li *msgcatp == NULL
+ */
+
+const char *
+isc_msgcat_get(isc_msgcat_t *msgcat, int set, int message,
+ const char *default_text);
+/*%<
+ * Get message 'message' from message set 'set' in 'msgcat'. If it
+ * is not available, use 'default_text'.
+ *
+ * Requires:
+ *
+ *\li 'msgcat' is a valid message catalog or is NULL.
+ *
+ *\li set > 0
+ *
+ *\li message > 0
+ *
+ *\li 'default_text' is a valid string.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_MSGCAT_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/msgs.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/msgs.h
new file mode 100644
index 0000000..60c5c7c
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/msgs.h
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000-2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: msgs.h,v 1.19 2009/10/01 23:48:08 tbox Exp $ */
+
+#ifndef ISC_MSGS_H
+#define ISC_MSGS_H 1
+
+/*! \file isc/msgs.h */
+
+#include <isc/lib.h> /* Provide isc_msgcat global variable. */
+#include <isc/msgcat.h> /* Provide isc_msgcat_*() functions. */
+
+/*@{*/
+/*!
+ * \brief Message sets, named per source file, excepting "GENERAL".
+ *
+ * IMPORTANT: The original list is alphabetical, but any new sets must
+ * be added to the end.
+ */
+#define ISC_MSGSET_GENERAL 1
+/* ISC_RESULT_RESULTSET 2 */ /* XXX */
+/* ISC_RESULT_UNAVAILABLESET 3 */ /* XXX */
+#define ISC_MSGSET_APP 4
+#define ISC_MSGSET_COMMANDLINE 5
+#define ISC_MSGSET_ENTROPY 6
+#define ISC_MSGSET_IFITERIOCTL 7
+#define ISC_MSGSET_IFITERSYSCTL 8
+#define ISC_MSGSET_LEX 9
+#define ISC_MSGSET_LOG 10
+#define ISC_MSGSET_MEM 11
+#define ISC_MSGSET_NETADDR 12
+#define ISC_MSGSET_PRINT 13
+#define ISC_MSGSET_RESULT 14
+#define ISC_MSGSET_RWLOCK 15
+#define ISC_MSGSET_SOCKADDR 16
+#define ISC_MSGSET_SOCKET 17
+#define ISC_MSGSET_TASK 18
+#define ISC_MSGSET_TIMER 19
+#define ISC_MSGSET_UTIL 20
+#define ISC_MSGSET_IFITERGETIFADDRS 21
+/*@}*/
+
+/*@{*/
+/*!
+ * Message numbers
+ * are only required to be unique per message set,
+ * but are unique throughout the entire catalog to not be as confusing when
+ * debugging.
+ *
+ * The initial numbering was done by multiply by 100 the set number the
+ * message appears in then adding the incremental message number.
+ */
+#define ISC_MSG_FAILED 101 /*%< "failed" */
+#define ISC_MSG_SUCCEEDED 102 /*%< Compatible with "failed" */
+#define ISC_MSG_SUCCESS 103 /*%< More usual way to say "success" */
+#define ISC_MSG_STARTING 104 /*%< As in "daemon: starting" */
+#define ISC_MSG_STOPING 105 /*%< As in "daemon: stopping" */
+#define ISC_MSG_ENTERING 106 /*%< As in "some_subr: entering" */
+#define ISC_MSG_EXITING 107 /*%< As in "some_subr: exiting" */
+#define ISC_MSG_CALLING 108 /*%< As in "calling some_subr()" */
+#define ISC_MSG_RETURNED 109 /*%< As in "some_subr: returned <foo>" */
+#define ISC_MSG_FATALERROR 110 /*%< "fatal error" */
+#define ISC_MSG_SHUTTINGDOWN 111 /*%< "shutting down" */
+#define ISC_MSG_RUNNING 112 /*%< "running" */
+#define ISC_MSG_WAIT 113 /*%< "wait" */
+#define ISC_MSG_WAITUNTIL 114 /*%< "waituntil" */
+
+#define ISC_MSG_SIGNALSETUP 201 /*%< "handle_signal() %d setup: %s" */
+
+#define ISC_MSG_ILLEGALOPT 301 /*%< "illegal option" */
+#define ISC_MSG_OPTNEEDARG 302 /*%< "option requires an argument" */
+
+#define ISC_MSG_ENTROPYSTATS 401 /*%< "Entropy pool %p: refcnt %u ..." */
+
+#define ISC_MSG_MAKESCANSOCKET 501 /*%< "making interface scan socket: %s" */
+#define ISC_MSG_GETIFCONFIG 502 /*%< "get interface configuration: %s" */
+#define ISC_MSG_BUFFERMAX 503 /*%< "... maximum buffer size exceeded" */
+#define ISC_MSG_GETDESTADDR 504 /*%< "%s: getting destination address: %s" */
+#define ISC_MSG_GETNETMASK 505 /*%< "%s: getting netmask: %s" */
+#define ISC_MSG_GETBCSTADDR 506 /*%< "%s: getting broadcast address: %s" */
+
+#define ISC_MSG_GETIFLISTSIZE 601 /*%< "getting interface list size: ..." */
+#define ISC_MSG_GETIFLIST 602 /*%< "getting interface list: ..." */
+#define ISC_MSG_UNEXPECTEDTYPE 603 /*%< "... unexpected ... message type" */
+
+#define ISC_MSG_UNEXPECTEDSTATE 701 /*%< "Unexpected state %d" */
+
+#define ISC_MSG_BADTIME 801 /*%< "Bad 00 99:99:99.999 " */
+#define ISC_MSG_LEVEL 802 /*%< "level %d: " */
+
+#define ISC_MSG_ADDTRACE 901 /*%< "add %p size %u " */
+#define ISC_MSG_DELTRACE 902 /*%< "del %p size %u " */
+#define ISC_MSG_POOLSTATS 903 /*%< "[Pool statistics]\n" */
+#define ISC_MSG_POOLNAME 904 /*%< "name" */
+#define ISC_MSG_POOLSIZE 905 /*%< "size" */
+#define ISC_MSG_POOLMAXALLOC 906 /*%< "maxalloc" */
+#define ISC_MSG_POOLALLOCATED 907 /*%< "allocated" */
+#define ISC_MSG_POOLFREECOUNT 908 /*%< "freecount" */
+#define ISC_MSG_POOLFREEMAX 909 /*%< "freemax" */
+#define ISC_MSG_POOLFILLCOUNT 910 /*%< "fillcount" */
+#define ISC_MSG_POOLGETS 911 /*%< "gets" */
+#define ISC_MSG_DUMPALLOC 912 /*%< "DUMP OF ALL OUTSTANDING MEMORY ..." */
+#define ISC_MSG_NONE 913 /*%< "\tNone.\n" */
+#define ISC_MSG_PTRFILELINE 914 /*%< "\tptr %p file %s line %u\n" */
+
+#define ISC_MSG_UNKNOWNADDR 1001 /*%< "<unknown address, family %u>" */
+
+#define ISC_MSG_NOLONGDBL 1104 /*%< "long doubles are not supported" */
+
+#define ISC_MSG_PRINTLOCK 1201 /*%< "rwlock %p thread %lu ..." */
+#define ISC_MSG_READ 1202 /*%< "read" */
+#define ISC_MSG_WRITE 1203 /*%< "write" */
+#define ISC_MSG_READING 1204 /*%< "reading" */
+#define ISC_MSG_WRITING 1205 /*%< "writing" */
+#define ISC_MSG_PRELOCK 1206 /*%< "prelock" */
+#define ISC_MSG_POSTLOCK 1207 /*%< "postlock" */
+#define ISC_MSG_PREUNLOCK 1208 /*%< "preunlock" */
+#define ISC_MSG_POSTUNLOCK 1209 /*%< "postunlock" */
+
+#define ISC_MSG_UNKNOWNFAMILY 1301 /*%< "unknown address family: %d" */
+
+#define ISC_MSG_WRITEFAILED 1401 /*%< "write() failed during watcher ..." */
+#define ISC_MSG_READFAILED 1402 /*%< "read() failed during watcher ... " */
+#define ISC_MSG_PROCESSCMSG 1403 /*%< "processing cmsg %p" */
+#define ISC_MSG_IFRECEIVED 1404 /*%< "interface received on ifindex %u" */
+#define ISC_MSG_SENDTODATA 1405 /*%< "sendto pktinfo data, ifindex %u" */
+#define ISC_MSG_DOIORECV 1406 /*%< "doio_recv: recvmsg(%d) %d bytes ..." */
+#define ISC_MSG_PKTRECV 1407 /*%< "packet received correctly" */
+#define ISC_MSG_DESTROYING 1408 /*%< "destroying" */
+#define ISC_MSG_CREATED 1409 /*%< "created" */
+#define ISC_MSG_ACCEPTLOCK 1410 /*%< "internal_accept called, locked ..." */
+#define ISC_MSG_ACCEPTEDCXN 1411 /*%< "accepted connection, new socket %p" */
+#define ISC_MSG_INTERNALRECV 1412 /*%< "internal_recv: task %p got event %p" */
+#define ISC_MSG_INTERNALSEND 1413 /*%< "internal_send: task %p got event %p" */
+#define ISC_MSG_WATCHERMSG 1414 /*%< "watcher got message %d" */
+#define ISC_MSG_SOCKETSREMAIN 1415 /*%< "sockets exist" */
+#define ISC_MSG_PKTINFOPROVIDED 1416 /*%< "pktinfo structure provided, ..." */
+#define ISC_MSG_BOUND 1417 /*%< "bound" */
+#define ISC_MSG_ACCEPTRETURNED 1418 /*%< accept() returned %d/%s */
+#define ISC_MSG_TOOMANYFDS 1419 /*%< %s: too many open file descriptors */
+#define ISC_MSG_ZEROPORT 1420 /*%< dropping source port zero packet */
+#define ISC_MSG_FILTER 1421 /*%< setsockopt(SO_ACCEPTFILTER): %s */
+
+#define ISC_MSG_TOOMANYHANDLES 1422 /*%< %s: too many open WSA event handles: %s */
+#define ISC_MSG_POKED 1423 /*%< "poked flags: %d" */
+
+#define ISC_MSG_AWAKE 1502 /*%< "awake" */
+#define ISC_MSG_WORKING 1503 /*%< "working" */
+#define ISC_MSG_EXECUTE 1504 /*%< "execute action" */
+#define ISC_MSG_EMPTY 1505 /*%< "empty" */
+#define ISC_MSG_DONE 1506 /*%< "done" */
+#define ISC_MSG_QUANTUM 1507 /*%< "quantum" */
+
+#define ISC_MSG_SCHEDULE 1601 /*%< "schedule" */
+#define ISC_MSG_SIGNALSCHED 1602 /*%< "signal (schedule)" */
+#define ISC_MSG_SIGNALDESCHED 1603 /*%< "signal (deschedule)" */
+#define ISC_MSG_SIGNALDESTROY 1604 /*%< "signal (destroy)" */
+#define ISC_MSG_IDLERESCHED 1605 /*%< "idle reschedule" */
+#define ISC_MSG_EVENTNOTALLOC 1606 /*%< "couldn't allocate event" */
+#define ISC_MSG_SCHEDFAIL 1607 /*%< "couldn't schedule timer: %u" */
+#define ISC_MSG_POSTING 1608 /*%< "posting" */
+#define ISC_MSG_WAKEUP 1609 /*%< "wakeup" */
+
+#define ISC_MSG_LOCK 1701 /*%< "LOCK" */
+#define ISC_MSG_LOCKING 1702 /*%< "LOCKING" */
+#define ISC_MSG_LOCKED 1703 /*%< "LOCKED" */
+#define ISC_MSG_UNLOCKED 1704 /*%< "UNLOCKED" */
+#define ISC_MSG_RWLOCK 1705 /*%< "RWLOCK" */
+#define ISC_MSG_RWLOCKED 1706 /*%< "RWLOCKED" */
+#define ISC_MSG_RWUNLOCK 1707 /*%< "RWUNLOCK" */
+#define ISC_MSG_BROADCAST 1708 /*%< "BROADCAST" */
+#define ISC_MSG_SIGNAL 1709 /*%< "SIGNAL" */
+#define ISC_MSG_UTILWAIT 1710 /*%< "WAIT" */
+#define ISC_MSG_WAITED 1711 /*%< "WAITED" */
+
+#define ISC_MSG_GETIFADDRS 1801 /*%< "getting interface addresses: ..." */
+
+/*@}*/
+
+#endif /* ISC_MSGS_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/mutexblock.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/mutexblock.h
new file mode 100644
index 0000000..65bf2bf
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/mutexblock.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: mutexblock.h,v 1.17 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_MUTEXBLOCK_H
+#define ISC_MUTEXBLOCK_H 1
+
+/*! \file isc/mutexblock.h */
+
+#include <isc/lang.h>
+#include <isc/mutex.h>
+#include <isc/types.h>
+
+ISC_LANG_BEGINDECLS
+
+isc_result_t
+isc_mutexblock_init(isc_mutex_t *block, unsigned int count);
+/*%<
+ * Initialize a block of locks. If an error occurs all initialized locks
+ * will be destroyed, if possible.
+ *
+ * Requires:
+ *
+ *\li block != NULL
+ *
+ *\li count > 0
+ *
+ * Returns:
+ *
+ *\li Any code isc_mutex_init() can return is a valid return for this
+ * function.
+ */
+
+isc_result_t
+isc_mutexblock_destroy(isc_mutex_t *block, unsigned int count);
+/*%<
+ * Destroy a block of locks.
+ *
+ * Requires:
+ *
+ *\li block != NULL
+ *
+ *\li count > 0
+ *
+ *\li Each lock in the block be initialized via isc_mutex_init() or
+ * the whole block was initialized via isc_mutex_initblock().
+ *
+ * Returns:
+ *
+ *\li Any code isc_mutex_init() can return is a valid return for this
+ * function.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_MUTEXBLOCK_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/namespace.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/namespace.h
new file mode 100644
index 0000000..cd4ec9a
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/namespace.h
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2009-2012 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+#ifndef ISCAPI_NAMESPACE_H
+#define ISCAPI_NAMESPACE_H 1
+
+/*%
+ * name space conversions
+ */
+
+#ifdef BIND9
+
+#define isc_app_start isc__app_start
+#define isc_app_ctxstart isc__app_ctxstart
+#define isc_app_onrun isc__app_onrun
+#define isc_app_run isc__app_run
+#define isc_app_ctxrun isc__app_ctxrun
+#define isc_app_shutdown isc__app_shutdown
+#define isc_app_ctxfinish isc__app_ctxfinish
+#define isc_app_ctxshutdown isc__app_ctxshutdown
+#define isc_app_ctxsuspend isc__app_ctxsuspend
+#define isc_app_reload isc__app_reload
+#define isc_app_finish isc__app_finish
+#define isc_app_block isc__app_block
+#define isc_app_unblock isc__app_unblock
+#define isc_appctx_create isc__appctx_create
+#define isc_appctx_destroy isc__appctx_destroy
+#define isc_appctx_settaskmgr isc__appctx_settaskmgr
+#define isc_appctx_setsocketmgr isc__appctx_setsocketmgr
+#define isc_appctx_settimermgr isc__appctx_settimermgr
+
+#define isc_mem_checkdestroyed isc__mem_checkdestroyed
+#define isc_mem_createx isc__mem_createx
+#define isc_mem_createx2 isc__mem_createx2
+#define isc_mem_create isc__mem_create
+#define isc_mem_create2 isc__mem_create2
+#define isc_mem_attach isc__mem_attach
+#define isc_mem_detach isc__mem_detach
+#define isc__mem_putanddetach isc___mem_putanddetach
+#define isc_mem_destroy isc__mem_destroy
+#define isc_mem_ondestroy isc__mem_ondestroy
+#define isc__mem_get isc___mem_get
+#define isc__mem_put isc___mem_put
+#define isc_mem_stats isc__mem_stats
+#define isc__mem_allocate isc___mem_allocate
+#define isc__mem_free isc___mem_free
+#define isc__mem_strdup isc___mem_strdup
+#define isc__mem_reallocate isc___mem_reallocate
+#define isc_mem_references isc__mem_references
+#define isc_mem_setdestroycheck isc__mem_setdestroycheck
+#define isc_mem_setquota isc__mem_setquota
+#define isc_mem_getname isc__mem_getname
+#define isc_mem_getquota isc__mem_getquota
+#define isc_mem_gettag isc__mem_gettag
+#define isc_mem_inuse isc__mem_inuse
+#define isc_mem_isovermem isc__mem_isovermem
+#define isc_mem_setname isc__mem_setname
+#define isc_mem_setwater isc__mem_setwater
+#define isc_mem_printallactive isc__mem_printallactive
+#define isc_mem_waterack isc__mem_waterack
+#define isc_mempool_create isc__mempool_create
+#define isc_mempool_setname isc__mempool_setname
+#define isc_mempool_destroy isc__mempool_destroy
+#define isc_mempool_associatelock isc__mempool_associatelock
+#define isc__mempool_get isc___mempool_get
+#define isc__mempool_put isc___mempool_put
+#define isc_mempool_setfreemax isc__mempool_setfreemax
+#define isc_mempool_getfreemax isc__mempool_getfreemax
+#define isc_mempool_getfreecount isc__mempool_getfreecount
+#define isc_mempool_setmaxalloc isc__mempool_setmaxalloc
+#define isc_mempool_getmaxalloc isc__mempool_getmaxalloc
+#define isc_mempool_getallocated isc__mempool_getallocated
+#define isc_mempool_setfillcount isc__mempool_setfillcount
+#define isc_mempool_getfillcount isc__mempool_getfillcount
+
+#define isc_socket_create isc__socket_create
+#define isc_socket_dup isc__socket_dup
+#define isc_socket_attach isc__socket_attach
+#define isc_socket_detach isc__socket_detach
+#define isc_socketmgr_create isc__socketmgr_create
+#define isc_socketmgr_create2 isc__socketmgr_create2
+#define isc_socketmgr_destroy isc__socketmgr_destroy
+#define isc_socket_open isc__socket_open
+#define isc_socket_close isc__socket_close
+#define isc_socket_recvv isc__socket_recvv
+#define isc_socket_recv isc__socket_recv
+#define isc_socket_recv2 isc__socket_recv2
+#define isc_socket_send isc__socket_send
+#define isc_socket_sendto isc__socket_sendto
+#define isc_socket_sendv isc__socket_sendv
+#define isc_socket_sendtov isc__socket_sendtov
+#define isc_socket_sendto2 isc__socket_sendto2
+#define isc_socket_cleanunix isc__socket_cleanunix
+#define isc_socket_permunix isc__socket_permunix
+#define isc_socket_bind isc__socket_bind
+#define isc_socket_filter isc__socket_filter
+#define isc_socket_listen isc__socket_listen
+#define isc_socket_accept isc__socket_accept
+#define isc_socket_connect isc__socket_connect
+#define isc_socket_getfd isc__socket_getfd
+#define isc_socket_getname isc__socket_getname
+#define isc_socket_gettag isc__socket_gettag
+#define isc_socket_getpeername isc__socket_getpeername
+#define isc_socket_getsockname isc__socket_getsockname
+#define isc_socket_cancel isc__socket_cancel
+#define isc_socket_gettype isc__socket_gettype
+#define isc_socket_isbound isc__socket_isbound
+#define isc_socket_ipv6only isc__socket_ipv6only
+#define isc_socket_setname isc__socket_setname
+#define isc_socketmgr_getmaxsockets isc__socketmgr_getmaxsockets
+#define isc_socketmgr_setstats isc__socketmgr_setstats
+#define isc_socketmgr_setreserved isc__socketmgr_setreserved
+#define isc__socketmgr_maxudp isc___socketmgr_maxudp
+#define isc_socket_fdwatchcreate isc__socket_fdwatchcreate
+#define isc_socket_fdwatchpoke isc__socket_fdwatchpoke
+
+#define isc_task_create isc__task_create
+#define isc_task_attach isc__task_attach
+#define isc_task_detach isc__task_detach
+/* #define isc_task_exiting isc__task_exiting XXXMPA */
+#define isc_task_send isc__task_send
+#define isc_task_sendanddetach isc__task_sendanddetach
+#define isc_task_purgerange isc__task_purgerange
+#define isc_task_purge isc__task_purge
+#define isc_task_purgeevent isc__task_purgeevent
+#define isc_task_unsendrange isc__task_unsendrange
+#define isc_task_unsend isc__task_unsend
+#define isc_task_onshutdown isc__task_onshutdown
+#define isc_task_shutdown isc__task_shutdown
+#define isc_task_destroy isc__task_destroy
+#define isc_task_setname isc__task_setname
+#define isc_task_getname isc__task_getname
+#define isc_task_gettag isc__task_gettag
+#define isc_task_getcurrenttime isc__task_getcurrenttime
+#define isc_taskmgr_create isc__taskmgr_create
+#define isc_taskmgr_setmode isc__taskmgr_setmode
+#define isc_taskmgr_mode isc__taskmgr_mode
+#define isc_taskmgr_destroy isc__taskmgr_destroy
+#define isc_task_beginexclusive isc__task_beginexclusive
+#define isc_task_endexclusive isc__task_endexclusive
+#define isc_task_setprivilege isc__task_setprivilege
+#define isc_task_privilege isc__task_privilege
+
+#define isc_timer_create isc__timer_create
+#define isc_timer_reset isc__timer_reset
+#define isc_timer_gettype isc__timer_gettype
+#define isc_timer_touch isc__timer_touch
+#define isc_timer_attach isc__timer_attach
+#define isc_timer_detach isc__timer_detach
+#define isc_timermgr_create isc__timermgr_create
+#define isc_timermgr_poke isc__timermgr_poke
+#define isc_timermgr_destroy isc__timermgr_destroy
+
+#endif /* BIND9 */
+
+#endif /* ISCAPI_NAMESPACE_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/netaddr.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/netaddr.h
new file mode 100644
index 0000000..954d770
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/netaddr.h
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: netaddr.h,v 1.37 2009/01/17 23:47:43 tbox Exp $ */
+
+#ifndef ISC_NETADDR_H
+#define ISC_NETADDR_H 1
+
+/*! \file isc/netaddr.h */
+
+#include <isc/lang.h>
+#include <isc/net.h>
+#include <isc/types.h>
+
+#ifdef ISC_PLATFORM_HAVESYSUNH
+#include <sys/types.h>
+#include <sys/un.h>
+#endif
+
+ISC_LANG_BEGINDECLS
+
+struct isc_netaddr {
+ unsigned int family;
+ union {
+ struct in_addr in;
+ struct in6_addr in6;
+#ifdef ISC_PLATFORM_HAVESYSUNH
+ char un[sizeof(((struct sockaddr_un *)0)->sun_path)];
+#endif
+ } type;
+ isc_uint32_t zone;
+};
+
+isc_boolean_t
+isc_netaddr_equal(const isc_netaddr_t *a, const isc_netaddr_t *b);
+
+/*%<
+ * Compare network addresses 'a' and 'b'. Return #ISC_TRUE if
+ * they are equal, #ISC_FALSE if not.
+ */
+
+isc_boolean_t
+isc_netaddr_eqprefix(const isc_netaddr_t *a, const isc_netaddr_t *b,
+ unsigned int prefixlen);
+/*%<
+ * Compare the 'prefixlen' most significant bits of the network
+ * addresses 'a' and 'b'. If 'b''s scope is zero then 'a''s scope is
+ * ignored. Return #ISC_TRUE if they are equal, #ISC_FALSE if not.
+ */
+
+isc_result_t
+isc_netaddr_masktoprefixlen(const isc_netaddr_t *s, unsigned int *lenp);
+/*%<
+ * Convert a netmask in 's' into a prefix length in '*lenp'.
+ * The mask should consist of zero or more '1' bits in the most
+ * most significant part of the address, followed by '0' bits.
+ * If this is not the case, #ISC_R_MASKNONCONTIG is returned.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_MASKNONCONTIG
+ */
+
+isc_result_t
+isc_netaddr_totext(const isc_netaddr_t *netaddr, isc_buffer_t *target);
+/*%<
+ * Append a text representation of 'sockaddr' to the buffer 'target'.
+ * The text is NOT null terminated. Handles IPv4 and IPv6 addresses.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOSPACE The text or the null termination did not fit.
+ *\li #ISC_R_FAILURE Unspecified failure
+ */
+
+void
+isc_netaddr_format(const isc_netaddr_t *na, char *array, unsigned int size);
+/*%<
+ * Format a human-readable representation of the network address '*na'
+ * into the character array 'array', which is of size 'size'.
+ * The resulting string is guaranteed to be null-terminated.
+ */
+
+#define ISC_NETADDR_FORMATSIZE \
+ sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:XXX.XXX.XXX.XXX%SSSSSSSSSS")
+/*%<
+ * Minimum size of array to pass to isc_netaddr_format().
+ */
+
+void
+isc_netaddr_fromsockaddr(isc_netaddr_t *netaddr, const isc_sockaddr_t *source);
+
+void
+isc_netaddr_fromin(isc_netaddr_t *netaddr, const struct in_addr *ina);
+
+void
+isc_netaddr_fromin6(isc_netaddr_t *netaddr, const struct in6_addr *ina6);
+
+isc_result_t
+isc_netaddr_frompath(isc_netaddr_t *netaddr, const char *path);
+
+void
+isc_netaddr_setzone(isc_netaddr_t *netaddr, isc_uint32_t zone);
+
+isc_uint32_t
+isc_netaddr_getzone(const isc_netaddr_t *netaddr);
+
+void
+isc_netaddr_any(isc_netaddr_t *netaddr);
+/*%<
+ * Return the IPv4 wildcard address.
+ */
+
+void
+isc_netaddr_any6(isc_netaddr_t *netaddr);
+/*%<
+ * Return the IPv6 wildcard address.
+ */
+
+isc_boolean_t
+isc_netaddr_ismulticast(isc_netaddr_t *na);
+/*%<
+ * Returns ISC_TRUE if the address is a multicast address.
+ */
+
+isc_boolean_t
+isc_netaddr_isexperimental(isc_netaddr_t *na);
+/*%<
+ * Returns ISC_TRUE if the address is a experimental (CLASS E) address.
+ */
+
+isc_boolean_t
+isc_netaddr_islinklocal(isc_netaddr_t *na);
+/*%<
+ * Returns #ISC_TRUE if the address is a link local address.
+ */
+
+isc_boolean_t
+isc_netaddr_issitelocal(isc_netaddr_t *na);
+/*%<
+ * Returns #ISC_TRUE if the address is a site local address.
+ */
+
+void
+isc_netaddr_fromv4mapped(isc_netaddr_t *t, const isc_netaddr_t *s);
+/*%<
+ * Convert an IPv6 v4mapped address into an IPv4 address.
+ */
+
+isc_result_t
+isc_netaddr_prefixok(const isc_netaddr_t *na, unsigned int prefixlen);
+/*
+ * Test whether the netaddr 'na' and 'prefixlen' are consistant.
+ * e.g. prefixlen within range.
+ * na does not have bits set which are not covered by the prefixlen.
+ *
+ * Returns:
+ * ISC_R_SUCCESS
+ * ISC_R_RANGE prefixlen out of range
+ * ISC_R_NOTIMPLEMENTED unsupported family
+ * ISC_R_FAILURE extra bits.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_NETADDR_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/netscope.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/netscope.h
new file mode 100644
index 0000000..163a08c
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/netscope.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: netscope.h,v 1.13 2009/06/25 23:48:02 tbox Exp $ */
+
+#ifndef ISC_NETSCOPE_H
+#define ISC_NETSCOPE_H 1
+
+/*! \file isc/netscope.h */
+
+ISC_LANG_BEGINDECLS
+
+/*%
+ * Convert a string of an IPv6 scope zone to zone index. If the conversion
+ * succeeds, 'zoneid' will store the index value.
+ *
+ * XXXJT: when a standard interface for this purpose is defined,
+ * we should use it.
+ *
+ * Returns:
+ * \li ISC_R_SUCCESS: conversion succeeds
+ * \li ISC_R_FAILURE: conversion fails
+ */
+isc_result_t
+isc_netscope_pton(int af, char *scopename, void *addr, isc_uint32_t *zoneid);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_NETSCOPE_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/ondestroy.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/ondestroy.h
new file mode 100644
index 0000000..64bd643
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/ondestroy.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: ondestroy.h,v 1.14 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_ONDESTROY_H
+#define ISC_ONDESTROY_H 1
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+ISC_LANG_BEGINDECLS
+
+/*! \file isc/ondestroy.h
+ * ondestroy handling.
+ *
+ * Any class ``X'' of objects that wants to send out notifications
+ * on its destruction should declare a field of type isc_ondestroy_t
+ * (call it 'ondest').
+ *
+ * \code
+ * typedef struct {
+ * ...
+ * isc_ondestroy_t ondest;
+ * ...
+ * } X;
+ * \endcode
+ *
+ * When an object ``A'' of type X is created
+ * it must initialize the field ondest with a call to
+ *
+ * \code
+ * isc_ondestroy_init(&A->ondest).
+ * \endcode
+ *
+ * X should also provide a registration function for third-party
+ * objects to call to register their interest in being told about
+ * the destruction of a particular instance of X.
+ *
+ * \code
+ * isc_result_t
+ * X_ondestroy(X *instance, isc_task_t *task,
+ * isc_event_t **eventp) {
+ * return(isc_ondestroy_register(&instance->ondest, task,eventp));
+ * }
+ * \endcode
+ *
+ * Note: locking of the ondestory structure embedded inside of X, is
+ * X's responsibility.
+ *
+ * When an instance of X is destroyed, a call to isc_ondestroy_notify()
+ * sends the notifications:
+ *
+ * \code
+ * X *instance;
+ * isc_ondestroy_t ondest = instance->ondest;
+ *
+ * ... completely cleanup 'instance' here...
+ *
+ * isc_ondestroy_notify(&ondest, instance);
+ * \endcode
+ *
+ *
+ * see lib/dns/zone.c for an ifdef'd-out example.
+ */
+
+struct isc_ondestroy {
+ unsigned int magic;
+ isc_eventlist_t events;
+};
+
+void
+isc_ondestroy_init(isc_ondestroy_t *ondest);
+/*%<
+ * Initialize the on ondest structure. *must* be called before first call
+ * to isc_ondestroy_register().
+ */
+
+isc_result_t
+isc_ondestroy_register(isc_ondestroy_t *ondest, isc_task_t *task,
+ isc_event_t **eventp);
+
+/*%<
+ * Stores task and *eventp away inside *ondest. Ownership of **event is
+ * taken from the caller (and *eventp is set to NULL). The task is attached
+ * to.
+ */
+
+void
+isc_ondestroy_notify(isc_ondestroy_t *ondest, void *sender);
+/*%<
+ * Dispatches the event(s) to the task(s) that were given in
+ * isc_ondestroy_register call(s) (done via calls to
+ * isc_task_sendanddetach()). Before dispatch, the sender value of each
+ * event structure is set to the value of the sender paramater. The
+ * internal structures of the ondest parameter are cleaned out, so no other
+ * cleanup is needed.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_ONDESTROY_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/os.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/os.h
new file mode 100644
index 0000000..3cf59e2
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/os.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: os.h,v 1.12 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_OS_H
+#define ISC_OS_H 1
+
+/*! \file isc/os.h */
+
+#include <isc/lang.h>
+
+ISC_LANG_BEGINDECLS
+
+unsigned int
+isc_os_ncpus(void);
+/*%<
+ * Return the number of CPUs available on the system, or 1 if this cannot
+ * be determined.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_OS_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/parseint.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/parseint.h
new file mode 100644
index 0000000..5047676
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/parseint.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2001, 2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: parseint.h,v 1.9 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_PARSEINT_H
+#define ISC_PARSEINT_H 1
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+/*! \file isc/parseint.h
+ * \brief Parse integers, in a saner way than atoi() or strtoul() do.
+ */
+
+/***
+ *** Functions
+ ***/
+
+ISC_LANG_BEGINDECLS
+
+isc_result_t
+isc_parse_uint32(isc_uint32_t *uip, const char *string, int base);
+
+isc_result_t
+isc_parse_uint16(isc_uint16_t *uip, const char *string, int base);
+
+isc_result_t
+isc_parse_uint8(isc_uint8_t *uip, const char *string, int base);
+/*%<
+ * Parse the null-terminated string 'string' containing a base 'base'
+ * integer, storing the result in '*uip'.
+ * The base is interpreted
+ * as in strtoul(). Unlike strtoul(), leading whitespace, minus or
+ * plus signs are not accepted, and all errors (including overflow)
+ * are reported uniformly through the return value.
+ *
+ * Requires:
+ *\li 'string' points to a null-terminated string
+ *\li 0 <= 'base' <= 36
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_BADNUMBER The string is not numeric (in the given base)
+ *\li #ISC_R_RANGE The number is not representable as the requested type.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_PARSEINT_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/platform.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/platform.h
new file mode 100644
index 0000000..bd11a25
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/platform.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: platform.h.in,v 1.28 2001/11/19 03:08:26 mayer Exp $ */
+
+#ifndef ISC_PLATFORM_H
+#define ISC_PLATFORM_H 1
+
+
+#ifndef ISC_PLATFORM_USEDECLSPEC
+#define LIBISC_EXTERNAL_DATA
+#define LIBDNS_EXTERNAL_DATA
+#define LIBISCCC_EXTERNAL_DATA
+#define LIBISCCFG_EXTERNAL_DATA
+#define LIBBIND9_EXTERNAL_DATA
+#endif /* ISC_PLATFORM_USEDECLSPEC */
+
+/*
+ * Tell emacs to use C mode for this file.
+ *
+ * Local Variables:
+ * mode: c
+ * End:
+ */
+
+#endif /* ISC_PLATFORM_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/portset.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/portset.h
new file mode 100644
index 0000000..774d6bb
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/portset.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2008, 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: portset.h,v 1.6 2009/06/25 05:28:34 marka Exp $ */
+
+/*! \file isc/portset.h
+ * \brief Transport Protocol Port Manipulation Module
+ *
+ * This module provides simple utilities to handle a set of transport protocol
+ * (UDP or TCP) port numbers, e.g., for creating an ACL list. An isc_portset_t
+ * object is an opaque instance of a port set, for which the user can add or
+ * remove a specific port or a range of consecutive ports. This object is
+ * expected to be used as a temporary work space only, and does not protect
+ * simultaneous access from multiple threads. Therefore it must not be stored
+ * in a place that can be accessed from multiple threads.
+ */
+
+#ifndef ISC_PORTSET_H
+#define ISC_PORTSET_H 1
+
+/***
+ *** Imports
+ ***/
+
+#include <isc/net.h>
+
+/***
+ *** Functions
+ ***/
+
+ISC_LANG_BEGINDECLS
+
+isc_result_t
+isc_portset_create(isc_mem_t *mctx, isc_portset_t **portsetp);
+/*%<
+ * Create a port set and initialize it as an empty set.
+ *
+ * Requires:
+ *\li 'mctx' to be valid.
+ *\li 'portsetp' to be non NULL and '*portsetp' to be NULL;
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOMEMORY
+ */
+
+void
+isc_portset_destroy(isc_mem_t *mctx, isc_portset_t **portsetp);
+/*%<
+ * Destroy a port set.
+ *
+ * Requires:
+ *\li 'mctx' to be valid and must be the same context given when the port set
+ * was created.
+ *\li '*portsetp' to be a valid set.
+ */
+
+isc_boolean_t
+isc_portset_isset(isc_portset_t *portset, in_port_t port);
+/*%<
+ * Test whether the given port is stored in the portset.
+ *
+ * Requires:
+ *\li 'portset' to be a valid set.
+ *
+ * Returns
+ * \li #ISC_TRUE if the port is found, ISC_FALSE otherwise.
+ */
+
+unsigned int
+isc_portset_nports(isc_portset_t *portset);
+/*%<
+ * Provides the number of ports stored in the given portset.
+ *
+ * Requires:
+ *\li 'portset' to be a valid set.
+ *
+ * Returns
+ * \li the number of ports stored in portset.
+ */
+
+void
+isc_portset_add(isc_portset_t *portset, in_port_t port);
+/*%<
+ * Add the given port to the portset. The port may or may not be stored in
+ * the portset.
+ *
+ * Requires:
+ *\li 'portlist' to be valid.
+ */
+
+void
+isc_portset_remove(isc_portset_t *portset, in_port_t port);
+/*%<
+ * Remove the given port to the portset. The port may or may not be stored in
+ * the portset.
+ *
+ * Requires:
+ *\li 'portlist' to be valid.
+ */
+
+void
+isc_portset_addrange(isc_portset_t *portset, in_port_t port_lo,
+ in_port_t port_hi);
+/*%<
+ * Add a subset of [port_lo, port_hi] (inclusive) to the portset. Ports in the
+ * subset may or may not be stored in portset.
+ *
+ * Requires:
+ *\li 'portlist' to be valid.
+ *\li port_lo <= port_hi
+ */
+
+void
+isc_portset_removerange(isc_portset_t *portset, in_port_t port_lo,
+ in_port_t port_hi);
+/*%<
+ * Subtract a subset of [port_lo, port_hi] (inclusive) from the portset. Ports
+ * in the subset may or may not be stored in portset.
+ *
+ * Requires:
+ *\li 'portlist' to be valid.
+ *\li port_lo <= port_hi
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_PORTSET_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/print.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/print.h
new file mode 100644
index 0000000..cd1e38e
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/print.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001, 2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: print.h,v 1.26 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_PRINT_H
+#define ISC_PRINT_H 1
+
+/*! \file isc/print.h */
+
+/***
+ *** Imports
+ ***/
+
+#include <isc/formatcheck.h> /* Required for ISC_FORMAT_PRINTF() macro. */
+#include <isc/lang.h>
+#include <isc/platform.h>
+
+/*!
+ * This block allows lib/isc/print.c to be cleanly compiled even if
+ * the platform does not need it. The standard Makefile will still
+ * not compile print.c or archive print.o, so this is just to make test
+ * compilation ("make print.o") easier.
+ */
+#if !defined(ISC_PLATFORM_NEEDVSNPRINTF) && defined(ISC__PRINT_SOURCE)
+#define ISC_PLATFORM_NEEDVSNPRINTF
+#endif
+
+#if !defined(ISC_PLATFORM_NEEDSPRINTF) && defined(ISC__PRINT_SOURCE)
+#define ISC_PLATFORM_NEEDSPRINTF
+#endif
+
+/***
+ *** Macros
+ ***/
+#define ISC_PRINT_QUADFORMAT ISC_PLATFORM_QUADFORMAT
+
+/***
+ *** Functions
+ ***/
+
+#ifdef ISC_PLATFORM_NEEDVSNPRINTF
+#include <stdarg.h>
+#include <stddef.h>
+#endif
+#ifdef ISC_PLATFORM_NEEDSPRINTF
+#include <stdio.h>
+#endif
+
+
+ISC_LANG_BEGINDECLS
+
+#ifdef ISC_PLATFORM_NEEDVSNPRINTF
+int
+isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap)
+ ISC_FORMAT_PRINTF(3, 0);
+#define vsnprintf isc_print_vsnprintf
+
+int
+isc_print_snprintf(char *str, size_t size, const char *format, ...)
+ ISC_FORMAT_PRINTF(3, 4);
+#define snprintf isc_print_snprintf
+#endif /* ISC_PLATFORM_NEEDVSNPRINTF */
+
+#ifdef ISC_PLATFORM_NEEDSPRINTF
+int
+isc_print_sprintf(char *str, const char *format, ...) ISC_FORMAT_PRINTF(2, 3);
+#define sprintf isc_print_sprintf
+#endif
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_PRINT_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/queue.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/queue.h
new file mode 100644
index 0000000..5bf84c5
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/queue.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+/*
+ * This is a generic implementation of a two-lock concurrent queue.
+ * There are built-in mutex locks for the head and tail of the queue,
+ * allowing elements to be safely added and removed at the same time.
+ */
+
+#ifndef ISC_QUEUE_H
+#define ISC_QUEUE_H 1
+#include <isc/assertions.h>
+#include <isc/boolean.h>
+#include <isc/mutex.h>
+
+#ifdef ISC_QUEUE_CHECKINIT
+#define ISC_QLINK_INSIST(x) ISC_INSIST(x)
+#else
+#define ISC_QLINK_INSIST(x) (void)0
+#endif
+
+#define ISC_QLINK(type) struct { void *next; isc_boolean_t linked; }
+#define ISC_QLINK_INIT(elt, link) \
+ do { \
+ (elt)->link.next = (void *)(-1); \
+ (elt)->link.linked = ISC_FALSE; \
+ } while (0)
+#define ISC_QLINK_LINKED(elt, link) ((elt)->link.linked)
+
+#define ISC_QUEUE(type) struct { \
+ type headnode; \
+ type *head, *tail; \
+ isc_mutex_t headlock, taillock; \
+}
+
+#define ISC_QUEUE_INIT(queue, link) \
+ do { \
+ isc_mutex_init(&(queue).headlock); \
+ isc_mutex_init(&(queue).taillock); \
+ (queue).head = (void *) &((queue).headnode); \
+ (queue).tail = (void *) &((queue).headnode); \
+ ISC_QLINK_INIT((queue).head, link); \
+ } while (0)
+
+#define ISC_QUEUE_EMPTY(queue) ISC_TF((queue).head == (queue).tail)
+
+#define ISC_QUEUE_DESTROY(queue) \
+ do { \
+ ISC_QLINK_INSIST(ISC_QUEUE_EMPTY(queue)); \
+ isc_mutex_destroy(&(queue).headlock); \
+ isc_mutex_destroy(&(queue).taillock); \
+ } while (0)
+
+#define ISC_QUEUE_PUSH(queue, elt, link) \
+ do { \
+ ISC_QLINK_INSIST(!ISC_QLINK_LINKED(elt, link)); \
+ (elt)->link.next = (void *)(-1); \
+ LOCK(&(queue).taillock); \
+ (queue).tail->link.next = elt; \
+ (queue).tail = elt; \
+ UNLOCK(&(queue).taillock); \
+ (elt)->link.linked = ISC_TRUE; \
+ } while (0)
+
+#define ISC_QUEUE_POP(queue, link, ret) \
+ do { \
+ LOCK(&(queue).headlock); \
+ ret = (queue).head->link.next; \
+ if (ret == (void *)(-1)) { \
+ UNLOCK(&(queue).headlock); \
+ ret = NULL; \
+ } else { \
+ (queue).head->link.next = ret->link.next; \
+ if (ret->link.next == (void *)(-1)) { \
+ LOCK(&(queue).taillock); \
+ (queue).tail = (queue).head; \
+ UNLOCK(&(queue).taillock); \
+ } \
+ UNLOCK(&(queue).headlock); \
+ ret->link.next = (void *)(-1); \
+ ret->link.linked = ISC_FALSE; \
+ } \
+ } while (0)
+
+#endif /* ISC_QUEUE_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/quota.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/quota.h
new file mode 100644
index 0000000..7b0d0d9
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/quota.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: quota.h,v 1.16 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_QUOTA_H
+#define ISC_QUOTA_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file isc/quota.h
+ *
+ * \brief The isc_quota_t object is a simple helper object for implementing
+ * quotas on things like the number of simultaneous connections to
+ * a server. It keeps track of the amount of quota in use, and
+ * encapsulates the locking necessary to allow multiple tasks to
+ * share a quota.
+ */
+
+/***
+ *** Imports.
+ ***/
+
+#include <isc/lang.h>
+#include <isc/mutex.h>
+#include <isc/types.h>
+
+/*****
+ ***** Types.
+ *****/
+
+ISC_LANG_BEGINDECLS
+
+/*% isc_quota structure */
+struct isc_quota {
+ isc_mutex_t lock; /*%< Locked by lock. */
+ int max;
+ int used;
+ int soft;
+};
+
+isc_result_t
+isc_quota_init(isc_quota_t *quota, int max);
+/*%<
+ * Initialize a quota object.
+ *
+ * Returns:
+ * ISC_R_SUCCESS
+ * Other error Lock creation failed.
+ */
+
+void
+isc_quota_destroy(isc_quota_t *quota);
+/*%<
+ * Destroy a quota object.
+ */
+
+void
+isc_quota_soft(isc_quota_t *quota, int soft);
+/*%<
+ * Set a soft quota.
+ */
+
+void
+isc_quota_max(isc_quota_t *quota, int max);
+/*%<
+ * Re-set a maximum quota.
+ */
+
+isc_result_t
+isc_quota_reserve(isc_quota_t *quota);
+/*%<
+ * Attempt to reserve one unit of 'quota'.
+ *
+ * Returns:
+ * \li #ISC_R_SUCCESS Success
+ * \li #ISC_R_SOFTQUOTA Success soft quota reached
+ * \li #ISC_R_QUOTA Quota is full
+ */
+
+void
+isc_quota_release(isc_quota_t *quota);
+/*%<
+ * Release one unit of quota.
+ */
+
+isc_result_t
+isc_quota_attach(isc_quota_t *quota, isc_quota_t **p);
+/*%<
+ * Like isc_quota_reserve, and also attaches '*p' to the
+ * quota if successful (ISC_R_SUCCESS or ISC_R_SOFTQUOTA).
+ */
+
+void
+isc_quota_detach(isc_quota_t **p);
+/*%<
+ * Like isc_quota_release, and also detaches '*p' from the
+ * quota.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_QUOTA_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/radix.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/radix.h
new file mode 100644
index 0000000..6b413a2
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/radix.h
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: radix.h,v 1.13 2008/12/01 23:47:45 tbox Exp $ */
+
+/*
+ * This source was adapted from MRT's RCS Ids:
+ * Id: radix.h,v 1.6 1999/08/03 03:32:53 masaki Exp
+ * Id: mrt.h,v 1.57.2.6 1999/12/28 23:41:27 labovit Exp
+ * Id: defs.h,v 1.5.2.2 2000/01/15 14:19:16 masaki Exp
+ */
+
+#include <isc/magic.h>
+#include <isc/types.h>
+#include <isc/mutex.h>
+#include <isc/net.h>
+#include <isc/refcount.h>
+
+#include <string.h>
+
+#ifndef _RADIX_H
+#define _RADIX_H
+
+#define NETADDR_TO_PREFIX_T(na,pt,bits) \
+ do { \
+ memset(&(pt), 0, sizeof(pt)); \
+ if((na) != NULL) { \
+ (pt).family = (na)->family; \
+ (pt).bitlen = (bits); \
+ if ((pt).family == AF_INET6) { \
+ memcpy(&(pt).add.sin6, &(na)->type.in6, \
+ ((bits)+7)/8); \
+ } else \
+ memcpy(&(pt).add.sin, &(na)->type.in, \
+ ((bits)+7)/8); \
+ } else { \
+ (pt).family = AF_UNSPEC; \
+ (pt).bitlen = 0; \
+ } \
+ isc_refcount_init(&(pt).refcount, 0); \
+ } while(0)
+
+typedef struct isc_prefix {
+ unsigned int family; /* AF_INET | AF_INET6, or AF_UNSPEC for "any" */
+ unsigned int bitlen; /* 0 for "any" */
+ isc_refcount_t refcount;
+ union {
+ struct in_addr sin;
+ struct in6_addr sin6;
+ } add;
+} isc_prefix_t;
+
+typedef void (*isc_radix_destroyfunc_t)(void *);
+typedef void (*isc_radix_processfunc_t)(isc_prefix_t *, void **);
+
+#define isc_prefix_tochar(prefix) ((char *)&(prefix)->add.sin)
+#define isc_prefix_touchar(prefix) ((u_char *)&(prefix)->add.sin)
+
+#define BIT_TEST(f, b) ((f) & (b))
+
+/*
+ * We need "first match" when we search the radix tree to preserve
+ * compatibility with the existing ACL implementation. Radix trees
+ * naturally lend themselves to "best match". In order to get "first match"
+ * behavior, we keep track of the order in which entries are added to the
+ * tree--and when a search is made, we find all matching entries, and
+ * return the one that was added first.
+ *
+ * An IPv4 prefix and an IPv6 prefix may share a radix tree node if they
+ * have the same length and bit pattern (e.g., 127/8 and 7f::/8). To
+ * disambiguate between them, node_num and data are two-element arrays;
+ * node_num[0] and data[0] are used for IPv4 addresses, node_num[1]
+ * and data[1] for IPv6 addresses. The only exception is a prefix of
+ * 0/0 (aka "any" or "none"), which is always stored as IPv4 but matches
+ * IPv6 addresses too.
+ */
+
+#define ISC_IS6(family) ((family) == AF_INET6 ? 1 : 0)
+typedef struct isc_radix_node {
+ isc_uint32_t bit; /* bit length of the prefix */
+ isc_prefix_t *prefix; /* who we are in radix tree */
+ struct isc_radix_node *l, *r; /* left and right children */
+ struct isc_radix_node *parent; /* may be used */
+ void *data[2]; /* pointers to IPv4 and IPV6 data */
+ int node_num[2]; /* which node this was in the tree,
+ or -1 for glue nodes */
+} isc_radix_node_t;
+
+#define RADIX_TREE_MAGIC ISC_MAGIC('R','d','x','T');
+#define RADIX_TREE_VALID(a) ISC_MAGIC_VALID(a, RADIX_TREE_MAGIC);
+
+typedef struct isc_radix_tree {
+ unsigned int magic;
+ isc_mem_t *mctx;
+ isc_radix_node_t *head;
+ isc_uint32_t maxbits; /* for IP, 32 bit addresses */
+ int num_active_node; /* for debugging purposes */
+ int num_added_node; /* total number of nodes */
+} isc_radix_tree_t;
+
+isc_result_t
+isc_radix_search(isc_radix_tree_t *radix, isc_radix_node_t **target,
+ isc_prefix_t *prefix);
+/*%<
+ * Search 'radix' for the best match to 'prefix'.
+ * Return the node found in '*target'.
+ *
+ * Requires:
+ * \li 'radix' to be valid.
+ * \li 'target' is not NULL and "*target" is NULL.
+ * \li 'prefix' to be valid.
+ *
+ * Returns:
+ * \li ISC_R_NOTFOUND
+ * \li ISC_R_SUCCESS
+ */
+
+isc_result_t
+isc_radix_insert(isc_radix_tree_t *radix, isc_radix_node_t **target,
+ isc_radix_node_t *source, isc_prefix_t *prefix);
+/*%<
+ * Insert 'source' or 'prefix' into the radix tree 'radix'.
+ * Return the node added in 'target'.
+ *
+ * Requires:
+ * \li 'radix' to be valid.
+ * \li 'target' is not NULL and "*target" is NULL.
+ * \li 'prefix' to be valid or 'source' to be non NULL and contain
+ * a valid prefix.
+ *
+ * Returns:
+ * \li ISC_R_NOMEMORY
+ * \li ISC_R_SUCCESS
+ */
+
+void
+isc_radix_remove(isc_radix_tree_t *radix, isc_radix_node_t *node);
+/*%<
+ * Remove the node 'node' from the radix tree 'radix'.
+ *
+ * Requires:
+ * \li 'radix' to be valid.
+ * \li 'node' to be valid.
+ */
+
+isc_result_t
+isc_radix_create(isc_mem_t *mctx, isc_radix_tree_t **target, int maxbits);
+/*%<
+ * Create a radix tree with a maximum depth of 'maxbits';
+ *
+ * Requires:
+ * \li 'mctx' to be valid.
+ * \li 'target' to be non NULL and '*target' to be NULL.
+ * \li 'maxbits' to be less than or equal to RADIX_MAXBITS.
+ *
+ * Returns:
+ * \li ISC_R_NOMEMORY
+ * \li ISC_R_SUCCESS
+ */
+
+void
+isc_radix_destroy(isc_radix_tree_t *radix, isc_radix_destroyfunc_t func);
+/*%<
+ * Destroy a radix tree optionally calling 'func' to clean up node data.
+ *
+ * Requires:
+ * \li 'radix' to be valid.
+ */
+
+void
+isc_radix_process(isc_radix_tree_t *radix, isc_radix_processfunc_t func);
+/*%<
+ * Walk a radix tree calling 'func' to process node data.
+ *
+ * Requires:
+ * \li 'radix' to be valid.
+ * \li 'func' to point to a function.
+ */
+
+#define RADIX_MAXBITS 128
+#define RADIX_NBIT(x) (0x80 >> ((x) & 0x7f))
+#define RADIX_NBYTE(x) ((x) >> 3)
+
+#define RADIX_DATA_GET(node, type) (type *)((node)->data)
+#define RADIX_DATA_SET(node, value) ((node)->data = (void *)(value))
+
+#define RADIX_WALK(Xhead, Xnode) \
+ do { \
+ isc_radix_node_t *Xstack[RADIX_MAXBITS+1]; \
+ isc_radix_node_t **Xsp = Xstack; \
+ isc_radix_node_t *Xrn = (Xhead); \
+ while ((Xnode = Xrn)) { \
+ if (Xnode->prefix)
+
+#define RADIX_WALK_ALL(Xhead, Xnode) \
+do { \
+ isc_radix_node_t *Xstack[RADIX_MAXBITS+1]; \
+ isc_radix_node_t **Xsp = Xstack; \
+ isc_radix_node_t *Xrn = (Xhead); \
+ while ((Xnode = Xrn)) { \
+ if (1)
+
+#define RADIX_WALK_BREAK { \
+ if (Xsp != Xstack) { \
+ Xrn = *(--Xsp); \
+ } else { \
+ Xrn = (radix_node_t *) 0; \
+ } \
+ continue; }
+
+#define RADIX_WALK_END \
+ if (Xrn->l) { \
+ if (Xrn->r) { \
+ *Xsp++ = Xrn->r; \
+ } \
+ Xrn = Xrn->l; \
+ } else if (Xrn->r) { \
+ Xrn = Xrn->r; \
+ } else if (Xsp != Xstack) { \
+ Xrn = *(--Xsp); \
+ } else { \
+ Xrn = (isc_radix_node_t *) 0; \
+ } \
+ } \
+ } while (0)
+
+#endif /* _RADIX_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/random.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/random.h
new file mode 100644
index 0000000..1f9572d
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/random.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: random.h,v 1.20 2009/01/17 23:47:43 tbox Exp $ */
+
+#ifndef ISC_RANDOM_H
+#define ISC_RANDOM_H 1
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+/*! \file isc/random.h
+ * \brief Implements a random state pool which will let the caller return a
+ * series of possibly non-reproducible random values.
+ *
+ * Note that the
+ * strength of these numbers is not all that high, and should not be
+ * used in cryptography functions. It is useful for jittering values
+ * a bit here and there, such as timeouts, etc.
+ */
+
+ISC_LANG_BEGINDECLS
+
+void
+isc_random_seed(isc_uint32_t seed);
+/*%<
+ * Set the initial seed of the random state.
+ */
+
+void
+isc_random_get(isc_uint32_t *val);
+/*%<
+ * Get a random value.
+ *
+ * Requires:
+ * val != NULL.
+ */
+
+isc_uint32_t
+isc_random_jitter(isc_uint32_t max, isc_uint32_t jitter);
+/*%<
+ * Get a random value between (max - jitter) and (max).
+ * This is useful for jittering timer values.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_RANDOM_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/ratelimiter.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/ratelimiter.h
new file mode 100644
index 0000000..00a7209
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/ratelimiter.h
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: ratelimiter.h,v 1.23 2009/01/18 23:48:14 tbox Exp $ */
+
+#ifndef ISC_RATELIMITER_H
+#define ISC_RATELIMITER_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file isc/ratelimiter.h
+ * \brief A rate limiter is a mechanism for dispatching events at a limited
+ * rate. This is intended to be used when sending zone maintenance
+ * SOA queries, NOTIFY messages, etc.
+ */
+
+/***
+ *** Imports.
+ ***/
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+ISC_LANG_BEGINDECLS
+
+/*****
+ ***** Functions.
+ *****/
+
+isc_result_t
+isc_ratelimiter_create(isc_mem_t *mctx, isc_timermgr_t *timermgr,
+ isc_task_t *task, isc_ratelimiter_t **ratelimiterp);
+/*%<
+ * Create a rate limiter. The execution interval is initially undefined.
+ */
+
+isc_result_t
+isc_ratelimiter_setinterval(isc_ratelimiter_t *rl, isc_interval_t *interval);
+/*!<
+ * Set the minimum interval between event executions.
+ * The interval value is copied, so the caller need not preserve it.
+ *
+ * Requires:
+ * '*interval' is a nonzero interval.
+ */
+
+void
+isc_ratelimiter_setpertic(isc_ratelimiter_t *rl, isc_uint32_t perint);
+/*%<
+ * Set the number of events processed per interval timer tick.
+ * If 'perint' is zero it is treated as 1.
+ */
+
+isc_result_t
+isc_ratelimiter_enqueue(isc_ratelimiter_t *rl, isc_task_t *task,
+ isc_event_t **eventp);
+/*%<
+ * Queue an event for rate-limited execution.
+ *
+ * This is similar
+ * to doing an isc_task_send() to the 'task', except that the
+ * execution may be delayed to achieve the desired rate of
+ * execution.
+ *
+ * '(*eventp)->ev_sender' is used to hold the task. The caller
+ * must ensure that the task exists until the event is delivered.
+ *
+ * Requires:
+ *\li An interval has been set by calling
+ * isc_ratelimiter_setinterval().
+ *
+ *\li 'task' to be non NULL.
+ *\li '(*eventp)->ev_sender' to be NULL.
+ */
+
+void
+isc_ratelimiter_shutdown(isc_ratelimiter_t *ratelimiter);
+/*%<
+ * Shut down a rate limiter.
+ *
+ * Ensures:
+ *\li All events that have not yet been
+ * dispatched to the task are dispatched immediately with
+ * the #ISC_EVENTATTR_CANCELED bit set in ev_attributes.
+ *
+ *\li Further attempts to enqueue events will fail with
+ * #ISC_R_SHUTTINGDOWN.
+ *
+ *\li The rate limiter is no longer attached to its task.
+ */
+
+void
+isc_ratelimiter_attach(isc_ratelimiter_t *source, isc_ratelimiter_t **target);
+/*%<
+ * Attach to a rate limiter.
+ */
+
+void
+isc_ratelimiter_detach(isc_ratelimiter_t **ratelimiterp);
+/*%<
+ * Detach from a rate limiter.
+ */
+
+isc_result_t
+isc_ratelimiter_stall(isc_ratelimiter_t *rl);
+/*%<
+ * Stall event processing.
+ */
+
+isc_result_t
+isc_ratelimiter_release(isc_ratelimiter_t *rl);
+/*%<
+ * Release a stalled rate limiter.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_RATELIMITER_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/refcount.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/refcount.h
new file mode 100644
index 0000000..b72b158
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/refcount.h
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2001, 2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: refcount.h,v 1.17 2009/09/29 23:48:04 tbox Exp $ */
+
+#ifndef ISC_REFCOUNT_H
+#define ISC_REFCOUNT_H 1
+
+#include <isc/atomic.h>
+#include <isc/lang.h>
+#include <isc/mutex.h>
+#include <isc/platform.h>
+#include <isc/types.h>
+#include <isc/util.h>
+
+/*! \file isc/refcount.h
+ * \brief Implements a locked reference counter.
+ *
+ * These functions may actually be
+ * implemented using macros, and implementations of these macros are below.
+ * The isc_refcount_t type should not be accessed directly, as its contents
+ * depend on the implementation.
+ */
+
+ISC_LANG_BEGINDECLS
+
+/*
+ * Function prototypes
+ */
+
+/*
+ * isc_result_t
+ * isc_refcount_init(isc_refcount_t *ref, unsigned int n);
+ *
+ * Initialize the reference counter. There will be 'n' initial references.
+ *
+ * Requires:
+ * ref != NULL
+ */
+
+/*
+ * void
+ * isc_refcount_destroy(isc_refcount_t *ref);
+ *
+ * Destroys a reference counter.
+ *
+ * Requires:
+ * ref != NULL
+ * The number of references is 0.
+ */
+
+/*
+ * void
+ * isc_refcount_increment(isc_refcount_t *ref, unsigned int *targetp);
+ * isc_refcount_increment0(isc_refcount_t *ref, unsigned int *targetp);
+ *
+ * Increments the reference count, returning the new value in targetp if it's
+ * not NULL. The reference counter typically begins with the initial counter
+ * of 1, and will be destroyed once the counter reaches 0. Thus,
+ * isc_refcount_increment() additionally requires the previous counter be
+ * larger than 0 so that an error which violates the usage can be easily
+ * caught. isc_refcount_increment0() does not have this restriction.
+ *
+ * Requires:
+ * ref != NULL.
+ */
+
+/*
+ * void
+ * isc_refcount_decrement(isc_refcount_t *ref, unsigned int *targetp);
+ *
+ * Decrements the reference count, returning the new value in targetp if it's
+ * not NULL.
+ *
+ * Requires:
+ * ref != NULL.
+ */
+
+
+/*
+ * Sample implementations
+ */
+#ifdef ISC_PLATFORM_USETHREADS
+#ifdef ISC_PLATFORM_HAVEXADD
+
+#define ISC_REFCOUNT_HAVEATOMIC 1
+
+typedef struct isc_refcount {
+ isc_int32_t refs;
+} isc_refcount_t;
+
+#define isc_refcount_destroy(rp) REQUIRE((rp)->refs == 0)
+#define isc_refcount_current(rp) ((unsigned int)((rp)->refs))
+
+#define isc_refcount_increment0(rp, tp) \
+ do { \
+ unsigned int *_tmp = (unsigned int *)(tp); \
+ isc_int32_t prev; \
+ prev = isc_atomic_xadd(&(rp)->refs, 1); \
+ if (_tmp != NULL) \
+ *_tmp = prev + 1; \
+ } while (0)
+
+#define isc_refcount_increment(rp, tp) \
+ do { \
+ unsigned int *_tmp = (unsigned int *)(tp); \
+ isc_int32_t prev; \
+ prev = isc_atomic_xadd(&(rp)->refs, 1); \
+ REQUIRE(prev > 0); \
+ if (_tmp != NULL) \
+ *_tmp = prev + 1; \
+ } while (0)
+
+#define isc_refcount_decrement(rp, tp) \
+ do { \
+ unsigned int *_tmp = (unsigned int *)(tp); \
+ isc_int32_t prev; \
+ prev = isc_atomic_xadd(&(rp)->refs, -1); \
+ REQUIRE(prev > 0); \
+ if (_tmp != NULL) \
+ *_tmp = prev - 1; \
+ } while (0)
+
+#else /* ISC_PLATFORM_HAVEXADD */
+
+typedef struct isc_refcount {
+ int refs;
+ isc_mutex_t lock;
+} isc_refcount_t;
+
+/*% Destroys a reference counter. */
+#define isc_refcount_destroy(rp) \
+ do { \
+ REQUIRE((rp)->refs == 0); \
+ DESTROYLOCK(&(rp)->lock); \
+ } while (0)
+
+#define isc_refcount_current(rp) ((unsigned int)((rp)->refs))
+
+/*% Increments the reference count, returning the new value in targetp if it's not NULL. */
+#define isc_refcount_increment0(rp, tp) \
+ do { \
+ unsigned int *_tmp = (unsigned int *)(tp); \
+ LOCK(&(rp)->lock); \
+ ++((rp)->refs); \
+ if (_tmp != NULL) \
+ *_tmp = ((rp)->refs); \
+ UNLOCK(&(rp)->lock); \
+ } while (0)
+
+#define isc_refcount_increment(rp, tp) \
+ do { \
+ unsigned int *_tmp = (unsigned int *)(tp); \
+ LOCK(&(rp)->lock); \
+ REQUIRE((rp)->refs > 0); \
+ ++((rp)->refs); \
+ if (_tmp != NULL) \
+ *_tmp = ((rp)->refs); \
+ UNLOCK(&(rp)->lock); \
+ } while (0)
+
+/*% Decrements the reference count, returning the new value in targetp if it's not NULL. */
+#define isc_refcount_decrement(rp, tp) \
+ do { \
+ unsigned int *_tmp = (unsigned int *)(tp); \
+ LOCK(&(rp)->lock); \
+ REQUIRE((rp)->refs > 0); \
+ --((rp)->refs); \
+ if (_tmp != NULL) \
+ *_tmp = ((rp)->refs); \
+ UNLOCK(&(rp)->lock); \
+ } while (0)
+
+#endif /* ISC_PLATFORM_HAVEXADD */
+#else /* ISC_PLATFORM_USETHREADS */
+
+typedef struct isc_refcount {
+ int refs;
+} isc_refcount_t;
+
+#define isc_refcount_destroy(rp) REQUIRE((rp)->refs == 0)
+#define isc_refcount_current(rp) ((unsigned int)((rp)->refs))
+
+#define isc_refcount_increment0(rp, tp) \
+ do { \
+ unsigned int *_tmp = (unsigned int *)(tp); \
+ int _n = ++(rp)->refs; \
+ if (_tmp != NULL) \
+ *_tmp = _n; \
+ } while (0)
+
+#define isc_refcount_increment(rp, tp) \
+ do { \
+ unsigned int *_tmp = (unsigned int *)(tp); \
+ int _n; \
+ REQUIRE((rp)->refs > 0); \
+ _n = ++(rp)->refs; \
+ if (_tmp != NULL) \
+ *_tmp = _n; \
+ } while (0)
+
+#define isc_refcount_decrement(rp, tp) \
+ do { \
+ unsigned int *_tmp = (unsigned int *)(tp); \
+ int _n; \
+ REQUIRE((rp)->refs > 0); \
+ _n = --(rp)->refs; \
+ if (_tmp != NULL) \
+ *_tmp = _n; \
+ } while (0)
+
+#endif /* ISC_PLATFORM_USETHREADS */
+
+isc_result_t
+isc_refcount_init(isc_refcount_t *ref, unsigned int n);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_REFCOUNT_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/region.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/region.h
new file mode 100644
index 0000000..43d8f8f
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/region.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: region.h,v 1.25 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_REGION_H
+#define ISC_REGION_H 1
+
+/*! \file isc/region.h */
+
+#include <isc/types.h>
+
+struct isc_region {
+ unsigned char * base;
+ unsigned int length;
+};
+
+struct isc_textregion {
+ char * base;
+ unsigned int length;
+};
+
+/* XXXDCL questionable ... bears discussion. we have been putting off
+ * discussing the region api.
+ */
+struct isc_constregion {
+ const void * base;
+ unsigned int length;
+};
+
+struct isc_consttextregion {
+ const char * base;
+ unsigned int length;
+};
+
+/*@{*/
+/*!
+ * The region structure is not opaque, and is usually directly manipulated.
+ * Some macros are defined below for convenience.
+ */
+
+#define isc_region_consume(r,l) \
+ do { \
+ isc_region_t *_r = (r); \
+ unsigned int _l = (l); \
+ INSIST(_r->length >= _l); \
+ _r->base += _l; \
+ _r->length -= _l; \
+ } while (0)
+
+#define isc_textregion_consume(r,l) \
+ do { \
+ isc_textregion_t *_r = (r); \
+ unsigned int _l = (l); \
+ INSIST(_r->length >= _l); \
+ _r->base += _l; \
+ _r->length -= _l; \
+ } while (0)
+
+#define isc_constregion_consume(r,l) \
+ do { \
+ isc_constregion_t *_r = (r); \
+ unsigned int _l = (l); \
+ INSIST(_r->length >= _l); \
+ _r->base += _l; \
+ _r->length -= _l; \
+ } while (0)
+/*@}*/
+
+int
+isc_region_compare(isc_region_t *r1, isc_region_t *r2);
+/*%<
+ * Compares the contents of two regions
+ *
+ * Requires:
+ *\li 'r1' is a valid region
+ *\li 'r2' is a valid region
+ *
+ * Returns:
+ *\li < 0 if r1 is lexicographically less than r2
+ *\li = 0 if r1 is lexicographically identical to r2
+ *\li > 0 if r1 is lexicographically greater than r2
+ */
+
+#endif /* ISC_REGION_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/resource.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/resource.h
new file mode 100644
index 0000000..747c9fd
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/resource.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: resource.h,v 1.13 2008/07/11 23:47:09 tbox Exp $ */
+
+#ifndef ISC_RESOURCE_H
+#define ISC_RESOURCE_H 1
+
+/*! \file isc/resource.h */
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+#define ISC_RESOURCE_UNLIMITED ((isc_resourcevalue_t)ISC_UINT64_MAX)
+
+ISC_LANG_BEGINDECLS
+
+isc_result_t
+isc_resource_setlimit(isc_resource_t resource, isc_resourcevalue_t value);
+/*%<
+ * Set the maximum limit for a system resource.
+ *
+ * Notes:
+ *\li If 'value' exceeds the maximum possible on the operating system,
+ * it is silently limited to that maximum -- or to "infinity", if
+ * the operating system has that concept. #ISC_RESOURCE_UNLIMITED
+ * can be used to explicitly ask for the maximum.
+ *
+ * Requires:
+ *\li 'resource' is a valid member of the isc_resource_t enumeration.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS Success.
+ *\li #ISC_R_NOTIMPLEMENTED 'resource' is not a type known by the OS.
+ *\li #ISC_R_NOPERM The calling process did not have adequate permission
+ * to change the resource limit.
+ */
+
+isc_result_t
+isc_resource_getlimit(isc_resource_t resource, isc_resourcevalue_t *value);
+/*%<
+ * Get the maximum limit for a system resource.
+ *
+ * Notes:
+ *\li 'value' is set to the maximum limit.
+ *
+ *\li #ISC_RESOURCE_UNLIMITED is the maximum value of isc_resourcevalue_t.
+ *
+ *\li On many (all?) Unix systems, RLIM_INFINITY is a valid value that is
+ * significantly less than #ISC_RESOURCE_UNLIMITED, but which in practice
+ * behaves the same.
+ *
+ *\li The current ISC libdns configuration file parser assigns a value
+ * of ISC_UINT32_MAX for a size_spec of "unlimited" and ISC_UNIT32_MAX - 1
+ * for "default", the latter of which is supposed to represent "the
+ * limit that was in force when the server started". Since these are
+ * valid values in the middle of the range of isc_resourcevalue_t,
+ * there is the possibility for confusion over what exactly those
+ * particular values are supposed to represent in a particular context --
+ * discrete integral values or generalized concepts.
+ *
+ * Requires:
+ *\li 'resource' is a valid member of the isc_resource_t enumeration.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS Success.
+ *\li #ISC_R_NOTIMPLEMENTED 'resource' is not a type known by the OS.
+ */
+
+isc_result_t
+isc_resource_getcurlimit(isc_resource_t resource, isc_resourcevalue_t *value);
+/*%<
+ * Same as isc_resource_getlimit(), but returns the current (soft) limit.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS Success.
+ *\li #ISC_R_NOTIMPLEMENTED 'resource' is not a type known by the OS.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_RESOURCE_H */
+
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/result.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/result.h
new file mode 100644
index 0000000..dcd457b
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/result.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2004-2009, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001, 2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+#ifndef ISC_RESULT_H
+#define ISC_RESULT_H 1
+
+/*! \file isc/result.h */
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+#define ISC_R_SUCCESS 0 /*%< success */
+#define ISC_R_NOMEMORY 1 /*%< out of memory */
+#define ISC_R_TIMEDOUT 2 /*%< timed out */
+#define ISC_R_NOTHREADS 3 /*%< no available threads */
+#define ISC_R_ADDRNOTAVAIL 4 /*%< address not available */
+#define ISC_R_ADDRINUSE 5 /*%< address in use */
+#define ISC_R_NOPERM 6 /*%< permission denied */
+#define ISC_R_NOCONN 7 /*%< no pending connections */
+#define ISC_R_NETUNREACH 8 /*%< network unreachable */
+#define ISC_R_HOSTUNREACH 9 /*%< host unreachable */
+#define ISC_R_NETDOWN 10 /*%< network down */
+#define ISC_R_HOSTDOWN 11 /*%< host down */
+#define ISC_R_CONNREFUSED 12 /*%< connection refused */
+#define ISC_R_NORESOURCES 13 /*%< not enough free resources */
+#define ISC_R_EOF 14 /*%< end of file */
+#define ISC_R_BOUND 15 /*%< socket already bound */
+#define ISC_R_RELOAD 16 /*%< reload */
+#define ISC_R_SUSPEND ISC_R_RELOAD /*%< alias of 'reload' */
+#define ISC_R_LOCKBUSY 17 /*%< lock busy */
+#define ISC_R_EXISTS 18 /*%< already exists */
+#define ISC_R_NOSPACE 19 /*%< ran out of space */
+#define ISC_R_CANCELED 20 /*%< operation canceled */
+#define ISC_R_NOTBOUND 21 /*%< socket is not bound */
+#define ISC_R_SHUTTINGDOWN 22 /*%< shutting down */
+#define ISC_R_NOTFOUND 23 /*%< not found */
+#define ISC_R_UNEXPECTEDEND 24 /*%< unexpected end of input */
+#define ISC_R_FAILURE 25 /*%< generic failure */
+#define ISC_R_IOERROR 26 /*%< I/O error */
+#define ISC_R_NOTIMPLEMENTED 27 /*%< not implemented */
+#define ISC_R_UNBALANCED 28 /*%< unbalanced parentheses */
+#define ISC_R_NOMORE 29 /*%< no more */
+#define ISC_R_INVALIDFILE 30 /*%< invalid file */
+#define ISC_R_BADBASE64 31 /*%< bad base64 encoding */
+#define ISC_R_UNEXPECTEDTOKEN 32 /*%< unexpected token */
+#define ISC_R_QUOTA 33 /*%< quota reached */
+#define ISC_R_UNEXPECTED 34 /*%< unexpected error */
+#define ISC_R_ALREADYRUNNING 35 /*%< already running */
+#define ISC_R_IGNORE 36 /*%< ignore */
+#define ISC_R_MASKNONCONTIG 37 /*%< addr mask not contiguous */
+#define ISC_R_FILENOTFOUND 38 /*%< file not found */
+#define ISC_R_FILEEXISTS 39 /*%< file already exists */
+#define ISC_R_NOTCONNECTED 40 /*%< socket is not connected */
+#define ISC_R_RANGE 41 /*%< out of range */
+#define ISC_R_NOENTROPY 42 /*%< out of entropy */
+#define ISC_R_MULTICAST 43 /*%< invalid use of multicast */
+#define ISC_R_NOTFILE 44 /*%< not a file */
+#define ISC_R_NOTDIRECTORY 45 /*%< not a directory */
+#define ISC_R_QUEUEFULL 46 /*%< queue is full */
+#define ISC_R_FAMILYMISMATCH 47 /*%< address family mismatch */
+#define ISC_R_FAMILYNOSUPPORT 48 /*%< AF not supported */
+#define ISC_R_BADHEX 49 /*%< bad hex encoding */
+#define ISC_R_TOOMANYOPENFILES 50 /*%< too many open files */
+#define ISC_R_NOTBLOCKING 51 /*%< not blocking */
+#define ISC_R_UNBALANCEDQUOTES 52 /*%< unbalanced quotes */
+#define ISC_R_INPROGRESS 53 /*%< operation in progress */
+#define ISC_R_CONNECTIONRESET 54 /*%< connection reset */
+#define ISC_R_SOFTQUOTA 55 /*%< soft quota reached */
+#define ISC_R_BADNUMBER 56 /*%< not a valid number */
+#define ISC_R_DISABLED 57 /*%< disabled */
+#define ISC_R_MAXSIZE 58 /*%< max size */
+#define ISC_R_BADADDRESSFORM 59 /*%< invalid address format */
+#define ISC_R_BADBASE32 60 /*%< bad base32 encoding */
+#define ISC_R_UNSET 61 /*%< unset */
+
+/*% Not a result code: the number of results. */
+#define ISC_R_NRESULTS 62
+
+ISC_LANG_BEGINDECLS
+
+const char *
+isc_result_totext(isc_result_t);
+/*%<
+ * Convert an isc_result_t into a string message describing the result.
+ */
+
+isc_result_t
+isc_result_register(unsigned int base, unsigned int nresults,
+ const char **text, isc_msgcat_t *msgcat, int set);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_RESULT_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/resultclass.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/resultclass.h
new file mode 100644
index 0000000..d91e800
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/resultclass.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: resultclass.h,v 1.20 2009/09/02 23:48:03 tbox Exp $ */
+
+#ifndef ISC_RESULTCLASS_H
+#define ISC_RESULTCLASS_H 1
+
+
+/*! \file isc/resultclass.h
+ * \brief Registry of Predefined Result Type Classes
+ *
+ * A result class number is an unsigned 16 bit number. Each class may
+ * contain up to 65536 results. A result code is formed by adding the
+ * result number within the class to the class number multiplied by 65536.
+ *
+ * Classes < 1024 are reserved for ISC use.
+ * Result classes >= 1024 and <= 65535 are reserved for application use.
+ */
+
+#define ISC_RESULTCLASS_FROMNUM(num) ((num) << 16)
+#define ISC_RESULTCLASS_TONUM(rclass) ((rclass) >> 16)
+#define ISC_RESULTCLASS_SIZE 65536
+#define ISC_RESULTCLASS_INCLASS(rclass, result) \
+ ((rclass) == ((result) & 0xFFFF0000))
+
+
+#define ISC_RESULTCLASS_ISC ISC_RESULTCLASS_FROMNUM(0)
+#define ISC_RESULTCLASS_DNS ISC_RESULTCLASS_FROMNUM(1)
+#define ISC_RESULTCLASS_DST ISC_RESULTCLASS_FROMNUM(2)
+#define ISC_RESULTCLASS_DNSRCODE ISC_RESULTCLASS_FROMNUM(3)
+#define ISC_RESULTCLASS_OMAPI ISC_RESULTCLASS_FROMNUM(4)
+#define ISC_RESULTCLASS_ISCCC ISC_RESULTCLASS_FROMNUM(5)
+#define ISC_RESULTCLASS_DHCP ISC_RESULTCLASS_FROMNUM(6)
+
+
+#endif /* ISC_RESULTCLASS_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/rwlock.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/rwlock.h
new file mode 100644
index 0000000..28052cd
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/rwlock.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001, 2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: rwlock.h,v 1.28 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_RWLOCK_H
+#define ISC_RWLOCK_H 1
+
+/*! \file isc/rwlock.h */
+
+#include <isc/condition.h>
+#include <isc/lang.h>
+#include <isc/platform.h>
+#include <isc/types.h>
+
+ISC_LANG_BEGINDECLS
+
+typedef enum {
+ isc_rwlocktype_none = 0,
+ isc_rwlocktype_read,
+ isc_rwlocktype_write
+} isc_rwlocktype_t;
+
+#ifdef ISC_PLATFORM_USETHREADS
+#if defined(ISC_PLATFORM_HAVEXADD) && defined(ISC_PLATFORM_HAVECMPXCHG)
+#define ISC_RWLOCK_USEATOMIC 1
+#endif
+
+struct isc_rwlock {
+ /* Unlocked. */
+ unsigned int magic;
+ isc_mutex_t lock;
+
+#if defined(ISC_PLATFORM_HAVEXADD) && defined(ISC_PLATFORM_HAVECMPXCHG)
+ /*
+ * When some atomic instructions with hardware assistance are
+ * available, rwlock will use those so that concurrent readers do not
+ * interfere with each other through mutex as long as no writers
+ * appear, massively reducing the lock overhead in the typical case.
+ *
+ * The basic algorithm of this approach is the "simple
+ * writer-preference lock" shown in the following URL:
+ * http://www.cs.rochester.edu/u/scott/synchronization/pseudocode/rw.html
+ * but our implementation does not rely on the spin lock unlike the
+ * original algorithm to be more portable as a user space application.
+ */
+
+ /* Read or modified atomically. */
+ isc_int32_t write_requests;
+ isc_int32_t write_completions;
+ isc_int32_t cnt_and_flag;
+
+ /* Locked by lock. */
+ isc_condition_t readable;
+ isc_condition_t writeable;
+ unsigned int readers_waiting;
+
+ /* Locked by rwlock itself. */
+ unsigned int write_granted;
+
+ /* Unlocked. */
+ unsigned int write_quota;
+
+#else /* ISC_PLATFORM_HAVEXADD && ISC_PLATFORM_HAVECMPXCHG */
+
+ /*%< Locked by lock. */
+ isc_condition_t readable;
+ isc_condition_t writeable;
+ isc_rwlocktype_t type;
+
+ /*% The number of threads that have the lock. */
+ unsigned int active;
+
+ /*%
+ * The number of lock grants made since the lock was last switched
+ * from reading to writing or vice versa; used in determining
+ * when the quota is reached and it is time to switch.
+ */
+ unsigned int granted;
+
+ unsigned int readers_waiting;
+ unsigned int writers_waiting;
+ unsigned int read_quota;
+ unsigned int write_quota;
+ isc_rwlocktype_t original;
+#endif /* ISC_PLATFORM_HAVEXADD && ISC_PLATFORM_HAVECMPXCHG */
+};
+#else /* ISC_PLATFORM_USETHREADS */
+struct isc_rwlock {
+ unsigned int magic;
+ isc_rwlocktype_t type;
+ unsigned int active;
+};
+#endif /* ISC_PLATFORM_USETHREADS */
+
+
+isc_result_t
+isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
+ unsigned int write_quota);
+
+isc_result_t
+isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type);
+
+isc_result_t
+isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type);
+
+isc_result_t
+isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type);
+
+isc_result_t
+isc_rwlock_tryupgrade(isc_rwlock_t *rwl);
+
+void
+isc_rwlock_downgrade(isc_rwlock_t *rwl);
+
+void
+isc_rwlock_destroy(isc_rwlock_t *rwl);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_RWLOCK_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/serial.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/serial.h
new file mode 100644
index 0000000..a5e0397
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/serial.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: serial.h,v 1.18 2009/01/18 23:48:14 tbox Exp $ */
+
+#ifndef ISC_SERIAL_H
+#define ISC_SERIAL_H 1
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+/*! \file isc/serial.h
+ * \brief Implement 32 bit serial space arithmetic comparison functions.
+ * Note: Undefined results are returned as ISC_FALSE.
+ */
+
+/***
+ *** Functions
+ ***/
+
+ISC_LANG_BEGINDECLS
+
+isc_boolean_t
+isc_serial_lt(isc_uint32_t a, isc_uint32_t b);
+/*%<
+ * Return true if 'a' < 'b' otherwise false.
+ */
+
+isc_boolean_t
+isc_serial_gt(isc_uint32_t a, isc_uint32_t b);
+/*%<
+ * Return true if 'a' > 'b' otherwise false.
+ */
+
+isc_boolean_t
+isc_serial_le(isc_uint32_t a, isc_uint32_t b);
+/*%<
+ * Return true if 'a' <= 'b' otherwise false.
+ */
+
+isc_boolean_t
+isc_serial_ge(isc_uint32_t a, isc_uint32_t b);
+/*%<
+ * Return true if 'a' >= 'b' otherwise false.
+ */
+
+isc_boolean_t
+isc_serial_eq(isc_uint32_t a, isc_uint32_t b);
+/*%<
+ * Return true if 'a' == 'b' otherwise false.
+ */
+
+isc_boolean_t
+isc_serial_ne(isc_uint32_t a, isc_uint32_t b);
+/*%<
+ * Return true if 'a' != 'b' otherwise false.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_SERIAL_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/sha1.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/sha1.h
new file mode 100644
index 0000000..313ff96
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/sha1.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef ISC_SHA1_H
+#define ISC_SHA1_H 1
+
+/* $Id: sha1.h,v 1.19 2009/02/06 23:47:42 tbox Exp $ */
+
+/* $NetBSD: sha1.h,v 1.2 1998/05/29 22:55:44 thorpej Exp $ */
+
+/*! \file isc/sha1.h
+ * \brief SHA-1 in C
+ * \author By Steve Reid <steve@edmweb.com>
+ * \note 100% Public Domain
+ */
+
+#include <isc/lang.h>
+#include <isc/platform.h>
+#include <isc/types.h>
+
+#define ISC_SHA1_DIGESTLENGTH 20U
+#define ISC_SHA1_BLOCK_LENGTH 64U
+
+#ifdef ISC_PLATFORM_OPENSSLHASH
+#include <openssl/evp.h>
+
+typedef EVP_MD_CTX isc_sha1_t;
+
+#else
+
+typedef struct {
+ isc_uint32_t state[5];
+ isc_uint32_t count[2];
+ unsigned char buffer[ISC_SHA1_BLOCK_LENGTH];
+} isc_sha1_t;
+#endif
+
+ISC_LANG_BEGINDECLS
+
+void
+isc_sha1_init(isc_sha1_t *ctx);
+
+void
+isc_sha1_invalidate(isc_sha1_t *ctx);
+
+void
+isc_sha1_update(isc_sha1_t *ctx, const unsigned char *data, unsigned int len);
+
+void
+isc_sha1_final(isc_sha1_t *ctx, unsigned char *digest);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_SHA1_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/sha2.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/sha2.h
new file mode 100644
index 0000000..0c9dea8
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/sha2.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2005-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: sha2.h,v 1.12 2009/10/22 02:21:31 each Exp $ */
+
+/* $FreeBSD: 258945 2013-12-04 21:33:17Z roberto $ */
+/* $KAME: sha2.h,v 1.3 2001/03/12 08:27:48 itojun Exp $ */
+
+/*
+ * sha2.h
+ *
+ * Version 1.0.0beta1
+ *
+ * Written by Aaron D. Gifford <me@aarongifford.com>
+ *
+ * Copyright 2000 Aaron D. Gifford. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTOR(S) ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED 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(S) OR CONTRIBUTOR(S) BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef ISC_SHA2_H
+#define ISC_SHA2_H
+
+#include <isc/lang.h>
+#include <isc/platform.h>
+#include <isc/types.h>
+
+/*** SHA-224/256/384/512 Various Length Definitions ***********************/
+
+#define ISC_SHA224_BLOCK_LENGTH 64U
+#define ISC_SHA224_DIGESTLENGTH 28U
+#define ISC_SHA224_DIGESTSTRINGLENGTH (ISC_SHA224_DIGESTLENGTH * 2 + 1)
+#define ISC_SHA256_BLOCK_LENGTH 64U
+#define ISC_SHA256_DIGESTLENGTH 32U
+#define ISC_SHA256_DIGESTSTRINGLENGTH (ISC_SHA256_DIGESTLENGTH * 2 + 1)
+#define ISC_SHA384_BLOCK_LENGTH 128
+#define ISC_SHA384_DIGESTLENGTH 48U
+#define ISC_SHA384_DIGESTSTRINGLENGTH (ISC_SHA384_DIGESTLENGTH * 2 + 1)
+#define ISC_SHA512_BLOCK_LENGTH 128U
+#define ISC_SHA512_DIGESTLENGTH 64U
+#define ISC_SHA512_DIGESTSTRINGLENGTH (ISC_SHA512_DIGESTLENGTH * 2 + 1)
+
+/*** SHA-256/384/512 Context Structures *******************************/
+
+#ifdef ISC_PLATFORM_OPENSSLHASH
+#include <openssl/evp.h>
+
+typedef EVP_MD_CTX isc_sha256_t;
+typedef EVP_MD_CTX isc_sha512_t;
+
+#else
+
+/*
+ * Keep buffer immediately after bitcount to preserve alignment.
+ */
+typedef struct {
+ isc_uint32_t state[8];
+ isc_uint64_t bitcount;
+ isc_uint8_t buffer[ISC_SHA256_BLOCK_LENGTH];
+} isc_sha256_t;
+
+/*
+ * Keep buffer immediately after bitcount to preserve alignment.
+ */
+typedef struct {
+ isc_uint64_t state[8];
+ isc_uint64_t bitcount[2];
+ isc_uint8_t buffer[ISC_SHA512_BLOCK_LENGTH];
+} isc_sha512_t;
+#endif
+
+typedef isc_sha256_t isc_sha224_t;
+typedef isc_sha512_t isc_sha384_t;
+
+ISC_LANG_BEGINDECLS
+
+/*** SHA-224/256/384/512 Function Prototypes ******************************/
+
+void isc_sha224_init (isc_sha224_t *);
+void isc_sha224_invalidate (isc_sha224_t *);
+void isc_sha224_update (isc_sha224_t *, const isc_uint8_t *, size_t);
+void isc_sha224_final (isc_uint8_t[ISC_SHA224_DIGESTLENGTH], isc_sha224_t *);
+char *isc_sha224_end (isc_sha224_t *, char[ISC_SHA224_DIGESTSTRINGLENGTH]);
+char *isc_sha224_data (const isc_uint8_t *, size_t, char[ISC_SHA224_DIGESTSTRINGLENGTH]);
+
+void isc_sha256_init (isc_sha256_t *);
+void isc_sha256_invalidate (isc_sha256_t *);
+void isc_sha256_update (isc_sha256_t *, const isc_uint8_t *, size_t);
+void isc_sha256_final (isc_uint8_t[ISC_SHA256_DIGESTLENGTH], isc_sha256_t *);
+char *isc_sha256_end (isc_sha256_t *, char[ISC_SHA256_DIGESTSTRINGLENGTH]);
+char *isc_sha256_data (const isc_uint8_t *, size_t, char[ISC_SHA256_DIGESTSTRINGLENGTH]);
+
+void isc_sha384_init (isc_sha384_t *);
+void isc_sha384_invalidate (isc_sha384_t *);
+void isc_sha384_update (isc_sha384_t *, const isc_uint8_t *, size_t);
+void isc_sha384_final (isc_uint8_t[ISC_SHA384_DIGESTLENGTH], isc_sha384_t *);
+char *isc_sha384_end (isc_sha384_t *, char[ISC_SHA384_DIGESTSTRINGLENGTH]);
+char *isc_sha384_data (const isc_uint8_t *, size_t, char[ISC_SHA384_DIGESTSTRINGLENGTH]);
+
+void isc_sha512_init (isc_sha512_t *);
+void isc_sha512_invalidate (isc_sha512_t *);
+void isc_sha512_update (isc_sha512_t *, const isc_uint8_t *, size_t);
+void isc_sha512_final (isc_uint8_t[ISC_SHA512_DIGESTLENGTH], isc_sha512_t *);
+char *isc_sha512_end (isc_sha512_t *, char[ISC_SHA512_DIGESTSTRINGLENGTH]);
+char *isc_sha512_data (const isc_uint8_t *, size_t, char[ISC_SHA512_DIGESTSTRINGLENGTH]);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_SHA2_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/sockaddr.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/sockaddr.h
new file mode 100644
index 0000000..1e69142
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/sockaddr.h
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: sockaddr.h,v 1.57 2009/01/18 23:48:14 tbox Exp $ */
+
+#ifndef ISC_SOCKADDR_H
+#define ISC_SOCKADDR_H 1
+
+/*! \file isc/sockaddr.h */
+
+#include <isc/lang.h>
+#include <isc/net.h>
+#include <isc/types.h>
+#ifdef ISC_PLATFORM_HAVESYSUNH
+#include <sys/un.h>
+#endif
+
+struct isc_sockaddr {
+ union {
+ struct sockaddr sa;
+ struct sockaddr_in sin;
+ struct sockaddr_in6 sin6;
+#ifdef ISC_PLATFORM_HAVESYSUNH
+ struct sockaddr_un sunix;
+#endif
+ } type;
+ unsigned int length; /* XXXRTH beginning? */
+ ISC_LINK(struct isc_sockaddr) link;
+};
+
+typedef ISC_LIST(struct isc_sockaddr) isc_sockaddrlist_t;
+
+#define ISC_SOCKADDR_CMPADDR 0x0001 /*%< compare the address
+ * sin_addr/sin6_addr */
+#define ISC_SOCKADDR_CMPPORT 0x0002 /*%< compare the port
+ * sin_port/sin6_port */
+#define ISC_SOCKADDR_CMPSCOPE 0x0004 /*%< compare the scope
+ * sin6_scope */
+#define ISC_SOCKADDR_CMPSCOPEZERO 0x0008 /*%< when comparing scopes
+ * zero scopes always match */
+
+ISC_LANG_BEGINDECLS
+
+isc_boolean_t
+isc_sockaddr_compare(const isc_sockaddr_t *a, const isc_sockaddr_t *b,
+ unsigned int flags);
+/*%<
+ * Compare the elements of the two address ('a' and 'b') as specified
+ * by 'flags' and report if they are equal or not.
+ *
+ * 'flags' is set from ISC_SOCKADDR_CMP*.
+ */
+
+isc_boolean_t
+isc_sockaddr_equal(const isc_sockaddr_t *a, const isc_sockaddr_t *b);
+/*%<
+ * Return ISC_TRUE iff the socket addresses 'a' and 'b' are equal.
+ */
+
+isc_boolean_t
+isc_sockaddr_eqaddr(const isc_sockaddr_t *a, const isc_sockaddr_t *b);
+/*%<
+ * Return ISC_TRUE iff the address parts of the socket addresses
+ * 'a' and 'b' are equal, ignoring the ports.
+ */
+
+isc_boolean_t
+isc_sockaddr_eqaddrprefix(const isc_sockaddr_t *a, const isc_sockaddr_t *b,
+ unsigned int prefixlen);
+/*%<
+ * Return ISC_TRUE iff the most significant 'prefixlen' bits of the
+ * socket addresses 'a' and 'b' are equal, ignoring the ports.
+ * If 'b''s scope is zero then 'a''s scope will be ignored.
+ */
+
+unsigned int
+isc_sockaddr_hash(const isc_sockaddr_t *sockaddr, isc_boolean_t address_only);
+/*%<
+ * Return a hash value for the socket address 'sockaddr'. If 'address_only'
+ * is ISC_TRUE, the hash value will not depend on the port.
+ *
+ * IPv6 addresses containing mapped IPv4 addresses generate the same hash
+ * value as the equivalent IPv4 address.
+ */
+
+void
+isc_sockaddr_any(isc_sockaddr_t *sockaddr);
+/*%<
+ * Return the IPv4 wildcard address.
+ */
+
+void
+isc_sockaddr_any6(isc_sockaddr_t *sockaddr);
+/*%<
+ * Return the IPv6 wildcard address.
+ */
+
+void
+isc_sockaddr_anyofpf(isc_sockaddr_t *sockaddr, int family);
+/*%<
+ * Set '*sockaddr' to the wildcard address of protocol family
+ * 'family'.
+ *
+ * Requires:
+ * \li 'family' is AF_INET or AF_INET6.
+ */
+
+void
+isc_sockaddr_fromin(isc_sockaddr_t *sockaddr, const struct in_addr *ina,
+ in_port_t port);
+/*%<
+ * Construct an isc_sockaddr_t from an IPv4 address and port.
+ */
+
+void
+isc_sockaddr_fromin6(isc_sockaddr_t *sockaddr, const struct in6_addr *ina6,
+ in_port_t port);
+/*%<
+ * Construct an isc_sockaddr_t from an IPv6 address and port.
+ */
+
+void
+isc_sockaddr_v6fromin(isc_sockaddr_t *sockaddr, const struct in_addr *ina,
+ in_port_t port);
+/*%<
+ * Construct an IPv6 isc_sockaddr_t representing a mapped IPv4 address.
+ */
+
+void
+isc_sockaddr_fromnetaddr(isc_sockaddr_t *sockaddr, const isc_netaddr_t *na,
+ in_port_t port);
+/*%<
+ * Construct an isc_sockaddr_t from an isc_netaddr_t and port.
+ */
+
+int
+isc_sockaddr_pf(const isc_sockaddr_t *sockaddr);
+/*%<
+ * Get the protocol family of 'sockaddr'.
+ *
+ * Requires:
+ *
+ *\li 'sockaddr' is a valid sockaddr with an address family of AF_INET
+ * or AF_INET6.
+ *
+ * Returns:
+ *
+ *\li The protocol family of 'sockaddr', e.g. PF_INET or PF_INET6.
+ */
+
+void
+isc_sockaddr_setport(isc_sockaddr_t *sockaddr, in_port_t port);
+/*%<
+ * Set the port of 'sockaddr' to 'port'.
+ */
+
+in_port_t
+isc_sockaddr_getport(const isc_sockaddr_t *sockaddr);
+/*%<
+ * Get the port stored in 'sockaddr'.
+ */
+
+isc_result_t
+isc_sockaddr_totext(const isc_sockaddr_t *sockaddr, isc_buffer_t *target);
+/*%<
+ * Append a text representation of 'sockaddr' to the buffer 'target'.
+ * The text will include both the IP address (v4 or v6) and the port.
+ * The text is null terminated, but the terminating null is not
+ * part of the buffer's used region.
+ *
+ * Returns:
+ * \li ISC_R_SUCCESS
+ * \li ISC_R_NOSPACE The text or the null termination did not fit.
+ */
+
+void
+isc_sockaddr_format(const isc_sockaddr_t *sa, char *array, unsigned int size);
+/*%<
+ * Format a human-readable representation of the socket address '*sa'
+ * into the character array 'array', which is of size 'size'.
+ * The resulting string is guaranteed to be null-terminated.
+ */
+
+isc_boolean_t
+isc_sockaddr_ismulticast(const isc_sockaddr_t *sa);
+/*%<
+ * Returns #ISC_TRUE if the address is a multicast address.
+ */
+
+isc_boolean_t
+isc_sockaddr_isexperimental(const isc_sockaddr_t *sa);
+/*
+ * Returns ISC_TRUE if the address is a experimental (CLASS E) address.
+ */
+
+isc_boolean_t
+isc_sockaddr_islinklocal(const isc_sockaddr_t *sa);
+/*%<
+ * Returns ISC_TRUE if the address is a link local address.
+ */
+
+isc_boolean_t
+isc_sockaddr_issitelocal(const isc_sockaddr_t *sa);
+/*%<
+ * Returns ISC_TRUE if the address is a sitelocal address.
+ */
+
+isc_result_t
+isc_sockaddr_frompath(isc_sockaddr_t *sockaddr, const char *path);
+/*
+ * Create a UNIX domain sockaddr that refers to path.
+ *
+ * Returns:
+ * \li ISC_R_NOSPACE
+ * \li ISC_R_NOTIMPLEMENTED
+ * \li ISC_R_SUCCESS
+ */
+
+#define ISC_SOCKADDR_FORMATSIZE \
+ sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:XXX.XXX.XXX.XXX%SSSSSSSSSS#YYYYY")
+/*%<
+ * Minimum size of array to pass to isc_sockaddr_format().
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_SOCKADDR_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/socket.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/socket.h
new file mode 100644
index 0000000..46e05a0
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/socket.h
@@ -0,0 +1,1168 @@
+/*
+ * Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+#ifndef ISC_SOCKET_H
+#define ISC_SOCKET_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file isc/socket.h
+ * \brief Provides TCP and UDP sockets for network I/O. The sockets are event
+ * sources in the task system.
+ *
+ * When I/O completes, a completion event for the socket is posted to the
+ * event queue of the task which requested the I/O.
+ *
+ * \li MP:
+ * The module ensures appropriate synchronization of data structures it
+ * creates and manipulates.
+ * Clients of this module must not be holding a socket's task's lock when
+ * making a call that affects that socket. Failure to follow this rule
+ * can result in deadlock.
+ * The caller must ensure that isc_socketmgr_destroy() is called only
+ * once for a given manager.
+ *
+ * \li Reliability:
+ * No anticipated impact.
+ *
+ * \li Resources:
+ * TBS
+ *
+ * \li Security:
+ * No anticipated impact.
+ *
+ * \li Standards:
+ * None.
+ */
+
+/***
+ *** Imports
+ ***/
+
+#include <isc/lang.h>
+#include <isc/types.h>
+#include <isc/event.h>
+#include <isc/eventclass.h>
+#include <isc/time.h>
+#include <isc/region.h>
+#include <isc/sockaddr.h>
+#include <isc/xml.h>
+
+ISC_LANG_BEGINDECLS
+
+/***
+ *** Constants
+ ***/
+
+/*%
+ * Maximum number of buffers in a scatter/gather read/write. The operating
+ * system in use must support at least this number (plus one on some.)
+ */
+#define ISC_SOCKET_MAXSCATTERGATHER 8
+
+/*%
+ * In isc_socket_bind() set socket option SO_REUSEADDR prior to calling
+ * bind() if a non zero port is specified (AF_INET and AF_INET6).
+ */
+#define ISC_SOCKET_REUSEADDRESS 0x01U
+
+/*%
+ * Statistics counters. Used as isc_statscounter_t values.
+ */
+enum {
+ isc_sockstatscounter_udp4open = 0,
+ isc_sockstatscounter_udp6open = 1,
+ isc_sockstatscounter_tcp4open = 2,
+ isc_sockstatscounter_tcp6open = 3,
+ isc_sockstatscounter_unixopen = 4,
+
+ isc_sockstatscounter_udp4openfail = 5,
+ isc_sockstatscounter_udp6openfail = 6,
+ isc_sockstatscounter_tcp4openfail = 7,
+ isc_sockstatscounter_tcp6openfail = 8,
+ isc_sockstatscounter_unixopenfail = 9,
+
+ isc_sockstatscounter_udp4close = 10,
+ isc_sockstatscounter_udp6close = 11,
+ isc_sockstatscounter_tcp4close = 12,
+ isc_sockstatscounter_tcp6close = 13,
+ isc_sockstatscounter_unixclose = 14,
+ isc_sockstatscounter_fdwatchclose = 15,
+
+ isc_sockstatscounter_udp4bindfail = 16,
+ isc_sockstatscounter_udp6bindfail = 17,
+ isc_sockstatscounter_tcp4bindfail = 18,
+ isc_sockstatscounter_tcp6bindfail = 19,
+ isc_sockstatscounter_unixbindfail = 20,
+ isc_sockstatscounter_fdwatchbindfail = 21,
+
+ isc_sockstatscounter_udp4connect = 22,
+ isc_sockstatscounter_udp6connect = 23,
+ isc_sockstatscounter_tcp4connect = 24,
+ isc_sockstatscounter_tcp6connect = 25,
+ isc_sockstatscounter_unixconnect = 26,
+ isc_sockstatscounter_fdwatchconnect = 27,
+
+ isc_sockstatscounter_udp4connectfail = 28,
+ isc_sockstatscounter_udp6connectfail = 29,
+ isc_sockstatscounter_tcp4connectfail = 30,
+ isc_sockstatscounter_tcp6connectfail = 31,
+ isc_sockstatscounter_unixconnectfail = 32,
+ isc_sockstatscounter_fdwatchconnectfail = 33,
+
+ isc_sockstatscounter_tcp4accept = 34,
+ isc_sockstatscounter_tcp6accept = 35,
+ isc_sockstatscounter_unixaccept = 36,
+
+ isc_sockstatscounter_tcp4acceptfail = 37,
+ isc_sockstatscounter_tcp6acceptfail = 38,
+ isc_sockstatscounter_unixacceptfail = 39,
+
+ isc_sockstatscounter_udp4sendfail = 40,
+ isc_sockstatscounter_udp6sendfail = 41,
+ isc_sockstatscounter_tcp4sendfail = 42,
+ isc_sockstatscounter_tcp6sendfail = 43,
+ isc_sockstatscounter_unixsendfail = 44,
+ isc_sockstatscounter_fdwatchsendfail = 45,
+
+ isc_sockstatscounter_udp4recvfail = 46,
+ isc_sockstatscounter_udp6recvfail = 47,
+ isc_sockstatscounter_tcp4recvfail = 48,
+ isc_sockstatscounter_tcp6recvfail = 49,
+ isc_sockstatscounter_unixrecvfail = 50,
+ isc_sockstatscounter_fdwatchrecvfail = 51,
+
+ isc_sockstatscounter_max = 52
+};
+
+/***
+ *** Types
+ ***/
+
+struct isc_socketevent {
+ ISC_EVENT_COMMON(isc_socketevent_t);
+ isc_result_t result; /*%< OK, EOF, whatever else */
+ unsigned int minimum; /*%< minimum i/o for event */
+ unsigned int n; /*%< bytes read or written */
+ unsigned int offset; /*%< offset into buffer list */
+ isc_region_t region; /*%< for single-buffer i/o */
+ isc_bufferlist_t bufferlist; /*%< list of buffers */
+ isc_sockaddr_t address; /*%< source address */
+ isc_time_t timestamp; /*%< timestamp of packet recv */
+ struct in6_pktinfo pktinfo; /*%< ipv6 pktinfo */
+ isc_uint32_t attributes; /*%< see below */
+ isc_eventdestructor_t destroy; /*%< original destructor */
+};
+
+typedef struct isc_socket_newconnev isc_socket_newconnev_t;
+struct isc_socket_newconnev {
+ ISC_EVENT_COMMON(isc_socket_newconnev_t);
+ isc_socket_t * newsocket;
+ isc_result_t result; /*%< OK, EOF, whatever else */
+ isc_sockaddr_t address; /*%< source address */
+};
+
+typedef struct isc_socket_connev isc_socket_connev_t;
+struct isc_socket_connev {
+ ISC_EVENT_COMMON(isc_socket_connev_t);
+ isc_result_t result; /*%< OK, EOF, whatever else */
+};
+
+/*@{*/
+/*!
+ * _ATTACHED: Internal use only.
+ * _TRUNC: Packet was truncated on receive.
+ * _CTRUNC: Packet control information was truncated. This can
+ * indicate that the packet is not complete, even though
+ * all the data is valid.
+ * _TIMESTAMP: The timestamp member is valid.
+ * _PKTINFO: The pktinfo member is valid.
+ * _MULTICAST: The UDP packet was received via a multicast transmission.
+ */
+#define ISC_SOCKEVENTATTR_ATTACHED 0x80000000U /* internal */
+#define ISC_SOCKEVENTATTR_TRUNC 0x00800000U /* public */
+#define ISC_SOCKEVENTATTR_CTRUNC 0x00400000U /* public */
+#define ISC_SOCKEVENTATTR_TIMESTAMP 0x00200000U /* public */
+#define ISC_SOCKEVENTATTR_PKTINFO 0x00100000U /* public */
+#define ISC_SOCKEVENTATTR_MULTICAST 0x00080000U /* public */
+/*@}*/
+
+#define ISC_SOCKEVENT_ANYEVENT (0)
+#define ISC_SOCKEVENT_RECVDONE (ISC_EVENTCLASS_SOCKET + 1)
+#define ISC_SOCKEVENT_SENDDONE (ISC_EVENTCLASS_SOCKET + 2)
+#define ISC_SOCKEVENT_NEWCONN (ISC_EVENTCLASS_SOCKET + 3)
+#define ISC_SOCKEVENT_CONNECT (ISC_EVENTCLASS_SOCKET + 4)
+
+/*
+ * Internal events.
+ */
+#define ISC_SOCKEVENT_INTR (ISC_EVENTCLASS_SOCKET + 256)
+#define ISC_SOCKEVENT_INTW (ISC_EVENTCLASS_SOCKET + 257)
+
+typedef enum {
+ isc_sockettype_udp = 1,
+ isc_sockettype_tcp = 2,
+ isc_sockettype_unix = 3,
+ isc_sockettype_fdwatch = 4
+} isc_sockettype_t;
+
+/*@{*/
+/*!
+ * How a socket should be shutdown in isc_socket_shutdown() calls.
+ */
+#define ISC_SOCKSHUT_RECV 0x00000001 /*%< close read side */
+#define ISC_SOCKSHUT_SEND 0x00000002 /*%< close write side */
+#define ISC_SOCKSHUT_ALL 0x00000003 /*%< close them all */
+/*@}*/
+
+/*@{*/
+/*!
+ * What I/O events to cancel in isc_socket_cancel() calls.
+ */
+#define ISC_SOCKCANCEL_RECV 0x00000001 /*%< cancel recv */
+#define ISC_SOCKCANCEL_SEND 0x00000002 /*%< cancel send */
+#define ISC_SOCKCANCEL_ACCEPT 0x00000004 /*%< cancel accept */
+#define ISC_SOCKCANCEL_CONNECT 0x00000008 /*%< cancel connect */
+#define ISC_SOCKCANCEL_ALL 0x0000000f /*%< cancel everything */
+/*@}*/
+
+/*@{*/
+/*!
+ * Flags for isc_socket_send() and isc_socket_recv() calls.
+ */
+#define ISC_SOCKFLAG_IMMEDIATE 0x00000001 /*%< send event only if needed */
+#define ISC_SOCKFLAG_NORETRY 0x00000002 /*%< drop failed UDP sends */
+/*@}*/
+
+/*@{*/
+/*!
+ * Flags for fdwatchcreate.
+ */
+#define ISC_SOCKFDWATCH_READ 0x00000001 /*%< watch for readable */
+#define ISC_SOCKFDWATCH_WRITE 0x00000002 /*%< watch for writable */
+/*@}*/
+
+/*% Socket and socket manager methods */
+typedef struct isc_socketmgrmethods {
+ void (*destroy)(isc_socketmgr_t **managerp);
+ isc_result_t (*socketcreate)(isc_socketmgr_t *manager, int pf,
+ isc_sockettype_t type,
+ isc_socket_t **socketp);
+ isc_result_t (*fdwatchcreate)(isc_socketmgr_t *manager, int fd,
+ int flags,
+ isc_sockfdwatch_t callback,
+ void *cbarg, isc_task_t *task,
+ isc_socket_t **socketp);
+} isc_socketmgrmethods_t;
+
+typedef struct isc_socketmethods {
+ void (*attach)(isc_socket_t *sock,
+ isc_socket_t **socketp);
+ void (*detach)(isc_socket_t **socketp);
+ isc_result_t (*bind)(isc_socket_t *sock, isc_sockaddr_t *sockaddr,
+ unsigned int options);
+ isc_result_t (*sendto)(isc_socket_t *sock, isc_region_t *region,
+ isc_task_t *task, isc_taskaction_t action,
+ const void *arg, isc_sockaddr_t *address,
+ struct in6_pktinfo *pktinfo);
+ isc_result_t (*connect)(isc_socket_t *sock, isc_sockaddr_t *addr,
+ isc_task_t *task, isc_taskaction_t action,
+ const void *arg);
+ isc_result_t (*recv)(isc_socket_t *sock, isc_region_t *region,
+ unsigned int minimum, isc_task_t *task,
+ isc_taskaction_t action, const void *arg);
+ void (*cancel)(isc_socket_t *sock, isc_task_t *task,
+ unsigned int how);
+ isc_result_t (*getsockname)(isc_socket_t *sock,
+ isc_sockaddr_t *addressp);
+ isc_sockettype_t (*gettype)(isc_socket_t *sock);
+ void (*ipv6only)(isc_socket_t *sock, isc_boolean_t yes);
+ isc_result_t (*fdwatchpoke)(isc_socket_t *sock, int flags);
+ isc_result_t (*dup)(isc_socket_t *sock,
+ isc_socket_t **socketp);
+ int (*getfd)(isc_socket_t *sock);
+} isc_socketmethods_t;
+
+/*%
+ * This structure is actually just the common prefix of a socket manager
+ * object implementation's version of an isc_socketmgr_t.
+ * \brief
+ * Direct use of this structure by clients is forbidden. socket implementations
+ * may change the structure. 'magic' must be ISCAPI_SOCKETMGR_MAGIC for any
+ * of the isc_socket_ routines to work. socket implementations must maintain
+ * all socket invariants.
+ * In effect, this definition is used only for non-BIND9 version ("export")
+ * of the library, and the export version does not work for win32. So, to avoid
+ * the definition conflict with win32/socket.c, we enable this definition only
+ * for non-Win32 (i.e. Unix) platforms.
+ */
+#ifndef WIN32
+struct isc_socketmgr {
+ unsigned int impmagic;
+ unsigned int magic;
+ isc_socketmgrmethods_t *methods;
+};
+#endif
+
+#define ISCAPI_SOCKETMGR_MAGIC ISC_MAGIC('A','s','m','g')
+#define ISCAPI_SOCKETMGR_VALID(m) ((m) != NULL && \
+ (m)->magic == ISCAPI_SOCKETMGR_MAGIC)
+
+/*%
+ * This is the common prefix of a socket object. The same note as
+ * that for the socketmgr structure applies.
+ */
+#ifndef WIN32
+struct isc_socket {
+ unsigned int impmagic;
+ unsigned int magic;
+ isc_socketmethods_t *methods;
+};
+#endif
+
+#define ISCAPI_SOCKET_MAGIC ISC_MAGIC('A','s','c','t')
+#define ISCAPI_SOCKET_VALID(s) ((s) != NULL && \
+ (s)->magic == ISCAPI_SOCKET_MAGIC)
+
+/***
+ *** Socket and Socket Manager Functions
+ ***
+ *** Note: all Ensures conditions apply only if the result is success for
+ *** those functions which return an isc_result.
+ ***/
+
+isc_result_t
+isc_socket_fdwatchcreate(isc_socketmgr_t *manager,
+ int fd,
+ int flags,
+ isc_sockfdwatch_t callback,
+ void *cbarg,
+ isc_task_t *task,
+ isc_socket_t **socketp);
+/*%<
+ * Create a new file descriptor watch socket managed by 'manager'.
+ *
+ * Note:
+ *
+ *\li 'fd' is the already-opened file descriptor.
+ *\li This function is not available on Windows.
+ *\li The callback function is called "in-line" - this means the function
+ * needs to return as fast as possible, as all other I/O will be suspended
+ * until the callback completes.
+ *
+ * Requires:
+ *
+ *\li 'manager' is a valid manager
+ *
+ *\li 'socketp' is a valid pointer, and *socketp == NULL
+ *
+ *\li 'fd' be opened.
+ *
+ * Ensures:
+ *
+ * '*socketp' is attached to the newly created fdwatch socket
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOMEMORY
+ *\li #ISC_R_NORESOURCES
+ *\li #ISC_R_UNEXPECTED
+ */
+
+isc_result_t
+isc_socket_fdwatchpoke(isc_socket_t *sock,
+ int flags);
+/*%<
+ * Poke a file descriptor watch socket informing the manager that it
+ * should restart watching the socket
+ *
+ * Note:
+ *
+ *\li 'sock' is the socket returned by isc_socket_fdwatchcreate
+ *
+ *\li 'flags' indicates what the manager should watch for on the socket
+ * in addition to what it may already be watching. It can be one or
+ * both of ISC_SOCKFDWATCH_READ and ISC_SOCKFDWATCH_WRITE. To
+ * temporarily disable watching on a socket the value indicating
+ * no more data should be returned from the call back routine.
+ *
+ *\li This function is not available on Windows.
+ *
+ * Requires:
+ *
+ *\li 'sock' is a valid isc socket
+ *
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ */
+
+isc_result_t
+isc_socket_create(isc_socketmgr_t *manager,
+ int pf,
+ isc_sockettype_t type,
+ isc_socket_t **socketp);
+/*%<
+ * Create a new 'type' socket managed by 'manager'.
+ *
+ * For isc_sockettype_fdwatch sockets you should use isc_socket_fdwatchcreate()
+ * rather than isc_socket_create().
+ *
+ * Note:
+ *
+ *\li 'pf' is the desired protocol family, e.g. PF_INET or PF_INET6.
+ *
+ * Requires:
+ *
+ *\li 'manager' is a valid manager
+ *
+ *\li 'socketp' is a valid pointer, and *socketp == NULL
+ *
+ *\li 'type' is not isc_sockettype_fdwatch
+ *
+ * Ensures:
+ *
+ * '*socketp' is attached to the newly created socket
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOMEMORY
+ *\li #ISC_R_NORESOURCES
+ *\li #ISC_R_UNEXPECTED
+ */
+
+isc_result_t
+isc_socket_dup(isc_socket_t *sock0, isc_socket_t **socketp);
+/*%<
+ * Duplicate an existing socket, reusing its file descriptor.
+ */
+
+void
+isc_socket_cancel(isc_socket_t *sock, isc_task_t *task,
+ unsigned int how);
+/*%<
+ * Cancel pending I/O of the type specified by "how".
+ *
+ * Note: if "task" is NULL, then the cancel applies to all tasks using the
+ * socket.
+ *
+ * Requires:
+ *
+ * \li "socket" is a valid socket
+ *
+ * \li "task" is NULL or a valid task
+ *
+ * "how" is a bitmask describing the type of cancelation to perform.
+ * The type ISC_SOCKCANCEL_ALL will cancel all pending I/O on this
+ * socket.
+ *
+ * \li ISC_SOCKCANCEL_RECV:
+ * Cancel pending isc_socket_recv() calls.
+ *
+ * \li ISC_SOCKCANCEL_SEND:
+ * Cancel pending isc_socket_send() and isc_socket_sendto() calls.
+ *
+ * \li ISC_SOCKCANCEL_ACCEPT:
+ * Cancel pending isc_socket_accept() calls.
+ *
+ * \li ISC_SOCKCANCEL_CONNECT:
+ * Cancel pending isc_socket_connect() call.
+ */
+
+void
+isc_socket_shutdown(isc_socket_t *sock, unsigned int how);
+/*%<
+ * Shutdown 'socket' according to 'how'.
+ *
+ * Requires:
+ *
+ * \li 'socket' is a valid socket.
+ *
+ * \li 'task' is NULL or is a valid task.
+ *
+ * \li If 'how' is 'ISC_SOCKSHUT_RECV' or 'ISC_SOCKSHUT_ALL' then
+ *
+ * The read queue must be empty.
+ *
+ * No further read requests may be made.
+ *
+ * \li If 'how' is 'ISC_SOCKSHUT_SEND' or 'ISC_SOCKSHUT_ALL' then
+ *
+ * The write queue must be empty.
+ *
+ * No further write requests may be made.
+ */
+
+void
+isc_socket_attach(isc_socket_t *sock, isc_socket_t **socketp);
+/*%<
+ * Attach *socketp to socket.
+ *
+ * Requires:
+ *
+ * \li 'socket' is a valid socket.
+ *
+ * \li 'socketp' points to a NULL socket.
+ *
+ * Ensures:
+ *
+ * \li *socketp is attached to socket.
+ */
+
+void
+isc_socket_detach(isc_socket_t **socketp);
+/*%<
+ * Detach *socketp from its socket.
+ *
+ * Requires:
+ *
+ * \li 'socketp' points to a valid socket.
+ *
+ * \li If '*socketp' is the last reference to the socket,
+ * then:
+ *
+ * There must be no pending I/O requests.
+ *
+ * Ensures:
+ *
+ * \li *socketp is NULL.
+ *
+ * \li If '*socketp' is the last reference to the socket,
+ * then:
+ *
+ * The socket will be shutdown (both reading and writing)
+ * for all tasks.
+ *
+ * All resources used by the socket have been freed
+ */
+
+isc_result_t
+isc_socket_open(isc_socket_t *sock);
+/*%<
+ * Open a new socket file descriptor of the given socket structure. It simply
+ * opens a new descriptor; all of the other parameters including the socket
+ * type are inherited from the existing socket. This function is provided to
+ * avoid overhead of destroying and creating sockets when many short-lived
+ * sockets are frequently opened and closed. When the efficiency is not an
+ * issue, it should be safer to detach the unused socket and re-create a new
+ * one. This optimization may not be available for some systems, in which
+ * case this function will return ISC_R_NOTIMPLEMENTED and must not be used.
+ *
+ * isc_socket_open() should not be called on sockets created by
+ * isc_socket_fdwatchcreate().
+ *
+ * Requires:
+ *
+ * \li there must be no other reference to this socket.
+ *
+ * \li 'socket' is a valid and previously closed by isc_socket_close()
+ *
+ * \li 'sock->type' is not isc_sockettype_fdwatch
+ *
+ * Returns:
+ * Same as isc_socket_create().
+ * \li ISC_R_NOTIMPLEMENTED
+ */
+
+isc_result_t
+isc_socket_close(isc_socket_t *sock);
+/*%<
+ * Close a socket file descriptor of the given socket structure. This function
+ * is provided as an alternative to destroying an unused socket when overhead
+ * destroying/re-creating sockets can be significant, and is expected to be
+ * used with isc_socket_open(). This optimization may not be available for some
+ * systems, in which case this function will return ISC_R_NOTIMPLEMENTED and
+ * must not be used.
+ *
+ * isc_socket_close() should not be called on sockets created by
+ * isc_socket_fdwatchcreate().
+ *
+ * Requires:
+ *
+ * \li The socket must have a valid descriptor.
+ *
+ * \li There must be no other reference to this socket.
+ *
+ * \li There must be no pending I/O requests.
+ *
+ * \li 'sock->type' is not isc_sockettype_fdwatch
+ *
+ * Returns:
+ * \li #ISC_R_NOTIMPLEMENTED
+ */
+
+isc_result_t
+isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *addressp,
+ unsigned int options);
+/*%<
+ * Bind 'socket' to '*addressp'.
+ *
+ * Requires:
+ *
+ * \li 'socket' is a valid socket
+ *
+ * \li 'addressp' points to a valid isc_sockaddr.
+ *
+ * Returns:
+ *
+ * \li ISC_R_SUCCESS
+ * \li ISC_R_NOPERM
+ * \li ISC_R_ADDRNOTAVAIL
+ * \li ISC_R_ADDRINUSE
+ * \li ISC_R_BOUND
+ * \li ISC_R_UNEXPECTED
+ */
+
+isc_result_t
+isc_socket_filter(isc_socket_t *sock, const char *filter);
+/*%<
+ * Inform the kernel that it should perform accept filtering.
+ * If filter is NULL the current filter will be removed.:w
+ */
+
+isc_result_t
+isc_socket_listen(isc_socket_t *sock, unsigned int backlog);
+/*%<
+ * Set listen mode on the socket. After this call, the only function that
+ * can be used (other than attach and detach) is isc_socket_accept().
+ *
+ * Notes:
+ *
+ * \li 'backlog' is as in the UNIX system call listen() and may be
+ * ignored by non-UNIX implementations.
+ *
+ * \li If 'backlog' is zero, a reasonable system default is used, usually
+ * SOMAXCONN.
+ *
+ * Requires:
+ *
+ * \li 'socket' is a valid, bound TCP socket or a valid, bound UNIX socket.
+ *
+ * Returns:
+ *
+ * \li ISC_R_SUCCESS
+ * \li ISC_R_UNEXPECTED
+ */
+
+isc_result_t
+isc_socket_accept(isc_socket_t *sock,
+ isc_task_t *task, isc_taskaction_t action, const void *arg);
+/*%<
+ * Queue accept event. When a new connection is received, the task will
+ * get an ISC_SOCKEVENT_NEWCONN event with the sender set to the listen
+ * socket. The new socket structure is sent inside the isc_socket_newconnev_t
+ * event type, and is attached to the task 'task'.
+ *
+ * REQUIRES:
+ * \li 'socket' is a valid TCP socket that isc_socket_listen() was called
+ * on.
+ *
+ * \li 'task' is a valid task
+ *
+ * \li 'action' is a valid action
+ *
+ * RETURNS:
+ * \li ISC_R_SUCCESS
+ * \li ISC_R_NOMEMORY
+ * \li ISC_R_UNEXPECTED
+ */
+
+isc_result_t
+isc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addressp,
+ isc_task_t *task, isc_taskaction_t action,
+ const void *arg);
+/*%<
+ * Connect 'socket' to peer with address *saddr. When the connection
+ * succeeds, or when an error occurs, a CONNECT event with action 'action'
+ * and arg 'arg' will be posted to the event queue for 'task'.
+ *
+ * Requires:
+ *
+ * \li 'socket' is a valid TCP socket
+ *
+ * \li 'addressp' points to a valid isc_sockaddr
+ *
+ * \li 'task' is a valid task
+ *
+ * \li 'action' is a valid action
+ *
+ * Returns:
+ *
+ * \li ISC_R_SUCCESS
+ * \li ISC_R_NOMEMORY
+ * \li ISC_R_UNEXPECTED
+ *
+ * Posted event's result code:
+ *
+ * \li ISC_R_SUCCESS
+ * \li ISC_R_TIMEDOUT
+ * \li ISC_R_CONNREFUSED
+ * \li ISC_R_NETUNREACH
+ * \li ISC_R_UNEXPECTED
+ */
+
+isc_result_t
+isc_socket_getpeername(isc_socket_t *sock, isc_sockaddr_t *addressp);
+/*%<
+ * Get the name of the peer connected to 'socket'.
+ *
+ * Requires:
+ *
+ * \li 'socket' is a valid TCP socket.
+ *
+ * Returns:
+ *
+ * \li ISC_R_SUCCESS
+ * \li ISC_R_TOOSMALL
+ * \li ISC_R_UNEXPECTED
+ */
+
+isc_result_t
+isc_socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp);
+/*%<
+ * Get the name of 'socket'.
+ *
+ * Requires:
+ *
+ * \li 'socket' is a valid socket.
+ *
+ * Returns:
+ *
+ * \li ISC_R_SUCCESS
+ * \li ISC_R_TOOSMALL
+ * \li ISC_R_UNEXPECTED
+ */
+
+/*@{*/
+isc_result_t
+isc_socket_recv(isc_socket_t *sock, isc_region_t *region,
+ unsigned int minimum,
+ isc_task_t *task, isc_taskaction_t action, const void *arg);
+isc_result_t
+isc_socket_recvv(isc_socket_t *sock, isc_bufferlist_t *buflist,
+ unsigned int minimum,
+ isc_task_t *task, isc_taskaction_t action, const void *arg);
+
+isc_result_t
+isc_socket_recv2(isc_socket_t *sock, isc_region_t *region,
+ unsigned int minimum, isc_task_t *task,
+ isc_socketevent_t *event, unsigned int flags);
+
+/*!
+ * Receive from 'socket', storing the results in region.
+ *
+ * Notes:
+ *
+ *\li Let 'length' refer to the length of 'region' or to the sum of all
+ * available regions in the list of buffers '*buflist'.
+ *
+ *\li If 'minimum' is non-zero and at least that many bytes are read,
+ * the completion event will be posted to the task 'task.' If minimum
+ * is zero, the exact number of bytes requested in the region must
+ * be read for an event to be posted. This only makes sense for TCP
+ * connections, and is always set to 1 byte for UDP.
+ *
+ *\li The read will complete when the desired number of bytes have been
+ * read, if end-of-input occurs, or if an error occurs. A read done
+ * event with the given 'action' and 'arg' will be posted to the
+ * event queue of 'task'.
+ *
+ *\li The caller may not modify 'region', the buffers which are passed
+ * into this function, or any data they refer to until the completion
+ * event is received.
+ *
+ *\li For isc_socket_recvv():
+ * On successful completion, '*buflist' will be empty, and the list of
+ * all buffers will be returned in the done event's 'bufferlist'
+ * member. On error return, '*buflist' will be unchanged.
+ *
+ *\li For isc_socket_recv2():
+ * 'event' is not NULL, and the non-socket specific fields are
+ * expected to be initialized.
+ *
+ *\li For isc_socket_recv2():
+ * The only defined value for 'flags' is ISC_SOCKFLAG_IMMEDIATE. If
+ * set and the operation completes, the return value will be
+ * ISC_R_SUCCESS and the event will be filled in and not sent. If the
+ * operation does not complete, the return value will be
+ * ISC_R_INPROGRESS and the event will be sent when the operation
+ * completes.
+ *
+ * Requires:
+ *
+ *\li 'socket' is a valid, bound socket.
+ *
+ *\li For isc_socket_recv():
+ * 'region' is a valid region
+ *
+ *\li For isc_socket_recvv():
+ * 'buflist' is non-NULL, and '*buflist' contain at least one buffer.
+ *
+ *\li 'task' is a valid task
+ *
+ *\li For isc_socket_recv() and isc_socket_recvv():
+ * action != NULL and is a valid action
+ *
+ *\li For isc_socket_recv2():
+ * event != NULL
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_INPROGRESS
+ *\li #ISC_R_NOMEMORY
+ *\li #ISC_R_UNEXPECTED
+ *
+ * Event results:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_UNEXPECTED
+ *\li XXX needs other net-type errors
+ */
+/*@}*/
+
+/*@{*/
+isc_result_t
+isc_socket_send(isc_socket_t *sock, isc_region_t *region,
+ isc_task_t *task, isc_taskaction_t action, const void *arg);
+isc_result_t
+isc_socket_sendto(isc_socket_t *sock, isc_region_t *region,
+ isc_task_t *task, isc_taskaction_t action, const void *arg,
+ isc_sockaddr_t *address, struct in6_pktinfo *pktinfo);
+isc_result_t
+isc_socket_sendv(isc_socket_t *sock, isc_bufferlist_t *buflist,
+ isc_task_t *task, isc_taskaction_t action, const void *arg);
+isc_result_t
+isc_socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist,
+ isc_task_t *task, isc_taskaction_t action, const void *arg,
+ isc_sockaddr_t *address, struct in6_pktinfo *pktinfo);
+isc_result_t
+isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region,
+ isc_task_t *task,
+ isc_sockaddr_t *address, struct in6_pktinfo *pktinfo,
+ isc_socketevent_t *event, unsigned int flags);
+
+/*!
+ * Send the contents of 'region' to the socket's peer.
+ *
+ * Notes:
+ *
+ *\li Shutting down the requestor's task *may* result in any
+ * still pending writes being dropped or completed, depending on the
+ * underlying OS implementation.
+ *
+ *\li If 'action' is NULL, then no completion event will be posted.
+ *
+ *\li The caller may not modify 'region', the buffers which are passed
+ * into this function, or any data they refer to until the completion
+ * event is received.
+ *
+ *\li For isc_socket_sendv() and isc_socket_sendtov():
+ * On successful completion, '*buflist' will be empty, and the list of
+ * all buffers will be returned in the done event's 'bufferlist'
+ * member. On error return, '*buflist' will be unchanged.
+ *
+ *\li For isc_socket_sendto2():
+ * 'event' is not NULL, and the non-socket specific fields are
+ * expected to be initialized.
+ *
+ *\li For isc_socket_sendto2():
+ * The only defined values for 'flags' are ISC_SOCKFLAG_IMMEDIATE
+ * and ISC_SOCKFLAG_NORETRY.
+ *
+ *\li If ISC_SOCKFLAG_IMMEDIATE is set and the operation completes, the
+ * return value will be ISC_R_SUCCESS and the event will be filled
+ * in and not sent. If the operation does not complete, the return
+ * value will be ISC_R_INPROGRESS and the event will be sent when
+ * the operation completes.
+ *
+ *\li ISC_SOCKFLAG_NORETRY can only be set for UDP sockets. If set
+ * and the send operation fails due to a transient error, the send
+ * will not be retried and the error will be indicated in the event.
+ * Using this option along with ISC_SOCKFLAG_IMMEDIATE allows the caller
+ * to specify a region that is allocated on the stack.
+ *
+ * Requires:
+ *
+ *\li 'socket' is a valid, bound socket.
+ *
+ *\li For isc_socket_send():
+ * 'region' is a valid region
+ *
+ *\li For isc_socket_sendv() and isc_socket_sendtov():
+ * 'buflist' is non-NULL, and '*buflist' contain at least one buffer.
+ *
+ *\li 'task' is a valid task
+ *
+ *\li For isc_socket_sendv(), isc_socket_sendtov(), isc_socket_send(), and
+ * isc_socket_sendto():
+ * action == NULL or is a valid action
+ *
+ *\li For isc_socket_sendto2():
+ * event != NULL
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_INPROGRESS
+ *\li #ISC_R_NOMEMORY
+ *\li #ISC_R_UNEXPECTED
+ *
+ * Event results:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_UNEXPECTED
+ *\li XXX needs other net-type errors
+ */
+/*@}*/
+
+isc_result_t
+isc_socketmgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx,
+ isc_socketmgr_t **managerp);
+
+isc_result_t
+isc_socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp);
+
+isc_result_t
+isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
+ unsigned int maxsocks);
+/*%<
+ * Create a socket manager. If "maxsocks" is non-zero, it specifies the
+ * maximum number of sockets that the created manager should handle.
+ * isc_socketmgr_create() is equivalent of isc_socketmgr_create2() with
+ * "maxsocks" being zero.
+ * isc_socketmgr_createinctx() also associates the new manager with the
+ * specified application context.
+ *
+ * Notes:
+ *
+ *\li All memory will be allocated in memory context 'mctx'.
+ *
+ * Requires:
+ *
+ *\li 'mctx' is a valid memory context.
+ *
+ *\li 'managerp' points to a NULL isc_socketmgr_t.
+ *
+ *\li 'actx' is a valid application context (for createinctx()).
+ *
+ * Ensures:
+ *
+ *\li '*managerp' is a valid isc_socketmgr_t.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOMEMORY
+ *\li #ISC_R_UNEXPECTED
+ *\li #ISC_R_NOTIMPLEMENTED
+ */
+
+isc_result_t
+isc_socketmgr_getmaxsockets(isc_socketmgr_t *manager, unsigned int *nsockp);
+/*%<
+ * Returns in "*nsockp" the maximum number of sockets this manager may open.
+ *
+ * Requires:
+ *
+ *\li '*manager' is a valid isc_socketmgr_t.
+ *\li 'nsockp' is not NULL.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOTIMPLEMENTED
+ */
+
+void
+isc_socketmgr_setstats(isc_socketmgr_t *manager, isc_stats_t *stats);
+/*%<
+ * Set a general socket statistics counter set 'stats' for 'manager'.
+ *
+ * Requires:
+ * \li 'manager' is valid, hasn't opened any socket, and doesn't have
+ * stats already set.
+ *
+ *\li stats is a valid statistics supporting socket statistics counters
+ * (see above).
+ */
+
+void
+isc_socketmgr_destroy(isc_socketmgr_t **managerp);
+/*%<
+ * Destroy a socket manager.
+ *
+ * Notes:
+ *
+ *\li This routine blocks until there are no sockets left in the manager,
+ * so if the caller holds any socket references using the manager, it
+ * must detach them before calling isc_socketmgr_destroy() or it will
+ * block forever.
+ *
+ * Requires:
+ *
+ *\li '*managerp' is a valid isc_socketmgr_t.
+ *
+ *\li All sockets managed by this manager are fully detached.
+ *
+ * Ensures:
+ *
+ *\li *managerp == NULL
+ *
+ *\li All resources used by the manager have been freed.
+ */
+
+isc_sockettype_t
+isc_socket_gettype(isc_socket_t *sock);
+/*%<
+ * Returns the socket type for "sock."
+ *
+ * Requires:
+ *
+ *\li "sock" is a valid socket.
+ */
+
+/*@{*/
+isc_boolean_t
+isc_socket_isbound(isc_socket_t *sock);
+
+void
+isc_socket_ipv6only(isc_socket_t *sock, isc_boolean_t yes);
+/*%<
+ * If the socket is an IPv6 socket set/clear the IPV6_IPV6ONLY socket
+ * option if the host OS supports this option.
+ *
+ * Requires:
+ *\li 'sock' is a valid socket.
+ */
+/*@}*/
+
+void
+isc_socket_cleanunix(isc_sockaddr_t *addr, isc_boolean_t active);
+
+/*%<
+ * Cleanup UNIX domain sockets in the file-system. If 'active' is true
+ * then just unlink the socket. If 'active' is false try to determine
+ * if there is a listener of the socket or not. If no listener is found
+ * then unlink socket.
+ *
+ * Prior to unlinking the path is tested to see if it a socket.
+ *
+ * Note: there are a number of race conditions which cannot be avoided
+ * both in the filesystem and any application using UNIX domain
+ * sockets (e.g. socket is tested between bind() and listen(),
+ * the socket is deleted and replaced in the file-system between
+ * stat() and unlink()).
+ */
+
+isc_result_t
+isc_socket_permunix(isc_sockaddr_t *sockaddr, isc_uint32_t perm,
+ isc_uint32_t owner, isc_uint32_t group);
+/*%<
+ * Set ownership and file permissions on the UNIX domain socket.
+ *
+ * Note: On Solaris and SunOS this secures the directory containing
+ * the socket as Solaris and SunOS do not honour the filesystem
+ * permissions on the socket.
+ *
+ * Requires:
+ * \li 'sockaddr' to be a valid UNIX domain sockaddr.
+ *
+ * Returns:
+ * \li #ISC_R_SUCCESS
+ * \li #ISC_R_FAILURE
+ */
+
+void isc_socket_setname(isc_socket_t *sock, const char *name, void *tag);
+/*%<
+ * Set the name and optional tag for a socket. This allows tracking of the
+ * owner or purpose for this socket, and is useful for tracing and statistics
+ * reporting.
+ */
+
+const char *isc_socket_getname(isc_socket_t *sock);
+/*%<
+ * Get the name associated with a socket, if any.
+ */
+
+void *isc_socket_gettag(isc_socket_t *sock);
+/*%<
+ * Get the tag associated with a socket, if any.
+ */
+
+int isc_socket_getfd(isc_socket_t *sock);
+/*%<
+ * Get the file descriptor associated with a socket
+ */
+
+void
+isc__socketmgr_setreserved(isc_socketmgr_t *mgr, isc_uint32_t);
+/*%<
+ * Temporary. For use by named only.
+ */
+
+void
+isc__socketmgr_maxudp(isc_socketmgr_t *mgr, int maxudp);
+/*%<
+ * Test interface. Drop UDP packet > 'maxudp'.
+ */
+
+#ifdef HAVE_LIBXML2
+
+void
+isc_socketmgr_renderxml(isc_socketmgr_t *mgr, xmlTextWriterPtr writer);
+/*%<
+ * Render internal statistics and other state into the XML document.
+ */
+
+#endif /* HAVE_LIBXML2 */
+
+#ifdef USE_SOCKETIMPREGISTER
+/*%<
+ * See isc_socketmgr_create() above.
+ */
+typedef isc_result_t
+(*isc_socketmgrcreatefunc_t)(isc_mem_t *mctx, isc_socketmgr_t **managerp);
+
+isc_result_t
+isc_socket_register(isc_socketmgrcreatefunc_t createfunc);
+/*%<
+ * Register a new socket I/O implementation and add it to the list of
+ * supported implementations. This function must be called when a different
+ * event library is used than the one contained in the ISC library.
+ */
+
+isc_result_t
+isc__socket_register(void);
+/*%<
+ * A short cut function that specifies the socket I/O module in the ISC
+ * library for isc_socket_register(). An application that uses the ISC library
+ * usually do not have to care about this function: it would call
+ * isc_lib_register(), which internally calls this function.
+ */
+#endif /* USE_SOCKETIMPREGISTER */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_SOCKET_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/stats.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/stats.h
new file mode 100644
index 0000000..682eefd
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/stats.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+#ifndef ISC_STATS_H
+#define ISC_STATS_H 1
+
+/*! \file isc/stats.h */
+
+#include <isc/types.h>
+
+ISC_LANG_BEGINDECLS
+
+/*%<
+ * Flag(s) for isc_stats_dump().
+ */
+#define ISC_STATSDUMP_VERBOSE 0x00000001 /*%< dump 0-value counters */
+
+/*%<
+ * Dump callback type.
+ */
+typedef void (*isc_stats_dumper_t)(isc_statscounter_t, isc_uint64_t, void *);
+
+isc_result_t
+isc_stats_create(isc_mem_t *mctx, isc_stats_t **statsp, int ncounters);
+/*%<
+ * Create a statistics counter structure of general type. It counts a general
+ * set of counters indexed by an ID between 0 and ncounters -1.
+ *
+ * Requires:
+ *\li 'mctx' must be a valid memory context.
+ *
+ *\li 'statsp' != NULL && '*statsp' == NULL.
+ *
+ * Returns:
+ *\li ISC_R_SUCCESS -- all ok
+ *
+ *\li anything else -- failure
+ */
+
+void
+isc_stats_attach(isc_stats_t *stats, isc_stats_t **statsp);
+/*%<
+ * Attach to a statistics set.
+ *
+ * Requires:
+ *\li 'stats' is a valid isc_stats_t.
+ *
+ *\li 'statsp' != NULL && '*statsp' == NULL
+ */
+
+void
+isc_stats_detach(isc_stats_t **statsp);
+/*%<
+ * Detaches from the statistics set.
+ *
+ * Requires:
+ *\li 'statsp' != NULL and '*statsp' is a valid isc_stats_t.
+ */
+
+int
+isc_stats_ncounters(isc_stats_t *stats);
+/*%<
+ * Returns the number of counters contained in stats.
+ *
+ * Requires:
+ *\li 'stats' is a valid isc_stats_t.
+ *
+ */
+
+void
+isc_stats_increment(isc_stats_t *stats, isc_statscounter_t counter);
+/*%<
+ * Increment the counter-th counter of stats.
+ *
+ * Requires:
+ *\li 'stats' is a valid isc_stats_t.
+ *
+ *\li counter is less than the maximum available ID for the stats specified
+ * on creation.
+ */
+
+void
+isc_stats_decrement(isc_stats_t *stats, isc_statscounter_t counter);
+/*%<
+ * Decrement the counter-th counter of stats.
+ *
+ * Requires:
+ *\li 'stats' is a valid isc_stats_t.
+ */
+
+void
+isc_stats_dump(isc_stats_t *stats, isc_stats_dumper_t dump_fn, void *arg,
+ unsigned int options);
+/*%<
+ * Dump the current statistics counters in a specified way. For each counter
+ * in stats, dump_fn is called with its current value and the given argument
+ * arg. By default counters that have a value of 0 is skipped; if options has
+ * the ISC_STATSDUMP_VERBOSE flag, even such counters are dumped.
+ *
+ * Requires:
+ *\li 'stats' is a valid isc_stats_t.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_STATS_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/stdio.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/stdio.h
new file mode 100644
index 0000000..1a7ae64
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/stdio.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: stdio.h,v 1.13 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_STDIO_H
+#define ISC_STDIO_H 1
+
+/*! \file isc/stdio.h */
+
+/*%
+ * These functions are wrappers around the corresponding stdio functions.
+ *
+ * They return a detailed error code in the form of an an isc_result_t. ANSI C
+ * does not guarantee that stdio functions set errno, hence these functions
+ * must use platform dependent methods (e.g., the POSIX errno) to construct the
+ * error code.
+ */
+
+#include <stdio.h>
+
+#include <isc/lang.h>
+#include <isc/result.h>
+
+ISC_LANG_BEGINDECLS
+
+/*% Open */
+isc_result_t
+isc_stdio_open(const char *filename, const char *mode, FILE **fp);
+
+/*% Close */
+isc_result_t
+isc_stdio_close(FILE *f);
+
+/*% Seek */
+isc_result_t
+isc_stdio_seek(FILE *f, long offset, int whence);
+
+/*% Read */
+isc_result_t
+isc_stdio_read(void *ptr, size_t size, size_t nmemb, FILE *f,
+ size_t *nret);
+
+/*% Write */
+isc_result_t
+isc_stdio_write(const void *ptr, size_t size, size_t nmemb, FILE *f,
+ size_t *nret);
+
+/*% Flush */
+isc_result_t
+isc_stdio_flush(FILE *f);
+
+isc_result_t
+isc_stdio_sync(FILE *f);
+/*%<
+ * Invoke fsync() on the file descriptor underlying an stdio stream, or an
+ * equivalent system-dependent operation. Note that this function has no
+ * direct counterpart in the stdio library.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_STDIO_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/stdlib.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/stdlib.h
new file mode 100644
index 0000000..02243f0
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/stdlib.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: stdlib.h,v 1.8 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_STDLIB_H
+#define ISC_STDLIB_H 1
+
+/*! \file isc/stdlib.h */
+
+#include <stdlib.h>
+
+#include <isc/lang.h>
+#include <isc/platform.h>
+
+#ifdef ISC_PLATFORM_NEEDSTRTOUL
+#define strtoul isc_strtoul
+#endif
+
+ISC_LANG_BEGINDECLS
+
+unsigned long isc_strtoul(const char *, char **, int);
+
+ISC_LANG_ENDDECLS
+
+#endif
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/string.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/string.h
new file mode 100644
index 0000000..395b550
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/string.h
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: string.h,v 1.23 2007/09/13 04:48:16 each Exp $ */
+
+#ifndef ISC_STRING_H
+#define ISC_STRING_H 1
+
+/*! \file isc/string.h */
+
+#include <isc/formatcheck.h>
+#include <isc/int.h>
+#include <isc/lang.h>
+#include <isc/platform.h>
+#include <isc/types.h>
+
+#include <string.h>
+
+#ifdef ISC_PLATFORM_HAVESTRINGSH
+#include <strings.h>
+#endif
+
+#define ISC_STRING_MAGIC 0x5e
+
+ISC_LANG_BEGINDECLS
+
+isc_uint64_t
+isc_string_touint64(char *source, char **endp, int base);
+/*%<
+ * Convert the string pointed to by 'source' to isc_uint64_t.
+ *
+ * On successful conversion 'endp' points to the first character
+ * after conversion is complete.
+ *
+ * 'base': 0 or 2..36
+ *
+ * If base is 0 the base is computed from the string type.
+ *
+ * On error 'endp' points to 'source'.
+ */
+
+isc_result_t
+isc_string_copy(char *target, size_t size, const char *source);
+/*
+ * Copy the string pointed to by 'source' to 'target' which is a
+ * pointer to a string of at least 'size' bytes.
+ *
+ * Requires:
+ * 'target' is a pointer to a char[] of at least 'size' bytes.
+ * 'size' an integer > 0.
+ * 'source' == NULL or points to a NUL terminated string.
+ *
+ * Ensures:
+ * If result == ISC_R_SUCCESS
+ * 'target' will be a NUL terminated string of no more
+ * than 'size' bytes (including NUL).
+ *
+ * If result == ISC_R_NOSPACE
+ * 'target' is undefined.
+ *
+ * Returns:
+ * ISC_R_SUCCESS -- 'source' was successfully copied to 'target'.
+ * ISC_R_NOSPACE -- 'source' could not be copied since 'target'
+ * is too small.
+ */
+
+void
+isc_string_copy_truncate(char *target, size_t size, const char *source);
+/*
+ * Copy the string pointed to by 'source' to 'target' which is a
+ * pointer to a string of at least 'size' bytes.
+ *
+ * Requires:
+ * 'target' is a pointer to a char[] of at least 'size' bytes.
+ * 'size' an integer > 0.
+ * 'source' == NULL or points to a NUL terminated string.
+ *
+ * Ensures:
+ * 'target' will be a NUL terminated string of no more
+ * than 'size' bytes (including NUL).
+ */
+
+isc_result_t
+isc_string_append(char *target, size_t size, const char *source);
+/*
+ * Append the string pointed to by 'source' to 'target' which is a
+ * pointer to a NUL terminated string of at least 'size' bytes.
+ *
+ * Requires:
+ * 'target' is a pointer to a NUL terminated char[] of at
+ * least 'size' bytes.
+ * 'size' an integer > 0.
+ * 'source' == NULL or points to a NUL terminated string.
+ *
+ * Ensures:
+ * If result == ISC_R_SUCCESS
+ * 'target' will be a NUL terminated string of no more
+ * than 'size' bytes (including NUL).
+ *
+ * If result == ISC_R_NOSPACE
+ * 'target' is undefined.
+ *
+ * Returns:
+ * ISC_R_SUCCESS -- 'source' was successfully appended to 'target'.
+ * ISC_R_NOSPACE -- 'source' could not be appended since 'target'
+ * is too small.
+ */
+
+void
+isc_string_append_truncate(char *target, size_t size, const char *source);
+/*
+ * Append the string pointed to by 'source' to 'target' which is a
+ * pointer to a NUL terminated string of at least 'size' bytes.
+ *
+ * Requires:
+ * 'target' is a pointer to a NUL terminated char[] of at
+ * least 'size' bytes.
+ * 'size' an integer > 0.
+ * 'source' == NULL or points to a NUL terminated string.
+ *
+ * Ensures:
+ * 'target' will be a NUL terminated string of no more
+ * than 'size' bytes (including NUL).
+ */
+
+isc_result_t
+isc_string_printf(char *target, size_t size, const char *format, ...)
+ ISC_FORMAT_PRINTF(3, 4);
+/*
+ * Print 'format' to 'target' which is a pointer to a string of at least
+ * 'size' bytes.
+ *
+ * Requires:
+ * 'target' is a pointer to a char[] of at least 'size' bytes.
+ * 'size' an integer > 0.
+ * 'format' == NULL or points to a NUL terminated string.
+ *
+ * Ensures:
+ * If result == ISC_R_SUCCESS
+ * 'target' will be a NUL terminated string of no more
+ * than 'size' bytes (including NUL).
+ *
+ * If result == ISC_R_NOSPACE
+ * 'target' is undefined.
+ *
+ * Returns:
+ * ISC_R_SUCCESS -- 'format' was successfully printed to 'target'.
+ * ISC_R_NOSPACE -- 'format' could not be printed to 'target' since it
+ * is too small.
+ */
+
+void
+isc_string_printf_truncate(char *target, size_t size, const char *format, ...)
+ ISC_FORMAT_PRINTF(3, 4);
+/*
+ * Print 'format' to 'target' which is a pointer to a string of at least
+ * 'size' bytes.
+ *
+ * Requires:
+ * 'target' is a pointer to a char[] of at least 'size' bytes.
+ * 'size' an integer > 0.
+ * 'format' == NULL or points to a NUL terminated string.
+ *
+ * Ensures:
+ * 'target' will be a NUL terminated string of no more
+ * than 'size' bytes (including NUL).
+ */
+
+
+char *
+isc_string_regiondup(isc_mem_t *mctx, const isc_region_t *source);
+/*
+ * Copy the region pointed to by r to a NUL terminated string
+ * allocated from the memory context pointed to by mctx.
+ *
+ * The result should be deallocated using isc_mem_free()
+ *
+ * Requires:
+ * 'mctx' is a point to a valid memory context.
+ * 'source' is a pointer to a valid region.
+ *
+ * Returns:
+ * a pointer to a NUL terminated string or
+ * NULL if memory for the copy could not be allocated
+ *
+ */
+
+int
+isc_tsmemcmp(const void *p1, const void *p2, size_t len);
+/*
+ * Lexicographic compare 'len' unsigned bytes from 'p1' and 'p2'
+ * like 'memcmp()'.
+ *
+ * This function is safe from timing attacks as it has a runtime that
+ * only depends on 'len' and has no early-out option.
+ *
+ * Use this to check MACs and other material that is security sensitive.
+ *
+ * Returns:
+ * (let x be the byte offset of the first different byte)
+ * -1 if (u_char)p1[x] < (u_char)p2[x]
+ * 1 if (u_char)p1[x] > (u_char)p2[x]
+ * 0 if byte series are equal
+ */
+
+char *
+isc_string_separate(char **stringp, const char *delim);
+
+#ifdef ISC_PLATFORM_NEEDSTRSEP
+#define strsep isc_string_separate
+#endif
+
+#ifdef ISC_PLATFORM_NEEDMEMMOVE
+#define memmove(a,b,c) bcopy(b,a,c)
+#endif
+
+size_t
+isc_string_strlcpy(char *dst, const char *src, size_t size);
+
+
+#ifdef ISC_PLATFORM_NEEDSTRLCPY
+#define strlcpy isc_string_strlcpy
+#endif
+
+
+size_t
+isc_string_strlcat(char *dst, const char *src, size_t size);
+
+#ifdef ISC_PLATFORM_NEEDSTRLCAT
+#define strlcat isc_string_strlcat
+#endif
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_STRING_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/symtab.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/symtab.h
new file mode 100644
index 0000000..9d0e5e2
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/symtab.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2004-2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1996-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+#ifndef ISC_SYMTAB_H
+#define ISC_SYMTAB_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file isc/symtab.h
+ * \brief Provides a simple memory-based symbol table.
+ *
+ * Keys are C strings, and key comparisons are case-insensitive. A type may
+ * be specified when looking up, defining, or undefining. A type value of
+ * 0 means "match any type"; any other value will only match the given
+ * type.
+ *
+ * It's possible that a client will attempt to define a <key, type, value>
+ * tuple when a tuple with the given key and type already exists in the table.
+ * What to do in this case is specified by the client. Possible policies are:
+ *
+ *\li #isc_symexists_reject Disallow the define, returning #ISC_R_EXISTS
+ *\li #isc_symexists_replace Replace the old value with the new. The
+ * undefine action (if provided) will be called
+ * with the old <key, type, value> tuple.
+ *\li #isc_symexists_add Add the new tuple, leaving the old tuple in
+ * the table. Subsequent lookups will retrieve
+ * the most-recently-defined tuple.
+ *
+ * A lookup of a key using type 0 will return the most-recently defined
+ * symbol with that key. An undefine of a key using type 0 will undefine the
+ * most-recently defined symbol with that key. Trying to define a key with
+ * type 0 is illegal.
+ *
+ * The symbol table library does not make a copy the key field, so the
+ * caller must ensure that any key it passes to isc_symtab_define() will not
+ * change until it calls isc_symtab_undefine() or isc_symtab_destroy().
+ *
+ * A user-specified action will be called (if provided) when a symbol is
+ * undefined. It can be used to free memory associated with keys and/or
+ * values.
+ *
+ * A symbol table is implemented as a hash table of lists; the size of the
+ * hash table is set by the 'size' parameter to isc_symtbl_create(). When
+ * the number of entries in the symbol table reaches three quarters of this
+ * value, the hash table is reallocated with size doubled, in order to
+ * optimize lookup performance. This has a negative effect on insertion
+ * performance, which can be mitigated by sizing the table appropriately
+ * when creating it.
+ *
+ * \li MP:
+ * The callers of this module must ensure any required synchronization.
+ *
+ * \li Reliability:
+ * No anticipated impact.
+ *
+ * \li Resources:
+ * TBS
+ *
+ * \li Security:
+ * No anticipated impact.
+ *
+ * \li Standards:
+ * None.
+ */
+
+/***
+ *** Imports.
+ ***/
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+/*
+ *** Symbol Tables.
+ ***/
+/*% Symbol table value. */
+typedef union isc_symvalue {
+ void * as_pointer;
+ const void * as_cpointer;
+ int as_integer;
+ unsigned int as_uinteger;
+} isc_symvalue_t;
+
+typedef void (*isc_symtabaction_t)(char *key, unsigned int type,
+ isc_symvalue_t value, void *userarg);
+/*% Symbol table exists. */
+typedef enum {
+ isc_symexists_reject = 0, /*%< Disallow the define */
+ isc_symexists_replace = 1, /*%< Replace the old value with the new */
+ isc_symexists_add = 2 /*%< Add the new tuple */
+} isc_symexists_t;
+
+ISC_LANG_BEGINDECLS
+
+/*% Create a symbol table. */
+isc_result_t
+isc_symtab_create(isc_mem_t *mctx, unsigned int size,
+ isc_symtabaction_t undefine_action, void *undefine_arg,
+ isc_boolean_t case_sensitive, isc_symtab_t **symtabp);
+
+/*% Destroy a symbol table. */
+void
+isc_symtab_destroy(isc_symtab_t **symtabp);
+
+/*% Lookup a symbol table. */
+isc_result_t
+isc_symtab_lookup(isc_symtab_t *symtab, const char *key, unsigned int type,
+ isc_symvalue_t *value);
+
+/*% Define a symbol table. */
+isc_result_t
+isc_symtab_define(isc_symtab_t *symtab, const char *key, unsigned int type,
+ isc_symvalue_t value, isc_symexists_t exists_policy);
+
+/*% Undefine a symbol table. */
+isc_result_t
+isc_symtab_undefine(isc_symtab_t *symtab, const char *key, unsigned int type);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_SYMTAB_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/task.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/task.h
new file mode 100644
index 0000000..594d80f
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/task.h
@@ -0,0 +1,796 @@
+/*
+ * Copyright (C) 2004-2007, 2009-2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001, 2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+#ifndef ISC_TASK_H
+#define ISC_TASK_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file isc/task.h
+ * \brief The task system provides a lightweight execution context, which is
+ * basically an event queue.
+
+ * When a task's event queue is non-empty, the
+ * task is runnable. A small work crew of threads, typically one per CPU,
+ * execute runnable tasks by dispatching the events on the tasks' event
+ * queues. Context switching between tasks is fast.
+ *
+ * \li MP:
+ * The module ensures appropriate synchronization of data structures it
+ * creates and manipulates.
+ * The caller must ensure that isc_taskmgr_destroy() is called only
+ * once for a given manager.
+ *
+ * \li Reliability:
+ * No anticipated impact.
+ *
+ * \li Resources:
+ * TBS
+ *
+ * \li Security:
+ * No anticipated impact.
+ *
+ * \li Standards:
+ * None.
+ *
+ * \section purge Purging and Unsending
+ *
+ * Events which have been queued for a task but not delivered may be removed
+ * from the task's event queue by purging or unsending.
+ *
+ * With both types, the caller specifies a matching pattern that selects
+ * events based upon their sender, type, and tag.
+ *
+ * Purging calls isc_event_free() on the matching events.
+ *
+ * Unsending returns a list of events that matched the pattern.
+ * The caller is then responsible for them.
+ *
+ * Consumers of events should purge, not unsend.
+ *
+ * Producers of events often want to remove events when the caller indicates
+ * it is no longer interested in the object, e.g. by canceling a timer.
+ * Sometimes this can be done by purging, but for some event types, the
+ * calls to isc_event_free() cause deadlock because the event free routine
+ * wants to acquire a lock the caller is already holding. Unsending instead
+ * of purging solves this problem. As a general rule, producers should only
+ * unsend events which they have sent.
+ */
+
+
+/***
+ *** Imports.
+ ***/
+
+#include <isc/eventclass.h>
+#include <isc/lang.h>
+#include <isc/stdtime.h>
+#include <isc/types.h>
+#include <isc/xml.h>
+
+#define ISC_TASKEVENT_FIRSTEVENT (ISC_EVENTCLASS_TASK + 0)
+#define ISC_TASKEVENT_SHUTDOWN (ISC_EVENTCLASS_TASK + 1)
+#define ISC_TASKEVENT_TEST (ISC_EVENTCLASS_TASK + 1)
+#define ISC_TASKEVENT_LASTEVENT (ISC_EVENTCLASS_TASK + 65535)
+
+/*****
+ ***** Tasks.
+ *****/
+
+ISC_LANG_BEGINDECLS
+
+/***
+ *** Types
+ ***/
+
+typedef enum {
+ isc_taskmgrmode_normal = 0,
+ isc_taskmgrmode_privileged
+} isc_taskmgrmode_t;
+
+/*% Task and task manager methods */
+typedef struct isc_taskmgrmethods {
+ void (*destroy)(isc_taskmgr_t **managerp);
+ void (*setmode)(isc_taskmgr_t *manager,
+ isc_taskmgrmode_t mode);
+ isc_taskmgrmode_t (*mode)(isc_taskmgr_t *manager);
+ isc_result_t (*taskcreate)(isc_taskmgr_t *manager,
+ unsigned int quantum,
+ isc_task_t **taskp);
+} isc_taskmgrmethods_t;
+
+typedef struct isc_taskmethods {
+ void (*attach)(isc_task_t *source, isc_task_t **targetp);
+ void (*detach)(isc_task_t **taskp);
+ void (*destroy)(isc_task_t **taskp);
+ void (*send)(isc_task_t *task, isc_event_t **eventp);
+ void (*sendanddetach)(isc_task_t **taskp, isc_event_t **eventp);
+ unsigned int (*unsend)(isc_task_t *task, void *sender, isc_eventtype_t type,
+ void *tag, isc_eventlist_t *events);
+ isc_result_t (*onshutdown)(isc_task_t *task, isc_taskaction_t action,
+ const void *arg);
+ void (*shutdown)(isc_task_t *task);
+ void (*setname)(isc_task_t *task, const char *name, void *tag);
+ unsigned int (*purgeevents)(isc_task_t *task, void *sender,
+ isc_eventtype_t type, void *tag);
+ unsigned int (*purgerange)(isc_task_t *task, void *sender,
+ isc_eventtype_t first, isc_eventtype_t last,
+ void *tag);
+ isc_result_t (*beginexclusive)(isc_task_t *task);
+ void (*endexclusive)(isc_task_t *task);
+ void (*setprivilege)(isc_task_t *task, isc_boolean_t priv);
+ isc_boolean_t (*privilege)(isc_task_t *task);
+} isc_taskmethods_t;
+
+/*%
+ * This structure is actually just the common prefix of a task manager
+ * object implementation's version of an isc_taskmgr_t.
+ * \brief
+ * Direct use of this structure by clients is forbidden. task implementations
+ * may change the structure. 'magic' must be ISCAPI_TASKMGR_MAGIC for any
+ * of the isc_task_ routines to work. task implementations must maintain
+ * all task invariants.
+ */
+struct isc_taskmgr {
+ unsigned int impmagic;
+ unsigned int magic;
+ isc_taskmgrmethods_t *methods;
+};
+
+#define ISCAPI_TASKMGR_MAGIC ISC_MAGIC('A','t','m','g')
+#define ISCAPI_TASKMGR_VALID(m) ((m) != NULL && \
+ (m)->magic == ISCAPI_TASKMGR_MAGIC)
+
+/*%
+ * This is the common prefix of a task object. The same note as
+ * that for the taskmgr structure applies.
+ */
+struct isc_task {
+ unsigned int impmagic;
+ unsigned int magic;
+ isc_taskmethods_t *methods;
+};
+
+#define ISCAPI_TASK_MAGIC ISC_MAGIC('A','t','s','t')
+#define ISCAPI_TASK_VALID(s) ((s) != NULL && \
+ (s)->magic == ISCAPI_TASK_MAGIC)
+
+isc_result_t
+isc_task_create(isc_taskmgr_t *manager, unsigned int quantum,
+ isc_task_t **taskp);
+/*%<
+ * Create a task.
+ *
+ * Notes:
+ *
+ *\li If 'quantum' is non-zero, then only that many events can be dispatched
+ * before the task must yield to other tasks waiting to execute. If
+ * quantum is zero, then the default quantum of the task manager will
+ * be used.
+ *
+ *\li The 'quantum' option may be removed from isc_task_create() in the
+ * future. If this happens, isc_task_getquantum() and
+ * isc_task_setquantum() will be provided.
+ *
+ * Requires:
+ *
+ *\li 'manager' is a valid task manager.
+ *
+ *\li taskp != NULL && *taskp == NULL
+ *
+ * Ensures:
+ *
+ *\li On success, '*taskp' is bound to the new task.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOMEMORY
+ *\li #ISC_R_UNEXPECTED
+ *\li #ISC_R_SHUTTINGDOWN
+ */
+
+void
+isc_task_attach(isc_task_t *source, isc_task_t **targetp);
+/*%<
+ * Attach *targetp to source.
+ *
+ * Requires:
+ *
+ *\li 'source' is a valid task.
+ *
+ *\li 'targetp' points to a NULL isc_task_t *.
+ *
+ * Ensures:
+ *
+ *\li *targetp is attached to source.
+ */
+
+void
+isc_task_detach(isc_task_t **taskp);
+/*%<
+ * Detach *taskp from its task.
+ *
+ * Requires:
+ *
+ *\li '*taskp' is a valid task.
+ *
+ * Ensures:
+ *
+ *\li *taskp is NULL.
+ *
+ *\li If '*taskp' is the last reference to the task, the task is idle (has
+ * an empty event queue), and has not been shutdown, the task will be
+ * shutdown.
+ *
+ *\li If '*taskp' is the last reference to the task and
+ * the task has been shutdown,
+ * all resources used by the task will be freed.
+ */
+
+void
+isc_task_send(isc_task_t *task, isc_event_t **eventp);
+/*%<
+ * Send '*event' to 'task'.
+ *
+ * Requires:
+ *
+ *\li 'task' is a valid task.
+ *\li eventp != NULL && *eventp != NULL.
+ *
+ * Ensures:
+ *
+ *\li *eventp == NULL.
+ */
+
+void
+isc_task_sendanddetach(isc_task_t **taskp, isc_event_t **eventp);
+/*%<
+ * Send '*event' to '*taskp' and then detach '*taskp' from its
+ * task.
+ *
+ * Requires:
+ *
+ *\li '*taskp' is a valid task.
+ *\li eventp != NULL && *eventp != NULL.
+ *
+ * Ensures:
+ *
+ *\li *eventp == NULL.
+ *
+ *\li *taskp == NULL.
+ *
+ *\li If '*taskp' is the last reference to the task, the task is
+ * idle (has an empty event queue), and has not been shutdown,
+ * the task will be shutdown.
+ *
+ *\li If '*taskp' is the last reference to the task and
+ * the task has been shutdown,
+ * all resources used by the task will be freed.
+ */
+
+
+unsigned int
+isc_task_purgerange(isc_task_t *task, void *sender, isc_eventtype_t first,
+ isc_eventtype_t last, void *tag);
+/*%<
+ * Purge events from a task's event queue.
+ *
+ * Requires:
+ *
+ *\li 'task' is a valid task.
+ *
+ *\li last >= first
+ *
+ * Ensures:
+ *
+ *\li Events in the event queue of 'task' whose sender is 'sender', whose
+ * type is >= first and <= last, and whose tag is 'tag' will be purged,
+ * unless they are marked as unpurgable.
+ *
+ *\li A sender of NULL will match any sender. A NULL tag matches any
+ * tag.
+ *
+ * Returns:
+ *
+ *\li The number of events purged.
+ */
+
+unsigned int
+isc_task_purge(isc_task_t *task, void *sender, isc_eventtype_t type,
+ void *tag);
+/*%<
+ * Purge events from a task's event queue.
+ *
+ * Notes:
+ *
+ *\li This function is equivalent to
+ *
+ *\code
+ * isc_task_purgerange(task, sender, type, type, tag);
+ *\endcode
+ *
+ * Requires:
+ *
+ *\li 'task' is a valid task.
+ *
+ * Ensures:
+ *
+ *\li Events in the event queue of 'task' whose sender is 'sender', whose
+ * type is 'type', and whose tag is 'tag' will be purged, unless they
+ * are marked as unpurgable.
+ *
+ *\li A sender of NULL will match any sender. A NULL tag matches any
+ * tag.
+ *
+ * Returns:
+ *
+ *\li The number of events purged.
+ */
+
+isc_boolean_t
+isc_task_purgeevent(isc_task_t *task, isc_event_t *event);
+/*%<
+ * Purge 'event' from a task's event queue.
+ *
+ * XXXRTH: WARNING: This method may be removed before beta.
+ *
+ * Notes:
+ *
+ *\li If 'event' is on the task's event queue, it will be purged,
+ * unless it is marked as unpurgeable. 'event' does not have to be
+ * on the task's event queue; in fact, it can even be an invalid
+ * pointer. Purging only occurs if the event is actually on the task's
+ * event queue.
+ *
+ * \li Purging never changes the state of the task.
+ *
+ * Requires:
+ *
+ *\li 'task' is a valid task.
+ *
+ * Ensures:
+ *
+ *\li 'event' is not in the event queue for 'task'.
+ *
+ * Returns:
+ *
+ *\li #ISC_TRUE The event was purged.
+ *\li #ISC_FALSE The event was not in the event queue,
+ * or was marked unpurgeable.
+ */
+
+unsigned int
+isc_task_unsendrange(isc_task_t *task, void *sender, isc_eventtype_t first,
+ isc_eventtype_t last, void *tag, isc_eventlist_t *events);
+/*%<
+ * Remove events from a task's event queue.
+ *
+ * Requires:
+ *
+ *\li 'task' is a valid task.
+ *
+ *\li last >= first.
+ *
+ *\li *events is a valid list.
+ *
+ * Ensures:
+ *
+ *\li Events in the event queue of 'task' whose sender is 'sender', whose
+ * type is >= first and <= last, and whose tag is 'tag' will be dequeued
+ * and appended to *events.
+ *
+ *\li A sender of NULL will match any sender. A NULL tag matches any
+ * tag.
+ *
+ * Returns:
+ *
+ *\li The number of events unsent.
+ */
+
+unsigned int
+isc_task_unsend(isc_task_t *task, void *sender, isc_eventtype_t type,
+ void *tag, isc_eventlist_t *events);
+/*%<
+ * Remove events from a task's event queue.
+ *
+ * Notes:
+ *
+ *\li This function is equivalent to
+ *
+ *\code
+ * isc_task_unsendrange(task, sender, type, type, tag, events);
+ *\endcode
+ *
+ * Requires:
+ *
+ *\li 'task' is a valid task.
+ *
+ *\li *events is a valid list.
+ *
+ * Ensures:
+ *
+ *\li Events in the event queue of 'task' whose sender is 'sender', whose
+ * type is 'type', and whose tag is 'tag' will be dequeued and appended
+ * to *events.
+ *
+ * Returns:
+ *
+ *\li The number of events unsent.
+ */
+
+isc_result_t
+isc_task_onshutdown(isc_task_t *task, isc_taskaction_t action,
+ const void *arg);
+/*%<
+ * Send a shutdown event with action 'action' and argument 'arg' when
+ * 'task' is shutdown.
+ *
+ * Notes:
+ *
+ *\li Shutdown events are posted in LIFO order.
+ *
+ * Requires:
+ *
+ *\li 'task' is a valid task.
+ *
+ *\li 'action' is a valid task action.
+ *
+ * Ensures:
+ *
+ *\li When the task is shutdown, shutdown events requested with
+ * isc_task_onshutdown() will be appended to the task's event queue.
+ *
+
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOMEMORY
+ *\li #ISC_R_TASKSHUTTINGDOWN Task is shutting down.
+ */
+
+void
+isc_task_shutdown(isc_task_t *task);
+/*%<
+ * Shutdown 'task'.
+ *
+ * Notes:
+ *
+ *\li Shutting down a task causes any shutdown events requested with
+ * isc_task_onshutdown() to be posted (in LIFO order). The task
+ * moves into a "shutting down" mode which prevents further calls
+ * to isc_task_onshutdown().
+ *
+ *\li Trying to shutdown a task that has already been shutdown has no
+ * effect.
+ *
+ * Requires:
+ *
+ *\li 'task' is a valid task.
+ *
+ * Ensures:
+ *
+ *\li Any shutdown events requested with isc_task_onshutdown() have been
+ * posted (in LIFO order).
+ */
+
+void
+isc_task_destroy(isc_task_t **taskp);
+/*%<
+ * Destroy '*taskp'.
+ *
+ * Notes:
+ *
+ *\li This call is equivalent to:
+ *
+ *\code
+ * isc_task_shutdown(*taskp);
+ * isc_task_detach(taskp);
+ *\endcode
+ *
+ * Requires:
+ *
+ * '*taskp' is a valid task.
+ *
+ * Ensures:
+ *
+ *\li Any shutdown events requested with isc_task_onshutdown() have been
+ * posted (in LIFO order).
+ *
+ *\li *taskp == NULL
+ *
+ *\li If '*taskp' is the last reference to the task,
+ * all resources used by the task will be freed.
+ */
+
+void
+isc_task_setname(isc_task_t *task, const char *name, void *tag);
+/*%<
+ * Name 'task'.
+ *
+ * Notes:
+ *
+ *\li Only the first 15 characters of 'name' will be copied.
+ *
+ *\li Naming a task is currently only useful for debugging purposes.
+ *
+ * Requires:
+ *
+ *\li 'task' is a valid task.
+ */
+
+const char *
+isc_task_getname(isc_task_t *task);
+/*%<
+ * Get the name of 'task', as previously set using isc_task_setname().
+ *
+ * Notes:
+ *\li This function is for debugging purposes only.
+ *
+ * Requires:
+ *\li 'task' is a valid task.
+ *
+ * Returns:
+ *\li A non-NULL pointer to a null-terminated string.
+ * If the task has not been named, the string is
+ * empty.
+ *
+ */
+
+void *
+isc_task_gettag(isc_task_t *task);
+/*%<
+ * Get the tag value for 'task', as previously set using isc_task_settag().
+ *
+ * Notes:
+ *\li This function is for debugging purposes only.
+ *
+ * Requires:
+ *\li 'task' is a valid task.
+ */
+
+isc_result_t
+isc_task_beginexclusive(isc_task_t *task);
+/*%<
+ * Request exclusive access for 'task', which must be the calling
+ * task. Waits for any other concurrently executing tasks to finish their
+ * current event, and prevents any new events from executing in any of the
+ * tasks sharing a task manager with 'task'.
+ *
+ * The exclusive access must be relinquished by calling
+ * isc_task_endexclusive() before returning from the current event handler.
+ *
+ * Requires:
+ *\li 'task' is the calling task.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS The current task now has exclusive access.
+ *\li #ISC_R_LOCKBUSY Another task has already requested exclusive
+ * access.
+ */
+
+void
+isc_task_endexclusive(isc_task_t *task);
+/*%<
+ * Relinquish the exclusive access obtained by isc_task_beginexclusive(),
+ * allowing other tasks to execute.
+ *
+ * Requires:
+ *\li 'task' is the calling task, and has obtained
+ * exclusive access by calling isc_task_spl().
+ */
+
+void
+isc_task_getcurrenttime(isc_task_t *task, isc_stdtime_t *t);
+/*%<
+ * Provide the most recent timestamp on the task. The timestamp is considered
+ * as the "current time" in the second-order granularity.
+ *
+ * Requires:
+ *\li 'task' is a valid task.
+ *\li 't' is a valid non NULL pointer.
+ *
+ * Ensures:
+ *\li '*t' has the "current time".
+ */
+
+isc_boolean_t
+isc_task_exiting(isc_task_t *t);
+/*%<
+ * Returns ISC_TRUE if the task is in the process of shutting down,
+ * ISC_FALSE otherwise.
+ *
+ * Requires:
+ *\li 'task' is a valid task.
+ */
+
+void
+isc_task_setprivilege(isc_task_t *task, isc_boolean_t priv);
+/*%<
+ * Set or unset the task's "privileged" flag depending on the value of
+ * 'priv'.
+ *
+ * Under normal circumstances this flag has no effect on the task behavior,
+ * but when the task manager has been set to privileged exeuction mode via
+ * isc_taskmgr_setmode(), only tasks with the flag set will be executed,
+ * and all other tasks will wait until they're done. Once all privileged
+ * tasks have finished executing, the task manager will automatically
+ * return to normal execution mode and nonprivileged task can resume.
+ *
+ * Requires:
+ *\li 'task' is a valid task.
+ */
+
+isc_boolean_t
+isc_task_privilege(isc_task_t *task);
+/*%<
+ * Returns the current value of the task's privilege flag.
+ *
+ * Requires:
+ *\li 'task' is a valid task.
+ */
+
+/*****
+ ***** Task Manager.
+ *****/
+
+isc_result_t
+isc_taskmgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx,
+ unsigned int workers, unsigned int default_quantum,
+ isc_taskmgr_t **managerp);
+isc_result_t
+isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
+ unsigned int default_quantum, isc_taskmgr_t **managerp);
+/*%<
+ * Create a new task manager. isc_taskmgr_createinctx() also associates
+ * the new manager with the specified application context.
+ *
+ * Notes:
+ *
+ *\li 'workers' in the number of worker threads to create. In general,
+ * the value should be close to the number of processors in the system.
+ * The 'workers' value is advisory only. An attempt will be made to
+ * create 'workers' threads, but if at least one thread creation
+ * succeeds, isc_taskmgr_create() may return ISC_R_SUCCESS.
+ *
+ *\li If 'default_quantum' is non-zero, then it will be used as the default
+ * quantum value when tasks are created. If zero, then an implementation
+ * defined default quantum will be used.
+ *
+ * Requires:
+ *
+ *\li 'mctx' is a valid memory context.
+ *
+ *\li workers > 0
+ *
+ *\li managerp != NULL && *managerp == NULL
+ *
+ *\li 'actx' is a valid application context (for createinctx()).
+ *
+ * Ensures:
+ *
+ *\li On success, '*managerp' will be attached to the newly created task
+ * manager.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOMEMORY
+ *\li #ISC_R_NOTHREADS No threads could be created.
+ *\li #ISC_R_UNEXPECTED An unexpected error occurred.
+ *\li #ISC_R_SHUTTINGDOWN The non-threaded, shared, task
+ * manager shutting down.
+ */
+
+void
+isc_taskmgr_setmode(isc_taskmgr_t *manager, isc_taskmgrmode_t mode);
+
+isc_taskmgrmode_t
+isc_taskmgr_mode(isc_taskmgr_t *manager);
+/*%<
+ * Set/get the current operating mode of the task manager. Valid modes are:
+ *
+ *\li isc_taskmgrmode_normal
+ *\li isc_taskmgrmode_privileged
+ *
+ * In privileged execution mode, only tasks that have had the "privilege"
+ * flag set via isc_task_setprivilege() can be executed. When all such
+ * tasks are complete, the manager automatically returns to normal mode
+ * and proceeds with running non-privileged ready tasks. This means it is
+ * necessary to have at least one privileged task waiting on the ready
+ * queue *before* setting the manager into privileged execution mode,
+ * which in turn means the task which calls this function should be in
+ * task-exclusive mode when it does so.
+ *
+ * Requires:
+ *
+ *\li 'manager' is a valid task manager.
+ */
+
+void
+isc_taskmgr_destroy(isc_taskmgr_t **managerp);
+/*%<
+ * Destroy '*managerp'.
+ *
+ * Notes:
+ *
+ *\li Calling isc_taskmgr_destroy() will shutdown all tasks managed by
+ * *managerp that haven't already been shutdown. The call will block
+ * until all tasks have entered the done state.
+ *
+ *\li isc_taskmgr_destroy() must not be called by a task event action,
+ * because it would block forever waiting for the event action to
+ * complete. An event action that wants to cause task manager shutdown
+ * should request some non-event action thread of execution to do the
+ * shutdown, e.g. by signaling a condition variable or using
+ * isc_app_shutdown().
+ *
+ *\li Task manager references are not reference counted, so the caller
+ * must ensure that no attempt will be made to use the manager after
+ * isc_taskmgr_destroy() returns.
+ *
+ * Requires:
+ *
+ *\li '*managerp' is a valid task manager.
+ *
+ *\li isc_taskmgr_destroy() has not be called previously on '*managerp'.
+ *
+ * Ensures:
+ *
+ *\li All resources used by the task manager, and any tasks it managed,
+ * have been freed.
+ */
+
+#ifdef HAVE_LIBXML2
+
+void
+isc_taskmgr_renderxml(isc_taskmgr_t *mgr, xmlTextWriterPtr writer);
+
+#endif
+
+/*%<
+ * See isc_taskmgr_create() above.
+ */
+typedef isc_result_t
+(*isc_taskmgrcreatefunc_t)(isc_mem_t *mctx, unsigned int workers,
+ unsigned int default_quantum,
+ isc_taskmgr_t **managerp);
+
+isc_result_t
+isc_task_register(isc_taskmgrcreatefunc_t createfunc);
+/*%<
+ * Register a new task management implementation and add it to the list of
+ * supported implementations. This function must be called when a different
+ * event library is used than the one contained in the ISC library.
+ */
+
+isc_result_t
+isc__task_register(void);
+/*%<
+ * A short cut function that specifies the task management module in the ISC
+ * library for isc_task_register(). An application that uses the ISC library
+ * usually do not have to care about this function: it would call
+ * isc_lib_register(), which internally calls this function.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_TASK_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/taskpool.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/taskpool.h
new file mode 100644
index 0000000..46f395e
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/taskpool.h
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2004-2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+#ifndef ISC_TASKPOOL_H
+#define ISC_TASKPOOL_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file isc/taskpool.h
+ * \brief A task pool is a mechanism for sharing a small number of tasks
+ * among a large number of objects such that each object is
+ * assigned a unique task, but each task may be shared by several
+ * objects.
+ *
+ * Task pools are used to let objects that can exist in large
+ * numbers (e.g., zones) use tasks for synchronization without
+ * the memory overhead and unfair scheduling competition that
+ * could result from creating a separate task for each object.
+ */
+
+
+/***
+ *** Imports.
+ ***/
+
+#include <isc/lang.h>
+#include <isc/task.h>
+
+ISC_LANG_BEGINDECLS
+
+/*****
+ ***** Types.
+ *****/
+
+typedef struct isc_taskpool isc_taskpool_t;
+
+/*****
+ ***** Functions.
+ *****/
+
+isc_result_t
+isc_taskpool_create(isc_taskmgr_t *tmgr, isc_mem_t *mctx,
+ unsigned int ntasks, unsigned int quantum,
+ isc_taskpool_t **poolp);
+/*%<
+ * Create a task pool of "ntasks" tasks, each with quantum
+ * "quantum".
+ *
+ * Requires:
+ *
+ *\li 'tmgr' is a valid task manager.
+ *
+ *\li 'mctx' is a valid memory context.
+ *
+ *\li poolp != NULL && *poolp == NULL
+ *
+ * Ensures:
+ *
+ *\li On success, '*taskp' points to the new task pool.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOMEMORY
+ *\li #ISC_R_UNEXPECTED
+ */
+
+void
+isc_taskpool_gettask(isc_taskpool_t *pool, isc_task_t **targetp);
+/*%<
+ * Attach to a task from the pool. Currently the next task is chosen
+ * from the pool at random. (This may be changed in the future to
+ * something that guaratees balance.)
+ */
+
+int
+isc_taskpool_size(isc_taskpool_t *pool);
+/*%<
+ * Returns the number of tasks in the task pool 'pool'.
+ */
+
+isc_result_t
+isc_taskpool_expand(isc_taskpool_t **sourcep, unsigned int size,
+ isc_taskpool_t **targetp);
+
+/*%<
+ * If 'size' is larger than the number of tasks in the pool pointed to by
+ * 'sourcep', then a new taskpool of size 'size' is allocated, the existing
+ * tasks from are moved into it, additional tasks are created to bring the
+ * total number up to 'size', and the resulting pool is attached to
+ * 'targetp'.
+ *
+ * If 'size' is less than or equal to the tasks in pool 'source', then
+ * 'sourcep' is attached to 'targetp' without any other action being taken.
+ *
+ * In either case, 'sourcep' is detached.
+ *
+ * Requires:
+ *
+ * \li 'sourcep' is not NULL and '*source' is not NULL
+ * \li 'targetp' is not NULL and '*source' is NULL
+ *
+ * Ensures:
+ *
+ * \li On success, '*targetp' points to a valid task pool.
+ * \li On success, '*sourcep' points to NULL.
+ *
+ * Returns:
+ *
+ * \li #ISC_R_SUCCESS
+ * \li #ISC_R_NOMEMORY
+ */
+
+void
+isc_taskpool_destroy(isc_taskpool_t **poolp);
+/*%<
+ * Destroy a task pool. The tasks in the pool are detached but not
+ * shut down.
+ *
+ * Requires:
+ * \li '*poolp' is a valid task pool.
+ */
+
+void
+isc_taskpool_setprivilege(isc_taskpool_t *pool, isc_boolean_t priv);
+/*%<
+ * Set the privilege flag on all tasks in 'pool' to 'priv'. If 'priv' is
+ * true, then when the task manager is set into privileged mode, only
+ * tasks wihin this pool will be able to execute. (Note: It is important
+ * to turn the pool tasks' privilege back off before the last task finishes
+ * executing.)
+ *
+ * Requires:
+ * \li 'pool' is a valid task pool.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_TASKPOOL_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/timer.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/timer.h
new file mode 100644
index 0000000..fa9abb1
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/timer.h
@@ -0,0 +1,431 @@
+/*
+ * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: timer.h,v 1.43 2009/09/02 23:48:03 tbox Exp $ */
+
+#ifndef ISC_TIMER_H
+#define ISC_TIMER_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file isc/timer.h
+ * \brief Provides timers which are event sources in the task system.
+ *
+ * Three types of timers are supported:
+ *
+ *\li 'ticker' timers generate a periodic tick event.
+ *
+ *\li 'once' timers generate an idle timeout event if they are idle for too
+ * long, and generate a life timeout event if their lifetime expires.
+ * They are used to implement both (possibly expiring) idle timers and
+ * 'one-shot' timers.
+ *
+ *\li 'limited' timers generate a periodic tick event until they reach
+ * their lifetime when they generate a life timeout event.
+ *
+ *\li 'inactive' timers generate no events.
+ *
+ * Timers can change type. It is typical to create a timer as
+ * an 'inactive' timer and then change it into a 'ticker' or
+ * 'once' timer.
+ *
+ *\li MP:
+ * The module ensures appropriate synchronization of data structures it
+ * creates and manipulates.
+ * Clients of this module must not be holding a timer's task's lock when
+ * making a call that affects that timer. Failure to follow this rule
+ * can result in deadlock.
+ * The caller must ensure that isc_timermgr_destroy() is called only
+ * once for a given manager.
+ *
+ * \li Reliability:
+ * No anticipated impact.
+ *
+ * \li Resources:
+ * TBS
+ *
+ * \li Security:
+ * No anticipated impact.
+ *
+ * \li Standards:
+ * None.
+ */
+
+
+/***
+ *** Imports
+ ***/
+
+#include <isc/types.h>
+#include <isc/event.h>
+#include <isc/eventclass.h>
+#include <isc/lang.h>
+#include <isc/time.h>
+
+ISC_LANG_BEGINDECLS
+
+/***
+ *** Types
+ ***/
+
+/*% Timer Type */
+typedef enum {
+ isc_timertype_ticker = 0, /*%< Ticker */
+ isc_timertype_once = 1, /*%< Once */
+ isc_timertype_limited = 2, /*%< Limited */
+ isc_timertype_inactive = 3 /*%< Inactive */
+} isc_timertype_t;
+
+typedef struct isc_timerevent {
+ struct isc_event common;
+ isc_time_t due;
+} isc_timerevent_t;
+
+#define ISC_TIMEREVENT_FIRSTEVENT (ISC_EVENTCLASS_TIMER + 0)
+#define ISC_TIMEREVENT_TICK (ISC_EVENTCLASS_TIMER + 1)
+#define ISC_TIMEREVENT_IDLE (ISC_EVENTCLASS_TIMER + 2)
+#define ISC_TIMEREVENT_LIFE (ISC_EVENTCLASS_TIMER + 3)
+#define ISC_TIMEREVENT_LASTEVENT (ISC_EVENTCLASS_TIMER + 65535)
+
+/*% Timer and timer manager methods */
+typedef struct {
+ void (*destroy)(isc_timermgr_t **managerp);
+ isc_result_t (*timercreate)(isc_timermgr_t *manager,
+ isc_timertype_t type,
+ isc_time_t *expires,
+ isc_interval_t *interval,
+ isc_task_t *task,
+ isc_taskaction_t action,
+ const void *arg,
+ isc_timer_t **timerp);
+} isc_timermgrmethods_t;
+
+typedef struct {
+ void (*attach)(isc_timer_t *timer, isc_timer_t **timerp);
+ void (*detach)(isc_timer_t **timerp);
+ isc_result_t (*reset)(isc_timer_t *timer, isc_timertype_t type,
+ isc_time_t *expires, isc_interval_t *interval,
+ isc_boolean_t purge);
+ isc_result_t (*touch)(isc_timer_t *timer);
+} isc_timermethods_t;
+
+/*%
+ * This structure is actually just the common prefix of a timer manager
+ * object implementation's version of an isc_timermgr_t.
+ * \brief
+ * Direct use of this structure by clients is forbidden. timer implementations
+ * may change the structure. 'magic' must be ISCAPI_TIMERMGR_MAGIC for any
+ * of the isc_timer_ routines to work. timer implementations must maintain
+ * all timer invariants.
+ */
+struct isc_timermgr {
+ unsigned int impmagic;
+ unsigned int magic;
+ isc_timermgrmethods_t *methods;
+};
+
+#define ISCAPI_TIMERMGR_MAGIC ISC_MAGIC('A','t','m','g')
+#define ISCAPI_TIMERMGR_VALID(m) ((m) != NULL && \
+ (m)->magic == ISCAPI_TIMERMGR_MAGIC)
+
+/*%
+ * This is the common prefix of a timer object. The same note as
+ * that for the timermgr structure applies.
+ */
+struct isc_timer {
+ unsigned int impmagic;
+ unsigned int magic;
+ isc_timermethods_t *methods;
+};
+
+#define ISCAPI_TIMER_MAGIC ISC_MAGIC('A','t','m','r')
+#define ISCAPI_TIMER_VALID(s) ((s) != NULL && \
+ (s)->magic == ISCAPI_TIMER_MAGIC)
+
+/***
+ *** Timer and Timer Manager Functions
+ ***
+ *** Note: all Ensures conditions apply only if the result is success for
+ *** those functions which return an isc_result_t.
+ ***/
+
+isc_result_t
+isc_timer_create(isc_timermgr_t *manager,
+ isc_timertype_t type,
+ isc_time_t *expires,
+ isc_interval_t *interval,
+ isc_task_t *task,
+ isc_taskaction_t action,
+ const void *arg,
+ isc_timer_t **timerp);
+/*%<
+ * Create a new 'type' timer managed by 'manager'. The timers parameters
+ * are specified by 'expires' and 'interval'. Events will be posted to
+ * 'task' and when dispatched 'action' will be called with 'arg' as the
+ * arg value. The new timer is returned in 'timerp'.
+ *
+ * Notes:
+ *
+ *\li For ticker timers, the timer will generate a 'tick' event every
+ * 'interval' seconds. The value of 'expires' is ignored.
+ *
+ *\li For once timers, 'expires' specifies the time when a life timeout
+ * event should be generated. If 'expires' is 0 (the epoch), then no life
+ * timeout will be generated. 'interval' specifies how long the timer
+ * can be idle before it generates an idle timeout. If 0, then no
+ * idle timeout will be generated.
+ *
+ *\li If 'expires' is NULL, the epoch will be used.
+ *
+ * If 'interval' is NULL, the zero interval will be used.
+ *
+ * Requires:
+ *
+ *\li 'manager' is a valid manager
+ *
+ *\li 'task' is a valid task
+ *
+ *\li 'action' is a valid action
+ *
+ *\li 'expires' points to a valid time, or is NULL.
+ *
+ *\li 'interval' points to a valid interval, or is NULL.
+ *
+ *\li type == isc_timertype_inactive ||
+ * ('expires' and 'interval' are not both 0)
+ *
+ *\li 'timerp' is a valid pointer, and *timerp == NULL
+ *
+ * Ensures:
+ *
+ *\li '*timerp' is attached to the newly created timer
+ *
+ *\li The timer is attached to the task
+ *
+ *\li An idle timeout will not be generated until at least Now + the
+ * timer's interval if 'timer' is a once timer with a non-zero
+ * interval.
+ *
+ * Returns:
+ *
+ *\li Success
+ *\li No memory
+ *\li Unexpected error
+ */
+
+isc_result_t
+isc_timer_reset(isc_timer_t *timer,
+ isc_timertype_t type,
+ isc_time_t *expires,
+ isc_interval_t *interval,
+ isc_boolean_t purge);
+/*%<
+ * Change the timer's type, expires, and interval values to the given
+ * values. If 'purge' is TRUE, any pending events from this timer
+ * are purged from its task's event queue.
+ *
+ * Notes:
+ *
+ *\li If 'expires' is NULL, the epoch will be used.
+ *
+ *\li If 'interval' is NULL, the zero interval will be used.
+ *
+ * Requires:
+ *
+ *\li 'timer' is a valid timer
+ *
+ *\li The same requirements that isc_timer_create() imposes on 'type',
+ * 'expires' and 'interval' apply.
+ *
+ * Ensures:
+ *
+ *\li An idle timeout will not be generated until at least Now + the
+ * timer's interval if 'timer' is a once timer with a non-zero
+ * interval.
+ *
+ * Returns:
+ *
+ *\li Success
+ *\li No memory
+ *\li Unexpected error
+ */
+
+isc_result_t
+isc_timer_touch(isc_timer_t *timer);
+/*%<
+ * Set the last-touched time of 'timer' to the current time.
+ *
+ * Requires:
+ *
+ *\li 'timer' is a valid once timer.
+ *
+ * Ensures:
+ *
+ *\li An idle timeout will not be generated until at least Now + the
+ * timer's interval if 'timer' is a once timer with a non-zero
+ * interval.
+ *
+ * Returns:
+ *
+ *\li Success
+ *\li Unexpected error
+ */
+
+void
+isc_timer_attach(isc_timer_t *timer, isc_timer_t **timerp);
+/*%<
+ * Attach *timerp to timer.
+ *
+ * Requires:
+ *
+ *\li 'timer' is a valid timer.
+ *
+ *\li 'timerp' points to a NULL timer.
+ *
+ * Ensures:
+ *
+ *\li *timerp is attached to timer.
+ */
+
+void
+isc_timer_detach(isc_timer_t **timerp);
+/*%<
+ * Detach *timerp from its timer.
+ *
+ * Requires:
+ *
+ *\li 'timerp' points to a valid timer.
+ *
+ * Ensures:
+ *
+ *\li *timerp is NULL.
+ *
+ *\li If '*timerp' is the last reference to the timer,
+ * then:
+ *
+ *\code
+ * The timer will be shutdown
+ *
+ * The timer will detach from its task
+ *
+ * All resources used by the timer have been freed
+ *
+ * Any events already posted by the timer will be purged.
+ * Therefore, if isc_timer_detach() is called in the context
+ * of the timer's task, it is guaranteed that no more
+ * timer event callbacks will run after the call.
+ *\endcode
+ */
+
+isc_timertype_t
+isc_timer_gettype(isc_timer_t *timer);
+/*%<
+ * Return the timer type.
+ *
+ * Requires:
+ *
+ *\li 'timer' to be a valid timer.
+ */
+
+isc_result_t
+isc_timermgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx,
+ isc_timermgr_t **managerp);
+
+isc_result_t
+isc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp);
+/*%<
+ * Create a timer manager. isc_timermgr_createinctx() also associates
+ * the new manager with the specified application context.
+ *
+ * Notes:
+ *
+ *\li All memory will be allocated in memory context 'mctx'.
+ *
+ * Requires:
+ *
+ *\li 'mctx' is a valid memory context.
+ *
+ *\li 'managerp' points to a NULL isc_timermgr_t.
+ *
+ *\li 'actx' is a valid application context (for createinctx()).
+ *
+ * Ensures:
+ *
+ *\li '*managerp' is a valid isc_timermgr_t.
+ *
+ * Returns:
+ *
+ *\li Success
+ *\li No memory
+ *\li Unexpected error
+ */
+
+void
+isc_timermgr_destroy(isc_timermgr_t **managerp);
+/*%<
+ * Destroy a timer manager.
+ *
+ * Notes:
+ *
+ *\li This routine blocks until there are no timers left in the manager,
+ * so if the caller holds any timer references using the manager, it
+ * must detach them before calling isc_timermgr_destroy() or it will
+ * block forever.
+ *
+ * Requires:
+ *
+ *\li '*managerp' is a valid isc_timermgr_t.
+ *
+ * Ensures:
+ *
+ *\li *managerp == NULL
+ *
+ *\li All resources used by the manager have been freed.
+ */
+
+void isc_timermgr_poke(isc_timermgr_t *m);
+
+#ifdef USE_TIMERIMPREGISTER
+/*%<
+ * See isc_timermgr_create() above.
+ */
+typedef isc_result_t
+(*isc_timermgrcreatefunc_t)(isc_mem_t *mctx, isc_timermgr_t **managerp);
+
+isc_result_t
+isc__timer_register(void);
+/*%<
+ * Register a new timer management implementation and add it to the list of
+ * supported implementations. This function must be called when a different
+ * event library is used than the one contained in the ISC library.
+ */
+
+isc_result_t
+isc_timer_register(isc_timermgrcreatefunc_t createfunc);
+/*%<
+ * A short cut function that specifies the timer management module in the ISC
+ * library for isc_timer_register(). An application that uses the ISC library
+ * usually do not have to care about this function: it would call
+ * isc_lib_register(), which internally calls this function.
+ */
+#endif /* USE_TIMERIMPREGISTER */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_TIMER_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/types.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/types.h
new file mode 100644
index 0000000..8dbf67e
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/types.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2004-2009, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+#ifndef ISC_TYPES_H
+#define ISC_TYPES_H 1
+
+#include <isc/bind9.h>
+#include <isc/namespace.h>
+
+/*! \file isc/types.h
+ * \brief
+ * OS-specific types, from the OS-specific include directories.
+ */
+#include <isc/int.h>
+#include <isc/offset.h>
+
+/*
+ * XXXDCL should isc_boolean_t be moved here, requiring an explicit include
+ * of <isc/boolean.h> when ISC_TRUE/ISC_FALSE/ISC_TF() are desired?
+ */
+#include <isc/boolean.h>
+/*
+ * XXXDCL This is just for ISC_LIST and ISC_LINK, but gets all of the other
+ * list macros too.
+ */
+#include <isc/list.h>
+
+/* Core Types. Alphabetized by defined type. */
+
+typedef struct isc_appctx isc_appctx_t; /*%< Application context */
+typedef struct isc_backtrace_symmap isc_backtrace_symmap_t; /*%< Symbol Table Entry */
+typedef struct isc_bitstring isc_bitstring_t; /*%< Bitstring */
+typedef struct isc_buffer isc_buffer_t; /*%< Buffer */
+typedef ISC_LIST(isc_buffer_t) isc_bufferlist_t; /*%< Buffer List */
+typedef struct isc_constregion isc_constregion_t; /*%< Const region */
+typedef struct isc_consttextregion isc_consttextregion_t; /*%< Const Text Region */
+typedef struct isc_entropy isc_entropy_t; /*%< Entropy */
+typedef struct isc_entropysource isc_entropysource_t; /*%< Entropy Source */
+typedef struct isc_event isc_event_t; /*%< Event */
+typedef ISC_LIST(isc_event_t) isc_eventlist_t; /*%< Event List */
+typedef unsigned int isc_eventtype_t; /*%< Event Type */
+typedef isc_uint32_t isc_fsaccess_t; /*%< FS Access */
+typedef struct isc_hash isc_hash_t; /*%< Hash */
+typedef struct isc_httpd isc_httpd_t; /*%< HTTP client */
+typedef void (isc_httpdfree_t)(isc_buffer_t *, void *); /*%< HTTP free function */
+typedef struct isc_httpdmgr isc_httpdmgr_t; /*%< HTTP manager */
+typedef struct isc_httpdurl isc_httpdurl_t; /*%< HTTP URL */
+typedef void (isc_httpdondestroy_t)(void *); /*%< Callback on destroying httpd */
+typedef struct isc_interface isc_interface_t; /*%< Interface */
+typedef struct isc_interfaceiter isc_interfaceiter_t; /*%< Interface Iterator */
+typedef struct isc_interval isc_interval_t; /*%< Interval */
+typedef struct isc_lex isc_lex_t; /*%< Lex */
+typedef struct isc_log isc_log_t; /*%< Log */
+typedef struct isc_logcategory isc_logcategory_t; /*%< Log Category */
+typedef struct isc_logconfig isc_logconfig_t; /*%< Log Configuration */
+typedef struct isc_logmodule isc_logmodule_t; /*%< Log Module */
+typedef struct isc_mem isc_mem_t; /*%< Memory */
+typedef struct isc_mempool isc_mempool_t; /*%< Memory Pool */
+typedef struct isc_msgcat isc_msgcat_t; /*%< Message Catalog */
+typedef struct isc_ondestroy isc_ondestroy_t; /*%< On Destroy */
+typedef struct isc_netaddr isc_netaddr_t; /*%< Net Address */
+typedef struct isc_portset isc_portset_t; /*%< Port Set */
+typedef struct isc_quota isc_quota_t; /*%< Quota */
+typedef struct isc_random isc_random_t; /*%< Random */
+typedef struct isc_ratelimiter isc_ratelimiter_t; /*%< Rate Limiter */
+typedef struct isc_region isc_region_t; /*%< Region */
+typedef isc_uint64_t isc_resourcevalue_t; /*%< Resource Value */
+typedef unsigned int isc_result_t; /*%< Result */
+typedef struct isc_rwlock isc_rwlock_t; /*%< Read Write Lock */
+typedef struct isc_sockaddr isc_sockaddr_t; /*%< Socket Address */
+typedef struct isc_socket isc_socket_t; /*%< Socket */
+typedef struct isc_socketevent isc_socketevent_t; /*%< Socket Event */
+typedef struct isc_socketmgr isc_socketmgr_t; /*%< Socket Manager */
+typedef struct isc_stats isc_stats_t; /*%< Statistics */
+typedef int isc_statscounter_t; /*%< Statistics Counter */
+typedef struct isc_symtab isc_symtab_t; /*%< Symbol Table */
+typedef struct isc_task isc_task_t; /*%< Task */
+typedef ISC_LIST(isc_task_t) isc_tasklist_t; /*%< Task List */
+typedef struct isc_taskmgr isc_taskmgr_t; /*%< Task Manager */
+typedef struct isc_textregion isc_textregion_t; /*%< Text Region */
+typedef struct isc_time isc_time_t; /*%< Time */
+typedef struct isc_timer isc_timer_t; /*%< Timer */
+typedef struct isc_timermgr isc_timermgr_t; /*%< Timer Manager */
+
+typedef void (*isc_taskaction_t)(isc_task_t *, isc_event_t *);
+typedef int (*isc_sockfdwatch_t)(isc_task_t *, isc_socket_t *, void *, int);
+
+/* The following cannot be listed alphabetically due to forward reference */
+typedef isc_result_t (isc_httpdaction_t)(const char *url,
+ const char *querystring,
+ void *arg,
+ unsigned int *retcode,
+ const char **retmsg,
+ const char **mimetype,
+ isc_buffer_t *body,
+ isc_httpdfree_t **freecb,
+ void **freecb_args);
+typedef isc_boolean_t (isc_httpdclientok_t)(const isc_sockaddr_t *, void *);
+
+/*% Resource */
+typedef enum {
+ isc_resource_coresize = 1,
+ isc_resource_cputime,
+ isc_resource_datasize,
+ isc_resource_filesize,
+ isc_resource_lockedmemory,
+ isc_resource_openfiles,
+ isc_resource_processes,
+ isc_resource_residentsize,
+ isc_resource_stacksize
+} isc_resource_t;
+
+#endif /* ISC_TYPES_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/util.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/util.h
new file mode 100644
index 0000000..670b28b
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/util.h
@@ -0,0 +1,238 @@
+/*
+ * Copyright (C) 2004-2007, 2010-2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+#ifndef ISC_UTIL_H
+#define ISC_UTIL_H 1
+
+/*! \file isc/util.h
+ * NOTE:
+ *
+ * This file is not to be included from any <isc/???.h> (or other) library
+ * files.
+ *
+ * \brief
+ * Including this file puts several macros in your name space that are
+ * not protected (as all the other ISC functions/macros do) by prepending
+ * ISC_ or isc_ to the name.
+ */
+
+/***
+ *** General Macros.
+ ***/
+
+/*%
+ * Use this to hide unused function arguments.
+ * \code
+ * int
+ * foo(char *bar)
+ * {
+ * UNUSED(bar);
+ * }
+ * \endcode
+ */
+#define UNUSED(x) (void)(x)
+
+/*%
+ * The opposite: silent warnings about stored values which are never read.
+ */
+#define POST(x) (void)(x)
+
+#define ISC_MAX(a, b) ((a) > (b) ? (a) : (b))
+#define ISC_MIN(a, b) ((a) < (b) ? (a) : (b))
+
+/*%
+ * Use this to remove the const qualifier of a variable to assign it to
+ * a non-const variable or pass it as a non-const function argument ...
+ * but only when you are sure it won't then be changed!
+ * This is necessary to sometimes shut up some compilers
+ * (as with gcc -Wcast-qual) when there is just no other good way to avoid the
+ * situation.
+ */
+#define DE_CONST(konst, var) \
+ do { \
+ union { const void *k; void *v; } _u; \
+ _u.k = konst; \
+ var = _u.v; \
+ } while (0)
+
+/*%
+ * Use this in translation units that would otherwise be empty, to
+ * suppress compiler warnings.
+ */
+#define EMPTY_TRANSLATION_UNIT extern void exit(int);
+
+/*%
+ * We use macros instead of calling the routines directly because
+ * the capital letters make the locking stand out.
+ * We RUNTIME_CHECK for success since in general there's no way
+ * for us to continue if they fail.
+ */
+
+#ifdef ISC_UTIL_TRACEON
+#define ISC_UTIL_TRACE(a) a
+#include <stdio.h> /* Required for fprintf/stderr when tracing. */
+#include <isc/msgs.h> /* Required for isc_msgcat when tracing. */
+#else
+#define ISC_UTIL_TRACE(a)
+#endif
+
+#include <isc/result.h> /* Contractual promise. */
+
+#define LOCK(lp) do { \
+ ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %d\n", \
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \
+ ISC_MSG_LOCKING, "LOCKING"), \
+ (lp), __FILE__, __LINE__)); \
+ RUNTIME_CHECK(isc_mutex_lock((lp)) == ISC_R_SUCCESS); \
+ ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %d\n", \
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \
+ ISC_MSG_LOCKED, "LOCKED"), \
+ (lp), __FILE__, __LINE__)); \
+ } while (0)
+#define UNLOCK(lp) do { \
+ RUNTIME_CHECK(isc_mutex_unlock((lp)) == ISC_R_SUCCESS); \
+ ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %d\n", \
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \
+ ISC_MSG_UNLOCKED, "UNLOCKED"), \
+ (lp), __FILE__, __LINE__)); \
+ } while (0)
+#define ISLOCKED(lp) (1)
+#define DESTROYLOCK(lp) \
+ RUNTIME_CHECK(isc_mutex_destroy((lp)) == ISC_R_SUCCESS)
+
+
+#define BROADCAST(cvp) do { \
+ ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %d\n", \
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \
+ ISC_MSG_BROADCAST, "BROADCAST"),\
+ (cvp), __FILE__, __LINE__)); \
+ RUNTIME_CHECK(isc_condition_broadcast((cvp)) == ISC_R_SUCCESS); \
+ } while (0)
+#define SIGNAL(cvp) do { \
+ ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %d\n", \
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \
+ ISC_MSG_SIGNAL, "SIGNAL"), \
+ (cvp), __FILE__, __LINE__)); \
+ RUNTIME_CHECK(isc_condition_signal((cvp)) == ISC_R_SUCCESS); \
+ } while (0)
+#define WAIT(cvp, lp) do { \
+ ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %p %s %d\n", \
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \
+ ISC_MSG_UTILWAIT, "WAIT"), \
+ (cvp), \
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \
+ ISC_MSG_LOCK, "LOCK"), \
+ (lp), __FILE__, __LINE__)); \
+ RUNTIME_CHECK(isc_condition_wait((cvp), (lp)) == ISC_R_SUCCESS); \
+ ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %p %s %d\n", \
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \
+ ISC_MSG_WAITED, "WAITED"), \
+ (cvp), \
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \
+ ISC_MSG_LOCKED, "LOCKED"), \
+ (lp), __FILE__, __LINE__)); \
+ } while (0)
+
+/*
+ * isc_condition_waituntil can return ISC_R_TIMEDOUT, so we
+ * don't RUNTIME_CHECK the result.
+ *
+ * XXX Also, can't really debug this then...
+ */
+
+#define WAITUNTIL(cvp, lp, tp) \
+ isc_condition_waituntil((cvp), (lp), (tp))
+
+#define RWLOCK(lp, t) do { \
+ ISC_UTIL_TRACE(fprintf(stderr, "%s %p, %d %s %d\n", \
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \
+ ISC_MSG_RWLOCK, "RWLOCK"), \
+ (lp), (t), __FILE__, __LINE__)); \
+ RUNTIME_CHECK(isc_rwlock_lock((lp), (t)) == ISC_R_SUCCESS); \
+ ISC_UTIL_TRACE(fprintf(stderr, "%s %p, %d %s %d\n", \
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \
+ ISC_MSG_RWLOCKED, "RWLOCKED"), \
+ (lp), (t), __FILE__, __LINE__)); \
+ } while (0)
+#define RWUNLOCK(lp, t) do { \
+ ISC_UTIL_TRACE(fprintf(stderr, "%s %p, %d %s %d\n", \
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \
+ ISC_MSG_RWUNLOCK, "RWUNLOCK"), \
+ (lp), (t), __FILE__, __LINE__)); \
+ RUNTIME_CHECK(isc_rwlock_unlock((lp), (t)) == ISC_R_SUCCESS); \
+ } while (0)
+
+#define DESTROYMUTEXBLOCK(bp, n) \
+ RUNTIME_CHECK(isc_mutexblock_destroy((bp), (n)) == ISC_R_SUCCESS)
+
+/*
+ * List Macros.
+ */
+#include <isc/list.h> /* Contractual promise. */
+
+#define LIST(type) ISC_LIST(type)
+#define INIT_LIST(type) ISC_LIST_INIT(type)
+#define LINK(type) ISC_LINK(type)
+#define INIT_LINK(elt, link) ISC_LINK_INIT(elt, link)
+#define HEAD(list) ISC_LIST_HEAD(list)
+#define TAIL(list) ISC_LIST_TAIL(list)
+#define EMPTY(list) ISC_LIST_EMPTY(list)
+#define PREV(elt, link) ISC_LIST_PREV(elt, link)
+#define NEXT(elt, link) ISC_LIST_NEXT(elt, link)
+#define APPEND(list, elt, link) ISC_LIST_APPEND(list, elt, link)
+#define PREPEND(list, elt, link) ISC_LIST_PREPEND(list, elt, link)
+#define UNLINK(list, elt, link) ISC_LIST_UNLINK(list, elt, link)
+#define ENQUEUE(list, elt, link) ISC_LIST_APPEND(list, elt, link)
+#define DEQUEUE(list, elt, link) ISC_LIST_UNLINK(list, elt, link)
+#define INSERTBEFORE(li, b, e, ln) ISC_LIST_INSERTBEFORE(li, b, e, ln)
+#define INSERTAFTER(li, a, e, ln) ISC_LIST_INSERTAFTER(li, a, e, ln)
+#define APPENDLIST(list1, list2, link) ISC_LIST_APPENDLIST(list1, list2, link)
+
+/*
+ * Assertions
+ */
+#include <isc/assertions.h> /* Contractual promise. */
+
+/*% Require Assertion */
+#define REQUIRE(e) ISC_REQUIRE(e)
+/*% Ensure Assertion */
+#define ENSURE(e) ISC_ENSURE(e)
+/*% Insist Assertion */
+#define INSIST(e) ISC_INSIST(e)
+/*% Invariant Assertion */
+#define INVARIANT(e) ISC_INVARIANT(e)
+
+/*
+ * Errors
+ */
+#include <isc/error.h> /* Contractual promise. */
+
+/*% Unexpected Error */
+#define UNEXPECTED_ERROR isc_error_unexpected
+/*% Fatal Error */
+#define FATAL_ERROR isc_error_fatal
+/*% Runtime Check */
+#define RUNTIME_CHECK(cond) ISC_ERROR_RUNTIMECHECK(cond)
+
+/*%
+ * Time
+ */
+#define TIME_NOW(tp) RUNTIME_CHECK(isc_time_now((tp)) == ISC_R_SUCCESS)
+
+#endif /* ISC_UTIL_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/version.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/version.h
new file mode 100644
index 0000000..ec00bde
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/version.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: version.h,v 1.9 2007/06/19 23:47:18 tbox Exp $ */
+
+/*! \file isc/version.h */
+
+#include <isc/platform.h>
+
+LIBISC_EXTERNAL_DATA extern const char isc_version[];
+
+LIBISC_EXTERNAL_DATA extern const unsigned int isc_libinterface;
+LIBISC_EXTERNAL_DATA extern const unsigned int isc_librevision;
+LIBISC_EXTERNAL_DATA extern const unsigned int isc_libage;
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/xml.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/xml.h
new file mode 100644
index 0000000..d31a31a
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/include/isc/xml.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2006, 2007 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: xml.h,v 1.4 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_XML_H
+#define ISC_XML_H 1
+
+/*
+ * This file is here mostly to make it easy to add additional libxml header
+ * files as needed across all the users of this file. Rather than place
+ * these libxml includes in each file, one include makes it easy to handle
+ * the ifdef as well as adding the ability to add additional functions
+ * which may be useful.
+ */
+
+#ifdef HAVE_LIBXML2
+#include <libxml/encoding.h>
+#include <libxml/xmlwriter.h>
+#endif
+
+#define ISC_XMLCHAR (const xmlChar *)
+
+#define ISC_XML_RENDERCONFIG 0x00000001 /* render config data */
+#define ISC_XML_RENDERSTATS 0x00000002 /* render stats */
+#define ISC_XML_RENDERALL 0x000000ff /* render everything */
+
+#endif /* ISC_XML_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/iterated_hash.c b/sebhbsd/freebsd/contrib/ntp/lib/isc/iterated_hash.c
new file mode 100644
index 0000000..af43dd2
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/iterated_hash.c
@@ -0,0 +1,50 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (C) 2006, 2008, 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: iterated_hash.c,v 1.6 2009/02/18 23:47:48 tbox Exp $ */
+
+#include "config.h"
+
+#include <stdio.h>
+
+#include <isc/sha1.h>
+#include <isc/iterated_hash.h>
+
+int
+isc_iterated_hash(unsigned char out[ISC_SHA1_DIGESTLENGTH],
+ unsigned int hashalg, int iterations,
+ const unsigned char *salt, int saltlength,
+ const unsigned char *in, int inlength)
+{
+ isc_sha1_t ctx;
+ int n = 0;
+
+ if (hashalg != 1)
+ return (0);
+
+ do {
+ isc_sha1_init(&ctx);
+ isc_sha1_update(&ctx, in, inlength);
+ isc_sha1_update(&ctx, salt, saltlength);
+ isc_sha1_final(&ctx, out);
+ in = out;
+ inlength = ISC_SHA1_DIGESTLENGTH;
+ } while (n++ < iterations);
+
+ return (ISC_SHA1_DIGESTLENGTH);
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/lib.c b/sebhbsd/freebsd/contrib/ntp/lib/isc/lib.c
new file mode 100644
index 0000000..3e8f956
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/lib.c
@@ -0,0 +1,105 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: lib.c,v 1.16 2009/09/02 23:48:02 tbox Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <isc/app.h>
+#include <isc/lib.h>
+#include <isc/mem.h>
+#include <isc/msgs.h>
+#include <isc/once.h>
+#include <isc/socket.h>
+#include <isc/task.h>
+#include <isc/timer.h>
+#include <isc/util.h>
+
+/***
+ *** Globals
+ ***/
+
+LIBISC_EXTERNAL_DATA isc_msgcat_t * isc_msgcat = NULL;
+
+
+/***
+ *** Private
+ ***/
+
+static isc_once_t msgcat_once = ISC_ONCE_INIT;
+
+/***
+ *** Functions
+ ***/
+
+static void
+open_msgcat(void) {
+ isc_msgcat_open("libisc.cat", &isc_msgcat);
+}
+
+void
+isc_lib_initmsgcat(void) {
+ isc_result_t result;
+
+ /*!
+ * Initialize the ISC library's message catalog, isc_msgcat, if it
+ * has not already been initialized.
+ */
+
+ result = isc_once_do(&msgcat_once, open_msgcat);
+ if (result != ISC_R_SUCCESS) {
+ /*
+ * Normally we'd use RUNTIME_CHECK() or FATAL_ERROR(), but
+ * we can't do that here, since they might call us!
+ * (Note that the catalog might be open anyway, so we might
+ * as well try to provide an internationalized message.)
+ */
+ fprintf(stderr, "%s:%d: %s: isc_once_do() %s.\n",
+ __FILE__, __LINE__,
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
+ ISC_MSG_FATALERROR, "fatal error"),
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
+ ISC_MSG_FAILED, "failed"));
+ abort();
+ }
+}
+
+#ifndef BIND9
+static isc_once_t register_once = ISC_ONCE_INIT;
+
+static void
+do_register(void) {
+ RUNTIME_CHECK(isc__mem_register() == ISC_R_SUCCESS);
+ RUNTIME_CHECK(isc__app_register() == ISC_R_SUCCESS);
+ RUNTIME_CHECK(isc__task_register() == ISC_R_SUCCESS);
+ RUNTIME_CHECK(isc__socket_register() == ISC_R_SUCCESS);
+ RUNTIME_CHECK(isc__timer_register() == ISC_R_SUCCESS);
+}
+
+void
+isc_lib_register() {
+ RUNTIME_CHECK(isc_once_do(&register_once, do_register)
+ == ISC_R_SUCCESS);
+}
+#endif
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/log.c b/sebhbsd/freebsd/contrib/ntp/lib/isc/log.c
new file mode 100644
index 0000000..4e29081
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/log.c
@@ -0,0 +1,1769 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (C) 2004-2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+/*! \file
+ * \author Principal Authors: DCL */
+
+#include <config.h>
+
+#include <errno.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <time.h>
+
+#include <sys/types.h> /* dev_t FreeBSD 2.1 */
+
+#include <isc/dir.h>
+#include <isc/file.h>
+#include <isc/log.h>
+#include <isc/magic.h>
+#include <isc/mem.h>
+#include <isc/msgs.h>
+#include <isc/print.h>
+#include <isc/stat.h>
+#include <isc/stdio.h>
+#include <isc/string.h>
+#include <isc/time.h>
+#include <isc/util.h>
+#include "ntp_stdlib.h" /* NTP change for strlcpy, strlcat */
+
+#define LCTX_MAGIC ISC_MAGIC('L', 'c', 't', 'x')
+#define VALID_CONTEXT(lctx) ISC_MAGIC_VALID(lctx, LCTX_MAGIC)
+
+#define LCFG_MAGIC ISC_MAGIC('L', 'c', 'f', 'g')
+#define VALID_CONFIG(lcfg) ISC_MAGIC_VALID(lcfg, LCFG_MAGIC)
+
+/*
+ * XXXDCL make dynamic?
+ */
+#define LOG_BUFFER_SIZE (8 * 1024)
+
+#ifndef PATH_MAX
+#define PATH_MAX 1024 /* AIX and others don't define this. */
+#endif
+
+/*!
+ * This is the structure that holds each named channel. A simple linked
+ * list chains all of the channels together, so an individual channel is
+ * found by doing strcmp()s with the names down the list. Their should
+ * be no performance penalty from this as it is expected that the number
+ * of named channels will be no more than a dozen or so, and name lookups
+ * from the head of the list are only done when isc_log_usechannel() is
+ * called, which should also be very infrequent.
+ */
+typedef struct isc_logchannel isc_logchannel_t;
+
+struct isc_logchannel {
+ char * name;
+ unsigned int type;
+ int level;
+ unsigned int flags;
+ isc_logdestination_t destination;
+ ISC_LINK(isc_logchannel_t) link;
+};
+
+/*!
+ * The logchannellist structure associates categories and modules with
+ * channels. First the appropriate channellist is found based on the
+ * category, and then each structure in the linked list is checked for
+ * a matching module. It is expected that the number of channels
+ * associated with any given category will be very short, no more than
+ * three or four in the more unusual cases.
+ */
+typedef struct isc_logchannellist isc_logchannellist_t;
+
+struct isc_logchannellist {
+ const isc_logmodule_t * module;
+ isc_logchannel_t * channel;
+ ISC_LINK(isc_logchannellist_t) link;
+};
+
+/*!
+ * This structure is used to remember messages for pruning via
+ * isc_log_[v]write1().
+ */
+typedef struct isc_logmessage isc_logmessage_t;
+
+struct isc_logmessage {
+ char * text;
+ isc_time_t time;
+ ISC_LINK(isc_logmessage_t) link;
+};
+
+/*!
+ * The isc_logconfig structure is used to store the configurable information
+ * about where messages are actually supposed to be sent -- the information
+ * that could changed based on some configuration file, as opposed to the
+ * the category/module specification of isc_log_[v]write[1] that is compiled
+ * into a program, or the debug_level which is dynamic state information.
+ */
+struct isc_logconfig {
+ unsigned int magic;
+ isc_log_t * lctx;
+ ISC_LIST(isc_logchannel_t) channels;
+ ISC_LIST(isc_logchannellist_t) *channellists;
+ unsigned int channellist_count;
+ unsigned int duplicate_interval;
+ int highest_level;
+ char * tag;
+ isc_boolean_t dynamic;
+};
+
+/*!
+ * This isc_log structure provides the context for the isc_log functions.
+ * The log context locks itself in isc_log_doit, the internal backend to
+ * isc_log_write. The locking is necessary both to provide exclusive access
+ * to the buffer into which the message is formatted and to guard against
+ * competing threads trying to write to the same syslog resource. (On
+ * some systems, such as BSD/OS, stdio is thread safe but syslog is not.)
+ * Unfortunately, the lock cannot guard against a _different_ logging
+ * context in the same program competing for syslog's attention. Thus
+ * There Can Be Only One, but this is not enforced.
+ * XXXDCL enforce it?
+ *
+ * Note that the category and module information is not locked.
+ * This is because in the usual case, only one isc_log_t is ever created
+ * in a program, and the category/module registration happens only once.
+ * XXXDCL it might be wise to add more locking overall.
+ */
+struct isc_log {
+ /* Not locked. */
+ unsigned int magic;
+ isc_mem_t * mctx;
+ isc_logcategory_t * categories;
+ unsigned int category_count;
+ isc_logmodule_t * modules;
+ unsigned int module_count;
+ int debug_level;
+ isc_mutex_t lock;
+ /* Locked by isc_log lock. */
+ isc_logconfig_t * logconfig;
+ char buffer[LOG_BUFFER_SIZE];
+ ISC_LIST(isc_logmessage_t) messages;
+};
+
+/*!
+ * Used when ISC_LOG_PRINTLEVEL is enabled for a channel.
+ */
+static const char *log_level_strings[] = {
+ "debug",
+ "info",
+ "notice",
+ "warning",
+ "error",
+ "critical"
+};
+
+/*!
+ * Used to convert ISC_LOG_* priorities into syslog priorities.
+ * XXXDCL This will need modification for NT.
+ */
+static const int syslog_map[] = {
+ LOG_DEBUG,
+ LOG_INFO,
+ LOG_NOTICE,
+ LOG_WARNING,
+ LOG_ERR,
+ LOG_CRIT
+};
+
+/*!
+ * When adding new categories, a corresponding ISC_LOGCATEGORY_foo
+ * definition needs to be added to <isc/log.h>.
+ *
+ * The default category is provided so that the internal default can
+ * be overridden. Since the default is always looked up as the first
+ * channellist in the log context, it must come first in isc_categories[].
+ */
+LIBISC_EXTERNAL_DATA isc_logcategory_t isc_categories[] = {
+ { "default", 0 }, /* "default" must come first. */
+ { "general", 0 },
+ { NULL, 0 }
+};
+
+/*!
+ * See above comment for categories on LIBISC_EXTERNAL_DATA, and apply it to modules.
+ */
+LIBISC_EXTERNAL_DATA isc_logmodule_t isc_modules[] = {
+ { "socket", 0 },
+ { "time", 0 },
+ { "interface", 0 },
+ { "timer", 0 },
+ { "file", 0 },
+ { NULL, 0 }
+};
+
+/*!
+ * This essentially constant structure must be filled in at run time,
+ * because its channel member is pointed to a channel that is created
+ * dynamically with isc_log_createchannel.
+ */
+static isc_logchannellist_t default_channel;
+
+/*!
+ * libisc logs to this context.
+ */
+LIBISC_EXTERNAL_DATA isc_log_t *isc_lctx = NULL;
+
+/*!
+ * Forward declarations.
+ */
+static isc_result_t
+assignchannel(isc_logconfig_t *lcfg, unsigned int category_id,
+ const isc_logmodule_t *module, isc_logchannel_t *channel);
+
+static isc_result_t
+sync_channellist(isc_logconfig_t *lcfg);
+
+static isc_result_t
+greatest_version(isc_logchannel_t *channel, int *greatest);
+
+static isc_result_t
+roll_log(isc_logchannel_t *channel);
+
+static void
+isc_log_doit(isc_log_t *lctx, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level, isc_boolean_t write_once,
+ isc_msgcat_t *msgcat, int msgset, int msg,
+ const char *format, va_list args)
+ ISC_FORMAT_PRINTF(9, 0);
+
+/*@{*/
+/*!
+ * Convenience macros.
+ */
+
+#define FACILITY(channel) (channel->destination.facility)
+#define FILE_NAME(channel) (channel->destination.file.name)
+#define FILE_STREAM(channel) (channel->destination.file.stream)
+#define FILE_VERSIONS(channel) (channel->destination.file.versions)
+#define FILE_MAXSIZE(channel) (channel->destination.file.maximum_size)
+#define FILE_MAXREACHED(channel) (channel->destination.file.maximum_reached)
+
+/*@}*/
+/****
+ **** Public interfaces.
+ ****/
+
+/*
+ * Establish a new logging context, with default channels.
+ */
+isc_result_t
+isc_log_create(isc_mem_t *mctx, isc_log_t **lctxp, isc_logconfig_t **lcfgp) {
+ isc_log_t *lctx;
+ isc_logconfig_t *lcfg = NULL;
+ isc_result_t result;
+
+ REQUIRE(mctx != NULL);
+ REQUIRE(lctxp != NULL && *lctxp == NULL);
+ REQUIRE(lcfgp == NULL || *lcfgp == NULL);
+
+ lctx = isc_mem_get(mctx, sizeof(*lctx));
+ if (lctx != NULL) {
+ lctx->mctx = mctx;
+ lctx->categories = NULL;
+ lctx->category_count = 0;
+ lctx->modules = NULL;
+ lctx->module_count = 0;
+ lctx->debug_level = 0;
+
+ ISC_LIST_INIT(lctx->messages);
+
+ result = isc_mutex_init(&lctx->lock);
+ if (result != ISC_R_SUCCESS) {
+ isc_mem_put(mctx, lctx, sizeof(*lctx));
+ return (result);
+ }
+
+ /*
+ * Normally setting the magic number is the last step done
+ * in a creation function, but a valid log context is needed
+ * by isc_log_registercategories and isc_logconfig_create.
+ * If either fails, the lctx is destroyed and not returned
+ * to the caller.
+ */
+ lctx->magic = LCTX_MAGIC;
+
+ isc_log_registercategories(lctx, isc_categories);
+ isc_log_registermodules(lctx, isc_modules);
+ result = isc_logconfig_create(lctx, &lcfg);
+
+ } else
+ result = ISC_R_NOMEMORY;
+
+ if (result == ISC_R_SUCCESS)
+ result = sync_channellist(lcfg);
+
+ if (result == ISC_R_SUCCESS) {
+ lctx->logconfig = lcfg;
+
+ *lctxp = lctx;
+ if (lcfgp != NULL)
+ *lcfgp = lcfg;
+
+ } else {
+ if (lcfg != NULL)
+ isc_logconfig_destroy(&lcfg);
+ if (lctx != NULL)
+ isc_log_destroy(&lctx);
+ }
+
+ return (result);
+}
+
+isc_result_t
+isc_logconfig_create(isc_log_t *lctx, isc_logconfig_t **lcfgp) {
+ isc_logconfig_t *lcfg;
+ isc_logdestination_t destination;
+ isc_result_t result = ISC_R_SUCCESS;
+ int level = ISC_LOG_INFO;
+
+ REQUIRE(lcfgp != NULL && *lcfgp == NULL);
+ REQUIRE(VALID_CONTEXT(lctx));
+
+ lcfg = isc_mem_get(lctx->mctx, sizeof(*lcfg));
+
+ if (lcfg != NULL) {
+ lcfg->lctx = lctx;
+ lcfg->channellists = NULL;
+ lcfg->channellist_count = 0;
+ lcfg->duplicate_interval = 0;
+ lcfg->highest_level = level;
+ lcfg->tag = NULL;
+ lcfg->dynamic = ISC_FALSE;
+
+ ISC_LIST_INIT(lcfg->channels);
+
+ /*
+ * Normally the magic number is the last thing set in the
+ * structure, but isc_log_createchannel() needs a valid
+ * config. If the channel creation fails, the lcfg is not
+ * returned to the caller.
+ */
+ lcfg->magic = LCFG_MAGIC;
+
+ } else
+ result = ISC_R_NOMEMORY;
+
+ /*
+ * Create the default channels:
+ * default_syslog, default_stderr, default_debug and null.
+ */
+ if (result == ISC_R_SUCCESS) {
+ destination.facility = LOG_DAEMON;
+ result = isc_log_createchannel(lcfg, "default_syslog",
+ ISC_LOG_TOSYSLOG, level,
+ &destination, 0);
+ }
+
+ if (result == ISC_R_SUCCESS) {
+ destination.file.stream = stderr;
+ destination.file.name = NULL;
+ destination.file.versions = ISC_LOG_ROLLNEVER;
+ destination.file.maximum_size = 0;
+ result = isc_log_createchannel(lcfg, "default_stderr",
+ ISC_LOG_TOFILEDESC,
+ level,
+ &destination,
+ ISC_LOG_PRINTTIME);
+ }
+
+ if (result == ISC_R_SUCCESS) {
+ /*
+ * Set the default category's channel to default_stderr,
+ * which is at the head of the channels list because it was
+ * just created.
+ */
+ default_channel.channel = ISC_LIST_HEAD(lcfg->channels);
+
+ destination.file.stream = stderr;
+ destination.file.name = NULL;
+ destination.file.versions = ISC_LOG_ROLLNEVER;
+ destination.file.maximum_size = 0;
+ result = isc_log_createchannel(lcfg, "default_debug",
+ ISC_LOG_TOFILEDESC,
+ ISC_LOG_DYNAMIC,
+ &destination,
+ ISC_LOG_PRINTTIME);
+ }
+
+ if (result == ISC_R_SUCCESS)
+ result = isc_log_createchannel(lcfg, "null",
+ ISC_LOG_TONULL,
+ ISC_LOG_DYNAMIC,
+ NULL, 0);
+
+ if (result == ISC_R_SUCCESS)
+ *lcfgp = lcfg;
+
+ else
+ if (lcfg != NULL)
+ isc_logconfig_destroy(&lcfg);
+
+ return (result);
+}
+
+isc_logconfig_t *
+isc_logconfig_get(isc_log_t *lctx) {
+ REQUIRE(VALID_CONTEXT(lctx));
+
+ ENSURE(lctx->logconfig != NULL);
+
+ return (lctx->logconfig);
+}
+
+isc_result_t
+isc_logconfig_use(isc_log_t *lctx, isc_logconfig_t *lcfg) {
+ isc_logconfig_t *old_cfg;
+ isc_result_t result;
+
+ REQUIRE(VALID_CONTEXT(lctx));
+ REQUIRE(VALID_CONFIG(lcfg));
+ REQUIRE(lcfg->lctx == lctx);
+
+ /*
+ * Ensure that lcfg->channellist_count == lctx->category_count.
+ * They won't be equal if isc_log_usechannel has not been called
+ * since any call to isc_log_registercategories.
+ */
+ result = sync_channellist(lcfg);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ LOCK(&lctx->lock);
+
+ old_cfg = lctx->logconfig;
+ lctx->logconfig = lcfg;
+
+ UNLOCK(&lctx->lock);
+
+ isc_logconfig_destroy(&old_cfg);
+
+ return (ISC_R_SUCCESS);
+}
+
+void
+isc_log_destroy(isc_log_t **lctxp) {
+ isc_log_t *lctx;
+ isc_logconfig_t *lcfg;
+ isc_mem_t *mctx;
+ isc_logmessage_t *message;
+
+ REQUIRE(lctxp != NULL && VALID_CONTEXT(*lctxp));
+
+ lctx = *lctxp;
+ mctx = lctx->mctx;
+
+ if (lctx->logconfig != NULL) {
+ lcfg = lctx->logconfig;
+ lctx->logconfig = NULL;
+ isc_logconfig_destroy(&lcfg);
+ }
+
+ DESTROYLOCK(&lctx->lock);
+
+ while ((message = ISC_LIST_HEAD(lctx->messages)) != NULL) {
+ ISC_LIST_UNLINK(lctx->messages, message, link);
+
+ isc_mem_put(mctx, message,
+ sizeof(*message) + strlen(message->text) + 1);
+ }
+
+ lctx->buffer[0] = '\0';
+ lctx->debug_level = 0;
+ lctx->categories = NULL;
+ lctx->category_count = 0;
+ lctx->modules = NULL;
+ lctx->module_count = 0;
+ lctx->mctx = NULL;
+ lctx->magic = 0;
+
+ isc_mem_put(mctx, lctx, sizeof(*lctx));
+
+ *lctxp = NULL;
+}
+
+void
+isc_logconfig_destroy(isc_logconfig_t **lcfgp) {
+ isc_logconfig_t *lcfg;
+ isc_mem_t *mctx;
+ isc_logchannel_t *channel;
+ isc_logchannellist_t *item;
+ char *filename;
+ unsigned int i;
+
+ REQUIRE(lcfgp != NULL && VALID_CONFIG(*lcfgp));
+
+ lcfg = *lcfgp;
+
+ /*
+ * This function cannot be called with a logconfig that is in
+ * use by a log context.
+ */
+ REQUIRE(lcfg->lctx != NULL && lcfg->lctx->logconfig != lcfg);
+
+ mctx = lcfg->lctx->mctx;
+
+ while ((channel = ISC_LIST_HEAD(lcfg->channels)) != NULL) {
+ ISC_LIST_UNLINK(lcfg->channels, channel, link);
+
+ if (channel->type == ISC_LOG_TOFILE) {
+ /*
+ * The filename for the channel may have ultimately
+ * started its life in user-land as a const string,
+ * but in isc_log_createchannel it gets copied
+ * into writable memory and is not longer truly const.
+ */
+ DE_CONST(FILE_NAME(channel), filename);
+ isc_mem_free(mctx, filename);
+
+ if (FILE_STREAM(channel) != NULL)
+ (void)fclose(FILE_STREAM(channel));
+ }
+
+ isc_mem_free(mctx, channel->name);
+ isc_mem_put(mctx, channel, sizeof(*channel));
+ }
+
+ for (i = 0; i < lcfg->channellist_count; i++)
+ while ((item = ISC_LIST_HEAD(lcfg->channellists[i])) != NULL) {
+ ISC_LIST_UNLINK(lcfg->channellists[i], item, link);
+ isc_mem_put(mctx, item, sizeof(*item));
+ }
+
+ if (lcfg->channellist_count > 0)
+ isc_mem_put(mctx, lcfg->channellists,
+ lcfg->channellist_count *
+ sizeof(ISC_LIST(isc_logchannellist_t)));
+
+ lcfg->dynamic = ISC_FALSE;
+ if (lcfg->tag != NULL)
+ isc_mem_free(lcfg->lctx->mctx, lcfg->tag);
+ lcfg->tag = NULL;
+ lcfg->highest_level = 0;
+ lcfg->duplicate_interval = 0;
+ lcfg->magic = 0;
+
+ isc_mem_put(mctx, lcfg, sizeof(*lcfg));
+
+ *lcfgp = NULL;
+}
+
+void
+isc_log_registercategories(isc_log_t *lctx, isc_logcategory_t categories[]) {
+ isc_logcategory_t *catp;
+
+ REQUIRE(VALID_CONTEXT(lctx));
+ REQUIRE(categories != NULL && categories[0].name != NULL);
+
+ /*
+ * XXXDCL This somewhat sleazy situation of using the last pointer
+ * in one category array to point to the next array exists because
+ * this registration function returns void and I didn't want to have
+ * change everything that used it by making it return an isc_result_t.
+ * It would need to do that if it had to allocate memory to store
+ * pointers to each array passed in.
+ */
+ if (lctx->categories == NULL)
+ lctx->categories = categories;
+
+ else {
+ /*
+ * Adjust the last (NULL) pointer of the already registered
+ * categories to point to the incoming array.
+ */
+ for (catp = lctx->categories; catp->name != NULL; )
+ if (catp->id == UINT_MAX)
+ /*
+ * The name pointer points to the next array.
+ * Ick.
+ */
+ DE_CONST(catp->name, catp);
+ else
+ catp++;
+
+ catp->name = (void *)categories;
+ catp->id = UINT_MAX;
+ }
+
+ /*
+ * Update the id number of the category with its new global id.
+ */
+ for (catp = categories; catp->name != NULL; catp++)
+ catp->id = lctx->category_count++;
+}
+
+isc_logcategory_t *
+isc_log_categorybyname(isc_log_t *lctx, const char *name) {
+ isc_logcategory_t *catp;
+
+ REQUIRE(VALID_CONTEXT(lctx));
+ REQUIRE(name != NULL);
+
+ for (catp = lctx->categories; catp->name != NULL; )
+ if (catp->id == UINT_MAX)
+ /*
+ * catp is neither modified nor returned to the
+ * caller, so removing its const qualifier is ok.
+ */
+ DE_CONST(catp->name, catp);
+ else {
+ if (strcmp(catp->name, name) == 0)
+ return (catp);
+ catp++;
+ }
+
+ return (NULL);
+}
+
+void
+isc_log_registermodules(isc_log_t *lctx, isc_logmodule_t modules[]) {
+ isc_logmodule_t *modp;
+
+ REQUIRE(VALID_CONTEXT(lctx));
+ REQUIRE(modules != NULL && modules[0].name != NULL);
+
+ /*
+ * XXXDCL This somewhat sleazy situation of using the last pointer
+ * in one category array to point to the next array exists because
+ * this registration function returns void and I didn't want to have
+ * change everything that used it by making it return an isc_result_t.
+ * It would need to do that if it had to allocate memory to store
+ * pointers to each array passed in.
+ */
+ if (lctx->modules == NULL)
+ lctx->modules = modules;
+
+ else {
+ /*
+ * Adjust the last (NULL) pointer of the already registered
+ * modules to point to the incoming array.
+ */
+ for (modp = lctx->modules; modp->name != NULL; )
+ if (modp->id == UINT_MAX)
+ /*
+ * The name pointer points to the next array.
+ * Ick.
+ */
+ DE_CONST(modp->name, modp);
+ else
+ modp++;
+
+ modp->name = (void *)modules;
+ modp->id = UINT_MAX;
+ }
+
+ /*
+ * Update the id number of the module with its new global id.
+ */
+ for (modp = modules; modp->name != NULL; modp++)
+ modp->id = lctx->module_count++;
+}
+
+isc_logmodule_t *
+isc_log_modulebyname(isc_log_t *lctx, const char *name) {
+ isc_logmodule_t *modp;
+
+ REQUIRE(VALID_CONTEXT(lctx));
+ REQUIRE(name != NULL);
+
+ for (modp = lctx->modules; modp->name != NULL; )
+ if (modp->id == UINT_MAX)
+ /*
+ * modp is neither modified nor returned to the
+ * caller, so removing its const qualifier is ok.
+ */
+ DE_CONST(modp->name, modp);
+ else {
+ if (strcmp(modp->name, name) == 0)
+ return (modp);
+ modp++;
+ }
+
+ return (NULL);
+}
+
+isc_result_t
+isc_log_createchannel(isc_logconfig_t *lcfg, const char *name,
+ unsigned int type, int level,
+ const isc_logdestination_t *destination,
+ unsigned int flags)
+{
+ isc_logchannel_t *channel;
+ isc_mem_t *mctx;
+
+ REQUIRE(VALID_CONFIG(lcfg));
+ REQUIRE(name != NULL);
+ REQUIRE(type == ISC_LOG_TOSYSLOG || type == ISC_LOG_TOFILE ||
+ type == ISC_LOG_TOFILEDESC || type == ISC_LOG_TONULL);
+ REQUIRE(destination != NULL || type == ISC_LOG_TONULL);
+ REQUIRE(level >= ISC_LOG_CRITICAL);
+ REQUIRE((flags &
+ (unsigned int)~(ISC_LOG_PRINTALL | ISC_LOG_DEBUGONLY)) == 0);
+
+ /* XXXDCL find duplicate names? */
+
+ mctx = lcfg->lctx->mctx;
+
+ channel = isc_mem_get(mctx, sizeof(*channel));
+ if (channel == NULL)
+ return (ISC_R_NOMEMORY);
+
+ channel->name = isc_mem_strdup(mctx, name);
+ if (channel->name == NULL) {
+ isc_mem_put(mctx, channel, sizeof(*channel));
+ return (ISC_R_NOMEMORY);
+ }
+
+ channel->type = type;
+ channel->level = level;
+ channel->flags = flags;
+ ISC_LINK_INIT(channel, link);
+
+ switch (type) {
+ case ISC_LOG_TOSYSLOG:
+ FACILITY(channel) = destination->facility;
+ break;
+
+ case ISC_LOG_TOFILE:
+ /*
+ * The file name is copied because greatest_version wants
+ * to scribble on it, so it needs to be definitely in
+ * writable memory.
+ */
+ FILE_NAME(channel) =
+ isc_mem_strdup(mctx, destination->file.name);
+ FILE_STREAM(channel) = NULL;
+ FILE_VERSIONS(channel) = destination->file.versions;
+ FILE_MAXSIZE(channel) = destination->file.maximum_size;
+ FILE_MAXREACHED(channel) = ISC_FALSE;
+ break;
+
+ case ISC_LOG_TOFILEDESC:
+ FILE_NAME(channel) = NULL;
+ FILE_STREAM(channel) = destination->file.stream;
+ FILE_MAXSIZE(channel) = 0;
+ FILE_VERSIONS(channel) = ISC_LOG_ROLLNEVER;
+ break;
+
+ case ISC_LOG_TONULL:
+ /* Nothing. */
+ break;
+
+ default:
+ isc_mem_put(mctx, channel->name, strlen(channel->name) + 1);
+ isc_mem_put(mctx, channel, sizeof(*channel));
+ return (ISC_R_UNEXPECTED);
+ }
+
+ ISC_LIST_PREPEND(lcfg->channels, channel, link);
+
+ /*
+ * If default_stderr was redefined, make the default category
+ * point to the new default_stderr.
+ */
+ if (strcmp(name, "default_stderr") == 0)
+ default_channel.channel = channel;
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_log_usechannel(isc_logconfig_t *lcfg, const char *name,
+ const isc_logcategory_t *category,
+ const isc_logmodule_t *module)
+{
+ isc_log_t *lctx;
+ isc_logchannel_t *channel;
+ isc_result_t result = ISC_R_SUCCESS;
+ unsigned int i;
+
+ REQUIRE(VALID_CONFIG(lcfg));
+ REQUIRE(name != NULL);
+
+ lctx = lcfg->lctx;
+
+ REQUIRE(category == NULL || category->id < lctx->category_count);
+ REQUIRE(module == NULL || module->id < lctx->module_count);
+
+ for (channel = ISC_LIST_HEAD(lcfg->channels); channel != NULL;
+ channel = ISC_LIST_NEXT(channel, link))
+ if (strcmp(name, channel->name) == 0)
+ break;
+
+ if (channel == NULL)
+ return (ISC_R_NOTFOUND);
+
+ if (category != NULL)
+ result = assignchannel(lcfg, category->id, module, channel);
+
+ else
+ /*
+ * Assign to all categories. Note that this includes
+ * the default channel.
+ */
+ for (i = 0; i < lctx->category_count; i++) {
+ result = assignchannel(lcfg, i, module, channel);
+ if (result != ISC_R_SUCCESS)
+ break;
+ }
+
+ return (result);
+}
+
+void
+isc_log_write(isc_log_t *lctx, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level, const char *format, ...)
+{
+ va_list args;
+
+ /*
+ * Contract checking is done in isc_log_doit().
+ */
+
+ va_start(args, format);
+ isc_log_doit(lctx, category, module, level, ISC_FALSE,
+ NULL, 0, 0, format, args);
+ va_end(args);
+}
+
+void
+isc_log_vwrite(isc_log_t *lctx, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level,
+ const char *format, va_list args)
+{
+ /*
+ * Contract checking is done in isc_log_doit().
+ */
+ isc_log_doit(lctx, category, module, level, ISC_FALSE,
+ NULL, 0, 0, format, args);
+}
+
+void
+isc_log_write1(isc_log_t *lctx, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level, const char *format, ...)
+{
+ va_list args;
+
+ /*
+ * Contract checking is done in isc_log_doit().
+ */
+
+ va_start(args, format);
+ isc_log_doit(lctx, category, module, level, ISC_TRUE,
+ NULL, 0, 0, format, args);
+ va_end(args);
+}
+
+void
+isc_log_vwrite1(isc_log_t *lctx, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level,
+ const char *format, va_list args)
+{
+ /*
+ * Contract checking is done in isc_log_doit().
+ */
+ isc_log_doit(lctx, category, module, level, ISC_TRUE,
+ NULL, 0, 0, format, args);
+}
+
+void
+isc_log_iwrite(isc_log_t *lctx, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level,
+ isc_msgcat_t *msgcat, int msgset, int msg,
+ const char *format, ...)
+{
+ va_list args;
+
+ /*
+ * Contract checking is done in isc_log_doit().
+ */
+
+ va_start(args, format);
+ isc_log_doit(lctx, category, module, level, ISC_FALSE,
+ msgcat, msgset, msg, format, args);
+ va_end(args);
+}
+
+void
+isc_log_ivwrite(isc_log_t *lctx, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level,
+ isc_msgcat_t *msgcat, int msgset, int msg,
+ const char *format, va_list args)
+{
+ /*
+ * Contract checking is done in isc_log_doit().
+ */
+ isc_log_doit(lctx, category, module, level, ISC_FALSE,
+ msgcat, msgset, msg, format, args);
+}
+
+void
+isc_log_iwrite1(isc_log_t *lctx, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level,
+ isc_msgcat_t *msgcat, int msgset, int msg,
+ const char *format, ...)
+{
+ va_list args;
+
+ /*
+ * Contract checking is done in isc_log_doit().
+ */
+
+ va_start(args, format);
+ isc_log_doit(lctx, category, module, level, ISC_TRUE,
+ msgcat, msgset, msg, format, args);
+ va_end(args);
+}
+
+void
+isc_log_ivwrite1(isc_log_t *lctx, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level,
+ isc_msgcat_t *msgcat, int msgset, int msg,
+ const char *format, va_list args)
+{
+ /*
+ * Contract checking is done in isc_log_doit().
+ */
+ isc_log_doit(lctx, category, module, level, ISC_TRUE,
+ msgcat, msgset, msg, format, args);
+}
+
+void
+isc_log_setcontext(isc_log_t *lctx) {
+ isc_lctx = lctx;
+}
+
+void
+isc_log_setdebuglevel(isc_log_t *lctx, unsigned int level) {
+ isc_logchannel_t *channel;
+
+ REQUIRE(VALID_CONTEXT(lctx));
+
+ LOCK(&lctx->lock);
+
+ lctx->debug_level = level;
+ /*
+ * Close ISC_LOG_DEBUGONLY channels if level is zero.
+ */
+ if (lctx->debug_level == 0)
+ for (channel = ISC_LIST_HEAD(lctx->logconfig->channels);
+ channel != NULL;
+ channel = ISC_LIST_NEXT(channel, link))
+ if (channel->type == ISC_LOG_TOFILE &&
+ (channel->flags & ISC_LOG_DEBUGONLY) != 0 &&
+ FILE_STREAM(channel) != NULL) {
+ (void)fclose(FILE_STREAM(channel));
+ FILE_STREAM(channel) = NULL;
+ }
+ UNLOCK(&lctx->lock);
+}
+
+unsigned int
+isc_log_getdebuglevel(isc_log_t *lctx) {
+ REQUIRE(VALID_CONTEXT(lctx));
+
+ return (lctx->debug_level);
+}
+
+void
+isc_log_setduplicateinterval(isc_logconfig_t *lcfg, unsigned int interval) {
+ REQUIRE(VALID_CONFIG(lcfg));
+
+ lcfg->duplicate_interval = interval;
+}
+
+unsigned int
+isc_log_getduplicateinterval(isc_logconfig_t *lcfg) {
+ REQUIRE(VALID_CONTEXT(lcfg));
+
+ return (lcfg->duplicate_interval);
+}
+
+isc_result_t
+isc_log_settag(isc_logconfig_t *lcfg, const char *tag) {
+ REQUIRE(VALID_CONFIG(lcfg));
+
+ if (tag != NULL && *tag != '\0') {
+ if (lcfg->tag != NULL)
+ isc_mem_free(lcfg->lctx->mctx, lcfg->tag);
+ lcfg->tag = isc_mem_strdup(lcfg->lctx->mctx, tag);
+ if (lcfg->tag == NULL)
+ return (ISC_R_NOMEMORY);
+
+ } else {
+ if (lcfg->tag != NULL)
+ isc_mem_free(lcfg->lctx->mctx, lcfg->tag);
+ lcfg->tag = NULL;
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+char *
+isc_log_gettag(isc_logconfig_t *lcfg) {
+ REQUIRE(VALID_CONFIG(lcfg));
+
+ return (lcfg->tag);
+}
+
+/* XXXDCL NT -- This interface will assuredly be changing. */
+void
+isc_log_opensyslog(const char *tag, int options, int facility) {
+ (void)openlog(tag, options, facility);
+}
+
+void
+isc_log_closefilelogs(isc_log_t *lctx) {
+ isc_logchannel_t *channel;
+
+ REQUIRE(VALID_CONTEXT(lctx));
+
+ LOCK(&lctx->lock);
+ for (channel = ISC_LIST_HEAD(lctx->logconfig->channels);
+ channel != NULL;
+ channel = ISC_LIST_NEXT(channel, link))
+
+ if (channel->type == ISC_LOG_TOFILE &&
+ FILE_STREAM(channel) != NULL) {
+ (void)fclose(FILE_STREAM(channel));
+ FILE_STREAM(channel) = NULL;
+ }
+ UNLOCK(&lctx->lock);
+}
+
+/****
+ **** Internal functions
+ ****/
+
+static isc_result_t
+assignchannel(isc_logconfig_t *lcfg, unsigned int category_id,
+ const isc_logmodule_t *module, isc_logchannel_t *channel)
+{
+ isc_logchannellist_t *new_item;
+ isc_log_t *lctx;
+ isc_result_t result;
+
+ REQUIRE(VALID_CONFIG(lcfg));
+
+ lctx = lcfg->lctx;
+
+ REQUIRE(category_id < lctx->category_count);
+ REQUIRE(module == NULL || module->id < lctx->module_count);
+ REQUIRE(channel != NULL);
+
+ /*
+ * Ensure lcfg->channellist_count == lctx->category_count.
+ */
+ result = sync_channellist(lcfg);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ new_item = isc_mem_get(lctx->mctx, sizeof(*new_item));
+ if (new_item == NULL)
+ return (ISC_R_NOMEMORY);
+
+ new_item->channel = channel;
+ new_item->module = module;
+ ISC_LIST_INITANDPREPEND(lcfg->channellists[category_id],
+ new_item, link);
+
+ /*
+ * Remember the highest logging level set by any channel in the
+ * logging config, so isc_log_doit() can quickly return if the
+ * message is too high to be logged by any channel.
+ */
+ if (channel->type != ISC_LOG_TONULL) {
+ if (lcfg->highest_level < channel->level)
+ lcfg->highest_level = channel->level;
+ if (channel->level == ISC_LOG_DYNAMIC)
+ lcfg->dynamic = ISC_TRUE;
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+/*
+ * This would ideally be part of isc_log_registercategories(), except then
+ * that function would have to return isc_result_t instead of void.
+ */
+static isc_result_t
+sync_channellist(isc_logconfig_t *lcfg) {
+ unsigned int bytes;
+ isc_log_t *lctx;
+ void *lists;
+
+ REQUIRE(VALID_CONFIG(lcfg));
+
+ lctx = lcfg->lctx;
+
+ REQUIRE(lctx->category_count != 0);
+
+ if (lctx->category_count == lcfg->channellist_count)
+ return (ISC_R_SUCCESS);
+
+ bytes = lctx->category_count * sizeof(ISC_LIST(isc_logchannellist_t));
+
+ lists = isc_mem_get(lctx->mctx, bytes);
+
+ if (lists == NULL)
+ return (ISC_R_NOMEMORY);
+
+ memset(lists, 0, bytes);
+
+ if (lcfg->channellist_count != 0) {
+ bytes = lcfg->channellist_count *
+ sizeof(ISC_LIST(isc_logchannellist_t));
+ memcpy(lists, lcfg->channellists, bytes);
+ isc_mem_put(lctx->mctx, lcfg->channellists, bytes);
+ }
+
+ lcfg->channellists = lists;
+ lcfg->channellist_count = lctx->category_count;
+
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+greatest_version(isc_logchannel_t *channel, int *greatestp) {
+ /* XXXDCL HIGHLY NT */
+ char *basenam, *digit_end;
+ const char *dirname;
+ int version, greatest = -1;
+ size_t basenamelen;
+ isc_dir_t dir;
+ isc_result_t result;
+ char sep = '/';
+#ifdef _WIN32
+ char *basename2;
+#endif
+
+ REQUIRE(channel->type == ISC_LOG_TOFILE);
+
+ /*
+ * It is safe to DE_CONST the file.name because it was copied
+ * with isc_mem_strdup in isc_log_createchannel.
+ */
+ basenam = strrchr(FILE_NAME(channel), sep);
+#ifdef _WIN32
+ basename2 = strrchr(FILE_NAME(channel), '\\');
+ if ((basenam != NULL && basename2 != NULL && basename2 > basenam) ||
+ (basenam == NULL && basename2 != NULL)) {
+ basenam = basename2;
+ sep = '\\';
+ }
+#endif
+ if (basenam != NULL) {
+ *basenam++ = '\0';
+ dirname = FILE_NAME(channel);
+ } else {
+ DE_CONST(FILE_NAME(channel), basenam);
+ dirname = ".";
+ }
+ basenamelen = strlen(basenam);
+
+ isc_dir_init(&dir);
+ result = isc_dir_open(&dir, dirname);
+
+ /*
+ * Replace the file separator if it was taken out.
+ */
+ if (basenam != FILE_NAME(channel))
+ *(basenam - 1) = sep;
+
+ /*
+ * Return if the directory open failed.
+ */
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ while (isc_dir_read(&dir) == ISC_R_SUCCESS) {
+ if (dir.entry.length > basenamelen &&
+ strncmp(dir.entry.name, basenam, basenamelen) == 0 &&
+ dir.entry.name[basenamelen] == '.') {
+
+ version = strtol(&dir.entry.name[basenamelen + 1],
+ &digit_end, 10);
+ if (*digit_end == '\0' && version > greatest)
+ greatest = version;
+ }
+ }
+ isc_dir_close(&dir);
+
+ *greatestp = ++greatest;
+
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+roll_log(isc_logchannel_t *channel) {
+ int i, n, greatest;
+ char current[PATH_MAX + 1];
+ char new[PATH_MAX + 1];
+ const char *path;
+ isc_result_t result;
+
+ /*
+ * Do nothing (not even excess version trimming) if ISC_LOG_ROLLNEVER
+ * is specified. Apparently complete external control over the log
+ * files is desired.
+ */
+ if (FILE_VERSIONS(channel) == ISC_LOG_ROLLNEVER)
+ return (ISC_R_SUCCESS);
+
+ path = FILE_NAME(channel);
+
+ /*
+ * Set greatest_version to the greatest existing version
+ * (not the maximum requested version). This is 1 based even
+ * though the file names are 0 based, so an oldest log of log.1
+ * is a greatest_version of 2.
+ */
+ result = greatest_version(channel, &greatest);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ /*
+ * Now greatest should be set to the highest version number desired.
+ * Since the highest number is one less than FILE_VERSIONS(channel)
+ * when not doing infinite log rolling, greatest will need to be
+ * decremented when it is equal to -- or greater than --
+ * FILE_VERSIONS(channel). When greatest is less than
+ * FILE_VERSIONS(channel), it is already suitable for use as
+ * the maximum version number.
+ */
+
+ if (FILE_VERSIONS(channel) == ISC_LOG_ROLLINFINITE ||
+ FILE_VERSIONS(channel) > greatest)
+ ; /* Do nothing. */
+ else
+ /*
+ * When greatest is >= FILE_VERSIONS(channel), it needs to
+ * be reduced until it is FILE_VERSIONS(channel) - 1.
+ * Remove any excess logs on the way to that value.
+ */
+ while (--greatest >= FILE_VERSIONS(channel)) {
+ n = snprintf(current, sizeof(current), "%s.%d",
+ path, greatest);
+ if (n >= (int)sizeof(current) || n < 0)
+ result = ISC_R_NOSPACE;
+ else
+ result = isc_file_remove(current);
+ if (result != ISC_R_SUCCESS &&
+ result != ISC_R_FILENOTFOUND)
+ syslog(LOG_ERR,
+ "unable to remove log file '%s.%d': %s",
+ path, greatest,
+ isc_result_totext(result));
+ }
+
+ for (i = greatest; i > 0; i--) {
+ result = ISC_R_SUCCESS;
+ n = snprintf(current, sizeof(current), "%s.%d", path, i - 1);
+ if (n >= (int)sizeof(current) || n < 0)
+ result = ISC_R_NOSPACE;
+ if (result == ISC_R_SUCCESS) {
+ n = snprintf(new, sizeof(new), "%s.%d", path, i);
+ if (n >= (int)sizeof(new) || n < 0)
+ result = ISC_R_NOSPACE;
+ }
+ if (result == ISC_R_SUCCESS)
+ result = isc_file_rename(current, new);
+ if (result != ISC_R_SUCCESS &&
+ result != ISC_R_FILENOTFOUND)
+ syslog(LOG_ERR,
+ "unable to rename log file '%s.%d' to "
+ "'%s.%d': %s", path, i - 1, path, i,
+ isc_result_totext(result));
+ }
+
+ if (FILE_VERSIONS(channel) != 0) {
+ n = snprintf(new, sizeof(new), "%s.0", path);
+ if (n >= (int)sizeof(new) || n < 0)
+ result = ISC_R_NOSPACE;
+ else
+ result = isc_file_rename(path, new);
+ if (result != ISC_R_SUCCESS &&
+ result != ISC_R_FILENOTFOUND)
+ syslog(LOG_ERR,
+ "unable to rename log file '%s' to '%s.0': %s",
+ path, path, isc_result_totext(result));
+ } else {
+ result = isc_file_remove(path);
+ if (result != ISC_R_SUCCESS &&
+ result != ISC_R_FILENOTFOUND)
+ syslog(LOG_ERR, "unable to remove log file '%s': %s",
+ path, isc_result_totext(result));
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+isc_log_open(isc_logchannel_t *channel) {
+ struct stat statbuf;
+ isc_boolean_t regular_file;
+ isc_boolean_t roll = ISC_FALSE;
+ isc_result_t result = ISC_R_SUCCESS;
+ const char *path;
+
+ REQUIRE(channel->type == ISC_LOG_TOFILE);
+ REQUIRE(FILE_STREAM(channel) == NULL);
+
+ path = FILE_NAME(channel);
+
+ REQUIRE(path != NULL && *path != '\0');
+
+ /*
+ * Determine type of file; only regular files will be
+ * version renamed, and only if the base file exists
+ * and either has no size limit or has reached its size limit.
+ */
+ if (stat(path, &statbuf) == 0) {
+ regular_file = S_ISREG(statbuf.st_mode) ? ISC_TRUE : ISC_FALSE;
+ /* XXXDCL if not regular_file complain? */
+ if ((FILE_MAXSIZE(channel) == 0 &&
+ FILE_VERSIONS(channel) != ISC_LOG_ROLLNEVER) ||
+ (FILE_MAXSIZE(channel) > 0 &&
+ statbuf.st_size >= FILE_MAXSIZE(channel)))
+ roll = regular_file;
+ } else if (errno == ENOENT) {
+ regular_file = ISC_TRUE;
+ POST(regular_file);
+ } else
+ result = ISC_R_INVALIDFILE;
+
+ /*
+ * Version control.
+ */
+ if (result == ISC_R_SUCCESS && roll) {
+ if (FILE_VERSIONS(channel) == ISC_LOG_ROLLNEVER)
+ return (ISC_R_MAXSIZE);
+ result = roll_log(channel);
+ if (result != ISC_R_SUCCESS) {
+ if ((channel->flags & ISC_LOG_OPENERR) == 0) {
+ syslog(LOG_ERR,
+ "isc_log_open: roll_log '%s' "
+ "failed: %s",
+ FILE_NAME(channel),
+ isc_result_totext(result));
+ channel->flags |= ISC_LOG_OPENERR;
+ }
+ return (result);
+ }
+ }
+
+ result = isc_stdio_open(path, "a", &FILE_STREAM(channel));
+
+ return (result);
+}
+
+isc_boolean_t
+isc_log_wouldlog(isc_log_t *lctx, int level) {
+ /*
+ * Try to avoid locking the mutex for messages which can't
+ * possibly be logged to any channels -- primarily debugging
+ * messages that the debug level is not high enough to print.
+ *
+ * If the level is (mathematically) less than or equal to the
+ * highest_level, or if there is a dynamic channel and the level is
+ * less than or equal to the debug level, the main loop must be
+ * entered to see if the message should really be output.
+ *
+ * NOTE: this is UNLOCKED access to the logconfig. However,
+ * the worst thing that can happen is that a bad decision is made
+ * about returning without logging, and that's not a big concern,
+ * because that's a risk anyway if the logconfig is being
+ * dynamically changed.
+ */
+
+ if (lctx == NULL || lctx->logconfig == NULL)
+ return (ISC_FALSE);
+
+ return (ISC_TF(level <= lctx->logconfig->highest_level ||
+ (lctx->logconfig->dynamic &&
+ level <= lctx->debug_level)));
+}
+
+static void
+isc_log_doit(isc_log_t *lctx, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level, isc_boolean_t write_once,
+ isc_msgcat_t *msgcat, int msgset, int msg,
+ const char *format, va_list args)
+{
+ int syslog_level;
+ char time_string[64];
+ char level_string[24];
+ size_t octets;
+ const char *iformat;
+ struct stat statbuf;
+ isc_boolean_t matched = ISC_FALSE;
+ isc_boolean_t printtime, printtag;
+ isc_boolean_t printcategory, printmodule, printlevel;
+ isc_logconfig_t *lcfg;
+ isc_logchannel_t *channel;
+ isc_logchannellist_t *category_channels;
+ isc_result_t result;
+
+ REQUIRE(lctx == NULL || VALID_CONTEXT(lctx));
+ REQUIRE(category != NULL);
+ REQUIRE(module != NULL);
+ REQUIRE(level != ISC_LOG_DYNAMIC);
+ REQUIRE(format != NULL);
+
+ /*
+ * Programs can use libraries that use this logging code without
+ * wanting to do any logging, thus the log context is allowed to
+ * be non-existent.
+ */
+ if (lctx == NULL)
+ return;
+
+ REQUIRE(category->id < lctx->category_count);
+ REQUIRE(module->id < lctx->module_count);
+
+ if (! isc_log_wouldlog(lctx, level))
+ return;
+
+ if (msgcat != NULL)
+ iformat = isc_msgcat_get(msgcat, msgset, msg, format);
+ else
+ iformat = format;
+
+ time_string[0] = '\0';
+ level_string[0] = '\0';
+
+ LOCK(&lctx->lock);
+
+ lctx->buffer[0] = '\0';
+
+ lcfg = lctx->logconfig;
+
+ category_channels = ISC_LIST_HEAD(lcfg->channellists[category->id]);
+
+ /*
+ * XXXDCL add duplicate filtering? (To not write multiple times to
+ * the same source via various channels).
+ */
+ do {
+ /*
+ * If the channel list end was reached and a match was made,
+ * everything is finished.
+ */
+ if (category_channels == NULL && matched)
+ break;
+
+ if (category_channels == NULL && ! matched &&
+ category_channels != ISC_LIST_HEAD(lcfg->channellists[0]))
+ /*
+ * No category/module pair was explicitly configured.
+ * Try the category named "default".
+ */
+ category_channels =
+ ISC_LIST_HEAD(lcfg->channellists[0]);
+
+ if (category_channels == NULL && ! matched)
+ /*
+ * No matching module was explicitly configured
+ * for the category named "default". Use the internal
+ * default channel.
+ */
+ category_channels = &default_channel;
+
+ if (category_channels->module != NULL &&
+ category_channels->module != module) {
+ category_channels = ISC_LIST_NEXT(category_channels,
+ link);
+ continue;
+ }
+
+ matched = ISC_TRUE;
+
+ channel = category_channels->channel;
+ category_channels = ISC_LIST_NEXT(category_channels, link);
+
+ if (((channel->flags & ISC_LOG_DEBUGONLY) != 0) &&
+ lctx->debug_level == 0)
+ continue;
+
+ if (channel->level == ISC_LOG_DYNAMIC) {
+ if (lctx->debug_level < level)
+ continue;
+ } else if (channel->level < level)
+ continue;
+
+ if ((channel->flags & ISC_LOG_PRINTTIME) != 0 &&
+ time_string[0] == '\0') {
+ isc_time_t isctime;
+
+ TIME_NOW(&isctime);
+ isc_time_formattimestamp(&isctime, time_string,
+ sizeof(time_string));
+ }
+
+ if ((channel->flags & ISC_LOG_PRINTLEVEL) != 0 &&
+ level_string[0] == '\0') {
+ if (level < ISC_LOG_CRITICAL)
+ snprintf(level_string, sizeof(level_string),
+ "%s %d: ",
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_LOG,
+ ISC_MSG_LEVEL,
+ "level"),
+ level);
+ else if (level > ISC_LOG_DYNAMIC)
+ snprintf(level_string, sizeof(level_string),
+ "%s %d: ", log_level_strings[0],
+ level);
+ else
+ snprintf(level_string, sizeof(level_string),
+ "%s: ", log_level_strings[-level]);
+ }
+
+ /*
+ * Only format the message once.
+ */
+ if (lctx->buffer[0] == '\0') {
+ (void)vsnprintf(lctx->buffer, sizeof(lctx->buffer),
+ iformat, args);
+
+ /*
+ * Check for duplicates.
+ */
+ if (write_once) {
+ isc_logmessage_t *message, *new;
+ isc_time_t oldest;
+ isc_interval_t interval;
+
+ isc_interval_set(&interval,
+ lcfg->duplicate_interval, 0);
+
+ /*
+ * 'oldest' is the age of the oldest messages
+ * which fall within the duplicate_interval
+ * range.
+ */
+ TIME_NOW(&oldest);
+ if (isc_time_subtract(&oldest, &interval, &oldest)
+ != ISC_R_SUCCESS)
+ /*
+ * Can't effectively do the checking
+ * without having a valid time.
+ */
+ message = NULL;
+ else
+ message =ISC_LIST_HEAD(lctx->messages);
+
+ while (message != NULL) {
+ if (isc_time_compare(&message->time,
+ &oldest) < 0) {
+ /*
+ * This message is older
+ * than the duplicate_interval,
+ * so it should be dropped from
+ * the history.
+ *
+ * Setting the interval to be
+ * to be longer will obviously
+ * not cause the expired
+ * message to spring back into
+ * existence.
+ */
+ new = ISC_LIST_NEXT(message,
+ link);
+
+ ISC_LIST_UNLINK(lctx->messages,
+ message, link);
+
+ isc_mem_put(lctx->mctx,
+ message,
+ sizeof(*message) + 1 +
+ strlen(message->text));
+
+ message = new;
+ continue;
+ }
+
+ /*
+ * This message is in the duplicate
+ * filtering interval ...
+ */
+ if (strcmp(lctx->buffer, message->text)
+ == 0) {
+ /*
+ * ... and it is a duplicate.
+ * Unlock the mutex and
+ * get the hell out of Dodge.
+ */
+ UNLOCK(&lctx->lock);
+ return;
+ }
+
+ message = ISC_LIST_NEXT(message, link);
+ }
+
+ /*
+ * It wasn't in the duplicate interval,
+ * so add it to the message list.
+ */
+ octets = strlen(lctx->buffer) + 1;
+ new = isc_mem_get(lctx->mctx,
+ sizeof(isc_logmessage_t) +
+ octets);
+ if (new != NULL) {
+ /*
+ * Put the text immediately after
+ * the struct. The strcpy is safe.
+ */
+ new->text = (char *)(new + 1);
+ strlcpy(new->text, lctx->buffer, octets);
+
+ TIME_NOW(&new->time);
+
+ ISC_LIST_APPEND(lctx->messages,
+ new, link);
+ }
+ }
+ }
+
+ printtime = ISC_TF((channel->flags & ISC_LOG_PRINTTIME)
+ != 0);
+ printtag = ISC_TF((channel->flags & ISC_LOG_PRINTTAG)
+ != 0 && lcfg->tag != NULL);
+ printcategory = ISC_TF((channel->flags & ISC_LOG_PRINTCATEGORY)
+ != 0);
+ printmodule = ISC_TF((channel->flags & ISC_LOG_PRINTMODULE)
+ != 0);
+ printlevel = ISC_TF((channel->flags & ISC_LOG_PRINTLEVEL)
+ != 0);
+
+ switch (channel->type) {
+ case ISC_LOG_TOFILE:
+ if (FILE_MAXREACHED(channel)) {
+ /*
+ * If the file can be rolled, OR
+ * If the file no longer exists, OR
+ * If the file is less than the maximum size,
+ * (such as if it had been renamed and
+ * a new one touched, or it was truncated
+ * in place)
+ * ... then close it to trigger reopening.
+ */
+ if (FILE_VERSIONS(channel) !=
+ ISC_LOG_ROLLNEVER ||
+ (stat(FILE_NAME(channel), &statbuf) != 0 &&
+ errno == ENOENT) ||
+ statbuf.st_size < FILE_MAXSIZE(channel)) {
+ (void)fclose(FILE_STREAM(channel));
+ FILE_STREAM(channel) = NULL;
+ FILE_MAXREACHED(channel) = ISC_FALSE;
+ } else
+ /*
+ * Eh, skip it.
+ */
+ break;
+ }
+
+ if (FILE_STREAM(channel) == NULL) {
+ result = isc_log_open(channel);
+ if (result != ISC_R_SUCCESS &&
+ result != ISC_R_MAXSIZE &&
+ (channel->flags & ISC_LOG_OPENERR) == 0) {
+ syslog(LOG_ERR,
+ "isc_log_open '%s' failed: %s",
+ FILE_NAME(channel),
+ isc_result_totext(result));
+ channel->flags |= ISC_LOG_OPENERR;
+ }
+ if (result != ISC_R_SUCCESS)
+ break;
+ channel->flags &= ~ISC_LOG_OPENERR;
+ }
+ /* FALLTHROUGH */
+
+ case ISC_LOG_TOFILEDESC:
+ fprintf(FILE_STREAM(channel), "%s%s%s%s%s%s%s%s%s%s\n",
+ printtime ? time_string : "",
+ printtime ? " " : "",
+ printtag ? lcfg->tag : "",
+ printtag ? ": " : "",
+ printcategory ? category->name : "",
+ printcategory ? ": " : "",
+ printmodule ? (module != NULL ? module->name
+ : "no_module")
+ : "",
+ printmodule ? ": " : "",
+ printlevel ? level_string : "",
+ lctx->buffer);
+
+ fflush(FILE_STREAM(channel));
+
+ /*
+ * If the file now exceeds its maximum size
+ * threshold, note it so that it will not be logged
+ * to any more.
+ */
+ if (FILE_MAXSIZE(channel) > 0) {
+ INSIST(channel->type == ISC_LOG_TOFILE);
+
+ /* XXXDCL NT fstat/fileno */
+ /* XXXDCL complain if fstat fails? */
+ if (fstat(fileno(FILE_STREAM(channel)),
+ &statbuf) >= 0 &&
+ statbuf.st_size > FILE_MAXSIZE(channel))
+ FILE_MAXREACHED(channel) = ISC_TRUE;
+ }
+
+ break;
+
+ case ISC_LOG_TOSYSLOG:
+ if (level > 0)
+ syslog_level = LOG_DEBUG;
+ else if (level < ISC_LOG_CRITICAL)
+ syslog_level = LOG_CRIT;
+ else
+ syslog_level = syslog_map[-level];
+
+ (void)syslog(FACILITY(channel) | syslog_level,
+ "%s%s%s%s%s%s%s%s%s%s",
+ printtime ? time_string : "",
+ printtime ? " " : "",
+ printtag ? lcfg->tag : "",
+ printtag ? ": " : "",
+ printcategory ? category->name : "",
+ printcategory ? ": " : "",
+ printmodule ? (module != NULL ? module->name
+ : "no_module")
+ : "",
+ printmodule ? ": " : "",
+ printlevel ? level_string : "",
+ lctx->buffer);
+ break;
+
+ case ISC_LOG_TONULL:
+ break;
+
+ }
+
+ } while (1);
+
+ UNLOCK(&lctx->lock);
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/netaddr.c b/sebhbsd/freebsd/contrib/ntp/lib/isc/netaddr.c
new file mode 100644
index 0000000..e01ac86
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/netaddr.c
@@ -0,0 +1,437 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (C) 2004, 2005, 2007, 2010-2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include <isc/buffer.h>
+#include <isc/msgs.h>
+#include <isc/net.h>
+#include <isc/netaddr.h>
+#include <isc/print.h>
+#include <isc/sockaddr.h>
+#include <isc/string.h>
+#include <isc/util.h>
+#include "ntp_stdlib.h" /* NTP change for strlcpy, strlcat */
+
+isc_boolean_t
+isc_netaddr_equal(const isc_netaddr_t *a, const isc_netaddr_t *b) {
+ REQUIRE(a != NULL && b != NULL);
+
+ if (a->family != b->family)
+ return (ISC_FALSE);
+
+ if (a->zone != b->zone)
+ return (ISC_FALSE);
+
+ switch (a->family) {
+ case AF_INET:
+ if (a->type.in.s_addr != b->type.in.s_addr)
+ return (ISC_FALSE);
+ break;
+ case AF_INET6:
+ if (memcmp(&a->type.in6, &b->type.in6,
+ sizeof(a->type.in6)) != 0 ||
+ a->zone != b->zone)
+ return (ISC_FALSE);
+ break;
+#ifdef ISC_PLATFORM_HAVESYSUNH
+ case AF_UNIX:
+ if (strcmp(a->type.un, b->type.un) != 0)
+ return (ISC_FALSE);
+ break;
+#endif
+ default:
+ return (ISC_FALSE);
+ }
+ return (ISC_TRUE);
+}
+
+isc_boolean_t
+isc_netaddr_eqprefix(const isc_netaddr_t *a, const isc_netaddr_t *b,
+ unsigned int prefixlen)
+{
+ const unsigned char *pa = NULL, *pb = NULL;
+ unsigned int ipabytes = 0; /* Length of whole IP address in bytes */
+ unsigned int nbytes; /* Number of significant whole bytes */
+ unsigned int nbits; /* Number of significant leftover bits */
+
+ REQUIRE(a != NULL && b != NULL);
+
+ if (a->family != b->family)
+ return (ISC_FALSE);
+
+ if (a->zone != b->zone && b->zone != 0)
+ return (ISC_FALSE);
+
+ switch (a->family) {
+ case AF_INET:
+ pa = (const unsigned char *) &a->type.in;
+ pb = (const unsigned char *) &b->type.in;
+ ipabytes = 4;
+ break;
+ case AF_INET6:
+ pa = (const unsigned char *) &a->type.in6;
+ pb = (const unsigned char *) &b->type.in6;
+ ipabytes = 16;
+ break;
+ default:
+ return (ISC_FALSE);
+ }
+
+ /*
+ * Don't crash if we get a pattern like 10.0.0.1/9999999.
+ */
+ if (prefixlen > ipabytes * 8)
+ prefixlen = ipabytes * 8;
+
+ nbytes = prefixlen / 8;
+ nbits = prefixlen % 8;
+
+ if (nbytes > 0) {
+ if (memcmp(pa, pb, nbytes) != 0)
+ return (ISC_FALSE);
+ }
+ if (nbits > 0) {
+ unsigned int bytea, byteb, mask;
+ INSIST(nbytes < ipabytes);
+ INSIST(nbits < 8);
+ bytea = pa[nbytes];
+ byteb = pb[nbytes];
+ mask = (0xFF << (8-nbits)) & 0xFF;
+ if ((bytea & mask) != (byteb & mask))
+ return (ISC_FALSE);
+ }
+ return (ISC_TRUE);
+}
+
+isc_result_t
+isc_netaddr_totext(const isc_netaddr_t *netaddr, isc_buffer_t *target) {
+ char abuf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255")];
+ char zbuf[sizeof("%4294967295")];
+ unsigned int alen;
+ int zlen;
+ const char *r;
+ const void *type;
+
+ REQUIRE(netaddr != NULL);
+
+ switch (netaddr->family) {
+ case AF_INET:
+ type = &netaddr->type.in;
+ break;
+ case AF_INET6:
+ type = &netaddr->type.in6;
+ break;
+#ifdef ISC_PLATFORM_HAVESYSUNH
+ case AF_UNIX:
+ alen = strlen(netaddr->type.un);
+ if (alen > isc_buffer_availablelength(target))
+ return (ISC_R_NOSPACE);
+ isc_buffer_putmem(target,
+ (const unsigned char *)(netaddr->type.un),
+ alen);
+ return (ISC_R_SUCCESS);
+#endif
+ default:
+ return (ISC_R_FAILURE);
+ }
+ r = inet_ntop(netaddr->family, type, abuf, sizeof(abuf));
+ if (r == NULL)
+ return (ISC_R_FAILURE);
+
+ alen = (unsigned int)strlen(abuf); /* no overflow possible */
+ INSIST(alen < sizeof(abuf));
+
+ zlen = 0;
+ if (netaddr->family == AF_INET6 && netaddr->zone != 0) {
+ zlen = snprintf(zbuf, sizeof(zbuf), "%%%u", netaddr->zone);
+ if (zlen < 0)
+ return (ISC_R_FAILURE);
+ INSIST((unsigned int)zlen < sizeof(zbuf));
+ }
+
+ if (alen + zlen > isc_buffer_availablelength(target))
+ return (ISC_R_NOSPACE);
+
+ isc_buffer_putmem(target, (unsigned char *)abuf, alen);
+ isc_buffer_putmem(target, (unsigned char *)zbuf, zlen);
+
+ return (ISC_R_SUCCESS);
+}
+
+void
+isc_netaddr_format(const isc_netaddr_t *na, char *array, unsigned int size) {
+ isc_result_t result;
+ isc_buffer_t buf;
+
+ isc_buffer_init(&buf, array, size);
+ result = isc_netaddr_totext(na, &buf);
+
+ if (size == 0)
+ return;
+
+ /*
+ * Null terminate.
+ */
+ if (result == ISC_R_SUCCESS) {
+ if (isc_buffer_availablelength(&buf) >= 1)
+ isc_buffer_putuint8(&buf, 0);
+ else
+ result = ISC_R_NOSPACE;
+ }
+
+ if (result != ISC_R_SUCCESS) {
+ snprintf(array, size,
+ "<%s %u>",
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_NETADDR,
+ ISC_MSG_UNKNOWNADDR,
+ "unknown address, family"),
+ na->family);
+ array[size - 1] = '\0';
+ }
+}
+
+
+isc_result_t
+isc_netaddr_prefixok(const isc_netaddr_t *na, unsigned int prefixlen) {
+ static const unsigned char zeros[16] = { 0 };
+ unsigned int nbits, nbytes, ipbytes = 0;
+ const unsigned char *p;
+
+ switch (na->family) {
+ case AF_INET:
+ p = (const unsigned char *) &na->type.in;
+ ipbytes = 4;
+ if (prefixlen > 32)
+ return (ISC_R_RANGE);
+ break;
+ case AF_INET6:
+ p = (const unsigned char *) &na->type.in6;
+ ipbytes = 16;
+ if (prefixlen > 128)
+ return (ISC_R_RANGE);
+ break;
+ default:
+ return (ISC_R_NOTIMPLEMENTED);
+ }
+ nbytes = prefixlen / 8;
+ nbits = prefixlen % 8;
+ if (nbits != 0) {
+ if ((p[nbytes] & (0xff>>nbits)) != 0U)
+ return (ISC_R_FAILURE);
+ nbytes++;
+ }
+ if (memcmp(p + nbytes, zeros, ipbytes - nbytes) != 0)
+ return (ISC_R_FAILURE);
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_netaddr_masktoprefixlen(const isc_netaddr_t *s, unsigned int *lenp) {
+ unsigned int nbits = 0, nbytes = 0, ipbytes = 0, i;
+ const unsigned char *p;
+
+ switch (s->family) {
+ case AF_INET:
+ p = (const unsigned char *) &s->type.in;
+ ipbytes = 4;
+ break;
+ case AF_INET6:
+ p = (const unsigned char *) &s->type.in6;
+ ipbytes = 16;
+ break;
+ default:
+ return (ISC_R_NOTIMPLEMENTED);
+ }
+ for (i = 0; i < ipbytes; i++) {
+ if (p[i] != 0xFF)
+ break;
+ }
+ nbytes = i;
+ if (i < ipbytes) {
+ unsigned int c = p[nbytes];
+ while ((c & 0x80) != 0 && nbits < 8) {
+ c <<= 1; nbits++;
+ }
+ if ((c & 0xFF) != 0)
+ return (ISC_R_MASKNONCONTIG);
+ i++;
+ }
+ for (; i < ipbytes; i++) {
+ if (p[i] != 0)
+ return (ISC_R_MASKNONCONTIG);
+ }
+ *lenp = nbytes * 8 + nbits;
+ return (ISC_R_SUCCESS);
+}
+
+void
+isc_netaddr_fromin(isc_netaddr_t *netaddr, const struct in_addr *ina) {
+ memset(netaddr, 0, sizeof(*netaddr));
+ netaddr->family = AF_INET;
+ netaddr->type.in = *ina;
+}
+
+void
+isc_netaddr_fromin6(isc_netaddr_t *netaddr, const struct in6_addr *ina6) {
+ memset(netaddr, 0, sizeof(*netaddr));
+ netaddr->family = AF_INET6;
+ netaddr->type.in6 = *ina6;
+}
+
+isc_result_t
+isc_netaddr_frompath(isc_netaddr_t *netaddr, const char *path) {
+#ifdef ISC_PLATFORM_HAVESYSUNH
+ if (strlen(path) > sizeof(netaddr->type.un) - 1)
+ return (ISC_R_NOSPACE);
+
+ memset(netaddr, 0, sizeof(*netaddr));
+ netaddr->family = AF_UNIX;
+ strlcpy(netaddr->type.un, path, sizeof(netaddr->type.un));
+ netaddr->zone = 0;
+ return (ISC_R_SUCCESS);
+#else
+ UNUSED(netaddr);
+ UNUSED(path);
+ return (ISC_R_NOTIMPLEMENTED);
+#endif
+}
+
+
+void
+isc_netaddr_setzone(isc_netaddr_t *netaddr, isc_uint32_t zone) {
+ /* we currently only support AF_INET6. */
+ REQUIRE(netaddr->family == AF_INET6);
+
+ netaddr->zone = zone;
+}
+
+isc_uint32_t
+isc_netaddr_getzone(const isc_netaddr_t *netaddr) {
+ return (netaddr->zone);
+}
+
+void
+isc_netaddr_fromsockaddr(isc_netaddr_t *t, const isc_sockaddr_t *s) {
+ int family = s->type.sa.sa_family;
+ t->family = family;
+ switch (family) {
+ case AF_INET:
+ t->type.in = s->type.sin.sin_addr;
+ t->zone = 0;
+ break;
+ case AF_INET6:
+ memcpy(&t->type.in6, &s->type.sin6.sin6_addr, 16);
+#ifdef ISC_PLATFORM_HAVESCOPEID
+ t->zone = s->type.sin6.sin6_scope_id;
+#else
+ t->zone = 0;
+#endif
+ break;
+#ifdef ISC_PLATFORM_HAVESYSUNH
+ case AF_UNIX:
+ memcpy(t->type.un, s->type.sunix.sun_path, sizeof(t->type.un));
+ t->zone = 0;
+ break;
+#endif
+ default:
+ INSIST(0);
+ }
+}
+
+void
+isc_netaddr_any(isc_netaddr_t *netaddr) {
+ memset(netaddr, 0, sizeof(*netaddr));
+ netaddr->family = AF_INET;
+ netaddr->type.in.s_addr = INADDR_ANY;
+}
+
+void
+isc_netaddr_any6(isc_netaddr_t *netaddr) {
+ memset(netaddr, 0, sizeof(*netaddr));
+ netaddr->family = AF_INET6;
+ netaddr->type.in6 = in6addr_any;
+}
+
+isc_boolean_t
+isc_netaddr_ismulticast(isc_netaddr_t *na) {
+ switch (na->family) {
+ case AF_INET:
+ return (ISC_TF(ISC_IPADDR_ISMULTICAST(na->type.in.s_addr)));
+ case AF_INET6:
+ return (ISC_TF(IN6_IS_ADDR_MULTICAST(&na->type.in6)));
+ default:
+ return (ISC_FALSE); /* XXXMLG ? */
+ }
+}
+
+isc_boolean_t
+isc_netaddr_isexperimental(isc_netaddr_t *na) {
+ switch (na->family) {
+ case AF_INET:
+ return (ISC_TF(ISC_IPADDR_ISEXPERIMENTAL(na->type.in.s_addr)));
+ default:
+ return (ISC_FALSE); /* XXXMLG ? */
+ }
+}
+
+isc_boolean_t
+isc_netaddr_islinklocal(isc_netaddr_t *na) {
+ switch (na->family) {
+ case AF_INET:
+ return (ISC_FALSE);
+ case AF_INET6:
+ return (ISC_TF(IN6_IS_ADDR_LINKLOCAL(&na->type.in6)));
+ default:
+ return (ISC_FALSE);
+ }
+}
+
+isc_boolean_t
+isc_netaddr_issitelocal(isc_netaddr_t *na) {
+ switch (na->family) {
+ case AF_INET:
+ return (ISC_FALSE);
+ case AF_INET6:
+ return (ISC_TF(IN6_IS_ADDR_SITELOCAL(&na->type.in6)));
+ default:
+ return (ISC_FALSE);
+ }
+}
+
+void
+isc_netaddr_fromv4mapped(isc_netaddr_t *t, const isc_netaddr_t *s) {
+ isc_netaddr_t *src;
+
+ DE_CONST(s, src); /* Must come before IN6_IS_ADDR_V4MAPPED. */
+
+ REQUIRE(s->family == AF_INET6);
+ REQUIRE(IN6_IS_ADDR_V4MAPPED(&src->type.in6));
+
+ memset(t, 0, sizeof(*t));
+ t->family = AF_INET;
+ memcpy(&t->type.in, (char *)&src->type.in6 + 12, 4);
+ return;
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/nls/msgcat.c b/sebhbsd/freebsd/contrib/ntp/lib/isc/nls/msgcat.c
new file mode 100644
index 0000000..e004c50
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/nls/msgcat.c
@@ -0,0 +1,133 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: msgcat.c,v 1.18 2007/06/19 23:47:18 tbox Exp $ */
+
+/*! \file msgcat.c
+ *
+ * \author Principal Author: Bob Halley
+ */
+
+#include <config.h>
+
+#include <stddef.h>
+#include <stdlib.h>
+
+#include <isc/magic.h>
+#include <isc/msgcat.h>
+#include <isc/util.h>
+
+#ifdef HAVE_CATGETS
+#include <nl_types.h> /* Required for nl_catd. */
+#endif
+
+/*
+ * Implementation Notes:
+ *
+ * We use malloc() and free() instead of isc_mem_get() and isc_mem_put()
+ * because we don't want to require a memory context to be specified
+ * in order to use a message catalog.
+ */
+
+struct isc_msgcat {
+ unsigned int magic;
+#ifdef HAVE_CATGETS
+ nl_catd catalog;
+#endif
+};
+
+#define MSGCAT_MAGIC ISC_MAGIC('M', 'C', 'a', 't')
+#define VALID_MSGCAT(m) ISC_MAGIC_VALID(m, MSGCAT_MAGIC)
+
+void
+isc_msgcat_open(const char *name, isc_msgcat_t **msgcatp) {
+ isc_msgcat_t *msgcat;
+
+ /*
+ * Open a message catalog.
+ */
+
+ REQUIRE(name != NULL);
+ REQUIRE(msgcatp != NULL && *msgcatp == NULL);
+
+ msgcat = malloc(sizeof(*msgcat));
+ if (msgcat == NULL) {
+ *msgcatp = NULL;
+ return;
+ }
+
+#ifdef HAVE_CATGETS
+ /*
+ * We don't check if catopen() fails because we don't care.
+ * If it does fail, then when we call catgets(), it will use
+ * the default string.
+ */
+ msgcat->catalog = catopen(name, 0);
+#endif
+ msgcat->magic = MSGCAT_MAGIC;
+
+ *msgcatp = msgcat;
+}
+
+void
+isc_msgcat_close(isc_msgcat_t **msgcatp) {
+ isc_msgcat_t *msgcat;
+
+ /*
+ * Close a message catalog.
+ */
+
+ REQUIRE(msgcatp != NULL);
+ msgcat = *msgcatp;
+ REQUIRE(VALID_MSGCAT(msgcat) || msgcat == NULL);
+
+ if (msgcat != NULL) {
+#ifdef HAVE_CATGETS
+ if (msgcat->catalog != (nl_catd)(-1))
+ (void)catclose(msgcat->catalog);
+#endif
+ msgcat->magic = 0;
+ free(msgcat);
+ }
+
+ *msgcatp = NULL;
+}
+
+const char *
+isc_msgcat_get(isc_msgcat_t *msgcat, int set, int message,
+ const char *default_text)
+{
+ /*
+ * Get message 'message' from message set 'set' in 'msgcat'. If it
+ * is not available, use 'default'.
+ */
+
+ REQUIRE(VALID_MSGCAT(msgcat) || msgcat == NULL);
+ REQUIRE(set > 0);
+ REQUIRE(message > 0);
+ REQUIRE(default_text != NULL);
+
+#ifdef HAVE_CATGETS
+ if (msgcat == NULL)
+ return (default_text);
+ return (catgets(msgcat->catalog, set, message, default_text));
+#else
+ return (default_text);
+#endif
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/pthreads/include/isc/mutex.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/pthreads/include/isc/mutex.h
new file mode 100644
index 0000000..dd7d326
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/pthreads/include/isc/mutex.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: mutex.h,v 1.30 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_MUTEX_H
+#define ISC_MUTEX_H 1
+
+/*! \file */
+
+#include <pthread.h>
+#include <stdio.h>
+
+#include <isc/lang.h>
+#include <isc/result.h> /* for ISC_R_ codes */
+
+ISC_LANG_BEGINDECLS
+
+/*!
+ * Supply mutex attributes that enable deadlock detection
+ * (helpful when debugging). This is system dependent and
+ * currently only supported on NetBSD.
+ */
+#if ISC_MUTEX_DEBUG && defined(__NetBSD__) && defined(PTHREAD_MUTEX_ERRORCHECK)
+extern pthread_mutexattr_t isc__mutex_attrs;
+#define ISC__MUTEX_ATTRS &isc__mutex_attrs
+#else
+#define ISC__MUTEX_ATTRS NULL
+#endif
+
+/* XXX We could do fancier error handling... */
+
+/*!
+ * Define ISC_MUTEX_PROFILE to turn on profiling of mutexes by line. When
+ * enabled, isc_mutex_stats() can be used to print a table showing the
+ * number of times each type of mutex was locked and the amount of time
+ * waiting to obtain the lock.
+ */
+#ifndef ISC_MUTEX_PROFILE
+#define ISC_MUTEX_PROFILE 0
+#endif
+
+#if ISC_MUTEX_PROFILE
+typedef struct isc_mutexstats isc_mutexstats_t;
+
+typedef struct {
+ pthread_mutex_t mutex; /*%< The actual mutex. */
+ isc_mutexstats_t * stats; /*%< Mutex statistics. */
+} isc_mutex_t;
+#else
+typedef pthread_mutex_t isc_mutex_t;
+#endif
+
+
+#if ISC_MUTEX_PROFILE
+#define isc_mutex_init(mp) \
+ isc_mutex_init_profile((mp), __FILE__, __LINE__)
+#else
+#if ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK)
+#define isc_mutex_init(mp) \
+ isc_mutex_init_errcheck((mp))
+#else
+#define isc_mutex_init(mp) \
+ isc__mutex_init((mp), __FILE__, __LINE__)
+isc_result_t isc__mutex_init(isc_mutex_t *mp, const char *file, unsigned int line);
+#endif
+#endif
+
+#if ISC_MUTEX_PROFILE
+#define isc_mutex_lock(mp) \
+ isc_mutex_lock_profile((mp), __FILE__, __LINE__)
+#else
+#define isc_mutex_lock(mp) \
+ ((pthread_mutex_lock((mp)) == 0) ? \
+ ISC_R_SUCCESS : ISC_R_UNEXPECTED)
+#endif
+
+#if ISC_MUTEX_PROFILE
+#define isc_mutex_unlock(mp) \
+ isc_mutex_unlock_profile((mp), __FILE__, __LINE__)
+#else
+#define isc_mutex_unlock(mp) \
+ ((pthread_mutex_unlock((mp)) == 0) ? \
+ ISC_R_SUCCESS : ISC_R_UNEXPECTED)
+#endif
+
+#if ISC_MUTEX_PROFILE
+#define isc_mutex_trylock(mp) \
+ ((pthread_mutex_trylock((&(mp)->mutex)) == 0) ? \
+ ISC_R_SUCCESS : ISC_R_LOCKBUSY)
+#else
+#define isc_mutex_trylock(mp) \
+ ((pthread_mutex_trylock((mp)) == 0) ? \
+ ISC_R_SUCCESS : ISC_R_LOCKBUSY)
+#endif
+
+#if ISC_MUTEX_PROFILE
+#define isc_mutex_destroy(mp) \
+ ((pthread_mutex_destroy((&(mp)->mutex)) == 0) ? \
+ ISC_R_SUCCESS : ISC_R_UNEXPECTED)
+#else
+#define isc_mutex_destroy(mp) \
+ ((pthread_mutex_destroy((mp)) == 0) ? \
+ ISC_R_SUCCESS : ISC_R_UNEXPECTED)
+#endif
+
+#if ISC_MUTEX_PROFILE
+#define isc_mutex_stats(fp) isc_mutex_statsprofile(fp);
+#else
+#define isc_mutex_stats(fp)
+#endif
+
+#if ISC_MUTEX_PROFILE
+
+isc_result_t
+isc_mutex_init_profile(isc_mutex_t *mp, const char * _file, int _line);
+isc_result_t
+isc_mutex_lock_profile(isc_mutex_t *mp, const char * _file, int _line);
+isc_result_t
+isc_mutex_unlock_profile(isc_mutex_t *mp, const char * _file, int _line);
+
+void
+isc_mutex_statsprofile(FILE *fp);
+
+isc_result_t
+isc_mutex_init_errcheck(isc_mutex_t *mp);
+
+#endif /* ISC_MUTEX_PROFILE */
+
+ISC_LANG_ENDDECLS
+#endif /* ISC_MUTEX_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/pthreads/include/isc/once.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/pthreads/include/isc/once.h
new file mode 100644
index 0000000..31d76fb
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/pthreads/include/isc/once.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: once.h,v 1.13 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_ONCE_H
+#define ISC_ONCE_H 1
+
+/*! \file */
+
+#include <pthread.h>
+
+#include <isc/platform.h>
+#include <isc/result.h>
+
+typedef pthread_once_t isc_once_t;
+
+#ifdef ISC_PLATFORM_BRACEPTHREADONCEINIT
+/*!
+ * This accomodates systems that define PTHRAD_ONCE_INIT improperly.
+ */
+#define ISC_ONCE_INIT { PTHREAD_ONCE_INIT }
+#else
+/*!
+ * This is the usual case.
+ */
+#define ISC_ONCE_INIT PTHREAD_ONCE_INIT
+#endif
+
+/* XXX We could do fancier error handling... */
+
+#define isc_once_do(op, f) \
+ ((pthread_once((op), (f)) == 0) ? \
+ ISC_R_SUCCESS : ISC_R_UNEXPECTED)
+
+#endif /* ISC_ONCE_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/pthreads/mutex.c b/sebhbsd/freebsd/contrib/ntp/lib/isc/pthreads/mutex.c
new file mode 100644
index 0000000..6b49f2a
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/pthreads/mutex.c
@@ -0,0 +1,286 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (C) 2004, 2005, 2007, 2008, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000-2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: mutex.c,v 1.18 2011/01/04 23:47:14 tbox Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <time.h>
+#include <sys/time.h>
+#include <errno.h>
+
+#include <isc/mutex.h>
+#include <isc/util.h>
+#include <isc/strerror.h>
+
+#if HAVE_PTHREADS < 5 /* HP-UX 10.20 has 4, needs this */
+# define pthread_mutex_init(m, a) \
+ pthread_mutex_init(m, (a) \
+ ? *(const pthread_mutexattr_t *)(a) \
+ : pthread_mutexattr_default)
+# define PTHREAD_MUTEX_RECURSIVE MUTEX_RECURSIVE_NP
+# define pthread_mutexattr_settype pthread_mutexattr_setkind_np
+#endif
+
+#if ISC_MUTEX_PROFILE
+
+/*@{*/
+/*% Operations on timevals; adapted from FreeBSD's sys/time.h */
+#define timevalclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0)
+#define timevaladd(vvp, uvp) \
+ do { \
+ (vvp)->tv_sec += (uvp)->tv_sec; \
+ (vvp)->tv_usec += (uvp)->tv_usec; \
+ if ((vvp)->tv_usec >= 1000000) { \
+ (vvp)->tv_sec++; \
+ (vvp)->tv_usec -= 1000000; \
+ } \
+ } while (0)
+#define timevalsub(vvp, uvp) \
+ do { \
+ (vvp)->tv_sec -= (uvp)->tv_sec; \
+ (vvp)->tv_usec -= (uvp)->tv_usec; \
+ if ((vvp)->tv_usec < 0) { \
+ (vvp)->tv_sec--; \
+ (vvp)->tv_usec += 1000000; \
+ } \
+ } while (0)
+
+/*@}*/
+
+#define ISC_MUTEX_MAX_LOCKERS 32
+
+typedef struct {
+ const char * file;
+ int line;
+ unsigned count;
+ struct timeval locked_total;
+ struct timeval wait_total;
+} isc_mutexlocker_t;
+
+struct isc_mutexstats {
+ const char * file; /*%< File mutex was created in. */
+ int line; /*%< Line mutex was created on. */
+ unsigned count;
+ struct timeval lock_t;
+ struct timeval locked_total;
+ struct timeval wait_total;
+ isc_mutexlocker_t * cur_locker;
+ isc_mutexlocker_t lockers[ISC_MUTEX_MAX_LOCKERS];
+};
+
+#ifndef ISC_MUTEX_PROFTABLESIZE
+#define ISC_MUTEX_PROFTABLESIZE (1024 * 1024)
+#endif
+static isc_mutexstats_t stats[ISC_MUTEX_PROFTABLESIZE];
+static int stats_next = 0;
+static isc_boolean_t stats_init = ISC_FALSE;
+static pthread_mutex_t statslock = PTHREAD_MUTEX_INITIALIZER;
+
+
+isc_result_t
+isc_mutex_init_profile(isc_mutex_t *mp, const char *file, int line) {
+ int i, err;
+
+ err = pthread_mutex_init(&mp->mutex, NULL);
+ if (err == ENOMEM)
+ return (ISC_R_NOMEMORY);
+ if (err != 0)
+ return (ISC_R_UNEXPECTED);
+
+ RUNTIME_CHECK(pthread_mutex_lock(&statslock) == 0);
+
+ if (stats_init == ISC_FALSE)
+ stats_init = ISC_TRUE;
+
+ /*
+ * If all statistics entries have been used, give up and trigger an
+ * assertion failure. There would be no other way to deal with this
+ * because we'd like to keep record of all locks for the purpose of
+ * debugging and the number of necessary locks is unpredictable.
+ * If this failure is triggered while debugging, named should be
+ * rebuilt with an increased ISC_MUTEX_PROFTABLESIZE.
+ */
+ RUNTIME_CHECK(stats_next < ISC_MUTEX_PROFTABLESIZE);
+ mp->stats = &stats[stats_next++];
+
+ RUNTIME_CHECK(pthread_mutex_unlock(&statslock) == 0);
+
+ mp->stats->file = file;
+ mp->stats->line = line;
+ mp->stats->count = 0;
+ timevalclear(&mp->stats->locked_total);
+ timevalclear(&mp->stats->wait_total);
+ for (i = 0; i < ISC_MUTEX_MAX_LOCKERS; i++) {
+ mp->stats->lockers[i].file = NULL;
+ mp->stats->lockers[i].line = 0;
+ mp->stats->lockers[i].count = 0;
+ timevalclear(&mp->stats->lockers[i].locked_total);
+ timevalclear(&mp->stats->lockers[i].wait_total);
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_mutex_lock_profile(isc_mutex_t *mp, const char *file, int line) {
+ struct timeval prelock_t;
+ struct timeval postlock_t;
+ isc_mutexlocker_t *locker = NULL;
+ int i;
+
+ gettimeofday(&prelock_t, NULL);
+
+ if (pthread_mutex_lock(&mp->mutex) != 0)
+ return (ISC_R_UNEXPECTED);
+
+ gettimeofday(&postlock_t, NULL);
+ mp->stats->lock_t = postlock_t;
+
+ timevalsub(&postlock_t, &prelock_t);
+
+ mp->stats->count++;
+ timevaladd(&mp->stats->wait_total, &postlock_t);
+
+ for (i = 0; i < ISC_MUTEX_MAX_LOCKERS; i++) {
+ if (mp->stats->lockers[i].file == NULL) {
+ locker = &mp->stats->lockers[i];
+ locker->file = file;
+ locker->line = line;
+ break;
+ } else if (mp->stats->lockers[i].file == file &&
+ mp->stats->lockers[i].line == line) {
+ locker = &mp->stats->lockers[i];
+ break;
+ }
+ }
+
+ if (locker != NULL) {
+ locker->count++;
+ timevaladd(&locker->wait_total, &postlock_t);
+ }
+
+ mp->stats->cur_locker = locker;
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_mutex_unlock_profile(isc_mutex_t *mp, const char *file, int line) {
+ struct timeval unlock_t;
+
+ UNUSED(file);
+ UNUSED(line);
+
+ if (mp->stats->cur_locker != NULL) {
+ gettimeofday(&unlock_t, NULL);
+ timevalsub(&unlock_t, &mp->stats->lock_t);
+ timevaladd(&mp->stats->locked_total, &unlock_t);
+ timevaladd(&mp->stats->cur_locker->locked_total, &unlock_t);
+ mp->stats->cur_locker = NULL;
+ }
+
+ return ((pthread_mutex_unlock((&mp->mutex)) == 0) ? \
+ ISC_R_SUCCESS : ISC_R_UNEXPECTED);
+}
+
+
+void
+isc_mutex_statsprofile(FILE *fp) {
+ isc_mutexlocker_t *locker;
+ int i, j;
+
+ fprintf(fp, "Mutex stats (in us)\n");
+ for (i = 0; i < stats_next; i++) {
+ fprintf(fp, "%-12s %4d: %10u %lu.%06lu %lu.%06lu %5d\n",
+ stats[i].file, stats[i].line, stats[i].count,
+ stats[i].locked_total.tv_sec,
+ stats[i].locked_total.tv_usec,
+ stats[i].wait_total.tv_sec,
+ stats[i].wait_total.tv_usec,
+ i);
+ for (j = 0; j < ISC_MUTEX_MAX_LOCKERS; j++) {
+ locker = &stats[i].lockers[j];
+ if (locker->file == NULL)
+ continue;
+ fprintf(fp, " %-11s %4d: %10u %lu.%06lu %lu.%06lu %5d\n",
+ locker->file, locker->line, locker->count,
+ locker->locked_total.tv_sec,
+ locker->locked_total.tv_usec,
+ locker->wait_total.tv_sec,
+ locker->wait_total.tv_usec,
+ i);
+ }
+ }
+}
+
+#endif /* ISC_MUTEX_PROFILE */
+
+#if ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK)
+isc_result_t
+isc_mutex_init_errcheck(isc_mutex_t *mp)
+{
+ pthread_mutexattr_t attr;
+ int err;
+
+ if (pthread_mutexattr_init(&attr) != 0)
+ return (ISC_R_UNEXPECTED);
+
+ if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK) != 0) {
+ pthread_mutexattr_destroy(&attr);
+ return (ISC_R_UNEXPECTED);
+ }
+
+ err = pthread_mutex_init(mp, &attr) != 0)
+ pthread_mutexattr_destroy(&attr);
+ if (err == ENOMEM)
+ return (ISC_R_NOMEMORY);
+ return ((err == 0) ? ISC_R_SUCCESS : ISC_R_UNEXPECTED);
+}
+#endif
+
+#if ISC_MUTEX_DEBUG && defined(__NetBSD__) && defined(PTHREAD_MUTEX_ERRORCHECK)
+pthread_mutexattr_t isc__mutex_attrs = {
+ PTHREAD_MUTEX_ERRORCHECK, /* m_type */
+ 0 /* m_flags, which appears to be unused. */
+};
+#endif
+
+#if !(ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK)) && !ISC_MUTEX_PROFILE
+isc_result_t
+isc__mutex_init(isc_mutex_t *mp, const char *file, unsigned int line) {
+ char strbuf[ISC_STRERRORSIZE];
+ isc_result_t result = ISC_R_SUCCESS;
+ int err;
+
+ err = pthread_mutex_init(mp, ISC__MUTEX_ATTRS);
+ if (err == ENOMEM)
+ return (ISC_R_NOMEMORY);
+ if (err != 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(file, line, "isc_mutex_init() failed: %s",
+ strbuf);
+ result = ISC_R_UNEXPECTED;
+ }
+ return (result);
+}
+#endif
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/result.c b/sebhbsd/freebsd/contrib/ntp/lib/isc/result.c
new file mode 100644
index 0000000..27a8695
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/result.c
@@ -0,0 +1,216 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (C) 2004, 2005, 2007, 2008, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001, 2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <stddef.h>
+#include <stdlib.h>
+
+#include <isc/lib.h>
+#include <isc/msgs.h>
+#include <isc/mutex.h>
+#include <isc/once.h>
+#include <isc/resultclass.h>
+#include <isc/util.h>
+
+typedef struct resulttable {
+ unsigned int base;
+ unsigned int last;
+ const char ** text;
+ isc_msgcat_t * msgcat;
+ int set;
+ ISC_LINK(struct resulttable) link;
+} resulttable;
+
+static const char *text[ISC_R_NRESULTS] = {
+ "success", /*%< 0 */
+ "out of memory", /*%< 1 */
+ "timed out", /*%< 2 */
+ "no available threads", /*%< 3 */
+ "address not available", /*%< 4 */
+ "address in use", /*%< 5 */
+ "permission denied", /*%< 6 */
+ "no pending connections", /*%< 7 */
+ "network unreachable", /*%< 8 */
+ "host unreachable", /*%< 9 */
+ "network down", /*%< 10 */
+ "host down", /*%< 11 */
+ "connection refused", /*%< 12 */
+ "not enough free resources", /*%< 13 */
+ "end of file", /*%< 14 */
+ "socket already bound", /*%< 15 */
+ "reload", /*%< 16 */
+ "lock busy", /*%< 17 */
+ "already exists", /*%< 18 */
+ "ran out of space", /*%< 19 */
+ "operation canceled", /*%< 20 */
+ "socket is not bound", /*%< 21 */
+ "shutting down", /*%< 22 */
+ "not found", /*%< 23 */
+ "unexpected end of input", /*%< 24 */
+ "failure", /*%< 25 */
+ "I/O error", /*%< 26 */
+ "not implemented", /*%< 27 */
+ "unbalanced parentheses", /*%< 28 */
+ "no more", /*%< 29 */
+ "invalid file", /*%< 30 */
+ "bad base64 encoding", /*%< 31 */
+ "unexpected token", /*%< 32 */
+ "quota reached", /*%< 33 */
+ "unexpected error", /*%< 34 */
+ "already running", /*%< 35 */
+ "ignore", /*%< 36 */
+ "address mask not contiguous", /*%< 37 */
+ "file not found", /*%< 38 */
+ "file already exists", /*%< 39 */
+ "socket is not connected", /*%< 40 */
+ "out of range", /*%< 41 */
+ "out of entropy", /*%< 42 */
+ "invalid use of multicast address", /*%< 43 */
+ "not a file", /*%< 44 */
+ "not a directory", /*%< 45 */
+ "queue is full", /*%< 46 */
+ "address family mismatch", /*%< 47 */
+ "address family not supported", /*%< 48 */
+ "bad hex encoding", /*%< 49 */
+ "too many open files", /*%< 50 */
+ "not blocking", /*%< 51 */
+ "unbalanced quotes", /*%< 52 */
+ "operation in progress", /*%< 53 */
+ "connection reset", /*%< 54 */
+ "soft quota reached", /*%< 55 */
+ "not a valid number", /*%< 56 */
+ "disabled", /*%< 57 */
+ "max size", /*%< 58 */
+ "invalid address format", /*%< 59 */
+ "bad base32 encoding", /*%< 60 */
+ "unset", /*%< 61 */
+};
+
+#define ISC_RESULT_RESULTSET 2
+#define ISC_RESULT_UNAVAILABLESET 3
+
+static isc_once_t once = ISC_ONCE_INIT;
+static ISC_LIST(resulttable) tables;
+static isc_mutex_t lock;
+
+static isc_result_t
+register_table(unsigned int base, unsigned int nresults, const char **txt,
+ isc_msgcat_t *msgcat, int set)
+{
+ resulttable *table;
+
+ REQUIRE(base % ISC_RESULTCLASS_SIZE == 0);
+ REQUIRE(nresults <= ISC_RESULTCLASS_SIZE);
+ REQUIRE(txt != NULL);
+
+ /*
+ * We use malloc() here because we we want to be able to use
+ * isc_result_totext() even if there is no memory context.
+ */
+ table = malloc(sizeof(*table));
+ if (table == NULL)
+ return (ISC_R_NOMEMORY);
+ table->base = base;
+ table->last = base + nresults - 1;
+ table->text = txt;
+ table->msgcat = msgcat;
+ table->set = set;
+ ISC_LINK_INIT(table, link);
+
+ LOCK(&lock);
+
+ ISC_LIST_APPEND(tables, table, link);
+
+ UNLOCK(&lock);
+
+ return (ISC_R_SUCCESS);
+}
+
+static void
+initialize_action(void) {
+ isc_result_t result;
+
+ RUNTIME_CHECK(isc_mutex_init(&lock) == ISC_R_SUCCESS);
+ ISC_LIST_INIT(tables);
+
+ result = register_table(ISC_RESULTCLASS_ISC, ISC_R_NRESULTS, text,
+ isc_msgcat, ISC_RESULT_RESULTSET);
+ if (result != ISC_R_SUCCESS)
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "register_table() %s: %u",
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
+ ISC_MSG_FAILED, "failed"),
+ result);
+}
+
+static void
+initialize(void) {
+ isc_lib_initmsgcat();
+ RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
+}
+
+const char *
+isc_result_totext(isc_result_t result) {
+ resulttable *table;
+ const char *txt, *default_text;
+ int idx;
+
+ initialize();
+
+ LOCK(&lock);
+
+ txt = NULL;
+ for (table = ISC_LIST_HEAD(tables);
+ table != NULL;
+ table = ISC_LIST_NEXT(table, link)) {
+ if (result >= table->base && result <= table->last) {
+ idx = (int)(result - table->base);
+ default_text = table->text[idx];
+ /*
+ * Note: we use 'idx + 1' as the message number
+ * instead of idx because isc_msgcat_get() requires
+ * the message number to be > 0.
+ */
+ txt = isc_msgcat_get(table->msgcat, table->set,
+ idx + 1, default_text);
+ break;
+ }
+ }
+ if (txt == NULL)
+ txt = isc_msgcat_get(isc_msgcat, ISC_RESULT_UNAVAILABLESET,
+ 1, "(result code text not available)");
+
+ UNLOCK(&lock);
+
+ return (txt);
+}
+
+isc_result_t
+isc_result_register(unsigned int base, unsigned int nresults,
+ const char **txt, isc_msgcat_t *msgcat, int set)
+{
+ initialize();
+
+ return (register_table(base, nresults, txt, msgcat, set));
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/sha1.c b/sebhbsd/freebsd/contrib/ntp/lib/isc/sha1.c
new file mode 100644
index 0000000..486a2a8
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/sha1.c
@@ -0,0 +1,356 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (C) 2004, 2005, 2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+/* $NetBSD: sha1.c,v 1.5 2000/01/22 22:19:14 mycroft Exp $ */
+/* $OpenBSD: sha1.c,v 1.9 1997/07/23 21:12:32 kstailey Exp $ */
+
+/*! \file
+ * SHA-1 in C
+ * \author By Steve Reid <steve@edmweb.com>
+ * 100% Public Domain
+ * \verbatim
+ * Test Vectors (from FIPS PUB 180-1)
+ * "abc"
+ * A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
+ * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+ * 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
+ * A million repetitions of "a"
+ * 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
+ * \endverbatim
+ */
+
+#include "config.h"
+
+#include <isc/assertions.h>
+#include <isc/platform.h>
+#include <isc/sha1.h>
+#include <isc/string.h>
+#include <isc/types.h>
+#include <isc/util.h>
+
+#ifdef ISC_PLATFORM_OPENSSLHASH
+
+void
+isc_sha1_init(isc_sha1_t *context)
+{
+ INSIST(context != NULL);
+
+ EVP_DigestInit(context, EVP_sha1());
+}
+
+void
+isc_sha1_invalidate(isc_sha1_t *context) {
+ EVP_MD_CTX_cleanup(context);
+}
+
+void
+isc_sha1_update(isc_sha1_t *context, const unsigned char *data,
+ unsigned int len)
+{
+ INSIST(context != 0);
+ INSIST(data != 0);
+
+ EVP_DigestUpdate(context, (const void *) data, (size_t) len);
+}
+
+void
+isc_sha1_final(isc_sha1_t *context, unsigned char *digest) {
+ INSIST(digest != 0);
+ INSIST(context != 0);
+
+ EVP_DigestFinal(context, digest, NULL);
+}
+
+#else
+
+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
+
+/*@{*/
+/*!
+ * blk0() and blk() perform the initial expand.
+ * I got the idea of expanding during the round function from SSLeay
+ */
+#if !defined(WORDS_BIGENDIAN)
+# define blk0(i) \
+ (block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) \
+ | (rol(block->l[i], 8) & 0x00FF00FF))
+#else
+# define blk0(i) block->l[i]
+#endif
+#define blk(i) \
+ (block->l[i & 15] = rol(block->l[(i + 13) & 15] \
+ ^ block->l[(i + 8) & 15] \
+ ^ block->l[(i + 2) & 15] \
+ ^ block->l[i & 15], 1))
+
+/*@}*/
+/*@{*/
+/*!
+ * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1
+ */
+#define R0(v,w,x,y,z,i) \
+ z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \
+ w = rol(w, 30);
+#define R1(v,w,x,y,z,i) \
+ z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \
+ w = rol(w, 30);
+#define R2(v,w,x,y,z,i) \
+ z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); \
+ w = rol(w, 30);
+#define R3(v,w,x,y,z,i) \
+ z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \
+ w = rol(w, 30);
+#define R4(v,w,x,y,z,i) \
+ z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \
+ w = rol(w, 30);
+
+/*@}*/
+
+typedef union {
+ unsigned char c[64];
+ unsigned int l[16];
+} CHAR64LONG16;
+
+#ifdef __sparc_v9__
+static void do_R01(isc_uint32_t *a, isc_uint32_t *b, isc_uint32_t *c,
+ isc_uint32_t *d, isc_uint32_t *e, CHAR64LONG16 *);
+static void do_R2(isc_uint32_t *a, isc_uint32_t *b, isc_uint32_t *c,
+ isc_uint32_t *d, isc_uint32_t *e, CHAR64LONG16 *);
+static void do_R3(isc_uint32_t *a, isc_uint32_t *b, isc_uint32_t *c,
+ isc_uint32_t *d, isc_uint32_t *e, CHAR64LONG16 *);
+static void do_R4(isc_uint32_t *a, isc_uint32_t *b, isc_uint32_t *c,
+ isc_uint32_t *d, isc_uint32_t *e, CHAR64LONG16 *);
+
+#define nR0(v,w,x,y,z,i) R0(*v,*w,*x,*y,*z,i)
+#define nR1(v,w,x,y,z,i) R1(*v,*w,*x,*y,*z,i)
+#define nR2(v,w,x,y,z,i) R2(*v,*w,*x,*y,*z,i)
+#define nR3(v,w,x,y,z,i) R3(*v,*w,*x,*y,*z,i)
+#define nR4(v,w,x,y,z,i) R4(*v,*w,*x,*y,*z,i)
+
+static void
+do_R01(isc_uint32_t *a, isc_uint32_t *b, isc_uint32_t *c, isc_uint32_t *d,
+ isc_uint32_t *e, CHAR64LONG16 *block)
+{
+ nR0(a,b,c,d,e, 0); nR0(e,a,b,c,d, 1); nR0(d,e,a,b,c, 2);
+ nR0(c,d,e,a,b, 3); nR0(b,c,d,e,a, 4); nR0(a,b,c,d,e, 5);
+ nR0(e,a,b,c,d, 6); nR0(d,e,a,b,c, 7); nR0(c,d,e,a,b, 8);
+ nR0(b,c,d,e,a, 9); nR0(a,b,c,d,e,10); nR0(e,a,b,c,d,11);
+ nR0(d,e,a,b,c,12); nR0(c,d,e,a,b,13); nR0(b,c,d,e,a,14);
+ nR0(a,b,c,d,e,15); nR1(e,a,b,c,d,16); nR1(d,e,a,b,c,17);
+ nR1(c,d,e,a,b,18); nR1(b,c,d,e,a,19);
+}
+
+static void
+do_R2(isc_uint32_t *a, isc_uint32_t *b, isc_uint32_t *c, isc_uint32_t *d,
+ isc_uint32_t *e, CHAR64LONG16 *block)
+{
+ nR2(a,b,c,d,e,20); nR2(e,a,b,c,d,21); nR2(d,e,a,b,c,22);
+ nR2(c,d,e,a,b,23); nR2(b,c,d,e,a,24); nR2(a,b,c,d,e,25);
+ nR2(e,a,b,c,d,26); nR2(d,e,a,b,c,27); nR2(c,d,e,a,b,28);
+ nR2(b,c,d,e,a,29); nR2(a,b,c,d,e,30); nR2(e,a,b,c,d,31);
+ nR2(d,e,a,b,c,32); nR2(c,d,e,a,b,33); nR2(b,c,d,e,a,34);
+ nR2(a,b,c,d,e,35); nR2(e,a,b,c,d,36); nR2(d,e,a,b,c,37);
+ nR2(c,d,e,a,b,38); nR2(b,c,d,e,a,39);
+}
+
+static void
+do_R3(isc_uint32_t *a, isc_uint32_t *b, isc_uint32_t *c, isc_uint32_t *d,
+ isc_uint32_t *e, CHAR64LONG16 *block)
+{
+ nR3(a,b,c,d,e,40); nR3(e,a,b,c,d,41); nR3(d,e,a,b,c,42);
+ nR3(c,d,e,a,b,43); nR3(b,c,d,e,a,44); nR3(a,b,c,d,e,45);
+ nR3(e,a,b,c,d,46); nR3(d,e,a,b,c,47); nR3(c,d,e,a,b,48);
+ nR3(b,c,d,e,a,49); nR3(a,b,c,d,e,50); nR3(e,a,b,c,d,51);
+ nR3(d,e,a,b,c,52); nR3(c,d,e,a,b,53); nR3(b,c,d,e,a,54);
+ nR3(a,b,c,d,e,55); nR3(e,a,b,c,d,56); nR3(d,e,a,b,c,57);
+ nR3(c,d,e,a,b,58); nR3(b,c,d,e,a,59);
+}
+
+static void
+do_R4(isc_uint32_t *a, isc_uint32_t *b, isc_uint32_t *c, isc_uint32_t *d,
+ isc_uint32_t *e, CHAR64LONG16 *block)
+{
+ nR4(a,b,c,d,e,60); nR4(e,a,b,c,d,61); nR4(d,e,a,b,c,62);
+ nR4(c,d,e,a,b,63); nR4(b,c,d,e,a,64); nR4(a,b,c,d,e,65);
+ nR4(e,a,b,c,d,66); nR4(d,e,a,b,c,67); nR4(c,d,e,a,b,68);
+ nR4(b,c,d,e,a,69); nR4(a,b,c,d,e,70); nR4(e,a,b,c,d,71);
+ nR4(d,e,a,b,c,72); nR4(c,d,e,a,b,73); nR4(b,c,d,e,a,74);
+ nR4(a,b,c,d,e,75); nR4(e,a,b,c,d,76); nR4(d,e,a,b,c,77);
+ nR4(c,d,e,a,b,78); nR4(b,c,d,e,a,79);
+}
+#endif
+
+/*!
+ * Hash a single 512-bit block. This is the core of the algorithm.
+ */
+static void
+transform(isc_uint32_t state[5], const unsigned char buffer[64]) {
+ isc_uint32_t a, b, c, d, e;
+ CHAR64LONG16 *block;
+ CHAR64LONG16 workspace;
+
+ INSIST(buffer != NULL);
+ INSIST(state != NULL);
+
+ block = &workspace;
+ (void)memcpy(block, buffer, 64);
+
+ /* Copy context->state[] to working vars */
+ a = state[0];
+ b = state[1];
+ c = state[2];
+ d = state[3];
+ e = state[4];
+
+#ifdef __sparc_v9__
+ do_R01(&a, &b, &c, &d, &e, block);
+ do_R2(&a, &b, &c, &d, &e, block);
+ do_R3(&a, &b, &c, &d, &e, block);
+ do_R4(&a, &b, &c, &d, &e, block);
+#else
+ /* 4 rounds of 20 operations each. Loop unrolled. */
+ R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
+ R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
+ R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
+ R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
+ R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
+ R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
+ R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
+ R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
+ R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
+ R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
+ R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
+ R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
+ R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
+ R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
+ R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
+ R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
+ R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
+ R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
+ R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
+ R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
+#endif
+
+ /* Add the working vars back into context.state[] */
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+ state[4] += e;
+
+ /* Wipe variables */
+ a = b = c = d = e = 0;
+ /* Avoid compiler warnings */
+ POST(a); POST(b); POST(c); POST(d); POST(e);
+}
+
+
+/*!
+ * isc_sha1_init - Initialize new context
+ */
+void
+isc_sha1_init(isc_sha1_t *context)
+{
+ INSIST(context != NULL);
+
+ /* SHA1 initialization constants */
+ context->state[0] = 0x67452301;
+ context->state[1] = 0xEFCDAB89;
+ context->state[2] = 0x98BADCFE;
+ context->state[3] = 0x10325476;
+ context->state[4] = 0xC3D2E1F0;
+ context->count[0] = 0;
+ context->count[1] = 0;
+}
+
+void
+isc_sha1_invalidate(isc_sha1_t *context) {
+ memset(context, 0, sizeof(isc_sha1_t));
+}
+
+/*!
+ * Run your data through this.
+ */
+void
+isc_sha1_update(isc_sha1_t *context, const unsigned char *data,
+ unsigned int len)
+{
+ unsigned int i, j;
+
+ INSIST(context != 0);
+ INSIST(data != 0);
+
+ j = context->count[0];
+ if ((context->count[0] += len << 3) < j)
+ context->count[1] += (len >> 29) + 1;
+ j = (j >> 3) & 63;
+ if ((j + len) > 63) {
+ (void)memcpy(&context->buffer[j], data, (i = 64 - j));
+ transform(context->state, context->buffer);
+ for (; i + 63 < len; i += 64)
+ transform(context->state, &data[i]);
+ j = 0;
+ } else {
+ i = 0;
+ }
+
+ (void)memcpy(&context->buffer[j], &data[i], len - i);
+}
+
+
+/*!
+ * Add padding and return the message digest.
+ */
+
+static const unsigned char final_200 = 128;
+static const unsigned char final_0 = 0;
+
+void
+isc_sha1_final(isc_sha1_t *context, unsigned char *digest) {
+ unsigned int i;
+ unsigned char finalcount[8];
+
+ INSIST(digest != 0);
+ INSIST(context != 0);
+
+ for (i = 0; i < 8; i++) {
+ /* Endian independent */
+ finalcount[i] = (unsigned char)
+ ((context->count[(i >= 4 ? 0 : 1)]
+ >> ((3 - (i & 3)) * 8)) & 255);
+ }
+
+ isc_sha1_update(context, &final_200, 1);
+ while ((context->count[0] & 504) != 448)
+ isc_sha1_update(context, &final_0, 1);
+ /* The next Update should cause a transform() */
+ isc_sha1_update(context, finalcount, 8);
+
+ if (digest) {
+ for (i = 0; i < 20; i++)
+ digest[i] = (unsigned char)
+ ((context->state[i >> 2]
+ >> ((3 - (i & 3)) * 8)) & 255);
+ }
+
+ memset(context, 0, sizeof(isc_sha1_t));
+}
+#endif
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/sockaddr.c b/sebhbsd/freebsd/contrib/ntp/lib/isc/sockaddr.c
new file mode 100644
index 0000000..9fb2415
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/sockaddr.c
@@ -0,0 +1,512 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (C) 2004-2007, 2010-2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include <isc/buffer.h>
+#include <isc/hash.h>
+#include <isc/msgs.h>
+#include <isc/netaddr.h>
+#include <isc/print.h>
+#include <isc/region.h>
+#include <isc/sockaddr.h>
+#include <isc/string.h>
+#include <isc/util.h>
+
+isc_boolean_t
+isc_sockaddr_equal(const isc_sockaddr_t *a, const isc_sockaddr_t *b) {
+ return (isc_sockaddr_compare(a, b, ISC_SOCKADDR_CMPADDR|
+ ISC_SOCKADDR_CMPPORT|
+ ISC_SOCKADDR_CMPSCOPE));
+}
+
+isc_boolean_t
+isc_sockaddr_eqaddr(const isc_sockaddr_t *a, const isc_sockaddr_t *b) {
+ return (isc_sockaddr_compare(a, b, ISC_SOCKADDR_CMPADDR|
+ ISC_SOCKADDR_CMPSCOPE));
+}
+
+isc_boolean_t
+isc_sockaddr_compare(const isc_sockaddr_t *a, const isc_sockaddr_t *b,
+ unsigned int flags)
+{
+ REQUIRE(a != NULL && b != NULL);
+
+ if (a->length != b->length)
+ return (ISC_FALSE);
+
+ /*
+ * We don't just memcmp because the sin_zero field isn't always
+ * zero.
+ */
+
+ if (a->type.sa.sa_family != b->type.sa.sa_family)
+ return (ISC_FALSE);
+ switch (a->type.sa.sa_family) {
+ case AF_INET:
+ if ((flags & ISC_SOCKADDR_CMPADDR) != 0 &&
+ memcmp(&a->type.sin.sin_addr, &b->type.sin.sin_addr,
+ sizeof(a->type.sin.sin_addr)) != 0)
+ return (ISC_FALSE);
+ if ((flags & ISC_SOCKADDR_CMPPORT) != 0 &&
+ a->type.sin.sin_port != b->type.sin.sin_port)
+ return (ISC_FALSE);
+ break;
+ case AF_INET6:
+ if ((flags & ISC_SOCKADDR_CMPADDR) != 0 &&
+ memcmp(&a->type.sin6.sin6_addr, &b->type.sin6.sin6_addr,
+ sizeof(a->type.sin6.sin6_addr)) != 0)
+ return (ISC_FALSE);
+#ifdef ISC_PLATFORM_HAVESCOPEID
+ /*
+ * If ISC_SOCKADDR_CMPSCOPEZERO is set then don't return
+ * ISC_FALSE if one of the scopes in zero.
+ */
+ if ((flags & ISC_SOCKADDR_CMPSCOPE) != 0 &&
+ a->type.sin6.sin6_scope_id != b->type.sin6.sin6_scope_id &&
+ ((flags & ISC_SOCKADDR_CMPSCOPEZERO) == 0 ||
+ (a->type.sin6.sin6_scope_id != 0 &&
+ b->type.sin6.sin6_scope_id != 0)))
+ return (ISC_FALSE);
+#endif
+ if ((flags & ISC_SOCKADDR_CMPPORT) != 0 &&
+ a->type.sin6.sin6_port != b->type.sin6.sin6_port)
+ return (ISC_FALSE);
+ break;
+ default:
+ if (memcmp(&a->type, &b->type, a->length) != 0)
+ return (ISC_FALSE);
+ }
+ return (ISC_TRUE);
+}
+
+isc_boolean_t
+isc_sockaddr_eqaddrprefix(const isc_sockaddr_t *a, const isc_sockaddr_t *b,
+ unsigned int prefixlen)
+{
+ isc_netaddr_t na, nb;
+ isc_netaddr_fromsockaddr(&na, a);
+ isc_netaddr_fromsockaddr(&nb, b);
+ return (isc_netaddr_eqprefix(&na, &nb, prefixlen));
+}
+
+isc_result_t
+isc_sockaddr_totext(const isc_sockaddr_t *sockaddr, isc_buffer_t *target) {
+ isc_result_t result;
+ isc_netaddr_t netaddr;
+ char pbuf[sizeof("65000")];
+ unsigned int plen;
+ isc_region_t avail;
+
+ REQUIRE(sockaddr != NULL);
+
+ /*
+ * Do the port first, giving us the opportunity to check for
+ * unsupported address families before calling
+ * isc_netaddr_fromsockaddr().
+ */
+ switch (sockaddr->type.sa.sa_family) {
+ case AF_INET:
+ snprintf(pbuf, sizeof(pbuf), "%u", ntohs(sockaddr->type.sin.sin_port));
+ break;
+ case AF_INET6:
+ snprintf(pbuf, sizeof(pbuf), "%u", ntohs(sockaddr->type.sin6.sin6_port));
+ break;
+#ifdef ISC_PLAFORM_HAVESYSUNH
+ case AF_UNIX:
+ plen = (unsigned int)strlen(sockaddr->type.sunix.sun_path);
+ if (plen >= isc_buffer_availablelength(target))
+ return (ISC_R_NOSPACE);
+
+ isc_buffer_putmem(target, sockaddr->type.sunix.sun_path, plen);
+
+ /*
+ * Null terminate after used region.
+ */
+ isc_buffer_availableregion(target, &avail);
+ INSIST(avail.length >= 1);
+ avail.base[0] = '\0';
+
+ return (ISC_R_SUCCESS);
+#endif
+ default:
+ return (ISC_R_FAILURE);
+ }
+
+ plen = (unsigned int)strlen(pbuf);
+ INSIST(plen < sizeof(pbuf));
+
+ isc_netaddr_fromsockaddr(&netaddr, sockaddr);
+ result = isc_netaddr_totext(&netaddr, target);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ if (1 + plen + 1 > isc_buffer_availablelength(target))
+ return (ISC_R_NOSPACE);
+
+ isc_buffer_putmem(target, (const unsigned char *)"#", 1);
+ isc_buffer_putmem(target, (const unsigned char *)pbuf, plen);
+
+ /*
+ * Null terminate after used region.
+ */
+ isc_buffer_availableregion(target, &avail);
+ INSIST(avail.length >= 1);
+ avail.base[0] = '\0';
+
+ return (ISC_R_SUCCESS);
+}
+
+void
+isc_sockaddr_format(const isc_sockaddr_t *sa, char *array, unsigned int size) {
+ isc_result_t result;
+ isc_buffer_t buf;
+
+ if (size == 0U)
+ return;
+
+ isc_buffer_init(&buf, array, size);
+ result = isc_sockaddr_totext(sa, &buf);
+ if (result != ISC_R_SUCCESS) {
+ /*
+ * The message is the same as in netaddr.c.
+ */
+ snprintf(array, size,
+ "<%s %u>",
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_NETADDR,
+ ISC_MSG_UNKNOWNADDR,
+ "unknown address, family"),
+ sa->type.sa.sa_family);
+ array[size - 1] = '\0';
+ }
+}
+
+unsigned int
+isc_sockaddr_hash(const isc_sockaddr_t *sockaddr, isc_boolean_t address_only) {
+ unsigned int length = 0;
+ const unsigned char *s = NULL;
+ unsigned int h = 0;
+ unsigned int g;
+ unsigned int p = 0;
+ const struct in6_addr *in6;
+
+ REQUIRE(sockaddr != NULL);
+
+ switch (sockaddr->type.sa.sa_family) {
+ case AF_INET:
+ s = (const unsigned char *)&sockaddr->type.sin.sin_addr;
+ p = ntohs(sockaddr->type.sin.sin_port);
+ length = sizeof(sockaddr->type.sin.sin_addr.s_addr);
+ break;
+ case AF_INET6:
+ in6 = &sockaddr->type.sin6.sin6_addr;
+ if (IN6_IS_ADDR_V4MAPPED(in6)) {
+ s = (const unsigned char *)&in6 + 12;
+ length = sizeof(sockaddr->type.sin.sin_addr.s_addr);
+ } else {
+ s = (const unsigned char *)in6;
+ length = sizeof(sockaddr->type.sin6.sin6_addr);
+ }
+ p = ntohs(sockaddr->type.sin6.sin6_port);
+ break;
+ default:
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "%s: %d",
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_SOCKADDR,
+ ISC_MSG_UNKNOWNFAMILY,
+ "unknown address family"),
+ (int)sockaddr->type.sa.sa_family);
+ s = (const unsigned char *)&sockaddr->type;
+ length = sockaddr->length;
+ p = 0;
+ }
+
+ h = isc_hash_calc(s, length, ISC_TRUE);
+ if (!address_only) {
+ g = isc_hash_calc((const unsigned char *)&p, sizeof(p),
+ ISC_TRUE);
+ h = h ^ g; /* XXX: we should concatenate h and p first */
+ }
+
+ return (h);
+}
+
+void
+isc_sockaddr_any(isc_sockaddr_t *sockaddr)
+{
+ memset(sockaddr, 0, sizeof(*sockaddr));
+ sockaddr->type.sin.sin_family = AF_INET;
+#ifdef ISC_PLATFORM_HAVESALEN
+ sockaddr->type.sin.sin_len = sizeof(sockaddr->type.sin);
+#endif
+ sockaddr->type.sin.sin_addr.s_addr = INADDR_ANY;
+ sockaddr->type.sin.sin_port = 0;
+ sockaddr->length = sizeof(sockaddr->type.sin);
+ ISC_LINK_INIT(sockaddr, link);
+}
+
+void
+isc_sockaddr_any6(isc_sockaddr_t *sockaddr)
+{
+ memset(sockaddr, 0, sizeof(*sockaddr));
+ sockaddr->type.sin6.sin6_family = AF_INET6;
+#ifdef ISC_PLATFORM_HAVESALEN
+ sockaddr->type.sin6.sin6_len = sizeof(sockaddr->type.sin6);
+#endif
+ sockaddr->type.sin6.sin6_addr = in6addr_any;
+ sockaddr->type.sin6.sin6_port = 0;
+ sockaddr->length = sizeof(sockaddr->type.sin6);
+ ISC_LINK_INIT(sockaddr, link);
+}
+
+void
+isc_sockaddr_fromin(isc_sockaddr_t *sockaddr, const struct in_addr *ina,
+ in_port_t port)
+{
+ memset(sockaddr, 0, sizeof(*sockaddr));
+ sockaddr->type.sin.sin_family = AF_INET;
+#ifdef ISC_PLATFORM_HAVESALEN
+ sockaddr->type.sin.sin_len = sizeof(sockaddr->type.sin);
+#endif
+ sockaddr->type.sin.sin_addr = *ina;
+ sockaddr->type.sin.sin_port = htons(port);
+ sockaddr->length = sizeof(sockaddr->type.sin);
+ ISC_LINK_INIT(sockaddr, link);
+}
+
+void
+isc_sockaddr_anyofpf(isc_sockaddr_t *sockaddr, int pf) {
+ switch (pf) {
+ case AF_INET:
+ isc_sockaddr_any(sockaddr);
+ break;
+ case AF_INET6:
+ isc_sockaddr_any6(sockaddr);
+ break;
+ default:
+ INSIST(0);
+ }
+}
+
+void
+isc_sockaddr_fromin6(isc_sockaddr_t *sockaddr, const struct in6_addr *ina6,
+ in_port_t port)
+{
+ memset(sockaddr, 0, sizeof(*sockaddr));
+ sockaddr->type.sin6.sin6_family = AF_INET6;
+#ifdef ISC_PLATFORM_HAVESALEN
+ sockaddr->type.sin6.sin6_len = sizeof(sockaddr->type.sin6);
+#endif
+ sockaddr->type.sin6.sin6_addr = *ina6;
+ sockaddr->type.sin6.sin6_port = htons(port);
+ sockaddr->length = sizeof(sockaddr->type.sin6);
+ ISC_LINK_INIT(sockaddr, link);
+}
+
+void
+isc_sockaddr_v6fromin(isc_sockaddr_t *sockaddr, const struct in_addr *ina,
+ in_port_t port)
+{
+ memset(sockaddr, 0, sizeof(*sockaddr));
+ sockaddr->type.sin6.sin6_family = AF_INET6;
+#ifdef ISC_PLATFORM_HAVESALEN
+ sockaddr->type.sin6.sin6_len = sizeof(sockaddr->type.sin6);
+#endif
+ sockaddr->type.sin6.sin6_addr.s6_addr[10] = 0xff;
+ sockaddr->type.sin6.sin6_addr.s6_addr[11] = 0xff;
+ memcpy(&sockaddr->type.sin6.sin6_addr.s6_addr[12], ina, 4);
+ sockaddr->type.sin6.sin6_port = htons(port);
+ sockaddr->length = sizeof(sockaddr->type.sin6);
+ ISC_LINK_INIT(sockaddr, link);
+}
+
+int
+isc_sockaddr_pf(const isc_sockaddr_t *sockaddr) {
+
+ /*
+ * Get the protocol family of 'sockaddr'.
+ */
+
+#if (AF_INET == PF_INET && AF_INET6 == PF_INET6)
+ /*
+ * Assume that PF_xxx == AF_xxx for all AF and PF.
+ */
+ return (sockaddr->type.sa.sa_family);
+#else
+ switch (sockaddr->type.sa.sa_family) {
+ case AF_INET:
+ return (PF_INET);
+ case AF_INET6:
+ return (PF_INET6);
+ default:
+ FATAL_ERROR(__FILE__, __LINE__,
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_SOCKADDR,
+ ISC_MSG_UNKNOWNFAMILY,
+ "unknown address family: %d"),
+ (int)sockaddr->type.sa.sa_family);
+ }
+#endif
+}
+
+void
+isc_sockaddr_fromnetaddr(isc_sockaddr_t *sockaddr, const isc_netaddr_t *na,
+ in_port_t port)
+{
+ memset(sockaddr, 0, sizeof(*sockaddr));
+ sockaddr->type.sin.sin_family = (short)na->family;
+ switch (na->family) {
+ case AF_INET:
+ sockaddr->length = sizeof(sockaddr->type.sin);
+#ifdef ISC_PLATFORM_HAVESALEN
+ sockaddr->type.sin.sin_len = sizeof(sockaddr->type.sin);
+#endif
+ sockaddr->type.sin.sin_addr = na->type.in;
+ sockaddr->type.sin.sin_port = htons(port);
+ break;
+ case AF_INET6:
+ sockaddr->length = sizeof(sockaddr->type.sin6);
+#ifdef ISC_PLATFORM_HAVESALEN
+ sockaddr->type.sin6.sin6_len = sizeof(sockaddr->type.sin6);
+#endif
+ memcpy(&sockaddr->type.sin6.sin6_addr, &na->type.in6, 16);
+#ifdef ISC_PLATFORM_HAVESCOPEID
+ sockaddr->type.sin6.sin6_scope_id = isc_netaddr_getzone(na);
+#endif
+ sockaddr->type.sin6.sin6_port = htons(port);
+ break;
+ default:
+ INSIST(0);
+ }
+ ISC_LINK_INIT(sockaddr, link);
+}
+
+void
+isc_sockaddr_setport(isc_sockaddr_t *sockaddr, in_port_t port) {
+ switch (sockaddr->type.sa.sa_family) {
+ case AF_INET:
+ sockaddr->type.sin.sin_port = htons(port);
+ break;
+ case AF_INET6:
+ sockaddr->type.sin6.sin6_port = htons(port);
+ break;
+ default:
+ FATAL_ERROR(__FILE__, __LINE__,
+ "%s: %d",
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_SOCKADDR,
+ ISC_MSG_UNKNOWNFAMILY,
+ "unknown address family"),
+ (int)sockaddr->type.sa.sa_family);
+ }
+}
+
+in_port_t
+isc_sockaddr_getport(const isc_sockaddr_t *sockaddr) {
+ in_port_t port = 0;
+
+ switch (sockaddr->type.sa.sa_family) {
+ case AF_INET:
+ port = ntohs(sockaddr->type.sin.sin_port);
+ break;
+ case AF_INET6:
+ port = ntohs(sockaddr->type.sin6.sin6_port);
+ break;
+ default:
+ FATAL_ERROR(__FILE__, __LINE__,
+ "%s: %d",
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_SOCKADDR,
+ ISC_MSG_UNKNOWNFAMILY,
+ "unknown address family"),
+ (int)sockaddr->type.sa.sa_family);
+ }
+
+ return (port);
+}
+
+isc_boolean_t
+isc_sockaddr_ismulticast(const isc_sockaddr_t *sockaddr) {
+ isc_netaddr_t netaddr;
+
+ if (sockaddr->type.sa.sa_family == AF_INET ||
+ sockaddr->type.sa.sa_family == AF_INET6) {
+ isc_netaddr_fromsockaddr(&netaddr, sockaddr);
+ return (isc_netaddr_ismulticast(&netaddr));
+ }
+ return (ISC_FALSE);
+}
+
+isc_boolean_t
+isc_sockaddr_isexperimental(const isc_sockaddr_t *sockaddr) {
+ isc_netaddr_t netaddr;
+
+ if (sockaddr->type.sa.sa_family == AF_INET) {
+ isc_netaddr_fromsockaddr(&netaddr, sockaddr);
+ return (isc_netaddr_isexperimental(&netaddr));
+ }
+ return (ISC_FALSE);
+}
+
+isc_boolean_t
+isc_sockaddr_issitelocal(const isc_sockaddr_t *sockaddr) {
+ isc_netaddr_t netaddr;
+
+ if (sockaddr->type.sa.sa_family == AF_INET6) {
+ isc_netaddr_fromsockaddr(&netaddr, sockaddr);
+ return (isc_netaddr_issitelocal(&netaddr));
+ }
+ return (ISC_FALSE);
+}
+
+isc_boolean_t
+isc_sockaddr_islinklocal(const isc_sockaddr_t *sockaddr) {
+ isc_netaddr_t netaddr;
+
+ if (sockaddr->type.sa.sa_family == AF_INET6) {
+ isc_netaddr_fromsockaddr(&netaddr, sockaddr);
+ return (isc_netaddr_islinklocal(&netaddr));
+ }
+ return (ISC_FALSE);
+}
+
+isc_result_t
+isc_sockaddr_frompath(isc_sockaddr_t *sockaddr, const char *path) {
+#ifdef ISC_PLATFORM_HAVESYSUNH
+ if (strlen(path) >= sizeof(sockaddr->type.sunix.sun_path))
+ return (ISC_R_NOSPACE);
+ memset(sockaddr, 0, sizeof(*sockaddr));
+ sockaddr->length = sizeof(sockaddr->type.sunix);
+ sockaddr->type.sunix.sun_family = AF_UNIX;
+#ifdef ISC_PLATFORM_HAVESALEN
+ sockaddr->type.sunix.sun_len =
+ (unsigned char)sizeof(sockaddr->type.sunix);
+#endif
+ strcpy(sockaddr->type.sunix.sun_path, path);
+ return (ISC_R_SUCCESS);
+#else
+ UNUSED(sockaddr);
+ UNUSED(path);
+ return (ISC_R_NOTIMPLEMENTED);
+#endif
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/tsmemcmp.c b/sebhbsd/freebsd/contrib/ntp/lib/isc/tsmemcmp.c
new file mode 100644
index 0000000..781612c
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/tsmemcmp.c
@@ -0,0 +1,57 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (C) 2004-2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001, 2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+/*! \file */
+
+#include <config.h>
+#include <limits.h>
+#include <isc/string.h>
+
+/* Making a portable memcmp that has no internal branches and loops always
+ * once for every byte without early-out shortcut has a few challenges.
+ *
+ * Inspired by 'timingsafe_memcmp()' from the BSD system and
+ * https://github.com/libressl-portable/openbsd/blob/master/src/lib/libc/string/timingsafe_memcmp.c
+ *
+ * Sadly, that one is not portable C: It makes assumptions on the representation
+ * of negative integers and assumes sign-preserving right-shift of negative
+ * signed values. This is a rewrite from scratch that should not suffer from
+ * such issues.
+ *
+ * 2015-12-12, J. Perlinger (perlinger-at-ntp-dot-org)
+ */
+int
+isc_tsmemcmp(const void *p1, const void *p2, size_t nb) {
+ const unsigned char *ucp1 = p1;
+ const unsigned char *ucp2 = p2;
+ unsigned int isLT = 0u;
+ unsigned int isGT = 0u;
+ volatile unsigned int mask = (1u << CHAR_BIT);
+
+ for (/*NOP*/; 0 != nb; --nb, ++ucp1, ++ucp2) {
+ isLT |= mask &
+ ((unsigned int)*ucp1 - (unsigned int)*ucp2);
+ isGT |= mask &
+ ((unsigned int)*ucp2 - (unsigned int)*ucp1);
+ mask &= ~(isLT | isGT);
+ }
+ return (int)(isGT >> CHAR_BIT) - (int)(isLT >> CHAR_BIT);
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/dir.c b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/dir.c
new file mode 100644
index 0000000..3b36fb3
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/dir.c
@@ -0,0 +1,258 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (C) 2004, 2005, 2007-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+/*! \file
+ * \author Principal Authors: DCL */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <isc/dir.h>
+#include <isc/magic.h>
+#include <isc/string.h>
+#include <isc/util.h>
+
+#include "errno2result.h"
+#include "ntp_stdlib.h" /* NTP change for strlcpy, strlcat */
+
+#define ISC_DIR_MAGIC ISC_MAGIC('D', 'I', 'R', '*')
+#define VALID_DIR(dir) ISC_MAGIC_VALID(dir, ISC_DIR_MAGIC)
+
+void
+isc_dir_init(isc_dir_t *dir) {
+ REQUIRE(dir != NULL);
+
+ dir->entry.name[0] = '\0';
+ dir->entry.length = 0;
+
+ dir->handle = NULL;
+
+ dir->magic = ISC_DIR_MAGIC;
+}
+
+/*!
+ * \brief Allocate workspace and open directory stream. If either one fails,
+ * NULL will be returned.
+ */
+isc_result_t
+isc_dir_open(isc_dir_t *dir, const char *dirname) {
+ char *p;
+ size_t octets;
+ isc_result_t result = ISC_R_SUCCESS;
+
+ REQUIRE(VALID_DIR(dir));
+ REQUIRE(dirname != NULL);
+
+ /*
+ * Copy directory name. Need to have enough space for the name,
+ * a possible path separator, the wildcard, and the final NUL.
+ */
+ octets = strlen(dirname) + 1;
+ if (octets + 2 > sizeof(dir->dirname))
+ /* XXXDCL ? */
+ return (ISC_R_NOSPACE);
+ strlcpy(dir->dirname, dirname, octets);
+
+ /*
+ * Append path separator, if needed, and "*".
+ */
+ p = dir->dirname + strlen(dir->dirname);
+ if (dir->dirname < p && *(p - 1) != '/')
+ *p++ = '/';
+ *p++ = '*';
+ *p = '\0';
+
+ /*
+ * Open stream.
+ */
+ dir->handle = opendir(dirname);
+
+ if (dir->handle == NULL)
+ return isc__errno2result(errno);
+
+ return (result);
+}
+
+/*!
+ * \brief Return previously retrieved file or get next one.
+
+ * Unix's dirent has
+ * separate open and read functions, but the Win32 and DOS interfaces open
+ * the dir stream and reads the first file in one operation.
+ */
+isc_result_t
+isc_dir_read(isc_dir_t *dir) {
+ struct dirent *entry;
+ size_t octets;
+
+ REQUIRE(VALID_DIR(dir) && dir->handle != NULL);
+
+ /*
+ * Fetch next file in directory.
+ */
+ entry = readdir(dir->handle);
+
+ if (entry == NULL)
+ return (ISC_R_NOMORE);
+
+ /*
+ * Make sure that the space for the name is long enough.
+ */
+ octets = strlen(entry->d_name) + 1;
+ if (sizeof(dir->entry.name) < octets)
+ return (ISC_R_UNEXPECTED);
+
+ strlcpy(dir->entry.name, entry->d_name, octets);
+
+ /*
+ * Some dirents have d_namlen, but it is not portable.
+ */
+ dir->entry.length = strlen(entry->d_name);
+
+ return (ISC_R_SUCCESS);
+}
+
+/*!
+ * \brief Close directory stream.
+ */
+void
+isc_dir_close(isc_dir_t *dir) {
+ REQUIRE(VALID_DIR(dir) && dir->handle != NULL);
+
+ (void)closedir(dir->handle);
+ dir->handle = NULL;
+}
+
+/*!
+ * \brief Reposition directory stream at start.
+ */
+isc_result_t
+isc_dir_reset(isc_dir_t *dir) {
+ REQUIRE(VALID_DIR(dir) && dir->handle != NULL);
+
+ rewinddir(dir->handle);
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_dir_chdir(const char *dirname) {
+ /*!
+ * \brief Change the current directory to 'dirname'.
+ */
+
+ REQUIRE(dirname != NULL);
+
+ if (chdir(dirname) < 0)
+ return (isc__errno2result(errno));
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_dir_chroot(const char *dirname) {
+
+ REQUIRE(dirname != NULL);
+
+#ifdef HAVE_CHROOT
+ if (chroot(dirname) < 0 || chdir("/") < 0)
+ return (isc__errno2result(errno));
+
+ return (ISC_R_SUCCESS);
+#else
+ return (ISC_R_NOTIMPLEMENTED);
+#endif
+}
+
+isc_result_t
+isc_dir_createunique(char *templet) {
+ isc_result_t result;
+ char *x;
+ char *p;
+ int i;
+ int pid;
+
+ REQUIRE(templet != NULL);
+
+ /*!
+ * \brief mkdtemp is not portable, so this emulates it.
+ */
+
+ pid = getpid();
+
+ /*
+ * Replace trailing Xs with the process-id, zero-filled.
+ */
+ for (x = templet + strlen(templet) - 1; *x == 'X' && x >= templet;
+ x--, pid /= 10)
+ *x = pid % 10 + '0';
+
+ x++; /* Set x to start of ex-Xs. */
+
+ do {
+ i = mkdir(templet, 0700);
+ if (i == 0 || errno != EEXIST)
+ break;
+
+ /*
+ * The BSD algorithm.
+ */
+ p = x;
+ while (*p != '\0') {
+ if (isdigit(*p & 0xff))
+ *p = 'a';
+ else if (*p != 'z')
+ ++*p;
+ else {
+ /*
+ * Reset character and move to next.
+ */
+ *p++ = 'a';
+ continue;
+ }
+
+ break;
+ }
+
+ if (*p == '\0') {
+ /*
+ * Tried all combinations. errno should already
+ * be EEXIST, but ensure it is anyway for
+ * isc__errno2result().
+ */
+ errno = EEXIST;
+ break;
+ }
+ } while (1);
+
+ if (i == -1)
+ result = isc__errno2result(errno);
+ else
+ result = ISC_R_SUCCESS;
+
+ return (result);
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/errno2result.c b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/errno2result.c
new file mode 100644
index 0000000..dff9a47
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/errno2result.c
@@ -0,0 +1,124 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (C) 2004, 2005, 2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000-2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <isc/result.h>
+#include <isc/strerror.h>
+#include <isc/util.h>
+
+#include "errno2result.h"
+
+/*%
+ * Convert a POSIX errno value into an isc_result_t. The
+ * list of supported errno values is not complete; new users
+ * of this function should add any expected errors that are
+ * not already there.
+ */
+isc_result_t
+isc___errno2result(int posixerrno, const char *file, unsigned int line) {
+ char strbuf[ISC_STRERRORSIZE];
+
+ switch (posixerrno) {
+ case ENOTDIR:
+ case ELOOP:
+ case EINVAL: /* XXX sometimes this is not for files */
+ case ENAMETOOLONG:
+ case EBADF:
+ return (ISC_R_INVALIDFILE);
+ case ENOENT:
+ return (ISC_R_FILENOTFOUND);
+ case EACCES:
+ case EPERM:
+ return (ISC_R_NOPERM);
+ case EEXIST:
+ return (ISC_R_FILEEXISTS);
+ case EIO:
+ return (ISC_R_IOERROR);
+ case ENOMEM:
+ return (ISC_R_NOMEMORY);
+ case ENFILE:
+ case EMFILE:
+ return (ISC_R_TOOMANYOPENFILES);
+ case EPIPE:
+#ifdef ECONNRESET
+ case ECONNRESET:
+#endif
+#ifdef ECONNABORTED
+ case ECONNABORTED:
+#endif
+ return (ISC_R_CONNECTIONRESET);
+#ifdef ENOTCONN
+ case ENOTCONN:
+ return (ISC_R_NOTCONNECTED);
+#endif
+#ifdef ETIMEDOUT
+ case ETIMEDOUT:
+ return (ISC_R_TIMEDOUT);
+#endif
+#ifdef ENOBUFS
+ case ENOBUFS:
+ return (ISC_R_NORESOURCES);
+#endif
+#ifdef EAFNOSUPPORT
+ case EAFNOSUPPORT:
+ return (ISC_R_FAMILYNOSUPPORT);
+#endif
+#ifdef ENETDOWN
+ case ENETDOWN:
+ return (ISC_R_NETDOWN);
+#endif
+#ifdef EHOSTDOWN
+ case EHOSTDOWN:
+ return (ISC_R_HOSTDOWN);
+#endif
+#ifdef ENETUNREACH
+ case ENETUNREACH:
+ return (ISC_R_NETUNREACH);
+#endif
+#ifdef EHOSTUNREACH
+ case EHOSTUNREACH:
+ return (ISC_R_HOSTUNREACH);
+#endif
+#ifdef EADDRINUSE
+ case EADDRINUSE:
+ return (ISC_R_ADDRINUSE);
+#endif
+ case EADDRNOTAVAIL:
+ return (ISC_R_ADDRNOTAVAIL);
+ case ECONNREFUSED:
+ return (ISC_R_CONNREFUSED);
+ default:
+ isc__strerror(posixerrno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(file, line, "unable to convert errno "
+ "to isc_result: %d: %s",
+ posixerrno, strbuf);
+ /*
+ * XXXDCL would be nice if perhaps this function could
+ * return the system's error string, so the caller
+ * might have something more descriptive than "unexpected
+ * error" to log with.
+ */
+ return (ISC_R_UNEXPECTED);
+ }
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/errno2result.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/errno2result.h
new file mode 100644
index 0000000..1e49ed1
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/errno2result.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2004, 2005, 2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+#ifndef UNIX_ERRNO2RESULT_H
+#define UNIX_ERRNO2RESULT_H 1
+
+/*! \file */
+
+/* XXXDCL this should be moved to lib/isc/include/isc/errno2result.h. */
+
+#include <errno.h> /* Provides errno. */
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+ISC_LANG_BEGINDECLS
+
+#define isc__errno2result(x) isc___errno2result(x, __FILE__, __LINE__)
+
+isc_result_t
+isc___errno2result(int posixerrno, const char *file, unsigned int line);
+
+ISC_LANG_ENDDECLS
+
+#endif /* UNIX_ERRNO2RESULT_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/file.c b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/file.c
new file mode 100644
index 0000000..7b02526
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/file.c
@@ -0,0 +1,546 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (C) 2004, 2005, 2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000-2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Portions Copyright (c) 1987, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* $Id$ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <time.h> /* Required for utimes on some platforms. */
+#include <unistd.h> /* Required for mkstemp on NetBSD. */
+
+
+#include <sys/stat.h>
+#include <sys/time.h>
+
+#include <isc/dir.h>
+#include <isc/file.h>
+#include <isc/log.h>
+#include <isc/mem.h>
+#include <isc/random.h>
+#include <isc/string.h>
+#include <isc/time.h>
+#include <isc/util.h>
+
+#include "errno2result.h"
+#include "ntp_stdlib.h" /* NTP change for strlcpy, strlcat */
+
+/*
+ * XXXDCL As the API for accessing file statistics undoubtedly gets expanded,
+ * it might be good to provide a mechanism that allows for the results
+ * of a previous stat() to be used again without having to do another stat,
+ * such as perl's mechanism of using "_" in place of a file name to indicate
+ * that the results of the last stat should be used. But then you get into
+ * annoying MP issues. BTW, Win32 has stat().
+ */
+static isc_result_t
+file_stats(const char *file, struct stat *stats) {
+ isc_result_t result = ISC_R_SUCCESS;
+
+ REQUIRE(file != NULL);
+ REQUIRE(stats != NULL);
+
+ if (stat(file, stats) != 0)
+ result = isc__errno2result(errno);
+
+ return (result);
+}
+
+isc_result_t
+isc_file_getmodtime(const char *file, isc_time_t *itime) {
+ isc_result_t result;
+ struct stat stats;
+
+ REQUIRE(file != NULL);
+ REQUIRE(itime != NULL);
+
+ result = file_stats(file, &stats);
+
+ if (result == ISC_R_SUCCESS)
+ /*
+ * XXXDCL some operating systems provide nanoseconds, too,
+ * such as BSD/OS via st_mtimespec.
+ */
+ isc_time_set(itime, stats.st_mtime, 0);
+
+ return (result);
+}
+
+isc_result_t
+isc_file_settime(const char *file, isc_time_t *itime) {
+ struct timeval times[2];
+
+ REQUIRE(file != NULL && itime != NULL);
+
+ /*
+ * tv_sec is at least a 32 bit quantity on all platforms we're
+ * dealing with, but it is signed on most (all?) of them,
+ * so we need to make sure the high bit isn't set. This unfortunately
+ * loses when either:
+ * * tv_sec becomes a signed 64 bit integer but long is 32 bits
+ * and isc_time_seconds > LONG_MAX, or
+ * * isc_time_seconds is changed to be > 32 bits but long is 32 bits
+ * and isc_time_seconds has at least 33 significant bits.
+ */
+ times[0].tv_sec = times[1].tv_sec = (long)isc_time_seconds(itime);
+
+ /*
+ * Here is the real check for the high bit being set.
+ */
+ if ((times[0].tv_sec &
+ (1ULL << (sizeof(times[0].tv_sec) * CHAR_BIT - 1))) != 0)
+ return (ISC_R_RANGE);
+
+ /*
+ * isc_time_nanoseconds guarantees a value that divided by 1000 will
+ * fit into the minimum possible size tv_usec field. Unfortunately,
+ * we don't know what that type is so can't cast directly ... but
+ * we can at least cast to signed so the IRIX compiler shuts up.
+ */
+ times[0].tv_usec = times[1].tv_usec =
+ (isc_int32_t)(isc_time_nanoseconds(itime) / 1000);
+
+ if (utimes(file, times) < 0)
+ return (isc__errno2result(errno));
+
+ return (ISC_R_SUCCESS);
+}
+
+#undef TEMPLATE
+#define TEMPLATE "tmp-XXXXXXXXXX" /*%< 14 characters. */
+
+isc_result_t
+isc_file_mktemplate(const char *path, char *buf, size_t buflen) {
+ return (isc_file_template(path, TEMPLATE, buf, buflen));
+}
+
+isc_result_t
+isc_file_template(const char *path, const char *templet, char *buf,
+ size_t buflen) {
+ char *s;
+
+ REQUIRE(path != NULL);
+ REQUIRE(templet != NULL);
+ REQUIRE(buf != NULL);
+
+ s = strrchr(templet, '/');
+ if (s != NULL)
+ templet = s + 1;
+
+ s = strrchr(path, '/');
+
+ if (s != NULL) {
+ if ((s - path + 1 + strlen(templet) + 1) > buflen)
+ return (ISC_R_NOSPACE);
+
+ strlcpy(buf, path, buflen);
+ buf[s - path + 1] = '\0';
+ strlcat(buf, templet, buflen);
+ } else {
+ if ((strlen(templet) + 1) > buflen)
+ return (ISC_R_NOSPACE);
+
+ strlcpy(buf, templet, buflen);
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+static char alphnum[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+
+isc_result_t
+isc_file_renameunique(const char *file, char *templet) {
+ char *x;
+ char *cp;
+ isc_uint32_t which;
+
+ REQUIRE(file != NULL);
+ REQUIRE(templet != NULL);
+
+ cp = templet;
+ while (*cp != '\0')
+ cp++;
+ if (cp == templet)
+ return (ISC_R_FAILURE);
+
+ x = cp--;
+ while (cp >= templet && *cp == 'X') {
+ isc_random_get(&which);
+ *cp = alphnum[which % (sizeof(alphnum) - 1)];
+ x = cp--;
+ }
+ while (link(file, templet) == -1) {
+ if (errno != EEXIST)
+ return (isc__errno2result(errno));
+ for (cp = x;;) {
+ char *t;
+ if (*cp == '\0')
+ return (ISC_R_FAILURE);
+ t = strchr(alphnum, *cp);
+ if (t == NULL || *++t == '\0')
+ *cp++ = alphnum[0];
+ else {
+ *cp = *t;
+ break;
+ }
+ }
+ }
+ if (unlink(file) < 0)
+ if (errno != ENOENT)
+ return (isc__errno2result(errno));
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_file_openunique(char *templet, FILE **fp) {
+ int mode = S_IWUSR|S_IRUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH;
+ return (isc_file_openuniquemode(templet, mode, fp));
+}
+
+isc_result_t
+isc_file_openuniqueprivate(char *templet, FILE **fp) {
+ int mode = S_IWUSR|S_IRUSR;
+ return (isc_file_openuniquemode(templet, mode, fp));
+}
+
+isc_result_t
+isc_file_openuniquemode(char *templet, int mode, FILE **fp) {
+ int fd;
+ FILE *f;
+ isc_result_t result = ISC_R_SUCCESS;
+ char *x;
+ char *cp;
+ isc_uint32_t which;
+
+ REQUIRE(templet != NULL);
+ REQUIRE(fp != NULL && *fp == NULL);
+
+ cp = templet;
+ while (*cp != '\0')
+ cp++;
+ if (cp == templet)
+ return (ISC_R_FAILURE);
+
+ x = cp--;
+ while (cp >= templet && *cp == 'X') {
+ isc_random_get(&which);
+ *cp = alphnum[which % (sizeof(alphnum) - 1)];
+ x = cp--;
+ }
+
+
+ while ((fd = open(templet, O_RDWR|O_CREAT|O_EXCL, mode)) == -1) {
+ if (errno != EEXIST)
+ return (isc__errno2result(errno));
+ for (cp = x;;) {
+ char *t;
+ if (*cp == '\0')
+ return (ISC_R_FAILURE);
+ t = strchr(alphnum, *cp);
+ if (t == NULL || *++t == '\0')
+ *cp++ = alphnum[0];
+ else {
+ *cp = *t;
+ break;
+ }
+ }
+ }
+ f = fdopen(fd, "w+");
+ if (f == NULL) {
+ result = isc__errno2result(errno);
+ if (remove(templet) < 0) {
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_FILE, ISC_LOG_ERROR,
+ "remove '%s': failed", templet);
+ }
+ (void)close(fd);
+ } else
+ *fp = f;
+
+ return (result);
+}
+
+isc_result_t
+isc_file_remove(const char *filename) {
+ int r;
+
+ REQUIRE(filename != NULL);
+
+ r = unlink(filename);
+ if (r == 0)
+ return (ISC_R_SUCCESS);
+ else
+ return (isc__errno2result(errno));
+}
+
+isc_result_t
+isc_file_rename(const char *oldname, const char *newname) {
+ int r;
+
+ REQUIRE(oldname != NULL);
+ REQUIRE(newname != NULL);
+
+ r = rename(oldname, newname);
+ if (r == 0)
+ return (ISC_R_SUCCESS);
+ else
+ return (isc__errno2result(errno));
+}
+
+isc_boolean_t
+isc_file_exists(const char *pathname) {
+ struct stat stats;
+
+ REQUIRE(pathname != NULL);
+
+ return (ISC_TF(file_stats(pathname, &stats) == ISC_R_SUCCESS));
+}
+
+isc_result_t
+isc_file_isplainfile(const char *filename) {
+ /*
+ * This function returns success if filename is a plain file.
+ */
+ struct stat filestat;
+ memset(&filestat,0,sizeof(struct stat));
+
+ if ((stat(filename, &filestat)) == -1)
+ return(isc__errno2result(errno));
+
+ if(! S_ISREG(filestat.st_mode))
+ return(ISC_R_INVALIDFILE);
+
+ return(ISC_R_SUCCESS);
+}
+
+isc_boolean_t
+isc_file_isabsolute(const char *filename) {
+ REQUIRE(filename != NULL);
+ return (ISC_TF(filename[0] == '/'));
+}
+
+isc_boolean_t
+isc_file_iscurrentdir(const char *filename) {
+ REQUIRE(filename != NULL);
+ return (ISC_TF(filename[0] == '.' && filename[1] == '\0'));
+}
+
+isc_boolean_t
+isc_file_ischdiridempotent(const char *filename) {
+ REQUIRE(filename != NULL);
+ if (isc_file_isabsolute(filename))
+ return (ISC_TRUE);
+ if (isc_file_iscurrentdir(filename))
+ return (ISC_TRUE);
+ return (ISC_FALSE);
+}
+
+const char *
+isc_file_basename(const char *filename) {
+ char *s;
+
+ REQUIRE(filename != NULL);
+
+ s = strrchr(filename, '/');
+ if (s == NULL)
+ return (filename);
+
+ return (s + 1);
+}
+
+isc_result_t
+isc_file_progname(const char *filename, char *buf, size_t buflen) {
+ const char *base;
+ size_t len;
+
+ REQUIRE(filename != NULL);
+ REQUIRE(buf != NULL);
+
+ base = isc_file_basename(filename);
+ len = strlen(base) + 1;
+
+ if (len > buflen)
+ return (ISC_R_NOSPACE);
+ memcpy(buf, base, len);
+
+ return (ISC_R_SUCCESS);
+}
+
+/*
+ * Put the absolute name of the current directory into 'dirname', which is
+ * a buffer of at least 'length' characters. End the string with the
+ * appropriate path separator, such that the final product could be
+ * concatenated with a relative pathname to make a valid pathname string.
+ */
+static isc_result_t
+dir_current(char *dirname, size_t length) {
+ char *cwd;
+ isc_result_t result = ISC_R_SUCCESS;
+
+ REQUIRE(dirname != NULL);
+ REQUIRE(length > 0U);
+
+ cwd = getcwd(dirname, length);
+
+ if (cwd == NULL) {
+ if (errno == ERANGE)
+ result = ISC_R_NOSPACE;
+ else
+ result = isc__errno2result(errno);
+ } else {
+ if (strlen(dirname) + 1 == length)
+ result = ISC_R_NOSPACE;
+ else if (dirname[1] != '\0')
+ strlcat(dirname, "/", length);
+ }
+
+ return (result);
+}
+
+isc_result_t
+isc_file_absolutepath(const char *filename, char *path, size_t pathlen) {
+ isc_result_t result;
+ result = dir_current(path, pathlen);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ if (strlen(path) + strlen(filename) + 1 > pathlen)
+ return (ISC_R_NOSPACE);
+ strlcat(path, filename, pathlen);
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_file_truncate(const char *filename, isc_offset_t size) {
+ isc_result_t result = ISC_R_SUCCESS;
+
+ if (truncate(filename, size) < 0)
+ result = isc__errno2result(errno);
+ return (result);
+}
+
+isc_result_t
+isc_file_safecreate(const char *filename, FILE **fp) {
+ isc_result_t result;
+ int flags;
+ struct stat sb;
+ FILE *f;
+ int fd;
+
+ REQUIRE(filename != NULL);
+ REQUIRE(fp != NULL && *fp == NULL);
+
+ result = file_stats(filename, &sb);
+ if (result == ISC_R_SUCCESS) {
+ if ((sb.st_mode & S_IFREG) == 0)
+ return (ISC_R_INVALIDFILE);
+ flags = O_WRONLY | O_TRUNC;
+ } else if (result == ISC_R_FILENOTFOUND) {
+ flags = O_WRONLY | O_CREAT | O_EXCL;
+ } else
+ return (result);
+
+ fd = open(filename, flags, S_IRUSR | S_IWUSR);
+ if (fd == -1)
+ return (isc__errno2result(errno));
+
+ f = fdopen(fd, "w");
+ if (f == NULL) {
+ result = isc__errno2result(errno);
+ close(fd);
+ return (result);
+ }
+
+ *fp = f;
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_file_splitpath(isc_mem_t *mctx, char *path, char **dirnam, char **basenam)
+{
+ char *dir, *file, *slash;
+
+ REQUIRE(path != NULL);
+
+ slash = strrchr(path, '/');
+
+ if (slash == path) {
+ file = ++slash;
+ dir = isc_mem_strdup(mctx, "/");
+ } else if (slash != NULL) {
+ file = ++slash;
+ dir = isc_mem_allocate(mctx, slash - path);
+ if (dir != NULL)
+ strlcpy(dir, path, slash - path);
+ } else {
+ file = path;
+ dir = isc_mem_strdup(mctx, ".");
+ }
+
+ if (dir == NULL)
+ return (ISC_R_NOMEMORY);
+
+ if (*file == '\0') {
+ isc_mem_free(mctx, dir);
+ return (ISC_R_INVALIDFILE);
+ }
+
+ *dirnam = dir;
+ *basenam = file;
+
+ return (ISC_R_SUCCESS);
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/ifiter_getifaddrs.c b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/ifiter_getifaddrs.c
new file mode 100644
index 0000000..ad7c5f8
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/ifiter_getifaddrs.c
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: ifiter_getifaddrs.c,v 1.13 2009/09/24 23:48:13 tbox Exp $ */
+
+/*! \file
+ * \brief
+ * Obtain the list of network interfaces using the getifaddrs(3) library.
+ */
+
+#include <ifaddrs.h>
+
+/*% Iterator Magic */
+#define IFITER_MAGIC ISC_MAGIC('I', 'F', 'I', 'G')
+/*% Valid Iterator */
+#define VALID_IFITER(t) ISC_MAGIC_VALID(t, IFITER_MAGIC)
+
+#ifdef __linux
+static isc_boolean_t seenv6 = ISC_FALSE;
+#endif
+
+/*% Iterator structure */
+struct isc_interfaceiter {
+ unsigned int magic; /*%< Magic number. */
+ isc_mem_t *mctx;
+ void *buf; /*%< (unused) */
+ unsigned int bufsize; /*%< (always 0) */
+ struct ifaddrs *ifaddrs; /*%< List of ifaddrs */
+ struct ifaddrs *pos; /*%< Ptr to current ifaddr */
+ isc_interface_t current; /*%< Current interface data. */
+ isc_result_t result; /*%< Last result code. */
+#ifdef __linux
+ FILE * proc;
+ char entry[ISC_IF_INET6_SZ];
+ isc_result_t valid;
+#endif
+};
+
+isc_result_t
+isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) {
+ isc_interfaceiter_t *iter;
+ isc_result_t result;
+ char strbuf[ISC_STRERRORSIZE];
+ int trys, ret;
+
+ REQUIRE(mctx != NULL);
+ REQUIRE(iterp != NULL);
+ REQUIRE(*iterp == NULL);
+
+ iter = isc_mem_get(mctx, sizeof(*iter));
+ if (iter == NULL)
+ return (ISC_R_NOMEMORY);
+
+ iter->mctx = mctx;
+ iter->buf = NULL;
+ iter->bufsize = 0;
+ iter->ifaddrs = NULL;
+#ifdef __linux
+ /*
+ * Only open "/proc/net/if_inet6" if we have never seen a IPv6
+ * address returned by getifaddrs().
+ */
+ if (!seenv6) {
+ iter->proc = fopen("/proc/net/if_inet6", "r");
+ if (iter->proc == NULL) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_SOCKET, ISC_LOG_WARNING,
+ "failed to open /proc/net/if_inet6");
+ }
+ } else
+ iter->proc = NULL;
+ iter->valid = ISC_R_FAILURE;
+#endif
+
+ /* If interrupted, try again */
+ for (trys = 0; trys < 3; trys++) {
+ if ((ret = getifaddrs(&iter->ifaddrs)) >= 0)
+ break;
+ if (errno != EINTR)
+ break;
+ }
+ if (ret < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "getting interface addresses: %s: %s",
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_IFITERGETIFADDRS,
+ ISC_MSG_GETIFADDRS,
+ "getifaddrs"),
+ strbuf);
+ result = ISC_R_UNEXPECTED;
+ goto failure;
+ }
+
+ /*
+ * A newly created iterator has an undefined position
+ * until isc_interfaceiter_first() is called.
+ */
+ iter->pos = NULL;
+ iter->result = ISC_R_FAILURE;
+
+ iter->magic = IFITER_MAGIC;
+ *iterp = iter;
+ return (ISC_R_SUCCESS);
+
+ failure:
+#ifdef __linux
+ if (iter->proc != NULL)
+ fclose(iter->proc);
+#endif
+ if (iter->ifaddrs != NULL) /* just in case */
+ freeifaddrs(iter->ifaddrs);
+ isc_mem_put(mctx, iter, sizeof(*iter));
+ return (result);
+}
+
+/*
+ * Get information about the current interface to iter->current.
+ * If successful, return ISC_R_SUCCESS.
+ * If the interface has an unsupported address family,
+ * return ISC_R_IGNORE.
+ */
+
+static isc_result_t
+internal_current(isc_interfaceiter_t *iter) {
+ struct ifaddrs *ifa;
+ int family;
+ unsigned int namelen;
+
+ REQUIRE(VALID_IFITER(iter));
+
+ ifa = iter->pos;
+
+#ifdef __linux
+ /*
+ * [Bug 2792]
+ * burnicki: iter->pos is usually never NULL here (anymore?),
+ * so linux_if_inet6_current(iter) is never called here.
+ * However, that routine would check (under Linux), if the
+ * interface is in a tentative state, e.g. if there's no link
+ * yet but an IPv6 address has already be assigned.
+ */
+ if (iter->pos == NULL)
+ return (linux_if_inet6_current(iter));
+#endif
+
+ INSIST(ifa != NULL);
+ INSIST(ifa->ifa_name != NULL);
+
+
+#ifdef IFF_RUNNING
+ /*
+ * [Bug 2792]
+ * burnicki: if the interface is not running then
+ * it may be in a tentative state. See above.
+ */
+ if ((ifa->ifa_flags & IFF_RUNNING) == 0)
+ return (ISC_R_IGNORE);
+#endif
+
+ if (ifa->ifa_addr == NULL)
+ return (ISC_R_IGNORE);
+
+ family = ifa->ifa_addr->sa_family;
+ if (family != AF_INET && family != AF_INET6)
+ return (ISC_R_IGNORE);
+
+#ifdef __linux
+ if (family == AF_INET6)
+ seenv6 = ISC_TRUE;
+#endif
+
+ memset(&iter->current, 0, sizeof(iter->current));
+
+ namelen = strlen(ifa->ifa_name);
+ if (namelen > sizeof(iter->current.name) - 1)
+ namelen = sizeof(iter->current.name) - 1;
+
+ memset(iter->current.name, 0, sizeof(iter->current.name));
+ memcpy(iter->current.name, ifa->ifa_name, namelen);
+
+ iter->current.flags = 0;
+
+ if ((ifa->ifa_flags & IFF_UP) != 0)
+ iter->current.flags |= INTERFACE_F_UP;
+
+ if ((ifa->ifa_flags & IFF_POINTOPOINT) != 0)
+ iter->current.flags |= INTERFACE_F_POINTTOPOINT;
+
+ if ((ifa->ifa_flags & IFF_LOOPBACK) != 0)
+ iter->current.flags |= INTERFACE_F_LOOPBACK;
+
+ if ((ifa->ifa_flags & IFF_BROADCAST) != 0)
+ iter->current.flags |= INTERFACE_F_BROADCAST;
+
+#ifdef IFF_MULTICAST
+ if ((ifa->ifa_flags & IFF_MULTICAST) != 0)
+ iter->current.flags |= INTERFACE_F_MULTICAST;
+#endif
+
+ iter->current.af = family;
+
+ get_addr(family, &iter->current.address, ifa->ifa_addr, ifa->ifa_name);
+
+ if (ifa->ifa_netmask != NULL)
+ get_addr(family, &iter->current.netmask, ifa->ifa_netmask,
+ ifa->ifa_name);
+
+ if (ifa->ifa_dstaddr != NULL &&
+ (iter->current.flags & INTERFACE_F_POINTTOPOINT) != 0)
+ get_addr(family, &iter->current.dstaddress, ifa->ifa_dstaddr,
+ ifa->ifa_name);
+
+ if (ifa->ifa_broadaddr != NULL &&
+ (iter->current.flags & INTERFACE_F_BROADCAST) != 0)
+ get_addr(family, &iter->current.broadcast, ifa->ifa_broadaddr,
+ ifa->ifa_name);
+
+#ifdef ISC_PLATFORM_HAVEIFNAMETOINDEX
+ iter->current.ifindex = if_nametoindex(iter->current.name);
+#endif
+ return (ISC_R_SUCCESS);
+}
+
+/*
+ * Step the iterator to the next interface. Unlike
+ * isc_interfaceiter_next(), this may leave the iterator
+ * positioned on an interface that will ultimately
+ * be ignored. Return ISC_R_NOMORE if there are no more
+ * interfaces, otherwise ISC_R_SUCCESS.
+ */
+static isc_result_t
+internal_next(isc_interfaceiter_t *iter) {
+
+ if (iter->pos != NULL)
+ iter->pos = iter->pos->ifa_next;
+ if (iter->pos == NULL) {
+#ifdef __linux
+ if (!seenv6)
+ return (linux_if_inet6_next(iter));
+#endif
+ return (ISC_R_NOMORE);
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+static void
+internal_destroy(isc_interfaceiter_t *iter) {
+
+#ifdef __linux
+ if (iter->proc != NULL)
+ fclose(iter->proc);
+ iter->proc = NULL;
+#endif
+ if (iter->ifaddrs)
+ freeifaddrs(iter->ifaddrs);
+ iter->ifaddrs = NULL;
+}
+
+static
+void internal_first(isc_interfaceiter_t *iter) {
+
+#ifdef __linux
+ linux_if_inet6_first(iter);
+#endif
+ iter->pos = iter->ifaddrs;
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/ifiter_ioctl.c b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/ifiter_ioctl.c
new file mode 100644
index 0000000..40ff569
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/ifiter_ioctl.c
@@ -0,0 +1,1034 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: ifiter_ioctl.c,v 1.62 2009/01/18 23:48:14 tbox Exp $ */
+
+/*! \file
+ * \brief
+ * Obtain the list of network interfaces using the SIOCGLIFCONF ioctl.
+ * See netintro(4).
+ */
+
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
+#ifdef ISC_PLATFORM_HAVEIF_LADDRCONF
+#define lifc_len iflc_len
+#define lifc_buf iflc_buf
+#define lifc_req iflc_req
+#define LIFCONF if_laddrconf
+#else
+#define ISC_HAVE_LIFC_FAMILY 1
+#define ISC_HAVE_LIFC_FLAGS 1
+#define LIFCONF lifconf
+#endif
+
+#ifdef ISC_PLATFORM_HAVEIF_LADDRREQ
+#define lifr_addr iflr_addr
+#define lifr_name iflr_name
+#define lifr_dstaddr iflr_dstaddr
+#define lifr_broadaddr iflr_broadaddr
+#define lifr_flags iflr_flags
+#define lifr_index iflr_index
+#define ss_family sa_family
+#define LIFREQ if_laddrreq
+#else
+#define LIFREQ lifreq
+#endif
+#endif
+
+#define IFITER_MAGIC ISC_MAGIC('I', 'F', 'I', 'T')
+#define VALID_IFITER(t) ISC_MAGIC_VALID(t, IFITER_MAGIC)
+
+struct isc_interfaceiter {
+ unsigned int magic; /* Magic number. */
+ isc_mem_t *mctx;
+ int mode;
+ int socket;
+ struct ifconf ifc;
+ void *buf; /* Buffer for sysctl data. */
+ unsigned int bufsize; /* Bytes allocated. */
+ unsigned int pos; /* Current offset in
+ SIOCGIFCONF data */
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
+ int socket6;
+ struct LIFCONF lifc;
+ void *buf6; /* Buffer for sysctl data. */
+ unsigned int bufsize6; /* Bytes allocated. */
+ unsigned int pos6; /* Current offset in
+ SIOCGLIFCONF data */
+ isc_result_t result6; /* Last result code. */
+ isc_boolean_t first6;
+#endif
+#ifdef HAVE_TRUCLUSTER
+ int clua_context; /* Cluster alias context */
+ isc_boolean_t clua_done;
+ struct sockaddr clua_sa;
+#endif
+#ifdef __linux
+ FILE * proc;
+ char entry[ISC_IF_INET6_SZ];
+ isc_result_t valid;
+#endif
+ isc_interface_t current; /* Current interface data. */
+ isc_result_t result; /* Last result code. */
+};
+
+#ifdef HAVE_TRUCLUSTER
+#include <clua/clua.h>
+#include <sys/socket.h>
+#endif
+
+
+/*%
+ * Size of buffer for SIOCGLIFCONF, in bytes. We assume no sane system
+ * will have more than a megabyte of interface configuration data.
+ */
+#define IFCONF_BUFSIZE_INITIAL 4096
+#define IFCONF_BUFSIZE_MAX 1048576
+
+#ifdef __linux
+#ifndef IF_NAMESIZE
+# ifdef IFNAMSIZ
+# define IF_NAMESIZE IFNAMSIZ
+# else
+# define IF_NAMESIZE 16
+# endif
+#endif
+#endif
+
+/* Silence a warning when this file is #included */
+int
+isc_ioctl(int fildes, int req, char *arg);
+
+int
+isc_ioctl(int fildes, int req, char *arg) {
+ int trys;
+ int ret;
+
+ for (trys = 0; trys < 3; trys++) {
+ if ((ret = ioctl(fildes, req, arg)) < 0) {
+ if (errno == EINTR)
+ continue;
+ }
+ break;
+ }
+ return (ret);
+}
+
+static isc_result_t
+getbuf4(isc_interfaceiter_t *iter) {
+ char strbuf[ISC_STRERRORSIZE];
+
+ iter->bufsize = IFCONF_BUFSIZE_INITIAL;
+
+ for (;;) {
+ iter->buf = isc_mem_get(iter->mctx, iter->bufsize);
+ if (iter->buf == NULL)
+ return (ISC_R_NOMEMORY);
+
+ memset(&iter->ifc.ifc_len, 0, sizeof(iter->ifc.ifc_len));
+ iter->ifc.ifc_len = iter->bufsize;
+ iter->ifc.ifc_buf = iter->buf;
+ /*
+ * Ignore the HP/UX warning about "integer overflow during
+ * conversion". It comes from its own macro definition,
+ * and is really hard to shut up.
+ */
+ if (isc_ioctl(iter->socket, SIOCGIFCONF, (char *)&iter->ifc)
+ == -1) {
+ if (errno != EINVAL) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_IFITERIOCTL,
+ ISC_MSG_GETIFCONFIG,
+ "get interface "
+ "configuration: %s"),
+ strbuf);
+ goto unexpected;
+ }
+ /*
+ * EINVAL. Retry with a bigger buffer.
+ */
+ } else {
+ /*
+ * The ioctl succeeded.
+ * Some OS's just return what will fit rather
+ * than set EINVAL if the buffer is too small
+ * to fit all the interfaces in. If
+ * ifc.lifc_len is too near to the end of the
+ * buffer we will grow it just in case and
+ * retry.
+ */
+ if (iter->ifc.ifc_len + 2 * sizeof(struct ifreq)
+ < iter->bufsize)
+ break;
+ }
+ if (iter->bufsize >= IFCONF_BUFSIZE_MAX) {
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_IFITERIOCTL,
+ ISC_MSG_BUFFERMAX,
+ "get interface "
+ "configuration: "
+ "maximum buffer "
+ "size exceeded"));
+ goto unexpected;
+ }
+ isc_mem_put(iter->mctx, iter->buf, iter->bufsize);
+
+ iter->bufsize *= 2;
+ }
+ return (ISC_R_SUCCESS);
+
+ unexpected:
+ isc_mem_put(iter->mctx, iter->buf, iter->bufsize);
+ iter->buf = NULL;
+ return (ISC_R_UNEXPECTED);
+}
+
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
+static isc_result_t
+getbuf6(isc_interfaceiter_t *iter) {
+ char strbuf[ISC_STRERRORSIZE];
+ isc_result_t result;
+
+ iter->bufsize6 = IFCONF_BUFSIZE_INITIAL;
+
+ for (;;) {
+ iter->buf6 = isc_mem_get(iter->mctx, iter->bufsize6);
+ if (iter->buf6 == NULL)
+ return (ISC_R_NOMEMORY);
+
+ memset(&iter->lifc, 0, sizeof(iter->lifc));
+#ifdef ISC_HAVE_LIFC_FAMILY
+ iter->lifc.lifc_family = AF_INET6;
+#endif
+#ifdef ISC_HAVE_LIFC_FLAGS
+ iter->lifc.lifc_flags = 0;
+#endif
+ iter->lifc.lifc_len = iter->bufsize6;
+ iter->lifc.lifc_buf = iter->buf6;
+ /*
+ * Ignore the HP/UX warning about "integer overflow during
+ * conversion". It comes from its own macro definition,
+ * and is really hard to shut up.
+ */
+ if (isc_ioctl(iter->socket6, SIOCGLIFCONF, (char *)&iter->lifc)
+ == -1) {
+#ifdef __hpux
+ /*
+ * IPv6 interface scanning is not available on all
+ * kernels w/ IPv6 sockets.
+ */
+ if (errno == ENOENT) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_INTERFACE,
+ ISC_LOG_DEBUG(1),
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_IFITERIOCTL,
+ ISC_MSG_GETIFCONFIG,
+ "get interface "
+ "configuration: %s"),
+ strbuf);
+ result = ISC_R_FAILURE;
+ goto cleanup;
+ }
+#endif
+ if (errno != EINVAL) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_IFITERIOCTL,
+ ISC_MSG_GETIFCONFIG,
+ "get interface "
+ "configuration: %s"),
+ strbuf);
+ result = ISC_R_UNEXPECTED;
+ goto cleanup;
+ }
+ /*
+ * EINVAL. Retry with a bigger buffer.
+ */
+ } else {
+ /*
+ * The ioctl succeeded.
+ * Some OS's just return what will fit rather
+ * than set EINVAL if the buffer is too small
+ * to fit all the interfaces in. If
+ * ifc.ifc_len is too near to the end of the
+ * buffer we will grow it just in case and
+ * retry.
+ */
+ if (iter->lifc.lifc_len + 2 * sizeof(struct LIFREQ)
+ < iter->bufsize6)
+ break;
+ }
+ if (iter->bufsize6 >= IFCONF_BUFSIZE_MAX) {
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_IFITERIOCTL,
+ ISC_MSG_BUFFERMAX,
+ "get interface "
+ "configuration: "
+ "maximum buffer "
+ "size exceeded"));
+ result = ISC_R_UNEXPECTED;
+ goto cleanup;
+ }
+ isc_mem_put(iter->mctx, iter->buf6, iter->bufsize6);
+
+ iter->bufsize6 *= 2;
+ }
+
+ if (iter->lifc.lifc_len != 0)
+ iter->mode = 6;
+ return (ISC_R_SUCCESS);
+
+ cleanup:
+ isc_mem_put(iter->mctx, iter->buf6, iter->bufsize6);
+ iter->buf6 = NULL;
+ return (result);
+}
+#endif
+
+isc_result_t
+isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) {
+ isc_interfaceiter_t *iter;
+ isc_result_t result;
+ char strbuf[ISC_STRERRORSIZE];
+
+ REQUIRE(mctx != NULL);
+ REQUIRE(iterp != NULL);
+ REQUIRE(*iterp == NULL);
+
+ iter = isc_mem_get(mctx, sizeof(*iter));
+ if (iter == NULL)
+ return (ISC_R_NOMEMORY);
+
+ iter->mctx = mctx;
+ iter->mode = 4;
+ iter->buf = NULL;
+ iter->pos = (unsigned int) -1;
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
+ iter->buf6 = NULL;
+ iter->pos6 = (unsigned int) -1;
+ iter->result6 = ISC_R_NOMORE;
+ iter->socket6 = -1;
+ iter->first6 = ISC_FALSE;
+#endif
+
+ /*
+ * Get the interface configuration, allocating more memory if
+ * necessary.
+ */
+
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
+ result = isc_net_probeipv6();
+ if (result == ISC_R_SUCCESS) {
+ /*
+ * Create an unbound datagram socket to do the SIOCGLIFCONF
+ * ioctl on. HP/UX requires an AF_INET6 socket for
+ * SIOCGLIFCONF to get IPv6 addresses.
+ */
+ if ((iter->socket6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_IFITERIOCTL,
+ ISC_MSG_MAKESCANSOCKET,
+ "making interface "
+ "scan socket: %s"),
+ strbuf);
+ result = ISC_R_UNEXPECTED;
+ goto socket6_failure;
+ }
+ result = iter->result6 = getbuf6(iter);
+ if (result != ISC_R_NOTIMPLEMENTED && result != ISC_R_SUCCESS)
+ goto ioctl6_failure;
+ }
+#endif
+ if ((iter->socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_IFITERIOCTL,
+ ISC_MSG_MAKESCANSOCKET,
+ "making interface "
+ "scan socket: %s"),
+ strbuf);
+ result = ISC_R_UNEXPECTED;
+ goto socket_failure;
+ }
+ result = getbuf4(iter);
+ if (result != ISC_R_SUCCESS)
+ goto ioctl_failure;
+
+ /*
+ * A newly created iterator has an undefined position
+ * until isc_interfaceiter_first() is called.
+ */
+#ifdef HAVE_TRUCLUSTER
+ iter->clua_context = -1;
+ iter->clua_done = ISC_TRUE;
+#endif
+#ifdef __linux
+ iter->proc = fopen("/proc/net/if_inet6", "r");
+ iter->valid = ISC_R_FAILURE;
+#endif
+ iter->result = ISC_R_FAILURE;
+
+ iter->magic = IFITER_MAGIC;
+ *iterp = iter;
+ return (ISC_R_SUCCESS);
+
+ ioctl_failure:
+ if (iter->buf != NULL)
+ isc_mem_put(mctx, iter->buf, iter->bufsize);
+ (void) close(iter->socket);
+
+ socket_failure:
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
+ if (iter->buf6 != NULL)
+ isc_mem_put(mctx, iter->buf6, iter->bufsize6);
+ ioctl6_failure:
+ if (iter->socket6 != -1)
+ (void) close(iter->socket6);
+ socket6_failure:
+#endif
+
+ isc_mem_put(mctx, iter, sizeof(*iter));
+ return (result);
+}
+
+#ifdef HAVE_TRUCLUSTER
+static void
+get_inaddr(isc_netaddr_t *dst, struct in_addr *src) {
+ dst->family = AF_INET;
+ memcpy(&dst->type.in, src, sizeof(struct in_addr));
+}
+
+static isc_result_t
+internal_current_clusteralias(isc_interfaceiter_t *iter) {
+ struct clua_info ci;
+ if (clua_getaliasinfo(&iter->clua_sa, &ci) != CLUA_SUCCESS)
+ return (ISC_R_IGNORE);
+ memset(&iter->current, 0, sizeof(iter->current));
+ iter->current.af = iter->clua_sa.sa_family;
+ memset(iter->current.name, 0, sizeof(iter->current.name));
+ sprintf(iter->current.name, "clua%d", ci.aliasid);
+ iter->current.flags = INTERFACE_F_UP;
+ get_inaddr(&iter->current.address, &ci.addr);
+ get_inaddr(&iter->current.netmask, &ci.netmask);
+ return (ISC_R_SUCCESS);
+}
+#endif
+
+/*
+ * Get information about the current interface to iter->current.
+ * If successful, return ISC_R_SUCCESS.
+ * If the interface has an unsupported address family, or if
+ * some operation on it fails, return ISC_R_IGNORE to make
+ * the higher-level iterator code ignore it.
+ */
+
+static isc_result_t
+internal_current4(isc_interfaceiter_t *iter) {
+ struct ifreq *ifrp;
+ struct ifreq ifreq;
+ int family;
+ char strbuf[ISC_STRERRORSIZE];
+#if !defined(ISC_PLATFORM_HAVEIF_LADDRREQ) && defined(SIOCGLIFADDR)
+ struct lifreq lifreq;
+#else
+ char sabuf[256];
+#endif
+ int i, bits, prefixlen;
+
+ REQUIRE(VALID_IFITER(iter));
+
+ if (iter->ifc.ifc_len == 0 ||
+ iter->pos == (unsigned int)iter->ifc.ifc_len) {
+#ifdef __linux
+ return (linux_if_inet6_current(iter));
+#else
+ return (ISC_R_NOMORE);
+#endif
+ }
+
+ INSIST( iter->pos < (unsigned int) iter->ifc.ifc_len);
+
+ ifrp = (void *)((char *) iter->ifc.ifc_req + iter->pos);
+
+ memset(&ifreq, 0, sizeof(ifreq));
+ memcpy(&ifreq, ifrp, sizeof(ifreq));
+
+ family = ifreq.ifr_addr.sa_family;
+#if defined(ISC_PLATFORM_HAVEIPV6)
+ if (family != AF_INET && family != AF_INET6)
+#else
+ if (family != AF_INET)
+#endif
+ return (ISC_R_IGNORE);
+
+ memset(&iter->current, 0, sizeof(iter->current));
+ iter->current.af = family;
+
+ INSIST(sizeof(ifreq.ifr_name) <= sizeof(iter->current.name));
+ memset(iter->current.name, 0, sizeof(iter->current.name));
+ memcpy(iter->current.name, ifreq.ifr_name, sizeof(ifreq.ifr_name));
+
+ get_addr(family, &iter->current.address,
+ (struct sockaddr *)&ifrp->ifr_addr, ifreq.ifr_name);
+
+ /*
+ * If the interface does not have a address ignore it.
+ */
+ switch (family) {
+ case AF_INET:
+ if (iter->current.address.type.in.s_addr == htonl(INADDR_ANY))
+ return (ISC_R_IGNORE);
+ break;
+ case AF_INET6:
+ if (memcmp(&iter->current.address.type.in6, &in6addr_any,
+ sizeof(in6addr_any)) == 0)
+ return (ISC_R_IGNORE);
+ break;
+ }
+
+ /*
+ * Get interface flags.
+ */
+
+ iter->current.flags = 0;
+
+ /*
+ * Ignore the HP/UX warning about "integer overflow during
+ * conversion. It comes from its own macro definition,
+ * and is really hard to shut up.
+ */
+ if (isc_ioctl(iter->socket, SIOCGIFFLAGS, (char *) &ifreq) < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "%s: getting interface flags: %s",
+ ifreq.ifr_name, strbuf);
+ return (ISC_R_IGNORE);
+ }
+
+ if ((ifreq.ifr_flags & IFF_UP) != 0)
+ iter->current.flags |= INTERFACE_F_UP;
+
+#ifdef IFF_POINTOPOINT
+ if ((ifreq.ifr_flags & IFF_POINTOPOINT) != 0)
+ iter->current.flags |= INTERFACE_F_POINTTOPOINT;
+#endif
+
+ if ((ifreq.ifr_flags & IFF_LOOPBACK) != 0)
+ iter->current.flags |= INTERFACE_F_LOOPBACK;
+
+ if ((ifreq.ifr_flags & IFF_BROADCAST) != 0)
+ iter->current.flags |= INTERFACE_F_BROADCAST;
+
+#ifdef IFF_MULTICAST
+ if ((ifreq.ifr_flags & IFF_MULTICAST) != 0)
+ iter->current.flags |= INTERFACE_F_MULTICAST;
+#endif
+
+ if (family == AF_INET)
+ goto inet;
+
+#if !defined(ISC_PLATFORM_HAVEIF_LADDRREQ) && defined(SIOCGLIFADDR)
+ memset(&lifreq, 0, sizeof(lifreq));
+ memcpy(lifreq.lifr_name, iter->current.name, sizeof(lifreq.lifr_name));
+ memcpy(&lifreq.lifr_addr, &iter->current.address.type.in6,
+ sizeof(iter->current.address.type.in6));
+
+ if (isc_ioctl(iter->socket, SIOCGLIFADDR, &lifreq) < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "%s: getting interface address: %s",
+ ifreq.ifr_name, strbuf);
+ return (ISC_R_IGNORE);
+ }
+ prefixlen = lifreq.lifr_addrlen;
+#else
+ isc_netaddr_format(&iter->current.address, sabuf, sizeof(sabuf));
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_INTERFACE,
+ ISC_LOG_INFO,
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_IFITERIOCTL,
+ ISC_MSG_GETIFCONFIG,
+ "prefix length for %s is unknown "
+ "(assume 128)"), sabuf);
+ prefixlen = 128;
+#endif
+
+ /*
+ * Netmask already zeroed.
+ */
+ iter->current.netmask.family = family;
+ for (i = 0; i < 16; i++) {
+ if (prefixlen > 8) {
+ bits = 0;
+ prefixlen -= 8;
+ } else {
+ bits = 8 - prefixlen;
+ prefixlen = 0;
+ }
+ iter->current.netmask.type.in6.s6_addr[i] = (~0 << bits) & 0xff;
+ }
+#ifdef ISC_PLATFORM_HAVEIFNAMETOINDEX
+ iter->current.ifindex = if_nametoindex(iter->current.name);
+#endif
+ return (ISC_R_SUCCESS);
+
+ inet:
+ if (family != AF_INET)
+ return (ISC_R_IGNORE);
+#ifdef IFF_POINTOPOINT
+ /*
+ * If the interface is point-to-point, get the destination address.
+ */
+ if ((iter->current.flags & INTERFACE_F_POINTTOPOINT) != 0) {
+ /*
+ * Ignore the HP/UX warning about "integer overflow during
+ * conversion. It comes from its own macro definition,
+ * and is really hard to shut up.
+ */
+ if (isc_ioctl(iter->socket, SIOCGIFDSTADDR, (char *)&ifreq)
+ < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_IFITERIOCTL,
+ ISC_MSG_GETDESTADDR,
+ "%s: getting "
+ "destination address: %s"),
+ ifreq.ifr_name, strbuf);
+ return (ISC_R_IGNORE);
+ }
+ get_addr(family, &iter->current.dstaddress,
+ (struct sockaddr *)&ifreq.ifr_dstaddr, ifreq.ifr_name);
+ }
+#endif
+
+ if ((iter->current.flags & INTERFACE_F_BROADCAST) != 0) {
+ /*
+ * Ignore the HP/UX warning about "integer overflow during
+ * conversion. It comes from its own macro definition,
+ * and is really hard to shut up.
+ */
+ if (isc_ioctl(iter->socket, SIOCGIFBRDADDR, (char *)&ifreq)
+ < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_IFITERIOCTL,
+ ISC_MSG_GETBCSTADDR,
+ "%s: getting "
+ "broadcast address: %s"),
+ ifreq.ifr_name, strbuf);
+ return (ISC_R_IGNORE);
+ }
+ get_addr(family, &iter->current.broadcast,
+ (struct sockaddr *)&ifreq.ifr_broadaddr, ifreq.ifr_name);
+ }
+
+ /*
+ * Get the network mask.
+ */
+ memset(&ifreq, 0, sizeof(ifreq));
+ memcpy(&ifreq, ifrp, sizeof(ifreq));
+ /*
+ * Ignore the HP/UX warning about "integer overflow during
+ * conversion. It comes from its own macro definition,
+ * and is really hard to shut up.
+ */
+ if (isc_ioctl(iter->socket, SIOCGIFNETMASK, (char *)&ifreq) < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_IFITERIOCTL,
+ ISC_MSG_GETNETMASK,
+ "%s: getting netmask: %s"),
+ ifreq.ifr_name, strbuf);
+ return (ISC_R_IGNORE);
+ }
+ get_addr(family, &iter->current.netmask,
+ (struct sockaddr *)&ifreq.ifr_addr, ifreq.ifr_name);
+#ifdef ISC_PLATFORM_HAVEIFNAMETOINDEX
+ iter->current.ifindex = if_nametoindex(iter->current.name);
+#endif
+ return (ISC_R_SUCCESS);
+}
+
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
+static isc_result_t
+internal_current6(isc_interfaceiter_t *iter) {
+ struct LIFREQ *ifrp;
+ struct LIFREQ lifreq;
+ int family;
+ char strbuf[ISC_STRERRORSIZE];
+ int fd;
+
+ REQUIRE(VALID_IFITER(iter));
+ if (iter->result6 != ISC_R_SUCCESS)
+ return (iter->result6);
+ REQUIRE(iter->pos6 < (unsigned int) iter->lifc.lifc_len);
+
+ ifrp = (void *)((char *)iter->lifc.lifc_req + iter->pos6);
+
+ memset(&lifreq, 0, sizeof(lifreq));
+ memcpy(&lifreq, ifrp, sizeof(lifreq));
+
+ family = lifreq.lifr_addr.ss_family;
+#ifdef ISC_PLATFORM_HAVEIPV6
+ if (family != AF_INET && family != AF_INET6)
+#else
+ if (family != AF_INET)
+#endif
+ return (ISC_R_IGNORE);
+
+ memset(&iter->current, 0, sizeof(iter->current));
+ iter->current.af = family;
+
+ INSIST(sizeof(lifreq.lifr_name) <= sizeof(iter->current.name));
+ memset(iter->current.name, 0, sizeof(iter->current.name));
+ memcpy(iter->current.name, lifreq.lifr_name, sizeof(lifreq.lifr_name));
+
+ get_addr(family, &iter->current.address,
+ (struct sockaddr *)&lifreq.lifr_addr, lifreq.lifr_name);
+
+ if (isc_netaddr_islinklocal(&iter->current.address))
+ isc_netaddr_setzone(&iter->current.address,
+ (isc_uint32_t)lifreq.lifr_index);
+
+ /*
+ * If the interface does not have a address ignore it.
+ */
+ switch (family) {
+ case AF_INET:
+ if (iter->current.address.type.in.s_addr == htonl(INADDR_ANY))
+ return (ISC_R_IGNORE);
+ break;
+ case AF_INET6:
+ if (memcmp(&iter->current.address.type.in6, &in6addr_any,
+ sizeof(in6addr_any)) == 0)
+ return (ISC_R_IGNORE);
+ break;
+ }
+
+ /*
+ * Get interface flags.
+ */
+
+ iter->current.flags = 0;
+
+ if (family == AF_INET6)
+ fd = iter->socket6;
+ else
+ fd = iter->socket;
+
+ /*
+ * Ignore the HP/UX warning about "integer overflow during
+ * conversion. It comes from its own macro definition,
+ * and is really hard to shut up.
+ */
+ if (isc_ioctl(fd, SIOCGLIFFLAGS, (char *) &lifreq) < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "%s: getting interface flags: %s",
+ lifreq.lifr_name, strbuf);
+ return (ISC_R_IGNORE);
+ }
+
+ if ((lifreq.lifr_flags & IFF_UP) != 0)
+ iter->current.flags |= INTERFACE_F_UP;
+
+#ifdef IFF_POINTOPOINT
+ if ((lifreq.lifr_flags & IFF_POINTOPOINT) != 0)
+ iter->current.flags |= INTERFACE_F_POINTTOPOINT;
+#endif
+
+ if ((lifreq.lifr_flags & IFF_LOOPBACK) != 0)
+ iter->current.flags |= INTERFACE_F_LOOPBACK;
+
+ if ((lifreq.lifr_flags & IFF_BROADCAST) != 0) {
+ iter->current.flags |= INTERFACE_F_BROADCAST;
+ }
+
+#ifdef IFF_MULTICAST
+ if ((lifreq.lifr_flags & IFF_MULTICAST) != 0) {
+ iter->current.flags |= INTERFACE_F_MULTICAST;
+ }
+#endif
+
+#ifdef IFF_POINTOPOINT
+ /*
+ * If the interface is point-to-point, get the destination address.
+ */
+ if ((iter->current.flags & INTERFACE_F_POINTTOPOINT) != 0) {
+ /*
+ * Ignore the HP/UX warning about "integer overflow during
+ * conversion. It comes from its own macro definition,
+ * and is really hard to shut up.
+ */
+ if (isc_ioctl(fd, SIOCGLIFDSTADDR, (char *)&lifreq)
+ < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_IFITERIOCTL,
+ ISC_MSG_GETDESTADDR,
+ "%s: getting "
+ "destination address: %s"),
+ lifreq.lifr_name, strbuf);
+ return (ISC_R_IGNORE);
+ }
+ get_addr(family, &iter->current.dstaddress,
+ (struct sockaddr *)&lifreq.lifr_dstaddr,
+ lifreq.lifr_name);
+ }
+#endif
+
+#ifdef SIOCGLIFBRDADDR
+ if ((iter->current.flags & INTERFACE_F_BROADCAST) != 0) {
+ /*
+ * Ignore the HP/UX warning about "integer overflow during
+ * conversion. It comes from its own macro definition,
+ * and is really hard to shut up.
+ */
+ if (isc_ioctl(iter->socket, SIOCGLIFBRDADDR, (char *)&lifreq)
+ < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_IFITERIOCTL,
+ ISC_MSG_GETBCSTADDR,
+ "%s: getting "
+ "broadcast address: %s"),
+ lifreq.lifr_name, strbuf);
+ return (ISC_R_IGNORE);
+ }
+ get_addr(family, &iter->current.broadcast,
+ (struct sockaddr *)&lifreq.lifr_broadaddr,
+ lifreq.lifr_name);
+ }
+#endif /* SIOCGLIFBRDADDR */
+
+ /*
+ * Get the network mask. Netmask already zeroed.
+ */
+ memset(&lifreq, 0, sizeof(lifreq));
+ memcpy(&lifreq, ifrp, sizeof(lifreq));
+
+#ifdef lifr_addrlen
+ /*
+ * Special case: if the system provides lifr_addrlen member, the
+ * netmask of an IPv6 address can be derived from the length, since
+ * an IPv6 address always has a contiguous mask.
+ */
+ if (family == AF_INET6) {
+ int i, bits;
+
+ iter->current.netmask.family = family;
+ for (i = 0; i < lifreq.lifr_addrlen; i += 8) {
+ bits = lifreq.lifr_addrlen - i;
+ bits = (bits < 8) ? (8 - bits) : 0;
+ iter->current.netmask.type.in6.s6_addr[i / 8] =
+ (~0 << bits) & 0xff;
+ }
+#ifdef ISC_PLATFORM_HAVEIFNAMETOINDEX
+ iter->current.ifindex = if_nametoindex(iter->current.name);
+#endif
+ return (ISC_R_SUCCESS);
+ }
+#endif
+
+ /*
+ * Ignore the HP/UX warning about "integer overflow during
+ * conversion. It comes from its own macro definition,
+ * and is really hard to shut up.
+ */
+ if (isc_ioctl(fd, SIOCGLIFNETMASK, (char *)&lifreq) < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_IFITERIOCTL,
+ ISC_MSG_GETNETMASK,
+ "%s: getting netmask: %s"),
+ lifreq.lifr_name, strbuf);
+ return (ISC_R_IGNORE);
+ }
+ get_addr(family, &iter->current.netmask,
+ (struct sockaddr *)&lifreq.lifr_addr, lifreq.lifr_name);
+
+#ifdef ISC_PLATFORM_HAVEIFNAMETOINDEX
+ iter->current.ifindex = if_nametoindex(iter->current.name);
+#endif
+ return (ISC_R_SUCCESS);
+}
+#endif
+
+static isc_result_t
+internal_current(isc_interfaceiter_t *iter) {
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
+ if (iter->mode == 6) {
+ iter->result6 = internal_current6(iter);
+ if (iter->result6 != ISC_R_NOMORE)
+ return (iter->result6);
+ }
+#endif
+#ifdef HAVE_TRUCLUSTER
+ if (!iter->clua_done)
+ return(internal_current_clusteralias(iter));
+#endif
+ return (internal_current4(iter));
+}
+
+/*
+ * Step the iterator to the next interface. Unlike
+ * isc_interfaceiter_next(), this may leave the iterator
+ * positioned on an interface that will ultimately
+ * be ignored. Return ISC_R_NOMORE if there are no more
+ * interfaces, otherwise ISC_R_SUCCESS.
+ */
+static isc_result_t
+internal_next4(isc_interfaceiter_t *iter) {
+#ifdef ISC_PLATFORM_HAVESALEN
+ struct ifreq *ifrp;
+#endif
+
+ if (iter->pos < (unsigned int) iter->ifc.ifc_len) {
+#ifdef ISC_PLATFORM_HAVESALEN
+ ifrp = (struct ifreq *)((char *) iter->ifc.ifc_req + iter->pos);
+
+ if (ifrp->ifr_addr.sa_len > sizeof(struct sockaddr))
+ iter->pos += sizeof(ifrp->ifr_name) +
+ ifrp->ifr_addr.sa_len;
+ else
+#endif
+ iter->pos += sizeof(struct ifreq);
+
+ } else {
+ INSIST(iter->pos == (unsigned int) iter->ifc.ifc_len);
+#ifdef __linux
+ return (linux_if_inet6_next(iter));
+#else
+ return (ISC_R_NOMORE);
+#endif
+ }
+ return (ISC_R_SUCCESS);
+}
+
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
+static isc_result_t
+internal_next6(isc_interfaceiter_t *iter) {
+#ifdef ISC_PLATFORM_HAVESALEN
+ struct LIFREQ *ifrp;
+#endif
+
+ if (iter->result6 != ISC_R_SUCCESS && iter->result6 != ISC_R_IGNORE)
+ return (iter->result6);
+
+ REQUIRE(iter->pos6 < (unsigned int) iter->lifc.lifc_len);
+
+#ifdef ISC_PLATFORM_HAVESALEN
+ ifrp = (struct LIFREQ *)((char *) iter->lifc.lifc_req + iter->pos6);
+
+ if (ifrp->lifr_addr.sa_len > sizeof(struct sockaddr))
+ iter->pos6 += sizeof(ifrp->lifr_name) + ifrp->lifr_addr.sa_len;
+ else
+#endif
+ iter->pos6 += sizeof(struct LIFREQ);
+
+ if (iter->pos6 >= (unsigned int) iter->lifc.lifc_len)
+ return (ISC_R_NOMORE);
+
+ return (ISC_R_SUCCESS);
+}
+#endif
+
+static isc_result_t
+internal_next(isc_interfaceiter_t *iter) {
+#ifdef HAVE_TRUCLUSTER
+ int clua_result;
+#endif
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
+ if (iter->mode == 6) {
+ iter->result6 = internal_next6(iter);
+ if (iter->result6 != ISC_R_NOMORE)
+ return (iter->result6);
+ if (iter->first6) {
+ iter->first6 = ISC_FALSE;
+ return (ISC_R_SUCCESS);
+ }
+ }
+#endif
+#ifdef HAVE_TRUCLUSTER
+ if (!iter->clua_done) {
+ clua_result = clua_getaliasaddress(&iter->clua_sa,
+ &iter->clua_context);
+ if (clua_result != CLUA_SUCCESS)
+ iter->clua_done = ISC_TRUE;
+ return (ISC_R_SUCCESS);
+ }
+#endif
+ return (internal_next4(iter));
+}
+
+static void
+internal_destroy(isc_interfaceiter_t *iter) {
+ (void) close(iter->socket);
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
+ if (iter->socket6 != -1)
+ (void) close(iter->socket6);
+ if (iter->buf6 != NULL) {
+ isc_mem_put(iter->mctx, iter->buf6, iter->bufsize6);
+ }
+#endif
+#ifdef __linux
+ if (iter->proc != NULL)
+ fclose(iter->proc);
+#endif
+}
+
+static
+void internal_first(isc_interfaceiter_t *iter) {
+#ifdef HAVE_TRUCLUSTER
+ int clua_result;
+#endif
+ iter->pos = 0;
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
+ iter->pos6 = 0;
+ if (iter->result6 == ISC_R_NOMORE)
+ iter->result6 = ISC_R_SUCCESS;
+ iter->first6 = ISC_TRUE;
+#endif
+#ifdef HAVE_TRUCLUSTER
+ iter->clua_context = 0;
+ clua_result = clua_getaliasaddress(&iter->clua_sa,
+ &iter->clua_context);
+ iter->clua_done = ISC_TF(clua_result != CLUA_SUCCESS);
+#endif
+#ifdef __linux
+ linux_if_inet6_first(iter);
+#endif
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/include/isc/dir.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/include/isc/dir.h
new file mode 100644
index 0000000..e4a2ad0
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/include/isc/dir.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: dir.h,v 1.21 2007/06/19 23:47:19 tbox Exp $ */
+
+/* Principal Authors: DCL */
+
+#ifndef ISC_DIR_H
+#define ISC_DIR_H 1
+
+/*! \file */
+
+#include <sys/types.h> /* Required on some systems. */
+#include <dirent.h>
+
+#include <isc/lang.h>
+#include <isc/result.h>
+
+#define ISC_DIR_NAMEMAX 256
+#define ISC_DIR_PATHMAX 1024
+
+/*% Directory Entry */
+typedef struct isc_direntry {
+ /*!
+ * Ideally, this should be NAME_MAX, but AIX does not define it by
+ * default and dynamically allocating the space based on pathconf()
+ * complicates things undesirably, as does adding special conditionals
+ * just for AIX. So a comfortably sized buffer is chosen instead.
+ */
+ char name[ISC_DIR_NAMEMAX];
+ unsigned int length;
+} isc_direntry_t;
+
+/*% Directory */
+typedef struct isc_dir {
+ unsigned int magic;
+ /*!
+ * As with isc_direntry_t->name, making this "right" for all systems
+ * is slightly problematic because AIX does not define PATH_MAX.
+ */
+ char dirname[ISC_DIR_PATHMAX];
+ isc_direntry_t entry;
+ DIR * handle;
+} isc_dir_t;
+
+ISC_LANG_BEGINDECLS
+
+void
+isc_dir_init(isc_dir_t *dir);
+
+isc_result_t
+isc_dir_open(isc_dir_t *dir, const char *dirname);
+
+isc_result_t
+isc_dir_read(isc_dir_t *dir);
+
+isc_result_t
+isc_dir_reset(isc_dir_t *dir);
+
+void
+isc_dir_close(isc_dir_t *dir);
+
+isc_result_t
+isc_dir_chdir(const char *dirname);
+
+isc_result_t
+isc_dir_chroot(const char *dirname);
+
+isc_result_t
+isc_dir_createunique(char *templet);
+/*!<
+ * Use a templet (such as from isc_file_mktemplate()) to create a uniquely
+ * named, empty directory. The templet string is modified in place.
+ * If result == ISC_R_SUCCESS, it is the name of the directory that was
+ * created.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_DIR_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/include/isc/int.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/include/isc/int.h
new file mode 100644
index 0000000..73feb3b
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/include/isc/int.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: int.h,v 1.16 2007/06/19 23:47:19 tbox Exp $ */
+
+#ifndef ISC_INT_H
+#define ISC_INT_H 1
+
+/*! \file */
+
+typedef char isc_int8_t;
+typedef unsigned char isc_uint8_t;
+typedef short isc_int16_t;
+typedef unsigned short isc_uint16_t;
+typedef int isc_int32_t;
+typedef unsigned int isc_uint32_t;
+typedef long long isc_int64_t;
+typedef unsigned long long isc_uint64_t;
+
+#define ISC_INT8_MIN -128
+#define ISC_INT8_MAX 127
+#define ISC_UINT8_MAX 255
+
+#define ISC_INT16_MIN -32768
+#define ISC_INT16_MAX 32767
+#define ISC_UINT16_MAX 65535
+
+/*%
+ * Note that "int" is 32 bits on all currently supported Unix-like operating
+ * systems, but "long" can be either 32 bits or 64 bits, thus the 32 bit
+ * constants are not qualified with "L".
+ */
+#define ISC_INT32_MIN -2147483648
+#define ISC_INT32_MAX 2147483647
+#define ISC_UINT32_MAX 4294967295U
+
+#define ISC_INT64_MIN -9223372036854775808LL
+#define ISC_INT64_MAX 9223372036854775807LL
+#define ISC_UINT64_MAX 18446744073709551615ULL
+
+#endif /* ISC_INT_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/include/isc/keyboard.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/include/isc/keyboard.h
new file mode 100644
index 0000000..43f5e7e
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/include/isc/keyboard.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: keyboard.h,v 1.11 2007/06/19 23:47:19 tbox Exp $ */
+
+#ifndef ISC_KEYBOARD_H
+#define ISC_KEYBOARD_H 1
+
+/*! \file */
+
+#include <termios.h>
+
+#include <isc/lang.h>
+#include <isc/result.h>
+
+ISC_LANG_BEGINDECLS
+
+typedef struct {
+ int fd;
+ struct termios saved_mode;
+ isc_result_t result;
+} isc_keyboard_t;
+
+isc_result_t
+isc_keyboard_open(isc_keyboard_t *keyboard);
+
+isc_result_t
+isc_keyboard_close(isc_keyboard_t *keyboard, unsigned int sleepseconds);
+
+isc_result_t
+isc_keyboard_getchar(isc_keyboard_t *keyboard, unsigned char *cp);
+
+isc_boolean_t
+isc_keyboard_canceled(isc_keyboard_t *keyboard);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_KEYBOARD_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/include/isc/net.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/include/isc/net.h
new file mode 100644
index 0000000..37a0f3b
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/include/isc/net.h
@@ -0,0 +1,364 @@
+/*
+ * Copyright (C) 2004, 2005, 2007, 2008, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+#ifndef ISC_NET_H
+#define ISC_NET_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file
+ * \brief
+ * Basic Networking Types
+ *
+ * This module is responsible for defining the following basic networking
+ * types:
+ *
+ *\li struct in_addr
+ *\li struct in6_addr
+ *\li struct in6_pktinfo
+ *\li struct sockaddr
+ *\li struct sockaddr_in
+ *\li struct sockaddr_in6
+ *\li in_port_t
+ *
+ * It ensures that the AF_ and PF_ macros are defined.
+ *
+ * It declares ntoh[sl]() and hton[sl]().
+ *
+ * It declares inet_aton(), inet_ntop(), and inet_pton().
+ *
+ * It ensures that #INADDR_LOOPBACK, #INADDR_ANY, #IN6ADDR_ANY_INIT,
+ * in6addr_any, and in6addr_loopback are available.
+ *
+ * It ensures that IN_MULTICAST() is available to check for multicast
+ * addresses.
+ *
+ * MP:
+ *\li No impact.
+ *
+ * Reliability:
+ *\li No anticipated impact.
+ *
+ * Resources:
+ *\li N/A.
+ *
+ * Security:
+ *\li No anticipated impact.
+ *
+ * Standards:
+ *\li BSD Socket API
+ *\li RFC2553
+ */
+
+/***
+ *** Imports.
+ ***/
+#include <isc/platform.h>
+
+#include <sys/types.h>
+#include <sys/socket.h> /* Contractual promise. */
+
+#include <net/if.h>
+
+#include <netinet/in.h> /* Contractual promise. */
+#include <arpa/inet.h> /* Contractual promise. */
+#ifdef ISC_PLATFORM_NEEDNETINETIN6H
+#include <netinet/in6.h> /* Required on UnixWare. */
+#endif
+#ifdef ISC_PLATFORM_NEEDNETINET6IN6H
+#include <netinet6/in6.h> /* Required on BSD/OS for in6_pktinfo. */
+#endif
+
+#ifndef ISC_PLATFORM_HAVEIPV6
+#include <isc/ipv6.h> /* Contractual promise. */
+#endif
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+#ifdef ISC_PLATFORM_HAVEINADDR6
+#define in6_addr in_addr6 /*%< Required for pre RFC2133 implementations. */
+#endif
+
+#ifdef ISC_PLATFORM_HAVEIPV6
+#ifndef IN6ADDR_ANY_INIT
+#ifdef s6_addr
+/*%
+ * Required for some pre RFC2133 implementations.
+ * IN6ADDR_ANY_INIT and IN6ADDR_LOOPBACK_INIT were added in
+ * draft-ietf-ipngwg-bsd-api-04.txt or draft-ietf-ipngwg-bsd-api-05.txt.
+ * If 's6_addr' is defined then assume that there is a union and three
+ * levels otherwise assume two levels required.
+ */
+#define IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }
+#else
+#define IN6ADDR_ANY_INIT { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } }
+#endif
+#endif
+
+#ifndef IN6ADDR_LOOPBACK_INIT
+#ifdef s6_addr
+/*% IPv6 address loopback init */
+#define IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }
+#else
+#define IN6ADDR_LOOPBACK_INIT { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } }
+#endif
+#endif
+
+#ifndef IN6_IS_ADDR_V4MAPPED
+/*% Is IPv6 address V4 mapped? */
+#define IN6_IS_ADDR_V4MAPPED(x) \
+ (memcmp((x)->s6_addr, in6addr_any.s6_addr, 10) == 0 && \
+ (x)->s6_addr[10] == 0xff && (x)->s6_addr[11] == 0xff)
+#endif
+
+#ifndef IN6_IS_ADDR_V4COMPAT
+/*% Is IPv6 address V4 compatible? */
+#define IN6_IS_ADDR_V4COMPAT(x) \
+ (memcmp((x)->s6_addr, in6addr_any.s6_addr, 12) == 0 && \
+ ((x)->s6_addr[12] != 0 || (x)->s6_addr[13] != 0 || \
+ (x)->s6_addr[14] != 0 || \
+ ((x)->s6_addr[15] != 0 && (x)->s6_addr[15] != 1)))
+#endif
+
+#ifndef IN6_IS_ADDR_MULTICAST
+/*% Is IPv6 address multicast? */
+#define IN6_IS_ADDR_MULTICAST(a) ((a)->s6_addr[0] == 0xff)
+#endif
+
+#ifndef IN6_IS_ADDR_LINKLOCAL
+/*% Is IPv6 address linklocal? */
+#define IN6_IS_ADDR_LINKLOCAL(a) \
+ (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0x80))
+#endif
+
+#ifndef IN6_IS_ADDR_SITELOCAL
+/*% is IPv6 address sitelocal? */
+#define IN6_IS_ADDR_SITELOCAL(a) \
+ (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0xc0))
+#endif
+
+
+#ifndef IN6_IS_ADDR_LOOPBACK
+/*% is IPv6 address loopback? */
+#define IN6_IS_ADDR_LOOPBACK(x) \
+ (memcmp((x)->s6_addr, in6addr_loopback.s6_addr, 16) == 0)
+#endif
+#endif
+
+#ifndef AF_INET6
+/*% IPv6 */
+#define AF_INET6 99
+#endif
+
+#ifndef PF_INET6
+/*% IPv6 */
+#define PF_INET6 AF_INET6
+#endif
+
+#ifndef INADDR_LOOPBACK
+/*% inaddr loopback */
+#define INADDR_LOOPBACK 0x7f000001UL
+#endif
+
+#ifndef ISC_PLATFORM_HAVEIN6PKTINFO
+/*% IPv6 packet info */
+struct in6_pktinfo {
+ struct in6_addr ipi6_addr; /*%< src/dst IPv6 address */
+ unsigned int ipi6_ifindex; /*%< send/recv interface index */
+};
+#endif
+
+#if defined(ISC_PLATFORM_NEEDIN6ADDRANY)
+extern const struct in6_addr isc_net_in6addrany;
+/*%
+ * Cope with a missing in6addr_any and in6addr_loopback.
+ */
+#define in6addr_any isc_net_in6addrany
+#endif
+
+#if defined(ISC_PLATFORM_HAVEIPV6) && defined(ISC_PLATFORM_NEEDIN6ADDRLOOPBACK)
+extern const struct in6_addr isc_net_in6addrloop;
+#define in6addr_loopback isc_net_in6addrloop
+#endif
+
+#ifdef ISC_PLATFORM_FIXIN6ISADDR
+#undef IN6_IS_ADDR_GEOGRAPHIC
+/*!
+ * \brief
+ * Fix UnixWare 7.1.1's broken IN6_IS_ADDR_* definitions.
+ */
+#define IN6_IS_ADDR_GEOGRAPHIC(a) (((a)->S6_un.S6_l[0] & 0xE0) == 0x80)
+#undef IN6_IS_ADDR_IPX
+#define IN6_IS_ADDR_IPX(a) (((a)->S6_un.S6_l[0] & 0xFE) == 0x04)
+#undef IN6_IS_ADDR_LINKLOCAL
+#define IN6_IS_ADDR_LINKLOCAL(a) (((a)->S6_un.S6_l[0] & 0xC0FF) == 0x80FE)
+#undef IN6_IS_ADDR_MULTICAST
+#define IN6_IS_ADDR_MULTICAST(a) (((a)->S6_un.S6_l[0] & 0xFF) == 0xFF)
+#undef IN6_IS_ADDR_NSAP
+#define IN6_IS_ADDR_NSAP(a) (((a)->S6_un.S6_l[0] & 0xFE) == 0x02)
+#undef IN6_IS_ADDR_PROVIDER
+#define IN6_IS_ADDR_PROVIDER(a) (((a)->S6_un.S6_l[0] & 0xE0) == 0x40)
+#undef IN6_IS_ADDR_SITELOCAL
+#define IN6_IS_ADDR_SITELOCAL(a) (((a)->S6_un.S6_l[0] & 0xC0FF) == 0xC0FE)
+#endif /* ISC_PLATFORM_FIXIN6ISADDR */
+
+#ifdef ISC_PLATFORM_NEEDPORTT
+/*%
+ * Ensure type in_port_t is defined.
+ */
+typedef isc_uint16_t in_port_t;
+#endif
+
+#ifndef MSG_TRUNC
+/*%
+ * If this system does not have MSG_TRUNC (as returned from recvmsg())
+ * ISC_PLATFORM_RECVOVERFLOW will be defined. This will enable the MSG_TRUNC
+ * faking code in socket.c.
+ */
+#define ISC_PLATFORM_RECVOVERFLOW
+#endif
+
+/*% IP address. */
+#define ISC__IPADDR(x) ((isc_uint32_t)htonl((isc_uint32_t)(x)))
+
+/*% Is IP address multicast? */
+#define ISC_IPADDR_ISMULTICAST(i) \
+ (((isc_uint32_t)(i) & ISC__IPADDR(0xf0000000)) \
+ == ISC__IPADDR(0xe0000000))
+
+#define ISC_IPADDR_ISEXPERIMENTAL(i) \
+ (((isc_uint32_t)(i) & ISC__IPADDR(0xf0000000)) \
+ == ISC__IPADDR(0xf0000000))
+
+/***
+ *** Functions.
+ ***/
+
+ISC_LANG_BEGINDECLS
+
+isc_result_t
+isc_net_probeipv4(void);
+/*%<
+ * Check if the system's kernel supports IPv4.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS IPv4 is supported.
+ *\li #ISC_R_NOTFOUND IPv4 is not supported.
+ *\li #ISC_R_DISABLED IPv4 is disabled.
+ *\li #ISC_R_UNEXPECTED
+ */
+
+isc_result_t
+isc_net_probeipv6(void);
+/*%<
+ * Check if the system's kernel supports IPv6.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS IPv6 is supported.
+ *\li #ISC_R_NOTFOUND IPv6 is not supported.
+ *\li #ISC_R_DISABLED IPv6 is disabled.
+ *\li #ISC_R_UNEXPECTED
+ */
+
+isc_result_t
+isc_net_probe_ipv6only(void);
+/*%<
+ * Check if the system's kernel supports the IPV6_V6ONLY socket option.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS the option is supported for both TCP and UDP.
+ *\li #ISC_R_NOTFOUND IPv6 itself or the option is not supported.
+ *\li #ISC_R_UNEXPECTED
+ */
+
+isc_result_t
+isc_net_probe_ipv6pktinfo(void);
+/*
+ * Check if the system's kernel supports the IPV6_(RECV)PKTINFO socket option
+ * for UDP sockets.
+ *
+ * Returns:
+ *
+ * \li #ISC_R_SUCCESS the option is supported.
+ * \li #ISC_R_NOTFOUND IPv6 itself or the option is not supported.
+ * \li #ISC_R_UNEXPECTED
+ */
+
+void
+isc_net_disableipv4(void);
+
+void
+isc_net_disableipv6(void);
+
+void
+isc_net_enableipv4(void);
+
+void
+isc_net_enableipv6(void);
+
+isc_result_t
+isc_net_probeunix(void);
+/*
+ * Returns whether UNIX domain sockets are supported.
+ */
+
+isc_result_t
+isc_net_getudpportrange(int af, in_port_t *low, in_port_t *high);
+/*%<
+ * Returns system's default range of ephemeral UDP ports, if defined.
+ * If the range is not available or unknown, ISC_NET_PORTRANGELOW and
+ * ISC_NET_PORTRANGEHIGH will be returned.
+ *
+ * Requires:
+ *
+ *\li 'low' and 'high' must be non NULL.
+ *
+ * Returns:
+ *
+ *\li *low and *high will be the ports specifying the low and high ends of
+ * the range.
+ */
+
+#ifdef ISC_PLATFORM_NEEDNTOP
+const char *
+isc_net_ntop(int af, const void *src, char *dst, size_t size);
+#define inet_ntop isc_net_ntop
+#endif
+
+#ifdef ISC_PLATFORM_NEEDPTON
+int
+isc_net_pton(int af, const char *src, void *dst);
+#undef inet_pton
+#define inet_pton isc_net_pton
+#endif
+
+int
+isc_net_aton(const char *cp, struct in_addr *addr);
+#undef inet_aton
+#define inet_aton isc_net_aton
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_NET_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/include/isc/offset.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/include/isc/offset.h
new file mode 100644
index 0000000..8bf3779
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/include/isc/offset.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: offset.h,v 1.17 2008/12/01 23:47:45 tbox Exp $ */
+
+#ifndef ISC_OFFSET_H
+#define ISC_OFFSET_H 1
+
+/*! \file
+ * \brief
+ * File offsets are operating-system dependent.
+ */
+#include <limits.h> /* Required for CHAR_BIT. */
+#include <sys/types.h>
+#include <stddef.h> /* For Linux Standard Base. */
+
+typedef off_t isc_offset_t;
+
+/*%
+ * POSIX says "Additionally, blkcnt_t and off_t are extended signed integral
+ * types", so the maximum value is all 1s except for the high bit.
+ * This definition is more complex than it really needs to be because it was
+ * crafted to keep both the SunOS 5.6 and the HP/UX 11 compilers quiet about
+ * integer overflow. For example, though this is equivalent to just left
+ * shifting 1 to the high bit and then inverting the bits, the SunOS compiler
+ * is unhappy about shifting a positive "1" to negative in a signed integer.
+ */
+#define ISC_OFFSET_MAXIMUM \
+ (~(((off_t)-1 >> (sizeof(off_t) * CHAR_BIT - 1)) \
+ << (sizeof(off_t) * CHAR_BIT - 1)))
+
+#endif /* ISC_OFFSET_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/include/isc/stat.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/include/isc/stat.h
new file mode 100644
index 0000000..b7a7986
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/include/isc/stat.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: stat.h,v 1.5 2007/06/19 23:47:19 tbox Exp $ */
+
+#ifndef ISC_STAT_H
+#define ISC_STAT_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*
+ * Portable netdb.h support.
+ *
+ * This module is responsible for defining S_IS??? macros.
+ *
+ * MP:
+ * No impact.
+ *
+ * Reliability:
+ * No anticipated impact.
+ *
+ * Resources:
+ * N/A.
+ *
+ * Security:
+ * No anticipated impact.
+ *
+ */
+
+/***
+ *** Imports.
+ ***/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#endif /* ISC_STAT_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/include/isc/stdtime.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/include/isc/stdtime.h
new file mode 100644
index 0000000..c4931bf
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/include/isc/stdtime.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2004, 2005, 2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+#ifndef ISC_STDTIME_H
+#define ISC_STDTIME_H 1
+
+/*! \file */
+
+#include <isc/lang.h>
+#include <isc/int.h>
+
+/*%
+ * It's public information that 'isc_stdtime_t' is an unsigned integral type.
+ * Applications that want maximum portability should not assume anything
+ * about its size.
+ */
+typedef isc_uint32_t isc_stdtime_t;
+
+/* but this flag helps... */
+#define STDTIME_ON_32BITS 1
+
+/*
+ * isc_stdtime32_t is a 32-bit version of isc_stdtime_t. A variable of this
+ * type should only be used as an opaque integer (e.g.,) to compare two
+ * time values.
+ */
+typedef isc_uint32_t isc_stdtime32_t;
+
+ISC_LANG_BEGINDECLS
+/* */
+void
+isc_stdtime_get(isc_stdtime_t *t);
+/*%<
+ * Set 't' to the number of seconds since 00:00:00 UTC, January 1, 1970.
+ *
+ * Requires:
+ *
+ *\li 't' is a valid pointer.
+ */
+
+#define isc_stdtime_convert32(t, t32p) (*(t32p) = t)
+/*
+ * Convert the standard time to its 32-bit version.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_STDTIME_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/include/isc/strerror.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/include/isc/strerror.h
new file mode 100644
index 0000000..899043b
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/include/isc/strerror.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: strerror.h,v 1.10 2008/12/01 23:47:45 tbox Exp $ */
+
+#ifndef ISC_STRERROR_H
+#define ISC_STRERROR_H
+
+/*! \file */
+
+#include <sys/types.h>
+
+#include <isc/lang.h>
+
+ISC_LANG_BEGINDECLS
+
+/*% String Error Size */
+#define ISC_STRERRORSIZE 128
+
+/*%
+ * Provide a thread safe wrapper to strerror().
+ *
+ * Requires:
+ * 'buf' to be non NULL.
+ */
+void
+isc__strerror(int num, char *buf, size_t bufsize);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_STRERROR_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/include/isc/time.h b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/include/isc/time.h
new file mode 100644
index 0000000..dc1cef9
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/include/isc/time.h
@@ -0,0 +1,334 @@
+/*
+ * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: time.h,v 1.40 2009/01/05 23:47:54 tbox Exp $ */
+
+#ifndef ISC_TIME_H
+#define ISC_TIME_H 1
+
+/*! \file */
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+/***
+ *** Intervals
+ ***/
+
+/*!
+ * \brief
+ * The contents of this structure are private, and MUST NOT be accessed
+ * directly by callers.
+ *
+ * The contents are exposed only to allow callers to avoid dynamic allocation.
+ */
+struct isc_interval {
+ unsigned int seconds;
+ unsigned int nanoseconds;
+};
+
+extern isc_interval_t *isc_interval_zero;
+
+ISC_LANG_BEGINDECLS
+
+void
+isc_interval_set(isc_interval_t *i,
+ unsigned int seconds, unsigned int nanoseconds);
+/*%<
+ * Set 'i' to a value representing an interval of 'seconds' seconds and
+ * 'nanoseconds' nanoseconds, suitable for use in isc_time_add() and
+ * isc_time_subtract().
+ *
+ * Requires:
+ *
+ *\li 't' is a valid pointer.
+ *\li nanoseconds < 1000000000.
+ */
+
+isc_boolean_t
+isc_interval_iszero(const isc_interval_t *i);
+/*%<
+ * Returns ISC_TRUE iff. 'i' is the zero interval.
+ *
+ * Requires:
+ *
+ *\li 'i' is a valid pointer.
+ */
+
+/***
+ *** Absolute Times
+ ***/
+
+/*%
+ * The contents of this structure are private, and MUST NOT be accessed
+ * directly by callers.
+ *
+ * The contents are exposed only to allow callers to avoid dynamic allocation.
+ */
+
+struct isc_time {
+ unsigned int seconds;
+ unsigned int nanoseconds;
+};
+
+extern isc_time_t *isc_time_epoch;
+
+void
+isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds);
+/*%<
+ * Set 't' to a value which represents the given number of seconds and
+ * nanoseconds since 00:00:00 January 1, 1970, UTC.
+ *
+ * Notes:
+ *\li The Unix version of this call is equivalent to:
+ *\code
+ * isc_time_settoepoch(t);
+ * isc_interval_set(i, seconds, nanoseconds);
+ * isc_time_add(t, i, t);
+ *\endcode
+ *
+ * Requires:
+ *\li 't' is a valid pointer.
+ *\li nanoseconds < 1000000000.
+ */
+
+void
+isc_time_settoepoch(isc_time_t *t);
+/*%<
+ * Set 't' to the time of the epoch.
+ *
+ * Notes:
+ *\li The date of the epoch is platform-dependent.
+ *
+ * Requires:
+ *
+ *\li 't' is a valid pointer.
+ */
+
+isc_boolean_t
+isc_time_isepoch(const isc_time_t *t);
+/*%<
+ * Returns ISC_TRUE iff. 't' is the epoch ("time zero").
+ *
+ * Requires:
+ *
+ *\li 't' is a valid pointer.
+ */
+
+isc_result_t
+isc_time_now(isc_time_t *t);
+/*%<
+ * Set 't' to the current absolute time.
+ *
+ * Requires:
+ *
+ *\li 't' is a valid pointer.
+ *
+ * Returns:
+ *
+ *\li Success
+ *\li Unexpected error
+ * Getting the time from the system failed.
+ *\li Out of range
+ * The time from the system is too large to be represented
+ * in the current definition of isc_time_t.
+ */
+
+isc_result_t
+isc_time_nowplusinterval(isc_time_t *t, const isc_interval_t *i);
+/*%<
+ * Set *t to the current absolute time + i.
+ *
+ * Note:
+ *\li This call is equivalent to:
+ *
+ *\code
+ * isc_time_now(t);
+ * isc_time_add(t, i, t);
+ *\endcode
+ *
+ * Requires:
+ *
+ *\li 't' and 'i' are valid pointers.
+ *
+ * Returns:
+ *
+ *\li Success
+ *\li Unexpected error
+ * Getting the time from the system failed.
+ *\li Out of range
+ * The interval added to the time from the system is too large to
+ * be represented in the current definition of isc_time_t.
+ */
+
+int
+isc_time_compare(const isc_time_t *t1, const isc_time_t *t2);
+/*%<
+ * Compare the times referenced by 't1' and 't2'
+ *
+ * Requires:
+ *
+ *\li 't1' and 't2' are valid pointers.
+ *
+ * Returns:
+ *
+ *\li -1 t1 < t2 (comparing times, not pointers)
+ *\li 0 t1 = t2
+ *\li 1 t1 > t2
+ */
+
+isc_result_t
+isc_time_add(const isc_time_t *t, const isc_interval_t *i, isc_time_t *result);
+/*%<
+ * Add 'i' to 't', storing the result in 'result'.
+ *
+ * Requires:
+ *
+ *\li 't', 'i', and 'result' are valid pointers.
+ *
+ * Returns:
+ *\li Success
+ *\li Out of range
+ * The interval added to the time is too large to
+ * be represented in the current definition of isc_time_t.
+ */
+
+isc_result_t
+isc_time_subtract(const isc_time_t *t, const isc_interval_t *i,
+ isc_time_t *result);
+/*%<
+ * Subtract 'i' from 't', storing the result in 'result'.
+ *
+ * Requires:
+ *
+ *\li 't', 'i', and 'result' are valid pointers.
+ *
+ * Returns:
+ *\li Success
+ *\li Out of range
+ * The interval is larger than the time since the epoch.
+ */
+
+isc_uint64_t
+isc_time_microdiff(const isc_time_t *t1, const isc_time_t *t2);
+/*%<
+ * Find the difference in microseconds between time t1 and time t2.
+ * t2 is the subtrahend of t1; ie, difference = t1 - t2.
+ *
+ * Requires:
+ *
+ *\li 't1' and 't2' are valid pointers.
+ *
+ * Returns:
+ *\li The difference of t1 - t2, or 0 if t1 <= t2.
+ */
+
+isc_uint32_t
+isc_time_seconds(const isc_time_t *t);
+/*%<
+ * Return the number of seconds since the epoch stored in a time structure.
+ *
+ * Requires:
+ *
+ *\li 't' is a valid pointer.
+ */
+
+isc_result_t
+isc_time_secondsastimet(const isc_time_t *t, time_t *secondsp);
+/*%<
+ * Ensure the number of seconds in an isc_time_t is representable by a time_t.
+ *
+ * Notes:
+ *\li The number of seconds stored in an isc_time_t might be larger
+ * than the number of seconds a time_t is able to handle. Since
+ * time_t is mostly opaque according to the ANSI/ISO standard
+ * (essentially, all you can be sure of is that it is an arithmetic type,
+ * not even necessarily integral), it can be tricky to ensure that
+ * the isc_time_t is in the range a time_t can handle. Use this
+ * function in place of isc_time_seconds() any time you need to set a
+ * time_t from an isc_time_t.
+ *
+ * Requires:
+ *\li 't' is a valid pointer.
+ *
+ * Returns:
+ *\li Success
+ *\li Out of range
+ */
+
+isc_uint32_t
+isc_time_nanoseconds(const isc_time_t *t);
+/*%<
+ * Return the number of nanoseconds stored in a time structure.
+ *
+ * Notes:
+ *\li This is the number of nanoseconds in excess of the number
+ * of seconds since the epoch; it will always be less than one
+ * full second.
+ *
+ * Requires:
+ *\li 't' is a valid pointer.
+ *
+ * Ensures:
+ *\li The returned value is less than 1*10^9.
+ */
+
+void
+isc_time_formattimestamp(const isc_time_t *t, char *buf, unsigned int len);
+/*%<
+ * Format the time 't' into the buffer 'buf' of length 'len',
+ * using a format like "30-Aug-2000 04:06:47.997" and the local time zone.
+ * If the text does not fit in the buffer, the result is indeterminate,
+ * but is always guaranteed to be null terminated.
+ *
+ * Requires:
+ *\li 'len' > 0
+ *\li 'buf' points to an array of at least len chars
+ *
+ */
+
+void
+isc_time_formathttptimestamp(const isc_time_t *t, char *buf, unsigned int len);
+/*%<
+ * Format the time 't' into the buffer 'buf' of length 'len',
+ * using a format like "Mon, 30 Aug 2000 04:06:47 GMT"
+ * If the text does not fit in the buffer, the result is indeterminate,
+ * but is always guaranteed to be null terminated.
+ *
+ * Requires:
+ *\li 'len' > 0
+ *\li 'buf' points to an array of at least len chars
+ *
+ */
+
+void
+isc_time_formatISO8601(const isc_time_t *t, char *buf, unsigned int len);
+/*%<
+ * Format the time 't' into the buffer 'buf' of length 'len',
+ * using the ISO8601 format: "yyyy-mm-ddThh:mm:ssZ"
+ * If the text does not fit in the buffer, the result is indeterminate,
+ * but is always guaranteed to be null terminated.
+ *
+ * Requires:
+ *\li 'len' > 0
+ *\li 'buf' points to an array of at least len chars
+ *
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_TIME_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/interfaceiter.c b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/interfaceiter.c
new file mode 100644
index 0000000..499dacb
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/interfaceiter.c
@@ -0,0 +1,329 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: interfaceiter.c,v 1.45 2008/12/01 03:51:47 marka Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#ifdef HAVE_SYS_SOCKIO_H
+#include <sys/sockio.h> /* Required for ifiter_ioctl.c. */
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <isc/interfaceiter.h>
+#include <isc/log.h>
+#include <isc/magic.h>
+#include <isc/mem.h>
+#include <isc/msgs.h>
+#include <isc/net.h>
+#include <isc/print.h>
+#include <isc/result.h>
+#include <isc/strerror.h>
+#include <isc/string.h>
+#include <isc/types.h>
+#include <isc/util.h>
+
+/* Must follow <isc/net.h>. */
+#ifdef HAVE_NET_IF6_H
+#include <net/if6.h>
+#endif
+#include <net/if.h>
+
+#ifdef HAVE_LINUX_IF_ADDR_H
+# include <linux/if_addr.h>
+#endif
+
+/* Common utility functions */
+
+/*%
+ * Extract the network address part from a "struct sockaddr".
+ * \brief
+ * The address family is given explicitly
+ * instead of using src->sa_family, because the latter does not work
+ * for copying a network mask obtained by SIOCGIFNETMASK (it does
+ * not have a valid address family).
+ */
+
+static void
+get_addr(unsigned int family, isc_netaddr_t *dst, struct sockaddr *src,
+ char *ifname)
+{
+ struct sockaddr_in6 *sa6;
+
+#if !defined(ISC_PLATFORM_HAVEIFNAMETOINDEX) || \
+ !defined(ISC_PLATFORM_HAVESCOPEID)
+ UNUSED(ifname);
+#endif
+
+ /* clear any remaining value for safety */
+ memset(dst, 0, sizeof(*dst));
+
+ dst->family = family;
+ switch (family) {
+ case AF_INET:
+ memcpy(&dst->type.in,
+ &((struct sockaddr_in *)(void *)src)->sin_addr,
+ sizeof(struct in_addr));
+ break;
+ case AF_INET6:
+ sa6 = (struct sockaddr_in6 *)(void *)src;
+ memcpy(&dst->type.in6, &sa6->sin6_addr,
+ sizeof(struct in6_addr));
+#ifdef ISC_PLATFORM_HAVESCOPEID
+ if (sa6->sin6_scope_id != 0)
+ isc_netaddr_setzone(dst, sa6->sin6_scope_id);
+ else {
+ /*
+ * BSD variants embed scope zone IDs in the 128bit
+ * address as a kernel internal form. Unfortunately,
+ * the embedded IDs are not hidden from applications
+ * when getting access to them by sysctl or ioctl.
+ * We convert the internal format to the pure address
+ * part and the zone ID part.
+ * Since multicast addresses should not appear here
+ * and they cannot be distinguished from netmasks,
+ * we only consider unicast link-local addresses.
+ */
+ if (IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr)) {
+ isc_uint16_t zone16;
+
+ memcpy(&zone16, &sa6->sin6_addr.s6_addr[2],
+ sizeof(zone16));
+ zone16 = ntohs(zone16);
+ if (zone16 != 0) {
+ /* the zone ID is embedded */
+ isc_netaddr_setzone(dst,
+ (isc_uint32_t)zone16);
+ dst->type.in6.s6_addr[2] = 0;
+ dst->type.in6.s6_addr[3] = 0;
+#ifdef ISC_PLATFORM_HAVEIFNAMETOINDEX
+ } else if (ifname != NULL) {
+ unsigned int zone;
+
+ /*
+ * sin6_scope_id is still not provided,
+ * but the corresponding interface name
+ * is know. Use the interface ID as
+ * the link ID.
+ */
+ zone = if_nametoindex(ifname);
+ if (zone != 0) {
+ isc_netaddr_setzone(dst,
+ (isc_uint32_t)zone);
+ }
+#endif
+ }
+ }
+ }
+#endif
+ break;
+ default:
+ INSIST(0);
+ break;
+ }
+}
+
+/*
+ * Include system-dependent code.
+ */
+
+#ifdef __linux
+#define ISC_IF_INET6_SZ \
+ sizeof("00000000000000000000000000000001 01 80 10 80 XXXXXXloXXXXXXXX\n")
+static isc_result_t linux_if_inet6_next(isc_interfaceiter_t *);
+static isc_result_t linux_if_inet6_current(isc_interfaceiter_t *);
+static void linux_if_inet6_first(isc_interfaceiter_t *iter);
+#endif
+
+#if HAVE_GETIFADDRS
+#include "ifiter_getifaddrs.c"
+#elif HAVE_IFLIST_SYSCTL
+#include "ifiter_sysctl.c"
+#else
+#include "ifiter_ioctl.c"
+#endif
+
+#ifdef __linux
+static void
+linux_if_inet6_first(isc_interfaceiter_t *iter) {
+ if (iter->proc != NULL) {
+ rewind(iter->proc);
+ (void)linux_if_inet6_next(iter);
+ } else
+ iter->valid = ISC_R_NOMORE;
+}
+
+static isc_result_t
+linux_if_inet6_next(isc_interfaceiter_t *iter) {
+ if (iter->proc != NULL &&
+ fgets(iter->entry, sizeof(iter->entry), iter->proc) != NULL)
+ iter->valid = ISC_R_SUCCESS;
+ else
+ iter->valid = ISC_R_NOMORE;
+ return (iter->valid);
+}
+
+static isc_result_t
+linux_if_inet6_current(isc_interfaceiter_t *iter) {
+ char address[33];
+ char name[IF_NAMESIZE+1];
+ struct in6_addr addr6;
+ unsigned int ifindex;
+ int prefix, scope, flags;
+ int res;
+ unsigned int i;
+
+ if (iter->valid != ISC_R_SUCCESS)
+ return (iter->valid);
+ if (iter->proc == NULL) {
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_INTERFACE, ISC_LOG_ERROR,
+ "/proc/net/if_inet6:iter->proc == NULL");
+ return (ISC_R_FAILURE);
+ }
+
+ res = sscanf(iter->entry, "%32[a-f0-9] %x %x %x %x %16s\n",
+ address, &ifindex, &prefix, &scope, &flags, name);
+ if (res != 6) {
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_INTERFACE, ISC_LOG_ERROR,
+ "/proc/net/if_inet6:sscanf() -> %d (expected 6)",
+ res);
+ return (ISC_R_FAILURE);
+ }
+ if (strlen(address) != 32) {
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_INTERFACE, ISC_LOG_ERROR,
+ "/proc/net/if_inet6:strlen(%s) != 32", address);
+ return (ISC_R_FAILURE);
+ }
+ /*
+ ** Ignore DAD addresses --
+ ** we can't bind to them until they are resolved
+ */
+#ifdef IFA_F_TENTATIVE
+ if (flags & IFA_F_TENTATIVE)
+ return (ISC_R_IGNORE);
+#endif
+
+ for (i = 0; i < 16; i++) {
+ unsigned char byte;
+ static const char hex[] = "0123456789abcdef";
+ byte = ((strchr(hex, address[i * 2]) - hex) << 4) |
+ (strchr(hex, address[i * 2 + 1]) - hex);
+ addr6.s6_addr[i] = byte;
+ }
+ iter->current.af = AF_INET6;
+ iter->current.flags = INTERFACE_F_UP;
+ isc_netaddr_fromin6(&iter->current.address, &addr6);
+ iter->current.ifindex = ifindex;
+ if (isc_netaddr_islinklocal(&iter->current.address)) {
+ isc_netaddr_setzone(&iter->current.address,
+ (isc_uint32_t)ifindex);
+ }
+ for (i = 0; i < 16; i++) {
+ if (prefix > 8) {
+ addr6.s6_addr[i] = 0xff;
+ prefix -= 8;
+ } else {
+ addr6.s6_addr[i] = (0xff << (8 - prefix)) & 0xff;
+ prefix = 0;
+ }
+ }
+ isc_netaddr_fromin6(&iter->current.netmask, &addr6);
+ strncpy(iter->current.name, name, sizeof(iter->current.name));
+ return (ISC_R_SUCCESS);
+}
+#endif
+
+/*
+ * The remaining code is common to the sysctl and ioctl case.
+ */
+
+isc_result_t
+isc_interfaceiter_current(isc_interfaceiter_t *iter,
+ isc_interface_t *ifdata)
+{
+ REQUIRE(iter->result == ISC_R_SUCCESS);
+ memcpy(ifdata, &iter->current, sizeof(*ifdata));
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_interfaceiter_first(isc_interfaceiter_t *iter) {
+ isc_result_t result;
+
+ REQUIRE(VALID_IFITER(iter));
+
+ internal_first(iter);
+ for (;;) {
+ result = internal_current(iter);
+ if (result != ISC_R_IGNORE)
+ break;
+ result = internal_next(iter);
+ if (result != ISC_R_SUCCESS)
+ break;
+ }
+ iter->result = result;
+ return (result);
+}
+
+isc_result_t
+isc_interfaceiter_next(isc_interfaceiter_t *iter) {
+ isc_result_t result;
+
+ REQUIRE(VALID_IFITER(iter));
+ REQUIRE(iter->result == ISC_R_SUCCESS);
+
+ for (;;) {
+ result = internal_next(iter);
+ if (result != ISC_R_SUCCESS)
+ break;
+ result = internal_current(iter);
+ if (result != ISC_R_IGNORE)
+ break;
+ }
+ iter->result = result;
+ return (result);
+}
+
+void
+isc_interfaceiter_destroy(isc_interfaceiter_t **iterp)
+{
+ isc_interfaceiter_t *iter;
+ REQUIRE(iterp != NULL);
+ iter = *iterp;
+ REQUIRE(VALID_IFITER(iter));
+
+ internal_destroy(iter);
+ if (iter->buf != NULL)
+ isc_mem_put(iter->mctx, iter->buf, iter->bufsize);
+
+ iter->magic = 0;
+ isc_mem_put(iter->mctx, iter, sizeof(*iter));
+ *iterp = NULL;
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/net.c b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/net.c
new file mode 100644
index 0000000..d28bc8e
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/net.c
@@ -0,0 +1,525 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (C) 2004, 2005, 2007, 2008, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+#include <config.h>
+
+#include <sys/types.h>
+
+#if defined(HAVE_SYS_SYSCTL_H)
+#if defined(HAVE_SYS_PARAM_H)
+#include <sys/param.h>
+#endif
+#include <sys/sysctl.h>
+#endif
+
+#include <errno.h>
+#include <unistd.h>
+
+#include <isc/log.h>
+#include <isc/msgs.h>
+#include <isc/net.h>
+#include <isc/once.h>
+#include <isc/strerror.h>
+#include <isc/string.h>
+#include <isc/util.h>
+
+/*%
+ * Definitions about UDP port range specification. This is a total mess of
+ * portability variants: some use sysctl (but the sysctl names vary), some use
+ * system-specific interfaces, some have the same interface for IPv4 and IPv6,
+ * some separate them, etc...
+ */
+
+/*%
+ * The last resort defaults: use all non well known port space
+ */
+#ifndef ISC_NET_PORTRANGELOW
+#define ISC_NET_PORTRANGELOW 1024
+#endif /* ISC_NET_PORTRANGELOW */
+#ifndef ISC_NET_PORTRANGEHIGH
+#define ISC_NET_PORTRANGEHIGH 65535
+#endif /* ISC_NET_PORTRANGEHIGH */
+
+#ifdef HAVE_SYSCTLBYNAME
+
+/*%
+ * sysctl variants
+ */
+#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__DragonFly__)
+#define USE_SYSCTL_PORTRANGE
+#define SYSCTL_V4PORTRANGE_LOW "net.inet.ip.portrange.hifirst"
+#define SYSCTL_V4PORTRANGE_HIGH "net.inet.ip.portrange.hilast"
+#define SYSCTL_V6PORTRANGE_LOW "net.inet.ip.portrange.hifirst"
+#define SYSCTL_V6PORTRANGE_HIGH "net.inet.ip.portrange.hilast"
+#endif
+
+#ifdef __NetBSD__
+#define USE_SYSCTL_PORTRANGE
+#define SYSCTL_V4PORTRANGE_LOW "net.inet.ip.anonportmin"
+#define SYSCTL_V4PORTRANGE_HIGH "net.inet.ip.anonportmax"
+#define SYSCTL_V6PORTRANGE_LOW "net.inet6.ip6.anonportmin"
+#define SYSCTL_V6PORTRANGE_HIGH "net.inet6.ip6.anonportmax"
+#endif
+
+#else /* !HAVE_SYSCTLBYNAME */
+
+#ifdef __OpenBSD__
+#define USE_SYSCTL_PORTRANGE
+#define SYSCTL_V4PORTRANGE_LOW { CTL_NET, PF_INET, IPPROTO_IP, \
+ IPCTL_IPPORT_HIFIRSTAUTO }
+#define SYSCTL_V4PORTRANGE_HIGH { CTL_NET, PF_INET, IPPROTO_IP, \
+ IPCTL_IPPORT_HILASTAUTO }
+/* Same for IPv6 */
+#define SYSCTL_V6PORTRANGE_LOW SYSCTL_V4PORTRANGE_LOW
+#define SYSCTL_V6PORTRANGE_HIGH SYSCTL_V4PORTRANGE_HIGH
+#endif
+
+#endif /* HAVE_SYSCTLBYNAME */
+
+#if defined(ISC_PLATFORM_NEEDIN6ADDRANY)
+const struct in6_addr isc_net_in6addrany = IN6ADDR_ANY_INIT;
+#endif
+
+#if defined(ISC_PLATFORM_HAVEIPV6)
+
+# if defined(ISC_PLATFORM_NEEDIN6ADDRLOOPBACK)
+const struct in6_addr isc_net_in6addrloop = IN6ADDR_LOOPBACK_INIT;
+# endif
+
+# if defined(WANT_IPV6)
+static isc_once_t once_ipv6only = ISC_ONCE_INIT;
+# endif
+
+# if defined(ISC_PLATFORM_HAVEIPV6) && \
+ defined(WANT_IPV6) && defined(ISC_PLATFORM_HAVEIN6PKTINFO)
+static isc_once_t once_ipv6pktinfo = ISC_ONCE_INIT;
+# endif
+#endif /* ISC_PLATFORM_HAVEIPV6 */
+
+static isc_once_t once = ISC_ONCE_INIT;
+
+static isc_result_t ipv4_result = ISC_R_NOTFOUND;
+static isc_result_t ipv6_result = ISC_R_NOTFOUND;
+static isc_result_t unix_result = ISC_R_NOTFOUND;
+static isc_result_t ipv6only_result = ISC_R_NOTFOUND;
+static isc_result_t ipv6pktinfo_result = ISC_R_NOTFOUND;
+
+static isc_result_t
+try_proto(int domain) {
+ int s;
+ isc_result_t result = ISC_R_SUCCESS;
+ char strbuf[ISC_STRERRORSIZE];
+
+ s = socket(domain, SOCK_STREAM, 0);
+ if (s == -1) {
+ switch (errno) {
+#ifdef EAFNOSUPPORT
+ case EAFNOSUPPORT:
+#endif
+#ifdef EPROTONOSUPPORT
+ case EPROTONOSUPPORT:
+#endif
+#ifdef EINVAL
+ case EINVAL:
+#endif
+ return (ISC_R_NOTFOUND);
+ default:
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "socket() %s: %s",
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_GENERAL,
+ ISC_MSG_FAILED,
+ "failed"),
+ strbuf);
+ return (ISC_R_UNEXPECTED);
+ }
+ }
+
+#ifdef ISC_PLATFORM_HAVEIPV6
+#ifdef WANT_IPV6
+#ifdef ISC_PLATFORM_HAVEIN6PKTINFO
+ if (domain == PF_INET6) {
+ struct sockaddr_in6 sin6;
+ GETSOCKNAME_SOCKLEN_TYPE len; /* NTP local change */
+
+ /*
+ * Check to see if IPv6 is broken, as is common on Linux.
+ */
+ len = sizeof(sin6);
+ if (getsockname(s, (struct sockaddr *)&sin6, &len) < 0)
+ {
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR,
+ "retrieving the address of an IPv6 "
+ "socket from the kernel failed.");
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR,
+ "IPv6 is not supported.");
+ result = ISC_R_NOTFOUND;
+ } else {
+ if (len == sizeof(struct sockaddr_in6))
+ result = ISC_R_SUCCESS;
+ else {
+ isc_log_write(isc_lctx,
+ ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_SOCKET,
+ ISC_LOG_ERROR,
+ "IPv6 structures in kernel and "
+ "user space do not match.");
+ isc_log_write(isc_lctx,
+ ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_SOCKET,
+ ISC_LOG_ERROR,
+ "IPv6 is not supported.");
+ result = ISC_R_NOTFOUND;
+ }
+ }
+ }
+#endif
+#endif
+#endif
+
+ (void)close(s);
+
+ return (result);
+}
+
+static void
+initialize_action(void) {
+ ipv4_result = try_proto(PF_INET);
+#ifdef ISC_PLATFORM_HAVEIPV6
+#ifdef WANT_IPV6
+#ifdef ISC_PLATFORM_HAVEIN6PKTINFO
+ ipv6_result = try_proto(PF_INET6);
+#endif
+#endif
+#endif
+#ifdef ISC_PLATFORM_HAVESYSUNH
+ unix_result = try_proto(PF_UNIX);
+#endif
+}
+
+static void
+initialize(void) {
+ RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_net_probeipv4(void) {
+ initialize();
+ return (ipv4_result);
+}
+
+isc_result_t
+isc_net_probeipv6(void) {
+ initialize();
+ return (ipv6_result);
+}
+
+isc_result_t
+isc_net_probeunix(void) {
+ initialize();
+ return (unix_result);
+}
+
+#ifdef ISC_PLATFORM_HAVEIPV6
+#ifdef WANT_IPV6
+static void
+try_ipv6only(void) {
+#ifdef IPV6_V6ONLY
+ int s, on;
+ char strbuf[ISC_STRERRORSIZE];
+#endif
+ isc_result_t result;
+
+ result = isc_net_probeipv6();
+ if (result != ISC_R_SUCCESS) {
+ ipv6only_result = result;
+ return;
+ }
+
+#ifndef IPV6_V6ONLY
+ ipv6only_result = ISC_R_NOTFOUND;
+ return;
+#else
+ /* check for TCP sockets */
+ s = socket(PF_INET6, SOCK_STREAM, 0);
+ if (s == -1) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "socket() %s: %s",
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_GENERAL,
+ ISC_MSG_FAILED,
+ "failed"),
+ strbuf);
+ ipv6only_result = ISC_R_UNEXPECTED;
+ return;
+ }
+
+ on = 1;
+ if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) {
+ ipv6only_result = ISC_R_NOTFOUND;
+ goto close;
+ }
+
+ close(s);
+
+ /* check for UDP sockets */
+ s = socket(PF_INET6, SOCK_DGRAM, 0);
+ if (s == -1) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "socket() %s: %s",
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_GENERAL,
+ ISC_MSG_FAILED,
+ "failed"),
+ strbuf);
+ ipv6only_result = ISC_R_UNEXPECTED;
+ return;
+ }
+
+ on = 1;
+ if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) {
+ ipv6only_result = ISC_R_NOTFOUND;
+ goto close;
+ }
+
+ ipv6only_result = ISC_R_SUCCESS;
+
+close:
+ close(s);
+ return;
+#endif /* IPV6_V6ONLY */
+}
+
+static void
+initialize_ipv6only(void) {
+ RUNTIME_CHECK(isc_once_do(&once_ipv6only,
+ try_ipv6only) == ISC_R_SUCCESS);
+}
+
+#ifdef ISC_PLATFORM_HAVEIN6PKTINFO
+static void
+try_ipv6pktinfo(void) {
+ int s, on;
+ char strbuf[ISC_STRERRORSIZE];
+ isc_result_t result;
+ int optname;
+
+ result = isc_net_probeipv6();
+ if (result != ISC_R_SUCCESS) {
+ ipv6pktinfo_result = result;
+ return;
+ }
+
+ /* we only use this for UDP sockets */
+ s = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+ if (s == -1) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "socket() %s: %s",
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_GENERAL,
+ ISC_MSG_FAILED,
+ "failed"),
+ strbuf);
+ ipv6pktinfo_result = ISC_R_UNEXPECTED;
+ return;
+ }
+
+#ifdef IPV6_RECVPKTINFO
+ optname = IPV6_RECVPKTINFO;
+#else
+ optname = IPV6_PKTINFO;
+#endif
+ on = 1;
+ if (setsockopt(s, IPPROTO_IPV6, optname, &on, sizeof(on)) < 0) {
+ ipv6pktinfo_result = ISC_R_NOTFOUND;
+ goto close;
+ }
+
+ ipv6pktinfo_result = ISC_R_SUCCESS;
+
+close:
+ close(s);
+ return;
+}
+
+static void
+initialize_ipv6pktinfo(void) {
+ RUNTIME_CHECK(isc_once_do(&once_ipv6pktinfo,
+ try_ipv6pktinfo) == ISC_R_SUCCESS);
+}
+#endif /* ISC_PLATFORM_HAVEIN6PKTINFO */
+#endif /* WANT_IPV6 */
+#endif /* ISC_PLATFORM_HAVEIPV6 */
+
+isc_result_t
+isc_net_probe_ipv6only(void) {
+#ifdef ISC_PLATFORM_HAVEIPV6
+#ifdef WANT_IPV6
+ initialize_ipv6only();
+#else
+ ipv6only_result = ISC_R_NOTFOUND;
+#endif
+#endif
+ return (ipv6only_result);
+}
+
+isc_result_t
+isc_net_probe_ipv6pktinfo(void) {
+#ifdef ISC_PLATFORM_HAVEIPV6
+#ifdef ISC_PLATFORM_HAVEIN6PKTINFO
+#ifdef WANT_IPV6
+ initialize_ipv6pktinfo();
+#else
+ ipv6pktinfo_result = ISC_R_NOTFOUND;
+#endif
+#endif
+#endif
+ return (ipv6pktinfo_result);
+}
+
+#if defined(USE_SYSCTL_PORTRANGE)
+#if defined(HAVE_SYSCTLBYNAME)
+static isc_result_t
+getudpportrange_sysctl(int af, in_port_t *low, in_port_t *high) {
+ int port_low, port_high;
+ size_t portlen;
+ const char *sysctlname_lowport, *sysctlname_hiport;
+
+ if (af == AF_INET) {
+ sysctlname_lowport = SYSCTL_V4PORTRANGE_LOW;
+ sysctlname_hiport = SYSCTL_V4PORTRANGE_HIGH;
+ } else {
+ sysctlname_lowport = SYSCTL_V6PORTRANGE_LOW;
+ sysctlname_hiport = SYSCTL_V6PORTRANGE_HIGH;
+ }
+ portlen = sizeof(portlen);
+ if (sysctlbyname(sysctlname_lowport, &port_low, &portlen,
+ NULL, 0) < 0) {
+ return (ISC_R_FAILURE);
+ }
+ portlen = sizeof(portlen);
+ if (sysctlbyname(sysctlname_hiport, &port_high, &portlen,
+ NULL, 0) < 0) {
+ return (ISC_R_FAILURE);
+ }
+ if ((port_low & ~0xffff) != 0 || (port_high & ~0xffff) != 0)
+ return (ISC_R_RANGE);
+
+ *low = (in_port_t)port_low;
+ *high = (in_port_t)port_high;
+
+ return (ISC_R_SUCCESS);
+}
+#else /* !HAVE_SYSCTLBYNAME */
+static isc_result_t
+getudpportrange_sysctl(int af, in_port_t *low, in_port_t *high) {
+ int mib_lo4[4] = SYSCTL_V4PORTRANGE_LOW;
+ int mib_hi4[4] = SYSCTL_V4PORTRANGE_HIGH;
+ int mib_lo6[4] = SYSCTL_V6PORTRANGE_LOW;
+ int mib_hi6[4] = SYSCTL_V6PORTRANGE_HIGH;
+ int *mib_lo, *mib_hi, miblen;
+ int port_low, port_high;
+ size_t portlen;
+
+ if (af == AF_INET) {
+ mib_lo = mib_lo4;
+ mib_hi = mib_hi4;
+ miblen = sizeof(mib_lo4) / sizeof(mib_lo4[0]);
+ } else {
+ mib_lo = mib_lo6;
+ mib_hi = mib_hi6;
+ miblen = sizeof(mib_lo6) / sizeof(mib_lo6[0]);
+ }
+
+ portlen = sizeof(portlen);
+ if (sysctl(mib_lo, miblen, &port_low, &portlen, NULL, 0) < 0) {
+ return (ISC_R_FAILURE);
+ }
+
+ portlen = sizeof(portlen);
+ if (sysctl(mib_hi, miblen, &port_high, &portlen, NULL, 0) < 0) {
+ return (ISC_R_FAILURE);
+ }
+
+ if ((port_low & ~0xffff) != 0 || (port_high & ~0xffff) != 0)
+ return (ISC_R_RANGE);
+
+ *low = (in_port_t) port_low;
+ *high = (in_port_t) port_high;
+
+ return (ISC_R_SUCCESS);
+}
+#endif /* HAVE_SYSCTLBYNAME */
+#endif /* USE_SYSCTL_PORTRANGE */
+
+isc_result_t
+isc_net_getudpportrange(int af, in_port_t *low, in_port_t *high) {
+ int result = ISC_R_FAILURE;
+
+ REQUIRE(low != NULL && high != NULL);
+
+#if defined(USE_SYSCTL_PORTRANGE)
+ result = getudpportrange_sysctl(af, low, high);
+#else
+ UNUSED(af);
+#endif
+
+ if (result != ISC_R_SUCCESS) {
+ *low = ISC_NET_PORTRANGELOW;
+ *high = ISC_NET_PORTRANGEHIGH;
+ }
+
+ return (ISC_R_SUCCESS); /* we currently never fail in this function */
+}
+
+void
+isc_net_disableipv4(void) {
+ initialize();
+ if (ipv4_result == ISC_R_SUCCESS)
+ ipv4_result = ISC_R_DISABLED;
+}
+
+void
+isc_net_disableipv6(void) {
+ initialize();
+ if (ipv6_result == ISC_R_SUCCESS)
+ ipv6_result = ISC_R_DISABLED;
+}
+
+void
+isc_net_enableipv4(void) {
+ initialize();
+ if (ipv4_result == ISC_R_DISABLED)
+ ipv4_result = ISC_R_SUCCESS;
+}
+
+void
+isc_net_enableipv6(void) {
+ initialize();
+ if (ipv6_result == ISC_R_DISABLED)
+ ipv6_result = ISC_R_SUCCESS;
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/stdio.c b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/stdio.c
new file mode 100644
index 0000000..befb25b
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/stdio.c
@@ -0,0 +1,131 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (C) 2004, 2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+#include <config.h>
+
+#include <errno.h>
+#include <unistd.h>
+
+#include <isc/stdio.h>
+#include <isc/stat.h>
+
+#include "errno2result.h"
+
+isc_result_t
+isc_stdio_open(const char *filename, const char *mode, FILE **fp) {
+ FILE *f;
+
+ f = fopen(filename, mode);
+ if (f == NULL)
+ return (isc__errno2result(errno));
+ *fp = f;
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_stdio_close(FILE *f) {
+ int r;
+
+ r = fclose(f);
+ if (r == 0)
+ return (ISC_R_SUCCESS);
+ else
+ return (isc__errno2result(errno));
+}
+
+isc_result_t
+isc_stdio_seek(FILE *f, long offset, int whence) {
+ int r;
+
+ r = fseek(f, offset, whence);
+ if (r == 0)
+ return (ISC_R_SUCCESS);
+ else
+ return (isc__errno2result(errno));
+}
+
+isc_result_t
+isc_stdio_read(void *ptr, size_t size, size_t nmemb, FILE *f, size_t *nret) {
+ isc_result_t result = ISC_R_SUCCESS;
+ size_t r;
+
+ clearerr(f);
+ r = fread(ptr, size, nmemb, f);
+ if (r != nmemb) {
+ if (feof(f))
+ result = ISC_R_EOF;
+ else
+ result = isc__errno2result(errno);
+ }
+ if (nret != NULL)
+ *nret = r;
+ return (result);
+}
+
+isc_result_t
+isc_stdio_write(const void *ptr, size_t size, size_t nmemb, FILE *f,
+ size_t *nret)
+{
+ isc_result_t result = ISC_R_SUCCESS;
+ size_t r;
+
+ clearerr(f);
+ r = fwrite(ptr, size, nmemb, f);
+ if (r != nmemb)
+ result = isc__errno2result(errno);
+ if (nret != NULL)
+ *nret = r;
+ return (result);
+}
+
+isc_result_t
+isc_stdio_flush(FILE *f) {
+ int r;
+
+ r = fflush(f);
+ if (r == 0)
+ return (ISC_R_SUCCESS);
+ else
+ return (isc__errno2result(errno));
+}
+
+/*
+ * OpenBSD has deprecated ENOTSUP in favor of EOPNOTSUPP.
+ */
+#if defined(EOPNOTSUPP) && !defined(ENOTSUP)
+#define ENOTSUP EOPNOTSUPP
+#endif
+
+isc_result_t
+isc_stdio_sync(FILE *f) {
+ int r;
+
+ r = fsync(fileno(f));
+ /*
+ * fsync is not supported on sockets and pipes which
+ * result in EINVAL / ENOTSUP.
+ */
+ if (r == 0 || errno == EINVAL || errno == ENOTSUP)
+ return (ISC_R_SUCCESS);
+ else
+ return (isc__errno2result(errno));
+}
+
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/strerror.c b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/strerror.c
new file mode 100644
index 0000000..9a556ad
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/strerror.c
@@ -0,0 +1,78 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: strerror.c,v 1.10 2009/02/16 23:48:04 tbox Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include <isc/mutex.h>
+#include <isc/once.h>
+#include <isc/print.h>
+#include <isc/strerror.h>
+#include <isc/util.h>
+
+#include "l_stdlib.h" /* NTP local change */
+
+#ifdef HAVE_STRERROR
+/*%
+ * We need to do this this way for profiled locks.
+ */
+static isc_mutex_t isc_strerror_lock;
+static void init_lock(void) {
+ RUNTIME_CHECK(isc_mutex_init(&isc_strerror_lock) == ISC_R_SUCCESS);
+}
+#else
+extern const char * const sys_errlist[];
+extern const int sys_nerr;
+#endif
+
+void
+isc__strerror(int num, char *buf, size_t size) {
+#ifdef HAVE_STRERROR
+ char *msg;
+ unsigned int unum = (unsigned int)num;
+ static isc_once_t once = ISC_ONCE_INIT;
+
+ REQUIRE(buf != NULL);
+
+ RUNTIME_CHECK(isc_once_do(&once, init_lock) == ISC_R_SUCCESS);
+
+ LOCK(&isc_strerror_lock);
+ msg = strerror(num);
+ if (msg != NULL)
+ snprintf(buf, size, "%s", msg);
+ else
+ snprintf(buf, size, "Unknown error: %u", unum);
+ UNLOCK(&isc_strerror_lock);
+#else
+ unsigned int unum = (unsigned int)num;
+
+ REQUIRE(buf != NULL);
+
+ if (num >= 0 && num < sys_nerr)
+ snprintf(buf, size, "%s", sys_errlist[num]);
+ else
+ snprintf(buf, size, "Unknown error: %u", unum);
+#endif
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/time.c b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/time.c
new file mode 100644
index 0000000..75882a6
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/lib/isc/unix/time.c
@@ -0,0 +1,422 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (C) 2004-2008, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001, 2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <errno.h>
+#include <limits.h>
+#include <syslog.h>
+#include <time.h>
+
+#include <sys/time.h> /* Required for struct timeval on some platforms. */
+
+#include <isc/log.h>
+#include <isc/print.h>
+#include <isc/strerror.h>
+#include <isc/string.h>
+#include <isc/time.h>
+#include <isc/util.h>
+
+#define NS_PER_S 1000000000 /*%< Nanoseconds per second. */
+#define NS_PER_US 1000 /*%< Nanoseconds per microsecond. */
+#define US_PER_S 1000000 /*%< Microseconds per second. */
+
+/*
+ * All of the INSIST()s checks of nanoseconds < NS_PER_S are for
+ * consistency checking of the type. In lieu of magic numbers, it
+ * is the best we've got. The check is only performed on functions which
+ * need an initialized type.
+ */
+
+#ifndef ISC_FIX_TV_USEC
+#define ISC_FIX_TV_USEC 1
+#endif
+
+/*%
+ *** Intervals
+ ***/
+
+static isc_interval_t zero_interval = { 0, 0 };
+isc_interval_t *isc_interval_zero = &zero_interval;
+
+#if ISC_FIX_TV_USEC
+static inline void
+fix_tv_usec(struct timeval *tv) {
+ isc_boolean_t fixed = ISC_FALSE;
+
+ if (tv->tv_usec < 0) {
+ fixed = ISC_TRUE;
+ do {
+ tv->tv_sec -= 1;
+ tv->tv_usec += US_PER_S;
+ } while (tv->tv_usec < 0);
+ } else if (tv->tv_usec >= US_PER_S) {
+ fixed = ISC_TRUE;
+ do {
+ tv->tv_sec += 1;
+ tv->tv_usec -= US_PER_S;
+ } while (tv->tv_usec >=US_PER_S);
+ }
+ /*
+ * Call syslog directly as was are called from the logging functions.
+ */
+ if (fixed)
+ (void)syslog(LOG_ERR, "gettimeofday returned bad tv_usec: corrected");
+}
+#endif
+
+void
+isc_interval_set(isc_interval_t *i,
+ unsigned int seconds, unsigned int nanoseconds)
+{
+ REQUIRE(i != NULL);
+ REQUIRE(nanoseconds < NS_PER_S);
+
+ i->seconds = seconds;
+ i->nanoseconds = nanoseconds;
+}
+
+isc_boolean_t
+isc_interval_iszero(const isc_interval_t *i) {
+ REQUIRE(i != NULL);
+ INSIST(i->nanoseconds < NS_PER_S);
+
+ if (i->seconds == 0 && i->nanoseconds == 0)
+ return (ISC_TRUE);
+
+ return (ISC_FALSE);
+}
+
+
+/***
+ *** Absolute Times
+ ***/
+
+static isc_time_t epoch = { 0, 0 };
+isc_time_t *isc_time_epoch = &epoch;
+
+void
+isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds) {
+ REQUIRE(t != NULL);
+ REQUIRE(nanoseconds < NS_PER_S);
+
+ t->seconds = seconds;
+ t->nanoseconds = nanoseconds;
+}
+
+void
+isc_time_settoepoch(isc_time_t *t) {
+ REQUIRE(t != NULL);
+
+ t->seconds = 0;
+ t->nanoseconds = 0;
+}
+
+isc_boolean_t
+isc_time_isepoch(const isc_time_t *t) {
+ REQUIRE(t != NULL);
+ INSIST(t->nanoseconds < NS_PER_S);
+
+ if (t->seconds == 0 && t->nanoseconds == 0)
+ return (ISC_TRUE);
+
+ return (ISC_FALSE);
+}
+
+
+isc_result_t
+isc_time_now(isc_time_t *t) {
+ struct timeval tv;
+ char strbuf[ISC_STRERRORSIZE];
+
+ REQUIRE(t != NULL);
+
+ if (gettimeofday(&tv, NULL) == -1) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__, "%s", strbuf);
+ return (ISC_R_UNEXPECTED);
+ }
+
+ /*
+ * Does POSIX guarantee the signedness of tv_sec and tv_usec? If not,
+ * then this test will generate warnings for platforms on which it is
+ * unsigned. In any event, the chances of any of these problems
+ * happening are pretty much zero, but since the libisc library ensures
+ * certain things to be true ...
+ */
+#if ISC_FIX_TV_USEC
+ fix_tv_usec(&tv);
+ if (tv.tv_sec < 0)
+ return (ISC_R_UNEXPECTED);
+#else
+ if (tv.tv_sec < 0 || tv.tv_usec < 0 || tv.tv_usec >= US_PER_S)
+ return (ISC_R_UNEXPECTED);
+#endif
+
+ /*
+ * Ensure the tv_sec value fits in t->seconds.
+ */
+ if (sizeof(tv.tv_sec) > sizeof(t->seconds) &&
+ ((tv.tv_sec | (unsigned int)-1) ^ (unsigned int)-1) != 0U)
+ return (ISC_R_RANGE);
+
+ t->seconds = tv.tv_sec;
+ t->nanoseconds = tv.tv_usec * NS_PER_US;
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_time_nowplusinterval(isc_time_t *t, const isc_interval_t *i) {
+ struct timeval tv;
+ char strbuf[ISC_STRERRORSIZE];
+
+ REQUIRE(t != NULL);
+ REQUIRE(i != NULL);
+ INSIST(i->nanoseconds < NS_PER_S);
+
+ if (gettimeofday(&tv, NULL) == -1) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__, "%s", strbuf);
+ return (ISC_R_UNEXPECTED);
+ }
+
+ /*
+ * Does POSIX guarantee the signedness of tv_sec and tv_usec? If not,
+ * then this test will generate warnings for platforms on which it is
+ * unsigned. In any event, the chances of any of these problems
+ * happening are pretty much zero, but since the libisc library ensures
+ * certain things to be true ...
+ */
+#if ISC_FIX_TV_USEC
+ fix_tv_usec(&tv);
+ if (tv.tv_sec < 0)
+ return (ISC_R_UNEXPECTED);
+#else
+ if (tv.tv_sec < 0 || tv.tv_usec < 0 || tv.tv_usec >= US_PER_S)
+ return (ISC_R_UNEXPECTED);
+#endif
+
+ /*
+ * Ensure the resulting seconds value fits in the size of an
+ * unsigned int. (It is written this way as a slight optimization;
+ * note that even if both values == INT_MAX, then when added
+ * and getting another 1 added below the result is UINT_MAX.)
+ */
+ if ((tv.tv_sec > INT_MAX || i->seconds > INT_MAX) &&
+ ((long long)tv.tv_sec + i->seconds > UINT_MAX))
+ return (ISC_R_RANGE);
+
+ t->seconds = tv.tv_sec + i->seconds;
+ t->nanoseconds = tv.tv_usec * NS_PER_US + i->nanoseconds;
+ if (t->nanoseconds >= NS_PER_S) {
+ t->seconds++;
+ t->nanoseconds -= NS_PER_S;
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+int
+isc_time_compare(const isc_time_t *t1, const isc_time_t *t2) {
+ REQUIRE(t1 != NULL && t2 != NULL);
+ INSIST(t1->nanoseconds < NS_PER_S && t2->nanoseconds < NS_PER_S);
+
+ if (t1->seconds < t2->seconds)
+ return (-1);
+ if (t1->seconds > t2->seconds)
+ return (1);
+ if (t1->nanoseconds < t2->nanoseconds)
+ return (-1);
+ if (t1->nanoseconds > t2->nanoseconds)
+ return (1);
+ return (0);
+}
+
+isc_result_t
+isc_time_add(const isc_time_t *t, const isc_interval_t *i, isc_time_t *result)
+{
+ REQUIRE(t != NULL && i != NULL && result != NULL);
+ INSIST(t->nanoseconds < NS_PER_S && i->nanoseconds < NS_PER_S);
+
+ /*
+ * Ensure the resulting seconds value fits in the size of an
+ * unsigned int. (It is written this way as a slight optimization;
+ * note that even if both values == INT_MAX, then when added
+ * and getting another 1 added below the result is UINT_MAX.)
+ */
+ if ((t->seconds > INT_MAX || i->seconds > INT_MAX) &&
+ ((long long)t->seconds + i->seconds > UINT_MAX))
+ return (ISC_R_RANGE);
+
+ result->seconds = t->seconds + i->seconds;
+ result->nanoseconds = t->nanoseconds + i->nanoseconds;
+ if (result->nanoseconds >= NS_PER_S) {
+ result->seconds++;
+ result->nanoseconds -= NS_PER_S;
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_time_subtract(const isc_time_t *t, const isc_interval_t *i,
+ isc_time_t *result)
+{
+ REQUIRE(t != NULL && i != NULL && result != NULL);
+ INSIST(t->nanoseconds < NS_PER_S && i->nanoseconds < NS_PER_S);
+
+ if ((unsigned int)t->seconds < i->seconds ||
+ ((unsigned int)t->seconds == i->seconds &&
+ t->nanoseconds < i->nanoseconds))
+ return (ISC_R_RANGE);
+
+ result->seconds = t->seconds - i->seconds;
+ if (t->nanoseconds >= i->nanoseconds)
+ result->nanoseconds = t->nanoseconds - i->nanoseconds;
+ else {
+ result->nanoseconds = NS_PER_S - i->nanoseconds +
+ t->nanoseconds;
+ result->seconds--;
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_uint64_t
+isc_time_microdiff(const isc_time_t *t1, const isc_time_t *t2) {
+ isc_uint64_t i1, i2, i3;
+
+ REQUIRE(t1 != NULL && t2 != NULL);
+ INSIST(t1->nanoseconds < NS_PER_S && t2->nanoseconds < NS_PER_S);
+
+ i1 = (isc_uint64_t)t1->seconds * NS_PER_S + t1->nanoseconds;
+ i2 = (isc_uint64_t)t2->seconds * NS_PER_S + t2->nanoseconds;
+
+ if (i1 <= i2)
+ return (0);
+
+ i3 = i1 - i2;
+
+ /*
+ * Convert to microseconds.
+ */
+ i3 /= NS_PER_US;
+
+ return (i3);
+}
+
+isc_uint32_t
+isc_time_seconds(const isc_time_t *t) {
+ REQUIRE(t != NULL);
+ INSIST(t->nanoseconds < NS_PER_S);
+
+ return ((isc_uint32_t)t->seconds);
+}
+
+isc_result_t
+isc_time_secondsastimet(const isc_time_t *t, time_t *secondsp) {
+ time_t seconds;
+
+ REQUIRE(t != NULL);
+ INSIST(t->nanoseconds < NS_PER_S);
+
+ /*
+ * Ensure that the number of seconds represented by t->seconds
+ * can be represented by a time_t. Since t->seconds is an unsigned
+ * int and since time_t is mostly opaque, this is trickier than
+ * it seems. (This standardized opaqueness of time_t is *very*
+ * frustrating; time_t is not even limited to being an integral
+ * type.)
+ *
+ * The mission, then, is to avoid generating any kind of warning
+ * about "signed versus unsigned" while trying to determine if the
+ * the unsigned int t->seconds is out range for tv_sec, which is
+ * pretty much only true if time_t is a signed integer of the same
+ * size as the return value of isc_time_seconds.
+ *
+ * If the paradox in the if clause below is true, t->seconds is out
+ * of range for time_t.
+ */
+ seconds = (time_t)t->seconds;
+
+ INSIST(sizeof(unsigned int) == sizeof(isc_uint32_t));
+ INSIST(sizeof(time_t) >= sizeof(isc_uint32_t));
+
+ if (t->seconds > (~0U>>1) && seconds <= (time_t)(~0U>>1))
+ return (ISC_R_RANGE);
+
+ *secondsp = seconds;
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_uint32_t
+isc_time_nanoseconds(const isc_time_t *t) {
+ REQUIRE(t != NULL);
+
+ ENSURE(t->nanoseconds < NS_PER_S);
+
+ return ((isc_uint32_t)t->nanoseconds);
+}
+
+void
+isc_time_formattimestamp(const isc_time_t *t, char *buf, unsigned int len) {
+ time_t now;
+ unsigned int flen;
+
+ REQUIRE(len > 0);
+
+ now = (time_t) t->seconds;
+ flen = strftime(buf, len, "%d-%b-%Y %X", localtime(&now));
+ INSIST(flen < len);
+ if (flen != 0)
+ snprintf(buf + flen, len - flen,
+ ".%03u", t->nanoseconds / 1000000);
+ else
+ snprintf(buf, len, "99-Bad-9999 99:99:99.999");
+}
+
+void
+isc_time_formathttptimestamp(const isc_time_t *t, char *buf, unsigned int len) {
+ time_t now;
+ unsigned int flen;
+
+ REQUIRE(len > 0);
+
+ now = (time_t)t->seconds;
+ flen = strftime(buf, len, "%a, %d %b %Y %H:%M:%S GMT", gmtime(&now));
+ INSIST(flen < len);
+}
+
+void
+isc_time_formatISO8601(const isc_time_t *t, char *buf, unsigned int len) {
+ time_t now;
+ unsigned int flen;
+
+ REQUIRE(len > 0);
+
+ now = (time_t)t->seconds;
+ flen = strftime(buf, len, "%Y-%m-%dT%H:%M:%SZ", gmtime(&now));
+ INSIST(flen < len);
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/libntp/a_md5encrypt.c b/sebhbsd/freebsd/contrib/ntp/libntp/a_md5encrypt.c
new file mode 100644
index 0000000..d84cac7
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/libntp/a_md5encrypt.c
@@ -0,0 +1,287 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * digest support for NTP, MD5 and with OpenSSL more
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "ntp_fp.h"
+#include "ntp_string.h"
+#include "ntp_stdlib.h"
+#include "ntp.h"
+#include "ntp_md5.h" /* provides OpenSSL digest API */
+#include "isc/string.h"
+
+typedef struct {
+ const void * buf;
+ size_t len;
+} robuffT;
+
+typedef struct {
+ void * buf;
+ size_t len;
+} rwbuffT;
+
+#if defined(OPENSSL) && defined(ENABLE_CMAC)
+static size_t
+cmac_ctx_size(
+ CMAC_CTX * ctx)
+{
+ size_t mlen = 0;
+
+ if (ctx) {
+ EVP_CIPHER_CTX * cctx;
+ if (NULL != (cctx = CMAC_CTX_get0_cipher_ctx (ctx)))
+ mlen = EVP_CIPHER_CTX_block_size(cctx);
+ }
+ return mlen;
+}
+#endif /*OPENSSL && ENABLE_CMAC*/
+
+static size_t
+make_mac(
+ const rwbuffT * digest,
+ int ktype,
+ const robuffT * key,
+ const robuffT * msg)
+{
+ /*
+ * Compute digest of key concatenated with packet. Note: the
+ * key type and digest type have been verified when the key
+ * was created.
+ */
+ size_t retlen = 0;
+
+#ifdef OPENSSL
+
+ INIT_SSL();
+
+ /* Check if CMAC key type specific code required */
+# ifdef ENABLE_CMAC
+ if (ktype == NID_cmac) {
+ CMAC_CTX * ctx = NULL;
+ void const * keyptr = key->buf;
+ u_char keybuf[AES_128_KEY_SIZE];
+
+ /* adjust key size (zero padded buffer) if necessary */
+ if (AES_128_KEY_SIZE > key->len) {
+ memcpy(keybuf, keyptr, key->len);
+ memset((keybuf + key->len), 0,
+ (AES_128_KEY_SIZE - key->len));
+ keyptr = keybuf;
+ }
+
+ if (NULL == (ctx = CMAC_CTX_new())) {
+ msyslog(LOG_ERR, "MAC encrypt: CMAC %s CTX new failed.", CMAC);
+ goto cmac_fail;
+ }
+ if (!CMAC_Init(ctx, keyptr, AES_128_KEY_SIZE, EVP_aes_128_cbc(), NULL)) {
+ msyslog(LOG_ERR, "MAC encrypt: CMAC %s Init failed.", CMAC);
+ goto cmac_fail;
+ }
+ if (cmac_ctx_size(ctx) > digest->len) {
+ msyslog(LOG_ERR, "MAC encrypt: CMAC %s buf too small.", CMAC);
+ goto cmac_fail;
+ }
+ if (!CMAC_Update(ctx, msg->buf, msg->len)) {
+ msyslog(LOG_ERR, "MAC encrypt: CMAC %s Update failed.", CMAC);
+ goto cmac_fail;
+ }
+ if (!CMAC_Final(ctx, digest->buf, &retlen)) {
+ msyslog(LOG_ERR, "MAC encrypt: CMAC %s Final failed.", CMAC);
+ retlen = 0;
+ }
+ cmac_fail:
+ if (ctx)
+ CMAC_CTX_cleanup(ctx);
+ }
+ else
+# endif /*ENABLE_CMAC*/
+ { /* generic MAC handling */
+ EVP_MD_CTX * ctx = EVP_MD_CTX_new();
+ u_int uilen = 0;
+
+ if ( ! ctx) {
+ msyslog(LOG_ERR, "MAC encrypt: MAC %s Digest CTX new failed.",
+ OBJ_nid2sn(ktype));
+ goto mac_fail;
+ }
+
+ #ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW
+ /* make sure MD5 is allowd */
+ EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+ #endif
+ /* [Bug 3457] DON'T use plain EVP_DigestInit! It would
+ * kill the flags! */
+ if (!EVP_DigestInit_ex(ctx, EVP_get_digestbynid(ktype), NULL)) {
+ msyslog(LOG_ERR, "MAC encrypt: MAC %s Digest Init failed.",
+ OBJ_nid2sn(ktype));
+ goto mac_fail;
+ }
+ if ((size_t)EVP_MD_CTX_size(ctx) > digest->len) {
+ msyslog(LOG_ERR, "MAC encrypt: MAC %s buf too small.",
+ OBJ_nid2sn(ktype));
+ goto mac_fail;
+ }
+ if (!EVP_DigestUpdate(ctx, key->buf, (u_int)key->len)) {
+ msyslog(LOG_ERR, "MAC encrypt: MAC %s Digest Update key failed.",
+ OBJ_nid2sn(ktype));
+ goto mac_fail;
+ }
+ if (!EVP_DigestUpdate(ctx, msg->buf, (u_int)msg->len)) {
+ msyslog(LOG_ERR, "MAC encrypt: MAC %s Digest Update data failed.",
+ OBJ_nid2sn(ktype));
+ goto mac_fail;
+ }
+ if (!EVP_DigestFinal(ctx, digest->buf, &uilen)) {
+ msyslog(LOG_ERR, "MAC encrypt: MAC %s Digest Final failed.",
+ OBJ_nid2sn(ktype));
+ uilen = 0;
+ }
+ mac_fail:
+ retlen = (size_t)uilen;
+
+ if (ctx)
+ EVP_MD_CTX_free(ctx);
+ }
+
+#else /* !OPENSSL follows */
+
+ if (ktype == NID_md5)
+ {
+ EVP_MD_CTX * ctx = EVP_MD_CTX_new();
+ u_int uilen = 0;
+
+ if (digest->len < 16) {
+ msyslog(LOG_ERR, "%s", "MAC encrypt: MAC md5 buf too small.");
+ }
+ else if ( ! ctx) {
+ msyslog(LOG_ERR, "%s", "MAC encrypt: MAC md5 Digest CTX new failed.");
+ }
+ else {
+ EVP_DigestInit(ctx, EVP_get_digestbynid(ktype));
+ EVP_DigestUpdate(ctx, key->buf, key->len);
+ EVP_DigestUpdate(ctx, msg->buf, msg->len);
+ EVP_DigestFinal(ctx, digest->buf, &uilen);
+ }
+ if (ctx)
+ EVP_MD_CTX_free(ctx);
+ retlen = (size_t)uilen;
+ }
+ else
+ {
+ msyslog(LOG_ERR, "MAC encrypt: invalid key type %d" , ktype);
+ }
+
+#endif /* !OPENSSL */
+
+ return retlen;
+}
+
+
+/*
+ * MD5authencrypt - generate message digest
+ *
+ * Returns length of MAC including key ID and digest.
+ */
+size_t
+MD5authencrypt(
+ int type, /* hash algorithm */
+ const u_char * key, /* key pointer */
+ size_t klen, /* key length */
+ u_int32 * pkt, /* packet pointer */
+ size_t length /* packet length */
+ )
+{
+ u_char digest[EVP_MAX_MD_SIZE];
+ rwbuffT digb = { digest, sizeof(digest) };
+ robuffT keyb = { key, klen };
+ robuffT msgb = { pkt, length };
+ size_t dlen = 0;
+
+ dlen = make_mac(&digb, type, &keyb, &msgb);
+ /* If the MAC is longer than the MAX then truncate it. */
+ if (dlen > MAX_MDG_LEN)
+ dlen = MAX_MDG_LEN;
+ memcpy((u_char *)pkt + length + KEY_MAC_LEN, digest, dlen);
+ return (dlen + KEY_MAC_LEN);
+}
+
+
+/*
+ * MD5authdecrypt - verify MD5 message authenticator
+ *
+ * Returns one if digest valid, zero if invalid.
+ */
+int
+MD5authdecrypt(
+ int type, /* hash algorithm */
+ const u_char * key, /* key pointer */
+ size_t klen, /* key length */
+ u_int32 * pkt, /* packet pointer */
+ size_t length, /* packet length */
+ size_t size /* MAC size */
+ )
+{
+ u_char digest[EVP_MAX_MD_SIZE];
+ rwbuffT digb = { digest, sizeof(digest) };
+ robuffT keyb = { key, klen };
+ robuffT msgb = { pkt, length };
+ size_t dlen = 0;
+
+ dlen = make_mac(&digb, type, &keyb, &msgb);
+
+ /* If the MAC is longer than the MAX then truncate it. */
+ if (dlen > MAX_MDG_LEN)
+ dlen = MAX_MDG_LEN;
+ if (size != (size_t)dlen + KEY_MAC_LEN) {
+ msyslog(LOG_ERR,
+ "MAC decrypt: MAC length error");
+ return (0);
+ }
+ return !isc_tsmemcmp(digest,
+ (u_char *)pkt + length + KEY_MAC_LEN, dlen);
+}
+
+/*
+ * Calculate the reference id from the address. If it is an IPv4
+ * address, use it as is. If it is an IPv6 address, do a md5 on
+ * it and use the bottom 4 bytes.
+ * The result is in network byte order.
+ */
+u_int32
+addr2refid(sockaddr_u *addr)
+{
+ u_char digest[EVP_MAX_MD_SIZE];
+ u_int32 addr_refid;
+ EVP_MD_CTX *ctx;
+ u_int len;
+
+ if (IS_IPV4(addr))
+ return (NSRCADR(addr));
+
+ INIT_SSL();
+
+ ctx = EVP_MD_CTX_new();
+# ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW
+ /* MD5 is not used as a crypto hash here. */
+ EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+# endif
+ /* [Bug 3457] DON'T use plain EVP_DigestInit! It would kill the
+ * flags! */
+ if (!EVP_DigestInit_ex(ctx, EVP_md5(), NULL)) {
+ msyslog(LOG_ERR,
+ "MD5 init failed");
+ EVP_MD_CTX_free(ctx); /* pedantic... but safe */
+ exit(1);
+ }
+
+ EVP_DigestUpdate(ctx, (u_char *)PSOCK_ADDR6(addr),
+ sizeof(struct in6_addr));
+ EVP_DigestFinal(ctx, digest, &len);
+ EVP_MD_CTX_free(ctx);
+ memcpy(&addr_refid, digest, sizeof(addr_refid));
+ return (addr_refid);
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/libntp/atoint.c b/sebhbsd/freebsd/contrib/ntp/libntp/atoint.c
new file mode 100644
index 0000000..e41798f
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/libntp/atoint.c
@@ -0,0 +1,53 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * atoint - convert an ascii string to a signed long, with error checking
+ */
+#include <config.h>
+#include <sys/types.h>
+#include <ctype.h>
+
+#include "ntp_types.h"
+#include "ntp_stdlib.h"
+
+int
+atoint(
+ const char *str,
+ long *ival
+ )
+{
+ register long u;
+ register const char *cp;
+ register int isneg;
+ register int oflow_digit;
+
+ cp = str;
+
+ if (*cp == '-') {
+ cp++;
+ isneg = 1;
+ oflow_digit = '8';
+ } else {
+ isneg = 0;
+ oflow_digit = '7';
+ }
+
+ if (*cp == '\0')
+ return 0;
+
+ u = 0;
+ while (*cp != '\0') {
+ if (!isdigit((unsigned char)*cp))
+ return 0;
+ if (u > 214748364 || (u == 214748364 && *cp > oflow_digit))
+ return 0; /* overflow */
+ u = (u << 3) + (u << 1);
+ u += *cp++ - '0'; /* ascii dependent */
+ }
+
+ if (isneg)
+ *ival = -u;
+ else
+ *ival = u;
+ return 1;
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/libntp/authkeys.c b/sebhbsd/freebsd/contrib/ntp/libntp/authkeys.c
new file mode 100644
index 0000000..dae5b2e
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/libntp/authkeys.c
@@ -0,0 +1,931 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * authkeys.c - routines to manage the storage of authentication keys
+ */
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <math.h>
+#include <stdio.h>
+
+#include "ntp.h"
+#include "ntp_fp.h"
+#include "ntpd.h"
+#include "ntp_lists.h"
+#include "ntp_string.h"
+#include "ntp_malloc.h"
+#include "ntp_stdlib.h"
+#include "ntp_keyacc.h"
+
+/*
+ * Structure to store keys in in the hash table.
+ */
+typedef struct savekey symkey;
+
+struct savekey {
+ symkey * hlink; /* next in hash bucket */
+ DECL_DLIST_LINK(symkey, llink); /* for overall & free lists */
+ u_char * secret; /* shared secret */
+ KeyAccT * keyacclist; /* Private key access list */
+ u_long lifetime; /* remaining lifetime */
+ keyid_t keyid; /* key identifier */
+ u_short type; /* OpenSSL digest NID */
+ size_t secretsize; /* secret octets */
+ u_short flags; /* KEY_ flags that wave */
+};
+
+/* define the payload region of symkey beyond the list pointers */
+#define symkey_payload secret
+
+#define KEY_TRUSTED 0x001 /* this key is trusted */
+
+#ifdef DEBUG
+typedef struct symkey_alloc_tag symkey_alloc;
+
+struct symkey_alloc_tag {
+ symkey_alloc * link;
+ void * mem; /* enable free() atexit */
+};
+
+symkey_alloc * authallocs;
+#endif /* DEBUG */
+
+static u_short auth_log2(size_t);
+static void auth_resize_hashtable(void);
+static void allocsymkey(keyid_t, u_short,
+ u_short, u_long, size_t, u_char *, KeyAccT *);
+static void freesymkey(symkey *);
+#ifdef DEBUG
+static void free_auth_mem(void);
+#endif
+
+symkey key_listhead; /* list of all in-use keys */;
+/*
+ * The hash table. This is indexed by the low order bits of the
+ * keyid. We make this fairly big for potentially busy servers.
+ */
+#define DEF_AUTHHASHSIZE 64
+/*#define HASHMASK ((HASHSIZE)-1)*/
+#define KEYHASH(keyid) ((keyid) & authhashmask)
+
+int authhashdisabled;
+u_short authhashbuckets = DEF_AUTHHASHSIZE;
+u_short authhashmask = DEF_AUTHHASHSIZE - 1;
+symkey **key_hash;
+
+u_long authkeynotfound; /* keys not found */
+u_long authkeylookups; /* calls to lookup keys */
+u_long authnumkeys; /* number of active keys */
+u_long authkeyexpired; /* key lifetime expirations */
+u_long authkeyuncached; /* cache misses */
+u_long authnokey; /* calls to encrypt with no key */
+u_long authencryptions; /* calls to encrypt */
+u_long authdecryptions; /* calls to decrypt */
+
+/*
+ * Storage for free symkey structures. We malloc() such things but
+ * never free them.
+ */
+symkey *authfreekeys;
+int authnumfreekeys;
+
+#define MEMINC 16 /* number of new free ones to get */
+
+/*
+ * The key cache. We cache the last key we looked at here.
+ * Note: this should hold the last *trusted* key. Also the
+ * cache is only loaded when the digest type / MAC algorithm
+ * is valid.
+ */
+keyid_t cache_keyid; /* key identifier */
+u_char *cache_secret; /* secret */
+size_t cache_secretsize; /* secret length */
+int cache_type; /* OpenSSL digest NID */
+u_short cache_flags; /* flags that wave */
+KeyAccT *cache_keyacclist; /* key access list */
+
+/* --------------------------------------------------------------------
+ * manage key access lists
+ * --------------------------------------------------------------------
+ */
+/* allocate and populate new access node and pushes it on the list.
+ * Returns the new head.
+ */
+KeyAccT*
+keyacc_new_push(
+ KeyAccT * head,
+ const sockaddr_u * addr,
+ unsigned int subnetbits
+ )
+{
+ KeyAccT * node = emalloc(sizeof(KeyAccT));
+
+ memcpy(&node->addr, addr, sizeof(sockaddr_u));
+ node->subnetbits = subnetbits;
+ node->next = head;
+
+ return node;
+}
+
+/* ----------------------------------------------------------------- */
+/* pop and deallocate the first node of a list of access nodes, if
+ * the list is not empty. Returns the tail of the list.
+ */
+KeyAccT*
+keyacc_pop_free(
+ KeyAccT *head
+ )
+{
+ KeyAccT * next = NULL;
+ if (head) {
+ next = head->next;
+ free(head);
+ }
+ return next;
+}
+
+/* ----------------------------------------------------------------- */
+/* deallocate the list; returns an empty list. */
+KeyAccT*
+keyacc_all_free(
+ KeyAccT * head
+ )
+{
+ while (head)
+ head = keyacc_pop_free(head);
+ return head;
+}
+
+/* ----------------------------------------------------------------- */
+/* scan a list to see if it contains a given address. Return the
+ * default result value in case of an empty list.
+ */
+int /*BOOL*/
+keyacc_contains(
+ const KeyAccT *head,
+ const sockaddr_u *addr,
+ int defv)
+{
+ if (head) {
+ do {
+ if (keyacc_amatch(&head->addr, addr,
+ head->subnetbits))
+ return TRUE;
+ } while (NULL != (head = head->next));
+ return FALSE;
+ } else {
+ return !!defv;
+ }
+}
+
+#if CHAR_BIT != 8
+# error "don't know how to handle bytes with that bit size"
+#endif
+
+/* ----------------------------------------------------------------- */
+/* check two addresses for a match, taking a prefix length into account
+ * when doing the compare.
+ *
+ * The ISC lib contains a similar function with not entirely specified
+ * semantics, so it seemed somewhat cleaner to do this from scratch.
+ *
+ * Note 1: It *is* assumed that the addresses are stored in network byte
+ * order, that is, most significant byte first!
+ *
+ * Note 2: "no address" compares unequal to all other addresses, even to
+ * itself. This has the same semantics as NaNs have for floats: *any*
+ * relational or equality operation involving a NaN returns FALSE, even
+ * equality with itself. "no address" is either a NULL pointer argument
+ * or an address of type AF_UNSPEC.
+ */
+int/*BOOL*/
+keyacc_amatch(
+ const sockaddr_u * a1,
+ const sockaddr_u * a2,
+ unsigned int mbits
+ )
+{
+ const uint8_t * pm1;
+ const uint8_t * pm2;
+ uint8_t msk;
+ unsigned int len;
+
+ /* 1st check: If any address is not an address, it's inequal. */
+ if ( !a1 || (AF_UNSPEC == AF(a1)) ||
+ !a2 || (AF_UNSPEC == AF(a2)) )
+ return FALSE;
+
+ /* We could check pointers for equality here and shortcut the
+ * other checks if we find object identity. But that use case is
+ * too rare to care for it.
+ */
+
+ /* 2nd check: Address families must be the same. */
+ if (AF(a1) != AF(a2))
+ return FALSE;
+
+ /* type check: address family determines buffer & size */
+ switch (AF(a1)) {
+ case AF_INET:
+ /* IPv4 is easy: clamp size, get byte pointers */
+ if (mbits > sizeof(NSRCADR(a1)) * 8)
+ mbits = sizeof(NSRCADR(a1)) * 8;
+ pm1 = (const void*)&NSRCADR(a1);
+ pm2 = (const void*)&NSRCADR(a2);
+ break;
+
+ case AF_INET6:
+ /* IPv6 is slightly different: Both scopes must match,
+ * too, before we even consider doing a match!
+ */
+ if ( ! SCOPE_EQ(a1, a2))
+ return FALSE;
+ if (mbits > sizeof(NSRCADR6(a1)) * 8)
+ mbits = sizeof(NSRCADR6(a1)) * 8;
+ pm1 = (const void*)&NSRCADR6(a1);
+ pm2 = (const void*)&NSRCADR6(a2);
+ break;
+
+ default:
+ /* don't know how to compare that!?! */
+ return FALSE;
+ }
+
+ /* Split bit length into byte length and partial byte mask.
+ * Note that the byte mask extends from the MSB of a byte down,
+ * and that zero shift (--> mbits % 8 == 0) results in an
+ * all-zero mask.
+ */
+ msk = 0xFFu ^ (0xFFu >> (mbits & 7));
+ len = mbits >> 3;
+
+ /* 3rd check: Do memcmp() over full bytes, if any */
+ if (len && memcmp(pm1, pm2, len))
+ return FALSE;
+
+ /* 4th check: compare last incomplete byte, if any */
+ if (msk && ((pm1[len] ^ pm2[len]) & msk))
+ return FALSE;
+
+ /* If none of the above failed, we're successfully through. */
+ return TRUE;
+}
+
+/*
+ * init_auth - initialize internal data
+ */
+void
+init_auth(void)
+{
+ size_t newalloc;
+
+ /*
+ * Initialize hash table and free list
+ */
+ newalloc = authhashbuckets * sizeof(key_hash[0]);
+
+ key_hash = erealloc(key_hash, newalloc);
+ memset(key_hash, '\0', newalloc);
+
+ INIT_DLIST(key_listhead, llink);
+
+#ifdef DEBUG
+ atexit(&free_auth_mem);
+#endif
+}
+
+
+/*
+ * free_auth_mem - assist in leak detection by freeing all dynamic
+ * allocations from this module.
+ */
+#ifdef DEBUG
+static void
+free_auth_mem(void)
+{
+ symkey * sk;
+ symkey_alloc * alloc;
+ symkey_alloc * next_alloc;
+
+ while (NULL != (sk = HEAD_DLIST(key_listhead, llink))) {
+ freesymkey(sk);
+ }
+ free(key_hash);
+ key_hash = NULL;
+ cache_keyid = 0;
+ cache_flags = 0;
+ cache_keyacclist = NULL;
+ for (alloc = authallocs; alloc != NULL; alloc = next_alloc) {
+ next_alloc = alloc->link;
+ free(alloc->mem);
+ }
+ authfreekeys = NULL;
+ authnumfreekeys = 0;
+}
+#endif /* DEBUG */
+
+
+/*
+ * auth_moremem - get some more free key structures
+ */
+void
+auth_moremem(
+ int keycount
+ )
+{
+ symkey * sk;
+ int i;
+#ifdef DEBUG
+ void * base;
+ symkey_alloc * allocrec;
+# define MOREMEM_EXTRA_ALLOC (sizeof(*allocrec))
+#else
+# define MOREMEM_EXTRA_ALLOC (0)
+#endif
+
+ i = (keycount > 0)
+ ? keycount
+ : MEMINC;
+ sk = eallocarrayxz(i, sizeof(*sk), MOREMEM_EXTRA_ALLOC);
+#ifdef DEBUG
+ base = sk;
+#endif
+ authnumfreekeys += i;
+
+ for (; i > 0; i--, sk++) {
+ LINK_SLIST(authfreekeys, sk, llink.f);
+ }
+
+#ifdef DEBUG
+ allocrec = (void *)sk;
+ allocrec->mem = base;
+ LINK_SLIST(authallocs, allocrec, link);
+#endif
+}
+
+
+/*
+ * auth_prealloc_symkeys
+ */
+void
+auth_prealloc_symkeys(
+ int keycount
+ )
+{
+ int allocated;
+ int additional;
+
+ allocated = authnumkeys + authnumfreekeys;
+ additional = keycount - allocated;
+ if (additional > 0)
+ auth_moremem(additional);
+ auth_resize_hashtable();
+}
+
+
+static u_short
+auth_log2(size_t x)
+{
+ /*
+ ** bithack to calculate floor(log2(x))
+ **
+ ** This assumes
+ ** - (sizeof(size_t) is a power of two
+ ** - CHAR_BITS is a power of two
+ ** - returning zero for arguments <= 0 is OK.
+ **
+ ** Does only shifts, masks and sums in integer arithmetic in
+ ** log2(CHAR_BIT*sizeof(size_t)) steps. (that is, 5/6 steps for
+ ** 32bit/64bit size_t)
+ */
+ int s;
+ int r = 0;
+ size_t m = ~(size_t)0;
+
+ for (s = sizeof(size_t) / 2 * CHAR_BIT; s != 0; s >>= 1) {
+ m <<= s;
+ if (x & m)
+ r += s;
+ else
+ x <<= s;
+ }
+ return (u_short)r;
+}
+
+int/*BOOL*/
+ipaddr_match_masked(const sockaddr_u *,const sockaddr_u *,
+ unsigned int mbits);
+
+static void
+authcache_flush_id(
+ keyid_t id
+ )
+{
+ if (cache_keyid == id) {
+ cache_keyid = 0;
+ cache_type = 0;
+ cache_flags = 0;
+ cache_secret = NULL;
+ cache_secretsize = 0;
+ cache_keyacclist = NULL;
+ }
+}
+
+
+/*
+ * auth_resize_hashtable
+ *
+ * Size hash table to average 4 or fewer entries per bucket initially,
+ * within the bounds of at least 4 and no more than 15 bits for the hash
+ * table index. Populate the hash table.
+ */
+static void
+auth_resize_hashtable(void)
+{
+ u_long totalkeys;
+ u_short hashbits;
+ u_short hash;
+ size_t newalloc;
+ symkey * sk;
+
+ totalkeys = authnumkeys + authnumfreekeys;
+ hashbits = auth_log2(totalkeys / 4) + 1;
+ hashbits = max(4, hashbits);
+ hashbits = min(15, hashbits);
+
+ authhashbuckets = 1 << hashbits;
+ authhashmask = authhashbuckets - 1;
+ newalloc = authhashbuckets * sizeof(key_hash[0]);
+
+ key_hash = erealloc(key_hash, newalloc);
+ memset(key_hash, '\0', newalloc);
+
+ ITER_DLIST_BEGIN(key_listhead, sk, llink, symkey)
+ hash = KEYHASH(sk->keyid);
+ LINK_SLIST(key_hash[hash], sk, hlink);
+ ITER_DLIST_END()
+}
+
+
+/*
+ * allocsymkey - common code to allocate and link in symkey
+ *
+ * secret must be allocated with a free-compatible allocator. It is
+ * owned by the referring symkey structure, and will be free()d by
+ * freesymkey().
+ */
+static void
+allocsymkey(
+ keyid_t id,
+ u_short flags,
+ u_short type,
+ u_long lifetime,
+ size_t secretsize,
+ u_char * secret,
+ KeyAccT * ka
+ )
+{
+ symkey * sk;
+ symkey ** bucket;
+
+ bucket = &key_hash[KEYHASH(id)];
+
+
+ if (authnumfreekeys < 1)
+ auth_moremem(-1);
+ UNLINK_HEAD_SLIST(sk, authfreekeys, llink.f);
+ DEBUG_ENSURE(sk != NULL);
+ sk->keyid = id;
+ sk->flags = flags;
+ sk->type = type;
+ sk->secretsize = secretsize;
+ sk->secret = secret;
+ sk->keyacclist = ka;
+ sk->lifetime = lifetime;
+ LINK_SLIST(*bucket, sk, hlink);
+ LINK_TAIL_DLIST(key_listhead, sk, llink);
+ authnumfreekeys--;
+ authnumkeys++;
+}
+
+
+/*
+ * freesymkey - common code to remove a symkey and recycle its entry.
+ */
+static void
+freesymkey(
+ symkey * sk
+ )
+{
+ symkey ** bucket;
+ symkey * unlinked;
+
+ if (NULL == sk)
+ return;
+
+ authcache_flush_id(sk->keyid);
+ keyacc_all_free(sk->keyacclist);
+
+ bucket = &key_hash[KEYHASH(sk->keyid)];
+ if (sk->secret != NULL) {
+ memset(sk->secret, '\0', sk->secretsize);
+ free(sk->secret);
+ }
+ UNLINK_SLIST(unlinked, *bucket, sk, hlink, symkey);
+ DEBUG_ENSURE(sk == unlinked);
+ UNLINK_DLIST(sk, llink);
+ memset((char *)sk + offsetof(symkey, symkey_payload), '\0',
+ sizeof(*sk) - offsetof(symkey, symkey_payload));
+ LINK_SLIST(authfreekeys, sk, llink.f);
+ authnumkeys--;
+ authnumfreekeys++;
+}
+
+
+/*
+ * auth_findkey - find a key in the hash table
+ */
+struct savekey *
+auth_findkey(
+ keyid_t id
+ )
+{
+ symkey * sk;
+
+ for (sk = key_hash[KEYHASH(id)]; sk != NULL; sk = sk->hlink)
+ if (id == sk->keyid)
+ return sk;
+ return NULL;
+}
+
+
+/*
+ * auth_havekey - return TRUE if the key id is zero or known. The
+ * key needs not to be trusted.
+ */
+int
+auth_havekey(
+ keyid_t id
+ )
+{
+ return
+ (0 == id) ||
+ (cache_keyid == id) ||
+ (NULL != auth_findkey(id));
+}
+
+
+/*
+ * authhavekey - return TRUE and cache the key, if zero or both known
+ * and trusted.
+ */
+int
+authhavekey(
+ keyid_t id
+ )
+{
+ symkey * sk;
+
+ authkeylookups++;
+ if (0 == id || cache_keyid == id)
+ return !!(KEY_TRUSTED & cache_flags);
+
+ /*
+ * Search the bin for the key. If not found, or found but the key
+ * type is zero, somebody marked it trusted without specifying a
+ * key or key type. In this case consider the key missing.
+ */
+ authkeyuncached++;
+ sk = auth_findkey(id);
+ if ((sk == NULL) || (sk->type == 0)) {
+ authkeynotfound++;
+ return FALSE;
+ }
+
+ /*
+ * If the key is not trusted, the key is not considered found.
+ */
+ if ( ! (KEY_TRUSTED & sk->flags)) {
+ authnokey++;
+ return FALSE;
+ }
+
+ /*
+ * The key is found and trusted. Initialize the key cache.
+ */
+ cache_keyid = sk->keyid;
+ cache_type = sk->type;
+ cache_flags = sk->flags;
+ cache_secret = sk->secret;
+ cache_secretsize = sk->secretsize;
+ cache_keyacclist = sk->keyacclist;
+
+ return TRUE;
+}
+
+
+/*
+ * authtrust - declare a key to be trusted/untrusted
+ */
+void
+authtrust(
+ keyid_t id,
+ u_long trust
+ )
+{
+ symkey * sk;
+ u_long lifetime;
+
+ /*
+ * Search bin for key; if it does not exist and is untrusted,
+ * forget it.
+ */
+
+ sk = auth_findkey(id);
+ if (!trust && sk == NULL)
+ return;
+
+ /*
+ * There are two conditions remaining. Either it does not
+ * exist and is to be trusted or it does exist and is or is
+ * not to be trusted.
+ */
+ if (sk != NULL) {
+ /*
+ * Key exists. If it is to be trusted, say so and update
+ * its lifetime. If no longer trusted, return it to the
+ * free list. Flush the cache first to be sure there are
+ * no discrepancies.
+ */
+ authcache_flush_id(id);
+ if (trust > 0) {
+ sk->flags |= KEY_TRUSTED;
+ if (trust > 1)
+ sk->lifetime = current_time + trust;
+ else
+ sk->lifetime = 0;
+ } else {
+ freesymkey(sk);
+ }
+ return;
+ }
+
+ /*
+ * keyid is not present, but the is to be trusted. We allocate
+ * a new key, but do not specify a key type or secret.
+ */
+ if (trust > 1) {
+ lifetime = current_time + trust;
+ } else {
+ lifetime = 0;
+ }
+ allocsymkey(id, KEY_TRUSTED, 0, lifetime, 0, NULL, NULL);
+}
+
+
+/*
+ * authistrusted - determine whether a key is trusted
+ */
+int
+authistrusted(
+ keyid_t id
+ )
+{
+ symkey * sk;
+
+ if (id == cache_keyid)
+ return !!(KEY_TRUSTED & cache_flags);
+
+ authkeyuncached++;
+ sk = auth_findkey(id);
+ if (sk == NULL || !(KEY_TRUSTED & sk->flags)) {
+ authkeynotfound++;
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+/*
+ * authistrustedip - determine if the IP is OK for the keyid
+ */
+ int
+ authistrustedip(
+ keyid_t keyno,
+ sockaddr_u * sau
+ )
+{
+ symkey * sk;
+
+ if (keyno == cache_keyid) {
+ return (KEY_TRUSTED & cache_flags) &&
+ keyacc_contains(cache_keyacclist, sau, TRUE);
+ }
+
+ if (NULL != (sk = auth_findkey(keyno))) {
+ authkeyuncached++;
+ return (KEY_TRUSTED & sk->flags) &&
+ keyacc_contains(sk->keyacclist, sau, TRUE);
+ }
+
+ authkeynotfound++;
+ return FALSE;
+}
+
+/* Note: There are two locations below where 'strncpy()' is used. While
+ * this function is a hazard by itself, it's essential that it is used
+ * here. Bug 1243 involved that the secret was filled with NUL bytes
+ * after the first NUL encountered, and 'strlcpy()' simply does NOT have
+ * this behaviour. So disabling the fix and reverting to the buggy
+ * behaviour due to compatibility issues MUST also fill with NUL and
+ * this needs 'strncpy'. Also, the secret is managed as a byte blob of a
+ * given size, and eventually truncating it and replacing the last byte
+ * with a NUL would be a bug.
+ * perlinger@ntp.org 2015-10-10
+ */
+void
+MD5auth_setkey(
+ keyid_t keyno,
+ int keytype,
+ const u_char *key,
+ size_t secretsize,
+ KeyAccT *ka
+ )
+{
+ symkey * sk;
+ u_char * secret;
+
+ DEBUG_ENSURE(keytype <= USHRT_MAX);
+ DEBUG_ENSURE(secretsize < 4 * 1024);
+ /*
+ * See if we already have the key. If so just stick in the
+ * new value.
+ */
+ sk = auth_findkey(keyno);
+ if (sk != NULL && keyno == sk->keyid) {
+ /* TALOS-CAN-0054: make sure we have a new buffer! */
+ if (NULL != sk->secret) {
+ memset(sk->secret, 0, sk->secretsize);
+ free(sk->secret);
+ }
+ sk->secret = emalloc(secretsize + 1);
+ sk->type = (u_short)keytype;
+ sk->secretsize = secretsize;
+ /* make sure access lists don't leak here! */
+ if (ka != sk->keyacclist) {
+ keyacc_all_free(sk->keyacclist);
+ sk->keyacclist = ka;
+ }
+#ifndef DISABLE_BUG1243_FIX
+ memcpy(sk->secret, key, secretsize);
+#else
+ /* >MUST< use 'strncpy()' here! See above! */
+ strncpy((char *)sk->secret, (const char *)key,
+ secretsize);
+#endif
+ authcache_flush_id(keyno);
+ return;
+ }
+
+ /*
+ * Need to allocate new structure. Do it.
+ */
+ secret = emalloc(secretsize + 1);
+#ifndef DISABLE_BUG1243_FIX
+ memcpy(secret, key, secretsize);
+#else
+ /* >MUST< use 'strncpy()' here! See above! */
+ strncpy((char *)secret, (const char *)key, secretsize);
+#endif
+ allocsymkey(keyno, 0, (u_short)keytype, 0,
+ secretsize, secret, ka);
+#ifdef DEBUG
+ if (debug >= 4) {
+ size_t j;
+
+ printf("auth_setkey: key %d type %d len %d ", (int)keyno,
+ keytype, (int)secretsize);
+ for (j = 0; j < secretsize; j++) {
+ printf("%02x", secret[j]);
+ }
+ printf("\n");
+ }
+#endif
+}
+
+
+/*
+ * auth_delkeys - delete non-autokey untrusted keys, and clear all info
+ * except the trusted bit of non-autokey trusted keys, in
+ * preparation for rereading the keys file.
+ */
+void
+auth_delkeys(void)
+{
+ symkey * sk;
+
+ ITER_DLIST_BEGIN(key_listhead, sk, llink, symkey)
+ if (sk->keyid > NTP_MAXKEY) { /* autokey */
+ continue;
+ }
+
+ /*
+ * Don't lose info as to which keys are trusted. Make
+ * sure there are no dangling pointers!
+ */
+ if (KEY_TRUSTED & sk->flags) {
+ if (sk->secret != NULL) {
+ memset(sk->secret, 0, sk->secretsize);
+ free(sk->secret);
+ sk->secret = NULL; /* TALOS-CAN-0054 */
+ }
+ sk->keyacclist = keyacc_all_free(sk->keyacclist);
+ sk->secretsize = 0;
+ sk->lifetime = 0;
+ } else {
+ freesymkey(sk);
+ }
+ ITER_DLIST_END()
+}
+
+
+/*
+ * auth_agekeys - delete keys whose lifetimes have expired
+ */
+void
+auth_agekeys(void)
+{
+ symkey * sk;
+
+ ITER_DLIST_BEGIN(key_listhead, sk, llink, symkey)
+ if (sk->lifetime > 0 && current_time > sk->lifetime) {
+ freesymkey(sk);
+ authkeyexpired++;
+ }
+ ITER_DLIST_END()
+ DPRINTF(1, ("auth_agekeys: at %lu keys %lu expired %lu\n",
+ current_time, authnumkeys, authkeyexpired));
+}
+
+
+/*
+ * authencrypt - generate message authenticator
+ *
+ * Returns length of authenticator field, zero if key not found.
+ */
+size_t
+authencrypt(
+ keyid_t keyno,
+ u_int32 * pkt,
+ size_t length
+ )
+{
+ /*
+ * A zero key identifier means the sender has not verified
+ * the last message was correctly authenticated. The MAC
+ * consists of a single word with value zero.
+ */
+ authencryptions++;
+ pkt[length / 4] = htonl(keyno);
+ if (0 == keyno) {
+ return 4;
+ }
+ if (!authhavekey(keyno)) {
+ return 0;
+ }
+
+ return MD5authencrypt(cache_type,
+ cache_secret, cache_secretsize,
+ pkt, length);
+}
+
+
+/*
+ * authdecrypt - verify message authenticator
+ *
+ * Returns TRUE if authenticator valid, FALSE if invalid or not found.
+ */
+int
+authdecrypt(
+ keyid_t keyno,
+ u_int32 * pkt,
+ size_t length,
+ size_t size
+ )
+{
+ /*
+ * A zero key identifier means the sender has not verified
+ * the last message was correctly authenticated. For our
+ * purpose this is an invalid authenticator.
+ */
+ authdecryptions++;
+ if (0 == keyno || !authhavekey(keyno) || size < 4) {
+ return FALSE;
+ }
+
+ return MD5authdecrypt(cache_type,
+ cache_secret, cache_secretsize,
+ pkt, length, size);
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/libntp/authreadkeys.c b/sebhbsd/freebsd/contrib/ntp/libntp/authreadkeys.c
new file mode 100644
index 0000000..f0b878a
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/libntp/authreadkeys.c
@@ -0,0 +1,409 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * authreadkeys.c - routines to support the reading of the key file
+ */
+#include <config.h>
+#include <stdio.h>
+#include <ctype.h>
+
+//#include "ntpd.h" /* Only for DPRINTF */
+//#include "ntp_fp.h"
+#include "ntp.h"
+#include "ntp_syslog.h"
+#include "ntp_stdlib.h"
+#include "ntp_keyacc.h"
+
+#ifdef OPENSSL
+#include "openssl/objects.h"
+#include "openssl/evp.h"
+#endif /* OPENSSL */
+
+/* Forwards */
+static char *nexttok (char **);
+
+/*
+ * nexttok - basic internal tokenizing routine
+ */
+static char *
+nexttok(
+ char **str
+ )
+{
+ register char *cp;
+ char *starttok;
+
+ cp = *str;
+
+ /*
+ * Space past white space
+ */
+ while (*cp == ' ' || *cp == '\t')
+ cp++;
+
+ /*
+ * Save this and space to end of token
+ */
+ starttok = cp;
+ while (*cp != '\0' && *cp != '\n' && *cp != ' '
+ && *cp != '\t' && *cp != '#')
+ cp++;
+
+ /*
+ * If token length is zero return an error, else set end of
+ * token to zero and return start.
+ */
+ if (starttok == cp)
+ return NULL;
+
+ if (*cp == ' ' || *cp == '\t')
+ *cp++ = '\0';
+ else
+ *cp = '\0';
+
+ *str = cp;
+ return starttok;
+}
+
+
+/* TALOS-CAN-0055: possibly DoS attack by setting the key file to the
+ * log file. This is hard to prevent (it would need to check two files
+ * to be the same on the inode level, which will not work so easily with
+ * Windows or VMS) but we can avoid the self-amplification loop: We only
+ * log the first 5 errors, silently ignore the next 10 errors, and give
+ * up when when we have found more than 15 errors.
+ *
+ * This avoids the endless file iteration we will end up with otherwise,
+ * and also avoids overflowing the log file.
+ *
+ * Nevertheless, once this happens, the keys are gone since this would
+ * require a save/swap strategy that is not easy to apply due to the
+ * data on global/static level.
+ */
+
+static const u_int nerr_loglimit = 5u;
+static const u_int nerr_maxlimit = 15;
+
+static void log_maybe(u_int*, const char*, ...) NTP_PRINTF(2, 3);
+
+typedef struct keydata KeyDataT;
+struct keydata {
+ KeyDataT *next; /* queue/stack link */
+ KeyAccT *keyacclist; /* key access list */
+ keyid_t keyid; /* stored key ID */
+ u_short keytype; /* stored key type */
+ u_short seclen; /* length of secret */
+ u_char secbuf[1]; /* begin of secret (formal only)*/
+};
+
+static void
+log_maybe(
+ u_int *pnerr,
+ const char *fmt ,
+ ...)
+{
+ va_list ap;
+ if ((NULL == pnerr) || (++(*pnerr) <= nerr_loglimit)) {
+ va_start(ap, fmt);
+ mvsyslog(LOG_ERR, fmt, ap);
+ va_end(ap);
+ }
+}
+
+static void
+free_keydata(
+ KeyDataT *node
+ )
+{
+ KeyAccT *kap;
+
+ if (node) {
+ while (node->keyacclist) {
+ kap = node->keyacclist;
+ node->keyacclist = kap->next;
+ free(kap);
+ }
+
+ /* purge secrets from memory before free()ing it */
+ memset(node, 0, sizeof(*node) + node->seclen);
+ free(node);
+ }
+}
+
+/*
+ * authreadkeys - (re)read keys from a file.
+ */
+int
+authreadkeys(
+ const char *file
+ )
+{
+ FILE *fp;
+ char *line;
+ char *token;
+ keyid_t keyno;
+ int keytype;
+ char buf[512]; /* lots of room for line */
+ u_char keystr[32]; /* Bug 2537 */
+ size_t len;
+ size_t j;
+ u_int nerr;
+ KeyDataT *list = NULL;
+ KeyDataT *next = NULL;
+
+ /*
+ * Open file. Complain and return if it can't be opened.
+ */
+ fp = fopen(file, "r");
+ if (fp == NULL) {
+ msyslog(LOG_ERR, "authreadkeys: file '%s': %m",
+ file);
+ goto onerror;
+ }
+ INIT_SSL();
+
+ /*
+ * Now read lines from the file, looking for key entries. Put
+ * the data into temporary store for later propagation to avoid
+ * two-pass processing.
+ */
+ nerr = 0;
+ while ((line = fgets(buf, sizeof buf, fp)) != NULL) {
+ if (nerr > nerr_maxlimit)
+ break;
+ token = nexttok(&line);
+ if (token == NULL)
+ continue;
+
+ /*
+ * First is key number. See if it is okay.
+ */
+ keyno = atoi(token);
+ if (keyno < 1) {
+ log_maybe(&nerr,
+ "authreadkeys: cannot change key %s",
+ token);
+ continue;
+ }
+
+ if (keyno > NTP_MAXKEY) {
+ log_maybe(&nerr,
+ "authreadkeys: key %s > %d reserved for Autokey",
+ token, NTP_MAXKEY);
+ continue;
+ }
+
+ /*
+ * Next is keytype. See if that is all right.
+ */
+ token = nexttok(&line);
+ if (token == NULL) {
+ log_maybe(&nerr,
+ "authreadkeys: no key type for key %d",
+ keyno);
+ continue;
+ }
+
+ /* We want to silently ignore keys where we do not
+ * support the requested digest type. OTOH, we want to
+ * make sure the file is well-formed. That means we
+ * have to process the line completely and have to
+ * finally throw away the result... This is a bit more
+ * work, but it also results in better error detection.
+ */
+#ifdef OPENSSL
+ /*
+ * The key type is the NID used by the message digest
+ * algorithm. There are a number of inconsistencies in
+ * the OpenSSL database. We attempt to discover them
+ * here and prevent use of inconsistent data later.
+ */
+ keytype = keytype_from_text(token, NULL);
+ if (keytype == 0) {
+ log_maybe(NULL,
+ "authreadkeys: invalid type for key %d",
+ keyno);
+# ifdef ENABLE_CMAC
+ } else if (NID_cmac != keytype &&
+ EVP_get_digestbynid(keytype) == NULL) {
+ log_maybe(NULL,
+ "authreadkeys: no algorithm for key %d",
+ keyno);
+ keytype = 0;
+# endif /* ENABLE_CMAC */
+ }
+#else /* !OPENSSL follows */
+ /*
+ * The key type is unused, but is required to be 'M' or
+ * 'm' for compatibility.
+ */
+ if (!(*token == 'M' || *token == 'm')) {
+ log_maybe(NULL,
+ "authreadkeys: invalid type for key %d",
+ keyno);
+ keytype = 0;
+ } else {
+ keytype = KEY_TYPE_MD5;
+ }
+#endif /* !OPENSSL */
+
+ /*
+ * Finally, get key and insert it. If it is longer than 20
+ * characters, it is a binary string encoded in hex;
+ * otherwise, it is a text string of printable ASCII
+ * characters.
+ */
+ token = nexttok(&line);
+ if (token == NULL) {
+ log_maybe(&nerr,
+ "authreadkeys: no key for key %d", keyno);
+ continue;
+ }
+ next = NULL;
+ len = strlen(token);
+ if (len <= 20) { /* Bug 2537 */
+ next = emalloc(sizeof(KeyDataT) + len);
+ next->keyacclist = NULL;
+ next->keyid = keyno;
+ next->keytype = keytype;
+ next->seclen = len;
+ memcpy(next->secbuf, token, len);
+ } else {
+ static const char hex[] = "0123456789abcdef";
+ u_char temp;
+ char *ptr;
+ size_t jlim;
+
+ jlim = min(len, 2 * sizeof(keystr));
+ for (j = 0; j < jlim; j++) {
+ ptr = strchr(hex, tolower((unsigned char)token[j]));
+ if (ptr == NULL)
+ break; /* abort decoding */
+ temp = (u_char)(ptr - hex);
+ if (j & 1)
+ keystr[j / 2] |= temp;
+ else
+ keystr[j / 2] = temp << 4;
+ }
+ if (j < jlim) {
+ log_maybe(&nerr,
+ "authreadkeys: invalid hex digit for key %d",
+ keyno);
+ continue;
+ }
+ len = jlim/2; /* hmmmm.... what about odd length?!? */
+ next = emalloc(sizeof(KeyDataT) + len);
+ next->keyacclist = NULL;
+ next->keyid = keyno;
+ next->keytype = keytype;
+ next->seclen = len;
+ memcpy(next->secbuf, keystr, len);
+ }
+
+ token = nexttok(&line);
+ if (token != NULL) { /* A comma-separated IP access list */
+ char *tp = token;
+
+ while (tp) {
+ char *i;
+ char *snp; /* subnet text pointer */
+ unsigned int snbits;
+ sockaddr_u addr;
+
+ i = strchr(tp, (int)',');
+ if (i) {
+ *i = '\0';
+ }
+ snp = strchr(tp, (int)'/');
+ if (snp) {
+ char *sp;
+
+ *snp++ = '\0';
+ snbits = 0;
+ sp = snp;
+
+ while (*sp != '\0') {
+ if (!isdigit((unsigned char)*sp))
+ break;
+ if (snbits > 1000)
+ break; /* overflow */
+ snbits = 10 * snbits + (*sp++ - '0'); /* ascii dependent */
+ }
+ if (*sp != '\0') {
+ log_maybe(&nerr,
+ "authreadkeys: Invalid character in subnet specification for <%s/%s> in key %d",
+ sp, snp, keyno);
+ goto nextip;
+ }
+ } else {
+ snbits = UINT_MAX;
+ }
+
+ if (is_ip_address(tp, AF_UNSPEC, &addr)) {
+ /* Make sure that snbits is valid for addr */
+ if ((snbits < UINT_MAX) &&
+ ( (IS_IPV4(&addr) && snbits > 32) ||
+ (IS_IPV6(&addr) && snbits > 128))) {
+ log_maybe(NULL,
+ "authreadkeys: excessive subnet mask <%s/%s> for key %d",
+ tp, snp, keyno);
+ }
+ next->keyacclist = keyacc_new_push(
+ next->keyacclist, &addr, snbits);
+ } else {
+ log_maybe(&nerr,
+ "authreadkeys: invalid IP address <%s> for key %d",
+ tp, keyno);
+ }
+
+ nextip:
+ if (i) {
+ tp = i + 1;
+ } else {
+ tp = 0;
+ }
+ }
+ }
+
+ /* check if this has to be weeded out... */
+ if (0 == keytype) {
+ free_keydata(next);
+ next = NULL;
+ continue;
+ }
+
+ INSIST(NULL != next);
+ next->next = list;
+ list = next;
+ }
+ fclose(fp);
+ if (nerr > 0) {
+ const char * why = "";
+ if (nerr > nerr_maxlimit)
+ why = " (emergency break)";
+ msyslog(LOG_ERR,
+ "authreadkeys: rejecting file '%s' after %u error(s)%s",
+ file, nerr, why);
+ goto onerror;
+ }
+
+ /* first remove old file-based keys */
+ auth_delkeys();
+ /* insert the new key material */
+ while (NULL != (next = list)) {
+ list = next->next;
+ MD5auth_setkey(next->keyid, next->keytype,
+ next->secbuf, next->seclen, next->keyacclist);
+ next->keyacclist = NULL; /* consumed by MD5auth_setkey */
+ free_keydata(next);
+ }
+ return (1);
+
+ onerror:
+ /* Mop up temporary storage before bailing out. */
+ while (NULL != (next = list)) {
+ list = next->next;
+ free_keydata(next);
+ }
+ return (0);
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/libntp/clocktypes.c b/sebhbsd/freebsd/contrib/ntp/libntp/clocktypes.c
new file mode 100644
index 0000000..b6d6007
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/libntp/clocktypes.c
@@ -0,0 +1,125 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Data for pretty printing clock types
+ */
+#include <config.h>
+#include <stdio.h>
+
+#include "ntp_fp.h"
+#include "ntp.h"
+#include "lib_strbuf.h"
+#include "ntp_refclock.h"
+#include "ntp_stdlib.h"
+
+struct clktype clktypes[] = {
+ { REFCLK_NONE, "unspecified type (0)",
+ "UNKNOWN" },
+ { REFCLK_LOCALCLOCK, "Undisciplined local clock (1)",
+ "LOCAL" },
+ { REFCLK_GPS_TRAK, "TRAK 8810 GPS Receiver (2)",
+ "GPS_TRAK" },
+ { REFCLK_WWV_PST, "PSTI/Traconex WWV/WWVH Receiver (3)",
+ "WWV_PST" },
+ { REFCLK_SPECTRACOM, "Spectracom (generic) Receivers (4)",
+ "SPECTRACOM" },
+ { REFCLK_TRUETIME, "TrueTime (generic) Receivers (5)",
+ "TRUETIME" },
+ { REFCLK_IRIG_AUDIO, "IRIG Audio Decoder (6)",
+ "IRIG_AUDIO" },
+ { REFCLK_CHU_AUDIO, "CHU Audio Demodulator/Decoder (7)",
+ "CHU_AUDIO" },
+ { REFCLK_PARSE, "Generic reference clock driver (8)",
+ "GENERIC" },
+ { REFCLK_GPS_MX4200, "Magnavox MX4200 GPS Receiver (9)",
+ "GPS_MX4200" },
+ { REFCLK_GPS_AS2201, "Austron 2201A GPS Receiver (10)",
+ "GPS_AS2201" },
+ { REFCLK_GPS_ARBITER, "Arbiter 1088A/B GPS Receiver (11)",
+ "GPS_ARBITER" },
+ { REFCLK_IRIG_TPRO, "KSI/Odetics TPRO/S IRIG Interface (12)",
+ "IRIG_TPRO" },
+ { REFCLK_ATOM_LEITCH, "Leitch CSD 5300 Master Clock Controller (13)",
+ "ATOM_LEITCH" },
+ { REFCLK_MSF_EES, "EES M201 MSF Receiver (14)",
+ "MSF_EES" },
+ { REFCLK_NONE, "not used (15)",
+ "NOT_USED" },
+ { REFCLK_IRIG_BANCOMM, "Bancomm GPS/IRIG Receiver (16)",
+ "GPS_BANC" },
+ { REFCLK_GPS_DATUM, "Datum Precision Time System (17)",
+ "GPS_DATUM" },
+ { REFCLK_ACTS, "Automated Computer Time Service (18)",
+ "ACTS_MODEM" },
+ { REFCLK_WWV_HEATH, "Heath WWV/WWVH Receiver (19)",
+ "WWV_HEATH" },
+ { REFCLK_GPS_NMEA, "Generic NMEA GPS Receiver (20)",
+ "GPS_NMEA" },
+ { REFCLK_GPS_VME, "TrueTime GPS-VME Interface (21)",
+ "GPS_VME" },
+ { REFCLK_ATOM_PPS, "PPS Clock Discipline (22)",
+ "PPS" },
+ { REFCLK_NONE, "not used (23)",
+ "NOT_USED" },
+ { REFCLK_NONE, "not used (24)",
+ "NOT_USED" },
+ { REFCLK_NONE, "not used (25)",
+ "NOT_USED" },
+ { REFCLK_GPS_HP, "HP 58503A GPS Time & Frequency Receiver (26)",
+ "GPS_HP" },
+ { REFCLK_ARCRON_MSF, "ARCRON MSF (and DCF77) Receiver (27)",
+ "MSF_ARCRON" },
+ { REFCLK_SHM, "Clock attached thru shared Memory (28)",
+ "SHM" },
+ { REFCLK_PALISADE, "Trimble Navigation Palisade GPS (29)",
+ "GPS_PALISADE" },
+ { REFCLK_ONCORE, "Motorola UT Oncore GPS (30)",
+ "GPS_ONCORE" },
+ { REFCLK_GPS_JUPITER, "Rockwell Jupiter GPS (31)",
+ "GPS_JUPITER" },
+ { REFCLK_CHRONOLOG, "Chrono-log K (32)",
+ "CHRONOLOG" },
+ { REFCLK_DUMBCLOCK, "Dumb generic hh:mm:ss local clock (33)",
+ "DUMBCLOCK" },
+ { REFCLK_ULINK, "Ultralink M320 WWVB receiver (34)",
+ "ULINK_M320"},
+ { REFCLK_PCF, "Conrad parallel port radio clock (35)",
+ "PCF"},
+ { REFCLK_WWV_AUDIO, "WWV/H Audio Demodulator/Decoder (36)",
+ "WWV_AUDIO"},
+ { REFCLK_FG, "Forum Graphic GPS Dating Station (37)",
+ "GPS_FG"},
+ { REFCLK_HOPF_SERIAL, "hopf Elektronic serial line receiver (38)",
+ "HOPF_S"},
+ { REFCLK_HOPF_PCI, "hopf Elektronic PCI receiver (39)",
+ "HOPF_P"},
+ { REFCLK_JJY, "JJY receiver (40)",
+ "JJY"},
+ { REFCLK_TT560, "TrueTime 560 IRIG-B decoder (41)",
+ "TT_IRIG"},
+ { REFCLK_ZYFER, "Zyfer GPStarplus receiver (42)",
+ "GPS_ZYFER" },
+ { REFCLK_RIPENCC, "RIPE NCC Trimble driver (43)",
+ "GPS_RIPENCC" },
+ { REFCLK_NEOCLOCK4X, "NeoClock4X DCF77 / TDF receiver (44)",
+ "NEOCLK4X"},
+ { REFCLK_TSYNCPCI, "Spectracom TSYNC PCI timing board (45)",
+ "PCI_TSYNC"},
+ { REFCLK_GPSDJSON, "GPSD JSON socket (46)",
+ "GPSD_JSON"},
+ { -1, "", "" }
+};
+
+const char *
+clockname(
+ int num
+ )
+{
+ register struct clktype *clk;
+
+ for (clk = clktypes; clk->code != -1; clk++) {
+ if (num == clk->code)
+ return (clk->abbrev);
+ }
+ return (NULL);
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/libntp/decodenetnum.c b/sebhbsd/freebsd/contrib/ntp/libntp/decodenetnum.c
new file mode 100644
index 0000000..db3d990
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/libntp/decodenetnum.c
@@ -0,0 +1,88 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * decodenetnum - return a net number (this is crude, but careful)
+ */
+#include <config.h>
+#include <sys/types.h>
+#include <ctype.h>
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#include "ntp.h"
+#include "ntp_stdlib.h"
+#include "ntp_assert.h"
+
+/*
+ * decodenetnum convert text IP address and port to sockaddr_u
+ *
+ * Returns 0 for failure, 1 for success.
+ */
+int
+decodenetnum(
+ const char *num,
+ sockaddr_u *netnum
+ )
+{
+ struct addrinfo hints, *ai = NULL;
+ int err;
+ u_short port;
+ const char *cp;
+ const char *port_str;
+ char *pp;
+ char *np;
+ char name[80];
+
+ REQUIRE(num != NULL);
+
+ if (strlen(num) >= sizeof(name)) {
+ return 0;
+ }
+
+ port_str = NULL;
+ if ('[' != num[0]) {
+ /*
+ * to distinguish IPv6 embedded colons from a port
+ * specification on an IPv4 address, assume all
+ * legal IPv6 addresses have at least two colons.
+ */
+ pp = strchr(num, ':');
+ if (NULL == pp)
+ cp = num; /* no colons */
+ else if (NULL != strchr(pp + 1, ':'))
+ cp = num; /* two or more colons */
+ else { /* one colon */
+ strlcpy(name, num, sizeof(name));
+ cp = name;
+ pp = strchr(cp, ':');
+ *pp = '\0';
+ port_str = pp + 1;
+ }
+ } else {
+ cp = num + 1;
+ np = name;
+ while (*cp && ']' != *cp)
+ *np++ = *cp++;
+ *np = 0;
+ if (']' == cp[0] && ':' == cp[1] && '\0' != cp[2])
+ port_str = &cp[2];
+ cp = name;
+ }
+ ZERO(hints);
+ hints.ai_flags = Z_AI_NUMERICHOST;
+ err = getaddrinfo(cp, "ntp", &hints, &ai);
+ if (err != 0)
+ return 0;
+ INSIST(ai->ai_addrlen <= sizeof(*netnum));
+ ZERO(*netnum);
+ memcpy(netnum, ai->ai_addr, ai->ai_addrlen);
+ freeaddrinfo(ai);
+ if (NULL == port_str || 1 != sscanf(port_str, "%hu", &port))
+ port = NTP_PORT;
+ SET_PORT(netnum, port);
+ return 1;
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/libntp/dolfptoa.c b/sebhbsd/freebsd/contrib/ntp/libntp/dolfptoa.c
new file mode 100644
index 0000000..b66e296
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/libntp/dolfptoa.c
@@ -0,0 +1,176 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * dolfptoa - do the grunge work of converting an l_fp number to decimal
+ */
+#include <config.h>
+#include <stdio.h>
+
+#include "ntp_fp.h"
+#include "lib_strbuf.h"
+#include "ntp_string.h"
+#include "ntp_stdlib.h"
+
+char *
+dolfptoa(
+ u_int32 fpi,
+ u_int32 fpv,
+ int neg,
+ short ndec,
+ int msec
+ )
+{
+ u_char *cp, *cpend, *cpdec;
+ int dec;
+ u_char cbuf[24];
+ char *buf, *bp;
+
+ /*
+ * Get a string buffer before starting
+ */
+ LIB_GETBUF(buf);
+
+ /*
+ * Zero the character buffer
+ */
+ ZERO(cbuf);
+
+ /*
+ * Work on the integral part. This should work reasonable on
+ * all machines with 32 bit arithmetic. Please note that 32 bits
+ * can *always* be represented with at most 10 decimal digits,
+ * including a possible rounding from the fractional part.
+ */
+ cp = cpend = cpdec = &cbuf[10];
+ for (dec = (int)(cp - cbuf); dec > 0 && fpi != 0; dec--) {
+ /* can add another digit */
+ u_int32 digit;
+
+ digit = fpi;
+ fpi /= 10U;
+ digit -= (fpi << 3) + (fpi << 1); /* i*10 */
+ *--cp = (u_char)digit;
+ }
+
+ /*
+ * Done that, now deal with the problem of the fraction. First
+ * determine the number of decimal places.
+ */
+ dec = ndec;
+ if (dec < 0)
+ dec = 0;
+ if (msec) {
+ dec += 3;
+ cpdec += 3;
+ }
+ if ((size_t)dec > sizeof(cbuf) - (cpend - cbuf))
+ dec = (int)(sizeof(cbuf) - (cpend - cbuf));
+
+ /*
+ * If there's a fraction to deal with, do so.
+ */
+ for (/*NOP*/; dec > 0 && fpv != 0; dec--) {
+ u_int32 digit, tmph, tmpl;
+
+ /*
+ * The scheme here is to multiply the fraction
+ * (0.1234...) by ten. This moves a junk of BCD into
+ * the units part. record that and iterate.
+ * multiply by shift/add in two dwords.
+ */
+ digit = 0;
+ M_LSHIFT(digit, fpv);
+ tmph = digit;
+ tmpl = fpv;
+ M_LSHIFT(digit, fpv);
+ M_LSHIFT(digit, fpv);
+ M_ADD(digit, fpv, tmph, tmpl);
+ *cpend++ = (u_char)digit;
+ }
+
+ /* decide whether to round or simply extend by zeros */
+ if (dec > 0) {
+ /* only '0' digits left -- just reposition end */
+ cpend += dec;
+ } else {
+ /* some bits remain in 'fpv'; do round */
+ u_char *tp = cpend;
+ int carry = ((fpv & 0x80000000) != 0);
+
+ for (dec = (int)(tp - cbuf); carry && dec > 0; dec--) {
+ *--tp += 1;
+ if (*tp == 10)
+ *tp = 0;
+ else
+ carry = FALSE;
+ }
+
+ if (tp < cp) /* rounding from 999 to 1000 or similiar? */
+ cp = tp;
+ }
+
+ /*
+ * We've now got the fraction in cbuf[], with cp pointing at
+ * the first character, cpend pointing past the last, and
+ * cpdec pointing at the first character past the decimal.
+ * Remove leading zeros, then format the number into the
+ * buffer.
+ */
+ while (cp < cpdec && *cp == 0)
+ cp++;
+ if (cp >= cpdec)
+ cp = cpdec - 1;
+
+ bp = buf;
+ if (neg)
+ *bp++ = '-';
+ while (cp < cpend) {
+ if (cp == cpdec)
+ *bp++ = '.';
+ *bp++ = (char)(*cp++) + '0';
+ }
+ *bp = '\0';
+
+ /*
+ * Done!
+ */
+ return buf;
+}
+
+
+char *
+mfptoa(
+ u_int32 fpi,
+ u_int32 fpf,
+ short ndec
+ )
+{
+ int isneg;
+
+ isneg = M_ISNEG(fpi);
+ if (isneg) {
+ M_NEG(fpi, fpf);
+ }
+
+ return dolfptoa(fpi, fpf, isneg, ndec, FALSE);
+}
+
+
+char *
+mfptoms(
+ u_int32 fpi,
+ u_int32 fpf,
+ short ndec
+ )
+{
+ int isneg;
+
+ isneg = M_ISNEG(fpi);
+ if (isneg) {
+ M_NEG(fpi, fpf);
+ }
+
+ return dolfptoa(fpi, fpf, isneg, ndec, TRUE);
+}
+
+
diff --git a/sebhbsd/freebsd/contrib/ntp/libntp/emalloc.c b/sebhbsd/freebsd/contrib/ntp/libntp/emalloc.c
new file mode 100644
index 0000000..10c2d80
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/libntp/emalloc.c
@@ -0,0 +1,152 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * emalloc - return new memory obtained from the system. Belch if none.
+ */
+#include <config.h>
+#include "ntp_types.h"
+#include "ntp_malloc.h"
+#include "ntp_syslog.h"
+#include "ntp_stdlib.h"
+
+
+/*
+ * When using the debug MS CRT allocator, each allocation stores the
+ * callsite __FILE__ and __LINE__, which is then displayed at process
+ * termination, to track down leaks. We don't want all of our
+ * allocations to show up as coming from emalloc.c, so we preserve the
+ * original callsite's source file and line using macros which pass
+ * __FILE__ and __LINE__ as parameters to these routines.
+ * Other debug malloc implementations can be used by defining
+ * EREALLOC_IMPL() as ports/winnt/include/config.h does.
+ */
+
+void *
+ereallocz(
+ void * ptr,
+ size_t newsz,
+ size_t priorsz,
+ int zero_init
+#ifdef EREALLOC_CALLSITE /* ntp_malloc.h */
+ ,
+ const char * file,
+ int line
+#endif
+ )
+{
+ char * mem;
+ size_t allocsz;
+
+ if (0 == newsz)
+ allocsz = 1;
+ else
+ allocsz = newsz;
+
+ mem = EREALLOC_IMPL(ptr, allocsz, file, line);
+ if (NULL == mem) {
+ msyslog_term = TRUE;
+#ifndef EREALLOC_CALLSITE
+ msyslog(LOG_ERR, "fatal out of memory (%lu bytes)",
+ (u_long)newsz);
+#else
+ msyslog(LOG_ERR,
+ "fatal out of memory %s line %d (%lu bytes)",
+ file, line, (u_long)newsz);
+#endif
+ exit(1);
+ }
+
+ if (zero_init && newsz > priorsz)
+ zero_mem(mem + priorsz, newsz - priorsz);
+
+ return mem;
+}
+
+/* oreallocarray.c is licensed under the following:
+ * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
+ * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
+ */
+#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
+
+void *
+oreallocarrayxz(
+ void *optr,
+ size_t nmemb,
+ size_t size,
+ size_t extra
+#ifdef EREALLOC_CALLSITE /* ntp_malloc.h */
+ ,
+ const char * file,
+ int line
+#endif
+ )
+{
+ if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
+ nmemb > 0 && SIZE_MAX / nmemb < size) {
+#ifndef EREALLOC_CALLSITE
+ msyslog(LOG_ERR, "fatal allocation size overflow");
+#else
+ msyslog(LOG_ERR,
+ "fatal allocation size overflow %s line %d",
+ file, line);
+#endif
+ exit(1);
+ }
+#ifndef EREALLOC_CALLSITE
+ return ereallocz(optr, extra + (size * nmemb), 0, TRUE);
+#else
+ return ereallocz(optr, extra + (size * nmemb), 0, TRUE, file, line);
+#endif
+}
+
+char *
+estrdup_impl(
+ const char * str
+#ifdef EREALLOC_CALLSITE
+ ,
+ const char * file,
+ int line
+#endif
+ )
+{
+ char * copy;
+ size_t bytes;
+
+ bytes = strlen(str) + 1;
+ copy = ereallocz(NULL, bytes, 0, FALSE
+#ifdef EREALLOC_CALLSITE
+ , file, line
+#endif
+ );
+ memcpy(copy, str, bytes);
+
+ return copy;
+}
+
+
+#if 0
+#ifndef EREALLOC_CALLSITE
+void *
+emalloc(size_t newsz)
+{
+ return ereallocz(NULL, newsz, 0, FALSE);
+}
+#endif
+#endif
+
diff --git a/sebhbsd/freebsd/contrib/ntp/libntp/findconfig.c b/sebhbsd/freebsd/contrib/ntp/libntp/findconfig.c
new file mode 100644
index 0000000..f9f376b
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/libntp/findconfig.c
@@ -0,0 +1,76 @@
+#include <machine/rtems-bsd-user-space.h>
+
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef NEED_HPUX_FINDCONFIG
+#include <string.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/utsname.h>
+#include <unistd.h>
+
+const char *
+FindConfig(
+ const char *base
+ )
+{
+ static char result[BUFSIZ];
+ char hostname[BUFSIZ], *cp;
+ struct stat sbuf;
+ struct utsname unamebuf;
+
+ /* All keyed by initial target being a directory */
+ strlcpy(result, base, sizeof(result));
+ if (stat(result, &sbuf) == 0) {
+ if (S_ISDIR(sbuf.st_mode)) {
+
+ /* First choice is my hostname */
+ if (gethostname(hostname, BUFSIZ) >= 0) {
+ snprintf(result, sizeof(result), "%s/%s", base, hostname);
+ if (stat(result, &sbuf) == 0) {
+ goto outahere;
+ } else {
+
+ /* Second choice is of form default.835 */
+ (void) uname(&unamebuf);
+ if (strncmp(unamebuf.machine, "9000/", 5) == 0)
+ cp = unamebuf.machine + 5;
+ else
+ cp = unamebuf.machine;
+ snprintf(result, sizeof(result), "%s/default.%s", base, cp);
+ if (stat(result, &sbuf) == 0) {
+ goto outahere;
+ } else {
+
+ /* Last choice is just default */
+ snprintf(result, sizeof(result), "%s/default", base);
+ if (stat(result, &sbuf) == 0) {
+ goto outahere;
+ } else {
+ strlcpy(result,
+ "/not/found",
+ sizeof(result));
+ }
+ }
+ }
+ }
+ }
+ }
+ outahere:
+ return(result);
+}
+#else
+#include "ntp_stdlib.h"
+
+const char *
+FindConfig(
+ const char *base
+ )
+{
+ return base;
+}
+#endif
diff --git a/sebhbsd/freebsd/contrib/ntp/libntp/humandate.c b/sebhbsd/freebsd/contrib/ntp/libntp/humandate.c
new file mode 100644
index 0000000..d7122a1
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/libntp/humandate.c
@@ -0,0 +1,62 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * humandate.c - convert an NTP (or the current) time to something readable
+ */
+#include <config.h>
+#include <stdio.h>
+
+#include "ntp_fp.h"
+#include "ntp_unixtime.h" /* includes <sys/time.h> and <time.h> */
+#include "lib_strbuf.h"
+#include "ntp_stdlib.h"
+
+
+/* This is used in msyslog.c; we don't want to clutter up the log with
+ the year and day of the week, etc.; just the minimal date and time. */
+
+const char *
+humanlogtime(void)
+{
+ char * bp;
+ time_t cursec;
+ struct tm * tm;
+
+ cursec = time(NULL);
+ tm = localtime(&cursec);
+ if (!tm)
+ return "-- --- --:--:--";
+
+ LIB_GETBUF(bp);
+
+ snprintf(bp, LIB_BUFLENGTH, "%2d %s %02d:%02d:%02d",
+ tm->tm_mday, months[tm->tm_mon],
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+ return bp;
+}
+
+
+/*
+ * humantime() -- like humanlogtime() but without date, and with the
+ * time to display given as an argument.
+ */
+const char *
+humantime(
+ time_t cursec
+ )
+{
+ char * bp;
+ struct tm * tm;
+
+ tm = localtime(&cursec);
+ if (!tm)
+ return "--:--:--";
+
+ LIB_GETBUF(bp);
+
+ snprintf(bp, LIB_BUFLENGTH, "%02d:%02d:%02d",
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+ return bp;
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/libntp/is_ip_address.c b/sebhbsd/freebsd/contrib/ntp/libntp/is_ip_address.c
new file mode 100644
index 0000000..0d01519
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/libntp/is_ip_address.c
@@ -0,0 +1,91 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * is_ip_address
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "ntp_assert.h"
+#include "ntp_stdlib.h"
+#include "safecast.h"
+
+/* Don't include ISC's version of IPv6 variables and structures */
+#define ISC_IPV6_H 1
+#include <isc/netaddr.h>
+#include <isc/sockaddr.h>
+
+
+/*
+ * Code to tell if we have an IP address
+ * If we have then return the sockaddr structure
+ * and set the return value
+ * see the bind9/getaddresses.c for details
+ */
+int
+is_ip_address(
+ const char * host,
+ u_short af,
+ sockaddr_u * addr
+ )
+{
+ struct in_addr in4;
+ struct addrinfo hints;
+ struct addrinfo *result;
+ struct sockaddr_in6 *resaddr6;
+ char tmpbuf[128];
+ char *pch;
+
+ REQUIRE(host != NULL);
+ REQUIRE(addr != NULL);
+
+ ZERO_SOCK(addr);
+
+ /*
+ * Try IPv4, then IPv6. In order to handle the extended format
+ * for IPv6 scoped addresses (address%scope_ID), we'll use a local
+ * working buffer of 128 bytes. The length is an ad-hoc value, but
+ * should be enough for this purpose; the buffer can contain a string
+ * of at least 80 bytes for scope_ID in addition to any IPv6 numeric
+ * addresses (up to 46 bytes), the delimiter character and the
+ * terminating NULL character.
+ */
+ if (AF_UNSPEC == af || AF_INET == af)
+ if (inet_pton(AF_INET, host, &in4) == 1) {
+ AF(addr) = AF_INET;
+ SET_ADDR4N(addr, in4.s_addr);
+
+ return TRUE;
+ }
+
+ if (AF_UNSPEC == af || AF_INET6 == af)
+ if (sizeof(tmpbuf) > strlen(host)) {
+ if ('[' == host[0]) {
+ strlcpy(tmpbuf, &host[1], sizeof(tmpbuf));
+ pch = strchr(tmpbuf, ']');
+ if (pch != NULL)
+ *pch = '\0';
+ } else {
+ strlcpy(tmpbuf, host, sizeof(tmpbuf));
+ }
+ ZERO(hints);
+ hints.ai_family = AF_INET6;
+ hints.ai_flags |= AI_NUMERICHOST;
+ if (getaddrinfo(tmpbuf, NULL, &hints, &result) == 0) {
+ AF(addr) = AF_INET6;
+ resaddr6 = UA_PTR(struct sockaddr_in6, result->ai_addr);
+ SET_ADDR6N(addr, resaddr6->sin6_addr);
+ SET_SCOPE(addr, resaddr6->sin6_scope_id);
+
+ freeaddrinfo(result);
+ return TRUE;
+ }
+ }
+ /*
+ * If we got here it was not an IP address
+ */
+ return FALSE;
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/libntp/lib_strbuf.c b/sebhbsd/freebsd/contrib/ntp/libntp/lib_strbuf.c
new file mode 100644
index 0000000..01c751e
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/libntp/lib_strbuf.c
@@ -0,0 +1,41 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * lib_strbuf - library string storage
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <isc/net.h>
+#include <isc/result.h>
+
+#include "ntp_fp.h"
+#include "ntp_stdlib.h"
+#include "lib_strbuf.h"
+
+
+/*
+ * Storage declarations
+ */
+int debug;
+libbufstr lib_stringbuf[LIB_NUMBUF];
+int lib_nextbuf;
+int ipv4_works;
+int ipv6_works;
+int lib_inited;
+
+
+/*
+ * initialization routine. Might be needed if the code is ROMized.
+ */
+void
+init_lib(void)
+{
+ if (lib_inited)
+ return;
+ ipv4_works = (ISC_R_SUCCESS == isc_net_probeipv4());
+ ipv6_works = (ISC_R_SUCCESS == isc_net_probeipv6());
+ init_systime();
+ lib_inited = TRUE;
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/libntp/machines.c b/sebhbsd/freebsd/contrib/ntp/libntp/machines.c
new file mode 100644
index 0000000..3907178
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/libntp/machines.c
@@ -0,0 +1,535 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/* machines.c - provide special support for peculiar architectures
+ *
+ * Real bummers unite !
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "ntp.h"
+#include "ntp_machine.h"
+#include "ntp_syslog.h"
+#include "ntp_stdlib.h"
+#include "ntp_unixtime.h"
+#include "lib_strbuf.h"
+#include "ntp_debug.h"
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef SYS_WINNT
+int _getch(void); /* Declare the one function rather than include conio.h */
+#else
+
+#ifdef SYS_VXWORKS
+#include "taskLib.h"
+#include "sysLib.h"
+#include "time.h"
+#include "ntp_syslog.h"
+
+/* some translations to the world of vxWorkings -casey */
+/* first some netdb type things */
+#include "ioLib.h"
+#include <socket.h>
+int h_errno;
+
+struct hostent *gethostbyname(char *name)
+ {
+ struct hostent *host1;
+ h_errno = 0; /* we are always successful!!! */
+ host1 = (struct hostent *) emalloc (sizeof(struct hostent));
+ host1->h_name = name;
+ host1->h_addrtype = AF_INET;
+ host1->h_aliases = name;
+ host1->h_length = 4;
+ host1->h_addr_list[0] = (char *)hostGetByName (name);
+ host1->h_addr_list[1] = NULL;
+ return host1;
+ }
+
+struct hostent *gethostbyaddr(char *name, int size, int addr_type)
+ {
+ struct hostent *host1;
+ h_errno = 0; /* we are always successful!!! */
+ host1 = (struct hostent *) emalloc (sizeof(struct hostent));
+ host1->h_name = name;
+ host1->h_addrtype = AF_INET;
+ host1->h_aliases = name;
+ host1->h_length = 4;
+ host1->h_addr_list = NULL;
+ return host1;
+ }
+
+struct servent *getservbyname (char *name, char *type)
+ {
+ struct servent *serv1;
+ serv1 = (struct servent *) emalloc (sizeof(struct servent));
+ serv1->s_name = "ntp"; /* official service name */
+ serv1->s_aliases = NULL; /* alias list */
+ serv1->s_port = 123; /* port # */
+ serv1->s_proto = "udp"; /* protocol to use */
+ return serv1;
+ }
+
+/* second
+ * vxworks thinks it has insomnia
+ * we have to sleep for number of seconds
+ */
+
+#define CLKRATE sysClkRateGet()
+
+/* I am not sure how valid the granularity is - it is from G. Eger's port */
+#define CLK_GRANULARITY 1 /* Granularity of system clock in usec */
+ /* Used to round down # usecs/tick */
+ /* On a VCOM-100, PIT gets 8 MHz clk, */
+ /* & it prescales by 32, thus 4 usec */
+ /* on mv167, granularity is 1usec anyway*/
+ /* To defeat rounding, set to 1 */
+#define USECS_PER_SEC MILLION /* Microseconds per second */
+#define TICK (((USECS_PER_SEC / CLKRATE) / CLK_GRANULARITY) * CLK_GRANULARITY)
+
+/* emulate unix sleep
+ * casey
+ */
+void sleep(int seconds)
+ {
+ taskDelay(seconds*TICK);
+ }
+/* emulate unix alarm
+ * that pauses and calls SIGALRM after the seconds are up...
+ * so ... taskDelay() fudged for seconds should amount to the same thing.
+ * casey
+ */
+void alarm (int seconds)
+ {
+ sleep(seconds);
+ }
+
+#endif /* SYS_VXWORKS */
+
+#ifdef SYS_PTX /* Does PTX still need this? */
+/*#include <sys/types.h> */
+#include <sys/procstats.h>
+
+int
+gettimeofday(
+ struct timeval *tvp
+ )
+{
+ /*
+ * hi, this is Sequents sneak path to get to a clock
+ * this is also the most logical syscall for such a function
+ */
+ return (get_process_stats(tvp, PS_SELF, (struct procstats *) 0,
+ (struct procstats *) 0));
+}
+#endif /* SYS_PTX */
+
+#ifdef MPE
+/* This is a substitute for bind() that if called for an AF_INET socket
+port less than 1024, GETPRIVMODE() and GETUSERMODE() calls will be done. */
+
+#undef bind
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/un.h>
+
+extern void GETPRIVMODE(void);
+extern void GETUSERMODE(void);
+
+int __ntp_mpe_bind(int s, void *addr, int addrlen);
+
+int __ntp_mpe_bind(int s, void *addr, int addrlen) {
+ int priv = 0;
+ int result;
+
+if (addrlen == sizeof(struct sockaddr_in)) { /* AF_INET */
+ if (((struct sockaddr_in *)addr)->sin_port > 0 &&
+ ((struct sockaddr_in *)addr)->sin_port < 1024) {
+ priv = 1;
+ GETPRIVMODE();
+ }
+/* ((struct sockaddr_in *)addr)->sin_addr.s_addr = 0; */
+ result = bind(s,addr,addrlen);
+ if (priv == 1) GETUSERMODE();
+} else /* AF_UNIX */
+ result = bind(s,addr,addrlen);
+
+return result;
+}
+
+/*
+ * MPE stupidly requires sfcntl() to be used on sockets instead of fcntl(),
+ * so we define a wrapper to analyze the file descriptor and call the correct
+ * function.
+ */
+
+#undef fcntl
+#include <errno.h>
+#include <fcntl.h>
+
+int __ntp_mpe_fcntl(int fd, int cmd, int arg);
+
+int __ntp_mpe_fcntl(int fd, int cmd, int arg) {
+ int len;
+ struct sockaddr sa;
+
+ extern int sfcntl(int, int, int);
+
+ len = sizeof sa;
+ if (getsockname(fd, &sa, &len) == -1) {
+ if (errno == EAFNOSUPPORT) /* AF_UNIX socket */
+ return sfcntl(fd, cmd, arg);
+ if (errno == ENOTSOCK) /* file or pipe */
+ return fcntl(fd, cmd, arg);
+ return (-1); /* unknown getsockname() failure */
+ } else /* AF_INET socket */
+ return sfcntl(fd, cmd, arg);
+}
+
+/*
+ * Setitimer emulation support. Note that we implement this using alarm(),
+ * and since alarm() only delivers one signal, we must re-enable the alarm
+ * by enabling our own SIGALRM setitimer_mpe_handler routine to be called
+ * before the real handler routine and re-enable the alarm at that time.
+ *
+ * Note that this solution assumes that sigaction(SIGALRM) is called before
+ * calling setitimer(). If it should ever to become necessary to support
+ * sigaction(SIGALRM) after calling setitimer(), it will be necessary to trap
+ * those sigaction() calls.
+ */
+
+#include <limits.h>
+#include <signal.h>
+
+/*
+ * Some global data that needs to be shared between setitimer() and
+ * setitimer_mpe_handler().
+ */
+
+struct {
+ unsigned long current_msec; /* current alarm() value in effect */
+ unsigned long interval_msec; /* next alarm() value from setitimer */
+ unsigned long value_msec; /* first alarm() value from setitimer */
+ struct itimerval current_itimerval; /* current itimerval in effect */
+ struct sigaction oldact; /* SIGALRM state saved by setitimer */
+} setitimer_mpe_ctx = { 0, 0, 0 };
+
+/*
+ * Undocumented, unsupported function to do alarm() in milliseconds.
+ */
+
+extern unsigned int px_alarm(unsigned long, int *);
+
+/*
+ * The SIGALRM handler routine enabled by setitimer(). Re-enable the alarm or
+ * restore the original SIGALRM setting if no more alarms are needed. Then
+ * call the original SIGALRM handler (if any).
+ */
+
+static RETSIGTYPE setitimer_mpe_handler(int sig)
+{
+int alarm_hpe_status;
+
+/* Update the new current alarm value */
+
+setitimer_mpe_ctx.current_msec = setitimer_mpe_ctx.interval_msec;
+
+if (setitimer_mpe_ctx.interval_msec > 0) {
+ /* Additional intervals needed; re-arm the alarm timer */
+ px_alarm(setitimer_mpe_ctx.interval_msec,&alarm_hpe_status);
+} else {
+ /* No more intervals, so restore previous original SIGALRM handler */
+ sigaction(SIGALRM, &setitimer_mpe_ctx.oldact, NULL);
+}
+
+/* Call the original SIGALRM handler if it is a function and not just a flag */
+
+if (setitimer_mpe_ctx.oldact.sa_handler != SIG_DFL &&
+ setitimer_mpe_ctx.oldact.sa_handler != SIG_ERR &&
+ setitimer_mpe_ctx.oldact.sa_handler != SIG_IGN)
+ (*setitimer_mpe_ctx.oldact.sa_handler)(SIGALRM);
+
+}
+
+/*
+ * Our implementation of setitimer().
+ */
+
+int
+setitimer(int which, struct itimerval *value,
+ struct itimerval *ovalue)
+{
+
+int alarm_hpe_status;
+unsigned long remaining_msec, value_msec, interval_msec;
+struct sigaction newact;
+
+/*
+ * Convert the initial interval to milliseconds
+ */
+
+if (value->it_value.tv_sec > (UINT_MAX / 1000))
+ value_msec = UINT_MAX;
+else
+ value_msec = value->it_value.tv_sec * 1000;
+
+value_msec += value->it_value.tv_usec / 1000;
+
+/*
+ * Convert the reset interval to milliseconds
+ */
+
+if (value->it_interval.tv_sec > (UINT_MAX / 1000))
+ interval_msec = UINT_MAX;
+else
+ interval_msec = value->it_interval.tv_sec * 1000;
+
+interval_msec += value->it_interval.tv_usec / 1000;
+
+if (value_msec > 0 && interval_msec > 0) {
+ /*
+ * We'll be starting an interval timer that will be repeating, so we need to
+ * insert our own SIGALRM signal handler to schedule the repeats.
+ */
+
+ /* Read the current SIGALRM action */
+
+ if (sigaction(SIGALRM, NULL, &setitimer_mpe_ctx.oldact) < 0) {
+ fprintf(stderr,"MPE setitimer old handler failed, errno=%d\n",errno);
+ return -1;
+ }
+
+ /* Initialize the new action to call our SIGALRM handler instead */
+
+ newact.sa_handler = &setitimer_mpe_handler;
+ newact.sa_mask = setitimer_mpe_ctx.oldact.sa_mask;
+ newact.sa_flags = setitimer_mpe_ctx.oldact.sa_flags;
+
+ if (sigaction(SIGALRM, &newact, NULL) < 0) {
+ fprintf(stderr,"MPE setitimer new handler failed, errno=%d\n",errno);
+ return -1;
+ }
+}
+
+/*
+ * Return previous itimerval if desired
+ */
+
+if (ovalue != NULL) *ovalue = setitimer_mpe_ctx.current_itimerval;
+
+/*
+ * Save current parameters for later usage
+ */
+
+setitimer_mpe_ctx.current_itimerval = *value;
+setitimer_mpe_ctx.current_msec = value_msec;
+setitimer_mpe_ctx.value_msec = value_msec;
+setitimer_mpe_ctx.interval_msec = interval_msec;
+
+/*
+ * Schedule the first alarm
+ */
+
+remaining_msec = px_alarm(value_msec, &alarm_hpe_status);
+if (alarm_hpe_status == 0)
+ return (0);
+else
+ return (-1);
+}
+
+/*
+ * MPE lacks gettimeofday(), so we define our own.
+ */
+
+int gettimeofday(struct timeval *tvp)
+
+{
+/* Documented, supported MPE functions. */
+extern void GETPRIVMODE(void);
+extern void GETUSERMODE(void);
+
+/* Undocumented, unsupported MPE functions. */
+extern long long get_time(void);
+extern void get_time_change_info(long long *, char *, char *);
+extern long long ticks_to_micro(long long);
+
+char pwf_since_boot, recover_pwf_time;
+long long mpetime, offset_ticks, offset_usec;
+
+GETPRIVMODE();
+mpetime = get_time(); /* MPE local time usecs since Jan 1 1970 */
+get_time_change_info(&offset_ticks, &pwf_since_boot, &recover_pwf_time);
+offset_usec = ticks_to_micro(offset_ticks); /* UTC offset usecs */
+GETUSERMODE();
+
+mpetime = mpetime - offset_usec; /* Convert from local time to UTC */
+tvp->tv_sec = mpetime / 1000000LL;
+tvp->tv_usec = mpetime % 1000000LL;
+
+return 0;
+}
+
+/*
+ * MPE lacks settimeofday(), so we define our own.
+ */
+
+#define HAVE_SETTIMEOFDAY
+
+int settimeofday(struct timeval *tvp)
+
+{
+/* Documented, supported MPE functions. */
+extern void GETPRIVMODE(void);
+extern void GETUSERMODE(void);
+
+/* Undocumented, unsupported MPE functions. */
+extern void get_time_change_info(long long *, char *, char *);
+extern void initialize_system_time(long long, int);
+extern void set_time_correction(long long, int, int);
+extern long long ticks_to_micro(long long);
+
+char pwf_since_boot, recover_pwf_time;
+long long big_sec, big_usec, mpetime, offset_ticks, offset_usec;
+
+big_sec = tvp->tv_sec;
+big_usec = tvp->tv_usec;
+mpetime = (big_sec * 1000000LL) + big_usec; /* Desired UTC microseconds */
+
+GETPRIVMODE();
+set_time_correction(0LL,0,0); /* Cancel previous time correction, if any */
+get_time_change_info(&offset_ticks, &pwf_since_boot, &recover_pwf_time);
+offset_usec = ticks_to_micro(offset_ticks); /* UTC offset microseconds */
+mpetime = mpetime + offset_usec; /* Convert from UTC to local time */
+initialize_system_time(mpetime,1);
+GETUSERMODE();
+
+return 0;
+}
+#endif /* MPE */
+
+#define SET_TOD_UNDETERMINED 0
+#define SET_TOD_CLOCK_SETTIME 1
+#define SET_TOD_SETTIMEOFDAY 2
+#define SET_TOD_STIME 3
+
+const char * const set_tod_used[] = {
+ "undetermined",
+ "clock_settime",
+ "settimeofday",
+ "stime"
+};
+
+pset_tod_using set_tod_using = NULL;
+
+
+int
+ntp_set_tod(
+ struct timeval *tvp,
+ void *tzp
+ )
+{
+ static int tod;
+ int rc;
+ int saved_errno;
+
+ TRACE(1, ("In ntp_set_tod\n"));
+ rc = -1;
+ saved_errno = 0;
+
+#ifdef HAVE_CLOCK_SETTIME
+ if (rc && (SET_TOD_CLOCK_SETTIME == tod || !tod)) {
+ struct timespec ts;
+
+ /* Convert timeval to timespec */
+ ts.tv_sec = tvp->tv_sec;
+ ts.tv_nsec = 1000 * tvp->tv_usec;
+
+ errno = 0;
+ rc = clock_settime(CLOCK_REALTIME, &ts);
+ saved_errno = errno;
+ TRACE(1, ("ntp_set_tod: clock_settime: %d %m\n", rc));
+ if (!tod && !rc)
+ tod = SET_TOD_CLOCK_SETTIME;
+
+ }
+#endif /* HAVE_CLOCK_SETTIME */
+#ifdef HAVE_SETTIMEOFDAY
+ if (rc && (SET_TOD_SETTIMEOFDAY == tod || !tod)) {
+ struct timeval adjtv;
+
+ /*
+ * Some broken systems don't reset adjtime() when the
+ * clock is stepped.
+ */
+ adjtv.tv_sec = adjtv.tv_usec = 0;
+ adjtime(&adjtv, NULL);
+ errno = 0;
+ rc = SETTIMEOFDAY(tvp, tzp);
+ saved_errno = errno;
+ TRACE(1, ("ntp_set_tod: settimeofday: %d %m\n", rc));
+ if (!tod && !rc)
+ tod = SET_TOD_SETTIMEOFDAY;
+ }
+#endif /* HAVE_SETTIMEOFDAY */
+#ifdef HAVE_STIME
+ if (rc && (SET_TOD_STIME == tod || !tod)) {
+ long tp = tvp->tv_sec;
+
+ errno = 0;
+ rc = stime(&tp); /* lie as bad as SysVR4 */
+ saved_errno = errno;
+ TRACE(1, ("ntp_set_tod: stime: %d %m\n", rc));
+ if (!tod && !rc)
+ tod = SET_TOD_STIME;
+ }
+#endif /* HAVE_STIME */
+
+ errno = saved_errno; /* for %m below */
+ TRACE(1, ("ntp_set_tod: Final result: %s: %d %m\n",
+ set_tod_used[tod], rc));
+ /*
+ * Say how we're setting the time of day
+ */
+ if (!rc && NULL != set_tod_using) {
+ (*set_tod_using)(set_tod_used[tod]);
+ set_tod_using = NULL;
+ }
+
+ if (rc)
+ errno = saved_errno;
+
+ return rc;
+}
+
+#endif /* not SYS_WINNT */
+
+#if defined (SYS_WINNT) || defined (SYS_VXWORKS) || defined(MPE)
+/* getpass is used in ntpq.c and ntpdc.c */
+
+char *
+getpass(const char * prompt)
+{
+ int c, i;
+ static char password[32];
+
+ fprintf(stderr, "%s", prompt);
+ fflush(stderr);
+
+ for (i=0; i<sizeof(password)-1 && ((c=_getch())!='\n' && c!='\r'); i++) {
+ password[i] = (char) c;
+ }
+ password[i] = '\0';
+
+ fputc('\n', stderr);
+ fflush(stderr);
+
+ return password;
+}
+#endif /* SYS_WINNT */
diff --git a/sebhbsd/freebsd/contrib/ntp/libntp/modetoa.c b/sebhbsd/freebsd/contrib/ntp/libntp/modetoa.c
new file mode 100644
index 0000000..0980380
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/libntp/modetoa.c
@@ -0,0 +1,37 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * modetoa - return an asciized mode
+ */
+#include <config.h>
+#include <stdio.h>
+
+#include "lib_strbuf.h"
+#include "ntp_stdlib.h"
+
+const char *
+modetoa(
+ size_t mode
+ )
+{
+ char *bp;
+ static const char * const modestrings[] = {
+ "unspec",
+ "sym_active",
+ "sym_passive",
+ "client",
+ "server",
+ "broadcast",
+ "control",
+ "private",
+ "bclient",
+ };
+
+ if (mode >= COUNTOF(modestrings)) {
+ LIB_GETBUF(bp);
+ snprintf(bp, LIB_BUFLENGTH, "mode#%zu", mode);
+ return bp;
+ }
+
+ return modestrings[mode];
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/libntp/msyslog.c b/sebhbsd/freebsd/contrib/ntp/libntp/msyslog.c
new file mode 100644
index 0000000..5a45404
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/libntp/msyslog.c
@@ -0,0 +1,586 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * msyslog - either send a message to the terminal or print it on
+ * the standard output.
+ *
+ * Converted to use varargs, much better ... jks
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/types.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#include <stdio.h>
+
+#include "ntp_string.h"
+#include "ntp.h"
+#include "ntp_debug.h"
+#include "ntp_syslog.h"
+
+#ifdef SYS_WINNT
+# include <stdarg.h>
+# include "..\ports\winnt\libntp\messages.h"
+#endif
+
+
+int syslogit = TRUE;
+int msyslog_term = FALSE; /* duplicate to stdout/err */
+int msyslog_term_pid = TRUE;
+int msyslog_include_timestamp = TRUE;
+FILE * syslog_file;
+char * syslog_fname;
+char * syslog_abs_fname;
+
+/* libntp default ntp_syslogmask is all bits lit */
+#define INIT_NTP_SYSLOGMASK ~(u_int32)0
+u_int32 ntp_syslogmask = INIT_NTP_SYSLOGMASK;
+
+extern char const * progname;
+
+/* Declare the local functions */
+void addto_syslog (int, const char *);
+#ifndef VSNPRINTF_PERCENT_M
+void format_errmsg (char *, size_t, const char *, int);
+
+/* format_errmsg() is under #ifndef VSNPRINTF_PERCENT_M above */
+void
+format_errmsg(
+ char * nfmt,
+ size_t lennfmt,
+ const char * fmt,
+ int errval
+ )
+{
+ char errmsg[256];
+ char c;
+ char *n;
+ const char *f;
+ size_t len;
+
+ n = nfmt;
+ f = fmt;
+ while ((c = *f++) != '\0' && n < (nfmt + lennfmt - 1)) {
+ if (c != '%') {
+ *n++ = c;
+ continue;
+ }
+ if ((c = *f++) != 'm') {
+ *n++ = '%';
+ if ('\0' == c)
+ break;
+ *n++ = c;
+ continue;
+ }
+ errno_to_str(errval, errmsg, sizeof(errmsg));
+ len = strlen(errmsg);
+
+ /* Make sure we have enough space for the error message */
+ if ((n + len) < (nfmt + lennfmt - 1)) {
+ memcpy(n, errmsg, len);
+ n += len;
+ }
+ }
+ *n = '\0';
+}
+#endif /* VSNPRINTF_PERCENT_M */
+
+
+/*
+ * errno_to_str() - a thread-safe strerror() replacement.
+ * Hides the varied signatures of strerror_r().
+ * For Windows, we have:
+ * #define errno_to_str isc_strerror
+ */
+#ifndef errno_to_str
+void
+errno_to_str(
+ int err,
+ char * buf,
+ size_t bufsiz
+ )
+{
+# if defined(STRERROR_R_CHAR_P) || !HAVE_DECL_STRERROR_R
+ char * pstatic;
+
+ buf[0] = '\0';
+# ifdef STRERROR_R_CHAR_P
+ pstatic = strerror_r(err, buf, bufsiz);
+# else
+ pstatic = strerror(err);
+# endif
+ if (NULL == pstatic && '\0' == buf[0])
+ snprintf(buf, bufsiz, "%s(%d): errno %d",
+# ifdef STRERROR_R_CHAR_P
+ "strerror_r",
+# else
+ "strerror",
+# endif
+ err, errno);
+ /* protect against believing an int return is a pointer */
+ else if (pstatic != buf && pstatic > (char *)bufsiz)
+ strlcpy(buf, pstatic, bufsiz);
+# else
+ int rc;
+
+ rc = strerror_r(err, buf, bufsiz);
+ if (rc < 0)
+ snprintf(buf, bufsiz, "strerror_r(%d): errno %d",
+ err, errno);
+# endif
+}
+#endif /* errno_to_str */
+
+
+/*
+ * addto_syslog()
+ * This routine adds the contents of a buffer to the syslog or an
+ * application-specific logfile.
+ */
+void
+addto_syslog(
+ int level,
+ const char * msg
+ )
+{
+ static char const * prevcall_progname;
+ static char const * prog;
+ const char nl[] = "\n";
+ const char empty[] = "";
+ FILE * term_file;
+ int log_to_term;
+ int log_to_file;
+ int pid;
+ const char * nl_or_empty;
+ const char * human_time;
+
+ /* setup program basename static var prog if needed */
+ if (progname != prevcall_progname) {
+ prevcall_progname = progname;
+ prog = strrchr(progname, DIR_SEP);
+ if (prog != NULL)
+ prog++;
+ else
+ prog = progname;
+ }
+
+ log_to_term = msyslog_term;
+ log_to_file = FALSE;
+#if !defined(VMS) && !defined(SYS_VXWORKS)
+ if (syslogit)
+ syslog(level, "%s", msg);
+ else
+#endif
+ if (syslog_file != NULL)
+ log_to_file = TRUE;
+ else
+ log_to_term = TRUE;
+#if DEBUG
+ if (debug > 0)
+ log_to_term = TRUE;
+#endif
+ if (!(log_to_file || log_to_term))
+ return;
+
+ /* syslog() adds the timestamp, name, and pid */
+ if (msyslog_include_timestamp)
+ human_time = humanlogtime();
+ else /* suppress gcc pot. uninit. warning */
+ human_time = NULL;
+ if (msyslog_term_pid || log_to_file)
+ pid = getpid();
+ else /* suppress gcc pot. uninit. warning */
+ pid = -1;
+
+ /* syslog() adds trailing \n if not present */
+ if ('\n' != msg[strlen(msg) - 1])
+ nl_or_empty = nl;
+ else
+ nl_or_empty = empty;
+
+ if (log_to_term) {
+ term_file = (level <= LOG_ERR)
+ ? stderr
+ : stdout;
+ if (msyslog_include_timestamp)
+ fprintf(term_file, "%s ", human_time);
+ if (msyslog_term_pid)
+ fprintf(term_file, "%s[%d]: ", prog, pid);
+ fprintf(term_file, "%s%s", msg, nl_or_empty);
+ fflush(term_file);
+ }
+
+ if (log_to_file) {
+ if (msyslog_include_timestamp)
+ fprintf(syslog_file, "%s ", human_time);
+ fprintf(syslog_file, "%s[%d]: %s%s", prog, pid, msg,
+ nl_or_empty);
+ fflush(syslog_file);
+ }
+}
+
+
+int
+mvsnprintf(
+ char * buf,
+ size_t bufsiz,
+ const char * fmt,
+ va_list ap
+ )
+{
+#ifndef VSNPRINTF_PERCENT_M
+ char nfmt[256];
+#else
+ const char * nfmt = fmt;
+#endif
+ int errval;
+
+ /*
+ * Save the error value as soon as possible
+ */
+#ifdef SYS_WINNT
+ errval = GetLastError();
+ if (NO_ERROR == errval)
+#endif /* SYS_WINNT */
+ errval = errno;
+
+#ifndef VSNPRINTF_PERCENT_M
+ format_errmsg(nfmt, sizeof(nfmt), fmt, errval);
+#else
+ errno = errval;
+#endif
+ return vsnprintf(buf, bufsiz, nfmt, ap);
+}
+
+
+int
+mvfprintf(
+ FILE * fp,
+ const char * fmt,
+ va_list ap
+ )
+{
+#ifndef VSNPRINTF_PERCENT_M
+ char nfmt[256];
+#else
+ const char * nfmt = fmt;
+#endif
+ int errval;
+
+ /*
+ * Save the error value as soon as possible
+ */
+#ifdef SYS_WINNT
+ errval = GetLastError();
+ if (NO_ERROR == errval)
+#endif /* SYS_WINNT */
+ errval = errno;
+
+#ifndef VSNPRINTF_PERCENT_M
+ format_errmsg(nfmt, sizeof(nfmt), fmt, errval);
+#else
+ errno = errval;
+#endif
+ return vfprintf(fp, nfmt, ap);
+}
+
+
+int
+mfprintf(
+ FILE * fp,
+ const char * fmt,
+ ...
+ )
+{
+ va_list ap;
+ int rc;
+
+ va_start(ap, fmt);
+ rc = mvfprintf(fp, fmt, ap);
+ va_end(ap);
+
+ return rc;
+}
+
+
+int
+mprintf(
+ const char * fmt,
+ ...
+ )
+{
+ va_list ap;
+ int rc;
+
+ va_start(ap, fmt);
+ rc = mvfprintf(stdout, fmt, ap);
+ va_end(ap);
+
+ return rc;
+}
+
+
+int
+msnprintf(
+ char * buf,
+ size_t bufsiz,
+ const char * fmt,
+ ...
+ )
+{
+ va_list ap;
+ int rc;
+
+ va_start(ap, fmt);
+ rc = mvsnprintf(buf, bufsiz, fmt, ap);
+ va_end(ap);
+
+ return rc;
+}
+
+
+void
+msyslog(
+ int level,
+ const char * fmt,
+ ...
+ )
+{
+ char buf[1024];
+ va_list ap;
+
+ va_start(ap, fmt);
+ mvsnprintf(buf, sizeof(buf), fmt, ap);
+ va_end(ap);
+ addto_syslog(level, buf);
+}
+
+void
+mvsyslog(
+ int level,
+ const char * fmt,
+ va_list ap
+ )
+{
+ char buf[1024];
+ mvsnprintf(buf, sizeof(buf), fmt, ap);
+ addto_syslog(level, buf);
+}
+
+
+/*
+ * Initialize the logging
+ *
+ * Called once per process, including forked children.
+ */
+void
+init_logging(
+ const char * name,
+ u_int32 def_syslogmask,
+ int is_daemon
+ )
+{
+ static int was_daemon;
+ char * cp;
+ const char * pname;
+
+ /*
+ * ntpd defaults to only logging sync-category events, when
+ * NLOG() is used to conditionalize. Other libntp clients
+ * leave it alone so that all NLOG() conditionals will fire.
+ * This presumes all bits lit in ntp_syslogmask can't be
+ * configured via logconfig and all lit is thereby a sentinel
+ * that ntp_syslogmask is still at its default from libntp,
+ * keeping in mind this function is called in forked children
+ * where it has already been called in the parent earlier.
+ * Forked children pass 0 for def_syslogmask.
+ */
+ if (INIT_NTP_SYSLOGMASK == ntp_syslogmask &&
+ 0 != def_syslogmask)
+ ntp_syslogmask = def_syslogmask; /* set more via logconfig */
+
+ /*
+ * Logging. This may actually work on the gizmo board. Find a name
+ * to log with by using the basename
+ */
+ cp = strrchr(name, DIR_SEP);
+ if (NULL == cp)
+ pname = name;
+ else
+ pname = 1 + cp; /* skip DIR_SEP */
+ progname = estrdup(pname);
+#ifdef SYS_WINNT /* strip ".exe" */
+ cp = strrchr(progname, '.');
+ if (NULL != cp && !strcasecmp(cp, ".exe"))
+ *cp = '\0';
+#endif
+
+#if !defined(VMS)
+
+ if (is_daemon)
+ was_daemon = TRUE;
+# ifndef LOG_DAEMON
+ openlog(progname, LOG_PID);
+# else /* LOG_DAEMON */
+
+# ifndef LOG_NTP
+# define LOG_NTP LOG_DAEMON
+# endif
+ openlog(progname, LOG_PID | LOG_NDELAY, (was_daemon)
+ ? LOG_NTP
+ : 0);
+# ifdef DEBUG
+ if (debug)
+ setlogmask(LOG_UPTO(LOG_DEBUG));
+ else
+# endif /* DEBUG */
+ setlogmask(LOG_UPTO(LOG_DEBUG)); /* @@@ was INFO */
+# endif /* LOG_DAEMON */
+#endif /* !VMS */
+}
+
+
+/*
+ * change_logfile()
+ *
+ * Used to change from syslog to a logfile, or from one logfile to
+ * another, and to reopen logfiles after forking. On systems where
+ * ntpd forks, deals with converting relative logfile paths to
+ * absolute (root-based) because we reopen logfiles after the current
+ * directory has changed.
+ */
+int
+change_logfile(
+ const char * fname,
+ int leave_crumbs
+ )
+{
+ FILE * new_file;
+ const char * log_fname;
+ char * abs_fname;
+#if !defined(SYS_WINNT) && !defined(SYS_VXWORKS) && !defined(VMS)
+ char curdir[512];
+ size_t cd_octets;
+ size_t octets;
+#endif /* POSIX */
+
+ REQUIRE(fname != NULL);
+ log_fname = fname;
+
+ /*
+ * In a forked child of a parent which is logging to a file
+ * instead of syslog, syslog_file will be NULL and both
+ * syslog_fname and syslog_abs_fname will be non-NULL.
+ * If we are given the same filename previously opened
+ * and it's still open, there's nothing to do here.
+ */
+ if (syslog_file != NULL && syslog_fname != NULL &&
+ 0 == strcmp(syslog_fname, log_fname))
+ return 0;
+
+ if (0 == strcmp(log_fname, "stderr")) {
+ new_file = stderr;
+ abs_fname = estrdup(log_fname);
+ } else if (0 == strcmp(log_fname, "stdout")) {
+ new_file = stdout;
+ abs_fname = estrdup(log_fname);
+ } else {
+ if (syslog_fname != NULL &&
+ 0 == strcmp(log_fname, syslog_fname))
+ log_fname = syslog_abs_fname;
+#if !defined(SYS_WINNT) && !defined(SYS_VXWORKS) && !defined(VMS)
+ if (log_fname != syslog_abs_fname &&
+ DIR_SEP != log_fname[0] &&
+ 0 != strcmp(log_fname, "stderr") &&
+ 0 != strcmp(log_fname, "stdout") &&
+ NULL != getcwd(curdir, sizeof(curdir))) {
+ cd_octets = strlen(curdir);
+ /* trim any trailing '/' */
+ if (cd_octets > 1 &&
+ DIR_SEP == curdir[cd_octets - 1])
+ cd_octets--;
+ octets = cd_octets;
+ octets += 1; /* separator '/' */
+ octets += strlen(log_fname);
+ octets += 1; /* NUL terminator */
+ abs_fname = emalloc(octets);
+ snprintf(abs_fname, octets, "%.*s%c%s",
+ (int)cd_octets, curdir, DIR_SEP,
+ log_fname);
+ } else
+#endif
+ abs_fname = estrdup(log_fname);
+ TRACE(1, ("attempting to open log %s\n", abs_fname));
+ new_file = fopen(abs_fname, "a");
+ }
+
+ if (NULL == new_file) {
+ free(abs_fname);
+ return -1;
+ }
+
+ /* leave a pointer in the old log */
+ if (leave_crumbs && (syslogit || log_fname != syslog_abs_fname))
+ msyslog(LOG_NOTICE, "switching logging to file %s",
+ abs_fname);
+
+ if (syslog_file != NULL &&
+ syslog_file != stderr && syslog_file != stdout &&
+ fileno(syslog_file) != fileno(new_file))
+ fclose(syslog_file);
+ syslog_file = new_file;
+ if (log_fname == syslog_abs_fname) {
+ free(abs_fname);
+ } else {
+ if (syslog_abs_fname != NULL &&
+ syslog_abs_fname != syslog_fname)
+ free(syslog_abs_fname);
+ if (syslog_fname != NULL)
+ free(syslog_fname);
+ syslog_fname = estrdup(log_fname);
+ syslog_abs_fname = abs_fname;
+ }
+ syslogit = FALSE;
+
+ return 0;
+}
+
+
+/*
+ * setup_logfile()
+ *
+ * Redirect logging to a file if requested with -l/--logfile or via
+ * ntp.conf logfile directive.
+ *
+ * This routine is invoked three different times in the sequence of a
+ * typical daemon ntpd with DNS lookups to do. First it is invoked in
+ * the original ntpd process, then again in the daemon after closing
+ * all descriptors. In both of those cases, ntp.conf has not been
+ * processed, so only -l/--logfile will trigger logfile redirection in
+ * those invocations. Finally, if DNS names are resolved, the worker
+ * child invokes this routine after its fork and close of all
+ * descriptors. In this case, ntp.conf has been processed and any
+ * "logfile" directive needs to be honored in the child as well.
+ */
+void
+setup_logfile(
+ const char * name
+ )
+{
+ if (NULL == syslog_fname && NULL != name) {
+ if (-1 == change_logfile(name, TRUE))
+ msyslog(LOG_ERR, "Cannot open log file %s, %m",
+ name);
+ return ;
+ }
+ if (NULL == syslog_fname)
+ return;
+
+ if (-1 == change_logfile(syslog_fname, FALSE))
+ msyslog(LOG_ERR, "Cannot reopen log file %s, %m",
+ syslog_fname);
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/libntp/netof.c b/sebhbsd/freebsd/contrib/ntp/libntp/netof.c
new file mode 100644
index 0000000..a129313
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/libntp/netof.c
@@ -0,0 +1,57 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * netof - return the net address part of an ip address in a sockaddr_storage structure
+ * (zero out host part)
+ */
+#include <config.h>
+#include <stdio.h>
+#include <syslog.h>
+
+#include "ntp_fp.h"
+#include "ntp_net.h"
+#include "ntp_stdlib.h"
+#include "ntp.h"
+
+sockaddr_u *
+netof(
+ sockaddr_u *hostaddr
+ )
+{
+ static sockaddr_u netofbuf[8];
+ static int next_netofbuf;
+ u_int32 netnum;
+ sockaddr_u * netaddr;
+
+ netaddr = &netofbuf[next_netofbuf];
+ next_netofbuf = (next_netofbuf + 1) % COUNTOF(netofbuf);
+
+ memcpy(netaddr, hostaddr, sizeof(*netaddr));
+
+ if (IS_IPV4(netaddr)) {
+ netnum = SRCADR(netaddr);
+
+ /*
+ * We live in a modern CIDR world where the basement nets, which
+ * used to be class A, are now probably associated with each
+ * host address. So, for class-A nets, all bits are significant.
+ */
+ if (IN_CLASSC(netnum))
+ netnum &= IN_CLASSC_NET;
+ else if (IN_CLASSB(netnum))
+ netnum &= IN_CLASSB_NET;
+
+ SET_ADDR4(netaddr, netnum);
+
+ } else if (IS_IPV6(netaddr))
+ /* assume the typical /64 subnet size */
+ zero_mem(&NSRCADR6(netaddr)[8], 8);
+#ifdef DEBUG
+ else {
+ msyslog(LOG_ERR, "netof unknown AF %d", AF(netaddr));
+ exit(1);
+ }
+#endif
+
+ return netaddr;
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/libntp/ntp_calendar.c b/sebhbsd/freebsd/contrib/ntp/libntp/ntp_calendar.c
new file mode 100644
index 0000000..dacc350
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/libntp/ntp_calendar.c
@@ -0,0 +1,1977 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * ntp_calendar.c - calendar and helper functions
+ *
+ * Written by Juergen Perlinger (perlinger@ntp.org) for the NTP project.
+ * The contents of 'html/copyright.html' apply.
+ *
+ * --------------------------------------------------------------------
+ * Some notes on the implementation:
+ *
+ * Calendar algorithms thrive on the division operation, which is one of
+ * the slowest numerical operations in any CPU. What saves us here from
+ * abysmal performance is the fact that all divisions are divisions by
+ * constant numbers, and most compilers can do this by a multiplication
+ * operation. But this might not work when using the div/ldiv/lldiv
+ * function family, because many compilers are not able to do inline
+ * expansion of the code with following optimisation for the
+ * constant-divider case.
+ *
+ * Also div/ldiv/lldiv are defined in terms of int/long/longlong, which
+ * are inherently target dependent. Nothing that could not be cured with
+ * autoconf, but still a mess...
+ *
+ * Furthermore, we need floor division in many places. C either leaves
+ * the division behaviour undefined (< C99) or demands truncation to
+ * zero (>= C99), so additional steps are required to make sure the
+ * algorithms work. The {l,ll}div function family is requested to
+ * truncate towards zero, which is also the wrong direction for our
+ * purpose.
+ *
+ * For all this, all divisions by constant are coded manually, even when
+ * there is a joined div/mod operation: The optimiser should sort that
+ * out, if possible. Most of the calculations are done with unsigned
+ * types, explicitely using two's complement arithmetics where
+ * necessary. This minimises the dependecies to compiler and target,
+ * while still giving reasonable to good performance.
+ *
+ * The implementation uses a few tricks that exploit properties of the
+ * two's complement: Floor division on negative dividents can be
+ * executed by using the one's complement of the divident. One's
+ * complement can be easily created using XOR and a mask.
+ *
+ * Finally, check for overflow conditions is minimal. There are only two
+ * calculation steps in the whole calendar that suffer from an internal
+ * overflow, and these conditions are checked: errno is set to EDOM and
+ * the results are clamped/saturated in this case. All other functions
+ * do not suffer from internal overflow and simply return the result
+ * truncated to 32 bits.
+ *
+ * This is a sacrifice made for execution speed. Since a 32-bit day
+ * counter covers +/- 5,879,610 years and the clamp limits the effective
+ * range to +/-2.9 million years, this should not pose a problem here.
+ *
+ */
+
+#include <config.h>
+#include <sys/types.h>
+
+#include "ntp_types.h"
+#include "ntp_calendar.h"
+#include "ntp_stdlib.h"
+#include "ntp_fp.h"
+#include "ntp_unixtime.h"
+
+/* For now, let's take the conservative approach: if the target property
+ * macros are not defined, check a few well-known compiler/architecture
+ * settings. Default is to assume that the representation of signed
+ * integers is unknown and shift-arithmetic-right is not available.
+ */
+#ifndef TARGET_HAS_2CPL
+# if defined(__GNUC__)
+# if defined(__i386__) || defined(__x86_64__) || defined(__arm__)
+# define TARGET_HAS_2CPL 1
+# else
+# define TARGET_HAS_2CPL 0
+# endif
+# elif defined(_MSC_VER)
+# if defined(_M_IX86) || defined(_M_X64) || defined(_M_ARM)
+# define TARGET_HAS_2CPL 1
+# else
+# define TARGET_HAS_2CPL 0
+# endif
+# else
+# define TARGET_HAS_2CPL 0
+# endif
+#endif
+
+#ifndef TARGET_HAS_SAR
+# define TARGET_HAS_SAR 0
+#endif
+
+/*
+ *---------------------------------------------------------------------
+ * replacing the 'time()' function
+ *---------------------------------------------------------------------
+ */
+
+static systime_func_ptr systime_func = &time;
+static inline time_t now(void);
+
+
+systime_func_ptr
+ntpcal_set_timefunc(
+ systime_func_ptr nfunc
+ )
+{
+ systime_func_ptr res;
+
+ res = systime_func;
+ if (NULL == nfunc)
+ nfunc = &time;
+ systime_func = nfunc;
+
+ return res;
+}
+
+
+static inline time_t
+now(void)
+{
+ return (*systime_func)(NULL);
+}
+
+/*
+ *---------------------------------------------------------------------
+ * Get sign extension mask and unsigned 2cpl rep for a signed integer
+ *---------------------------------------------------------------------
+ */
+
+static inline uint32_t
+int32_sflag(
+ const int32_t v)
+{
+# if TARGET_HAS_2CPL && TARGET_HAS_SAR && SIZEOF_INT >= 4
+
+ /* Let's assume that shift is the fastest way to get the sign
+ * extension of of a signed integer. This might not always be
+ * true, though -- On 8bit CPUs or machines without barrel
+ * shifter this will kill the performance. So we make sure
+ * we do this only if 'int' has at least 4 bytes.
+ */
+ return (uint32_t)(v >> 31);
+
+# else
+
+ /* This should be a rather generic approach for getting a sign
+ * extension mask...
+ */
+ return UINT32_C(0) - (uint32_t)(v < 0);
+
+# endif
+}
+
+static inline uint32_t
+int32_to_uint32_2cpl(
+ const int32_t v)
+{
+ uint32_t vu;
+
+# if TARGET_HAS_2CPL
+
+ /* Just copy through the 32 bits from the signed value if we're
+ * on a two's complement target.
+ */
+ vu = (uint32_t)v;
+
+# else
+
+ /* Convert from signed int to unsigned int two's complement. Do
+ * not make any assumptions about the representation of signed
+ * integers, but make sure signed integer overflow cannot happen
+ * here. A compiler on a two's complement target *might* find
+ * out that this is just a complicated cast (as above), but your
+ * mileage might vary.
+ */
+ if (v < 0)
+ vu = ~(uint32_t)(-(v + 1));
+ else
+ vu = (uint32_t)v;
+
+# endif
+
+ return vu;
+}
+
+static inline int32_t
+uint32_2cpl_to_int32(
+ const uint32_t vu)
+{
+ int32_t v;
+
+# if TARGET_HAS_2CPL
+
+ /* Just copy through the 32 bits from the unsigned value if
+ * we're on a two's complement target.
+ */
+ v = (int32_t)vu;
+
+# else
+
+ /* Convert to signed integer, making sure signed integer
+ * overflow cannot happen. Again, the optimiser might or might
+ * not find out that this is just a copy of 32 bits on a target
+ * with two's complement representation for signed integers.
+ */
+ if (vu > INT32_MAX)
+ v = -(int32_t)(~vu) - 1;
+ else
+ v = (int32_t)vu;
+
+# endif
+
+ return v;
+}
+
+/* Some of the calculations need to multiply the input by 4 before doing
+ * a division. This can cause overflow and strange results. Therefore we
+ * clamp / saturate the input operand. And since we do the calculations
+ * in unsigned int with an extra sign flag/mask, we only loose one bit
+ * of the input value range.
+ */
+static inline uint32_t
+uint32_saturate(
+ uint32_t vu,
+ uint32_t mu)
+{
+ static const uint32_t limit = UINT32_MAX/4u;
+ if ((mu ^ vu) > limit) {
+ vu = mu ^ limit;
+ errno = EDOM;
+ }
+ return vu;
+}
+
+/*
+ *---------------------------------------------------------------------
+ * Convert between 'time_t' and 'vint64'
+ *---------------------------------------------------------------------
+ */
+vint64
+time_to_vint64(
+ const time_t * ptt
+ )
+{
+ vint64 res;
+ time_t tt;
+
+ tt = *ptt;
+
+# if SIZEOF_TIME_T <= 4
+
+ res.D_s.hi = 0;
+ if (tt < 0) {
+ res.D_s.lo = (uint32_t)-tt;
+ M_NEG(res.D_s.hi, res.D_s.lo);
+ } else {
+ res.D_s.lo = (uint32_t)tt;
+ }
+
+# elif defined(HAVE_INT64)
+
+ res.q_s = tt;
+
+# else
+ /*
+ * shifting negative signed quantities is compiler-dependent, so
+ * we better avoid it and do it all manually. And shifting more
+ * than the width of a quantity is undefined. Also a don't do!
+ */
+ if (tt < 0) {
+ tt = -tt;
+ res.D_s.lo = (uint32_t)tt;
+ res.D_s.hi = (uint32_t)(tt >> 32);
+ M_NEG(res.D_s.hi, res.D_s.lo);
+ } else {
+ res.D_s.lo = (uint32_t)tt;
+ res.D_s.hi = (uint32_t)(tt >> 32);
+ }
+
+# endif
+
+ return res;
+}
+
+
+time_t
+vint64_to_time(
+ const vint64 *tv
+ )
+{
+ time_t res;
+
+# if SIZEOF_TIME_T <= 4
+
+ res = (time_t)tv->D_s.lo;
+
+# elif defined(HAVE_INT64)
+
+ res = (time_t)tv->q_s;
+
+# else
+
+ res = ((time_t)tv->d_s.hi << 32) | tv->D_s.lo;
+
+# endif
+
+ return res;
+}
+
+/*
+ *---------------------------------------------------------------------
+ * Get the build date & time
+ *---------------------------------------------------------------------
+ */
+int
+ntpcal_get_build_date(
+ struct calendar * jd
+ )
+{
+ /* The C standard tells us the format of '__DATE__':
+ *
+ * __DATE__ The date of translation of the preprocessing
+ * translation unit: a character string literal of the form "Mmm
+ * dd yyyy", where the names of the months are the same as those
+ * generated by the asctime function, and the first character of
+ * dd is a space character if the value is less than 10. If the
+ * date of translation is not available, an
+ * implementation-defined valid date shall be supplied.
+ *
+ * __TIME__ The time of translation of the preprocessing
+ * translation unit: a character string literal of the form
+ * "hh:mm:ss" as in the time generated by the asctime
+ * function. If the time of translation is not available, an
+ * implementation-defined valid time shall be supplied.
+ *
+ * Note that MSVC declares DATE and TIME to be in the local time
+ * zone, while neither the C standard nor the GCC docs make any
+ * statement about this. As a result, we may be +/-12hrs off
+ * UTC. But for practical purposes, this should not be a
+ * problem.
+ *
+ */
+# ifdef MKREPRO_DATE
+ static const char build[] = MKREPRO_TIME "/" MKREPRO_DATE;
+# else
+ static const char build[] = __TIME__ "/" __DATE__;
+# endif
+ static const char mlist[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
+
+ char monstr[4];
+ const char * cp;
+ unsigned short hour, minute, second, day, year;
+ /* Note: The above quantities are used for sscanf 'hu' format,
+ * so using 'uint16_t' is contra-indicated!
+ */
+
+# ifdef DEBUG
+ static int ignore = 0;
+# endif
+
+ ZERO(*jd);
+ jd->year = 1970;
+ jd->month = 1;
+ jd->monthday = 1;
+
+# ifdef DEBUG
+ /* check environment if build date should be ignored */
+ if (0 == ignore) {
+ const char * envstr;
+ envstr = getenv("NTPD_IGNORE_BUILD_DATE");
+ ignore = 1 + (envstr && (!*envstr || !strcasecmp(envstr, "yes")));
+ }
+ if (ignore > 1)
+ return FALSE;
+# endif
+
+ if (6 == sscanf(build, "%hu:%hu:%hu/%3s %hu %hu",
+ &hour, &minute, &second, monstr, &day, &year)) {
+ cp = strstr(mlist, monstr);
+ if (NULL != cp) {
+ jd->year = year;
+ jd->month = (uint8_t)((cp - mlist) / 3 + 1);
+ jd->monthday = (uint8_t)day;
+ jd->hour = (uint8_t)hour;
+ jd->minute = (uint8_t)minute;
+ jd->second = (uint8_t)second;
+
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+
+/*
+ *---------------------------------------------------------------------
+ * basic calendar stuff
+ *---------------------------------------------------------------------
+ */
+
+/* month table for a year starting with March,1st */
+static const uint16_t shift_month_table[13] = {
+ 0, 31, 61, 92, 122, 153, 184, 214, 245, 275, 306, 337, 366
+};
+
+/* month tables for years starting with January,1st; regular & leap */
+static const uint16_t real_month_table[2][13] = {
+ /* -*- table for regular years -*- */
+ { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
+ /* -*- table for leap years -*- */
+ { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
+};
+
+/*
+ * Some notes on the terminology:
+ *
+ * We use the proleptic Gregorian calendar, which is the Gregorian
+ * calendar extended in both directions ad infinitum. This totally
+ * disregards the fact that this calendar was invented in 1582, and
+ * was adopted at various dates over the world; sometimes even after
+ * the start of the NTP epoch.
+ *
+ * Normally date parts are given as current cycles, while time parts
+ * are given as elapsed cycles:
+ *
+ * 1970-01-01/03:04:05 means 'IN the 1970st. year, IN the first month,
+ * ON the first day, with 3hrs, 4minutes and 5 seconds elapsed.
+ *
+ * The basic calculations for this calendar implementation deal with
+ * ELAPSED date units, which is the number of full years, full months
+ * and full days before a date: 1970-01-01 would be (1969, 0, 0) in
+ * that notation.
+ *
+ * To ease the numeric computations, month and day values outside the
+ * normal range are acceptable: 2001-03-00 will be treated as the day
+ * before 2001-03-01, 2000-13-32 will give the same result as
+ * 2001-02-01 and so on.
+ *
+ * 'rd' or 'RD' is used as an abbreviation for the latin 'rata die'
+ * (day number). This is the number of days elapsed since 0000-12-31
+ * in the proleptic Gregorian calendar. The begin of the Christian Era
+ * (0001-01-01) is RD(1).
+ */
+
+/*
+ * ====================================================================
+ *
+ * General algorithmic stuff
+ *
+ * ====================================================================
+ */
+
+/*
+ *---------------------------------------------------------------------
+ * Do a periodic extension of 'value' around 'pivot' with a period of
+ * 'cycle'.
+ *
+ * The result 'res' is a number that holds to the following properties:
+ *
+ * 1) res MOD cycle == value MOD cycle
+ * 2) pivot <= res < pivot + cycle
+ * (replace </<= with >/>= for negative cycles)
+ *
+ * where 'MOD' denotes the modulo operator for FLOOR DIVISION, which
+ * is not the same as the '%' operator in C: C requires division to be
+ * a truncated division, where remainder and dividend have the same
+ * sign if the remainder is not zero, whereas floor division requires
+ * divider and modulus to have the same sign for a non-zero modulus.
+ *
+ * This function has some useful applications:
+ *
+ * + let Y be a calendar year and V a truncated 2-digit year: then
+ * periodic_extend(Y-50, V, 100)
+ * is the closest expansion of the truncated year with respect to
+ * the full year, that is a 4-digit year with a difference of less
+ * than 50 years to the year Y. ("century unfolding")
+ *
+ * + let T be a UN*X time stamp and V be seconds-of-day: then
+ * perodic_extend(T-43200, V, 86400)
+ * is a time stamp that has the same seconds-of-day as the input
+ * value, with an absolute difference to T of <= 12hrs. ("day
+ * unfolding")
+ *
+ * + Wherever you have a truncated periodic value and a non-truncated
+ * base value and you want to match them somehow...
+ *
+ * Basically, the function delivers 'pivot + (value - pivot) % cycle',
+ * but the implementation takes some pains to avoid internal signed
+ * integer overflows in the '(value - pivot) % cycle' part and adheres
+ * to the floor division convention.
+ *
+ * If 64bit scalars where available on all intended platforms, writing a
+ * version that uses 64 bit ops would be easy; writing a general
+ * division routine for 64bit ops on a platform that can only do
+ * 32/16bit divisions and is still performant is a bit more
+ * difficult. Since most usecases can be coded in a way that does only
+ * require the 32-bit version a 64bit version is NOT provided here.
+ *---------------------------------------------------------------------
+ */
+int32_t
+ntpcal_periodic_extend(
+ int32_t pivot,
+ int32_t value,
+ int32_t cycle
+ )
+{
+ uint32_t diff;
+ char cpl = 0; /* modulo complement flag */
+ char neg = 0; /* sign change flag */
+
+ /* make the cycle positive and adjust the flags */
+ if (cycle < 0) {
+ cycle = - cycle;
+ neg ^= 1;
+ cpl ^= 1;
+ }
+ /* guard against div by zero or one */
+ if (cycle > 1) {
+ /*
+ * Get absolute difference as unsigned quantity and
+ * the complement flag. This is done by always
+ * subtracting the smaller value from the bigger
+ * one.
+ */
+ if (value >= pivot) {
+ diff = int32_to_uint32_2cpl(value)
+ - int32_to_uint32_2cpl(pivot);
+ } else {
+ diff = int32_to_uint32_2cpl(pivot)
+ - int32_to_uint32_2cpl(value);
+ cpl ^= 1;
+ }
+ diff %= (uint32_t)cycle;
+ if (diff) {
+ if (cpl)
+ diff = (uint32_t)cycle - diff;
+ if (neg)
+ diff = ~diff + 1;
+ pivot += uint32_2cpl_to_int32(diff);
+ }
+ }
+ return pivot;
+}
+
+/*---------------------------------------------------------------------
+ * Note to the casual reader
+ *
+ * In the next two functions you will find (or would have found...)
+ * the expression
+ *
+ * res.Q_s -= 0x80000000;
+ *
+ * There was some ruckus about a possible programming error due to
+ * integer overflow and sign propagation.
+ *
+ * This assumption is based on a lack of understanding of the C
+ * standard. (Though this is admittedly not one of the most 'natural'
+ * aspects of the 'C' language and easily to get wrong.)
+ *
+ * see
+ * http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
+ * "ISO/IEC 9899:201x Committee Draft — April 12, 2011"
+ * 6.4.4.1 Integer constants, clause 5
+ *
+ * why there is no sign extension/overflow problem here.
+ *
+ * But to ease the minds of the doubtful, I added back the 'u' qualifiers
+ * that somehow got lost over the last years.
+ */
+
+
+/*
+ *---------------------------------------------------------------------
+ * Convert a timestamp in NTP scale to a 64bit seconds value in the UN*X
+ * scale with proper epoch unfolding around a given pivot or the current
+ * system time. This function happily accepts negative pivot values as
+ * timestamps befor 1970-01-01, so be aware of possible trouble on
+ * platforms with 32bit 'time_t'!
+ *
+ * This is also a periodic extension, but since the cycle is 2^32 and
+ * the shift is 2^31, we can do some *very* fast math without explicit
+ * divisions.
+ *---------------------------------------------------------------------
+ */
+vint64
+ntpcal_ntp_to_time(
+ uint32_t ntp,
+ const time_t * pivot
+ )
+{
+ vint64 res;
+
+# if defined(HAVE_INT64)
+
+ res.q_s = (pivot != NULL)
+ ? *pivot
+ : now();
+ res.Q_s -= 0x80000000u; /* unshift of half range */
+ ntp -= (uint32_t)JAN_1970; /* warp into UN*X domain */
+ ntp -= res.D_s.lo; /* cycle difference */
+ res.Q_s += (uint64_t)ntp; /* get expanded time */
+
+# else /* no 64bit scalars */
+
+ time_t tmp;
+
+ tmp = (pivot != NULL)
+ ? *pivot
+ : now();
+ res = time_to_vint64(&tmp);
+ M_SUB(res.D_s.hi, res.D_s.lo, 0, 0x80000000u);
+ ntp -= (uint32_t)JAN_1970; /* warp into UN*X domain */
+ ntp -= res.D_s.lo; /* cycle difference */
+ M_ADD(res.D_s.hi, res.D_s.lo, 0, ntp);
+
+# endif /* no 64bit scalars */
+
+ return res;
+}
+
+/*
+ *---------------------------------------------------------------------
+ * Convert a timestamp in NTP scale to a 64bit seconds value in the NTP
+ * scale with proper epoch unfolding around a given pivot or the current
+ * system time.
+ *
+ * Note: The pivot must be given in the UN*X time domain!
+ *
+ * This is also a periodic extension, but since the cycle is 2^32 and
+ * the shift is 2^31, we can do some *very* fast math without explicit
+ * divisions.
+ *---------------------------------------------------------------------
+ */
+vint64
+ntpcal_ntp_to_ntp(
+ uint32_t ntp,
+ const time_t *pivot
+ )
+{
+ vint64 res;
+
+# if defined(HAVE_INT64)
+
+ res.q_s = (pivot)
+ ? *pivot
+ : now();
+ res.Q_s -= 0x80000000u; /* unshift of half range */
+ res.Q_s += (uint32_t)JAN_1970; /* warp into NTP domain */
+ ntp -= res.D_s.lo; /* cycle difference */
+ res.Q_s += (uint64_t)ntp; /* get expanded time */
+
+# else /* no 64bit scalars */
+
+ time_t tmp;
+
+ tmp = (pivot)
+ ? *pivot
+ : now();
+ res = time_to_vint64(&tmp);
+ M_SUB(res.D_s.hi, res.D_s.lo, 0, 0x80000000u);
+ M_ADD(res.D_s.hi, res.D_s.lo, 0, (uint32_t)JAN_1970);/*into NTP */
+ ntp -= res.D_s.lo; /* cycle difference */
+ M_ADD(res.D_s.hi, res.D_s.lo, 0, ntp);
+
+# endif /* no 64bit scalars */
+
+ return res;
+}
+
+
+/*
+ * ====================================================================
+ *
+ * Splitting values to composite entities
+ *
+ * ====================================================================
+ */
+
+/*
+ *---------------------------------------------------------------------
+ * Split a 64bit seconds value into elapsed days in 'res.hi' and
+ * elapsed seconds since midnight in 'res.lo' using explicit floor
+ * division. This function happily accepts negative time values as
+ * timestamps before the respective epoch start.
+ *---------------------------------------------------------------------
+ */
+ntpcal_split
+ntpcal_daysplit(
+ const vint64 *ts
+ )
+{
+ ntpcal_split res;
+ uint32_t Q;
+
+# if defined(HAVE_INT64)
+
+ /* Manual floor division by SECSPERDAY. This uses the one's
+ * complement trick, too, but without an extra flag value: The
+ * flag would be 64bit, and that's a bit of overkill on a 32bit
+ * target that has to use a register pair for a 64bit number.
+ */
+ if (ts->q_s < 0)
+ Q = ~(uint32_t)(~ts->Q_s / SECSPERDAY);
+ else
+ Q = (uint32_t)(ts->Q_s / SECSPERDAY);
+
+# else
+
+ uint32_t ah, al, sflag, A;
+
+ /* get operand into ah/al (either ts or ts' one's complement,
+ * for later floor division)
+ */
+ sflag = int32_sflag(ts->d_s.hi);
+ ah = sflag ^ ts->D_s.hi;
+ al = sflag ^ ts->D_s.lo;
+
+ /* Since 86400 == 128*675 we can drop the least 7 bits and
+ * divide by 675 instead of 86400. Then the maximum remainder
+ * after each devision step is 674, and we need 10 bits for
+ * that. So in the next step we can shift in 22 bits from the
+ * numerator.
+ *
+ * Therefore we load the accu with the top 13 bits (51..63) in
+ * the first shot. We don't have to remember the quotient -- it
+ * would be shifted out anyway.
+ */
+ A = ah >> 19;
+ if (A >= 675)
+ A = (A % 675u);
+
+ /* Now assemble the remainder with bits 29..50 from the
+ * numerator and divide. This creates the upper ten bits of the
+ * quotient. (Well, the top 22 bits of a 44bit result. But that
+ * will be truncated to 32 bits anyway.)
+ */
+ A = (A << 19) | (ah & 0x0007FFFFu);
+ A = (A << 3) | (al >> 29);
+ Q = A / 675u;
+ A = A % 675u;
+
+ /* Now assemble the remainder with bits 7..28 from the numerator
+ * and do a final division step.
+ */
+ A = (A << 22) | ((al >> 7) & 0x003FFFFFu);
+ Q = (Q << 22) | (A / 675u);
+
+ /* The last 7 bits get simply dropped, as they have no affect on
+ * the quotient when dividing by 86400.
+ */
+
+ /* apply sign correction and calculate the true floor
+ * remainder.
+ */
+ Q ^= sflag;
+
+# endif
+
+ res.hi = uint32_2cpl_to_int32(Q);
+ res.lo = ts->D_s.lo - Q * SECSPERDAY;
+
+ return res;
+}
+
+/*
+ *---------------------------------------------------------------------
+ * Split a 32bit seconds value into h/m/s and excessive days. This
+ * function happily accepts negative time values as timestamps before
+ * midnight.
+ *---------------------------------------------------------------------
+ */
+static int32_t
+priv_timesplit(
+ int32_t split[3],
+ int32_t ts
+ )
+{
+ /* Do 3 chained floor divisions by positive constants, using the
+ * one's complement trick and factoring out the intermediate XOR
+ * ops to reduce the number of operations.
+ */
+ uint32_t us, um, uh, ud, sflag;
+
+ sflag = int32_sflag(ts);
+ us = int32_to_uint32_2cpl(ts);
+
+ um = (sflag ^ us) / SECSPERMIN;
+ uh = um / MINSPERHR;
+ ud = uh / HRSPERDAY;
+
+ um ^= sflag;
+ uh ^= sflag;
+ ud ^= sflag;
+
+ split[0] = (int32_t)(uh - ud * HRSPERDAY );
+ split[1] = (int32_t)(um - uh * MINSPERHR );
+ split[2] = (int32_t)(us - um * SECSPERMIN);
+
+ return uint32_2cpl_to_int32(ud);
+}
+
+/*
+ *---------------------------------------------------------------------
+ * Given the number of elapsed days in the calendar era, split this
+ * number into the number of elapsed years in 'res.hi' and the number
+ * of elapsed days of that year in 'res.lo'.
+ *
+ * if 'isleapyear' is not NULL, it will receive an integer that is 0 for
+ * regular years and a non-zero value for leap years.
+ *---------------------------------------------------------------------
+ */
+ntpcal_split
+ntpcal_split_eradays(
+ int32_t days,
+ int *isleapyear
+ )
+{
+ /* Use the fast cyclesplit algorithm here, to calculate the
+ * centuries and years in a century with one division each. This
+ * reduces the number of division operations to two, but is
+ * susceptible to internal range overflow. We make sure the
+ * input operands are in the safe range; this still gives us
+ * approx +/-2.9 million years.
+ */
+ ntpcal_split res;
+ int32_t n100, n001; /* calendar year cycles */
+ uint32_t uday, Q, sflag;
+
+ /* split off centuries first */
+ sflag = int32_sflag(days);
+ uday = uint32_saturate(int32_to_uint32_2cpl(days), sflag);
+ uday = (4u * uday) | 3u;
+ Q = sflag ^ ((sflag ^ uday) / GREGORIAN_CYCLE_DAYS);
+ uday = uday - Q * GREGORIAN_CYCLE_DAYS;
+ n100 = uint32_2cpl_to_int32(Q);
+
+ /* Split off years in century -- days >= 0 here, and we're far
+ * away from integer overflow trouble now. */
+ uday |= 3;
+ n001 = uday / GREGORIAN_NORMAL_LEAP_CYCLE_DAYS;
+ uday = uday % GREGORIAN_NORMAL_LEAP_CYCLE_DAYS;
+
+ /* Assemble the year and day in year */
+ res.hi = n100 * 100 + n001;
+ res.lo = uday / 4u;
+
+ /* Eventually set the leap year flag. Note: 0 <= n001 <= 99 and
+ * Q is still the two's complement representation of the
+ * centuries: The modulo 4 ops can be done with masking here.
+ * We also shift the year and the century by one, so the tests
+ * can be done against zero instead of 3.
+ */
+ if (isleapyear)
+ *isleapyear = !((n001+1) & 3)
+ && ((n001 != 99) || !((Q+1) & 3));
+
+ return res;
+}
+
+/*
+ *---------------------------------------------------------------------
+ * Given a number of elapsed days in a year and a leap year indicator,
+ * split the number of elapsed days into the number of elapsed months in
+ * 'res.hi' and the number of elapsed days of that month in 'res.lo'.
+ *
+ * This function will fail and return {-1,-1} if the number of elapsed
+ * days is not in the valid range!
+ *---------------------------------------------------------------------
+ */
+ntpcal_split
+ntpcal_split_yeardays(
+ int32_t eyd,
+ int isleapyear
+ )
+{
+ ntpcal_split res;
+ const uint16_t *lt; /* month length table */
+
+ /* check leap year flag and select proper table */
+ lt = real_month_table[(isleapyear != 0)];
+ if (0 <= eyd && eyd < lt[12]) {
+ /* get zero-based month by approximation & correction step */
+ res.hi = eyd >> 5; /* approx month; might be 1 too low */
+ if (lt[res.hi + 1] <= eyd) /* fixup approximative month value */
+ res.hi += 1;
+ res.lo = eyd - lt[res.hi];
+ } else {
+ res.lo = res.hi = -1;
+ }
+
+ return res;
+}
+
+/*
+ *---------------------------------------------------------------------
+ * Convert a RD into the date part of a 'struct calendar'.
+ *---------------------------------------------------------------------
+ */
+int
+ntpcal_rd_to_date(
+ struct calendar *jd,
+ int32_t rd
+ )
+{
+ ntpcal_split split;
+ int leapy;
+ u_int ymask;
+
+ /* Get day-of-week first. Since rd is signed, the remainder can
+ * be in the range [-6..+6], but the assignment to an unsigned
+ * variable maps the negative values to positive values >=7.
+ * This makes the sign correction look strange, but adding 7
+ * causes the needed wrap-around into the desired value range of
+ * zero to six, both inclusive.
+ */
+ jd->weekday = rd % DAYSPERWEEK;
+ if (jd->weekday >= DAYSPERWEEK) /* weekday is unsigned! */
+ jd->weekday += DAYSPERWEEK;
+
+ split = ntpcal_split_eradays(rd - 1, &leapy);
+ /* Get year and day-of-year, with overflow check. If any of the
+ * upper 16 bits is set after shifting to unity-based years, we
+ * will have an overflow when converting to an unsigned 16bit
+ * year. Shifting to the right is OK here, since it does not
+ * matter if the shift is logic or arithmetic.
+ */
+ split.hi += 1;
+ ymask = 0u - ((split.hi >> 16) == 0);
+ jd->year = (uint16_t)(split.hi & ymask);
+ jd->yearday = (uint16_t)split.lo + 1;
+
+ /* convert to month and mday */
+ split = ntpcal_split_yeardays(split.lo, leapy);
+ jd->month = (uint8_t)split.hi + 1;
+ jd->monthday = (uint8_t)split.lo + 1;
+
+ return ymask ? leapy : -1;
+}
+
+/*
+ *---------------------------------------------------------------------
+ * Convert a RD into the date part of a 'struct tm'.
+ *---------------------------------------------------------------------
+ */
+int
+ntpcal_rd_to_tm(
+ struct tm *utm,
+ int32_t rd
+ )
+{
+ ntpcal_split split;
+ int leapy;
+
+ /* get day-of-week first */
+ utm->tm_wday = rd % DAYSPERWEEK;
+ if (utm->tm_wday < 0)
+ utm->tm_wday += DAYSPERWEEK;
+
+ /* get year and day-of-year */
+ split = ntpcal_split_eradays(rd - 1, &leapy);
+ utm->tm_year = split.hi - 1899;
+ utm->tm_yday = split.lo; /* 0-based */
+
+ /* convert to month and mday */
+ split = ntpcal_split_yeardays(split.lo, leapy);
+ utm->tm_mon = split.hi; /* 0-based */
+ utm->tm_mday = split.lo + 1; /* 1-based */
+
+ return leapy;
+}
+
+/*
+ *---------------------------------------------------------------------
+ * Take a value of seconds since midnight and split it into hhmmss in a
+ * 'struct calendar'.
+ *---------------------------------------------------------------------
+ */
+int32_t
+ntpcal_daysec_to_date(
+ struct calendar *jd,
+ int32_t sec
+ )
+{
+ int32_t days;
+ int ts[3];
+
+ days = priv_timesplit(ts, sec);
+ jd->hour = (uint8_t)ts[0];
+ jd->minute = (uint8_t)ts[1];
+ jd->second = (uint8_t)ts[2];
+
+ return days;
+}
+
+/*
+ *---------------------------------------------------------------------
+ * Take a value of seconds since midnight and split it into hhmmss in a
+ * 'struct tm'.
+ *---------------------------------------------------------------------
+ */
+int32_t
+ntpcal_daysec_to_tm(
+ struct tm *utm,
+ int32_t sec
+ )
+{
+ int32_t days;
+ int32_t ts[3];
+
+ days = priv_timesplit(ts, sec);
+ utm->tm_hour = ts[0];
+ utm->tm_min = ts[1];
+ utm->tm_sec = ts[2];
+
+ return days;
+}
+
+/*
+ *---------------------------------------------------------------------
+ * take a split representation for day/second-of-day and day offset
+ * and convert it to a 'struct calendar'. The seconds will be normalised
+ * into the range of a day, and the day will be adjusted accordingly.
+ *
+ * returns >0 if the result is in a leap year, 0 if in a regular
+ * year and <0 if the result did not fit into the calendar struct.
+ *---------------------------------------------------------------------
+ */
+int
+ntpcal_daysplit_to_date(
+ struct calendar *jd,
+ const ntpcal_split *ds,
+ int32_t dof
+ )
+{
+ dof += ntpcal_daysec_to_date(jd, ds->lo);
+ return ntpcal_rd_to_date(jd, ds->hi + dof);
+}
+
+/*
+ *---------------------------------------------------------------------
+ * take a split representation for day/second-of-day and day offset
+ * and convert it to a 'struct tm'. The seconds will be normalised
+ * into the range of a day, and the day will be adjusted accordingly.
+ *
+ * returns 1 if the result is in a leap year and zero if in a regular
+ * year.
+ *---------------------------------------------------------------------
+ */
+int
+ntpcal_daysplit_to_tm(
+ struct tm *utm,
+ const ntpcal_split *ds ,
+ int32_t dof
+ )
+{
+ dof += ntpcal_daysec_to_tm(utm, ds->lo);
+
+ return ntpcal_rd_to_tm(utm, ds->hi + dof);
+}
+
+/*
+ *---------------------------------------------------------------------
+ * Take a UN*X time and convert to a calendar structure.
+ *---------------------------------------------------------------------
+ */
+int
+ntpcal_time_to_date(
+ struct calendar *jd,
+ const vint64 *ts
+ )
+{
+ ntpcal_split ds;
+
+ ds = ntpcal_daysplit(ts);
+ ds.hi += ntpcal_daysec_to_date(jd, ds.lo);
+ ds.hi += DAY_UNIX_STARTS;
+
+ return ntpcal_rd_to_date(jd, ds.hi);
+}
+
+
+/*
+ * ====================================================================
+ *
+ * merging composite entities
+ *
+ * ====================================================================
+ */
+
+/*
+ *---------------------------------------------------------------------
+ * Merge a number of days and a number of seconds into seconds,
+ * expressed in 64 bits to avoid overflow.
+ *---------------------------------------------------------------------
+ */
+vint64
+ntpcal_dayjoin(
+ int32_t days,
+ int32_t secs
+ )
+{
+ vint64 res;
+
+# if defined(HAVE_INT64)
+
+ res.q_s = days;
+ res.q_s *= SECSPERDAY;
+ res.q_s += secs;
+
+# else
+
+ uint32_t p1, p2;
+ int isneg;
+
+ /*
+ * res = days *86400 + secs, using manual 16/32 bit
+ * multiplications and shifts.
+ */
+ isneg = (days < 0);
+ if (isneg)
+ days = -days;
+
+ /* assemble days * 675 */
+ res.D_s.lo = (days & 0xFFFF) * 675u;
+ res.D_s.hi = 0;
+ p1 = (days >> 16) * 675u;
+ p2 = p1 >> 16;
+ p1 = p1 << 16;
+ M_ADD(res.D_s.hi, res.D_s.lo, p2, p1);
+
+ /* mul by 128, using shift */
+ res.D_s.hi = (res.D_s.hi << 7) | (res.D_s.lo >> 25);
+ res.D_s.lo = (res.D_s.lo << 7);
+
+ /* fix sign */
+ if (isneg)
+ M_NEG(res.D_s.hi, res.D_s.lo);
+
+ /* properly add seconds */
+ p2 = 0;
+ if (secs < 0) {
+ p1 = (uint32_t)-secs;
+ M_NEG(p2, p1);
+ } else {
+ p1 = (uint32_t)secs;
+ }
+ M_ADD(res.D_s.hi, res.D_s.lo, p2, p1);
+
+# endif
+
+ return res;
+}
+
+/*
+ *---------------------------------------------------------------------
+ * get leap years since epoch in elapsed years
+ *---------------------------------------------------------------------
+ */
+int32_t
+ntpcal_leapyears_in_years(
+ int32_t years
+ )
+{
+ /* We use the in-out-in algorithm here, using the one's
+ * complement division trick for negative numbers. The chained
+ * division sequence by 4/25/4 gives the compiler the chance to
+ * get away with only one true division and doing shifts otherwise.
+ */
+
+ uint32_t sflag, sum, uyear;
+
+ sflag = int32_sflag(years);
+ uyear = int32_to_uint32_2cpl(years);
+ uyear ^= sflag;
+
+ sum = (uyear /= 4u); /* 4yr rule --> IN */
+ sum -= (uyear /= 25u); /* 100yr rule --> OUT */
+ sum += (uyear /= 4u); /* 400yr rule --> IN */
+
+ /* Thanks to the alternation of IN/OUT/IN we can do the sum
+ * directly and have a single one's complement operation
+ * here. (Only if the years are negative, of course.) Otherwise
+ * the one's complement would have to be done when
+ * adding/subtracting the terms.
+ */
+ return uint32_2cpl_to_int32(sflag ^ sum);
+}
+
+/*
+ *---------------------------------------------------------------------
+ * Convert elapsed years in Era into elapsed days in Era.
+ *---------------------------------------------------------------------
+ */
+int32_t
+ntpcal_days_in_years(
+ int32_t years
+ )
+{
+ return years * DAYSPERYEAR + ntpcal_leapyears_in_years(years);
+}
+
+/*
+ *---------------------------------------------------------------------
+ * Convert a number of elapsed month in a year into elapsed days in year.
+ *
+ * The month will be normalized, and 'res.hi' will contain the
+ * excessive years that must be considered when converting the years,
+ * while 'res.lo' will contain the number of elapsed days since start
+ * of the year.
+ *
+ * This code uses the shifted-month-approach to convert month to days,
+ * because then there is no need to have explicit leap year
+ * information. The slight disadvantage is that for most month values
+ * the result is a negative value, and the year excess is one; the
+ * conversion is then simply based on the start of the following year.
+ *---------------------------------------------------------------------
+ */
+ntpcal_split
+ntpcal_days_in_months(
+ int32_t m
+ )
+{
+ ntpcal_split res;
+
+ /* Add ten months and correct if needed. (It likely is...) */
+ res.lo = m + 10;
+ res.hi = (res.lo >= 12);
+ if (res.hi)
+ res.lo -= 12;
+
+ /* if still out of range, normalise by floor division ... */
+ if (res.lo < 0 || res.lo >= 12) {
+ uint32_t mu, Q, sflag;
+ sflag = int32_sflag(res.lo);
+ mu = int32_to_uint32_2cpl(res.lo);
+ Q = sflag ^ ((sflag ^ mu) / 12u);
+ res.hi += uint32_2cpl_to_int32(Q);
+ res.lo = mu - Q * 12u;
+ }
+
+ /* get cummulated days in year with unshift */
+ res.lo = shift_month_table[res.lo] - 306;
+
+ return res;
+}
+
+/*
+ *---------------------------------------------------------------------
+ * Convert ELAPSED years/months/days of gregorian calendar to elapsed
+ * days in Gregorian epoch.
+ *
+ * If you want to convert years and days-of-year, just give a month of
+ * zero.
+ *---------------------------------------------------------------------
+ */
+int32_t
+ntpcal_edate_to_eradays(
+ int32_t years,
+ int32_t mons,
+ int32_t mdays
+ )
+{
+ ntpcal_split tmp;
+ int32_t res;
+
+ if (mons) {
+ tmp = ntpcal_days_in_months(mons);
+ res = ntpcal_days_in_years(years + tmp.hi) + tmp.lo;
+ } else
+ res = ntpcal_days_in_years(years);
+ res += mdays;
+
+ return res;
+}
+
+/*
+ *---------------------------------------------------------------------
+ * Convert ELAPSED years/months/days of gregorian calendar to elapsed
+ * days in year.
+ *
+ * Note: This will give the true difference to the start of the given
+ * year, even if months & days are off-scale.
+ *---------------------------------------------------------------------
+ */
+int32_t
+ntpcal_edate_to_yeardays(
+ int32_t years,
+ int32_t mons,
+ int32_t mdays
+ )
+{
+ ntpcal_split tmp;
+
+ if (0 <= mons && mons < 12) {
+ years += 1;
+ mdays += real_month_table[is_leapyear(years)][mons];
+ } else {
+ tmp = ntpcal_days_in_months(mons);
+ mdays += tmp.lo
+ + ntpcal_days_in_years(years + tmp.hi)
+ - ntpcal_days_in_years(years);
+ }
+
+ return mdays;
+}
+
+/*
+ *---------------------------------------------------------------------
+ * Convert elapsed days and the hour/minute/second information into
+ * total seconds.
+ *
+ * If 'isvalid' is not NULL, do a range check on the time specification
+ * and tell if the time input is in the normal range, permitting for a
+ * single leapsecond.
+ *---------------------------------------------------------------------
+ */
+int32_t
+ntpcal_etime_to_seconds(
+ int32_t hours,
+ int32_t minutes,
+ int32_t seconds
+ )
+{
+ int32_t res;
+
+ res = (hours * MINSPERHR + minutes) * SECSPERMIN + seconds;
+
+ return res;
+}
+
+/*
+ *---------------------------------------------------------------------
+ * Convert the date part of a 'struct tm' (that is, year, month,
+ * day-of-month) into the RD of that day.
+ *---------------------------------------------------------------------
+ */
+int32_t
+ntpcal_tm_to_rd(
+ const struct tm *utm
+ )
+{
+ return ntpcal_edate_to_eradays(utm->tm_year + 1899,
+ utm->tm_mon,
+ utm->tm_mday - 1) + 1;
+}
+
+/*
+ *---------------------------------------------------------------------
+ * Convert the date part of a 'struct calendar' (that is, year, month,
+ * day-of-month) into the RD of that day.
+ *---------------------------------------------------------------------
+ */
+int32_t
+ntpcal_date_to_rd(
+ const struct calendar *jd
+ )
+{
+ return ntpcal_edate_to_eradays((int32_t)jd->year - 1,
+ (int32_t)jd->month - 1,
+ (int32_t)jd->monthday - 1) + 1;
+}
+
+/*
+ *---------------------------------------------------------------------
+ * convert a year number to rata die of year start
+ *---------------------------------------------------------------------
+ */
+int32_t
+ntpcal_year_to_ystart(
+ int32_t year
+ )
+{
+ return ntpcal_days_in_years(year - 1) + 1;
+}
+
+/*
+ *---------------------------------------------------------------------
+ * For a given RD, get the RD of the associated year start,
+ * that is, the RD of the last January,1st on or before that day.
+ *---------------------------------------------------------------------
+ */
+int32_t
+ntpcal_rd_to_ystart(
+ int32_t rd
+ )
+{
+ /*
+ * Rather simple exercise: split the day number into elapsed
+ * years and elapsed days, then remove the elapsed days from the
+ * input value. Nice'n sweet...
+ */
+ return rd - ntpcal_split_eradays(rd - 1, NULL).lo;
+}
+
+/*
+ *---------------------------------------------------------------------
+ * For a given RD, get the RD of the associated month start.
+ *---------------------------------------------------------------------
+ */
+int32_t
+ntpcal_rd_to_mstart(
+ int32_t rd
+ )
+{
+ ntpcal_split split;
+ int leaps;
+
+ split = ntpcal_split_eradays(rd - 1, &leaps);
+ split = ntpcal_split_yeardays(split.lo, leaps);
+
+ return rd - split.lo;
+}
+
+/*
+ *---------------------------------------------------------------------
+ * take a 'struct calendar' and get the seconds-of-day from it.
+ *---------------------------------------------------------------------
+ */
+int32_t
+ntpcal_date_to_daysec(
+ const struct calendar *jd
+ )
+{
+ return ntpcal_etime_to_seconds(jd->hour, jd->minute,
+ jd->second);
+}
+
+/*
+ *---------------------------------------------------------------------
+ * take a 'struct tm' and get the seconds-of-day from it.
+ *---------------------------------------------------------------------
+ */
+int32_t
+ntpcal_tm_to_daysec(
+ const struct tm *utm
+ )
+{
+ return ntpcal_etime_to_seconds(utm->tm_hour, utm->tm_min,
+ utm->tm_sec);
+}
+
+/*
+ *---------------------------------------------------------------------
+ * take a 'struct calendar' and convert it to a 'time_t'
+ *---------------------------------------------------------------------
+ */
+time_t
+ntpcal_date_to_time(
+ const struct calendar *jd
+ )
+{
+ vint64 join;
+ int32_t days, secs;
+
+ days = ntpcal_date_to_rd(jd) - DAY_UNIX_STARTS;
+ secs = ntpcal_date_to_daysec(jd);
+ join = ntpcal_dayjoin(days, secs);
+
+ return vint64_to_time(&join);
+}
+
+
+/*
+ * ====================================================================
+ *
+ * extended and unchecked variants of caljulian/caltontp
+ *
+ * ====================================================================
+ */
+int
+ntpcal_ntp64_to_date(
+ struct calendar *jd,
+ const vint64 *ntp
+ )
+{
+ ntpcal_split ds;
+
+ ds = ntpcal_daysplit(ntp);
+ ds.hi += ntpcal_daysec_to_date(jd, ds.lo);
+
+ return ntpcal_rd_to_date(jd, ds.hi + DAY_NTP_STARTS);
+}
+
+int
+ntpcal_ntp_to_date(
+ struct calendar *jd,
+ uint32_t ntp,
+ const time_t *piv
+ )
+{
+ vint64 ntp64;
+
+ /*
+ * Unfold ntp time around current time into NTP domain. Split
+ * into days and seconds, shift days into CE domain and
+ * process the parts.
+ */
+ ntp64 = ntpcal_ntp_to_ntp(ntp, piv);
+ return ntpcal_ntp64_to_date(jd, &ntp64);
+}
+
+
+vint64
+ntpcal_date_to_ntp64(
+ const struct calendar *jd
+ )
+{
+ /*
+ * Convert date to NTP. Ignore yearday, use d/m/y only.
+ */
+ return ntpcal_dayjoin(ntpcal_date_to_rd(jd) - DAY_NTP_STARTS,
+ ntpcal_date_to_daysec(jd));
+}
+
+
+uint32_t
+ntpcal_date_to_ntp(
+ const struct calendar *jd
+ )
+{
+ /*
+ * Get lower half of 64-bit NTP timestamp from date/time.
+ */
+ return ntpcal_date_to_ntp64(jd).d_s.lo;
+}
+
+
+
+/*
+ * ====================================================================
+ *
+ * day-of-week calculations
+ *
+ * ====================================================================
+ */
+/*
+ * Given a RataDie and a day-of-week, calculate a RDN that is reater-than,
+ * greater-or equal, closest, less-or-equal or less-than the given RDN
+ * and denotes the given day-of-week
+ */
+int32_t
+ntpcal_weekday_gt(
+ int32_t rdn,
+ int32_t dow
+ )
+{
+ return ntpcal_periodic_extend(rdn+1, dow, 7);
+}
+
+int32_t
+ntpcal_weekday_ge(
+ int32_t rdn,
+ int32_t dow
+ )
+{
+ return ntpcal_periodic_extend(rdn, dow, 7);
+}
+
+int32_t
+ntpcal_weekday_close(
+ int32_t rdn,
+ int32_t dow
+ )
+{
+ return ntpcal_periodic_extend(rdn-3, dow, 7);
+}
+
+int32_t
+ntpcal_weekday_le(
+ int32_t rdn,
+ int32_t dow
+ )
+{
+ return ntpcal_periodic_extend(rdn, dow, -7);
+}
+
+int32_t
+ntpcal_weekday_lt(
+ int32_t rdn,
+ int32_t dow
+ )
+{
+ return ntpcal_periodic_extend(rdn-1, dow, -7);
+}
+
+/*
+ * ====================================================================
+ *
+ * ISO week-calendar conversions
+ *
+ * The ISO8601 calendar defines a calendar of years, weeks and weekdays.
+ * It is related to the Gregorian calendar, and a ISO year starts at the
+ * Monday closest to Jan,1st of the corresponding Gregorian year. A ISO
+ * calendar year has always 52 or 53 weeks, and like the Grogrian
+ * calendar the ISO8601 calendar repeats itself every 400 years, or
+ * 146097 days, or 20871 weeks.
+ *
+ * While it is possible to write ISO calendar functions based on the
+ * Gregorian calendar functions, the following implementation takes a
+ * different approach, based directly on years and weeks.
+ *
+ * Analysis of the tabulated data shows that it is not possible to
+ * interpolate from years to weeks over a full 400 year range; cyclic
+ * shifts over 400 years do not provide a solution here. But it *is*
+ * possible to interpolate over every single century of the 400-year
+ * cycle. (The centennial leap year rule seems to be the culprit here.)
+ *
+ * It can be shown that a conversion from years to weeks can be done
+ * using a linear transformation of the form
+ *
+ * w = floor( y * a + b )
+ *
+ * where the slope a must hold to
+ *
+ * 52.1780821918 <= a < 52.1791044776
+ *
+ * and b must be chosen according to the selected slope and the number
+ * of the century in a 400-year period.
+ *
+ * The inverse calculation can also be done in this way. Careful scaling
+ * provides an unlimited set of integer coefficients a,k,b that enable
+ * us to write the calulation in the form
+ *
+ * w = (y * a + b ) / k
+ * y = (w * a' + b') / k'
+ *
+ * In this implementation the values of k and k' are chosen to be
+ * smallest possible powers of two, so the division can be implemented
+ * as shifts if the optimiser chooses to do so.
+ *
+ * ====================================================================
+ */
+
+/*
+ * Given a number of elapsed (ISO-)years since the begin of the
+ * christian era, return the number of elapsed weeks corresponding to
+ * the number of years.
+ */
+int32_t
+isocal_weeks_in_years(
+ int32_t years
+ )
+{
+ /*
+ * use: w = (y * 53431 + b[c]) / 1024 as interpolation
+ */
+ static const uint16_t bctab[4] = { 157, 449, 597, 889 };
+
+ int32_t cs, cw;
+ uint32_t cc, ci, yu, sflag;
+
+ sflag = int32_sflag(years);
+ yu = int32_to_uint32_2cpl(years);
+
+ /* split off centuries, using floor division */
+ cc = sflag ^ ((sflag ^ yu) / 100u);
+ yu -= cc * 100u;
+
+ /* calculate century cycles shift and cycle index:
+ * Assuming a century is 5217 weeks, we have to add a cycle
+ * shift that is 3 for every 4 centuries, because 3 of the four
+ * centuries have 5218 weeks. So '(cc*3 + 1) / 4' is the actual
+ * correction, and the second century is the defective one.
+ *
+ * Needs floor division by 4, which is done with masking and
+ * shifting.
+ */
+ ci = cc * 3u + 1;
+ cs = uint32_2cpl_to_int32(sflag ^ ((sflag ^ ci) / 4u));
+ ci = ci % 4u;
+
+ /* Get weeks in century. Can use plain division here as all ops
+ * are >= 0, and let the compiler sort out the possible
+ * optimisations.
+ */
+ cw = (yu * 53431u + bctab[ci]) / 1024u;
+
+ return uint32_2cpl_to_int32(cc) * 5217 + cs + cw;
+}
+
+/*
+ * Given a number of elapsed weeks since the begin of the christian
+ * era, split this number into the number of elapsed years in res.hi
+ * and the excessive number of weeks in res.lo. (That is, res.lo is
+ * the number of elapsed weeks in the remaining partial year.)
+ */
+ntpcal_split
+isocal_split_eraweeks(
+ int32_t weeks
+ )
+{
+ /*
+ * use: y = (w * 157 + b[c]) / 8192 as interpolation
+ */
+
+ static const uint16_t bctab[4] = { 85, 130, 17, 62 };
+
+ ntpcal_split res;
+ int32_t cc, ci;
+ uint32_t sw, cy, Q, sflag;
+
+ /* Use two fast cycle-split divisions here. This is again
+ * susceptible to internal overflow, so we check the range. This
+ * still permits more than +/-20 million years, so this is
+ * likely a pure academical problem.
+ *
+ * We want to execute '(weeks * 4 + 2) /% 20871' under floor
+ * division rules in the first step.
+ */
+ sflag = int32_sflag(weeks);
+ sw = uint32_saturate(int32_to_uint32_2cpl(weeks), sflag);
+ sw = 4u * sw + 2;
+ Q = sflag ^ ((sflag ^ sw) / GREGORIAN_CYCLE_WEEKS);
+ sw -= Q * GREGORIAN_CYCLE_WEEKS;
+ ci = Q % 4u;
+ cc = uint32_2cpl_to_int32(Q);
+
+ /* Split off years; sw >= 0 here! The scaled weeks in the years
+ * are scaled up by 157 afterwards.
+ */
+ sw = (sw / 4u) * 157u + bctab[ci];
+ cy = sw / 8192u; /* ws >> 13 , let the compiler sort it out */
+ sw = sw % 8192u; /* ws & 8191, let the compiler sort it out */
+
+ /* assemble elapsed years and downscale the elapsed weeks in
+ * the year.
+ */
+ res.hi = 100*cc + cy;
+ res.lo = sw / 157u;
+
+ return res;
+}
+
+/*
+ * Given a second in the NTP time scale and a pivot, expand the NTP
+ * time stamp around the pivot and convert into an ISO calendar time
+ * stamp.
+ */
+int
+isocal_ntp64_to_date(
+ struct isodate *id,
+ const vint64 *ntp
+ )
+{
+ ntpcal_split ds;
+ int32_t ts[3];
+ uint32_t uw, ud, sflag;
+
+ /*
+ * Split NTP time into days and seconds, shift days into CE
+ * domain and process the parts.
+ */
+ ds = ntpcal_daysplit(ntp);
+
+ /* split time part */
+ ds.hi += priv_timesplit(ts, ds.lo);
+ id->hour = (uint8_t)ts[0];
+ id->minute = (uint8_t)ts[1];
+ id->second = (uint8_t)ts[2];
+
+ /* split days into days and weeks, using floor division in unsigned */
+ ds.hi += DAY_NTP_STARTS - 1; /* shift from NTP to RDN */
+ sflag = int32_sflag(ds.hi);
+ ud = int32_to_uint32_2cpl(ds.hi);
+ uw = sflag ^ ((sflag ^ ud) / DAYSPERWEEK);
+ ud -= uw * DAYSPERWEEK;
+ ds.hi = uint32_2cpl_to_int32(uw);
+ ds.lo = ud;
+
+ id->weekday = (uint8_t)ds.lo + 1; /* weekday result */
+
+ /* get year and week in year */
+ ds = isocal_split_eraweeks(ds.hi); /* elapsed years&week*/
+ id->year = (uint16_t)ds.hi + 1; /* shift to current */
+ id->week = (uint8_t )ds.lo + 1;
+
+ return (ds.hi >= 0 && ds.hi < 0x0000FFFF);
+}
+
+int
+isocal_ntp_to_date(
+ struct isodate *id,
+ uint32_t ntp,
+ const time_t *piv
+ )
+{
+ vint64 ntp64;
+
+ /*
+ * Unfold ntp time around current time into NTP domain, then
+ * convert the full time stamp.
+ */
+ ntp64 = ntpcal_ntp_to_ntp(ntp, piv);
+ return isocal_ntp64_to_date(id, &ntp64);
+}
+
+/*
+ * Convert a ISO date spec into a second in the NTP time scale,
+ * properly truncated to 32 bit.
+ */
+vint64
+isocal_date_to_ntp64(
+ const struct isodate *id
+ )
+{
+ int32_t weeks, days, secs;
+
+ weeks = isocal_weeks_in_years((int32_t)id->year - 1)
+ + (int32_t)id->week - 1;
+ days = weeks * 7 + (int32_t)id->weekday;
+ /* days is RDN of ISO date now */
+ secs = ntpcal_etime_to_seconds(id->hour, id->minute, id->second);
+
+ return ntpcal_dayjoin(days - DAY_NTP_STARTS, secs);
+}
+
+uint32_t
+isocal_date_to_ntp(
+ const struct isodate *id
+ )
+{
+ /*
+ * Get lower half of 64-bit NTP timestamp from date/time.
+ */
+ return isocal_date_to_ntp64(id).d_s.lo;
+}
+
+/*
+ * ====================================================================
+ * 'basedate' support functions
+ * ====================================================================
+ */
+
+static int32_t s_baseday = NTP_TO_UNIX_DAYS;
+static int32_t s_gpsweek = 0;
+
+int32_t
+basedate_eval_buildstamp(void)
+{
+ struct calendar jd;
+ int32_t ed;
+
+ if (!ntpcal_get_build_date(&jd))
+ return NTP_TO_UNIX_DAYS;
+
+ /* The time zone of the build stamp is unspecified; we remove
+ * one day to provide a certain slack. And in case somebody
+ * fiddled with the system clock, we make sure we do not go
+ * before the UNIX epoch (1970-01-01). It's probably not possible
+ * to do this to the clock on most systems, but there are other
+ * ways to tweak the build stamp.
+ */
+ jd.monthday -= 1;
+ ed = ntpcal_date_to_rd(&jd) - DAY_NTP_STARTS;
+ return (ed < NTP_TO_UNIX_DAYS) ? NTP_TO_UNIX_DAYS : ed;
+}
+
+int32_t
+basedate_eval_string(
+ const char * str
+ )
+{
+ u_short y,m,d;
+ u_long ned;
+ int rc, nc;
+ size_t sl;
+
+ sl = strlen(str);
+ rc = sscanf(str, "%4hu-%2hu-%2hu%n", &y, &m, &d, &nc);
+ if (rc == 3 && (size_t)nc == sl) {
+ if (m >= 1 && m <= 12 && d >= 1 && d <= 31)
+ return ntpcal_edate_to_eradays(y-1, m-1, d)
+ - DAY_NTP_STARTS;
+ goto buildstamp;
+ }
+
+ rc = sscanf(str, "%lu%n", &ned, &nc);
+ if (rc == 1 && (size_t)nc == sl) {
+ if (ned <= INT32_MAX)
+ return (int32_t)ned;
+ goto buildstamp;
+ }
+
+ buildstamp:
+ msyslog(LOG_WARNING,
+ "basedate string \"%s\" invalid, build date substituted!",
+ str);
+ return basedate_eval_buildstamp();
+}
+
+uint32_t
+basedate_get_day(void)
+{
+ return s_baseday;
+}
+
+int32_t
+basedate_set_day(
+ int32_t day
+ )
+{
+ struct calendar jd;
+ int32_t retv;
+
+ /* set NTP base date for NTP era unfolding */
+ if (day < NTP_TO_UNIX_DAYS) {
+ msyslog(LOG_WARNING,
+ "baseday_set_day: invalid day (%lu), UNIX epoch substituted",
+ (unsigned long)day);
+ day = NTP_TO_UNIX_DAYS;
+ }
+ retv = s_baseday;
+ s_baseday = day;
+ ntpcal_rd_to_date(&jd, day + DAY_NTP_STARTS);
+ msyslog(LOG_INFO, "basedate set to %04hu-%02hu-%02hu",
+ jd.year, (u_short)jd.month, (u_short)jd.monthday);
+
+ /* set GPS base week for GPS week unfolding */
+ day = ntpcal_weekday_ge(day + DAY_NTP_STARTS, CAL_SUNDAY)
+ - DAY_NTP_STARTS;
+ if (day < NTP_TO_GPS_DAYS)
+ day = NTP_TO_GPS_DAYS;
+ s_gpsweek = (day - NTP_TO_GPS_DAYS) / DAYSPERWEEK;
+ ntpcal_rd_to_date(&jd, day + DAY_NTP_STARTS);
+ msyslog(LOG_INFO, "gps base set to %04hu-%02hu-%02hu (week %d)",
+ jd.year, (u_short)jd.month, (u_short)jd.monthday, s_gpsweek);
+
+ return retv;
+}
+
+time_t
+basedate_get_eracenter(void)
+{
+ time_t retv;
+ retv = (time_t)(s_baseday - NTP_TO_UNIX_DAYS);
+ retv *= SECSPERDAY;
+ retv += (UINT32_C(1) << 31);
+ return retv;
+}
+
+time_t
+basedate_get_erabase(void)
+{
+ time_t retv;
+ retv = (time_t)(s_baseday - NTP_TO_UNIX_DAYS);
+ retv *= SECSPERDAY;
+ return retv;
+}
+
+uint32_t
+basedate_get_gpsweek(void)
+{
+ return s_gpsweek;
+}
+
+uint32_t
+basedate_expand_gpsweek(
+ unsigned short weekno
+ )
+{
+ /* We do a fast modulus expansion here. Since all quantities are
+ * unsigned and we cannot go before the start of the GPS epoch
+ * anyway, and since the truncated GPS week number is 10 bit, the
+ * expansion becomes a simple sub/and/add sequence.
+ */
+ #if GPSWEEKS != 1024
+ # error GPSWEEKS defined wrong -- should be 1024!
+ #endif
+
+ uint32_t diff;
+ diff = ((uint32_t)weekno - s_gpsweek) & (GPSWEEKS - 1);
+ return s_gpsweek + diff;
+}
+
+/* -*-EOF-*- */
diff --git a/sebhbsd/freebsd/contrib/ntp/libntp/ntp_intres.c b/sebhbsd/freebsd/contrib/ntp/libntp/ntp_intres.c
new file mode 100644
index 0000000..ec9aa55
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/libntp/ntp_intres.c
@@ -0,0 +1,1156 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * ntp_intres.c - Implements a generic blocking worker child or thread,
+ * initially to provide a nonblocking solution for DNS
+ * name to address lookups available with getaddrinfo().
+ *
+ * This is a new implementation as of 2009 sharing the filename and
+ * very little else with the prior implementation, which used a
+ * temporary file to receive a single set of requests from the parent,
+ * and a NTP mode 7 authenticated request to push back responses.
+ *
+ * A primary goal in rewriting this code was the need to support the
+ * pool configuration directive's requirement to retrieve multiple
+ * addresses resolving a single name, which has previously been
+ * satisfied with blocking resolver calls from the ntpd mainline code.
+ *
+ * A secondary goal is to provide a generic mechanism for other
+ * blocking operations to be delegated to a worker using a common
+ * model for both Unix and Windows ntpd. ntp_worker.c, work_fork.c,
+ * and work_thread.c implement the generic mechanism. This file
+ * implements the two current consumers, getaddrinfo_sometime() and the
+ * presently unused getnameinfo_sometime().
+ *
+ * Both routines deliver results to a callback and manage memory
+ * allocation, meaning there is no freeaddrinfo_sometime().
+ *
+ * The initial implementation for Unix uses a pair of unidirectional
+ * pipes, one each for requests and responses, connecting the forked
+ * blocking child worker with the ntpd mainline. The threaded code
+ * uses arrays of pointers to queue requests and responses.
+ *
+ * The parent drives the process, including scheduling sleeps between
+ * retries.
+ *
+ * Memory is managed differently for a child process, which mallocs
+ * request buffers to read from the pipe into, whereas the threaded
+ * code mallocs a copy of the request to hand off to the worker via
+ * the queueing array. The resulting request buffer is free()d by
+ * platform-independent code. A wrinkle is the request needs to be
+ * available to the requestor during response processing.
+ *
+ * Response memory allocation is also platform-dependent. With a
+ * separate process and pipes, the response is free()d after being
+ * written to the pipe. With threads, the same memory is handed
+ * over and the requestor frees it after processing is completed.
+ *
+ * The code should be generalized to support threads on Unix using
+ * much of the same code used for Windows initially.
+ *
+ */
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "ntp_workimpl.h"
+
+#ifdef WORKER
+
+#include <stdio.h>
+#include <ctype.h>
+#include <signal.h>
+
+/**/
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#include <arpa/inet.h>
+/**/
+#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif
+
+#if !defined(HAVE_RES_INIT) && defined(HAVE___RES_INIT)
+# define HAVE_RES_INIT
+#endif
+
+#if defined(HAVE_RESOLV_H) && defined(HAVE_RES_INIT)
+# ifdef HAVE_ARPA_NAMESER_H
+# include <arpa/nameser.h> /* DNS HEADER struct */
+# endif
+# ifdef HAVE_NETDB_H
+# include <netdb.h>
+# endif
+# include <resolv.h>
+# ifdef HAVE_INT32_ONLY_WITH_DNS
+# define HAVE_INT32
+# endif
+# ifdef HAVE_U_INT32_ONLY_WITH_DNS
+# define HAVE_U_INT32
+# endif
+#endif
+
+#include "ntp.h"
+#include "ntp_debug.h"
+#include "ntp_malloc.h"
+#include "ntp_syslog.h"
+#include "ntp_unixtime.h"
+#include "ntp_intres.h"
+#include "intreswork.h"
+
+
+/*
+ * Following are implementations of getaddrinfo_sometime() and
+ * getnameinfo_sometime(). Each is implemented in three routines:
+ *
+ * getaddrinfo_sometime() getnameinfo_sometime()
+ * blocking_getaddrinfo() blocking_getnameinfo()
+ * getaddrinfo_sometime_complete() getnameinfo_sometime_complete()
+ *
+ * The first runs in the parent and marshalls (or serializes) request
+ * parameters into a request blob which is processed in the child by
+ * the second routine, blocking_*(), which serializes the results into
+ * a response blob unpacked by the third routine, *_complete(), which
+ * calls the callback routine provided with the request and frees
+ * _request_ memory allocated by the first routine. Response memory
+ * is managed by the code which calls the *_complete routines.
+ */
+
+
+/* === typedefs === */
+typedef struct blocking_gai_req_tag { /* marshalled args */
+ size_t octets;
+ u_int dns_idx;
+ time_t scheduled;
+ time_t earliest;
+ int retry;
+ struct addrinfo hints;
+ u_int qflags;
+ gai_sometime_callback callback;
+ void * context;
+ size_t nodesize;
+ size_t servsize;
+} blocking_gai_req;
+
+typedef struct blocking_gai_resp_tag {
+ size_t octets;
+ int retcode;
+ int retry;
+ int gai_errno; /* for EAI_SYSTEM case */
+ int ai_count;
+ /*
+ * Followed by ai_count struct addrinfo and then ai_count
+ * sockaddr_u and finally the canonical name strings.
+ */
+} blocking_gai_resp;
+
+typedef struct blocking_gni_req_tag {
+ size_t octets;
+ u_int dns_idx;
+ time_t scheduled;
+ time_t earliest;
+ int retry;
+ size_t hostoctets;
+ size_t servoctets;
+ int flags;
+ gni_sometime_callback callback;
+ void * context;
+ sockaddr_u socku;
+} blocking_gni_req;
+
+typedef struct blocking_gni_resp_tag {
+ size_t octets;
+ int retcode;
+ int gni_errno; /* for EAI_SYSTEM case */
+ int retry;
+ size_t hostoctets;
+ size_t servoctets;
+ /*
+ * Followed by hostoctets bytes of null-terminated host,
+ * then servoctets bytes of null-terminated service.
+ */
+} blocking_gni_resp;
+
+/* per-DNS-worker state in parent */
+typedef struct dnschild_ctx_tag {
+ u_int index;
+ time_t next_dns_timeslot;
+} dnschild_ctx;
+
+/* per-DNS-worker state in worker */
+typedef struct dnsworker_ctx_tag {
+ blocking_child * c;
+ time_t ignore_scheduled_before;
+#ifdef HAVE_RES_INIT
+ time_t next_res_init;
+#endif
+} dnsworker_ctx;
+
+
+/* === variables === */
+dnschild_ctx ** dnschild_contexts; /* parent */
+u_int dnschild_contexts_alloc;
+dnsworker_ctx ** dnsworker_contexts; /* child */
+u_int dnsworker_contexts_alloc;
+
+#ifdef HAVE_RES_INIT
+static time_t next_res_init;
+#endif
+
+
+/* === forward declarations === */
+static u_int reserve_dnschild_ctx(void);
+static u_int get_dnschild_ctx(void);
+static dnsworker_ctx * get_worker_context(blocking_child *, u_int);
+static void scheduled_sleep(time_t, time_t,
+ dnsworker_ctx *);
+static void manage_dns_retry_interval(time_t *, time_t *,
+ int *, time_t *,
+ int/*BOOL*/);
+static int should_retry_dns(int, int);
+#ifdef HAVE_RES_INIT
+static void reload_resolv_conf(dnsworker_ctx *);
+#else
+# define reload_resolv_conf(wc) \
+ do { \
+ (void)(wc); \
+ } while (FALSE)
+#endif
+static void getaddrinfo_sometime_complete(blocking_work_req,
+ void *, size_t,
+ void *);
+static void getnameinfo_sometime_complete(blocking_work_req,
+ void *, size_t,
+ void *);
+
+
+/* === functions === */
+/*
+ * getaddrinfo_sometime - uses blocking child to call getaddrinfo then
+ * invokes provided callback completion function.
+ */
+int
+getaddrinfo_sometime_ex(
+ const char * node,
+ const char * service,
+ const struct addrinfo * hints,
+ int retry,
+ gai_sometime_callback callback,
+ void * context,
+ u_int qflags
+ )
+{
+ blocking_gai_req * gai_req;
+ u_int idx;
+ dnschild_ctx * child_ctx;
+ size_t req_size;
+ size_t nodesize;
+ size_t servsize;
+ time_t now;
+
+ REQUIRE(NULL != node);
+ if (NULL != hints) {
+ REQUIRE(0 == hints->ai_addrlen);
+ REQUIRE(NULL == hints->ai_addr);
+ REQUIRE(NULL == hints->ai_canonname);
+ REQUIRE(NULL == hints->ai_next);
+ }
+
+ idx = get_dnschild_ctx();
+ child_ctx = dnschild_contexts[idx];
+
+ nodesize = strlen(node) + 1;
+ servsize = strlen(service) + 1;
+ req_size = sizeof(*gai_req) + nodesize + servsize;
+
+ gai_req = emalloc_zero(req_size);
+
+ gai_req->octets = req_size;
+ gai_req->dns_idx = idx;
+ now = time(NULL);
+ gai_req->scheduled = now;
+ gai_req->earliest = max(now, child_ctx->next_dns_timeslot);
+ child_ctx->next_dns_timeslot = gai_req->earliest;
+ if (hints != NULL)
+ gai_req->hints = *hints;
+ gai_req->retry = retry;
+ gai_req->callback = callback;
+ gai_req->context = context;
+ gai_req->nodesize = nodesize;
+ gai_req->servsize = servsize;
+ gai_req->qflags = qflags;
+
+ memcpy((char *)gai_req + sizeof(*gai_req), node, nodesize);
+ memcpy((char *)gai_req + sizeof(*gai_req) + nodesize, service,
+ servsize);
+
+ if (queue_blocking_request(
+ BLOCKING_GETADDRINFO,
+ gai_req,
+ req_size,
+ &getaddrinfo_sometime_complete,
+ gai_req)) {
+
+ msyslog(LOG_ERR, "unable to queue getaddrinfo request");
+ errno = EFAULT;
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+blocking_getaddrinfo(
+ blocking_child * c,
+ blocking_pipe_header * req
+ )
+{
+ blocking_gai_req * gai_req;
+ dnsworker_ctx * worker_ctx;
+ blocking_pipe_header * resp;
+ blocking_gai_resp * gai_resp;
+ char * node;
+ char * service;
+ struct addrinfo * ai_res;
+ struct addrinfo * ai;
+ struct addrinfo * serialized_ai;
+ size_t canons_octets;
+ size_t this_octets;
+ size_t resp_octets;
+ char * cp;
+ time_t time_now;
+
+ gai_req = (void *)((char *)req + sizeof(*req));
+ node = (char *)gai_req + sizeof(*gai_req);
+ service = node + gai_req->nodesize;
+
+ worker_ctx = get_worker_context(c, gai_req->dns_idx);
+ scheduled_sleep(gai_req->scheduled, gai_req->earliest,
+ worker_ctx);
+ reload_resolv_conf(worker_ctx);
+
+ /*
+ * Take a shot at the final size, better to overestimate
+ * at first and then realloc to a smaller size.
+ */
+
+ resp_octets = sizeof(*resp) + sizeof(*gai_resp) +
+ 16 * (sizeof(struct addrinfo) +
+ sizeof(sockaddr_u)) +
+ 256;
+ resp = emalloc_zero(resp_octets);
+ gai_resp = (void *)(resp + 1);
+
+ TRACE(2, ("blocking_getaddrinfo given node %s serv %s fam %d flags %x\n",
+ node, service, gai_req->hints.ai_family,
+ gai_req->hints.ai_flags));
+#ifdef DEBUG
+ if (debug >= 2)
+ fflush(stdout);
+#endif
+ ai_res = NULL;
+ gai_resp->retcode = getaddrinfo(node, service, &gai_req->hints,
+ &ai_res);
+ gai_resp->retry = gai_req->retry;
+#ifdef EAI_SYSTEM
+ if (EAI_SYSTEM == gai_resp->retcode)
+ gai_resp->gai_errno = errno;
+#endif
+ canons_octets = 0;
+
+ if (0 == gai_resp->retcode) {
+ ai = ai_res;
+ while (NULL != ai) {
+ gai_resp->ai_count++;
+ if (ai->ai_canonname)
+ canons_octets += strlen(ai->ai_canonname) + 1;
+ ai = ai->ai_next;
+ }
+ /*
+ * If this query succeeded only after retrying, DNS may have
+ * just become responsive. Ignore previously-scheduled
+ * retry sleeps once for each pending request, similar to
+ * the way scheduled_sleep() does when its worker_sleep()
+ * is interrupted.
+ */
+ if (gai_resp->retry > INITIAL_DNS_RETRY) {
+ time_now = time(NULL);
+ worker_ctx->ignore_scheduled_before = time_now;
+ TRACE(1, ("DNS success after retry, ignoring sleeps scheduled before now (%s)\n",
+ humantime(time_now)));
+ }
+ }
+
+ /*
+ * Our response consists of a header, followed by ai_count
+ * addrinfo structs followed by ai_count sockaddr_storage
+ * structs followed by the canonical names.
+ */
+ gai_resp->octets = sizeof(*gai_resp)
+ + gai_resp->ai_count
+ * (sizeof(gai_req->hints)
+ + sizeof(sockaddr_u))
+ + canons_octets;
+
+ resp_octets = sizeof(*resp) + gai_resp->octets;
+ resp = erealloc(resp, resp_octets);
+ gai_resp = (void *)(resp + 1);
+
+ /* cp serves as our current pointer while serializing */
+ cp = (void *)(gai_resp + 1);
+ canons_octets = 0;
+
+ if (0 == gai_resp->retcode) {
+ ai = ai_res;
+ while (NULL != ai) {
+ memcpy(cp, ai, sizeof(*ai));
+ serialized_ai = (void *)cp;
+ cp += sizeof(*ai);
+
+ /* transform ai_canonname into offset */
+ if (NULL != ai->ai_canonname) {
+ serialized_ai->ai_canonname = (char *)canons_octets;
+ canons_octets += strlen(ai->ai_canonname) + 1;
+ }
+
+ /* leave fixup of ai_addr pointer for receiver */
+
+ ai = ai->ai_next;
+ }
+
+ ai = ai_res;
+ while (NULL != ai) {
+ INSIST(ai->ai_addrlen <= sizeof(sockaddr_u));
+ memcpy(cp, ai->ai_addr, ai->ai_addrlen);
+ cp += sizeof(sockaddr_u);
+
+ ai = ai->ai_next;
+ }
+
+ ai = ai_res;
+ while (NULL != ai) {
+ if (NULL != ai->ai_canonname) {
+ this_octets = strlen(ai->ai_canonname) + 1;
+ memcpy(cp, ai->ai_canonname, this_octets);
+ cp += this_octets;
+ }
+
+ ai = ai->ai_next;
+ }
+ freeaddrinfo(ai_res);
+ }
+
+ /*
+ * make sure our walk and earlier calc match
+ */
+ DEBUG_INSIST((size_t)(cp - (char *)resp) == resp_octets);
+
+ if (queue_blocking_response(c, resp, resp_octets, req)) {
+ msyslog(LOG_ERR, "blocking_getaddrinfo can not queue response");
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+getaddrinfo_sometime(
+ const char * node,
+ const char * service,
+ const struct addrinfo * hints,
+ int retry,
+ gai_sometime_callback callback,
+ void * context
+ )
+{
+ return getaddrinfo_sometime_ex(node, service, hints, retry,
+ callback, context, 0);
+}
+
+
+static void
+getaddrinfo_sometime_complete(
+ blocking_work_req rtype,
+ void * context,
+ size_t respsize,
+ void * resp
+ )
+{
+ blocking_gai_req * gai_req;
+ blocking_gai_resp * gai_resp;
+ dnschild_ctx * child_ctx;
+ struct addrinfo * ai;
+ struct addrinfo * next_ai;
+ sockaddr_u * psau;
+ char * node;
+ char * service;
+ char * canon_start;
+ time_t time_now;
+ int again, noerr;
+ int af;
+ const char * fam_spec;
+ int i;
+
+ gai_req = context;
+ gai_resp = resp;
+
+ DEBUG_REQUIRE(BLOCKING_GETADDRINFO == rtype);
+ DEBUG_REQUIRE(respsize == gai_resp->octets);
+
+ node = (char *)gai_req + sizeof(*gai_req);
+ service = node + gai_req->nodesize;
+
+ child_ctx = dnschild_contexts[gai_req->dns_idx];
+
+ if (0 == gai_resp->retcode) {
+ /*
+ * If this query succeeded only after retrying, DNS may have
+ * just become responsive.
+ */
+ if (gai_resp->retry > INITIAL_DNS_RETRY) {
+ time_now = time(NULL);
+ child_ctx->next_dns_timeslot = time_now;
+ TRACE(1, ("DNS success after retry, %u next_dns_timeslot reset (%s)\n",
+ gai_req->dns_idx, humantime(time_now)));
+ }
+ } else {
+ noerr = !!(gai_req->qflags & GAIR_F_IGNDNSERR);
+ again = noerr || should_retry_dns(
+ gai_resp->retcode, gai_resp->gai_errno);
+ /*
+ * exponential backoff of DNS retries to 64s
+ */
+ if (gai_req->retry > 0 && again) {
+ /* log the first retry only */
+ if (INITIAL_DNS_RETRY == gai_req->retry)
+ NLOG(NLOG_SYSINFO) {
+ af = gai_req->hints.ai_family;
+ fam_spec = (AF_INET6 == af)
+ ? " (AAAA)"
+ : (AF_INET == af)
+ ? " (A)"
+ : "";
+#ifdef EAI_SYSTEM
+ if (EAI_SYSTEM == gai_resp->retcode) {
+ errno = gai_resp->gai_errno;
+ msyslog(LOG_INFO,
+ "retrying DNS %s%s: EAI_SYSTEM %d: %m",
+ node, fam_spec,
+ gai_resp->gai_errno);
+ } else
+#endif
+ msyslog(LOG_INFO,
+ "retrying DNS %s%s: %s (%d)",
+ node, fam_spec,
+ gai_strerror(gai_resp->retcode),
+ gai_resp->retcode);
+ }
+ manage_dns_retry_interval(
+ &gai_req->scheduled, &gai_req->earliest,
+ &gai_req->retry, &child_ctx->next_dns_timeslot,
+ noerr);
+ if (!queue_blocking_request(
+ BLOCKING_GETADDRINFO,
+ gai_req,
+ gai_req->octets,
+ &getaddrinfo_sometime_complete,
+ gai_req))
+ return;
+ else
+ msyslog(LOG_ERR,
+ "unable to retry hostname %s",
+ node);
+ }
+ }
+
+ /*
+ * fixup pointers in returned addrinfo array
+ */
+ ai = (void *)((char *)gai_resp + sizeof(*gai_resp));
+ next_ai = NULL;
+ for (i = gai_resp->ai_count - 1; i >= 0; i--) {
+ ai[i].ai_next = next_ai;
+ next_ai = &ai[i];
+ }
+
+ psau = (void *)((char *)ai + gai_resp->ai_count * sizeof(*ai));
+ canon_start = (char *)psau + gai_resp->ai_count * sizeof(*psau);
+
+ for (i = 0; i < gai_resp->ai_count; i++) {
+ if (NULL != ai[i].ai_addr)
+ ai[i].ai_addr = &psau->sa;
+ psau++;
+ if (NULL != ai[i].ai_canonname)
+ ai[i].ai_canonname += (size_t)canon_start;
+ }
+
+ ENSURE((char *)psau == canon_start);
+
+ if (!gai_resp->ai_count)
+ ai = NULL;
+
+ (*gai_req->callback)(gai_resp->retcode, gai_resp->gai_errno,
+ gai_req->context, node, service,
+ &gai_req->hints, ai);
+
+ free(gai_req);
+ /* gai_resp is part of block freed by process_blocking_resp() */
+}
+
+
+#ifdef TEST_BLOCKING_WORKER
+void gai_test_callback(int rescode, int gai_errno, void *context, const char *name, const char *service, const struct addrinfo *hints, const struct addrinfo *ai_res)
+{
+ sockaddr_u addr;
+
+ if (rescode) {
+ TRACE(1, ("gai_test_callback context %p error rescode %d %s serv %s\n",
+ context, rescode, name, service));
+ return;
+ }
+ while (!rescode && NULL != ai_res) {
+ ZERO_SOCK(&addr);
+ memcpy(&addr, ai_res->ai_addr, ai_res->ai_addrlen);
+ TRACE(1, ("ctx %p fam %d addr %s canon '%s' type %s at %p ai_addr %p ai_next %p\n",
+ context,
+ AF(&addr),
+ stoa(&addr),
+ (ai_res->ai_canonname)
+ ? ai_res->ai_canonname
+ : "",
+ (SOCK_DGRAM == ai_res->ai_socktype)
+ ? "DGRAM"
+ : (SOCK_STREAM == ai_res->ai_socktype)
+ ? "STREAM"
+ : "(other)",
+ ai_res,
+ ai_res->ai_addr,
+ ai_res->ai_next));
+
+ getnameinfo_sometime((sockaddr_u *)ai_res->ai_addr, 128, 32, 0, gni_test_callback, context);
+
+ ai_res = ai_res->ai_next;
+ }
+}
+#endif /* TEST_BLOCKING_WORKER */
+
+
+int
+getnameinfo_sometime(
+ sockaddr_u * psau,
+ size_t hostoctets,
+ size_t servoctets,
+ int flags,
+ gni_sometime_callback callback,
+ void * context
+ )
+{
+ blocking_gni_req * gni_req;
+ u_int idx;
+ dnschild_ctx * child_ctx;
+ time_t time_now;
+
+ REQUIRE(hostoctets);
+ REQUIRE(hostoctets + servoctets < 1024);
+
+ idx = get_dnschild_ctx();
+ child_ctx = dnschild_contexts[idx];
+
+ gni_req = emalloc_zero(sizeof(*gni_req));
+
+ gni_req->octets = sizeof(*gni_req);
+ gni_req->dns_idx = idx;
+ time_now = time(NULL);
+ gni_req->scheduled = time_now;
+ gni_req->earliest = max(time_now, child_ctx->next_dns_timeslot);
+ child_ctx->next_dns_timeslot = gni_req->earliest;
+ memcpy(&gni_req->socku, psau, SOCKLEN(psau));
+ gni_req->hostoctets = hostoctets;
+ gni_req->servoctets = servoctets;
+ gni_req->flags = flags;
+ gni_req->retry = INITIAL_DNS_RETRY;
+ gni_req->callback = callback;
+ gni_req->context = context;
+
+ if (queue_blocking_request(
+ BLOCKING_GETNAMEINFO,
+ gni_req,
+ sizeof(*gni_req),
+ &getnameinfo_sometime_complete,
+ gni_req)) {
+
+ msyslog(LOG_ERR, "unable to queue getnameinfo request");
+ errno = EFAULT;
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int
+blocking_getnameinfo(
+ blocking_child * c,
+ blocking_pipe_header * req
+ )
+{
+ blocking_gni_req * gni_req;
+ dnsworker_ctx * worker_ctx;
+ blocking_pipe_header * resp;
+ blocking_gni_resp * gni_resp;
+ size_t octets;
+ size_t resp_octets;
+ char * service;
+ char * cp;
+ int rc;
+ time_t time_now;
+ char host[1024];
+
+ gni_req = (void *)((char *)req + sizeof(*req));
+
+ octets = gni_req->hostoctets + gni_req->servoctets;
+
+ /*
+ * Some alloca() implementations are fragile regarding
+ * large allocations. We only need room for the host
+ * and service names.
+ */
+ REQUIRE(octets < sizeof(host));
+ service = host + gni_req->hostoctets;
+
+ worker_ctx = get_worker_context(c, gni_req->dns_idx);
+ scheduled_sleep(gni_req->scheduled, gni_req->earliest,
+ worker_ctx);
+ reload_resolv_conf(worker_ctx);
+
+ /*
+ * Take a shot at the final size, better to overestimate
+ * then realloc to a smaller size.
+ */
+
+ resp_octets = sizeof(*resp) + sizeof(*gni_resp) + octets;
+ resp = emalloc_zero(resp_octets);
+ gni_resp = (void *)((char *)resp + sizeof(*resp));
+
+ TRACE(2, ("blocking_getnameinfo given addr %s flags 0x%x hostlen %lu servlen %lu\n",
+ stoa(&gni_req->socku), gni_req->flags,
+ (u_long)gni_req->hostoctets, (u_long)gni_req->servoctets));
+
+ gni_resp->retcode = getnameinfo(&gni_req->socku.sa,
+ SOCKLEN(&gni_req->socku),
+ host,
+ gni_req->hostoctets,
+ service,
+ gni_req->servoctets,
+ gni_req->flags);
+ gni_resp->retry = gni_req->retry;
+#ifdef EAI_SYSTEM
+ if (EAI_SYSTEM == gni_resp->retcode)
+ gni_resp->gni_errno = errno;
+#endif
+
+ if (0 != gni_resp->retcode) {
+ gni_resp->hostoctets = 0;
+ gni_resp->servoctets = 0;
+ } else {
+ gni_resp->hostoctets = strlen(host) + 1;
+ gni_resp->servoctets = strlen(service) + 1;
+ /*
+ * If this query succeeded only after retrying, DNS may have
+ * just become responsive. Ignore previously-scheduled
+ * retry sleeps once for each pending request, similar to
+ * the way scheduled_sleep() does when its worker_sleep()
+ * is interrupted.
+ */
+ if (gni_req->retry > INITIAL_DNS_RETRY) {
+ time_now = time(NULL);
+ worker_ctx->ignore_scheduled_before = time_now;
+ TRACE(1, ("DNS success after retrying, ignoring sleeps scheduled before now (%s)\n",
+ humantime(time_now)));
+ }
+ }
+ octets = gni_resp->hostoctets + gni_resp->servoctets;
+ /*
+ * Our response consists of a header, followed by the host and
+ * service strings, each null-terminated.
+ */
+ resp_octets = sizeof(*resp) + sizeof(*gni_resp) + octets;
+
+ resp = erealloc(resp, resp_octets);
+ gni_resp = (void *)(resp + 1);
+
+ gni_resp->octets = sizeof(*gni_resp) + octets;
+
+ /* cp serves as our current pointer while serializing */
+ cp = (void *)(gni_resp + 1);
+
+ if (0 == gni_resp->retcode) {
+ memcpy(cp, host, gni_resp->hostoctets);
+ cp += gni_resp->hostoctets;
+ memcpy(cp, service, gni_resp->servoctets);
+ cp += gni_resp->servoctets;
+ }
+
+ INSIST((size_t)(cp - (char *)resp) == resp_octets);
+ INSIST(resp_octets - sizeof(*resp) == gni_resp->octets);
+
+ rc = queue_blocking_response(c, resp, resp_octets, req);
+ if (rc)
+ msyslog(LOG_ERR, "blocking_getnameinfo unable to queue response");
+ return rc;
+}
+
+
+static void
+getnameinfo_sometime_complete(
+ blocking_work_req rtype,
+ void * context,
+ size_t respsize,
+ void * resp
+ )
+{
+ blocking_gni_req * gni_req;
+ blocking_gni_resp * gni_resp;
+ dnschild_ctx * child_ctx;
+ char * host;
+ char * service;
+ time_t time_now;
+ int again;
+
+ gni_req = context;
+ gni_resp = resp;
+
+ DEBUG_REQUIRE(BLOCKING_GETNAMEINFO == rtype);
+ DEBUG_REQUIRE(respsize == gni_resp->octets);
+
+ child_ctx = dnschild_contexts[gni_req->dns_idx];
+
+ if (0 == gni_resp->retcode) {
+ /*
+ * If this query succeeded only after retrying, DNS may have
+ * just become responsive.
+ */
+ if (gni_resp->retry > INITIAL_DNS_RETRY) {
+ time_now = time(NULL);
+ child_ctx->next_dns_timeslot = time_now;
+ TRACE(1, ("DNS success after retry, %u next_dns_timeslot reset (%s)\n",
+ gni_req->dns_idx, humantime(time_now)));
+ }
+ } else {
+ again = should_retry_dns(gni_resp->retcode, gni_resp->gni_errno);
+ /*
+ * exponential backoff of DNS retries to 64s
+ */
+ if (gni_req->retry > 0)
+ manage_dns_retry_interval(&gni_req->scheduled,
+ &gni_req->earliest, &gni_req->retry,
+ &child_ctx->next_dns_timeslot, FALSE);
+
+ if (gni_req->retry > 0 && again) {
+ if (!queue_blocking_request(
+ BLOCKING_GETNAMEINFO,
+ gni_req,
+ gni_req->octets,
+ &getnameinfo_sometime_complete,
+ gni_req))
+ return;
+
+ msyslog(LOG_ERR, "unable to retry reverse lookup of %s", stoa(&gni_req->socku));
+ }
+ }
+
+ if (!gni_resp->hostoctets) {
+ host = NULL;
+ service = NULL;
+ } else {
+ host = (char *)gni_resp + sizeof(*gni_resp);
+ service = (gni_resp->servoctets)
+ ? host + gni_resp->hostoctets
+ : NULL;
+ }
+
+ (*gni_req->callback)(gni_resp->retcode, gni_resp->gni_errno,
+ &gni_req->socku, gni_req->flags, host,
+ service, gni_req->context);
+
+ free(gni_req);
+ /* gni_resp is part of block freed by process_blocking_resp() */
+}
+
+
+#ifdef TEST_BLOCKING_WORKER
+void gni_test_callback(int rescode, int gni_errno, sockaddr_u *psau, int flags, const char *host, const char *service, void *context)
+{
+ if (!rescode)
+ TRACE(1, ("gni_test_callback got host '%s' serv '%s' for addr %s context %p\n",
+ host, service, stoa(psau), context));
+ else
+ TRACE(1, ("gni_test_callback context %p rescode %d gni_errno %d flags 0x%x addr %s\n",
+ context, rescode, gni_errno, flags, stoa(psau)));
+}
+#endif /* TEST_BLOCKING_WORKER */
+
+
+#ifdef HAVE_RES_INIT
+static void
+reload_resolv_conf(
+ dnsworker_ctx * worker_ctx
+ )
+{
+ time_t time_now;
+
+ /*
+ * This is ad-hoc. Reload /etc/resolv.conf once per minute
+ * to pick up on changes from the DHCP client. [Bug 1226]
+ * When using threads for the workers, this needs to happen
+ * only once per minute process-wide.
+ */
+ time_now = time(NULL);
+# ifdef WORK_THREAD
+ worker_ctx->next_res_init = next_res_init;
+# endif
+ if (worker_ctx->next_res_init <= time_now) {
+ if (worker_ctx->next_res_init != 0)
+ res_init();
+ worker_ctx->next_res_init = time_now + 60;
+# ifdef WORK_THREAD
+ next_res_init = worker_ctx->next_res_init;
+# endif
+ }
+}
+#endif /* HAVE_RES_INIT */
+
+
+static u_int
+reserve_dnschild_ctx(void)
+{
+ const size_t ps = sizeof(dnschild_contexts[0]);
+ const size_t cs = sizeof(*dnschild_contexts[0]);
+ u_int c;
+ u_int new_alloc;
+ size_t octets;
+ size_t new_octets;
+
+ c = 0;
+ while (TRUE) {
+ for ( ; c < dnschild_contexts_alloc; c++) {
+ if (NULL == dnschild_contexts[c]) {
+ dnschild_contexts[c] = emalloc_zero(cs);
+
+ return c;
+ }
+ }
+ new_alloc = dnschild_contexts_alloc + 20;
+ new_octets = new_alloc * ps;
+ octets = dnschild_contexts_alloc * ps;
+ dnschild_contexts = erealloc_zero(dnschild_contexts,
+ new_octets, octets);
+ dnschild_contexts_alloc = new_alloc;
+ }
+}
+
+
+static u_int
+get_dnschild_ctx(void)
+{
+ static u_int shared_ctx = UINT_MAX;
+
+ if (worker_per_query)
+ return reserve_dnschild_ctx();
+
+ if (UINT_MAX == shared_ctx)
+ shared_ctx = reserve_dnschild_ctx();
+
+ return shared_ctx;
+}
+
+
+static dnsworker_ctx *
+get_worker_context(
+ blocking_child * c,
+ u_int idx
+ )
+{
+ u_int min_new_alloc;
+ u_int new_alloc;
+ size_t octets;
+ size_t new_octets;
+ dnsworker_ctx * retv;
+
+ worker_global_lock(TRUE);
+
+ if (dnsworker_contexts_alloc <= idx) {
+ min_new_alloc = 1 + idx;
+ /* round new_alloc up to nearest multiple of 4 */
+ new_alloc = (min_new_alloc + 4) & ~(4 - 1);
+ new_octets = new_alloc * sizeof(dnsworker_ctx*);
+ octets = dnsworker_contexts_alloc * sizeof(dnsworker_ctx*);
+ dnsworker_contexts = erealloc_zero(dnsworker_contexts,
+ new_octets, octets);
+ dnsworker_contexts_alloc = new_alloc;
+ retv = emalloc_zero(sizeof(dnsworker_ctx));
+ dnsworker_contexts[idx] = retv;
+ } else if (NULL == (retv = dnsworker_contexts[idx])) {
+ retv = emalloc_zero(sizeof(dnsworker_ctx));
+ dnsworker_contexts[idx] = retv;
+ }
+
+ worker_global_lock(FALSE);
+
+ ZERO(*retv);
+ retv->c = c;
+ return retv;
+}
+
+
+static void
+scheduled_sleep(
+ time_t scheduled,
+ time_t earliest,
+ dnsworker_ctx * worker_ctx
+ )
+{
+ time_t now;
+
+ if (scheduled < worker_ctx->ignore_scheduled_before) {
+ TRACE(1, ("ignoring sleep until %s scheduled at %s (before %s)\n",
+ humantime(earliest), humantime(scheduled),
+ humantime(worker_ctx->ignore_scheduled_before)));
+ return;
+ }
+
+ now = time(NULL);
+
+ if (now < earliest) {
+ TRACE(1, ("sleep until %s scheduled at %s (>= %s)\n",
+ humantime(earliest), humantime(scheduled),
+ humantime(worker_ctx->ignore_scheduled_before)));
+ if (-1 == worker_sleep(worker_ctx->c, earliest - now)) {
+ /* our sleep was interrupted */
+ now = time(NULL);
+ worker_ctx->ignore_scheduled_before = now;
+#ifdef HAVE_RES_INIT
+ worker_ctx->next_res_init = now + 60;
+ next_res_init = worker_ctx->next_res_init;
+ res_init();
+#endif
+ TRACE(1, ("sleep interrupted by daemon, ignoring sleeps scheduled before now (%s)\n",
+ humantime(worker_ctx->ignore_scheduled_before)));
+ }
+ }
+}
+
+
+/*
+ * manage_dns_retry_interval is a helper used by
+ * getaddrinfo_sometime_complete and getnameinfo_sometime_complete
+ * to calculate the new retry interval and schedule the next query.
+ */
+static void
+manage_dns_retry_interval(
+ time_t * pscheduled,
+ time_t * pwhen,
+ int * pretry,
+ time_t * pnext_timeslot,
+ int forever
+ )
+{
+ time_t now;
+ time_t when;
+ int retry;
+ int retmax;
+
+ now = time(NULL);
+ retry = *pretry;
+ when = max(now + retry, *pnext_timeslot);
+ *pnext_timeslot = when;
+
+ /* this exponential backoff is slower than doubling up: The
+ * sequence goes 2-3-4-6-8-12-16-24-32... and the upper limit is
+ * 64 seconds for things that should not repeat forever, and
+ * 1024 when repeated forever.
+ */
+ retmax = forever ? 1024 : 64;
+ retry <<= 1;
+ if (retry & (retry - 1))
+ retry &= (retry - 1);
+ else
+ retry -= (retry >> 2);
+ retry = min(retmax, retry);
+
+ *pscheduled = now;
+ *pwhen = when;
+ *pretry = retry;
+}
+
+/*
+ * should_retry_dns is a helper used by getaddrinfo_sometime_complete
+ * and getnameinfo_sometime_complete which implements ntpd's DNS retry
+ * policy.
+ */
+static int
+should_retry_dns(
+ int rescode,
+ int res_errno
+ )
+{
+ static int eai_again_seen;
+ int again;
+#if defined (EAI_SYSTEM) && defined(DEBUG)
+ char msg[256];
+#endif
+
+ /*
+ * If the resolver failed, see if the failure is
+ * temporary. If so, return success.
+ */
+ again = 0;
+
+ switch (rescode) {
+
+ case EAI_FAIL:
+ again = 1;
+ break;
+
+ case EAI_AGAIN:
+ again = 1;
+ eai_again_seen = 1; /* [Bug 1178] */
+ break;
+
+ case EAI_NONAME:
+#if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME)
+ case EAI_NODATA:
+#endif
+ again = !eai_again_seen; /* [Bug 1178] */
+ break;
+
+#ifdef EAI_SYSTEM
+ case EAI_SYSTEM:
+ /*
+ * EAI_SYSTEM means the real error is in errno. We should be more
+ * discriminating about which errno values require retrying, but
+ * this matches existing behavior.
+ */
+ again = 1;
+# ifdef DEBUG
+ errno_to_str(res_errno, msg, sizeof(msg));
+ TRACE(1, ("intres: EAI_SYSTEM errno %d (%s) means try again, right?\n",
+ res_errno, msg));
+# endif
+ break;
+#endif
+ }
+
+ TRACE(2, ("intres: resolver returned: %s (%d), %sretrying\n",
+ gai_strerror(rescode), rescode, again ? "" : "not "));
+
+ return again;
+}
+
+#else /* !WORKER follows */
+int ntp_intres_nonempty_compilation_unit;
+#endif
diff --git a/sebhbsd/freebsd/contrib/ntp/libntp/ntp_libopts.c b/sebhbsd/freebsd/contrib/ntp/libntp/ntp_libopts.c
new file mode 100644
index 0000000..4669603
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/libntp/ntp_libopts.c
@@ -0,0 +1,60 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * ntp_libopts.c
+ *
+ * Common code interfacing with Autogen's libopts command-line option
+ * processing.
+ */
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stddef.h>
+#include "ntp_libopts.h"
+#include "ntp_stdlib.h"
+
+extern const char *Version; /* version.c for each program */
+
+
+/*
+ * ntpOptionProcess() was a clone of libopts' optionProcess which
+ * overrode the --version output, appending detail from version.c
+ * which was not available at Autogen time. This is now done via
+ * AutoOpts' version-proc = override in copyright.def, so this
+ * routine is a straightforward wrapper of optionProcess().
+ */
+int
+ntpOptionProcess(
+ tOptions * pOpts,
+ int argc,
+ char ** argv
+ )
+{
+ return optionProcess(pOpts, argc, argv);
+}
+
+
+/*
+ * ntpOptionPrintVersion() replaces the stock optionPrintVersion() via
+ * version-proc = ntpOptionPrintVersion; in copyright.def. It differs
+ * from the stock function by displaying the complete version string,
+ * including compile time which was unknown when Autogen ran.
+ *
+ * Like optionPrintVersion() this function must exit(0) rather than
+ * return.
+ */
+void
+ntpOptionPrintVersion(
+ tOptions * pOpts,
+ tOptDesc * pOD
+ )
+{
+ UNUSED_ARG(pOpts);
+ UNUSED_ARG(pOD);
+
+ printf("%s\n", Version);
+ fflush(stdout);
+ exit(EXIT_SUCCESS);
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/libntp/ntp_random.c b/sebhbsd/freebsd/contrib/ntp/libntp/ntp_random.c
new file mode 100644
index 0000000..5ced3d9
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/libntp/ntp_random.c
@@ -0,0 +1,501 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/lib/libc/stdlib/random.c,v 1.4.2.2 1999/09/05 11:16:45 peter Exp $
+ *
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)random.c 8.2 (Berkeley) 5/19/95";
+#endif /* LIBC_SCCS and not lint */
+
+#include "config.h"
+#include <sys/types.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#include <stdio.h>
+
+#include <l_stdlib.h>
+#include <ntp_random.h>
+#include <ntp_unixtime.h>
+
+/*
+ * random.c:
+ *
+ * An improved random number generation package. In addition to the standard
+ * rand()/srand() like interface, this package also has a special state info
+ * interface. The initstate() routine is called with a seed, an array of
+ * bytes, and a count of how many bytes are being passed in; this array is
+ * then initialized to contain information for random number generation with
+ * that much state information. Good sizes for the amount of state
+ * information are 32, 64, 128, and 256 bytes. The state can be switched by
+ * calling the setstate() routine with the same array as was initiallized
+ * with initstate(). By default, the package runs with 128 bytes of state
+ * information and generates far better random numbers than a linear
+ * congruential generator. If the amount of state information is less than
+ * 32 bytes, a simple linear congruential R.N.G. is used.
+ *
+ * Internally, the state information is treated as an array of longs; the
+ * zeroeth element of the array is the type of R.N.G. being used (small
+ * integer); the remainder of the array is the state information for the
+ * R.N.G. Thus, 32 bytes of state information will give 7 longs worth of
+ * state information, which will allow a degree seven polynomial. (Note:
+ * the zeroeth word of state information also has some other information
+ * stored in it -- see setstate() for details).
+ *
+ * The random number generation technique is a linear feedback shift register
+ * approach, employing trinomials (since there are fewer terms to sum up that
+ * way). In this approach, the least significant bit of all the numbers in
+ * the state table will act as a linear feedback shift register, and will
+ * have period 2^deg - 1 (where deg is the degree of the polynomial being
+ * used, assuming that the polynomial is irreducible and primitive). The
+ * higher order bits will have longer periods, since their values are also
+ * influenced by pseudo-random carries out of the lower bits. The total
+ * period of the generator is approximately deg*(2**deg - 1); thus doubling
+ * the amount of state information has a vast influence on the period of the
+ * generator. Note: the deg*(2**deg - 1) is an approximation only good for
+ * large deg, when the period of the shift register is the dominant factor.
+ * With deg equal to seven, the period is actually much longer than the
+ * 7*(2**7 - 1) predicted by this formula.
+ *
+ * Modified 28 December 1994 by Jacob S. Rosenberg.
+ * The following changes have been made:
+ * All references to the type u_int have been changed to unsigned long.
+ * All references to type int have been changed to type long. Other
+ * cleanups have been made as well. A warning for both initstate and
+ * setstate has been inserted to the effect that on Sparc platforms
+ * the 'arg_state' variable must be forced to begin on word boundaries.
+ * This can be easily done by casting a long integer array to char *.
+ * The overall logic has been left STRICTLY alone. This software was
+ * tested on both a VAX and Sun SpacsStation with exactly the same
+ * results. The new version and the original give IDENTICAL results.
+ * The new version is somewhat faster than the original. As the
+ * documentation says: "By default, the package runs with 128 bytes of
+ * state information and generates far better random numbers than a linear
+ * congruential generator. If the amount of state information is less than
+ * 32 bytes, a simple linear congruential R.N.G. is used." For a buffer of
+ * 128 bytes, this new version runs about 19 percent faster and for a 16
+ * byte buffer it is about 5 percent faster.
+ */
+
+/*
+ * For each of the currently supported random number generators, we have a
+ * break value on the amount of state information (you need at least this
+ * many bytes of state info to support this random number generator), a degree
+ * for the polynomial (actually a trinomial) that the R.N.G. is based on, and
+ * the separation between the two lower order coefficients of the trinomial.
+ */
+#define TYPE_0 0 /* linear congruential */
+#define BREAK_0 8
+#define DEG_0 0
+#define SEP_0 0
+
+#define TYPE_1 1 /* x**7 + x**3 + 1 */
+#define BREAK_1 32
+#define DEG_1 7
+#define SEP_1 3
+
+#define TYPE_2 2 /* x**15 + x + 1 */
+#define BREAK_2 64
+#define DEG_2 15
+#define SEP_2 1
+
+#define TYPE_3 3 /* x**31 + x**3 + 1 */
+#define BREAK_3 128
+#define DEG_3 31
+#define SEP_3 3
+
+#define TYPE_4 4 /* x**63 + x + 1 */
+#define BREAK_4 256
+#define DEG_4 63
+#define SEP_4 1
+
+#define MAX_TYPES 5 /* max number of types above */
+
+/*
+ * Initially, everything is set up as if from:
+ *
+ * initstate(1, randtbl, 128);
+ *
+ * Note that this initialization takes advantage of the fact that srandom()
+ * advances the front and rear pointers 10*rand_deg times, and hence the
+ * rear pointer which starts at 0 will also end up at zero; thus the zeroeth
+ * element of the state information, which contains info about the current
+ * position of the rear pointer is just
+ *
+ * MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3.
+ */
+
+static unsigned long randtbl[DEG_3 + 1] = {
+ TYPE_3,
+#ifdef USE_WEAK_SEEDING
+/* Historic implementation compatibility */
+/* The random sequences do not vary much with the seed */
+ 0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342, 0xde3b81e0, 0xdf0a6fb5,
+ 0xf103bc02, 0x48f340fb, 0x7449e56b, 0xbeb1dbb0, 0xab5c5918, 0x946554fd,
+ 0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86, 0xda672e2a, 0x1588ca88,
+ 0xe369735d, 0x904f35f7, 0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc,
+ 0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b, 0xf5ad9d0e, 0x8999220b,
+ 0x27fb47b9,
+#else /* !USE_WEAK_SEEDING */
+ 0x991539b1, 0x16a5bce3, 0x6774a4cd, 0x3e01511e, 0x4e508aaa, 0x61048c05,
+ 0xf5500617, 0x846b7115, 0x6a19892c, 0x896a97af, 0xdb48f936, 0x14898454,
+ 0x37ffd106, 0xb58bff9c, 0x59e17104, 0xcf918a49, 0x09378c83, 0x52c7a471,
+ 0x8d293ea9, 0x1f4fc301, 0xc3db71be, 0x39b44e1c, 0xf8a44ef9, 0x4c8b80b1,
+ 0x19edc328, 0x87bf4bdd, 0xc9b240e5, 0xe9ee4b1b, 0x4382aee7, 0x535b6b41,
+ 0xf3bec5da
+#endif /* !USE_WEAK_SEEDING */
+};
+
+/*
+ * fptr and rptr are two pointers into the state info, a front and a rear
+ * pointer. These two pointers are always rand_sep places aparts, as they
+ * cycle cyclically through the state information. (Yes, this does mean we
+ * could get away with just one pointer, but the code for random() is more
+ * efficient this way). The pointers are left positioned as they would be
+ * from the call
+ *
+ * initstate(1, randtbl, 128);
+ *
+ * (The position of the rear pointer, rptr, is really 0 (as explained above
+ * in the initialization of randtbl) because the state table pointer is set
+ * to point to randtbl[1] (as explained below).
+ */
+static unsigned long *fptr = &randtbl[SEP_3 + 1];
+static unsigned long *rptr = &randtbl[1];
+
+/*
+ * The following things are the pointer to the state information table, the
+ * type of the current generator, the degree of the current polynomial being
+ * used, and the separation between the two pointers. Note that for efficiency
+ * of random(), we remember the first location of the state information, not
+ * the zeroeth. Hence it is valid to access state[-1], which is used to
+ * store the type of the R.N.G. Also, we remember the last location, since
+ * this is more efficient than indexing every time to find the address of
+ * the last element to see if the front and rear pointers have wrapped.
+ */
+static unsigned long *state = &randtbl[1];
+static long rand_type = TYPE_3;
+static long rand_deg = DEG_3;
+static long rand_sep = SEP_3;
+static unsigned long *end_ptr = &randtbl[DEG_3 + 1];
+
+static inline long good_rand (long);
+
+static inline long
+good_rand (
+ register long x
+ )
+{
+#ifdef USE_WEAK_SEEDING
+/*
+ * Historic implementation compatibility.
+ * The random sequences do not vary much with the seed,
+ * even with overflowing.
+ */
+ return (1103515245 * x + 12345);
+#else /* !USE_WEAK_SEEDING */
+/*
+ * Compute x = (7^5 * x) mod (2^31 - 1)
+ * wihout overflowing 31 bits:
+ * (2^31 - 1) = 127773 * (7^5) + 2836
+ * From "Random number generators: good ones are hard to find",
+ * Park and Miller, Communications of the ACM, vol. 31, no. 10,
+ * October 1988, p. 1195.
+ */
+ register long hi, lo;
+
+ hi = x / 127773;
+ lo = x % 127773;
+ x = 16807 * lo - 2836 * hi;
+ if (x <= 0)
+ x += 0x7fffffff;
+ return (x);
+#endif /* !USE_WEAK_SEEDING */
+}
+
+/*
+ * srandom:
+ *
+ * Initialize the random number generator based on the given seed. If the
+ * type is the trivial no-state-information type, just remember the seed.
+ * Otherwise, initializes state[] based on the given "seed" via a linear
+ * congruential generator. Then, the pointers are set to known locations
+ * that are exactly rand_sep places apart. Lastly, it cycles the state
+ * information a given number of times to get rid of any initial dependencies
+ * introduced by the L.C.R.N.G. Note that the initialization of randtbl[]
+ * for default usage relies on values produced by this routine.
+ */
+void
+ntp_srandom(
+ unsigned long x
+ )
+{
+ long i;
+
+ if (rand_type == TYPE_0) {
+ state[0] = x;
+ } else {
+ state[0] = x;
+ for (i = 1; i < rand_deg; i++)
+ state[i] = good_rand(state[i - 1]);
+ fptr = &state[rand_sep];
+ rptr = &state[0];
+ for (i = 0; i < 10 * rand_deg; i++)
+ x = ntp_random();
+ }
+
+ /* seed the likely faster (and poorer) rand() as well */
+ srand((u_int)x);
+}
+
+/*
+ * srandomdev:
+ *
+ * Many programs choose the seed value in a totally predictable manner.
+ * This often causes problems. We seed the generator using the much more
+ * secure urandom(4) interface. Note that this particular seeding
+ * procedure can generate states which are impossible to reproduce by
+ * calling srandom() with any value, since the succeeding terms in the
+ * state buffer are no longer derived from the LC algorithm applied to
+ * a fixed seed.
+ */
+#ifdef NEED_SRANDOMDEV
+void
+ntp_srandomdev( void )
+{
+ struct timeval tv;
+ unsigned long junk; /* Purposely used uninitialized */
+
+ GETTIMEOFDAY(&tv, NULL);
+ ntp_srandom(getpid() ^ tv.tv_sec ^ tv.tv_usec ^ junk);
+ return;
+}
+#endif
+
+
+/*
+ * ntp_initstate() and ntp_setstate() are unused in our codebase and
+ * trigger warnings due to casting to a more-strictly-aligned pointer
+ * on alignment-sensitive platforms. #ifdef them away to save noise,
+ * build time, and binary space, but retain the code in case we find a
+ * use.
+ */
+#ifdef COMPILE_UNUSED_FUNCTIONS
+/*
+ * Array versions of the above information to make code run faster --
+ * relies on fact that TYPE_i == i.
+ */
+#define MAX_TYPES 5 /* max number of types above */
+
+static long degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 };
+static long seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
+
+/*
+ * initstate:
+ *
+ * Initialize the state information in the given array of n bytes for future
+ * random number generation. Based on the number of bytes we are given, and
+ * the break values for the different R.N.G.'s, we choose the best (largest)
+ * one we can and set things up for it. srandom() is then called to
+ * initialize the state information.
+ *
+ * Note that on return from srandom(), we set state[-1] to be the type
+ * multiplexed with the current value of the rear pointer; this is so
+ * successive calls to initstate() won't lose this information and will be
+ * able to restart with setstate().
+ *
+ * Note: the first thing we do is save the current state, if any, just like
+ * setstate() so that it doesn't matter when initstate is called.
+ *
+ * Returns a pointer to the old state.
+ *
+ * Note: The Sparc platform requires that arg_state begin on a long
+ * word boundary; otherwise a bus error will occur. Even so, lint will
+ * complain about mis-alignment, but you should disregard these messages.
+ */
+char *
+ntp_initstate(
+ unsigned long seed, /* seed for R.N.G. */
+ char *arg_state, /* pointer to state array */
+ long n /* # bytes of state info */
+ )
+{
+ register char *ostate = (char *)(&state[-1]);
+ register long *long_arg_state = (long *) arg_state;
+
+ if (rand_type == TYPE_0)
+ state[-1] = rand_type;
+ else
+ state[-1] = MAX_TYPES * (rptr - state) + rand_type;
+ if (n < BREAK_0) {
+ (void)fprintf(stderr,
+ "random: not enough state (%ld bytes); ignored.\n", n);
+ return(0);
+ }
+ if (n < BREAK_1) {
+ rand_type = TYPE_0;
+ rand_deg = DEG_0;
+ rand_sep = SEP_0;
+ } else if (n < BREAK_2) {
+ rand_type = TYPE_1;
+ rand_deg = DEG_1;
+ rand_sep = SEP_1;
+ } else if (n < BREAK_3) {
+ rand_type = TYPE_2;
+ rand_deg = DEG_2;
+ rand_sep = SEP_2;
+ } else if (n < BREAK_4) {
+ rand_type = TYPE_3;
+ rand_deg = DEG_3;
+ rand_sep = SEP_3;
+ } else {
+ rand_type = TYPE_4;
+ rand_deg = DEG_4;
+ rand_sep = SEP_4;
+ }
+ state = (unsigned long *) (long_arg_state + 1); /* first location */
+ end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */
+ ntp_srandom(seed);
+ if (rand_type == TYPE_0)
+ long_arg_state[0] = rand_type;
+ else
+ long_arg_state[0] = MAX_TYPES * (rptr - state) + rand_type;
+ return(ostate);
+}
+
+/*
+ * setstate:
+ *
+ * Restore the state from the given state array.
+ *
+ * Note: it is important that we also remember the locations of the pointers
+ * in the current state information, and restore the locations of the pointers
+ * from the old state information. This is done by multiplexing the pointer
+ * location into the zeroeth word of the state information.
+ *
+ * Note that due to the order in which things are done, it is OK to call
+ * setstate() with the same state as the current state.
+ *
+ * Returns a pointer to the old state information.
+ *
+ * Note: The Sparc platform requires that arg_state begin on a long
+ * word boundary; otherwise a bus error will occur. Even so, lint will
+ * complain about mis-alignment, but you should disregard these messages.
+ */
+char *
+ntp_setstate(
+ char *arg_state /* pointer to state array */
+ )
+{
+ register unsigned long *new_state = (unsigned long *) arg_state;
+ register long type = new_state[0] % MAX_TYPES;
+ register long rear = new_state[0] / MAX_TYPES;
+ char *ostate = (char *)(&state[-1]);
+
+ if (rand_type == TYPE_0)
+ state[-1] = rand_type;
+ else
+ state[-1] = MAX_TYPES * (rptr - state) + rand_type;
+ switch(type) {
+ case TYPE_0:
+ case TYPE_1:
+ case TYPE_2:
+ case TYPE_3:
+ case TYPE_4:
+ rand_type = type;
+ rand_deg = degrees[type];
+ rand_sep = seps[type];
+ break;
+ default:
+ (void)fprintf(stderr,
+ "random: state info corrupted; not changed.\n");
+ }
+ state = (new_state + 1);
+ if (rand_type != TYPE_0) {
+ rptr = &state[rear];
+ fptr = &state[(rear + rand_sep) % rand_deg];
+ }
+ end_ptr = &state[rand_deg]; /* set end_ptr too */
+ return(ostate);
+}
+#endif /* COMPILE_UNUSED_FUNCTIONS */
+
+
+/*
+ * random:
+ *
+ * If we are using the trivial TYPE_0 R.N.G., just do the old linear
+ * congruential bit. Otherwise, we do our fancy trinomial stuff, which is
+ * the same in all the other cases due to all the global variables that have
+ * been set up. The basic operation is to add the number at the rear pointer
+ * into the one at the front pointer. Then both pointers are advanced to
+ * the next location cyclically in the table. The value returned is the sum
+ * generated, reduced to 31 bits by throwing away the "least random" low bit.
+ *
+ * Note: the code takes advantage of the fact that both the front and
+ * rear pointers can't wrap on the same call by not testing the rear
+ * pointer if the front one has wrapped.
+ *
+ * Returns a 31-bit random number.
+ */
+long
+ntp_random( void )
+{
+ register long i;
+ register unsigned long *f, *r;
+
+ if (rand_type == TYPE_0) {
+ i = state[0];
+ state[0] = i = (good_rand(i)) & 0x7fffffff;
+ } else {
+ /*
+ * Use local variables rather than static variables for speed.
+ */
+ f = fptr; r = rptr;
+ *f += *r;
+ i = (*f >> 1) & 0x7fffffff; /* chucking least random bit */
+ if (++f >= end_ptr) {
+ f = state;
+ ++r;
+ }
+ else if (++r >= end_ptr) {
+ r = state;
+ }
+
+ fptr = f; rptr = r;
+ }
+ return(i);
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/libntp/ntp_rfc2553.c b/sebhbsd/freebsd/contrib/ntp/libntp/ntp_rfc2553.c
new file mode 100644
index 0000000..c255801
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/libntp/ntp_rfc2553.c
@@ -0,0 +1,580 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+/*
+ * Compatability shims with the rfc2553 API to simplify ntp.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <ctype.h>
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#include <isc/net.h>
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#include "ntp_rfc2553.h"
+
+#include "ntpd.h"
+#include "ntp_malloc.h"
+#include "ntp_string.h"
+#include "ntp_debug.h"
+
+
+/*
+ * copy_addrinfo() - copy a single addrinfo to malloc()'d block.
+ * copy_addrinfo_list() - copy an addrinfo list to malloc()'d block.
+ *
+ * Copies an addrinfo list and its associated data to a contiguous block
+ * of storage from emalloc(). Callback routines invoked via
+ * getaddrinfo_sometime() have access to the resulting addrinfo list
+ * only until they return. This routine provides an easy way to make a
+ * persistent copy. Although the list provided to gai_sometime_callback
+ * routines is similarly contiguous, to keep this code usable in any
+ * context where we might want to duplicate an addrinfo list, it does
+ * not require the input list be contiguous.
+ *
+ * The returned list head pointer is passed to free() to release the
+ * entire list.
+ *
+ * In keeping with the rest of the NTP distribution, sockaddr_u is used
+ * in preference to struct sockaddr_storage, which is a member of the
+ * former union and so compatible.
+ *
+ * The rest of ntp_rfc2553.c is conditioned on ISC_PLATFORM_HAVEIPV6
+ * not being defined, copy_addrinfo_*() are exceptions.
+ */
+struct addrinfo * copy_addrinfo_common(const struct addrinfo *, int
+#ifdef EREALLOC_CALLSITE
+ ,
+ const char *, int
+#endif
+ );
+
+
+struct addrinfo *
+copy_addrinfo_impl(
+ const struct addrinfo * src
+#ifdef EREALLOC_CALLSITE
+ ,
+ const char * caller_file,
+ int caller_line
+#endif
+ )
+{
+ return copy_addrinfo_common(src, TRUE
+#ifdef EREALLOC_CALLSITE
+ ,
+ caller_file, caller_line
+#endif
+ );
+}
+
+
+struct addrinfo *
+copy_addrinfo_list_impl(
+ const struct addrinfo * src
+#ifdef EREALLOC_CALLSITE
+ ,
+ const char * caller_file,
+ int caller_line
+#endif
+ )
+{
+ return copy_addrinfo_common(src, FALSE
+#ifdef EREALLOC_CALLSITE
+ ,
+ caller_file, caller_line
+#endif
+ );
+}
+
+
+struct addrinfo *
+copy_addrinfo_common(
+ const struct addrinfo * src,
+ int just_one
+#ifdef EREALLOC_CALLSITE
+ ,
+ const char * caller_file,
+ int caller_line
+#endif
+ )
+{
+ const struct addrinfo * ai_src;
+ const struct addrinfo * ai_nxt;
+ struct addrinfo * ai_cpy;
+ struct addrinfo * dst;
+ sockaddr_u * psau;
+ char * pcanon;
+ u_int elements;
+ size_t octets;
+ size_t canons_octets;
+ size_t str_octets;
+
+ elements = 0;
+ canons_octets = 0;
+
+ for (ai_src = src; NULL != ai_src; ai_src = ai_nxt) {
+ if (just_one)
+ ai_nxt = NULL;
+ else
+ ai_nxt = ai_src->ai_next;
+ ++elements;
+ if (NULL != ai_src->ai_canonname)
+ canons_octets += 1 + strlen(ai_src->ai_canonname);
+ }
+
+ octets = elements * (sizeof(*ai_cpy) + sizeof(*psau));
+ octets += canons_octets;
+
+ dst = erealloczsite(NULL, octets, 0, TRUE, caller_file,
+ caller_line);
+ ai_cpy = dst;
+ psau = (void *)(ai_cpy + elements);
+ pcanon = (void *)(psau + elements);
+
+ for (ai_src = src; NULL != ai_src; ai_src = ai_nxt) {
+ if (just_one)
+ ai_nxt = NULL;
+ else
+ ai_nxt = ai_src->ai_next;
+ *ai_cpy = *ai_src;
+ DEBUG_INSIST(ai_cpy->ai_canonname == ai_src->ai_canonname);
+ INSIST(ai_src->ai_addrlen <= sizeof(sockaddr_u));
+ memcpy(psau, ai_src->ai_addr, ai_src->ai_addrlen);
+ ai_cpy->ai_addr = &psau->sa;
+ ++psau;
+ if (NULL != ai_src->ai_canonname) {
+ ai_cpy->ai_canonname = pcanon;
+ str_octets = 1 + strlen(ai_src->ai_canonname);
+ memcpy(pcanon, ai_src->ai_canonname, str_octets);
+ pcanon += str_octets;
+ }
+ if (NULL != ai_cpy->ai_next) {
+ if (just_one)
+ ai_cpy->ai_next = NULL;
+ else
+ ai_cpy->ai_next = ai_cpy + 1;
+ }
+ ++ai_cpy;
+ }
+ ENSURE(pcanon == ((char *)dst + octets));
+
+ return dst;
+}
+
+
+#ifndef ISC_PLATFORM_HAVEIPV6
+
+static char *ai_errlist[] = {
+ "Success",
+ "Address family for hostname not supported", /* EAI_ADDRFAMILY */
+ "Temporary failure in name resolution", /* EAI_AGAIN */
+ "Invalid value for ai_flags", /* EAI_BADFLAGS */
+ "Non-recoverable failure in name resolution", /* EAI_FAIL */
+ "ai_family not supported", /* EAI_FAMILY */
+ "Memory allocation failure", /* EAI_MEMORY */
+ "No address associated with hostname", /* EAI_NODATA */
+ "hostname nor servname provided, or not known", /* EAI_NONAME */
+ "servname not supported for ai_socktype", /* EAI_SERVICE */
+ "ai_socktype not supported", /* EAI_SOCKTYPE */
+ "System error returned in errno", /* EAI_SYSTEM */
+ "Invalid value for hints", /* EAI_BADHINTS */
+ "Resolved protocol is unknown", /* EAI_PROTOCOL */
+ "Unknown error", /* EAI_MAX */
+};
+
+/*
+ * Local declaration
+ */
+int
+DNSlookup_name(
+ const char *name,
+ int ai_family,
+ struct hostent **Addresses
+);
+
+#ifndef SYS_WINNT
+/*
+ * Encapsulate gethostbyname to control the error code
+ */
+int
+DNSlookup_name(
+ const char *name,
+ int ai_family,
+ struct hostent **Addresses
+)
+{
+ *Addresses = gethostbyname(name);
+ return (h_errno);
+}
+#endif
+
+static int do_nodename (const char *nodename, struct addrinfo *ai,
+ const struct addrinfo *hints);
+
+int
+getaddrinfo (const char *nodename, const char *servname,
+ const struct addrinfo *hints, struct addrinfo **res)
+{
+ int rval;
+ struct servent *sp;
+ struct addrinfo *ai = NULL;
+ int port;
+ const char *proto = NULL;
+ int family, socktype, flags, protocol;
+
+
+ /*
+ * If no name is provide just return an error
+ */
+ if (nodename == NULL && servname == NULL)
+ return (EAI_NONAME);
+
+ ai = calloc(sizeof(struct addrinfo), 1);
+ if (ai == NULL)
+ return (EAI_MEMORY);
+
+ /*
+ * Copy default values from hints, if available
+ */
+ if (hints != NULL) {
+ ai->ai_flags = hints->ai_flags;
+ ai->ai_family = hints->ai_family;
+ ai->ai_socktype = hints->ai_socktype;
+ ai->ai_protocol = hints->ai_protocol;
+
+ family = hints->ai_family;
+ socktype = hints->ai_socktype;
+ protocol = hints->ai_protocol;
+ flags = hints->ai_flags;
+
+ switch (family) {
+ case AF_UNSPEC:
+ switch (hints->ai_socktype) {
+ case SOCK_STREAM:
+ proto = "tcp";
+ break;
+ case SOCK_DGRAM:
+ proto = "udp";
+ break;
+ }
+ break;
+ case AF_INET:
+ case AF_INET6:
+ switch (hints->ai_socktype) {
+ case 0:
+ break;
+ case SOCK_STREAM:
+ proto = "tcp";
+ break;
+ case SOCK_DGRAM:
+ proto = "udp";
+ break;
+ case SOCK_RAW:
+ break;
+ default:
+ return (EAI_SOCKTYPE);
+ }
+ break;
+#ifdef AF_LOCAL
+ case AF_LOCAL:
+ switch (hints->ai_socktype) {
+ case 0:
+ break;
+ case SOCK_STREAM:
+ break;
+ case SOCK_DGRAM:
+ break;
+ default:
+ return (EAI_SOCKTYPE);
+ }
+ break;
+#endif
+ default:
+ return (EAI_FAMILY);
+ }
+ } else {
+ protocol = 0;
+ family = 0;
+ socktype = 0;
+ flags = 0;
+ }
+
+ rval = do_nodename(nodename, ai, hints);
+ if (rval != 0) {
+ freeaddrinfo(ai);
+ return (rval);
+ }
+
+ /*
+ * First, look up the service name (port) if it was
+ * requested. If the socket type wasn't specified, then
+ * try and figure it out.
+ */
+ if (servname != NULL) {
+ char *e;
+
+ port = strtol(servname, &e, 10);
+ if (*e == '\0') {
+ if (socktype == 0)
+ return (EAI_SOCKTYPE);
+ if (port < 0 || port > 65535)
+ return (EAI_SERVICE);
+ port = htons((unsigned short) port);
+ } else {
+ sp = getservbyname(servname, proto);
+ if (sp == NULL)
+ return (EAI_SERVICE);
+ port = sp->s_port;
+ if (socktype == 0) {
+ if (strcmp(sp->s_proto, "tcp") == 0)
+ socktype = SOCK_STREAM;
+ else if (strcmp(sp->s_proto, "udp") == 0)
+ socktype = SOCK_DGRAM;
+ }
+ }
+ } else
+ port = 0;
+
+ /*
+ *
+ * Set up the port number
+ */
+ if (ai->ai_family == AF_INET)
+ ((struct sockaddr_in *)ai->ai_addr)->sin_port = (unsigned short) port;
+ else if (ai->ai_family == AF_INET6)
+ ((struct sockaddr_in6 *)ai->ai_addr)->sin6_port = (unsigned short) port;
+ *res = ai;
+ return (0);
+}
+
+void
+freeaddrinfo(struct addrinfo *ai)
+{
+ if (ai->ai_canonname != NULL)
+ {
+ free(ai->ai_canonname);
+ ai->ai_canonname = NULL;
+ }
+ if (ai->ai_addr != NULL)
+ {
+ free(ai->ai_addr);
+ ai->ai_addr = NULL;
+ }
+ free(ai);
+ ai = NULL;
+}
+
+int
+getnameinfo (const struct sockaddr *sa, u_int salen, char *host,
+ size_t hostlen, char *serv, size_t servlen, int flags)
+{
+ struct hostent *hp;
+
+ if (sa->sa_family != AF_INET)
+ return (EAI_FAMILY);
+ hp = gethostbyaddr(
+ (const char *)&((const struct sockaddr_in *)sa)->sin_addr,
+ 4, AF_INET);
+ if (hp == NULL) {
+ if (h_errno == TRY_AGAIN)
+ return (EAI_AGAIN);
+ else
+ return (EAI_FAIL);
+ }
+ if (host != NULL && hostlen > 0)
+ strlcpy(host, hp->h_name, hostlen);
+ return (0);
+}
+
+char *
+gai_strerror(int ecode)
+{
+ if (ecode < 0 || ecode > EAI_MAX)
+ ecode = EAI_MAX;
+ return ai_errlist[ecode];
+}
+
+static int
+do_nodename(
+ const char *nodename,
+ struct addrinfo *ai,
+ const struct addrinfo *hints)
+{
+ struct hostent *hp = NULL;
+ struct sockaddr_in *sockin;
+ struct sockaddr_in6 *sockin6;
+ int errval;
+
+ ai->ai_addr = calloc(sizeof(struct sockaddr_storage), 1);
+ if (ai->ai_addr == NULL)
+ return (EAI_MEMORY);
+
+ /*
+ * For an empty node name just use the wildcard.
+ * NOTE: We need to assume that the address family is
+ * set elsewhere so that we can set the appropriate wildcard
+ */
+ if (nodename == NULL) {
+ if (ai->ai_family == AF_INET)
+ {
+ ai->ai_addrlen = sizeof(struct sockaddr_in);
+ sockin = (struct sockaddr_in *)ai->ai_addr;
+ sockin->sin_family = (short) ai->ai_family;
+ sockin->sin_addr.s_addr = htonl(INADDR_ANY);
+ }
+ else
+ {
+ ai->ai_addrlen = sizeof(struct sockaddr_in6);
+ sockin6 = (struct sockaddr_in6 *)ai->ai_addr;
+ sockin6->sin6_family = (short) ai->ai_family;
+ /*
+ * we have already zeroed out the address
+ * so we don't actually need to do this
+ * This assignment is causing problems so
+ * we don't do what this would do.
+ sockin6->sin6_addr = in6addr_any;
+ */
+ }
+#ifdef ISC_PLATFORM_HAVESALEN
+ ai->ai_addr->sa_len = SOCKLEN(ai->ai_addr);
+#endif
+
+ return (0);
+ }
+
+ /*
+ * See if we have an IPv6 address
+ */
+ if(strchr(nodename, ':') != NULL) {
+ if (inet_pton(AF_INET6, nodename,
+ &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr) == 1) {
+ ((struct sockaddr_in6 *)ai->ai_addr)->sin6_family = AF_INET6;
+ ai->ai_family = AF_INET6;
+ ai->ai_addrlen = sizeof(struct sockaddr_in6);
+ return (0);
+ }
+ }
+
+ /*
+ * See if we have an IPv4 address
+ */
+ if (inet_pton(AF_INET, nodename,
+ &((struct sockaddr_in *)ai->ai_addr)->sin_addr) == 1) {
+ ((struct sockaddr *)ai->ai_addr)->sa_family = AF_INET;
+ ai->ai_family = AF_INET;
+ ai->ai_addrlen = sizeof(struct sockaddr_in);
+ return (0);
+ }
+
+ /*
+ * If the numeric host flag is set, don't attempt resolution
+ */
+ if (hints != NULL && (hints->ai_flags & AI_NUMERICHOST))
+ return (EAI_NONAME);
+
+ /*
+ * Look for a name
+ */
+
+ errval = DNSlookup_name(nodename, AF_INET, &hp);
+
+ if (hp == NULL) {
+ if (errval == TRY_AGAIN || errval == EAI_AGAIN)
+ return (EAI_AGAIN);
+ else if (errval == EAI_NONAME) {
+ if (inet_pton(AF_INET, nodename,
+ &((struct sockaddr_in *)ai->ai_addr)->sin_addr) == 1) {
+ ((struct sockaddr *)ai->ai_addr)->sa_family = AF_INET;
+ ai->ai_family = AF_INET;
+ ai->ai_addrlen = sizeof(struct sockaddr_in);
+ return (0);
+ }
+ return (errval);
+ }
+ else
+ {
+ return (errval);
+ }
+ }
+ ai->ai_family = hp->h_addrtype;
+ ai->ai_addrlen = sizeof(struct sockaddr);
+ sockin = (struct sockaddr_in *)ai->ai_addr;
+ memcpy(&sockin->sin_addr, hp->h_addr, hp->h_length);
+ ai->ai_addr->sa_family = hp->h_addrtype;
+#ifdef ISC_PLATFORM_HAVESALEN
+ ai->ai_addr->sa_len = sizeof(struct sockaddr);
+#endif
+ if (hints != NULL && (hints->ai_flags & AI_CANONNAME))
+ ai->ai_canonname = estrdup(hp->h_name);
+ return (0);
+}
+
+#endif /* !ISC_PLATFORM_HAVEIPV6 */
diff --git a/sebhbsd/freebsd/contrib/ntp/libntp/ntp_worker.c b/sebhbsd/freebsd/contrib/ntp/libntp/ntp_worker.c
new file mode 100644
index 0000000..7f2cda0
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/libntp/ntp_worker.c
@@ -0,0 +1,374 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * ntp_worker.c
+ */
+#include <config.h>
+#include "ntp_workimpl.h"
+
+#ifdef WORKER
+
+#include <stdio.h>
+#include <ctype.h>
+#include <signal.h>
+
+#include "iosignal.h"
+#include "ntp_stdlib.h"
+#include "ntp_malloc.h"
+#include "ntp_syslog.h"
+#include "ntpd.h"
+#include "ntp_io.h"
+#include "ntp_assert.h"
+#include "ntp_unixtime.h"
+#include "intreswork.h"
+
+
+#define CHILD_MAX_IDLE (3 * 60) /* seconds, idle worker limit */
+
+blocking_child ** blocking_children;
+size_t blocking_children_alloc;
+int worker_per_query; /* boolean */
+int intres_req_pending;
+volatile u_int blocking_child_ready_seen;
+volatile u_int blocking_child_ready_done;
+
+
+#ifndef HAVE_IO_COMPLETION_PORT
+/*
+ * pipe_socketpair()
+ *
+ * Provides an AF_UNIX socketpair on systems which have them, otherwise
+ * pair of unidirectional pipes.
+ */
+int
+pipe_socketpair(
+ int caller_fds[2],
+ int * is_pipe
+ )
+{
+ int rc;
+ int fds[2];
+ int called_pipe;
+
+#ifdef HAVE_SOCKETPAIR
+ rc = socketpair(AF_UNIX, SOCK_STREAM, 0, &fds[0]);
+#else
+ rc = -1;
+#endif
+
+#ifndef __rtems__
+ if (-1 == rc) {
+ rc = pipe(&fds[0]);
+ called_pipe = TRUE;
+ } else {
+ called_pipe = FALSE;
+ }
+#else /* __rtems__ */
+ called_pipe = FALSE;
+#endif /* __rtems__ */
+
+ if (-1 == rc)
+ return rc;
+
+ caller_fds[0] = fds[0];
+ caller_fds[1] = fds[1];
+ if (is_pipe != NULL)
+ *is_pipe = called_pipe;
+
+ return 0;
+}
+
+
+/*
+ * close_all_except()
+ *
+ * Close all file descriptors except the given keep_fd.
+ */
+void
+close_all_except(
+ int keep_fd
+ )
+{
+ int fd;
+
+ for (fd = 0; fd < keep_fd; fd++)
+ close(fd);
+
+ close_all_beyond(keep_fd);
+}
+
+
+/*
+ * close_all_beyond()
+ *
+ * Close all file descriptors after the given keep_fd, which is the
+ * highest fd to keep open.
+ */
+void
+close_all_beyond(
+ int keep_fd
+ )
+{
+# ifdef HAVE_CLOSEFROM
+ closefrom(keep_fd + 1);
+# elif defined(F_CLOSEM)
+ /*
+ * From 'Writing Reliable AIX Daemons,' SG24-4946-00,
+ * by Eric Agar (saves us from doing 32767 system
+ * calls)
+ */
+ if (fcntl(keep_fd + 1, F_CLOSEM, 0) == -1)
+ msyslog(LOG_ERR, "F_CLOSEM(%d): %m", keep_fd + 1);
+# else /* !HAVE_CLOSEFROM && !F_CLOSEM follows */
+ int fd;
+ int max_fd;
+
+ max_fd = GETDTABLESIZE();
+ for (fd = keep_fd + 1; fd < max_fd; fd++)
+ close(fd);
+# endif /* !HAVE_CLOSEFROM && !F_CLOSEM */
+}
+#endif /* HAVE_IO_COMPLETION_PORT */
+
+
+u_int
+available_blocking_child_slot(void)
+{
+ const size_t each = sizeof(blocking_children[0]);
+ u_int slot;
+ size_t prev_alloc;
+ size_t new_alloc;
+ size_t prev_octets;
+ size_t octets;
+
+ for (slot = 0; slot < blocking_children_alloc; slot++) {
+ if (NULL == blocking_children[slot])
+ return slot;
+ if (blocking_children[slot]->reusable) {
+ blocking_children[slot]->reusable = FALSE;
+ return slot;
+ }
+ }
+
+ prev_alloc = blocking_children_alloc;
+ prev_octets = prev_alloc * each;
+ new_alloc = blocking_children_alloc + 4;
+ octets = new_alloc * each;
+ blocking_children = erealloc_zero(blocking_children, octets,
+ prev_octets);
+ blocking_children_alloc = new_alloc;
+
+ /* assume we'll never have enough workers to overflow u_int */
+ return (u_int)prev_alloc;
+}
+
+
+int
+queue_blocking_request(
+ blocking_work_req rtype,
+ void * req,
+ size_t reqsize,
+ blocking_work_callback done_func,
+ void * context
+ )
+{
+ static u_int intres_slot = UINT_MAX;
+ u_int child_slot;
+ blocking_child * c;
+ blocking_pipe_header req_hdr;
+
+ req_hdr.octets = sizeof(req_hdr) + reqsize;
+ req_hdr.magic_sig = BLOCKING_REQ_MAGIC;
+ req_hdr.rtype = rtype;
+ req_hdr.done_func = done_func;
+ req_hdr.context = context;
+
+ child_slot = UINT_MAX;
+ if (worker_per_query || UINT_MAX == intres_slot ||
+ blocking_children[intres_slot]->reusable)
+ child_slot = available_blocking_child_slot();
+ if (!worker_per_query) {
+ if (UINT_MAX == intres_slot)
+ intres_slot = child_slot;
+ else
+ child_slot = intres_slot;
+ if (0 == intres_req_pending)
+ intres_timeout_req(0);
+ }
+ intres_req_pending++;
+ INSIST(UINT_MAX != child_slot);
+ c = blocking_children[child_slot];
+ if (NULL == c) {
+ c = emalloc_zero(sizeof(*c));
+#ifdef WORK_FORK
+ c->req_read_pipe = -1;
+ c->req_write_pipe = -1;
+#endif
+#ifdef WORK_PIPE
+ c->resp_read_pipe = -1;
+ c->resp_write_pipe = -1;
+#endif
+ blocking_children[child_slot] = c;
+ }
+ req_hdr.child_idx = child_slot;
+
+ return send_blocking_req_internal(c, &req_hdr, req);
+}
+
+
+int queue_blocking_response(
+ blocking_child * c,
+ blocking_pipe_header * resp,
+ size_t respsize,
+ const blocking_pipe_header * req
+ )
+{
+ resp->octets = respsize;
+ resp->magic_sig = BLOCKING_RESP_MAGIC;
+ resp->rtype = req->rtype;
+ resp->context = req->context;
+ resp->done_func = req->done_func;
+
+ return send_blocking_resp_internal(c, resp);
+}
+
+
+void
+process_blocking_resp(
+ blocking_child * c
+ )
+{
+ blocking_pipe_header * resp;
+ void * data;
+
+ /*
+ * On Windows send_blocking_resp_internal() may signal the
+ * blocking_response_ready event multiple times while we're
+ * processing a response, so always consume all available
+ * responses before returning to test the event again.
+ */
+#ifdef WORK_THREAD
+ do {
+#endif
+ resp = receive_blocking_resp_internal(c);
+ if (NULL != resp) {
+ DEBUG_REQUIRE(BLOCKING_RESP_MAGIC ==
+ resp->magic_sig);
+ data = (char *)resp + sizeof(*resp);
+ intres_req_pending--;
+ (*resp->done_func)(resp->rtype, resp->context,
+ resp->octets - sizeof(*resp),
+ data);
+ free(resp);
+ }
+#ifdef WORK_THREAD
+ } while (NULL != resp);
+#endif
+ if (!worker_per_query && 0 == intres_req_pending)
+ intres_timeout_req(CHILD_MAX_IDLE);
+ else if (worker_per_query)
+ req_child_exit(c);
+}
+
+void
+harvest_blocking_responses(void)
+{
+ size_t idx;
+ blocking_child* cp;
+ u_int scseen, scdone;
+
+ scseen = blocking_child_ready_seen;
+ scdone = blocking_child_ready_done;
+ if (scdone != scseen) {
+ blocking_child_ready_done = scseen;
+ for (idx = 0; idx < blocking_children_alloc; idx++) {
+ cp = blocking_children[idx];
+ if (NULL == cp)
+ continue;
+ scseen = cp->resp_ready_seen;
+ scdone = cp->resp_ready_done;
+ if (scdone != scseen) {
+ cp->resp_ready_done = scseen;
+ process_blocking_resp(cp);
+ }
+ }
+ }
+}
+
+
+/*
+ * blocking_child_common runs as a forked child or a thread
+ */
+int
+blocking_child_common(
+ blocking_child *c
+ )
+{
+ int say_bye;
+ blocking_pipe_header *req;
+
+ say_bye = FALSE;
+ while (!say_bye) {
+ req = receive_blocking_req_internal(c);
+ if (NULL == req) {
+ say_bye = TRUE;
+ continue;
+ }
+
+ DEBUG_REQUIRE(BLOCKING_REQ_MAGIC == req->magic_sig);
+
+ switch (req->rtype) {
+ case BLOCKING_GETADDRINFO:
+ if (blocking_getaddrinfo(c, req))
+ say_bye = TRUE;
+ break;
+
+ case BLOCKING_GETNAMEINFO:
+ if (blocking_getnameinfo(c, req))
+ say_bye = TRUE;
+ break;
+
+ default:
+ msyslog(LOG_ERR, "unknown req %d to blocking worker", req->rtype);
+ say_bye = TRUE;
+ }
+
+ free(req);
+ }
+
+ return 0;
+}
+
+
+/*
+ * worker_idle_timer_fired()
+ *
+ * The parent starts this timer when the last pending response has been
+ * received from the child, making it idle, and clears the timer when a
+ * request is dispatched to the child. Once the timer expires, the
+ * child is sent packing.
+ *
+ * This is called when worker_idle_timer is nonzero and less than or
+ * equal to current_time.
+ */
+void
+worker_idle_timer_fired(void)
+{
+ u_int idx;
+ blocking_child * c;
+
+ DEBUG_REQUIRE(0 == intres_req_pending);
+
+ intres_timeout_req(0);
+ for (idx = 0; idx < blocking_children_alloc; idx++) {
+ c = blocking_children[idx];
+ if (NULL == c)
+ continue;
+ req_child_exit(c);
+ }
+}
+
+
+#else /* !WORKER follows */
+int ntp_worker_nonempty_compilation_unit;
+#endif
diff --git a/sebhbsd/freebsd/contrib/ntp/libntp/numtoa.c b/sebhbsd/freebsd/contrib/ntp/libntp/numtoa.c
new file mode 100644
index 0000000..511c029
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/libntp/numtoa.c
@@ -0,0 +1,61 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * numtoa - return asciized network numbers store in local array space
+ */
+#include <config.h>
+
+#include <sys/types.h>
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h> /* ntohl */
+#endif
+
+#include <stdio.h>
+
+#include "ntp_fp.h"
+#include "lib_strbuf.h"
+#include "ntp_stdlib.h"
+
+char *
+numtoa(
+ u_int32 num
+ )
+{
+ register u_int32 netnum;
+ register char *buf;
+
+ netnum = ntohl(num);
+ LIB_GETBUF(buf);
+ snprintf(buf, LIB_BUFLENGTH, "%lu.%lu.%lu.%lu",
+ ((u_long)netnum >> 24) & 0xff,
+ ((u_long)netnum >> 16) & 0xff,
+ ((u_long)netnum >> 8) & 0xff,
+ (u_long)netnum & 0xff);
+ return buf;
+}
+
+
+/* Convert a refid & stratum to a string */
+const char *
+refid_str(
+ u_int32 refid,
+ int stratum
+ )
+{
+ char * text;
+ size_t tlen;
+
+ if (stratum > 1)
+ return numtoa(refid);
+
+ LIB_GETBUF(text);
+ text[0] = '.';
+ memcpy(&text[1], &refid, sizeof(refid));
+ text[1 + sizeof(refid)] = '\0';
+ tlen = strlen(text);
+ text[tlen] = '.';
+ text[tlen + 1] = '\0';
+
+ return text;
+}
+
diff --git a/sebhbsd/freebsd/contrib/ntp/libntp/prettydate.c b/sebhbsd/freebsd/contrib/ntp/libntp/prettydate.c
new file mode 100644
index 0000000..0f3d160
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/libntp/prettydate.c
@@ -0,0 +1,238 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * prettydate - convert a time stamp to something readable
+ */
+#include <config.h>
+#include <stdio.h>
+
+#include "ntp_fp.h"
+#include "ntp_unixtime.h" /* includes <sys/time.h> */
+#include "lib_strbuf.h"
+#include "ntp_stdlib.h"
+#include "ntp_assert.h"
+#include "ntp_calendar.h"
+
+#if SIZEOF_TIME_T < 4
+# error sizeof(time_t) < 4 -- this will not work!
+#endif
+
+static char *common_prettydate(l_fp *, int);
+
+const char * const months[12] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
+
+const char * const daynames[7] = {
+ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
+};
+
+/* Helper function to handle possible wraparound of the ntp epoch.
+ *
+ * Works by periodic extension of the ntp time stamp in the UN*X epoch.
+ * If the 'time_t' is 32 bit, use solar cycle warping to get the value
+ * in a suitable range. Also uses solar cycle warping to work around
+ * really buggy implementations of 'gmtime()' / 'localtime()' that
+ * cannot work with a negative time value, that is, times before
+ * 1970-01-01. (MSVCRT...)
+ *
+ * Apart from that we're assuming that the localtime/gmtime library
+ * functions have been updated so that they work...
+ *
+ * An explanation: The julian calendar repeats ever 28 years, because
+ * it's the LCM of 7 and 1461, the week and leap year cycles. This is
+ * called a 'solar cycle'. The gregorian calendar does the same as
+ * long as no centennial year (divisible by 100, but not 400) goes in
+ * the way. So between 1901 and 2099 (inclusive) we can warp time
+ * stamps by 28 years to make them suitable for localtime() and
+ * gmtime() if we have trouble. Of course this will play hubbubb with
+ * the DST zone switches, so we should do it only if necessary; but as
+ * we NEED a proper conversion to dates via gmtime() we should try to
+ * cope with as many idiosyncrasies as possible.
+ *
+ */
+
+/*
+ * solar cycle in unsigned secs and years, and the cycle limits.
+ */
+#define SOLAR_CYCLE_SECS 0x34AADC80UL /* 7*1461*86400*/
+#define SOLAR_CYCLE_YEARS 28
+#define MINFOLD -3
+#define MAXFOLD 3
+
+static struct tm *
+get_struct_tm(
+ const vint64 *stamp,
+ int local)
+{
+ struct tm *tm = NULL;
+ int32 folds = 0;
+ time_t ts;
+
+#ifdef HAVE_INT64
+
+ int64 tl;
+ ts = tl = stamp->q_s;
+
+ /*
+ * If there is chance of truncation, try to fix it. Let the
+ * compiler find out if this can happen at all.
+ */
+ while (ts != tl) { /* truncation? */
+ if (tl < 0) {
+ if (--folds < MINFOLD)
+ return NULL;
+ tl += SOLAR_CYCLE_SECS;
+ } else {
+ if (++folds > MAXFOLD)
+ return NULL;
+ tl -= SOLAR_CYCLE_SECS;
+ }
+ ts = tl; /* next try... */
+ }
+#else
+
+ /*
+ * since we do not have 64-bit scalars, it's not likely we have
+ * 64-bit time_t. Assume 32 bits and properly reduce the value.
+ */
+ u_int32 hi, lo;
+
+ hi = stamp->D_s.hi;
+ lo = stamp->D_s.lo;
+
+ while ((hi && ~hi) || ((hi ^ lo) & 0x80000000u)) {
+ if (M_ISNEG(hi, lo)) {
+ if (--folds < MINFOLD)
+ return NULL;
+ M_ADD(hi, lo, 0, SOLAR_CYCLE_SECS);
+ } else {
+ if (++folds > MAXFOLD)
+ return NULL;
+ M_SUB(hi, lo, 0, SOLAR_CYCLE_SECS);
+ }
+ }
+ ts = (int32)lo;
+
+#endif
+
+ /*
+ * 'ts' should be a suitable value by now. Just go ahead, but
+ * with care:
+ *
+ * There are some pathological implementations of 'gmtime()'
+ * and 'localtime()' out there. No matter if we have 32-bit or
+ * 64-bit 'time_t', try to fix this by solar cycle warping
+ * again...
+ *
+ * At least the MSDN says that the (Microsoft) Windoze
+ * versions of 'gmtime()' and 'localtime()' will bark on time
+ * stamps < 0.
+ */
+ while ((tm = (*(local ? localtime : gmtime))(&ts)) == NULL)
+ if (ts < 0) {
+ if (--folds < MINFOLD)
+ return NULL;
+ ts += SOLAR_CYCLE_SECS;
+ } else if (ts >= (time_t)SOLAR_CYCLE_SECS) {
+ if (++folds > MAXFOLD)
+ return NULL;
+ ts -= SOLAR_CYCLE_SECS;
+ } else
+ return NULL; /* That's truly pathological! */
+
+ /* 'tm' surely not NULL here! */
+ INSIST(tm != NULL);
+ if (folds != 0) {
+ tm->tm_year += folds * SOLAR_CYCLE_YEARS;
+ if (tm->tm_year <= 0 || tm->tm_year >= 200)
+ return NULL; /* left warp range... can't help here! */
+ }
+
+ return tm;
+}
+
+static char *
+common_prettydate(
+ l_fp *ts,
+ int local
+ )
+{
+ static const char pfmt0[] =
+ "%08lx.%08lx %s, %s %2d %4d %2d:%02d:%02d.%03u";
+ static const char pfmt1[] =
+ "%08lx.%08lx [%s, %s %2d %4d %2d:%02d:%02d.%03u UTC]";
+
+ char *bp;
+ struct tm *tm;
+ u_int msec;
+ u_int32 ntps;
+ vint64 sec;
+
+ LIB_GETBUF(bp);
+
+ if (ts->l_ui == 0 && ts->l_uf == 0) {
+ strlcpy (bp, "(no time)", LIB_BUFLENGTH);
+ return (bp);
+ }
+
+ /* get & fix milliseconds */
+ ntps = ts->l_ui;
+ msec = ts->l_uf / 4294967; /* fract / (2 ** 32 / 1000) */
+ if (msec >= 1000u) {
+ msec -= 1000u;
+ ntps++;
+ }
+ sec = ntpcal_ntp_to_time(ntps, NULL);
+ tm = get_struct_tm(&sec, local);
+ if (!tm) {
+ /*
+ * get a replacement, but always in UTC, using
+ * ntpcal_time_to_date()
+ */
+ struct calendar jd;
+ ntpcal_time_to_date(&jd, &sec);
+ snprintf(bp, LIB_BUFLENGTH, local ? pfmt1 : pfmt0,
+ (u_long)ts->l_ui, (u_long)ts->l_uf,
+ daynames[jd.weekday], months[jd.month-1],
+ jd.monthday, jd.year, jd.hour,
+ jd.minute, jd.second, msec);
+ } else
+ snprintf(bp, LIB_BUFLENGTH, pfmt0,
+ (u_long)ts->l_ui, (u_long)ts->l_uf,
+ daynames[tm->tm_wday], months[tm->tm_mon],
+ tm->tm_mday, 1900 + tm->tm_year, tm->tm_hour,
+ tm->tm_min, tm->tm_sec, msec);
+ return bp;
+}
+
+
+char *
+prettydate(
+ l_fp *ts
+ )
+{
+ return common_prettydate(ts, 1);
+}
+
+
+char *
+gmprettydate(
+ l_fp *ts
+ )
+{
+ return common_prettydate(ts, 0);
+}
+
+
+struct tm *
+ntp2unix_tm(
+ u_int32 ntp, int local
+ )
+{
+ vint64 vl;
+ vl = ntpcal_ntp_to_time(ntp, NULL);
+ return get_struct_tm(&vl, local);
+}
+
diff --git a/sebhbsd/freebsd/contrib/ntp/libntp/recvbuff.c b/sebhbsd/freebsd/contrib/ntp/libntp/recvbuff.c
new file mode 100644
index 0000000..64c9155
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/libntp/recvbuff.c
@@ -0,0 +1,330 @@
+#include <machine/rtems-bsd-user-space.h>
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+
+#include "ntp_assert.h"
+#include "ntp_syslog.h"
+#include "ntp_stdlib.h"
+#include "ntp_lists.h"
+#include "recvbuff.h"
+#include "iosignal.h"
+
+
+/*
+ * Memory allocation
+ */
+static u_long volatile full_recvbufs; /* recvbufs on full_recv_fifo */
+static u_long volatile free_recvbufs; /* recvbufs on free_recv_list */
+static u_long volatile total_recvbufs; /* total recvbufs currently in use */
+static u_long volatile lowater_adds; /* number of times we have added memory */
+static u_long volatile buffer_shortfall;/* number of missed free receive buffers
+ between replenishments */
+
+static DECL_FIFO_ANCHOR(recvbuf_t) full_recv_fifo;
+static recvbuf_t * free_recv_list;
+
+#if defined(SYS_WINNT)
+
+/*
+ * For Windows we need to set up a lock to manipulate the
+ * recv buffers to prevent corruption. We keep it lock for as
+ * short a time as possible
+ */
+static CRITICAL_SECTION RecvLock;
+# define LOCK() EnterCriticalSection(&RecvLock)
+# define UNLOCK() LeaveCriticalSection(&RecvLock)
+#else
+# define LOCK() do {} while (FALSE)
+# define UNLOCK() do {} while (FALSE)
+#endif
+
+#ifdef DEBUG
+static void uninit_recvbuff(void);
+#endif
+
+
+u_long
+free_recvbuffs (void)
+{
+ return free_recvbufs;
+}
+
+u_long
+full_recvbuffs (void)
+{
+ return full_recvbufs;
+}
+
+u_long
+total_recvbuffs (void)
+{
+ return total_recvbufs;
+}
+
+u_long
+lowater_additions(void)
+{
+ return lowater_adds;
+}
+
+static inline void
+initialise_buffer(recvbuf_t *buff)
+{
+ ZERO(*buff);
+}
+
+static void
+create_buffers(int nbufs)
+{
+ register recvbuf_t *bufp;
+ int i, abuf;
+
+ abuf = nbufs + buffer_shortfall;
+ buffer_shortfall = 0;
+
+#ifndef DEBUG
+ bufp = eallocarray(abuf, sizeof(*bufp));
+#endif
+
+ for (i = 0; i < abuf; i++) {
+#ifdef DEBUG
+ /*
+ * Allocate each buffer individually so they can be
+ * free()d during ntpd shutdown on DEBUG builds to
+ * keep them out of heap leak reports.
+ */
+ bufp = emalloc_zero(sizeof(*bufp));
+#endif
+ LINK_SLIST(free_recv_list, bufp, link);
+ bufp++;
+ free_recvbufs++;
+ total_recvbufs++;
+ }
+ lowater_adds++;
+}
+
+void
+init_recvbuff(int nbufs)
+{
+
+ /*
+ * Init buffer free list and stat counters
+ */
+ free_recvbufs = total_recvbufs = 0;
+ full_recvbufs = lowater_adds = 0;
+
+ create_buffers(nbufs);
+
+#if defined(SYS_WINNT)
+ InitializeCriticalSection(&RecvLock);
+#endif
+
+#ifdef DEBUG
+ atexit(&uninit_recvbuff);
+#endif
+}
+
+
+#ifdef DEBUG
+static void
+uninit_recvbuff(void)
+{
+ recvbuf_t *rbunlinked;
+
+ for (;;) {
+ UNLINK_FIFO(rbunlinked, full_recv_fifo, link);
+ if (rbunlinked == NULL)
+ break;
+ free(rbunlinked);
+ }
+
+ for (;;) {
+ UNLINK_HEAD_SLIST(rbunlinked, free_recv_list, link);
+ if (rbunlinked == NULL)
+ break;
+ free(rbunlinked);
+ }
+}
+#endif /* DEBUG */
+
+
+/*
+ * freerecvbuf - make a single recvbuf available for reuse
+ */
+void
+freerecvbuf(recvbuf_t *rb)
+{
+ if (rb) {
+ LOCK();
+ rb->used--;
+ if (rb->used != 0)
+ msyslog(LOG_ERR, "******** freerecvbuff non-zero usage: %d *******", rb->used);
+ LINK_SLIST(free_recv_list, rb, link);
+ free_recvbufs++;
+ UNLOCK();
+ }
+}
+
+
+void
+add_full_recv_buffer(recvbuf_t *rb)
+{
+ if (rb == NULL) {
+ msyslog(LOG_ERR, "add_full_recv_buffer received NULL buffer");
+ return;
+ }
+ LOCK();
+ LINK_FIFO(full_recv_fifo, rb, link);
+ full_recvbufs++;
+ UNLOCK();
+}
+
+
+recvbuf_t *
+get_free_recv_buffer(void)
+{
+ recvbuf_t *buffer;
+
+ LOCK();
+ UNLINK_HEAD_SLIST(buffer, free_recv_list, link);
+ if (buffer != NULL) {
+ free_recvbufs--;
+ initialise_buffer(buffer);
+ buffer->used++;
+ } else {
+ buffer_shortfall++;
+ }
+ UNLOCK();
+
+ return buffer;
+}
+
+
+#ifdef HAVE_IO_COMPLETION_PORT
+recvbuf_t *
+get_free_recv_buffer_alloc(void)
+{
+ recvbuf_t *buffer;
+
+ buffer = get_free_recv_buffer();
+ if (NULL == buffer) {
+ create_buffers(RECV_INC);
+ buffer = get_free_recv_buffer();
+ }
+ ENSURE(buffer != NULL);
+ return (buffer);
+}
+#endif
+
+
+recvbuf_t *
+get_full_recv_buffer(void)
+{
+ recvbuf_t * rbuf;
+
+ LOCK();
+
+#ifdef HAVE_SIGNALED_IO
+ /*
+ * make sure there are free buffers when we
+ * wander off to do lengthy packet processing with
+ * any buffer we grab from the full list.
+ *
+ * fixes malloc() interrupted by SIGIO risk
+ * (Bug 889)
+ */
+ if (NULL == free_recv_list || buffer_shortfall > 0) {
+ /*
+ * try to get us some more buffers
+ */
+ create_buffers(RECV_INC);
+ }
+#endif
+
+ /*
+ * try to grab a full buffer
+ */
+ UNLINK_FIFO(rbuf, full_recv_fifo, link);
+ if (rbuf != NULL)
+ full_recvbufs--;
+ UNLOCK();
+
+ return rbuf;
+}
+
+
+/*
+ * purge_recv_buffers_for_fd() - purges any previously-received input
+ * from a given file descriptor.
+ */
+void
+purge_recv_buffers_for_fd(
+ int fd
+ )
+{
+ recvbuf_t *rbufp;
+ recvbuf_t *next;
+ recvbuf_t *punlinked;
+
+ LOCK();
+
+ for (rbufp = HEAD_FIFO(full_recv_fifo);
+ rbufp != NULL;
+ rbufp = next) {
+ next = rbufp->link;
+# ifdef HAVE_IO_COMPLETION_PORT
+ if (rbufp->dstadr == NULL && rbufp->fd == fd)
+# else
+ if (rbufp->fd == fd)
+# endif
+ {
+ UNLINK_MID_FIFO(punlinked, full_recv_fifo,
+ rbufp, link, recvbuf_t);
+ INSIST(punlinked == rbufp);
+ full_recvbufs--;
+ freerecvbuf(rbufp);
+ }
+ }
+
+ UNLOCK();
+}
+
+
+/*
+ * Checks to see if there are buffers to process
+ */
+isc_boolean_t has_full_recv_buffer(void)
+{
+ if (HEAD_FIFO(full_recv_fifo) != NULL)
+ return (ISC_TRUE);
+ else
+ return (ISC_FALSE);
+}
+
+
+#ifdef NTP_DEBUG_LISTS_H
+void
+check_gen_fifo_consistency(void *fifo)
+{
+ gen_fifo *pf;
+ gen_node *pthis;
+ gen_node **pptail;
+
+ pf = fifo;
+ REQUIRE((NULL == pf->phead && NULL == pf->pptail) ||
+ (NULL != pf->phead && NULL != pf->pptail));
+
+ pptail = &pf->phead;
+ for (pthis = pf->phead;
+ pthis != NULL;
+ pthis = pthis->link)
+ if (NULL != pthis->link)
+ pptail = &pthis->link;
+
+ REQUIRE(NULL == pf->pptail || pptail == pf->pptail);
+}
+#endif /* NTP_DEBUG_LISTS_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/libntp/refidsmear.c b/sebhbsd/freebsd/contrib/ntp/libntp/refidsmear.c
new file mode 100644
index 0000000..f39926b
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/libntp/refidsmear.c
@@ -0,0 +1,60 @@
+#include <machine/rtems-bsd-user-space.h>
+
+#include <config.h>
+
+#include <ntp.h>
+#include <ntp_fp.h>
+#include <refidsmear.h>
+
+/*
+ * we want to test a refid format of:
+ * 254.x.y.x
+ *
+ * where x.y.z are 24 bits containing 2 (signed) integer bits
+ * and 22 fractional bits.
+ *
+ */
+
+
+l_fp
+convertRefIDToLFP(uint32_t r)
+{
+ l_fp temp;
+
+ r = ntohl(r);
+
+ // printf("%03d %08x: ", (r >> 24) & 0xFF, (r & 0x00FFFFFF) );
+
+ temp.l_uf = (r << 10); /* 22 fractional bits */
+
+ temp.l_ui = (r >> 22) & 0x3;
+ temp.l_ui |= ~(temp.l_ui & 2) + 1;
+
+ return temp;
+}
+
+
+uint32_t
+convertLFPToRefID(l_fp num)
+{
+ uint32_t temp;
+
+ /* round the input with the highest bit to shift out from the
+ * fraction, then keep just two bits from the integral part.
+ *
+ * TODO: check for overflows; should we clamp/saturate or just
+ * complain?
+ */
+ L_ADDUF(&num, 0x200);
+ num.l_ui &= 3;
+
+ /* combine integral and fractional part to 24 bits */
+ temp = (num.l_ui << 22) | (num.l_uf >> 10);
+
+ /* put in the leading 254.0.0.0 */
+ temp |= UINT32_C(0xFE000000);
+
+ // printf("%03d %08x: ", (temp >> 24) & 0xFF, (temp & 0x00FFFFFF) );
+
+ return htonl(temp);
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/libntp/refnumtoa.c b/sebhbsd/freebsd/contrib/ntp/libntp/refnumtoa.c
new file mode 100644
index 0000000..736c33c
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/libntp/refnumtoa.c
@@ -0,0 +1,38 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * refnumtoa - return asciized refclock addresses stored in local array space
+ */
+#include <config.h>
+#include <stdio.h>
+
+#include "ntp_net.h"
+#include "lib_strbuf.h"
+#include "ntp_stdlib.h"
+
+const char *
+refnumtoa(
+ sockaddr_u *num
+ )
+{
+ u_int32 netnum;
+ char *buf;
+ const char *rclock;
+
+ if (!ISREFCLOCKADR(num))
+ return socktoa(num);
+
+ LIB_GETBUF(buf);
+ netnum = SRCADR(num);
+ rclock = clockname((int)((u_long)netnum >> 8) & 0xff);
+
+ if (rclock != NULL)
+ snprintf(buf, LIB_BUFLENGTH, "%s(%lu)",
+ rclock, (u_long)netnum & 0xff);
+ else
+ snprintf(buf, LIB_BUFLENGTH, "REFCLK(%lu,%lu)",
+ ((u_long)netnum >> 8) & 0xff,
+ (u_long)netnum & 0xff);
+
+ return buf;
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/libntp/socket.c b/sebhbsd/freebsd/contrib/ntp/libntp/socket.c
new file mode 100644
index 0000000..2784236
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/libntp/socket.c
@@ -0,0 +1,220 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * socket.c - low-level socket operations
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+
+#include "ntp.h"
+#include "ntp_io.h"
+#include "ntp_net.h"
+#include "ntp_debug.h"
+
+/*
+ * Windows C runtime ioctl() can't deal properly with sockets,
+ * map to ioctlsocket for this source file.
+ */
+#ifdef SYS_WINNT
+#define ioctl(fd, opt, val) ioctlsocket(fd, opt, (u_long *)(val))
+#endif
+
+/*
+ * on Unix systems the stdio library typically
+ * makes use of file descriptors in the lower
+ * integer range. stdio usually will make use
+ * of the file descriptors in the range of
+ * [0..FOPEN_MAX)
+ * in order to keep this range clean, for socket
+ * file descriptors we attempt to move them above
+ * FOPEN_MAX. This is not as easy as it sounds as
+ * FOPEN_MAX changes from implementation to implementation
+ * and may exceed to current file decriptor limits.
+ * We are using following strategy:
+ * - keep a current socket fd boundary initialized with
+ * max(0, min(GETDTABLESIZE() - FD_CHUNK, FOPEN_MAX))
+ * - attempt to move the descriptor to the boundary or
+ * above.
+ * - if that fails and boundary > 0 set boundary
+ * to min(0, socket_fd_boundary - FD_CHUNK)
+ * -> retry
+ * if failure and boundary == 0 return old fd
+ * - on success close old fd return new fd
+ *
+ * effects:
+ * - fds will be moved above the socket fd boundary
+ * if at all possible.
+ * - the socket boundary will be reduced until
+ * allocation is possible or 0 is reached - at this
+ * point the algrithm will be disabled
+ */
+SOCKET
+move_fd(
+ SOCKET fd
+ )
+{
+#if !defined(SYS_WINNT) && defined(F_DUPFD)
+#ifndef FD_CHUNK
+#define FD_CHUNK 10
+#endif
+#ifndef FOPEN_MAX
+#define FOPEN_MAX 20
+#endif
+/*
+ * number of fds we would like to have for
+ * stdio FILE* available.
+ * we can pick a "low" number as our use of
+ * FILE* is limited to log files and temporarily
+ * to data and config files. Except for log files
+ * we don't keep the other FILE* open beyond the
+ * scope of the function that opened it.
+ */
+#ifndef FD_PREFERRED_SOCKBOUNDARY
+#define FD_PREFERRED_SOCKBOUNDARY 48
+#endif
+
+ static SOCKET socket_boundary = -1;
+ SOCKET newfd;
+
+ REQUIRE((int)fd >= 0);
+
+ /*
+ * check whether boundary has be set up
+ * already
+ */
+ if (socket_boundary == -1) {
+ socket_boundary = max(0, min(GETDTABLESIZE() - FD_CHUNK,
+ min(FOPEN_MAX, FD_PREFERRED_SOCKBOUNDARY)));
+ TRACE(1, ("move_fd: estimated max descriptors: %d, "
+ "initial socket boundary: %d\n",
+ GETDTABLESIZE(), socket_boundary));
+ }
+
+ /*
+ * Leave a space for stdio to work in. potentially moving the
+ * socket_boundary lower until allocation succeeds.
+ */
+ do {
+ if (fd >= 0 && fd < socket_boundary) {
+ /* inside reserved range: attempt to move fd */
+ newfd = fcntl(fd, F_DUPFD, socket_boundary);
+
+ if (newfd != -1) {
+ /* success: drop the old one - return the new one */
+ close(fd);
+ return newfd;
+ }
+ } else {
+ /* outside reserved range: no work - return the original one */
+ return fd;
+ }
+ socket_boundary = max(0, socket_boundary - FD_CHUNK);
+ TRACE(1, ("move_fd: selecting new socket boundary: %d\n",
+ socket_boundary));
+ } while (socket_boundary > 0);
+#else
+ ENSURE((int)fd >= 0);
+#endif /* !defined(SYS_WINNT) && defined(F_DUPFD) */
+ return fd;
+}
+
+
+/*
+ * make_socket_nonblocking() - set up descriptor to be non blocking
+ */
+void
+make_socket_nonblocking(
+ SOCKET fd
+ )
+{
+ /*
+ * set non-blocking,
+ */
+
+#ifdef USE_FIONBIO
+ /* in vxWorks we use FIONBIO, but the others are defined for old
+ * systems, so all hell breaks loose if we leave them defined
+ */
+#undef O_NONBLOCK
+#undef FNDELAY
+#undef O_NDELAY
+#endif
+
+#if defined(O_NONBLOCK) /* POSIX */
+ if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
+ msyslog(LOG_ERR,
+ "fcntl(O_NONBLOCK) fails on fd #%d: %m", fd);
+ exit(1);
+ }
+#elif defined(FNDELAY)
+ if (fcntl(fd, F_SETFL, FNDELAY) < 0) {
+ msyslog(LOG_ERR, "fcntl(FNDELAY) fails on fd #%d: %m",
+ fd);
+ exit(1);
+ }
+#elif defined(O_NDELAY) /* generally the same as FNDELAY */
+ if (fcntl(fd, F_SETFL, O_NDELAY) < 0) {
+ msyslog(LOG_ERR, "fcntl(O_NDELAY) fails on fd #%d: %m",
+ fd);
+ exit(1);
+ }
+#elif defined(FIONBIO)
+ {
+ int on = 1;
+
+ if (ioctl(fd, FIONBIO, &on) < 0) {
+ msyslog(LOG_ERR,
+ "ioctl(FIONBIO) fails on fd #%d: %m",
+ fd);
+ exit(1);
+ }
+ }
+#elif defined(FIOSNBIO)
+ if (ioctl(fd, FIOSNBIO, &on) < 0) {
+ msyslog(LOG_ERR,
+ "ioctl(FIOSNBIO) fails on fd #%d: %m", fd);
+ exit(1);
+ }
+#else
+# include "Bletch: Need non-blocking I/O!"
+#endif
+}
+
+#if 0
+
+/* The following subroutines should probably be moved here */
+
+static SOCKET
+open_socket(
+ sockaddr_u * addr,
+ int bcast,
+ int turn_off_reuse,
+ endpt * interf
+ )
+void
+sendpkt(
+ sockaddr_u * dest,
+ struct interface * ep,
+ int ttl,
+ struct pkt * pkt,
+ int len
+ )
+
+static inline int
+read_refclock_packet(SOCKET fd, struct refclockio *rp, l_fp ts)
+
+static inline int
+read_network_packet(
+ SOCKET fd,
+ struct interface * itf,
+ l_fp ts
+ )
+
+void
+kill_asyncio(int startfd)
+
+#endif /* 0 */
diff --git a/sebhbsd/freebsd/contrib/ntp/libntp/socktoa.c b/sebhbsd/freebsd/contrib/ntp/libntp/socktoa.c
new file mode 100644
index 0000000..6e43314
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/libntp/socktoa.c
@@ -0,0 +1,172 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * socktoa.c socktoa(), sockporttoa(), and sock_hash()
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sys/types.h>
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#include <stdio.h>
+#include <arpa/inet.h>
+#include <isc/result.h>
+#include <isc/netaddr.h>
+#include <isc/sockaddr.h>
+
+#include "ntp_fp.h"
+#include "lib_strbuf.h"
+#include "ntp_stdlib.h"
+#include "ntp.h"
+
+/*
+ * socktoa - return a numeric host name from a sockaddr_storage structure
+ */
+const char *
+socktoa(
+ const sockaddr_u *sock
+ )
+{
+ int saved_errno;
+ char * res;
+ char * addr;
+ u_long scope;
+
+ saved_errno = socket_errno();
+ LIB_GETBUF(res);
+
+ if (NULL == sock) {
+ strlcpy(res, "(null)", LIB_BUFLENGTH);
+ } else {
+ switch(AF(sock)) {
+
+ case AF_INET:
+ case AF_UNSPEC:
+ inet_ntop(AF_INET, PSOCK_ADDR4(sock), res,
+ LIB_BUFLENGTH);
+ break;
+
+ case AF_INET6:
+ inet_ntop(AF_INET6, PSOCK_ADDR6(sock), res,
+ LIB_BUFLENGTH);
+ scope = SCOPE_VAR(sock);
+ if (0 != scope && !strchr(res, '%')) {
+ addr = res;
+ LIB_GETBUF(res);
+ snprintf(res, LIB_BUFLENGTH, "%s%%%lu",
+ addr, scope);
+ res[LIB_BUFLENGTH - 1] = '\0';
+ }
+ break;
+
+ default:
+ snprintf(res, LIB_BUFLENGTH,
+ "(socktoa unknown family %d)",
+ AF(sock));
+ }
+ }
+ errno = saved_errno;
+
+ return res;
+}
+
+
+const char *
+sockporttoa(
+ const sockaddr_u *sock
+ )
+{
+ int saved_errno;
+ const char * atext;
+ char * buf;
+
+ saved_errno = socket_errno();
+ atext = socktoa(sock);
+ LIB_GETBUF(buf);
+ snprintf(buf, LIB_BUFLENGTH,
+ (IS_IPV6(sock))
+ ? "[%s]:%hu"
+ : "%s:%hu",
+ atext, SRCPORT(sock));
+ errno = saved_errno;
+
+ return buf;
+}
+
+
+/*
+ * sock_hash - hash a sockaddr_u structure
+ */
+u_short
+sock_hash(
+ const sockaddr_u *addr
+ )
+{
+ u_int hashVal;
+ u_int j;
+ size_t len;
+ const u_char *pch;
+
+ hashVal = 0;
+ len = 0;
+
+ /*
+ * We can't just hash the whole thing because there are hidden
+ * fields in sockaddr_in6 that might be filled in by recvfrom(),
+ * so just use the family, port and address.
+ */
+ pch = (const void *)&AF(addr);
+ hashVal = 37 * hashVal + *pch;
+ if (sizeof(AF(addr)) > 1) {
+ pch++;
+ hashVal = 37 * hashVal + *pch;
+ }
+ switch(AF(addr)) {
+ case AF_INET:
+ pch = (const void *)&SOCK_ADDR4(addr);
+ len = sizeof(SOCK_ADDR4(addr));
+ break;
+
+ case AF_INET6:
+ pch = (const void *)&SOCK_ADDR6(addr);
+ len = sizeof(SOCK_ADDR6(addr));
+ break;
+ }
+
+ for (j = 0; j < len ; j++)
+ hashVal = 37 * hashVal + pch[j];
+
+ return (u_short)(hashVal & USHRT_MAX);
+}
+
+
+int
+sockaddr_masktoprefixlen(
+ const sockaddr_u * psa
+ )
+{
+ isc_netaddr_t isc_na;
+ isc_sockaddr_t isc_sa;
+ u_int pfxlen;
+ isc_result_t result;
+ int rc;
+
+ ZERO(isc_sa);
+ memcpy(&isc_sa.type, psa,
+ min(sizeof(isc_sa.type), sizeof(*psa)));
+ isc_netaddr_fromsockaddr(&isc_na, &isc_sa);
+ result = isc_netaddr_masktoprefixlen(&isc_na, &pfxlen);
+ rc = (ISC_R_SUCCESS == result)
+ ? (int)pfxlen
+ : -1;
+
+ return rc;
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/libntp/statestr.c b/sebhbsd/freebsd/contrib/ntp/libntp/statestr.c
new file mode 100644
index 0000000..428df55
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/libntp/statestr.c
@@ -0,0 +1,512 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * pretty printing of status information
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include "ntp_stdlib.h"
+#include "ntp_fp.h"
+#include "ntp.h"
+#include "lib_strbuf.h"
+#include "ntp_refclock.h"
+#include "ntp_control.h"
+#include "ntp_string.h"
+#ifdef KERNEL_PLL
+# include "ntp_syscall.h"
+#endif
+
+
+/*
+ * Structure for turning various constants into a readable string.
+ */
+struct codestring {
+ int code;
+ const char * const string1;
+ const char * const string0;
+};
+
+/*
+ * Leap status (leap)
+ */
+static const struct codestring leap_codes[] = {
+ { LEAP_NOWARNING, "leap_none", 0 },
+ { LEAP_ADDSECOND, "leap_add_sec", 0 },
+ { LEAP_DELSECOND, "leap_del_sec", 0 },
+ { LEAP_NOTINSYNC, "leap_alarm", 0 },
+ { -1, "leap", 0 }
+};
+
+/*
+ * Clock source status (sync)
+ */
+static const struct codestring sync_codes[] = {
+ { CTL_SST_TS_UNSPEC, "sync_unspec", 0 },
+ { CTL_SST_TS_ATOM, "sync_pps", 0 },
+ { CTL_SST_TS_LF, "sync_lf_radio", 0 },
+ { CTL_SST_TS_HF, "sync_hf_radio", 0 },
+ { CTL_SST_TS_UHF, "sync_uhf_radio", 0 },
+ { CTL_SST_TS_LOCAL, "sync_local", 0 },
+ { CTL_SST_TS_NTP, "sync_ntp", 0 },
+ { CTL_SST_TS_UDPTIME, "sync_other", 0 },
+ { CTL_SST_TS_WRSTWTCH, "sync_wristwatch", 0 },
+ { CTL_SST_TS_TELEPHONE, "sync_telephone", 0 },
+ { -1, "sync", 0 }
+};
+
+/*
+ * Peer selection status (sel)
+ */
+static const struct codestring select_codes[] = {
+ { CTL_PST_SEL_REJECT, "sel_reject", 0 },
+ { CTL_PST_SEL_SANE, "sel_falsetick", 0 },
+ { CTL_PST_SEL_CORRECT, "sel_excess", 0 },
+ { CTL_PST_SEL_SELCAND, "sel_outlier", 0 },
+ { CTL_PST_SEL_SYNCCAND, "sel_candidate", 0 },
+ { CTL_PST_SEL_EXCESS, "sel_backup", 0 },
+ { CTL_PST_SEL_SYSPEER, "sel_sys.peer", 0 },
+ { CTL_PST_SEL_PPS, "sel_pps.peer", 0 },
+ { -1, "sel", 0 }
+};
+
+/*
+ * Clock status (clk)
+ */
+static const struct codestring clock_codes[] = {
+ { CTL_CLK_OKAY, "clk_unspec", 0 },
+ { CTL_CLK_NOREPLY, "clk_no_reply", 0 },
+ { CTL_CLK_BADFORMAT, "clk_bad_format", 0 },
+ { CTL_CLK_FAULT, "clk_fault", 0 },
+ { CTL_CLK_PROPAGATION, "clk_bad_signal", 0 },
+ { CTL_CLK_BADDATE, "clk_bad_date", 0 },
+ { CTL_CLK_BADTIME, "clk_bad_time", 0 },
+ { -1, "clk", 0 }
+};
+
+
+#ifdef FLASH_CODES_UNUSED
+/*
+ * Flash bits -- see ntpq.c tstflags & tstflagnames
+ */
+static const struct codestring flash_codes[] = {
+ { TEST1, "pkt_dup", 0 },
+ { TEST2, "pkt_bogus", 0 },
+ { TEST3, "pkt_unsync", 0 },
+ { TEST4, "pkt_denied", 0 },
+ { TEST5, "pkt_auth", 0 },
+ { TEST6, "pkt_stratum", 0 },
+ { TEST7, "pkt_header", 0 },
+ { TEST8, "pkt_autokey", 0 },
+ { TEST9, "pkt_crypto", 0 },
+ { TEST10, "peer_stratum", 0 },
+ { TEST11, "peer_dist", 0 },
+ { TEST12, "peer_loop", 0 },
+ { TEST13, "peer_unreach", 0 },
+ { -1, "flash", 0 }
+};
+#endif
+
+
+/*
+ * System events (sys)
+ */
+static const struct codestring sys_codes[] = {
+ { EVNT_UNSPEC, "unspecified", 0 },
+ { EVNT_NSET, "freq_not_set", 0 },
+ { EVNT_FSET, "freq_set", 0 },
+ { EVNT_SPIK, "spike_detect", 0 },
+ { EVNT_FREQ, "freq_mode", 0 },
+ { EVNT_SYNC, "clock_sync", 0 },
+ { EVNT_SYSRESTART, "restart", 0 },
+ { EVNT_SYSFAULT, "panic_stop", 0 },
+ { EVNT_NOPEER, "no_sys_peer", 0 },
+ { EVNT_ARMED, "leap_armed", 0 },
+ { EVNT_DISARMED, "leap_disarmed", 0 },
+ { EVNT_LEAP, "leap_event", 0 },
+ { EVNT_CLOCKRESET, "clock_step", 0 },
+ { EVNT_KERN, "kern", 0 },
+ { EVNT_TAI, "TAI", 0 },
+ { EVNT_LEAPVAL, "stale_leapsecond_values", 0 },
+ { -1, "", 0 }
+};
+
+/*
+ * Peer events (peer)
+ */
+static const struct codestring peer_codes[] = {
+ { PEVNT_MOBIL & ~PEER_EVENT, "mobilize", 0 },
+ { PEVNT_DEMOBIL & ~PEER_EVENT, "demobilize", 0 },
+ { PEVNT_UNREACH & ~PEER_EVENT, "unreachable", 0 },
+ { PEVNT_REACH & ~PEER_EVENT, "reachable", 0 },
+ { PEVNT_RESTART & ~PEER_EVENT, "restart", 0 },
+ { PEVNT_REPLY & ~PEER_EVENT, "no_reply", 0 },
+ { PEVNT_RATE & ~PEER_EVENT, "rate_exceeded", 0 },
+ { PEVNT_DENY & ~PEER_EVENT, "access_denied", 0 },
+ { PEVNT_ARMED & ~PEER_EVENT, "leap_armed", 0 },
+ { PEVNT_NEWPEER & ~PEER_EVENT, "sys_peer", 0 },
+ { PEVNT_CLOCK & ~PEER_EVENT, "clock_event", 0 },
+ { PEVNT_AUTH & ~PEER_EVENT, "bad_auth", 0 },
+ { PEVNT_POPCORN & ~PEER_EVENT, "popcorn", 0 },
+ { PEVNT_XLEAVE & ~PEER_EVENT, "interleave_mode", 0 },
+ { PEVNT_XERR & ~PEER_EVENT, "interleave_error", 0 },
+ { -1, "", 0 }
+};
+
+/*
+ * Peer status bits
+ */
+static const struct codestring peer_st_bits[] = {
+ { CTL_PST_CONFIG, "conf", 0 },
+ { CTL_PST_AUTHENABLE, "authenb", 0 },
+ { CTL_PST_AUTHENTIC, "auth", 0 },
+ { CTL_PST_REACH, "reach", 0 },
+ { CTL_PST_BCAST, "bcast", 0 },
+ /* not used with getcode(), no terminating entry needed */
+};
+
+/*
+ * Restriction match bits
+ */
+static const struct codestring res_match_bits[] = {
+ { RESM_NTPONLY, "ntpport", 0 },
+ { RESM_INTERFACE, "interface", 0 },
+ { RESM_SOURCE, "source", 0 },
+ /* not used with getcode(), no terminating entry needed */
+};
+
+/*
+ * Restriction access bits
+ */
+static const struct codestring res_access_bits[] = {
+ { RES_IGNORE, "ignore", 0 },
+ { RES_DONTSERVE, "noserve", "serve" },
+ { RES_DONTTRUST, "notrust", "trust" },
+ { RES_NOQUERY, "noquery", "query" },
+ { RES_NOMODIFY, "nomodify", 0 },
+ { RES_NOPEER, "nopeer", "peer" },
+ { RES_NOEPEER, "noepeer", "epeer" },
+ { RES_NOTRAP, "notrap", "trap" },
+ { RES_LPTRAP, "lptrap", 0 },
+ { RES_LIMITED, "limited", 0 },
+ { RES_VERSION, "version", 0 },
+ { RES_KOD, "kod", 0 },
+ { RES_FLAKE, "flake", 0 },
+ /* not used with getcode(), no terminating entry needed */
+};
+
+#ifdef AUTOKEY
+/*
+ * Crypto events (cryp)
+ */
+static const struct codestring crypto_codes[] = {
+ { XEVNT_OK & ~CRPT_EVENT, "success", 0 },
+ { XEVNT_LEN & ~CRPT_EVENT, "bad_field_format_or_length", 0 },
+ { XEVNT_TSP & ~CRPT_EVENT, "bad_timestamp", 0 },
+ { XEVNT_FSP & ~CRPT_EVENT, "bad_filestamp", 0 },
+ { XEVNT_PUB & ~CRPT_EVENT, "bad_or_missing_public_key", 0 },
+ { XEVNT_MD & ~CRPT_EVENT, "unsupported_digest_type", 0 },
+ { XEVNT_KEY & ~CRPT_EVENT, "unsupported_identity_type", 0 },
+ { XEVNT_SGL & ~CRPT_EVENT, "bad_signature_length", 0 },
+ { XEVNT_SIG & ~CRPT_EVENT, "signature_not_verified", 0 },
+ { XEVNT_VFY & ~CRPT_EVENT, "certificate_not_verified", 0 },
+ { XEVNT_PER & ~CRPT_EVENT, "host_certificate_expired", 0 },
+ { XEVNT_CKY & ~CRPT_EVENT, "bad_or_missing_cookie", 0 },
+ { XEVNT_DAT & ~CRPT_EVENT, "bad_or_missing_leapseconds", 0 },
+ { XEVNT_CRT & ~CRPT_EVENT, "bad_or_missing_certificate", 0 },
+ { XEVNT_ID & ~CRPT_EVENT, "bad_or_missing_group key", 0 },
+ { XEVNT_ERR & ~CRPT_EVENT, "protocol_error", 0 },
+ { -1, "", 0 }
+};
+#endif /* AUTOKEY */
+
+#ifdef KERNEL_PLL
+/*
+ * kernel discipline status bits
+ */
+static const struct codestring k_st_bits[] = {
+# ifdef STA_PLL
+ { STA_PLL, "pll", 0 },
+# endif
+# ifdef STA_PPSFREQ
+ { STA_PPSFREQ, "ppsfreq", 0 },
+# endif
+# ifdef STA_PPSTIME
+ { STA_PPSTIME, "ppstime", 0 },
+# endif
+# ifdef STA_FLL
+ { STA_FLL, "fll", 0 },
+# endif
+# ifdef STA_INS
+ { STA_INS, "ins", 0 },
+# endif
+# ifdef STA_DEL
+ { STA_DEL, "del", 0 },
+# endif
+# ifdef STA_UNSYNC
+ { STA_UNSYNC, "unsync", 0 },
+# endif
+# ifdef STA_FREQHOLD
+ { STA_FREQHOLD, "freqhold", 0 },
+# endif
+# ifdef STA_PPSSIGNAL
+ { STA_PPSSIGNAL, "ppssignal", 0 },
+# endif
+# ifdef STA_PPSJITTER
+ { STA_PPSJITTER, "ppsjitter", 0 },
+# endif
+# ifdef STA_PPSWANDER
+ { STA_PPSWANDER, "ppswander", 0 },
+# endif
+# ifdef STA_PPSERROR
+ { STA_PPSERROR, "ppserror", 0 },
+# endif
+# ifdef STA_CLOCKERR
+ { STA_CLOCKERR, "clockerr", 0 },
+# endif
+# ifdef STA_NANO
+ { STA_NANO, "nano", 0 },
+# endif
+# ifdef STA_MODE
+ { STA_MODE, "mode=fll", 0 },
+# endif
+# ifdef STA_CLK
+ { STA_CLK, "src=B", 0 },
+# endif
+ /* not used with getcode(), no terminating entry needed */
+};
+#endif /* KERNEL_PLL */
+
+/* Forwards */
+static const char * getcode(int, const struct codestring *);
+static const char * getevents(int);
+static const char * peer_st_flags(u_char pst);
+
+/*
+ * getcode - return string corresponding to code
+ */
+static const char *
+getcode(
+ int code,
+ const struct codestring * codetab
+ )
+{
+ char * buf;
+
+ while (codetab->code != -1) {
+ if (codetab->code == code)
+ return codetab->string1;
+ codetab++;
+ }
+
+ LIB_GETBUF(buf);
+ snprintf(buf, LIB_BUFLENGTH, "%s_%d", codetab->string1, code);
+
+ return buf;
+}
+
+/*
+ * getevents - return a descriptive string for the event count
+ */
+static const char *
+getevents(
+ int cnt
+ )
+{
+ char * buf;
+
+ if (cnt == 0)
+ return "no events";
+
+ LIB_GETBUF(buf);
+ snprintf(buf, LIB_BUFLENGTH, "%d event%s", cnt,
+ (1 == cnt)
+ ? ""
+ : "s");
+
+ return buf;
+}
+
+
+/*
+ * decode_bitflags()
+ *
+ * returns a human-readable string with a keyword from tab for each bit
+ * set in bits, separating multiple entries with text of sep2.
+ */
+static const char *
+decode_bitflags(
+ int bits,
+ const char * sep2,
+ const struct codestring * tab,
+ size_t tab_ct
+ )
+{
+ const char * sep;
+ char * buf;
+ char * pch;
+ char * lim;
+ size_t b;
+ int rc;
+ int saved_errno; /* for use in DPRINTF with %m */
+
+ saved_errno = errno;
+ LIB_GETBUF(buf);
+ pch = buf;
+ lim = buf + LIB_BUFLENGTH;
+ sep = "";
+
+ for (b = 0; b < tab_ct; b++) {
+ const char * flagstr;
+
+ if (tab[b].code & bits) {
+ flagstr = tab[b].string1;
+ } else {
+ flagstr = tab[b].string0;
+ }
+
+ if (flagstr) {
+ size_t avail = lim - pch;
+ rc = snprintf(pch, avail, "%s%s", sep,
+ flagstr);
+ if ((size_t)rc >= avail)
+ goto toosmall;
+ pch += rc;
+ sep = sep2;
+ }
+ }
+
+ return buf;
+
+ toosmall:
+ snprintf(buf, LIB_BUFLENGTH,
+ "decode_bitflags(%s) can't decode 0x%x in %d bytes",
+ (tab == peer_st_bits)
+ ? "peer_st"
+ :
+#ifdef KERNEL_PLL
+ (tab == k_st_bits)
+ ? "kern_st"
+ :
+#endif
+ "",
+ bits, (int)LIB_BUFLENGTH);
+ errno = saved_errno;
+
+ return buf;
+}
+
+
+static const char *
+peer_st_flags(
+ u_char pst
+ )
+{
+ return decode_bitflags(pst, ", ", peer_st_bits,
+ COUNTOF(peer_st_bits));
+}
+
+
+const char *
+res_match_flags(
+ u_short mf
+ )
+{
+ return decode_bitflags(mf, " ", res_match_bits,
+ COUNTOF(res_match_bits));
+}
+
+
+const char *
+res_access_flags(
+ u_short af
+ )
+{
+ return decode_bitflags(af, " ", res_access_bits,
+ COUNTOF(res_access_bits));
+}
+
+
+#ifdef KERNEL_PLL
+const char *
+k_st_flags(
+ u_int32 st
+ )
+{
+ return decode_bitflags(st, " ", k_st_bits, COUNTOF(k_st_bits));
+}
+#endif /* KERNEL_PLL */
+
+
+/*
+ * statustoa - return a descriptive string for a peer status
+ */
+char *
+statustoa(
+ int type,
+ int st
+ )
+{
+ char * cb;
+ char * cc;
+ u_char pst;
+
+ LIB_GETBUF(cb);
+
+ switch (type) {
+
+ case TYPE_SYS:
+ snprintf(cb, LIB_BUFLENGTH, "%s, %s, %s, %s",
+ getcode(CTL_SYS_LI(st), leap_codes),
+ getcode(CTL_SYS_SOURCE(st), sync_codes),
+ getevents(CTL_SYS_NEVNT(st)),
+ getcode(CTL_SYS_EVENT(st), sys_codes));
+ break;
+
+ case TYPE_PEER:
+ pst = (u_char)CTL_PEER_STATVAL(st);
+ snprintf(cb, LIB_BUFLENGTH, "%s, %s, %s",
+ peer_st_flags(pst),
+ getcode(pst & 0x7, select_codes),
+ getevents(CTL_PEER_NEVNT(st)));
+ if (CTL_PEER_EVENT(st) != EVNT_UNSPEC) {
+ cc = cb + strlen(cb);
+ snprintf(cc, LIB_BUFLENGTH - (cc - cb), ", %s",
+ getcode(CTL_PEER_EVENT(st),
+ peer_codes));
+ }
+ break;
+
+ case TYPE_CLOCK:
+ snprintf(cb, LIB_BUFLENGTH, "%s, %s",
+ getevents(CTL_SYS_NEVNT(st)),
+ getcode((st) & 0xf, clock_codes));
+ break;
+ }
+
+ return cb;
+}
+
+const char *
+eventstr(
+ int num
+ )
+{
+ if (num & PEER_EVENT)
+ return (getcode(num & ~PEER_EVENT, peer_codes));
+#ifdef AUTOKEY
+ else if (num & CRPT_EVENT)
+ return (getcode(num & ~CRPT_EVENT, crypto_codes));
+#endif /* AUTOKEY */
+ else
+ return (getcode(num, sys_codes));
+}
+
+const char *
+ceventstr(
+ int num
+ )
+{
+ return getcode(num, clock_codes);
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/libntp/systime.c b/sebhbsd/freebsd/contrib/ntp/libntp/systime.c
new file mode 100644
index 0000000..3b75f1a
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/libntp/systime.c
@@ -0,0 +1,685 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * systime -- routines to fiddle a UNIX clock.
+ *
+ * ATTENTION: Get approval from Dave Mills on all changes to this file!
+ *
+ */
+#include <config.h>
+#include <math.h>
+
+#include "ntp.h"
+#include "ntpd.h"
+#include "ntp_syslog.h"
+#include "ntp_stdlib.h"
+#include "ntp_random.h"
+#include "iosignal.h"
+#include "timevalops.h"
+#include "timespecops.h"
+#include "ntp_calendar.h"
+#include "lib_strbuf.h"
+
+#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif
+#ifdef HAVE_UTMP_H
+# include <utmp.h>
+#endif /* HAVE_UTMP_H */
+#ifdef HAVE_UTMPX_H
+# include <utmpx.h>
+#endif /* HAVE_UTMPX_H */
+
+int allow_panic = FALSE; /* allow panic correction (-g) */
+int enable_panic_check = TRUE; /* Can we check allow_panic's state? */
+
+u_long sys_lamport; /* Lamport violation */
+u_long sys_tsrounding; /* timestamp rounding errors */
+
+#ifndef USE_COMPILETIME_PIVOT
+# define USE_COMPILETIME_PIVOT 1
+#endif
+
+/*
+ * These routines (get_systime, step_systime, adj_systime) implement an
+ * interface between the system independent NTP clock and the Unix
+ * system clock in various architectures and operating systems. Time is
+ * a precious quantity in these routines and every effort is made to
+ * minimize errors by unbiased rounding and amortizing adjustment
+ * residues.
+ *
+ * In order to improve the apparent resolution, provide unbiased
+ * rounding and most importantly ensure that the readings cannot be
+ * predicted, the low-order unused portion of the time below the minimum
+ * time to read the clock is filled with an unbiased random fuzz.
+ *
+ * The sys_tick variable specifies the system clock tick interval in
+ * seconds, for stepping clocks, defined as those which return times
+ * less than MINSTEP greater than the previous reading. For systems that
+ * use a high-resolution counter such that each clock reading is always
+ * at least MINSTEP greater than the prior, sys_tick is the time to read
+ * the system clock.
+ *
+ * The sys_fuzz variable measures the minimum time to read the system
+ * clock, regardless of its precision. When reading the system clock
+ * using get_systime() after sys_tick and sys_fuzz have been determined,
+ * ntpd ensures each unprocessed clock reading is no less than sys_fuzz
+ * later than the prior unprocessed reading, and then fuzzes the bits
+ * below sys_fuzz in the timestamp returned, ensuring each of its
+ * resulting readings is strictly later than the previous.
+ *
+ * When slewing the system clock using adj_systime() (with the kernel
+ * loop discipline unavailable or disabled), adjtime() offsets are
+ * quantized to sys_tick, if sys_tick is greater than sys_fuzz, which
+ * is to say if the OS presents a stepping clock. Otherwise, offsets
+ * are quantized to the microsecond resolution of adjtime()'s timeval
+ * input. The remaining correction sys_residual is carried into the
+ * next adjtime() and meanwhile is also factored into get_systime()
+ * readings.
+ */
+double sys_tick = 0; /* tick size or time to read (s) */
+double sys_fuzz = 0; /* min. time to read the clock (s) */
+long sys_fuzz_nsec = 0; /* min. time to read the clock (ns) */
+double measured_tick; /* non-overridable sys_tick (s) */
+double sys_residual = 0; /* adjustment residue (s) */
+int trunc_os_clock; /* sys_tick > measured_tick */
+time_stepped_callback step_callback;
+
+#ifndef SIM
+/* perlinger@ntp.org: As 'get_sysime()' does it's own check for clock
+ * backstepping, this could probably become a local variable in
+ * 'get_systime()' and the cruft associated with communicating via a
+ * static value could be removed after the v4.2.8 release.
+ */
+static int lamport_violated; /* clock was stepped back */
+#endif /* !SIM */
+
+#ifdef DEBUG
+static int systime_init_done;
+# define DONE_SYSTIME_INIT() systime_init_done = TRUE
+#else
+# define DONE_SYSTIME_INIT() do {} while (FALSE)
+#endif
+
+#ifdef HAVE_SIGNALED_IO
+int using_sigio;
+#endif
+
+#ifdef SYS_WINNT
+CRITICAL_SECTION get_systime_cs;
+#endif
+
+
+void
+set_sys_fuzz(
+ double fuzz_val
+ )
+{
+ sys_fuzz = fuzz_val;
+ INSIST(sys_fuzz >= 0);
+ INSIST(sys_fuzz <= 1.0);
+ /* [Bug 3450] ensure nsec fuzz >= sys_fuzz to reduce chance of
+ * short-falling fuzz advance
+ */
+ sys_fuzz_nsec = (long)ceil(sys_fuzz * 1e9);
+}
+
+
+void
+init_systime(void)
+{
+ INIT_GET_SYSTIME_CRITSEC();
+ INIT_WIN_PRECISE_TIME();
+ DONE_SYSTIME_INIT();
+}
+
+
+#ifndef SIM /* ntpsim.c has get_systime() and friends for sim */
+
+static inline void
+get_ostime(
+ struct timespec * tsp
+ )
+{
+ int rc;
+ long ticks;
+
+#if defined(HAVE_CLOCK_GETTIME)
+ rc = clock_gettime(CLOCK_REALTIME, tsp);
+#elif defined(HAVE_GETCLOCK)
+ rc = getclock(TIMEOFDAY, tsp);
+#else
+ struct timeval tv;
+
+ rc = GETTIMEOFDAY(&tv, NULL);
+ tsp->tv_sec = tv.tv_sec;
+ tsp->tv_nsec = tv.tv_usec * 1000;
+#endif
+ if (rc < 0) {
+ msyslog(LOG_ERR, "read system clock failed: %m (%d)",
+ errno);
+ exit(1);
+ }
+
+ if (trunc_os_clock) {
+ ticks = (long)((tsp->tv_nsec * 1e-9) / sys_tick);
+ tsp->tv_nsec = (long)(ticks * 1e9 * sys_tick);
+ }
+}
+
+
+/*
+ * get_systime - return system time in NTP timestamp format.
+ */
+void
+get_systime(
+ l_fp *now /* system time */
+ )
+{
+ static struct timespec ts_last; /* last sampled os time */
+ static struct timespec ts_prev; /* prior os time */
+ static l_fp lfp_prev; /* prior result */
+ struct timespec ts; /* seconds and nanoseconds */
+ struct timespec ts_min; /* earliest permissible */
+ struct timespec ts_lam; /* lamport fictional increment */
+ double dfuzz;
+ l_fp result;
+ l_fp lfpfuzz;
+ l_fp lfpdelta;
+
+ get_ostime(&ts);
+ DEBUG_REQUIRE(systime_init_done);
+ ENTER_GET_SYSTIME_CRITSEC();
+
+ /* First check if here was a Lamport violation, that is, two
+ * successive calls to 'get_ostime()' resulted in negative
+ * time difference. Use a few milliseconds of permissible
+ * tolerance -- being too sharp can hurt here. (This is intented
+ * for the Win32 target, where the HPC interpolation might
+ * introduce small steps backward. It should not be an issue on
+ * systems where get_ostime() results in a true syscall.)
+ */
+ if (cmp_tspec(add_tspec_ns(ts, 50000000), ts_last) < 0) {
+ lamport_violated = 1;
+ sys_lamport++;
+ }
+ ts_last = ts;
+
+ /*
+ * After default_get_precision() has set a nonzero sys_fuzz,
+ * ensure every reading of the OS clock advances by at least
+ * sys_fuzz over the prior reading, thereby assuring each
+ * fuzzed result is strictly later than the prior. Limit the
+ * necessary fiction to 1 second.
+ */
+ if (!USING_SIGIO()) {
+ ts_min = add_tspec_ns(ts_prev, sys_fuzz_nsec);
+ if (cmp_tspec(ts, ts_min) < 0) {
+ ts_lam = sub_tspec(ts_min, ts);
+ if (ts_lam.tv_sec > 0 && !lamport_violated) {
+ msyslog(LOG_ERR,
+ "get_systime Lamport advance exceeds one second (%.9f)",
+ ts_lam.tv_sec +
+ 1e-9 * ts_lam.tv_nsec);
+ exit(1);
+ }
+ if (!lamport_violated)
+ ts = ts_min;
+ }
+ ts_prev = ts;
+ }
+
+ /* convert from timespec to l_fp fixed-point */
+ result = tspec_stamp_to_lfp(ts);
+
+ /*
+ * Add in the fuzz. 'ntp_random()' returns [0..2**31-1] so we
+ * must scale up the result by 2.0 to cover the full fractional
+ * range.
+ */
+ dfuzz = ntp_random() * 2. / FRAC * sys_fuzz;
+ DTOLFP(dfuzz, &lfpfuzz);
+ L_ADD(&result, &lfpfuzz);
+
+ /*
+ * Ensure result is strictly greater than prior result (ignoring
+ * sys_residual's effect for now) once sys_fuzz has been
+ * determined.
+ *
+ * [Bug 3450] Rounding errors and time slew can lead to a
+ * violation of the expected postcondition. This is bound to
+ * happen from time to time (depending on state of the random
+ * generator, the current slew and the closeness of system time
+ * stamps drawn) and does not warrant a syslog entry. Instead it
+ * makes much more sense to ensure the postcondition and hop
+ * along silently.
+ */
+ if (!USING_SIGIO()) {
+ if ( !L_ISZERO(&lfp_prev)
+ && !lamport_violated
+ && (sys_fuzz > 0.0)
+ ) {
+ lfpdelta = result;
+ L_SUB(&lfpdelta, &lfp_prev);
+ L_SUBUF(&lfpdelta, 1);
+ if (lfpdelta.l_i < 0)
+ {
+ L_NEG(&lfpdelta);
+ DPRINTF(1, ("get_systime: postcond failed by %s secs, fixed\n",
+ lfptoa(&lfpdelta, 9)));
+ result = lfp_prev;
+ L_ADDUF(&result, 1);
+ sys_tsrounding++;
+ }
+ }
+ lfp_prev = result;
+ if (lamport_violated)
+ lamport_violated = FALSE;
+ }
+ LEAVE_GET_SYSTIME_CRITSEC();
+ *now = result;
+}
+
+
+/*
+ * adj_systime - adjust system time by the argument.
+ */
+#if !defined SYS_WINNT
+int /* 0 okay, 1 error */
+adj_systime(
+ double now /* adjustment (s) */
+ )
+{
+ struct timeval adjtv; /* new adjustment */
+ struct timeval oadjtv; /* residual adjustment */
+ double quant; /* quantize to multiples of */
+ double dtemp;
+ long ticks;
+ int isneg = 0;
+
+ /*
+ * The Windows port adj_systime() depends on being called each
+ * second even when there's no additional correction, to allow
+ * emulation of adjtime() behavior on top of an API that simply
+ * sets the current rate. This POSIX implementation needs to
+ * ignore invocations with zero correction, otherwise ongoing
+ * EVNT_NSET adjtime() can be aborted by a tiny adjtime()
+ * triggered by sys_residual.
+ */
+ if (0. == now) {
+ if (enable_panic_check && allow_panic) {
+ msyslog(LOG_ERR, "adj_systime: allow_panic is TRUE!");
+ INSIST(!allow_panic);
+ }
+ return TRUE;
+ }
+
+ /*
+ * Most Unix adjtime() implementations adjust the system clock
+ * in microsecond quanta, but some adjust in 10-ms quanta. We
+ * carefully round the adjustment to the nearest quantum, then
+ * adjust in quanta and keep the residue for later.
+ */
+ dtemp = now + sys_residual;
+ if (dtemp < 0) {
+ isneg = 1;
+ dtemp = -dtemp;
+ }
+ adjtv.tv_sec = (long)dtemp;
+ dtemp -= adjtv.tv_sec;
+ if (sys_tick > sys_fuzz)
+ quant = sys_tick;
+ else
+ quant = 1e-6;
+ ticks = (long)(dtemp / quant + .5);
+ adjtv.tv_usec = (long)(ticks * quant * 1.e6 + .5);
+ /* The rounding in the conversions could us push over the
+ * limits: make sure the result is properly normalised!
+ * note: sign comes later, all numbers non-negative here.
+ */
+ if (adjtv.tv_usec >= 1000000) {
+ adjtv.tv_sec += 1;
+ adjtv.tv_usec -= 1000000;
+ dtemp -= 1.;
+ }
+ /* set the new residual with leftover from correction */
+ sys_residual = dtemp - adjtv.tv_usec * 1.e-6;
+
+ /*
+ * Convert to signed seconds and microseconds for the Unix
+ * adjtime() system call. Note we purposely lose the adjtime()
+ * leftover.
+ */
+ if (isneg) {
+ adjtv.tv_sec = -adjtv.tv_sec;
+ adjtv.tv_usec = -adjtv.tv_usec;
+ sys_residual = -sys_residual;
+ }
+ if (adjtv.tv_sec != 0 || adjtv.tv_usec != 0) {
+ if (adjtime(&adjtv, &oadjtv) < 0) {
+ msyslog(LOG_ERR, "adj_systime: %m");
+ if (enable_panic_check && allow_panic) {
+ msyslog(LOG_ERR, "adj_systime: allow_panic is TRUE!");
+ }
+ return FALSE;
+ }
+ }
+ if (enable_panic_check && allow_panic) {
+ msyslog(LOG_ERR, "adj_systime: allow_panic is TRUE!");
+ }
+ return TRUE;
+}
+#endif
+
+/*
+ * helper to keep utmp/wtmp up to date
+ */
+static void
+update_uwtmp(
+ struct timeval timetv,
+ struct timeval tvlast
+ )
+{
+ struct timeval tvdiff;
+ /*
+ * FreeBSD, for example, has:
+ * struct utmp {
+ * char ut_line[UT_LINESIZE];
+ * char ut_name[UT_NAMESIZE];
+ * char ut_host[UT_HOSTSIZE];
+ * long ut_time;
+ * };
+ * and appends line="|", name="date", host="", time for the OLD
+ * and appends line="{", name="date", host="", time for the NEW // }
+ * to _PATH_WTMP .
+ *
+ * Some OSes have utmp, some have utmpx.
+ */
+
+ /*
+ * Write old and new time entries in utmp and wtmp if step
+ * adjustment is greater than one second.
+ *
+ * This might become even Uglier...
+ */
+ tvdiff = abs_tval(sub_tval(timetv, tvlast));
+ if (tvdiff.tv_sec > 0) {
+#ifdef HAVE_UTMP_H
+ struct utmp ut;
+#endif
+#ifdef HAVE_UTMPX_H
+ struct utmpx utx;
+#endif
+
+#ifdef HAVE_UTMP_H
+ ZERO(ut);
+#endif
+#ifdef HAVE_UTMPX_H
+ ZERO(utx);
+#endif
+
+ /* UTMP */
+
+#ifdef UPDATE_UTMP
+# ifdef HAVE_PUTUTLINE
+# ifndef _PATH_UTMP
+# define _PATH_UTMP UTMP_FILE
+# endif
+ utmpname(_PATH_UTMP);
+ ut.ut_type = OLD_TIME;
+ strlcpy(ut.ut_line, OTIME_MSG, sizeof(ut.ut_line));
+ ut.ut_time = tvlast.tv_sec;
+ setutent();
+ pututline(&ut);
+ ut.ut_type = NEW_TIME;
+ strlcpy(ut.ut_line, NTIME_MSG, sizeof(ut.ut_line));
+ ut.ut_time = timetv.tv_sec;
+ setutent();
+ pututline(&ut);
+ endutent();
+# else /* not HAVE_PUTUTLINE */
+# endif /* not HAVE_PUTUTLINE */
+#endif /* UPDATE_UTMP */
+
+ /* UTMPX */
+
+#ifdef UPDATE_UTMPX
+# ifdef HAVE_PUTUTXLINE
+ utx.ut_type = OLD_TIME;
+ strlcpy(utx.ut_line, OTIME_MSG, sizeof(utx.ut_line));
+ utx.ut_tv = tvlast;
+ setutxent();
+ pututxline(&utx);
+ utx.ut_type = NEW_TIME;
+ strlcpy(utx.ut_line, NTIME_MSG, sizeof(utx.ut_line));
+ utx.ut_tv = timetv;
+ setutxent();
+ pututxline(&utx);
+ endutxent();
+# else /* not HAVE_PUTUTXLINE */
+# endif /* not HAVE_PUTUTXLINE */
+#endif /* UPDATE_UTMPX */
+
+ /* WTMP */
+
+#ifdef UPDATE_WTMP
+# ifdef HAVE_PUTUTLINE
+# ifndef _PATH_WTMP
+# define _PATH_WTMP WTMP_FILE
+# endif
+ utmpname(_PATH_WTMP);
+ ut.ut_type = OLD_TIME;
+ strlcpy(ut.ut_line, OTIME_MSG, sizeof(ut.ut_line));
+ ut.ut_time = tvlast.tv_sec;
+ setutent();
+ pututline(&ut);
+ ut.ut_type = NEW_TIME;
+ strlcpy(ut.ut_line, NTIME_MSG, sizeof(ut.ut_line));
+ ut.ut_time = timetv.tv_sec;
+ setutent();
+ pututline(&ut);
+ endutent();
+# else /* not HAVE_PUTUTLINE */
+# endif /* not HAVE_PUTUTLINE */
+#endif /* UPDATE_WTMP */
+
+ /* WTMPX */
+
+#ifdef UPDATE_WTMPX
+# ifdef HAVE_PUTUTXLINE
+ utx.ut_type = OLD_TIME;
+ utx.ut_tv = tvlast;
+ strlcpy(utx.ut_line, OTIME_MSG, sizeof(utx.ut_line));
+# ifdef HAVE_UPDWTMPX
+ updwtmpx(WTMPX_FILE, &utx);
+# else /* not HAVE_UPDWTMPX */
+# endif /* not HAVE_UPDWTMPX */
+# else /* not HAVE_PUTUTXLINE */
+# endif /* not HAVE_PUTUTXLINE */
+# ifdef HAVE_PUTUTXLINE
+ utx.ut_type = NEW_TIME;
+ utx.ut_tv = timetv;
+ strlcpy(utx.ut_line, NTIME_MSG, sizeof(utx.ut_line));
+# ifdef HAVE_UPDWTMPX
+ updwtmpx(WTMPX_FILE, &utx);
+# else /* not HAVE_UPDWTMPX */
+# endif /* not HAVE_UPDWTMPX */
+# else /* not HAVE_PUTUTXLINE */
+# endif /* not HAVE_PUTUTXLINE */
+#endif /* UPDATE_WTMPX */
+
+ }
+}
+
+/*
+ * step_systime - step the system clock.
+ */
+
+int
+step_systime(
+ double step
+ )
+{
+ time_t pivot; /* for ntp era unfolding */
+ struct timeval timetv, tvlast;
+ struct timespec timets;
+ l_fp fp_ofs, fp_sys; /* offset and target system time in FP */
+
+ /*
+ * Get pivot time for NTP era unfolding. Since we don't step
+ * very often, we can afford to do the whole calculation from
+ * scratch. And we're not in the time-critical path yet.
+ */
+#if SIZEOF_TIME_T > 4
+ pivot = basedate_get_eracenter();
+#else
+ /* This makes sure the resulting time stamp is on or after
+ * 1969-12-31/23:59:59 UTC and gives us additional two years,
+ * from the change of NTP era in 2036 to the UNIX rollover in
+ * 2038. (Minus one second, but that won't hurt.) We *really*
+ * need a longer 'time_t' after that! Or a different baseline,
+ * but that would cause other serious trouble, too.
+ */
+ pivot = 0x7FFFFFFF;
+#endif
+
+ /* get the complete jump distance as l_fp */
+ DTOLFP(sys_residual, &fp_sys);
+ DTOLFP(step, &fp_ofs);
+ L_ADD(&fp_ofs, &fp_sys);
+
+ /* ---> time-critical path starts ---> */
+
+ /* get the current time as l_fp (without fuzz) and as struct timeval */
+ get_ostime(&timets);
+ fp_sys = tspec_stamp_to_lfp(timets);
+ tvlast.tv_sec = timets.tv_sec;
+ tvlast.tv_usec = (timets.tv_nsec + 500) / 1000;
+
+ /* get the target time as l_fp */
+ L_ADD(&fp_sys, &fp_ofs);
+
+ /* unfold the new system time */
+ timetv = lfp_stamp_to_tval(fp_sys, &pivot);
+
+ /* now set new system time */
+ if (ntp_set_tod(&timetv, NULL) != 0) {
+ msyslog(LOG_ERR, "step-systime: %m");
+ if (enable_panic_check && allow_panic) {
+ msyslog(LOG_ERR, "step_systime: allow_panic is TRUE!");
+ }
+ return FALSE;
+ }
+
+ /* <--- time-critical path ended with 'ntp_set_tod()' <--- */
+
+ sys_residual = 0;
+ lamport_violated = (step < 0);
+ if (step_callback)
+ (*step_callback)();
+
+#ifdef NEED_HPUX_ADJTIME
+ /*
+ * CHECKME: is this correct when called by ntpdate?????
+ */
+ _clear_adjtime();
+#endif
+
+ update_uwtmp(timetv, tvlast);
+ if (enable_panic_check && allow_panic) {
+ msyslog(LOG_ERR, "step_systime: allow_panic is TRUE!");
+ INSIST(!allow_panic);
+ }
+ return TRUE;
+}
+
+static const char *
+tv_fmt_libbuf(
+ const struct timeval * ptv
+ )
+{
+ char * retv;
+ vint64 secs;
+ ntpcal_split dds;
+ struct calendar jd;
+
+ secs = time_to_vint64(&ptv->tv_sec);
+ dds = ntpcal_daysplit(&secs);
+ ntpcal_daysplit_to_date(&jd, &dds, DAY_UNIX_STARTS);
+ LIB_GETBUF(retv);
+ snprintf(retv, LIB_BUFLENGTH,
+ "%04hu-%02hu-%02hu/%02hu:%02hu:%02hu.%06u",
+ jd.year, (u_short)jd.month, (u_short)jd.monthday,
+ (u_short)jd.hour, (u_short)jd.minute, (u_short)jd.second,
+ (u_int)ptv->tv_usec);
+ return retv;
+}
+
+
+int /*BOOL*/
+clamp_systime(void)
+{
+#if SIZEOF_TIME_T > 4
+
+ struct timeval timetv, tvlast;
+ struct timespec timets;
+ uint32_t tdiff;
+
+
+ timetv.tv_sec = basedate_get_erabase();
+
+ /* ---> time-critical path starts ---> */
+
+ /* get the current time as l_fp (without fuzz) and as struct timeval */
+ get_ostime(&timets);
+ tvlast.tv_sec = timets.tv_sec;
+ tvlast.tv_usec = (timets.tv_nsec + 500) / 1000;
+ if (tvlast.tv_usec >= 1000000) {
+ tvlast.tv_usec -= 1000000;
+ tvlast.tv_sec += 1;
+ }
+ timetv.tv_usec = tvlast.tv_usec;
+
+ tdiff = (uint32_t)(tvlast.tv_sec & UINT32_MAX) -
+ (uint32_t)(timetv.tv_sec & UINT32_MAX);
+ timetv.tv_sec += tdiff;
+ if (timetv.tv_sec != tvlast.tv_sec) {
+ /* now set new system time */
+ if (ntp_set_tod(&timetv, NULL) != 0) {
+ msyslog(LOG_ERR, "clamp-systime: %m");
+ return FALSE;
+ }
+ } else {
+ msyslog(LOG_INFO,
+ "clamp-systime: clock (%s) in allowed range",
+ tv_fmt_libbuf(&timetv));
+ return FALSE;
+ }
+
+ /* <--- time-critical path ended with 'ntp_set_tod()' <--- */
+
+ sys_residual = 0;
+ lamport_violated = (timetv.tv_sec < tvlast.tv_sec);
+ if (step_callback)
+ (*step_callback)();
+
+# ifdef NEED_HPUX_ADJTIME
+ /*
+ * CHECKME: is this correct when called by ntpdate?????
+ */
+ _clear_adjtime();
+# endif
+
+ update_uwtmp(timetv, tvlast);
+ msyslog(LOG_WARNING,
+ "clamp-systime: clock stepped from %s to %s!",
+ tv_fmt_libbuf(&tvlast), tv_fmt_libbuf(&timetv));
+ return TRUE;
+
+#else
+
+ return 0;
+#endif
+}
+
+#endif /* !SIM */
diff --git a/sebhbsd/freebsd/contrib/ntp/libntp/vint64ops.c b/sebhbsd/freebsd/contrib/ntp/libntp/vint64ops.c
new file mode 100644
index 0000000..4b623e2
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/libntp/vint64ops.c
@@ -0,0 +1,286 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * vint64ops.c - operations on 'vint64' values
+ *
+ * Written by Juergen Perlinger (perlinger@ntp.org) for the NTP project.
+ * The contents of 'html/copyright.html' apply.
+ * ----------------------------------------------------------------------
+ * This is an attempt to get the vint64 calculations stuff centralised.
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <errno.h>
+
+#include "ntp_types.h"
+#include "ntp_fp.h"
+#include "vint64ops.h"
+
+/* ---------------------------------------------------------------------
+ * GCC is rather sticky with its 'const' attribute. We have to do it more
+ * explicit than with a cast if we want to get rid of a CONST qualifier.
+ * Greetings from the PASCAL world, where casting was only possible via
+ * untagged unions...
+ */
+static inline void*
+noconst(
+ const void* ptr
+ )
+{
+ union {
+ const void * cp;
+ void * vp;
+ } tmp;
+ tmp.cp = ptr;
+ return tmp.vp;
+}
+
+/* -------------------------------------------------------------------------*/
+
+vint64
+strtouv64(
+ const char * begp,
+ char ** endp,
+ int base
+ )
+{
+ vint64 res;
+ u_char digit;
+ int sig, num;
+ const u_char *src;
+
+ num = sig = 0;
+ src = (const u_char*)begp;
+ while (isspace(*src))
+ src++;
+
+ if (*src == '-') {
+ src++;
+ sig = 1;
+ } else if (*src == '+') {
+ src++;
+ }
+
+ if (base == 0) {
+ base = 10;
+ if (*src == '0') {
+ base = 8;
+ if (toupper(*++src) == 'X') {
+ src++;
+ base = 16;
+ }
+ }
+ } else if (base == 16) { /* remove optional leading '0x' or '0X' */
+ if (src[0] == '0' && toupper(src[1]) == 'X')
+ src += 2;
+ } else if (base <= 2 || base > 36) {
+ memset(&res, 0xFF, sizeof(res));
+ errno = ERANGE;
+ return res;
+ }
+
+ memset(&res, 0, sizeof(res));
+ while (*src) {
+ if (isdigit(*src))
+ digit = *src - '0';
+ else if (isupper(*src))
+ digit = *src - 'A' + 10;
+ else if (islower(*src))
+ digit = *src - 'a' + 10;
+ else
+ break;
+ if (digit >= base)
+ break;
+ num = 1;
+#if defined(HAVE_INT64)
+ res.Q_s = res.Q_s * base + digit;
+#else
+ /* res *= base, using 16x16->32 bit
+ * multiplication. Slow but portable.
+ */
+ {
+ uint32_t accu;
+ accu = (uint32_t)res.W_s.ll * base;
+ res.W_s.ll = (uint16_t)accu;
+ accu = (accu >> 16)
+ + (uint32_t)res.W_s.lh * base;
+ res.W_s.lh = (uint16_t)accu;
+ /* the upper bits can be done in one step: */
+ res.D_s.hi = res.D_s.hi * base + (accu >> 16);
+ }
+ M_ADD(res.D_s.hi, res.D_s.lo, 0, digit);
+#endif
+ src++;
+ }
+ if (!num)
+ errno = EINVAL;
+ if (endp)
+ *endp = (char*)noconst(src);
+ if (sig)
+ M_NEG(res.D_s.hi, res.D_s.lo);
+ return res;
+}
+
+/* -------------------------------------------------------------------------*/
+
+int
+icmpv64(
+ const vint64 * lhs,
+ const vint64 * rhs
+ )
+{
+ int res;
+
+#if defined(HAVE_INT64)
+ res = (lhs->q_s > rhs->q_s)
+ - (lhs->q_s < rhs->q_s);
+#else
+ res = (lhs->d_s.hi > rhs->d_s.hi)
+ - (lhs->d_s.hi < rhs->d_s.hi);
+ if ( ! res )
+ res = (lhs->D_s.lo > rhs->D_s.lo)
+ - (lhs->D_s.lo < rhs->D_s.lo);
+#endif
+
+ return res;
+}
+
+/* -------------------------------------------------------------------------*/
+
+int
+ucmpv64(
+ const vint64 * lhs,
+ const vint64 * rhs
+ )
+{
+ int res;
+
+#if defined(HAVE_INT64)
+ res = (lhs->Q_s > rhs->Q_s)
+ - (lhs->Q_s < rhs->Q_s);
+#else
+ res = (lhs->D_s.hi > rhs->D_s.hi)
+ - (lhs->D_s.hi < rhs->D_s.hi);
+ if ( ! res )
+ res = (lhs->D_s.lo > rhs->D_s.lo)
+ - (lhs->D_s.lo < rhs->D_s.lo);
+#endif
+ return res;
+}
+
+/* -------------------------------------------------------------------------*/
+
+vint64
+addv64(
+ const vint64 *lhs,
+ const vint64 *rhs
+ )
+{
+ vint64 res;
+
+#if defined(HAVE_INT64)
+ res.Q_s = lhs->Q_s + rhs->Q_s;
+#else
+ res = *lhs;
+ M_ADD(res.D_s.hi, res.D_s.lo, rhs->D_s.hi, rhs->D_s.lo);
+#endif
+ return res;
+}
+
+/* -------------------------------------------------------------------------*/
+
+vint64
+subv64(
+ const vint64 *lhs,
+ const vint64 *rhs
+ )
+{
+ vint64 res;
+
+#if defined(HAVE_INT64)
+ res.Q_s = lhs->Q_s - rhs->Q_s;
+#else
+ res = *lhs;
+ M_SUB(res.D_s.hi, res.D_s.lo, rhs->D_s.hi, rhs->D_s.lo);
+#endif
+ return res;
+}
+
+/* -------------------------------------------------------------------------*/
+
+vint64
+addv64i32(
+ const vint64 * lhs,
+ int32_t rhs
+ )
+{
+ vint64 res;
+
+ res = *lhs;
+#if defined(HAVE_INT64)
+ res.q_s += rhs;
+#else
+ M_ADD(res.D_s.hi, res.D_s.lo, -(rhs < 0), rhs);
+#endif
+ return res;
+}
+
+/* -------------------------------------------------------------------------*/
+
+vint64
+subv64i32(
+ const vint64 * lhs,
+ int32_t rhs
+ )
+{
+ vint64 res;
+
+ res = *lhs;
+#if defined(HAVE_INT64)
+ res.q_s -= rhs;
+#else
+ M_SUB(res.D_s.hi, res.D_s.lo, -(rhs < 0), rhs);
+#endif
+ return res;
+}
+
+/* -------------------------------------------------------------------------*/
+
+vint64
+addv64u32(
+ const vint64 * lhs,
+ uint32_t rhs
+ )
+{
+ vint64 res;
+
+ res = *lhs;
+#if defined(HAVE_INT64)
+ res.Q_s += rhs;
+#else
+ M_ADD(res.D_s.hi, res.D_s.lo, 0, rhs);
+#endif
+ return res;
+}
+
+/* -------------------------------------------------------------------------*/
+
+vint64
+subv64u32(
+ const vint64 * lhs,
+ uint32_t rhs
+ )
+{
+ vint64 res;
+
+ res = *lhs;
+#if defined(HAVE_INT64)
+ res.Q_s -= rhs;
+#else
+ M_SUB(res.D_s.hi, res.D_s.lo, 0, rhs);
+#endif
+ return res;
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/libntp/work_fork.c b/sebhbsd/freebsd/contrib/ntp/libntp/work_fork.c
new file mode 100644
index 0000000..fbb0611
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/libntp/work_fork.c
@@ -0,0 +1,619 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * work_fork.c - fork implementation for blocking worker child.
+ */
+#include <config.h>
+#include "ntp_workimpl.h"
+
+#ifdef WORK_FORK
+#include <stdio.h>
+#include <ctype.h>
+#include <signal.h>
+#include <sys/wait.h>
+
+#include "iosignal.h"
+#include "ntp_stdlib.h"
+#include "ntp_malloc.h"
+#include "ntp_syslog.h"
+#include "ntpd.h"
+#include "ntp_io.h"
+#include "ntp_assert.h"
+#include "ntp_unixtime.h"
+#include "ntp_worker.h"
+
+/* === variables === */
+ int worker_process;
+ addremove_io_fd_func addremove_io_fd;
+static volatile int worker_sighup_received;
+int saved_argc = 0;
+char **saved_argv;
+
+/* === function prototypes === */
+static void fork_blocking_child(blocking_child *);
+static RETSIGTYPE worker_sighup(int);
+static void send_worker_home_atexit(void);
+static void cleanup_after_child(blocking_child *);
+
+/* === I/O helpers === */
+/* Since we have signals enabled, there's a good chance that blocking IO
+ * via pipe suffers from EINTR -- and this goes for both directions.
+ * The next two wrappers will loop until either all the data is written
+ * or read, plus handling the EOF condition on read. They may return
+ * zero if no data was transferred at all, and effectively every return
+ * value that differs from the given transfer length signifies an error
+ * condition.
+ */
+
+static size_t
+netread(
+ int fd,
+ void * vb,
+ size_t l
+ )
+{
+ char * b = vb;
+ ssize_t r;
+
+ while (l) {
+ r = read(fd, b, l);
+ if (r > 0) {
+ l -= r;
+ b += r;
+ } else if (r == 0 || errno != EINTR) {
+ l = 0;
+ }
+ }
+ return (size_t)(b - (char *)vb);
+}
+
+
+static size_t
+netwrite(
+ int fd,
+ const void * vb,
+ size_t l
+ )
+{
+ const char * b = vb;
+ ssize_t w;
+
+ while (l) {
+ w = write(fd, b, l);
+ if (w > 0) {
+ l -= w;
+ b += w;
+ } else if (errno != EINTR) {
+ l = 0;
+ }
+ }
+ return (size_t)(b - (const char *)vb);
+}
+
+
+#if defined(HAVE_DROPROOT)
+extern int set_user_group_ids(void);
+#endif
+
+/* === functions === */
+/*
+ * exit_worker()
+ *
+ * On some systems _exit() is preferred to exit() for forked children.
+ * For example, http://netbsd.gw.com/cgi-bin/man-cgi?fork++NetBSD-5.0
+ * recommends _exit() to avoid double-flushing C runtime stream buffers
+ * and also to avoid calling the parent's atexit() routines in the
+ * child. On those systems WORKER_CHILD_EXIT is _exit. Since _exit
+ * bypasses CRT cleanup, fflush() files we know might have output
+ * buffered.
+ */
+void
+exit_worker(
+ int exitcode
+ )
+{
+ if (syslog_file != NULL)
+ fflush(syslog_file);
+ fflush(stdout);
+ fflush(stderr);
+ WORKER_CHILD_EXIT (exitcode); /* space before ( required */
+}
+
+
+static RETSIGTYPE
+worker_sighup(
+ int sig
+ )
+{
+ if (SIGHUP == sig)
+ worker_sighup_received = 1;
+}
+
+
+int
+worker_sleep(
+ blocking_child * c,
+ time_t seconds
+ )
+{
+ u_int sleep_remain;
+
+ sleep_remain = (u_int)seconds;
+ do {
+ if (!worker_sighup_received)
+ sleep_remain = sleep(sleep_remain);
+ if (worker_sighup_received) {
+ TRACE(1, ("worker SIGHUP with %us left to sleep",
+ sleep_remain));
+ worker_sighup_received = 0;
+ return -1;
+ }
+ } while (sleep_remain);
+
+ return 0;
+}
+
+
+void
+interrupt_worker_sleep(void)
+{
+ u_int idx;
+ blocking_child * c;
+ int rc;
+
+ for (idx = 0; idx < blocking_children_alloc; idx++) {
+ c = blocking_children[idx];
+
+ if (NULL == c || c->reusable == TRUE)
+ continue;
+
+ rc = kill(c->pid, SIGHUP);
+ if (rc < 0)
+ msyslog(LOG_ERR,
+ "Unable to signal HUP to wake child pid %d: %m",
+ c->pid);
+ }
+}
+
+
+/*
+ * harvest_child_status() runs in the parent.
+ *
+ * Note the error handling -- this is an interaction with SIGCHLD.
+ * SIG_IGN on SIGCHLD on some OSes means do not wait but reap
+ * automatically. Since we're not really interested in the result code,
+ * we simply ignore the error.
+ */
+static void
+harvest_child_status(
+ blocking_child * c
+ )
+{
+ if (c->pid) {
+ /* Wait on the child so it can finish terminating */
+ if (waitpid(c->pid, NULL, 0) == c->pid)
+ TRACE(4, ("harvested child %d\n", c->pid));
+ else if (errno != ECHILD)
+ msyslog(LOG_ERR, "error waiting on child %d: %m", c->pid);
+ c->pid = 0;
+ }
+}
+
+/*
+ * req_child_exit() runs in the parent.
+ */
+int
+req_child_exit(
+ blocking_child * c
+ )
+{
+ if (-1 != c->req_write_pipe) {
+ close(c->req_write_pipe);
+ c->req_write_pipe = -1;
+ return 0;
+ }
+ /* Closing the pipe forces the child to exit */
+ harvest_child_status(c);
+ return -1;
+}
+
+
+/*
+ * cleanup_after_child() runs in parent.
+ */
+static void
+cleanup_after_child(
+ blocking_child * c
+ )
+{
+ harvest_child_status(c);
+ if (-1 != c->resp_read_pipe) {
+ (*addremove_io_fd)(c->resp_read_pipe, c->ispipe, TRUE);
+ close(c->resp_read_pipe);
+ c->resp_read_pipe = -1;
+ }
+ c->resp_read_ctx = NULL;
+ DEBUG_INSIST(-1 == c->req_read_pipe);
+ DEBUG_INSIST(-1 == c->resp_write_pipe);
+ c->reusable = TRUE;
+}
+
+
+static void
+send_worker_home_atexit(void)
+{
+ u_int idx;
+ blocking_child * c;
+
+ if (worker_process)
+ return;
+
+ for (idx = 0; idx < blocking_children_alloc; idx++) {
+ c = blocking_children[idx];
+ if (NULL == c)
+ continue;
+ req_child_exit(c);
+ }
+}
+
+
+int
+send_blocking_req_internal(
+ blocking_child * c,
+ blocking_pipe_header * hdr,
+ void * data
+ )
+{
+ size_t octets;
+ size_t rc;
+
+ DEBUG_REQUIRE(hdr != NULL);
+ DEBUG_REQUIRE(data != NULL);
+ DEBUG_REQUIRE(BLOCKING_REQ_MAGIC == hdr->magic_sig);
+
+ if (-1 == c->req_write_pipe) {
+ fork_blocking_child(c);
+ DEBUG_INSIST(-1 != c->req_write_pipe);
+ }
+
+ octets = sizeof(*hdr);
+ rc = netwrite(c->req_write_pipe, hdr, octets);
+
+ if (rc == octets) {
+ octets = hdr->octets - sizeof(*hdr);
+ rc = netwrite(c->req_write_pipe, data, octets);
+ if (rc == octets)
+ return 0;
+ }
+
+ msyslog(LOG_ERR,
+ "send_blocking_req_internal: short write (%zu of %zu), %m",
+ rc, octets);
+
+ /* Fatal error. Clean up the child process. */
+ req_child_exit(c);
+ exit(1); /* otherwise would be return -1 */
+}
+
+
+blocking_pipe_header *
+receive_blocking_req_internal(
+ blocking_child * c
+ )
+{
+ blocking_pipe_header hdr;
+ blocking_pipe_header * req;
+ size_t rc;
+ size_t octets;
+
+ DEBUG_REQUIRE(-1 != c->req_read_pipe);
+
+ req = NULL;
+ rc = netread(c->req_read_pipe, &hdr, sizeof(hdr));
+
+ if (0 == rc) {
+ TRACE(4, ("parent closed request pipe, child %d terminating\n",
+ c->pid));
+ } else if (rc != sizeof(hdr)) {
+ msyslog(LOG_ERR,
+ "receive_blocking_req_internal: short header read (%zu of %zu), %m",
+ rc, sizeof(hdr));
+ } else {
+ INSIST(sizeof(hdr) < hdr.octets && hdr.octets < 4 * 1024);
+ req = emalloc(hdr.octets);
+ memcpy(req, &hdr, sizeof(*req));
+ octets = hdr.octets - sizeof(hdr);
+ rc = netread(c->req_read_pipe, (char *)(req + 1),
+ octets);
+
+ if (rc != octets)
+ msyslog(LOG_ERR,
+ "receive_blocking_req_internal: short read (%zu of %zu), %m",
+ rc, octets);
+ else if (BLOCKING_REQ_MAGIC != req->magic_sig)
+ msyslog(LOG_ERR,
+ "receive_blocking_req_internal: packet header mismatch (0x%x)",
+ req->magic_sig);
+ else
+ return req;
+ }
+
+ if (req != NULL)
+ free(req);
+
+ return NULL;
+}
+
+
+int
+send_blocking_resp_internal(
+ blocking_child * c,
+ blocking_pipe_header * resp
+ )
+{
+ size_t octets;
+ size_t rc;
+
+ DEBUG_REQUIRE(-1 != c->resp_write_pipe);
+
+ octets = resp->octets;
+ rc = netwrite(c->resp_write_pipe, resp, octets);
+ free(resp);
+
+ if (octets == rc)
+ return 0;
+
+ TRACE(1, ("send_blocking_resp_internal: short write (%zu of %zu), %m\n",
+ rc, octets));
+ return -1;
+}
+
+
+blocking_pipe_header *
+receive_blocking_resp_internal(
+ blocking_child * c
+ )
+{
+ blocking_pipe_header hdr;
+ blocking_pipe_header * resp;
+ size_t rc;
+ size_t octets;
+
+ DEBUG_REQUIRE(c->resp_read_pipe != -1);
+
+ resp = NULL;
+ rc = netread(c->resp_read_pipe, &hdr, sizeof(hdr));
+
+ if (0 == rc) {
+ /* this is the normal child exited indication */
+ } else if (rc != sizeof(hdr)) {
+ TRACE(1, ("receive_blocking_resp_internal: short header read (%zu of %zu), %m\n",
+ rc, sizeof(hdr)));
+ } else if (BLOCKING_RESP_MAGIC != hdr.magic_sig) {
+ TRACE(1, ("receive_blocking_resp_internal: header mismatch (0x%x)\n",
+ hdr.magic_sig));
+ } else {
+ INSIST(sizeof(hdr) < hdr.octets &&
+ hdr.octets < 16 * 1024);
+ resp = emalloc(hdr.octets);
+ memcpy(resp, &hdr, sizeof(*resp));
+ octets = hdr.octets - sizeof(hdr);
+ rc = netread(c->resp_read_pipe, (char *)(resp + 1),
+ octets);
+
+ if (rc != octets)
+ TRACE(1, ("receive_blocking_resp_internal: short read (%zu of %zu), %m\n",
+ rc, octets));
+ else
+ return resp;
+ }
+
+ cleanup_after_child(c);
+
+ if (resp != NULL)
+ free(resp);
+
+ return NULL;
+}
+
+
+#if defined(HAVE_DROPROOT) && defined(WORK_FORK)
+void
+fork_deferred_worker(void)
+{
+ u_int idx;
+ blocking_child * c;
+
+ REQUIRE(droproot && root_dropped);
+
+ for (idx = 0; idx < blocking_children_alloc; idx++) {
+ c = blocking_children[idx];
+ if (NULL == c)
+ continue;
+ if (-1 != c->req_write_pipe && 0 == c->pid)
+ fork_blocking_child(c);
+ }
+}
+#endif
+
+
+static void
+fork_blocking_child(
+ blocking_child * c
+ )
+{
+ static int atexit_installed;
+ static int blocking_pipes[4] = { -1, -1, -1, -1 };
+ int rc;
+ int was_pipe;
+ int is_pipe;
+ int saved_errno = 0;
+ int childpid;
+ int keep_fd;
+ int fd;
+
+ /*
+ * parent and child communicate via a pair of pipes.
+ *
+ * 0 child read request
+ * 1 parent write request
+ * 2 parent read response
+ * 3 child write response
+ */
+ if (-1 == c->req_write_pipe) {
+ rc = pipe_socketpair(&blocking_pipes[0], &was_pipe);
+ if (0 != rc) {
+ saved_errno = errno;
+ } else {
+ rc = pipe_socketpair(&blocking_pipes[2], &is_pipe);
+ if (0 != rc) {
+ saved_errno = errno;
+ close(blocking_pipes[0]);
+ close(blocking_pipes[1]);
+ } else {
+ INSIST(was_pipe == is_pipe);
+ }
+ }
+ if (0 != rc) {
+ errno = saved_errno;
+ msyslog(LOG_ERR, "unable to create worker pipes: %m");
+ exit(1);
+ }
+
+ /*
+ * Move the descriptors the parent will keep open out of the
+ * low descriptors preferred by C runtime buffered FILE *.
+ */
+ c->req_write_pipe = move_fd(blocking_pipes[1]);
+ c->resp_read_pipe = move_fd(blocking_pipes[2]);
+ /*
+ * wake any worker child on orderly shutdown of the
+ * daemon so that it can notice the broken pipes and
+ * go away promptly.
+ */
+ if (!atexit_installed) {
+ atexit(&send_worker_home_atexit);
+ atexit_installed = TRUE;
+ }
+ }
+
+#if defined(HAVE_DROPROOT) && !defined(NEED_EARLY_FORK)
+ /* defer the fork until after root is dropped */
+ if (droproot && !root_dropped)
+ return;
+#endif
+ if (syslog_file != NULL)
+ fflush(syslog_file);
+ fflush(stdout);
+ fflush(stderr);
+
+ /* [BUG 3050] setting SIGCHLD to SIG_IGN likely causes unwanted
+ * or undefined effects. We don't do it and leave SIGCHLD alone.
+ */
+ /* signal_no_reset(SIGCHLD, SIG_IGN); */
+
+ childpid = fork();
+ if (-1 == childpid) {
+ msyslog(LOG_ERR, "unable to fork worker: %m");
+ exit(1);
+ }
+
+ if (childpid) {
+ /* this is the parent */
+ TRACE(1, ("forked worker child (pid %d)\n", childpid));
+ c->pid = childpid;
+ c->ispipe = is_pipe;
+
+ /* close the child's pipe descriptors. */
+ close(blocking_pipes[0]);
+ close(blocking_pipes[3]);
+
+ memset(blocking_pipes, -1, sizeof(blocking_pipes));
+
+ /* wire into I/O loop */
+ (*addremove_io_fd)(c->resp_read_pipe, is_pipe, FALSE);
+
+ return; /* parent returns */
+ }
+
+ /*
+ * The parent gets the child pid as the return value of fork().
+ * The child must work for it.
+ */
+ c->pid = getpid();
+ worker_process = TRUE;
+
+ /*
+ * Change the process name of the child to avoid confusion
+ * about ntpd trunning twice.
+ */
+ if (saved_argc != 0) {
+ int argcc;
+ int argvlen = 0;
+ /* Clear argv */
+ for (argcc = 0; argcc < saved_argc; argcc++) {
+ int l = strlen(saved_argv[argcc]);
+ argvlen += l + 1;
+ memset(saved_argv[argcc], 0, l);
+ }
+ strlcpy(saved_argv[0], "ntpd: asynchronous dns resolver", argvlen);
+ }
+
+ /*
+ * In the child, close all files except stdin, stdout, stderr,
+ * and the two child ends of the pipes.
+ */
+ DEBUG_INSIST(-1 == c->req_read_pipe);
+ DEBUG_INSIST(-1 == c->resp_write_pipe);
+ c->req_read_pipe = blocking_pipes[0];
+ c->resp_write_pipe = blocking_pipes[3];
+
+ kill_asyncio(0);
+ closelog();
+ if (syslog_file != NULL) {
+ fclose(syslog_file);
+ syslog_file = NULL;
+ syslogit = TRUE;
+ }
+ keep_fd = max(c->req_read_pipe, c->resp_write_pipe);
+ for (fd = 3; fd < keep_fd; fd++)
+ if (fd != c->req_read_pipe &&
+ fd != c->resp_write_pipe)
+ close(fd);
+ close_all_beyond(keep_fd);
+ /*
+ * We get signals from refclock serial I/O on NetBSD in the
+ * worker if we do not reset SIGIO's handler to the default.
+ * It is not conditionalized for NetBSD alone because on
+ * systems where it is not needed, it is harmless, and that
+ * allows us to handle unknown others with NetBSD behavior.
+ * [Bug 1386]
+ */
+#if defined(USE_SIGIO)
+ signal_no_reset(SIGIO, SIG_DFL);
+#elif defined(USE_SIGPOLL)
+ signal_no_reset(SIGPOLL, SIG_DFL);
+#endif
+ signal_no_reset(SIGHUP, worker_sighup);
+ init_logging("ntp_intres", 0, FALSE);
+ setup_logfile(NULL);
+
+#ifdef HAVE_DROPROOT
+ (void) set_user_group_ids();
+#endif
+
+ /*
+ * And now back to the portable code
+ */
+ exit_worker(blocking_child_common(c));
+}
+
+
+void worker_global_lock(int inOrOut)
+{
+ (void)inOrOut;
+}
+
+#else /* !WORK_FORK follows */
+char work_fork_nonempty_compilation_unit;
+#endif
diff --git a/sebhbsd/freebsd/contrib/ntp/libntp/work_thread.c b/sebhbsd/freebsd/contrib/ntp/libntp/work_thread.c
new file mode 100644
index 0000000..2b0bdc5
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/libntp/work_thread.c
@@ -0,0 +1,945 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * work_thread.c - threads implementation for blocking worker child.
+ */
+#include <config.h>
+#include "ntp_workimpl.h"
+
+#ifdef WORK_THREAD
+
+#include <stdio.h>
+#include <ctype.h>
+#include <signal.h>
+#ifndef SYS_WINNT
+#include <pthread.h>
+#endif
+
+#include "ntp_stdlib.h"
+#include "ntp_malloc.h"
+#include "ntp_syslog.h"
+#include "ntpd.h"
+#include "ntp_io.h"
+#include "ntp_assert.h"
+#include "ntp_unixtime.h"
+#include "timespecops.h"
+#include "ntp_worker.h"
+
+#define CHILD_EXIT_REQ ((blocking_pipe_header *)(intptr_t)-1)
+#define CHILD_GONE_RESP CHILD_EXIT_REQ
+/* Queue size increments:
+ * The request queue grows a bit faster than the response queue -- the
+ * daemon can push requests and pull results faster on avarage than the
+ * worker can process requests and push results... If this really pays
+ * off is debatable.
+ */
+#define WORKITEMS_ALLOC_INC 16
+#define RESPONSES_ALLOC_INC 4
+
+/* Fiddle with min/max stack sizes. 64kB minimum seems to work, so we
+ * set the maximum to 256kB. If the minimum goes below the
+ * system-defined minimum stack size, we have to adjust accordingly.
+ */
+#ifndef THREAD_MINSTACKSIZE
+# define THREAD_MINSTACKSIZE (64U * 1024)
+#endif
+#ifndef __sun
+#if defined(PTHREAD_STACK_MIN) && THREAD_MINSTACKSIZE < PTHREAD_STACK_MIN
+# undef THREAD_MINSTACKSIZE
+# define THREAD_MINSTACKSIZE PTHREAD_STACK_MIN
+#endif
+#endif
+
+#ifndef THREAD_MAXSTACKSIZE
+# define THREAD_MAXSTACKSIZE (256U * 1024)
+#endif
+#if THREAD_MAXSTACKSIZE < THREAD_MINSTACKSIZE
+# undef THREAD_MAXSTACKSIZE
+# define THREAD_MAXSTACKSIZE THREAD_MINSTACKSIZE
+#endif
+
+/* need a good integer to store a pointer... */
+#ifndef UINTPTR_T
+# if defined(UINTPTR_MAX)
+# define UINTPTR_T uintptr_t
+# elif defined(UINT_PTR)
+# define UINTPTR_T UINT_PTR
+# else
+# define UINTPTR_T size_t
+# endif
+#endif
+
+
+#ifdef SYS_WINNT
+
+# define thread_exit(c) _endthreadex(c)
+# define tickle_sem(sh) ReleaseSemaphore((sh->shnd), 1, NULL)
+u_int WINAPI blocking_thread(void *);
+static BOOL same_os_sema(const sem_ref obj, void * osobj);
+
+#else
+
+# define thread_exit(c) pthread_exit((void*)(UINTPTR_T)(c))
+# define tickle_sem sem_post
+void * blocking_thread(void *);
+static void block_thread_signals(sigset_t *);
+
+#endif
+
+#ifdef WORK_PIPE
+addremove_io_fd_func addremove_io_fd;
+#else
+addremove_io_semaphore_func addremove_io_semaphore;
+#endif
+
+static void start_blocking_thread(blocking_child *);
+static void start_blocking_thread_internal(blocking_child *);
+static void prepare_child_sems(blocking_child *);
+static int wait_for_sem(sem_ref, struct timespec *);
+static int ensure_workitems_empty_slot(blocking_child *);
+static int ensure_workresp_empty_slot(blocking_child *);
+static int queue_req_pointer(blocking_child *, blocking_pipe_header *);
+static void cleanup_after_child(blocking_child *);
+
+static sema_type worker_mmutex;
+static sem_ref worker_memlock;
+
+/* --------------------------------------------------------------------
+ * locking the global worker state table (and other global stuff)
+ */
+void
+worker_global_lock(
+ int inOrOut)
+{
+ if (worker_memlock) {
+ if (inOrOut)
+ wait_for_sem(worker_memlock, NULL);
+ else
+ tickle_sem(worker_memlock);
+ }
+}
+
+/* --------------------------------------------------------------------
+ * implementation isolation wrapper
+ */
+void
+exit_worker(
+ int exitcode
+ )
+{
+ thread_exit(exitcode); /* see #define thread_exit */
+}
+
+/* --------------------------------------------------------------------
+ * sleep for a given time or until the wakup semaphore is tickled.
+ */
+int
+worker_sleep(
+ blocking_child * c,
+ time_t seconds
+ )
+{
+ struct timespec until;
+ int rc;
+
+# ifdef HAVE_CLOCK_GETTIME
+ if (0 != clock_gettime(CLOCK_REALTIME, &until)) {
+ msyslog(LOG_ERR, "worker_sleep: clock_gettime() failed: %m");
+ return -1;
+ }
+# else
+ if (0 != getclock(TIMEOFDAY, &until)) {
+ msyslog(LOG_ERR, "worker_sleep: getclock() failed: %m");
+ return -1;
+ }
+# endif
+ until.tv_sec += seconds;
+ rc = wait_for_sem(c->wake_scheduled_sleep, &until);
+ if (0 == rc)
+ return -1;
+ if (-1 == rc && ETIMEDOUT == errno)
+ return 0;
+ msyslog(LOG_ERR, "worker_sleep: sem_timedwait: %m");
+ return -1;
+}
+
+
+/* --------------------------------------------------------------------
+ * Wake up a worker that takes a nap.
+ */
+void
+interrupt_worker_sleep(void)
+{
+ u_int idx;
+ blocking_child * c;
+
+ for (idx = 0; idx < blocking_children_alloc; idx++) {
+ c = blocking_children[idx];
+ if (NULL == c || NULL == c->wake_scheduled_sleep)
+ continue;
+ tickle_sem(c->wake_scheduled_sleep);
+ }
+}
+
+/* --------------------------------------------------------------------
+ * Make sure there is an empty slot at the head of the request
+ * queue. Tell if the queue is currently empty.
+ */
+static int
+ensure_workitems_empty_slot(
+ blocking_child *c
+ )
+{
+ /*
+ ** !!! PRECONDITION: caller holds access lock!
+ **
+ ** This simply tries to increase the size of the buffer if it
+ ** becomes full. The resize operation does *not* maintain the
+ ** order of requests, but that should be irrelevant since the
+ ** processing is considered asynchronous anyway.
+ **
+ ** Return if the buffer is currently empty.
+ */
+
+ static const size_t each =
+ sizeof(blocking_children[0]->workitems[0]);
+
+ size_t new_alloc;
+ size_t slots_used;
+ size_t sidx;
+
+ slots_used = c->head_workitem - c->tail_workitem;
+ if (slots_used >= c->workitems_alloc) {
+ new_alloc = c->workitems_alloc + WORKITEMS_ALLOC_INC;
+ c->workitems = erealloc(c->workitems, new_alloc * each);
+ for (sidx = c->workitems_alloc; sidx < new_alloc; ++sidx)
+ c->workitems[sidx] = NULL;
+ c->tail_workitem = 0;
+ c->head_workitem = c->workitems_alloc;
+ c->workitems_alloc = new_alloc;
+ }
+ INSIST(NULL == c->workitems[c->head_workitem % c->workitems_alloc]);
+ return (0 == slots_used);
+}
+
+/* --------------------------------------------------------------------
+ * Make sure there is an empty slot at the head of the response
+ * queue. Tell if the queue is currently empty.
+ */
+static int
+ensure_workresp_empty_slot(
+ blocking_child *c
+ )
+{
+ /*
+ ** !!! PRECONDITION: caller holds access lock!
+ **
+ ** Works like the companion function above.
+ */
+
+ static const size_t each =
+ sizeof(blocking_children[0]->responses[0]);
+
+ size_t new_alloc;
+ size_t slots_used;
+ size_t sidx;
+
+ slots_used = c->head_response - c->tail_response;
+ if (slots_used >= c->responses_alloc) {
+ new_alloc = c->responses_alloc + RESPONSES_ALLOC_INC;
+ c->responses = erealloc(c->responses, new_alloc * each);
+ for (sidx = c->responses_alloc; sidx < new_alloc; ++sidx)
+ c->responses[sidx] = NULL;
+ c->tail_response = 0;
+ c->head_response = c->responses_alloc;
+ c->responses_alloc = new_alloc;
+ }
+ INSIST(NULL == c->responses[c->head_response % c->responses_alloc]);
+ return (0 == slots_used);
+}
+
+
+/* --------------------------------------------------------------------
+ * queue_req_pointer() - append a work item or idle exit request to
+ * blocking_workitems[]. Employ proper locking.
+ */
+static int
+queue_req_pointer(
+ blocking_child * c,
+ blocking_pipe_header * hdr
+ )
+{
+ size_t qhead;
+
+ /* >>>> ACCESS LOCKING STARTS >>>> */
+ wait_for_sem(c->accesslock, NULL);
+ ensure_workitems_empty_slot(c);
+ qhead = c->head_workitem;
+ c->workitems[qhead % c->workitems_alloc] = hdr;
+ c->head_workitem = 1 + qhead;
+ tickle_sem(c->accesslock);
+ /* <<<< ACCESS LOCKING ENDS <<<< */
+
+ /* queue consumer wake-up notification */
+ tickle_sem(c->workitems_pending);
+
+ return 0;
+}
+
+/* --------------------------------------------------------------------
+ * API function to make sure a worker is running, a proper private copy
+ * of the data is made, the data eneterd into the queue and the worker
+ * is signalled.
+ */
+int
+send_blocking_req_internal(
+ blocking_child * c,
+ blocking_pipe_header * hdr,
+ void * data
+ )
+{
+ blocking_pipe_header * threadcopy;
+ size_t payload_octets;
+
+ REQUIRE(hdr != NULL);
+ REQUIRE(data != NULL);
+ DEBUG_REQUIRE(BLOCKING_REQ_MAGIC == hdr->magic_sig);
+
+ if (hdr->octets <= sizeof(*hdr))
+ return 1; /* failure */
+ payload_octets = hdr->octets - sizeof(*hdr);
+
+ if (NULL == c->thread_ref)
+ start_blocking_thread(c);
+ threadcopy = emalloc(hdr->octets);
+ memcpy(threadcopy, hdr, sizeof(*hdr));
+ memcpy((char *)threadcopy + sizeof(*hdr), data, payload_octets);
+
+ return queue_req_pointer(c, threadcopy);
+}
+
+/* --------------------------------------------------------------------
+ * Wait for the 'incoming queue no longer empty' signal, lock the shared
+ * structure and dequeue an item.
+ */
+blocking_pipe_header *
+receive_blocking_req_internal(
+ blocking_child * c
+ )
+{
+ blocking_pipe_header * req;
+ size_t qhead, qtail;
+
+ req = NULL;
+ do {
+ /* wait for tickle from the producer side */
+ wait_for_sem(c->workitems_pending, NULL);
+
+ /* >>>> ACCESS LOCKING STARTS >>>> */
+ wait_for_sem(c->accesslock, NULL);
+ qhead = c->head_workitem;
+ do {
+ qtail = c->tail_workitem;
+ if (qhead == qtail)
+ break;
+ c->tail_workitem = qtail + 1;
+ qtail %= c->workitems_alloc;
+ req = c->workitems[qtail];
+ c->workitems[qtail] = NULL;
+ } while (NULL == req);
+ tickle_sem(c->accesslock);
+ /* <<<< ACCESS LOCKING ENDS <<<< */
+
+ } while (NULL == req);
+
+ INSIST(NULL != req);
+ if (CHILD_EXIT_REQ == req) { /* idled out */
+ send_blocking_resp_internal(c, CHILD_GONE_RESP);
+ req = NULL;
+ }
+
+ return req;
+}
+
+/* --------------------------------------------------------------------
+ * Push a response into the return queue and eventually tickle the
+ * receiver.
+ */
+int
+send_blocking_resp_internal(
+ blocking_child * c,
+ blocking_pipe_header * resp
+ )
+{
+ size_t qhead;
+ int empty;
+
+ /* >>>> ACCESS LOCKING STARTS >>>> */
+ wait_for_sem(c->accesslock, NULL);
+ empty = ensure_workresp_empty_slot(c);
+ qhead = c->head_response;
+ c->responses[qhead % c->responses_alloc] = resp;
+ c->head_response = 1 + qhead;
+ tickle_sem(c->accesslock);
+ /* <<<< ACCESS LOCKING ENDS <<<< */
+
+ /* queue consumer wake-up notification */
+ if (empty)
+ {
+# ifdef WORK_PIPE
+ if (1 != write(c->resp_write_pipe, "", 1))
+ msyslog(LOG_WARNING, "async resolver: %s",
+ "failed to notify main thread!");
+# else
+ tickle_sem(c->responses_pending);
+# endif
+ }
+ return 0;
+}
+
+
+#ifndef WORK_PIPE
+
+/* --------------------------------------------------------------------
+ * Check if a (Windows-)hanndle to a semaphore is actually the same we
+ * are using inside the sema wrapper.
+ */
+static BOOL
+same_os_sema(
+ const sem_ref obj,
+ void* osh
+ )
+{
+ return obj && osh && (obj->shnd == (HANDLE)osh);
+}
+
+/* --------------------------------------------------------------------
+ * Find the shared context that associates to an OS handle and make sure
+ * the data is dequeued and processed.
+ */
+void
+handle_blocking_resp_sem(
+ void * context
+ )
+{
+ blocking_child * c;
+ u_int idx;
+
+ c = NULL;
+ for (idx = 0; idx < blocking_children_alloc; idx++) {
+ c = blocking_children[idx];
+ if (c != NULL &&
+ c->thread_ref != NULL &&
+ same_os_sema(c->responses_pending, context))
+ break;
+ }
+ if (idx < blocking_children_alloc)
+ process_blocking_resp(c);
+}
+#endif /* !WORK_PIPE */
+
+/* --------------------------------------------------------------------
+ * Fetch the next response from the return queue. In case of signalling
+ * via pipe, make sure the pipe is flushed, too.
+ */
+blocking_pipe_header *
+receive_blocking_resp_internal(
+ blocking_child * c
+ )
+{
+ blocking_pipe_header * removed;
+ size_t qhead, qtail, slot;
+
+#ifdef WORK_PIPE
+ int rc;
+ char scratch[32];
+
+ do
+ rc = read(c->resp_read_pipe, scratch, sizeof(scratch));
+ while (-1 == rc && EINTR == errno);
+#endif
+
+ /* >>>> ACCESS LOCKING STARTS >>>> */
+ wait_for_sem(c->accesslock, NULL);
+ qhead = c->head_response;
+ qtail = c->tail_response;
+ for (removed = NULL; !removed && (qhead != qtail); ++qtail) {
+ slot = qtail % c->responses_alloc;
+ removed = c->responses[slot];
+ c->responses[slot] = NULL;
+ }
+ c->tail_response = qtail;
+ tickle_sem(c->accesslock);
+ /* <<<< ACCESS LOCKING ENDS <<<< */
+
+ if (NULL != removed) {
+ DEBUG_ENSURE(CHILD_GONE_RESP == removed ||
+ BLOCKING_RESP_MAGIC == removed->magic_sig);
+ }
+ if (CHILD_GONE_RESP == removed) {
+ cleanup_after_child(c);
+ removed = NULL;
+ }
+
+ return removed;
+}
+
+/* --------------------------------------------------------------------
+ * Light up a new worker.
+ */
+static void
+start_blocking_thread(
+ blocking_child * c
+ )
+{
+
+ DEBUG_INSIST(!c->reusable);
+
+ prepare_child_sems(c);
+ start_blocking_thread_internal(c);
+}
+
+/* --------------------------------------------------------------------
+ * Create a worker thread. There are several differences between POSIX
+ * and Windows, of course -- most notably the Windows thread is no
+ * detached thread, and we keep the handle around until we want to get
+ * rid of the thread. The notification scheme also differs: Windows
+ * makes use of semaphores in both directions, POSIX uses a pipe for
+ * integration with 'select()' or alike.
+ */
+static void
+start_blocking_thread_internal(
+ blocking_child * c
+ )
+#ifdef SYS_WINNT
+{
+ BOOL resumed;
+
+ c->thread_ref = NULL;
+ (*addremove_io_semaphore)(c->responses_pending->shnd, FALSE);
+ c->thr_table[0].thnd =
+ (HANDLE)_beginthreadex(
+ NULL,
+ 0,
+ &blocking_thread,
+ c,
+ CREATE_SUSPENDED,
+ NULL);
+
+ if (NULL == c->thr_table[0].thnd) {
+ msyslog(LOG_ERR, "start blocking thread failed: %m");
+ exit(-1);
+ }
+ /* remember the thread priority is only within the process class */
+ if (!SetThreadPriority(c->thr_table[0].thnd,
+ THREAD_PRIORITY_BELOW_NORMAL))
+ msyslog(LOG_ERR, "Error lowering blocking thread priority: %m");
+
+ resumed = ResumeThread(c->thr_table[0].thnd);
+ DEBUG_INSIST(resumed);
+ c->thread_ref = &c->thr_table[0];
+}
+#else /* pthreads start_blocking_thread_internal() follows */
+{
+# ifdef NEED_PTHREAD_INIT
+ static int pthread_init_called;
+# endif
+ pthread_attr_t thr_attr;
+ int rc;
+ int pipe_ends[2]; /* read then write */
+ int is_pipe;
+ int flags;
+ size_t ostacksize;
+ size_t nstacksize;
+ sigset_t saved_sig_mask;
+
+ c->thread_ref = NULL;
+
+# ifdef NEED_PTHREAD_INIT
+ /*
+ * from lib/isc/unix/app.c:
+ * BSDI 3.1 seg faults in pthread_sigmask() if we don't do this.
+ */
+ if (!pthread_init_called) {
+ pthread_init();
+ pthread_init_called = TRUE;
+ }
+# endif
+
+ rc = pipe_socketpair(&pipe_ends[0], &is_pipe);
+ if (0 != rc) {
+ msyslog(LOG_ERR, "start_blocking_thread: pipe_socketpair() %m");
+ exit(1);
+ }
+ c->resp_read_pipe = move_fd(pipe_ends[0]);
+ c->resp_write_pipe = move_fd(pipe_ends[1]);
+ c->ispipe = is_pipe;
+ flags = fcntl(c->resp_read_pipe, F_GETFL, 0);
+ if (-1 == flags) {
+ msyslog(LOG_ERR, "start_blocking_thread: fcntl(F_GETFL) %m");
+ exit(1);
+ }
+ rc = fcntl(c->resp_read_pipe, F_SETFL, O_NONBLOCK | flags);
+ if (-1 == rc) {
+ msyslog(LOG_ERR,
+ "start_blocking_thread: fcntl(F_SETFL, O_NONBLOCK) %m");
+ exit(1);
+ }
+ (*addremove_io_fd)(c->resp_read_pipe, c->ispipe, FALSE);
+ pthread_attr_init(&thr_attr);
+ pthread_attr_setdetachstate(&thr_attr, PTHREAD_CREATE_DETACHED);
+#if defined(HAVE_PTHREAD_ATTR_GETSTACKSIZE) && \
+ defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE)
+ rc = pthread_attr_getstacksize(&thr_attr, &ostacksize);
+ if (0 != rc) {
+ msyslog(LOG_ERR,
+ "start_blocking_thread: pthread_attr_getstacksize() -> %s",
+ strerror(rc));
+ } else {
+ if (ostacksize < THREAD_MINSTACKSIZE)
+ nstacksize = THREAD_MINSTACKSIZE;
+ else if (ostacksize > THREAD_MAXSTACKSIZE)
+ nstacksize = THREAD_MAXSTACKSIZE;
+ else
+ nstacksize = ostacksize;
+ if (nstacksize != ostacksize)
+ rc = pthread_attr_setstacksize(&thr_attr, nstacksize);
+ if (0 != rc)
+ msyslog(LOG_ERR,
+ "start_blocking_thread: pthread_attr_setstacksize(0x%lx -> 0x%lx) -> %s",
+ (u_long)ostacksize, (u_long)nstacksize,
+ strerror(rc));
+ }
+#else
+ UNUSED_ARG(nstacksize);
+ UNUSED_ARG(ostacksize);
+#endif
+#if defined(PTHREAD_SCOPE_SYSTEM) && defined(NEED_PTHREAD_SCOPE_SYSTEM)
+ pthread_attr_setscope(&thr_attr, PTHREAD_SCOPE_SYSTEM);
+#endif
+ c->thread_ref = emalloc_zero(sizeof(*c->thread_ref));
+ block_thread_signals(&saved_sig_mask);
+ rc = pthread_create(&c->thr_table[0], &thr_attr,
+ &blocking_thread, c);
+ pthread_sigmask(SIG_SETMASK, &saved_sig_mask, NULL);
+ pthread_attr_destroy(&thr_attr);
+ if (0 != rc) {
+ msyslog(LOG_ERR, "start_blocking_thread: pthread_create() -> %s",
+ strerror(rc));
+ exit(1);
+ }
+ c->thread_ref = &c->thr_table[0];
+}
+#endif
+
+/* --------------------------------------------------------------------
+ * block_thread_signals()
+ *
+ * Temporarily block signals used by ntpd main thread, so that signal
+ * mask inherited by child threads leaves them blocked. Returns prior
+ * active signal mask via pmask, to be restored by the main thread
+ * after pthread_create().
+ */
+#ifndef SYS_WINNT
+void
+block_thread_signals(
+ sigset_t * pmask
+ )
+{
+#ifndef __rtems__
+ sigset_t block;
+
+ sigemptyset(&block);
+# ifdef HAVE_SIGNALED_IO
+# ifdef SIGIO
+ sigaddset(&block, SIGIO);
+# endif
+# ifdef SIGPOLL
+ sigaddset(&block, SIGPOLL);
+# endif
+# endif /* HAVE_SIGNALED_IO */
+ sigaddset(&block, SIGALRM);
+ sigaddset(&block, MOREDEBUGSIG);
+ sigaddset(&block, LESSDEBUGSIG);
+# ifdef SIGDIE1
+ sigaddset(&block, SIGDIE1);
+# endif
+# ifdef SIGDIE2
+ sigaddset(&block, SIGDIE2);
+# endif
+# ifdef SIGDIE3
+ sigaddset(&block, SIGDIE3);
+# endif
+# ifdef SIGDIE4
+ sigaddset(&block, SIGDIE4);
+# endif
+# ifdef SIGBUS
+ sigaddset(&block, SIGBUS);
+# endif
+ sigemptyset(pmask);
+ pthread_sigmask(SIG_BLOCK, &block, pmask);
+#endif /* __rtems__ */
+}
+#endif /* !SYS_WINNT */
+
+
+/* --------------------------------------------------------------------
+ * Create & destroy semaphores. This is sufficiently different between
+ * POSIX and Windows to warrant wrapper functions and close enough to
+ * use the concept of synchronization via semaphore for all platforms.
+ */
+static sem_ref
+create_sema(
+ sema_type* semptr,
+ u_int inival,
+ u_int maxval)
+{
+#ifdef SYS_WINNT
+
+ long svini, svmax;
+ if (NULL != semptr) {
+ svini = (inival < LONG_MAX)
+ ? (long)inival : LONG_MAX;
+ svmax = (maxval < LONG_MAX && maxval > 0)
+ ? (long)maxval : LONG_MAX;
+ semptr->shnd = CreateSemaphore(NULL, svini, svmax, NULL);
+ if (NULL == semptr->shnd)
+ semptr = NULL;
+ }
+
+#else
+
+ (void)maxval;
+ if (semptr && sem_init(semptr, FALSE, inival))
+ semptr = NULL;
+
+#endif
+
+ return semptr;
+}
+
+/* ------------------------------------------------------------------ */
+static sem_ref
+delete_sema(
+ sem_ref obj)
+{
+
+# ifdef SYS_WINNT
+
+ if (obj) {
+ if (obj->shnd)
+ CloseHandle(obj->shnd);
+ obj->shnd = NULL;
+ }
+
+# else
+
+ if (obj)
+ sem_destroy(obj);
+
+# endif
+
+ return NULL;
+}
+
+/* --------------------------------------------------------------------
+ * prepare_child_sems()
+ *
+ * create sync & access semaphores
+ *
+ * All semaphores are cleared, only the access semaphore has 1 unit.
+ * Childs wait on 'workitems_pending', then grabs 'sema_access'
+ * and dequeues jobs. When done, 'sema_access' is given one unit back.
+ *
+ * The producer grabs 'sema_access', manages the queue, restores
+ * 'sema_access' and puts one unit into 'workitems_pending'.
+ *
+ * The story goes the same for the response queue.
+ */
+static void
+prepare_child_sems(
+ blocking_child *c
+ )
+{
+ if (NULL == worker_memlock)
+ worker_memlock = create_sema(&worker_mmutex, 1, 1);
+
+ c->accesslock = create_sema(&c->sem_table[0], 1, 1);
+ c->workitems_pending = create_sema(&c->sem_table[1], 0, 0);
+ c->wake_scheduled_sleep = create_sema(&c->sem_table[2], 0, 1);
+# ifndef WORK_PIPE
+ c->responses_pending = create_sema(&c->sem_table[3], 0, 0);
+# endif
+}
+
+/* --------------------------------------------------------------------
+ * wait for semaphore. Where the wait can be interrupted, it will
+ * internally resume -- When this function returns, there is either no
+ * semaphore at all, a timeout occurred, or the caller could
+ * successfully take a token from the semaphore.
+ *
+ * For untimed wait, not checking the result of this function at all is
+ * definitely an option.
+ */
+static int
+wait_for_sem(
+ sem_ref sem,
+ struct timespec * timeout /* wall-clock */
+ )
+#ifdef SYS_WINNT
+{
+ struct timespec now;
+ struct timespec delta;
+ DWORD msec;
+ DWORD rc;
+
+ if (!(sem && sem->shnd)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (NULL == timeout) {
+ msec = INFINITE;
+ } else {
+ getclock(TIMEOFDAY, &now);
+ delta = sub_tspec(*timeout, now);
+ if (delta.tv_sec < 0) {
+ msec = 0;
+ } else if ((delta.tv_sec + 1) >= (MAXDWORD / 1000)) {
+ msec = INFINITE;
+ } else {
+ msec = 1000 * (DWORD)delta.tv_sec;
+ msec += delta.tv_nsec / (1000 * 1000);
+ }
+ }
+ rc = WaitForSingleObject(sem->shnd, msec);
+ if (WAIT_OBJECT_0 == rc)
+ return 0;
+ if (WAIT_TIMEOUT == rc) {
+ errno = ETIMEDOUT;
+ return -1;
+ }
+ msyslog(LOG_ERR, "WaitForSingleObject unexpected 0x%x", rc);
+ errno = EFAULT;
+ return -1;
+}
+#else /* pthreads wait_for_sem() follows */
+{
+ int rc = -1;
+
+ if (sem) do {
+ if (NULL == timeout)
+ rc = sem_wait(sem);
+ else
+ rc = sem_timedwait(sem, timeout);
+ } while (rc == -1 && errno == EINTR);
+ else
+ errno = EINVAL;
+
+ return rc;
+}
+#endif
+
+/* --------------------------------------------------------------------
+ * blocking_thread - thread functions have WINAPI (aka 'stdcall')
+ * calling conventions under Windows and POSIX-defined signature
+ * otherwise.
+ */
+#ifdef SYS_WINNT
+u_int WINAPI
+#else
+void *
+#endif
+blocking_thread(
+ void * ThreadArg
+ )
+{
+ blocking_child *c;
+
+ c = ThreadArg;
+ exit_worker(blocking_child_common(c));
+
+ /* NOTREACHED */
+ return 0;
+}
+
+/* --------------------------------------------------------------------
+ * req_child_exit() runs in the parent.
+ *
+ * This function is called from from the idle timer, too, and possibly
+ * without a thread being there any longer. Since we have folded up our
+ * tent in that case and all the semaphores are already gone, we simply
+ * ignore this request in this case.
+ *
+ * Since the existence of the semaphores is controlled exclusively by
+ * the parent, there's no risk of data race here.
+ */
+int
+req_child_exit(
+ blocking_child *c
+ )
+{
+ return (c->accesslock)
+ ? queue_req_pointer(c, CHILD_EXIT_REQ)
+ : 0;
+}
+
+/* --------------------------------------------------------------------
+ * cleanup_after_child() runs in parent.
+ */
+static void
+cleanup_after_child(
+ blocking_child * c
+ )
+{
+ DEBUG_INSIST(!c->reusable);
+
+# ifdef SYS_WINNT
+ /* The thread was not created in detached state, so we better
+ * clean up.
+ */
+ if (c->thread_ref && c->thread_ref->thnd) {
+ WaitForSingleObject(c->thread_ref->thnd, INFINITE);
+ INSIST(CloseHandle(c->thread_ref->thnd));
+ c->thread_ref->thnd = NULL;
+ }
+# endif
+ c->thread_ref = NULL;
+
+ /* remove semaphores and (if signalling vi IO) pipes */
+
+ c->accesslock = delete_sema(c->accesslock);
+ c->workitems_pending = delete_sema(c->workitems_pending);
+ c->wake_scheduled_sleep = delete_sema(c->wake_scheduled_sleep);
+
+# ifdef WORK_PIPE
+ DEBUG_INSIST(-1 != c->resp_read_pipe);
+ DEBUG_INSIST(-1 != c->resp_write_pipe);
+ (*addremove_io_fd)(c->resp_read_pipe, c->ispipe, TRUE);
+ close(c->resp_write_pipe);
+ close(c->resp_read_pipe);
+ c->resp_write_pipe = -1;
+ c->resp_read_pipe = -1;
+# else
+ DEBUG_INSIST(NULL != c->responses_pending);
+ (*addremove_io_semaphore)(c->responses_pending->shnd, TRUE);
+ c->responses_pending = delete_sema(c->responses_pending);
+# endif
+
+ /* Is it necessary to check if there are pending requests and
+ * responses? If so, and if there are, what to do with them?
+ */
+
+ /* re-init buffer index sequencers */
+ c->head_workitem = 0;
+ c->tail_workitem = 0;
+ c->head_response = 0;
+ c->tail_response = 0;
+
+ c->reusable = TRUE;
+}
+
+
+#else /* !WORK_THREAD follows */
+char work_thread_nonempty_compilation_unit;
+#endif
diff --git a/sebhbsd/freebsd/contrib/ntp/libntp/xsbprintf.c b/sebhbsd/freebsd/contrib/ntp/libntp/xsbprintf.c
new file mode 100644
index 0000000..88d6ec9
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/libntp/xsbprintf.c
@@ -0,0 +1,77 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * xsbprintf.c - string buffer formatting helpers
+ *
+ * Written by Juergen Perlinger (perlinger@ntp.org) for the NTP project.
+ * The contents of 'html/copyright.html' apply.
+ */
+
+#include <config.h>
+#include <sys/types.h>
+
+#include "ntp_stdlib.h"
+
+/* eXtended Varlist String Buffer printf
+ *
+ * Formats via 'vsnprintf' into a string buffer, with some semantic
+ * specialties:
+ *
+ * - The start of the buffer pointer is updated according to the number
+ * of characters written.
+ * - If the buffer is insufficient to format the number of charactes,
+ * the partial result will be be discarded, and zero is returned to
+ * indicate nothing was written to the buffer.
+ * - On successful formatting, the return code is the return value of
+ * the inner call to 'vsnprintf()'.
+ * - If there is any error, the state of the buffer will not be
+ * changed. (Bytes in the buffer might be smashed, but the buffer
+ * position does not change, and the NUL marker stays in place at the
+ * current buffer position.)
+ * - If '(*ppbuf - pend) <= 0' (or ppbuf is NULL), fail with EINVAL.
+ */
+int
+xvsbprintf(
+ char **ppbuf, /* pointer to buffer pointer (I/O) */
+ char * const pend, /* buffer end (I) */
+ char const *pfmt, /* printf-like format string */
+ va_list va /* formatting args for above */
+ )
+{
+ char *pbuf = (ppbuf) ? *ppbuf : NULL;
+ int rc = -1;
+ if (pbuf && (pend - pbuf > 0)) {
+ size_t blen = (size_t)(pend - pbuf);
+ rc = vsnprintf(pbuf, blen, pfmt, va);
+ if (rc > 0) {
+ if ((size_t)rc >= blen)
+ rc = 0;
+ pbuf += rc;
+ }
+ *pbuf = '\0'; /* fear of bad vsnprintf */
+ *ppbuf = pbuf;
+ } else {
+ errno = EINVAL;
+ }
+ return rc;
+}
+
+/* variadic wrapper around the buffer string formatter */
+int
+xsbprintf(
+ char **ppbuf, /* pointer to buffer pointer (I/O) */
+ char * const pend, /* buffer end (I) */
+ char const *pfmt, /* printf-like format string */
+ ... /* formatting args for above */
+ )
+{
+ va_list va;
+ int rc;
+
+ va_start(va, pfmt);
+ rc = xvsbprintf(ppbuf, pend, pfmt, va);
+ va_end(va);
+ return rc;
+}
+
+/* that's all folks! */
diff --git a/sebhbsd/freebsd/contrib/ntp/ntpd/cmd_args.c b/sebhbsd/freebsd/contrib/ntp/ntpd/cmd_args.c
new file mode 100644
index 0000000..23ec8c1
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/ntpd/cmd_args.c
@@ -0,0 +1,207 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * cmd_args.c = command-line argument processing
+ */
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "ntpd.h"
+#include "ntp_stdlib.h"
+#include "ntp_config.h"
+#include "ntp_cmdargs.h"
+
+#include "ntpd-opts.h"
+
+/*
+ * Definitions of things either imported from or exported to outside
+ */
+extern char const *progname;
+
+#ifdef HAVE_NETINFO
+extern int check_netinfo;
+#endif
+
+
+/*
+ * getCmdOpts - apply most command line options
+ *
+ * A few options are examined earlier in ntpd.c ntpdmain() and
+ * ports/winnt/ntpd/ntservice.c main().
+ */
+void
+getCmdOpts(
+ int argc,
+ char ** argv
+ )
+{
+ extern const char *config_file;
+ int errflg;
+
+ /*
+ * Initialize, initialize
+ */
+ errflg = 0;
+
+ if (ipv4_works && ipv6_works) {
+ if (HAVE_OPT( IPV4 ))
+ ipv6_works = 0;
+ else if (HAVE_OPT( IPV6 ))
+ ipv4_works = 0;
+ } else if (!ipv4_works && !ipv6_works) {
+ msyslog(LOG_ERR, "Neither IPv4 nor IPv6 networking detected, fatal.");
+ exit(1);
+ } else if (HAVE_OPT( IPV4 ) && !ipv4_works)
+ msyslog(LOG_WARNING, "-4/--ipv4 ignored, IPv4 networking not found.");
+ else if (HAVE_OPT( IPV6 ) && !ipv6_works)
+ msyslog(LOG_WARNING, "-6/--ipv6 ignored, IPv6 networking not found.");
+
+ if (HAVE_OPT( AUTHREQ ))
+ proto_config(PROTO_AUTHENTICATE, 1, 0., NULL);
+ else if (HAVE_OPT( AUTHNOREQ ))
+ proto_config(PROTO_AUTHENTICATE, 0, 0., NULL);
+
+ if (HAVE_OPT( BCASTSYNC ))
+ proto_config(PROTO_BROADCLIENT, 1, 0., NULL);
+
+ if (HAVE_OPT( CONFIGFILE )) {
+ config_file = OPT_ARG( CONFIGFILE );
+#ifdef HAVE_NETINFO
+ check_netinfo = 0;
+#endif
+ }
+
+ if (HAVE_OPT( DRIFTFILE ))
+ stats_config(STATS_FREQ_FILE, OPT_ARG( DRIFTFILE ));
+
+ if (HAVE_OPT( PANICGATE ))
+ allow_panic = TRUE;
+
+ if (HAVE_OPT( FORCE_STEP_ONCE ))
+ force_step_once = TRUE;
+
+#ifdef HAVE_DROPROOT
+ if (HAVE_OPT( JAILDIR )) {
+ droproot = 1;
+ chrootdir = OPT_ARG( JAILDIR );
+ }
+#endif
+
+ if (HAVE_OPT( KEYFILE ))
+ getauthkeys(OPT_ARG( KEYFILE ));
+
+ if (HAVE_OPT( PIDFILE ))
+ stats_config(STATS_PID_FILE, OPT_ARG( PIDFILE ));
+
+ if (HAVE_OPT( QUIT ))
+ mode_ntpdate = TRUE;
+
+ if (HAVE_OPT( PROPAGATIONDELAY ))
+ do {
+ double tmp;
+ const char *my_ntp_optarg = OPT_ARG( PROPAGATIONDELAY );
+
+ if (sscanf(my_ntp_optarg, "%lf", &tmp) != 1) {
+ msyslog(LOG_ERR,
+ "command line broadcast delay value %s undecodable",
+ my_ntp_optarg);
+ } else {
+ proto_config(PROTO_BROADDELAY, 0, tmp, NULL);
+ }
+ } while (0);
+
+ if (HAVE_OPT( STATSDIR ))
+ stats_config(STATS_STATSDIR, OPT_ARG( STATSDIR ));
+
+ if (HAVE_OPT( TRUSTEDKEY )) {
+ int ct = STACKCT_OPT( TRUSTEDKEY );
+ const char** pp = STACKLST_OPT( TRUSTEDKEY );
+
+ do {
+ u_long tkey;
+ const char* p = *pp++;
+
+ tkey = (int)atol(p);
+ if (tkey == 0 || tkey > NTP_MAXKEY) {
+ msyslog(LOG_ERR,
+ "command line trusted key %s is invalid",
+ p);
+ } else {
+ authtrust(tkey, 1);
+ }
+ } while (--ct > 0);
+ }
+
+#ifdef HAVE_DROPROOT
+ if (HAVE_OPT( USER )) {
+ droproot = 1;
+ user = estrdup(OPT_ARG( USER ));
+ group = strrchr(user, ':');
+ if (group != NULL) {
+ size_t len;
+
+ *group++ = '\0'; /* get rid of the ':' */
+ len = group - user;
+ group = estrdup(group);
+ user = erealloc(user, len);
+ }
+ }
+#endif
+
+ if (HAVE_OPT( VAR )) {
+ int ct;
+ const char ** pp;
+ const char * v_assign;
+
+ ct = STACKCT_OPT( VAR );
+ pp = STACKLST_OPT( VAR );
+
+ do {
+ v_assign = *pp++;
+ set_sys_var(v_assign, strlen(v_assign) + 1, RW);
+ } while (--ct > 0);
+ }
+
+ if (HAVE_OPT( DVAR )) {
+ int ct = STACKCT_OPT( DVAR );
+ const char** pp = STACKLST_OPT( DVAR );
+
+ do {
+ const char* my_ntp_optarg = *pp++;
+
+ set_sys_var(my_ntp_optarg, strlen(my_ntp_optarg)+1,
+ (u_short) (RW | DEF));
+ } while (--ct > 0);
+ }
+
+ if (HAVE_OPT( SLEW ))
+ loop_config(LOOP_MAX, 600);
+
+ if (HAVE_OPT( UPDATEINTERVAL )) {
+ long val = OPT_VALUE_UPDATEINTERVAL;
+
+ if (val >= 0)
+ interface_interval = val;
+ else {
+ fprintf(stderr,
+ "command line interface update interval %ld must not be negative\n",
+ val);
+ msyslog(LOG_ERR,
+ "command line interface update interval %ld must not be negative",
+ val);
+ errflg++;
+ }
+ }
+
+
+ /* save list of servers from cmd line for config_peers() use */
+ if (argc > 0) {
+ cmdline_server_count = argc;
+ cmdline_servers = argv;
+ }
+
+ /* display usage & exit with any option processing errors */
+ if (errflg)
+ optionUsage(&ntpdOptions, 2); /* does not return */
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/ntpd/jupiter.h b/sebhbsd/freebsd/contrib/ntp/ntpd/jupiter.h
new file mode 100644
index 0000000..ed80b0c
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/ntpd/jupiter.h
@@ -0,0 +1,255 @@
+/* @(#) $Header$ (LBL) */
+
+/*
+ * Rockwell Jupiter GPS receiver definitions
+ *
+ * This is all based on the "Zodiac GPS Receiver Family Designer's
+ * Guide" (dated 12/96)
+ */
+
+#define JUPITER_SYNC 0x81ff /* sync word (book says 0xff81 !?!?) */
+#define JUPITER_ALL 0xffff /* disable all output messages */
+
+/* Output messages (sent by the Jupiter board) */
+#define JUPITER_O_GPOS 1000 /* geodetic position status */
+#define JUPITER_O_EPOS 1001 /* ECEF position status */
+#define JUPITER_O_CHAN 1002 /* channel summary */
+#define JUPITER_O_VIS 1003 /* visible satellites */
+#define JUPITER_O_DGPS 1005 /* differential GPS status */
+#define JUPITER_O_MEAS 1007 /* channel measurement */
+#define JUPITER_O_ID 1011 /* receiver id */
+#define JUPITER_O_USER 1012 /* user-settings output */
+#define JUPITER_O_TEST 1100 /* built-in test results */
+#define JUPITER_O_MARK 1102 /* measurement time mark */
+#define JUPITER_O_PULSE 1108 /* UTC time mark pulse output */
+#define JUPITER_O_PORT 1130 /* serial port com parameters in use */
+#define JUPITER_O_EUP 1135 /* EEPROM update */
+#define JUPITER_O_ESTAT 1136 /* EEPROM status */
+
+/* Input messages (sent to the Jupiter board) */
+#define JUPITER_I_PVTINIT 1200 /* geodetic position and velocity */
+#define JUPITER_I_USER 1210 /* user-defined datum */
+#define JUPITER_I_MAPSEL 1211 /* map datum select */
+#define JUPITER_I_ELEV 1212 /* satellite elevation mask control */
+#define JUPITER_I_CAND 1213 /* satellite candidate select */
+#define JUPITER_I_DGPS 1214 /* differential GPS control */
+#define JUPITER_I_COLD 1216 /* cold start control */
+#define JUPITER_I_VALID 1217 /* solution validity criteria */
+#define JUPITER_I_ALT 1219 /* user-entered altitude input */
+#define JUPITER_I_PLAT 1220 /* application platform control */
+#define JUPITER_I_NAV 1221 /* nav configuration */
+#define JUPITER_I_TEST 1300 /* preform built-in test command */
+#define JUPITER_I_RESTART 1303 /* restart command */
+#define JUPITER_I_PORT 1330 /* serial port com parameters */
+#define JUPITER_I_PROTO 1331 /* message protocol control */
+#define JUPITER_I_RDGPS 1351 /* raw DGPS RTCM SC-104 data */
+
+struct jheader {
+ u_short sync; /* (JUPITER_SYNC) */
+ u_short id; /* message id */
+ u_short len; /* number of data short wordss (w/o cksum) */
+ u_char reqid; /* JUPITER_REQID_MASK bits available as id */
+ u_char flags; /* flags */
+ u_short hsum; /* header cksum */
+};
+
+#define JUPITER_REQID_MASK 0x3f /* bits available as id */
+#define JUPITER_FLAG_NAK 0x01 /* negative acknowledgement */
+#define JUPITER_FLAG_ACK 0x02 /* acknowledgement */
+#define JUPITER_FLAG_REQUEST 0x04 /* request ACK or NAK */
+#define JUPITER_FLAG_QUERY 0x08 /* request one shot output message */
+#define JUPITER_FLAG_LOG 0x20 /* request periodic output message */
+#define JUPITER_FLAG_CONN 0x40 /* enable periodic message */
+#define JUPITER_FLAG_DISC 0x80 /* disable periodic message */
+
+#define JUPITER_H_FLAG_BITS \
+ "\020\1NAK\2ACK\3REQUEST\4QUERY\5MBZ\6LOG\7CONN\10DISC"
+
+/* Log request messages (data payload when using JUPITER_FLAG_LOG) */
+struct jrequest {
+ u_short trigger; /* if 0, trigger on time trigger on
+ update (e.g. new almanac) */
+ u_short interval; /* frequency in seconds */
+ u_short offset; /* offset into minute */
+ u_short dsum; /* checksum */
+};
+
+/* JUPITER_O_GPOS (1000) */
+struct jgpos {
+ u_short stime[2]; /* set time (10 ms ticks) */
+ u_short seq; /* sequence number */
+ u_short sseq; /* sat measurement sequence number */
+ u_short navval; /* navigation soltuion validity */
+ u_short navtype; /* navigation solution type */
+ u_short nmeas; /* # of measurements used in solution */
+ u_short polar; /* if 1 then polar navigation */
+ u_short gweek; /* GPS week number */
+ u_short sweek[2]; /* GPS seconds into week */
+ u_short nsweek[2]; /* GPS nanoseconds into second */
+ u_short utcday; /* 1 to 31 */
+ u_short utcmon; /* 1 to 12 */
+ u_short utcyear; /* 1980 to 2079 */
+ u_short utchour; /* 0 to 23 */
+ u_short utcmin; /* 0 to 59 */
+ u_short utcsec; /* 0 to 59 */
+ u_short utcnsec[2]; /* 0 to 999999999 */
+ u_short lat[2]; /* latitude (radians) */
+ u_short lon[2]; /* longitude (radians) */
+ u_short height[2]; /* height (meters) */
+ u_short gsep; /* geoidal separation */
+ u_short speed[2]; /* ground speed (meters/sec) */
+ u_short course; /* true course (radians) */
+ u_short mvar;
+ u_short climb;
+ u_short mapd;
+ u_short herr[2];
+ u_short verr[2];
+ u_short terr[2];
+ u_short hverr;
+ u_short bias[2];
+ u_short biassd[2];
+ u_short drift[2];
+ u_short driftsd[2];
+ u_short dsum; /* checksum */
+};
+#define JUPITER_O_GPOS_NAV_NOALT 0x01 /* altitude used */
+#define JUPITER_O_GPOS_NAV_NODGPS 0x02 /* no differential GPS */
+#define JUPITER_O_GPOS_NAV_NOSAT 0x04 /* not enough satellites */
+#define JUPITER_O_GPOS_NAV_MAXH 0x08 /* exceeded max EHPE */
+#define JUPITER_O_GPOS_NAV_MAXV 0x10 /* exceeded max EVPE */
+
+/* JUPITER_O_CHAN (1002) */
+struct jchan {
+ u_short stime[2]; /* set time (10 ms ticks) */
+ u_short seq; /* sequence number */
+ u_short sseq; /* sat measurement sequence number */
+ u_short gweek; /* GPS week number */
+ u_short sweek[2]; /* GPS seconds into week */
+ u_short gpsns[2]; /* GPS nanoseconds from epoch */
+ struct jchan2 {
+ u_short flags; /* flags */
+ u_short prn; /* satellite PRN */
+ u_short chan; /* channel number */
+ } sat[12];
+ u_short dsum;
+};
+
+/* JUPITER_O_VIS (1003) */
+struct jvis {
+ u_short stime[2]; /* set time (10 ms ticks) */
+ u_short seq; /* sequence number */
+ u_short gdop; /* best possible GDOP */
+ u_short pdop; /* best possible PDOP */
+ u_short hdop; /* best possible HDOP */
+ u_short vdop; /* best possible VDOP */
+ u_short tdop; /* best possible TDOP */
+ u_short nvis; /* number of visible satellites */
+ struct jvis2 {
+ u_short prn; /* satellite PRN */
+ u_short azi; /* satellite azimuth (radians) */
+ u_short elev; /* satellite elevation (radians) */
+ } sat[12];
+ u_short dsum; /* checksum */
+};
+
+/* JUPITER_O_ID (1011) */
+struct jid {
+ u_short stime[2]; /* set time (10 ms ticks) */
+ u_short seq; /* sequence number */
+ char chans[20]; /* number of channels (ascii) */
+ char vers[20]; /* software version (ascii) */
+ char date[20]; /* software date (ascii) */
+ char opts[20]; /* software options (ascii) */
+ char reserved[20];
+ u_short dsum; /* checksum */
+};
+
+/* JUPITER_O_USER (1012) */
+struct juser {
+ u_short stime[2]; /* set time (10 ms ticks) */
+ u_short seq; /* sequence number */
+ u_short status; /* operatinoal status */
+ u_short coldtmo; /* cold start time-out */
+ u_short dgpstmo; /* DGPS correction time-out*/
+ u_short emask; /* elevation mask */
+ u_short selcand[2]; /* selected candidate */
+ u_short solflags; /* solution validity criteria */
+ u_short nsat; /* number of satellites in track */
+ u_short herr[2]; /* minimum expected horizontal error */
+ u_short verr[2]; /* minimum expected vertical error */
+ u_short platform; /* application platform */
+ u_short dsum; /* checksum */
+};
+
+/* JUPITER_O_PULSE (1108) */
+struct jpulse {
+ u_short stime[2]; /* set time (10 ms ticks) */
+ u_short seq; /* sequence number */
+ u_short reserved[5];
+ u_short sweek[2]; /* GPS seconds into week */
+ short offs; /* GPS to UTC time offset (seconds) */
+ u_short offns[2]; /* GPS to UTC offset (nanoseconds) */
+ u_short flags; /* flags */
+ u_short dsum; /* checksum */
+};
+#define JUPITER_O_PULSE_VALID 0x1 /* time mark validity */
+#define JUPITER_O_PULSE_UTC 0x2 /* GPS/UTC sync */
+
+/* JUPITER_O_EUP (1135) */
+struct jeup {
+ u_short stime[2]; /* set time (10 ms ticks) */
+ u_short seq; /* sequence number */
+ u_char dataid; /* data id */
+ u_char prn; /* satellite PRN */
+ u_short dsum; /* checksum */
+};
+
+/* JUPITER_I_RESTART (1303) */
+struct jrestart {
+ u_short seq; /* sequence number */
+ u_short flags;
+ u_short dsum; /* checksum */
+};
+#define JUPITER_I_RESTART_INVRAM 0x01
+#define JUPITER_I_RESTART_INVEEPROM 0x02
+#define JUPITER_I_RESTART_INVRTC 0x04
+#define JUPITER_I_RESTART_COLD 0x80
+
+/* JUPITER_I_PVTINIT (1200) */
+struct jpvtinit {
+ u_short flags;
+ u_short gweek; /* GPS week number */
+ u_short sweek[2]; /* GPS seconds into week */
+ u_short utcday; /* 1 to 31 */
+ u_short utcmon; /* 1 to 12 */
+ u_short utcyear; /* 1980 to 2079 */
+ u_short utchour; /* 0 to 23 */
+ u_short utcmin; /* 0 to 59 */
+ u_short utcsec; /* 0 to 59 */
+ u_short lat[2]; /* latitude (radians) */
+ u_short lon[2]; /* longitude (radians) */
+ u_short height[2]; /* height (meters) */
+ u_short speed[2]; /* ground speed (meters/sec) */
+ u_short course; /* true course (radians) */
+ u_short climb;
+ u_short dsum;
+};
+#define JUPITER_I_PVTINIT_FORCE 0x01
+#define JUPITER_I_PVTINIT_GPSVAL 0x02
+#define JUPITER_I_PVTINIT_UTCVAL 0x04
+#define JUPITER_I_PVTINIT_POSVAL 0x08
+#define JUPITER_I_PVTINIT_ALTVAL 0x10
+#define JUPITER_I_PVTINIT_SPDVAL 0x12
+#define JUPITER_I_PVTINIT_MAGVAL 0x14
+#define JUPITER_I_PVTINIT_CLIMBVAL 0x18
+
+/* JUPITER_I_PLAT (1220) */
+struct jplat {
+ u_short seq; /* sequence number */
+ u_short platform; /* application platform */
+ u_short dsum;
+};
+#define JUPITER_I_PLAT_DEFAULT 0 /* default dynamics */
+#define JUPITER_I_PLAT_LOW 2 /* pedestrian */
+#define JUPITER_I_PLAT_MED 5 /* land (e.g. automobile) */
+#define JUPITER_I_PLAT_HIGH 6 /* air */
diff --git a/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_config.c b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_config.c
new file mode 100644
index 0000000..7a469ac
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_config.c
@@ -0,0 +1,5493 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/* ntp_config.c
+ *
+ * This file contains the ntpd configuration code.
+ *
+ * Written By: Sachin Kamboj
+ * University of Delaware
+ * Newark, DE 19711
+ * Some parts borrowed from the older ntp_config.c
+ * Copyright (c) 2006
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef HAVE_NETINFO
+# include <netinfo/ni.h>
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif
+#include <signal.h>
+#ifndef SIGCHLD
+# define SIGCHLD SIGCLD
+#endif
+#ifdef HAVE_SYS_WAIT_H
+# include <sys/wait.h>
+#endif
+
+#include <isc/net.h>
+#include <isc/result.h>
+
+#include "ntp.h"
+#include "ntpd.h"
+#include "ntp_io.h"
+#include "ntp_unixtime.h"
+#include "ntp_refclock.h"
+#include "ntp_filegen.h"
+#include "ntp_stdlib.h"
+#include "lib_strbuf.h"
+#include "ntp_assert.h"
+#include "ntp_random.h"
+/*
+ * [Bug 467]: Some linux headers collide with CONFIG_PHONE and CONFIG_KEYS
+ * so #include these later.
+ */
+#include "ntp_config.h"
+#include "ntp_cmdargs.h"
+#include "ntp_scanner.h"
+#include "ntp_parser.h"
+#include "ntpd-opts.h"
+
+#ifndef IGNORE_DNS_ERRORS
+# define DNSFLAGS 0
+#else
+# define DNSFLAGS GAIR_F_IGNDNSERR
+#endif
+
+extern int yyparse(void);
+
+/* Bug 2817 */
+#if defined(HAVE_SYS_MMAN_H)
+# include <sys/mman.h>
+#endif
+
+/* list of servers from command line for config_peers() */
+int cmdline_server_count;
+char ** cmdline_servers;
+
+/* Current state of memory locking:
+ * -1: default
+ * 0: memory locking disabled
+ * 1: Memory locking enabled
+ */
+int cur_memlock = -1;
+
+/*
+ * "logconfig" building blocks
+ */
+struct masks {
+ const char * const name;
+ const u_int32 mask;
+};
+
+static struct masks logcfg_class[] = {
+ { "clock", NLOG_OCLOCK },
+ { "peer", NLOG_OPEER },
+ { "sync", NLOG_OSYNC },
+ { "sys", NLOG_OSYS },
+ { NULL, 0 }
+};
+
+/* logcfg_noclass_items[] masks are complete and must not be shifted */
+static struct masks logcfg_noclass_items[] = {
+ { "allall", NLOG_SYSMASK | NLOG_PEERMASK | NLOG_CLOCKMASK | NLOG_SYNCMASK },
+ { "allinfo", NLOG_SYSINFO | NLOG_PEERINFO | NLOG_CLOCKINFO | NLOG_SYNCINFO },
+ { "allevents", NLOG_SYSEVENT | NLOG_PEEREVENT | NLOG_CLOCKEVENT | NLOG_SYNCEVENT },
+ { "allstatus", NLOG_SYSSTATUS | NLOG_PEERSTATUS | NLOG_CLOCKSTATUS | NLOG_SYNCSTATUS },
+ { "allstatistics", NLOG_SYSSTATIST | NLOG_PEERSTATIST | NLOG_CLOCKSTATIST | NLOG_SYNCSTATIST },
+ /* the remainder are misspellings of clockall, peerall, sysall, and syncall. */
+ { "allclock", (NLOG_INFO | NLOG_STATIST | NLOG_EVENT | NLOG_STATUS) << NLOG_OCLOCK },
+ { "allpeer", (NLOG_INFO | NLOG_STATIST | NLOG_EVENT | NLOG_STATUS) << NLOG_OPEER },
+ { "allsys", (NLOG_INFO | NLOG_STATIST | NLOG_EVENT | NLOG_STATUS) << NLOG_OSYS },
+ { "allsync", (NLOG_INFO | NLOG_STATIST | NLOG_EVENT | NLOG_STATUS) << NLOG_OSYNC },
+ { NULL, 0 }
+};
+
+/* logcfg_class_items[] masks are shiftable by NLOG_O* counts */
+static struct masks logcfg_class_items[] = {
+ { "all", NLOG_INFO | NLOG_EVENT | NLOG_STATUS | NLOG_STATIST },
+ { "info", NLOG_INFO },
+ { "events", NLOG_EVENT },
+ { "status", NLOG_STATUS },
+ { "statistics", NLOG_STATIST },
+ { NULL, 0 }
+};
+
+typedef struct peer_resolved_ctx_tag {
+ int flags;
+ int host_mode; /* T_* token identifier */
+ u_short family;
+ keyid_t keyid;
+ u_char hmode; /* MODE_* */
+ u_char version;
+ u_char minpoll;
+ u_char maxpoll;
+ u_int32 ttl;
+ const char * group;
+} peer_resolved_ctx;
+
+/* Limits */
+#define MAXPHONE 10 /* maximum number of phone strings */
+#define MAXPPS 20 /* maximum length of PPS device string */
+
+/*
+ * Miscellaneous macros
+ */
+#define ISEOL(c) ((c) == '#' || (c) == '\n' || (c) == '\0')
+#define ISSPACE(c) ((c) == ' ' || (c) == '\t')
+
+#define _UC(str) ((char *)(intptr_t)(str))
+
+/*
+ * Definitions of things either imported from or exported to outside
+ */
+extern int yydebug; /* ntp_parser.c (.y) */
+config_tree cfgt; /* Parser output stored here */
+struct config_tree_tag *cfg_tree_history; /* History of configs */
+char * sys_phone[MAXPHONE] = {NULL}; /* ACTS phone numbers */
+char default_keysdir[] = NTP_KEYSDIR;
+char * keysdir = default_keysdir; /* crypto keys directory */
+char * saveconfigdir;
+#if defined(HAVE_SCHED_SETSCHEDULER)
+int config_priority_override = 0;
+int config_priority;
+#endif
+
+const char *config_file;
+static char default_ntp_signd_socket[] =
+#ifdef NTP_SIGND_PATH
+ NTP_SIGND_PATH;
+#else
+ "";
+#endif
+char *ntp_signd_socket = default_ntp_signd_socket;
+#ifdef HAVE_NETINFO
+struct netinfo_config_state *config_netinfo = NULL;
+int check_netinfo = 1;
+#endif /* HAVE_NETINFO */
+#ifdef SYS_WINNT
+char *alt_config_file;
+LPTSTR temp;
+char config_file_storage[MAX_PATH];
+char alt_config_file_storage[MAX_PATH];
+#endif /* SYS_WINNT */
+
+#ifdef HAVE_NETINFO
+/*
+ * NetInfo configuration state
+ */
+struct netinfo_config_state {
+ void *domain; /* domain with config */
+ ni_id config_dir; /* ID config dir */
+ int prop_index; /* current property */
+ int val_index; /* current value */
+ char **val_list; /* value list */
+};
+#endif
+
+struct REMOTE_CONFIG_INFO remote_config; /* Remote configuration buffer and
+ pointer info */
+int old_config_style = 1; /* A boolean flag, which when set,
+ * indicates that the old configuration
+ * format with a newline at the end of
+ * every command is being used
+ */
+int cryptosw; /* crypto command called */
+
+extern char *stats_drift_file; /* name of the driftfile */
+
+#ifdef BC_LIST_FRAMEWORK_NOT_YET_USED
+/*
+ * backwards compatibility flags
+ */
+bc_entry bc_list[] = {
+ { T_Bc_bugXXXX, 1 } /* default enabled */
+};
+
+/*
+ * declare an int pointer for each flag for quick testing without
+ * walking bc_list. If the pointer is consumed by libntp rather
+ * than ntpd, declare it in a libntp source file pointing to storage
+ * initialized with the appropriate value for other libntp clients, and
+ * redirect it to point into bc_list during ntpd startup.
+ */
+int *p_bcXXXX_enabled = &bc_list[0].enabled;
+#endif
+
+/* FUNCTION PROTOTYPES */
+
+static void init_syntax_tree(config_tree *);
+static void apply_enable_disable(attr_val_fifo *q, int enable);
+
+#ifdef FREE_CFG_T
+static void free_auth_node(config_tree *);
+static void free_all_config_trees(void);
+
+static void free_config_access(config_tree *);
+static void free_config_auth(config_tree *);
+static void free_config_fudge(config_tree *);
+static void free_config_logconfig(config_tree *);
+static void free_config_monitor(config_tree *);
+static void free_config_nic_rules(config_tree *);
+static void free_config_other_modes(config_tree *);
+static void free_config_peers(config_tree *);
+static void free_config_phone(config_tree *);
+static void free_config_reset_counters(config_tree *);
+static void free_config_rlimit(config_tree *);
+static void free_config_setvar(config_tree *);
+static void free_config_system_opts(config_tree *);
+static void free_config_tinker(config_tree *);
+static void free_config_tos(config_tree *);
+static void free_config_trap(config_tree *);
+static void free_config_ttl(config_tree *);
+static void free_config_unpeers(config_tree *);
+static void free_config_vars(config_tree *);
+
+#ifdef SIM
+static void free_config_sim(config_tree *);
+#endif
+static void destroy_address_fifo(address_fifo *);
+#define FREE_ADDRESS_FIFO(pf) \
+ do { \
+ destroy_address_fifo(pf); \
+ (pf) = NULL; \
+ } while (0)
+ void free_all_config_trees(void); /* atexit() */
+static void free_config_tree(config_tree *ptree);
+#endif /* FREE_CFG_T */
+
+static void destroy_restrict_node(restrict_node *my_node);
+static int is_sane_resolved_address(sockaddr_u *peeraddr, int hmode);
+static void save_and_apply_config_tree(int/*BOOL*/ from_file);
+static void destroy_int_fifo(int_fifo *);
+#define FREE_INT_FIFO(pf) \
+ do { \
+ destroy_int_fifo(pf); \
+ (pf) = NULL; \
+ } while (0)
+static void destroy_string_fifo(string_fifo *);
+#define FREE_STRING_FIFO(pf) \
+ do { \
+ destroy_string_fifo(pf); \
+ (pf) = NULL; \
+ } while (0)
+static void destroy_attr_val_fifo(attr_val_fifo *);
+#define FREE_ATTR_VAL_FIFO(pf) \
+ do { \
+ destroy_attr_val_fifo(pf); \
+ (pf) = NULL; \
+ } while (0)
+static void destroy_filegen_fifo(filegen_fifo *);
+#define FREE_FILEGEN_FIFO(pf) \
+ do { \
+ destroy_filegen_fifo(pf); \
+ (pf) = NULL; \
+ } while (0)
+static void destroy_restrict_fifo(restrict_fifo *);
+#define FREE_RESTRICT_FIFO(pf) \
+ do { \
+ destroy_restrict_fifo(pf); \
+ (pf) = NULL; \
+ } while (0)
+static void destroy_setvar_fifo(setvar_fifo *);
+#define FREE_SETVAR_FIFO(pf) \
+ do { \
+ destroy_setvar_fifo(pf); \
+ (pf) = NULL; \
+ } while (0)
+static void destroy_addr_opts_fifo(addr_opts_fifo *);
+#define FREE_ADDR_OPTS_FIFO(pf) \
+ do { \
+ destroy_addr_opts_fifo(pf); \
+ (pf) = NULL; \
+ } while (0)
+
+static void config_logconfig(config_tree *);
+static void config_monitor(config_tree *);
+static void config_rlimit(config_tree *);
+static void config_system_opts(config_tree *);
+static void config_tinker(config_tree *);
+static int config_tos_clock(config_tree *);
+static void config_tos(config_tree *);
+static void config_vars(config_tree *);
+
+#ifdef SIM
+static sockaddr_u *get_next_address(address_node *addr);
+static void config_sim(config_tree *);
+static void config_ntpdsim(config_tree *);
+#else /* !SIM follows */
+static void config_ntpd(config_tree *, int/*BOOL*/ input_from_file);
+static void config_other_modes(config_tree *);
+static void config_auth(config_tree *);
+static void config_access(config_tree *);
+static void config_mdnstries(config_tree *);
+static void config_phone(config_tree *);
+static void config_setvar(config_tree *);
+static void config_ttl(config_tree *);
+static void config_trap(config_tree *);
+static void config_fudge(config_tree *);
+static void config_peers(config_tree *);
+static void config_unpeers(config_tree *);
+static void config_nic_rules(config_tree *, int/*BOOL*/ input_from_file);
+static void config_reset_counters(config_tree *);
+static u_char get_correct_host_mode(int token);
+static int peerflag_bits(peer_node *);
+#endif /* !SIM */
+
+#ifdef WORKER
+static void peer_name_resolved(int, int, void *, const char *, const char *,
+ const struct addrinfo *,
+ const struct addrinfo *);
+static void unpeer_name_resolved(int, int, void *, const char *, const char *,
+ const struct addrinfo *,
+ const struct addrinfo *);
+static void trap_name_resolved(int, int, void *, const char *, const char *,
+ const struct addrinfo *,
+ const struct addrinfo *);
+#endif
+
+enum gnn_type {
+ t_UNK, /* Unknown */
+ t_REF, /* Refclock */
+ t_MSK /* Network Mask */
+};
+
+static void ntpd_set_tod_using(const char *);
+static char * normal_dtoa(double);
+static u_int32 get_pfxmatch(const char **, struct masks *);
+static u_int32 get_match(const char *, struct masks *);
+static u_int32 get_logmask(const char *);
+static int/*BOOL*/ is_refclk_addr(const address_node * addr);
+
+static void appendstr(char *, size_t, const char *);
+
+
+#ifndef SIM
+static int getnetnum(const char *num, sockaddr_u *addr, int complain,
+ enum gnn_type a_type);
+
+#endif
+
+#if defined(__GNUC__) /* this covers CLANG, too */
+static void __attribute__((noreturn,format(printf,1,2))) fatal_error(const char *fmt, ...)
+#elif defined(_MSC_VER)
+static void __declspec(noreturn) fatal_error(const char *fmt, ...)
+#else
+static void fatal_error(const char *fmt, ...)
+#endif
+{
+ va_list va;
+
+ va_start(va, fmt);
+ mvsyslog(LOG_EMERG, fmt, va);
+ va_end(va);
+ _exit(1);
+}
+
+
+/* FUNCTIONS FOR INITIALIZATION
+ * ----------------------------
+ */
+
+#ifdef FREE_CFG_T
+static void
+free_auth_node(
+ config_tree *ptree
+ )
+{
+ if (ptree->auth.keys) {
+ free(ptree->auth.keys);
+ ptree->auth.keys = NULL;
+ }
+
+ if (ptree->auth.keysdir) {
+ free(ptree->auth.keysdir);
+ ptree->auth.keysdir = NULL;
+ }
+
+ if (ptree->auth.ntp_signd_socket) {
+ free(ptree->auth.ntp_signd_socket);
+ ptree->auth.ntp_signd_socket = NULL;
+ }
+}
+#endif /* DEBUG */
+
+
+static void
+init_syntax_tree(
+ config_tree *ptree
+ )
+{
+ ZERO(*ptree);
+ ptree->mdnstries = 5;
+}
+
+
+#ifdef FREE_CFG_T
+static void
+free_all_config_trees(void)
+{
+ config_tree *ptree;
+ config_tree *pnext;
+
+ ptree = cfg_tree_history;
+
+ while (ptree != NULL) {
+ pnext = ptree->link;
+ free_config_tree(ptree);
+ ptree = pnext;
+ }
+}
+
+
+static void
+free_config_tree(
+ config_tree *ptree
+ )
+{
+#if defined(_MSC_VER) && defined (_DEBUG)
+ _CrtCheckMemory();
+#endif
+
+ if (ptree->source.value.s != NULL)
+ free(ptree->source.value.s);
+
+ free_config_other_modes(ptree);
+ free_config_auth(ptree);
+ free_config_tos(ptree);
+ free_config_monitor(ptree);
+ free_config_access(ptree);
+ free_config_tinker(ptree);
+ free_config_rlimit(ptree);
+ free_config_system_opts(ptree);
+ free_config_logconfig(ptree);
+ free_config_phone(ptree);
+ free_config_setvar(ptree);
+ free_config_ttl(ptree);
+ free_config_trap(ptree);
+ free_config_fudge(ptree);
+ free_config_vars(ptree);
+ free_config_peers(ptree);
+ free_config_unpeers(ptree);
+ free_config_nic_rules(ptree);
+ free_config_reset_counters(ptree);
+#ifdef SIM
+ free_config_sim(ptree);
+#endif
+ free_auth_node(ptree);
+
+ free(ptree);
+
+#if defined(_MSC_VER) && defined (_DEBUG)
+ _CrtCheckMemory();
+#endif
+}
+#endif /* FREE_CFG_T */
+
+
+#ifdef SAVECONFIG
+/* Dump all trees */
+int
+dump_all_config_trees(
+ FILE *df,
+ int comment
+ )
+{
+ config_tree * cfg_ptr;
+ int return_value;
+
+ return_value = 0;
+ for (cfg_ptr = cfg_tree_history;
+ cfg_ptr != NULL;
+ cfg_ptr = cfg_ptr->link)
+ return_value |= dump_config_tree(cfg_ptr, df, comment);
+
+ return return_value;
+}
+
+
+/* The config dumper */
+int
+dump_config_tree(
+ config_tree *ptree,
+ FILE *df,
+ int comment
+ )
+{
+ peer_node *peern;
+ unpeer_node *unpeern;
+ attr_val *atrv;
+ address_node *addr;
+ address_node *peer_addr;
+ address_node *fudge_addr;
+ filegen_node *fgen_node;
+ restrict_node *rest_node;
+ addr_opts_node *addr_opts;
+ setvar_node *setv_node;
+ nic_rule_node *rule_node;
+ int_node *i_n;
+ int_node *flag_tok_fifo;
+ int_node *counter_set;
+ string_node *str_node;
+
+ const char *s = NULL;
+ char *s1;
+ char *s2;
+ char timestamp[80];
+ int enable;
+
+ DPRINTF(1, ("dump_config_tree(%p)\n", ptree));
+
+ if (comment) {
+ if (!strftime(timestamp, sizeof(timestamp),
+ "%Y-%m-%d %H:%M:%S",
+ localtime(&ptree->timestamp)))
+ timestamp[0] = '\0';
+
+ fprintf(df, "# %s %s %s\n",
+ timestamp,
+ (CONF_SOURCE_NTPQ == ptree->source.attr)
+ ? "ntpq remote config from"
+ : "startup configuration file",
+ ptree->source.value.s);
+ }
+
+ /*
+ * For options without documentation we just output the name
+ * and its data value
+ */
+ atrv = HEAD_PFIFO(ptree->vars);
+ for ( ; atrv != NULL; atrv = atrv->link) {
+ switch (atrv->type) {
+#ifdef DEBUG
+ default:
+ fprintf(df, "\n# dump error:\n"
+ "# unknown vars type %d (%s) for %s\n",
+ atrv->type, token_name(atrv->type),
+ token_name(atrv->attr));
+ break;
+#endif
+ case T_Double:
+ fprintf(df, "%s %s\n", keyword(atrv->attr),
+ normal_dtoa(atrv->value.d));
+ break;
+
+ case T_Integer:
+ fprintf(df, "%s %d\n", keyword(atrv->attr),
+ atrv->value.i);
+ break;
+
+ case T_String:
+ fprintf(df, "%s \"%s\"", keyword(atrv->attr),
+ atrv->value.s);
+ if (T_Driftfile == atrv->attr &&
+ atrv->link != NULL &&
+ T_WanderThreshold == atrv->link->attr) {
+ atrv = atrv->link;
+ fprintf(df, " %s\n",
+ normal_dtoa(atrv->value.d));
+ } else {
+ fprintf(df, "\n");
+ }
+ break;
+ }
+ }
+
+ atrv = HEAD_PFIFO(ptree->logconfig);
+ if (atrv != NULL) {
+ fprintf(df, "logconfig");
+ for ( ; atrv != NULL; atrv = atrv->link)
+ fprintf(df, " %c%s", atrv->attr, atrv->value.s);
+ fprintf(df, "\n");
+ }
+
+ if (ptree->stats_dir)
+ fprintf(df, "statsdir \"%s\"\n", ptree->stats_dir);
+
+ i_n = HEAD_PFIFO(ptree->stats_list);
+ if (i_n != NULL) {
+ fprintf(df, "statistics");
+ for ( ; i_n != NULL; i_n = i_n->link)
+ fprintf(df, " %s", keyword(i_n->i));
+ fprintf(df, "\n");
+ }
+
+ fgen_node = HEAD_PFIFO(ptree->filegen_opts);
+ for ( ; fgen_node != NULL; fgen_node = fgen_node->link) {
+ atrv = HEAD_PFIFO(fgen_node->options);
+ if (atrv != NULL) {
+ fprintf(df, "filegen %s",
+ keyword(fgen_node->filegen_token));
+ for ( ; atrv != NULL; atrv = atrv->link) {
+ switch (atrv->attr) {
+#ifdef DEBUG
+ default:
+ fprintf(df, "\n# dump error:\n"
+ "# unknown filegen option token %s\n"
+ "filegen %s",
+ token_name(atrv->attr),
+ keyword(fgen_node->filegen_token));
+ break;
+#endif
+ case T_File:
+ fprintf(df, " file %s",
+ atrv->value.s);
+ break;
+
+ case T_Type:
+ fprintf(df, " type %s",
+ keyword(atrv->value.i));
+ break;
+
+ case T_Flag:
+ fprintf(df, " %s",
+ keyword(atrv->value.i));
+ break;
+ }
+ }
+ fprintf(df, "\n");
+ }
+ }
+
+ atrv = HEAD_PFIFO(ptree->auth.crypto_cmd_list);
+ if (atrv != NULL) {
+ fprintf(df, "crypto");
+ for ( ; atrv != NULL; atrv = atrv->link) {
+ fprintf(df, " %s %s", keyword(atrv->attr),
+ atrv->value.s);
+ }
+ fprintf(df, "\n");
+ }
+
+ if (ptree->auth.revoke != 0)
+ fprintf(df, "revoke %d\n", ptree->auth.revoke);
+
+ if (ptree->auth.keysdir != NULL)
+ fprintf(df, "keysdir \"%s\"\n", ptree->auth.keysdir);
+
+ if (ptree->auth.keys != NULL)
+ fprintf(df, "keys \"%s\"\n", ptree->auth.keys);
+
+ atrv = HEAD_PFIFO(ptree->auth.trusted_key_list);
+ if (atrv != NULL) {
+ fprintf(df, "trustedkey");
+ for ( ; atrv != NULL; atrv = atrv->link) {
+ if (T_Integer == atrv->type)
+ fprintf(df, " %d", atrv->value.i);
+ else if (T_Intrange == atrv->type)
+ fprintf(df, " (%d ... %d)",
+ atrv->value.r.first,
+ atrv->value.r.last);
+#ifdef DEBUG
+ else
+ fprintf(df, "\n# dump error:\n"
+ "# unknown trustedkey attr type %d\n"
+ "trustedkey", atrv->type);
+#endif
+ }
+ fprintf(df, "\n");
+ }
+
+ if (ptree->auth.control_key)
+ fprintf(df, "controlkey %d\n", ptree->auth.control_key);
+
+ if (ptree->auth.request_key)
+ fprintf(df, "requestkey %d\n", ptree->auth.request_key);
+
+ /* dump enable list, then disable list */
+ for (enable = 1; enable >= 0; enable--) {
+ atrv = (enable)
+ ? HEAD_PFIFO(ptree->enable_opts)
+ : HEAD_PFIFO(ptree->disable_opts);
+ if (atrv != NULL) {
+ fprintf(df, "%s", (enable)
+ ? "enable"
+ : "disable");
+ for ( ; atrv != NULL; atrv = atrv->link)
+ fprintf(df, " %s",
+ keyword(atrv->value.i));
+ fprintf(df, "\n");
+ }
+ }
+
+ atrv = HEAD_PFIFO(ptree->orphan_cmds);
+ if (atrv != NULL) {
+ fprintf(df, "tos");
+ for ( ; atrv != NULL; atrv = atrv->link) {
+ switch (atrv->type) {
+#ifdef DEBUG
+ default:
+ fprintf(df, "\n# dump error:\n"
+ "# unknown tos attr type %d %s\n"
+ "tos", atrv->type,
+ token_name(atrv->type));
+ break;
+#endif
+ case T_Integer:
+ if (atrv->attr == T_Basedate) {
+ struct calendar jd;
+ ntpcal_rd_to_date(&jd, atrv->value.i + DAY_NTP_STARTS);
+ fprintf(df, " %s \"%04hu-%02hu-%02hu\"",
+ keyword(atrv->attr), jd.year,
+ (u_short)jd.month,
+ (u_short)jd.monthday);
+ } else {
+ fprintf(df, " %s %d",
+ keyword(atrv->attr),
+ atrv->value.i);
+ }
+ break;
+
+ case T_Double:
+ fprintf(df, " %s %s",
+ keyword(atrv->attr),
+ normal_dtoa(atrv->value.d));
+ break;
+ }
+ }
+ fprintf(df, "\n");
+ }
+
+ atrv = HEAD_PFIFO(ptree->rlimit);
+ if (atrv != NULL) {
+ fprintf(df, "rlimit");
+ for ( ; atrv != NULL; atrv = atrv->link) {
+ INSIST(T_Integer == atrv->type);
+ fprintf(df, " %s %d", keyword(atrv->attr),
+ atrv->value.i);
+ }
+ fprintf(df, "\n");
+ }
+
+ atrv = HEAD_PFIFO(ptree->tinker);
+ if (atrv != NULL) {
+ fprintf(df, "tinker");
+ for ( ; atrv != NULL; atrv = atrv->link) {
+ INSIST(T_Double == atrv->type);
+ fprintf(df, " %s %s", keyword(atrv->attr),
+ normal_dtoa(atrv->value.d));
+ }
+ fprintf(df, "\n");
+ }
+
+ if (ptree->broadcastclient)
+ fprintf(df, "broadcastclient\n");
+
+ peern = HEAD_PFIFO(ptree->peers);
+ for ( ; peern != NULL; peern = peern->link) {
+ addr = peern->addr;
+ fprintf(df, "%s", keyword(peern->host_mode));
+ switch (addr->type) {
+#ifdef DEBUG
+ default:
+ fprintf(df, "# dump error:\n"
+ "# unknown peer family %d for:\n"
+ "%s", addr->type,
+ keyword(peern->host_mode));
+ break;
+#endif
+ case AF_UNSPEC:
+ break;
+
+ case AF_INET:
+ fprintf(df, " -4");
+ break;
+
+ case AF_INET6:
+ fprintf(df, " -6");
+ break;
+ }
+ fprintf(df, " %s", addr->address);
+
+ if (peern->minpoll != 0)
+ fprintf(df, " minpoll %u", peern->minpoll);
+
+ if (peern->maxpoll != 0)
+ fprintf(df, " maxpoll %u", peern->maxpoll);
+
+ if (peern->ttl != 0) {
+ if (strlen(addr->address) > 8
+ && !memcmp(addr->address, "127.127.", 8))
+ fprintf(df, " mode %u", peern->ttl);
+ else
+ fprintf(df, " ttl %u", peern->ttl);
+ }
+
+ if (peern->peerversion != NTP_VERSION)
+ fprintf(df, " version %u", peern->peerversion);
+
+ if (peern->peerkey != 0)
+ fprintf(df, " key %u", peern->peerkey);
+
+ if (peern->group != NULL)
+ fprintf(df, " ident \"%s\"", peern->group);
+
+ atrv = HEAD_PFIFO(peern->peerflags);
+ for ( ; atrv != NULL; atrv = atrv->link) {
+ INSIST(T_Flag == atrv->attr);
+ INSIST(T_Integer == atrv->type);
+ fprintf(df, " %s", keyword(atrv->value.i));
+ }
+
+ fprintf(df, "\n");
+
+ addr_opts = HEAD_PFIFO(ptree->fudge);
+ for ( ; addr_opts != NULL; addr_opts = addr_opts->link) {
+ peer_addr = peern->addr;
+ fudge_addr = addr_opts->addr;
+
+ s1 = peer_addr->address;
+ s2 = fudge_addr->address;
+
+ if (strcmp(s1, s2))
+ continue;
+
+ fprintf(df, "fudge %s", s1);
+
+ for (atrv = HEAD_PFIFO(addr_opts->options);
+ atrv != NULL;
+ atrv = atrv->link) {
+
+ switch (atrv->type) {
+#ifdef DEBUG
+ default:
+ fprintf(df, "\n# dump error:\n"
+ "# unknown fudge atrv->type %d\n"
+ "fudge %s", atrv->type,
+ s1);
+ break;
+#endif
+ case T_Double:
+ fprintf(df, " %s %s",
+ keyword(atrv->attr),
+ normal_dtoa(atrv->value.d));
+ break;
+
+ case T_Integer:
+ fprintf(df, " %s %d",
+ keyword(atrv->attr),
+ atrv->value.i);
+ break;
+
+ case T_String:
+ fprintf(df, " %s %s",
+ keyword(atrv->attr),
+ atrv->value.s);
+ break;
+ }
+ }
+ fprintf(df, "\n");
+ }
+ }
+
+ addr = HEAD_PFIFO(ptree->manycastserver);
+ if (addr != NULL) {
+ fprintf(df, "manycastserver");
+ for ( ; addr != NULL; addr = addr->link)
+ fprintf(df, " %s", addr->address);
+ fprintf(df, "\n");
+ }
+
+ addr = HEAD_PFIFO(ptree->multicastclient);
+ if (addr != NULL) {
+ fprintf(df, "multicastclient");
+ for ( ; addr != NULL; addr = addr->link)
+ fprintf(df, " %s", addr->address);
+ fprintf(df, "\n");
+ }
+
+
+ for (unpeern = HEAD_PFIFO(ptree->unpeers);
+ unpeern != NULL;
+ unpeern = unpeern->link)
+ fprintf(df, "unpeer %s\n", unpeern->addr->address);
+
+ atrv = HEAD_PFIFO(ptree->mru_opts);
+ if (atrv != NULL) {
+ fprintf(df, "mru");
+ for ( ; atrv != NULL; atrv = atrv->link)
+ fprintf(df, " %s %d", keyword(atrv->attr),
+ atrv->value.i);
+ fprintf(df, "\n");
+ }
+
+ atrv = HEAD_PFIFO(ptree->discard_opts);
+ if (atrv != NULL) {
+ fprintf(df, "discard");
+ for ( ; atrv != NULL; atrv = atrv->link)
+ fprintf(df, " %s %d", keyword(atrv->attr),
+ atrv->value.i);
+ fprintf(df, "\n");
+ }
+
+ for (rest_node = HEAD_PFIFO(ptree->restrict_opts);
+ rest_node != NULL;
+ rest_node = rest_node->link) {
+ int is_default = 0;
+
+ if (NULL == rest_node->addr) {
+ s = "default";
+ /* Don't need to set is_default=1 here */
+ flag_tok_fifo = HEAD_PFIFO(rest_node->flag_tok_fifo);
+ for ( ; flag_tok_fifo != NULL; flag_tok_fifo = flag_tok_fifo->link) {
+ if (T_Source == flag_tok_fifo->i) {
+ s = "source";
+ break;
+ }
+ }
+ } else {
+ const char *ap = rest_node->addr->address;
+ const char *mp = "";
+
+ if (rest_node->mask)
+ mp = rest_node->mask->address;
+
+ if ( rest_node->addr->type == AF_INET
+ && !strcmp(ap, "0.0.0.0")
+ && !strcmp(mp, "0.0.0.0")) {
+ is_default = 1;
+ s = "-4 default";
+ } else if ( rest_node->mask
+ && rest_node->mask->type == AF_INET6
+ && !strcmp(ap, "::")
+ && !strcmp(mp, "::")) {
+ is_default = 1;
+ s = "-6 default";
+ } else {
+ s = ap;
+ }
+ }
+ fprintf(df, "restrict %s", s);
+ if (rest_node->mask != NULL && !is_default)
+ fprintf(df, " mask %s",
+ rest_node->mask->address);
+ fprintf(df, " ippeerlimit %d", rest_node->ippeerlimit);
+ flag_tok_fifo = HEAD_PFIFO(rest_node->flag_tok_fifo);
+ for ( ; flag_tok_fifo != NULL; flag_tok_fifo = flag_tok_fifo->link)
+ if (T_Source != flag_tok_fifo->i)
+ fprintf(df, " %s", keyword(flag_tok_fifo->i));
+ fprintf(df, "\n");
+ }
+
+ rule_node = HEAD_PFIFO(ptree->nic_rules);
+ for ( ; rule_node != NULL; rule_node = rule_node->link) {
+ fprintf(df, "interface %s %s\n",
+ keyword(rule_node->action),
+ (rule_node->match_class)
+ ? keyword(rule_node->match_class)
+ : rule_node->if_name);
+ }
+
+ str_node = HEAD_PFIFO(ptree->phone);
+ if (str_node != NULL) {
+ fprintf(df, "phone");
+ for ( ; str_node != NULL; str_node = str_node->link)
+ fprintf(df, " \"%s\"", str_node->s);
+ fprintf(df, "\n");
+ }
+
+ setv_node = HEAD_PFIFO(ptree->setvar);
+ for ( ; setv_node != NULL; setv_node = setv_node->link) {
+ s1 = quote_if_needed(setv_node->var);
+ s2 = quote_if_needed(setv_node->val);
+ fprintf(df, "setvar %s = %s", s1, s2);
+ free(s1);
+ free(s2);
+ if (setv_node->isdefault)
+ fprintf(df, " default");
+ fprintf(df, "\n");
+ }
+
+ i_n = HEAD_PFIFO(ptree->ttl);
+ if (i_n != NULL) {
+ fprintf(df, "ttl");
+ for( ; i_n != NULL; i_n = i_n->link)
+ fprintf(df, " %d", i_n->i);
+ fprintf(df, "\n");
+ }
+
+ addr_opts = HEAD_PFIFO(ptree->trap);
+ for ( ; addr_opts != NULL; addr_opts = addr_opts->link) {
+ addr = addr_opts->addr;
+ fprintf(df, "trap %s", addr->address);
+ atrv = HEAD_PFIFO(addr_opts->options);
+ for ( ; atrv != NULL; atrv = atrv->link) {
+ switch (atrv->attr) {
+#ifdef DEBUG
+ default:
+ fprintf(df, "\n# dump error:\n"
+ "# unknown trap token %d\n"
+ "trap %s", atrv->attr,
+ addr->address);
+ break;
+#endif
+ case T_Port:
+ fprintf(df, " port %d", atrv->value.i);
+ break;
+
+ case T_Interface:
+ fprintf(df, " interface %s",
+ atrv->value.s);
+ break;
+ }
+ }
+ fprintf(df, "\n");
+ }
+
+ counter_set = HEAD_PFIFO(ptree->reset_counters);
+ if (counter_set != NULL) {
+ fprintf(df, "reset");
+ for ( ; counter_set != NULL;
+ counter_set = counter_set->link)
+ fprintf(df, " %s", keyword(counter_set->i));
+ fprintf(df, "\n");
+ }
+
+ return 0;
+}
+#endif /* SAVECONFIG */
+
+
+
+/* generic fifo routines for structs linked by 1st member */
+void *
+append_gen_fifo(
+ void *fifo,
+ void *entry
+ )
+{
+ gen_fifo *pf;
+ gen_node *pe;
+
+ pf = fifo;
+ pe = entry;
+ if (NULL == pf)
+ pf = emalloc_zero(sizeof(*pf));
+ else
+ CHECK_FIFO_CONSISTENCY(*pf);
+ if (pe != NULL)
+ LINK_FIFO(*pf, pe, link);
+ CHECK_FIFO_CONSISTENCY(*pf);
+
+ return pf;
+}
+
+
+void *
+concat_gen_fifos(
+ void *first,
+ void *second
+ )
+{
+ gen_fifo *pf1;
+ gen_fifo *pf2;
+
+ pf1 = first;
+ pf2 = second;
+ if (NULL == pf1)
+ return pf2;
+ if (NULL == pf2)
+ return pf1;
+
+ CONCAT_FIFO(*pf1, *pf2, link);
+ free(pf2);
+
+ return pf1;
+}
+
+void*
+destroy_gen_fifo(
+ void *fifo,
+ fifo_deleter func
+ )
+{
+ any_node * np = NULL;
+ any_node_fifo * pf1 = fifo;
+
+ if (pf1 != NULL) {
+ if (!func)
+ func = free;
+ for (;;) {
+ UNLINK_FIFO(np, *pf1, link);
+ if (np == NULL)
+ break;
+ (*func)(np);
+ }
+ free(pf1);
+ }
+ return NULL;
+}
+
+/* FUNCTIONS FOR CREATING NODES ON THE SYNTAX TREE
+ * -----------------------------------------------
+ */
+
+void
+destroy_attr_val(
+ attr_val * av
+ )
+{
+ if (av) {
+ if (T_String == av->type)
+ free(av->value.s);
+ free(av);
+ }
+}
+
+attr_val *
+create_attr_dval(
+ int attr,
+ double value
+ )
+{
+ attr_val *my_val;
+
+ my_val = emalloc_zero(sizeof(*my_val));
+ my_val->attr = attr;
+ my_val->value.d = value;
+ my_val->type = T_Double;
+
+ return my_val;
+}
+
+
+attr_val *
+create_attr_ival(
+ int attr,
+ int value
+ )
+{
+ attr_val *my_val;
+
+ my_val = emalloc_zero(sizeof(*my_val));
+ my_val->attr = attr;
+ my_val->value.i = value;
+ my_val->type = T_Integer;
+
+ return my_val;
+}
+
+
+attr_val *
+create_attr_uval(
+ int attr,
+ u_int value
+ )
+{
+ attr_val *my_val;
+
+ my_val = emalloc_zero(sizeof(*my_val));
+ my_val->attr = attr;
+ my_val->value.u = value;
+ my_val->type = T_U_int;
+
+ return my_val;
+}
+
+
+attr_val *
+create_attr_rangeval(
+ int attr,
+ int first,
+ int last
+ )
+{
+ attr_val *my_val;
+
+ my_val = emalloc_zero(sizeof(*my_val));
+ my_val->attr = attr;
+ my_val->value.r.first = first;
+ my_val->value.r.last = last;
+ my_val->type = T_Intrange;
+
+ return my_val;
+}
+
+
+attr_val *
+create_attr_sval(
+ int attr,
+ const char *s
+ )
+{
+ attr_val *my_val;
+
+ my_val = emalloc_zero(sizeof(*my_val));
+ my_val->attr = attr;
+ if (NULL == s) /* free() hates NULL */
+ s = estrdup("");
+ my_val->value.s = _UC(s);
+ my_val->type = T_String;
+
+ return my_val;
+}
+
+
+int_node *
+create_int_node(
+ int val
+ )
+{
+ int_node *i_n;
+
+ i_n = emalloc_zero(sizeof(*i_n));
+ i_n->i = val;
+
+ return i_n;
+}
+
+
+string_node *
+create_string_node(
+ char *str
+ )
+{
+ string_node *sn;
+
+ sn = emalloc_zero(sizeof(*sn));
+ sn->s = str;
+
+ return sn;
+}
+
+
+address_node *
+create_address_node(
+ char * addr,
+ int type
+ )
+{
+ address_node *my_node;
+
+ REQUIRE(NULL != addr);
+ REQUIRE(AF_INET == type || AF_INET6 == type || AF_UNSPEC == type);
+ my_node = emalloc_zero(sizeof(*my_node));
+ my_node->address = addr;
+ my_node->type = (u_short)type;
+
+ return my_node;
+}
+
+
+void
+destroy_address_node(
+ address_node *my_node
+ )
+{
+ if (NULL == my_node)
+ return;
+ REQUIRE(NULL != my_node->address);
+
+ free(my_node->address);
+ free(my_node);
+}
+
+
+peer_node *
+create_peer_node(
+ int hmode,
+ address_node * addr,
+ attr_val_fifo * options
+ )
+{
+ peer_node *my_node;
+ attr_val *option;
+ int freenode;
+ int errflag = 0;
+
+ my_node = emalloc_zero(sizeof(*my_node));
+
+ /* Initialize node values to default */
+ my_node->peerversion = NTP_VERSION;
+
+ /* Now set the node to the read values */
+ my_node->host_mode = hmode;
+ my_node->addr = addr;
+
+ /*
+ * the options FIFO mixes items that will be saved in the
+ * peer_node as explicit members, such as minpoll, and
+ * those that are moved intact to the peer_node's peerflags
+ * FIFO. The options FIFO is consumed and reclaimed here.
+ */
+
+ if (options != NULL)
+ CHECK_FIFO_CONSISTENCY(*options);
+ while (options != NULL) {
+ UNLINK_FIFO(option, *options, link);
+ if (NULL == option) {
+ free(options);
+ break;
+ }
+
+ freenode = 1;
+ /* Check the kind of option being set */
+ switch (option->attr) {
+
+ case T_Flag:
+ APPEND_G_FIFO(my_node->peerflags, option);
+ freenode = 0;
+ break;
+
+ case T_Minpoll:
+ if (option->value.i < NTP_MINPOLL ||
+ option->value.i > UCHAR_MAX) {
+ msyslog(LOG_INFO,
+ "minpoll: provided value (%d) is out of range [%d-%d])",
+ option->value.i, NTP_MINPOLL,
+ UCHAR_MAX);
+ my_node->minpoll = NTP_MINPOLL;
+ } else {
+ my_node->minpoll =
+ (u_char)option->value.u;
+ }
+ break;
+
+ case T_Maxpoll:
+ if (option->value.i < 0 ||
+ option->value.i > NTP_MAXPOLL) {
+ msyslog(LOG_INFO,
+ "maxpoll: provided value (%d) is out of range [0-%d])",
+ option->value.i, NTP_MAXPOLL);
+ my_node->maxpoll = NTP_MAXPOLL;
+ } else {
+ my_node->maxpoll =
+ (u_char)option->value.u;
+ }
+ break;
+
+ case T_Ttl:
+ if (is_refclk_addr(addr)) {
+ msyslog(LOG_ERR, "'ttl' does not apply for refclocks");
+ errflag = 1;
+ } else if (option->value.u >= MAX_TTL) {
+ msyslog(LOG_ERR, "ttl: invalid argument");
+ errflag = 1;
+ } else {
+ my_node->ttl = (u_char)option->value.u;
+ }
+ break;
+
+ case T_Mode:
+ if (is_refclk_addr(addr)) {
+ my_node->ttl = option->value.u;
+ } else {
+ msyslog(LOG_ERR, "'mode' does not apply for network peers");
+ errflag = 1;
+ }
+ break;
+
+ case T_Key:
+ if (option->value.u >= KEYID_T_MAX) {
+ msyslog(LOG_ERR, "key: invalid argument");
+ errflag = 1;
+ } else {
+ my_node->peerkey =
+ (keyid_t)option->value.u;
+ }
+ break;
+
+ case T_Version:
+ if (option->value.u >= UCHAR_MAX) {
+ msyslog(LOG_ERR, "version: invalid argument");
+ errflag = 1;
+ } else {
+ my_node->peerversion =
+ (u_char)option->value.u;
+ }
+ break;
+
+ case T_Ident:
+ my_node->group = option->value.s;
+ break;
+
+ default:
+ msyslog(LOG_ERR,
+ "Unknown peer/server option token %s",
+ token_name(option->attr));
+ errflag = 1;
+ }
+ if (freenode)
+ free(option);
+ }
+
+ /* Check if errors were reported. If yes, ignore the node */
+ if (errflag) {
+ free(my_node);
+ my_node = NULL;
+ }
+
+ return my_node;
+}
+
+
+unpeer_node *
+create_unpeer_node(
+ address_node *addr
+ )
+{
+ unpeer_node * my_node;
+ u_long u;
+ const u_char * pch;
+
+ my_node = emalloc_zero(sizeof(*my_node));
+
+ /*
+ * From the parser's perspective an association ID fits into
+ * its generic T_String definition of a name/address "address".
+ * We treat all valid 16-bit numbers as association IDs.
+ */
+ for (u = 0, pch = (u_char*)addr->address; isdigit(*pch); ++pch) {
+ /* accumulate with overflow retention */
+ u = (10 * u + *pch - '0') | (u & 0xFF000000u);
+ }
+
+ if (!*pch && u <= ASSOCID_MAX) {
+ my_node->assocID = (associd_t)u;
+ my_node->addr = NULL;
+ destroy_address_node(addr);
+ } else {
+ my_node->assocID = 0;
+ my_node->addr = addr;
+ }
+
+ return my_node;
+}
+
+filegen_node *
+create_filegen_node(
+ int filegen_token,
+ attr_val_fifo * options
+ )
+{
+ filegen_node *my_node;
+
+ my_node = emalloc_zero(sizeof(*my_node));
+ my_node->filegen_token = filegen_token;
+ my_node->options = options;
+
+ return my_node;
+}
+
+
+restrict_node *
+create_restrict_node(
+ address_node * addr,
+ address_node * mask,
+ short ippeerlimit,
+ int_fifo * flag_tok_fifo,
+ int line_no
+ )
+{
+ restrict_node *my_node;
+
+ my_node = emalloc_zero(sizeof(*my_node));
+ my_node->addr = addr;
+ my_node->mask = mask;
+ my_node->ippeerlimit = ippeerlimit;
+ my_node->flag_tok_fifo = flag_tok_fifo;
+ my_node->line_no = line_no;
+
+ return my_node;
+}
+
+
+static void
+destroy_restrict_node(
+ restrict_node *my_node
+ )
+{
+ /* With great care, free all the memory occupied by
+ * the restrict node
+ */
+ destroy_address_node(my_node->addr);
+ destroy_address_node(my_node->mask);
+ destroy_int_fifo(my_node->flag_tok_fifo);
+ free(my_node);
+}
+
+
+static void
+destroy_int_fifo(
+ int_fifo * fifo
+ )
+{
+ int_node * i_n;
+
+ if (fifo != NULL) {
+ for (;;) {
+ UNLINK_FIFO(i_n, *fifo, link);
+ if (i_n == NULL)
+ break;
+ free(i_n);
+ }
+ free(fifo);
+ }
+}
+
+
+static void
+destroy_string_fifo(
+ string_fifo * fifo
+ )
+{
+ string_node * sn;
+
+ if (fifo != NULL) {
+ for (;;) {
+ UNLINK_FIFO(sn, *fifo, link);
+ if (sn == NULL)
+ break;
+ free(sn->s);
+ free(sn);
+ }
+ free(fifo);
+ }
+}
+
+
+static void
+destroy_attr_val_fifo(
+ attr_val_fifo * av_fifo
+ )
+{
+ attr_val * av;
+
+ if (av_fifo != NULL) {
+ for (;;) {
+ UNLINK_FIFO(av, *av_fifo, link);
+ if (av == NULL)
+ break;
+ destroy_attr_val(av);
+ }
+ free(av_fifo);
+ }
+}
+
+
+static void
+destroy_filegen_fifo(
+ filegen_fifo * fifo
+ )
+{
+ filegen_node * fg;
+
+ if (fifo != NULL) {
+ for (;;) {
+ UNLINK_FIFO(fg, *fifo, link);
+ if (fg == NULL)
+ break;
+ destroy_attr_val_fifo(fg->options);
+ free(fg);
+ }
+ free(fifo);
+ }
+}
+
+
+static void
+destroy_restrict_fifo(
+ restrict_fifo * fifo
+ )
+{
+ restrict_node * rn;
+
+ if (fifo != NULL) {
+ for (;;) {
+ UNLINK_FIFO(rn, *fifo, link);
+ if (rn == NULL)
+ break;
+ destroy_restrict_node(rn);
+ }
+ free(fifo);
+ }
+}
+
+
+static void
+destroy_setvar_fifo(
+ setvar_fifo * fifo
+ )
+{
+ setvar_node * sv;
+
+ if (fifo != NULL) {
+ for (;;) {
+ UNLINK_FIFO(sv, *fifo, link);
+ if (sv == NULL)
+ break;
+ free(sv->var);
+ free(sv->val);
+ free(sv);
+ }
+ free(fifo);
+ }
+}
+
+
+static void
+destroy_addr_opts_fifo(
+ addr_opts_fifo * fifo
+ )
+{
+ addr_opts_node * aon;
+
+ if (fifo != NULL) {
+ for (;;) {
+ UNLINK_FIFO(aon, *fifo, link);
+ if (aon == NULL)
+ break;
+ destroy_address_node(aon->addr);
+ destroy_attr_val_fifo(aon->options);
+ free(aon);
+ }
+ free(fifo);
+ }
+}
+
+
+setvar_node *
+create_setvar_node(
+ char * var,
+ char * val,
+ int isdefault
+ )
+{
+ setvar_node * my_node;
+ char * pch;
+
+ /* do not allow = in the variable name */
+ pch = strchr(var, '=');
+ if (NULL != pch)
+ *pch = '\0';
+
+ /* Now store the string into a setvar_node */
+ my_node = emalloc_zero(sizeof(*my_node));
+ my_node->var = var;
+ my_node->val = val;
+ my_node->isdefault = isdefault;
+
+ return my_node;
+}
+
+
+nic_rule_node *
+create_nic_rule_node(
+ int match_class,
+ char *if_name, /* interface name or numeric address */
+ int action
+ )
+{
+ nic_rule_node *my_node;
+
+ REQUIRE(match_class != 0 || if_name != NULL);
+
+ my_node = emalloc_zero(sizeof(*my_node));
+ my_node->match_class = match_class;
+ my_node->if_name = if_name;
+ my_node->action = action;
+
+ return my_node;
+}
+
+
+addr_opts_node *
+create_addr_opts_node(
+ address_node * addr,
+ attr_val_fifo * options
+ )
+{
+ addr_opts_node *my_node;
+
+ my_node = emalloc_zero(sizeof(*my_node));
+ my_node->addr = addr;
+ my_node->options = options;
+
+ return my_node;
+}
+
+
+#ifdef SIM
+script_info *
+create_sim_script_info(
+ double duration,
+ attr_val_fifo * script_queue
+ )
+{
+ script_info *my_info;
+ attr_val *my_attr_val;
+
+ my_info = emalloc_zero(sizeof(*my_info));
+
+ /* Initialize Script Info with default values*/
+ my_info->duration = duration;
+ my_info->prop_delay = NET_DLY;
+ my_info->proc_delay = PROC_DLY;
+
+ /* Traverse the script_queue and fill out non-default values */
+
+ for (my_attr_val = HEAD_PFIFO(script_queue);
+ my_attr_val != NULL;
+ my_attr_val = my_attr_val->link) {
+
+ /* Set the desired value */
+ switch (my_attr_val->attr) {
+
+ case T_Freq_Offset:
+ my_info->freq_offset = my_attr_val->value.d;
+ break;
+
+ case T_Wander:
+ my_info->wander = my_attr_val->value.d;
+ break;
+
+ case T_Jitter:
+ my_info->jitter = my_attr_val->value.d;
+ break;
+
+ case T_Prop_Delay:
+ my_info->prop_delay = my_attr_val->value.d;
+ break;
+
+ case T_Proc_Delay:
+ my_info->proc_delay = my_attr_val->value.d;
+ break;
+
+ default:
+ msyslog(LOG_ERR, "Unknown script token %d",
+ my_attr_val->attr);
+ }
+ }
+
+ return my_info;
+}
+#endif /* SIM */
+
+
+#ifdef SIM
+static sockaddr_u *
+get_next_address(
+ address_node *addr
+ )
+{
+ const char addr_prefix[] = "192.168.0.";
+ static int curr_addr_num = 1;
+#define ADDR_LENGTH 16 + 1 /* room for 192.168.1.255 */
+ char addr_string[ADDR_LENGTH];
+ sockaddr_u *final_addr;
+ struct addrinfo *ptr;
+ int gai_err;
+
+ final_addr = emalloc(sizeof(*final_addr));
+
+ if (addr->type == T_String) {
+ snprintf(addr_string, sizeof(addr_string), "%s%d",
+ addr_prefix, curr_addr_num++);
+ printf("Selecting ip address %s for hostname %s\n",
+ addr_string, addr->address);
+ gai_err = getaddrinfo(addr_string, "ntp", NULL, &ptr);
+ } else {
+ gai_err = getaddrinfo(addr->address, "ntp", NULL, &ptr);
+ }
+
+ if (gai_err) {
+ fprintf(stderr, "ERROR!! Could not get a new address\n");
+ exit(1);
+ }
+ memcpy(final_addr, ptr->ai_addr, ptr->ai_addrlen);
+ fprintf(stderr, "Successful in setting ip address of simulated server to: %s\n",
+ stoa(final_addr));
+ freeaddrinfo(ptr);
+
+ return final_addr;
+}
+#endif /* SIM */
+
+
+#ifdef SIM
+server_info *
+create_sim_server(
+ address_node * addr,
+ double server_offset,
+ script_info_fifo * script
+ )
+{
+ server_info *my_info;
+
+ my_info = emalloc_zero(sizeof(*my_info));
+ my_info->server_time = server_offset;
+ my_info->addr = get_next_address(addr);
+ my_info->script = script;
+ UNLINK_FIFO(my_info->curr_script, *my_info->script, link);
+
+ return my_info;
+}
+#endif /* SIM */
+
+sim_node *
+create_sim_node(
+ attr_val_fifo * init_opts,
+ server_info_fifo * servers
+ )
+{
+ sim_node *my_node;
+
+ my_node = emalloc(sizeof(*my_node));
+ my_node->init_opts = init_opts;
+ my_node->servers = servers;
+
+ return my_node;
+}
+
+
+
+
+/* FUNCTIONS FOR PERFORMING THE CONFIGURATION
+ * ------------------------------------------
+ */
+
+#ifndef SIM
+static void
+config_other_modes(
+ config_tree * ptree
+ )
+{
+ sockaddr_u addr_sock;
+ address_node * addr_node;
+
+ if (ptree->broadcastclient)
+ proto_config(PROTO_BROADCLIENT, ptree->broadcastclient,
+ 0., NULL);
+
+ addr_node = HEAD_PFIFO(ptree->manycastserver);
+ while (addr_node != NULL) {
+ ZERO_SOCK(&addr_sock);
+ AF(&addr_sock) = addr_node->type;
+ if (1 == getnetnum(addr_node->address, &addr_sock, 1,
+ t_UNK)) {
+ proto_config(PROTO_MULTICAST_ADD,
+ 0, 0., &addr_sock);
+ sys_manycastserver = 1;
+ }
+ addr_node = addr_node->link;
+ }
+
+ /* Configure the multicast clients */
+ addr_node = HEAD_PFIFO(ptree->multicastclient);
+ if (addr_node != NULL) {
+ do {
+ ZERO_SOCK(&addr_sock);
+ AF(&addr_sock) = addr_node->type;
+ if (1 == getnetnum(addr_node->address,
+ &addr_sock, 1, t_UNK)) {
+ proto_config(PROTO_MULTICAST_ADD, 0, 0.,
+ &addr_sock);
+ }
+ addr_node = addr_node->link;
+ } while (addr_node != NULL);
+ proto_config(PROTO_MULTICAST_ADD, 1, 0., NULL);
+ }
+}
+#endif /* !SIM */
+
+
+#ifdef FREE_CFG_T
+static void
+destroy_address_fifo(
+ address_fifo * pfifo
+ )
+{
+ address_node * addr_node;
+
+ if (pfifo != NULL) {
+ for (;;) {
+ UNLINK_FIFO(addr_node, *pfifo, link);
+ if (addr_node == NULL)
+ break;
+ destroy_address_node(addr_node);
+ }
+ free(pfifo);
+ }
+}
+
+
+static void
+free_config_other_modes(
+ config_tree *ptree
+ )
+{
+ FREE_ADDRESS_FIFO(ptree->manycastserver);
+ FREE_ADDRESS_FIFO(ptree->multicastclient);
+}
+#endif /* FREE_CFG_T */
+
+
+#ifndef SIM
+static void
+config_auth(
+ config_tree *ptree
+ )
+{
+ attr_val * my_val;
+ int first;
+ int last;
+ int i;
+ int count;
+#ifdef AUTOKEY
+ int item;
+#endif
+
+ /* Crypto Command */
+#ifdef AUTOKEY
+ my_val = HEAD_PFIFO(ptree->auth.crypto_cmd_list);
+ for (; my_val != NULL; my_val = my_val->link) {
+ switch (my_val->attr) {
+
+ default:
+ fatal_error("config_auth: attr-token=%d", my_val->attr);
+
+ case T_Host:
+ item = CRYPTO_CONF_PRIV;
+ break;
+
+ case T_Ident:
+ item = CRYPTO_CONF_IDENT;
+ break;
+
+ case T_Pw:
+ item = CRYPTO_CONF_PW;
+ break;
+
+ case T_Randfile:
+ item = CRYPTO_CONF_RAND;
+ break;
+
+ case T_Digest:
+ item = CRYPTO_CONF_NID;
+ break;
+ }
+ crypto_config(item, my_val->value.s);
+ }
+#endif /* AUTOKEY */
+
+ /* Keysdir Command */
+ if (ptree->auth.keysdir) {
+ if (keysdir != default_keysdir)
+ free(keysdir);
+ keysdir = estrdup(ptree->auth.keysdir);
+ }
+
+
+ /* ntp_signd_socket Command */
+ if (ptree->auth.ntp_signd_socket) {
+ if (ntp_signd_socket != default_ntp_signd_socket)
+ free(ntp_signd_socket);
+ ntp_signd_socket = estrdup(ptree->auth.ntp_signd_socket);
+ }
+
+#ifdef AUTOKEY
+ if (ptree->auth.cryptosw && !cryptosw) {
+ crypto_setup();
+ cryptosw = 1;
+ }
+#endif /* AUTOKEY */
+
+ /*
+ * Count the number of trusted keys to preallocate storage and
+ * size the hash table.
+ */
+ count = 0;
+ my_val = HEAD_PFIFO(ptree->auth.trusted_key_list);
+ for (; my_val != NULL; my_val = my_val->link) {
+ if (T_Integer == my_val->type) {
+ first = my_val->value.i;
+ if (first > 1 && first <= NTP_MAXKEY)
+ count++;
+ } else {
+ REQUIRE(T_Intrange == my_val->type);
+ first = my_val->value.r.first;
+ last = my_val->value.r.last;
+ if (!(first > last || first < 1 ||
+ last > NTP_MAXKEY)) {
+ count += 1 + last - first;
+ }
+ }
+ }
+ auth_prealloc_symkeys(count);
+
+ /* Keys Command */
+ if (ptree->auth.keys)
+ getauthkeys(ptree->auth.keys);
+
+ /* Control Key Command */
+ if (ptree->auth.control_key)
+ ctl_auth_keyid = (keyid_t)ptree->auth.control_key;
+
+ /* Requested Key Command */
+ if (ptree->auth.request_key) {
+ DPRINTF(4, ("set info_auth_keyid to %08lx\n",
+ (u_long) ptree->auth.request_key));
+ info_auth_keyid = (keyid_t)ptree->auth.request_key;
+ }
+
+ /* Trusted Key Command */
+ my_val = HEAD_PFIFO(ptree->auth.trusted_key_list);
+ for (; my_val != NULL; my_val = my_val->link) {
+ if (T_Integer == my_val->type) {
+ first = my_val->value.i;
+ if (first >= 1 && first <= NTP_MAXKEY) {
+ authtrust(first, TRUE);
+ } else {
+ msyslog(LOG_NOTICE,
+ "Ignoring invalid trustedkey %d, min 1 max %d.",
+ first, NTP_MAXKEY);
+ }
+ } else {
+ first = my_val->value.r.first;
+ last = my_val->value.r.last;
+ if (first > last || first < 1 ||
+ last > NTP_MAXKEY) {
+ msyslog(LOG_NOTICE,
+ "Ignoring invalid trustedkey range %d ... %d, min 1 max %d.",
+ first, last, NTP_MAXKEY);
+ } else {
+ for (i = first; i <= last; i++) {
+ authtrust(i, TRUE);
+ }
+ }
+ }
+ }
+
+#ifdef AUTOKEY
+ /* crypto revoke command */
+ if (ptree->auth.revoke > 2 && ptree->auth.revoke < 32)
+ sys_revoke = (u_char)ptree->auth.revoke;
+ else if (ptree->auth.revoke)
+ msyslog(LOG_ERR,
+ "'revoke' value %d ignored",
+ ptree->auth.revoke);
+#endif /* AUTOKEY */
+}
+#endif /* !SIM */
+
+
+#ifdef FREE_CFG_T
+static void
+free_config_auth(
+ config_tree *ptree
+ )
+{
+ destroy_attr_val_fifo(ptree->auth.crypto_cmd_list);
+ ptree->auth.crypto_cmd_list = NULL;
+ destroy_attr_val_fifo(ptree->auth.trusted_key_list);
+ ptree->auth.trusted_key_list = NULL;
+}
+#endif /* FREE_CFG_T */
+
+
+/* Configure low-level clock-related parameters. Return TRUE if the
+ * clock might need adjustment like era-checking after the call, FALSE
+ * otherwise.
+ */
+static int/*BOOL*/
+config_tos_clock(
+ config_tree *ptree
+ )
+{
+ int ret;
+ attr_val * tos;
+
+ ret = FALSE;
+ tos = HEAD_PFIFO(ptree->orphan_cmds);
+ for (; tos != NULL; tos = tos->link) {
+ switch(tos->attr) {
+
+ default:
+ break;
+
+ case T_Basedate:
+ basedate_set_day(tos->value.i);
+ ret = TRUE;
+ break;
+ }
+ }
+
+ if (basedate_get_day() <= NTP_TO_UNIX_DAYS)
+ basedate_set_day(basedate_eval_buildstamp() - 11);
+
+ return ret;
+}
+
+static void
+config_tos(
+ config_tree *ptree
+ )
+{
+ attr_val * tos;
+ int item;
+ double val;
+
+ /* [Bug 2896] For the daemon to work properly it is essential
+ * that minsane < minclock <= maxclock.
+ *
+ * If either constraint is violated, the daemon will be or might
+ * become dysfunctional. Fixing the values is too fragile here,
+ * since three variables with interdependecies are involved. We
+ * just log an error but do not stop: This might be caused by
+ * remote config, and it might be fixed by remote config, too.
+ */
+ int l_maxclock = sys_maxclock;
+ int l_minclock = sys_minclock;
+ int l_minsane = sys_minsane;
+
+ /* -*- phase one: inspect / sanitize the values */
+ tos = HEAD_PFIFO(ptree->orphan_cmds);
+ for (; tos != NULL; tos = tos->link) {
+ /* not all attributes are doubles (any more), so loading
+ * 'val' in all cases is not a good idea: It should be
+ * done as needed in every case processed here.
+ */
+ switch(tos->attr) {
+ default:
+ break;
+
+ case T_Bcpollbstep:
+ val = tos->value.d;
+ if (val > 4) {
+ msyslog(LOG_WARNING,
+ "Using maximum bcpollbstep ceiling %d, %d requested",
+ 4, (int)val);
+ tos->value.d = 4;
+ } else if (val < 0) {
+ msyslog(LOG_WARNING,
+ "Using minimum bcpollbstep floor %d, %d requested",
+ 0, (int)val);
+ tos->value.d = 0;
+ }
+ break;
+
+ case T_Ceiling:
+ val = tos->value.d;
+ if (val > STRATUM_UNSPEC - 1) {
+ msyslog(LOG_WARNING,
+ "Using maximum tos ceiling %d, %d requested",
+ STRATUM_UNSPEC - 1, (int)val);
+ tos->value.d = STRATUM_UNSPEC - 1;
+ } else if (val < 1) {
+ msyslog(LOG_WARNING,
+ "Using minimum tos floor %d, %d requested",
+ 1, (int)val);
+ tos->value.d = 1;
+ }
+ break;
+
+ case T_Minclock:
+ val = tos->value.d;
+ if ((int)tos->value.d < 1)
+ tos->value.d = 1;
+ l_minclock = (int)tos->value.d;
+ break;
+
+ case T_Maxclock:
+ val = tos->value.d;
+ if ((int)tos->value.d < 1)
+ tos->value.d = 1;
+ l_maxclock = (int)tos->value.d;
+ break;
+
+ case T_Minsane:
+ val = tos->value.d;
+ if ((int)tos->value.d < 0)
+ tos->value.d = 0;
+ l_minsane = (int)tos->value.d;
+ break;
+ }
+ }
+
+ if ( ! (l_minsane < l_minclock && l_minclock <= l_maxclock)) {
+ msyslog(LOG_ERR,
+ "tos error: must have minsane (%d) < minclock (%d) <= maxclock (%d)"
+ " - daemon will not operate properly!",
+ l_minsane, l_minclock, l_maxclock);
+ }
+
+ /* -*- phase two: forward the values to the protocol machinery */
+ tos = HEAD_PFIFO(ptree->orphan_cmds);
+ for (; tos != NULL; tos = tos->link) {
+ switch(tos->attr) {
+
+ default:
+ fatal_error("config-tos: attr-token=%d", tos->attr);
+
+ case T_Bcpollbstep:
+ item = PROTO_BCPOLLBSTEP;
+ break;
+
+ case T_Ceiling:
+ item = PROTO_CEILING;
+ break;
+
+ case T_Floor:
+ item = PROTO_FLOOR;
+ break;
+
+ case T_Cohort:
+ item = PROTO_COHORT;
+ break;
+
+ case T_Orphan:
+ item = PROTO_ORPHAN;
+ break;
+
+ case T_Orphanwait:
+ item = PROTO_ORPHWAIT;
+ break;
+
+ case T_Mindist:
+ item = PROTO_MINDISP;
+ break;
+
+ case T_Maxdist:
+ item = PROTO_MAXDIST;
+ break;
+
+ case T_Minclock:
+ item = PROTO_MINCLOCK;
+ break;
+
+ case T_Maxclock:
+ item = PROTO_MAXCLOCK;
+ break;
+
+ case T_Minsane:
+ item = PROTO_MINSANE;
+ break;
+
+ case T_Beacon:
+ item = PROTO_BEACON;
+ break;
+
+ case T_Basedate:
+ continue; /* SKIP proto-config for this! */
+ }
+ proto_config(item, 0, tos->value.d, NULL);
+ }
+}
+
+
+#ifdef FREE_CFG_T
+static void
+free_config_tos(
+ config_tree *ptree
+ )
+{
+ FREE_ATTR_VAL_FIFO(ptree->orphan_cmds);
+}
+#endif /* FREE_CFG_T */
+
+
+static void
+config_monitor(
+ config_tree *ptree
+ )
+{
+ int_node *pfilegen_token;
+ const char *filegen_string;
+ const char *filegen_file;
+ FILEGEN *filegen;
+ filegen_node *my_node;
+ attr_val *my_opts;
+ int filegen_type;
+ int filegen_flag;
+
+ /* Set the statistics directory */
+ if (ptree->stats_dir)
+ stats_config(STATS_STATSDIR, ptree->stats_dir);
+
+ /* NOTE:
+ * Calling filegen_get is brain dead. Doing a string
+ * comparison to find the relavant filegen structure is
+ * expensive.
+ *
+ * Through the parser, we already know which filegen is
+ * being specified. Hence, we should either store a
+ * pointer to the specified structure in the syntax tree
+ * or an index into a filegen array.
+ *
+ * Need to change the filegen code to reflect the above.
+ */
+
+ /* Turn on the specified statistics */
+ pfilegen_token = HEAD_PFIFO(ptree->stats_list);
+ for (; pfilegen_token != NULL; pfilegen_token = pfilegen_token->link) {
+ filegen_string = keyword(pfilegen_token->i);
+ filegen = filegen_get(filegen_string);
+ if (NULL == filegen) {
+ msyslog(LOG_ERR,
+ "stats %s unrecognized",
+ filegen_string);
+ continue;
+ }
+ DPRINTF(4, ("enabling filegen for %s statistics '%s%s'\n",
+ filegen_string, filegen->dir,
+ filegen->fname));
+ filegen_flag = filegen->flag;
+ filegen_flag |= FGEN_FLAG_ENABLED;
+ filegen_config(filegen, statsdir, filegen_string,
+ filegen->type, filegen_flag);
+ }
+
+ /* Configure the statistics with the options */
+ my_node = HEAD_PFIFO(ptree->filegen_opts);
+ for (; my_node != NULL; my_node = my_node->link) {
+ filegen_string = keyword(my_node->filegen_token);
+ filegen = filegen_get(filegen_string);
+ if (NULL == filegen) {
+ msyslog(LOG_ERR,
+ "filegen category '%s' unrecognized",
+ filegen_string);
+ continue;
+ }
+ filegen_file = filegen_string;
+
+ /* Initialize the filegen variables to their pre-configuration states */
+ filegen_flag = filegen->flag;
+ filegen_type = filegen->type;
+
+ /* "filegen ... enabled" is the default (when filegen is used) */
+ filegen_flag |= FGEN_FLAG_ENABLED;
+
+ my_opts = HEAD_PFIFO(my_node->options);
+ for (; my_opts != NULL; my_opts = my_opts->link) {
+ switch (my_opts->attr) {
+
+ case T_File:
+ filegen_file = my_opts->value.s;
+ break;
+
+ case T_Type:
+ switch (my_opts->value.i) {
+
+ default:
+ fatal_error("config-monitor: type-token=%d", my_opts->value.i);
+
+ case T_None:
+ filegen_type = FILEGEN_NONE;
+ break;
+
+ case T_Pid:
+ filegen_type = FILEGEN_PID;
+ break;
+
+ case T_Day:
+ filegen_type = FILEGEN_DAY;
+ break;
+
+ case T_Week:
+ filegen_type = FILEGEN_WEEK;
+ break;
+
+ case T_Month:
+ filegen_type = FILEGEN_MONTH;
+ break;
+
+ case T_Year:
+ filegen_type = FILEGEN_YEAR;
+ break;
+
+ case T_Age:
+ filegen_type = FILEGEN_AGE;
+ break;
+ }
+ break;
+
+ case T_Flag:
+ switch (my_opts->value.i) {
+
+ case T_Link:
+ filegen_flag |= FGEN_FLAG_LINK;
+ break;
+
+ case T_Nolink:
+ filegen_flag &= ~FGEN_FLAG_LINK;
+ break;
+
+ case T_Enable:
+ filegen_flag |= FGEN_FLAG_ENABLED;
+ break;
+
+ case T_Disable:
+ filegen_flag &= ~FGEN_FLAG_ENABLED;
+ break;
+
+ default:
+ msyslog(LOG_ERR,
+ "Unknown filegen flag token %d",
+ my_opts->value.i);
+ exit(1);
+ }
+ break;
+
+ default:
+ msyslog(LOG_ERR,
+ "Unknown filegen option token %d",
+ my_opts->attr);
+ exit(1);
+ }
+ }
+ filegen_config(filegen, statsdir, filegen_file,
+ filegen_type, filegen_flag);
+ }
+}
+
+
+#ifdef FREE_CFG_T
+static void
+free_config_monitor(
+ config_tree *ptree
+ )
+{
+ if (ptree->stats_dir) {
+ free(ptree->stats_dir);
+ ptree->stats_dir = NULL;
+ }
+
+ FREE_INT_FIFO(ptree->stats_list);
+ FREE_FILEGEN_FIFO(ptree->filegen_opts);
+}
+#endif /* FREE_CFG_T */
+
+
+#ifndef SIM
+static void
+config_access(
+ config_tree *ptree
+ )
+{
+ static int warned_signd;
+ attr_val * my_opt;
+ restrict_node * my_node;
+ int_node * curr_tok_fifo;
+ sockaddr_u addr;
+ sockaddr_u mask;
+ struct addrinfo hints;
+ struct addrinfo * ai_list;
+ struct addrinfo * pai;
+ int rc;
+ int restrict_default;
+ u_short rflags;
+ u_short mflags;
+ short ippeerlimit;
+ int range_err;
+ const char * signd_warning =
+#ifdef HAVE_NTP_SIGND
+ "MS-SNTP signd operations currently block ntpd degrading service to all clients.";
+#else
+ "mssntp restrict bit ignored, this ntpd was configured without --enable-ntp-signd.";
+#endif
+
+ /* Configure the mru options */
+ my_opt = HEAD_PFIFO(ptree->mru_opts);
+ for (; my_opt != NULL; my_opt = my_opt->link) {
+
+ range_err = FALSE;
+
+ switch (my_opt->attr) {
+
+ case T_Incalloc:
+ if (0 <= my_opt->value.i)
+ mru_incalloc = my_opt->value.u;
+ else
+ range_err = TRUE;
+ break;
+
+ case T_Incmem:
+ if (0 <= my_opt->value.i)
+ mru_incalloc = (my_opt->value.u * 1024U)
+ / sizeof(mon_entry);
+ else
+ range_err = TRUE;
+ break;
+
+ case T_Initalloc:
+ if (0 <= my_opt->value.i)
+ mru_initalloc = my_opt->value.u;
+ else
+ range_err = TRUE;
+ break;
+
+ case T_Initmem:
+ if (0 <= my_opt->value.i)
+ mru_initalloc = (my_opt->value.u * 1024U)
+ / sizeof(mon_entry);
+ else
+ range_err = TRUE;
+ break;
+
+ case T_Mindepth:
+ if (0 <= my_opt->value.i)
+ mru_mindepth = my_opt->value.u;
+ else
+ range_err = TRUE;
+ break;
+
+ case T_Maxage:
+ mru_maxage = my_opt->value.i;
+ break;
+
+ case T_Maxdepth:
+ if (0 <= my_opt->value.i)
+ mru_maxdepth = my_opt->value.u;
+ else
+ mru_maxdepth = UINT_MAX;
+ break;
+
+ case T_Maxmem:
+ if (0 <= my_opt->value.i)
+ mru_maxdepth = (my_opt->value.u * 1024U) /
+ sizeof(mon_entry);
+ else
+ mru_maxdepth = UINT_MAX;
+ break;
+
+ default:
+ msyslog(LOG_ERR,
+ "Unknown mru option %s (%d)",
+ keyword(my_opt->attr), my_opt->attr);
+ exit(1);
+ }
+ if (range_err)
+ msyslog(LOG_ERR,
+ "mru %s %d out of range, ignored.",
+ keyword(my_opt->attr), my_opt->value.i);
+ }
+
+ /* Configure the discard options */
+ my_opt = HEAD_PFIFO(ptree->discard_opts);
+ for (; my_opt != NULL; my_opt = my_opt->link) {
+
+ switch (my_opt->attr) {
+
+ case T_Average:
+ if (0 <= my_opt->value.i &&
+ my_opt->value.i <= UCHAR_MAX)
+ ntp_minpoll = (u_char)my_opt->value.u;
+ else
+ msyslog(LOG_ERR,
+ "discard average %d out of range, ignored.",
+ my_opt->value.i);
+ break;
+
+ case T_Minimum:
+ ntp_minpkt = my_opt->value.i;
+ break;
+
+ case T_Monitor:
+ mon_age = my_opt->value.i;
+ break;
+
+ default:
+ msyslog(LOG_ERR,
+ "Unknown discard option %s (%d)",
+ keyword(my_opt->attr), my_opt->attr);
+ exit(1);
+ }
+ }
+
+ /* Configure the restrict options */
+ my_node = HEAD_PFIFO(ptree->restrict_opts);
+
+ for (; my_node != NULL; my_node = my_node->link) {
+ /* Grab the ippeerlmit */
+ ippeerlimit = my_node->ippeerlimit;
+
+DPRINTF(1, ("config_access: top-level node %p: ippeerlimit %d\n", my_node, ippeerlimit));
+
+ /* Parse the flags */
+ rflags = 0;
+ mflags = 0;
+
+ curr_tok_fifo = HEAD_PFIFO(my_node->flag_tok_fifo);
+ for (; curr_tok_fifo != NULL; curr_tok_fifo = curr_tok_fifo->link) {
+ switch (curr_tok_fifo->i) {
+
+ default:
+ fatal_error("config_access: flag-type-token=%d", curr_tok_fifo->i);
+
+ case T_Ntpport:
+ mflags |= RESM_NTPONLY;
+ break;
+
+ case T_Source:
+ mflags |= RESM_SOURCE;
+ break;
+
+ case T_Flake:
+ rflags |= RES_FLAKE;
+ break;
+
+ case T_Ignore:
+ rflags |= RES_IGNORE;
+ break;
+
+ case T_Kod:
+ rflags |= RES_KOD;
+ break;
+
+ case T_Mssntp:
+ rflags |= RES_MSSNTP;
+ break;
+
+ case T_Limited:
+ rflags |= RES_LIMITED;
+ break;
+
+ case T_Lowpriotrap:
+ rflags |= RES_LPTRAP;
+ break;
+
+ case T_Nomodify:
+ rflags |= RES_NOMODIFY;
+ break;
+
+ case T_Nomrulist:
+ rflags |= RES_NOMRULIST;
+ break;
+
+ case T_Noepeer:
+ rflags |= RES_NOEPEER;
+ break;
+
+ case T_Nopeer:
+ rflags |= RES_NOPEER;
+ break;
+
+ case T_Noquery:
+ rflags |= RES_NOQUERY;
+ break;
+
+ case T_Noserve:
+ rflags |= RES_DONTSERVE;
+ break;
+
+ case T_Notrap:
+ rflags |= RES_NOTRAP;
+ break;
+
+ case T_Notrust:
+ rflags |= RES_DONTTRUST;
+ break;
+
+ case T_Version:
+ rflags |= RES_VERSION;
+ break;
+ }
+ }
+
+ if ((RES_MSSNTP & rflags) && !warned_signd) {
+ warned_signd = 1;
+ fprintf(stderr, "%s\n", signd_warning);
+ msyslog(LOG_WARNING, "%s", signd_warning);
+ }
+
+ /* It would be swell if we could identify the line number */
+ if ((RES_KOD & rflags) && !(RES_LIMITED & rflags)) {
+ const char *kod_where = (my_node->addr)
+ ? my_node->addr->address
+ : (mflags & RESM_SOURCE)
+ ? "source"
+ : "default";
+ const char *kod_warn = "KOD does nothing without LIMITED.";
+
+ fprintf(stderr, "restrict %s: %s\n", kod_where, kod_warn);
+ msyslog(LOG_WARNING, "restrict %s: %s", kod_where, kod_warn);
+ }
+
+ ZERO_SOCK(&addr);
+ ai_list = NULL;
+ pai = NULL;
+ restrict_default = 0;
+
+ if (NULL == my_node->addr) {
+ ZERO_SOCK(&mask);
+ if (!(RESM_SOURCE & mflags)) {
+ /*
+ * The user specified a default rule
+ * without a -4 / -6 qualifier, add to
+ * both lists
+ */
+ restrict_default = 1;
+ } else {
+ /* apply "restrict source ..." */
+ DPRINTF(1, ("restrict source template ippeerlimit %d mflags %x rflags %x\n",
+ ippeerlimit, mflags, rflags));
+ hack_restrict(RESTRICT_FLAGS, NULL, NULL,
+ ippeerlimit, mflags, rflags, 0);
+ continue;
+ }
+ } else {
+ /* Resolve the specified address */
+ AF(&addr) = (u_short)my_node->addr->type;
+
+ if (getnetnum(my_node->addr->address,
+ &addr, 1, t_UNK) != 1) {
+ /*
+ * Attempt a blocking lookup. This
+ * is in violation of the nonblocking
+ * design of ntpd's mainline code. The
+ * alternative of running without the
+ * restriction until the name resolved
+ * seems worse.
+ * Ideally some scheme could be used for
+ * restrict directives in the startup
+ * ntp.conf to delay starting up the
+ * protocol machinery until after all
+ * restrict hosts have been resolved.
+ */
+ ai_list = NULL;
+ ZERO(hints);
+ hints.ai_protocol = IPPROTO_UDP;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_family = my_node->addr->type;
+ rc = getaddrinfo(my_node->addr->address,
+ "ntp", &hints,
+ &ai_list);
+ if (rc) {
+ msyslog(LOG_ERR,
+ "restrict: ignoring line %d, address/host '%s' unusable.",
+ my_node->line_no,
+ my_node->addr->address);
+ continue;
+ }
+ INSIST(ai_list != NULL);
+ pai = ai_list;
+ INSIST(pai->ai_addr != NULL);
+ INSIST(sizeof(addr) >=
+ pai->ai_addrlen);
+ memcpy(&addr, pai->ai_addr,
+ pai->ai_addrlen);
+ INSIST(AF_INET == AF(&addr) ||
+ AF_INET6 == AF(&addr));
+ }
+
+ SET_HOSTMASK(&mask, AF(&addr));
+
+ /* Resolve the mask */
+ if (my_node->mask) {
+ ZERO_SOCK(&mask);
+ AF(&mask) = my_node->mask->type;
+ if (getnetnum(my_node->mask->address,
+ &mask, 1, t_MSK) != 1) {
+ msyslog(LOG_ERR,
+ "restrict: ignoring line %d, mask '%s' unusable.",
+ my_node->line_no,
+ my_node->mask->address);
+ continue;
+ }
+ }
+ }
+
+ /* Set the flags */
+ if (restrict_default) {
+ AF(&addr) = AF_INET;
+ AF(&mask) = AF_INET;
+ hack_restrict(RESTRICT_FLAGS, &addr, &mask,
+ ippeerlimit, mflags, rflags, 0);
+ AF(&addr) = AF_INET6;
+ AF(&mask) = AF_INET6;
+ }
+
+ do {
+ hack_restrict(RESTRICT_FLAGS, &addr, &mask,
+ ippeerlimit, mflags, rflags, 0);
+ if (pai != NULL &&
+ NULL != (pai = pai->ai_next)) {
+ INSIST(pai->ai_addr != NULL);
+ INSIST(sizeof(addr) >=
+ pai->ai_addrlen);
+ ZERO_SOCK(&addr);
+ memcpy(&addr, pai->ai_addr,
+ pai->ai_addrlen);
+ INSIST(AF_INET == AF(&addr) ||
+ AF_INET6 == AF(&addr));
+ SET_HOSTMASK(&mask, AF(&addr));
+ }
+ } while (pai != NULL);
+
+ if (ai_list != NULL)
+ freeaddrinfo(ai_list);
+ }
+}
+#endif /* !SIM */
+
+
+#ifdef FREE_CFG_T
+static void
+free_config_access(
+ config_tree *ptree
+ )
+{
+ FREE_ATTR_VAL_FIFO(ptree->mru_opts);
+ FREE_ATTR_VAL_FIFO(ptree->discard_opts);
+ FREE_RESTRICT_FIFO(ptree->restrict_opts);
+}
+#endif /* FREE_CFG_T */
+
+
+static void
+config_rlimit(
+ config_tree *ptree
+ )
+{
+ attr_val * rlimit_av;
+
+ rlimit_av = HEAD_PFIFO(ptree->rlimit);
+ for (; rlimit_av != NULL; rlimit_av = rlimit_av->link) {
+ switch (rlimit_av->attr) {
+
+ default:
+ fatal_error("config-rlimit: value-token=%d", rlimit_av->attr);
+
+ case T_Memlock:
+ /* What if we HAVE_OPT(SAVECONFIGQUIT) ? */
+ if (HAVE_OPT( SAVECONFIGQUIT )) {
+ break;
+ }
+ if (rlimit_av->value.i == -1) {
+# if defined(HAVE_MLOCKALL)
+ if (cur_memlock != 0) {
+ if (-1 == munlockall()) {
+ msyslog(LOG_ERR, "munlockall() failed: %m");
+ }
+ }
+ cur_memlock = 0;
+# endif /* HAVE_MLOCKALL */
+ } else if (rlimit_av->value.i >= 0) {
+#if defined(RLIMIT_MEMLOCK)
+# if defined(HAVE_MLOCKALL)
+ if (cur_memlock != 1) {
+ if (-1 == mlockall(MCL_CURRENT|MCL_FUTURE)) {
+ msyslog(LOG_ERR, "mlockall() failed: %m");
+ }
+ }
+# endif /* HAVE_MLOCKALL */
+ ntp_rlimit(RLIMIT_MEMLOCK,
+ (rlim_t)(rlimit_av->value.i * 1024 * 1024),
+ 1024 * 1024,
+ "MB");
+ cur_memlock = 1;
+#else
+ /* STDERR as well would be fine... */
+ msyslog(LOG_WARNING, "'rlimit memlock' specified but is not available on this system.");
+#endif /* RLIMIT_MEMLOCK */
+ } else {
+ msyslog(LOG_WARNING, "'rlimit memlock' value of %d is unexpected!", rlimit_av->value.i);
+ }
+ break;
+
+ case T_Stacksize:
+#if defined(RLIMIT_STACK)
+ ntp_rlimit(RLIMIT_STACK,
+ (rlim_t)(rlimit_av->value.i * 4096),
+ 4096,
+ "4k");
+#else
+ /* STDERR as well would be fine... */
+ msyslog(LOG_WARNING, "'rlimit stacksize' specified but is not available on this system.");
+#endif /* RLIMIT_STACK */
+ break;
+
+ case T_Filenum:
+#if defined(RLIMIT_NOFILE)
+ ntp_rlimit(RLIMIT_NOFILE,
+ (rlim_t)(rlimit_av->value.i),
+ 1,
+ "");
+#else
+ /* STDERR as well would be fine... */
+ msyslog(LOG_WARNING, "'rlimit filenum' specified but is not available on this system.");
+#endif /* RLIMIT_NOFILE */
+ break;
+
+ }
+ }
+}
+
+
+static void
+config_tinker(
+ config_tree *ptree
+ )
+{
+ attr_val * tinker;
+ int item;
+
+ tinker = HEAD_PFIFO(ptree->tinker);
+ for (; tinker != NULL; tinker = tinker->link) {
+ switch (tinker->attr) {
+
+ default:
+ fatal_error("config_tinker: attr-token=%d", tinker->attr);
+
+ case T_Allan:
+ item = LOOP_ALLAN;
+ break;
+
+ case T_Dispersion:
+ item = LOOP_PHI;
+ break;
+
+ case T_Freq:
+ item = LOOP_FREQ;
+ break;
+
+ case T_Huffpuff:
+ item = LOOP_HUFFPUFF;
+ break;
+
+ case T_Panic:
+ item = LOOP_PANIC;
+ break;
+
+ case T_Step:
+ item = LOOP_MAX;
+ break;
+
+ case T_Stepback:
+ item = LOOP_MAX_BACK;
+ break;
+
+ case T_Stepfwd:
+ item = LOOP_MAX_FWD;
+ break;
+
+ case T_Stepout:
+ item = LOOP_MINSTEP;
+ break;
+
+ case T_Tick:
+ item = LOOP_TICK;
+ break;
+ }
+ loop_config(item, tinker->value.d);
+ }
+}
+
+
+#ifdef FREE_CFG_T
+static void
+free_config_rlimit(
+ config_tree *ptree
+ )
+{
+ FREE_ATTR_VAL_FIFO(ptree->rlimit);
+}
+
+static void
+free_config_tinker(
+ config_tree *ptree
+ )
+{
+ FREE_ATTR_VAL_FIFO(ptree->tinker);
+}
+#endif /* FREE_CFG_T */
+
+
+/*
+ * config_nic_rules - apply interface listen/ignore/drop items
+ */
+#ifndef SIM
+static void
+config_nic_rules(
+ config_tree *ptree,
+ int/*BOOL*/ input_from_file
+ )
+{
+ nic_rule_node * curr_node;
+ sockaddr_u addr;
+ nic_rule_match match_type;
+ nic_rule_action action;
+ char * if_name;
+ char * pchSlash;
+ int prefixlen;
+ int addrbits;
+
+ curr_node = HEAD_PFIFO(ptree->nic_rules);
+
+ if (curr_node != NULL
+ && (HAVE_OPT( NOVIRTUALIPS ) || HAVE_OPT( INTERFACE ))) {
+ msyslog(LOG_ERR,
+ "interface/nic rules are not allowed with --interface (-I) or --novirtualips (-L)%s",
+ (input_from_file) ? ", exiting" : "");
+ if (input_from_file)
+ exit(1);
+ else
+ return;
+ }
+
+ for (; curr_node != NULL; curr_node = curr_node->link) {
+ prefixlen = -1;
+ if_name = curr_node->if_name;
+ if (if_name != NULL)
+ if_name = estrdup(if_name);
+
+ switch (curr_node->match_class) {
+
+ default:
+ fatal_error("config_nic_rules: match-class-token=%d", curr_node->match_class);
+
+ case 0:
+ /*
+ * 0 is out of range for valid token T_...
+ * and in a nic_rules_node indicates the
+ * interface descriptor is either a name or
+ * address, stored in if_name in either case.
+ */
+ INSIST(if_name != NULL);
+ pchSlash = strchr(if_name, '/');
+ if (pchSlash != NULL)
+ *pchSlash = '\0';
+ if (is_ip_address(if_name, AF_UNSPEC, &addr)) {
+ match_type = MATCH_IFADDR;
+ if (pchSlash != NULL
+ && 1 == sscanf(pchSlash + 1, "%d",
+ &prefixlen)) {
+ addrbits = 8 *
+ SIZEOF_INADDR(AF(&addr));
+ prefixlen = max(-1, prefixlen);
+ prefixlen = min(prefixlen,
+ addrbits);
+ }
+ } else {
+ match_type = MATCH_IFNAME;
+ if (pchSlash != NULL)
+ *pchSlash = '/';
+ }
+ break;
+
+ case T_All:
+ match_type = MATCH_ALL;
+ break;
+
+ case T_Ipv4:
+ match_type = MATCH_IPV4;
+ break;
+
+ case T_Ipv6:
+ match_type = MATCH_IPV6;
+ break;
+
+ case T_Wildcard:
+ match_type = MATCH_WILDCARD;
+ break;
+ }
+
+ switch (curr_node->action) {
+
+ default:
+ fatal_error("config_nic_rules: action-token=%d", curr_node->action);
+
+ case T_Listen:
+ action = ACTION_LISTEN;
+ break;
+
+ case T_Ignore:
+ action = ACTION_IGNORE;
+ break;
+
+ case T_Drop:
+ action = ACTION_DROP;
+ break;
+ }
+
+ add_nic_rule(match_type, if_name, prefixlen,
+ action);
+ timer_interfacetimeout(current_time + 2);
+ if (if_name != NULL)
+ free(if_name);
+ }
+}
+#endif /* !SIM */
+
+
+#ifdef FREE_CFG_T
+static void
+free_config_nic_rules(
+ config_tree *ptree
+ )
+{
+ nic_rule_node *curr_node;
+
+ if (ptree->nic_rules != NULL) {
+ for (;;) {
+ UNLINK_FIFO(curr_node, *ptree->nic_rules, link);
+ if (NULL == curr_node)
+ break;
+ free(curr_node->if_name);
+ free(curr_node);
+ }
+ free(ptree->nic_rules);
+ ptree->nic_rules = NULL;
+ }
+}
+#endif /* FREE_CFG_T */
+
+
+static void
+apply_enable_disable(
+ attr_val_fifo * fifo,
+ int enable
+ )
+{
+ attr_val *curr_tok_fifo;
+ int option;
+#ifdef BC_LIST_FRAMEWORK_NOT_YET_USED
+ bc_entry *pentry;
+#endif
+
+ for (curr_tok_fifo = HEAD_PFIFO(fifo);
+ curr_tok_fifo != NULL;
+ curr_tok_fifo = curr_tok_fifo->link) {
+
+ option = curr_tok_fifo->value.i;
+ switch (option) {
+
+ default:
+ msyslog(LOG_ERR,
+ "can not apply enable/disable token %d, unknown",
+ option);
+ break;
+
+ case T_Auth:
+ proto_config(PROTO_AUTHENTICATE, enable, 0., NULL);
+ break;
+
+ case T_Bclient:
+ proto_config(PROTO_BROADCLIENT, enable, 0., NULL);
+ break;
+
+ case T_Calibrate:
+ proto_config(PROTO_CAL, enable, 0., NULL);
+ break;
+
+ case T_Kernel:
+ proto_config(PROTO_KERNEL, enable, 0., NULL);
+ break;
+
+ case T_Monitor:
+ proto_config(PROTO_MONITOR, enable, 0., NULL);
+ break;
+
+ case T_Mode7:
+ proto_config(PROTO_MODE7, enable, 0., NULL);
+ break;
+
+ case T_Ntp:
+ proto_config(PROTO_NTP, enable, 0., NULL);
+ break;
+
+ case T_PCEdigest:
+ proto_config(PROTO_PCEDIGEST, enable, 0., NULL);
+ break;
+
+ case T_Stats:
+ proto_config(PROTO_FILEGEN, enable, 0., NULL);
+ break;
+
+ case T_UEcrypto:
+ proto_config(PROTO_UECRYPTO, enable, 0., NULL);
+ break;
+
+ case T_UEcryptonak:
+ proto_config(PROTO_UECRYPTONAK, enable, 0., NULL);
+ break;
+
+ case T_UEdigest:
+ proto_config(PROTO_UEDIGEST, enable, 0., NULL);
+ break;
+
+#ifdef BC_LIST_FRAMEWORK_NOT_YET_USED
+ case T_Bc_bugXXXX:
+ pentry = bc_list;
+ while (pentry->token) {
+ if (pentry->token == option)
+ break;
+ pentry++;
+ }
+ if (!pentry->token) {
+ msyslog(LOG_ERR,
+ "compat token %d not in bc_list[]",
+ option);
+ continue;
+ }
+ pentry->enabled = enable;
+ break;
+#endif
+ }
+ }
+}
+
+
+static void
+config_system_opts(
+ config_tree *ptree
+ )
+{
+ apply_enable_disable(ptree->enable_opts, 1);
+ apply_enable_disable(ptree->disable_opts, 0);
+}
+
+
+#ifdef FREE_CFG_T
+static void
+free_config_system_opts(
+ config_tree *ptree
+ )
+{
+ FREE_ATTR_VAL_FIFO(ptree->enable_opts);
+ FREE_ATTR_VAL_FIFO(ptree->disable_opts);
+}
+#endif /* FREE_CFG_T */
+
+
+static void
+config_logconfig(
+ config_tree *ptree
+ )
+{
+ attr_val * my_lc;
+
+ my_lc = HEAD_PFIFO(ptree->logconfig);
+ for (; my_lc != NULL; my_lc = my_lc->link) {
+ switch (my_lc->attr) {
+
+ case '+':
+ ntp_syslogmask |= get_logmask(my_lc->value.s);
+ break;
+
+ case '-':
+ ntp_syslogmask &= ~get_logmask(my_lc->value.s);
+ break;
+
+ case '=':
+ ntp_syslogmask = get_logmask(my_lc->value.s);
+ break;
+ default:
+ fatal_error("config-logconfig: modifier='%c'", my_lc->attr);
+ }
+ }
+}
+
+
+#ifdef FREE_CFG_T
+static void
+free_config_logconfig(
+ config_tree *ptree
+ )
+{
+ FREE_ATTR_VAL_FIFO(ptree->logconfig);
+}
+#endif /* FREE_CFG_T */
+
+
+#ifndef SIM
+static void
+config_phone(
+ config_tree *ptree
+ )
+{
+ size_t i;
+ string_node * sn;
+
+ i = 0;
+ sn = HEAD_PFIFO(ptree->phone);
+ for (; sn != NULL; sn = sn->link) {
+ /* need to leave array entry for NULL terminator */
+ if (i < COUNTOF(sys_phone) - 1) {
+ sys_phone[i++] = estrdup(sn->s);
+ sys_phone[i] = NULL;
+ } else {
+ msyslog(LOG_INFO,
+ "phone: Number of phone entries exceeds %zu. Ignoring phone %s...",
+ (COUNTOF(sys_phone) - 1), sn->s);
+ }
+ }
+}
+#endif /* !SIM */
+
+static void
+config_mdnstries(
+ config_tree *ptree
+ )
+{
+#ifdef HAVE_DNSREGISTRATION
+ extern int mdnstries;
+ mdnstries = ptree->mdnstries;
+#endif /* HAVE_DNSREGISTRATION */
+}
+
+#ifdef FREE_CFG_T
+static void
+free_config_phone(
+ config_tree *ptree
+ )
+{
+ FREE_STRING_FIFO(ptree->phone);
+}
+#endif /* FREE_CFG_T */
+
+
+#ifndef SIM
+static void
+config_setvar(
+ config_tree *ptree
+ )
+{
+ setvar_node *my_node;
+ size_t varlen, vallen, octets;
+ char * str;
+
+ str = NULL;
+ my_node = HEAD_PFIFO(ptree->setvar);
+ for (; my_node != NULL; my_node = my_node->link) {
+ varlen = strlen(my_node->var);
+ vallen = strlen(my_node->val);
+ octets = varlen + vallen + 1 + 1;
+ str = erealloc(str, octets);
+ snprintf(str, octets, "%s=%s", my_node->var,
+ my_node->val);
+ set_sys_var(str, octets, (my_node->isdefault)
+ ? DEF
+ : 0);
+ }
+ if (str != NULL)
+ free(str);
+}
+#endif /* !SIM */
+
+
+#ifdef FREE_CFG_T
+static void
+free_config_setvar(
+ config_tree *ptree
+ )
+{
+ FREE_SETVAR_FIFO(ptree->setvar);
+}
+#endif /* FREE_CFG_T */
+
+
+#ifndef SIM
+static void
+config_ttl(
+ config_tree *ptree
+ )
+{
+ size_t i = 0;
+ int_node *curr_ttl;
+
+ /* [Bug 3465] There is a built-in default for the TTLs. We must
+ * overwrite 'sys_ttlmax' if we change that preset, and leave it
+ * alone otherwise!
+ */
+ curr_ttl = HEAD_PFIFO(ptree->ttl);
+ for (; curr_ttl != NULL; curr_ttl = curr_ttl->link) {
+ if (i < COUNTOF(sys_ttl))
+ sys_ttl[i++] = (u_char)curr_ttl->i;
+ else
+ msyslog(LOG_INFO,
+ "ttl: Number of TTL entries exceeds %zu. Ignoring TTL %d...",
+ COUNTOF(sys_ttl), curr_ttl->i);
+ }
+ if (0 != i) /* anything written back at all? */
+ sys_ttlmax = i - 1;
+}
+#endif /* !SIM */
+
+
+#ifdef FREE_CFG_T
+static void
+free_config_ttl(
+ config_tree *ptree
+ )
+{
+ FREE_INT_FIFO(ptree->ttl);
+}
+#endif /* FREE_CFG_T */
+
+
+#ifndef SIM
+static void
+config_trap(
+ config_tree *ptree
+ )
+{
+ addr_opts_node *curr_trap;
+ attr_val *curr_opt;
+ sockaddr_u addr_sock;
+ sockaddr_u peeraddr;
+ struct interface *localaddr;
+ struct addrinfo hints;
+ char port_text[8];
+ settrap_parms *pstp;
+ u_short port;
+ int err_flag;
+ int rc;
+
+ /* silence warning about addr_sock potentially uninitialized */
+ AF(&addr_sock) = AF_UNSPEC;
+
+ curr_trap = HEAD_PFIFO(ptree->trap);
+ for (; curr_trap != NULL; curr_trap = curr_trap->link) {
+ err_flag = 0;
+ port = 0;
+ localaddr = NULL;
+
+ curr_opt = HEAD_PFIFO(curr_trap->options);
+ for (; curr_opt != NULL; curr_opt = curr_opt->link) {
+ if (T_Port == curr_opt->attr) {
+ if (curr_opt->value.i < 1
+ || curr_opt->value.i > USHRT_MAX) {
+ msyslog(LOG_ERR,
+ "invalid port number "
+ "%d, trap ignored",
+ curr_opt->value.i);
+ err_flag = 1;
+ }
+ port = (u_short)curr_opt->value.i;
+ }
+ else if (T_Interface == curr_opt->attr) {
+ /* Resolve the interface address */
+ ZERO_SOCK(&addr_sock);
+ if (getnetnum(curr_opt->value.s,
+ &addr_sock, 1, t_UNK) != 1) {
+ err_flag = 1;
+ break;
+ }
+
+ localaddr = findinterface(&addr_sock);
+
+ if (NULL == localaddr) {
+ msyslog(LOG_ERR,
+ "can't find interface with address %s",
+ stoa(&addr_sock));
+ err_flag = 1;
+ }
+ }
+ }
+
+ /* Now process the trap for the specified interface
+ * and port number
+ */
+ if (!err_flag) {
+ if (!port)
+ port = TRAPPORT;
+ ZERO_SOCK(&peeraddr);
+ rc = getnetnum(curr_trap->addr->address,
+ &peeraddr, 1, t_UNK);
+ if (1 != rc) {
+#ifndef WORKER
+ msyslog(LOG_ERR,
+ "trap: unable to use IP address %s.",
+ curr_trap->addr->address);
+#else /* WORKER follows */
+ /*
+ * save context and hand it off
+ * for name resolution.
+ */
+ ZERO(hints);
+ hints.ai_protocol = IPPROTO_UDP;
+ hints.ai_socktype = SOCK_DGRAM;
+ snprintf(port_text, sizeof(port_text),
+ "%u", port);
+ hints.ai_flags = Z_AI_NUMERICSERV;
+ pstp = emalloc_zero(sizeof(*pstp));
+ if (localaddr != NULL) {
+ hints.ai_family = localaddr->family;
+ pstp->ifaddr_nonnull = 1;
+ memcpy(&pstp->ifaddr,
+ &localaddr->sin,
+ sizeof(pstp->ifaddr));
+ }
+ rc = getaddrinfo_sometime(
+ curr_trap->addr->address,
+ port_text, &hints,
+ INITIAL_DNS_RETRY,
+ &trap_name_resolved,
+ pstp);
+ if (!rc)
+ msyslog(LOG_ERR,
+ "config_trap: getaddrinfo_sometime(%s,%s): %m",
+ curr_trap->addr->address,
+ port_text);
+#endif /* WORKER */
+ continue;
+ }
+ /* port is at same location for v4 and v6 */
+ SET_PORT(&peeraddr, port);
+
+ if (NULL == localaddr)
+ localaddr = ANY_INTERFACE_CHOOSE(&peeraddr);
+ else
+ AF(&peeraddr) = AF(&addr_sock);
+
+ if (!ctlsettrap(&peeraddr, localaddr, 0,
+ NTP_VERSION))
+ msyslog(LOG_ERR,
+ "set trap %s -> %s failed.",
+ latoa(localaddr),
+ stoa(&peeraddr));
+ }
+ }
+}
+
+
+/*
+ * trap_name_resolved()
+ *
+ * Callback invoked when config_trap()'s DNS lookup completes.
+ */
+# ifdef WORKER
+static void
+trap_name_resolved(
+ int rescode,
+ int gai_errno,
+ void * context,
+ const char * name,
+ const char * service,
+ const struct addrinfo * hints,
+ const struct addrinfo * res
+ )
+{
+ settrap_parms *pstp;
+ struct interface *localaddr;
+ sockaddr_u peeraddr;
+
+ (void)gai_errno;
+ (void)service;
+ (void)hints;
+ pstp = context;
+ if (rescode) {
+ msyslog(LOG_ERR,
+ "giving up resolving trap host %s: %s (%d)",
+ name, gai_strerror(rescode), rescode);
+ free(pstp);
+ return;
+ }
+ INSIST(sizeof(peeraddr) >= res->ai_addrlen);
+ ZERO(peeraddr);
+ memcpy(&peeraddr, res->ai_addr, res->ai_addrlen);
+ localaddr = NULL;
+ if (pstp->ifaddr_nonnull)
+ localaddr = findinterface(&pstp->ifaddr);
+ if (NULL == localaddr)
+ localaddr = ANY_INTERFACE_CHOOSE(&peeraddr);
+ if (!ctlsettrap(&peeraddr, localaddr, 0, NTP_VERSION))
+ msyslog(LOG_ERR, "set trap %s -> %s failed.",
+ latoa(localaddr), stoa(&peeraddr));
+ free(pstp);
+}
+# endif /* WORKER */
+#endif /* !SIM */
+
+
+#ifdef FREE_CFG_T
+static void
+free_config_trap(
+ config_tree *ptree
+ )
+{
+ FREE_ADDR_OPTS_FIFO(ptree->trap);
+}
+#endif /* FREE_CFG_T */
+
+
+#ifndef SIM
+static void
+config_fudge(
+ config_tree *ptree
+ )
+{
+ addr_opts_node *curr_fudge;
+ attr_val *curr_opt;
+ sockaddr_u addr_sock;
+ address_node *addr_node;
+ struct refclockstat clock_stat;
+ int err_flag;
+
+ curr_fudge = HEAD_PFIFO(ptree->fudge);
+ for (; curr_fudge != NULL; curr_fudge = curr_fudge->link) {
+ err_flag = 0;
+
+ /* Get the reference clock address and
+ * ensure that it is sane
+ */
+ addr_node = curr_fudge->addr;
+ ZERO_SOCK(&addr_sock);
+ if (getnetnum(addr_node->address, &addr_sock, 1, t_REF)
+ != 1) {
+ err_flag = 1;
+ msyslog(LOG_ERR,
+ "unrecognized fudge reference clock address %s, line ignored",
+ addr_node->address);
+ } else if (!ISREFCLOCKADR(&addr_sock)) {
+ err_flag = 1;
+ msyslog(LOG_ERR,
+ "inappropriate address %s for the fudge command, line ignored",
+ stoa(&addr_sock));
+ }
+
+ /* Parse all the options to the fudge command */
+ ZERO(clock_stat);
+ curr_opt = HEAD_PFIFO(curr_fudge->options);
+ for (; curr_opt != NULL; curr_opt = curr_opt->link) {
+ switch (curr_opt->attr) {
+
+ case T_Time1:
+ clock_stat.haveflags |= CLK_HAVETIME1;
+ clock_stat.fudgetime1 = curr_opt->value.d;
+ break;
+
+ case T_Time2:
+ clock_stat.haveflags |= CLK_HAVETIME2;
+ clock_stat.fudgetime2 = curr_opt->value.d;
+ break;
+
+ case T_Stratum:
+ clock_stat.haveflags |= CLK_HAVEVAL1;
+ clock_stat.fudgeval1 = curr_opt->value.i;
+ break;
+
+ case T_Refid:
+ clock_stat.haveflags |= CLK_HAVEVAL2;
+ clock_stat.fudgeval2 = 0;
+ memcpy(&clock_stat.fudgeval2,
+ curr_opt->value.s,
+ min(strlen(curr_opt->value.s), 4));
+ break;
+
+ case T_Flag1:
+ clock_stat.haveflags |= CLK_HAVEFLAG1;
+ if (curr_opt->value.i)
+ clock_stat.flags |= CLK_FLAG1;
+ else
+ clock_stat.flags &= ~CLK_FLAG1;
+ break;
+
+ case T_Flag2:
+ clock_stat.haveflags |= CLK_HAVEFLAG2;
+ if (curr_opt->value.i)
+ clock_stat.flags |= CLK_FLAG2;
+ else
+ clock_stat.flags &= ~CLK_FLAG2;
+ break;
+
+ case T_Flag3:
+ clock_stat.haveflags |= CLK_HAVEFLAG3;
+ if (curr_opt->value.i)
+ clock_stat.flags |= CLK_FLAG3;
+ else
+ clock_stat.flags &= ~CLK_FLAG3;
+ break;
+
+ case T_Flag4:
+ clock_stat.haveflags |= CLK_HAVEFLAG4;
+ if (curr_opt->value.i)
+ clock_stat.flags |= CLK_FLAG4;
+ else
+ clock_stat.flags &= ~CLK_FLAG4;
+ break;
+
+ default:
+ msyslog(LOG_ERR,
+ "Unexpected fudge flag %s (%d) for %s",
+ token_name(curr_opt->attr),
+ curr_opt->attr, addr_node->address);
+ exit(curr_opt->attr ? curr_opt->attr : 1);
+ }
+ }
+# ifdef REFCLOCK
+ if (!err_flag)
+ refclock_control(&addr_sock, &clock_stat, NULL);
+# endif
+ }
+}
+#endif /* !SIM */
+
+
+#ifdef FREE_CFG_T
+static void
+free_config_fudge(
+ config_tree *ptree
+ )
+{
+ FREE_ADDR_OPTS_FIFO(ptree->fudge);
+}
+#endif /* FREE_CFG_T */
+
+
+static void
+config_vars(
+ config_tree *ptree
+ )
+{
+ attr_val *curr_var;
+ int len;
+
+ curr_var = HEAD_PFIFO(ptree->vars);
+ for (; curr_var != NULL; curr_var = curr_var->link) {
+ /* Determine which variable to set and set it */
+ switch (curr_var->attr) {
+
+ case T_Broadcastdelay:
+ proto_config(PROTO_BROADDELAY, 0, curr_var->value.d, NULL);
+ break;
+
+ case T_Tick:
+ loop_config(LOOP_TICK, curr_var->value.d);
+ break;
+
+ case T_Driftfile:
+ if ('\0' == curr_var->value.s[0]) {
+ stats_drift_file = 0;
+ msyslog(LOG_INFO, "config: driftfile disabled");
+ } else
+ stats_config(STATS_FREQ_FILE, curr_var->value.s);
+ break;
+
+ case T_Dscp:
+ /* DSCP is in the upper 6 bits of the IP TOS/DS field */
+ qos = curr_var->value.i << 2;
+ break;
+
+ case T_Ident:
+ sys_ident = curr_var->value.s;
+ break;
+
+ case T_WanderThreshold: /* FALLTHROUGH */
+ case T_Nonvolatile:
+ wander_threshold = curr_var->value.d;
+ break;
+
+ case T_Leapfile:
+ stats_config(STATS_LEAP_FILE, curr_var->value.s);
+ break;
+
+#ifdef LEAP_SMEAR
+ case T_Leapsmearinterval:
+ leap_smear_intv = curr_var->value.i;
+ msyslog(LOG_INFO, "config: leap smear interval %i s", leap_smear_intv);
+ break;
+#endif
+
+ case T_Pidfile:
+ stats_config(STATS_PID_FILE, curr_var->value.s);
+ break;
+
+ case T_Logfile:
+ if (-1 == change_logfile(curr_var->value.s, TRUE))
+ msyslog(LOG_ERR,
+ "Cannot open logfile %s: %m",
+ curr_var->value.s);
+ break;
+
+ case T_Saveconfigdir:
+ if (saveconfigdir != NULL)
+ free(saveconfigdir);
+ len = strlen(curr_var->value.s);
+ if (0 == len) {
+ saveconfigdir = NULL;
+ } else if (DIR_SEP != curr_var->value.s[len - 1]
+#ifdef SYS_WINNT /* slash is also a dir. sep. on Windows */
+ && '/' != curr_var->value.s[len - 1]
+#endif
+ ) {
+ len++;
+ saveconfigdir = emalloc(len + 1);
+ snprintf(saveconfigdir, len + 1,
+ "%s%c",
+ curr_var->value.s,
+ DIR_SEP);
+ } else {
+ saveconfigdir = estrdup(
+ curr_var->value.s);
+ }
+ break;
+
+ case T_Automax:
+#ifdef AUTOKEY
+ if (curr_var->value.i > 2 && curr_var->value.i < 32)
+ sys_automax = (u_char)curr_var->value.i;
+ else
+ msyslog(LOG_ERR,
+ "'automax' value %d ignored",
+ curr_var->value.i);
+#endif
+ break;
+
+ default:
+ msyslog(LOG_ERR,
+ "config_vars(): unexpected token %d",
+ curr_var->attr);
+ }
+ }
+}
+
+
+#ifdef FREE_CFG_T
+static void
+free_config_vars(
+ config_tree *ptree
+ )
+{
+ FREE_ATTR_VAL_FIFO(ptree->vars);
+}
+#endif /* FREE_CFG_T */
+
+
+/* Define a function to check if a resolved address is sane.
+ * If yes, return 1, else return 0;
+ */
+static int
+is_sane_resolved_address(
+ sockaddr_u * peeraddr,
+ int hmode
+ )
+{
+ if (!ISREFCLOCKADR(peeraddr) && ISBADADR(peeraddr)) {
+ msyslog(LOG_ERR,
+ "attempt to configure invalid address %s",
+ stoa(peeraddr));
+ return 0;
+ }
+ /*
+ * Shouldn't be able to specify multicast
+ * address for server/peer!
+ * and unicast address for manycastclient!
+ */
+ if ((T_Server == hmode || T_Peer == hmode || T_Pool == hmode)
+ && IS_MCAST(peeraddr)) {
+ msyslog(LOG_ERR,
+ "attempt to configure invalid address %s",
+ stoa(peeraddr));
+ return 0;
+ }
+ if (T_Manycastclient == hmode && !IS_MCAST(peeraddr)) {
+ msyslog(LOG_ERR,
+ "attempt to configure invalid address %s",
+ stoa(peeraddr));
+ return 0;
+ }
+
+ if (IS_IPV6(peeraddr) && !ipv6_works)
+ return 0;
+
+ /* Ok, all tests succeeded, now we can return 1 */
+ return 1;
+}
+
+
+#ifndef SIM
+static u_char
+get_correct_host_mode(
+ int token
+ )
+{
+ switch (token) {
+
+ case T_Server:
+ case T_Pool:
+ case T_Manycastclient:
+ return MODE_CLIENT;
+
+ case T_Peer:
+ return MODE_ACTIVE;
+
+ case T_Broadcast:
+ return MODE_BROADCAST;
+
+ default:
+ return 0;
+ }
+}
+
+
+/*
+ * peerflag_bits() get config_peers() peerflags value from a
+ * peer_node's queue of flag attr_val entries.
+ */
+static int
+peerflag_bits(
+ peer_node *pn
+ )
+{
+ int peerflags;
+ attr_val *option;
+
+ /* translate peerflags options to bits */
+ peerflags = 0;
+ option = HEAD_PFIFO(pn->peerflags);
+ for (; option != NULL; option = option->link) {
+ switch (option->value.i) {
+
+ default:
+ fatal_error("peerflag_bits: option-token=%d", option->value.i);
+
+ case T_Autokey:
+ peerflags |= FLAG_SKEY;
+ break;
+
+ case T_Burst:
+ peerflags |= FLAG_BURST;
+ break;
+
+ case T_Iburst:
+ peerflags |= FLAG_IBURST;
+ break;
+
+ case T_Noselect:
+ peerflags |= FLAG_NOSELECT;
+ break;
+
+ case T_Preempt:
+ peerflags |= FLAG_PREEMPT;
+ break;
+
+ case T_Prefer:
+ peerflags |= FLAG_PREFER;
+ break;
+
+ case T_True:
+ peerflags |= FLAG_TRUE;
+ break;
+
+ case T_Xleave:
+ peerflags |= FLAG_XLEAVE;
+ break;
+ }
+ }
+
+ return peerflags;
+}
+
+
+static void
+config_peers(
+ config_tree *ptree
+ )
+{
+ sockaddr_u peeraddr;
+ struct addrinfo hints;
+ peer_node * curr_peer;
+ peer_resolved_ctx * ctx;
+ u_char hmode;
+
+ /* add servers named on the command line with iburst implied */
+ for (;
+ cmdline_server_count > 0;
+ cmdline_server_count--, cmdline_servers++) {
+
+ ZERO_SOCK(&peeraddr);
+ /*
+ * If we have a numeric address, we can safely
+ * proceed in the mainline with it. Otherwise, hand
+ * the hostname off to the blocking child.
+ *
+ * Note that if we're told to add the peer here, we
+ * do that regardless of ippeerlimit.
+ */
+ if (is_ip_address(*cmdline_servers, AF_UNSPEC,
+ &peeraddr)) {
+
+ SET_PORT(&peeraddr, NTP_PORT);
+ if (is_sane_resolved_address(&peeraddr,
+ T_Server))
+ peer_config(
+ &peeraddr,
+ NULL,
+ NULL,
+ -1,
+ MODE_CLIENT,
+ NTP_VERSION,
+ 0,
+ 0,
+ FLAG_IBURST,
+ 0,
+ 0,
+ NULL);
+ } else {
+ /* we have a hostname to resolve */
+# ifdef WORKER
+ ctx = emalloc_zero(sizeof(*ctx));
+ ctx->family = AF_UNSPEC;
+ ctx->host_mode = T_Server;
+ ctx->hmode = MODE_CLIENT;
+ ctx->version = NTP_VERSION;
+ ctx->flags = FLAG_IBURST;
+
+ ZERO(hints);
+ hints.ai_family = (u_short)ctx->family;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_protocol = IPPROTO_UDP;
+
+ getaddrinfo_sometime_ex(*cmdline_servers,
+ "ntp", &hints,
+ INITIAL_DNS_RETRY,
+ &peer_name_resolved,
+ (void *)ctx, DNSFLAGS);
+# else /* !WORKER follows */
+ msyslog(LOG_ERR,
+ "hostname %s can not be used, please use IP address instead.",
+ curr_peer->addr->address);
+# endif
+ }
+ }
+
+ /* add associations from the configuration file */
+ curr_peer = HEAD_PFIFO(ptree->peers);
+ for (; curr_peer != NULL; curr_peer = curr_peer->link) {
+ ZERO_SOCK(&peeraddr);
+ /* Find the correct host-mode */
+ hmode = get_correct_host_mode(curr_peer->host_mode);
+ INSIST(hmode != 0);
+
+ if (T_Pool == curr_peer->host_mode) {
+ AF(&peeraddr) = curr_peer->addr->type;
+ peer_config(
+ &peeraddr,
+ curr_peer->addr->address,
+ NULL,
+ -1,
+ hmode,
+ curr_peer->peerversion,
+ curr_peer->minpoll,
+ curr_peer->maxpoll,
+ peerflag_bits(curr_peer),
+ curr_peer->ttl,
+ curr_peer->peerkey,
+ curr_peer->group);
+ /*
+ * If we have a numeric address, we can safely
+ * proceed in the mainline with it. Otherwise, hand
+ * the hostname off to the blocking child.
+ */
+ } else if (is_ip_address(curr_peer->addr->address,
+ curr_peer->addr->type, &peeraddr)) {
+
+ SET_PORT(&peeraddr, NTP_PORT);
+ if (is_sane_resolved_address(&peeraddr,
+ curr_peer->host_mode))
+ peer_config(
+ &peeraddr,
+ NULL,
+ NULL,
+ -1,
+ hmode,
+ curr_peer->peerversion,
+ curr_peer->minpoll,
+ curr_peer->maxpoll,
+ peerflag_bits(curr_peer),
+ curr_peer->ttl,
+ curr_peer->peerkey,
+ curr_peer->group);
+ } else {
+ /* we have a hostname to resolve */
+# ifdef WORKER
+ ctx = emalloc_zero(sizeof(*ctx));
+ ctx->family = curr_peer->addr->type;
+ ctx->host_mode = curr_peer->host_mode;
+ ctx->hmode = hmode;
+ ctx->version = curr_peer->peerversion;
+ ctx->minpoll = curr_peer->minpoll;
+ ctx->maxpoll = curr_peer->maxpoll;
+ ctx->flags = peerflag_bits(curr_peer);
+ ctx->ttl = curr_peer->ttl;
+ ctx->keyid = curr_peer->peerkey;
+ ctx->group = curr_peer->group;
+
+ ZERO(hints);
+ hints.ai_family = ctx->family;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_protocol = IPPROTO_UDP;
+
+ getaddrinfo_sometime_ex(curr_peer->addr->address,
+ "ntp", &hints,
+ INITIAL_DNS_RETRY,
+ &peer_name_resolved, ctx,
+ DNSFLAGS);
+# else /* !WORKER follows */
+ msyslog(LOG_ERR,
+ "hostname %s can not be used, please use IP address instead.",
+ curr_peer->addr->address);
+# endif
+ }
+ }
+}
+#endif /* !SIM */
+
+/*
+ * peer_name_resolved()
+ *
+ * Callback invoked when config_peers()'s DNS lookup completes.
+ */
+#ifdef WORKER
+static void
+peer_name_resolved(
+ int rescode,
+ int gai_errno,
+ void * context,
+ const char * name,
+ const char * service,
+ const struct addrinfo * hints,
+ const struct addrinfo * res
+ )
+{
+ sockaddr_u peeraddr;
+ peer_resolved_ctx * ctx;
+ u_short af;
+ const char * fam_spec;
+
+ (void)gai_errno;
+ (void)service;
+ (void)hints;
+ ctx = context;
+
+ DPRINTF(1, ("peer_name_resolved(%s) rescode %d\n", name, rescode));
+
+ if (rescode) {
+ free(ctx);
+ msyslog(LOG_ERR,
+ "giving up resolving host %s: %s (%d)",
+ name, gai_strerror(rescode), rescode);
+ return;
+ }
+
+ /* Loop to configure a single association */
+ for (; res != NULL; res = res->ai_next) {
+ memcpy(&peeraddr, res->ai_addr, res->ai_addrlen);
+ if (is_sane_resolved_address(&peeraddr,
+ ctx->host_mode)) {
+ NLOG(NLOG_SYSINFO) {
+ af = ctx->family;
+ fam_spec = (AF_INET6 == af)
+ ? "(AAAA) "
+ : (AF_INET == af)
+ ? "(A) "
+ : "";
+ msyslog(LOG_INFO, "DNS %s %s-> %s",
+ name, fam_spec,
+ stoa(&peeraddr));
+ }
+ peer_config(
+ &peeraddr,
+ NULL,
+ NULL,
+ -1,
+ ctx->hmode,
+ ctx->version,
+ ctx->minpoll,
+ ctx->maxpoll,
+ ctx->flags,
+ ctx->ttl,
+ ctx->keyid,
+ ctx->group);
+ break;
+ }
+ }
+ free(ctx);
+}
+#endif /* WORKER */
+
+
+#ifdef FREE_CFG_T
+static void
+free_config_peers(
+ config_tree *ptree
+ )
+{
+ peer_node *curr_peer;
+
+ if (ptree->peers != NULL) {
+ for (;;) {
+ UNLINK_FIFO(curr_peer, *ptree->peers, link);
+ if (NULL == curr_peer)
+ break;
+ destroy_address_node(curr_peer->addr);
+ destroy_attr_val_fifo(curr_peer->peerflags);
+ free(curr_peer);
+ }
+ free(ptree->peers);
+ ptree->peers = NULL;
+ }
+}
+#endif /* FREE_CFG_T */
+
+
+#ifndef SIM
+static void
+config_unpeers(
+ config_tree *ptree
+ )
+{
+ sockaddr_u peeraddr;
+ struct addrinfo hints;
+ unpeer_node * curr_unpeer;
+ struct peer * p;
+ const char * name;
+ int rc;
+
+ curr_unpeer = HEAD_PFIFO(ptree->unpeers);
+ for (; curr_unpeer != NULL; curr_unpeer = curr_unpeer->link) {
+ /*
+ * If we have no address attached, assume we have to
+ * unpeer by AssocID.
+ */
+ if (!curr_unpeer->addr) {
+ p = findpeerbyassoc(curr_unpeer->assocID);
+ if (p != NULL) {
+ msyslog(LOG_NOTICE, "unpeered %s",
+ stoa(&p->srcadr));
+ peer_clear(p, "GONE");
+ unpeer(p);
+ }
+ continue;
+ }
+
+ ZERO(peeraddr);
+ AF(&peeraddr) = curr_unpeer->addr->type;
+ name = curr_unpeer->addr->address;
+ rc = getnetnum(name, &peeraddr, 0, t_UNK);
+ /* Do we have a numeric address? */
+ if (rc > 0) {
+ DPRINTF(1, ("unpeer: searching for %s\n",
+ stoa(&peeraddr)));
+ p = findexistingpeer(&peeraddr, NULL, NULL, -1, 0, NULL);
+ if (p != NULL) {
+ msyslog(LOG_NOTICE, "unpeered %s",
+ stoa(&peeraddr));
+ peer_clear(p, "GONE");
+ unpeer(p);
+ }
+ continue;
+ }
+ /*
+ * It's not a numeric IP address, it's a hostname.
+ * Check for associations with a matching hostname.
+ */
+ for (p = peer_list; p != NULL; p = p->p_link)
+ if (p->hostname != NULL)
+ if (!strcasecmp(p->hostname, name))
+ break;
+ if (p != NULL) {
+ msyslog(LOG_NOTICE, "unpeered %s", name);
+ peer_clear(p, "GONE");
+ unpeer(p);
+ }
+ /* Resolve the hostname to address(es). */
+# ifdef WORKER
+ ZERO(hints);
+ hints.ai_family = curr_unpeer->addr->type;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_protocol = IPPROTO_UDP;
+ getaddrinfo_sometime(name, "ntp", &hints,
+ INITIAL_DNS_RETRY,
+ &unpeer_name_resolved, NULL);
+# else /* !WORKER follows */
+ msyslog(LOG_ERR,
+ "hostname %s can not be used, please use IP address instead.",
+ name);
+# endif
+ }
+}
+#endif /* !SIM */
+
+
+/*
+ * unpeer_name_resolved()
+ *
+ * Callback invoked when config_unpeers()'s DNS lookup completes.
+ */
+#ifdef WORKER
+static void
+unpeer_name_resolved(
+ int rescode,
+ int gai_errno,
+ void * context,
+ const char * name,
+ const char * service,
+ const struct addrinfo * hints,
+ const struct addrinfo * res
+ )
+{
+ sockaddr_u peeraddr;
+ struct peer * peer;
+ u_short af;
+ const char * fam_spec;
+
+ (void)context;
+ (void)hints;
+ DPRINTF(1, ("unpeer_name_resolved(%s) rescode %d\n", name, rescode));
+
+ if (rescode) {
+ msyslog(LOG_ERR, "giving up resolving unpeer %s: %s (%d)",
+ name, gai_strerror(rescode), rescode);
+ return;
+ }
+ /*
+ * Loop through the addresses found
+ */
+ for (; res != NULL; res = res->ai_next) {
+ INSIST(res->ai_addrlen <= sizeof(peeraddr));
+ memcpy(&peeraddr, res->ai_addr, res->ai_addrlen);
+ DPRINTF(1, ("unpeer: searching for peer %s\n",
+ stoa(&peeraddr)));
+ peer = findexistingpeer(&peeraddr, NULL, NULL, -1, 0, NULL);
+ if (peer != NULL) {
+ af = AF(&peeraddr);
+ fam_spec = (AF_INET6 == af)
+ ? "(AAAA) "
+ : (AF_INET == af)
+ ? "(A) "
+ : "";
+ msyslog(LOG_NOTICE, "unpeered %s %s-> %s", name,
+ fam_spec, stoa(&peeraddr));
+ peer_clear(peer, "GONE");
+ unpeer(peer);
+ }
+ }
+}
+#endif /* WORKER */
+
+
+#ifdef FREE_CFG_T
+static void
+free_config_unpeers(
+ config_tree *ptree
+ )
+{
+ unpeer_node *curr_unpeer;
+
+ if (ptree->unpeers != NULL) {
+ for (;;) {
+ UNLINK_FIFO(curr_unpeer, *ptree->unpeers, link);
+ if (NULL == curr_unpeer)
+ break;
+ destroy_address_node(curr_unpeer->addr);
+ free(curr_unpeer);
+ }
+ free(ptree->unpeers);
+ }
+}
+#endif /* FREE_CFG_T */
+
+
+#ifndef SIM
+static void
+config_reset_counters(
+ config_tree *ptree
+ )
+{
+ int_node *counter_set;
+
+ for (counter_set = HEAD_PFIFO(ptree->reset_counters);
+ counter_set != NULL;
+ counter_set = counter_set->link) {
+ switch (counter_set->i) {
+ default:
+ DPRINTF(1, ("config_reset_counters %s (%d) invalid\n",
+ keyword(counter_set->i), counter_set->i));
+ break;
+
+ case T_Allpeers:
+ peer_all_reset();
+ break;
+
+ case T_Auth:
+ reset_auth_stats();
+ break;
+
+ case T_Ctl:
+ ctl_clr_stats();
+ break;
+
+ case T_Io:
+ io_clr_stats();
+ break;
+
+ case T_Mem:
+ peer_clr_stats();
+ break;
+
+ case T_Sys:
+ proto_clr_stats();
+ break;
+
+ case T_Timer:
+ timer_clr_stats();
+ break;
+ }
+ }
+}
+#endif /* !SIM */
+
+
+#ifdef FREE_CFG_T
+static void
+free_config_reset_counters(
+ config_tree *ptree
+ )
+{
+ FREE_INT_FIFO(ptree->reset_counters);
+}
+#endif /* FREE_CFG_T */
+
+
+#ifdef SIM
+static void
+config_sim(
+ config_tree *ptree
+ )
+{
+ int i;
+ server_info *serv_info;
+ attr_val *init_stmt;
+ sim_node *sim_n;
+
+ /* Check if a simulate block was found in the configuration code.
+ * If not, return an error and exit
+ */
+ sim_n = HEAD_PFIFO(ptree->sim_details);
+ if (NULL == sim_n) {
+ fprintf(stderr, "ERROR!! I couldn't find a \"simulate\" block for configuring the simulator.\n");
+ fprintf(stderr, "\tCheck your configuration file.\n");
+ exit(1);
+ }
+
+ /* Process the initialization statements
+ * -------------------------------------
+ */
+ init_stmt = HEAD_PFIFO(sim_n->init_opts);
+ for (; init_stmt != NULL; init_stmt = init_stmt->link) {
+ switch(init_stmt->attr) {
+
+ case T_Beep_Delay:
+ simulation.beep_delay = init_stmt->value.d;
+ break;
+
+ case T_Sim_Duration:
+ simulation.end_time = init_stmt->value.d;
+ break;
+
+ default:
+ fprintf(stderr,
+ "Unknown simulator init token %d\n",
+ init_stmt->attr);
+ exit(1);
+ }
+ }
+
+ /* Process the server list
+ * -----------------------
+ */
+ simulation.num_of_servers = 0;
+ serv_info = HEAD_PFIFO(sim_n->servers);
+ for (; serv_info != NULL; serv_info = serv_info->link)
+ simulation.num_of_servers++;
+ simulation.servers = eallocarray(simulation.num_of_servers,
+ sizeof(simulation.servers[0]));
+
+ i = 0;
+ serv_info = HEAD_PFIFO(sim_n->servers);
+ for (; serv_info != NULL; serv_info = serv_info->link) {
+ if (NULL == serv_info) {
+ fprintf(stderr, "Simulator server list is corrupt\n");
+ exit(1);
+ } else {
+ simulation.servers[i] = *serv_info;
+ simulation.servers[i].link = NULL;
+ i++;
+ }
+ }
+
+ printf("Creating server associations\n");
+ create_server_associations();
+ fprintf(stderr,"\tServer associations successfully created!!\n");
+}
+
+
+#ifdef FREE_CFG_T
+static void
+free_config_sim(
+ config_tree *ptree
+ )
+{
+ sim_node *sim_n;
+ server_info *serv_n;
+ script_info *script_n;
+
+ if (NULL == ptree->sim_details)
+ return;
+ sim_n = HEAD_PFIFO(ptree->sim_details);
+ free(ptree->sim_details);
+ ptree->sim_details = NULL;
+ if (NULL == sim_n)
+ return;
+
+ FREE_ATTR_VAL_FIFO(sim_n->init_opts);
+ for (;;) {
+ UNLINK_FIFO(serv_n, *sim_n->servers, link);
+ if (NULL == serv_n)
+ break;
+ free(serv_n->curr_script);
+ if (serv_n->script != NULL) {
+ for (;;) {
+ UNLINK_FIFO(script_n, *serv_n->script,
+ link);
+ if (script_n == NULL)
+ break;
+ free(script_n);
+ }
+ free(serv_n->script);
+ }
+ free(serv_n);
+ }
+ free(sim_n);
+}
+#endif /* FREE_CFG_T */
+#endif /* SIM */
+
+
+/* Define two different config functions. One for the daemon and the other for
+ * the simulator. The simulator ignores a lot of the standard ntpd configuration
+ * options
+ */
+#ifndef SIM
+static void
+config_ntpd(
+ config_tree *ptree,
+ int/*BOOL*/ input_from_files
+ )
+{
+ /* [Bug 3435] check and esure clock sanity if configured from
+ * file and clock sanity parameters (-> basedate) are given. Do
+ * this ASAP, so we don't disturb the closed loop controller.
+ */
+ if (input_from_files) {
+ if (config_tos_clock(ptree))
+ clamp_systime();
+ }
+
+ config_nic_rules(ptree, input_from_files);
+ config_monitor(ptree);
+ config_auth(ptree);
+ config_tos(ptree);
+ config_access(ptree);
+ config_tinker(ptree);
+ config_rlimit(ptree);
+ config_system_opts(ptree);
+ config_logconfig(ptree);
+ config_phone(ptree);
+ config_mdnstries(ptree);
+ config_setvar(ptree);
+ config_ttl(ptree);
+ config_vars(ptree);
+
+ io_open_sockets(); /* [bug 2837] dep. on config_vars() */
+
+ config_trap(ptree); /* [bug 2923] dep. on io_open_sockets() */
+ config_other_modes(ptree);
+ config_peers(ptree);
+ config_unpeers(ptree);
+ config_fudge(ptree);
+ config_reset_counters(ptree);
+
+#ifdef DEBUG
+ if (debug > 1) {
+ dump_restricts();
+ }
+#endif
+
+#ifdef TEST_BLOCKING_WORKER
+ {
+ struct addrinfo hints;
+
+ ZERO(hints);
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+ getaddrinfo_sometime("www.cnn.com", "ntp", &hints,
+ INITIAL_DNS_RETRY,
+ gai_test_callback, (void *)1);
+ hints.ai_family = AF_INET6;
+ getaddrinfo_sometime("ipv6.google.com", "ntp", &hints,
+ INITIAL_DNS_RETRY,
+ gai_test_callback, (void *)0x600);
+ }
+#endif
+}
+#endif /* !SIM */
+
+
+#ifdef SIM
+static void
+config_ntpdsim(
+ config_tree *ptree
+ )
+{
+ printf("Configuring Simulator...\n");
+ printf("Some ntpd-specific commands in the configuration file will be ignored.\n");
+
+ config_tos(ptree);
+ config_monitor(ptree);
+ config_tinker(ptree);
+ if (0)
+ config_rlimit(ptree); /* not needed for the simulator */
+ config_system_opts(ptree);
+ config_logconfig(ptree);
+ config_vars(ptree);
+ config_sim(ptree);
+}
+#endif /* SIM */
+
+
+/*
+ * config_remotely() - implements ntpd side of ntpq :config
+ */
+void
+config_remotely(
+ sockaddr_u * remote_addr
+ )
+{
+ char origin[128];
+
+ snprintf(origin, sizeof(origin), "remote config from %s",
+ stoa(remote_addr));
+ lex_init_stack(origin, NULL); /* no checking needed... */
+ init_syntax_tree(&cfgt);
+ yyparse();
+ lex_drop_stack();
+
+ cfgt.source.attr = CONF_SOURCE_NTPQ;
+ cfgt.timestamp = time(NULL);
+ cfgt.source.value.s = estrdup(stoa(remote_addr));
+
+ DPRINTF(1, ("Finished Parsing!!\n"));
+
+ save_and_apply_config_tree(FALSE);
+}
+
+
+/*
+ * getconfig() - process startup configuration file e.g /etc/ntp.conf
+ */
+void
+getconfig(
+ int argc,
+ char ** argv
+ )
+{
+ char line[256];
+
+#ifdef DEBUG
+ atexit(free_all_config_trees);
+#endif
+#ifndef SYS_WINNT
+ config_file = CONFIG_FILE;
+#else
+ temp = CONFIG_FILE;
+ if (!ExpandEnvironmentStringsA(temp, config_file_storage,
+ sizeof(config_file_storage))) {
+ msyslog(LOG_ERR, "ExpandEnvironmentStrings CONFIG_FILE failed: %m");
+ exit(1);
+ }
+ config_file = config_file_storage;
+
+ temp = ALT_CONFIG_FILE;
+ if (!ExpandEnvironmentStringsA(temp, alt_config_file_storage,
+ sizeof(alt_config_file_storage))) {
+ msyslog(LOG_ERR, "ExpandEnvironmentStrings ALT_CONFIG_FILE failed: %m");
+ exit(1);
+ }
+ alt_config_file = alt_config_file_storage;
+#endif /* SYS_WINNT */
+
+ /*
+ * install a non default variable with this daemon version
+ */
+ snprintf(line, sizeof(line), "daemon_version=\"%s\"", Version);
+ set_sys_var(line, strlen(line) + 1, RO);
+
+ /*
+ * Set up for the first time step to install a variable showing
+ * which syscall is being used to step.
+ */
+ set_tod_using = &ntpd_set_tod_using;
+
+ getCmdOpts(argc, argv);
+ init_syntax_tree(&cfgt);
+ if (
+ !lex_init_stack(FindConfig(config_file), "r")
+#ifdef HAVE_NETINFO
+ /* If there is no config_file, try NetInfo. */
+ && check_netinfo && !(config_netinfo = get_netinfo_config())
+#endif /* HAVE_NETINFO */
+ ) {
+ msyslog(LOG_INFO, "getconfig: Couldn't open <%s>: %m", FindConfig(config_file));
+#ifndef SYS_WINNT
+ io_open_sockets();
+
+ return;
+#else
+ /* Under WinNT try alternate_config_file name, first NTP.CONF, then NTP.INI */
+
+ if (!lex_init_stack(FindConfig(alt_config_file), "r")) {
+ /*
+ * Broadcast clients can sometimes run without
+ * a configuration file.
+ */
+ msyslog(LOG_INFO, "getconfig: Couldn't open <%s>: %m", FindConfig(alt_config_file));
+ io_open_sockets();
+
+ return;
+ }
+ cfgt.source.value.s = estrdup(alt_config_file);
+#endif /* SYS_WINNT */
+ } else
+ cfgt.source.value.s = estrdup(config_file);
+
+
+ /*** BULK OF THE PARSER ***/
+#ifdef DEBUG
+ yydebug = !!(debug >= 5);
+#endif
+ yyparse();
+ lex_drop_stack();
+
+ DPRINTF(1, ("Finished Parsing!!\n"));
+
+ cfgt.source.attr = CONF_SOURCE_FILE;
+ cfgt.timestamp = time(NULL);
+
+ save_and_apply_config_tree(TRUE);
+
+#ifdef HAVE_NETINFO
+ if (config_netinfo)
+ free_netinfo_config(config_netinfo);
+#endif /* HAVE_NETINFO */
+}
+
+
+void
+save_and_apply_config_tree(int/*BOOL*/ input_from_file)
+{
+ config_tree *ptree;
+#ifndef SAVECONFIG
+ config_tree *punlinked;
+#endif
+
+ /*
+ * Keep all the configuration trees applied since startup in
+ * a list that can be used to dump the configuration back to
+ * a text file.
+ */
+ ptree = emalloc(sizeof(*ptree));
+ memcpy(ptree, &cfgt, sizeof(*ptree));
+ ZERO(cfgt);
+
+ LINK_TAIL_SLIST(cfg_tree_history, ptree, link, config_tree);
+
+#ifdef SAVECONFIG
+ if (HAVE_OPT( SAVECONFIGQUIT )) {
+ FILE *dumpfile;
+ int err;
+ int dumpfailed;
+
+ dumpfile = fopen(OPT_ARG( SAVECONFIGQUIT ), "w");
+ if (NULL == dumpfile) {
+ err = errno;
+ mfprintf(stderr,
+ "can not create save file %s, error %d %m\n",
+ OPT_ARG(SAVECONFIGQUIT), err);
+ exit(err);
+ }
+
+ dumpfailed = dump_all_config_trees(dumpfile, 0);
+ if (dumpfailed)
+ fprintf(stderr,
+ "--saveconfigquit %s error %d\n",
+ OPT_ARG( SAVECONFIGQUIT ),
+ dumpfailed);
+ else
+ fprintf(stderr,
+ "configuration saved to %s\n",
+ OPT_ARG( SAVECONFIGQUIT ));
+
+ exit(dumpfailed);
+ }
+#endif /* SAVECONFIG */
+
+ /* The actual configuration done depends on whether we are configuring the
+ * simulator or the daemon. Perform a check and call the appropriate
+ * function as needed.
+ */
+
+#ifndef SIM
+ config_ntpd(ptree, input_from_file);
+#else
+ config_ntpdsim(ptree);
+#endif
+
+ /*
+ * With configure --disable-saveconfig, there's no use keeping
+ * the config tree around after application, so free it.
+ */
+#ifndef SAVECONFIG
+ UNLINK_SLIST(punlinked, cfg_tree_history, ptree, link,
+ config_tree);
+ INSIST(punlinked == ptree);
+ free_config_tree(ptree);
+#endif
+}
+
+/* Hack to disambiguate 'server' statements for refclocks and network peers.
+ * Please note the qualification 'hack'. It's just that.
+ */
+static int/*BOOL*/
+is_refclk_addr(
+ const address_node * addr
+ )
+{
+ return addr && addr->address && !strncmp(addr->address, "127.127.", 8);
+}
+
+static void
+ntpd_set_tod_using(
+ const char *which
+ )
+{
+ char line[128];
+
+ snprintf(line, sizeof(line), "settimeofday=\"%s\"", which);
+ set_sys_var(line, strlen(line) + 1, RO);
+}
+
+
+static char *
+normal_dtoa(
+ double d
+ )
+{
+ char * buf;
+ char * pch_e;
+ char * pch_nz;
+
+ LIB_GETBUF(buf);
+ snprintf(buf, LIB_BUFLENGTH, "%g", d);
+
+ /* use lowercase 'e', strip any leading zeroes in exponent */
+ pch_e = strchr(buf, 'e');
+ if (NULL == pch_e) {
+ pch_e = strchr(buf, 'E');
+ if (NULL == pch_e)
+ return buf;
+ *pch_e = 'e';
+ }
+ pch_e++;
+ if ('-' == *pch_e)
+ pch_e++;
+ pch_nz = pch_e;
+ while ('0' == *pch_nz)
+ pch_nz++;
+ if (pch_nz == pch_e)
+ return buf;
+ strlcpy(pch_e, pch_nz, LIB_BUFLENGTH - (pch_e - buf));
+
+ return buf;
+}
+
+
+/* FUNCTIONS COPIED FROM THE OLDER ntp_config.c
+ * --------------------------------------------
+ */
+
+
+/*
+ * get_pfxmatch - find value for prefixmatch
+ * and update char * accordingly
+ */
+static u_int32
+get_pfxmatch(
+ const char ** pstr,
+ struct masks * m
+ )
+{
+ while (m->name != NULL) {
+ if (strncmp(*pstr, m->name, strlen(m->name)) == 0) {
+ *pstr += strlen(m->name);
+ return m->mask;
+ } else {
+ m++;
+ }
+ }
+ return 0;
+}
+
+/*
+ * get_match - find logmask value
+ */
+static u_int32
+get_match(
+ const char * str,
+ struct masks * m
+ )
+{
+ while (m->name != NULL) {
+ if (strcmp(str, m->name) == 0)
+ return m->mask;
+ else
+ m++;
+ }
+ return 0;
+}
+
+/*
+ * get_logmask - build bitmask for ntp_syslogmask
+ */
+static u_int32
+get_logmask(
+ const char * str
+ )
+{
+ const char * t;
+ u_int32 offset;
+ u_int32 mask;
+
+ mask = get_match(str, logcfg_noclass_items);
+ if (mask != 0)
+ return mask;
+
+ t = str;
+ offset = get_pfxmatch(&t, logcfg_class);
+ mask = get_match(t, logcfg_class_items);
+
+ if (mask)
+ return mask << offset;
+ else
+ msyslog(LOG_ERR, "logconfig: '%s' not recognized - ignored",
+ str);
+
+ return 0;
+}
+
+
+#ifdef HAVE_NETINFO
+
+/*
+ * get_netinfo_config - find the nearest NetInfo domain with an ntp
+ * configuration and initialize the configuration state.
+ */
+static struct netinfo_config_state *
+get_netinfo_config(void)
+{
+ ni_status status;
+ void *domain;
+ ni_id config_dir;
+ struct netinfo_config_state *config;
+
+ if (ni_open(NULL, ".", &domain) != NI_OK) return NULL;
+
+ while ((status = ni_pathsearch(domain, &config_dir, NETINFO_CONFIG_DIR)) == NI_NODIR) {
+ void *next_domain;
+ if (ni_open(domain, "..", &next_domain) != NI_OK) {
+ ni_free(next_domain);
+ break;
+ }
+ ni_free(domain);
+ domain = next_domain;
+ }
+ if (status != NI_OK) {
+ ni_free(domain);
+ return NULL;
+ }
+
+ config = emalloc(sizeof(*config));
+ config->domain = domain;
+ config->config_dir = config_dir;
+ config->prop_index = 0;
+ config->val_index = 0;
+ config->val_list = NULL;
+
+ return config;
+}
+
+
+/*
+ * free_netinfo_config - release NetInfo configuration state
+ */
+static void
+free_netinfo_config(
+ struct netinfo_config_state *config
+ )
+{
+ ni_free(config->domain);
+ free(config);
+}
+
+
+/*
+ * gettokens_netinfo - return tokens from NetInfo
+ */
+static int
+gettokens_netinfo (
+ struct netinfo_config_state *config,
+ char **tokenlist,
+ int *ntokens
+ )
+{
+ int prop_index = config->prop_index;
+ int val_index = config->val_index;
+ char **val_list = config->val_list;
+
+ /*
+ * Iterate through each keyword and look for a property that matches it.
+ */
+ again:
+ if (!val_list) {
+ for (; prop_index < COUNTOF(keywords); prop_index++)
+ {
+ ni_namelist namelist;
+ struct keyword current_prop = keywords[prop_index];
+ ni_index index;
+
+ /*
+ * For each value associated in the property, we're going to return
+ * a separate line. We squirrel away the values in the config state
+ * so the next time through, we don't need to do this lookup.
+ */
+ NI_INIT(&namelist);
+ if (NI_OK == ni_lookupprop(config->domain,
+ &config->config_dir, current_prop.text,
+ &namelist)) {
+
+ /* Found the property, but it has no values */
+ if (namelist.ni_namelist_len == 0) continue;
+
+ config->val_list =
+ eallocarray(
+ (namelist.ni_namelist_len + 1),
+ sizeof(char*));
+ val_list = config->val_list;
+
+ for (index = 0;
+ index < namelist.ni_namelist_len;
+ index++) {
+ char *value;
+
+ value = namelist.ni_namelist_val[index];
+ val_list[index] = estrdup(value);
+ }
+ val_list[index] = NULL;
+
+ break;
+ }
+ ni_namelist_free(&namelist);
+ }
+ config->prop_index = prop_index;
+ }
+
+ /* No list; we're done here. */
+ if (!val_list)
+ return CONFIG_UNKNOWN;
+
+ /*
+ * We have a list of values for the current property.
+ * Iterate through them and return each in order.
+ */
+ if (val_list[val_index]) {
+ int ntok = 1;
+ int quoted = 0;
+ char *tokens = val_list[val_index];
+
+ msyslog(LOG_INFO, "%s %s", keywords[prop_index].text, val_list[val_index]);
+
+ (const char*)tokenlist[0] = keywords[prop_index].text;
+ for (ntok = 1; ntok < MAXTOKENS; ntok++) {
+ tokenlist[ntok] = tokens;
+ while (!ISEOL(*tokens) && (!ISSPACE(*tokens) || quoted))
+ quoted ^= (*tokens++ == '"');
+
+ if (ISEOL(*tokens)) {
+ *tokens = '\0';
+ break;
+ } else { /* must be space */
+ *tokens++ = '\0';
+ while (ISSPACE(*tokens))
+ tokens++;
+ if (ISEOL(*tokens))
+ break;
+ }
+ }
+
+ if (ntok == MAXTOKENS) {
+ /* HMS: chomp it to lose the EOL? */
+ msyslog(LOG_ERR,
+ "gettokens_netinfo: too many tokens. Ignoring: %s",
+ tokens);
+ } else {
+ *ntokens = ntok + 1;
+ }
+
+ config->val_index++; /* HMS: Should this be in the 'else'? */
+
+ return keywords[prop_index].keytype;
+ }
+
+ /* We're done with the current property. */
+ prop_index = ++config->prop_index;
+
+ /* Free val_list and reset counters. */
+ for (val_index = 0; val_list[val_index]; val_index++)
+ free(val_list[val_index]);
+ free(val_list);
+ val_list = config->val_list = NULL;
+ val_index = config->val_index = 0;
+
+ goto again;
+}
+#endif /* HAVE_NETINFO */
+
+
+/*
+ * getnetnum - return a net number (this is crude, but careful)
+ *
+ * returns 1 for success, and mysteriously, 0 for most failures, and
+ * -1 if the address found is IPv6 and we believe IPv6 isn't working.
+ */
+#ifndef SIM
+static int
+getnetnum(
+ const char *num,
+ sockaddr_u *addr,
+ int complain,
+ enum gnn_type a_type /* ignored */
+ )
+{
+ REQUIRE(AF_UNSPEC == AF(addr) ||
+ AF_INET == AF(addr) ||
+ AF_INET6 == AF(addr));
+
+ if (!is_ip_address(num, AF(addr), addr))
+ return 0;
+
+ if (IS_IPV6(addr) && !ipv6_works)
+ return -1;
+
+# ifdef ISC_PLATFORM_HAVESALEN
+ addr->sa.sa_len = SIZEOF_SOCKADDR(AF(addr));
+# endif
+ SET_PORT(addr, NTP_PORT);
+
+ DPRINTF(2, ("getnetnum given %s, got %s\n", num, stoa(addr)));
+
+ return 1;
+}
+#endif /* !SIM */
+
+#if defined(HAVE_SETRLIMIT)
+void
+ntp_rlimit(
+ int rl_what,
+ rlim_t rl_value,
+ int rl_scale,
+ const char * rl_sstr
+ )
+{
+ struct rlimit rl;
+
+ switch (rl_what) {
+# ifdef RLIMIT_MEMLOCK
+ case RLIMIT_MEMLOCK:
+ if (HAVE_OPT( SAVECONFIGQUIT )) {
+ break;
+ }
+ /*
+ * The default RLIMIT_MEMLOCK is very low on Linux systems.
+ * Unless we increase this limit malloc calls are likely to
+ * fail if we drop root privilege. To be useful the value
+ * has to be larger than the largest ntpd resident set size.
+ */
+ DPRINTF(2, ("ntp_rlimit: MEMLOCK: %d %s\n",
+ (int)(rl_value / rl_scale), rl_sstr));
+ rl.rlim_cur = rl.rlim_max = rl_value;
+ if (setrlimit(RLIMIT_MEMLOCK, &rl) == -1)
+ msyslog(LOG_ERR, "Cannot set RLIMIT_MEMLOCK: %m");
+ break;
+# endif /* RLIMIT_MEMLOCK */
+
+# ifdef RLIMIT_NOFILE
+ case RLIMIT_NOFILE:
+ /*
+ * For large systems the default file descriptor limit may
+ * not be enough.
+ */
+ DPRINTF(2, ("ntp_rlimit: NOFILE: %d %s\n",
+ (int)(rl_value / rl_scale), rl_sstr));
+ rl.rlim_cur = rl.rlim_max = rl_value;
+ if (setrlimit(RLIMIT_NOFILE, &rl) == -1)
+ msyslog(LOG_ERR, "Cannot set RLIMIT_NOFILE: %m");
+ break;
+# endif /* RLIMIT_NOFILE */
+
+# ifdef RLIMIT_STACK
+ case RLIMIT_STACK:
+ /*
+ * Provide a way to set the stack limit to something
+ * smaller, so that we don't lock a lot of unused
+ * stack memory.
+ */
+ DPRINTF(2, ("ntp_rlimit: STACK: %d %s pages\n",
+ (int)(rl_value / rl_scale), rl_sstr));
+ if (-1 == getrlimit(RLIMIT_STACK, &rl)) {
+ msyslog(LOG_ERR, "getrlimit(RLIMIT_STACK) failed: %m");
+ } else {
+ if (rl_value > rl.rlim_max) {
+ msyslog(LOG_WARNING,
+ "ntp_rlimit: using maximum allowed stack limit %lu instead of %lu.",
+ (u_long)rl.rlim_max,
+ (u_long)rl_value);
+ rl_value = rl.rlim_max;
+ }
+ rl.rlim_cur = rl_value;
+ if (-1 == setrlimit(RLIMIT_STACK, &rl)) {
+ msyslog(LOG_ERR,
+ "ntp_rlimit: Cannot set RLIMIT_STACK: %m");
+ }
+ }
+ break;
+# endif /* RLIMIT_STACK */
+
+ default:
+ fatal_error("ntp_rlimit: unexpected RLIMIT case: %d", rl_what);
+ }
+}
+#endif /* HAVE_SETRLIMIT */
+
+
+char *
+build_iflags(u_int32 iflags)
+{
+ static char ifs[1024];
+
+ ifs[0] = '\0';
+
+ if (iflags & INT_UP) {
+ iflags &= ~INT_UP;
+ appendstr(ifs, sizeof ifs, "up");
+ }
+
+ if (iflags & INT_PPP) {
+ iflags &= ~INT_PPP;
+ appendstr(ifs, sizeof ifs, "ppp");
+ }
+
+ if (iflags & INT_LOOPBACK) {
+ iflags &= ~INT_LOOPBACK;
+ appendstr(ifs, sizeof ifs, "loopback");
+ }
+
+ if (iflags & INT_BROADCAST) {
+ iflags &= ~INT_BROADCAST;
+ appendstr(ifs, sizeof ifs, "broadcast");
+ }
+
+ if (iflags & INT_MULTICAST) {
+ iflags &= ~INT_MULTICAST;
+ appendstr(ifs, sizeof ifs, "multicast");
+ }
+
+ if (iflags & INT_BCASTOPEN) {
+ iflags &= ~INT_BCASTOPEN;
+ appendstr(ifs, sizeof ifs, "bcastopen");
+ }
+
+ if (iflags & INT_MCASTOPEN) {
+ iflags &= ~INT_MCASTOPEN;
+ appendstr(ifs, sizeof ifs, "mcastopen");
+ }
+
+ if (iflags & INT_WILDCARD) {
+ iflags &= ~INT_WILDCARD;
+ appendstr(ifs, sizeof ifs, "wildcard");
+ }
+
+ if (iflags & INT_MCASTIF) {
+ iflags &= ~INT_MCASTIF;
+ appendstr(ifs, sizeof ifs, "MCASTif");
+ }
+
+ if (iflags & INT_PRIVACY) {
+ iflags &= ~INT_PRIVACY;
+ appendstr(ifs, sizeof ifs, "IPv6privacy");
+ }
+
+ if (iflags & INT_BCASTXMIT) {
+ iflags &= ~INT_BCASTXMIT;
+ appendstr(ifs, sizeof ifs, "bcastxmit");
+ }
+
+ if (iflags) {
+ char string[10];
+
+ snprintf(string, sizeof string, "%0x", iflags);
+ appendstr(ifs, sizeof ifs, string);
+ }
+
+ return ifs;
+}
+
+
+char *
+build_mflags(u_short mflags)
+{
+ static char mfs[1024];
+
+ mfs[0] = '\0';
+
+ if (mflags & RESM_NTPONLY) {
+ mflags &= ~RESM_NTPONLY;
+ appendstr(mfs, sizeof mfs, "ntponly");
+ }
+
+ if (mflags & RESM_SOURCE) {
+ mflags &= ~RESM_SOURCE;
+ appendstr(mfs, sizeof mfs, "source");
+ }
+
+ if (mflags) {
+ char string[10];
+
+ snprintf(string, sizeof string, "%0x", mflags);
+ appendstr(mfs, sizeof mfs, string);
+ }
+
+ return mfs;
+}
+
+
+char *
+build_rflags(u_short rflags)
+{
+ static char rfs[1024];
+
+ rfs[0] = '\0';
+
+ if (rflags & RES_FLAKE) {
+ rflags &= ~RES_FLAKE;
+ appendstr(rfs, sizeof rfs, "flake");
+ }
+
+ if (rflags & RES_IGNORE) {
+ rflags &= ~RES_IGNORE;
+ appendstr(rfs, sizeof rfs, "ignore");
+ }
+
+ if (rflags & RES_KOD) {
+ rflags &= ~RES_KOD;
+ appendstr(rfs, sizeof rfs, "kod");
+ }
+
+ if (rflags & RES_MSSNTP) {
+ rflags &= ~RES_MSSNTP;
+ appendstr(rfs, sizeof rfs, "mssntp");
+ }
+
+ if (rflags & RES_LIMITED) {
+ rflags &= ~RES_LIMITED;
+ appendstr(rfs, sizeof rfs, "limited");
+ }
+
+ if (rflags & RES_LPTRAP) {
+ rflags &= ~RES_LPTRAP;
+ appendstr(rfs, sizeof rfs, "lptrap");
+ }
+
+ if (rflags & RES_NOMODIFY) {
+ rflags &= ~RES_NOMODIFY;
+ appendstr(rfs, sizeof rfs, "nomodify");
+ }
+
+ if (rflags & RES_NOMRULIST) {
+ rflags &= ~RES_NOMRULIST;
+ appendstr(rfs, sizeof rfs, "nomrulist");
+ }
+
+ if (rflags & RES_NOEPEER) {
+ rflags &= ~RES_NOEPEER;
+ appendstr(rfs, sizeof rfs, "noepeer");
+ }
+
+ if (rflags & RES_NOPEER) {
+ rflags &= ~RES_NOPEER;
+ appendstr(rfs, sizeof rfs, "nopeer");
+ }
+
+ if (rflags & RES_NOQUERY) {
+ rflags &= ~RES_NOQUERY;
+ appendstr(rfs, sizeof rfs, "noquery");
+ }
+
+ if (rflags & RES_DONTSERVE) {
+ rflags &= ~RES_DONTSERVE;
+ appendstr(rfs, sizeof rfs, "dontserve");
+ }
+
+ if (rflags & RES_NOTRAP) {
+ rflags &= ~RES_NOTRAP;
+ appendstr(rfs, sizeof rfs, "notrap");
+ }
+
+ if (rflags & RES_DONTTRUST) {
+ rflags &= ~RES_DONTTRUST;
+ appendstr(rfs, sizeof rfs, "notrust");
+ }
+
+ if (rflags & RES_VERSION) {
+ rflags &= ~RES_VERSION;
+ appendstr(rfs, sizeof rfs, "version");
+ }
+
+ if (rflags) {
+ char string[10];
+
+ snprintf(string, sizeof string, "%0x", rflags);
+ appendstr(rfs, sizeof rfs, string);
+ }
+
+ if ('\0' == rfs[0]) {
+ appendstr(rfs, sizeof rfs, "(none)");
+ }
+
+ return rfs;
+}
+
+
+static void
+appendstr(
+ char *string,
+ size_t s,
+ const char *new
+ )
+{
+ if (*string != '\0') {
+ (void)strlcat(string, ",", s);
+ }
+ (void)strlcat(string, new, s);
+
+ return;
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_control.c b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_control.c
new file mode 100644
index 0000000..813ae8a
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_control.c
@@ -0,0 +1,5297 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * ntp_control.c - respond to mode 6 control messages and send async
+ * traps. Provides service to ntpq and others.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+#include <signal.h>
+#include <sys/stat.h>
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#include <arpa/inet.h>
+
+#include "ntpd.h"
+#include "ntp_io.h"
+#include "ntp_refclock.h"
+#include "ntp_control.h"
+#include "ntp_unixtime.h"
+#include "ntp_stdlib.h"
+#include "ntp_config.h"
+#include "ntp_crypto.h"
+#include "ntp_assert.h"
+#include "ntp_leapsec.h"
+#include "ntp_md5.h" /* provides OpenSSL digest API */
+#include "lib_strbuf.h"
+#include <rc_cmdlength.h>
+#ifdef KERNEL_PLL
+# include "ntp_syscall.h"
+#endif
+
+/*
+ * Structure to hold request procedure information
+ */
+
+struct ctl_proc {
+ short control_code; /* defined request code */
+#define NO_REQUEST (-1)
+ u_short flags; /* flags word */
+ /* Only one flag. Authentication required or not. */
+#define NOAUTH 0
+#define AUTH 1
+ void (*handler) (struct recvbuf *, int); /* handle request */
+};
+
+
+/*
+ * Request processing routines
+ */
+static void ctl_error (u_char);
+#ifdef REFCLOCK
+static u_short ctlclkstatus (struct refclockstat *);
+#endif
+static void ctl_flushpkt (u_char);
+static void ctl_putdata (const char *, unsigned int, int);
+static void ctl_putstr (const char *, const char *, size_t);
+static void ctl_putdblf (const char *, int, int, double);
+#define ctl_putdbl(tag, d) ctl_putdblf(tag, 1, 3, d)
+#define ctl_putdbl6(tag, d) ctl_putdblf(tag, 1, 6, d)
+#define ctl_putsfp(tag, sfp) ctl_putdblf(tag, 0, -1, \
+ FPTOD(sfp))
+static void ctl_putuint (const char *, u_long);
+static void ctl_puthex (const char *, u_long);
+static void ctl_putint (const char *, long);
+static void ctl_putts (const char *, l_fp *);
+static void ctl_putadr (const char *, u_int32,
+ sockaddr_u *);
+static void ctl_putrefid (const char *, u_int32);
+static void ctl_putarray (const char *, double *, int);
+static void ctl_putsys (int);
+static void ctl_putpeer (int, struct peer *);
+static void ctl_putfs (const char *, tstamp_t);
+static void ctl_printf (const char *, ...) NTP_PRINTF(1, 2);
+#ifdef REFCLOCK
+static void ctl_putclock (int, struct refclockstat *, int);
+#endif /* REFCLOCK */
+static const struct ctl_var *ctl_getitem(const struct ctl_var *,
+ char **);
+static u_short count_var (const struct ctl_var *);
+static void control_unspec (struct recvbuf *, int);
+static void read_status (struct recvbuf *, int);
+static void read_sysvars (void);
+static void read_peervars (void);
+static void read_variables (struct recvbuf *, int);
+static void write_variables (struct recvbuf *, int);
+static void read_clockstatus(struct recvbuf *, int);
+static void write_clockstatus(struct recvbuf *, int);
+static void set_trap (struct recvbuf *, int);
+static void save_config (struct recvbuf *, int);
+static void configure (struct recvbuf *, int);
+static void send_mru_entry (mon_entry *, int);
+static void send_random_tag_value(int);
+static void read_mru_list (struct recvbuf *, int);
+static void send_ifstats_entry(endpt *, u_int);
+static void read_ifstats (struct recvbuf *);
+static void sockaddrs_from_restrict_u(sockaddr_u *, sockaddr_u *,
+ restrict_u *, int);
+static void send_restrict_entry(restrict_u *, int, u_int);
+static void send_restrict_list(restrict_u *, int, u_int *);
+static void read_addr_restrictions(struct recvbuf *);
+static void read_ordlist (struct recvbuf *, int);
+static u_int32 derive_nonce (sockaddr_u *, u_int32, u_int32);
+static void generate_nonce (struct recvbuf *, char *, size_t);
+static int validate_nonce (const char *, struct recvbuf *);
+static void req_nonce (struct recvbuf *, int);
+static void unset_trap (struct recvbuf *, int);
+static struct ctl_trap *ctlfindtrap(sockaddr_u *,
+ struct interface *);
+
+int/*BOOL*/ is_safe_filename(const char * name);
+
+static const struct ctl_proc control_codes[] = {
+ { CTL_OP_UNSPEC, NOAUTH, control_unspec },
+ { CTL_OP_READSTAT, NOAUTH, read_status },
+ { CTL_OP_READVAR, NOAUTH, read_variables },
+ { CTL_OP_WRITEVAR, AUTH, write_variables },
+ { CTL_OP_READCLOCK, NOAUTH, read_clockstatus },
+ { CTL_OP_WRITECLOCK, AUTH, write_clockstatus },
+ { CTL_OP_SETTRAP, AUTH, set_trap },
+ { CTL_OP_CONFIGURE, AUTH, configure },
+ { CTL_OP_SAVECONFIG, AUTH, save_config },
+ { CTL_OP_READ_MRU, NOAUTH, read_mru_list },
+ { CTL_OP_READ_ORDLIST_A, AUTH, read_ordlist },
+ { CTL_OP_REQ_NONCE, NOAUTH, req_nonce },
+ { CTL_OP_UNSETTRAP, AUTH, unset_trap },
+ { NO_REQUEST, 0, NULL }
+};
+
+/*
+ * System variables we understand
+ */
+#define CS_LEAP 1
+#define CS_STRATUM 2
+#define CS_PRECISION 3
+#define CS_ROOTDELAY 4
+#define CS_ROOTDISPERSION 5
+#define CS_REFID 6
+#define CS_REFTIME 7
+#define CS_POLL 8
+#define CS_PEERID 9
+#define CS_OFFSET 10
+#define CS_DRIFT 11
+#define CS_JITTER 12
+#define CS_ERROR 13
+#define CS_CLOCK 14
+#define CS_PROCESSOR 15
+#define CS_SYSTEM 16
+#define CS_VERSION 17
+#define CS_STABIL 18
+#define CS_VARLIST 19
+#define CS_TAI 20
+#define CS_LEAPTAB 21
+#define CS_LEAPEND 22
+#define CS_RATE 23
+#define CS_MRU_ENABLED 24
+#define CS_MRU_DEPTH 25
+#define CS_MRU_DEEPEST 26
+#define CS_MRU_MINDEPTH 27
+#define CS_MRU_MAXAGE 28
+#define CS_MRU_MAXDEPTH 29
+#define CS_MRU_MEM 30
+#define CS_MRU_MAXMEM 31
+#define CS_SS_UPTIME 32
+#define CS_SS_RESET 33
+#define CS_SS_RECEIVED 34
+#define CS_SS_THISVER 35
+#define CS_SS_OLDVER 36
+#define CS_SS_BADFORMAT 37
+#define CS_SS_BADAUTH 38
+#define CS_SS_DECLINED 39
+#define CS_SS_RESTRICTED 40
+#define CS_SS_LIMITED 41
+#define CS_SS_KODSENT 42
+#define CS_SS_PROCESSED 43
+#define CS_SS_LAMPORT 44
+#define CS_SS_TSROUNDING 45
+#define CS_PEERADR 46
+#define CS_PEERMODE 47
+#define CS_BCASTDELAY 48
+#define CS_AUTHDELAY 49
+#define CS_AUTHKEYS 50
+#define CS_AUTHFREEK 51
+#define CS_AUTHKLOOKUPS 52
+#define CS_AUTHKNOTFOUND 53
+#define CS_AUTHKUNCACHED 54
+#define CS_AUTHKEXPIRED 55
+#define CS_AUTHENCRYPTS 56
+#define CS_AUTHDECRYPTS 57
+#define CS_AUTHRESET 58
+#define CS_K_OFFSET 59
+#define CS_K_FREQ 60
+#define CS_K_MAXERR 61
+#define CS_K_ESTERR 62
+#define CS_K_STFLAGS 63
+#define CS_K_TIMECONST 64
+#define CS_K_PRECISION 65
+#define CS_K_FREQTOL 66
+#define CS_K_PPS_FREQ 67
+#define CS_K_PPS_STABIL 68
+#define CS_K_PPS_JITTER 69
+#define CS_K_PPS_CALIBDUR 70
+#define CS_K_PPS_CALIBS 71
+#define CS_K_PPS_CALIBERRS 72
+#define CS_K_PPS_JITEXC 73
+#define CS_K_PPS_STBEXC 74
+#define CS_KERN_FIRST CS_K_OFFSET
+#define CS_KERN_LAST CS_K_PPS_STBEXC
+#define CS_IOSTATS_RESET 75
+#define CS_TOTAL_RBUF 76
+#define CS_FREE_RBUF 77
+#define CS_USED_RBUF 78
+#define CS_RBUF_LOWATER 79
+#define CS_IO_DROPPED 80
+#define CS_IO_IGNORED 81
+#define CS_IO_RECEIVED 82
+#define CS_IO_SENT 83
+#define CS_IO_SENDFAILED 84
+#define CS_IO_WAKEUPS 85
+#define CS_IO_GOODWAKEUPS 86
+#define CS_TIMERSTATS_RESET 87
+#define CS_TIMER_OVERRUNS 88
+#define CS_TIMER_XMTS 89
+#define CS_FUZZ 90
+#define CS_WANDER_THRESH 91
+#define CS_LEAPSMEARINTV 92
+#define CS_LEAPSMEAROFFS 93
+#define CS_MAX_NOAUTOKEY CS_LEAPSMEAROFFS
+#ifdef AUTOKEY
+#define CS_FLAGS (1 + CS_MAX_NOAUTOKEY)
+#define CS_HOST (2 + CS_MAX_NOAUTOKEY)
+#define CS_PUBLIC (3 + CS_MAX_NOAUTOKEY)
+#define CS_CERTIF (4 + CS_MAX_NOAUTOKEY)
+#define CS_SIGNATURE (5 + CS_MAX_NOAUTOKEY)
+#define CS_REVTIME (6 + CS_MAX_NOAUTOKEY)
+#define CS_IDENT (7 + CS_MAX_NOAUTOKEY)
+#define CS_DIGEST (8 + CS_MAX_NOAUTOKEY)
+#define CS_MAXCODE CS_DIGEST
+#else /* !AUTOKEY follows */
+#define CS_MAXCODE CS_MAX_NOAUTOKEY
+#endif /* !AUTOKEY */
+
+/*
+ * Peer variables we understand
+ */
+#define CP_CONFIG 1
+#define CP_AUTHENABLE 2
+#define CP_AUTHENTIC 3
+#define CP_SRCADR 4
+#define CP_SRCPORT 5
+#define CP_DSTADR 6
+#define CP_DSTPORT 7
+#define CP_LEAP 8
+#define CP_HMODE 9
+#define CP_STRATUM 10
+#define CP_PPOLL 11
+#define CP_HPOLL 12
+#define CP_PRECISION 13
+#define CP_ROOTDELAY 14
+#define CP_ROOTDISPERSION 15
+#define CP_REFID 16
+#define CP_REFTIME 17
+#define CP_ORG 18
+#define CP_REC 19
+#define CP_XMT 20
+#define CP_REACH 21
+#define CP_UNREACH 22
+#define CP_TIMER 23
+#define CP_DELAY 24
+#define CP_OFFSET 25
+#define CP_JITTER 26
+#define CP_DISPERSION 27
+#define CP_KEYID 28
+#define CP_FILTDELAY 29
+#define CP_FILTOFFSET 30
+#define CP_PMODE 31
+#define CP_RECEIVED 32
+#define CP_SENT 33
+#define CP_FILTERROR 34
+#define CP_FLASH 35
+#define CP_TTL 36
+#define CP_VARLIST 37
+#define CP_IN 38
+#define CP_OUT 39
+#define CP_RATE 40
+#define CP_BIAS 41
+#define CP_SRCHOST 42
+#define CP_TIMEREC 43
+#define CP_TIMEREACH 44
+#define CP_BADAUTH 45
+#define CP_BOGUSORG 46
+#define CP_OLDPKT 47
+#define CP_SELDISP 48
+#define CP_SELBROKEN 49
+#define CP_CANDIDATE 50
+#define CP_MAX_NOAUTOKEY CP_CANDIDATE
+#ifdef AUTOKEY
+#define CP_FLAGS (1 + CP_MAX_NOAUTOKEY)
+#define CP_HOST (2 + CP_MAX_NOAUTOKEY)
+#define CP_VALID (3 + CP_MAX_NOAUTOKEY)
+#define CP_INITSEQ (4 + CP_MAX_NOAUTOKEY)
+#define CP_INITKEY (5 + CP_MAX_NOAUTOKEY)
+#define CP_INITTSP (6 + CP_MAX_NOAUTOKEY)
+#define CP_SIGNATURE (7 + CP_MAX_NOAUTOKEY)
+#define CP_IDENT (8 + CP_MAX_NOAUTOKEY)
+#define CP_MAXCODE CP_IDENT
+#else /* !AUTOKEY follows */
+#define CP_MAXCODE CP_MAX_NOAUTOKEY
+#endif /* !AUTOKEY */
+
+/*
+ * Clock variables we understand
+ */
+#define CC_TYPE 1
+#define CC_TIMECODE 2
+#define CC_POLL 3
+#define CC_NOREPLY 4
+#define CC_BADFORMAT 5
+#define CC_BADDATA 6
+#define CC_FUDGETIME1 7
+#define CC_FUDGETIME2 8
+#define CC_FUDGEVAL1 9
+#define CC_FUDGEVAL2 10
+#define CC_FLAGS 11
+#define CC_DEVICE 12
+#define CC_VARLIST 13
+#define CC_MAXCODE CC_VARLIST
+
+/*
+ * System variable values. The array can be indexed by the variable
+ * index to find the textual name.
+ */
+static const struct ctl_var sys_var[] = {
+ { 0, PADDING, "" }, /* 0 */
+ { CS_LEAP, RW, "leap" }, /* 1 */
+ { CS_STRATUM, RO, "stratum" }, /* 2 */
+ { CS_PRECISION, RO, "precision" }, /* 3 */
+ { CS_ROOTDELAY, RO, "rootdelay" }, /* 4 */
+ { CS_ROOTDISPERSION, RO, "rootdisp" }, /* 5 */
+ { CS_REFID, RO, "refid" }, /* 6 */
+ { CS_REFTIME, RO, "reftime" }, /* 7 */
+ { CS_POLL, RO, "tc" }, /* 8 */
+ { CS_PEERID, RO, "peer" }, /* 9 */
+ { CS_OFFSET, RO, "offset" }, /* 10 */
+ { CS_DRIFT, RO, "frequency" }, /* 11 */
+ { CS_JITTER, RO, "sys_jitter" }, /* 12 */
+ { CS_ERROR, RO, "clk_jitter" }, /* 13 */
+ { CS_CLOCK, RO, "clock" }, /* 14 */
+ { CS_PROCESSOR, RO, "processor" }, /* 15 */
+ { CS_SYSTEM, RO, "system" }, /* 16 */
+ { CS_VERSION, RO, "version" }, /* 17 */
+ { CS_STABIL, RO, "clk_wander" }, /* 18 */
+ { CS_VARLIST, RO, "sys_var_list" }, /* 19 */
+ { CS_TAI, RO, "tai" }, /* 20 */
+ { CS_LEAPTAB, RO, "leapsec" }, /* 21 */
+ { CS_LEAPEND, RO, "expire" }, /* 22 */
+ { CS_RATE, RO, "mintc" }, /* 23 */
+ { CS_MRU_ENABLED, RO, "mru_enabled" }, /* 24 */
+ { CS_MRU_DEPTH, RO, "mru_depth" }, /* 25 */
+ { CS_MRU_DEEPEST, RO, "mru_deepest" }, /* 26 */
+ { CS_MRU_MINDEPTH, RO, "mru_mindepth" }, /* 27 */
+ { CS_MRU_MAXAGE, RO, "mru_maxage" }, /* 28 */
+ { CS_MRU_MAXDEPTH, RO, "mru_maxdepth" }, /* 29 */
+ { CS_MRU_MEM, RO, "mru_mem" }, /* 30 */
+ { CS_MRU_MAXMEM, RO, "mru_maxmem" }, /* 31 */
+ { CS_SS_UPTIME, RO, "ss_uptime" }, /* 32 */
+ { CS_SS_RESET, RO, "ss_reset" }, /* 33 */
+ { CS_SS_RECEIVED, RO, "ss_received" }, /* 34 */
+ { CS_SS_THISVER, RO, "ss_thisver" }, /* 35 */
+ { CS_SS_OLDVER, RO, "ss_oldver" }, /* 36 */
+ { CS_SS_BADFORMAT, RO, "ss_badformat" }, /* 37 */
+ { CS_SS_BADAUTH, RO, "ss_badauth" }, /* 38 */
+ { CS_SS_DECLINED, RO, "ss_declined" }, /* 39 */
+ { CS_SS_RESTRICTED, RO, "ss_restricted" }, /* 40 */
+ { CS_SS_LIMITED, RO, "ss_limited" }, /* 41 */
+ { CS_SS_KODSENT, RO, "ss_kodsent" }, /* 42 */
+ { CS_SS_PROCESSED, RO, "ss_processed" }, /* 43 */
+ { CS_SS_LAMPORT, RO, "ss_lamport" }, /* 44 */
+ { CS_SS_TSROUNDING, RO, "ss_tsrounding" }, /* 45 */
+ { CS_PEERADR, RO, "peeradr" }, /* 46 */
+ { CS_PEERMODE, RO, "peermode" }, /* 47 */
+ { CS_BCASTDELAY, RO, "bcastdelay" }, /* 48 */
+ { CS_AUTHDELAY, RO, "authdelay" }, /* 49 */
+ { CS_AUTHKEYS, RO, "authkeys" }, /* 50 */
+ { CS_AUTHFREEK, RO, "authfreek" }, /* 51 */
+ { CS_AUTHKLOOKUPS, RO, "authklookups" }, /* 52 */
+ { CS_AUTHKNOTFOUND, RO, "authknotfound" }, /* 53 */
+ { CS_AUTHKUNCACHED, RO, "authkuncached" }, /* 54 */
+ { CS_AUTHKEXPIRED, RO, "authkexpired" }, /* 55 */
+ { CS_AUTHENCRYPTS, RO, "authencrypts" }, /* 56 */
+ { CS_AUTHDECRYPTS, RO, "authdecrypts" }, /* 57 */
+ { CS_AUTHRESET, RO, "authreset" }, /* 58 */
+ { CS_K_OFFSET, RO, "koffset" }, /* 59 */
+ { CS_K_FREQ, RO, "kfreq" }, /* 60 */
+ { CS_K_MAXERR, RO, "kmaxerr" }, /* 61 */
+ { CS_K_ESTERR, RO, "kesterr" }, /* 62 */
+ { CS_K_STFLAGS, RO, "kstflags" }, /* 63 */
+ { CS_K_TIMECONST, RO, "ktimeconst" }, /* 64 */
+ { CS_K_PRECISION, RO, "kprecis" }, /* 65 */
+ { CS_K_FREQTOL, RO, "kfreqtol" }, /* 66 */
+ { CS_K_PPS_FREQ, RO, "kppsfreq" }, /* 67 */
+ { CS_K_PPS_STABIL, RO, "kppsstab" }, /* 68 */
+ { CS_K_PPS_JITTER, RO, "kppsjitter" }, /* 69 */
+ { CS_K_PPS_CALIBDUR, RO, "kppscalibdur" }, /* 70 */
+ { CS_K_PPS_CALIBS, RO, "kppscalibs" }, /* 71 */
+ { CS_K_PPS_CALIBERRS, RO, "kppscaliberrs" }, /* 72 */
+ { CS_K_PPS_JITEXC, RO, "kppsjitexc" }, /* 73 */
+ { CS_K_PPS_STBEXC, RO, "kppsstbexc" }, /* 74 */
+ { CS_IOSTATS_RESET, RO, "iostats_reset" }, /* 75 */
+ { CS_TOTAL_RBUF, RO, "total_rbuf" }, /* 76 */
+ { CS_FREE_RBUF, RO, "free_rbuf" }, /* 77 */
+ { CS_USED_RBUF, RO, "used_rbuf" }, /* 78 */
+ { CS_RBUF_LOWATER, RO, "rbuf_lowater" }, /* 79 */
+ { CS_IO_DROPPED, RO, "io_dropped" }, /* 80 */
+ { CS_IO_IGNORED, RO, "io_ignored" }, /* 81 */
+ { CS_IO_RECEIVED, RO, "io_received" }, /* 82 */
+ { CS_IO_SENT, RO, "io_sent" }, /* 83 */
+ { CS_IO_SENDFAILED, RO, "io_sendfailed" }, /* 84 */
+ { CS_IO_WAKEUPS, RO, "io_wakeups" }, /* 85 */
+ { CS_IO_GOODWAKEUPS, RO, "io_goodwakeups" }, /* 86 */
+ { CS_TIMERSTATS_RESET, RO, "timerstats_reset" },/* 87 */
+ { CS_TIMER_OVERRUNS, RO, "timer_overruns" }, /* 88 */
+ { CS_TIMER_XMTS, RO, "timer_xmts" }, /* 89 */
+ { CS_FUZZ, RO, "fuzz" }, /* 90 */
+ { CS_WANDER_THRESH, RO, "clk_wander_threshold" }, /* 91 */
+
+ { CS_LEAPSMEARINTV, RO, "leapsmearinterval" }, /* 92 */
+ { CS_LEAPSMEAROFFS, RO, "leapsmearoffset" }, /* 93 */
+
+#ifdef AUTOKEY
+ { CS_FLAGS, RO, "flags" }, /* 1 + CS_MAX_NOAUTOKEY */
+ { CS_HOST, RO, "host" }, /* 2 + CS_MAX_NOAUTOKEY */
+ { CS_PUBLIC, RO, "update" }, /* 3 + CS_MAX_NOAUTOKEY */
+ { CS_CERTIF, RO, "cert" }, /* 4 + CS_MAX_NOAUTOKEY */
+ { CS_SIGNATURE, RO, "signature" }, /* 5 + CS_MAX_NOAUTOKEY */
+ { CS_REVTIME, RO, "until" }, /* 6 + CS_MAX_NOAUTOKEY */
+ { CS_IDENT, RO, "ident" }, /* 7 + CS_MAX_NOAUTOKEY */
+ { CS_DIGEST, RO, "digest" }, /* 8 + CS_MAX_NOAUTOKEY */
+#endif /* AUTOKEY */
+ { 0, EOV, "" } /* 94/102 */
+};
+
+static struct ctl_var *ext_sys_var = NULL;
+
+/*
+ * System variables we print by default (in fuzzball order,
+ * more-or-less)
+ */
+static const u_char def_sys_var[] = {
+ CS_VERSION,
+ CS_PROCESSOR,
+ CS_SYSTEM,
+ CS_LEAP,
+ CS_STRATUM,
+ CS_PRECISION,
+ CS_ROOTDELAY,
+ CS_ROOTDISPERSION,
+ CS_REFID,
+ CS_REFTIME,
+ CS_CLOCK,
+ CS_PEERID,
+ CS_POLL,
+ CS_RATE,
+ CS_OFFSET,
+ CS_DRIFT,
+ CS_JITTER,
+ CS_ERROR,
+ CS_STABIL,
+ CS_TAI,
+ CS_LEAPTAB,
+ CS_LEAPEND,
+ CS_LEAPSMEARINTV,
+ CS_LEAPSMEAROFFS,
+#ifdef AUTOKEY
+ CS_HOST,
+ CS_IDENT,
+ CS_FLAGS,
+ CS_DIGEST,
+ CS_SIGNATURE,
+ CS_PUBLIC,
+ CS_CERTIF,
+#endif /* AUTOKEY */
+ 0
+};
+
+
+/*
+ * Peer variable list
+ */
+static const struct ctl_var peer_var[] = {
+ { 0, PADDING, "" }, /* 0 */
+ { CP_CONFIG, RO, "config" }, /* 1 */
+ { CP_AUTHENABLE, RO, "authenable" }, /* 2 */
+ { CP_AUTHENTIC, RO, "authentic" }, /* 3 */
+ { CP_SRCADR, RO, "srcadr" }, /* 4 */
+ { CP_SRCPORT, RO, "srcport" }, /* 5 */
+ { CP_DSTADR, RO, "dstadr" }, /* 6 */
+ { CP_DSTPORT, RO, "dstport" }, /* 7 */
+ { CP_LEAP, RO, "leap" }, /* 8 */
+ { CP_HMODE, RO, "hmode" }, /* 9 */
+ { CP_STRATUM, RO, "stratum" }, /* 10 */
+ { CP_PPOLL, RO, "ppoll" }, /* 11 */
+ { CP_HPOLL, RO, "hpoll" }, /* 12 */
+ { CP_PRECISION, RO, "precision" }, /* 13 */
+ { CP_ROOTDELAY, RO, "rootdelay" }, /* 14 */
+ { CP_ROOTDISPERSION, RO, "rootdisp" }, /* 15 */
+ { CP_REFID, RO, "refid" }, /* 16 */
+ { CP_REFTIME, RO, "reftime" }, /* 17 */
+ { CP_ORG, RO, "org" }, /* 18 */
+ { CP_REC, RO, "rec" }, /* 19 */
+ { CP_XMT, RO, "xleave" }, /* 20 */
+ { CP_REACH, RO, "reach" }, /* 21 */
+ { CP_UNREACH, RO, "unreach" }, /* 22 */
+ { CP_TIMER, RO, "timer" }, /* 23 */
+ { CP_DELAY, RO, "delay" }, /* 24 */
+ { CP_OFFSET, RO, "offset" }, /* 25 */
+ { CP_JITTER, RO, "jitter" }, /* 26 */
+ { CP_DISPERSION, RO, "dispersion" }, /* 27 */
+ { CP_KEYID, RO, "keyid" }, /* 28 */
+ { CP_FILTDELAY, RO, "filtdelay" }, /* 29 */
+ { CP_FILTOFFSET, RO, "filtoffset" }, /* 30 */
+ { CP_PMODE, RO, "pmode" }, /* 31 */
+ { CP_RECEIVED, RO, "received"}, /* 32 */
+ { CP_SENT, RO, "sent" }, /* 33 */
+ { CP_FILTERROR, RO, "filtdisp" }, /* 34 */
+ { CP_FLASH, RO, "flash" }, /* 35 */
+ { CP_TTL, RO, "ttl" }, /* 36 */
+ { CP_VARLIST, RO, "peer_var_list" }, /* 37 */
+ { CP_IN, RO, "in" }, /* 38 */
+ { CP_OUT, RO, "out" }, /* 39 */
+ { CP_RATE, RO, "headway" }, /* 40 */
+ { CP_BIAS, RO, "bias" }, /* 41 */
+ { CP_SRCHOST, RO, "srchost" }, /* 42 */
+ { CP_TIMEREC, RO, "timerec" }, /* 43 */
+ { CP_TIMEREACH, RO, "timereach" }, /* 44 */
+ { CP_BADAUTH, RO, "badauth" }, /* 45 */
+ { CP_BOGUSORG, RO, "bogusorg" }, /* 46 */
+ { CP_OLDPKT, RO, "oldpkt" }, /* 47 */
+ { CP_SELDISP, RO, "seldisp" }, /* 48 */
+ { CP_SELBROKEN, RO, "selbroken" }, /* 49 */
+ { CP_CANDIDATE, RO, "candidate" }, /* 50 */
+#ifdef AUTOKEY
+ { CP_FLAGS, RO, "flags" }, /* 1 + CP_MAX_NOAUTOKEY */
+ { CP_HOST, RO, "host" }, /* 2 + CP_MAX_NOAUTOKEY */
+ { CP_VALID, RO, "valid" }, /* 3 + CP_MAX_NOAUTOKEY */
+ { CP_INITSEQ, RO, "initsequence" }, /* 4 + CP_MAX_NOAUTOKEY */
+ { CP_INITKEY, RO, "initkey" }, /* 5 + CP_MAX_NOAUTOKEY */
+ { CP_INITTSP, RO, "timestamp" }, /* 6 + CP_MAX_NOAUTOKEY */
+ { CP_SIGNATURE, RO, "signature" }, /* 7 + CP_MAX_NOAUTOKEY */
+ { CP_IDENT, RO, "ident" }, /* 8 + CP_MAX_NOAUTOKEY */
+#endif /* AUTOKEY */
+ { 0, EOV, "" } /* 50/58 */
+};
+
+
+/*
+ * Peer variables we print by default
+ */
+static const u_char def_peer_var[] = {
+ CP_SRCADR,
+ CP_SRCPORT,
+ CP_SRCHOST,
+ CP_DSTADR,
+ CP_DSTPORT,
+ CP_OUT,
+ CP_IN,
+ CP_LEAP,
+ CP_STRATUM,
+ CP_PRECISION,
+ CP_ROOTDELAY,
+ CP_ROOTDISPERSION,
+ CP_REFID,
+ CP_REFTIME,
+ CP_REC,
+ CP_REACH,
+ CP_UNREACH,
+ CP_HMODE,
+ CP_PMODE,
+ CP_HPOLL,
+ CP_PPOLL,
+ CP_RATE,
+ CP_FLASH,
+ CP_KEYID,
+ CP_TTL,
+ CP_OFFSET,
+ CP_DELAY,
+ CP_DISPERSION,
+ CP_JITTER,
+ CP_XMT,
+ CP_BIAS,
+ CP_FILTDELAY,
+ CP_FILTOFFSET,
+ CP_FILTERROR,
+#ifdef AUTOKEY
+ CP_HOST,
+ CP_FLAGS,
+ CP_SIGNATURE,
+ CP_VALID,
+ CP_INITSEQ,
+ CP_IDENT,
+#endif /* AUTOKEY */
+ 0
+};
+
+
+#ifdef REFCLOCK
+/*
+ * Clock variable list
+ */
+static const struct ctl_var clock_var[] = {
+ { 0, PADDING, "" }, /* 0 */
+ { CC_TYPE, RO, "type" }, /* 1 */
+ { CC_TIMECODE, RO, "timecode" }, /* 2 */
+ { CC_POLL, RO, "poll" }, /* 3 */
+ { CC_NOREPLY, RO, "noreply" }, /* 4 */
+ { CC_BADFORMAT, RO, "badformat" }, /* 5 */
+ { CC_BADDATA, RO, "baddata" }, /* 6 */
+ { CC_FUDGETIME1, RO, "fudgetime1" }, /* 7 */
+ { CC_FUDGETIME2, RO, "fudgetime2" }, /* 8 */
+ { CC_FUDGEVAL1, RO, "stratum" }, /* 9 */
+ { CC_FUDGEVAL2, RO, "refid" }, /* 10 */
+ { CC_FLAGS, RO, "flags" }, /* 11 */
+ { CC_DEVICE, RO, "device" }, /* 12 */
+ { CC_VARLIST, RO, "clock_var_list" }, /* 13 */
+ { 0, EOV, "" } /* 14 */
+};
+
+
+/*
+ * Clock variables printed by default
+ */
+static const u_char def_clock_var[] = {
+ CC_DEVICE,
+ CC_TYPE, /* won't be output if device = known */
+ CC_TIMECODE,
+ CC_POLL,
+ CC_NOREPLY,
+ CC_BADFORMAT,
+ CC_BADDATA,
+ CC_FUDGETIME1,
+ CC_FUDGETIME2,
+ CC_FUDGEVAL1,
+ CC_FUDGEVAL2,
+ CC_FLAGS,
+ 0
+};
+#endif
+
+/*
+ * MRU string constants shared by send_mru_entry() and read_mru_list().
+ */
+static const char addr_fmt[] = "addr.%d";
+static const char last_fmt[] = "last.%d";
+
+/*
+ * System and processor definitions.
+ */
+#ifndef HAVE_UNAME
+# ifndef STR_SYSTEM
+# define STR_SYSTEM "UNIX"
+# endif
+# ifndef STR_PROCESSOR
+# define STR_PROCESSOR "unknown"
+# endif
+
+static const char str_system[] = STR_SYSTEM;
+static const char str_processor[] = STR_PROCESSOR;
+#else
+# include <sys/utsname.h>
+static struct utsname utsnamebuf;
+#endif /* HAVE_UNAME */
+
+/*
+ * Trap structures. We only allow a few of these, and send a copy of
+ * each async message to each live one. Traps time out after an hour, it
+ * is up to the trap receipient to keep resetting it to avoid being
+ * timed out.
+ */
+/* ntp_request.c */
+struct ctl_trap ctl_traps[CTL_MAXTRAPS];
+int num_ctl_traps;
+
+/*
+ * Type bits, for ctlsettrap() call.
+ */
+#define TRAP_TYPE_CONFIG 0 /* used by configuration code */
+#define TRAP_TYPE_PRIO 1 /* priority trap */
+#define TRAP_TYPE_NONPRIO 2 /* nonpriority trap */
+
+
+/*
+ * List relating reference clock types to control message time sources.
+ * Index by the reference clock type. This list will only be used iff
+ * the reference clock driver doesn't set peer->sstclktype to something
+ * different than CTL_SST_TS_UNSPEC.
+ */
+#ifdef REFCLOCK
+static const u_char clocktypes[] = {
+ CTL_SST_TS_NTP, /* REFCLK_NONE (0) */
+ CTL_SST_TS_LOCAL, /* REFCLK_LOCALCLOCK (1) */
+ CTL_SST_TS_UHF, /* deprecated REFCLK_GPS_TRAK (2) */
+ CTL_SST_TS_HF, /* REFCLK_WWV_PST (3) */
+ CTL_SST_TS_LF, /* REFCLK_WWVB_SPECTRACOM (4) */
+ CTL_SST_TS_UHF, /* REFCLK_TRUETIME (5) */
+ CTL_SST_TS_UHF, /* REFCLK_IRIG_AUDIO (6) */
+ CTL_SST_TS_HF, /* REFCLK_CHU (7) */
+ CTL_SST_TS_LF, /* REFCLOCK_PARSE (default) (8) */
+ CTL_SST_TS_LF, /* REFCLK_GPS_MX4200 (9) */
+ CTL_SST_TS_UHF, /* REFCLK_GPS_AS2201 (10) */
+ CTL_SST_TS_UHF, /* REFCLK_GPS_ARBITER (11) */
+ CTL_SST_TS_UHF, /* REFCLK_IRIG_TPRO (12) */
+ CTL_SST_TS_ATOM, /* REFCLK_ATOM_LEITCH (13) */
+ CTL_SST_TS_LF, /* deprecated REFCLK_MSF_EES (14) */
+ CTL_SST_TS_NTP, /* not used (15) */
+ CTL_SST_TS_UHF, /* REFCLK_IRIG_BANCOMM (16) */
+ CTL_SST_TS_UHF, /* REFCLK_GPS_DATU (17) */
+ CTL_SST_TS_TELEPHONE, /* REFCLK_NIST_ACTS (18) */
+ CTL_SST_TS_HF, /* REFCLK_WWV_HEATH (19) */
+ CTL_SST_TS_UHF, /* REFCLK_GPS_NMEA (20) */
+ CTL_SST_TS_UHF, /* REFCLK_GPS_VME (21) */
+ CTL_SST_TS_ATOM, /* REFCLK_ATOM_PPS (22) */
+ CTL_SST_TS_NTP, /* not used (23) */
+ CTL_SST_TS_NTP, /* not used (24) */
+ CTL_SST_TS_NTP, /* not used (25) */
+ CTL_SST_TS_UHF, /* REFCLK_GPS_HP (26) */
+ CTL_SST_TS_LF, /* REFCLK_ARCRON_MSF (27) */
+ CTL_SST_TS_UHF, /* REFCLK_SHM (28) */
+ CTL_SST_TS_UHF, /* REFCLK_PALISADE (29) */
+ CTL_SST_TS_UHF, /* REFCLK_ONCORE (30) */
+ CTL_SST_TS_UHF, /* REFCLK_JUPITER (31) */
+ CTL_SST_TS_LF, /* REFCLK_CHRONOLOG (32) */
+ CTL_SST_TS_LF, /* REFCLK_DUMBCLOCK (33) */
+ CTL_SST_TS_LF, /* REFCLK_ULINK (34) */
+ CTL_SST_TS_LF, /* REFCLK_PCF (35) */
+ CTL_SST_TS_HF, /* REFCLK_WWV (36) */
+ CTL_SST_TS_LF, /* REFCLK_FG (37) */
+ CTL_SST_TS_UHF, /* REFCLK_HOPF_SERIAL (38) */
+ CTL_SST_TS_UHF, /* REFCLK_HOPF_PCI (39) */
+ CTL_SST_TS_LF, /* REFCLK_JJY (40) */
+ CTL_SST_TS_UHF, /* REFCLK_TT560 (41) */
+ CTL_SST_TS_UHF, /* REFCLK_ZYFER (42) */
+ CTL_SST_TS_UHF, /* REFCLK_RIPENCC (43) */
+ CTL_SST_TS_UHF, /* REFCLK_NEOCLOCK4X (44) */
+ CTL_SST_TS_UHF, /* REFCLK_TSYNCPCI (45) */
+ CTL_SST_TS_UHF /* REFCLK_GPSDJSON (46) */
+};
+#endif /* REFCLOCK */
+
+
+/*
+ * Keyid used for authenticating write requests.
+ */
+keyid_t ctl_auth_keyid;
+
+/*
+ * We keep track of the last error reported by the system internally
+ */
+static u_char ctl_sys_last_event;
+static u_char ctl_sys_num_events;
+
+
+/*
+ * Statistic counters to keep track of requests and responses.
+ */
+u_long ctltimereset; /* time stats reset */
+u_long numctlreq; /* number of requests we've received */
+u_long numctlbadpkts; /* number of bad control packets */
+u_long numctlresponses; /* number of resp packets sent with data */
+u_long numctlfrags; /* number of fragments sent */
+u_long numctlerrors; /* number of error responses sent */
+u_long numctltooshort; /* number of too short input packets */
+u_long numctlinputresp; /* number of responses on input */
+u_long numctlinputfrag; /* number of fragments on input */
+u_long numctlinputerr; /* number of input pkts with err bit set */
+u_long numctlbadoffset; /* number of input pkts with nonzero offset */
+u_long numctlbadversion; /* number of input pkts with unknown version */
+u_long numctldatatooshort; /* data too short for count */
+u_long numctlbadop; /* bad op code found in packet */
+u_long numasyncmsgs; /* number of async messages we've sent */
+
+/*
+ * Response packet used by these routines. Also some state information
+ * so that we can handle packet formatting within a common set of
+ * subroutines. Note we try to enter data in place whenever possible,
+ * but the need to set the more bit correctly means we occasionally
+ * use the extra buffer and copy.
+ */
+static struct ntp_control rpkt;
+static u_char res_version;
+static u_char res_opcode;
+static associd_t res_associd;
+static u_short res_frags; /* datagrams in this response */
+static int res_offset; /* offset of payload in response */
+static u_char * datapt;
+static u_char * dataend;
+static int datalinelen;
+static int datasent; /* flag to avoid initial ", " */
+static int datanotbinflag;
+static sockaddr_u *rmt_addr;
+static struct interface *lcl_inter;
+
+static u_char res_authenticate;
+static u_char res_authokay;
+static keyid_t res_keyid;
+
+#define MAXDATALINELEN (72)
+
+static u_char res_async; /* sending async trap response? */
+
+/*
+ * Pointers for saving state when decoding request packets
+ */
+static char *reqpt;
+static char *reqend;
+
+#ifndef MIN
+#define MIN(a, b) (((a) <= (b)) ? (a) : (b))
+#endif
+
+/*
+ * init_control - initialize request data
+ */
+void
+init_control(void)
+{
+ size_t i;
+
+#ifdef HAVE_UNAME
+ uname(&utsnamebuf);
+#endif /* HAVE_UNAME */
+
+ ctl_clr_stats();
+
+ ctl_auth_keyid = 0;
+ ctl_sys_last_event = EVNT_UNSPEC;
+ ctl_sys_num_events = 0;
+
+ num_ctl_traps = 0;
+ for (i = 0; i < COUNTOF(ctl_traps); i++)
+ ctl_traps[i].tr_flags = 0;
+}
+
+
+/*
+ * ctl_error - send an error response for the current request
+ */
+static void
+ctl_error(
+ u_char errcode
+ )
+{
+ size_t maclen;
+
+ numctlerrors++;
+ DPRINTF(3, ("sending control error %u\n", errcode));
+
+ /*
+ * Fill in the fields. We assume rpkt.sequence and rpkt.associd
+ * have already been filled in.
+ */
+ rpkt.r_m_e_op = (u_char)CTL_RESPONSE | CTL_ERROR |
+ (res_opcode & CTL_OP_MASK);
+ rpkt.status = htons((u_short)(errcode << 8) & 0xff00);
+ rpkt.count = 0;
+
+ /*
+ * send packet and bump counters
+ */
+ if (res_authenticate && sys_authenticate) {
+ maclen = authencrypt(res_keyid, (u_int32 *)&rpkt,
+ CTL_HEADER_LEN);
+ sendpkt(rmt_addr, lcl_inter, -2, (void *)&rpkt,
+ CTL_HEADER_LEN + maclen);
+ } else
+ sendpkt(rmt_addr, lcl_inter, -3, (void *)&rpkt,
+ CTL_HEADER_LEN);
+}
+
+int/*BOOL*/
+is_safe_filename(const char * name)
+{
+ /* We need a strict validation of filenames we should write: The
+ * daemon might run with special permissions and is remote
+ * controllable, so we better take care what we allow as file
+ * name!
+ *
+ * The first character must be digit or a letter from the ASCII
+ * base plane or a '_' ([_A-Za-z0-9]), the following characters
+ * must be from [-._+A-Za-z0-9].
+ *
+ * We do not trust the character classification much here: Since
+ * the NTP protocol makes no provisions for UTF-8 or local code
+ * pages, we strictly require the 7bit ASCII code page.
+ *
+ * The following table is a packed bit field of 128 two-bit
+ * groups. The LSB in each group tells us if a character is
+ * acceptable at the first position, the MSB if the character is
+ * accepted at any other position.
+ *
+ * This does not ensure that the file name is syntactically
+ * correct (multiple dots will not work with VMS...) but it will
+ * exclude potential globbing bombs and directory traversal. It
+ * also rules out drive selection. (For systems that have this
+ * notion, like Windows or VMS.)
+ */
+ static const uint32_t chclass[8] = {
+ 0x00000000, 0x00000000,
+ 0x28800000, 0x000FFFFF,
+ 0xFFFFFFFC, 0xC03FFFFF,
+ 0xFFFFFFFC, 0x003FFFFF
+ };
+
+ u_int widx, bidx, mask;
+ if ( ! (name && *name))
+ return FALSE;
+
+ mask = 1u;
+ while (0 != (widx = (u_char)*name++)) {
+ bidx = (widx & 15) << 1;
+ widx = widx >> 4;
+ if (widx >= sizeof(chclass)/sizeof(chclass[0]))
+ return FALSE;
+ if (0 == ((chclass[widx] >> bidx) & mask))
+ return FALSE;
+ mask = 2u;
+ }
+ return TRUE;
+}
+
+
+/*
+ * save_config - Implements ntpq -c "saveconfig <filename>"
+ * Writes current configuration including any runtime
+ * changes by ntpq's :config or config-from-file
+ *
+ * Note: There should be no buffer overflow or truncation in the
+ * processing of file names -- both cause security problems. This is bit
+ * painful to code but essential here.
+ */
+void
+save_config(
+ struct recvbuf *rbufp,
+ int restrict_mask
+ )
+{
+ /* block directory traversal by searching for characters that
+ * indicate directory components in a file path.
+ *
+ * Conceptually we should be searching for DIRSEP in filename,
+ * however Windows actually recognizes both forward and
+ * backslashes as equivalent directory separators at the API
+ * level. On POSIX systems we could allow '\\' but such
+ * filenames are tricky to manipulate from a shell, so just
+ * reject both types of slashes on all platforms.
+ */
+ /* TALOS-CAN-0062: block directory traversal for VMS, too */
+ static const char * illegal_in_filename =
+#if defined(VMS)
+ ":[]" /* do not allow drive and path components here */
+#elif defined(SYS_WINNT)
+ ":\\/" /* path and drive separators */
+#else
+ "\\/" /* separator and critical char for POSIX */
+#endif
+ ;
+ char reply[128];
+#ifdef SAVECONFIG
+ static const char savedconfig_eq[] = "savedconfig=";
+
+ /* Build a safe open mode from the available mode flags. We want
+ * to create a new file and write it in text mode (when
+ * applicable -- only Windows does this...)
+ */
+ static const int openmode = O_CREAT | O_TRUNC | O_WRONLY
+# if defined(O_EXCL) /* posix, vms */
+ | O_EXCL
+# elif defined(_O_EXCL) /* windows is alway very special... */
+ | _O_EXCL
+# endif
+# if defined(_O_TEXT) /* windows, again */
+ | _O_TEXT
+#endif
+ ;
+
+ char filespec[128];
+ char filename[128];
+ char fullpath[512];
+ char savedconfig[sizeof(savedconfig_eq) + sizeof(filename)];
+ time_t now;
+ int fd;
+ FILE *fptr;
+ int prc;
+ size_t reqlen;
+#endif
+
+ if (RES_NOMODIFY & restrict_mask) {
+ ctl_printf("%s", "saveconfig prohibited by restrict ... nomodify");
+ ctl_flushpkt(0);
+ NLOG(NLOG_SYSINFO)
+ msyslog(LOG_NOTICE,
+ "saveconfig from %s rejected due to nomodify restriction",
+ stoa(&rbufp->recv_srcadr));
+ sys_restricted++;
+ return;
+ }
+
+#ifdef SAVECONFIG
+ if (NULL == saveconfigdir) {
+ ctl_printf("%s", "saveconfig prohibited, no saveconfigdir configured");
+ ctl_flushpkt(0);
+ NLOG(NLOG_SYSINFO)
+ msyslog(LOG_NOTICE,
+ "saveconfig from %s rejected, no saveconfigdir",
+ stoa(&rbufp->recv_srcadr));
+ return;
+ }
+
+ /* The length checking stuff gets serious. Do not assume a NUL
+ * byte can be found, but if so, use it to calculate the needed
+ * buffer size. If the available buffer is too short, bail out;
+ * likewise if there is no file spec. (The latter will not
+ * happen when using NTPQ, but there are other ways to craft a
+ * network packet!)
+ */
+ reqlen = (size_t)(reqend - reqpt);
+ if (0 != reqlen) {
+ char * nulpos = (char*)memchr(reqpt, 0, reqlen);
+ if (NULL != nulpos)
+ reqlen = (size_t)(nulpos - reqpt);
+ }
+ if (0 == reqlen)
+ return;
+ if (reqlen >= sizeof(filespec)) {
+ ctl_printf("saveconfig exceeded maximum raw name length (%u)",
+ (u_int)sizeof(filespec));
+ ctl_flushpkt(0);
+ msyslog(LOG_NOTICE,
+ "saveconfig exceeded maximum raw name length from %s",
+ stoa(&rbufp->recv_srcadr));
+ return;
+ }
+
+ /* copy data directly as we exactly know the size */
+ memcpy(filespec, reqpt, reqlen);
+ filespec[reqlen] = '\0';
+
+ /*
+ * allow timestamping of the saved config filename with
+ * strftime() format such as:
+ * ntpq -c "saveconfig ntp-%Y%m%d-%H%M%S.conf"
+ * XXX: Nice feature, but not too safe.
+ * YYY: The check for permitted characters in file names should
+ * weed out the worst. Let's hope 'strftime()' does not
+ * develop pathological problems.
+ */
+ time(&now);
+ if (0 == strftime(filename, sizeof(filename), filespec,
+ localtime(&now)))
+ {
+ /*
+ * If we arrive here, 'strftime()' balked; most likely
+ * the buffer was too short. (Or it encounterd an empty
+ * format, or just a format that expands to an empty
+ * string.) We try to use the original name, though this
+ * is very likely to fail later if there are format
+ * specs in the string. Note that truncation cannot
+ * happen here as long as both buffers have the same
+ * size!
+ */
+ strlcpy(filename, filespec, sizeof(filename));
+ }
+
+ /*
+ * Check the file name for sanity. This might/will rule out file
+ * names that would be legal but problematic, and it blocks
+ * directory traversal.
+ */
+ if (!is_safe_filename(filename)) {
+ ctl_printf("saveconfig rejects unsafe file name '%s'",
+ filename);
+ ctl_flushpkt(0);
+ msyslog(LOG_NOTICE,
+ "saveconfig rejects unsafe file name from %s",
+ stoa(&rbufp->recv_srcadr));
+ return;
+ }
+
+ /*
+ * XXX: This next test may not be needed with is_safe_filename()
+ */
+
+ /* block directory/drive traversal */
+ /* TALOS-CAN-0062: block directory traversal for VMS, too */
+ if (NULL != strpbrk(filename, illegal_in_filename)) {
+ snprintf(reply, sizeof(reply),
+ "saveconfig does not allow directory in filename");
+ ctl_putdata(reply, strlen(reply), 0);
+ ctl_flushpkt(0);
+ msyslog(LOG_NOTICE,
+ "saveconfig rejects unsafe file name from %s",
+ stoa(&rbufp->recv_srcadr));
+ return;
+ }
+
+ /* concatenation of directory and path can cause another
+ * truncation...
+ */
+ prc = snprintf(fullpath, sizeof(fullpath), "%s%s",
+ saveconfigdir, filename);
+ if (prc < 0 || (size_t)prc >= sizeof(fullpath)) {
+ ctl_printf("saveconfig exceeded maximum path length (%u)",
+ (u_int)sizeof(fullpath));
+ ctl_flushpkt(0);
+ msyslog(LOG_NOTICE,
+ "saveconfig exceeded maximum path length from %s",
+ stoa(&rbufp->recv_srcadr));
+ return;
+ }
+
+ fd = open(fullpath, openmode, S_IRUSR | S_IWUSR);
+ if (-1 == fd)
+ fptr = NULL;
+ else
+ fptr = fdopen(fd, "w");
+
+ if (NULL == fptr || -1 == dump_all_config_trees(fptr, 1)) {
+ ctl_printf("Unable to save configuration to file '%s': %s",
+ filename, strerror(errno));
+ msyslog(LOG_ERR,
+ "saveconfig %s from %s failed", filename,
+ stoa(&rbufp->recv_srcadr));
+ } else {
+ ctl_printf("Configuration saved to '%s'", filename);
+ msyslog(LOG_NOTICE,
+ "Configuration saved to '%s' (requested by %s)",
+ fullpath, stoa(&rbufp->recv_srcadr));
+ /*
+ * save the output filename in system variable
+ * savedconfig, retrieved with:
+ * ntpq -c "rv 0 savedconfig"
+ * Note: the way 'savedconfig' is defined makes overflow
+ * checks unnecessary here.
+ */
+ snprintf(savedconfig, sizeof(savedconfig), "%s%s",
+ savedconfig_eq, filename);
+ set_sys_var(savedconfig, strlen(savedconfig) + 1, RO);
+ }
+
+ if (NULL != fptr)
+ fclose(fptr);
+#else /* !SAVECONFIG follows */
+ ctl_printf("%s",
+ "saveconfig unavailable, configured with --disable-saveconfig");
+#endif
+ ctl_flushpkt(0);
+}
+
+
+/*
+ * process_control - process an incoming control message
+ */
+void
+process_control(
+ struct recvbuf *rbufp,
+ int restrict_mask
+ )
+{
+ struct ntp_control *pkt;
+ int req_count;
+ int req_data;
+ const struct ctl_proc *cc;
+ keyid_t *pkid;
+ int properlen;
+ size_t maclen;
+
+ DPRINTF(3, ("in process_control()\n"));
+
+ /*
+ * Save the addresses for error responses
+ */
+ numctlreq++;
+ rmt_addr = &rbufp->recv_srcadr;
+ lcl_inter = rbufp->dstadr;
+ pkt = (struct ntp_control *)&rbufp->recv_pkt;
+
+ /*
+ * If the length is less than required for the header, or
+ * it is a response or a fragment, ignore this.
+ */
+ if (rbufp->recv_length < (int)CTL_HEADER_LEN
+ || (CTL_RESPONSE | CTL_MORE | CTL_ERROR) & pkt->r_m_e_op
+ || pkt->offset != 0) {
+ DPRINTF(1, ("invalid format in control packet\n"));
+ if (rbufp->recv_length < (int)CTL_HEADER_LEN)
+ numctltooshort++;
+ if (CTL_RESPONSE & pkt->r_m_e_op)
+ numctlinputresp++;
+ if (CTL_MORE & pkt->r_m_e_op)
+ numctlinputfrag++;
+ if (CTL_ERROR & pkt->r_m_e_op)
+ numctlinputerr++;
+ if (pkt->offset != 0)
+ numctlbadoffset++;
+ return;
+ }
+ res_version = PKT_VERSION(pkt->li_vn_mode);
+ if (res_version > NTP_VERSION || res_version < NTP_OLDVERSION) {
+ DPRINTF(1, ("unknown version %d in control packet\n",
+ res_version));
+ numctlbadversion++;
+ return;
+ }
+
+ /*
+ * Pull enough data from the packet to make intelligent
+ * responses
+ */
+ rpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap, res_version,
+ MODE_CONTROL);
+ res_opcode = pkt->r_m_e_op;
+ rpkt.sequence = pkt->sequence;
+ rpkt.associd = pkt->associd;
+ rpkt.status = 0;
+ res_frags = 1;
+ res_offset = 0;
+ res_associd = htons(pkt->associd);
+ res_async = FALSE;
+ res_authenticate = FALSE;
+ res_keyid = 0;
+ res_authokay = FALSE;
+ req_count = (int)ntohs(pkt->count);
+ datanotbinflag = FALSE;
+ datalinelen = 0;
+ datasent = 0;
+ datapt = rpkt.u.data;
+ dataend = &rpkt.u.data[CTL_MAX_DATA_LEN];
+
+ if ((rbufp->recv_length & 0x3) != 0)
+ DPRINTF(3, ("Control packet length %d unrounded\n",
+ rbufp->recv_length));
+
+ /*
+ * We're set up now. Make sure we've got at least enough
+ * incoming data space to match the count.
+ */
+ req_data = rbufp->recv_length - CTL_HEADER_LEN;
+ if (req_data < req_count || rbufp->recv_length & 0x3) {
+ ctl_error(CERR_BADFMT);
+ numctldatatooshort++;
+ return;
+ }
+
+ properlen = req_count + CTL_HEADER_LEN;
+ /* round up proper len to a 8 octet boundary */
+
+ properlen = (properlen + 7) & ~7;
+ maclen = rbufp->recv_length - properlen;
+ if ((rbufp->recv_length & 3) == 0 &&
+ maclen >= MIN_MAC_LEN && maclen <= MAX_MAC_LEN &&
+ sys_authenticate) {
+ res_authenticate = TRUE;
+ pkid = (void *)((char *)pkt + properlen);
+ res_keyid = ntohl(*pkid);
+ DPRINTF(3, ("recv_len %d, properlen %d, wants auth with keyid %08x, MAC length=%zu\n",
+ rbufp->recv_length, properlen, res_keyid,
+ maclen));
+
+ if (!authistrustedip(res_keyid, &rbufp->recv_srcadr))
+ DPRINTF(3, ("invalid keyid %08x\n", res_keyid));
+ else if (authdecrypt(res_keyid, (u_int32 *)pkt,
+ rbufp->recv_length - maclen,
+ maclen)) {
+ res_authokay = TRUE;
+ DPRINTF(3, ("authenticated okay\n"));
+ } else {
+ res_keyid = 0;
+ DPRINTF(3, ("authentication failed\n"));
+ }
+ }
+
+ /*
+ * Set up translate pointers
+ */
+ reqpt = (char *)pkt->u.data;
+ reqend = reqpt + req_count;
+
+ /*
+ * Look for the opcode processor
+ */
+ for (cc = control_codes; cc->control_code != NO_REQUEST; cc++) {
+ if (cc->control_code == res_opcode) {
+ DPRINTF(3, ("opcode %d, found command handler\n",
+ res_opcode));
+ if (cc->flags == AUTH
+ && (!res_authokay
+ || res_keyid != ctl_auth_keyid)) {
+ ctl_error(CERR_PERMISSION);
+ return;
+ }
+ (cc->handler)(rbufp, restrict_mask);
+ return;
+ }
+ }
+
+ /*
+ * Can't find this one, return an error.
+ */
+ numctlbadop++;
+ ctl_error(CERR_BADOP);
+ return;
+}
+
+
+/*
+ * ctlpeerstatus - return a status word for this peer
+ */
+u_short
+ctlpeerstatus(
+ register struct peer *p
+ )
+{
+ u_short status;
+
+ status = p->status;
+ if (FLAG_CONFIG & p->flags)
+ status |= CTL_PST_CONFIG;
+ if (p->keyid)
+ status |= CTL_PST_AUTHENABLE;
+ if (FLAG_AUTHENTIC & p->flags)
+ status |= CTL_PST_AUTHENTIC;
+ if (p->reach)
+ status |= CTL_PST_REACH;
+ if (MDF_TXONLY_MASK & p->cast_flags)
+ status |= CTL_PST_BCAST;
+
+ return CTL_PEER_STATUS(status, p->num_events, p->last_event);
+}
+
+
+/*
+ * ctlclkstatus - return a status word for this clock
+ */
+#ifdef REFCLOCK
+static u_short
+ctlclkstatus(
+ struct refclockstat *pcs
+ )
+{
+ return CTL_PEER_STATUS(0, pcs->lastevent, pcs->currentstatus);
+}
+#endif
+
+
+/*
+ * ctlsysstatus - return the system status word
+ */
+u_short
+ctlsysstatus(void)
+{
+ register u_char this_clock;
+
+ this_clock = CTL_SST_TS_UNSPEC;
+#ifdef REFCLOCK
+ if (sys_peer != NULL) {
+ if (CTL_SST_TS_UNSPEC != sys_peer->sstclktype)
+ this_clock = sys_peer->sstclktype;
+ else if (sys_peer->refclktype < COUNTOF(clocktypes))
+ this_clock = clocktypes[sys_peer->refclktype];
+ }
+#else /* REFCLOCK */
+ if (sys_peer != 0)
+ this_clock = CTL_SST_TS_NTP;
+#endif /* REFCLOCK */
+ return CTL_SYS_STATUS(sys_leap, this_clock, ctl_sys_num_events,
+ ctl_sys_last_event);
+}
+
+
+/*
+ * ctl_flushpkt - write out the current packet and prepare
+ * another if necessary.
+ */
+static void
+ctl_flushpkt(
+ u_char more
+ )
+{
+ size_t i;
+ size_t dlen;
+ size_t sendlen;
+ size_t maclen;
+ size_t totlen;
+ keyid_t keyid;
+
+ dlen = datapt - rpkt.u.data;
+ if (!more && datanotbinflag && dlen + 2 < CTL_MAX_DATA_LEN) {
+ /*
+ * Big hack, output a trailing \r\n
+ */
+ *datapt++ = '\r';
+ *datapt++ = '\n';
+ dlen += 2;
+ }
+ sendlen = dlen + CTL_HEADER_LEN;
+
+ /*
+ * Pad to a multiple of 32 bits
+ */
+ while (sendlen & 0x3) {
+ *datapt++ = '\0';
+ sendlen++;
+ }
+
+ /*
+ * Fill in the packet with the current info
+ */
+ rpkt.r_m_e_op = CTL_RESPONSE | more |
+ (res_opcode & CTL_OP_MASK);
+ rpkt.count = htons((u_short)dlen);
+ rpkt.offset = htons((u_short)res_offset);
+ if (res_async) {
+ for (i = 0; i < COUNTOF(ctl_traps); i++) {
+ if (TRAP_INUSE & ctl_traps[i].tr_flags) {
+ rpkt.li_vn_mode =
+ PKT_LI_VN_MODE(
+ sys_leap,
+ ctl_traps[i].tr_version,
+ MODE_CONTROL);
+ rpkt.sequence =
+ htons(ctl_traps[i].tr_sequence);
+ sendpkt(&ctl_traps[i].tr_addr,
+ ctl_traps[i].tr_localaddr, -4,
+ (struct pkt *)&rpkt, sendlen);
+ if (!more)
+ ctl_traps[i].tr_sequence++;
+ numasyncmsgs++;
+ }
+ }
+ } else {
+ if (res_authenticate && sys_authenticate) {
+ totlen = sendlen;
+ /*
+ * If we are going to authenticate, then there
+ * is an additional requirement that the MAC
+ * begin on a 64 bit boundary.
+ */
+ while (totlen & 7) {
+ *datapt++ = '\0';
+ totlen++;
+ }
+ keyid = htonl(res_keyid);
+ memcpy(datapt, &keyid, sizeof(keyid));
+ maclen = authencrypt(res_keyid,
+ (u_int32 *)&rpkt, totlen);
+ sendpkt(rmt_addr, lcl_inter, -5,
+ (struct pkt *)&rpkt, totlen + maclen);
+ } else {
+ sendpkt(rmt_addr, lcl_inter, -6,
+ (struct pkt *)&rpkt, sendlen);
+ }
+ if (more)
+ numctlfrags++;
+ else
+ numctlresponses++;
+ }
+
+ /*
+ * Set us up for another go around.
+ */
+ res_frags++;
+ res_offset += dlen;
+ datapt = rpkt.u.data;
+}
+
+
+/* --------------------------------------------------------------------
+ * block transfer API -- stream string/data fragments into xmit buffer
+ * without additional copying
+ */
+
+/* buffer descriptor: address & size of fragment
+ * 'buf' may only be NULL when 'len' is zero!
+ */
+typedef struct {
+ const void *buf;
+ size_t len;
+} CtlMemBufT;
+
+/* put ctl data in a gather-style operation */
+static void
+ctl_putdata_ex(
+ const CtlMemBufT * argv,
+ size_t argc,
+ int/*BOOL*/ bin /* set to 1 when data is binary */
+ )
+{
+ const char * src_ptr;
+ size_t src_len, cur_len, add_len, argi;
+
+ /* text / binary preprocessing, possibly create new linefeed */
+ if (bin) {
+ add_len = 0;
+ } else {
+ datanotbinflag = TRUE;
+ add_len = 3;
+
+ if (datasent) {
+ *datapt++ = ',';
+ datalinelen++;
+
+ /* sum up total length */
+ for (argi = 0, src_len = 0; argi < argc; ++argi)
+ src_len += argv[argi].len;
+ /* possibly start a new line, assume no size_t overflow */
+ if ((src_len + datalinelen + 1) >= MAXDATALINELEN) {
+ *datapt++ = '\r';
+ *datapt++ = '\n';
+ datalinelen = 0;
+ } else {
+ *datapt++ = ' ';
+ datalinelen++;
+ }
+ }
+ }
+
+ /* now stream out all buffers */
+ for (argi = 0; argi < argc; ++argi) {
+ src_ptr = argv[argi].buf;
+ src_len = argv[argi].len;
+
+ if ( ! (src_ptr && src_len))
+ continue;
+
+ cur_len = (size_t)(dataend - datapt);
+ while ((src_len + add_len) > cur_len) {
+ /* Not enough room in this one, flush it out. */
+ if (src_len < cur_len)
+ cur_len = src_len;
+
+ memcpy(datapt, src_ptr, cur_len);
+ datapt += cur_len;
+ datalinelen += cur_len;
+
+ src_ptr += cur_len;
+ src_len -= cur_len;
+
+ ctl_flushpkt(CTL_MORE);
+ cur_len = (size_t)(dataend - datapt);
+ }
+
+ memcpy(datapt, src_ptr, src_len);
+ datapt += src_len;
+ datalinelen += src_len;
+
+ datasent = TRUE;
+ }
+}
+
+/*
+ * ctl_putdata - write data into the packet, fragmenting and starting
+ * another if this one is full.
+ */
+static void
+ctl_putdata(
+ const char *dp,
+ unsigned int dlen,
+ int bin /* set to 1 when data is binary */
+ )
+{
+ CtlMemBufT args[1];
+
+ args[0].buf = dp;
+ args[0].len = dlen;
+ ctl_putdata_ex(args, 1, bin);
+}
+
+/*
+ * ctl_putstr - write a tagged string into the response packet
+ * in the form:
+ *
+ * tag="data"
+ *
+ * len is the data length excluding the NUL terminator,
+ * as in ctl_putstr("var", "value", strlen("value"));
+ */
+static void
+ctl_putstr(
+ const char * tag,
+ const char * data,
+ size_t len
+ )
+{
+ CtlMemBufT args[4];
+
+ args[0].buf = tag;
+ args[0].len = strlen(tag);
+ if (data && len) {
+ args[1].buf = "=\"";
+ args[1].len = 2;
+ args[2].buf = data;
+ args[2].len = len;
+ args[3].buf = "\"";
+ args[3].len = 1;
+ ctl_putdata_ex(args, 4, FALSE);
+ } else {
+ args[1].buf = "=\"\"";
+ args[1].len = 3;
+ ctl_putdata_ex(args, 2, FALSE);
+ }
+}
+
+
+/*
+ * ctl_putunqstr - write a tagged string into the response packet
+ * in the form:
+ *
+ * tag=data
+ *
+ * len is the data length excluding the NUL terminator.
+ * data must not contain a comma or whitespace.
+ */
+static void
+ctl_putunqstr(
+ const char * tag,
+ const char * data,
+ size_t len
+ )
+{
+ CtlMemBufT args[3];
+
+ args[0].buf = tag;
+ args[0].len = strlen(tag);
+ args[1].buf = "=";
+ args[1].len = 1;
+ if (data && len) {
+ args[2].buf = data;
+ args[2].len = len;
+ ctl_putdata_ex(args, 3, FALSE);
+ } else {
+ ctl_putdata_ex(args, 2, FALSE);
+ }
+}
+
+
+/*
+ * ctl_putdblf - write a tagged, signed double into the response packet
+ */
+static void
+ctl_putdblf(
+ const char * tag,
+ int use_f,
+ int precision,
+ double d
+ )
+{
+ char buffer[40];
+ int rc;
+
+ rc = snprintf(buffer, sizeof(buffer),
+ (use_f ? "%.*f" : "%.*g"),
+ precision, d);
+ INSIST(rc >= 0 && (size_t)rc < sizeof(buffer));
+ ctl_putunqstr(tag, buffer, rc);
+}
+
+/*
+ * ctl_putuint - write a tagged unsigned integer into the response
+ */
+static void
+ctl_putuint(
+ const char *tag,
+ u_long uval
+ )
+{
+ char buffer[24]; /* needs to fit for 64 bits! */
+ int rc;
+
+ rc = snprintf(buffer, sizeof(buffer), "%lu", uval);
+ INSIST(rc >= 0 && (size_t)rc < sizeof(buffer));
+ ctl_putunqstr(tag, buffer, rc);
+}
+
+/*
+ * ctl_putcal - write a decoded calendar data into the response.
+ * only used with AUTOKEY currently, so compiled conditional
+ */
+#ifdef AUTOKEY
+static void
+ctl_putcal(
+ const char *tag,
+ const struct calendar *pcal
+ )
+{
+ char buffer[16];
+ int rc;
+
+ rc = snprintf(buffer, sizeof(buffer),
+ "%04d%02d%02d%02d%02d",
+ pcal->year, pcal->month, pcal->monthday,
+ pcal->hour, pcal->minute
+ );
+ INSIST(rc >= 0 && (size_t)rc < sizeof(buffer));
+ ctl_putunqstr(tag, buffer, rc);
+}
+#endif
+
+/*
+ * ctl_putfs - write a decoded filestamp into the response
+ */
+static void
+ctl_putfs(
+ const char *tag,
+ tstamp_t uval
+ )
+{
+ char buffer[16];
+ int rc;
+
+ time_t fstamp = (time_t)uval - JAN_1970;
+ struct tm *tm = gmtime(&fstamp);
+
+ if (NULL == tm)
+ return;
+
+ rc = snprintf(buffer, sizeof(buffer),
+ "%04d%02d%02d%02d%02d",
+ tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
+ tm->tm_hour, tm->tm_min);
+ INSIST(rc >= 0 && (size_t)rc < sizeof(buffer));
+ ctl_putunqstr(tag, buffer, rc);
+}
+
+
+/*
+ * ctl_puthex - write a tagged unsigned integer, in hex, into the
+ * response
+ */
+static void
+ctl_puthex(
+ const char *tag,
+ u_long uval
+ )
+{
+ char buffer[24]; /* must fit 64bit int! */
+ int rc;
+
+ rc = snprintf(buffer, sizeof(buffer), "0x%lx", uval);
+ INSIST(rc >= 0 && (size_t)rc < sizeof(buffer));
+ ctl_putunqstr(tag, buffer, rc);
+}
+
+
+/*
+ * ctl_putint - write a tagged signed integer into the response
+ */
+static void
+ctl_putint(
+ const char *tag,
+ long ival
+ )
+{
+ char buffer[24]; /*must fit 64bit int */
+ int rc;
+
+ rc = snprintf(buffer, sizeof(buffer), "%ld", ival);
+ INSIST(rc >= 0 && (size_t)rc < sizeof(buffer));
+ ctl_putunqstr(tag, buffer, rc);
+}
+
+
+/*
+ * ctl_putts - write a tagged timestamp, in hex, into the response
+ */
+static void
+ctl_putts(
+ const char *tag,
+ l_fp *ts
+ )
+{
+ char buffer[24];
+ int rc;
+
+ rc = snprintf(buffer, sizeof(buffer),
+ "0x%08lx.%08lx",
+ (u_long)ts->l_ui, (u_long)ts->l_uf);
+ INSIST(rc >= 0 && (size_t)rc < sizeof(buffer));
+ ctl_putunqstr(tag, buffer, rc);
+}
+
+
+/*
+ * ctl_putadr - write an IP address into the response
+ */
+static void
+ctl_putadr(
+ const char *tag,
+ u_int32 addr32,
+ sockaddr_u *addr
+ )
+{
+ const char *cq;
+
+ if (NULL == addr)
+ cq = numtoa(addr32);
+ else
+ cq = stoa(addr);
+ ctl_putunqstr(tag, cq, strlen(cq));
+}
+
+
+/*
+ * ctl_putrefid - send a u_int32 refid as printable text
+ */
+static void
+ctl_putrefid(
+ const char * tag,
+ u_int32 refid
+ )
+{
+ size_t nc;
+
+ union {
+ uint32_t w;
+ uint8_t b[sizeof(uint32_t)];
+ } bytes;
+
+ bytes.w = refid;
+ for (nc = 0; nc < sizeof(bytes.b) && bytes.b[nc]; ++nc)
+ if ( !isprint(bytes.b[nc])
+ || isspace(bytes.b[nc])
+ || bytes.b[nc] == ',' )
+ bytes.b[nc] = '.';
+ ctl_putunqstr(tag, (const char*)bytes.b, nc);
+}
+
+
+/*
+ * ctl_putarray - write a tagged eight element double array into the response
+ */
+static void
+ctl_putarray(
+ const char *tag,
+ double *arr,
+ int start
+ )
+{
+ char *cp, *ep;
+ char buffer[200];
+ int i, rc;
+
+ cp = buffer;
+ ep = buffer + sizeof(buffer);
+ i = start;
+ do {
+ if (i == 0)
+ i = NTP_SHIFT;
+ i--;
+ rc = snprintf(cp, (size_t)(ep - cp), " %.2f", arr[i] * 1e3);
+ INSIST(rc >= 0 && (size_t)rc < (size_t)(ep - cp));
+ cp += rc;
+ } while (i != start);
+ ctl_putunqstr(tag, buffer, (size_t)(cp - buffer));
+}
+
+/*
+ * ctl_printf - put a formatted string into the data buffer
+ */
+static void
+ctl_printf(
+ const char * fmt,
+ ...
+ )
+{
+ static const char * ellipsis = "[...]";
+ va_list va;
+ char fmtbuf[128];
+ int rc;
+
+ va_start(va, fmt);
+ rc = vsnprintf(fmtbuf, sizeof(fmtbuf), fmt, va);
+ va_end(va);
+ if (rc < 0 || (size_t)rc >= sizeof(fmtbuf))
+ strcpy(fmtbuf + sizeof(fmtbuf) - strlen(ellipsis) - 1,
+ ellipsis);
+ ctl_putdata(fmtbuf, strlen(fmtbuf), 0);
+}
+
+
+/*
+ * ctl_putsys - output a system variable
+ */
+static void
+ctl_putsys(
+ int varid
+ )
+{
+ l_fp tmp;
+ char str[256];
+ u_int u;
+ double kb;
+ double dtemp;
+ const char *ss;
+#ifdef AUTOKEY
+ struct cert_info *cp;
+#endif /* AUTOKEY */
+#ifdef KERNEL_PLL
+ static struct timex ntx;
+ static u_long ntp_adjtime_time;
+
+ static const double to_ms_usec =
+ 1.0e-3; /* usec to msec */
+ static const double to_ms_nusec =
+# ifdef STA_NANO
+ 1.0e-6; /* nsec to msec */
+# else
+ to_ms_usec;
+# endif
+
+ /*
+ * CS_K_* variables depend on up-to-date output of ntp_adjtime()
+ */
+ if (CS_KERN_FIRST <= varid && varid <= CS_KERN_LAST &&
+ current_time != ntp_adjtime_time) {
+ ZERO(ntx);
+ if (ntp_adjtime(&ntx) < 0)
+ msyslog(LOG_ERR, "ntp_adjtime() for mode 6 query failed: %m");
+ else
+ ntp_adjtime_time = current_time;
+ }
+#endif /* KERNEL_PLL */
+
+ switch (varid) {
+
+ case CS_LEAP:
+ ctl_putuint(sys_var[CS_LEAP].text, sys_leap);
+ break;
+
+ case CS_STRATUM:
+ ctl_putuint(sys_var[CS_STRATUM].text, sys_stratum);
+ break;
+
+ case CS_PRECISION:
+ ctl_putint(sys_var[CS_PRECISION].text, sys_precision);
+ break;
+
+ case CS_ROOTDELAY:
+ ctl_putdbl(sys_var[CS_ROOTDELAY].text, sys_rootdelay *
+ 1e3);
+ break;
+
+ case CS_ROOTDISPERSION:
+ ctl_putdbl(sys_var[CS_ROOTDISPERSION].text,
+ sys_rootdisp * 1e3);
+ break;
+
+ case CS_REFID:
+ if (REFID_ISTEXT(sys_stratum))
+ ctl_putrefid(sys_var[varid].text, sys_refid);
+ else
+ ctl_putadr(sys_var[varid].text, sys_refid, NULL);
+ break;
+
+ case CS_REFTIME:
+ ctl_putts(sys_var[CS_REFTIME].text, &sys_reftime);
+ break;
+
+ case CS_POLL:
+ ctl_putuint(sys_var[CS_POLL].text, sys_poll);
+ break;
+
+ case CS_PEERID:
+ if (sys_peer == NULL)
+ ctl_putuint(sys_var[CS_PEERID].text, 0);
+ else
+ ctl_putuint(sys_var[CS_PEERID].text,
+ sys_peer->associd);
+ break;
+
+ case CS_PEERADR:
+ if (sys_peer != NULL && sys_peer->dstadr != NULL)
+ ss = sptoa(&sys_peer->srcadr);
+ else
+ ss = "0.0.0.0:0";
+ ctl_putunqstr(sys_var[CS_PEERADR].text, ss, strlen(ss));
+ break;
+
+ case CS_PEERMODE:
+ u = (sys_peer != NULL)
+ ? sys_peer->hmode
+ : MODE_UNSPEC;
+ ctl_putuint(sys_var[CS_PEERMODE].text, u);
+ break;
+
+ case CS_OFFSET:
+ ctl_putdbl6(sys_var[CS_OFFSET].text, last_offset * 1e3);
+ break;
+
+ case CS_DRIFT:
+ ctl_putdbl(sys_var[CS_DRIFT].text, drift_comp * 1e6);
+ break;
+
+ case CS_JITTER:
+ ctl_putdbl6(sys_var[CS_JITTER].text, sys_jitter * 1e3);
+ break;
+
+ case CS_ERROR:
+ ctl_putdbl(sys_var[CS_ERROR].text, clock_jitter * 1e3);
+ break;
+
+ case CS_CLOCK:
+ get_systime(&tmp);
+ ctl_putts(sys_var[CS_CLOCK].text, &tmp);
+ break;
+
+ case CS_PROCESSOR:
+#ifndef HAVE_UNAME
+ ctl_putstr(sys_var[CS_PROCESSOR].text, str_processor,
+ sizeof(str_processor) - 1);
+#else
+ ctl_putstr(sys_var[CS_PROCESSOR].text,
+ utsnamebuf.machine, strlen(utsnamebuf.machine));
+#endif /* HAVE_UNAME */
+ break;
+
+ case CS_SYSTEM:
+#ifndef HAVE_UNAME
+ ctl_putstr(sys_var[CS_SYSTEM].text, str_system,
+ sizeof(str_system) - 1);
+#else
+ snprintf(str, sizeof(str), "%s/%s", utsnamebuf.sysname,
+ utsnamebuf.release);
+ ctl_putstr(sys_var[CS_SYSTEM].text, str, strlen(str));
+#endif /* HAVE_UNAME */
+ break;
+
+ case CS_VERSION:
+ ctl_putstr(sys_var[CS_VERSION].text, Version,
+ strlen(Version));
+ break;
+
+ case CS_STABIL:
+ ctl_putdbl(sys_var[CS_STABIL].text, clock_stability *
+ 1e6);
+ break;
+
+ case CS_VARLIST:
+ {
+ char buf[CTL_MAX_DATA_LEN];
+ //buffPointer, firstElementPointer, buffEndPointer
+ char *buffp, *buffend;
+ int firstVarName;
+ const char *ss1;
+ int len;
+ const struct ctl_var *k;
+
+ buffp = buf;
+ buffend = buf + sizeof(buf);
+ if (strlen(sys_var[CS_VARLIST].text) > (sizeof(buf) - 4))
+ break; /* really long var name */
+
+ snprintf(buffp, sizeof(buf), "%s=\"",sys_var[CS_VARLIST].text);
+ buffp += strlen(buffp);
+ firstVarName = TRUE;
+ for (k = sys_var; !(k->flags & EOV); k++) {
+ if (k->flags & PADDING)
+ continue;
+ len = strlen(k->text);
+ if (len + 1 >= buffend - buffp)
+ break;
+ if (!firstVarName)
+ *buffp++ = ',';
+ else
+ firstVarName = FALSE;
+ memcpy(buffp, k->text, len);
+ buffp += len;
+ }
+
+ for (k = ext_sys_var; k && !(k->flags & EOV); k++) {
+ if (k->flags & PADDING)
+ continue;
+ if (NULL == k->text)
+ continue;
+ ss1 = strchr(k->text, '=');
+ if (NULL == ss1)
+ len = strlen(k->text);
+ else
+ len = ss1 - k->text;
+ if (len + 1 >= buffend - buffp)
+ break;
+ if (firstVarName) {
+ *buffp++ = ',';
+ firstVarName = FALSE;
+ }
+ memcpy(buffp, k->text,(unsigned)len);
+ buffp += len;
+ }
+ if (2 >= buffend - buffp)
+ break;
+
+ *buffp++ = '"';
+ *buffp = '\0';
+
+ ctl_putdata(buf, (unsigned)( buffp - buf ), 0);
+ break;
+ }
+
+ case CS_TAI:
+ if (sys_tai > 0)
+ ctl_putuint(sys_var[CS_TAI].text, sys_tai);
+ break;
+
+ case CS_LEAPTAB:
+ {
+ leap_signature_t lsig;
+ leapsec_getsig(&lsig);
+ if (lsig.ttime > 0)
+ ctl_putfs(sys_var[CS_LEAPTAB].text, lsig.ttime);
+ break;
+ }
+
+ case CS_LEAPEND:
+ {
+ leap_signature_t lsig;
+ leapsec_getsig(&lsig);
+ if (lsig.etime > 0)
+ ctl_putfs(sys_var[CS_LEAPEND].text, lsig.etime);
+ break;
+ }
+
+#ifdef LEAP_SMEAR
+ case CS_LEAPSMEARINTV:
+ if (leap_smear_intv > 0)
+ ctl_putuint(sys_var[CS_LEAPSMEARINTV].text, leap_smear_intv);
+ break;
+
+ case CS_LEAPSMEAROFFS:
+ if (leap_smear_intv > 0)
+ ctl_putdbl(sys_var[CS_LEAPSMEAROFFS].text,
+ leap_smear.doffset * 1e3);
+ break;
+#endif /* LEAP_SMEAR */
+
+ case CS_RATE:
+ ctl_putuint(sys_var[CS_RATE].text, ntp_minpoll);
+ break;
+
+ case CS_MRU_ENABLED:
+ ctl_puthex(sys_var[varid].text, mon_enabled);
+ break;
+
+ case CS_MRU_DEPTH:
+ ctl_putuint(sys_var[varid].text, mru_entries);
+ break;
+
+ case CS_MRU_MEM:
+ kb = mru_entries * (sizeof(mon_entry) / 1024.);
+ u = (u_int)kb;
+ if (kb - u >= 0.5)
+ u++;
+ ctl_putuint(sys_var[varid].text, u);
+ break;
+
+ case CS_MRU_DEEPEST:
+ ctl_putuint(sys_var[varid].text, mru_peakentries);
+ break;
+
+ case CS_MRU_MINDEPTH:
+ ctl_putuint(sys_var[varid].text, mru_mindepth);
+ break;
+
+ case CS_MRU_MAXAGE:
+ ctl_putint(sys_var[varid].text, mru_maxage);
+ break;
+
+ case CS_MRU_MAXDEPTH:
+ ctl_putuint(sys_var[varid].text, mru_maxdepth);
+ break;
+
+ case CS_MRU_MAXMEM:
+ kb = mru_maxdepth * (sizeof(mon_entry) / 1024.);
+ u = (u_int)kb;
+ if (kb - u >= 0.5)
+ u++;
+ ctl_putuint(sys_var[varid].text, u);
+ break;
+
+ case CS_SS_UPTIME:
+ ctl_putuint(sys_var[varid].text, current_time);
+ break;
+
+ case CS_SS_RESET:
+ ctl_putuint(sys_var[varid].text,
+ current_time - sys_stattime);
+ break;
+
+ case CS_SS_RECEIVED:
+ ctl_putuint(sys_var[varid].text, sys_received);
+ break;
+
+ case CS_SS_THISVER:
+ ctl_putuint(sys_var[varid].text, sys_newversion);
+ break;
+
+ case CS_SS_OLDVER:
+ ctl_putuint(sys_var[varid].text, sys_oldversion);
+ break;
+
+ case CS_SS_BADFORMAT:
+ ctl_putuint(sys_var[varid].text, sys_badlength);
+ break;
+
+ case CS_SS_BADAUTH:
+ ctl_putuint(sys_var[varid].text, sys_badauth);
+ break;
+
+ case CS_SS_DECLINED:
+ ctl_putuint(sys_var[varid].text, sys_declined);
+ break;
+
+ case CS_SS_RESTRICTED:
+ ctl_putuint(sys_var[varid].text, sys_restricted);
+ break;
+
+ case CS_SS_LIMITED:
+ ctl_putuint(sys_var[varid].text, sys_limitrejected);
+ break;
+
+ case CS_SS_LAMPORT:
+ ctl_putuint(sys_var[varid].text, sys_lamport);
+ break;
+
+ case CS_SS_TSROUNDING:
+ ctl_putuint(sys_var[varid].text, sys_tsrounding);
+ break;
+
+ case CS_SS_KODSENT:
+ ctl_putuint(sys_var[varid].text, sys_kodsent);
+ break;
+
+ case CS_SS_PROCESSED:
+ ctl_putuint(sys_var[varid].text, sys_processed);
+ break;
+
+ case CS_BCASTDELAY:
+ ctl_putdbl(sys_var[varid].text, sys_bdelay * 1e3);
+ break;
+
+ case CS_AUTHDELAY:
+ LFPTOD(&sys_authdelay, dtemp);
+ ctl_putdbl(sys_var[varid].text, dtemp * 1e3);
+ break;
+
+ case CS_AUTHKEYS:
+ ctl_putuint(sys_var[varid].text, authnumkeys);
+ break;
+
+ case CS_AUTHFREEK:
+ ctl_putuint(sys_var[varid].text, authnumfreekeys);
+ break;
+
+ case CS_AUTHKLOOKUPS:
+ ctl_putuint(sys_var[varid].text, authkeylookups);
+ break;
+
+ case CS_AUTHKNOTFOUND:
+ ctl_putuint(sys_var[varid].text, authkeynotfound);
+ break;
+
+ case CS_AUTHKUNCACHED:
+ ctl_putuint(sys_var[varid].text, authkeyuncached);
+ break;
+
+ case CS_AUTHKEXPIRED:
+ ctl_putuint(sys_var[varid].text, authkeyexpired);
+ break;
+
+ case CS_AUTHENCRYPTS:
+ ctl_putuint(sys_var[varid].text, authencryptions);
+ break;
+
+ case CS_AUTHDECRYPTS:
+ ctl_putuint(sys_var[varid].text, authdecryptions);
+ break;
+
+ case CS_AUTHRESET:
+ ctl_putuint(sys_var[varid].text,
+ current_time - auth_timereset);
+ break;
+
+ /*
+ * CTL_IF_KERNLOOP() puts a zero if the kernel loop is
+ * unavailable, otherwise calls putfunc with args.
+ */
+#ifndef KERNEL_PLL
+# define CTL_IF_KERNLOOP(putfunc, args) \
+ ctl_putint(sys_var[varid].text, 0)
+#else
+# define CTL_IF_KERNLOOP(putfunc, args) \
+ putfunc args
+#endif
+
+ /*
+ * CTL_IF_KERNPPS() puts a zero if either the kernel
+ * loop is unavailable, or kernel hard PPS is not
+ * active, otherwise calls putfunc with args.
+ */
+#ifndef KERNEL_PLL
+# define CTL_IF_KERNPPS(putfunc, args) \
+ ctl_putint(sys_var[varid].text, 0)
+#else
+# define CTL_IF_KERNPPS(putfunc, args) \
+ if (0 == ntx.shift) \
+ ctl_putint(sys_var[varid].text, 0); \
+ else \
+ putfunc args /* no trailing ; */
+#endif
+
+ case CS_K_OFFSET:
+ CTL_IF_KERNLOOP(
+ ctl_putdblf,
+ (sys_var[varid].text, 0, -1, to_ms_nusec * ntx.offset)
+ );
+ break;
+
+ case CS_K_FREQ:
+ CTL_IF_KERNLOOP(
+ ctl_putsfp,
+ (sys_var[varid].text, ntx.freq)
+ );
+ break;
+
+ case CS_K_MAXERR:
+ CTL_IF_KERNLOOP(
+ ctl_putdblf,
+ (sys_var[varid].text, 0, 6,
+ to_ms_usec * ntx.maxerror)
+ );
+ break;
+
+ case CS_K_ESTERR:
+ CTL_IF_KERNLOOP(
+ ctl_putdblf,
+ (sys_var[varid].text, 0, 6,
+ to_ms_usec * ntx.esterror)
+ );
+ break;
+
+ case CS_K_STFLAGS:
+#ifndef KERNEL_PLL
+ ss = "";
+#else
+ ss = k_st_flags(ntx.status);
+#endif
+ ctl_putstr(sys_var[varid].text, ss, strlen(ss));
+ break;
+
+ case CS_K_TIMECONST:
+ CTL_IF_KERNLOOP(
+ ctl_putint,
+ (sys_var[varid].text, ntx.constant)
+ );
+ break;
+
+ case CS_K_PRECISION:
+ CTL_IF_KERNLOOP(
+ ctl_putdblf,
+ (sys_var[varid].text, 0, 6,
+ to_ms_usec * ntx.precision)
+ );
+ break;
+
+ case CS_K_FREQTOL:
+ CTL_IF_KERNLOOP(
+ ctl_putsfp,
+ (sys_var[varid].text, ntx.tolerance)
+ );
+ break;
+
+ case CS_K_PPS_FREQ:
+ CTL_IF_KERNPPS(
+ ctl_putsfp,
+ (sys_var[varid].text, ntx.ppsfreq)
+ );
+ break;
+
+ case CS_K_PPS_STABIL:
+ CTL_IF_KERNPPS(
+ ctl_putsfp,
+ (sys_var[varid].text, ntx.stabil)
+ );
+ break;
+
+ case CS_K_PPS_JITTER:
+ CTL_IF_KERNPPS(
+ ctl_putdbl,
+ (sys_var[varid].text, to_ms_nusec * ntx.jitter)
+ );
+ break;
+
+ case CS_K_PPS_CALIBDUR:
+ CTL_IF_KERNPPS(
+ ctl_putint,
+ (sys_var[varid].text, 1 << ntx.shift)
+ );
+ break;
+
+ case CS_K_PPS_CALIBS:
+ CTL_IF_KERNPPS(
+ ctl_putint,
+ (sys_var[varid].text, ntx.calcnt)
+ );
+ break;
+
+ case CS_K_PPS_CALIBERRS:
+ CTL_IF_KERNPPS(
+ ctl_putint,
+ (sys_var[varid].text, ntx.errcnt)
+ );
+ break;
+
+ case CS_K_PPS_JITEXC:
+ CTL_IF_KERNPPS(
+ ctl_putint,
+ (sys_var[varid].text, ntx.jitcnt)
+ );
+ break;
+
+ case CS_K_PPS_STBEXC:
+ CTL_IF_KERNPPS(
+ ctl_putint,
+ (sys_var[varid].text, ntx.stbcnt)
+ );
+ break;
+
+ case CS_IOSTATS_RESET:
+ ctl_putuint(sys_var[varid].text,
+ current_time - io_timereset);
+ break;
+
+ case CS_TOTAL_RBUF:
+ ctl_putuint(sys_var[varid].text, total_recvbuffs());
+ break;
+
+ case CS_FREE_RBUF:
+ ctl_putuint(sys_var[varid].text, free_recvbuffs());
+ break;
+
+ case CS_USED_RBUF:
+ ctl_putuint(sys_var[varid].text, full_recvbuffs());
+ break;
+
+ case CS_RBUF_LOWATER:
+ ctl_putuint(sys_var[varid].text, lowater_additions());
+ break;
+
+ case CS_IO_DROPPED:
+ ctl_putuint(sys_var[varid].text, packets_dropped);
+ break;
+
+ case CS_IO_IGNORED:
+ ctl_putuint(sys_var[varid].text, packets_ignored);
+ break;
+
+ case CS_IO_RECEIVED:
+ ctl_putuint(sys_var[varid].text, packets_received);
+ break;
+
+ case CS_IO_SENT:
+ ctl_putuint(sys_var[varid].text, packets_sent);
+ break;
+
+ case CS_IO_SENDFAILED:
+ ctl_putuint(sys_var[varid].text, packets_notsent);
+ break;
+
+ case CS_IO_WAKEUPS:
+ ctl_putuint(sys_var[varid].text, handler_calls);
+ break;
+
+ case CS_IO_GOODWAKEUPS:
+ ctl_putuint(sys_var[varid].text, handler_pkts);
+ break;
+
+ case CS_TIMERSTATS_RESET:
+ ctl_putuint(sys_var[varid].text,
+ current_time - timer_timereset);
+ break;
+
+ case CS_TIMER_OVERRUNS:
+ ctl_putuint(sys_var[varid].text, alarm_overflow);
+ break;
+
+ case CS_TIMER_XMTS:
+ ctl_putuint(sys_var[varid].text, timer_xmtcalls);
+ break;
+
+ case CS_FUZZ:
+ ctl_putdbl(sys_var[varid].text, sys_fuzz * 1e3);
+ break;
+ case CS_WANDER_THRESH:
+ ctl_putdbl(sys_var[varid].text, wander_threshold * 1e6);
+ break;
+#ifdef AUTOKEY
+ case CS_FLAGS:
+ if (crypto_flags)
+ ctl_puthex(sys_var[CS_FLAGS].text,
+ crypto_flags);
+ break;
+
+ case CS_DIGEST:
+ if (crypto_flags) {
+ strlcpy(str, OBJ_nid2ln(crypto_nid),
+ COUNTOF(str));
+ ctl_putstr(sys_var[CS_DIGEST].text, str,
+ strlen(str));
+ }
+ break;
+
+ case CS_SIGNATURE:
+ if (crypto_flags) {
+ const EVP_MD *dp;
+
+ dp = EVP_get_digestbynid(crypto_flags >> 16);
+ strlcpy(str, OBJ_nid2ln(EVP_MD_pkey_type(dp)),
+ COUNTOF(str));
+ ctl_putstr(sys_var[CS_SIGNATURE].text, str,
+ strlen(str));
+ }
+ break;
+
+ case CS_HOST:
+ if (hostval.ptr != NULL)
+ ctl_putstr(sys_var[CS_HOST].text, hostval.ptr,
+ strlen(hostval.ptr));
+ break;
+
+ case CS_IDENT:
+ if (sys_ident != NULL)
+ ctl_putstr(sys_var[CS_IDENT].text, sys_ident,
+ strlen(sys_ident));
+ break;
+
+ case CS_CERTIF:
+ for (cp = cinfo; cp != NULL; cp = cp->link) {
+ snprintf(str, sizeof(str), "%s %s 0x%x",
+ cp->subject, cp->issuer, cp->flags);
+ ctl_putstr(sys_var[CS_CERTIF].text, str,
+ strlen(str));
+ ctl_putcal(sys_var[CS_REVTIME].text, &(cp->last));
+ }
+ break;
+
+ case CS_PUBLIC:
+ if (hostval.tstamp != 0)
+ ctl_putfs(sys_var[CS_PUBLIC].text,
+ ntohl(hostval.tstamp));
+ break;
+#endif /* AUTOKEY */
+
+ default:
+ break;
+ }
+}
+
+
+/*
+ * ctl_putpeer - output a peer variable
+ */
+static void
+ctl_putpeer(
+ int id,
+ struct peer *p
+ )
+{
+ char buf[CTL_MAX_DATA_LEN];
+ char *s;
+ char *t;
+ char *be;
+ int i;
+ const struct ctl_var *k;
+#ifdef AUTOKEY
+ struct autokey *ap;
+ const EVP_MD *dp;
+ const char *str;
+#endif /* AUTOKEY */
+
+ switch (id) {
+
+ case CP_CONFIG:
+ ctl_putuint(peer_var[id].text,
+ !(FLAG_PREEMPT & p->flags));
+ break;
+
+ case CP_AUTHENABLE:
+ ctl_putuint(peer_var[id].text, !(p->keyid));
+ break;
+
+ case CP_AUTHENTIC:
+ ctl_putuint(peer_var[id].text,
+ !!(FLAG_AUTHENTIC & p->flags));
+ break;
+
+ case CP_SRCADR:
+ ctl_putadr(peer_var[id].text, 0, &p->srcadr);
+ break;
+
+ case CP_SRCPORT:
+ ctl_putuint(peer_var[id].text, SRCPORT(&p->srcadr));
+ break;
+
+ case CP_SRCHOST:
+ if (p->hostname != NULL)
+ ctl_putstr(peer_var[id].text, p->hostname,
+ strlen(p->hostname));
+ break;
+
+ case CP_DSTADR:
+ ctl_putadr(peer_var[id].text, 0,
+ (p->dstadr != NULL)
+ ? &p->dstadr->sin
+ : NULL);
+ break;
+
+ case CP_DSTPORT:
+ ctl_putuint(peer_var[id].text,
+ (p->dstadr != NULL)
+ ? SRCPORT(&p->dstadr->sin)
+ : 0);
+ break;
+
+ case CP_IN:
+ if (p->r21 > 0.)
+ ctl_putdbl(peer_var[id].text, p->r21 / 1e3);
+ break;
+
+ case CP_OUT:
+ if (p->r34 > 0.)
+ ctl_putdbl(peer_var[id].text, p->r34 / 1e3);
+ break;
+
+ case CP_RATE:
+ ctl_putuint(peer_var[id].text, p->throttle);
+ break;
+
+ case CP_LEAP:
+ ctl_putuint(peer_var[id].text, p->leap);
+ break;
+
+ case CP_HMODE:
+ ctl_putuint(peer_var[id].text, p->hmode);
+ break;
+
+ case CP_STRATUM:
+ ctl_putuint(peer_var[id].text, p->stratum);
+ break;
+
+ case CP_PPOLL:
+ ctl_putuint(peer_var[id].text, p->ppoll);
+ break;
+
+ case CP_HPOLL:
+ ctl_putuint(peer_var[id].text, p->hpoll);
+ break;
+
+ case CP_PRECISION:
+ ctl_putint(peer_var[id].text, p->precision);
+ break;
+
+ case CP_ROOTDELAY:
+ ctl_putdbl(peer_var[id].text, p->rootdelay * 1e3);
+ break;
+
+ case CP_ROOTDISPERSION:
+ ctl_putdbl(peer_var[id].text, p->rootdisp * 1e3);
+ break;
+
+ case CP_REFID:
+#ifdef REFCLOCK
+ if (p->flags & FLAG_REFCLOCK) {
+ ctl_putrefid(peer_var[id].text, p->refid);
+ break;
+ }
+#endif
+ if (REFID_ISTEXT(p->stratum))
+ ctl_putrefid(peer_var[id].text, p->refid);
+ else
+ ctl_putadr(peer_var[id].text, p->refid, NULL);
+ break;
+
+ case CP_REFTIME:
+ ctl_putts(peer_var[id].text, &p->reftime);
+ break;
+
+ case CP_ORG:
+ ctl_putts(peer_var[id].text, &p->aorg);
+ break;
+
+ case CP_REC:
+ ctl_putts(peer_var[id].text, &p->dst);
+ break;
+
+ case CP_XMT:
+ if (p->xleave)
+ ctl_putdbl(peer_var[id].text, p->xleave * 1e3);
+ break;
+
+ case CP_BIAS:
+ if (p->bias != 0.)
+ ctl_putdbl(peer_var[id].text, p->bias * 1e3);
+ break;
+
+ case CP_REACH:
+ ctl_puthex(peer_var[id].text, p->reach);
+ break;
+
+ case CP_FLASH:
+ ctl_puthex(peer_var[id].text, p->flash);
+ break;
+
+ case CP_TTL:
+#ifdef REFCLOCK
+ if (p->flags & FLAG_REFCLOCK) {
+ ctl_putuint(peer_var[id].text, p->ttl);
+ break;
+ }
+#endif
+ if (p->ttl > 0 && p->ttl < COUNTOF(sys_ttl))
+ ctl_putint(peer_var[id].text,
+ sys_ttl[p->ttl]);
+ break;
+
+ case CP_UNREACH:
+ ctl_putuint(peer_var[id].text, p->unreach);
+ break;
+
+ case CP_TIMER:
+ ctl_putuint(peer_var[id].text,
+ p->nextdate - current_time);
+ break;
+
+ case CP_DELAY:
+ ctl_putdbl(peer_var[id].text, p->delay * 1e3);
+ break;
+
+ case CP_OFFSET:
+ ctl_putdbl(peer_var[id].text, p->offset * 1e3);
+ break;
+
+ case CP_JITTER:
+ ctl_putdbl(peer_var[id].text, p->jitter * 1e3);
+ break;
+
+ case CP_DISPERSION:
+ ctl_putdbl(peer_var[id].text, p->disp * 1e3);
+ break;
+
+ case CP_KEYID:
+ if (p->keyid > NTP_MAXKEY)
+ ctl_puthex(peer_var[id].text, p->keyid);
+ else
+ ctl_putuint(peer_var[id].text, p->keyid);
+ break;
+
+ case CP_FILTDELAY:
+ ctl_putarray(peer_var[id].text, p->filter_delay,
+ p->filter_nextpt);
+ break;
+
+ case CP_FILTOFFSET:
+ ctl_putarray(peer_var[id].text, p->filter_offset,
+ p->filter_nextpt);
+ break;
+
+ case CP_FILTERROR:
+ ctl_putarray(peer_var[id].text, p->filter_disp,
+ p->filter_nextpt);
+ break;
+
+ case CP_PMODE:
+ ctl_putuint(peer_var[id].text, p->pmode);
+ break;
+
+ case CP_RECEIVED:
+ ctl_putuint(peer_var[id].text, p->received);
+ break;
+
+ case CP_SENT:
+ ctl_putuint(peer_var[id].text, p->sent);
+ break;
+
+ case CP_VARLIST:
+ s = buf;
+ be = buf + sizeof(buf);
+ if (strlen(peer_var[id].text) + 4 > sizeof(buf))
+ break; /* really long var name */
+
+ snprintf(s, sizeof(buf), "%s=\"", peer_var[id].text);
+ s += strlen(s);
+ t = s;
+ for (k = peer_var; !(EOV & k->flags); k++) {
+ if (PADDING & k->flags)
+ continue;
+ i = strlen(k->text);
+ if (s + i + 1 >= be)
+ break;
+ if (s != t)
+ *s++ = ',';
+ memcpy(s, k->text, i);
+ s += i;
+ }
+ if (s + 2 < be) {
+ *s++ = '"';
+ *s = '\0';
+ ctl_putdata(buf, (u_int)(s - buf), 0);
+ }
+ break;
+
+ case CP_TIMEREC:
+ ctl_putuint(peer_var[id].text,
+ current_time - p->timereceived);
+ break;
+
+ case CP_TIMEREACH:
+ ctl_putuint(peer_var[id].text,
+ current_time - p->timereachable);
+ break;
+
+ case CP_BADAUTH:
+ ctl_putuint(peer_var[id].text, p->badauth);
+ break;
+
+ case CP_BOGUSORG:
+ ctl_putuint(peer_var[id].text, p->bogusorg);
+ break;
+
+ case CP_OLDPKT:
+ ctl_putuint(peer_var[id].text, p->oldpkt);
+ break;
+
+ case CP_SELDISP:
+ ctl_putuint(peer_var[id].text, p->seldisptoolarge);
+ break;
+
+ case CP_SELBROKEN:
+ ctl_putuint(peer_var[id].text, p->selbroken);
+ break;
+
+ case CP_CANDIDATE:
+ ctl_putuint(peer_var[id].text, p->status);
+ break;
+#ifdef AUTOKEY
+ case CP_FLAGS:
+ if (p->crypto)
+ ctl_puthex(peer_var[id].text, p->crypto);
+ break;
+
+ case CP_SIGNATURE:
+ if (p->crypto) {
+ dp = EVP_get_digestbynid(p->crypto >> 16);
+ str = OBJ_nid2ln(EVP_MD_pkey_type(dp));
+ ctl_putstr(peer_var[id].text, str, strlen(str));
+ }
+ break;
+
+ case CP_HOST:
+ if (p->subject != NULL)
+ ctl_putstr(peer_var[id].text, p->subject,
+ strlen(p->subject));
+ break;
+
+ case CP_VALID: /* not used */
+ break;
+
+ case CP_INITSEQ:
+ if (NULL == (ap = p->recval.ptr))
+ break;
+
+ ctl_putint(peer_var[CP_INITSEQ].text, ap->seq);
+ ctl_puthex(peer_var[CP_INITKEY].text, ap->key);
+ ctl_putfs(peer_var[CP_INITTSP].text,
+ ntohl(p->recval.tstamp));
+ break;
+
+ case CP_IDENT:
+ if (p->ident != NULL)
+ ctl_putstr(peer_var[id].text, p->ident,
+ strlen(p->ident));
+ break;
+
+
+#endif /* AUTOKEY */
+ }
+}
+
+
+#ifdef REFCLOCK
+/*
+ * ctl_putclock - output clock variables
+ */
+static void
+ctl_putclock(
+ int id,
+ struct refclockstat *pcs,
+ int mustput
+ )
+{
+ char buf[CTL_MAX_DATA_LEN];
+ char *s, *t, *be;
+ const char *ss;
+ int i;
+ const struct ctl_var *k;
+
+ switch (id) {
+
+ case CC_TYPE:
+ if (mustput || pcs->clockdesc == NULL
+ || *(pcs->clockdesc) == '\0') {
+ ctl_putuint(clock_var[id].text, pcs->type);
+ }
+ break;
+ case CC_TIMECODE:
+ ctl_putstr(clock_var[id].text,
+ pcs->p_lastcode,
+ (unsigned)pcs->lencode);
+ break;
+
+ case CC_POLL:
+ ctl_putuint(clock_var[id].text, pcs->polls);
+ break;
+
+ case CC_NOREPLY:
+ ctl_putuint(clock_var[id].text,
+ pcs->noresponse);
+ break;
+
+ case CC_BADFORMAT:
+ ctl_putuint(clock_var[id].text,
+ pcs->badformat);
+ break;
+
+ case CC_BADDATA:
+ ctl_putuint(clock_var[id].text,
+ pcs->baddata);
+ break;
+
+ case CC_FUDGETIME1:
+ if (mustput || (pcs->haveflags & CLK_HAVETIME1))
+ ctl_putdbl(clock_var[id].text,
+ pcs->fudgetime1 * 1e3);
+ break;
+
+ case CC_FUDGETIME2:
+ if (mustput || (pcs->haveflags & CLK_HAVETIME2))
+ ctl_putdbl(clock_var[id].text,
+ pcs->fudgetime2 * 1e3);
+ break;
+
+ case CC_FUDGEVAL1:
+ if (mustput || (pcs->haveflags & CLK_HAVEVAL1))
+ ctl_putint(clock_var[id].text,
+ pcs->fudgeval1);
+ break;
+
+ case CC_FUDGEVAL2:
+ if (mustput || (pcs->haveflags & CLK_HAVEVAL2)) {
+ if (pcs->fudgeval1 > 1)
+ ctl_putadr(clock_var[id].text,
+ pcs->fudgeval2, NULL);
+ else
+ ctl_putrefid(clock_var[id].text,
+ pcs->fudgeval2);
+ }
+ break;
+
+ case CC_FLAGS:
+ ctl_putuint(clock_var[id].text, pcs->flags);
+ break;
+
+ case CC_DEVICE:
+ if (pcs->clockdesc == NULL ||
+ *(pcs->clockdesc) == '\0') {
+ if (mustput)
+ ctl_putstr(clock_var[id].text,
+ "", 0);
+ } else {
+ ctl_putstr(clock_var[id].text,
+ pcs->clockdesc,
+ strlen(pcs->clockdesc));
+ }
+ break;
+
+ case CC_VARLIST:
+ s = buf;
+ be = buf + sizeof(buf);
+ if (strlen(clock_var[CC_VARLIST].text) + 4 >
+ sizeof(buf))
+ break; /* really long var name */
+
+ snprintf(s, sizeof(buf), "%s=\"",
+ clock_var[CC_VARLIST].text);
+ s += strlen(s);
+ t = s;
+
+ for (k = clock_var; !(EOV & k->flags); k++) {
+ if (PADDING & k->flags)
+ continue;
+
+ i = strlen(k->text);
+ if (s + i + 1 >= be)
+ break;
+
+ if (s != t)
+ *s++ = ',';
+ memcpy(s, k->text, i);
+ s += i;
+ }
+
+ for (k = pcs->kv_list; k && !(EOV & k->flags); k++) {
+ if (PADDING & k->flags)
+ continue;
+
+ ss = k->text;
+ if (NULL == ss)
+ continue;
+
+ while (*ss && *ss != '=')
+ ss++;
+ i = ss - k->text;
+ if (s + i + 1 >= be)
+ break;
+
+ if (s != t)
+ *s++ = ',';
+ memcpy(s, k->text, (unsigned)i);
+ s += i;
+ *s = '\0';
+ }
+ if (s + 2 >= be)
+ break;
+
+ *s++ = '"';
+ *s = '\0';
+ ctl_putdata(buf, (unsigned)(s - buf), 0);
+ break;
+ }
+}
+#endif
+
+
+
+/*
+ * ctl_getitem - get the next data item from the incoming packet
+ */
+static const struct ctl_var *
+ctl_getitem(
+ const struct ctl_var *var_list,
+ char **data
+ )
+{
+ /* [Bug 3008] First check the packet data sanity, then search
+ * the key. This improves the consistency of result values: If
+ * the result is NULL once, it will never be EOV again for this
+ * packet; If it's EOV, it will never be NULL again until the
+ * variable is found and processed in a given 'var_list'. (That
+ * is, a result is returned that is neither NULL nor EOV).
+ */
+ static const struct ctl_var eol = { 0, EOV, NULL };
+ static char buf[128];
+ static u_long quiet_until;
+ const struct ctl_var *v;
+ char *cp;
+ char *tp;
+
+ /*
+ * Part One: Validate the packet state
+ */
+
+ /* Delete leading commas and white space */
+ while (reqpt < reqend && (*reqpt == ',' ||
+ isspace((unsigned char)*reqpt)))
+ reqpt++;
+ if (reqpt >= reqend)
+ return NULL;
+
+ /* Scan the string in the packet until we hit comma or
+ * EoB. Register position of first '=' on the fly. */
+ for (tp = NULL, cp = reqpt; cp != reqend; ++cp) {
+ if (*cp == '=' && tp == NULL)
+ tp = cp;
+ if (*cp == ',')
+ break;
+ }
+
+ /* Process payload, if any. */
+ *data = NULL;
+ if (NULL != tp) {
+ /* eventually strip white space from argument. */
+ const char *plhead = tp + 1; /* skip the '=' */
+ const char *pltail = cp;
+ size_t plsize;
+
+ while (plhead != pltail && isspace((u_char)plhead[0]))
+ ++plhead;
+ while (plhead != pltail && isspace((u_char)pltail[-1]))
+ --pltail;
+
+ /* check payload size, terminate packet on overflow */
+ plsize = (size_t)(pltail - plhead);
+ if (plsize >= sizeof(buf))
+ goto badpacket;
+
+ /* copy data, NUL terminate, and set result data ptr */
+ memcpy(buf, plhead, plsize);
+ buf[plsize] = '\0';
+ *data = buf;
+ } else {
+ /* no payload, current end --> current name termination */
+ tp = cp;
+ }
+
+ /* Part Two
+ *
+ * Now we're sure that the packet data itself is sane. Scan the
+ * list now. Make sure a NULL list is properly treated by
+ * returning a synthetic End-Of-Values record. We must not
+ * return NULL pointers after this point, or the behaviour would
+ * become inconsistent if called several times with different
+ * variable lists after an EoV was returned. (Such a behavior
+ * actually caused Bug 3008.)
+ */
+
+ if (NULL == var_list)
+ return &eol;
+
+ for (v = var_list; !(EOV & v->flags); ++v)
+ if (!(PADDING & v->flags)) {
+ /* Check if the var name matches the buffer. The
+ * name is bracketed by [reqpt..tp] and not NUL
+ * terminated, and it contains no '=' char. The
+ * lookup value IS NUL-terminated but might
+ * include a '='... We have to look out for
+ * that!
+ */
+ const char *sp1 = reqpt;
+ const char *sp2 = v->text;
+
+ /* [Bug 3412] do not compare past NUL byte in name */
+ while ( (sp1 != tp)
+ && ('\0' != *sp2) && (*sp1 == *sp2)) {
+ ++sp1;
+ ++sp2;
+ }
+ if (sp1 == tp && (*sp2 == '\0' || *sp2 == '='))
+ break;
+ }
+
+ /* See if we have found a valid entry or not. If found, advance
+ * the request pointer for the next round; if not, clear the
+ * data pointer so we have no dangling garbage here.
+ */
+ if (EOV & v->flags)
+ *data = NULL;
+ else
+ reqpt = cp + (cp != reqend);
+ return v;
+
+ badpacket:
+ /*TODO? somehow indicate this packet was bad, apart from syslog? */
+ numctlbadpkts++;
+ NLOG(NLOG_SYSEVENT)
+ if (quiet_until <= current_time) {
+ quiet_until = current_time + 300;
+ msyslog(LOG_WARNING,
+ "Possible 'ntpdx' exploit from %s#%u (possibly spoofed)",
+ stoa(rmt_addr), SRCPORT(rmt_addr));
+ }
+ reqpt = reqend; /* never again for this packet! */
+ return NULL;
+}
+
+
+/*
+ * control_unspec - response to an unspecified op-code
+ */
+/*ARGSUSED*/
+static void
+control_unspec(
+ struct recvbuf *rbufp,
+ int restrict_mask
+ )
+{
+ struct peer *peer;
+
+ /*
+ * What is an appropriate response to an unspecified op-code?
+ * I return no errors and no data, unless a specified assocation
+ * doesn't exist.
+ */
+ if (res_associd) {
+ peer = findpeerbyassoc(res_associd);
+ if (NULL == peer) {
+ ctl_error(CERR_BADASSOC);
+ return;
+ }
+ rpkt.status = htons(ctlpeerstatus(peer));
+ } else
+ rpkt.status = htons(ctlsysstatus());
+ ctl_flushpkt(0);
+}
+
+
+/*
+ * read_status - return either a list of associd's, or a particular
+ * peer's status.
+ */
+/*ARGSUSED*/
+static void
+read_status(
+ struct recvbuf *rbufp,
+ int restrict_mask
+ )
+{
+ struct peer *peer;
+ const u_char *cp;
+ size_t n;
+ /* a_st holds association ID, status pairs alternating */
+ u_short a_st[CTL_MAX_DATA_LEN / sizeof(u_short)];
+
+#ifdef DEBUG
+ if (debug > 2)
+ printf("read_status: ID %d\n", res_associd);
+#endif
+ /*
+ * Two choices here. If the specified association ID is
+ * zero we return all known assocation ID's. Otherwise
+ * we return a bunch of stuff about the particular peer.
+ */
+ if (res_associd) {
+ peer = findpeerbyassoc(res_associd);
+ if (NULL == peer) {
+ ctl_error(CERR_BADASSOC);
+ return;
+ }
+ rpkt.status = htons(ctlpeerstatus(peer));
+ if (res_authokay)
+ peer->num_events = 0;
+ /*
+ * For now, output everything we know about the
+ * peer. May be more selective later.
+ */
+ for (cp = def_peer_var; *cp != 0; cp++)
+ ctl_putpeer((int)*cp, peer);
+ ctl_flushpkt(0);
+ return;
+ }
+ n = 0;
+ rpkt.status = htons(ctlsysstatus());
+ for (peer = peer_list; peer != NULL; peer = peer->p_link) {
+ a_st[n++] = htons(peer->associd);
+ a_st[n++] = htons(ctlpeerstatus(peer));
+ /* two entries each loop iteration, so n + 1 */
+ if (n + 1 >= COUNTOF(a_st)) {
+ ctl_putdata((void *)a_st, n * sizeof(a_st[0]),
+ 1);
+ n = 0;
+ }
+ }
+ if (n)
+ ctl_putdata((void *)a_st, n * sizeof(a_st[0]), 1);
+ ctl_flushpkt(0);
+}
+
+
+/*
+ * read_peervars - half of read_variables() implementation
+ */
+static void
+read_peervars(void)
+{
+ const struct ctl_var *v;
+ struct peer *peer;
+ const u_char *cp;
+ size_t i;
+ char * valuep;
+ u_char wants[CP_MAXCODE + 1];
+ u_int gotvar;
+
+ /*
+ * Wants info for a particular peer. See if we know
+ * the guy.
+ */
+ peer = findpeerbyassoc(res_associd);
+ if (NULL == peer) {
+ ctl_error(CERR_BADASSOC);
+ return;
+ }
+ rpkt.status = htons(ctlpeerstatus(peer));
+ if (res_authokay)
+ peer->num_events = 0;
+ ZERO(wants);
+ gotvar = 0;
+ while (NULL != (v = ctl_getitem(peer_var, &valuep))) {
+ if (v->flags & EOV) {
+ ctl_error(CERR_UNKNOWNVAR);
+ return;
+ }
+ INSIST(v->code < COUNTOF(wants));
+ wants[v->code] = 1;
+ gotvar = 1;
+ }
+ if (gotvar) {
+ for (i = 1; i < COUNTOF(wants); i++)
+ if (wants[i])
+ ctl_putpeer(i, peer);
+ } else
+ for (cp = def_peer_var; *cp != 0; cp++)
+ ctl_putpeer((int)*cp, peer);
+ ctl_flushpkt(0);
+}
+
+
+/*
+ * read_sysvars - half of read_variables() implementation
+ */
+static void
+read_sysvars(void)
+{
+ const struct ctl_var *v;
+ struct ctl_var *kv;
+ u_int n;
+ u_int gotvar;
+ const u_char *cs;
+ char * valuep;
+ const char * pch;
+ u_char *wants;
+ size_t wants_count;
+
+ /*
+ * Wants system variables. Figure out which he wants
+ * and give them to him.
+ */
+ rpkt.status = htons(ctlsysstatus());
+ if (res_authokay)
+ ctl_sys_num_events = 0;
+ wants_count = CS_MAXCODE + 1 + count_var(ext_sys_var);
+ wants = emalloc_zero(wants_count);
+ gotvar = 0;
+ while (NULL != (v = ctl_getitem(sys_var, &valuep))) {
+ if (!(EOV & v->flags)) {
+ INSIST(v->code < wants_count);
+ wants[v->code] = 1;
+ gotvar = 1;
+ } else {
+ v = ctl_getitem(ext_sys_var, &valuep);
+ if (NULL == v) {
+ ctl_error(CERR_BADVALUE);
+ free(wants);
+ return;
+ }
+ if (EOV & v->flags) {
+ ctl_error(CERR_UNKNOWNVAR);
+ free(wants);
+ return;
+ }
+ n = v->code + CS_MAXCODE + 1;
+ INSIST(n < wants_count);
+ wants[n] = 1;
+ gotvar = 1;
+ }
+ }
+ if (gotvar) {
+ for (n = 1; n <= CS_MAXCODE; n++)
+ if (wants[n])
+ ctl_putsys(n);
+ for (n = 0; n + CS_MAXCODE + 1 < wants_count; n++)
+ if (wants[n + CS_MAXCODE + 1]) {
+ pch = ext_sys_var[n].text;
+ ctl_putdata(pch, strlen(pch), 0);
+ }
+ } else {
+ for (cs = def_sys_var; *cs != 0; cs++)
+ ctl_putsys((int)*cs);
+ for (kv = ext_sys_var; kv && !(EOV & kv->flags); kv++)
+ if (DEF & kv->flags)
+ ctl_putdata(kv->text, strlen(kv->text),
+ 0);
+ }
+ free(wants);
+ ctl_flushpkt(0);
+}
+
+
+/*
+ * read_variables - return the variables the caller asks for
+ */
+/*ARGSUSED*/
+static void
+read_variables(
+ struct recvbuf *rbufp,
+ int restrict_mask
+ )
+{
+ if (res_associd)
+ read_peervars();
+ else
+ read_sysvars();
+}
+
+
+/*
+ * write_variables - write into variables. We only allow leap bit
+ * writing this way.
+ */
+/*ARGSUSED*/
+static void
+write_variables(
+ struct recvbuf *rbufp,
+ int restrict_mask
+ )
+{
+ const struct ctl_var *v;
+ int ext_var;
+ char *valuep;
+ long val;
+ size_t octets;
+ char *vareqv;
+ const char *t;
+ char *tt;
+
+ val = 0;
+ /*
+ * If he's trying to write into a peer tell him no way
+ */
+ if (res_associd != 0) {
+ ctl_error(CERR_PERMISSION);
+ return;
+ }
+
+ /*
+ * Set status
+ */
+ rpkt.status = htons(ctlsysstatus());
+
+ /*
+ * Look through the variables. Dump out at the first sign of
+ * trouble.
+ */
+ while ((v = ctl_getitem(sys_var, &valuep)) != NULL) {
+ ext_var = 0;
+ if (v->flags & EOV) {
+ v = ctl_getitem(ext_sys_var, &valuep);
+ if (v != NULL) {
+ if (v->flags & EOV) {
+ ctl_error(CERR_UNKNOWNVAR);
+ return;
+ }
+ ext_var = 1;
+ } else {
+ break;
+ }
+ }
+ if (!(v->flags & CAN_WRITE)) {
+ ctl_error(CERR_PERMISSION);
+ return;
+ }
+ /* [bug 3565] writing makes sense only if we *have* a
+ * value in the packet!
+ */
+ if (valuep == NULL) {
+ ctl_error(CERR_BADFMT);
+ return;
+ }
+ if (!ext_var) {
+ if ( !(*valuep && atoint(valuep, &val))) {
+ ctl_error(CERR_BADFMT);
+ return;
+ }
+ if ((val & ~LEAP_NOTINSYNC) != 0) {
+ ctl_error(CERR_BADVALUE);
+ return;
+ }
+ }
+
+ if (ext_var) {
+ octets = strlen(v->text) + strlen(valuep) + 2;
+ vareqv = emalloc(octets);
+ tt = vareqv;
+ t = v->text;
+ while (*t && *t != '=')
+ *tt++ = *t++;
+ *tt++ = '=';
+ memcpy(tt, valuep, 1 + strlen(valuep));
+ set_sys_var(vareqv, 1 + strlen(vareqv), v->flags);
+ free(vareqv);
+ } else {
+ ctl_error(CERR_UNSPEC); /* really */
+ return;
+ }
+ }
+
+ /*
+ * If we got anything, do it. xxx nothing to do ***
+ */
+ /*
+ if (leapind != ~0 || leapwarn != ~0) {
+ if (!leap_setleap((int)leapind, (int)leapwarn)) {
+ ctl_error(CERR_PERMISSION);
+ return;
+ }
+ }
+ */
+ ctl_flushpkt(0);
+}
+
+
+/*
+ * configure() processes ntpq :config/config-from-file, allowing
+ * generic runtime reconfiguration.
+ */
+static void configure(
+ struct recvbuf *rbufp,
+ int restrict_mask
+ )
+{
+ size_t data_count;
+ int retval;
+
+ /* I haven't yet implemented changes to an existing association.
+ * Hence check if the association id is 0
+ */
+ if (res_associd != 0) {
+ ctl_error(CERR_BADVALUE);
+ return;
+ }
+
+ if (RES_NOMODIFY & restrict_mask) {
+ snprintf(remote_config.err_msg,
+ sizeof(remote_config.err_msg),
+ "runtime configuration prohibited by restrict ... nomodify");
+ ctl_putdata(remote_config.err_msg,
+ strlen(remote_config.err_msg), 0);
+ ctl_flushpkt(0);
+ NLOG(NLOG_SYSINFO)
+ msyslog(LOG_NOTICE,
+ "runtime config from %s rejected due to nomodify restriction",
+ stoa(&rbufp->recv_srcadr));
+ sys_restricted++;
+ return;
+ }
+
+ /* Initialize the remote config buffer */
+ data_count = remoteconfig_cmdlength(reqpt, reqend);
+
+ if (data_count > sizeof(remote_config.buffer) - 2) {
+ snprintf(remote_config.err_msg,
+ sizeof(remote_config.err_msg),
+ "runtime configuration failed: request too long");
+ ctl_putdata(remote_config.err_msg,
+ strlen(remote_config.err_msg), 0);
+ ctl_flushpkt(0);
+ msyslog(LOG_NOTICE,
+ "runtime config from %s rejected: request too long",
+ stoa(&rbufp->recv_srcadr));
+ return;
+ }
+ /* Bug 2853 -- check if all characters were acceptable */
+ if (data_count != (size_t)(reqend - reqpt)) {
+ snprintf(remote_config.err_msg,
+ sizeof(remote_config.err_msg),
+ "runtime configuration failed: request contains an unprintable character");
+ ctl_putdata(remote_config.err_msg,
+ strlen(remote_config.err_msg), 0);
+ ctl_flushpkt(0);
+ msyslog(LOG_NOTICE,
+ "runtime config from %s rejected: request contains an unprintable character: %0x",
+ stoa(&rbufp->recv_srcadr),
+ reqpt[data_count]);
+ return;
+ }
+
+ memcpy(remote_config.buffer, reqpt, data_count);
+ /* The buffer has no trailing linefeed or NUL right now. For
+ * logging, we do not want a newline, so we do that first after
+ * adding the necessary NUL byte.
+ */
+ remote_config.buffer[data_count] = '\0';
+ DPRINTF(1, ("Got Remote Configuration Command: %s\n",
+ remote_config.buffer));
+ msyslog(LOG_NOTICE, "%s config: %s",
+ stoa(&rbufp->recv_srcadr),
+ remote_config.buffer);
+
+ /* Now we have to make sure there is a NL/NUL sequence at the
+ * end of the buffer before we parse it.
+ */
+ remote_config.buffer[data_count++] = '\n';
+ remote_config.buffer[data_count] = '\0';
+ remote_config.pos = 0;
+ remote_config.err_pos = 0;
+ remote_config.no_errors = 0;
+ config_remotely(&rbufp->recv_srcadr);
+
+ /*
+ * Check if errors were reported. If not, output 'Config
+ * Succeeded'. Else output the error count. It would be nice
+ * to output any parser error messages.
+ */
+ if (0 == remote_config.no_errors) {
+ retval = snprintf(remote_config.err_msg,
+ sizeof(remote_config.err_msg),
+ "Config Succeeded");
+ if (retval > 0)
+ remote_config.err_pos += retval;
+ }
+
+ ctl_putdata(remote_config.err_msg, remote_config.err_pos, 0);
+ ctl_flushpkt(0);
+
+ DPRINTF(1, ("Reply: %s\n", remote_config.err_msg));
+
+ if (remote_config.no_errors > 0)
+ msyslog(LOG_NOTICE, "%d error in %s config",
+ remote_config.no_errors,
+ stoa(&rbufp->recv_srcadr));
+}
+
+
+/*
+ * derive_nonce - generate client-address-specific nonce value
+ * associated with a given timestamp.
+ */
+static u_int32 derive_nonce(
+ sockaddr_u * addr,
+ u_int32 ts_i,
+ u_int32 ts_f
+ )
+{
+ static u_int32 salt[4];
+ static u_long last_salt_update;
+ union d_tag {
+ u_char digest[EVP_MAX_MD_SIZE];
+ u_int32 extract;
+ } d;
+ EVP_MD_CTX *ctx;
+ u_int len;
+
+ while (!salt[0] || current_time - last_salt_update >= 3600) {
+ salt[0] = ntp_random();
+ salt[1] = ntp_random();
+ salt[2] = ntp_random();
+ salt[3] = ntp_random();
+ last_salt_update = current_time;
+ }
+
+ ctx = EVP_MD_CTX_new();
+# if defined(OPENSSL) && defined(EVP_MD_CTX_FLAG_NON_FIPS_ALLOW)
+ /* [Bug 3457] set flags and don't kill them again */
+ EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+ EVP_DigestInit_ex(ctx, EVP_get_digestbynid(NID_md5), NULL);
+# else
+ EVP_DigestInit(ctx, EVP_get_digestbynid(NID_md5));
+# endif
+ EVP_DigestUpdate(ctx, salt, sizeof(salt));
+ EVP_DigestUpdate(ctx, &ts_i, sizeof(ts_i));
+ EVP_DigestUpdate(ctx, &ts_f, sizeof(ts_f));
+ if (IS_IPV4(addr))
+ EVP_DigestUpdate(ctx, &SOCK_ADDR4(addr),
+ sizeof(SOCK_ADDR4(addr)));
+ else
+ EVP_DigestUpdate(ctx, &SOCK_ADDR6(addr),
+ sizeof(SOCK_ADDR6(addr)));
+ EVP_DigestUpdate(ctx, &NSRCPORT(addr), sizeof(NSRCPORT(addr)));
+ EVP_DigestUpdate(ctx, salt, sizeof(salt));
+ EVP_DigestFinal(ctx, d.digest, &len);
+ EVP_MD_CTX_free(ctx);
+
+ return d.extract;
+}
+
+
+/*
+ * generate_nonce - generate client-address-specific nonce string.
+ */
+static void generate_nonce(
+ struct recvbuf * rbufp,
+ char * nonce,
+ size_t nonce_octets
+ )
+{
+ u_int32 derived;
+
+ derived = derive_nonce(&rbufp->recv_srcadr,
+ rbufp->recv_time.l_ui,
+ rbufp->recv_time.l_uf);
+ snprintf(nonce, nonce_octets, "%08x%08x%08x",
+ rbufp->recv_time.l_ui, rbufp->recv_time.l_uf, derived);
+}
+
+
+/*
+ * validate_nonce - validate client-address-specific nonce string.
+ *
+ * Returns TRUE if the local calculation of the nonce matches the
+ * client-provided value and the timestamp is recent enough.
+ */
+static int validate_nonce(
+ const char * pnonce,
+ struct recvbuf * rbufp
+ )
+{
+ u_int ts_i;
+ u_int ts_f;
+ l_fp ts;
+ l_fp now_delta;
+ u_int supposed;
+ u_int derived;
+
+ if (3 != sscanf(pnonce, "%08x%08x%08x", &ts_i, &ts_f, &supposed))
+ return FALSE;
+
+ ts.l_ui = (u_int32)ts_i;
+ ts.l_uf = (u_int32)ts_f;
+ derived = derive_nonce(&rbufp->recv_srcadr, ts.l_ui, ts.l_uf);
+ get_systime(&now_delta);
+ L_SUB(&now_delta, &ts);
+
+ return (supposed == derived && now_delta.l_ui < 16);
+}
+
+
+/*
+ * send_random_tag_value - send a randomly-generated three character
+ * tag prefix, a '.', an index, a '=' and a
+ * random integer value.
+ *
+ * To try to force clients to ignore unrecognized tags in mrulist,
+ * reslist, and ifstats responses, the first and last rows are spiced
+ * with randomly-generated tag names with correct .# index. Make it
+ * three characters knowing that none of the currently-used subscripted
+ * tags have that length, avoiding the need to test for
+ * tag collision.
+ */
+static void
+send_random_tag_value(
+ int indx
+ )
+{
+ int noise;
+ char buf[32];
+
+ noise = rand() ^ (rand() << 16);
+ buf[0] = 'a' + noise % 26;
+ noise >>= 5;
+ buf[1] = 'a' + noise % 26;
+ noise >>= 5;
+ buf[2] = 'a' + noise % 26;
+ noise >>= 5;
+ buf[3] = '.';
+ snprintf(&buf[4], sizeof(buf) - 4, "%d", indx);
+ ctl_putuint(buf, noise);
+}
+
+
+/*
+ * Send a MRU list entry in response to a "ntpq -c mrulist" operation.
+ *
+ * To keep clients honest about not depending on the order of values,
+ * and thereby avoid being locked into ugly workarounds to maintain
+ * backward compatibility later as new fields are added to the response,
+ * the order is random.
+ */
+static void
+send_mru_entry(
+ mon_entry * mon,
+ int count
+ )
+{
+ const char first_fmt[] = "first.%d";
+ const char ct_fmt[] = "ct.%d";
+ const char mv_fmt[] = "mv.%d";
+ const char rs_fmt[] = "rs.%d";
+ char tag[32];
+ u_char sent[6]; /* 6 tag=value pairs */
+ u_int32 noise;
+ u_int which;
+ u_int remaining;
+ const char * pch;
+
+ remaining = COUNTOF(sent);
+ ZERO(sent);
+ noise = (u_int32)(rand() ^ (rand() << 16));
+ while (remaining > 0) {
+ which = (noise & 7) % COUNTOF(sent);
+ noise >>= 3;
+ while (sent[which])
+ which = (which + 1) % COUNTOF(sent);
+
+ switch (which) {
+
+ case 0:
+ snprintf(tag, sizeof(tag), addr_fmt, count);
+ pch = sptoa(&mon->rmtadr);
+ ctl_putunqstr(tag, pch, strlen(pch));
+ break;
+
+ case 1:
+ snprintf(tag, sizeof(tag), last_fmt, count);
+ ctl_putts(tag, &mon->last);
+ break;
+
+ case 2:
+ snprintf(tag, sizeof(tag), first_fmt, count);
+ ctl_putts(tag, &mon->first);
+ break;
+
+ case 3:
+ snprintf(tag, sizeof(tag), ct_fmt, count);
+ ctl_putint(tag, mon->count);
+ break;
+
+ case 4:
+ snprintf(tag, sizeof(tag), mv_fmt, count);
+ ctl_putuint(tag, mon->vn_mode);
+ break;
+
+ case 5:
+ snprintf(tag, sizeof(tag), rs_fmt, count);
+ ctl_puthex(tag, mon->flags);
+ break;
+ }
+ sent[which] = TRUE;
+ remaining--;
+ }
+}
+
+
+/*
+ * read_mru_list - supports ntpq's mrulist command.
+ *
+ * The challenge here is to match ntpdc's monlist functionality without
+ * being limited to hundreds of entries returned total, and without
+ * requiring state on the server. If state were required, ntpq's
+ * mrulist command would require authentication.
+ *
+ * The approach was suggested by Ry Jones. A finite and variable number
+ * of entries are retrieved per request, to avoid having responses with
+ * such large numbers of packets that socket buffers are overflowed and
+ * packets lost. The entries are retrieved oldest-first, taking into
+ * account that the MRU list will be changing between each request. We
+ * can expect to see duplicate entries for addresses updated in the MRU
+ * list during the fetch operation. In the end, the client can assemble
+ * a close approximation of the MRU list at the point in time the last
+ * response was sent by ntpd. The only difference is it may be longer,
+ * containing some number of oldest entries which have since been
+ * reclaimed. If necessary, the protocol could be extended to zap those
+ * from the client snapshot at the end, but so far that doesn't seem
+ * useful.
+ *
+ * To accomodate the changing MRU list, the starting point for requests
+ * after the first request is supplied as a series of last seen
+ * timestamps and associated addresses, the newest ones the client has
+ * received. As long as at least one of those entries hasn't been
+ * bumped to the head of the MRU list, ntpd can pick up at that point.
+ * Otherwise, the request is failed and it is up to ntpq to back up and
+ * provide the next newest entry's timestamps and addresses, conceivably
+ * backing up all the way to the starting point.
+ *
+ * input parameters:
+ * nonce= Regurgitated nonce retrieved by the client
+ * previously using CTL_OP_REQ_NONCE, demonstrating
+ * ability to receive traffic sent to its address.
+ * frags= Limit on datagrams (fragments) in response. Used
+ * by newer ntpq versions instead of limit= when
+ * retrieving multiple entries.
+ * limit= Limit on MRU entries returned. One of frags= or
+ * limit= must be provided.
+ * limit=1 is a special case: Instead of fetching
+ * beginning with the supplied starting point's
+ * newer neighbor, fetch the supplied entry, and
+ * in that case the #.last timestamp can be zero.
+ * This enables fetching a single entry by IP
+ * address. When limit is not one and frags= is
+ * provided, the fragment limit controls.
+ * mincount= (decimal) Return entries with count >= mincount.
+ * laddr= Return entries associated with the server's IP
+ * address given. No port specification is needed,
+ * and any supplied is ignored.
+ * resall= 0x-prefixed hex restrict bits which must all be
+ * lit for an MRU entry to be included.
+ * Has precedence over any resany=.
+ * resany= 0x-prefixed hex restrict bits, at least one of
+ * which must be list for an MRU entry to be
+ * included.
+ * last.0= 0x-prefixed hex l_fp timestamp of newest entry
+ * which client previously received.
+ * addr.0= text of newest entry's IP address and port,
+ * IPv6 addresses in bracketed form: [::]:123
+ * last.1= timestamp of 2nd newest entry client has.
+ * addr.1= address of 2nd newest entry.
+ * [...]
+ *
+ * ntpq provides as many last/addr pairs as will fit in a single request
+ * packet, except for the first request in a MRU fetch operation.
+ *
+ * The response begins with a new nonce value to be used for any
+ * followup request. Following the nonce is the next newer entry than
+ * referred to by last.0 and addr.0, if the "0" entry has not been
+ * bumped to the front. If it has, the first entry returned will be the
+ * next entry newer than referred to by last.1 and addr.1, and so on.
+ * If none of the referenced entries remain unchanged, the request fails
+ * and ntpq backs up to the next earlier set of entries to resync.
+ *
+ * Except for the first response, the response begins with confirmation
+ * of the entry that precedes the first additional entry provided:
+ *
+ * last.older= hex l_fp timestamp matching one of the input
+ * .last timestamps, which entry now precedes the
+ * response 0. entry in the MRU list.
+ * addr.older= text of address corresponding to older.last.
+ *
+ * And in any case, a successful response contains sets of values
+ * comprising entries, with the oldest numbered 0 and incrementing from
+ * there:
+ *
+ * addr.# text of IPv4 or IPv6 address and port
+ * last.# hex l_fp timestamp of last receipt
+ * first.# hex l_fp timestamp of first receipt
+ * ct.# count of packets received
+ * mv.# mode and version
+ * rs.# restriction mask (RES_* bits)
+ *
+ * Note the code currently assumes there are no valid three letter
+ * tags sent with each row, and needs to be adjusted if that changes.
+ *
+ * The client should accept the values in any order, and ignore .#
+ * values which it does not understand, to allow a smooth path to
+ * future changes without requiring a new opcode. Clients can rely
+ * on all *.0 values preceding any *.1 values, that is all values for
+ * a given index number are together in the response.
+ *
+ * The end of the response list is noted with one or two tag=value
+ * pairs. Unconditionally:
+ *
+ * now= 0x-prefixed l_fp timestamp at the server marking
+ * the end of the operation.
+ *
+ * If any entries were returned, now= is followed by:
+ *
+ * last.newest= hex l_fp identical to last.# of the prior
+ * entry.
+ */
+static void read_mru_list(
+ struct recvbuf *rbufp,
+ int restrict_mask
+ )
+{
+ static const char nulltxt[1] = { '\0' };
+ static const char nonce_text[] = "nonce";
+ static const char frags_text[] = "frags";
+ static const char limit_text[] = "limit";
+ static const char mincount_text[] = "mincount";
+ static const char resall_text[] = "resall";
+ static const char resany_text[] = "resany";
+ static const char maxlstint_text[] = "maxlstint";
+ static const char laddr_text[] = "laddr";
+ static const char resaxx_fmt[] = "0x%hx";
+
+ u_int limit;
+ u_short frags;
+ u_short resall;
+ u_short resany;
+ int mincount;
+ u_int maxlstint;
+ sockaddr_u laddr;
+ struct interface * lcladr;
+ u_int count;
+ u_int ui;
+ u_int uf;
+ l_fp last[16];
+ sockaddr_u addr[COUNTOF(last)];
+ char buf[128];
+ struct ctl_var * in_parms;
+ const struct ctl_var * v;
+ const char * val;
+ const char * pch;
+ char * pnonce;
+ int nonce_valid;
+ size_t i;
+ int priors;
+ u_short hash;
+ mon_entry * mon;
+ mon_entry * prior_mon;
+ l_fp now;
+
+ if (RES_NOMRULIST & restrict_mask) {
+ ctl_error(CERR_PERMISSION);
+ NLOG(NLOG_SYSINFO)
+ msyslog(LOG_NOTICE,
+ "mrulist from %s rejected due to nomrulist restriction",
+ stoa(&rbufp->recv_srcadr));
+ sys_restricted++;
+ return;
+ }
+ /*
+ * fill in_parms var list with all possible input parameters.
+ */
+ in_parms = NULL;
+ set_var(&in_parms, nonce_text, sizeof(nonce_text), 0);
+ set_var(&in_parms, frags_text, sizeof(frags_text), 0);
+ set_var(&in_parms, limit_text, sizeof(limit_text), 0);
+ set_var(&in_parms, mincount_text, sizeof(mincount_text), 0);
+ set_var(&in_parms, resall_text, sizeof(resall_text), 0);
+ set_var(&in_parms, resany_text, sizeof(resany_text), 0);
+ set_var(&in_parms, maxlstint_text, sizeof(maxlstint_text), 0);
+ set_var(&in_parms, laddr_text, sizeof(laddr_text), 0);
+ for (i = 0; i < COUNTOF(last); i++) {
+ snprintf(buf, sizeof(buf), last_fmt, (int)i);
+ set_var(&in_parms, buf, strlen(buf) + 1, 0);
+ snprintf(buf, sizeof(buf), addr_fmt, (int)i);
+ set_var(&in_parms, buf, strlen(buf) + 1, 0);
+ }
+
+ /* decode input parms */
+ pnonce = NULL;
+ frags = 0;
+ limit = 0;
+ mincount = 0;
+ resall = 0;
+ resany = 0;
+ maxlstint = 0;
+ lcladr = NULL;
+ priors = 0;
+ ZERO(last);
+ ZERO(addr);
+
+ /* have to go through '(void*)' to drop 'const' property from pointer.
+ * ctl_getitem()' needs some cleanup, too.... perlinger@ntp.org
+ */
+ while (NULL != (v = ctl_getitem(in_parms, (void*)&val)) &&
+ !(EOV & v->flags)) {
+ int si;
+
+ if (NULL == val)
+ val = nulltxt;
+
+ if (!strcmp(nonce_text, v->text)) {
+ free(pnonce);
+ pnonce = (*val) ? estrdup(val) : NULL;
+ } else if (!strcmp(frags_text, v->text)) {
+ if (1 != sscanf(val, "%hu", &frags))
+ goto blooper;
+ } else if (!strcmp(limit_text, v->text)) {
+ if (1 != sscanf(val, "%u", &limit))
+ goto blooper;
+ } else if (!strcmp(mincount_text, v->text)) {
+ if (1 != sscanf(val, "%d", &mincount))
+ goto blooper;
+ if (mincount < 0)
+ mincount = 0;
+ } else if (!strcmp(resall_text, v->text)) {
+ if (1 != sscanf(val, resaxx_fmt, &resall))
+ goto blooper;
+ } else if (!strcmp(resany_text, v->text)) {
+ if (1 != sscanf(val, resaxx_fmt, &resany))
+ goto blooper;
+ } else if (!strcmp(maxlstint_text, v->text)) {
+ if (1 != sscanf(val, "%u", &maxlstint))
+ goto blooper;
+ } else if (!strcmp(laddr_text, v->text)) {
+ if (!decodenetnum(val, &laddr))
+ goto blooper;
+ lcladr = getinterface(&laddr, 0);
+ } else if (1 == sscanf(v->text, last_fmt, &si) &&
+ (size_t)si < COUNTOF(last)) {
+ if (2 != sscanf(val, "0x%08x.%08x", &ui, &uf))
+ goto blooper;
+ last[si].l_ui = ui;
+ last[si].l_uf = uf;
+ if (!SOCK_UNSPEC(&addr[si]) && si == priors)
+ priors++;
+ } else if (1 == sscanf(v->text, addr_fmt, &si) &&
+ (size_t)si < COUNTOF(addr)) {
+ if (!decodenetnum(val, &addr[si]))
+ goto blooper;
+ if (last[si].l_ui && last[si].l_uf && si == priors)
+ priors++;
+ } else {
+ DPRINTF(1, ("read_mru_list: invalid key item: '%s' (ignored)\n",
+ v->text));
+ continue;
+
+ blooper:
+ DPRINTF(1, ("read_mru_list: invalid param for '%s': '%s' (bailing)\n",
+ v->text, val));
+ free(pnonce);
+ pnonce = NULL;
+ break;
+ }
+ }
+ free_varlist(in_parms);
+ in_parms = NULL;
+
+ /* return no responses until the nonce is validated */
+ if (NULL == pnonce)
+ return;
+
+ nonce_valid = validate_nonce(pnonce, rbufp);
+ free(pnonce);
+ if (!nonce_valid)
+ return;
+
+ if ((0 == frags && !(0 < limit && limit <= MRU_ROW_LIMIT)) ||
+ frags > MRU_FRAGS_LIMIT) {
+ ctl_error(CERR_BADVALUE);
+ return;
+ }
+
+ /*
+ * If either frags or limit is not given, use the max.
+ */
+ if (0 != frags && 0 == limit)
+ limit = UINT_MAX;
+ else if (0 != limit && 0 == frags)
+ frags = MRU_FRAGS_LIMIT;
+
+ /*
+ * Find the starting point if one was provided.
+ */
+ mon = NULL;
+ for (i = 0; i < (size_t)priors; i++) {
+ hash = MON_HASH(&addr[i]);
+ for (mon = mon_hash[hash];
+ mon != NULL;
+ mon = mon->hash_next)
+ if (ADDR_PORT_EQ(&mon->rmtadr, &addr[i]))
+ break;
+ if (mon != NULL) {
+ if (L_ISEQU(&mon->last, &last[i]))
+ break;
+ mon = NULL;
+ }
+ }
+
+ /* If a starting point was provided... */
+ if (priors) {
+ /* and none could be found unmodified... */
+ if (NULL == mon) {
+ /* tell ntpq to try again with older entries */
+ ctl_error(CERR_UNKNOWNVAR);
+ return;
+ }
+ /* confirm the prior entry used as starting point */
+ ctl_putts("last.older", &mon->last);
+ pch = sptoa(&mon->rmtadr);
+ ctl_putunqstr("addr.older", pch, strlen(pch));
+
+ /*
+ * Move on to the first entry the client doesn't have,
+ * except in the special case of a limit of one. In
+ * that case return the starting point entry.
+ */
+ if (limit > 1)
+ mon = PREV_DLIST(mon_mru_list, mon, mru);
+ } else { /* start with the oldest */
+ mon = TAIL_DLIST(mon_mru_list, mru);
+ }
+
+ /*
+ * send up to limit= entries in up to frags= datagrams
+ */
+ get_systime(&now);
+ generate_nonce(rbufp, buf, sizeof(buf));
+ ctl_putunqstr("nonce", buf, strlen(buf));
+ prior_mon = NULL;
+ for (count = 0;
+ mon != NULL && res_frags < frags && count < limit;
+ mon = PREV_DLIST(mon_mru_list, mon, mru)) {
+
+ if (mon->count < mincount)
+ continue;
+ if (resall && resall != (resall & mon->flags))
+ continue;
+ if (resany && !(resany & mon->flags))
+ continue;
+ if (maxlstint > 0 && now.l_ui - mon->last.l_ui >
+ maxlstint)
+ continue;
+ if (lcladr != NULL && mon->lcladr != lcladr)
+ continue;
+
+ send_mru_entry(mon, count);
+ if (!count)
+ send_random_tag_value(0);
+ count++;
+ prior_mon = mon;
+ }
+
+ /*
+ * If this batch completes the MRU list, say so explicitly with
+ * a now= l_fp timestamp.
+ */
+ if (NULL == mon) {
+ if (count > 1)
+ send_random_tag_value(count - 1);
+ ctl_putts("now", &now);
+ /* if any entries were returned confirm the last */
+ if (prior_mon != NULL)
+ ctl_putts("last.newest", &prior_mon->last);
+ }
+ ctl_flushpkt(0);
+}
+
+
+/*
+ * Send a ifstats entry in response to a "ntpq -c ifstats" request.
+ *
+ * To keep clients honest about not depending on the order of values,
+ * and thereby avoid being locked into ugly workarounds to maintain
+ * backward compatibility later as new fields are added to the response,
+ * the order is random.
+ */
+static void
+send_ifstats_entry(
+ endpt * la,
+ u_int ifnum
+ )
+{
+ const char addr_fmtu[] = "addr.%u";
+ const char bcast_fmt[] = "bcast.%u";
+ const char en_fmt[] = "en.%u"; /* enabled */
+ const char name_fmt[] = "name.%u";
+ const char flags_fmt[] = "flags.%u";
+ const char tl_fmt[] = "tl.%u"; /* ttl */
+ const char mc_fmt[] = "mc.%u"; /* mcast count */
+ const char rx_fmt[] = "rx.%u";
+ const char tx_fmt[] = "tx.%u";
+ const char txerr_fmt[] = "txerr.%u";
+ const char pc_fmt[] = "pc.%u"; /* peer count */
+ const char up_fmt[] = "up.%u"; /* uptime */
+ char tag[32];
+ u_char sent[IFSTATS_FIELDS]; /* 12 tag=value pairs */
+ int noisebits;
+ u_int32 noise;
+ u_int which;
+ u_int remaining;
+ const char *pch;
+
+ remaining = COUNTOF(sent);
+ ZERO(sent);
+ noise = 0;
+ noisebits = 0;
+ while (remaining > 0) {
+ if (noisebits < 4) {
+ noise = rand() ^ (rand() << 16);
+ noisebits = 31;
+ }
+ which = (noise & 0xf) % COUNTOF(sent);
+ noise >>= 4;
+ noisebits -= 4;
+
+ while (sent[which])
+ which = (which + 1) % COUNTOF(sent);
+
+ switch (which) {
+
+ case 0:
+ snprintf(tag, sizeof(tag), addr_fmtu, ifnum);
+ pch = sptoa(&la->sin);
+ ctl_putunqstr(tag, pch, strlen(pch));
+ break;
+
+ case 1:
+ snprintf(tag, sizeof(tag), bcast_fmt, ifnum);
+ if (INT_BCASTOPEN & la->flags)
+ pch = sptoa(&la->bcast);
+ else
+ pch = "";
+ ctl_putunqstr(tag, pch, strlen(pch));
+ break;
+
+ case 2:
+ snprintf(tag, sizeof(tag), en_fmt, ifnum);
+ ctl_putint(tag, !la->ignore_packets);
+ break;
+
+ case 3:
+ snprintf(tag, sizeof(tag), name_fmt, ifnum);
+ ctl_putstr(tag, la->name, strlen(la->name));
+ break;
+
+ case 4:
+ snprintf(tag, sizeof(tag), flags_fmt, ifnum);
+ ctl_puthex(tag, (u_int)la->flags);
+ break;
+
+ case 5:
+ snprintf(tag, sizeof(tag), tl_fmt, ifnum);
+ ctl_putint(tag, la->last_ttl);
+ break;
+
+ case 6:
+ snprintf(tag, sizeof(tag), mc_fmt, ifnum);
+ ctl_putint(tag, la->num_mcast);
+ break;
+
+ case 7:
+ snprintf(tag, sizeof(tag), rx_fmt, ifnum);
+ ctl_putint(tag, la->received);
+ break;
+
+ case 8:
+ snprintf(tag, sizeof(tag), tx_fmt, ifnum);
+ ctl_putint(tag, la->sent);
+ break;
+
+ case 9:
+ snprintf(tag, sizeof(tag), txerr_fmt, ifnum);
+ ctl_putint(tag, la->notsent);
+ break;
+
+ case 10:
+ snprintf(tag, sizeof(tag), pc_fmt, ifnum);
+ ctl_putuint(tag, la->peercnt);
+ break;
+
+ case 11:
+ snprintf(tag, sizeof(tag), up_fmt, ifnum);
+ ctl_putuint(tag, current_time - la->starttime);
+ break;
+ }
+ sent[which] = TRUE;
+ remaining--;
+ }
+ send_random_tag_value((int)ifnum);
+}
+
+
+/*
+ * read_ifstats - send statistics for each local address, exposed by
+ * ntpq -c ifstats
+ */
+static void
+read_ifstats(
+ struct recvbuf * rbufp
+ )
+{
+ u_int ifidx;
+ endpt * la;
+
+ /*
+ * loop over [0..sys_ifnum] searching ep_list for each
+ * ifnum in turn.
+ */
+ for (ifidx = 0; ifidx < sys_ifnum; ifidx++) {
+ for (la = ep_list; la != NULL; la = la->elink)
+ if (ifidx == la->ifnum)
+ break;
+ if (NULL == la)
+ continue;
+ /* return stats for one local address */
+ send_ifstats_entry(la, ifidx);
+ }
+ ctl_flushpkt(0);
+}
+
+static void
+sockaddrs_from_restrict_u(
+ sockaddr_u * psaA,
+ sockaddr_u * psaM,
+ restrict_u * pres,
+ int ipv6
+ )
+{
+ ZERO(*psaA);
+ ZERO(*psaM);
+ if (!ipv6) {
+ psaA->sa.sa_family = AF_INET;
+ psaA->sa4.sin_addr.s_addr = htonl(pres->u.v4.addr);
+ psaM->sa.sa_family = AF_INET;
+ psaM->sa4.sin_addr.s_addr = htonl(pres->u.v4.mask);
+ } else {
+ psaA->sa.sa_family = AF_INET6;
+ memcpy(&psaA->sa6.sin6_addr, &pres->u.v6.addr,
+ sizeof(psaA->sa6.sin6_addr));
+ psaM->sa.sa_family = AF_INET6;
+ memcpy(&psaM->sa6.sin6_addr, &pres->u.v6.mask,
+ sizeof(psaA->sa6.sin6_addr));
+ }
+}
+
+
+/*
+ * Send a restrict entry in response to a "ntpq -c reslist" request.
+ *
+ * To keep clients honest about not depending on the order of values,
+ * and thereby avoid being locked into ugly workarounds to maintain
+ * backward compatibility later as new fields are added to the response,
+ * the order is random.
+ */
+static void
+send_restrict_entry(
+ restrict_u * pres,
+ int ipv6,
+ u_int idx
+ )
+{
+ const char addr_fmtu[] = "addr.%u";
+ const char mask_fmtu[] = "mask.%u";
+ const char hits_fmt[] = "hits.%u";
+ const char flags_fmt[] = "flags.%u";
+ char tag[32];
+ u_char sent[RESLIST_FIELDS]; /* 4 tag=value pairs */
+ int noisebits;
+ u_int32 noise;
+ u_int which;
+ u_int remaining;
+ sockaddr_u addr;
+ sockaddr_u mask;
+ const char * pch;
+ char * buf;
+ const char * match_str;
+ const char * access_str;
+
+ sockaddrs_from_restrict_u(&addr, &mask, pres, ipv6);
+ remaining = COUNTOF(sent);
+ ZERO(sent);
+ noise = 0;
+ noisebits = 0;
+ while (remaining > 0) {
+ if (noisebits < 2) {
+ noise = rand() ^ (rand() << 16);
+ noisebits = 31;
+ }
+ which = (noise & 0x3) % COUNTOF(sent);
+ noise >>= 2;
+ noisebits -= 2;
+
+ while (sent[which])
+ which = (which + 1) % COUNTOF(sent);
+
+ /* XXX: Numbers? Really? */
+ switch (which) {
+
+ case 0:
+ snprintf(tag, sizeof(tag), addr_fmtu, idx);
+ pch = stoa(&addr);
+ ctl_putunqstr(tag, pch, strlen(pch));
+ break;
+
+ case 1:
+ snprintf(tag, sizeof(tag), mask_fmtu, idx);
+ pch = stoa(&mask);
+ ctl_putunqstr(tag, pch, strlen(pch));
+ break;
+
+ case 2:
+ snprintf(tag, sizeof(tag), hits_fmt, idx);
+ ctl_putuint(tag, pres->count);
+ break;
+
+ case 3:
+ snprintf(tag, sizeof(tag), flags_fmt, idx);
+ match_str = res_match_flags(pres->mflags);
+ access_str = res_access_flags(pres->rflags);
+ if ('\0' == match_str[0]) {
+ pch = access_str;
+ } else {
+ LIB_GETBUF(buf);
+ snprintf(buf, LIB_BUFLENGTH, "%s %s",
+ match_str, access_str);
+ pch = buf;
+ }
+ ctl_putunqstr(tag, pch, strlen(pch));
+ break;
+ }
+ sent[which] = TRUE;
+ remaining--;
+ }
+ send_random_tag_value((int)idx);
+}
+
+
+static void
+send_restrict_list(
+ restrict_u * pres,
+ int ipv6,
+ u_int * pidx
+ )
+{
+ for ( ; pres != NULL; pres = pres->link) {
+ send_restrict_entry(pres, ipv6, *pidx);
+ (*pidx)++;
+ }
+}
+
+
+/*
+ * read_addr_restrictions - returns IPv4 and IPv6 access control lists
+ */
+static void
+read_addr_restrictions(
+ struct recvbuf * rbufp
+)
+{
+ u_int idx;
+
+ idx = 0;
+ send_restrict_list(restrictlist4, FALSE, &idx);
+ send_restrict_list(restrictlist6, TRUE, &idx);
+ ctl_flushpkt(0);
+}
+
+
+/*
+ * read_ordlist - CTL_OP_READ_ORDLIST_A for ntpq -c ifstats & reslist
+ */
+static void
+read_ordlist(
+ struct recvbuf * rbufp,
+ int restrict_mask
+ )
+{
+ const char ifstats_s[] = "ifstats";
+ const size_t ifstats_chars = COUNTOF(ifstats_s) - 1;
+ const char addr_rst_s[] = "addr_restrictions";
+ const size_t a_r_chars = COUNTOF(addr_rst_s) - 1;
+ struct ntp_control * cpkt;
+ u_short qdata_octets;
+
+ /*
+ * CTL_OP_READ_ORDLIST_A was first named CTL_OP_READ_IFSTATS and
+ * used only for ntpq -c ifstats. With the addition of reslist
+ * the same opcode was generalized to retrieve ordered lists
+ * which require authentication. The request data is empty or
+ * contains "ifstats" (not null terminated) to retrieve local
+ * addresses and associated stats. It is "addr_restrictions"
+ * to retrieve the IPv4 then IPv6 remote address restrictions,
+ * which are access control lists. Other request data return
+ * CERR_UNKNOWNVAR.
+ */
+ cpkt = (struct ntp_control *)&rbufp->recv_pkt;
+ qdata_octets = ntohs(cpkt->count);
+ if (0 == qdata_octets || (ifstats_chars == qdata_octets &&
+ !memcmp(ifstats_s, cpkt->u.data, ifstats_chars))) {
+ read_ifstats(rbufp);
+ return;
+ }
+ if (a_r_chars == qdata_octets &&
+ !memcmp(addr_rst_s, cpkt->u.data, a_r_chars)) {
+ read_addr_restrictions(rbufp);
+ return;
+ }
+ ctl_error(CERR_UNKNOWNVAR);
+}
+
+
+/*
+ * req_nonce - CTL_OP_REQ_NONCE for ntpq -c mrulist prerequisite.
+ */
+static void req_nonce(
+ struct recvbuf * rbufp,
+ int restrict_mask
+ )
+{
+ char buf[64];
+
+ generate_nonce(rbufp, buf, sizeof(buf));
+ ctl_putunqstr("nonce", buf, strlen(buf));
+ ctl_flushpkt(0);
+}
+
+
+/*
+ * read_clockstatus - return clock radio status
+ */
+/*ARGSUSED*/
+static void
+read_clockstatus(
+ struct recvbuf *rbufp,
+ int restrict_mask
+ )
+{
+#ifndef REFCLOCK
+ /*
+ * If no refclock support, no data to return
+ */
+ ctl_error(CERR_BADASSOC);
+#else
+ const struct ctl_var * v;
+ int i;
+ struct peer * peer;
+ char * valuep;
+ u_char * wants;
+ size_t wants_alloc;
+ int gotvar;
+ const u_char * cc;
+ struct ctl_var * kv;
+ struct refclockstat cs;
+
+ if (res_associd != 0) {
+ peer = findpeerbyassoc(res_associd);
+ } else {
+ /*
+ * Find a clock for this jerk. If the system peer
+ * is a clock use it, else search peer_list for one.
+ */
+ if (sys_peer != NULL && (FLAG_REFCLOCK &
+ sys_peer->flags))
+ peer = sys_peer;
+ else
+ for (peer = peer_list;
+ peer != NULL;
+ peer = peer->p_link)
+ if (FLAG_REFCLOCK & peer->flags)
+ break;
+ }
+ if (NULL == peer || !(FLAG_REFCLOCK & peer->flags)) {
+ ctl_error(CERR_BADASSOC);
+ return;
+ }
+ /*
+ * If we got here we have a peer which is a clock. Get his
+ * status.
+ */
+ cs.kv_list = NULL;
+ refclock_control(&peer->srcadr, NULL, &cs);
+ kv = cs.kv_list;
+ /*
+ * Look for variables in the packet.
+ */
+ rpkt.status = htons(ctlclkstatus(&cs));
+ wants_alloc = CC_MAXCODE + 1 + count_var(kv);
+ wants = emalloc_zero(wants_alloc);
+ gotvar = FALSE;
+ while (NULL != (v = ctl_getitem(clock_var, &valuep))) {
+ if (!(EOV & v->flags)) {
+ wants[v->code] = TRUE;
+ gotvar = TRUE;
+ } else {
+ v = ctl_getitem(kv, &valuep);
+ if (NULL == v) {
+ ctl_error(CERR_BADVALUE);
+ free(wants);
+ free_varlist(cs.kv_list);
+ return;
+ }
+ if (EOV & v->flags) {
+ ctl_error(CERR_UNKNOWNVAR);
+ free(wants);
+ free_varlist(cs.kv_list);
+ return;
+ }
+ wants[CC_MAXCODE + 1 + v->code] = TRUE;
+ gotvar = TRUE;
+ }
+ }
+
+ if (gotvar) {
+ for (i = 1; i <= CC_MAXCODE; i++)
+ if (wants[i])
+ ctl_putclock(i, &cs, TRUE);
+ if (kv != NULL)
+ for (i = 0; !(EOV & kv[i].flags); i++)
+ if (wants[i + CC_MAXCODE + 1])
+ ctl_putdata(kv[i].text,
+ strlen(kv[i].text),
+ FALSE);
+ } else {
+ for (cc = def_clock_var; *cc != 0; cc++)
+ ctl_putclock((int)*cc, &cs, FALSE);
+ for ( ; kv != NULL && !(EOV & kv->flags); kv++)
+ if (DEF & kv->flags)
+ ctl_putdata(kv->text, strlen(kv->text),
+ FALSE);
+ }
+
+ free(wants);
+ free_varlist(cs.kv_list);
+
+ ctl_flushpkt(0);
+#endif
+}
+
+
+/*
+ * write_clockstatus - we don't do this
+ */
+/*ARGSUSED*/
+static void
+write_clockstatus(
+ struct recvbuf *rbufp,
+ int restrict_mask
+ )
+{
+ ctl_error(CERR_PERMISSION);
+}
+
+/*
+ * Trap support from here on down. We send async trap messages when the
+ * upper levels report trouble. Traps can by set either by control
+ * messages or by configuration.
+ */
+/*
+ * set_trap - set a trap in response to a control message
+ */
+static void
+set_trap(
+ struct recvbuf *rbufp,
+ int restrict_mask
+ )
+{
+ int traptype;
+
+ /*
+ * See if this guy is allowed
+ */
+ if (restrict_mask & RES_NOTRAP) {
+ ctl_error(CERR_PERMISSION);
+ return;
+ }
+
+ /*
+ * Determine his allowed trap type.
+ */
+ traptype = TRAP_TYPE_PRIO;
+ if (restrict_mask & RES_LPTRAP)
+ traptype = TRAP_TYPE_NONPRIO;
+
+ /*
+ * Call ctlsettrap() to do the work. Return
+ * an error if it can't assign the trap.
+ */
+ if (!ctlsettrap(&rbufp->recv_srcadr, rbufp->dstadr, traptype,
+ (int)res_version))
+ ctl_error(CERR_NORESOURCE);
+ ctl_flushpkt(0);
+}
+
+
+/*
+ * unset_trap - unset a trap in response to a control message
+ */
+static void
+unset_trap(
+ struct recvbuf *rbufp,
+ int restrict_mask
+ )
+{
+ int traptype;
+
+ /*
+ * We don't prevent anyone from removing his own trap unless the
+ * trap is configured. Note we also must be aware of the
+ * possibility that restriction flags were changed since this
+ * guy last set his trap. Set the trap type based on this.
+ */
+ traptype = TRAP_TYPE_PRIO;
+ if (restrict_mask & RES_LPTRAP)
+ traptype = TRAP_TYPE_NONPRIO;
+
+ /*
+ * Call ctlclrtrap() to clear this out.
+ */
+ if (!ctlclrtrap(&rbufp->recv_srcadr, rbufp->dstadr, traptype))
+ ctl_error(CERR_BADASSOC);
+ ctl_flushpkt(0);
+}
+
+
+/*
+ * ctlsettrap - called to set a trap
+ */
+int
+ctlsettrap(
+ sockaddr_u *raddr,
+ struct interface *linter,
+ int traptype,
+ int version
+ )
+{
+ size_t n;
+ struct ctl_trap *tp;
+ struct ctl_trap *tptouse;
+
+ /*
+ * See if we can find this trap. If so, we only need update
+ * the flags and the time.
+ */
+ if ((tp = ctlfindtrap(raddr, linter)) != NULL) {
+ switch (traptype) {
+
+ case TRAP_TYPE_CONFIG:
+ tp->tr_flags = TRAP_INUSE|TRAP_CONFIGURED;
+ break;
+
+ case TRAP_TYPE_PRIO:
+ if (tp->tr_flags & TRAP_CONFIGURED)
+ return (1); /* don't change anything */
+ tp->tr_flags = TRAP_INUSE;
+ break;
+
+ case TRAP_TYPE_NONPRIO:
+ if (tp->tr_flags & TRAP_CONFIGURED)
+ return (1); /* don't change anything */
+ tp->tr_flags = TRAP_INUSE|TRAP_NONPRIO;
+ break;
+ }
+ tp->tr_settime = current_time;
+ tp->tr_resets++;
+ return (1);
+ }
+
+ /*
+ * First we heard of this guy. Try to find a trap structure
+ * for him to use, clearing out lesser priority guys if we
+ * have to. Clear out anyone who's expired while we're at it.
+ */
+ tptouse = NULL;
+ for (n = 0; n < COUNTOF(ctl_traps); n++) {
+ tp = &ctl_traps[n];
+ if ((TRAP_INUSE & tp->tr_flags) &&
+ !(TRAP_CONFIGURED & tp->tr_flags) &&
+ ((tp->tr_settime + CTL_TRAPTIME) > current_time)) {
+ tp->tr_flags = 0;
+ num_ctl_traps--;
+ }
+ if (!(TRAP_INUSE & tp->tr_flags)) {
+ tptouse = tp;
+ } else if (!(TRAP_CONFIGURED & tp->tr_flags)) {
+ switch (traptype) {
+
+ case TRAP_TYPE_CONFIG:
+ if (tptouse == NULL) {
+ tptouse = tp;
+ break;
+ }
+ if ((TRAP_NONPRIO & tptouse->tr_flags) &&
+ !(TRAP_NONPRIO & tp->tr_flags))
+ break;
+
+ if (!(TRAP_NONPRIO & tptouse->tr_flags)
+ && (TRAP_NONPRIO & tp->tr_flags)) {
+ tptouse = tp;
+ break;
+ }
+ if (tptouse->tr_origtime <
+ tp->tr_origtime)
+ tptouse = tp;
+ break;
+
+ case TRAP_TYPE_PRIO:
+ if ( TRAP_NONPRIO & tp->tr_flags) {
+ if (tptouse == NULL ||
+ ((TRAP_INUSE &
+ tptouse->tr_flags) &&
+ tptouse->tr_origtime <
+ tp->tr_origtime))
+ tptouse = tp;
+ }
+ break;
+
+ case TRAP_TYPE_NONPRIO:
+ break;
+ }
+ }
+ }
+
+ /*
+ * If we don't have room for him return an error.
+ */
+ if (tptouse == NULL)
+ return (0);
+
+ /*
+ * Set up this structure for him.
+ */
+ tptouse->tr_settime = tptouse->tr_origtime = current_time;
+ tptouse->tr_count = tptouse->tr_resets = 0;
+ tptouse->tr_sequence = 1;
+ tptouse->tr_addr = *raddr;
+ tptouse->tr_localaddr = linter;
+ tptouse->tr_version = (u_char) version;
+ tptouse->tr_flags = TRAP_INUSE;
+ if (traptype == TRAP_TYPE_CONFIG)
+ tptouse->tr_flags |= TRAP_CONFIGURED;
+ else if (traptype == TRAP_TYPE_NONPRIO)
+ tptouse->tr_flags |= TRAP_NONPRIO;
+ num_ctl_traps++;
+ return (1);
+}
+
+
+/*
+ * ctlclrtrap - called to clear a trap
+ */
+int
+ctlclrtrap(
+ sockaddr_u *raddr,
+ struct interface *linter,
+ int traptype
+ )
+{
+ register struct ctl_trap *tp;
+
+ if ((tp = ctlfindtrap(raddr, linter)) == NULL)
+ return (0);
+
+ if (tp->tr_flags & TRAP_CONFIGURED
+ && traptype != TRAP_TYPE_CONFIG)
+ return (0);
+
+ tp->tr_flags = 0;
+ num_ctl_traps--;
+ return (1);
+}
+
+
+/*
+ * ctlfindtrap - find a trap given the remote and local addresses
+ */
+static struct ctl_trap *
+ctlfindtrap(
+ sockaddr_u *raddr,
+ struct interface *linter
+ )
+{
+ size_t n;
+
+ for (n = 0; n < COUNTOF(ctl_traps); n++)
+ if ((ctl_traps[n].tr_flags & TRAP_INUSE)
+ && ADDR_PORT_EQ(raddr, &ctl_traps[n].tr_addr)
+ && (linter == ctl_traps[n].tr_localaddr))
+ return &ctl_traps[n];
+
+ return NULL;
+}
+
+
+/*
+ * report_event - report an event to the trappers
+ */
+void
+report_event(
+ int err, /* error code */
+ struct peer *peer, /* peer structure pointer */
+ const char *str /* protostats string */
+ )
+{
+ char statstr[NTP_MAXSTRLEN];
+ int i;
+ size_t len;
+
+ /*
+ * Report the error to the protostats file, system log and
+ * trappers.
+ */
+ if (peer == NULL) {
+
+ /*
+ * Discard a system report if the number of reports of
+ * the same type exceeds the maximum.
+ */
+ if (ctl_sys_last_event != (u_char)err)
+ ctl_sys_num_events= 0;
+ if (ctl_sys_num_events >= CTL_SYS_MAXEVENTS)
+ return;
+
+ ctl_sys_last_event = (u_char)err;
+ ctl_sys_num_events++;
+ snprintf(statstr, sizeof(statstr),
+ "0.0.0.0 %04x %02x %s",
+ ctlsysstatus(), err, eventstr(err));
+ if (str != NULL) {
+ len = strlen(statstr);
+ snprintf(statstr + len, sizeof(statstr) - len,
+ " %s", str);
+ }
+ NLOG(NLOG_SYSEVENT)
+ msyslog(LOG_INFO, "%s", statstr);
+ } else {
+
+ /*
+ * Discard a peer report if the number of reports of
+ * the same type exceeds the maximum for that peer.
+ */
+ const char * src;
+ u_char errlast;
+
+ errlast = (u_char)err & ~PEER_EVENT;
+ if (peer->last_event != errlast)
+ peer->num_events = 0;
+ if (peer->num_events >= CTL_PEER_MAXEVENTS)
+ return;
+
+ peer->last_event = errlast;
+ peer->num_events++;
+ if (ISREFCLOCKADR(&peer->srcadr))
+ src = refnumtoa(&peer->srcadr);
+ else
+ src = stoa(&peer->srcadr);
+
+ snprintf(statstr, sizeof(statstr),
+ "%s %04x %02x %s", src,
+ ctlpeerstatus(peer), err, eventstr(err));
+ if (str != NULL) {
+ len = strlen(statstr);
+ snprintf(statstr + len, sizeof(statstr) - len,
+ " %s", str);
+ }
+ NLOG(NLOG_PEEREVENT)
+ msyslog(LOG_INFO, "%s", statstr);
+ }
+ record_proto_stats(statstr);
+#if DEBUG
+ if (debug)
+ printf("event at %lu %s\n", current_time, statstr);
+#endif
+
+ /*
+ * If no trappers, return.
+ */
+ if (num_ctl_traps <= 0)
+ return;
+
+ /* [Bug 3119]
+ * Peer Events should be associated with a peer -- hence the
+ * name. But there are instances where this function is called
+ * *without* a valid peer. This happens e.g. with an unsolicited
+ * CryptoNAK, or when a leap second alarm is going off while
+ * currently without a system peer.
+ *
+ * The most sensible approach to this seems to bail out here if
+ * this happens. Avoiding to call this function would also
+ * bypass the log reporting in the first part of this function,
+ * and this is probably not the best of all options.
+ * -*-perlinger@ntp.org-*-
+ */
+ if ((err & PEER_EVENT) && !peer)
+ return;
+
+ /*
+ * Set up the outgoing packet variables
+ */
+ res_opcode = CTL_OP_ASYNCMSG;
+ res_offset = 0;
+ res_async = TRUE;
+ res_authenticate = FALSE;
+ datapt = rpkt.u.data;
+ dataend = &rpkt.u.data[CTL_MAX_DATA_LEN];
+ if (!(err & PEER_EVENT)) {
+ rpkt.associd = 0;
+ rpkt.status = htons(ctlsysstatus());
+
+ /* Include the core system variables and the list. */
+ for (i = 1; i <= CS_VARLIST; i++)
+ ctl_putsys(i);
+ } else if (NULL != peer) { /* paranoia -- skip output */
+ rpkt.associd = htons(peer->associd);
+ rpkt.status = htons(ctlpeerstatus(peer));
+
+ /* Dump it all. Later, maybe less. */
+ for (i = 1; i <= CP_MAX_NOAUTOKEY; i++)
+ ctl_putpeer(i, peer);
+# ifdef REFCLOCK
+ /*
+ * for clock exception events: add clock variables to
+ * reflect info on exception
+ */
+ if (err == PEVNT_CLOCK) {
+ struct refclockstat cs;
+ struct ctl_var *kv;
+
+ cs.kv_list = NULL;
+ refclock_control(&peer->srcadr, NULL, &cs);
+
+ ctl_puthex("refclockstatus",
+ ctlclkstatus(&cs));
+
+ for (i = 1; i <= CC_MAXCODE; i++)
+ ctl_putclock(i, &cs, FALSE);
+ for (kv = cs.kv_list;
+ kv != NULL && !(EOV & kv->flags);
+ kv++)
+ if (DEF & kv->flags)
+ ctl_putdata(kv->text,
+ strlen(kv->text),
+ FALSE);
+ free_varlist(cs.kv_list);
+ }
+# endif /* REFCLOCK */
+ }
+
+ /*
+ * We're done, return.
+ */
+ ctl_flushpkt(0);
+}
+
+
+/*
+ * mprintf_event - printf-style varargs variant of report_event()
+ */
+int
+mprintf_event(
+ int evcode, /* event code */
+ struct peer * p, /* may be NULL */
+ const char * fmt, /* msnprintf format */
+ ...
+ )
+{
+ va_list ap;
+ int rc;
+ char msg[512];
+
+ va_start(ap, fmt);
+ rc = mvsnprintf(msg, sizeof(msg), fmt, ap);
+ va_end(ap);
+ report_event(evcode, p, msg);
+
+ return rc;
+}
+
+
+/*
+ * ctl_clr_stats - clear stat counters
+ */
+void
+ctl_clr_stats(void)
+{
+ ctltimereset = current_time;
+ numctlreq = 0;
+ numctlbadpkts = 0;
+ numctlresponses = 0;
+ numctlfrags = 0;
+ numctlerrors = 0;
+ numctlfrags = 0;
+ numctltooshort = 0;
+ numctlinputresp = 0;
+ numctlinputfrag = 0;
+ numctlinputerr = 0;
+ numctlbadoffset = 0;
+ numctlbadversion = 0;
+ numctldatatooshort = 0;
+ numctlbadop = 0;
+ numasyncmsgs = 0;
+}
+
+static u_short
+count_var(
+ const struct ctl_var *k
+ )
+{
+ u_int c;
+
+ if (NULL == k)
+ return 0;
+
+ c = 0;
+ while (!(EOV & (k++)->flags))
+ c++;
+
+ ENSURE(c <= USHRT_MAX);
+ return (u_short)c;
+}
+
+
+char *
+add_var(
+ struct ctl_var **kv,
+ u_long size,
+ u_short def
+ )
+{
+ u_short c;
+ struct ctl_var *k;
+ char * buf;
+
+ c = count_var(*kv);
+ *kv = erealloc(*kv, (c + 2) * sizeof(**kv));
+ k = *kv;
+ buf = emalloc(size);
+ k[c].code = c;
+ k[c].text = buf;
+ k[c].flags = def;
+ k[c + 1].code = 0;
+ k[c + 1].text = NULL;
+ k[c + 1].flags = EOV;
+
+ return buf;
+}
+
+
+void
+set_var(
+ struct ctl_var **kv,
+ const char *data,
+ u_long size,
+ u_short def
+ )
+{
+ struct ctl_var *k;
+ const char *s;
+ const char *t;
+ char *td;
+
+ if (NULL == data || !size)
+ return;
+
+ k = *kv;
+ if (k != NULL) {
+ while (!(EOV & k->flags)) {
+ if (NULL == k->text) {
+ td = emalloc(size);
+ memcpy(td, data, size);
+ k->text = td;
+ k->flags = def;
+ return;
+ } else {
+ s = data;
+ t = k->text;
+ while (*t != '=' && *s == *t) {
+ s++;
+ t++;
+ }
+ if (*s == *t && ((*t == '=') || !*t)) {
+ td = erealloc((void *)(intptr_t)k->text, size);
+ memcpy(td, data, size);
+ k->text = td;
+ k->flags = def;
+ return;
+ }
+ }
+ k++;
+ }
+ }
+ td = add_var(kv, size, def);
+ memcpy(td, data, size);
+}
+
+
+void
+set_sys_var(
+ const char *data,
+ u_long size,
+ u_short def
+ )
+{
+ set_var(&ext_sys_var, data, size, def);
+}
+
+
+/*
+ * get_ext_sys_var() retrieves the value of a user-defined variable or
+ * NULL if the variable has not been setvar'd.
+ */
+const char *
+get_ext_sys_var(const char *tag)
+{
+ struct ctl_var * v;
+ size_t c;
+ const char * val;
+
+ val = NULL;
+ c = strlen(tag);
+ for (v = ext_sys_var; !(EOV & v->flags); v++) {
+ if (NULL != v->text && !memcmp(tag, v->text, c)) {
+ if ('=' == v->text[c]) {
+ val = v->text + c + 1;
+ break;
+ } else if ('\0' == v->text[c]) {
+ val = "";
+ break;
+ }
+ }
+ }
+
+ return val;
+}
+
+
+void
+free_varlist(
+ struct ctl_var *kv
+ )
+{
+ struct ctl_var *k;
+ if (kv) {
+ for (k = kv; !(k->flags & EOV); k++)
+ free((void *)(intptr_t)k->text);
+ free((void *)kv);
+ }
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_crypto.c b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_crypto.c
new file mode 100644
index 0000000..3e5647d
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_crypto.c
@@ -0,0 +1,4174 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * ntp_crypto.c - NTP version 4 public key routines
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef AUTOKEY
+#include <stdio.h>
+#include <stdlib.h> /* strtoul */
+#include <sys/types.h>
+#include <sys/param.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "ntpd.h"
+#include "ntp_stdlib.h"
+#include "ntp_unixtime.h"
+#include "ntp_string.h"
+#include "ntp_random.h"
+#include "ntp_assert.h"
+#include "ntp_calendar.h"
+#include "ntp_leapsec.h"
+
+#include "openssl/asn1.h"
+#include "openssl/bn.h"
+#include "openssl/crypto.h"
+#include "openssl/err.h"
+#include "openssl/evp.h"
+#include "openssl/opensslv.h"
+#include "openssl/pem.h"
+#include "openssl/rand.h"
+#include "openssl/x509.h"
+#include "openssl/x509v3.h"
+#include "libssl_compat.h"
+
+#ifdef KERNEL_PLL
+#include "ntp_syscall.h"
+#endif /* KERNEL_PLL */
+
+/*
+ * calcomp - compare two calendar structures, ignoring yearday and weekday; like strcmp
+ * No, it's not a plotter. If you don't understand that, you're too young.
+ */
+static int calcomp(struct calendar *pjd1, struct calendar *pjd2)
+{
+ int32_t diff; /* large enough to hold the signed difference between two uint16_t values */
+
+ diff = pjd1->year - pjd2->year;
+ if (diff < 0) return -1; else if (diff > 0) return 1;
+ /* same year; compare months */
+ diff = pjd1->month - pjd2->month;
+ if (diff < 0) return -1; else if (diff > 0) return 1;
+ /* same year and month; compare monthday */
+ diff = pjd1->monthday - pjd2->monthday;
+ if (diff < 0) return -1; else if (diff > 0) return 1;
+ /* same year and month and monthday; compare time */
+ diff = pjd1->hour - pjd2->hour;
+ if (diff < 0) return -1; else if (diff > 0) return 1;
+ diff = pjd1->minute - pjd2->minute;
+ if (diff < 0) return -1; else if (diff > 0) return 1;
+ diff = pjd1->second - pjd2->second;
+ if (diff < 0) return -1; else if (diff > 0) return 1;
+ /* identical */
+ return 0;
+}
+
+/*
+ * Extension field message format
+ *
+ * These are always signed and saved before sending in network byte
+ * order. They must be converted to and from host byte order for
+ * processing.
+ *
+ * +-------+-------+
+ * | op | len | <- extension pointer
+ * +-------+-------+
+ * | associd |
+ * +---------------+
+ * | timestamp | <- value pointer
+ * +---------------+
+ * | filestamp |
+ * +---------------+
+ * | value len |
+ * +---------------+
+ * | |
+ * = value =
+ * | |
+ * +---------------+
+ * | signature len |
+ * +---------------+
+ * | |
+ * = signature =
+ * | |
+ * +---------------+
+ *
+ * The CRYPTO_RESP bit is set to 0 for requests, 1 for responses.
+ * Requests carry the association ID of the receiver; responses carry
+ * the association ID of the sender. Some messages include only the
+ * operation/length and association ID words and so have length 8
+ * octets. Ohers include the value structure and associated value and
+ * signature fields. These messages include the timestamp, filestamp,
+ * value and signature words and so have length at least 24 octets. The
+ * signature and/or value fields can be empty, in which case the
+ * respective length words are zero. An empty value with nonempty
+ * signature is syntactically valid, but semantically questionable.
+ *
+ * The filestamp represents the time when a cryptographic data file such
+ * as a public/private key pair is created. It follows every reference
+ * depending on that file and serves as a means to obsolete earlier data
+ * of the same type. The timestamp represents the time when the
+ * cryptographic data of the message were last signed. Creation of a
+ * cryptographic data file or signing a message can occur only when the
+ * creator or signor is synchronized to an authoritative source and
+ * proventicated to a trusted authority.
+ *
+ * Note there are several conditions required for server trust. First,
+ * the public key on the server certificate must be verified, which can
+ * involve a hike along the certificate trail to a trusted host. Next,
+ * the server trust must be confirmed by one of several identity
+ * schemes. Valid cryptographic values are signed with attached
+ * timestamp and filestamp. Individual packet trust is confirmed
+ * relative to these values by a message digest with keys generated by a
+ * reverse-order pseudorandom hash.
+ *
+ * State decomposition. These flags are lit in the order given. They are
+ * dim only when the association is demobilized.
+ *
+ * CRYPTO_FLAG_ENAB Lit upon acceptance of a CRYPTO_ASSOC message
+ * CRYPTO_FLAG_CERT Lit when a self-digned trusted certificate is
+ * accepted.
+ * CRYPTO_FLAG_VRFY Lit when identity is confirmed.
+ * CRYPTO_FLAG_PROV Lit when the first signature is verified.
+ * CRYPTO_FLAG_COOK Lit when a valid cookie is accepted.
+ * CRYPTO_FLAG_AUTO Lit when valid autokey values are accepted.
+ * CRYPTO_FLAG_SIGN Lit when the server signed certificate is
+ * accepted.
+ * CRYPTO_FLAG_LEAP Lit when the leapsecond values are accepted.
+ */
+/*
+ * Cryptodefines
+ */
+#define TAI_1972 10 /* initial TAI offset (s) */
+#define MAX_LEAP 100 /* max UTC leapseconds (s) */
+#define VALUE_LEN (6 * 4) /* min response field length */
+#define MAX_VALLEN (65535 - VALUE_LEN)
+#define YEAR (60 * 60 * 24 * 365) /* seconds in year */
+
+/*
+ * Global cryptodata in host byte order
+ */
+u_int32 crypto_flags = 0x0; /* status word */
+int crypto_nid = KEY_TYPE_MD5; /* digest nid */
+char *sys_hostname = NULL;
+char *sys_groupname = NULL;
+static char *host_filename = NULL; /* host file name */
+static char *ident_filename = NULL; /* group file name */
+
+/*
+ * Global cryptodata in network byte order
+ */
+struct cert_info *cinfo = NULL; /* certificate info/value cache */
+struct cert_info *cert_host = NULL; /* host certificate */
+struct pkey_info *pkinfo = NULL; /* key info/value cache */
+struct value hostval; /* host value */
+struct value pubkey; /* public key */
+struct value tai_leap; /* leapseconds values */
+struct pkey_info *iffkey_info = NULL; /* IFF keys */
+struct pkey_info *gqkey_info = NULL; /* GQ keys */
+struct pkey_info *mvkey_info = NULL; /* MV keys */
+
+/*
+ * Private cryptodata in host byte order
+ */
+static char *passwd = NULL; /* private key password */
+static EVP_PKEY *host_pkey = NULL; /* host key */
+static EVP_PKEY *sign_pkey = NULL; /* sign key */
+static const EVP_MD *sign_digest = NULL; /* sign digest */
+static u_int sign_siglen; /* sign key length */
+static char *rand_file = NULL; /* random seed file */
+
+/*
+ * Cryptotypes
+ */
+static int crypto_verify (struct exten *, struct value *,
+ struct peer *);
+static int crypto_encrypt (const u_char *, u_int, keyid_t *,
+ struct value *);
+static int crypto_alice (struct peer *, struct value *);
+static int crypto_alice2 (struct peer *, struct value *);
+static int crypto_alice3 (struct peer *, struct value *);
+static int crypto_bob (struct exten *, struct value *);
+static int crypto_bob2 (struct exten *, struct value *);
+static int crypto_bob3 (struct exten *, struct value *);
+static int crypto_iff (struct exten *, struct peer *);
+static int crypto_gq (struct exten *, struct peer *);
+static int crypto_mv (struct exten *, struct peer *);
+static int crypto_send (struct exten *, struct value *, int);
+static tstamp_t crypto_time (void);
+static void asn_to_calendar (const ASN1_TIME *, struct calendar*);
+static struct cert_info *cert_parse (const u_char *, long, tstamp_t);
+static int cert_sign (struct exten *, struct value *);
+static struct cert_info *cert_install (struct exten *, struct peer *);
+static int cert_hike (struct peer *, struct cert_info *);
+static void cert_free (struct cert_info *);
+static struct pkey_info *crypto_key (char *, char *, sockaddr_u *);
+static void bighash (BIGNUM *, BIGNUM *);
+static struct cert_info *crypto_cert (char *);
+static u_int exten_payload_size(const struct exten *);
+
+#ifdef SYS_WINNT
+int
+readlink(char * link, char * file, int len) {
+ return (-1);
+}
+#endif
+
+/*
+ * session_key - generate session key
+ *
+ * This routine generates a session key from the source address,
+ * destination address, key ID and private value. The value of the
+ * session key is the MD5 hash of these values, while the next key ID is
+ * the first four octets of the hash.
+ *
+ * Returns the next key ID or 0 if there is no destination address.
+ */
+keyid_t
+session_key(
+ sockaddr_u *srcadr, /* source address */
+ sockaddr_u *dstadr, /* destination address */
+ keyid_t keyno, /* key ID */
+ keyid_t private, /* private value */
+ u_long lifetime /* key lifetime */
+ )
+{
+ EVP_MD_CTX *ctx; /* message digest context */
+ u_char dgst[EVP_MAX_MD_SIZE]; /* message digest */
+ keyid_t keyid; /* key identifer */
+ u_int32 header[10]; /* data in network byte order */
+ u_int hdlen, len;
+
+ if (!dstadr)
+ return 0;
+
+ /*
+ * Generate the session key and key ID. If the lifetime is
+ * greater than zero, install the key and call it trusted.
+ */
+ hdlen = 0;
+ switch(AF(srcadr)) {
+ case AF_INET:
+ header[0] = NSRCADR(srcadr);
+ header[1] = NSRCADR(dstadr);
+ header[2] = htonl(keyno);
+ header[3] = htonl(private);
+ hdlen = 4 * sizeof(u_int32);
+ break;
+
+ case AF_INET6:
+ memcpy(&header[0], PSOCK_ADDR6(srcadr),
+ sizeof(struct in6_addr));
+ memcpy(&header[4], PSOCK_ADDR6(dstadr),
+ sizeof(struct in6_addr));
+ header[8] = htonl(keyno);
+ header[9] = htonl(private);
+ hdlen = 10 * sizeof(u_int32);
+ break;
+ }
+ ctx = EVP_MD_CTX_new();
+# if defined(OPENSSL) && defined(EVP_MD_CTX_FLAG_NON_FIPS_ALLOW)
+ /* [Bug 3457] set flags and don't kill them again */
+ EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+ EVP_DigestInit_ex(ctx, EVP_get_digestbynid(crypto_nid), NULL);
+# else
+ EVP_DigestInit(ctx, EVP_get_digestbynid(crypto_nid));
+# endif
+ EVP_DigestUpdate(ctx, (u_char *)header, hdlen);
+ EVP_DigestFinal(ctx, dgst, &len);
+ EVP_MD_CTX_free(ctx);
+ memcpy(&keyid, dgst, 4);
+ keyid = ntohl(keyid);
+ if (lifetime != 0) {
+ MD5auth_setkey(keyno, crypto_nid, dgst, len, NULL);
+ authtrust(keyno, lifetime);
+ }
+ DPRINTF(2, ("session_key: %s > %s %08x %08x hash %08x life %lu\n",
+ stoa(srcadr), stoa(dstadr), keyno,
+ private, keyid, lifetime));
+
+ return (keyid);
+}
+
+
+/*
+ * make_keylist - generate key list
+ *
+ * Returns
+ * XEVNT_OK success
+ * XEVNT_ERR protocol error
+ *
+ * This routine constructs a pseudo-random sequence by repeatedly
+ * hashing the session key starting from a given source address,
+ * destination address, private value and the next key ID of the
+ * preceeding session key. The last entry on the list is saved along
+ * with its sequence number and public signature.
+ */
+int
+make_keylist(
+ struct peer *peer, /* peer structure pointer */
+ struct interface *dstadr /* interface */
+ )
+{
+ EVP_MD_CTX *ctx; /* signature context */
+ tstamp_t tstamp; /* NTP timestamp */
+ struct autokey *ap; /* autokey pointer */
+ struct value *vp; /* value pointer */
+ keyid_t keyid = 0; /* next key ID */
+ keyid_t cookie; /* private value */
+ long lifetime;
+ u_int len, mpoll;
+ int i;
+
+ if (!dstadr)
+ return XEVNT_ERR;
+
+ /*
+ * Allocate the key list if necessary.
+ */
+ tstamp = crypto_time();
+ if (peer->keylist == NULL)
+ peer->keylist = eallocarray(NTP_MAXSESSION,
+ sizeof(keyid_t));
+
+ /*
+ * Generate an initial key ID which is unique and greater than
+ * NTP_MAXKEY.
+ */
+ while (1) {
+ keyid = ntp_random() & 0xffffffff;
+ if (keyid <= NTP_MAXKEY)
+ continue;
+
+ if (authhavekey(keyid))
+ continue;
+ break;
+ }
+
+ /*
+ * Generate up to NTP_MAXSESSION session keys. Stop if the
+ * next one would not be unique or not a session key ID or if
+ * it would expire before the next poll. The private value
+ * included in the hash is zero if broadcast mode, the peer
+ * cookie if client mode or the host cookie if symmetric modes.
+ */
+ mpoll = 1U << min(peer->ppoll, peer->hpoll);
+ lifetime = min((1UL << sys_automax), NTP_MAXSESSION * mpoll);
+ if (peer->hmode == MODE_BROADCAST)
+ cookie = 0;
+ else
+ cookie = peer->pcookie;
+ for (i = 0; i < NTP_MAXSESSION; i++) {
+ peer->keylist[i] = keyid;
+ peer->keynumber = i;
+ keyid = session_key(&dstadr->sin, &peer->srcadr, keyid,
+ cookie, lifetime + mpoll);
+ lifetime -= mpoll;
+ if (auth_havekey(keyid) || keyid <= NTP_MAXKEY ||
+ lifetime < 0 || tstamp == 0)
+ break;
+ }
+
+ /*
+ * Save the last session key ID, sequence number and timestamp,
+ * then sign these values for later retrieval by the clients. Be
+ * careful not to use invalid key media. Use the public values
+ * timestamp as filestamp.
+ */
+ vp = &peer->sndval;
+ if (vp->ptr == NULL)
+ vp->ptr = emalloc(sizeof(struct autokey));
+ ap = (struct autokey *)vp->ptr;
+ ap->seq = htonl(peer->keynumber);
+ ap->key = htonl(keyid);
+ vp->tstamp = htonl(tstamp);
+ vp->fstamp = hostval.tstamp;
+ vp->vallen = htonl(sizeof(struct autokey));
+ vp->siglen = 0;
+ if (tstamp != 0) {
+ if (vp->sig == NULL)
+ vp->sig = emalloc(sign_siglen);
+ ctx = EVP_MD_CTX_new();
+ EVP_SignInit(ctx, sign_digest);
+ EVP_SignUpdate(ctx, (u_char *)vp, 12);
+ EVP_SignUpdate(ctx, vp->ptr, sizeof(struct autokey));
+ if (EVP_SignFinal(ctx, vp->sig, &len, sign_pkey)) {
+ INSIST(len <= sign_siglen);
+ vp->siglen = htonl(len);
+ peer->flags |= FLAG_ASSOC;
+ }
+ EVP_MD_CTX_free(ctx);
+ }
+ DPRINTF(1, ("make_keys: %d %08x %08x ts %u fs %u poll %d\n",
+ peer->keynumber, keyid, cookie, ntohl(vp->tstamp),
+ ntohl(vp->fstamp), peer->hpoll));
+ return (XEVNT_OK);
+}
+
+
+/*
+ * crypto_recv - parse extension fields
+ *
+ * This routine is called when the packet has been matched to an
+ * association and passed sanity, format and MAC checks. We believe the
+ * extension field values only if the field has proper format and
+ * length, the timestamp and filestamp are valid and the signature has
+ * valid length and is verified. There are a few cases where some values
+ * are believed even if the signature fails, but only if the proventic
+ * bit is not set.
+ *
+ * Returns
+ * XEVNT_OK success
+ * XEVNT_ERR protocol error
+ * XEVNT_LEN bad field format or length
+ */
+int
+crypto_recv(
+ struct peer *peer, /* peer structure pointer */
+ struct recvbuf *rbufp /* packet buffer pointer */
+ )
+{
+ const EVP_MD *dp; /* message digest algorithm */
+ u_int32 *pkt; /* receive packet pointer */
+ struct autokey *ap, *bp; /* autokey pointer */
+ struct exten *ep, *fp; /* extension pointers */
+ struct cert_info *xinfo; /* certificate info pointer */
+ int macbytes; /* length of MAC field, signed by intention */
+ int authlen; /* offset of MAC field */
+ associd_t associd; /* association ID */
+ tstamp_t fstamp = 0; /* filestamp */
+ u_int len; /* extension field length */
+ u_int code; /* extension field opcode */
+ u_int vallen = 0; /* value length */
+ X509 *cert; /* X509 certificate */
+ char statstr[NTP_MAXSTRLEN]; /* statistics for filegen */
+ keyid_t cookie; /* crumbles */
+ int hismode; /* packet mode */
+ int rval = XEVNT_OK;
+ const u_char *puch;
+ u_int32 temp32;
+
+ /*
+ * Initialize. Note that the packet has already been checked for
+ * valid format and extension field lengths. First extract the
+ * field length, command code and association ID in host byte
+ * order. These are used with all commands and modes. Then check
+ * the version number, which must be 2, and length, which must
+ * be at least 8 for requests and VALUE_LEN (24) for responses.
+ * Packets that fail either test sink without a trace. The
+ * association ID is saved only if nonzero.
+ */
+ authlen = LEN_PKT_NOMAC;
+ hismode = (int)PKT_MODE((&rbufp->recv_pkt)->li_vn_mode);
+ while ((macbytes = rbufp->recv_length - authlen) > (int)MAX_MAC_LEN) {
+ /* We can be reasonably sure that we can read at least
+ * the opcode and the size field here. More stringent
+ * checks follow up shortly.
+ */
+ pkt = (u_int32 *)&rbufp->recv_pkt + authlen / 4;
+ ep = (struct exten *)pkt;
+ code = ntohl(ep->opcode) & 0xffff0000;
+ len = ntohl(ep->opcode) & 0x0000ffff;
+ // HMS: Why pkt[1] instead of ep->associd ?
+ associd = (associd_t)ntohl(pkt[1]);
+ rval = XEVNT_OK;
+ DPRINTF(1, ("crypto_recv: flags 0x%x ext offset %d len %u code 0x%x associd %d\n",
+ peer->crypto, authlen, len, code >> 16,
+ associd));
+
+ /*
+ * Check version number and field length. If bad,
+ * quietly ignore the packet.
+ */
+ if (((code >> 24) & 0x3f) != CRYPTO_VN || len < 8) {
+ sys_badlength++;
+ code |= CRYPTO_ERROR;
+ }
+
+ /* Check if the declared size fits into the remaining
+ * buffer. We *know* 'macbytes' > 0 here!
+ */
+ if (len > (u_int)macbytes) {
+ DPRINTF(1, ("crypto_recv: possible attack detected, associd %d\n",
+ associd));
+ return XEVNT_LEN;
+ }
+
+ /* Check if the paylod of the extension fits into the
+ * declared frame.
+ */
+ if (len >= VALUE_LEN) {
+ fstamp = ntohl(ep->fstamp);
+ vallen = ntohl(ep->vallen);
+ /*
+ * Bug 2761: I hope this isn't too early...
+ */
+ if ( vallen == 0
+ || len - VALUE_LEN < vallen)
+ return XEVNT_LEN;
+ }
+ switch (code) {
+
+ /*
+ * Install status word, host name, signature scheme and
+ * association ID. In OpenSSL the signature algorithm is
+ * bound to the digest algorithm, so the NID completely
+ * defines the signature scheme. Note the request and
+ * response are identical, but neither is validated by
+ * signature. The request is processed here only in
+ * symmetric modes. The server name field might be
+ * useful to implement access controls in future.
+ */
+ case CRYPTO_ASSOC:
+
+ /*
+ * If our state machine is running when this
+ * message arrives, the other fellow might have
+ * restarted. However, this could be an
+ * intruder, so just clamp the poll interval and
+ * find out for ourselves. Otherwise, pass the
+ * extension field to the transmit side.
+ */
+ if (peer->crypto & CRYPTO_FLAG_CERT) {
+ rval = XEVNT_ERR;
+ break;
+ }
+ if (peer->cmmd) {
+ if (peer->assoc != associd) {
+ rval = XEVNT_ERR;
+ break;
+ }
+ free(peer->cmmd); /* will be set again! */
+ }
+ fp = emalloc(len);
+ memcpy(fp, ep, len);
+ fp->associd = htonl(peer->associd);
+ peer->cmmd = fp;
+ /* fall through */
+
+ case CRYPTO_ASSOC | CRYPTO_RESP:
+
+ /*
+ * Discard the message if it has already been
+ * stored or the message has been amputated.
+ */
+ if (peer->crypto) {
+ if (peer->assoc != associd)
+ rval = XEVNT_ERR;
+ break;
+ }
+ INSIST(len >= VALUE_LEN);
+ if (vallen == 0 || vallen > MAXHOSTNAME ||
+ len - VALUE_LEN < vallen) {
+ rval = XEVNT_LEN;
+ break;
+ }
+ DPRINTF(1, ("crypto_recv: ident host 0x%x %d server 0x%x %d\n",
+ crypto_flags, peer->associd, fstamp,
+ peer->assoc));
+ temp32 = crypto_flags & CRYPTO_FLAG_MASK;
+
+ /*
+ * If the client scheme is PC, the server scheme
+ * must be PC. The public key and identity are
+ * presumed valid, so we skip the certificate
+ * and identity exchanges and move immediately
+ * to the cookie exchange which confirms the
+ * server signature.
+ */
+ if (crypto_flags & CRYPTO_FLAG_PRIV) {
+ if (!(fstamp & CRYPTO_FLAG_PRIV)) {
+ rval = XEVNT_KEY;
+ break;
+ }
+ fstamp |= CRYPTO_FLAG_CERT |
+ CRYPTO_FLAG_VRFY | CRYPTO_FLAG_SIGN;
+
+ /*
+ * It is an error if either peer supports
+ * identity, but the other does not.
+ */
+ } else if (hismode == MODE_ACTIVE || hismode ==
+ MODE_PASSIVE) {
+ if ((temp32 && !(fstamp &
+ CRYPTO_FLAG_MASK)) ||
+ (!temp32 && (fstamp &
+ CRYPTO_FLAG_MASK))) {
+ rval = XEVNT_KEY;
+ break;
+ }
+ }
+
+ /*
+ * Discard the message if the signature digest
+ * NID is not supported.
+ */
+ temp32 = (fstamp >> 16) & 0xffff;
+ dp =
+ (const EVP_MD *)EVP_get_digestbynid(temp32);
+ if (dp == NULL) {
+ rval = XEVNT_MD;
+ break;
+ }
+
+ /*
+ * Save status word, host name and message
+ * digest/signature type. If this is from a
+ * broadcast and the association ID has changed,
+ * request the autokey values.
+ */
+ peer->assoc = associd;
+ if (hismode == MODE_SERVER)
+ fstamp |= CRYPTO_FLAG_AUTO;
+ if (!(fstamp & CRYPTO_FLAG_TAI))
+ fstamp |= CRYPTO_FLAG_LEAP;
+ RAND_bytes((u_char *)&peer->hcookie, 4);
+ peer->crypto = fstamp;
+ peer->digest = dp;
+ if (peer->subject != NULL)
+ free(peer->subject);
+ peer->subject = emalloc(vallen + 1);
+ memcpy(peer->subject, ep->pkt, vallen);
+ peer->subject[vallen] = '\0';
+ if (peer->issuer != NULL)
+ free(peer->issuer);
+ peer->issuer = estrdup(peer->subject);
+ snprintf(statstr, sizeof(statstr),
+ "assoc %d %d host %s %s", peer->associd,
+ peer->assoc, peer->subject,
+ OBJ_nid2ln(temp32));
+ record_crypto_stats(&peer->srcadr, statstr);
+ DPRINTF(1, ("crypto_recv: %s\n", statstr));
+ break;
+
+ /*
+ * Decode X509 certificate in ASN.1 format and extract
+ * the data containing, among other things, subject
+ * name and public key. In the default identification
+ * scheme, the certificate trail is followed to a self
+ * signed trusted certificate.
+ */
+ case CRYPTO_CERT | CRYPTO_RESP:
+
+ /*
+ * Discard the message if empty or invalid.
+ */
+ if (len < VALUE_LEN)
+ break;
+
+ if ((rval = crypto_verify(ep, NULL, peer)) !=
+ XEVNT_OK)
+ break;
+
+ /*
+ * Scan the certificate list to delete old
+ * versions and link the newest version first on
+ * the list. Then, verify the signature. If the
+ * certificate is bad or missing, just ignore
+ * it.
+ */
+ if ((xinfo = cert_install(ep, peer)) == NULL) {
+ rval = XEVNT_CRT;
+ break;
+ }
+ if ((rval = cert_hike(peer, xinfo)) != XEVNT_OK)
+ break;
+
+ /*
+ * We plug in the public key and lifetime from
+ * the first certificate received. However, note
+ * that this certificate might not be signed by
+ * the server, so we can't check the
+ * signature/digest NID.
+ */
+ if (peer->pkey == NULL) {
+ puch = xinfo->cert.ptr;
+ cert = d2i_X509(NULL, &puch,
+ ntohl(xinfo->cert.vallen));
+ peer->pkey = X509_get_pubkey(cert);
+ X509_free(cert);
+ }
+ peer->flash &= ~TEST8;
+ temp32 = xinfo->nid;
+ snprintf(statstr, sizeof(statstr),
+ "cert %s %s 0x%x %s (%u) fs %u",
+ xinfo->subject, xinfo->issuer, xinfo->flags,
+ OBJ_nid2ln(temp32), temp32,
+ ntohl(ep->fstamp));
+ record_crypto_stats(&peer->srcadr, statstr);
+ DPRINTF(1, ("crypto_recv: %s\n", statstr));
+ break;
+
+ /*
+ * Schnorr (IFF) identity scheme. This scheme is
+ * designed for use with shared secret server group keys
+ * and where the certificate may be generated by a third
+ * party. The client sends a challenge to the server,
+ * which performs a calculation and returns the result.
+ * A positive result is possible only if both client and
+ * server contain the same secret group key.
+ */
+ case CRYPTO_IFF | CRYPTO_RESP:
+
+ /*
+ * Discard the message if invalid.
+ */
+ if ((rval = crypto_verify(ep, NULL, peer)) !=
+ XEVNT_OK)
+ break;
+
+ /*
+ * If the challenge matches the response, the
+ * server public key, signature and identity are
+ * all verified at the same time. The server is
+ * declared trusted, so we skip further
+ * certificate exchanges and move immediately to
+ * the cookie exchange.
+ */
+ if ((rval = crypto_iff(ep, peer)) != XEVNT_OK)
+ break;
+
+ peer->crypto |= CRYPTO_FLAG_VRFY;
+ peer->flash &= ~TEST8;
+ snprintf(statstr, sizeof(statstr), "iff %s fs %u",
+ peer->issuer, ntohl(ep->fstamp));
+ record_crypto_stats(&peer->srcadr, statstr);
+ DPRINTF(1, ("crypto_recv: %s\n", statstr));
+ break;
+
+ /*
+ * Guillou-Quisquater (GQ) identity scheme. This scheme
+ * is designed for use with public certificates carrying
+ * the GQ public key in an extension field. The client
+ * sends a challenge to the server, which performs a
+ * calculation and returns the result. A positive result
+ * is possible only if both client and server contain
+ * the same group key and the server has the matching GQ
+ * private key.
+ */
+ case CRYPTO_GQ | CRYPTO_RESP:
+
+ /*
+ * Discard the message if invalid
+ */
+ if ((rval = crypto_verify(ep, NULL, peer)) !=
+ XEVNT_OK)
+ break;
+
+ /*
+ * If the challenge matches the response, the
+ * server public key, signature and identity are
+ * all verified at the same time. The server is
+ * declared trusted, so we skip further
+ * certificate exchanges and move immediately to
+ * the cookie exchange.
+ */
+ if ((rval = crypto_gq(ep, peer)) != XEVNT_OK)
+ break;
+
+ peer->crypto |= CRYPTO_FLAG_VRFY;
+ peer->flash &= ~TEST8;
+ snprintf(statstr, sizeof(statstr), "gq %s fs %u",
+ peer->issuer, ntohl(ep->fstamp));
+ record_crypto_stats(&peer->srcadr, statstr);
+ DPRINTF(1, ("crypto_recv: %s\n", statstr));
+ break;
+
+ /*
+ * Mu-Varadharajan (MV) identity scheme. This scheme is
+ * designed for use with three levels of trust, trusted
+ * host, server and client. The trusted host key is
+ * opaque to servers and clients; the server keys are
+ * opaque to clients and each client key is different.
+ * Client keys can be revoked without requiring new key
+ * generations.
+ */
+ case CRYPTO_MV | CRYPTO_RESP:
+
+ /*
+ * Discard the message if invalid.
+ */
+ if ((rval = crypto_verify(ep, NULL, peer)) !=
+ XEVNT_OK)
+ break;
+
+ /*
+ * If the challenge matches the response, the
+ * server public key, signature and identity are
+ * all verified at the same time. The server is
+ * declared trusted, so we skip further
+ * certificate exchanges and move immediately to
+ * the cookie exchange.
+ */
+ if ((rval = crypto_mv(ep, peer)) != XEVNT_OK)
+ break;
+
+ peer->crypto |= CRYPTO_FLAG_VRFY;
+ peer->flash &= ~TEST8;
+ snprintf(statstr, sizeof(statstr), "mv %s fs %u",
+ peer->issuer, ntohl(ep->fstamp));
+ record_crypto_stats(&peer->srcadr, statstr);
+ DPRINTF(1, ("crypto_recv: %s\n", statstr));
+ break;
+
+
+ /*
+ * Cookie response in client and symmetric modes. If the
+ * cookie bit is set, the working cookie is the EXOR of
+ * the current and new values.
+ */
+ case CRYPTO_COOK | CRYPTO_RESP:
+
+ /*
+ * Discard the message if invalid or signature
+ * not verified with respect to the cookie
+ * values.
+ */
+ if ((rval = crypto_verify(ep, &peer->cookval,
+ peer)) != XEVNT_OK)
+ break;
+
+ /*
+ * Decrypt the cookie, hunting all the time for
+ * errors.
+ */
+ if (vallen == (u_int)EVP_PKEY_size(host_pkey)) {
+ RSA *rsa = EVP_PKEY_get0_RSA(host_pkey);
+ u_int32 *cookiebuf = malloc(RSA_size(rsa));
+ if (!cookiebuf) {
+ rval = XEVNT_CKY;
+ break;
+ }
+
+ if (RSA_private_decrypt(vallen,
+ (u_char *)ep->pkt,
+ (u_char *)cookiebuf,
+ rsa,
+ RSA_PKCS1_OAEP_PADDING) != 4) {
+ rval = XEVNT_CKY;
+ free(cookiebuf);
+ break;
+ } else {
+ cookie = ntohl(*cookiebuf);
+ free(cookiebuf);
+ }
+ } else {
+ rval = XEVNT_CKY;
+ break;
+ }
+
+ /*
+ * Install cookie values and light the cookie
+ * bit. If this is not broadcast client mode, we
+ * are done here.
+ */
+ key_expire(peer);
+ if (hismode == MODE_ACTIVE || hismode ==
+ MODE_PASSIVE)
+ peer->pcookie = peer->hcookie ^ cookie;
+ else
+ peer->pcookie = cookie;
+ peer->crypto |= CRYPTO_FLAG_COOK;
+ peer->flash &= ~TEST8;
+ snprintf(statstr, sizeof(statstr),
+ "cook %x ts %u fs %u", peer->pcookie,
+ ntohl(ep->tstamp), ntohl(ep->fstamp));
+ record_crypto_stats(&peer->srcadr, statstr);
+ DPRINTF(1, ("crypto_recv: %s\n", statstr));
+ break;
+
+ /*
+ * Install autokey values in broadcast client and
+ * symmetric modes. We have to do this every time the
+ * sever/peer cookie changes or a new keylist is
+ * rolled. Ordinarily, this is automatic as this message
+ * is piggybacked on the first NTP packet sent upon
+ * either of these events. Note that a broadcast client
+ * or symmetric peer can receive this response without a
+ * matching request.
+ */
+ case CRYPTO_AUTO | CRYPTO_RESP:
+
+ /*
+ * Discard the message if invalid or signature
+ * not verified with respect to the receive
+ * autokey values.
+ */
+ if ((rval = crypto_verify(ep, &peer->recval,
+ peer)) != XEVNT_OK)
+ break;
+
+ /*
+ * Discard the message if a broadcast client and
+ * the association ID does not match. This might
+ * happen if a broacast server restarts the
+ * protocol. A protocol restart will occur at
+ * the next ASSOC message.
+ */
+ if ((peer->cast_flags & MDF_BCLNT) &&
+ peer->assoc != associd)
+ break;
+
+ /*
+ * Install autokey values and light the
+ * autokey bit. This is not hard.
+ */
+ if (ep->tstamp == 0)
+ break;
+
+ if (peer->recval.ptr == NULL)
+ peer->recval.ptr =
+ emalloc(sizeof(struct autokey));
+ bp = (struct autokey *)peer->recval.ptr;
+ peer->recval.tstamp = ep->tstamp;
+ peer->recval.fstamp = ep->fstamp;
+ ap = (struct autokey *)ep->pkt;
+ bp->seq = ntohl(ap->seq);
+ bp->key = ntohl(ap->key);
+ peer->pkeyid = bp->key;
+ peer->crypto |= CRYPTO_FLAG_AUTO;
+ peer->flash &= ~TEST8;
+ snprintf(statstr, sizeof(statstr),
+ "auto seq %d key %x ts %u fs %u", bp->seq,
+ bp->key, ntohl(ep->tstamp),
+ ntohl(ep->fstamp));
+ record_crypto_stats(&peer->srcadr, statstr);
+ DPRINTF(1, ("crypto_recv: %s\n", statstr));
+ break;
+
+ /*
+ * X509 certificate sign response. Validate the
+ * certificate signed by the server and install. Later
+ * this can be provided to clients of this server in
+ * lieu of the self signed certificate in order to
+ * validate the public key.
+ */
+ case CRYPTO_SIGN | CRYPTO_RESP:
+
+ /*
+ * Discard the message if invalid.
+ */
+ if ((rval = crypto_verify(ep, NULL, peer)) !=
+ XEVNT_OK)
+ break;
+
+ /*
+ * Scan the certificate list to delete old
+ * versions and link the newest version first on
+ * the list.
+ */
+ if ((xinfo = cert_install(ep, peer)) == NULL) {
+ rval = XEVNT_CRT;
+ break;
+ }
+ peer->crypto |= CRYPTO_FLAG_SIGN;
+ peer->flash &= ~TEST8;
+ temp32 = xinfo->nid;
+ snprintf(statstr, sizeof(statstr),
+ "sign %s %s 0x%x %s (%u) fs %u",
+ xinfo->subject, xinfo->issuer, xinfo->flags,
+ OBJ_nid2ln(temp32), temp32,
+ ntohl(ep->fstamp));
+ record_crypto_stats(&peer->srcadr, statstr);
+ DPRINTF(1, ("crypto_recv: %s\n", statstr));
+ break;
+
+ /*
+ * Install leapseconds values. While the leapsecond
+ * values epoch, TAI offset and values expiration epoch
+ * are retained, only the current TAI offset is provided
+ * via the kernel to other applications.
+ */
+ case CRYPTO_LEAP | CRYPTO_RESP:
+ /*
+ * Discard the message if invalid. We can't
+ * compare the value timestamps here, as they
+ * can be updated by different servers.
+ */
+ rval = crypto_verify(ep, NULL, peer);
+ if ((rval != XEVNT_OK ) ||
+ (vallen != 3*sizeof(uint32_t)) )
+ break;
+
+ /* Check if we can update the basic TAI offset
+ * for our current leap frame. This is a hack
+ * and ignores the time stamps in the autokey
+ * message.
+ */
+ if (sys_leap != LEAP_NOTINSYNC)
+ leapsec_autokey_tai(ntohl(ep->pkt[0]),
+ rbufp->recv_time.l_ui, NULL);
+ tai_leap.tstamp = ep->tstamp;
+ tai_leap.fstamp = ep->fstamp;
+ crypto_update();
+ mprintf_event(EVNT_TAI, peer,
+ "%d seconds", ntohl(ep->pkt[0]));
+ peer->crypto |= CRYPTO_FLAG_LEAP;
+ peer->flash &= ~TEST8;
+ snprintf(statstr, sizeof(statstr),
+ "leap TAI offset %d at %u expire %u fs %u",
+ ntohl(ep->pkt[0]), ntohl(ep->pkt[1]),
+ ntohl(ep->pkt[2]), ntohl(ep->fstamp));
+ record_crypto_stats(&peer->srcadr, statstr);
+ DPRINTF(1, ("crypto_recv: %s\n", statstr));
+ break;
+
+ /*
+ * We come here in symmetric modes for miscellaneous
+ * commands that have value fields but are processed on
+ * the transmit side. All we need do here is check for
+ * valid field length. Note that ASSOC is handled
+ * separately.
+ */
+ case CRYPTO_CERT:
+ case CRYPTO_IFF:
+ case CRYPTO_GQ:
+ case CRYPTO_MV:
+ case CRYPTO_COOK:
+ case CRYPTO_SIGN:
+ if (len < VALUE_LEN) {
+ rval = XEVNT_LEN;
+ break;
+ }
+ /* fall through */
+
+ /*
+ * We come here in symmetric modes for requests
+ * requiring a response (above plus AUTO and LEAP) and
+ * for responses. If a request, save the extension field
+ * for later; invalid requests will be caught on the
+ * transmit side. If an error or invalid response,
+ * declare a protocol error.
+ */
+ default:
+ if (code & (CRYPTO_RESP | CRYPTO_ERROR)) {
+ rval = XEVNT_ERR;
+ } else if (peer->cmmd == NULL) {
+ fp = emalloc(len);
+ memcpy(fp, ep, len);
+ peer->cmmd = fp;
+ }
+ }
+
+ /*
+ * The first error found terminates the extension field
+ * scan and we return the laundry to the caller.
+ */
+ if (rval != XEVNT_OK) {
+ snprintf(statstr, sizeof(statstr),
+ "%04x %d %02x %s", htonl(ep->opcode),
+ associd, rval, eventstr(rval));
+ record_crypto_stats(&peer->srcadr, statstr);
+ DPRINTF(1, ("crypto_recv: %s\n", statstr));
+ return (rval);
+ }
+ authlen += (len + 3) / 4 * 4;
+ }
+ return (rval);
+}
+
+
+/*
+ * crypto_xmit - construct extension fields
+ *
+ * This routine is called both when an association is configured and
+ * when one is not. The only case where this matters is to retrieve the
+ * autokey information, in which case the caller has to provide the
+ * association ID to match the association.
+ *
+ * Side effect: update the packet offset.
+ *
+ * Errors
+ * XEVNT_OK success
+ * XEVNT_CRT bad or missing certificate
+ * XEVNT_ERR protocol error
+ * XEVNT_LEN bad field format or length
+ * XEVNT_PER host certificate expired
+ */
+int
+crypto_xmit(
+ struct peer *peer, /* peer structure pointer */
+ struct pkt *xpkt, /* transmit packet pointer */
+ struct recvbuf *rbufp, /* receive buffer pointer */
+ int start, /* offset to extension field */
+ struct exten *ep, /* extension pointer */
+ keyid_t cookie /* session cookie */
+ )
+{
+ struct exten *fp; /* extension pointers */
+ struct cert_info *cp, *xp, *yp; /* cert info/value pointer */
+ sockaddr_u *srcadr_sin; /* source address */
+ u_int32 *pkt; /* packet pointer */
+ u_int opcode; /* extension field opcode */
+ char certname[MAXHOSTNAME + 1]; /* subject name buffer */
+ char statstr[NTP_MAXSTRLEN]; /* statistics for filegen */
+ tstamp_t tstamp;
+ struct calendar tscal;
+ u_int vallen;
+ struct value vtemp;
+ associd_t associd;
+ int rval;
+ int len;
+ keyid_t tcookie;
+
+ /*
+ * Generate the requested extension field request code, length
+ * and association ID. If this is a response and the host is not
+ * synchronized, light the error bit and go home.
+ */
+ pkt = (u_int32 *)xpkt + start / 4;
+ fp = (struct exten *)pkt;
+ opcode = ntohl(ep->opcode);
+ if (peer != NULL) {
+ srcadr_sin = &peer->srcadr;
+ if (!(opcode & CRYPTO_RESP))
+ peer->opcode = ep->opcode;
+ } else {
+ srcadr_sin = &rbufp->recv_srcadr;
+ }
+ associd = (associd_t) ntohl(ep->associd);
+ len = 8;
+ fp->opcode = htonl((opcode & 0xffff0000) | len);
+ fp->associd = ep->associd;
+ rval = XEVNT_OK;
+ tstamp = crypto_time();
+ switch (opcode & 0xffff0000) {
+
+ /*
+ * Send association request and response with status word and
+ * host name. Note, this message is not signed and the filestamp
+ * contains only the status word.
+ */
+ case CRYPTO_ASSOC:
+ case CRYPTO_ASSOC | CRYPTO_RESP:
+ len = crypto_send(fp, &hostval, start);
+ fp->fstamp = htonl(crypto_flags);
+ break;
+
+ /*
+ * Send certificate request. Use the values from the extension
+ * field.
+ */
+ case CRYPTO_CERT:
+ memset(&vtemp, 0, sizeof(vtemp));
+ vtemp.tstamp = ep->tstamp;
+ vtemp.fstamp = ep->fstamp;
+ vtemp.vallen = ep->vallen;
+ vtemp.ptr = (u_char *)ep->pkt;
+ len = crypto_send(fp, &vtemp, start);
+ break;
+
+ /*
+ * Send sign request. Use the host certificate, which is self-
+ * signed and may or may not be trusted.
+ */
+ case CRYPTO_SIGN:
+ (void)ntpcal_ntp_to_date(&tscal, tstamp, NULL);
+ if ((calcomp(&tscal, &(cert_host->first)) < 0)
+ || (calcomp(&tscal, &(cert_host->last)) > 0))
+ rval = XEVNT_PER;
+ else
+ len = crypto_send(fp, &cert_host->cert, start);
+ break;
+
+ /*
+ * Send certificate response. Use the name in the extension
+ * field to find the certificate in the cache. If the request
+ * contains no subject name, assume the name of this host. This
+ * is for backwards compatibility. Private certificates are
+ * never sent.
+ *
+ * There may be several certificates matching the request. First
+ * choice is a self-signed trusted certificate; second choice is
+ * any certificate signed by another host. There is no third
+ * choice.
+ */
+ case CRYPTO_CERT | CRYPTO_RESP:
+ vallen = exten_payload_size(ep); /* Must be <64k */
+ if (vallen == 0 || vallen >= sizeof(certname) ) {
+ rval = XEVNT_LEN;
+ break;
+ }
+
+ /*
+ * Find all public valid certificates with matching
+ * subject. If a self-signed, trusted certificate is
+ * found, use that certificate. If not, use the last non
+ * self-signed certificate.
+ */
+ memcpy(certname, ep->pkt, vallen);
+ certname[vallen] = '\0';
+ xp = yp = NULL;
+ for (cp = cinfo; cp != NULL; cp = cp->link) {
+ if (cp->flags & (CERT_PRIV | CERT_ERROR))
+ continue;
+
+ if (strcmp(certname, cp->subject) != 0)
+ continue;
+
+ if (strcmp(certname, cp->issuer) != 0)
+ yp = cp;
+ else if (cp ->flags & CERT_TRUST)
+ xp = cp;
+ continue;
+ }
+
+ /*
+ * Be careful who you trust. If the certificate is not
+ * found, return an empty response. Note that we dont
+ * enforce lifetimes here.
+ *
+ * The timestamp and filestamp are taken from the
+ * certificate value structure. For all certificates the
+ * timestamp is the latest signature update time. For
+ * host and imported certificates the filestamp is the
+ * creation epoch. For signed certificates the filestamp
+ * is the creation epoch of the trusted certificate at
+ * the root of the certificate trail. In principle, this
+ * allows strong checking for signature masquerade.
+ */
+ if (xp == NULL)
+ xp = yp;
+ if (xp == NULL)
+ break;
+
+ if (tstamp == 0)
+ break;
+
+ len = crypto_send(fp, &xp->cert, start);
+ break;
+
+ /*
+ * Send challenge in Schnorr (IFF) identity scheme.
+ */
+ case CRYPTO_IFF:
+ if (peer == NULL)
+ break; /* hack attack */
+
+ if ((rval = crypto_alice(peer, &vtemp)) == XEVNT_OK) {
+ len = crypto_send(fp, &vtemp, start);
+ value_free(&vtemp);
+ }
+ break;
+
+ /*
+ * Send response in Schnorr (IFF) identity scheme.
+ */
+ case CRYPTO_IFF | CRYPTO_RESP:
+ if ((rval = crypto_bob(ep, &vtemp)) == XEVNT_OK) {
+ len = crypto_send(fp, &vtemp, start);
+ value_free(&vtemp);
+ }
+ break;
+
+ /*
+ * Send challenge in Guillou-Quisquater (GQ) identity scheme.
+ */
+ case CRYPTO_GQ:
+ if (peer == NULL)
+ break; /* hack attack */
+
+ if ((rval = crypto_alice2(peer, &vtemp)) == XEVNT_OK) {
+ len = crypto_send(fp, &vtemp, start);
+ value_free(&vtemp);
+ }
+ break;
+
+ /*
+ * Send response in Guillou-Quisquater (GQ) identity scheme.
+ */
+ case CRYPTO_GQ | CRYPTO_RESP:
+ if ((rval = crypto_bob2(ep, &vtemp)) == XEVNT_OK) {
+ len = crypto_send(fp, &vtemp, start);
+ value_free(&vtemp);
+ }
+ break;
+
+ /*
+ * Send challenge in MV identity scheme.
+ */
+ case CRYPTO_MV:
+ if (peer == NULL)
+ break; /* hack attack */
+
+ if ((rval = crypto_alice3(peer, &vtemp)) == XEVNT_OK) {
+ len = crypto_send(fp, &vtemp, start);
+ value_free(&vtemp);
+ }
+ break;
+
+ /*
+ * Send response in MV identity scheme.
+ */
+ case CRYPTO_MV | CRYPTO_RESP:
+ if ((rval = crypto_bob3(ep, &vtemp)) == XEVNT_OK) {
+ len = crypto_send(fp, &vtemp, start);
+ value_free(&vtemp);
+ }
+ break;
+
+ /*
+ * Send certificate sign response. The integrity of the request
+ * certificate has already been verified on the receive side.
+ * Sign the response using the local server key. Use the
+ * filestamp from the request and use the timestamp as the
+ * current time. Light the error bit if the certificate is
+ * invalid or contains an unverified signature.
+ */
+ case CRYPTO_SIGN | CRYPTO_RESP:
+ if ((rval = cert_sign(ep, &vtemp)) == XEVNT_OK) {
+ len = crypto_send(fp, &vtemp, start);
+ value_free(&vtemp);
+ }
+ break;
+
+ /*
+ * Send public key and signature. Use the values from the public
+ * key.
+ */
+ case CRYPTO_COOK:
+ len = crypto_send(fp, &pubkey, start);
+ break;
+
+ /*
+ * Encrypt and send cookie and signature. Light the error bit if
+ * anything goes wrong.
+ */
+ case CRYPTO_COOK | CRYPTO_RESP:
+ vallen = ntohl(ep->vallen); /* Must be <64k */
+ if ( vallen == 0
+ || (vallen >= MAX_VALLEN)
+ || (opcode & 0x0000ffff) < VALUE_LEN + vallen) {
+ rval = XEVNT_LEN;
+ break;
+ }
+ if (peer == NULL)
+ tcookie = cookie;
+ else
+ tcookie = peer->hcookie;
+ if ((rval = crypto_encrypt((const u_char *)ep->pkt, vallen, &tcookie, &vtemp))
+ == XEVNT_OK) {
+ len = crypto_send(fp, &vtemp, start);
+ value_free(&vtemp);
+ }
+ break;
+
+ /*
+ * Find peer and send autokey data and signature in broadcast
+ * server and symmetric modes. Use the values in the autokey
+ * structure. If no association is found, either the server has
+ * restarted with new associations or some perp has replayed an
+ * old message, in which case light the error bit.
+ */
+ case CRYPTO_AUTO | CRYPTO_RESP:
+ if (peer == NULL) {
+ if ((peer = findpeerbyassoc(associd)) == NULL) {
+ rval = XEVNT_ERR;
+ break;
+ }
+ }
+ peer->flags &= ~FLAG_ASSOC;
+ len = crypto_send(fp, &peer->sndval, start);
+ break;
+
+ /*
+ * Send leapseconds values and signature. Use the values from
+ * the tai structure. If no table has been loaded, just send an
+ * empty request.
+ */
+ case CRYPTO_LEAP | CRYPTO_RESP:
+ len = crypto_send(fp, &tai_leap, start);
+ break;
+
+ /*
+ * Default - Send a valid command for unknown requests; send
+ * an error response for unknown resonses.
+ */
+ default:
+ if (opcode & CRYPTO_RESP)
+ rval = XEVNT_ERR;
+ }
+
+ /*
+ * In case of error, flame the log. If a request, toss the
+ * puppy; if a response, return so the sender can flame, too.
+ */
+ if (rval != XEVNT_OK) {
+ u_int32 uint32;
+
+ uint32 = CRYPTO_ERROR;
+ opcode |= uint32;
+ fp->opcode |= htonl(uint32);
+ snprintf(statstr, sizeof(statstr),
+ "%04x %d %02x %s", opcode, associd, rval,
+ eventstr(rval));
+ record_crypto_stats(srcadr_sin, statstr);
+ DPRINTF(1, ("crypto_xmit: %s\n", statstr));
+ if (!(opcode & CRYPTO_RESP))
+ return (0);
+ }
+ DPRINTF(1, ("crypto_xmit: flags 0x%x offset %d len %d code 0x%x associd %d\n",
+ crypto_flags, start, len, opcode >> 16, associd));
+ return (len);
+}
+
+
+/*
+ * crypto_verify - verify the extension field value and signature
+ *
+ * Returns
+ * XEVNT_OK success
+ * XEVNT_ERR protocol error
+ * XEVNT_FSP bad filestamp
+ * XEVNT_LEN bad field format or length
+ * XEVNT_PUB bad or missing public key
+ * XEVNT_SGL bad signature length
+ * XEVNT_SIG signature not verified
+ * XEVNT_TSP bad timestamp
+ */
+static int
+crypto_verify(
+ struct exten *ep, /* extension pointer */
+ struct value *vp, /* value pointer */
+ struct peer *peer /* peer structure pointer */
+ )
+{
+ EVP_PKEY *pkey; /* server public key */
+ EVP_MD_CTX *ctx; /* signature context */
+ tstamp_t tstamp, tstamp1 = 0; /* timestamp */
+ tstamp_t fstamp, fstamp1 = 0; /* filestamp */
+ u_int vallen; /* value length */
+ u_int siglen; /* signature length */
+ u_int opcode, len;
+ int i;
+
+ /*
+ * We are extremely parannoyed. We require valid opcode, length,
+ * association ID, timestamp, filestamp, public key, digest,
+ * signature length and signature, where relevant. Note that
+ * preliminary length checks are done in the main loop.
+ */
+ len = ntohl(ep->opcode) & 0x0000ffff;
+ opcode = ntohl(ep->opcode) & 0xffff0000;
+
+ /*
+ * Check for valid value header, association ID and extension
+ * field length. Remember, it is not an error to receive an
+ * unsolicited response; however, the response ID must match
+ * the association ID.
+ */
+ if (opcode & CRYPTO_ERROR)
+ return (XEVNT_ERR);
+
+ if (len < VALUE_LEN)
+ return (XEVNT_LEN);
+
+ if (opcode == (CRYPTO_AUTO | CRYPTO_RESP) && (peer->pmode ==
+ MODE_BROADCAST || (peer->cast_flags & MDF_BCLNT))) {
+ if (ntohl(ep->associd) != peer->assoc)
+ return (XEVNT_ERR);
+ } else {
+ if (ntohl(ep->associd) != peer->associd)
+ return (XEVNT_ERR);
+ }
+
+ /*
+ * We have a valid value header. Check for valid value and
+ * signature field lengths. The extension field length must be
+ * long enough to contain the value header, value and signature.
+ * Note both the value and signature field lengths are rounded
+ * up to the next word (4 octets).
+ */
+ vallen = ntohl(ep->vallen);
+ if ( vallen == 0
+ || vallen > MAX_VALLEN)
+ return (XEVNT_LEN);
+
+ i = (vallen + 3) / 4;
+ siglen = ntohl(ep->pkt[i]);
+ ++i;
+ if ( siglen > MAX_VALLEN
+ || len - VALUE_LEN < ((vallen + 3) / 4) * 4
+ || len - VALUE_LEN - ((vallen + 3) / 4) * 4
+ < ((siglen + 3) / 4) * 4)
+ return (XEVNT_LEN);
+
+ /*
+ * Check for valid timestamp and filestamp. If the timestamp is
+ * zero, the sender is not synchronized and signatures are
+ * not possible. If nonzero the timestamp must not precede the
+ * filestamp. The timestamp and filestamp must not precede the
+ * corresponding values in the value structure, if present.
+ */
+ tstamp = ntohl(ep->tstamp);
+ fstamp = ntohl(ep->fstamp);
+ if (tstamp == 0)
+ return (XEVNT_TSP);
+
+ if (tstamp < fstamp)
+ return (XEVNT_TSP);
+
+ if (vp != NULL) {
+ tstamp1 = ntohl(vp->tstamp);
+ fstamp1 = ntohl(vp->fstamp);
+ if (tstamp1 != 0 && fstamp1 != 0) {
+ if (tstamp < tstamp1)
+ return (XEVNT_TSP);
+
+ if ((tstamp < fstamp1 || fstamp < fstamp1))
+ return (XEVNT_FSP);
+ }
+ }
+
+ /*
+ * At the time the certificate message is validated, the public
+ * key in the message is not available. Thus, don't try to
+ * verify the signature.
+ */
+ if (opcode == (CRYPTO_CERT | CRYPTO_RESP))
+ return (XEVNT_OK);
+
+ /*
+ * Check for valid signature length, public key and digest
+ * algorithm.
+ */
+ if (crypto_flags & peer->crypto & CRYPTO_FLAG_PRIV)
+ pkey = sign_pkey;
+ else
+ pkey = peer->pkey;
+ if (siglen == 0 || pkey == NULL || peer->digest == NULL)
+ return (XEVNT_ERR);
+
+ if (siglen != (u_int)EVP_PKEY_size(pkey))
+ return (XEVNT_SGL);
+
+ /*
+ * Darn, I thought we would never get here. Verify the
+ * signature. If the identity exchange is verified, light the
+ * proventic bit. What a relief.
+ */
+ ctx = EVP_MD_CTX_new();
+ EVP_VerifyInit(ctx, peer->digest);
+ /* XXX: the "+ 12" needs to be at least documented... */
+ EVP_VerifyUpdate(ctx, (u_char *)&ep->tstamp, vallen + 12);
+ if (EVP_VerifyFinal(ctx, (u_char *)&ep->pkt[i], siglen,
+ pkey) <= 0) {
+ EVP_MD_CTX_free(ctx);
+ return (XEVNT_SIG);
+ }
+ EVP_MD_CTX_free(ctx);
+
+ if (peer->crypto & CRYPTO_FLAG_VRFY)
+ peer->crypto |= CRYPTO_FLAG_PROV;
+ return (XEVNT_OK);
+}
+
+
+/*
+ * crypto_encrypt - construct vp (encrypted cookie and signature) from
+ * the public key and cookie.
+ *
+ * Returns:
+ * XEVNT_OK success
+ * XEVNT_CKY bad or missing cookie
+ * XEVNT_PUB bad or missing public key
+ */
+static int
+crypto_encrypt(
+ const u_char *ptr, /* Public Key */
+ u_int vallen, /* Length of Public Key */
+ keyid_t *cookie, /* server cookie */
+ struct value *vp /* value pointer */
+ )
+{
+ EVP_PKEY *pkey; /* public key */
+ EVP_MD_CTX *ctx; /* signature context */
+ tstamp_t tstamp; /* NTP timestamp */
+ u_int32 temp32;
+ u_char *puch;
+
+ /*
+ * Extract the public key from the request.
+ */
+ pkey = d2i_PublicKey(EVP_PKEY_RSA, NULL, &ptr, vallen);
+ if (pkey == NULL) {
+ msyslog(LOG_ERR, "crypto_encrypt: %s",
+ ERR_error_string(ERR_get_error(), NULL));
+ return (XEVNT_PUB);
+ }
+
+ /*
+ * Encrypt the cookie, encode in ASN.1 and sign.
+ */
+ memset(vp, 0, sizeof(struct value));
+ tstamp = crypto_time();
+ vp->tstamp = htonl(tstamp);
+ vp->fstamp = hostval.tstamp;
+ vallen = EVP_PKEY_size(pkey);
+ vp->vallen = htonl(vallen);
+ vp->ptr = emalloc(vallen);
+ puch = vp->ptr;
+ temp32 = htonl(*cookie);
+ if (RSA_public_encrypt(4, (u_char *)&temp32, puch,
+ EVP_PKEY_get0_RSA(pkey), RSA_PKCS1_OAEP_PADDING) <= 0) {
+ msyslog(LOG_ERR, "crypto_encrypt: %s",
+ ERR_error_string(ERR_get_error(), NULL));
+ free(vp->ptr);
+ EVP_PKEY_free(pkey);
+ return (XEVNT_CKY);
+ }
+ EVP_PKEY_free(pkey);
+ if (tstamp == 0)
+ return (XEVNT_OK);
+
+ vp->sig = emalloc(sign_siglen);
+ ctx = EVP_MD_CTX_new();
+ EVP_SignInit(ctx, sign_digest);
+ EVP_SignUpdate(ctx, (u_char *)&vp->tstamp, 12);
+ EVP_SignUpdate(ctx, vp->ptr, vallen);
+ if (EVP_SignFinal(ctx, vp->sig, &vallen, sign_pkey)) {
+ INSIST(vallen <= sign_siglen);
+ vp->siglen = htonl(vallen);
+ }
+ EVP_MD_CTX_free(ctx);
+ return (XEVNT_OK);
+}
+
+
+/*
+ * crypto_ident - construct extension field for identity scheme
+ *
+ * This routine determines which identity scheme is in use and
+ * constructs an extension field for that scheme.
+ *
+ * Returns
+ * CRYTPO_IFF IFF scheme
+ * CRYPTO_GQ GQ scheme
+ * CRYPTO_MV MV scheme
+ * CRYPTO_NULL no available scheme
+ */
+u_int
+crypto_ident(
+ struct peer *peer /* peer structure pointer */
+ )
+{
+ char filename[MAXFILENAME];
+ const char * scheme_name;
+ u_int scheme_id;
+
+ /*
+ * We come here after the group trusted host has been found; its
+ * name defines the group name. Search the key cache for all
+ * keys matching the same group name in order IFF, GQ and MV.
+ * Use the first one available.
+ */
+ scheme_name = NULL;
+ if (peer->crypto & CRYPTO_FLAG_IFF) {
+ scheme_name = "iff";
+ scheme_id = CRYPTO_IFF;
+ } else if (peer->crypto & CRYPTO_FLAG_GQ) {
+ scheme_name = "gq";
+ scheme_id = CRYPTO_GQ;
+ } else if (peer->crypto & CRYPTO_FLAG_MV) {
+ scheme_name = "mv";
+ scheme_id = CRYPTO_MV;
+ }
+
+ if (scheme_name != NULL) {
+ snprintf(filename, sizeof(filename), "ntpkey_%spar_%s",
+ scheme_name, peer->ident);
+ peer->ident_pkey = crypto_key(filename, NULL,
+ &peer->srcadr);
+ if (peer->ident_pkey != NULL)
+ return scheme_id;
+ }
+
+ msyslog(LOG_NOTICE,
+ "crypto_ident: no identity parameters found for group %s",
+ peer->ident);
+
+ return CRYPTO_NULL;
+}
+
+
+/*
+ * crypto_args - construct extension field from arguments
+ *
+ * This routine creates an extension field with current timestamps and
+ * specified opcode, association ID and optional string. Note that the
+ * extension field is created here, but freed after the crypto_xmit()
+ * call in the protocol module.
+ *
+ * Returns extension field pointer (no errors)
+ *
+ * XXX: opcode and len should really be 32-bit quantities and
+ * we should make sure that str is not too big.
+ */
+struct exten *
+crypto_args(
+ struct peer *peer, /* peer structure pointer */
+ u_int opcode, /* operation code */
+ associd_t associd, /* association ID */
+ char *str /* argument string */
+ )
+{
+ tstamp_t tstamp; /* NTP timestamp */
+ struct exten *ep; /* extension field pointer */
+ u_int len; /* extension field length */
+ size_t slen = 0;
+
+ tstamp = crypto_time();
+ len = sizeof(struct exten);
+ if (str != NULL) {
+ slen = strlen(str);
+ INSIST(slen < MAX_VALLEN);
+ len += slen;
+ }
+ ep = emalloc_zero(len);
+ if (opcode == 0)
+ return (ep);
+
+ REQUIRE(0 == (len & ~0x0000ffff));
+ REQUIRE(0 == (opcode & ~0xffff0000));
+
+ ep->opcode = htonl(opcode + len);
+ ep->associd = htonl(associd);
+ ep->tstamp = htonl(tstamp);
+ ep->fstamp = hostval.tstamp;
+ ep->vallen = 0;
+ if (str != NULL) {
+ ep->vallen = htonl(slen);
+ memcpy((char *)ep->pkt, str, slen);
+ }
+ return (ep);
+}
+
+
+/*
+ * crypto_send - construct extension field from value components
+ *
+ * The value and signature fields are zero-padded to a word boundary.
+ * Note: it is not polite to send a nonempty signature with zero
+ * timestamp or a nonzero timestamp with an empty signature, but those
+ * rules are not enforced here.
+ *
+ * XXX This code won't work on a box with 16-bit ints.
+ */
+int
+crypto_send(
+ struct exten *ep, /* extension field pointer */
+ struct value *vp, /* value pointer */
+ int start /* buffer offset */
+ )
+{
+ u_int len, vallen, siglen, opcode;
+ u_int i, j;
+
+ /*
+ * Calculate extension field length and check for buffer
+ * overflow. Leave room for the MAC.
+ */
+ len = 16; /* XXX Document! */
+ vallen = ntohl(vp->vallen);
+ INSIST(vallen <= MAX_VALLEN);
+ len += ((vallen + 3) / 4 + 1) * 4;
+ siglen = ntohl(vp->siglen);
+ len += ((siglen + 3) / 4 + 1) * 4;
+ if (start + len > sizeof(struct pkt) - MAX_MAC_LEN)
+ return (0);
+
+ /*
+ * Copy timestamps.
+ */
+ ep->tstamp = vp->tstamp;
+ ep->fstamp = vp->fstamp;
+ ep->vallen = vp->vallen;
+
+ /*
+ * Copy value. If the data field is empty or zero length,
+ * encode an empty value with length zero.
+ */
+ i = 0;
+ if (vallen > 0 && vp->ptr != NULL) {
+ j = vallen / 4;
+ if (j * 4 < vallen)
+ ep->pkt[i + j++] = 0;
+ memcpy(&ep->pkt[i], vp->ptr, vallen);
+ i += j;
+ }
+
+ /*
+ * Copy signature. If the signature field is empty or zero
+ * length, encode an empty signature with length zero.
+ */
+ ep->pkt[i++] = vp->siglen;
+ if (siglen > 0 && vp->sig != NULL) {
+ j = siglen / 4;
+ if (j * 4 < siglen)
+ ep->pkt[i + j++] = 0;
+ memcpy(&ep->pkt[i], vp->sig, siglen);
+ /* i += j; */ /* We don't use i after this */
+ }
+ opcode = ntohl(ep->opcode);
+ ep->opcode = htonl((opcode & 0xffff0000) | len);
+ ENSURE(len <= MAX_VALLEN);
+ return (len);
+}
+
+
+/*
+ * crypto_update - compute new public value and sign extension fields
+ *
+ * This routine runs periodically, like once a day, and when something
+ * changes. It updates the timestamps on three value structures and one
+ * value structure list, then signs all the structures:
+ *
+ * hostval host name (not signed)
+ * pubkey public key
+ * cinfo certificate info/value list
+ * tai_leap leap values
+ *
+ * Filestamps are proventic data, so this routine runs only when the
+ * host is synchronized to a proventicated source. Thus, the timestamp
+ * is proventic and can be used to deflect clogging attacks.
+ *
+ * Returns void (no errors)
+ */
+void
+crypto_update(void)
+{
+ EVP_MD_CTX *ctx; /* message digest context */
+ struct cert_info *cp; /* certificate info/value */
+ char statstr[NTP_MAXSTRLEN]; /* statistics for filegen */
+ u_int32 *ptr;
+ u_int len;
+ leap_result_t leap_data;
+
+ hostval.tstamp = htonl(crypto_time());
+ if (hostval.tstamp == 0)
+ return;
+
+ ctx = EVP_MD_CTX_new();
+
+ /*
+ * Sign public key and timestamps. The filestamp is derived from
+ * the host key file extension from wherever the file was
+ * generated.
+ */
+ if (pubkey.vallen != 0) {
+ pubkey.tstamp = hostval.tstamp;
+ pubkey.siglen = 0;
+ if (pubkey.sig == NULL)
+ pubkey.sig = emalloc(sign_siglen);
+ EVP_SignInit(ctx, sign_digest);
+ EVP_SignUpdate(ctx, (u_char *)&pubkey, 12);
+ EVP_SignUpdate(ctx, pubkey.ptr, ntohl(pubkey.vallen));
+ if (EVP_SignFinal(ctx, pubkey.sig, &len, sign_pkey)) {
+ INSIST(len <= sign_siglen);
+ pubkey.siglen = htonl(len);
+ }
+ }
+
+ /*
+ * Sign certificates and timestamps. The filestamp is derived
+ * from the certificate file extension from wherever the file
+ * was generated. Note we do not throw expired certificates
+ * away; they may have signed younger ones.
+ */
+ for (cp = cinfo; cp != NULL; cp = cp->link) {
+ cp->cert.tstamp = hostval.tstamp;
+ cp->cert.siglen = 0;
+ if (cp->cert.sig == NULL)
+ cp->cert.sig = emalloc(sign_siglen);
+ EVP_SignInit(ctx, sign_digest);
+ EVP_SignUpdate(ctx, (u_char *)&cp->cert, 12);
+ EVP_SignUpdate(ctx, cp->cert.ptr,
+ ntohl(cp->cert.vallen));
+ if (EVP_SignFinal(ctx, cp->cert.sig, &len, sign_pkey)) {
+ INSIST(len <= sign_siglen);
+ cp->cert.siglen = htonl(len);
+ }
+ }
+
+ /*
+ * Sign leapseconds values and timestamps. Note it is not an
+ * error to return null values.
+ */
+ tai_leap.tstamp = hostval.tstamp;
+ tai_leap.fstamp = hostval.fstamp;
+
+ /* Get the leap second era. We might need a full lookup early
+ * after start, when the cache is not yet loaded.
+ */
+ leapsec_frame(&leap_data);
+ if ( ! memcmp(&leap_data.ebase, &leap_data.ttime, sizeof(vint64))) {
+ time_t now = time(NULL);
+ uint32_t nowntp = (uint32_t)now + JAN_1970;
+ leapsec_query(&leap_data, nowntp, &now);
+ }
+
+ /* Create the data block. The protocol does not work without. */
+ len = 3 * sizeof(u_int32);
+ if (tai_leap.ptr == NULL || ntohl(tai_leap.vallen) != len) {
+ free(tai_leap.ptr);
+ tai_leap.ptr = emalloc(len);
+ tai_leap.vallen = htonl(len);
+ }
+ ptr = (u_int32 *)tai_leap.ptr;
+ if (leap_data.tai_offs > 10) {
+ /* create a TAI / leap era block. The end time is a
+ * fake -- maybe we can do better.
+ */
+ ptr[0] = htonl(leap_data.tai_offs);
+ ptr[1] = htonl(leap_data.ebase.d_s.lo);
+ if (leap_data.ttime.d_s.hi >= 0)
+ ptr[2] = htonl(leap_data.ttime.D_s.lo + 7*86400);
+ else
+ ptr[2] = htonl(leap_data.ebase.D_s.lo + 25*86400);
+ } else {
+ /* no leap era available */
+ memset(ptr, 0, len);
+ }
+ if (tai_leap.sig == NULL)
+ tai_leap.sig = emalloc(sign_siglen);
+ EVP_SignInit(ctx, sign_digest);
+ EVP_SignUpdate(ctx, (u_char *)&tai_leap, 12);
+ EVP_SignUpdate(ctx, tai_leap.ptr, len);
+ if (EVP_SignFinal(ctx, tai_leap.sig, &len, sign_pkey)) {
+ INSIST(len <= sign_siglen);
+ tai_leap.siglen = htonl(len);
+ }
+ crypto_flags |= CRYPTO_FLAG_TAI;
+
+ snprintf(statstr, sizeof(statstr), "signature update ts %u",
+ ntohl(hostval.tstamp));
+ record_crypto_stats(NULL, statstr);
+ DPRINTF(1, ("crypto_update: %s\n", statstr));
+ EVP_MD_CTX_free(ctx);
+}
+
+/*
+ * crypto_update_taichange - eventually trigger crypto_update
+ *
+ * This is called when a change in 'sys_tai' is detected. This will
+ * happen shortly after a leap second is detected, but unhappily also
+ * early after system start; also, the crypto stuff might be unused and
+ * an unguarded call to crypto_update() causes a crash.
+ *
+ * This function makes sure that there already *is* a valid crypto block
+ * for the use with autokey, and only calls 'crypto_update()' if it can
+ * succeed.
+ *
+ * Returns void (no errors)
+ */
+void
+crypto_update_taichange(void)
+{
+ static const u_int len = 3 * sizeof(u_int32);
+
+ /* check if the signing digest algo is available */
+ if (sign_digest == NULL || sign_pkey == NULL)
+ return;
+
+ /* check size of TAI extension block */
+ if (tai_leap.ptr == NULL || ntohl(tai_leap.vallen) != len)
+ return;
+
+ /* crypto_update should at least not crash here! */
+ crypto_update();
+}
+
+/*
+ * value_free - free value structure components.
+ *
+ * Returns void (no errors)
+ */
+void
+value_free(
+ struct value *vp /* value structure */
+ )
+{
+ if (vp->ptr != NULL)
+ free(vp->ptr);
+ if (vp->sig != NULL)
+ free(vp->sig);
+ memset(vp, 0, sizeof(struct value));
+}
+
+
+/*
+ * crypto_time - returns current NTP time.
+ *
+ * Returns NTP seconds if in synch, 0 otherwise
+ */
+tstamp_t
+crypto_time()
+{
+ l_fp tstamp; /* NTP time */
+
+ L_CLR(&tstamp);
+ if (sys_leap != LEAP_NOTINSYNC)
+ get_systime(&tstamp);
+ return (tstamp.l_ui);
+}
+
+
+/*
+ * asn_to_calendar - convert ASN1_TIME time structure to struct calendar.
+ *
+ */
+static
+void
+asn_to_calendar (
+ const ASN1_TIME *asn1time, /* pointer to ASN1_TIME structure */
+ struct calendar *pjd /* pointer to result */
+ )
+{
+ size_t len; /* length of ASN1_TIME string */
+ char v[24]; /* writable copy of ASN1_TIME string */
+ unsigned long temp; /* result from strtoul */
+
+ /*
+ * Extract time string YYMMDDHHMMSSZ from ASN1 time structure.
+ * Or YYYYMMDDHHMMSSZ.
+ * Note that the YY, MM, DD fields start with one, the HH, MM,
+ * SS fields start with zero and the Z character is ignored.
+ * Also note that two-digit years less than 50 map to years greater than
+ * 100. Dontcha love ASN.1? Better than MIL-188.
+ */
+ len = asn1time->length;
+ REQUIRE(len < sizeof(v));
+ (void)strncpy(v, (char *)(asn1time->data), len);
+ REQUIRE(len >= 13);
+ temp = strtoul(v+len-3, NULL, 10);
+ pjd->second = temp;
+ v[len-3] = '\0';
+
+ temp = strtoul(v+len-5, NULL, 10);
+ pjd->minute = temp;
+ v[len-5] = '\0';
+
+ temp = strtoul(v+len-7, NULL, 10);
+ pjd->hour = temp;
+ v[len-7] = '\0';
+
+ temp = strtoul(v+len-9, NULL, 10);
+ pjd->monthday = temp;
+ v[len-9] = '\0';
+
+ temp = strtoul(v+len-11, NULL, 10);
+ pjd->month = temp;
+ v[len-11] = '\0';
+
+ temp = strtoul(v, NULL, 10);
+ /* handle two-digit years */
+ if (temp < 50UL)
+ temp += 100UL;
+ if (temp < 150UL)
+ temp += 1900UL;
+ pjd->year = temp;
+
+ pjd->yearday = pjd->weekday = 0;
+ return;
+}
+
+
+/*
+ * bigdig() - compute a BIGNUM MD5 hash of a BIGNUM number.
+ *
+ * Returns void (no errors)
+ */
+static void
+bighash(
+ BIGNUM *bn, /* BIGNUM * from */
+ BIGNUM *bk /* BIGNUM * to */
+ )
+{
+ EVP_MD_CTX *ctx; /* message digest context */
+ u_char dgst[EVP_MAX_MD_SIZE]; /* message digest */
+ u_char *ptr; /* a BIGNUM as binary string */
+ u_int len;
+
+ len = BN_num_bytes(bn);
+ ptr = emalloc(len);
+ BN_bn2bin(bn, ptr);
+ ctx = EVP_MD_CTX_new();
+# if defined(OPENSSL) && defined(EVP_MD_CTX_FLAG_NON_FIPS_ALLOW)
+ /* [Bug 3457] set flags and don't kill them again */
+ EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+ EVP_DigestInit_ex(ctx, EVP_md5(), NULL);
+# else
+ EVP_DigestInit(ctx, EVP_md5());
+# endif
+ EVP_DigestUpdate(ctx, ptr, len);
+ EVP_DigestFinal(ctx, dgst, &len);
+ EVP_MD_CTX_free(ctx);
+ BN_bin2bn(dgst, len, bk);
+ free(ptr);
+}
+
+
+/*
+ ***********************************************************************
+ * *
+ * The following routines implement the Schnorr (IFF) identity scheme *
+ * *
+ ***********************************************************************
+ *
+ * The Schnorr (IFF) identity scheme is intended for use when
+ * certificates are generated by some other trusted certificate
+ * authority and the certificate cannot be used to convey public
+ * parameters. There are two kinds of files: encrypted server files that
+ * contain private and public values and nonencrypted client files that
+ * contain only public values. New generations of server files must be
+ * securely transmitted to all servers of the group; client files can be
+ * distributed by any means. The scheme is self contained and
+ * independent of new generations of host keys, sign keys and
+ * certificates.
+ *
+ * The IFF values hide in a DSA cuckoo structure which uses the same
+ * parameters. The values are used by an identity scheme based on DSA
+ * cryptography and described in Stimson p. 285. The p is a 512-bit
+ * prime, g a generator of Zp* and q a 160-bit prime that divides p - 1
+ * and is a qth root of 1 mod p; that is, g^q = 1 mod p. The TA rolls a
+ * private random group key b (0 < b < q) and public key v = g^b, then
+ * sends (p, q, g, b) to the servers and (p, q, g, v) to the clients.
+ * Alice challenges Bob to confirm identity using the protocol described
+ * below.
+ *
+ * How it works
+ *
+ * The scheme goes like this. Both Alice and Bob have the public primes
+ * p, q and generator g. The TA gives private key b to Bob and public
+ * key v to Alice.
+ *
+ * Alice rolls new random challenge r (o < r < q) and sends to Bob in
+ * the IFF request message. Bob rolls new random k (0 < k < q), then
+ * computes y = k + b r mod q and x = g^k mod p and sends (y, hash(x))
+ * to Alice in the response message. Besides making the response
+ * shorter, the hash makes it effectivey impossible for an intruder to
+ * solve for b by observing a number of these messages.
+ *
+ * Alice receives the response and computes g^y v^r mod p. After a bit
+ * of algebra, this simplifies to g^k. If the hash of this result
+ * matches hash(x), Alice knows that Bob has the group key b. The signed
+ * response binds this knowledge to Bob's private key and the public key
+ * previously received in his certificate.
+ *
+ * crypto_alice - construct Alice's challenge in IFF scheme
+ *
+ * Returns
+ * XEVNT_OK success
+ * XEVNT_ID bad or missing group key
+ * XEVNT_PUB bad or missing public key
+ */
+static int
+crypto_alice(
+ struct peer *peer, /* peer pointer */
+ struct value *vp /* value pointer */
+ )
+{
+ DSA *dsa; /* IFF parameters */
+ BN_CTX *bctx; /* BIGNUM context */
+ EVP_MD_CTX *ctx; /* signature context */
+ tstamp_t tstamp;
+ u_int len;
+ const BIGNUM *q;
+
+ /*
+ * The identity parameters must have correct format and content.
+ */
+ if (peer->ident_pkey == NULL) {
+ msyslog(LOG_NOTICE, "crypto_alice: scheme unavailable");
+ return (XEVNT_ID);
+ }
+
+ if ((dsa = EVP_PKEY_get0_DSA(peer->ident_pkey->pkey)) == NULL) {
+ msyslog(LOG_NOTICE, "crypto_alice: defective key");
+ return (XEVNT_PUB);
+ }
+
+ /*
+ * Roll new random r (0 < r < q).
+ */
+ if (peer->iffval != NULL)
+ BN_free(peer->iffval);
+ peer->iffval = BN_new();
+ DSA_get0_pqg(dsa, NULL, &q, NULL);
+ len = BN_num_bytes(q);
+ BN_rand(peer->iffval, len * 8, -1, 1); /* r mod q*/
+ bctx = BN_CTX_new();
+ BN_mod(peer->iffval, peer->iffval, q, bctx);
+ BN_CTX_free(bctx);
+
+ /*
+ * Sign and send to Bob. The filestamp is from the local file.
+ */
+ memset(vp, 0, sizeof(struct value));
+ tstamp = crypto_time();
+ vp->tstamp = htonl(tstamp);
+ vp->fstamp = htonl(peer->ident_pkey->fstamp);
+ vp->vallen = htonl(len);
+ vp->ptr = emalloc(len);
+ BN_bn2bin(peer->iffval, vp->ptr);
+ if (tstamp == 0)
+ return (XEVNT_OK);
+
+ vp->sig = emalloc(sign_siglen);
+ ctx = EVP_MD_CTX_new();
+ EVP_SignInit(ctx, sign_digest);
+ EVP_SignUpdate(ctx, (u_char *)&vp->tstamp, 12);
+ EVP_SignUpdate(ctx, vp->ptr, len);
+ if (EVP_SignFinal(ctx, vp->sig, &len, sign_pkey)) {
+ INSIST(len <= sign_siglen);
+ vp->siglen = htonl(len);
+ }
+ EVP_MD_CTX_free(ctx);
+ return (XEVNT_OK);
+}
+
+
+/*
+ * crypto_bob - construct Bob's response to Alice's challenge
+ *
+ * Returns
+ * XEVNT_OK success
+ * XEVNT_ERR protocol error
+ * XEVNT_ID bad or missing group key
+ */
+static int
+crypto_bob(
+ struct exten *ep, /* extension pointer */
+ struct value *vp /* value pointer */
+ )
+{
+ DSA *dsa; /* IFF parameters */
+ DSA_SIG *sdsa; /* DSA signature context fake */
+ BN_CTX *bctx; /* BIGNUM context */
+ EVP_MD_CTX *ctx; /* signature context */
+ tstamp_t tstamp; /* NTP timestamp */
+ BIGNUM *bn, *bk, *r;
+ u_char *ptr;
+ u_int len; /* extension field value length */
+ const BIGNUM *p, *q, *g;
+ const BIGNUM *priv_key;
+
+ /*
+ * If the IFF parameters are not valid, something awful
+ * happened or we are being tormented.
+ */
+ if (iffkey_info == NULL) {
+ msyslog(LOG_NOTICE, "crypto_bob: scheme unavailable");
+ return (XEVNT_ID);
+ }
+ dsa = EVP_PKEY_get0_DSA(iffkey_info->pkey);
+ DSA_get0_pqg(dsa, &p, &q, &g);
+ DSA_get0_key(dsa, NULL, &priv_key);
+
+ /*
+ * Extract r from the challenge.
+ */
+ len = exten_payload_size(ep);
+ if (len == 0 || len > MAX_VALLEN)
+ return (XEVNT_LEN);
+ if ((r = BN_bin2bn((u_char *)ep->pkt, len, NULL)) == NULL) {
+ msyslog(LOG_ERR, "crypto_bob: %s",
+ ERR_error_string(ERR_get_error(), NULL));
+ return (XEVNT_ERR);
+ }
+
+ /*
+ * Bob rolls random k (0 < k < q), computes y = k + b r mod q
+ * and x = g^k mod p, then sends (y, hash(x)) to Alice.
+ */
+ bctx = BN_CTX_new(); bk = BN_new(); bn = BN_new();
+ sdsa = DSA_SIG_new();
+ BN_rand(bk, len * 8, -1, 1); /* k */
+ BN_mod_mul(bn, priv_key, r, q, bctx); /* b r mod q */
+ BN_add(bn, bn, bk);
+ BN_mod(bn, bn, q, bctx); /* k + b r mod q */
+ BN_mod_exp(bk, g, bk, p, bctx); /* g^k mod p */
+ bighash(bk, bk);
+ DSA_SIG_set0(sdsa, bn, bk);
+ BN_CTX_free(bctx);
+ BN_free(r);
+#ifdef DEBUG
+ if (debug > 1)
+ DSA_print_fp(stdout, dsa, 0);
+#endif
+
+ /*
+ * Encode the values in ASN.1 and sign. The filestamp is from
+ * the local file.
+ */
+ len = i2d_DSA_SIG(sdsa, NULL);
+ if (len == 0) {
+ msyslog(LOG_ERR, "crypto_bob: %s",
+ ERR_error_string(ERR_get_error(), NULL));
+ DSA_SIG_free(sdsa);
+ return (XEVNT_ERR);
+ }
+ if (len > MAX_VALLEN) {
+ msyslog(LOG_ERR, "crypto_bob: signature is too big: %u",
+ len);
+ DSA_SIG_free(sdsa);
+ return (XEVNT_LEN);
+ }
+ memset(vp, 0, sizeof(struct value));
+ tstamp = crypto_time();
+ vp->tstamp = htonl(tstamp);
+ vp->fstamp = htonl(iffkey_info->fstamp);
+ vp->vallen = htonl(len);
+ ptr = emalloc(len);
+ vp->ptr = ptr;
+ i2d_DSA_SIG(sdsa, &ptr);
+ DSA_SIG_free(sdsa);
+ if (tstamp == 0)
+ return (XEVNT_OK);
+
+ /* XXX: more validation to make sure the sign fits... */
+ vp->sig = emalloc(sign_siglen);
+ ctx = EVP_MD_CTX_new();
+ EVP_SignInit(ctx, sign_digest);
+ EVP_SignUpdate(ctx, (u_char *)&vp->tstamp, 12);
+ EVP_SignUpdate(ctx, vp->ptr, len);
+ if (EVP_SignFinal(ctx, vp->sig, &len, sign_pkey)) {
+ INSIST(len <= sign_siglen);
+ vp->siglen = htonl(len);
+ }
+ EVP_MD_CTX_free(ctx);
+ return (XEVNT_OK);
+}
+
+
+/*
+ * crypto_iff - verify Bob's response to Alice's challenge
+ *
+ * Returns
+ * XEVNT_OK success
+ * XEVNT_FSP bad filestamp
+ * XEVNT_ID bad or missing group key
+ * XEVNT_PUB bad or missing public key
+ */
+int
+crypto_iff(
+ struct exten *ep, /* extension pointer */
+ struct peer *peer /* peer structure pointer */
+ )
+{
+ DSA *dsa; /* IFF parameters */
+ BN_CTX *bctx; /* BIGNUM context */
+ DSA_SIG *sdsa; /* DSA parameters */
+ BIGNUM *bn, *bk;
+ u_int len;
+ const u_char *ptr;
+ int temp;
+ const BIGNUM *p, *g;
+ const BIGNUM *r, *s;
+ const BIGNUM *pub_key;
+
+ /*
+ * If the IFF parameters are not valid or no challenge was sent,
+ * something awful happened or we are being tormented.
+ */
+ if (peer->ident_pkey == NULL) {
+ msyslog(LOG_NOTICE, "crypto_iff: scheme unavailable");
+ return (XEVNT_ID);
+ }
+ if (ntohl(ep->fstamp) != peer->ident_pkey->fstamp) {
+ msyslog(LOG_NOTICE, "crypto_iff: invalid filestamp %u",
+ ntohl(ep->fstamp));
+ return (XEVNT_FSP);
+ }
+ if ((dsa = EVP_PKEY_get0_DSA(peer->ident_pkey->pkey)) == NULL) {
+ msyslog(LOG_NOTICE, "crypto_iff: defective key");
+ return (XEVNT_PUB);
+ }
+ if (peer->iffval == NULL) {
+ msyslog(LOG_NOTICE, "crypto_iff: missing challenge");
+ return (XEVNT_ID);
+ }
+
+ /*
+ * Extract the k + b r and g^k values from the response.
+ */
+ bctx = BN_CTX_new(); bk = BN_new(); bn = BN_new();
+ len = ntohl(ep->vallen);
+ ptr = (u_char *)ep->pkt;
+ if ((sdsa = d2i_DSA_SIG(NULL, &ptr, len)) == NULL) {
+ BN_free(bn); BN_free(bk); BN_CTX_free(bctx);
+ msyslog(LOG_ERR, "crypto_iff: %s",
+ ERR_error_string(ERR_get_error(), NULL));
+ return (XEVNT_ERR);
+ }
+
+ /*
+ * Compute g^(k + b r) g^(q - b)r mod p.
+ */
+ DSA_get0_key(dsa, &pub_key, NULL);
+ DSA_get0_pqg(dsa, &p, NULL, &g);
+ DSA_SIG_get0(sdsa, &r, &s);
+ BN_mod_exp(bn, pub_key, peer->iffval, p, bctx);
+ BN_mod_exp(bk, g, r, p, bctx);
+ BN_mod_mul(bn, bn, bk, p, bctx);
+
+ /*
+ * Verify the hash of the result matches hash(x).
+ */
+ bighash(bn, bn);
+ temp = BN_cmp(bn, s);
+ BN_free(bn); BN_free(bk); BN_CTX_free(bctx);
+ BN_free(peer->iffval);
+ peer->iffval = NULL;
+ DSA_SIG_free(sdsa);
+ if (temp == 0)
+ return (XEVNT_OK);
+
+ msyslog(LOG_NOTICE, "crypto_iff: identity not verified");
+ return (XEVNT_ID);
+}
+
+
+/*
+ ***********************************************************************
+ * *
+ * The following routines implement the Guillou-Quisquater (GQ) *
+ * identity scheme *
+ * *
+ ***********************************************************************
+ *
+ * The Guillou-Quisquater (GQ) identity scheme is intended for use when
+ * the certificate can be used to convey public parameters. The scheme
+ * uses a X509v3 certificate extension field do convey the public key of
+ * a private key known only to servers. There are two kinds of files:
+ * encrypted server files that contain private and public values and
+ * nonencrypted client files that contain only public values. New
+ * generations of server files must be securely transmitted to all
+ * servers of the group; client files can be distributed by any means.
+ * The scheme is self contained and independent of new generations of
+ * host keys and sign keys. The scheme is self contained and independent
+ * of new generations of host keys and sign keys.
+ *
+ * The GQ parameters hide in a RSA cuckoo structure which uses the same
+ * parameters. The values are used by an identity scheme based on RSA
+ * cryptography and described in Stimson p. 300 (with errors). The 512-
+ * bit public modulus is n = p q, where p and q are secret large primes.
+ * The TA rolls private random group key b as RSA exponent. These values
+ * are known to all group members.
+ *
+ * When rolling new certificates, a server recomputes the private and
+ * public keys. The private key u is a random roll, while the public key
+ * is the inverse obscured by the group key v = (u^-1)^b. These values
+ * replace the private and public keys normally generated by the RSA
+ * scheme. Alice challenges Bob to confirm identity using the protocol
+ * described below.
+ *
+ * How it works
+ *
+ * The scheme goes like this. Both Alice and Bob have the same modulus n
+ * and some random b as the group key. These values are computed and
+ * distributed in advance via secret means, although only the group key
+ * b is truly secret. Each has a private random private key u and public
+ * key (u^-1)^b, although not necessarily the same ones. Bob and Alice
+ * can regenerate the key pair from time to time without affecting
+ * operations. The public key is conveyed on the certificate in an
+ * extension field; the private key is never revealed.
+ *
+ * Alice rolls new random challenge r and sends to Bob in the GQ
+ * request message. Bob rolls new random k, then computes y = k u^r mod
+ * n and x = k^b mod n and sends (y, hash(x)) to Alice in the response
+ * message. Besides making the response shorter, the hash makes it
+ * effectivey impossible for an intruder to solve for b by observing
+ * a number of these messages.
+ *
+ * Alice receives the response and computes y^b v^r mod n. After a bit
+ * of algebra, this simplifies to k^b. If the hash of this result
+ * matches hash(x), Alice knows that Bob has the group key b. The signed
+ * response binds this knowledge to Bob's private key and the public key
+ * previously received in his certificate.
+ *
+ * crypto_alice2 - construct Alice's challenge in GQ scheme
+ *
+ * Returns
+ * XEVNT_OK success
+ * XEVNT_ID bad or missing group key
+ * XEVNT_PUB bad or missing public key
+ */
+static int
+crypto_alice2(
+ struct peer *peer, /* peer pointer */
+ struct value *vp /* value pointer */
+ )
+{
+ RSA *rsa; /* GQ parameters */
+ BN_CTX *bctx; /* BIGNUM context */
+ EVP_MD_CTX *ctx; /* signature context */
+ tstamp_t tstamp;
+ u_int len;
+ const BIGNUM *n;
+
+ /*
+ * The identity parameters must have correct format and content.
+ */
+ if (peer->ident_pkey == NULL)
+ return (XEVNT_ID);
+
+ if ((rsa = EVP_PKEY_get0_RSA(peer->ident_pkey->pkey)) == NULL) {
+ msyslog(LOG_NOTICE, "crypto_alice2: defective key");
+ return (XEVNT_PUB);
+ }
+
+ /*
+ * Roll new random r (0 < r < n).
+ */
+ if (peer->iffval != NULL)
+ BN_free(peer->iffval);
+ peer->iffval = BN_new();
+ RSA_get0_key(rsa, &n, NULL, NULL);
+ len = BN_num_bytes(n);
+ BN_rand(peer->iffval, len * 8, -1, 1); /* r mod n */
+ bctx = BN_CTX_new();
+ BN_mod(peer->iffval, peer->iffval, n, bctx);
+ BN_CTX_free(bctx);
+
+ /*
+ * Sign and send to Bob. The filestamp is from the local file.
+ */
+ memset(vp, 0, sizeof(struct value));
+ tstamp = crypto_time();
+ vp->tstamp = htonl(tstamp);
+ vp->fstamp = htonl(peer->ident_pkey->fstamp);
+ vp->vallen = htonl(len);
+ vp->ptr = emalloc(len);
+ BN_bn2bin(peer->iffval, vp->ptr);
+ if (tstamp == 0)
+ return (XEVNT_OK);
+
+ vp->sig = emalloc(sign_siglen);
+ ctx = EVP_MD_CTX_new();
+ EVP_SignInit(ctx, sign_digest);
+ EVP_SignUpdate(ctx, (u_char *)&vp->tstamp, 12);
+ EVP_SignUpdate(ctx, vp->ptr, len);
+ if (EVP_SignFinal(ctx, vp->sig, &len, sign_pkey)) {
+ INSIST(len <= sign_siglen);
+ vp->siglen = htonl(len);
+ }
+ EVP_MD_CTX_free(ctx);
+ return (XEVNT_OK);
+}
+
+
+/*
+ * crypto_bob2 - construct Bob's response to Alice's challenge
+ *
+ * Returns
+ * XEVNT_OK success
+ * XEVNT_ERR protocol error
+ * XEVNT_ID bad or missing group key
+ */
+static int
+crypto_bob2(
+ struct exten *ep, /* extension pointer */
+ struct value *vp /* value pointer */
+ )
+{
+ RSA *rsa; /* GQ parameters */
+ DSA_SIG *sdsa; /* DSA parameters */
+ BN_CTX *bctx; /* BIGNUM context */
+ EVP_MD_CTX *ctx; /* signature context */
+ tstamp_t tstamp; /* NTP timestamp */
+ BIGNUM *r, *k, *g, *y;
+ u_char *ptr;
+ u_int len;
+ int s_len;
+ const BIGNUM *n, *p, *e;
+
+ /*
+ * If the GQ parameters are not valid, something awful
+ * happened or we are being tormented.
+ */
+ if (gqkey_info == NULL) {
+ msyslog(LOG_NOTICE, "crypto_bob2: scheme unavailable");
+ return (XEVNT_ID);
+ }
+ rsa = EVP_PKEY_get0_RSA(gqkey_info->pkey);
+ RSA_get0_key(rsa, &n, &p, &e);
+
+ /*
+ * Extract r from the challenge.
+ */
+ len = exten_payload_size(ep);
+ if (len == 0 || len > MAX_VALLEN)
+ return (XEVNT_LEN);
+ if ((r = BN_bin2bn((u_char *)ep->pkt, len, NULL)) == NULL) {
+ msyslog(LOG_ERR, "crypto_bob2: %s",
+ ERR_error_string(ERR_get_error(), NULL));
+ return (XEVNT_ERR);
+ }
+
+ /*
+ * Bob rolls random k (0 < k < n), computes y = k u^r mod n and
+ * x = k^b mod n, then sends (y, hash(x)) to Alice.
+ */
+ bctx = BN_CTX_new(); k = BN_new(); g = BN_new(); y = BN_new();
+ sdsa = DSA_SIG_new();
+ BN_rand(k, len * 8, -1, 1); /* k */
+ BN_mod(k, k, n, bctx);
+ BN_mod_exp(y, p, r, n, bctx); /* u^r mod n */
+ BN_mod_mul(y, k, y, n, bctx); /* k u^r mod n */
+ BN_mod_exp(g, k, e, n, bctx); /* k^b mod n */
+ bighash(g, g);
+ DSA_SIG_set0(sdsa, y, g);
+ BN_CTX_free(bctx);
+ BN_free(r); BN_free(k);
+#ifdef DEBUG
+ if (debug > 1)
+ RSA_print_fp(stdout, rsa, 0);
+#endif
+
+ /*
+ * Encode the values in ASN.1 and sign. The filestamp is from
+ * the local file.
+ */
+ len = s_len = i2d_DSA_SIG(sdsa, NULL);
+ if (s_len <= 0) {
+ msyslog(LOG_ERR, "crypto_bob2: %s",
+ ERR_error_string(ERR_get_error(), NULL));
+ DSA_SIG_free(sdsa);
+ return (XEVNT_ERR);
+ }
+ memset(vp, 0, sizeof(struct value));
+ tstamp = crypto_time();
+ vp->tstamp = htonl(tstamp);
+ vp->fstamp = htonl(gqkey_info->fstamp);
+ vp->vallen = htonl(len);
+ ptr = emalloc(len);
+ vp->ptr = ptr;
+ i2d_DSA_SIG(sdsa, &ptr);
+ DSA_SIG_free(sdsa);
+ if (tstamp == 0)
+ return (XEVNT_OK);
+
+ vp->sig = emalloc(sign_siglen);
+ ctx = EVP_MD_CTX_new();
+ EVP_SignInit(ctx, sign_digest);
+ EVP_SignUpdate(ctx, (u_char *)&vp->tstamp, 12);
+ EVP_SignUpdate(ctx, vp->ptr, len);
+ if (EVP_SignFinal(ctx, vp->sig, &len, sign_pkey)) {
+ INSIST(len <= sign_siglen);
+ vp->siglen = htonl(len);
+ }
+ EVP_MD_CTX_free(ctx);
+ return (XEVNT_OK);
+}
+
+
+/*
+ * crypto_gq - verify Bob's response to Alice's challenge
+ *
+ * Returns
+ * XEVNT_OK success
+ * XEVNT_ERR protocol error
+ * XEVNT_FSP bad filestamp
+ * XEVNT_ID bad or missing group keys
+ * XEVNT_PUB bad or missing public key
+ */
+int
+crypto_gq(
+ struct exten *ep, /* extension pointer */
+ struct peer *peer /* peer structure pointer */
+ )
+{
+ RSA *rsa; /* GQ parameters */
+ BN_CTX *bctx; /* BIGNUM context */
+ DSA_SIG *sdsa; /* RSA signature context fake */
+ BIGNUM *y, *v;
+ const u_char *ptr;
+ long len;
+ u_int temp;
+ const BIGNUM *n, *e;
+ const BIGNUM *r, *s;
+
+ /*
+ * If the GQ parameters are not valid or no challenge was sent,
+ * something awful happened or we are being tormented. Note that
+ * the filestamp on the local key file can be greater than on
+ * the remote parameter file if the keys have been refreshed.
+ */
+ if (peer->ident_pkey == NULL) {
+ msyslog(LOG_NOTICE, "crypto_gq: scheme unavailable");
+ return (XEVNT_ID);
+ }
+ if (ntohl(ep->fstamp) < peer->ident_pkey->fstamp) {
+ msyslog(LOG_NOTICE, "crypto_gq: invalid filestamp %u",
+ ntohl(ep->fstamp));
+ return (XEVNT_FSP);
+ }
+ if ((rsa = EVP_PKEY_get0_RSA(peer->ident_pkey->pkey)) == NULL) {
+ msyslog(LOG_NOTICE, "crypto_gq: defective key");
+ return (XEVNT_PUB);
+ }
+ RSA_get0_key(rsa, &n, NULL, &e);
+ if (peer->iffval == NULL) {
+ msyslog(LOG_NOTICE, "crypto_gq: missing challenge");
+ return (XEVNT_ID);
+ }
+
+ /*
+ * Extract the y = k u^r and hash(x = k^b) values from the
+ * response.
+ */
+ bctx = BN_CTX_new(); y = BN_new(); v = BN_new();
+ len = ntohl(ep->vallen);
+ ptr = (u_char *)ep->pkt;
+ if ((sdsa = d2i_DSA_SIG(NULL, &ptr, len)) == NULL) {
+ BN_CTX_free(bctx); BN_free(y); BN_free(v);
+ msyslog(LOG_ERR, "crypto_gq: %s",
+ ERR_error_string(ERR_get_error(), NULL));
+ return (XEVNT_ERR);
+ }
+ DSA_SIG_get0(sdsa, &r, &s);
+
+ /*
+ * Compute v^r y^b mod n.
+ */
+ if (peer->grpkey == NULL) {
+ msyslog(LOG_NOTICE, "crypto_gq: missing group key");
+ return (XEVNT_ID);
+ }
+ BN_mod_exp(v, peer->grpkey, peer->iffval, n, bctx);
+ /* v^r mod n */
+ BN_mod_exp(y, r, e, n, bctx); /* y^b mod n */
+ BN_mod_mul(y, v, y, n, bctx); /* v^r y^b mod n */
+
+ /*
+ * Verify the hash of the result matches hash(x).
+ */
+ bighash(y, y);
+ temp = BN_cmp(y, s);
+ BN_CTX_free(bctx); BN_free(y); BN_free(v);
+ BN_free(peer->iffval);
+ peer->iffval = NULL;
+ DSA_SIG_free(sdsa);
+ if (temp == 0)
+ return (XEVNT_OK);
+
+ msyslog(LOG_NOTICE, "crypto_gq: identity not verified");
+ return (XEVNT_ID);
+}
+
+
+/*
+ ***********************************************************************
+ * *
+ * The following routines implement the Mu-Varadharajan (MV) identity *
+ * scheme *
+ * *
+ ***********************************************************************
+ *
+ * The Mu-Varadharajan (MV) cryptosystem was originally intended when
+ * servers broadcast messages to clients, but clients never send
+ * messages to servers. There is one encryption key for the server and a
+ * separate decryption key for each client. It operated something like a
+ * pay-per-view satellite broadcasting system where the session key is
+ * encrypted by the broadcaster and the decryption keys are held in a
+ * tamperproof set-top box.
+ *
+ * The MV parameters and private encryption key hide in a DSA cuckoo
+ * structure which uses the same parameters, but generated in a
+ * different way. The values are used in an encryption scheme similar to
+ * El Gamal cryptography and a polynomial formed from the expansion of
+ * product terms (x - x[j]), as described in Mu, Y., and V.
+ * Varadharajan: Robust and Secure Broadcasting, Proc. Indocrypt 2001,
+ * 223-231. The paper has significant errors and serious omissions.
+ *
+ * Let q be the product of n distinct primes s1[j] (j = 1...n), where
+ * each s1[j] has m significant bits. Let p be a prime p = 2 * q + 1, so
+ * that q and each s1[j] divide p - 1 and p has M = n * m + 1
+ * significant bits. Let g be a generator of Zp; that is, gcd(g, p - 1)
+ * = 1 and g^q = 1 mod p. We do modular arithmetic over Zq and then
+ * project into Zp* as exponents of g. Sometimes we have to compute an
+ * inverse b^-1 of random b in Zq, but for that purpose we require
+ * gcd(b, q) = 1. We expect M to be in the 500-bit range and n
+ * relatively small, like 30. These are the parameters of the scheme and
+ * they are expensive to compute.
+ *
+ * We set up an instance of the scheme as follows. A set of random
+ * values x[j] mod q (j = 1...n), are generated as the zeros of a
+ * polynomial of order n. The product terms (x - x[j]) are expanded to
+ * form coefficients a[i] mod q (i = 0...n) in powers of x. These are
+ * used as exponents of the generator g mod p to generate the private
+ * encryption key A. The pair (gbar, ghat) of public server keys and the
+ * pairs (xbar[j], xhat[j]) (j = 1...n) of private client keys are used
+ * to construct the decryption keys. The devil is in the details.
+ *
+ * This routine generates a private server encryption file including the
+ * private encryption key E and partial decryption keys gbar and ghat.
+ * It then generates public client decryption files including the public
+ * keys xbar[j] and xhat[j] for each client j. The partial decryption
+ * files are used to compute the inverse of E. These values are suitably
+ * blinded so secrets are not revealed.
+ *
+ * The distinguishing characteristic of this scheme is the capability to
+ * revoke keys. Included in the calculation of E, gbar and ghat is the
+ * product s = prod(s1[j]) (j = 1...n) above. If the factor s1[j] is
+ * subsequently removed from the product and E, gbar and ghat
+ * recomputed, the jth client will no longer be able to compute E^-1 and
+ * thus unable to decrypt the messageblock.
+ *
+ * How it works
+ *
+ * The scheme goes like this. Bob has the server values (p, E, q, gbar,
+ * ghat) and Alice has the client values (p, xbar, xhat).
+ *
+ * Alice rolls new random nonce r mod p and sends to Bob in the MV
+ * request message. Bob rolls random nonce k mod q, encrypts y = r E^k
+ * mod p and sends (y, gbar^k, ghat^k) to Alice.
+ *
+ * Alice receives the response and computes the inverse (E^k)^-1 from
+ * the partial decryption keys gbar^k, ghat^k, xbar and xhat. She then
+ * decrypts y and verifies it matches the original r. The signed
+ * response binds this knowledge to Bob's private key and the public key
+ * previously received in his certificate.
+ *
+ * crypto_alice3 - construct Alice's challenge in MV scheme
+ *
+ * Returns
+ * XEVNT_OK success
+ * XEVNT_ID bad or missing group key
+ * XEVNT_PUB bad or missing public key
+ */
+static int
+crypto_alice3(
+ struct peer *peer, /* peer pointer */
+ struct value *vp /* value pointer */
+ )
+{
+ DSA *dsa; /* MV parameters */
+ BN_CTX *bctx; /* BIGNUM context */
+ EVP_MD_CTX *ctx; /* signature context */
+ tstamp_t tstamp;
+ u_int len;
+ const BIGNUM *p;
+
+ /*
+ * The identity parameters must have correct format and content.
+ */
+ if (peer->ident_pkey == NULL)
+ return (XEVNT_ID);
+
+ if ((dsa = EVP_PKEY_get0_DSA(peer->ident_pkey->pkey)) == NULL) {
+ msyslog(LOG_NOTICE, "crypto_alice3: defective key");
+ return (XEVNT_PUB);
+ }
+ DSA_get0_pqg(dsa, &p, NULL, NULL);
+
+ /*
+ * Roll new random r (0 < r < q).
+ */
+ if (peer->iffval != NULL)
+ BN_free(peer->iffval);
+ peer->iffval = BN_new();
+ len = BN_num_bytes(p);
+ BN_rand(peer->iffval, len * 8, -1, 1); /* r mod p */
+ bctx = BN_CTX_new();
+ BN_mod(peer->iffval, peer->iffval, p, bctx);
+ BN_CTX_free(bctx);
+
+ /*
+ * Sign and send to Bob. The filestamp is from the local file.
+ */
+ memset(vp, 0, sizeof(struct value));
+ tstamp = crypto_time();
+ vp->tstamp = htonl(tstamp);
+ vp->fstamp = htonl(peer->ident_pkey->fstamp);
+ vp->vallen = htonl(len);
+ vp->ptr = emalloc(len);
+ BN_bn2bin(peer->iffval, vp->ptr);
+ if (tstamp == 0)
+ return (XEVNT_OK);
+
+ vp->sig = emalloc(sign_siglen);
+ ctx = EVP_MD_CTX_new();
+ EVP_SignInit(ctx, sign_digest);
+ EVP_SignUpdate(ctx, (u_char *)&vp->tstamp, 12);
+ EVP_SignUpdate(ctx, vp->ptr, len);
+ if (EVP_SignFinal(ctx, vp->sig, &len, sign_pkey)) {
+ INSIST(len <= sign_siglen);
+ vp->siglen = htonl(len);
+ }
+ EVP_MD_CTX_free(ctx);
+ return (XEVNT_OK);
+}
+
+
+/*
+ * crypto_bob3 - construct Bob's response to Alice's challenge
+ *
+ * Returns
+ * XEVNT_OK success
+ * XEVNT_ERR protocol error
+ */
+static int
+crypto_bob3(
+ struct exten *ep, /* extension pointer */
+ struct value *vp /* value pointer */
+ )
+{
+ DSA *dsa; /* MV parameters */
+ DSA *sdsa; /* DSA signature context fake */
+ BN_CTX *bctx; /* BIGNUM context */
+ EVP_MD_CTX *ctx; /* signature context */
+ tstamp_t tstamp; /* NTP timestamp */
+ BIGNUM *r, *k, *u;
+ u_char *ptr;
+ u_int len;
+ const BIGNUM *p, *q, *g;
+ const BIGNUM *pub_key, *priv_key;
+ BIGNUM *sp, *sq, *sg;
+
+ /*
+ * If the MV parameters are not valid, something awful
+ * happened or we are being tormented.
+ */
+ if (mvkey_info == NULL) {
+ msyslog(LOG_NOTICE, "crypto_bob3: scheme unavailable");
+ return (XEVNT_ID);
+ }
+ dsa = EVP_PKEY_get0_DSA(mvkey_info->pkey);
+ DSA_get0_pqg(dsa, &p, &q, &g);
+ DSA_get0_key(dsa, &pub_key, &priv_key);
+
+ /*
+ * Extract r from the challenge.
+ */
+ len = exten_payload_size(ep);
+ if (len == 0 || len > MAX_VALLEN)
+ return (XEVNT_LEN);
+ if ((r = BN_bin2bn((u_char *)ep->pkt, len, NULL)) == NULL) {
+ msyslog(LOG_ERR, "crypto_bob3: %s",
+ ERR_error_string(ERR_get_error(), NULL));
+ return (XEVNT_ERR);
+ }
+
+ /*
+ * Bob rolls random k (0 < k < q), making sure it is not a
+ * factor of q. He then computes y = r A^k and sends (y, gbar^k,
+ * and ghat^k) to Alice.
+ */
+ bctx = BN_CTX_new(); k = BN_new(); u = BN_new();
+ sdsa = DSA_new();
+ sp = BN_new(); sq = BN_new(); sg = BN_new();
+ while (1) {
+ BN_rand(k, BN_num_bits(q), 0, 0);
+ BN_mod(k, k, q, bctx);
+ BN_gcd(u, k, q, bctx);
+ if (BN_is_one(u))
+ break;
+ }
+ BN_mod_exp(u, g, k, p, bctx); /* A^k r */
+ BN_mod_mul(sp, u, r, p, bctx);
+ BN_mod_exp(sq, priv_key, k, p, bctx); /* gbar */
+ BN_mod_exp(sg, pub_key, k, p, bctx); /* ghat */
+ DSA_set0_key(sdsa, BN_dup(pub_key), NULL);
+ DSA_set0_pqg(sdsa, sp, sq, sg);
+ BN_CTX_free(bctx); BN_free(k); BN_free(r); BN_free(u);
+#ifdef DEBUG
+ if (debug > 1)
+ DSA_print_fp(stdout, sdsa, 0);
+#endif
+
+ /*
+ * Encode the values in ASN.1 and sign. The filestamp is from
+ * the local file.
+ */
+ memset(vp, 0, sizeof(struct value));
+ tstamp = crypto_time();
+ vp->tstamp = htonl(tstamp);
+ vp->fstamp = htonl(mvkey_info->fstamp);
+ len = i2d_DSAparams(sdsa, NULL);
+ if (len == 0) {
+ msyslog(LOG_ERR, "crypto_bob3: %s",
+ ERR_error_string(ERR_get_error(), NULL));
+ DSA_free(sdsa);
+ return (XEVNT_ERR);
+ }
+ vp->vallen = htonl(len);
+ ptr = emalloc(len);
+ vp->ptr = ptr;
+ i2d_DSAparams(sdsa, &ptr);
+ DSA_free(sdsa);
+ if (tstamp == 0)
+ return (XEVNT_OK);
+
+ vp->sig = emalloc(sign_siglen);
+ ctx = EVP_MD_CTX_new();
+ EVP_SignInit(ctx, sign_digest);
+ EVP_SignUpdate(ctx, (u_char *)&vp->tstamp, 12);
+ EVP_SignUpdate(ctx, vp->ptr, len);
+ if (EVP_SignFinal(ctx, vp->sig, &len, sign_pkey)) {
+ INSIST(len <= sign_siglen);
+ vp->siglen = htonl(len);
+ }
+ EVP_MD_CTX_free(ctx);
+ return (XEVNT_OK);
+}
+
+
+/*
+ * crypto_mv - verify Bob's response to Alice's challenge
+ *
+ * Returns
+ * XEVNT_OK success
+ * XEVNT_ERR protocol error
+ * XEVNT_FSP bad filestamp
+ * XEVNT_ID bad or missing group key
+ * XEVNT_PUB bad or missing public key
+ */
+int
+crypto_mv(
+ struct exten *ep, /* extension pointer */
+ struct peer *peer /* peer structure pointer */
+ )
+{
+ DSA *dsa; /* MV parameters */
+ DSA *sdsa; /* DSA parameters */
+ BN_CTX *bctx; /* BIGNUM context */
+ BIGNUM *k, *u, *v;
+ u_int len;
+ const u_char *ptr;
+ int temp;
+ const BIGNUM *p;
+ const BIGNUM *pub_key, *priv_key;
+ const BIGNUM *sp, *sq, *sg;
+
+ /*
+ * If the MV parameters are not valid or no challenge was sent,
+ * something awful happened or we are being tormented.
+ */
+ if (peer->ident_pkey == NULL) {
+ msyslog(LOG_NOTICE, "crypto_mv: scheme unavailable");
+ return (XEVNT_ID);
+ }
+ if (ntohl(ep->fstamp) != peer->ident_pkey->fstamp) {
+ msyslog(LOG_NOTICE, "crypto_mv: invalid filestamp %u",
+ ntohl(ep->fstamp));
+ return (XEVNT_FSP);
+ }
+ if ((dsa = EVP_PKEY_get0_DSA(peer->ident_pkey->pkey)) == NULL) {
+ msyslog(LOG_NOTICE, "crypto_mv: defective key");
+ return (XEVNT_PUB);
+ }
+ DSA_get0_pqg(dsa, &p, NULL, NULL);
+ DSA_get0_key(dsa, &pub_key, &priv_key);
+ if (peer->iffval == NULL) {
+ msyslog(LOG_NOTICE, "crypto_mv: missing challenge");
+ return (XEVNT_ID);
+ }
+
+ /*
+ * Extract the y, gbar and ghat values from the response.
+ */
+ bctx = BN_CTX_new(); k = BN_new(); u = BN_new(); v = BN_new();
+ len = ntohl(ep->vallen);
+ ptr = (u_char *)ep->pkt;
+ if ((sdsa = d2i_DSAparams(NULL, &ptr, len)) == NULL) {
+ msyslog(LOG_ERR, "crypto_mv: %s",
+ ERR_error_string(ERR_get_error(), NULL));
+ return (XEVNT_ERR);
+ }
+ DSA_get0_pqg(sdsa, &sp, &sq, &sg);
+
+ /*
+ * Compute (gbar^xhat ghat^xbar) mod p.
+ */
+ BN_mod_exp(u, sq, pub_key, p, bctx);
+ BN_mod_exp(v, sg, priv_key, p, bctx);
+ BN_mod_mul(u, u, v, p, bctx);
+ BN_mod_mul(u, u, sp, p, bctx);
+
+ /*
+ * The result should match r.
+ */
+ temp = BN_cmp(u, peer->iffval);
+ BN_CTX_free(bctx); BN_free(k); BN_free(u); BN_free(v);
+ BN_free(peer->iffval);
+ peer->iffval = NULL;
+ DSA_free(sdsa);
+ if (temp == 0)
+ return (XEVNT_OK);
+
+ msyslog(LOG_NOTICE, "crypto_mv: identity not verified");
+ return (XEVNT_ID);
+}
+
+
+/*
+ ***********************************************************************
+ * *
+ * The following routines are used to manipulate certificates *
+ * *
+ ***********************************************************************
+ */
+/*
+ * cert_sign - sign x509 certificate equest and update value structure.
+ *
+ * The certificate request includes a copy of the host certificate,
+ * which includes the version number, subject name and public key of the
+ * host. The resulting certificate includes these values plus the
+ * serial number, issuer name and valid interval of the server. The
+ * valid interval extends from the current time to the same time one
+ * year hence. This may extend the life of the signed certificate beyond
+ * that of the signer certificate.
+ *
+ * It is convenient to use the NTP seconds of the current time as the
+ * serial number. In the value structure the timestamp is the current
+ * time and the filestamp is taken from the extension field. Note this
+ * routine is called only when the client clock is synchronized to a
+ * proventic source, so timestamp comparisons are valid.
+ *
+ * The host certificate is valid from the time it was generated for a
+ * period of one year. A signed certificate is valid from the time of
+ * signature for a period of one year, but only the host certificate (or
+ * sign certificate if used) is actually used to encrypt and decrypt
+ * signatures. The signature trail is built from the client via the
+ * intermediate servers to the trusted server. Each signature on the
+ * trail must be valid at the time of signature, but it could happen
+ * that a signer certificate expire before the signed certificate, which
+ * remains valid until its expiration.
+ *
+ * Returns
+ * XEVNT_OK success
+ * XEVNT_CRT bad or missing certificate
+ * XEVNT_PER host certificate expired
+ * XEVNT_PUB bad or missing public key
+ * XEVNT_VFY certificate not verified
+ */
+static int
+cert_sign(
+ struct exten *ep, /* extension field pointer */
+ struct value *vp /* value pointer */
+ )
+{
+ X509 *req; /* X509 certificate request */
+ X509 *cert; /* X509 certificate */
+ X509_EXTENSION *ext; /* certificate extension */
+ ASN1_INTEGER *serial; /* serial number */
+ X509_NAME *subj; /* distinguished (common) name */
+ EVP_PKEY *pkey; /* public key */
+ EVP_MD_CTX *ctx; /* message digest context */
+ tstamp_t tstamp; /* NTP timestamp */
+ struct calendar tscal;
+ u_int len;
+ const u_char *cptr;
+ u_char *ptr;
+ int i, temp;
+
+ /*
+ * Decode ASN.1 objects and construct certificate structure.
+ * Make sure the system clock is synchronized to a proventic
+ * source.
+ */
+ tstamp = crypto_time();
+ if (tstamp == 0)
+ return (XEVNT_TSP);
+
+ len = exten_payload_size(ep);
+ if (len == 0 || len > MAX_VALLEN)
+ return (XEVNT_LEN);
+ cptr = (void *)ep->pkt;
+ if ((req = d2i_X509(NULL, &cptr, len)) == NULL) {
+ msyslog(LOG_ERR, "cert_sign: %s",
+ ERR_error_string(ERR_get_error(), NULL));
+ return (XEVNT_CRT);
+ }
+ /*
+ * Extract public key and check for errors.
+ */
+ if ((pkey = X509_get_pubkey(req)) == NULL) {
+ msyslog(LOG_ERR, "cert_sign: %s",
+ ERR_error_string(ERR_get_error(), NULL));
+ X509_free(req);
+ return (XEVNT_PUB);
+ }
+
+ /*
+ * Generate X509 certificate signed by this server. If this is a
+ * trusted host, the issuer name is the group name; otherwise,
+ * it is the host name. Also copy any extensions that might be
+ * present.
+ */
+ cert = X509_new();
+ X509_set_version(cert, X509_get_version(req));
+ serial = ASN1_INTEGER_new();
+ ASN1_INTEGER_set(serial, tstamp);
+ X509_set_serialNumber(cert, serial);
+ X509_gmtime_adj(X509_getm_notBefore(cert), 0L);
+ X509_gmtime_adj(X509_getm_notAfter(cert), YEAR);
+ subj = X509_get_issuer_name(cert);
+ X509_NAME_add_entry_by_txt(subj, "commonName", MBSTRING_ASC,
+ hostval.ptr, strlen((const char *)hostval.ptr), -1, 0);
+ subj = X509_get_subject_name(req);
+ X509_set_subject_name(cert, subj);
+ X509_set_pubkey(cert, pkey);
+ temp = X509_get_ext_count(req);
+ for (i = 0; i < temp; i++) {
+ ext = X509_get_ext(req, i);
+ INSIST(X509_add_ext(cert, ext, -1));
+ }
+ X509_free(req);
+
+ /*
+ * Sign and verify the client certificate, but only if the host
+ * certificate has not expired.
+ */
+ (void)ntpcal_ntp_to_date(&tscal, tstamp, NULL);
+ if ((calcomp(&tscal, &(cert_host->first)) < 0)
+ || (calcomp(&tscal, &(cert_host->last)) > 0)) {
+ X509_free(cert);
+ return (XEVNT_PER);
+ }
+ X509_sign(cert, sign_pkey, sign_digest);
+ if (X509_verify(cert, sign_pkey) <= 0) {
+ msyslog(LOG_ERR, "cert_sign: %s",
+ ERR_error_string(ERR_get_error(), NULL));
+ X509_free(cert);
+ return (XEVNT_VFY);
+ }
+ len = i2d_X509(cert, NULL);
+
+ /*
+ * Build and sign the value structure. We have to sign it here,
+ * since the response has to be returned right away. This is a
+ * clogging hazard.
+ */
+ memset(vp, 0, sizeof(struct value));
+ vp->tstamp = htonl(tstamp);
+ vp->fstamp = ep->fstamp;
+ vp->vallen = htonl(len);
+ vp->ptr = emalloc(len);
+ ptr = vp->ptr;
+ i2d_X509(cert, (unsigned char **)(intptr_t)&ptr);
+ vp->siglen = 0;
+ if (tstamp != 0) {
+ vp->sig = emalloc(sign_siglen);
+ ctx = EVP_MD_CTX_new();
+ EVP_SignInit(ctx, sign_digest);
+ EVP_SignUpdate(ctx, (u_char *)vp, 12);
+ EVP_SignUpdate(ctx, vp->ptr, len);
+ if (EVP_SignFinal(ctx, vp->sig, &len, sign_pkey)) {
+ INSIST(len <= sign_siglen);
+ vp->siglen = htonl(len);
+ }
+ EVP_MD_CTX_free(ctx);
+ }
+#ifdef DEBUG
+ if (debug > 1)
+ X509_print_fp(stdout, cert);
+#endif
+ X509_free(cert);
+ return (XEVNT_OK);
+}
+
+
+/*
+ * cert_install - install certificate in certificate cache
+ *
+ * This routine encodes an extension field into a certificate info/value
+ * structure. It searches the certificate list for duplicates and
+ * expunges whichever is older. Finally, it inserts this certificate
+ * first on the list.
+ *
+ * Returns certificate info pointer if valid, NULL if not.
+ */
+struct cert_info *
+cert_install(
+ struct exten *ep, /* cert info/value */
+ struct peer *peer /* peer structure */
+ )
+{
+ struct cert_info *cp, *xp, **zp;
+
+ /*
+ * Parse and validate the signed certificate. If valid,
+ * construct the info/value structure; otherwise, scamper home
+ * empty handed.
+ */
+ if ((cp = cert_parse((u_char *)ep->pkt, (long)ntohl(ep->vallen),
+ (tstamp_t)ntohl(ep->fstamp))) == NULL)
+ return (NULL);
+
+ /*
+ * Scan certificate list looking for another certificate with
+ * the same subject and issuer. If another is found with the
+ * same or older filestamp, unlink it and return the goodies to
+ * the heap. If another is found with a later filestamp, discard
+ * the new one and leave the building with the old one.
+ *
+ * Make a note to study this issue again. An earlier certificate
+ * with a long lifetime might be overtaken by a later
+ * certificate with a short lifetime, thus invalidating the
+ * earlier signature. However, we gotta find a way to leak old
+ * stuff from the cache, so we do it anyway.
+ */
+ zp = &cinfo;
+ for (xp = cinfo; xp != NULL; xp = xp->link) {
+ if (strcmp(cp->subject, xp->subject) == 0 &&
+ strcmp(cp->issuer, xp->issuer) == 0) {
+ if (ntohl(cp->cert.fstamp) <=
+ ntohl(xp->cert.fstamp)) {
+ cert_free(cp);
+ cp = xp;
+ } else {
+ *zp = xp->link;
+ cert_free(xp);
+ xp = NULL;
+ }
+ break;
+ }
+ zp = &xp->link;
+ }
+ if (xp == NULL) {
+ cp->link = cinfo;
+ cinfo = cp;
+ }
+ cp->flags |= CERT_VALID;
+ crypto_update();
+ return (cp);
+}
+
+
+/*
+ * cert_hike - verify the signature using the issuer public key
+ *
+ * Returns
+ * XEVNT_OK success
+ * XEVNT_CRT bad or missing certificate
+ * XEVNT_PER host certificate expired
+ * XEVNT_VFY certificate not verified
+ */
+int
+cert_hike(
+ struct peer *peer, /* peer structure pointer */
+ struct cert_info *yp /* issuer certificate */
+ )
+{
+ struct cert_info *xp; /* subject certificate */
+ X509 *cert; /* X509 certificate */
+ const u_char *ptr;
+
+ /*
+ * Save the issuer on the new certificate, but remember the old
+ * one.
+ */
+ if (peer->issuer != NULL)
+ free(peer->issuer);
+ peer->issuer = estrdup(yp->issuer);
+ xp = peer->xinfo;
+ peer->xinfo = yp;
+
+ /*
+ * If subject Y matches issuer Y, then the certificate trail is
+ * complete. If Y is not trusted, the server certificate has yet
+ * been signed, so keep trying. Otherwise, save the group key
+ * and light the valid bit. If the host certificate is trusted,
+ * do not execute a sign exchange. If no identity scheme is in
+ * use, light the identity and proventic bits.
+ */
+ if (strcmp(yp->subject, yp->issuer) == 0) {
+ if (!(yp->flags & CERT_TRUST))
+ return (XEVNT_OK);
+
+ /*
+ * If the server has an an identity scheme, fetch the
+ * identity credentials. If not, the identity is
+ * verified only by the trusted certificate. The next
+ * signature will set the server proventic.
+ */
+ peer->crypto |= CRYPTO_FLAG_CERT;
+ peer->grpkey = yp->grpkey;
+ if (peer->ident == NULL || !(peer->crypto &
+ CRYPTO_FLAG_MASK))
+ peer->crypto |= CRYPTO_FLAG_VRFY;
+ }
+
+ /*
+ * If X exists, verify signature X using public key Y.
+ */
+ if (xp == NULL)
+ return (XEVNT_OK);
+
+ ptr = (u_char *)xp->cert.ptr;
+ cert = d2i_X509(NULL, &ptr, ntohl(xp->cert.vallen));
+ if (cert == NULL) {
+ xp->flags |= CERT_ERROR;
+ return (XEVNT_CRT);
+ }
+ if (X509_verify(cert, yp->pkey) <= 0) {
+ X509_free(cert);
+ xp->flags |= CERT_ERROR;
+ return (XEVNT_VFY);
+ }
+ X509_free(cert);
+
+ /*
+ * Signature X is valid only if it begins during the
+ * lifetime of Y.
+ */
+ if ((calcomp(&(xp->first), &(yp->first)) < 0)
+ || (calcomp(&(xp->first), &(yp->last)) > 0)) {
+ xp->flags |= CERT_ERROR;
+ return (XEVNT_PER);
+ }
+ xp->flags |= CERT_SIGN;
+ return (XEVNT_OK);
+}
+
+
+/*
+ * cert_parse - parse x509 certificate and create info/value structures.
+ *
+ * The server certificate includes the version number, issuer name,
+ * subject name, public key and valid date interval. If the issuer name
+ * is the same as the subject name, the certificate is self signed and
+ * valid only if the server is configured as trustable. If the names are
+ * different, another issuer has signed the server certificate and
+ * vouched for it. In this case the server certificate is valid if
+ * verified by the issuer public key.
+ *
+ * Returns certificate info/value pointer if valid, NULL if not.
+ */
+struct cert_info * /* certificate information structure */
+cert_parse(
+ const u_char *asn1cert, /* X509 certificate */
+ long len, /* certificate length */
+ tstamp_t fstamp /* filestamp */
+ )
+{
+ X509 *cert; /* X509 certificate */
+ struct cert_info *ret; /* certificate info/value */
+ BIO *bp;
+ char pathbuf[MAXFILENAME];
+ const u_char *ptr;
+ char *pch;
+ int cnt, i;
+ struct calendar fscal;
+
+ /*
+ * Decode ASN.1 objects and construct certificate structure.
+ */
+ ptr = asn1cert;
+ if ((cert = d2i_X509(NULL, &ptr, len)) == NULL) {
+ msyslog(LOG_ERR, "cert_parse: %s",
+ ERR_error_string(ERR_get_error(), NULL));
+ return (NULL);
+ }
+#ifdef DEBUG
+ if (debug > 1)
+ X509_print_fp(stdout, cert);
+#endif
+
+ /*
+ * Extract version, subject name and public key.
+ */
+ ret = emalloc_zero(sizeof(*ret));
+ if ((ret->pkey = X509_get_pubkey(cert)) == NULL) {
+ msyslog(LOG_ERR, "cert_parse: %s",
+ ERR_error_string(ERR_get_error(), NULL));
+ cert_free(ret);
+ X509_free(cert);
+ return (NULL);
+ }
+ ret->version = X509_get_version(cert);
+ X509_NAME_oneline(X509_get_subject_name(cert), pathbuf,
+ sizeof(pathbuf));
+ pch = strstr(pathbuf, "CN=");
+ if (NULL == pch) {
+ msyslog(LOG_NOTICE, "cert_parse: invalid subject %s",
+ pathbuf);
+ cert_free(ret);
+ X509_free(cert);
+ return (NULL);
+ }
+ ret->subject = estrdup(pch + 3);
+
+ /*
+ * Extract remaining objects. Note that the NTP serial number is
+ * the NTP seconds at the time of signing, but this might not be
+ * the case for other authority. We don't bother to check the
+ * objects at this time, since the real crunch can happen only
+ * when the time is valid but not yet certificated.
+ */
+ ret->nid = X509_get_signature_nid(cert);
+ ret->digest = (const EVP_MD *)EVP_get_digestbynid(ret->nid);
+ ret->serial =
+ (u_long)ASN1_INTEGER_get(X509_get_serialNumber(cert));
+ X509_NAME_oneline(X509_get_issuer_name(cert), pathbuf,
+ sizeof(pathbuf));
+ if ((pch = strstr(pathbuf, "CN=")) == NULL) {
+ msyslog(LOG_NOTICE, "cert_parse: invalid issuer %s",
+ pathbuf);
+ cert_free(ret);
+ X509_free(cert);
+ return (NULL);
+ }
+ ret->issuer = estrdup(pch + 3);
+ asn_to_calendar(X509_get0_notBefore(cert), &(ret->first));
+ asn_to_calendar(X509_get0_notAfter(cert), &(ret->last));
+
+ /*
+ * Extract extension fields. These are ad hoc ripoffs of
+ * currently assigned functions and will certainly be changed
+ * before prime time.
+ */
+ cnt = X509_get_ext_count(cert);
+ for (i = 0; i < cnt; i++) {
+ X509_EXTENSION *ext;
+ ASN1_OBJECT *obj;
+ int nid;
+ ASN1_OCTET_STRING *data;
+
+ ext = X509_get_ext(cert, i);
+ obj = X509_EXTENSION_get_object(ext);
+ nid = OBJ_obj2nid(obj);
+
+ switch (nid) {
+
+ /*
+ * If a key_usage field is present, we decode whether
+ * this is a trusted or private certificate. This is
+ * dorky; all we want is to compare NIDs, but OpenSSL
+ * insists on BIO text strings.
+ */
+ case NID_ext_key_usage:
+ bp = BIO_new(BIO_s_mem());
+ X509V3_EXT_print(bp, ext, 0, 0);
+ BIO_gets(bp, pathbuf, sizeof(pathbuf));
+ BIO_free(bp);
+ if (strcmp(pathbuf, "Trust Root") == 0)
+ ret->flags |= CERT_TRUST;
+ else if (strcmp(pathbuf, "Private") == 0)
+ ret->flags |= CERT_PRIV;
+ DPRINTF(1, ("cert_parse: %s: %s\n",
+ OBJ_nid2ln(nid), pathbuf));
+ break;
+
+ /*
+ * If a NID_subject_key_identifier field is present, it
+ * contains the GQ public key.
+ */
+ case NID_subject_key_identifier:
+ data = X509_EXTENSION_get_data(ext);
+ ret->grpkey = BN_bin2bn(&data->data[2],
+ data->length - 2, NULL);
+ /* fall through */
+ default:
+ DPRINTF(1, ("cert_parse: %s\n",
+ OBJ_nid2ln(nid)));
+ break;
+ }
+ }
+ if (strcmp(ret->subject, ret->issuer) == 0) {
+
+ /*
+ * If certificate is self signed, verify signature.
+ */
+ if (X509_verify(cert, ret->pkey) <= 0) {
+ msyslog(LOG_NOTICE,
+ "cert_parse: signature not verified %s",
+ ret->subject);
+ cert_free(ret);
+ X509_free(cert);
+ return (NULL);
+ }
+ } else {
+
+ /*
+ * Check for a certificate loop.
+ */
+ if (strcmp((const char *)hostval.ptr, ret->issuer) == 0) {
+ msyslog(LOG_NOTICE,
+ "cert_parse: certificate trail loop %s",
+ ret->subject);
+ cert_free(ret);
+ X509_free(cert);
+ return (NULL);
+ }
+ }
+
+ /*
+ * Verify certificate valid times. Note that certificates cannot
+ * be retroactive.
+ */
+ (void)ntpcal_ntp_to_date(&fscal, fstamp, NULL);
+ if ((calcomp(&(ret->first), &(ret->last)) > 0)
+ || (calcomp(&(ret->first), &fscal) < 0)) {
+ msyslog(LOG_NOTICE,
+ "cert_parse: invalid times %s first %u-%02u-%02uT%02u:%02u:%02u last %u-%02u-%02uT%02u:%02u:%02u fstamp %u-%02u-%02uT%02u:%02u:%02u",
+ ret->subject,
+ ret->first.year, ret->first.month, ret->first.monthday,
+ ret->first.hour, ret->first.minute, ret->first.second,
+ ret->last.year, ret->last.month, ret->last.monthday,
+ ret->last.hour, ret->last.minute, ret->last.second,
+ fscal.year, fscal.month, fscal.monthday,
+ fscal.hour, fscal.minute, fscal.second);
+ cert_free(ret);
+ X509_free(cert);
+ return (NULL);
+ }
+
+ /*
+ * Build the value structure to sign and send later.
+ */
+ ret->cert.fstamp = htonl(fstamp);
+ ret->cert.vallen = htonl(len);
+ ret->cert.ptr = emalloc(len);
+ memcpy(ret->cert.ptr, asn1cert, len);
+ X509_free(cert);
+ return (ret);
+}
+
+
+/*
+ * cert_free - free certificate information structure
+ */
+void
+cert_free(
+ struct cert_info *cinf /* certificate info/value structure */
+ )
+{
+ if (cinf->pkey != NULL)
+ EVP_PKEY_free(cinf->pkey);
+ if (cinf->subject != NULL)
+ free(cinf->subject);
+ if (cinf->issuer != NULL)
+ free(cinf->issuer);
+ if (cinf->grpkey != NULL)
+ BN_free(cinf->grpkey);
+ value_free(&cinf->cert);
+ free(cinf);
+}
+
+
+/*
+ * crypto_key - load cryptographic parameters and keys
+ *
+ * This routine searches the key cache for matching name in the form
+ * ntpkey_<key>_<name>, where <key> is one of host, sign, iff, gq, mv,
+ * and <name> is the host/group name. If not found, it tries to load a
+ * PEM-encoded file of the same name and extracts the filestamp from
+ * the first line of the file name. It returns the key pointer if valid,
+ * NULL if not.
+ */
+static struct pkey_info *
+crypto_key(
+ char *cp, /* file name */
+ char *passwd1, /* password */
+ sockaddr_u *addr /* IP address */
+ )
+{
+ FILE *str; /* file handle */
+ struct pkey_info *pkp; /* generic key */
+ EVP_PKEY *pkey = NULL; /* public/private key */
+ tstamp_t fstamp;
+ char filename[MAXFILENAME]; /* name of key file */
+ char linkname[MAXFILENAME]; /* filestamp buffer) */
+ char statstr[NTP_MAXSTRLEN]; /* statistics for filegen */
+ char *ptr;
+
+ /*
+ * Search the key cache for matching key and name.
+ */
+ for (pkp = pkinfo; pkp != NULL; pkp = pkp->link) {
+ if (strcmp(cp, pkp->name) == 0)
+ return (pkp);
+ }
+
+ /*
+ * Open the key file. If the first character of the file name is
+ * not '/', prepend the keys directory string. If something goes
+ * wrong, abandon ship.
+ */
+ if (*cp == '/')
+ strlcpy(filename, cp, sizeof(filename));
+ else
+ snprintf(filename, sizeof(filename), "%s/%s", keysdir,
+ cp);
+ str = fopen(filename, "r");
+ if (str == NULL)
+ return (NULL);
+
+ /*
+ * Read the filestamp, which is contained in the first line.
+ */
+ if ((ptr = fgets(linkname, sizeof(linkname), str)) == NULL) {
+ msyslog(LOG_ERR, "crypto_key: empty file %s",
+ filename);
+ fclose(str);
+ return (NULL);
+ }
+ if ((ptr = strrchr(ptr, '.')) == NULL) {
+ msyslog(LOG_ERR, "crypto_key: no filestamp %s",
+ filename);
+ fclose(str);
+ return (NULL);
+ }
+ if (sscanf(++ptr, "%u", &fstamp) != 1) {
+ msyslog(LOG_ERR, "crypto_key: invalid filestamp %s",
+ filename);
+ fclose(str);
+ return (NULL);
+ }
+
+ /*
+ * Read and decrypt PEM-encoded private key. If it fails to
+ * decrypt, game over.
+ */
+ pkey = PEM_read_PrivateKey(str, NULL, NULL, passwd1);
+ fclose(str);
+ if (pkey == NULL) {
+ msyslog(LOG_ERR, "crypto_key: %s",
+ ERR_error_string(ERR_get_error(), NULL));
+ exit (-1);
+ }
+
+ /*
+ * Make a new entry in the key cache.
+ */
+ pkp = emalloc(sizeof(struct pkey_info));
+ pkp->link = pkinfo;
+ pkinfo = pkp;
+ pkp->pkey = pkey;
+ pkp->name = estrdup(cp);
+ pkp->fstamp = fstamp;
+
+ /*
+ * Leave tracks in the cryptostats.
+ */
+ if ((ptr = strrchr(linkname, '\n')) != NULL)
+ *ptr = '\0';
+ snprintf(statstr, sizeof(statstr), "%s mod %d", &linkname[2],
+ EVP_PKEY_size(pkey) * 8);
+ record_crypto_stats(addr, statstr);
+
+ DPRINTF(1, ("crypto_key: %s\n", statstr));
+#ifdef DEBUG
+ if (debug > 1) {
+ if (EVP_PKEY_base_id(pkey) == EVP_PKEY_DSA)
+ DSA_print_fp(stdout, EVP_PKEY_get0_DSA(pkey), 0);
+ else if (EVP_PKEY_base_id(pkey) == EVP_PKEY_RSA)
+ RSA_print_fp(stdout, EVP_PKEY_get0_RSA(pkey), 0);
+ }
+#endif
+ return (pkp);
+}
+
+
+/*
+ ***********************************************************************
+ * *
+ * The following routines are used only at initialization time *
+ * *
+ ***********************************************************************
+ */
+/*
+ * crypto_cert - load certificate from file
+ *
+ * This routine loads an X.509 RSA or DSA certificate from a file and
+ * constructs a info/cert value structure for this machine. The
+ * structure includes a filestamp extracted from the file name. Later
+ * the certificate can be sent to another machine on request.
+ *
+ * Returns certificate info/value pointer if valid, NULL if not.
+ */
+static struct cert_info * /* certificate information */
+crypto_cert(
+ char *cp /* file name */
+ )
+{
+ struct cert_info *ret; /* certificate information */
+ FILE *str; /* file handle */
+ char filename[MAXFILENAME]; /* name of certificate file */
+ char linkname[MAXFILENAME]; /* filestamp buffer */
+ char statstr[NTP_MAXSTRLEN]; /* statistics for filegen */
+ tstamp_t fstamp; /* filestamp */
+ long len;
+ char *ptr;
+ char *name, *header;
+ u_char *data;
+
+ /*
+ * Open the certificate file. If the first character of the file
+ * name is not '/', prepend the keys directory string. If
+ * something goes wrong, abandon ship.
+ */
+ if (*cp == '/')
+ strlcpy(filename, cp, sizeof(filename));
+ else
+ snprintf(filename, sizeof(filename), "%s/%s", keysdir,
+ cp);
+ str = fopen(filename, "r");
+ if (str == NULL)
+ return (NULL);
+
+ /*
+ * Read the filestamp, which is contained in the first line.
+ */
+ if ((ptr = fgets(linkname, sizeof(linkname), str)) == NULL) {
+ msyslog(LOG_ERR, "crypto_cert: empty file %s",
+ filename);
+ fclose(str);
+ return (NULL);
+ }
+ if ((ptr = strrchr(ptr, '.')) == NULL) {
+ msyslog(LOG_ERR, "crypto_cert: no filestamp %s",
+ filename);
+ fclose(str);
+ return (NULL);
+ }
+ if (sscanf(++ptr, "%u", &fstamp) != 1) {
+ msyslog(LOG_ERR, "crypto_cert: invalid filestamp %s",
+ filename);
+ fclose(str);
+ return (NULL);
+ }
+
+ /*
+ * Read PEM-encoded certificate and install.
+ */
+ if (!PEM_read(str, &name, &header, &data, &len)) {
+ msyslog(LOG_ERR, "crypto_cert: %s",
+ ERR_error_string(ERR_get_error(), NULL));
+ fclose(str);
+ return (NULL);
+ }
+ fclose(str);
+ free(header);
+ if (strcmp(name, "CERTIFICATE") != 0) {
+ msyslog(LOG_NOTICE, "crypto_cert: wrong PEM type %s",
+ name);
+ free(name);
+ free(data);
+ return (NULL);
+ }
+ free(name);
+
+ /*
+ * Parse certificate and generate info/value structure. The
+ * pointer and copy nonsense is due something broken in Solaris.
+ */
+ ret = cert_parse(data, len, fstamp);
+ free(data);
+ if (ret == NULL)
+ return (NULL);
+
+ if ((ptr = strrchr(linkname, '\n')) != NULL)
+ *ptr = '\0';
+ snprintf(statstr, sizeof(statstr), "%s 0x%x len %lu",
+ &linkname[2], ret->flags, len);
+ record_crypto_stats(NULL, statstr);
+ DPRINTF(1, ("crypto_cert: %s\n", statstr));
+ return (ret);
+}
+
+
+/*
+ * crypto_setup - load keys, certificate and identity parameters
+ *
+ * This routine loads the public/private host key and certificate. If
+ * available, it loads the public/private sign key, which defaults to
+ * the host key. The host key must be RSA, but the sign key can be
+ * either RSA or DSA. If a trusted certificate, it loads the identity
+ * parameters. In either case, the public key on the certificate must
+ * agree with the sign key.
+ *
+ * Required but missing files and inconsistent data and errors are
+ * fatal. Allowing configuration to continue would be hazardous and
+ * require really messy error checks.
+ */
+void
+crypto_setup(void)
+{
+ struct pkey_info *pinfo; /* private/public key */
+ char filename[MAXFILENAME]; /* file name buffer */
+ char hostname[MAXFILENAME]; /* host name buffer */
+ char *randfile;
+ char statstr[NTP_MAXSTRLEN]; /* statistics for filegen */
+ l_fp seed; /* crypto PRNG seed as NTP timestamp */
+ u_int len;
+ int bytes;
+ u_char *ptr;
+
+ /*
+ * Check for correct OpenSSL version and avoid initialization in
+ * the case of multiple crypto commands.
+ */
+ if (crypto_flags & CRYPTO_FLAG_ENAB) {
+ msyslog(LOG_NOTICE,
+ "crypto_setup: spurious crypto command");
+ return;
+ }
+ ssl_check_version();
+
+ /*
+ * Load required random seed file and seed the random number
+ * generator. Be default, it is found as .rnd in the user home
+ * directory. The root home directory may be / or /root,
+ * depending on the system. Wiggle the contents a bit and write
+ * it back so the sequence does not repeat when we next restart.
+ */
+ if (!RAND_status()) {
+ if (rand_file == NULL) {
+ RAND_file_name(filename, sizeof(filename));
+ randfile = filename;
+ } else if (*rand_file != '/') {
+ snprintf(filename, sizeof(filename), "%s/%s",
+ keysdir, rand_file);
+ randfile = filename;
+ } else
+ randfile = rand_file;
+
+ if ((bytes = RAND_load_file(randfile, -1)) == 0) {
+ msyslog(LOG_ERR,
+ "crypto_setup: random seed file %s missing",
+ randfile);
+ exit (-1);
+ }
+ arc4random_buf(&seed, sizeof(l_fp));
+ RAND_seed(&seed, sizeof(l_fp));
+ RAND_write_file(randfile);
+ DPRINTF(1, ("crypto_setup: OpenSSL version %lx random seed file %s bytes read %d\n",
+ OpenSSL_version_num(), randfile, bytes));
+
+ }
+
+ /*
+ * Initialize structures.
+ */
+ gethostname(hostname, sizeof(hostname));
+ if (host_filename != NULL)
+ strlcpy(hostname, host_filename, sizeof(hostname));
+ if (passwd == NULL)
+ passwd = estrdup(hostname);
+ memset(&hostval, 0, sizeof(hostval));
+ memset(&pubkey, 0, sizeof(pubkey));
+ memset(&tai_leap, 0, sizeof(tai_leap));
+
+ /*
+ * Load required host key from file "ntpkey_host_<hostname>". If
+ * no host key file is not found or has invalid password, life
+ * as we know it ends. The host key also becomes the default
+ * sign key.
+ */
+ snprintf(filename, sizeof(filename), "ntpkey_host_%s", hostname);
+ pinfo = crypto_key(filename, passwd, NULL);
+ if (pinfo == NULL) {
+ msyslog(LOG_ERR,
+ "crypto_setup: host key file %s not found or corrupt",
+ filename);
+ exit (-1);
+ }
+ if (EVP_PKEY_base_id(pinfo->pkey) != EVP_PKEY_RSA) {
+ msyslog(LOG_ERR,
+ "crypto_setup: host key is not RSA key type");
+ exit (-1);
+ }
+ host_pkey = pinfo->pkey;
+ sign_pkey = host_pkey;
+ hostval.fstamp = htonl(pinfo->fstamp);
+
+ /*
+ * Construct public key extension field for agreement scheme.
+ */
+ len = i2d_PublicKey(host_pkey, NULL);
+ ptr = emalloc(len);
+ pubkey.ptr = ptr;
+ i2d_PublicKey(host_pkey, &ptr);
+ pubkey.fstamp = hostval.fstamp;
+ pubkey.vallen = htonl(len);
+
+ /*
+ * Load optional sign key from file "ntpkey_sign_<hostname>". If
+ * available, it becomes the sign key.
+ */
+ snprintf(filename, sizeof(filename), "ntpkey_sign_%s", hostname);
+ pinfo = crypto_key(filename, passwd, NULL);
+ if (pinfo != NULL)
+ sign_pkey = pinfo->pkey;
+
+ /*
+ * Load required certificate from file "ntpkey_cert_<hostname>".
+ */
+ snprintf(filename, sizeof(filename), "ntpkey_cert_%s", hostname);
+ cinfo = crypto_cert(filename);
+ if (cinfo == NULL) {
+ msyslog(LOG_ERR,
+ "crypto_setup: certificate file %s not found or corrupt",
+ filename);
+ exit (-1);
+ }
+ cert_host = cinfo;
+ sign_digest = cinfo->digest;
+ sign_siglen = EVP_PKEY_size(sign_pkey);
+ if (cinfo->flags & CERT_PRIV)
+ crypto_flags |= CRYPTO_FLAG_PRIV;
+
+ /*
+ * The certificate must be self-signed.
+ */
+ if (strcmp(cinfo->subject, cinfo->issuer) != 0) {
+ msyslog(LOG_ERR,
+ "crypto_setup: certificate %s is not self-signed",
+ filename);
+ exit (-1);
+ }
+ hostval.ptr = estrdup(cinfo->subject);
+ hostval.vallen = htonl(strlen(cinfo->subject));
+ sys_hostname = hostval.ptr;
+ ptr = (u_char *)strchr(sys_hostname, '@');
+ if (ptr != NULL)
+ sys_groupname = estrdup((char *)++ptr);
+ if (ident_filename != NULL)
+ strlcpy(hostname, ident_filename, sizeof(hostname));
+
+ /*
+ * Load optional IFF parameters from file
+ * "ntpkey_iffkey_<hostname>".
+ */
+ snprintf(filename, sizeof(filename), "ntpkey_iffkey_%s",
+ hostname);
+ iffkey_info = crypto_key(filename, passwd, NULL);
+ if (iffkey_info != NULL)
+ crypto_flags |= CRYPTO_FLAG_IFF;
+
+ /*
+ * Load optional GQ parameters from file
+ * "ntpkey_gqkey_<hostname>".
+ */
+ snprintf(filename, sizeof(filename), "ntpkey_gqkey_%s",
+ hostname);
+ gqkey_info = crypto_key(filename, passwd, NULL);
+ if (gqkey_info != NULL)
+ crypto_flags |= CRYPTO_FLAG_GQ;
+
+ /*
+ * Load optional MV parameters from file
+ * "ntpkey_mvkey_<hostname>".
+ */
+ snprintf(filename, sizeof(filename), "ntpkey_mvkey_%s",
+ hostname);
+ mvkey_info = crypto_key(filename, passwd, NULL);
+ if (mvkey_info != NULL)
+ crypto_flags |= CRYPTO_FLAG_MV;
+
+ /*
+ * We met the enemy and he is us. Now strike up the dance.
+ */
+ crypto_flags |= CRYPTO_FLAG_ENAB | (cinfo->nid << 16);
+ snprintf(statstr, sizeof(statstr), "setup 0x%x host %s %s",
+ crypto_flags, hostname, OBJ_nid2ln(cinfo->nid));
+ record_crypto_stats(NULL, statstr);
+ DPRINTF(1, ("crypto_setup: %s\n", statstr));
+}
+
+
+/*
+ * crypto_config - configure data from the crypto command.
+ */
+void
+crypto_config(
+ int item, /* configuration item */
+ char *cp /* item name */
+ )
+{
+ int nid;
+
+ DPRINTF(1, ("crypto_config: item %d %s\n", item, cp));
+
+ switch (item) {
+
+ /*
+ * Set host name (host).
+ */
+ case CRYPTO_CONF_PRIV:
+ if (NULL != host_filename)
+ free(host_filename);
+ host_filename = estrdup(cp);
+ break;
+
+ /*
+ * Set group name (ident).
+ */
+ case CRYPTO_CONF_IDENT:
+ if (NULL != ident_filename)
+ free(ident_filename);
+ ident_filename = estrdup(cp);
+ break;
+
+ /*
+ * Set private key password (pw).
+ */
+ case CRYPTO_CONF_PW:
+ if (NULL != passwd)
+ free(passwd);
+ passwd = estrdup(cp);
+ break;
+
+ /*
+ * Set random seed file name (randfile).
+ */
+ case CRYPTO_CONF_RAND:
+ if (NULL != rand_file)
+ free(rand_file);
+ rand_file = estrdup(cp);
+ break;
+
+ /*
+ * Set message digest NID.
+ */
+ case CRYPTO_CONF_NID:
+ nid = OBJ_sn2nid(cp);
+ if (nid == 0)
+ msyslog(LOG_ERR,
+ "crypto_config: invalid digest name %s", cp);
+ else
+ crypto_nid = nid;
+ break;
+ }
+}
+
+/*
+ * Get the payload size (internal value length) of an extension packet.
+ * If the inner value size does not match the outer packet size (that
+ * is, the value would end behind the frame given by the opcode/size
+ * field) the function will effectively return UINT_MAX. If the frame is
+ * too short to hold a variable-sized value, the return value is zero.
+ */
+static u_int
+exten_payload_size(
+ const struct exten * ep)
+{
+ typedef const u_char *BPTR;
+
+ size_t extn_size;
+ size_t data_size;
+ size_t head_size;
+
+ data_size = 0;
+ if (NULL != ep) {
+ head_size = (BPTR)(&ep->vallen + 1) - (BPTR)ep;
+ extn_size = (uint16_t)(ntohl(ep->opcode) & 0x0000ffff);
+ if (extn_size >= head_size) {
+ data_size = (uint32_t)ntohl(ep->vallen);
+ if (data_size > extn_size - head_size)
+ data_size = ~(size_t)0u;
+ }
+ }
+ return (u_int)data_size;
+}
+# else /* !AUTOKEY follows */
+int ntp_crypto_bs_pubkey;
+# endif /* !AUTOKEY */
diff --git a/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_filegen.c b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_filegen.c
new file mode 100644
index 0000000..e46291a
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_filegen.c
@@ -0,0 +1,647 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * ntp_filegen.c,v 3.12 1994/01/25 19:06:11 kardel Exp
+ *
+ * implements file generations support for NTP
+ * logfiles and statistic files
+ *
+ *
+ * Copyright (C) 1992, 1996 by Rainer Pruy
+ * Friedrich-Alexander Universitaet Erlangen-Nuernberg, Germany
+ *
+ * This code may be modified and used freely
+ * provided credits remain intact.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "ntpd.h"
+#include "ntp_io.h"
+#include "ntp_string.h"
+#include "ntp_calendar.h"
+#include "ntp_filegen.h"
+#include "ntp_stdlib.h"
+
+/*
+ * NTP is intended to run long periods of time without restart.
+ * Thus log and statistic files generated by NTP will grow large.
+ *
+ * this set of routines provides a central interface
+ * to generating files using file generations
+ *
+ * the generation of a file is changed according to file generation type
+ */
+
+
+/*
+ * redefine this if your system dislikes filename suffixes like
+ * X.19910101 or X.1992W50 or ....
+ */
+#define SUFFIX_SEP '.'
+
+static void filegen_open (FILEGEN *, u_int32, const time_t*);
+static int valid_fileref (const char *, const char *);
+static void filegen_init (const char *, const char *, FILEGEN *);
+#ifdef DEBUG
+static void filegen_uninit (FILEGEN *);
+#endif /* DEBUG */
+
+
+/*
+ * filegen_init
+ */
+
+static void
+filegen_init(
+ const char * dir,
+ const char * fname,
+ FILEGEN * fgp
+ )
+{
+ fgp->fp = NULL;
+ fgp->dir = estrdup(dir);
+ fgp->fname = estrdup(fname);
+ fgp->id_lo = 0;
+ fgp->id_hi = 0;
+ fgp->type = FILEGEN_DAY;
+ fgp->flag = FGEN_FLAG_LINK; /* not yet enabled !!*/
+}
+
+
+/*
+ * filegen_uninit - free memory allocated by filegen_init
+ */
+#ifdef DEBUG
+static void
+filegen_uninit(
+ FILEGEN *fgp
+ )
+{
+ free(fgp->dir);
+ free(fgp->fname);
+}
+#endif
+
+
+/*
+ * open a file generation according to the current settings of gen
+ * will also provide a link to basename if requested to do so
+ */
+
+static void
+filegen_open(
+ FILEGEN * gen,
+ u_int32 stamp,
+ const time_t * pivot
+ )
+{
+ char *savename; /* temp store for name collision handling */
+ char *fullname; /* name with any designation extension */
+ char *filename; /* name without designation extension */
+ char *suffix; /* where to print suffix extension */
+ u_int len, suflen;
+ FILE *fp;
+ struct calendar cal;
+ struct isodate iso;
+
+ /* get basic filename in buffer, leave room for extensions */
+ len = strlen(gen->dir) + strlen(gen->fname) + 65;
+ filename = emalloc(len);
+ fullname = emalloc(len);
+ savename = NULL;
+ snprintf(filename, len, "%s%s", gen->dir, gen->fname);
+
+ /* where to place suffix */
+ suflen = strlcpy(fullname, filename, len);
+ suffix = fullname + suflen;
+ suflen = len - suflen;
+
+ /* last octet of fullname set to '\0' for truncation check */
+ fullname[len - 1] = '\0';
+
+ switch (gen->type) {
+
+ default:
+ msyslog(LOG_ERR,
+ "unsupported file generations type %d for "
+ "\"%s\" - reverting to FILEGEN_NONE",
+ gen->type, filename);
+ gen->type = FILEGEN_NONE;
+ break;
+
+ case FILEGEN_NONE:
+ /* no suffix, all set */
+ break;
+
+ case FILEGEN_PID:
+ gen->id_lo = getpid();
+ gen->id_hi = 0;
+ snprintf(suffix, suflen, "%c#%ld",
+ SUFFIX_SEP, gen->id_lo);
+ break;
+
+ case FILEGEN_DAY:
+ /*
+ * You can argue here in favor of using MJD, but I
+ * would assume it to be easier for humans to interpret
+ * dates in a format they are used to in everyday life.
+ */
+ ntpcal_ntp_to_date(&cal, stamp, pivot);
+ snprintf(suffix, suflen, "%c%04d%02d%02d",
+ SUFFIX_SEP, cal.year, cal.month, cal.monthday);
+ cal.hour = cal.minute = cal.second = 0;
+ gen->id_lo = ntpcal_date_to_ntp(&cal);
+ gen->id_hi = (u_int32)(gen->id_lo + SECSPERDAY);
+ break;
+
+ case FILEGEN_WEEK:
+ isocal_ntp_to_date(&iso, stamp, pivot);
+ snprintf(suffix, suflen, "%c%04dw%02d",
+ SUFFIX_SEP, iso.year, iso.week);
+ iso.hour = iso.minute = iso.second = 0;
+ iso.weekday = 1;
+ gen->id_lo = isocal_date_to_ntp(&iso);
+ gen->id_hi = (u_int32)(gen->id_lo + 7 * SECSPERDAY);
+ break;
+
+ case FILEGEN_MONTH:
+ ntpcal_ntp_to_date(&cal, stamp, pivot);
+ snprintf(suffix, suflen, "%c%04d%02d",
+ SUFFIX_SEP, cal.year, cal.month);
+ cal.hour = cal.minute = cal.second = 0;
+ cal.monthday = 1;
+ gen->id_lo = ntpcal_date_to_ntp(&cal);
+ cal.month++;
+ gen->id_hi = ntpcal_date_to_ntp(&cal);
+ break;
+
+ case FILEGEN_YEAR:
+ ntpcal_ntp_to_date(&cal, stamp, pivot);
+ snprintf(suffix, suflen, "%c%04d",
+ SUFFIX_SEP, cal.year);
+ cal.hour = cal.minute = cal.second = 0;
+ cal.month = cal.monthday = 1;
+ gen->id_lo = ntpcal_date_to_ntp(&cal);
+ cal.year++;
+ gen->id_hi = ntpcal_date_to_ntp(&cal);
+ break;
+
+ case FILEGEN_AGE:
+ gen->id_lo = current_time - (current_time % SECSPERDAY);
+ gen->id_hi = gen->id_lo + SECSPERDAY;
+ snprintf(suffix, suflen, "%ca%08ld",
+ SUFFIX_SEP, gen->id_lo);
+ }
+
+ /* check possible truncation */
+ if ('\0' != fullname[len - 1]) {
+ fullname[len - 1] = '\0';
+ msyslog(LOG_ERR, "logfile name truncated: \"%s\"",
+ fullname);
+ }
+
+ if (FILEGEN_NONE != gen->type) {
+ /*
+ * check for existence of a file with name 'basename'
+ * as we disallow such a file
+ * if FGEN_FLAG_LINK is set create a link
+ */
+ struct stat stats;
+ /*
+ * try to resolve name collisions
+ */
+ static u_long conflicts = 0;
+
+#ifndef S_ISREG
+#define S_ISREG(mode) (((mode) & S_IFREG) == S_IFREG)
+#endif
+ if (stat(filename, &stats) == 0) {
+ /* Hm, file exists... */
+ if (S_ISREG(stats.st_mode)) {
+ if (stats.st_nlink <= 1) {
+ /*
+ * Oh, it is not linked - try to save it
+ */
+ savename = emalloc(len);
+ snprintf(savename, len,
+ "%s%c%dC%lu",
+ filename, SUFFIX_SEP,
+ (int)getpid(), conflicts++);
+
+ if (rename(filename, savename) != 0)
+ msyslog(LOG_ERR,
+ "couldn't save %s: %m",
+ filename);
+ free(savename);
+ } else {
+ /*
+ * there is at least a second link to
+ * this file.
+ * just remove the conflicting one
+ */
+ if (
+#if !defined(VMS)
+ unlink(filename) != 0
+#else
+ delete(filename) != 0
+#endif
+ )
+ msyslog(LOG_ERR,
+ "couldn't unlink %s: %m",
+ filename);
+ }
+ } else {
+ /*
+ * Ehh? Not a regular file ?? strange !!!!
+ */
+ msyslog(LOG_ERR,
+ "expected regular file for %s "
+ "(found mode 0%lo)",
+ filename,
+ (unsigned long)stats.st_mode);
+ }
+ } else {
+ /*
+ * stat(..) failed, but it is absolutely correct for
+ * 'basename' not to exist
+ */
+ if (ENOENT != errno)
+ msyslog(LOG_ERR, "stat(%s) failed: %m",
+ filename);
+ }
+ }
+
+ /*
+ * now, try to open new file generation...
+ */
+ DPRINTF(4, ("opening filegen (type=%d/stamp=%u) \"%s\"\n",
+ gen->type, stamp, fullname));
+
+ fp = fopen(fullname, "a");
+
+ if (NULL == fp) {
+ /* open failed -- keep previous state
+ *
+ * If the file was open before keep the previous generation.
+ * This will cause output to end up in the 'wrong' file,
+ * but I think this is still better than losing output
+ *
+ * ignore errors due to missing directories
+ */
+
+ if (ENOENT != errno)
+ msyslog(LOG_ERR, "can't open %s: %m", fullname);
+ } else {
+ if (NULL != gen->fp) {
+ fclose(gen->fp);
+ gen->fp = NULL;
+ }
+ gen->fp = fp;
+
+ if (gen->flag & FGEN_FLAG_LINK) {
+ /*
+ * need to link file to basename
+ * have to use hardlink for now as I want to allow
+ * gen->basename spanning directory levels
+ * this would make it more complex to get the correct
+ * fullname for symlink
+ *
+ * Ok, it would just mean taking the part following
+ * the last '/' in the name.... Should add it later....
+ */
+
+ /* Windows NT does not support file links -Greg Schueman 1/18/97 */
+
+#if defined(SYS_WINNT) || defined(SYS_VXWORKS)
+ SetLastError(0); /* On WinNT, don't support FGEN_FLAG_LINK */
+#elif defined(VMS)
+ errno = 0; /* On VMS, don't support FGEN_FLAG_LINK */
+#else /* not (VMS) / VXWORKS / WINNT ; DO THE LINK) */
+ if (link(fullname, filename) != 0)
+ if (EEXIST != errno)
+ msyslog(LOG_ERR,
+ "can't link(%s, %s): %m",
+ fullname, filename);
+#endif /* SYS_WINNT || VXWORKS */
+ } /* flags & FGEN_FLAG_LINK */
+ } /* else fp == NULL */
+
+ free(filename);
+ free(fullname);
+ return;
+}
+
+/*
+ * this function sets up gen->fp to point to the correct
+ * generation of the file for the time specified by 'now'
+ *
+ * 'now' usually is interpreted as second part of a l_fp as is in the cal...
+ * library routines
+ */
+
+void
+filegen_setup(
+ FILEGEN * gen,
+ u_int32 now
+ )
+{
+ int current;
+ time_t pivot;
+
+ if (!(gen->flag & FGEN_FLAG_ENABLED)) {
+ if (NULL != gen->fp) {
+ fclose(gen->fp);
+ gen->fp = NULL;
+ }
+ return;
+ }
+
+ switch (gen->type) {
+
+ default:
+ case FILEGEN_NONE:
+ current = TRUE;
+ break;
+
+ case FILEGEN_PID:
+ current = ((int)gen->id_lo == getpid());
+ break;
+
+ case FILEGEN_AGE:
+ current = (gen->id_lo <= current_time) &&
+ (gen->id_hi > current_time);
+ break;
+
+ case FILEGEN_DAY:
+ case FILEGEN_WEEK:
+ case FILEGEN_MONTH:
+ case FILEGEN_YEAR:
+ current = (gen->id_lo <= now) &&
+ (gen->id_hi > now);
+ break;
+ }
+ /*
+ * try to open file if not yet open
+ * reopen new file generation file on change of generation id
+ */
+ if (NULL == gen->fp || !current) {
+ DPRINTF(1, ("filegen %0x %u\n", gen->type, now));
+ pivot = time(NULL);
+ filegen_open(gen, now, &pivot);
+ }
+}
+
+
+/*
+ * change settings for filegen files
+ */
+void
+filegen_config(
+ FILEGEN * gen,
+ const char * dir,
+ const char * fname,
+ u_int type,
+ u_int flag
+ )
+{
+ int file_existed;
+ l_fp now;
+
+
+ /*
+ * if nothing would be changed...
+ */
+ if (strcmp(dir, gen->dir) == 0 && strcmp(fname, gen->fname) == 0
+ && type == gen->type && flag == gen->flag)
+ return;
+
+ /*
+ * validate parameters
+ */
+ if (!valid_fileref(dir, fname))
+ return;
+
+ if (NULL != gen->fp) {
+ fclose(gen->fp);
+ gen->fp = NULL;
+ file_existed = TRUE;
+ } else {
+ file_existed = FALSE;
+ }
+
+ DPRINTF(3, ("configuring filegen:\n"
+ "\tdir:\t%s -> %s\n"
+ "\tfname:\t%s -> %s\n"
+ "\ttype:\t%d -> %d\n"
+ "\tflag: %x -> %x\n",
+ gen->dir, dir,
+ gen->fname, fname,
+ gen->type, type,
+ gen->flag, flag));
+
+ if (strcmp(gen->dir, dir) != 0) {
+ free(gen->dir);
+ gen->dir = estrdup(dir);
+ }
+
+ if (strcmp(gen->fname, fname) != 0) {
+ free(gen->fname);
+ gen->fname = estrdup(fname);
+ }
+ gen->type = (u_char)type;
+ gen->flag = (u_char)flag;
+
+ /*
+ * make filegen use the new settings
+ * special action is only required when a generation file
+ * is currently open
+ * otherwise the new settings will be used anyway at the next open
+ */
+ if (file_existed) {
+ get_systime(&now);
+ filegen_setup(gen, now.l_ui);
+ }
+}
+
+
+/*
+ * check whether concatenating prefix and basename
+ * yields a legal filename
+ */
+static int
+valid_fileref(
+ const char * dir,
+ const char * fname
+ )
+{
+ /*
+ * dir cannot be changed dynamically
+ * (within the context of filegen)
+ * so just reject basenames containing '..'
+ *
+ * ASSUMPTION:
+ * file system parts 'below' dir may be
+ * specified without infringement of security
+ *
+ * restricting dir to legal values
+ * has to be ensured by other means
+ * (however, it would be possible to perform some checks here...)
+ */
+ const char *p;
+
+ /*
+ * Just to catch, dumb errors opening up the world...
+ */
+ if (NULL == dir || '\0' == dir[0])
+ return FALSE;
+
+ if (NULL == fname)
+ return FALSE;
+
+#ifdef SYS_WINNT
+ /*
+ * Windows treats / equivalent to \, reject any / to ensure
+ * check below for DIR_SEP (\ on windows) are adequate.
+ */
+ if (strchr(fname, '/')) {
+ msyslog(LOG_ERR,
+ "filegen filenames must not contain '/': %s",
+ fname);
+ return FALSE;
+ }
+#endif
+
+ for (p = fname; p != NULL; p = strchr(p, DIR_SEP)) {
+ if ('.' == p[0] && '.' == p[1]
+ && ('\0' == p[2] || DIR_SEP == p[2]))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * filegen registry
+ */
+
+static struct filegen_entry {
+ char * name;
+ FILEGEN * filegen;
+ struct filegen_entry * next;
+} *filegen_registry = NULL;
+
+
+FILEGEN *
+filegen_get(
+ const char * name
+ )
+{
+ struct filegen_entry *f = filegen_registry;
+
+ while (f) {
+ if (f->name == name || strcmp(name, f->name) == 0) {
+ DPRINTF(4, ("filegen_get(%s) = %p\n",
+ name, f->filegen));
+ return f->filegen;
+ }
+ f = f->next;
+ }
+ DPRINTF(4, ("filegen_get(%s) = NULL\n", name));
+ return NULL;
+}
+
+
+void
+filegen_register(
+ const char * dir,
+ const char * name,
+ FILEGEN * filegen
+ )
+{
+ struct filegen_entry **ppfe;
+
+ DPRINTF(4, ("filegen_register(%s, %p)\n", name, filegen));
+
+ filegen_init(dir, name, filegen);
+
+ ppfe = &filegen_registry;
+ while (NULL != *ppfe) {
+ if ((*ppfe)->name == name
+ || !strcmp((*ppfe)->name, name)) {
+
+ DPRINTF(5, ("replacing filegen %p\n",
+ (*ppfe)->filegen));
+
+ (*ppfe)->filegen = filegen;
+ return;
+ }
+ ppfe = &((*ppfe)->next);
+ }
+
+ *ppfe = emalloc(sizeof **ppfe);
+
+ (*ppfe)->next = NULL;
+ (*ppfe)->name = estrdup(name);
+ (*ppfe)->filegen = filegen;
+
+ DPRINTF(6, ("adding new filegen\n"));
+
+ return;
+}
+
+
+/*
+ * filegen_statsdir() - reset each filegen entry's dir to statsdir.
+ */
+void
+filegen_statsdir(void)
+{
+ struct filegen_entry *f;
+
+ for (f = filegen_registry; f != NULL; f = f->next)
+ filegen_config(f->filegen, statsdir, f->filegen->fname,
+ f->filegen->type, f->filegen->flag);
+}
+
+
+/*
+ * filegen_unregister frees memory allocated by filegen_register for
+ * name.
+ */
+#ifdef DEBUG
+void
+filegen_unregister(
+ const char *name
+ )
+{
+ struct filegen_entry ** ppfe;
+ struct filegen_entry * pfe;
+ FILEGEN * fg;
+
+ DPRINTF(4, ("filegen_unregister(%s)\n", name));
+
+ ppfe = &filegen_registry;
+
+ while (NULL != *ppfe) {
+ if ((*ppfe)->name == name
+ || !strcmp((*ppfe)->name, name)) {
+ pfe = *ppfe;
+ *ppfe = (*ppfe)->next;
+ fg = pfe->filegen;
+ free(pfe->name);
+ free(pfe);
+ filegen_uninit(fg);
+ break;
+ }
+ ppfe = &((*ppfe)->next);
+ }
+}
+#endif /* DEBUG */
diff --git a/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_io.c b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_io.c
new file mode 100644
index 0000000..f572255
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_io.c
@@ -0,0 +1,4870 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * ntp_io.c - input/output routines for ntpd. The socket-opening code
+ * was shamelessly stolen from ntpd.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <signal.h>
+#ifdef HAVE_FNMATCH_H
+# include <fnmatch.h>
+# if !defined(FNM_CASEFOLD) && defined(FNM_IGNORECASE)
+# define FNM_CASEFOLD FNM_IGNORECASE
+# endif
+#endif
+#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_SOCKIO_H /* UXPV: SIOC* #defines (Frank Vance <fvance@waii.com>) */
+# include <sys/sockio.h>
+#endif
+#ifdef HAVE_SYS_UIO_H
+# include <sys/uio.h>
+#endif
+
+#include "ntp_machine.h"
+#include "ntpd.h"
+#include "ntp_io.h"
+#include "iosignal.h"
+#include "ntp_lists.h"
+#include "ntp_refclock.h"
+#include "ntp_stdlib.h"
+#include "ntp_worker.h"
+#include "ntp_request.h"
+#include "ntp_assert.h"
+#include "timevalops.h"
+#include "timespecops.h"
+#include "ntpd-opts.h"
+#include "safecast.h"
+
+/* Don't include ISC's version of IPv6 variables and structures */
+#define ISC_IPV6_H 1
+#include <isc/mem.h>
+#include <isc/interfaceiter.h>
+#include <isc/netaddr.h>
+#include <isc/result.h>
+#include <isc/sockaddr.h>
+
+#ifdef SIM
+#include "ntpsim.h"
+#endif
+
+#ifdef HAS_ROUTING_SOCKET
+# include <net/route.h>
+# ifdef HAVE_RTNETLINK
+# include <linux/rtnetlink.h>
+# endif
+#endif
+
+/*
+ * setsockopt does not always have the same arg declaration
+ * across all platforms. If it's not defined we make it empty
+ */
+
+#ifndef SETSOCKOPT_ARG_CAST
+#define SETSOCKOPT_ARG_CAST
+#endif
+
+extern int listen_to_virtual_ips;
+
+#ifndef IPTOS_DSCP_EF
+#define IPTOS_DSCP_EF 0xb8
+#endif
+int qos = IPTOS_DSCP_EF; /* QoS RFC3246 */
+
+#ifdef LEAP_SMEAR
+/* TODO burnicki: This should be moved to ntp_timer.c, but if we do so
+ * we get a linker error. Since we're running out of time before the leap
+ * second occurs, we let it here where it just works.
+ */
+int leap_smear_intv;
+#endif
+
+/*
+ * NIC rule entry
+ */
+typedef struct nic_rule_tag nic_rule;
+
+struct nic_rule_tag {
+ nic_rule * next;
+ nic_rule_action action;
+ nic_rule_match match_type;
+ char * if_name;
+ sockaddr_u addr;
+ int prefixlen;
+};
+
+/*
+ * NIC rule listhead. Entries are added at the head so that the first
+ * match in the list is the last matching rule specified.
+ */
+nic_rule *nic_rule_list;
+
+
+#if defined(SO_BINTIME) && defined(SCM_BINTIME) && defined(CMSG_FIRSTHDR)
+# define HAVE_PACKET_TIMESTAMP
+# define HAVE_BINTIME
+# ifdef BINTIME_CTLMSGBUF_SIZE
+# define CMSG_BUFSIZE BINTIME_CTLMSGBUF_SIZE
+# else
+# define CMSG_BUFSIZE 1536 /* moderate default */
+# endif
+#elif defined(SO_TIMESTAMPNS) && defined(SCM_TIMESTAMPNS) && defined(CMSG_FIRSTHDR)
+# define HAVE_PACKET_TIMESTAMP
+# define HAVE_TIMESTAMPNS
+# ifdef TIMESTAMPNS_CTLMSGBUF_SIZE
+# define CMSG_BUFSIZE TIMESTAMPNS_CTLMSGBUF_SIZE
+# else
+# define CMSG_BUFSIZE 1536 /* moderate default */
+# endif
+#elif defined(SO_TIMESTAMP) && defined(SCM_TIMESTAMP) && defined(CMSG_FIRSTHDR)
+# define HAVE_PACKET_TIMESTAMP
+# define HAVE_TIMESTAMP
+# ifdef TIMESTAMP_CTLMSGBUF_SIZE
+# define CMSG_BUFSIZE TIMESTAMP_CTLMSGBUF_SIZE
+# else
+# define CMSG_BUFSIZE 1536 /* moderate default */
+# endif
+#else
+/* fill in for old/other timestamp interfaces */
+#endif
+
+#if defined(SYS_WINNT)
+#include "win32_io.h"
+#include <isc/win32os.h>
+#endif
+
+/*
+ * We do asynchronous input using the SIGIO facility. A number of
+ * recvbuf buffers are preallocated for input. In the signal
+ * handler we poll to see which sockets are ready and read the
+ * packets from them into the recvbuf's along with a time stamp and
+ * an indication of the source host and the interface it was received
+ * through. This allows us to get as accurate receive time stamps
+ * as possible independent of other processing going on.
+ *
+ * We watch the number of recvbufs available to the signal handler
+ * and allocate more when this number drops below the low water
+ * mark. If the signal handler should run out of buffers in the
+ * interim it will drop incoming frames, the idea being that it is
+ * better to drop a packet than to be inaccurate.
+ */
+
+
+/*
+ * Other statistics of possible interest
+ */
+volatile u_long packets_dropped; /* total number of packets dropped on reception */
+volatile u_long packets_ignored; /* packets received on wild card interface */
+volatile u_long packets_received; /* total number of packets received */
+ u_long packets_sent; /* total number of packets sent */
+ u_long packets_notsent; /* total number of packets which couldn't be sent */
+
+volatile u_long handler_calls; /* number of calls to interrupt handler */
+volatile u_long handler_pkts; /* number of pkts received by handler */
+u_long io_timereset; /* time counters were reset */
+
+/*
+ * Interface stuff
+ */
+endpt * any_interface; /* wildcard ipv4 interface */
+endpt * any6_interface; /* wildcard ipv6 interface */
+endpt * loopback_interface; /* loopback ipv4 interface */
+
+isc_boolean_t broadcast_client_enabled; /* is broadcast client enabled */
+u_int sys_ifnum; /* next .ifnum to assign */
+int ninterfaces; /* Total number of interfaces */
+
+int disable_dynamic_updates; /* scan interfaces once only */
+
+#ifdef REFCLOCK
+/*
+ * Refclock stuff. We keep a chain of structures with data concerning
+ * the guys we are doing I/O for.
+ */
+static struct refclockio *refio;
+#endif /* REFCLOCK */
+
+/*
+ * File descriptor masks etc. for call to select
+ * Not needed for I/O Completion Ports or anything outside this file
+ */
+static fd_set activefds;
+static int maxactivefd;
+
+/*
+ * bit alternating value to detect verified interfaces during an update cycle
+ */
+static u_short sys_interphase = 0;
+
+static endpt * new_interface(endpt *);
+static void add_interface(endpt *);
+static int update_interfaces(u_short, interface_receiver_t,
+ void *);
+static void remove_interface(endpt *);
+static endpt * create_interface(u_short, endpt *);
+
+static int is_wildcard_addr (const sockaddr_u *);
+
+/*
+ * Multicast functions
+ */
+static isc_boolean_t addr_ismulticast (sockaddr_u *);
+static isc_boolean_t is_anycast (sockaddr_u *,
+ const char *);
+
+/*
+ * Not all platforms support multicast
+ */
+#ifdef MCAST
+static isc_boolean_t socket_multicast_enable (endpt *, sockaddr_u *);
+static isc_boolean_t socket_multicast_disable(endpt *, sockaddr_u *);
+#endif
+
+#ifdef DEBUG
+static void interface_dump (const endpt *);
+static void sockaddr_dump (const sockaddr_u *);
+static void print_interface (const endpt *, const char *, const char *);
+#define DPRINT_INTERFACE(level, args) do { if (debug >= (level)) { print_interface args; } } while (0)
+#else
+#define DPRINT_INTERFACE(level, args) do {} while (0)
+#endif
+
+typedef struct vsock vsock_t;
+enum desc_type { FD_TYPE_SOCKET, FD_TYPE_FILE };
+
+struct vsock {
+ vsock_t * link;
+ SOCKET fd;
+ enum desc_type type;
+};
+
+vsock_t *fd_list;
+
+#if !defined(HAVE_IO_COMPLETION_PORT) && defined(HAS_ROUTING_SOCKET)
+/*
+ * async notification processing (e. g. routing sockets)
+ */
+/*
+ * support for receiving data on fd that is not a refclock or a socket
+ * like e. g. routing sockets
+ */
+struct asyncio_reader {
+ struct asyncio_reader *link; /* the list this is being kept in */
+ SOCKET fd; /* fd to be read */
+ void *data; /* possibly local data */
+ void (*receiver)(struct asyncio_reader *); /* input handler */
+};
+
+struct asyncio_reader *asyncio_reader_list;
+
+static void delete_asyncio_reader (struct asyncio_reader *);
+static struct asyncio_reader *new_asyncio_reader (void);
+static void add_asyncio_reader (struct asyncio_reader *, enum desc_type);
+static void remove_asyncio_reader (struct asyncio_reader *);
+
+#endif /* !defined(HAVE_IO_COMPLETION_PORT) && defined(HAS_ROUTING_SOCKET) */
+
+static void init_async_notifications (void);
+
+static int addr_eqprefix (const sockaddr_u *, const sockaddr_u *,
+ int);
+static int addr_samesubnet (const sockaddr_u *, const sockaddr_u *,
+ const sockaddr_u *, const sockaddr_u *);
+static int create_sockets (u_short);
+static SOCKET open_socket (sockaddr_u *, int, int, endpt *);
+static void set_reuseaddr (int);
+static isc_boolean_t socket_broadcast_enable (struct interface *, SOCKET, sockaddr_u *);
+
+#if !defined(HAVE_IO_COMPLETION_PORT) && !defined(HAVE_SIGNALED_IO)
+static char * fdbits (int, const fd_set *);
+#endif
+#ifdef OS_MISSES_SPECIFIC_ROUTE_UPDATES
+static isc_boolean_t socket_broadcast_disable (struct interface *, sockaddr_u *);
+#endif
+
+typedef struct remaddr remaddr_t;
+
+struct remaddr {
+ remaddr_t * link;
+ sockaddr_u addr;
+ endpt * ep;
+};
+
+remaddr_t * remoteaddr_list;
+endpt * ep_list; /* complete endpt list */
+endpt * mc4_list; /* IPv4 mcast-capable unicast endpts */
+endpt * mc6_list; /* IPv6 mcast-capable unicast endpts */
+
+static endpt * wildipv4;
+static endpt * wildipv6;
+
+#ifdef SYS_WINNT
+int accept_wildcard_if_for_winnt;
+#else
+const int accept_wildcard_if_for_winnt = FALSE;
+#endif
+
+static void add_fd_to_list (SOCKET, enum desc_type);
+static endpt * find_addr_in_list (sockaddr_u *);
+static endpt * find_flagged_addr_in_list(sockaddr_u *, u_int32);
+static void delete_addr_from_list (sockaddr_u *);
+static void delete_interface_from_list(endpt *);
+static void close_and_delete_fd_from_list(SOCKET);
+static void add_addr_to_list (sockaddr_u *, endpt *);
+static void create_wildcards (u_short);
+static endpt * findlocalinterface (sockaddr_u *, int, int);
+static endpt * findclosestinterface (sockaddr_u *, int);
+#ifdef DEBUG
+static const char * action_text (nic_rule_action);
+#endif
+static nic_rule_action interface_action(char *, sockaddr_u *, u_int32);
+static void convert_isc_if (isc_interface_t *,
+ endpt *, u_short);
+static void calc_addr_distance(sockaddr_u *,
+ const sockaddr_u *,
+ const sockaddr_u *);
+static int cmp_addr_distance(const sockaddr_u *,
+ const sockaddr_u *);
+
+/*
+ * Routines to read the ntp packets
+ */
+#if !defined(HAVE_IO_COMPLETION_PORT)
+static inline int read_network_packet (SOCKET, struct interface *, l_fp);
+static void ntpd_addremove_io_fd (int, int, int);
+static void input_handler_scan (const l_fp*, const fd_set*);
+static int/*BOOL*/ sanitize_fdset (int errc);
+#ifdef REFCLOCK
+static inline int read_refclock_packet (SOCKET, struct refclockio *, l_fp);
+#endif
+#ifdef HAVE_SIGNALED_IO
+static void input_handler (l_fp*);
+#endif
+#endif
+
+
+#ifndef HAVE_IO_COMPLETION_PORT
+void
+maintain_activefds(
+ int fd,
+ int closing
+ )
+{
+ int i;
+
+ if (fd < 0 || fd >= FD_SETSIZE) {
+ msyslog(LOG_ERR,
+ "Too many sockets in use, FD_SETSIZE %d exceeded by fd %d",
+ FD_SETSIZE, fd);
+ exit(1);
+ }
+
+ if (!closing) {
+ FD_SET(fd, &activefds);
+ maxactivefd = max(fd, maxactivefd);
+ } else {
+ FD_CLR(fd, &activefds);
+ if (maxactivefd && fd == maxactivefd) {
+ for (i = maxactivefd - 1; i >= 0; i--)
+ if (FD_ISSET(i, &activefds)) {
+ maxactivefd = i;
+ break;
+ }
+ INSIST(fd != maxactivefd);
+ }
+ }
+}
+#endif /* !HAVE_IO_COMPLETION_PORT */
+
+
+#ifdef DEBUG_TIMING
+/*
+ * collect timing information for various processing
+ * paths. currently we only pass them on to the file
+ * for later processing. this could also do histogram
+ * based analysis in other to reduce the load (and skew)
+ * dur to the file output
+ */
+void
+collect_timing(struct recvbuf *rb, const char *tag, int count, l_fp *dts)
+{
+ char buf[256];
+
+ snprintf(buf, sizeof(buf), "%s %d %s %s",
+ (rb != NULL)
+ ? ((rb->dstadr != NULL)
+ ? stoa(&rb->recv_srcadr)
+ : "-REFCLOCK-")
+ : "-",
+ count, lfptoa(dts, 9), tag);
+ record_timing_stats(buf);
+}
+#endif
+
+/*
+ * About dynamic interfaces, sockets, reception and more...
+ *
+ * the code solves following tasks:
+ *
+ * - keep a current list of active interfaces in order
+ * to bind to to the interface address on NTP_PORT so that
+ * all wild and specific bindings for NTP_PORT are taken by ntpd
+ * to avoid other daemons messing with the time or sockets.
+ * - all interfaces keep a list of peers that are referencing
+ * the interface in order to quickly re-assign the peers to
+ * new interface in case an interface is deleted (=> gone from system or
+ * down)
+ * - have a preconfigured socket ready with the right local address
+ * for transmission and reception
+ * - have an address list for all destination addresses used within ntpd
+ * to find the "right" preconfigured socket.
+ * - facilitate updating the internal interface list with respect to
+ * the current kernel state
+ *
+ * special issues:
+ *
+ * - mapping of multicast addresses to the interface affected is not always
+ * one to one - especially on hosts with multiple interfaces
+ * the code here currently allocates a separate interface entry for those
+ * multicast addresses
+ * iff it is able to bind to a *new* socket with the multicast address (flags |= MCASTIF)
+ * in case of failure the multicast address is bound to an existing interface.
+ * - on some systems it is perfectly legal to assign the same address to
+ * multiple interfaces. Therefore this code does not keep a list of interfaces
+ * but a list of interfaces that represent a unique address as determined by the kernel
+ * by the procedure in findlocalinterface. Thus it is perfectly legal to see only
+ * one representative of a group of real interfaces if they share the same address.
+ *
+ * Frank Kardel 20050910
+ */
+
+/*
+ * init_io - initialize I/O module.
+ */
+void
+init_io(void)
+{
+ /* Init buffer free list and stat counters */
+ init_recvbuff(RECV_INIT);
+ /* update interface every 5 minutes as default */
+ interface_interval = 300;
+
+#ifdef WORK_PIPE
+ addremove_io_fd = &ntpd_addremove_io_fd;
+#endif
+
+#if defined(SYS_WINNT)
+ init_io_completion_port();
+#elif defined(HAVE_SIGNALED_IO)
+ (void) set_signal(input_handler);
+#endif
+}
+
+
+static void
+ntpd_addremove_io_fd(
+ int fd,
+ int is_pipe,
+ int remove_it
+ )
+{
+ UNUSED_ARG(is_pipe);
+
+#ifdef HAVE_SIGNALED_IO
+ if (!remove_it)
+ init_socket_sig(fd);
+#endif /* not HAVE_SIGNALED_IO */
+
+ maintain_activefds(fd, remove_it);
+}
+
+
+/*
+ * io_open_sockets - call socket creation routine
+ */
+void
+io_open_sockets(void)
+{
+ static int already_opened;
+
+ if (already_opened || HAVE_OPT( SAVECONFIGQUIT ))
+ return;
+
+ already_opened = 1;
+
+ /*
+ * Create the sockets
+ */
+ BLOCKIO();
+ create_sockets(NTP_PORT);
+ UNBLOCKIO();
+
+ init_async_notifications();
+
+ DPRINTF(3, ("io_open_sockets: maxactivefd %d\n", maxactivefd));
+}
+
+
+#ifdef DEBUG
+/*
+ * function to dump the contents of the interface structure
+ * for debugging use only.
+ * We face a dilemma here -- sockets are FDs under POSIX and
+ * actually HANDLES under Windows. So we use '%lld' as format
+ * and cast the value to 'long long'; this should not hurt
+ * with UNIX-like systems and does not truncate values on Win64.
+ */
+void
+interface_dump(const endpt *itf)
+{
+ printf("Dumping interface: %p\n", itf);
+ printf("fd = %lld\n", (long long)itf->fd);
+ printf("bfd = %lld\n", (long long)itf->bfd);
+ printf("sin = %s,\n", stoa(&itf->sin));
+ sockaddr_dump(&itf->sin);
+ printf("bcast = %s,\n", stoa(&itf->bcast));
+ sockaddr_dump(&itf->bcast);
+ printf("mask = %s,\n", stoa(&itf->mask));
+ sockaddr_dump(&itf->mask);
+ printf("name = %s\n", itf->name);
+ printf("flags = 0x%08x\n", itf->flags);
+ printf("last_ttl = %d\n", itf->last_ttl);
+ printf("addr_refid = %08x\n", itf->addr_refid);
+ printf("num_mcast = %d\n", itf->num_mcast);
+ printf("received = %ld\n", itf->received);
+ printf("sent = %ld\n", itf->sent);
+ printf("notsent = %ld\n", itf->notsent);
+ printf("ifindex = %u\n", itf->ifindex);
+ printf("peercnt = %u\n", itf->peercnt);
+ printf("phase = %u\n", itf->phase);
+}
+
+/*
+ * sockaddr_dump - hex dump the start of a sockaddr_u
+ */
+static void
+sockaddr_dump(const sockaddr_u *psau)
+{
+ /* Limit the size of the sockaddr_in6 hex dump */
+ const int maxsize = min(32, sizeof(psau->sa6));
+ const u_char * cp;
+ int i;
+
+ /* XXX: Should we limit maxsize based on psau->saX.sin_family? */
+ cp = (const void *)&psau->sa6;
+
+ for(i = 0; i < maxsize; i++) {
+ printf("%02x", *cp++);
+ if (!((i + 1) % 4))
+ printf(" ");
+ }
+ printf("\n");
+}
+
+/*
+ * print_interface - helper to output debug information
+ */
+static void
+print_interface(const endpt *iface, const char *pfx, const char *sfx)
+{
+ printf("%sinterface #%d: fd=%lld, bfd=%lld, name=%s, flags=0x%x, ifindex=%u, sin=%s",
+ pfx,
+ iface->ifnum,
+ (long long)iface->fd,
+ (long long)iface->bfd,
+ iface->name,
+ iface->flags,
+ iface->ifindex,
+ stoa(&iface->sin));
+ if (AF_INET == iface->family) {
+ if (iface->flags & INT_BROADCAST)
+ printf(", bcast=%s", stoa(&iface->bcast));
+ printf(", mask=%s", stoa(&iface->mask));
+ }
+ printf(", %s:%s",
+ (iface->ignore_packets)
+ ? "Disabled"
+ : "Enabled",
+ sfx);
+ if (debug > 4) /* in-depth debugging only */
+ interface_dump(iface);
+}
+#endif
+
+#if !defined(HAVE_IO_COMPLETION_PORT) && defined(HAS_ROUTING_SOCKET)
+/*
+ * create an asyncio_reader structure
+ */
+static struct asyncio_reader *
+new_asyncio_reader(void)
+{
+ struct asyncio_reader *reader;
+
+ reader = emalloc_zero(sizeof(*reader));
+ reader->fd = INVALID_SOCKET;
+
+ return reader;
+}
+
+/*
+ * delete a reader
+ */
+static void
+delete_asyncio_reader(
+ struct asyncio_reader *reader
+ )
+{
+ free(reader);
+}
+
+/*
+ * add asynchio_reader
+ */
+static void
+add_asyncio_reader(
+ struct asyncio_reader * reader,
+ enum desc_type type)
+{
+ LINK_SLIST(asyncio_reader_list, reader, link);
+ add_fd_to_list(reader->fd, type);
+}
+
+/*
+ * remove asynchio_reader
+ */
+static void
+remove_asyncio_reader(
+ struct asyncio_reader *reader
+ )
+{
+ struct asyncio_reader *unlinked;
+
+ UNLINK_SLIST(unlinked, asyncio_reader_list, reader, link,
+ struct asyncio_reader);
+
+ if (reader->fd != INVALID_SOCKET)
+ close_and_delete_fd_from_list(reader->fd);
+
+ reader->fd = INVALID_SOCKET;
+}
+#endif /* !defined(HAVE_IO_COMPLETION_PORT) && defined(HAS_ROUTING_SOCKET) */
+
+
+/* compare two sockaddr prefixes */
+static int
+addr_eqprefix(
+ const sockaddr_u * a,
+ const sockaddr_u * b,
+ int prefixlen
+ )
+{
+ isc_netaddr_t isc_a;
+ isc_netaddr_t isc_b;
+ isc_sockaddr_t isc_sa;
+
+ ZERO(isc_sa);
+ memcpy(&isc_sa.type, a, min(sizeof(isc_sa.type), sizeof(*a)));
+ isc_netaddr_fromsockaddr(&isc_a, &isc_sa);
+
+ ZERO(isc_sa);
+ memcpy(&isc_sa.type, b, min(sizeof(isc_sa.type), sizeof(*b)));
+ isc_netaddr_fromsockaddr(&isc_b, &isc_sa);
+
+ return (int)isc_netaddr_eqprefix(&isc_a, &isc_b,
+ (u_int)prefixlen);
+}
+
+
+static int
+addr_samesubnet(
+ const sockaddr_u * a,
+ const sockaddr_u * a_mask,
+ const sockaddr_u * b,
+ const sockaddr_u * b_mask
+ )
+{
+ const u_int32 * pa;
+ const u_int32 * pa_limit;
+ const u_int32 * pb;
+ const u_int32 * pm;
+ size_t loops;
+
+ REQUIRE(AF(a) == AF(a_mask));
+ REQUIRE(AF(b) == AF(b_mask));
+ /*
+ * With address and mask families verified to match, comparing
+ * the masks also validates the address's families match.
+ */
+ if (!SOCK_EQ(a_mask, b_mask))
+ return FALSE;
+
+ if (IS_IPV6(a)) {
+ loops = sizeof(NSRCADR6(a)) / sizeof(*pa);
+ pa = (const void *)&NSRCADR6(a);
+ pb = (const void *)&NSRCADR6(b);
+ pm = (const void *)&NSRCADR6(a_mask);
+ } else {
+ loops = sizeof(NSRCADR(a)) / sizeof(*pa);
+ pa = (const void *)&NSRCADR(a);
+ pb = (const void *)&NSRCADR(b);
+ pm = (const void *)&NSRCADR(a_mask);
+ }
+ for (pa_limit = pa + loops; pa < pa_limit; pa++, pb++, pm++)
+ if ((*pa & *pm) != (*pb & *pm))
+ return FALSE;
+
+ return TRUE;
+}
+
+
+/*
+ * interface list enumerator - visitor pattern
+ */
+void
+interface_enumerate(
+ interface_receiver_t receiver,
+ void * data
+ )
+{
+ interface_info_t ifi;
+
+ ifi.action = IFS_EXISTS;
+ for (ifi.ep = ep_list; ifi.ep != NULL; ifi.ep = ifi.ep->elink)
+ (*receiver)(data, &ifi);
+}
+
+/*
+ * do standard initialization of interface structure
+ */
+static void
+init_interface(
+ endpt *ep
+ )
+{
+ ZERO(*ep);
+ ep->fd = INVALID_SOCKET;
+ ep->bfd = INVALID_SOCKET;
+ ep->phase = sys_interphase;
+}
+
+
+/*
+ * create new interface structure initialize from
+ * template structure or via standard initialization
+ * function
+ */
+static struct interface *
+new_interface(
+ struct interface *interface
+ )
+{
+ struct interface * iface;
+
+ iface = emalloc(sizeof(*iface));
+
+ if (NULL == interface)
+ init_interface(iface);
+ else /* use the template */
+ memcpy(iface, interface, sizeof(*iface));
+
+ /* count every new instance of an interface in the system */
+ iface->ifnum = sys_ifnum++;
+ iface->starttime = current_time;
+
+# ifdef HAVE_IO_COMPLETION_PORT
+ if (!io_completion_port_add_interface(iface)) {
+ msyslog(LOG_EMERG, "cannot register interface with IO engine -- will exit now");
+ exit(1);
+ }
+# endif
+ return iface;
+}
+
+
+/*
+ * return interface storage into free memory pool
+ */
+static void
+delete_interface(
+ endpt *ep
+ )
+{
+# ifdef HAVE_IO_COMPLETION_PORT
+ io_completion_port_remove_interface(ep);
+# endif
+ free(ep);
+}
+
+
+/*
+ * link interface into list of known interfaces
+ */
+static void
+add_interface(
+ endpt * ep
+ )
+{
+ endpt ** pmclisthead;
+ endpt * scan;
+ endpt * scan_next;
+ endpt * unlinked;
+ sockaddr_u * addr;
+ int ep_local;
+ int scan_local;
+ int same_subnet;
+ int ep_univ_iid; /* iface ID from MAC address */
+ int scan_univ_iid; /* see RFC 4291 */
+ int ep_privacy; /* random local iface ID */
+ int scan_privacy; /* see RFC 4941 */
+ int rc;
+
+ /* Calculate the refid */
+ ep->addr_refid = addr2refid(&ep->sin);
+ /* link at tail so ntpdc -c ifstats index increases each row */
+ LINK_TAIL_SLIST(ep_list, ep, elink, endpt);
+ ninterfaces++;
+#ifdef MCAST
+ /* the rest is for enabled multicast-capable addresses only */
+ if (ep->ignore_packets || !(INT_MULTICAST & ep->flags) ||
+ INT_LOOPBACK & ep->flags)
+ return;
+# ifndef INCLUDE_IPV6_MULTICAST_SUPPORT
+ if (AF_INET6 == ep->family)
+ return;
+# endif
+ pmclisthead = (AF_INET == ep->family)
+ ? &mc4_list
+ : &mc6_list;
+
+ if (AF_INET6 == ep->family) {
+ ep_local =
+ IN6_IS_ADDR_LINKLOCAL(PSOCK_ADDR6(&ep->sin)) ||
+ IN6_IS_ADDR_SITELOCAL(PSOCK_ADDR6(&ep->sin));
+ ep_univ_iid = IS_IID_UNIV(&ep->sin);
+ ep_privacy = !!(INT_PRIVACY & ep->flags);
+ } else {
+ ep_local = FALSE;
+ ep_univ_iid = FALSE;
+ ep_privacy = FALSE;
+ }
+ DPRINTF(4, ("add_interface mcast-capable %s%s%s%s\n",
+ stoa(&ep->sin),
+ (ep_local) ? " link/scope-local" : "",
+ (ep_univ_iid) ? " univ-IID" : "",
+ (ep_privacy) ? " privacy" : ""));
+ /*
+ * If we have multiple local addresses on the same network
+ * interface, and some are link- or site-local, do not multicast
+ * out from the link-/site-local addresses by default, to avoid
+ * duplicate manycastclient associations between v6 peers using
+ * link-local and global addresses. link-local can still be
+ * chosen using "nic ignore myv6globalprefix::/64".
+ * Similarly, if we have multiple global addresses from the same
+ * prefix on the same network interface, multicast from one,
+ * preferring EUI-64, then static, then least RFC 4941 privacy
+ * addresses.
+ */
+ for (scan = *pmclisthead; scan != NULL; scan = scan_next) {
+ scan_next = scan->mclink;
+ if (ep->family != scan->family)
+ continue;
+ if (strcmp(ep->name, scan->name))
+ continue;
+ same_subnet = addr_samesubnet(&ep->sin, &ep->mask,
+ &scan->sin, &scan->mask);
+ if (AF_INET6 == ep->family) {
+ addr = &scan->sin;
+ scan_local =
+ IN6_IS_ADDR_LINKLOCAL(PSOCK_ADDR6(addr)) ||
+ IN6_IS_ADDR_SITELOCAL(PSOCK_ADDR6(addr));
+ scan_univ_iid = IS_IID_UNIV(addr);
+ scan_privacy = !!(INT_PRIVACY & scan->flags);
+ } else {
+ scan_local = FALSE;
+ scan_univ_iid = FALSE;
+ scan_privacy = FALSE;
+ }
+ DPRINTF(4, ("add_interface mcast-capable scan %s%s%s%s\n",
+ stoa(&scan->sin),
+ (scan_local) ? " link/scope-local" : "",
+ (scan_univ_iid) ? " univ-IID" : "",
+ (scan_privacy) ? " privacy" : ""));
+ if ((ep_local && !scan_local) || (same_subnet &&
+ ((ep_privacy && !scan_privacy) ||
+ (!ep_univ_iid && scan_univ_iid)))) {
+ DPRINTF(4, ("did not add %s to %s of IPv6 multicast-capable list which already has %s\n",
+ stoa(&ep->sin),
+ (ep_local)
+ ? "tail"
+ : "head",
+ stoa(&scan->sin)));
+ return;
+ }
+ if ((scan_local && !ep_local) || (same_subnet &&
+ ((scan_privacy && !ep_privacy) ||
+ (!scan_univ_iid && ep_univ_iid)))) {
+ UNLINK_SLIST(unlinked, *pmclisthead,
+ scan, mclink, endpt);
+ DPRINTF(4, ("%s %s from IPv6 multicast-capable list to add %s\n",
+ (unlinked != scan)
+ ? "Failed to remove"
+ : "removed",
+ stoa(&scan->sin), stoa(&ep->sin)));
+ }
+ }
+ /*
+ * Add link/site local at the tail of the multicast-
+ * capable unicast interfaces list, so that ntpd will
+ * send from global addresses before link-/site-local
+ * ones.
+ */
+ if (ep_local)
+ LINK_TAIL_SLIST(*pmclisthead, ep, mclink, endpt);
+ else
+ LINK_SLIST(*pmclisthead, ep, mclink);
+ DPRINTF(4, ("added %s to %s of IPv%s multicast-capable unicast local address list\n",
+ stoa(&ep->sin),
+ (ep_local)
+ ? "tail"
+ : "head",
+ (AF_INET == ep->family)
+ ? "4"
+ : "6"));
+
+ if (INVALID_SOCKET == ep->fd)
+ return;
+
+ /*
+ * select the local address from which to send to multicast.
+ */
+ switch (AF(&ep->sin)) {
+
+ case AF_INET :
+ rc = setsockopt(ep->fd, IPPROTO_IP,
+ IP_MULTICAST_IF,
+ (void *)&NSRCADR(&ep->sin),
+ sizeof(NSRCADR(&ep->sin)));
+ if (rc)
+ msyslog(LOG_ERR,
+ "setsockopt IP_MULTICAST_IF %s fails: %m",
+ stoa(&ep->sin));
+ break;
+
+# ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
+ case AF_INET6 :
+ rc = setsockopt(ep->fd, IPPROTO_IPV6,
+ IPV6_MULTICAST_IF,
+ (void *)&ep->ifindex,
+ sizeof(ep->ifindex));
+ /* do not complain if bound addr scope is ifindex */
+ if (rc && ep->ifindex != SCOPE(&ep->sin))
+ msyslog(LOG_ERR,
+ "setsockopt IPV6_MULTICAST_IF %u for %s fails: %m",
+ ep->ifindex, stoa(&ep->sin));
+ break;
+# endif
+ }
+#endif /* MCAST */
+}
+
+
+/*
+ * remove interface from known interface list and clean up
+ * associated resources
+ */
+static void
+remove_interface(
+ endpt * ep
+ )
+{
+ endpt * unlinked;
+ endpt ** pmclisthead;
+ sockaddr_u resmask;
+
+ UNLINK_SLIST(unlinked, ep_list, ep, elink, endpt);
+ if (!ep->ignore_packets && INT_MULTICAST & ep->flags) {
+ pmclisthead = (AF_INET == ep->family)
+ ? &mc4_list
+ : &mc6_list;
+ UNLINK_SLIST(unlinked, *pmclisthead, ep, mclink, endpt);
+ DPRINTF(4, ("%s %s IPv%s multicast-capable unicast local address list\n",
+ stoa(&ep->sin),
+ (unlinked != NULL)
+ ? "removed from"
+ : "not found on",
+ (AF_INET == ep->family)
+ ? "4"
+ : "6"));
+ }
+ delete_interface_from_list(ep);
+
+ if (ep->fd != INVALID_SOCKET) {
+ msyslog(LOG_INFO,
+ "Deleting interface #%d %s, %s#%d, interface stats: received=%ld, sent=%ld, dropped=%ld, active_time=%ld secs",
+ ep->ifnum,
+ ep->name,
+ stoa(&ep->sin),
+ SRCPORT(&ep->sin),
+ ep->received,
+ ep->sent,
+ ep->notsent,
+ current_time - ep->starttime);
+# ifdef HAVE_IO_COMPLETION_PORT
+ io_completion_port_remove_socket(ep->fd, ep);
+# endif
+ close_and_delete_fd_from_list(ep->fd);
+ ep->fd = INVALID_SOCKET;
+ }
+
+ if (ep->bfd != INVALID_SOCKET) {
+ msyslog(LOG_INFO,
+ "stop listening for broadcasts to %s on interface #%d %s",
+ stoa(&ep->bcast), ep->ifnum, ep->name);
+# ifdef HAVE_IO_COMPLETION_PORT
+ io_completion_port_remove_socket(ep->bfd, ep);
+# endif
+ close_and_delete_fd_from_list(ep->bfd);
+ ep->bfd = INVALID_SOCKET;
+ }
+# ifdef HAVE_IO_COMPLETION_PORT
+ io_completion_port_remove_interface(ep);
+# endif
+
+ ninterfaces--;
+ mon_clearinterface(ep);
+
+ /* remove restrict interface entry */
+ SET_HOSTMASK(&resmask, AF(&ep->sin));
+ hack_restrict(RESTRICT_REMOVEIF, &ep->sin, &resmask,
+ -3, RESM_NTPONLY | RESM_INTERFACE, RES_IGNORE, 0);
+}
+
+
+static void
+log_listen_address(
+ endpt * ep
+ )
+{
+ msyslog(LOG_INFO, "%s on %d %s %s",
+ (ep->ignore_packets)
+ ? "Listen and drop"
+ : "Listen normally",
+ ep->ifnum,
+ ep->name,
+ sptoa(&ep->sin));
+}
+
+
+static void
+create_wildcards(
+ u_short port
+ )
+{
+ int v4wild;
+#ifdef INCLUDE_IPV6_SUPPORT
+ int v6wild;
+#endif
+ sockaddr_u wildaddr;
+ nic_rule_action action;
+ struct interface * wildif;
+
+ /*
+ * silence "potentially uninitialized" warnings from VC9
+ * failing to follow the logic. Ideally action could remain
+ * uninitialized, and the memset be the first statement under
+ * the first if (v4wild).
+ */
+ action = ACTION_LISTEN;
+ ZERO(wildaddr);
+
+#ifdef INCLUDE_IPV6_SUPPORT
+ /*
+ * create pseudo-interface with wildcard IPv6 address
+ */
+ v6wild = ipv6_works;
+ if (v6wild) {
+ /* set wildaddr to the v6 wildcard address :: */
+ ZERO(wildaddr);
+ AF(&wildaddr) = AF_INET6;
+ SET_ADDR6N(&wildaddr, in6addr_any);
+ SET_PORT(&wildaddr, port);
+ SET_SCOPE(&wildaddr, 0);
+
+ /* check for interface/nic rules affecting the wildcard */
+ action = interface_action(NULL, &wildaddr, 0);
+ v6wild = (ACTION_IGNORE != action);
+ }
+ if (v6wild) {
+ wildif = new_interface(NULL);
+
+ strlcpy(wildif->name, "v6wildcard", sizeof(wildif->name));
+ memcpy(&wildif->sin, &wildaddr, sizeof(wildif->sin));
+ wildif->family = AF_INET6;
+ AF(&wildif->mask) = AF_INET6;
+ SET_ONESMASK(&wildif->mask);
+
+ wildif->flags = INT_UP | INT_WILDCARD;
+ wildif->ignore_packets = (ACTION_DROP == action);
+
+ wildif->fd = open_socket(&wildif->sin, 0, 1, wildif);
+
+ if (wildif->fd != INVALID_SOCKET) {
+ wildipv6 = wildif;
+ any6_interface = wildif;
+ add_addr_to_list(&wildif->sin, wildif);
+ add_interface(wildif);
+ log_listen_address(wildif);
+ } else {
+ msyslog(LOG_ERR,
+ "unable to bind to wildcard address %s - another process may be running - EXITING",
+ stoa(&wildif->sin));
+ exit(1);
+ }
+ DPRINT_INTERFACE(2, (wildif, "created ", "\n"));
+ }
+#endif
+
+ /*
+ * create pseudo-interface with wildcard IPv4 address
+ */
+ v4wild = ipv4_works;
+ if (v4wild) {
+ /* set wildaddr to the v4 wildcard address 0.0.0.0 */
+ AF(&wildaddr) = AF_INET;
+ SET_ADDR4N(&wildaddr, INADDR_ANY);
+ SET_PORT(&wildaddr, port);
+
+ /* check for interface/nic rules affecting the wildcard */
+ action = interface_action(NULL, &wildaddr, 0);
+ v4wild = (ACTION_IGNORE != action);
+ }
+ if (v4wild) {
+ wildif = new_interface(NULL);
+
+ strlcpy(wildif->name, "v4wildcard", sizeof(wildif->name));
+ memcpy(&wildif->sin, &wildaddr, sizeof(wildif->sin));
+ wildif->family = AF_INET;
+ AF(&wildif->mask) = AF_INET;
+ SET_ONESMASK(&wildif->mask);
+
+ wildif->flags = INT_BROADCAST | INT_UP | INT_WILDCARD;
+ wildif->ignore_packets = (ACTION_DROP == action);
+#if defined(MCAST)
+ /*
+ * enable multicast reception on the broadcast socket
+ */
+ AF(&wildif->bcast) = AF_INET;
+ SET_ADDR4N(&wildif->bcast, INADDR_ANY);
+ SET_PORT(&wildif->bcast, port);
+#endif /* MCAST */
+ wildif->fd = open_socket(&wildif->sin, 0, 1, wildif);
+
+ if (wildif->fd != INVALID_SOCKET) {
+ wildipv4 = wildif;
+ any_interface = wildif;
+
+ add_addr_to_list(&wildif->sin, wildif);
+ add_interface(wildif);
+ log_listen_address(wildif);
+ } else {
+ msyslog(LOG_ERR,
+ "unable to bind to wildcard address %s - another process may be running - EXITING",
+ stoa(&wildif->sin));
+ exit(1);
+ }
+ DPRINT_INTERFACE(2, (wildif, "created ", "\n"));
+ }
+}
+
+
+/*
+ * add_nic_rule() -- insert a rule entry at the head of nic_rule_list.
+ */
+void
+add_nic_rule(
+ nic_rule_match match_type,
+ const char * if_name, /* interface name or numeric address */
+ int prefixlen,
+ nic_rule_action action
+ )
+{
+ nic_rule * rule;
+ isc_boolean_t is_ip;
+
+ rule = emalloc_zero(sizeof(*rule));
+ rule->match_type = match_type;
+ rule->prefixlen = prefixlen;
+ rule->action = action;
+
+ if (MATCH_IFNAME == match_type) {
+ REQUIRE(NULL != if_name);
+ rule->if_name = estrdup(if_name);
+ } else if (MATCH_IFADDR == match_type) {
+ REQUIRE(NULL != if_name);
+ /* set rule->addr */
+ is_ip = is_ip_address(if_name, AF_UNSPEC, &rule->addr);
+ REQUIRE(is_ip);
+ } else
+ REQUIRE(NULL == if_name);
+
+ LINK_SLIST(nic_rule_list, rule, next);
+}
+
+
+#ifdef DEBUG
+static const char *
+action_text(
+ nic_rule_action action
+ )
+{
+ const char *t;
+
+ switch (action) {
+
+ default:
+ t = "ERROR"; /* quiet uninit warning */
+ DPRINTF(1, ("fatal: unknown nic_rule_action %d\n",
+ action));
+ ENSURE(0);
+ break;
+
+ case ACTION_LISTEN:
+ t = "listen";
+ break;
+
+ case ACTION_IGNORE:
+ t = "ignore";
+ break;
+
+ case ACTION_DROP:
+ t = "drop";
+ break;
+ }
+
+ return t;
+}
+#endif /* DEBUG */
+
+
+static nic_rule_action
+interface_action(
+ char * if_name,
+ sockaddr_u * if_addr,
+ u_int32 if_flags
+ )
+{
+ nic_rule * rule;
+ int isloopback;
+ int iswildcard;
+
+ DPRINTF(4, ("interface_action: interface %s ",
+ (if_name != NULL) ? if_name : "wildcard"));
+
+ iswildcard = is_wildcard_addr(if_addr);
+ isloopback = !!(INT_LOOPBACK & if_flags);
+
+ /*
+ * Find any matching NIC rule from --interface / -I or ntp.conf
+ * interface/nic rules.
+ */
+ for (rule = nic_rule_list; rule != NULL; rule = rule->next) {
+
+ switch (rule->match_type) {
+
+ case MATCH_ALL:
+ /* loopback and wildcard excluded from "all" */
+ if (isloopback || iswildcard)
+ break;
+ DPRINTF(4, ("nic all %s\n",
+ action_text(rule->action)));
+ return rule->action;
+
+ case MATCH_IPV4:
+ if (IS_IPV4(if_addr)) {
+ DPRINTF(4, ("nic ipv4 %s\n",
+ action_text(rule->action)));
+ return rule->action;
+ }
+ break;
+
+ case MATCH_IPV6:
+ if (IS_IPV6(if_addr)) {
+ DPRINTF(4, ("nic ipv6 %s\n",
+ action_text(rule->action)));
+ return rule->action;
+ }
+ break;
+
+ case MATCH_WILDCARD:
+ if (iswildcard) {
+ DPRINTF(4, ("nic wildcard %s\n",
+ action_text(rule->action)));
+ return rule->action;
+ }
+ break;
+
+ case MATCH_IFADDR:
+ if (rule->prefixlen != -1) {
+ if (addr_eqprefix(if_addr, &rule->addr,
+ rule->prefixlen)) {
+
+ DPRINTF(4, ("subnet address match - %s\n",
+ action_text(rule->action)));
+ return rule->action;
+ }
+ } else
+ if (SOCK_EQ(if_addr, &rule->addr)) {
+
+ DPRINTF(4, ("address match - %s\n",
+ action_text(rule->action)));
+ return rule->action;
+ }
+ break;
+
+ case MATCH_IFNAME:
+ if (if_name != NULL
+#if defined(HAVE_FNMATCH) && defined(FNM_CASEFOLD)
+ && !fnmatch(rule->if_name, if_name, FNM_CASEFOLD)
+#else
+ && !strcasecmp(if_name, rule->if_name)
+#endif
+ ) {
+
+ DPRINTF(4, ("interface name match - %s\n",
+ action_text(rule->action)));
+ return rule->action;
+ }
+ break;
+ }
+ }
+
+ /*
+ * Unless explicitly disabled such as with "nic ignore ::1"
+ * listen on loopback addresses. Since ntpq and ntpdc query
+ * "localhost" by default, which typically resolves to ::1 and
+ * 127.0.0.1, it's useful to default to listening on both.
+ */
+ if (isloopback) {
+ DPRINTF(4, ("default loopback listen\n"));
+ return ACTION_LISTEN;
+ }
+
+ /*
+ * Treat wildcard addresses specially. If there is no explicit
+ * "nic ... wildcard" or "nic ... 0.0.0.0" or "nic ... ::" rule
+ * default to drop.
+ */
+ if (iswildcard) {
+ DPRINTF(4, ("default wildcard drop\n"));
+ return ACTION_DROP;
+ }
+
+ /*
+ * Check for "virtual IP" (colon in the interface name) after
+ * the rules so that "ntpd --interface eth0:1 -novirtualips"
+ * does indeed listen on eth0:1's addresses.
+ */
+ if (!listen_to_virtual_ips && if_name != NULL
+ && (strchr(if_name, ':') != NULL)) {
+
+ DPRINTF(4, ("virtual ip - ignore\n"));
+ return ACTION_IGNORE;
+ }
+
+ /*
+ * If there are no --interface/-I command-line options and no
+ * interface/nic rules in ntp.conf, the default action is to
+ * listen. In the presence of rules from either, the default
+ * is to ignore. This implements ntpd's traditional listen-
+ * every default with no interface listen configuration, and
+ * ensures a single -I eth0 or "nic listen eth0" means do not
+ * listen on any other addresses.
+ */
+ if (NULL == nic_rule_list) {
+ DPRINTF(4, ("default listen\n"));
+ return ACTION_LISTEN;
+ }
+
+ DPRINTF(4, ("implicit ignore\n"));
+ return ACTION_IGNORE;
+}
+
+
+static void
+convert_isc_if(
+ isc_interface_t *isc_if,
+ endpt *itf,
+ u_short port
+ )
+{
+ const u_char v6loop[16] = {0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1};
+
+ strlcpy(itf->name, isc_if->name, sizeof(itf->name));
+ itf->ifindex = isc_if->ifindex;
+ itf->family = (u_short)isc_if->af;
+ AF(&itf->sin) = itf->family;
+ AF(&itf->mask) = itf->family;
+ AF(&itf->bcast) = itf->family;
+ SET_PORT(&itf->sin, port);
+ SET_PORT(&itf->mask, port);
+ SET_PORT(&itf->bcast, port);
+
+ if (IS_IPV4(&itf->sin)) {
+ NSRCADR(&itf->sin) = isc_if->address.type.in.s_addr;
+ NSRCADR(&itf->mask) = isc_if->netmask.type.in.s_addr;
+
+ if (isc_if->flags & INTERFACE_F_BROADCAST) {
+ itf->flags |= INT_BROADCAST;
+ NSRCADR(&itf->bcast) =
+ isc_if->broadcast.type.in.s_addr;
+ }
+ }
+#ifdef INCLUDE_IPV6_SUPPORT
+ else if (IS_IPV6(&itf->sin)) {
+ SET_ADDR6N(&itf->sin, isc_if->address.type.in6);
+ SET_ADDR6N(&itf->mask, isc_if->netmask.type.in6);
+
+ SET_SCOPE(&itf->sin, isc_if->address.zone);
+ }
+#endif /* INCLUDE_IPV6_SUPPORT */
+
+
+ /* Process the rest of the flags */
+
+ itf->flags |=
+ ((INTERFACE_F_UP & isc_if->flags)
+ ? INT_UP : 0)
+ | ((INTERFACE_F_LOOPBACK & isc_if->flags)
+ ? INT_LOOPBACK : 0)
+ | ((INTERFACE_F_POINTTOPOINT & isc_if->flags)
+ ? INT_PPP : 0)
+ | ((INTERFACE_F_MULTICAST & isc_if->flags)
+ ? INT_MULTICAST : 0)
+ | ((INTERFACE_F_PRIVACY & isc_if->flags)
+ ? INT_PRIVACY : 0)
+ ;
+
+ /*
+ * Clear the loopback flag if the address is not localhost.
+ * http://bugs.ntp.org/1683
+ */
+ if (INT_LOOPBACK & itf->flags) {
+ if (AF_INET == itf->family) {
+ if (127 != (SRCADR(&itf->sin) >> 24))
+ itf->flags &= ~INT_LOOPBACK;
+ } else {
+ if (memcmp(v6loop, NSRCADR6(&itf->sin),
+ sizeof(NSRCADR6(&itf->sin))))
+ itf->flags &= ~INT_LOOPBACK;
+ }
+ }
+}
+
+
+/*
+ * refresh_interface
+ *
+ * some OSes have been observed to keep
+ * cached routes even when more specific routes
+ * become available.
+ * this can be mitigated by re-binding
+ * the socket.
+ */
+static int
+refresh_interface(
+ struct interface * interface
+ )
+{
+#ifdef OS_MISSES_SPECIFIC_ROUTE_UPDATES
+ if (interface->fd != INVALID_SOCKET) {
+ int bcast = (interface->flags & INT_BCASTXMIT) != 0;
+ /* as we forcibly close() the socket remove the
+ broadcast permission indication */
+ if (bcast)
+ socket_broadcast_disable(interface, &interface->sin);
+
+ close_and_delete_fd_from_list(interface->fd);
+
+ /* create new socket picking up a new first hop binding
+ at connect() time */
+ interface->fd = open_socket(&interface->sin,
+ bcast, 0, interface);
+ /*
+ * reset TTL indication so TTL is is set again
+ * next time around
+ */
+ interface->last_ttl = 0;
+ return (interface->fd != INVALID_SOCKET);
+ } else
+ return 0; /* invalid sockets are not refreshable */
+#else /* !OS_MISSES_SPECIFIC_ROUTE_UPDATES */
+ return (interface->fd != INVALID_SOCKET);
+#endif /* !OS_MISSES_SPECIFIC_ROUTE_UPDATES */
+}
+
+/*
+ * interface_update - externally callable update function
+ */
+void
+interface_update(
+ interface_receiver_t receiver,
+ void * data)
+{
+ int new_interface_found;
+
+ if (disable_dynamic_updates)
+ return;
+
+ BLOCKIO();
+ new_interface_found = update_interfaces(NTP_PORT, receiver, data);
+ UNBLOCKIO();
+
+ if (!new_interface_found)
+ return;
+
+#ifdef DEBUG
+ msyslog(LOG_DEBUG, "new interface(s) found: waking up resolver");
+#endif
+ interrupt_worker_sleep();
+}
+
+
+/*
+ * sau_from_netaddr() - convert network address on-wire formats.
+ * Convert from libisc's isc_netaddr_t to NTP's sockaddr_u
+ */
+void
+sau_from_netaddr(
+ sockaddr_u *psau,
+ const isc_netaddr_t *pna
+ )
+{
+ ZERO_SOCK(psau);
+ AF(psau) = (u_short)pna->family;
+ switch (pna->family) {
+
+ case AF_INET:
+ memcpy(&psau->sa4.sin_addr, &pna->type.in,
+ sizeof(psau->sa4.sin_addr));
+ break;
+
+ case AF_INET6:
+ memcpy(&psau->sa6.sin6_addr, &pna->type.in6,
+ sizeof(psau->sa6.sin6_addr));
+ break;
+ }
+}
+
+
+static int
+is_wildcard_addr(
+ const sockaddr_u *psau
+ )
+{
+ if (IS_IPV4(psau) && !NSRCADR(psau))
+ return 1;
+
+#ifdef INCLUDE_IPV6_SUPPORT
+ if (IS_IPV6(psau) && S_ADDR6_EQ(psau, &in6addr_any))
+ return 1;
+#endif
+
+ return 0;
+}
+
+
+#ifdef OS_NEEDS_REUSEADDR_FOR_IFADDRBIND
+/*
+ * enable/disable re-use of wildcard address socket
+ */
+static void
+set_wildcard_reuse(
+ u_short family,
+ int on
+ )
+{
+ struct interface *any;
+ SOCKET fd = INVALID_SOCKET;
+
+ any = ANY_INTERFACE_BYFAM(family);
+ if (any != NULL)
+ fd = any->fd;
+
+ if (fd != INVALID_SOCKET) {
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
+ (void *)&on, sizeof(on)))
+ msyslog(LOG_ERR,
+ "set_wildcard_reuse: setsockopt(SO_REUSEADDR, %s) failed: %m",
+ on ? "on" : "off");
+
+ DPRINTF(4, ("set SO_REUSEADDR to %s on %s\n",
+ on ? "on" : "off",
+ stoa(&any->sin)));
+ }
+}
+#endif /* OS_NEEDS_REUSEADDR_FOR_IFADDRBIND */
+
+static isc_boolean_t
+check_flags(
+ sockaddr_u *psau,
+ const char *name,
+ u_int32 flags
+ )
+{
+#if defined(SIOCGIFAFLAG_IN)
+ struct ifreq ifr;
+ int fd;
+
+ if (psau->sa.sa_family != AF_INET)
+ return ISC_FALSE;
+ if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+ return ISC_FALSE;
+ ZERO(ifr);
+ memcpy(&ifr.ifr_addr, &psau->sa, sizeof(ifr.ifr_addr));
+ strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+ if (ioctl(fd, SIOCGIFAFLAG_IN, &ifr) < 0) {
+ close(fd);
+ return ISC_FALSE;
+ }
+ close(fd);
+ if ((ifr.ifr_addrflags & flags) != 0)
+ return ISC_TRUE;
+#endif /* SIOCGIFAFLAG_IN */
+ return ISC_FALSE;
+}
+
+static isc_boolean_t
+check_flags6(
+ sockaddr_u *psau,
+ const char *name,
+ u_int32 flags6
+ )
+{
+#if defined(INCLUDE_IPV6_SUPPORT) && defined(SIOCGIFAFLAG_IN6)
+ struct in6_ifreq ifr6;
+ int fd;
+
+ if (psau->sa.sa_family != AF_INET6)
+ return ISC_FALSE;
+ if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
+ return ISC_FALSE;
+ ZERO(ifr6);
+ memcpy(&ifr6.ifr_addr, &psau->sa6, sizeof(ifr6.ifr_addr));
+ strlcpy(ifr6.ifr_name, name, sizeof(ifr6.ifr_name));
+ if (ioctl(fd, SIOCGIFAFLAG_IN6, &ifr6) < 0) {
+ close(fd);
+ return ISC_FALSE;
+ }
+ close(fd);
+ if ((ifr6.ifr_ifru.ifru_flags6 & flags6) != 0)
+ return ISC_TRUE;
+#endif /* INCLUDE_IPV6_SUPPORT && SIOCGIFAFLAG_IN6 */
+ return ISC_FALSE;
+}
+
+static isc_boolean_t
+is_anycast(
+ sockaddr_u *psau,
+ const char *name
+ )
+{
+#ifdef IN6_IFF_ANYCAST
+ return check_flags6(psau, name, IN6_IFF_ANYCAST);
+#else
+ return ISC_FALSE;
+#endif
+}
+
+static isc_boolean_t
+is_valid(
+ sockaddr_u *psau,
+ const char *name
+ )
+{
+ u_int32 flags;
+
+ flags = 0;
+ switch (psau->sa.sa_family) {
+ case AF_INET:
+#ifdef IN_IFF_DETACHED
+ flags |= IN_IFF_DETACHED;
+#endif
+#ifdef IN_IFF_TENTATIVE
+ flags |= IN_IFF_TENTATIVE;
+#endif
+ return check_flags(psau, name, flags) ? ISC_FALSE : ISC_TRUE;
+ case AF_INET6:
+#ifdef IN6_IFF_DEPARTED
+ flags |= IN6_IFF_DEPARTED;
+#endif
+#ifdef IN6_IFF_DETACHED
+ flags |= IN6_IFF_DETACHED;
+#endif
+#ifdef IN6_IFF_TENTATIVE
+ flags |= IN6_IFF_TENTATIVE;
+#endif
+ return check_flags6(psau, name, flags) ? ISC_FALSE : ISC_TRUE;
+ default:
+ return ISC_FALSE;
+ }
+}
+
+/*
+ * update_interface strategy
+ *
+ * toggle configuration phase
+ *
+ * Phase 1:
+ * forall currently existing interfaces
+ * if address is known:
+ * drop socket - rebind again
+ *
+ * if address is NOT known:
+ * attempt to create a new interface entry
+ *
+ * Phase 2:
+ * forall currently known non MCAST and WILDCARD interfaces
+ * if interface does not match configuration phase (not seen in phase 1):
+ * remove interface from known interface list
+ * forall peers associated with this interface
+ * disconnect peer from this interface
+ *
+ * Phase 3:
+ * attempt to re-assign interfaces to peers
+ *
+ */
+
+static int
+update_interfaces(
+ u_short port,
+ interface_receiver_t receiver,
+ void * data
+ )
+{
+ isc_mem_t * mctx = (void *)-1;
+ interface_info_t ifi;
+ isc_interfaceiter_t * iter;
+ isc_result_t result;
+ isc_interface_t isc_if;
+ int new_interface_found;
+ unsigned int family;
+ endpt enumep;
+ endpt * ep;
+ endpt * next_ep;
+
+ DPRINTF(3, ("update_interfaces(%d)\n", port));
+
+ /*
+ * phase one - scan interfaces
+ * - create those that are not found
+ * - update those that are found
+ */
+
+ new_interface_found = FALSE;
+ iter = NULL;
+ result = isc_interfaceiter_create(mctx, &iter);
+
+ if (result != ISC_R_SUCCESS)
+ return 0;
+
+ /*
+ * Toggle system interface scan phase to find untouched
+ * interfaces to be deleted.
+ */
+ sys_interphase ^= 0x1;
+
+ for (result = isc_interfaceiter_first(iter);
+ ISC_R_SUCCESS == result;
+ result = isc_interfaceiter_next(iter)) {
+
+ result = isc_interfaceiter_current(iter, &isc_if);
+
+ if (result != ISC_R_SUCCESS)
+ break;
+
+ /* See if we have a valid family to use */
+ family = isc_if.address.family;
+ if (AF_INET != family && AF_INET6 != family)
+ continue;
+ if (AF_INET == family && !ipv4_works)
+ continue;
+ if (AF_INET6 == family && !ipv6_works)
+ continue;
+
+ /* create prototype */
+ init_interface(&enumep);
+
+ convert_isc_if(&isc_if, &enumep, port);
+
+ DPRINT_INTERFACE(4, (&enumep, "examining ", "\n"));
+
+ /*
+ * Check if and how we are going to use the interface.
+ */
+ switch (interface_action(enumep.name, &enumep.sin,
+ enumep.flags)) {
+
+ case ACTION_IGNORE:
+ DPRINTF(4, ("ignoring interface %s (%s) - by nic rules\n",
+ enumep.name, stoa(&enumep.sin)));
+ continue;
+
+ case ACTION_LISTEN:
+ DPRINTF(4, ("listen interface %s (%s) - by nic rules\n",
+ enumep.name, stoa(&enumep.sin)));
+ enumep.ignore_packets = ISC_FALSE;
+ break;
+
+ case ACTION_DROP:
+ DPRINTF(4, ("drop on interface %s (%s) - by nic rules\n",
+ enumep.name, stoa(&enumep.sin)));
+ enumep.ignore_packets = ISC_TRUE;
+ break;
+ }
+
+ /* interfaces must be UP to be usable */
+ if (!(enumep.flags & INT_UP)) {
+ DPRINTF(4, ("skipping interface %s (%s) - DOWN\n",
+ enumep.name, stoa(&enumep.sin)));
+ continue;
+ }
+
+ /*
+ * skip any interfaces UP and bound to a wildcard
+ * address - some dhcp clients produce that in the
+ * wild
+ */
+ if (is_wildcard_addr(&enumep.sin))
+ continue;
+
+ if (is_anycast(&enumep.sin, isc_if.name))
+ continue;
+
+ /*
+ * skip any address that is an invalid state to be used
+ */
+ if (!is_valid(&enumep.sin, isc_if.name))
+ continue;
+
+ /*
+ * map to local *address* in order to map all duplicate
+ * interfaces to an endpt structure with the appropriate
+ * socket. Our name space is (ip-address), NOT
+ * (interface name, ip-address).
+ */
+ ep = getinterface(&enumep.sin, INT_WILDCARD);
+
+ if (ep != NULL && refresh_interface(ep)) {
+ /*
+ * found existing and up to date interface -
+ * mark present.
+ */
+ if (ep->phase != sys_interphase) {
+ /*
+ * On a new round we reset the name so
+ * the interface name shows up again if
+ * this address is no longer shared.
+ * We reset ignore_packets from the
+ * new prototype to respect any runtime
+ * changes to the nic rules.
+ */
+ strlcpy(ep->name, enumep.name,
+ sizeof(ep->name));
+ ep->ignore_packets =
+ enumep.ignore_packets;
+ } else {
+ /* name collision - rename interface */
+ strlcpy(ep->name, "*multiple*",
+ sizeof(ep->name));
+ }
+
+ DPRINT_INTERFACE(4, (ep, "updating ",
+ " present\n"));
+
+ if (ep->ignore_packets !=
+ enumep.ignore_packets) {
+ /*
+ * We have conflicting configurations
+ * for the interface address. This is
+ * caused by using -I <interfacename>
+ * for an interface that shares its
+ * address with other interfaces. We
+ * can not disambiguate incoming
+ * packets delivered to this socket
+ * without extra syscalls/features.
+ * These are not (commonly) available.
+ * Note this is a more unusual
+ * configuration where several
+ * interfaces share an address but
+ * filtering via interface name is
+ * attempted. We resolve the
+ * configuration conflict by disabling
+ * the processing of received packets.
+ * This leads to no service on the
+ * interface address where the conflict
+ * occurs.
+ */
+ msyslog(LOG_ERR,
+ "WARNING: conflicting enable configuration for interfaces %s and %s for address %s - unsupported configuration - address DISABLED",
+ enumep.name, ep->name,
+ stoa(&enumep.sin));
+
+ ep->ignore_packets = ISC_TRUE;
+ }
+
+ ep->phase = sys_interphase;
+
+ ifi.action = IFS_EXISTS;
+ ifi.ep = ep;
+ if (receiver != NULL)
+ (*receiver)(data, &ifi);
+ } else {
+ /*
+ * This is new or refreshing failed - add to
+ * our interface list. If refreshing failed we
+ * will delete the interface structure in phase
+ * 2 as the interface was not marked current.
+ * We can bind to the address as the refresh
+ * code already closed the offending socket
+ */
+ ep = create_interface(port, &enumep);
+
+ if (ep != NULL) {
+ ifi.action = IFS_CREATED;
+ ifi.ep = ep;
+ if (receiver != NULL)
+ (*receiver)(data, &ifi);
+
+ new_interface_found = TRUE;
+ DPRINT_INTERFACE(3,
+ (ep, "updating ",
+ " new - created\n"));
+ } else {
+ DPRINT_INTERFACE(3,
+ (&enumep, "updating ",
+ " new - creation FAILED"));
+
+ msyslog(LOG_INFO,
+ "failed to init interface for address %s",
+ stoa(&enumep.sin));
+ continue;
+ }
+ }
+ }
+
+ isc_interfaceiter_destroy(&iter);
+
+ /*
+ * phase 2 - delete gone interfaces - reassigning peers to
+ * other interfaces
+ */
+ for (ep = ep_list; ep != NULL; ep = next_ep) {
+ next_ep = ep->elink;
+
+ /*
+ * if phase does not match sys_phase this interface was
+ * not enumerated during the last interface scan - so it
+ * is gone and will be deleted here unless it did not
+ * originate from interface enumeration (INT_WILDCARD,
+ * INT_MCASTIF).
+ */
+ if (((INT_WILDCARD | INT_MCASTIF) & ep->flags) ||
+ ep->phase == sys_interphase)
+ continue;
+
+ DPRINT_INTERFACE(3, (ep, "updating ",
+ "GONE - deleting\n"));
+ remove_interface(ep);
+
+ ifi.action = IFS_DELETED;
+ ifi.ep = ep;
+ if (receiver != NULL)
+ (*receiver)(data, &ifi);
+
+ /* disconnect peers from deleted endpt. */
+ while (ep->peers != NULL)
+ set_peerdstadr(ep->peers, NULL);
+
+ /*
+ * update globals in case we lose
+ * a loopback interface
+ */
+ if (ep == loopback_interface)
+ loopback_interface = NULL;
+
+ delete_interface(ep);
+ }
+
+ /*
+ * phase 3 - re-configure as the world has possibly changed
+ *
+ * never ever make this conditional again - it is needed to track
+ * routing updates. see bug #2506
+ */
+ refresh_all_peerinterfaces();
+
+ if (broadcast_client_enabled)
+ io_setbclient();
+
+ if (sys_bclient)
+ io_setbclient();
+
+#ifdef MCAST
+ /*
+ * Check multicast interfaces and try to join multicast groups if
+ * not joined yet.
+ */
+ for (ep = ep_list; ep != NULL; ep = ep->elink) {
+ remaddr_t *entry;
+
+ if (!(INT_MCASTIF & ep->flags) || (INT_MCASTOPEN & ep->flags))
+ continue;
+
+ /* Find remote address that was linked to this interface */
+ for (entry = remoteaddr_list;
+ entry != NULL;
+ entry = entry->link) {
+ if (entry->ep == ep) {
+ if (socket_multicast_enable(ep, &entry->addr)) {
+ msyslog(LOG_INFO,
+ "Joined %s socket to multicast group %s",
+ stoa(&ep->sin),
+ stoa(&entry->addr));
+ }
+ break;
+ }
+ }
+ }
+#endif /* MCAST */
+
+ return new_interface_found;
+}
+
+
+/*
+ * create_sockets - create a socket for each interface plus a default
+ * socket for when we don't know where to send
+ */
+static int
+create_sockets(
+ u_short port
+ )
+{
+#ifndef HAVE_IO_COMPLETION_PORT
+ /*
+ * I/O Completion Ports don't care about the select and FD_SET
+ */
+ maxactivefd = 0;
+ FD_ZERO(&activefds);
+#endif
+
+ DPRINTF(2, ("create_sockets(%d)\n", port));
+
+ create_wildcards(port);
+
+ update_interfaces(port, NULL, NULL);
+
+ /*
+ * Now that we have opened all the sockets, turn off the reuse
+ * flag for security.
+ */
+ set_reuseaddr(0);
+
+ DPRINTF(2, ("create_sockets: Total interfaces = %d\n", ninterfaces));
+
+ return ninterfaces;
+}
+
+/*
+ * create_interface - create a new interface for a given prototype
+ * binding the socket.
+ */
+static struct interface *
+create_interface(
+ u_short port,
+ struct interface * protot
+ )
+{
+ sockaddr_u resmask;
+ endpt * iface;
+#if defined(MCAST) && defined(MULTICAST_NONEWSOCKET)
+ remaddr_t * entry;
+ remaddr_t * next_entry;
+#endif
+ DPRINTF(2, ("create_interface(%s#%d)\n", stoa(&protot->sin),
+ port));
+
+ /* build an interface */
+ iface = new_interface(protot);
+
+ /*
+ * create socket
+ */
+ iface->fd = open_socket(&iface->sin, 0, 0, iface);
+
+ if (iface->fd != INVALID_SOCKET)
+ log_listen_address(iface);
+
+ if ((INT_BROADCAST & iface->flags)
+ && iface->bfd != INVALID_SOCKET)
+ msyslog(LOG_INFO, "Listening on broadcast address %s#%d",
+ stoa((&iface->bcast)), port);
+
+ if (INVALID_SOCKET == iface->fd
+ && INVALID_SOCKET == iface->bfd) {
+ msyslog(LOG_ERR, "unable to create socket on %s (%d) for %s#%d",
+ iface->name,
+ iface->ifnum,
+ stoa((&iface->sin)),
+ port);
+ delete_interface(iface);
+ return NULL;
+ }
+
+ /*
+ * Blacklist our own addresses, no use talking to ourself
+ */
+ SET_HOSTMASK(&resmask, AF(&iface->sin));
+ hack_restrict(RESTRICT_FLAGS, &iface->sin, &resmask,
+ -4, RESM_NTPONLY | RESM_INTERFACE, RES_IGNORE, 0);
+
+ /*
+ * set globals with the first found
+ * loopback interface of the appropriate class
+ */
+ if (NULL == loopback_interface && AF_INET == iface->family
+ && (INT_LOOPBACK & iface->flags))
+ loopback_interface = iface;
+
+ /*
+ * put into our interface list
+ */
+ add_addr_to_list(&iface->sin, iface);
+ add_interface(iface);
+
+#if defined(MCAST) && defined(MULTICAST_NONEWSOCKET)
+ /*
+ * Join any previously-configured compatible multicast groups.
+ */
+ if (INT_MULTICAST & iface->flags &&
+ !((INT_LOOPBACK | INT_WILDCARD) & iface->flags) &&
+ !iface->ignore_packets) {
+ for (entry = remoteaddr_list;
+ entry != NULL;
+ entry = next_entry) {
+ next_entry = entry->link;
+ if (AF(&iface->sin) != AF(&entry->addr) ||
+ !IS_MCAST(&entry->addr))
+ continue;
+ if (socket_multicast_enable(iface,
+ &entry->addr))
+ msyslog(LOG_INFO,
+ "Joined %s socket to multicast group %s",
+ stoa(&iface->sin),
+ stoa(&entry->addr));
+ else
+ msyslog(LOG_ERR,
+ "Failed to join %s socket to multicast group %s",
+ stoa(&iface->sin),
+ stoa(&entry->addr));
+ }
+ }
+#endif /* MCAST && MCAST_NONEWSOCKET */
+
+ DPRINT_INTERFACE(2, (iface, "created ", "\n"));
+ return iface;
+}
+
+
+#ifdef SO_EXCLUSIVEADDRUSE
+static void
+set_excladdruse(
+ SOCKET fd
+ )
+{
+ int one = 1;
+ int failed;
+#ifdef SYS_WINNT
+ DWORD err;
+#endif
+
+ failed = setsockopt(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE,
+ (void *)&one, sizeof(one));
+
+ if (!failed)
+ return;
+
+#ifdef SYS_WINNT
+ /*
+ * Prior to Windows XP setting SO_EXCLUSIVEADDRUSE can fail with
+ * error WSAINVAL depending on service pack level and whether
+ * the user account is in the Administrators group. Do not
+ * complain if it fails that way on versions prior to XP (5.1).
+ */
+ err = GetLastError();
+
+ if (isc_win32os_versioncheck(5, 1, 0, 0) < 0 /* < 5.1/XP */
+ && WSAEINVAL == err)
+ return;
+
+ SetLastError(err);
+#endif
+ msyslog(LOG_ERR,
+ "setsockopt(%d, SO_EXCLUSIVEADDRUSE, on): %m",
+ (int)fd);
+}
+#endif /* SO_EXCLUSIVEADDRUSE */
+
+
+/*
+ * set_reuseaddr() - set/clear REUSEADDR on all sockets
+ * NB possible hole - should we be doing this on broadcast
+ * fd's also?
+ */
+static void
+set_reuseaddr(
+ int flag
+ )
+{
+#ifndef SO_EXCLUSIVEADDRUSE
+ endpt *ep;
+
+ for (ep = ep_list; ep != NULL; ep = ep->elink) {
+ if (ep->flags & INT_WILDCARD)
+ continue;
+
+ /*
+ * if ep->fd is INVALID_SOCKET, we might have a adapter
+ * configured but not present
+ */
+ DPRINTF(4, ("setting SO_REUSEADDR on %.16s@%s to %s\n",
+ ep->name, stoa(&ep->sin),
+ flag ? "on" : "off"));
+
+ if (ep->fd != INVALID_SOCKET) {
+ if (setsockopt(ep->fd, SOL_SOCKET, SO_REUSEADDR,
+ (void *)&flag, sizeof(flag))) {
+ msyslog(LOG_ERR, "set_reuseaddr: setsockopt(%s, SO_REUSEADDR, %s) failed: %m",
+ stoa(&ep->sin), flag ? "on" : "off");
+ }
+ }
+ }
+#endif /* ! SO_EXCLUSIVEADDRUSE */
+}
+
+/*
+ * This is just a wrapper around an internal function so we can
+ * make other changes as necessary later on
+ */
+void
+enable_broadcast(
+ struct interface * iface,
+ sockaddr_u * baddr
+ )
+{
+#ifdef OPEN_BCAST_SOCKET
+ socket_broadcast_enable(iface, iface->fd, baddr);
+#endif
+}
+
+#ifdef OPEN_BCAST_SOCKET
+/*
+ * Enable a broadcast address to a given socket
+ * The socket is in the ep_list all we need to do is enable
+ * broadcasting. It is not this function's job to select the socket
+ */
+static isc_boolean_t
+socket_broadcast_enable(
+ struct interface * iface,
+ SOCKET fd,
+ sockaddr_u * baddr
+ )
+{
+#ifdef SO_BROADCAST
+ int on = 1;
+
+ if (IS_IPV4(baddr)) {
+ /* if this interface can support broadcast, set SO_BROADCAST */
+ if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST,
+ (void *)&on, sizeof(on)))
+ msyslog(LOG_ERR,
+ "setsockopt(SO_BROADCAST) enable failure on address %s: %m",
+ stoa(baddr));
+ else
+ DPRINTF(2, ("Broadcast enabled on socket %d for address %s\n",
+ fd, stoa(baddr)));
+ }
+ iface->flags |= INT_BCASTXMIT;
+ return ISC_TRUE;
+#else
+ return ISC_FALSE;
+#endif /* SO_BROADCAST */
+}
+
+#ifdef OS_MISSES_SPECIFIC_ROUTE_UPDATES
+/*
+ * Remove a broadcast address from a given socket
+ * The socket is in the ep_list all we need to do is disable
+ * broadcasting. It is not this function's job to select the socket
+ */
+static isc_boolean_t
+socket_broadcast_disable(
+ struct interface * iface,
+ sockaddr_u * baddr
+ )
+{
+#ifdef SO_BROADCAST
+ int off = 0; /* This seems to be OK as an int */
+
+ if (IS_IPV4(baddr) && setsockopt(iface->fd, SOL_SOCKET,
+ SO_BROADCAST, (void *)&off, sizeof(off)))
+ msyslog(LOG_ERR,
+ "setsockopt(SO_BROADCAST) disable failure on address %s: %m",
+ stoa(baddr));
+
+ iface->flags &= ~INT_BCASTXMIT;
+ return ISC_TRUE;
+#else
+ return ISC_FALSE;
+#endif /* SO_BROADCAST */
+}
+#endif /* OS_MISSES_SPECIFIC_ROUTE_UPDATES */
+
+#endif /* OPEN_BCAST_SOCKET */
+
+/*
+ * return the broadcast client flag value
+ */
+isc_boolean_t
+get_broadcastclient_flag(void)
+{
+ return (broadcast_client_enabled);
+}
+
+/*
+ * Check to see if the address is a multicast address
+ */
+static isc_boolean_t
+addr_ismulticast(
+ sockaddr_u *maddr
+ )
+{
+ isc_boolean_t result;
+
+#ifndef INCLUDE_IPV6_MULTICAST_SUPPORT
+ /*
+ * If we don't have IPV6 support any IPV6 addr is not multicast
+ */
+ if (IS_IPV6(maddr))
+ result = ISC_FALSE;
+ else
+#endif
+ result = IS_MCAST(maddr);
+
+ if (!result)
+ DPRINTF(4, ("address %s is not multicast\n",
+ stoa(maddr)));
+
+ return result;
+}
+
+/*
+ * Multicast servers need to set the appropriate Multicast interface
+ * socket option in order for it to know which interface to use for
+ * send the multicast packet.
+ */
+void
+enable_multicast_if(
+ struct interface * iface,
+ sockaddr_u * maddr
+ )
+{
+#ifdef MCAST
+#ifdef IP_MULTICAST_LOOP
+ TYPEOF_IP_MULTICAST_LOOP off = 0;
+#endif
+#if defined(INCLUDE_IPV6_MULTICAST_SUPPORT) && defined(IPV6_MULTICAST_LOOP)
+ u_int off6 = 0;
+#endif
+
+ REQUIRE(AF(maddr) == AF(&iface->sin));
+
+ switch (AF(&iface->sin)) {
+
+ case AF_INET:
+#ifdef IP_MULTICAST_LOOP
+ /*
+ * Don't send back to itself, but allow failure to set
+ */
+ if (setsockopt(iface->fd, IPPROTO_IP,
+ IP_MULTICAST_LOOP,
+ (void *)&off,
+ sizeof(off))) {
+
+ msyslog(LOG_ERR,
+ "setsockopt IP_MULTICAST_LOOP failed: %m on socket %d, addr %s for multicast address %s",
+ iface->fd, stoa(&iface->sin),
+ stoa(maddr));
+ }
+#endif
+ break;
+
+ case AF_INET6:
+#ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
+#ifdef IPV6_MULTICAST_LOOP
+ /*
+ * Don't send back to itself, but allow failure to set
+ */
+ if (setsockopt(iface->fd, IPPROTO_IPV6,
+ IPV6_MULTICAST_LOOP,
+ (void *) &off6, sizeof(off6))) {
+
+ msyslog(LOG_ERR,
+ "setsockopt IPV6_MULTICAST_LOOP failed: %m on socket %d, addr %s for multicast address %s",
+ iface->fd, stoa(&iface->sin),
+ stoa(maddr));
+ }
+#endif
+ break;
+#else
+ return;
+#endif /* INCLUDE_IPV6_MULTICAST_SUPPORT */
+ }
+ return;
+#endif
+}
+
+/*
+ * Add a multicast address to a given socket
+ * The socket is in the ep_list all we need to do is enable
+ * multicasting. It is not this function's job to select the socket
+ */
+#if defined(MCAST)
+static isc_boolean_t
+socket_multicast_enable(
+ endpt * iface,
+ sockaddr_u * maddr
+ )
+{
+ struct ip_mreq mreq;
+# ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
+ struct ipv6_mreq mreq6;
+# endif
+ switch (AF(maddr)) {
+
+ case AF_INET:
+ ZERO(mreq);
+ mreq.imr_multiaddr = SOCK_ADDR4(maddr);
+ mreq.imr_interface.s_addr = htonl(INADDR_ANY);
+ if (setsockopt(iface->fd,
+ IPPROTO_IP,
+ IP_ADD_MEMBERSHIP,
+ (void *)&mreq,
+ sizeof(mreq))) {
+ DPRINTF(2, (
+ "setsockopt IP_ADD_MEMBERSHIP failed: %m on socket %d, addr %s for %x / %x (%s)",
+ iface->fd, stoa(&iface->sin),
+ mreq.imr_multiaddr.s_addr,
+ mreq.imr_interface.s_addr,
+ stoa(maddr)));
+ return ISC_FALSE;
+ }
+ DPRINTF(4, ("Added IPv4 multicast membership on socket %d, addr %s for %x / %x (%s)\n",
+ iface->fd, stoa(&iface->sin),
+ mreq.imr_multiaddr.s_addr,
+ mreq.imr_interface.s_addr, stoa(maddr)));
+ break;
+
+ case AF_INET6:
+# ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
+ /*
+ * Enable reception of multicast packets.
+ * If the address is link-local we can get the
+ * interface index from the scope id. Don't do this
+ * for other types of multicast addresses. For now let
+ * the kernel figure it out.
+ */
+ ZERO(mreq6);
+ mreq6.ipv6mr_multiaddr = SOCK_ADDR6(maddr);
+ mreq6.ipv6mr_interface = iface->ifindex;
+
+ if (setsockopt(iface->fd, IPPROTO_IPV6,
+ IPV6_JOIN_GROUP, (void *)&mreq6,
+ sizeof(mreq6))) {
+ DPRINTF(2, (
+ "setsockopt IPV6_JOIN_GROUP failed: %m on socket %d, addr %s for interface %u (%s)",
+ iface->fd, stoa(&iface->sin),
+ mreq6.ipv6mr_interface, stoa(maddr)));
+ return ISC_FALSE;
+ }
+ DPRINTF(4, ("Added IPv6 multicast group on socket %d, addr %s for interface %u (%s)\n",
+ iface->fd, stoa(&iface->sin),
+ mreq6.ipv6mr_interface, stoa(maddr)));
+# else
+ return ISC_FALSE;
+# endif /* INCLUDE_IPV6_MULTICAST_SUPPORT */
+ }
+ iface->flags |= INT_MCASTOPEN;
+ iface->num_mcast++;
+
+ return ISC_TRUE;
+}
+#endif /* MCAST */
+
+
+/*
+ * Remove a multicast address from a given socket
+ * The socket is in the ep_list all we need to do is disable
+ * multicasting. It is not this function's job to select the socket
+ */
+#ifdef MCAST
+static isc_boolean_t
+socket_multicast_disable(
+ struct interface * iface,
+ sockaddr_u * maddr
+ )
+{
+# ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
+ struct ipv6_mreq mreq6;
+# endif
+ struct ip_mreq mreq;
+
+ ZERO(mreq);
+
+ if (find_addr_in_list(maddr) == NULL) {
+ DPRINTF(4, ("socket_multicast_disable(%s): not found\n",
+ stoa(maddr)));
+ return ISC_TRUE;
+ }
+
+ switch (AF(maddr)) {
+
+ case AF_INET:
+ mreq.imr_multiaddr = SOCK_ADDR4(maddr);
+ mreq.imr_interface = SOCK_ADDR4(&iface->sin);
+ if (setsockopt(iface->fd, IPPROTO_IP,
+ IP_DROP_MEMBERSHIP, (void *)&mreq,
+ sizeof(mreq))) {
+
+ msyslog(LOG_ERR,
+ "setsockopt IP_DROP_MEMBERSHIP failed: %m on socket %d, addr %s for %x / %x (%s)",
+ iface->fd, stoa(&iface->sin),
+ SRCADR(maddr), SRCADR(&iface->sin),
+ stoa(maddr));
+ return ISC_FALSE;
+ }
+ break;
+ case AF_INET6:
+# ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
+ /*
+ * Disable reception of multicast packets
+ * If the address is link-local we can get the
+ * interface index from the scope id. Don't do this
+ * for other types of multicast addresses. For now let
+ * the kernel figure it out.
+ */
+ mreq6.ipv6mr_multiaddr = SOCK_ADDR6(maddr);
+ mreq6.ipv6mr_interface = iface->ifindex;
+
+ if (setsockopt(iface->fd, IPPROTO_IPV6,
+ IPV6_LEAVE_GROUP, (void *)&mreq6,
+ sizeof(mreq6))) {
+
+ msyslog(LOG_ERR,
+ "setsockopt IPV6_LEAVE_GROUP failure: %m on socket %d, addr %s for %d (%s)",
+ iface->fd, stoa(&iface->sin),
+ iface->ifindex, stoa(maddr));
+ return ISC_FALSE;
+ }
+ break;
+# else
+ return ISC_FALSE;
+# endif /* INCLUDE_IPV6_MULTICAST_SUPPORT */
+ }
+
+ iface->num_mcast--;
+ if (!iface->num_mcast)
+ iface->flags &= ~INT_MCASTOPEN;
+
+ return ISC_TRUE;
+}
+#endif /* MCAST */
+
+/*
+ * io_setbclient - open the broadcast client sockets
+ */
+void
+io_setbclient(void)
+{
+#ifdef OPEN_BCAST_SOCKET
+ struct interface * interf;
+ unsigned int nif;
+
+ nif = 0;
+ set_reuseaddr(1);
+
+ for (interf = ep_list;
+ interf != NULL;
+ interf = interf->elink) {
+
+ if (interf->flags & (INT_WILDCARD | INT_LOOPBACK))
+ continue;
+
+ /* use only allowed addresses */
+ if (interf->ignore_packets)
+ continue;
+
+ /* Need a broadcast-capable interface */
+ if (!(interf->flags & INT_BROADCAST))
+ continue;
+
+ /* Only IPv4 addresses are valid for broadcast */
+ REQUIRE(IS_IPV4(&interf->bcast));
+
+ /* Do we already have the broadcast address open? */
+ if (interf->flags & INT_BCASTOPEN) {
+ /*
+ * account for already open interfaces to avoid
+ * misleading warning below
+ */
+ nif++;
+ continue;
+ }
+
+ /*
+ * Try to open the broadcast address
+ */
+ interf->family = AF_INET;
+ interf->bfd = open_socket(&interf->bcast, 1, 0, interf);
+
+ /*
+ * If we succeeded then we use it otherwise enable
+ * broadcast on the interface address
+ */
+ if (interf->bfd != INVALID_SOCKET) {
+ nif++;
+ interf->flags |= INT_BCASTOPEN;
+ msyslog(LOG_INFO,
+ "Listen for broadcasts to %s on interface #%d %s",
+ stoa(&interf->bcast), interf->ifnum, interf->name);
+ } else switch (errno) {
+ /* Silently ignore EADDRINUSE as we probably
+ * opened the socket already for an address in
+ * the same network */
+ case EADDRINUSE:
+ /* Some systems cannot bind a socket to a broadcast
+ * address, as that is not a valid host address. */
+ case EADDRNOTAVAIL:
+# ifdef SYS_WINNT /*TODO: use for other systems, too? */
+ /* avoid recurrence here -- if we already have a
+ * regular socket, it's quite useless to try this
+ * again.
+ */
+ if (interf->fd != INVALID_SOCKET) {
+ interf->flags |= INT_BCASTOPEN;
+ nif++;
+ }
+# endif
+ break;
+
+ default:
+ msyslog(LOG_INFO,
+ "failed to listen for broadcasts to %s on interface #%d %s",
+ stoa(&interf->bcast), interf->ifnum, interf->name);
+ break;
+ }
+ }
+ set_reuseaddr(0);
+ if (nif != 0) {
+ broadcast_client_enabled = ISC_TRUE;
+ DPRINTF(1, ("io_setbclient: listening to %d broadcast addresses\n", nif));
+ } else {
+ broadcast_client_enabled = ISC_FALSE;
+ msyslog(LOG_ERR,
+ "Unable to listen for broadcasts, no broadcast interfaces available");
+ }
+#else
+ msyslog(LOG_ERR,
+ "io_setbclient: Broadcast Client disabled by build");
+#endif /* OPEN_BCAST_SOCKET */
+}
+
+/*
+ * io_unsetbclient - close the broadcast client sockets
+ */
+void
+io_unsetbclient(void)
+{
+ endpt *ep;
+
+ for (ep = ep_list; ep != NULL; ep = ep->elink) {
+ if (INT_WILDCARD & ep->flags)
+ continue;
+ if (!(INT_BCASTOPEN & ep->flags))
+ continue;
+
+ if (ep->bfd != INVALID_SOCKET) {
+ /* destroy broadcast listening socket */
+ msyslog(LOG_INFO,
+ "stop listening for broadcasts to %s on interface #%d %s",
+ stoa(&ep->bcast), ep->ifnum, ep->name);
+# ifdef HAVE_IO_COMPLETION_PORT
+ io_completion_port_remove_socket(ep->bfd, ep);
+# endif
+ close_and_delete_fd_from_list(ep->bfd);
+ ep->bfd = INVALID_SOCKET;
+ }
+ ep->flags &= ~INT_BCASTOPEN;
+ }
+ broadcast_client_enabled = ISC_FALSE;
+}
+
+/*
+ * io_multicast_add() - add multicast group address
+ */
+void
+io_multicast_add(
+ sockaddr_u *addr
+ )
+{
+#ifdef MCAST
+ endpt * ep;
+ endpt * one_ep;
+
+ /*
+ * Check to see if this is a multicast address
+ */
+ if (!addr_ismulticast(addr))
+ return;
+
+ /* If we already have it we can just return */
+ if (NULL != find_flagged_addr_in_list(addr, INT_MCASTOPEN)) {
+ msyslog(LOG_INFO,
+ "Duplicate request found for multicast address %s",
+ stoa(addr));
+ return;
+ }
+
+# ifndef MULTICAST_NONEWSOCKET
+ ep = new_interface(NULL);
+
+ /*
+ * Open a new socket for the multicast address
+ */
+ ep->sin = *addr;
+ SET_PORT(&ep->sin, NTP_PORT);
+ ep->family = AF(&ep->sin);
+ AF(&ep->mask) = ep->family;
+ SET_ONESMASK(&ep->mask);
+
+ set_reuseaddr(1);
+ ep->bfd = INVALID_SOCKET;
+ ep->fd = open_socket(&ep->sin, 0, 0, ep);
+ if (ep->fd != INVALID_SOCKET) {
+ ep->ignore_packets = ISC_FALSE;
+ ep->flags |= INT_MCASTIF;
+ ep->ifindex = SCOPE(addr);
+
+ strlcpy(ep->name, "multicast", sizeof(ep->name));
+ DPRINT_INTERFACE(2, (ep, "multicast add ", "\n"));
+ add_interface(ep);
+ log_listen_address(ep);
+ } else {
+ /* bind failed, re-use wildcard interface */
+ delete_interface(ep);
+
+ if (IS_IPV4(addr))
+ ep = wildipv4;
+ else if (IS_IPV6(addr))
+ ep = wildipv6;
+ else
+ ep = NULL;
+
+ if (ep != NULL) {
+ /* HACK ! -- stuff in an address */
+ /* because we don't bind addr? DH */
+ ep->bcast = *addr;
+ msyslog(LOG_ERR,
+ "multicast address %s using wildcard interface #%d %s",
+ stoa(addr), ep->ifnum, ep->name);
+ } else {
+ msyslog(LOG_ERR,
+ "No multicast socket available to use for address %s",
+ stoa(addr));
+ return;
+ }
+ }
+ { /* in place of the { following for in #else clause */
+ one_ep = ep;
+# else /* MULTICAST_NONEWSOCKET follows */
+ /*
+ * For the case where we can't use a separate socket (Windows)
+ * join each applicable endpoint socket to the group address.
+ */
+ if (IS_IPV4(addr))
+ one_ep = wildipv4;
+ else
+ one_ep = wildipv6;
+ for (ep = ep_list; ep != NULL; ep = ep->elink) {
+ if (ep->ignore_packets || AF(&ep->sin) != AF(addr) ||
+ !(INT_MULTICAST & ep->flags) ||
+ (INT_LOOPBACK | INT_WILDCARD) & ep->flags)
+ continue;
+ one_ep = ep;
+# endif /* MULTICAST_NONEWSOCKET */
+ if (socket_multicast_enable(ep, addr))
+ msyslog(LOG_INFO,
+ "Joined %s socket to multicast group %s",
+ stoa(&ep->sin),
+ stoa(addr));
+ }
+
+ add_addr_to_list(addr, one_ep);
+#else /* !MCAST follows*/
+ msyslog(LOG_ERR,
+ "Can not add multicast address %s: no multicast support",
+ stoa(addr));
+#endif
+ return;
+}
+
+
+/*
+ * io_multicast_del() - delete multicast group address
+ */
+void
+io_multicast_del(
+ sockaddr_u * addr
+ )
+{
+#ifdef MCAST
+ endpt *iface;
+
+ /*
+ * Check to see if this is a multicast address
+ */
+ if (!addr_ismulticast(addr)) {
+ msyslog(LOG_ERR, "invalid multicast address %s",
+ stoa(addr));
+ return;
+ }
+
+ /*
+ * Disable reception of multicast packets
+ */
+ while ((iface = find_flagged_addr_in_list(addr, INT_MCASTOPEN))
+ != NULL)
+ socket_multicast_disable(iface, addr);
+
+ delete_addr_from_list(addr);
+
+#else /* not MCAST */
+ msyslog(LOG_ERR,
+ "Can not delete multicast address %s: no multicast support",
+ stoa(addr));
+#endif /* not MCAST */
+}
+
+
+/*
+ * open_socket - open a socket, returning the file descriptor
+ */
+
+static SOCKET
+open_socket(
+ sockaddr_u * addr,
+ int bcast,
+ int turn_off_reuse,
+ endpt * interf
+ )
+{
+ SOCKET fd;
+ int errval;
+ /*
+ * int is OK for REUSEADR per
+ * http://www.kohala.com/start/mcast.api.txt
+ */
+ int on = 1;
+ int off = 0;
+
+ if (IS_IPV6(addr) && !ipv6_works)
+ return INVALID_SOCKET;
+
+ /* create a datagram (UDP) socket */
+ fd = socket(AF(addr), SOCK_DGRAM, 0);
+ if (INVALID_SOCKET == fd) {
+ errval = socket_errno();
+ msyslog(LOG_ERR,
+ "socket(AF_INET%s, SOCK_DGRAM, 0) failed on address %s: %m",
+ IS_IPV6(addr) ? "6" : "", stoa(addr));
+
+ if (errval == EPROTONOSUPPORT ||
+ errval == EAFNOSUPPORT ||
+ errval == EPFNOSUPPORT)
+ return (INVALID_SOCKET);
+
+ errno = errval;
+ msyslog(LOG_ERR,
+ "unexpected socket() error %m code %d (not EPROTONOSUPPORT nor EAFNOSUPPORT nor EPFNOSUPPORT) - exiting",
+ errno);
+ exit(1);
+ }
+
+#ifdef SYS_WINNT
+ connection_reset_fix(fd, addr);
+#endif
+ /*
+ * Fixup the file descriptor for some systems
+ * See bug #530 for details of the issue.
+ */
+ fd = move_fd(fd);
+
+ /*
+ * set SO_REUSEADDR since we will be binding the same port
+ * number on each interface according to turn_off_reuse.
+ * This is undesirable on Windows versions starting with
+ * Windows XP (numeric version 5.1).
+ */
+#ifdef SYS_WINNT
+ if (isc_win32os_versioncheck(5, 1, 0, 0) < 0) /* before 5.1 */
+#endif
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
+ (void *)((turn_off_reuse)
+ ? &off
+ : &on),
+ sizeof(on))) {
+
+ msyslog(LOG_ERR,
+ "setsockopt SO_REUSEADDR %s fails for address %s: %m",
+ (turn_off_reuse)
+ ? "off"
+ : "on",
+ stoa(addr));
+ closesocket(fd);
+ return INVALID_SOCKET;
+ }
+#ifdef SO_EXCLUSIVEADDRUSE
+ /*
+ * setting SO_EXCLUSIVEADDRUSE on the wildcard we open
+ * first will cause more specific binds to fail.
+ */
+ if (!(interf->flags & INT_WILDCARD))
+ set_excladdruse(fd);
+#endif
+
+ /*
+ * IPv4 specific options go here
+ */
+ if (IS_IPV4(addr)) {
+#if defined(IPPROTO_IP) && defined(IP_TOS)
+ if (setsockopt(fd, IPPROTO_IP, IP_TOS, (void *)&qos,
+ sizeof(qos)))
+ msyslog(LOG_ERR,
+ "setsockopt IP_TOS (%02x) fails on address %s: %m",
+ qos, stoa(addr));
+#endif /* IPPROTO_IP && IP_TOS */
+ if (bcast)
+ socket_broadcast_enable(interf, fd, addr);
+ }
+
+ /*
+ * IPv6 specific options go here
+ */
+ if (IS_IPV6(addr)) {
+#if defined(IPPROTO_IPV6) && defined(IPV6_TCLASS)
+ if (setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, (void *)&qos,
+ sizeof(qos)))
+ msyslog(LOG_ERR,
+ "setsockopt IPV6_TCLASS (%02x) fails on address %s: %m",
+ qos, stoa(addr));
+#endif /* IPPROTO_IPV6 && IPV6_TCLASS */
+#ifdef IPV6_V6ONLY
+ if (isc_net_probe_ipv6only() == ISC_R_SUCCESS
+ && setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY,
+ (void *)&on, sizeof(on)))
+ msyslog(LOG_ERR,
+ "setsockopt IPV6_V6ONLY on fails on address %s: %m",
+ stoa(addr));
+#endif
+#ifdef IPV6_BINDV6ONLY
+ if (setsockopt(fd, IPPROTO_IPV6, IPV6_BINDV6ONLY,
+ (void *)&on, sizeof(on)))
+ msyslog(LOG_ERR,
+ "setsockopt IPV6_BINDV6ONLY on fails on address %s: %m",
+ stoa(addr));
+#endif
+ }
+
+#ifdef OS_NEEDS_REUSEADDR_FOR_IFADDRBIND
+ /*
+ * some OSes don't allow binding to more specific
+ * addresses if a wildcard address already bound
+ * to the port and SO_REUSEADDR is not set
+ */
+ if (!is_wildcard_addr(addr))
+ set_wildcard_reuse(AF(addr), 1);
+#endif
+
+ /*
+ * bind the local address.
+ */
+ errval = bind(fd, &addr->sa, SOCKLEN(addr));
+
+#ifdef OS_NEEDS_REUSEADDR_FOR_IFADDRBIND
+ if (!is_wildcard_addr(addr))
+ set_wildcard_reuse(AF(addr), 0);
+#endif
+
+ if (errval < 0) {
+ /*
+ * Don't log this under all conditions
+ */
+ if (turn_off_reuse == 0
+#ifdef DEBUG
+ || debug > 1
+#endif
+ ) {
+ msyslog(LOG_ERR,
+ "bind(%d) AF_INET%s %s#%d%s flags 0x%x failed: %m",
+ fd, IS_IPV6(addr) ? "6" : "",
+ stoa(addr), SRCPORT(addr),
+ IS_MCAST(addr) ? " (multicast)" : "",
+ interf->flags);
+ }
+
+ closesocket(fd);
+
+ return INVALID_SOCKET;
+ }
+
+#ifdef HAVE_TIMESTAMP
+ {
+ if (setsockopt(fd, SOL_SOCKET, SO_TIMESTAMP,
+ (void *)&on, sizeof(on)))
+ msyslog(LOG_DEBUG,
+ "setsockopt SO_TIMESTAMP on fails on address %s: %m",
+ stoa(addr));
+ else
+ DPRINTF(4, ("setsockopt SO_TIMESTAMP enabled on fd %d address %s\n",
+ fd, stoa(addr)));
+ }
+#endif
+#ifdef HAVE_TIMESTAMPNS
+ {
+ if (setsockopt(fd, SOL_SOCKET, SO_TIMESTAMPNS,
+ (void *)&on, sizeof(on)))
+ msyslog(LOG_DEBUG,
+ "setsockopt SO_TIMESTAMPNS on fails on address %s: %m",
+ stoa(addr));
+ else
+ DPRINTF(4, ("setsockopt SO_TIMESTAMPNS enabled on fd %d address %s\n",
+ fd, stoa(addr)));
+ }
+#endif
+#ifdef HAVE_BINTIME
+ {
+ if (setsockopt(fd, SOL_SOCKET, SO_BINTIME,
+ (void *)&on, sizeof(on)))
+ msyslog(LOG_DEBUG,
+ "setsockopt SO_BINTIME on fails on address %s: %m",
+ stoa(addr));
+ else
+ DPRINTF(4, ("setsockopt SO_BINTIME enabled on fd %d address %s\n",
+ fd, stoa(addr)));
+ }
+#endif
+
+ DPRINTF(4, ("bind(%d) AF_INET%s, addr %s%%%d#%d, flags 0x%x\n",
+ fd, IS_IPV6(addr) ? "6" : "", stoa(addr),
+ SCOPE(addr), SRCPORT(addr), interf->flags));
+
+ make_socket_nonblocking(fd);
+
+#ifdef HAVE_SIGNALED_IO
+ init_socket_sig(fd);
+#endif /* not HAVE_SIGNALED_IO */
+
+ add_fd_to_list(fd, FD_TYPE_SOCKET);
+
+#if !defined(SYS_WINNT) && !defined(VMS)
+ DPRINTF(4, ("flags for fd %d: 0x%x\n", fd,
+ fcntl(fd, F_GETFL, 0)));
+#endif /* SYS_WINNT || VMS */
+
+#if defined(HAVE_IO_COMPLETION_PORT)
+/*
+ * Add the socket to the completion port
+ */
+ if (!io_completion_port_add_socket(fd, interf, bcast)) {
+ msyslog(LOG_ERR, "unable to set up io completion port - EXITING");
+ exit(1);
+ }
+#endif
+ return fd;
+}
+
+
+
+/* XXX ELIMINATE sendpkt similar in ntpq.c, ntpdc.c, ntp_io.c, ntptrace.c */
+/*
+ * sendpkt - send a packet to the specified destination. Maintain a
+ * send error cache so that only the first consecutive error for a
+ * destination is logged.
+ */
+void
+sendpkt(
+ sockaddr_u * dest,
+ struct interface * ep,
+ int ttl,
+ struct pkt * pkt,
+ int len
+ )
+{
+ endpt * src;
+ int ismcast;
+ int cc;
+ int rc;
+ u_char cttl;
+ l_fp fp_zero = { { 0 }, 0 };
+
+ ismcast = IS_MCAST(dest);
+ if (!ismcast)
+ src = ep;
+ else
+ src = (IS_IPV4(dest))
+ ? mc4_list
+ : mc6_list;
+
+ if (NULL == src) {
+ /*
+ * unbound peer - drop request and wait for better
+ * network conditions
+ */
+ DPRINTF(2, ("%ssendpkt(dst=%s, ttl=%d, len=%d): no interface - IGNORED\n",
+ ismcast ? "\tMCAST\t***** " : "",
+ stoa(dest), ttl, len));
+ return;
+ }
+
+ do {
+ DPRINTF(2, ("%ssendpkt(%d, dst=%s, src=%s, ttl=%d, len=%d)\n",
+ ismcast ? "\tMCAST\t***** " : "", src->fd,
+ stoa(dest), stoa(&src->sin), ttl, len));
+#ifdef MCAST
+ /*
+ * for the moment we use the bcast option to set multicast ttl
+ */
+ if (ismcast && ttl > 0 && ttl != src->last_ttl) {
+ /*
+ * set the multicast ttl for outgoing packets
+ */
+ switch (AF(&src->sin)) {
+
+ case AF_INET :
+ cttl = (u_char)ttl;
+ rc = setsockopt(src->fd, IPPROTO_IP,
+ IP_MULTICAST_TTL,
+ (void *)&cttl,
+ sizeof(cttl));
+ break;
+
+# ifdef INCLUDE_IPV6_SUPPORT
+ case AF_INET6 :
+ rc = setsockopt(src->fd, IPPROTO_IPV6,
+ IPV6_MULTICAST_HOPS,
+ (void *)&ttl,
+ sizeof(ttl));
+ break;
+# endif /* INCLUDE_IPV6_SUPPORT */
+
+ default:
+ rc = 0;
+ }
+
+ if (!rc)
+ src->last_ttl = ttl;
+ else
+ msyslog(LOG_ERR,
+ "setsockopt IP_MULTICAST_TTL/IPV6_MULTICAST_HOPS fails on address %s: %m",
+ stoa(&src->sin));
+ }
+#endif /* MCAST */
+
+#ifdef SIM
+ cc = simulate_server(dest, src, pkt);
+#elif defined(HAVE_IO_COMPLETION_PORT)
+ cc = io_completion_port_sendto(src, src->fd, pkt,
+ (size_t)len, (sockaddr_u *)&dest->sa);
+#else
+ cc = sendto(src->fd, (char *)pkt, (u_int)len, 0,
+ &dest->sa, SOCKLEN(dest));
+#endif
+ if (cc == -1) {
+ src->notsent++;
+ packets_notsent++;
+ } else {
+ src->sent++;
+ packets_sent++;
+ }
+ if (ismcast)
+ src = src->mclink;
+ } while (ismcast && src != NULL);
+
+ /* HMS: pkt->rootdisp is usually random here */
+ record_raw_stats(src ? &src->sin : NULL, dest,
+ &pkt->org, &pkt->rec, &pkt->xmt, &fp_zero,
+ PKT_MODE(pkt->li_vn_mode),
+ PKT_VERSION(pkt->li_vn_mode),
+ PKT_LEAP(pkt->li_vn_mode),
+ pkt->stratum,
+ pkt->ppoll, pkt->precision,
+ pkt->rootdelay, pkt->rootdisp, pkt->refid,
+ len - MIN_V4_PKT_LEN, (u_char *)&pkt->exten);
+
+ return;
+}
+
+
+#if !defined(HAVE_IO_COMPLETION_PORT)
+#if !defined(HAVE_SIGNALED_IO)
+/*
+ * fdbits - generate ascii representation of fd_set (FAU debug support)
+ * HFDF format - highest fd first.
+ */
+static char *
+fdbits(
+ int count,
+ const fd_set* set
+ )
+{
+ static char buffer[256];
+ char * buf = buffer;
+
+ count = min(count, 255);
+
+ while (count >= 0) {
+ *buf++ = FD_ISSET(count, set) ? '#' : '-';
+ count--;
+ }
+ *buf = '\0';
+
+ return buffer;
+}
+#endif
+
+#ifdef REFCLOCK
+/*
+ * Routine to read the refclock packets for a specific interface
+ * Return the number of bytes read. That way we know if we should
+ * read it again or go on to the next one if no bytes returned
+ */
+static inline int
+read_refclock_packet(
+ SOCKET fd,
+ struct refclockio * rp,
+ l_fp ts
+ )
+{
+ u_int read_count;
+ int buflen;
+ int saved_errno;
+ int consumed;
+ struct recvbuf * rb;
+
+ rb = get_free_recv_buffer();
+
+ if (NULL == rb) {
+ /*
+ * No buffer space available - just drop the packet
+ */
+ char buf[RX_BUFF_SIZE];
+
+ buflen = read(fd, buf, sizeof buf);
+ packets_dropped++;
+ return (buflen);
+ }
+
+ /* TALOS-CAN-0064: avoid signed/unsigned clashes that can lead
+ * to buffer overrun and memory corruption
+ */
+ if (rp->datalen <= 0 || (size_t)rp->datalen > sizeof(rb->recv_space))
+ read_count = sizeof(rb->recv_space);
+ else
+ read_count = (u_int)rp->datalen;
+ do {
+ buflen = read(fd, (char *)&rb->recv_space, read_count);
+ } while (buflen < 0 && EINTR == errno);
+
+ if (buflen <= 0) {
+ saved_errno = errno;
+ freerecvbuf(rb);
+ errno = saved_errno;
+ return buflen;
+ }
+
+ /*
+ * Got one. Mark how and when it got here,
+ * put it on the full list and do bookkeeping.
+ */
+ rb->recv_length = buflen;
+ rb->recv_peer = rp->srcclock;
+ rb->dstadr = 0;
+ rb->fd = fd;
+ rb->recv_time = ts;
+ rb->receiver = rp->clock_recv;
+
+ consumed = indicate_refclock_packet(rp, rb);
+ if (!consumed) {
+ rp->recvcount++;
+ packets_received++;
+ }
+
+ return buflen;
+}
+#endif /* REFCLOCK */
+
+
+#ifdef HAVE_PACKET_TIMESTAMP
+/*
+ * extract timestamps from control message buffer
+ */
+static l_fp
+fetch_timestamp(
+ struct recvbuf * rb,
+ struct msghdr * msghdr,
+ l_fp ts
+ )
+{
+ struct cmsghdr * cmsghdr;
+ unsigned long ticks;
+ double fuzz;
+ l_fp lfpfuzz;
+ l_fp nts;
+#ifdef DEBUG_TIMING
+ l_fp dts;
+#endif
+
+ cmsghdr = CMSG_FIRSTHDR(msghdr);
+ while (cmsghdr != NULL) {
+ switch (cmsghdr->cmsg_type)
+ {
+#ifdef HAVE_BINTIME
+ case SCM_BINTIME:
+#endif /* HAVE_BINTIME */
+#ifdef HAVE_TIMESTAMPNS
+ case SCM_TIMESTAMPNS:
+#endif /* HAVE_TIMESTAMPNS */
+#ifdef HAVE_TIMESTAMP
+ case SCM_TIMESTAMP:
+#endif /* HAVE_TIMESTAMP */
+#if defined(HAVE_BINTIME) || defined (HAVE_TIMESTAMPNS) || defined(HAVE_TIMESTAMP)
+ switch (cmsghdr->cmsg_type)
+ {
+#ifdef HAVE_BINTIME
+ case SCM_BINTIME:
+ {
+ struct bintime pbt;
+ memcpy(&pbt, CMSG_DATA(cmsghdr), sizeof(pbt));
+ /*
+ * bintime documentation is at http://phk.freebsd.dk/pubs/timecounter.pdf
+ */
+ nts.l_i = pbt.sec + JAN_1970;
+ nts.l_uf = (u_int32)(pbt.frac >> 32);
+ if (sys_tick > measured_tick &&
+ sys_tick > 1e-9) {
+ ticks = (unsigned long)(nts.l_uf / (unsigned long)(sys_tick * FRAC));
+ nts.l_uf = (unsigned long)(ticks * (unsigned long)(sys_tick * FRAC));
+ }
+ DPRINTF(4, ("fetch_timestamp: system bintime network time stamp: %ld.%09lu\n",
+ pbt.sec, (unsigned long)((nts.l_uf / FRAC) * 1e9)));
+ }
+ break;
+#endif /* HAVE_BINTIME */
+#ifdef HAVE_TIMESTAMPNS
+ case SCM_TIMESTAMPNS:
+ {
+ struct timespec pts;
+ memcpy(&pts, CMSG_DATA(cmsghdr), sizeof(pts));
+ if (sys_tick > measured_tick &&
+ sys_tick > 1e-9) {
+ ticks = (unsigned long)((pts.tv_nsec * 1e-9) /
+ sys_tick);
+ pts.tv_nsec = (long)(ticks * 1e9 *
+ sys_tick);
+ }
+ DPRINTF(4, ("fetch_timestamp: system nsec network time stamp: %ld.%09ld\n",
+ pts.tv_sec, pts.tv_nsec));
+ nts = tspec_stamp_to_lfp(pts);
+ }
+ break;
+#endif /* HAVE_TIMESTAMPNS */
+#ifdef HAVE_TIMESTAMP
+ case SCM_TIMESTAMP:
+ {
+ struct timeval ptv;
+ memcpy(&ptv, CMSG_DATA(cmsghdr), sizeof(ptv));
+ if (sys_tick > measured_tick &&
+ sys_tick > 1e-6) {
+ ticks = (unsigned long)((ptv.tv_usec * 1e-6) /
+ sys_tick);
+ ptv.tv_usec = (long)(ticks * 1e6 *
+ sys_tick);
+ }
+ DPRINTF(4, ("fetch_timestamp: system usec network time stamp: %jd.%06ld\n",
+ (intmax_t)ptv.tv_sec, (long)ptv.tv_usec));
+ nts = tval_stamp_to_lfp(ptv);
+ }
+ break;
+#endif /* HAVE_TIMESTAMP */
+ }
+ fuzz = ntp_random() * 2. / FRAC * sys_fuzz;
+ DTOLFP(fuzz, &lfpfuzz);
+ L_ADD(&nts, &lfpfuzz);
+#ifdef DEBUG_TIMING
+ dts = ts;
+ L_SUB(&dts, &nts);
+ collect_timing(rb, "input processing delay", 1,
+ &dts);
+ DPRINTF(4, ("fetch_timestamp: timestamp delta: %s (incl. fuzz)\n",
+ lfptoa(&dts, 9)));
+#endif /* DEBUG_TIMING */
+ ts = nts; /* network time stamp */
+ break;
+#endif /* HAVE_BINTIME || HAVE_TIMESTAMPNS || HAVE_TIMESTAMP */
+
+ default:
+ DPRINTF(4, ("fetch_timestamp: skipping control message 0x%x\n",
+ cmsghdr->cmsg_type));
+ }
+ cmsghdr = CMSG_NXTHDR(msghdr, cmsghdr);
+ }
+ return ts;
+}
+#endif /* HAVE_PACKET_TIMESTAMP */
+
+
+/*
+ * Routine to read the network NTP packets for a specific interface
+ * Return the number of bytes read. That way we know if we should
+ * read it again or go on to the next one if no bytes returned
+ */
+static inline int
+read_network_packet(
+ SOCKET fd,
+ struct interface * itf,
+ l_fp ts
+ )
+{
+ GETSOCKNAME_SOCKLEN_TYPE fromlen;
+ int buflen;
+ register struct recvbuf *rb;
+#ifdef HAVE_PACKET_TIMESTAMP
+ struct msghdr msghdr;
+ struct iovec iovec;
+ char control[CMSG_BUFSIZE];
+#endif
+
+ /*
+ * Get a buffer and read the frame. If we
+ * haven't got a buffer, or this is received
+ * on a disallowed socket, just dump the
+ * packet.
+ */
+
+ rb = get_free_recv_buffer();
+ if (NULL == rb || itf->ignore_packets) {
+ char buf[RX_BUFF_SIZE];
+ sockaddr_u from;
+
+ if (rb != NULL)
+ freerecvbuf(rb);
+
+ fromlen = sizeof(from);
+ buflen = recvfrom(fd, buf, sizeof(buf), 0,
+ &from.sa, &fromlen);
+ DPRINTF(4, ("%s on (%lu) fd=%d from %s\n",
+ (itf->ignore_packets)
+ ? "ignore"
+ : "drop",
+ free_recvbuffs(), fd, stoa(&from)));
+ if (itf->ignore_packets)
+ packets_ignored++;
+ else
+ packets_dropped++;
+ return (buflen);
+ }
+
+ fromlen = sizeof(rb->recv_srcadr);
+
+#ifndef HAVE_PACKET_TIMESTAMP
+ rb->recv_length = recvfrom(fd, (char *)&rb->recv_space,
+ sizeof(rb->recv_space), 0,
+ &rb->recv_srcadr.sa, &fromlen);
+#else
+ iovec.iov_base = &rb->recv_space;
+ iovec.iov_len = sizeof(rb->recv_space);
+ msghdr.msg_name = &rb->recv_srcadr;
+ msghdr.msg_namelen = fromlen;
+ msghdr.msg_iov = &iovec;
+ msghdr.msg_iovlen = 1;
+ msghdr.msg_control = (void *)&control;
+ msghdr.msg_controllen = sizeof(control);
+ msghdr.msg_flags = 0;
+ rb->recv_length = recvmsg(fd, &msghdr, 0);
+#endif
+
+ buflen = rb->recv_length;
+
+ if (buflen == 0 || (buflen == -1 &&
+ (EWOULDBLOCK == errno
+#ifdef EAGAIN
+ || EAGAIN == errno
+#endif
+ ))) {
+ freerecvbuf(rb);
+ return (buflen);
+ } else if (buflen < 0) {
+ msyslog(LOG_ERR, "recvfrom(%s) fd=%d: %m",
+ stoa(&rb->recv_srcadr), fd);
+ DPRINTF(5, ("read_network_packet: fd=%d dropped (bad recvfrom)\n",
+ fd));
+ freerecvbuf(rb);
+ return (buflen);
+ }
+
+ DPRINTF(3, ("read_network_packet: fd=%d length %d from %s\n",
+ fd, buflen, stoa(&rb->recv_srcadr)));
+
+#ifdef ENABLE_BUG3020_FIX
+ if (ISREFCLOCKADR(&rb->recv_srcadr)) {
+ msyslog(LOG_ERR, "recvfrom(%s) fd=%d: refclock srcadr on a network interface!",
+ stoa(&rb->recv_srcadr), fd);
+ DPRINTF(1, ("read_network_packet: fd=%d dropped (refclock srcadr))\n",
+ fd));
+ packets_dropped++;
+ freerecvbuf(rb);
+ return (buflen);
+ }
+#endif
+
+ /*
+ ** Bug 2672: Some OSes (MacOSX and Linux) don't block spoofed ::1
+ */
+
+ if (AF_INET6 == itf->family) {
+ DPRINTF(2, ("Got an IPv6 packet, from <%s> (%d) to <%s> (%d)\n",
+ stoa(&rb->recv_srcadr),
+ IN6_IS_ADDR_LOOPBACK(PSOCK_ADDR6(&rb->recv_srcadr)),
+ stoa(&itf->sin),
+ !IN6_IS_ADDR_LOOPBACK(PSOCK_ADDR6(&itf->sin))
+ ));
+
+ if ( IN6_IS_ADDR_LOOPBACK(PSOCK_ADDR6(&rb->recv_srcadr))
+ && !IN6_IS_ADDR_LOOPBACK(PSOCK_ADDR6(&itf->sin))
+ ) {
+ packets_dropped++;
+ DPRINTF(2, ("DROPPING that packet\n"));
+ freerecvbuf(rb);
+ return buflen;
+ }
+ DPRINTF(2, ("processing that packet\n"));
+ }
+
+ /*
+ * Got one. Mark how and when it got here,
+ * put it on the full list and do bookkeeping.
+ */
+ rb->dstadr = itf;
+ rb->fd = fd;
+#ifdef HAVE_PACKET_TIMESTAMP
+ /* pick up a network time stamp if possible */
+ ts = fetch_timestamp(rb, &msghdr, ts);
+#endif
+ rb->recv_time = ts;
+ rb->receiver = receive;
+
+ add_full_recv_buffer(rb);
+
+ itf->received++;
+ packets_received++;
+ return (buflen);
+}
+
+/*
+ * attempt to handle io (select()/signaled IO)
+ */
+void
+io_handler(void)
+{
+# ifndef HAVE_SIGNALED_IO
+ fd_set rdfdes;
+ int nfound;
+
+ /*
+ * Use select() on all on all input fd's for unlimited
+ * time. select() will terminate on SIGALARM or on the
+ * reception of input. Using select() means we can't do
+ * robust signal handling and we get a potential race
+ * between checking for alarms and doing the select().
+ * Mostly harmless, I think.
+ */
+ /*
+ * On VMS, I suspect that select() can't be interrupted
+ * by a "signal" either, so I take the easy way out and
+ * have select() time out after one second.
+ * System clock updates really aren't time-critical,
+ * and - lacking a hardware reference clock - I have
+ * yet to learn about anything else that is.
+ */
+ ++handler_calls;
+ rdfdes = activefds;
+# if !defined(VMS) && !defined(SYS_VXWORKS) && !defined(__rtems__)
+ nfound = select(maxactivefd + 1, &rdfdes, NULL,
+ NULL, NULL);
+# else /* VMS, VxWorks */
+ /* make select() wake up after one second */
+ {
+ struct timeval t1;
+ t1.tv_sec = 1;
+ t1.tv_usec = 0;
+ nfound = select(maxactivefd + 1,
+ &rdfdes, NULL, NULL,
+ &t1);
+ alarm_flag = nfound <= 0;
+ }
+# endif /* VMS, VxWorks */
+ if (nfound < 0 && sanitize_fdset(errno)) {
+ struct timeval t1;
+ t1.tv_sec = 0;
+ t1.tv_usec = 0;
+ rdfdes = activefds;
+ nfound = select(maxactivefd + 1,
+ &rdfdes, NULL, NULL,
+ &t1);
+ }
+
+ if (nfound > 0) {
+ l_fp ts;
+
+ get_systime(&ts);
+
+ input_handler_scan(&ts, &rdfdes);
+ } else if (nfound == -1 && errno != EINTR) {
+ msyslog(LOG_ERR, "select() error: %m");
+ }
+# ifdef DEBUG
+ else if (debug > 4) {
+ msyslog(LOG_DEBUG, "select(): nfound=%d, error: %m", nfound);
+ } else {
+ DPRINTF(3, ("select() returned %d: %m\n", nfound));
+ }
+# endif /* DEBUG */
+# else /* HAVE_SIGNALED_IO */
+ wait_for_signal();
+# endif /* HAVE_SIGNALED_IO */
+}
+
+#ifdef HAVE_SIGNALED_IO
+/*
+ * input_handler - receive packets asynchronously
+ *
+ * ALWAYS IN SIGNAL HANDLER CONTEXT -- only async-safe functions allowed!
+ */
+static RETSIGTYPE
+input_handler(
+ l_fp * cts
+ )
+{
+ int n;
+ struct timeval tvzero;
+ fd_set fds;
+
+ ++handler_calls;
+
+ /*
+ * Do a poll to see who has data
+ */
+
+ fds = activefds;
+ tvzero.tv_sec = tvzero.tv_usec = 0;
+
+ n = select(maxactivefd + 1, &fds, NULL, NULL, &tvzero);
+ if (n < 0 && sanitize_fdset(errno)) {
+ fds = activefds;
+ tvzero.tv_sec = tvzero.tv_usec = 0;
+ n = select(maxactivefd + 1, &fds, NULL, NULL, &tvzero);
+ }
+ if (n > 0)
+ input_handler_scan(cts, &fds);
+}
+#endif /* HAVE_SIGNALED_IO */
+
+
+/*
+ * Try to sanitize the global FD set
+ *
+ * SIGNAL HANDLER CONTEXT if HAVE_SIGNALED_IO, ordinary userspace otherwise
+ */
+static int/*BOOL*/
+sanitize_fdset(
+ int errc
+ )
+{
+ int j, b, maxscan;
+
+# ifndef HAVE_SIGNALED_IO
+ /*
+ * extended FAU debugging output
+ */
+ if (errc != EINTR) {
+ msyslog(LOG_ERR,
+ "select(%d, %s, 0L, 0L, &0.0) error: %m",
+ maxactivefd + 1,
+ fdbits(maxactivefd, &activefds));
+ }
+# endif
+
+ if (errc != EBADF)
+ return FALSE;
+
+ /* if we have oviously bad FDs, try to sanitize the FD set. */
+ for (j = 0, maxscan = 0; j <= maxactivefd; j++) {
+ if (FD_ISSET(j, &activefds)) {
+ if (-1 != read(j, &b, 0)) {
+ maxscan = j;
+ continue;
+ }
+# ifndef HAVE_SIGNALED_IO
+ msyslog(LOG_ERR,
+ "Removing bad file descriptor %d from select set",
+ j);
+# endif
+ FD_CLR(j, &activefds);
+ }
+ }
+ if (maxactivefd != maxscan)
+ maxactivefd = maxscan;
+ return TRUE;
+}
+
+/*
+ * scan the known FDs (clocks, servers, ...) for presence in a 'fd_set'.
+ *
+ * SIGNAL HANDLER CONTEXT if HAVE_SIGNALED_IO, ordinary userspace otherwise
+ */
+static void
+input_handler_scan(
+ const l_fp * cts,
+ const fd_set * pfds
+ )
+{
+ int buflen;
+ u_int idx;
+ int doing;
+ SOCKET fd;
+ blocking_child *c;
+ l_fp ts; /* Timestamp at BOselect() gob */
+
+#if defined(DEBUG_TIMING)
+ l_fp ts_e; /* Timestamp at EOselect() gob */
+#endif
+ endpt * ep;
+#ifdef REFCLOCK
+ struct refclockio *rp;
+ int saved_errno;
+ const char * clk;
+#endif
+#ifdef HAS_ROUTING_SOCKET
+ struct asyncio_reader * asyncio_reader;
+ struct asyncio_reader * next_asyncio_reader;
+#endif
+
+ ++handler_pkts;
+ ts = *cts;
+
+#ifdef REFCLOCK
+ /*
+ * Check out the reference clocks first, if any
+ */
+
+ for (rp = refio; rp != NULL; rp = rp->next) {
+ fd = rp->fd;
+
+ if (!FD_ISSET(fd, pfds))
+ continue;
+ buflen = read_refclock_packet(fd, rp, ts);
+ /*
+ * The first read must succeed after select() indicates
+ * readability, or we've reached a permanent EOF.
+ * http://bugs.ntp.org/1732 reported ntpd munching CPU
+ * after a USB GPS was unplugged because select was
+ * indicating EOF but ntpd didn't remove the descriptor
+ * from the activefds set.
+ */
+ if (buflen < 0 && EAGAIN != errno) {
+ saved_errno = errno;
+ clk = refnumtoa(&rp->srcclock->srcadr);
+ errno = saved_errno;
+ msyslog(LOG_ERR, "%s read: %m", clk);
+ maintain_activefds(fd, TRUE);
+ } else if (0 == buflen) {
+ clk = refnumtoa(&rp->srcclock->srcadr);
+ msyslog(LOG_ERR, "%s read EOF", clk);
+ maintain_activefds(fd, TRUE);
+ } else {
+ /* drain any remaining refclock input */
+ do {
+ buflen = read_refclock_packet(fd, rp, ts);
+ } while (buflen > 0);
+ }
+ }
+#endif /* REFCLOCK */
+
+ /*
+ * Loop through the interfaces looking for data to read.
+ */
+ for (ep = ep_list; ep != NULL; ep = ep->elink) {
+ for (doing = 0; doing < 2; doing++) {
+ if (!doing) {
+ fd = ep->fd;
+ } else {
+ if (!(ep->flags & INT_BCASTOPEN))
+ break;
+ fd = ep->bfd;
+ }
+ if (fd < 0)
+ continue;
+ if (FD_ISSET(fd, pfds))
+ do {
+ buflen = read_network_packet(
+ fd, ep, ts);
+ } while (buflen > 0);
+ /* Check more interfaces */
+ }
+ }
+
+#ifdef HAS_ROUTING_SOCKET
+ /*
+ * scan list of asyncio readers - currently only used for routing sockets
+ */
+ asyncio_reader = asyncio_reader_list;
+
+ while (asyncio_reader != NULL) {
+ /* callback may unlink and free asyncio_reader */
+ next_asyncio_reader = asyncio_reader->link;
+ if (FD_ISSET(asyncio_reader->fd, pfds))
+ (*asyncio_reader->receiver)(asyncio_reader);
+ asyncio_reader = next_asyncio_reader;
+ }
+#endif /* HAS_ROUTING_SOCKET */
+
+ /*
+ * Check for a response from a blocking child
+ */
+ for (idx = 0; idx < blocking_children_alloc; idx++) {
+ c = blocking_children[idx];
+ if (NULL == c || -1 == c->resp_read_pipe)
+ continue;
+ if (FD_ISSET(c->resp_read_pipe, pfds)) {
+ ++c->resp_ready_seen;
+ ++blocking_child_ready_seen;
+ }
+ }
+
+ /* We've done our work */
+#if defined(DEBUG_TIMING)
+ get_systime(&ts_e);
+ /*
+ * (ts_e - ts) is the amount of time we spent
+ * processing this gob of file descriptors. Log
+ * it.
+ */
+ L_SUB(&ts_e, &ts);
+ collect_timing(NULL, "input handler", 1, &ts_e);
+ if (debug > 3)
+ msyslog(LOG_DEBUG,
+ "input_handler: Processed a gob of fd's in %s msec",
+ lfptoms(&ts_e, 6));
+#endif /* DEBUG_TIMING */
+}
+#endif /* !HAVE_IO_COMPLETION_PORT */
+
+/*
+ * find an interface suitable for the src address
+ */
+endpt *
+select_peerinterface(
+ struct peer * peer,
+ sockaddr_u * srcadr,
+ endpt * dstadr
+ )
+{
+ endpt *ep;
+#ifndef SIM
+ endpt *wild;
+
+ wild = ANY_INTERFACE_CHOOSE(srcadr);
+
+ /*
+ * Initialize the peer structure and dance the interface jig.
+ * Reference clocks step the loopback waltz, the others
+ * squaredance around the interface list looking for a buddy. If
+ * the dance peters out, there is always the wildcard interface.
+ * This might happen in some systems and would preclude proper
+ * operation with public key cryptography.
+ */
+ if (ISREFCLOCKADR(srcadr)) {
+ ep = loopback_interface;
+ } else if (peer->cast_flags &
+ (MDF_BCLNT | MDF_ACAST | MDF_MCAST | MDF_BCAST)) {
+ ep = findbcastinter(srcadr);
+ if (ep != NULL)
+ DPRINTF(4, ("Found *-cast interface %s for address %s\n",
+ stoa(&ep->sin), stoa(srcadr)));
+ else
+ DPRINTF(4, ("No *-cast local address found for address %s\n",
+ stoa(srcadr)));
+ } else {
+ ep = dstadr;
+ if (NULL == ep)
+ ep = wild;
+ }
+ /*
+ * If it is a multicast address, findbcastinter() may not find
+ * it. For unicast, we get to find the interface when dstadr is
+ * given to us as the wildcard (ANY_INTERFACE_CHOOSE). Either
+ * way, try a little harder.
+ */
+ if (wild == ep)
+ ep = findinterface(srcadr);
+ /*
+ * we do not bind to the wildcard interfaces for output
+ * as our (network) source address would be undefined and
+ * crypto will not work without knowing the own transmit address
+ */
+ if (ep != NULL && INT_WILDCARD & ep->flags)
+ if (!accept_wildcard_if_for_winnt)
+ ep = NULL;
+#else /* SIM follows */
+ ep = loopback_interface;
+#endif
+
+ return ep;
+}
+
+
+/*
+ * findinterface - find local interface corresponding to address
+ */
+endpt *
+findinterface(
+ sockaddr_u *addr
+ )
+{
+ endpt *iface;
+
+ iface = findlocalinterface(addr, INT_WILDCARD, 0);
+
+ if (NULL == iface) {
+ DPRINTF(4, ("Found no interface for address %s - returning wildcard\n",
+ stoa(addr)));
+
+ iface = ANY_INTERFACE_CHOOSE(addr);
+ } else
+ DPRINTF(4, ("Found interface #%d %s for address %s\n",
+ iface->ifnum, iface->name, stoa(addr)));
+
+ return iface;
+}
+
+/*
+ * findlocalinterface - find local interface corresponding to addr,
+ * which does not have any of flags set. If bast is nonzero, addr is
+ * a broadcast address.
+ *
+ * This code attempts to find the local sending address for an outgoing
+ * address by connecting a new socket to destinationaddress:NTP_PORT
+ * and reading the sockname of the resulting connect.
+ * the complicated sequence simulates the routing table lookup
+ * for to first hop without duplicating any of the routing logic into
+ * ntpd. preferably we would have used an API call - but its not there -
+ * so this is the best we can do here short of duplicating to entire routing
+ * logic in ntpd which would be a silly and really unportable thing to do.
+ *
+ */
+static endpt *
+findlocalinterface(
+ sockaddr_u * addr,
+ int flags,
+ int bcast
+ )
+{
+ GETSOCKNAME_SOCKLEN_TYPE sockaddrlen;
+ endpt * iface;
+ sockaddr_u saddr;
+ SOCKET s;
+ int rtn;
+ int on;
+
+ DPRINTF(4, ("Finding interface for addr %s in list of addresses\n",
+ stoa(addr)));
+
+ /* [Bug 3437] The dummy POOL peer comes in with an AF of
+ * zero. This is bound to fail, but on the way to nowhere it
+ * triggers a security incident on SELinux.
+ *
+ * Checking the condition and failing early is probably a good
+ * advice, and even saves us some syscalls in that case.
+ * Thanks to Miroslav Lichvar for finding this.
+ */
+ if (AF_UNSPEC == AF(addr))
+ return NULL;
+
+ s = socket(AF(addr), SOCK_DGRAM, 0);
+ if (INVALID_SOCKET == s)
+ return NULL;
+
+ /*
+ * If we are looking for broadcast interface we need to set this
+ * socket to allow broadcast
+ */
+ if (bcast) {
+ on = 1;
+ if (SOCKET_ERROR == setsockopt(s, SOL_SOCKET,
+ SO_BROADCAST,
+ (void *)&on,
+ sizeof(on))) {
+ closesocket(s);
+ return NULL;
+ }
+ }
+
+ rtn = connect(s, &addr->sa, SOCKLEN(addr));
+ if (SOCKET_ERROR == rtn) {
+ closesocket(s);
+ return NULL;
+ }
+
+ sockaddrlen = sizeof(saddr);
+ rtn = getsockname(s, &saddr.sa, &sockaddrlen);
+ closesocket(s);
+ if (SOCKET_ERROR == rtn)
+ return NULL;
+
+ DPRINTF(4, ("findlocalinterface: kernel maps %s to %s\n",
+ stoa(addr), stoa(&saddr)));
+
+ iface = getinterface(&saddr, flags);
+
+ /*
+ * if we didn't find an exact match on saddr, find the closest
+ * available local address. This handles the case of the
+ * address suggested by the kernel being excluded by nic rules
+ * or the user's -I and -L options to ntpd.
+ * See http://bugs.ntp.org/1184 and http://bugs.ntp.org/1683
+ * for more background.
+ */
+ if (NULL == iface || iface->ignore_packets)
+ iface = findclosestinterface(&saddr,
+ flags | INT_LOOPBACK);
+
+ /* Don't use an interface which will ignore replies */
+ if (iface != NULL && iface->ignore_packets)
+ iface = NULL;
+
+ return iface;
+}
+
+
+/*
+ * findclosestinterface
+ *
+ * If there are -I/--interface or -L/novirtualips command-line options,
+ * or "nic" or "interface" rules in ntp.conf, findlocalinterface() may
+ * find the kernel's preferred local address for a given peer address is
+ * administratively unavailable to ntpd, and punt to this routine's more
+ * expensive search.
+ *
+ * Find the numerically closest local address to the one connect()
+ * suggested. This matches an address on the same subnet first, as
+ * needed by Bug 1184, and provides a consistent choice if there are
+ * multiple feasible local addresses, regardless of the order ntpd
+ * enumerated them.
+ */
+endpt *
+findclosestinterface(
+ sockaddr_u * addr,
+ int flags
+ )
+{
+ endpt * ep;
+ endpt * winner;
+ sockaddr_u addr_dist;
+ sockaddr_u min_dist;
+
+ ZERO_SOCK(&min_dist);
+ winner = NULL;
+
+ for (ep = ep_list; ep != NULL; ep = ep->elink) {
+ if (ep->ignore_packets ||
+ AF(addr) != ep->family ||
+ flags & ep->flags)
+ continue;
+
+ calc_addr_distance(&addr_dist, addr, &ep->sin);
+ if (NULL == winner ||
+ -1 == cmp_addr_distance(&addr_dist, &min_dist)) {
+ min_dist = addr_dist;
+ winner = ep;
+ }
+ }
+ if (NULL == winner)
+ DPRINTF(4, ("findclosestinterface(%s) failed\n",
+ stoa(addr)));
+ else
+ DPRINTF(4, ("findclosestinterface(%s) -> %s\n",
+ stoa(addr), stoa(&winner->sin)));
+
+ return winner;
+}
+
+
+/*
+ * calc_addr_distance - calculate the distance between two addresses,
+ * the absolute value of the difference between
+ * the addresses numerically, stored as an address.
+ */
+static void
+calc_addr_distance(
+ sockaddr_u * dist,
+ const sockaddr_u * a1,
+ const sockaddr_u * a2
+ )
+{
+ u_int32 a1val;
+ u_int32 a2val;
+ u_int32 v4dist;
+ int found_greater;
+ int a1_greater;
+ int i;
+
+ REQUIRE(AF(a1) == AF(a2));
+
+ ZERO_SOCK(dist);
+ AF(dist) = AF(a1);
+
+ /* v4 can be done a bit simpler */
+ if (IS_IPV4(a1)) {
+ a1val = SRCADR(a1);
+ a2val = SRCADR(a2);
+ v4dist = (a1val > a2val)
+ ? a1val - a2val
+ : a2val - a1val;
+ SET_ADDR4(dist, v4dist);
+
+ return;
+ }
+
+ found_greater = FALSE;
+ a1_greater = FALSE; /* suppress pot. uninit. warning */
+ for (i = 0; i < (int)sizeof(NSRCADR6(a1)); i++) {
+ if (!found_greater &&
+ NSRCADR6(a1)[i] != NSRCADR6(a2)[i]) {
+ found_greater = TRUE;
+ a1_greater = (NSRCADR6(a1)[i] > NSRCADR6(a2)[i]);
+ }
+ if (!found_greater) {
+ NSRCADR6(dist)[i] = 0;
+ } else {
+ if (a1_greater)
+ NSRCADR6(dist)[i] = NSRCADR6(a1)[i] -
+ NSRCADR6(a2)[i];
+ else
+ NSRCADR6(dist)[i] = NSRCADR6(a2)[i] -
+ NSRCADR6(a1)[i];
+ }
+ }
+}
+
+
+/*
+ * cmp_addr_distance - compare two address distances, returning -1, 0,
+ * 1 to indicate their relationship.
+ */
+static int
+cmp_addr_distance(
+ const sockaddr_u * d1,
+ const sockaddr_u * d2
+ )
+{
+ int i;
+
+ REQUIRE(AF(d1) == AF(d2));
+
+ if (IS_IPV4(d1)) {
+ if (SRCADR(d1) < SRCADR(d2))
+ return -1;
+ else if (SRCADR(d1) == SRCADR(d2))
+ return 0;
+ else
+ return 1;
+ }
+
+ for (i = 0; i < (int)sizeof(NSRCADR6(d1)); i++) {
+ if (NSRCADR6(d1)[i] < NSRCADR6(d2)[i])
+ return -1;
+ else if (NSRCADR6(d1)[i] > NSRCADR6(d2)[i])
+ return 1;
+ }
+
+ return 0;
+}
+
+
+
+/*
+ * fetch an interface structure the matches the
+ * address and has the given flags NOT set
+ */
+endpt *
+getinterface(
+ sockaddr_u * addr,
+ u_int32 flags
+ )
+{
+ endpt *iface;
+
+ iface = find_addr_in_list(addr);
+
+ if (iface != NULL && (iface->flags & flags))
+ iface = NULL;
+
+ return iface;
+}
+
+
+/*
+ * findbcastinter - find broadcast interface corresponding to address
+ */
+endpt *
+findbcastinter(
+ sockaddr_u *addr
+ )
+{
+ endpt * iface;
+
+ iface = NULL;
+#if !defined(MPE) && (defined(SIOCGIFCONF) || defined(SYS_WINNT))
+ DPRINTF(4, ("Finding broadcast/multicast interface for addr %s in list of addresses\n",
+ stoa(addr)));
+
+ iface = findlocalinterface(addr, INT_LOOPBACK | INT_WILDCARD,
+ 1);
+ if (iface != NULL) {
+ DPRINTF(4, ("Easily found bcast-/mcast- interface index #%d %s\n",
+ iface->ifnum, iface->name));
+ return iface;
+ }
+
+ /*
+ * plan B - try to find something reasonable in our lists in
+ * case kernel lookup doesn't help
+ */
+ for (iface = ep_list; iface != NULL; iface = iface->elink) {
+ if (iface->flags & INT_WILDCARD)
+ continue;
+
+ /* Don't bother with ignored interfaces */
+ if (iface->ignore_packets)
+ continue;
+
+ /*
+ * First look if this is the correct family
+ */
+ if(AF(&iface->sin) != AF(addr))
+ continue;
+
+ /* Skip the loopback addresses */
+ if (iface->flags & INT_LOOPBACK)
+ continue;
+
+ /*
+ * If we are looking to match a multicast address and
+ * this interface is one...
+ */
+ if (addr_ismulticast(addr)
+ && (iface->flags & INT_MULTICAST)) {
+#ifdef INCLUDE_IPV6_SUPPORT
+ /*
+ * ...it is the winner unless we're looking for
+ * an interface to use for link-local multicast
+ * and its address is not link-local.
+ */
+ if (IS_IPV6(addr)
+ && IN6_IS_ADDR_MC_LINKLOCAL(PSOCK_ADDR6(addr))
+ && !IN6_IS_ADDR_LINKLOCAL(PSOCK_ADDR6(&iface->sin)))
+ continue;
+#endif
+ break;
+ }
+
+ /*
+ * We match only those interfaces marked as
+ * broadcastable and either the explicit broadcast
+ * address or the network portion of the IP address.
+ * Sloppy.
+ */
+ if (IS_IPV4(addr)) {
+ if (SOCK_EQ(&iface->bcast, addr))
+ break;
+
+ if ((NSRCADR(&iface->sin) & NSRCADR(&iface->mask))
+ == (NSRCADR(addr) & NSRCADR(&iface->mask)))
+ break;
+ }
+#ifdef INCLUDE_IPV6_SUPPORT
+ else if (IS_IPV6(addr)) {
+ if (SOCK_EQ(&iface->bcast, addr))
+ break;
+
+ if (SOCK_EQ(netof(&iface->sin), netof(addr)))
+ break;
+ }
+#endif
+ }
+#endif /* SIOCGIFCONF */
+ if (NULL == iface) {
+ DPRINTF(4, ("No bcast interface found for %s\n",
+ stoa(addr)));
+ iface = ANY_INTERFACE_CHOOSE(addr);
+ } else {
+ DPRINTF(4, ("Found bcast-/mcast- interface index #%d %s\n",
+ iface->ifnum, iface->name));
+ }
+
+ return iface;
+}
+
+
+/*
+ * io_clr_stats - clear I/O module statistics
+ */
+void
+io_clr_stats(void)
+{
+ packets_dropped = 0;
+ packets_ignored = 0;
+ packets_received = 0;
+ packets_sent = 0;
+ packets_notsent = 0;
+
+ handler_calls = 0;
+ handler_pkts = 0;
+ io_timereset = current_time;
+}
+
+
+#ifdef REFCLOCK
+/*
+ * io_addclock - add a reference clock to the list and arrange that we
+ * get SIGIO interrupts from it.
+ */
+int
+io_addclock(
+ struct refclockio *rio
+ )
+{
+ BLOCKIO();
+
+ /*
+ * Stuff the I/O structure in the list and mark the descriptor
+ * in use. There is a harmless (I hope) race condition here.
+ */
+ rio->active = TRUE;
+
+# ifdef HAVE_SIGNALED_IO
+ if (init_clock_sig(rio)) {
+ UNBLOCKIO();
+ return 0;
+ }
+# elif defined(HAVE_IO_COMPLETION_PORT)
+ if (!io_completion_port_add_clock_io(rio)) {
+ UNBLOCKIO();
+ return 0;
+ }
+# endif
+
+ /*
+ * enqueue
+ */
+ LINK_SLIST(refio, rio, next);
+
+ /*
+ * register fd
+ */
+ add_fd_to_list(rio->fd, FD_TYPE_FILE);
+
+ UNBLOCKIO();
+ return 1;
+}
+
+
+/*
+ * io_closeclock - close the clock in the I/O structure given
+ */
+void
+io_closeclock(
+ struct refclockio *rio
+ )
+{
+ struct refclockio *unlinked;
+
+ BLOCKIO();
+
+ /*
+ * Remove structure from the list
+ */
+ rio->active = FALSE;
+ UNLINK_SLIST(unlinked, refio, rio, next, struct refclockio);
+ if (NULL != unlinked) {
+ /* Close the descriptor. The order of operations is
+ * important here in case of async / overlapped IO:
+ * only after we have removed the clock from the
+ * IO completion port we can be sure no further
+ * input is queued. So...
+ * - we first disable feeding to the queu by removing
+ * the clock from the IO engine
+ * - close the file (which brings down any IO on it)
+ * - clear the buffer from results for this fd
+ */
+# ifdef HAVE_IO_COMPLETION_PORT
+ io_completion_port_remove_clock_io(rio);
+# endif
+ close_and_delete_fd_from_list(rio->fd);
+ purge_recv_buffers_for_fd(rio->fd);
+ rio->fd = -1;
+ }
+
+ UNBLOCKIO();
+}
+#endif /* REFCLOCK */
+
+
+/*
+ * On NT a SOCKET is an unsigned int so we cannot possibly keep it in
+ * an array. So we use one of the ISC_LIST functions to hold the
+ * socket value and use that when we want to enumerate it.
+ *
+ * This routine is called by the forked intres child process to close
+ * all open sockets. On Windows there's no need as intres runs in
+ * the same process as a thread.
+ */
+#ifndef SYS_WINNT
+void
+kill_asyncio(
+ int startfd
+ )
+{
+ BLOCKIO();
+
+ /*
+ * In the child process we do not maintain activefds and
+ * maxactivefd. Zeroing maxactivefd disables code which
+ * maintains it in close_and_delete_fd_from_list().
+ */
+ maxactivefd = 0;
+
+ while (fd_list != NULL)
+ close_and_delete_fd_from_list(fd_list->fd);
+
+ UNBLOCKIO();
+}
+#endif /* !SYS_WINNT */
+
+
+/*
+ * Add and delete functions for the list of open sockets
+ */
+static void
+add_fd_to_list(
+ SOCKET fd,
+ enum desc_type type
+ )
+{
+ vsock_t *lsock = emalloc(sizeof(*lsock));
+
+ lsock->fd = fd;
+ lsock->type = type;
+
+ LINK_SLIST(fd_list, lsock, link);
+ maintain_activefds(fd, 0);
+}
+
+
+static void
+close_and_delete_fd_from_list(
+ SOCKET fd
+ )
+{
+ vsock_t *lsock;
+
+ UNLINK_EXPR_SLIST(lsock, fd_list, fd ==
+ UNLINK_EXPR_SLIST_CURRENT()->fd, link, vsock_t);
+
+ if (NULL == lsock)
+ return;
+
+ switch (lsock->type) {
+
+ case FD_TYPE_SOCKET:
+ closesocket(lsock->fd);
+ break;
+
+ case FD_TYPE_FILE:
+ closeserial((int)lsock->fd);
+ break;
+
+ default:
+ msyslog(LOG_ERR,
+ "internal error - illegal descriptor type %d - EXITING",
+ (int)lsock->type);
+ exit(1);
+ }
+
+ free(lsock);
+ /*
+ * remove from activefds
+ */
+ maintain_activefds(fd, 1);
+}
+
+
+static void
+add_addr_to_list(
+ sockaddr_u * addr,
+ endpt * ep
+ )
+{
+ remaddr_t *laddr;
+
+#ifdef DEBUG
+ if (find_addr_in_list(addr) == NULL) {
+#endif
+ /* not there yet - add to list */
+ laddr = emalloc(sizeof(*laddr));
+ laddr->addr = *addr;
+ laddr->ep = ep;
+
+ LINK_SLIST(remoteaddr_list, laddr, link);
+
+ DPRINTF(4, ("Added addr %s to list of addresses\n",
+ stoa(addr)));
+#ifdef DEBUG
+ } else
+ DPRINTF(4, ("WARNING: Attempt to add duplicate addr %s to address list\n",
+ stoa(addr)));
+#endif
+}
+
+
+static void
+delete_addr_from_list(
+ sockaddr_u *addr
+ )
+{
+ remaddr_t *unlinked;
+
+ UNLINK_EXPR_SLIST(unlinked, remoteaddr_list, SOCK_EQ(addr,
+ &(UNLINK_EXPR_SLIST_CURRENT()->addr)), link, remaddr_t);
+
+ if (unlinked != NULL) {
+ DPRINTF(4, ("Deleted addr %s from list of addresses\n",
+ stoa(addr)));
+ free(unlinked);
+ }
+}
+
+
+static void
+delete_interface_from_list(
+ endpt *iface
+ )
+{
+ remaddr_t *unlinked;
+
+ for (;;) {
+ UNLINK_EXPR_SLIST(unlinked, remoteaddr_list, iface ==
+ UNLINK_EXPR_SLIST_CURRENT()->ep, link,
+ remaddr_t);
+
+ if (unlinked == NULL)
+ break;
+ DPRINTF(4, ("Deleted addr %s for interface #%d %s from list of addresses\n",
+ stoa(&unlinked->addr), iface->ifnum,
+ iface->name));
+ free(unlinked);
+ }
+}
+
+
+static struct interface *
+find_addr_in_list(
+ sockaddr_u *addr
+ )
+{
+ remaddr_t *entry;
+
+ DPRINTF(4, ("Searching for addr %s in list of addresses - ",
+ stoa(addr)));
+
+ for (entry = remoteaddr_list;
+ entry != NULL;
+ entry = entry->link)
+ if (SOCK_EQ(&entry->addr, addr)) {
+ DPRINTF(4, ("FOUND\n"));
+ return entry->ep;
+ }
+
+ DPRINTF(4, ("NOT FOUND\n"));
+ return NULL;
+}
+
+
+/*
+ * Find the given address with the all given flags set in the list
+ */
+static endpt *
+find_flagged_addr_in_list(
+ sockaddr_u * addr,
+ u_int32 flags
+ )
+{
+ remaddr_t *entry;
+
+ DPRINTF(4, ("Finding addr %s with flags %d in list: ",
+ stoa(addr), flags));
+
+ for (entry = remoteaddr_list;
+ entry != NULL;
+ entry = entry->link)
+
+ if (SOCK_EQ(&entry->addr, addr)
+ && (entry->ep->flags & flags) == flags) {
+
+ DPRINTF(4, ("FOUND\n"));
+ return entry->ep;
+ }
+
+ DPRINTF(4, ("NOT FOUND\n"));
+ return NULL;
+}
+
+
+const char *
+localaddrtoa(
+ endpt *la
+ )
+{
+ return (NULL == la)
+ ? "<null>"
+ : stoa(&la->sin);
+}
+
+
+#ifdef HAS_ROUTING_SOCKET
+# ifndef UPDATE_GRACE
+# define UPDATE_GRACE 2 /* wait UPDATE_GRACE seconds before scanning */
+# endif
+
+static void
+process_routing_msgs(struct asyncio_reader *reader)
+{
+ char buffer[5120];
+ int cnt, msg_type;
+#ifdef HAVE_RTNETLINK
+ struct nlmsghdr *nh;
+#else
+ struct rt_msghdr rtm;
+ char *p;
+#endif
+
+ if (disable_dynamic_updates) {
+ /*
+ * discard ourselves if we are not needed any more
+ * usually happens when running unprivileged
+ */
+ remove_asyncio_reader(reader);
+ delete_asyncio_reader(reader);
+ return;
+ }
+
+ cnt = read(reader->fd, buffer, sizeof(buffer));
+
+ if (cnt < 0) {
+ if (errno == ENOBUFS) {
+ msyslog(LOG_ERR,
+ "routing socket reports: %m");
+ } else {
+ msyslog(LOG_ERR,
+ "routing socket reports: %m - disabling");
+ remove_asyncio_reader(reader);
+ delete_asyncio_reader(reader);
+ }
+ return;
+ }
+
+ /*
+ * process routing message
+ */
+#ifdef HAVE_RTNETLINK
+ for (nh = UA_PTR(struct nlmsghdr, buffer);
+ NLMSG_OK(nh, cnt);
+ nh = NLMSG_NEXT(nh, cnt)) {
+ msg_type = nh->nlmsg_type;
+#else
+ for (p = buffer;
+ (p + sizeof(struct rt_msghdr)) <= (buffer + cnt);
+ p += rtm.rtm_msglen) {
+ memcpy(&rtm, p, sizeof(rtm));
+ if (rtm.rtm_version != RTM_VERSION) {
+ msyslog(LOG_ERR,
+ "version mismatch (got %d - expected %d) on routing socket - disabling",
+ rtm.rtm_version, RTM_VERSION);
+
+ remove_asyncio_reader(reader);
+ delete_asyncio_reader(reader);
+ return;
+ }
+ msg_type = rtm.rtm_type;
+#endif
+ switch (msg_type) {
+#ifdef RTM_NEWADDR
+ case RTM_NEWADDR:
+#endif
+#ifdef RTM_DELADDR
+ case RTM_DELADDR:
+#endif
+#ifdef RTM_ADD
+ case RTM_ADD:
+#endif
+#ifdef RTM_DELETE
+ case RTM_DELETE:
+#endif
+#ifdef RTM_REDIRECT
+ case RTM_REDIRECT:
+#endif
+#ifdef RTM_CHANGE
+ case RTM_CHANGE:
+#endif
+#ifdef RTM_LOSING
+ case RTM_LOSING:
+#endif
+#ifdef RTM_IFINFO
+ case RTM_IFINFO:
+#endif
+#ifdef RTM_IFANNOUNCE
+ case RTM_IFANNOUNCE:
+#endif
+#ifdef RTM_NEWLINK
+ case RTM_NEWLINK:
+#endif
+#ifdef RTM_DELLINK
+ case RTM_DELLINK:
+#endif
+#ifdef RTM_NEWROUTE
+ case RTM_NEWROUTE:
+#endif
+#ifdef RTM_DELROUTE
+ case RTM_DELROUTE:
+#endif
+ /*
+ * we are keen on new and deleted addresses and
+ * if an interface goes up and down or routing
+ * changes
+ */
+ DPRINTF(3, ("routing message op = %d: scheduling interface update\n",
+ msg_type));
+ timer_interfacetimeout(current_time + UPDATE_GRACE);
+ break;
+#ifdef HAVE_RTNETLINK
+ case NLMSG_DONE:
+ /* end of multipart message */
+ return;
+#endif
+ default:
+ /*
+ * the rest doesn't bother us.
+ */
+ DPRINTF(4, ("routing message op = %d: ignored\n",
+ msg_type));
+ break;
+ }
+ }
+}
+
+/*
+ * set up routing notifications
+ */
+static void
+init_async_notifications()
+{
+ struct asyncio_reader *reader;
+#ifdef HAVE_RTNETLINK
+ int fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+ struct sockaddr_nl sa;
+#else
+ int fd = socket(PF_ROUTE, SOCK_RAW, 0);
+#endif
+ if (fd < 0) {
+ msyslog(LOG_ERR,
+ "unable to open routing socket (%m) - using polled interface update");
+ return;
+ }
+
+ fd = move_fd(fd);
+#ifdef HAVE_RTNETLINK
+ ZERO(sa);
+ sa.nl_family = PF_NETLINK;
+ sa.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR
+ | RTMGRP_IPV6_IFADDR | RTMGRP_IPV4_ROUTE
+ | RTMGRP_IPV4_MROUTE | RTMGRP_IPV6_ROUTE
+ | RTMGRP_IPV6_MROUTE;
+ if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
+ msyslog(LOG_ERR,
+ "bind failed on routing socket (%m) - using polled interface update");
+ return;
+ }
+#endif
+ make_socket_nonblocking(fd);
+#if defined(HAVE_SIGNALED_IO)
+ init_socket_sig(fd);
+#endif /* HAVE_SIGNALED_IO */
+
+ reader = new_asyncio_reader();
+
+ reader->fd = fd;
+ reader->receiver = process_routing_msgs;
+
+ add_asyncio_reader(reader, FD_TYPE_SOCKET);
+ msyslog(LOG_INFO,
+ "Listening on routing socket on fd #%d for interface updates",
+ fd);
+}
+#else
+/* HAS_ROUTING_SOCKET not defined */
+static void
+init_async_notifications(void)
+{
+}
+#endif
+
diff --git a/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_keyword.h b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_keyword.h
new file mode 100644
index 0000000..6638810
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_keyword.h
@@ -0,0 +1,1164 @@
+/*
+ * ntp_keyword.h
+ *
+ * NOTE: edit this file with caution, it is generated by keyword-gen.c
+ * Generated 2018-01-14 03:53:33 UTC diff_ignore_line
+ *
+ */
+#include "ntp_scanner.h"
+#include "ntp_parser.h"
+
+#define LOWEST_KEYWORD_ID 258
+
+const char * const keyword_text[200] = {
+ /* 0 258 T_Abbrev */ "abbrev",
+ /* 1 259 T_Age */ "age",
+ /* 2 260 T_All */ "all",
+ /* 3 261 T_Allan */ "allan",
+ /* 4 262 T_Allpeers */ "allpeers",
+ /* 5 263 T_Auth */ "auth",
+ /* 6 264 T_Autokey */ "autokey",
+ /* 7 265 T_Automax */ "automax",
+ /* 8 266 T_Average */ "average",
+ /* 9 267 T_Basedate */ "basedate",
+ /* 10 268 T_Bclient */ "bclient",
+ /* 11 269 T_Bcpollbstep */ "bcpollbstep",
+ /* 12 270 T_Beacon */ "beacon",
+ /* 13 271 T_Broadcast */ "broadcast",
+ /* 14 272 T_Broadcastclient */ "broadcastclient",
+ /* 15 273 T_Broadcastdelay */ "broadcastdelay",
+ /* 16 274 T_Burst */ "burst",
+ /* 17 275 T_Calibrate */ "calibrate",
+ /* 18 276 T_Ceiling */ "ceiling",
+ /* 19 277 T_Clockstats */ "clockstats",
+ /* 20 278 T_Cohort */ "cohort",
+ /* 21 279 T_ControlKey */ "controlkey",
+ /* 22 280 T_Crypto */ "crypto",
+ /* 23 281 T_Cryptostats */ "cryptostats",
+ /* 24 282 T_Ctl */ "ctl",
+ /* 25 283 T_Day */ "day",
+ /* 26 284 T_Default */ "default",
+ /* 27 285 T_Digest */ "digest",
+ /* 28 286 T_Disable */ "disable",
+ /* 29 287 T_Discard */ "discard",
+ /* 30 288 T_Dispersion */ "dispersion",
+ /* 31 289 T_Double */ NULL,
+ /* 32 290 T_Driftfile */ "driftfile",
+ /* 33 291 T_Drop */ "drop",
+ /* 34 292 T_Dscp */ "dscp",
+ /* 35 293 T_Ellipsis */ "...",
+ /* 36 294 T_Enable */ "enable",
+ /* 37 295 T_End */ "end",
+ /* 38 296 T_Epeer */ "epeer",
+ /* 39 297 T_False */ NULL,
+ /* 40 298 T_File */ "file",
+ /* 41 299 T_Filegen */ "filegen",
+ /* 42 300 T_Filenum */ "filenum",
+ /* 43 301 T_Flag1 */ "flag1",
+ /* 44 302 T_Flag2 */ "flag2",
+ /* 45 303 T_Flag3 */ "flag3",
+ /* 46 304 T_Flag4 */ "flag4",
+ /* 47 305 T_Flake */ "flake",
+ /* 48 306 T_Floor */ "floor",
+ /* 49 307 T_Freq */ "freq",
+ /* 50 308 T_Fudge */ "fudge",
+ /* 51 309 T_Host */ "host",
+ /* 52 310 T_Huffpuff */ "huffpuff",
+ /* 53 311 T_Iburst */ "iburst",
+ /* 54 312 T_Ident */ "ident",
+ /* 55 313 T_Ignore */ "ignore",
+ /* 56 314 T_Incalloc */ "incalloc",
+ /* 57 315 T_Incmem */ "incmem",
+ /* 58 316 T_Initalloc */ "initalloc",
+ /* 59 317 T_Initmem */ "initmem",
+ /* 60 318 T_Includefile */ "includefile",
+ /* 61 319 T_Integer */ NULL,
+ /* 62 320 T_Interface */ "interface",
+ /* 63 321 T_Intrange */ NULL,
+ /* 64 322 T_Io */ "io",
+ /* 65 323 T_Ippeerlimit */ "ippeerlimit",
+ /* 66 324 T_Ipv4 */ "ipv4",
+ /* 67 325 T_Ipv4_flag */ "-4",
+ /* 68 326 T_Ipv6 */ "ipv6",
+ /* 69 327 T_Ipv6_flag */ "-6",
+ /* 70 328 T_Kernel */ "kernel",
+ /* 71 329 T_Key */ "key",
+ /* 72 330 T_Keys */ "keys",
+ /* 73 331 T_Keysdir */ "keysdir",
+ /* 74 332 T_Kod */ "kod",
+ /* 75 333 T_Mssntp */ "mssntp",
+ /* 76 334 T_Leapfile */ "leapfile",
+ /* 77 335 T_Leapsmearinterval */ "leapsmearinterval",
+ /* 78 336 T_Limited */ "limited",
+ /* 79 337 T_Link */ "link",
+ /* 80 338 T_Listen */ "listen",
+ /* 81 339 T_Logconfig */ "logconfig",
+ /* 82 340 T_Logfile */ "logfile",
+ /* 83 341 T_Loopstats */ "loopstats",
+ /* 84 342 T_Lowpriotrap */ "lowpriotrap",
+ /* 85 343 T_Manycastclient */ "manycastclient",
+ /* 86 344 T_Manycastserver */ "manycastserver",
+ /* 87 345 T_Mask */ "mask",
+ /* 88 346 T_Maxage */ "maxage",
+ /* 89 347 T_Maxclock */ "maxclock",
+ /* 90 348 T_Maxdepth */ "maxdepth",
+ /* 91 349 T_Maxdist */ "maxdist",
+ /* 92 350 T_Maxmem */ "maxmem",
+ /* 93 351 T_Maxpoll */ "maxpoll",
+ /* 94 352 T_Mdnstries */ "mdnstries",
+ /* 95 353 T_Mem */ "mem",
+ /* 96 354 T_Memlock */ "memlock",
+ /* 97 355 T_Minclock */ "minclock",
+ /* 98 356 T_Mindepth */ "mindepth",
+ /* 99 357 T_Mindist */ "mindist",
+ /* 100 358 T_Minimum */ "minimum",
+ /* 101 359 T_Minpoll */ "minpoll",
+ /* 102 360 T_Minsane */ "minsane",
+ /* 103 361 T_Mode */ "mode",
+ /* 104 362 T_Mode7 */ "mode7",
+ /* 105 363 T_Monitor */ "monitor",
+ /* 106 364 T_Month */ "month",
+ /* 107 365 T_Mru */ "mru",
+ /* 108 366 T_Multicastclient */ "multicastclient",
+ /* 109 367 T_Nic */ "nic",
+ /* 110 368 T_Nolink */ "nolink",
+ /* 111 369 T_Nomodify */ "nomodify",
+ /* 112 370 T_Nomrulist */ "nomrulist",
+ /* 113 371 T_None */ "none",
+ /* 114 372 T_Nonvolatile */ "nonvolatile",
+ /* 115 373 T_Noepeer */ "noepeer",
+ /* 116 374 T_Nopeer */ "nopeer",
+ /* 117 375 T_Noquery */ "noquery",
+ /* 118 376 T_Noselect */ "noselect",
+ /* 119 377 T_Noserve */ "noserve",
+ /* 120 378 T_Notrap */ "notrap",
+ /* 121 379 T_Notrust */ "notrust",
+ /* 122 380 T_Ntp */ "ntp",
+ /* 123 381 T_Ntpport */ "ntpport",
+ /* 124 382 T_NtpSignDsocket */ "ntpsigndsocket",
+ /* 125 383 T_Orphan */ "orphan",
+ /* 126 384 T_Orphanwait */ "orphanwait",
+ /* 127 385 T_PCEdigest */ "peer_clear_digest_early",
+ /* 128 386 T_Panic */ "panic",
+ /* 129 387 T_Peer */ "peer",
+ /* 130 388 T_Peerstats */ "peerstats",
+ /* 131 389 T_Phone */ "phone",
+ /* 132 390 T_Pid */ "pid",
+ /* 133 391 T_Pidfile */ "pidfile",
+ /* 134 392 T_Pool */ "pool",
+ /* 135 393 T_Port */ "port",
+ /* 136 394 T_Preempt */ "preempt",
+ /* 137 395 T_Prefer */ "prefer",
+ /* 138 396 T_Protostats */ "protostats",
+ /* 139 397 T_Pw */ "pw",
+ /* 140 398 T_Randfile */ "randfile",
+ /* 141 399 T_Rawstats */ "rawstats",
+ /* 142 400 T_Refid */ "refid",
+ /* 143 401 T_Requestkey */ "requestkey",
+ /* 144 402 T_Reset */ "reset",
+ /* 145 403 T_Restrict */ "restrict",
+ /* 146 404 T_Revoke */ "revoke",
+ /* 147 405 T_Rlimit */ "rlimit",
+ /* 148 406 T_Saveconfigdir */ "saveconfigdir",
+ /* 149 407 T_Server */ "server",
+ /* 150 408 T_Setvar */ "setvar",
+ /* 151 409 T_Source */ "source",
+ /* 152 410 T_Stacksize */ "stacksize",
+ /* 153 411 T_Statistics */ "statistics",
+ /* 154 412 T_Stats */ "stats",
+ /* 155 413 T_Statsdir */ "statsdir",
+ /* 156 414 T_Step */ "step",
+ /* 157 415 T_Stepback */ "stepback",
+ /* 158 416 T_Stepfwd */ "stepfwd",
+ /* 159 417 T_Stepout */ "stepout",
+ /* 160 418 T_Stratum */ "stratum",
+ /* 161 419 T_String */ NULL,
+ /* 162 420 T_Sys */ "sys",
+ /* 163 421 T_Sysstats */ "sysstats",
+ /* 164 422 T_Tick */ "tick",
+ /* 165 423 T_Time1 */ "time1",
+ /* 166 424 T_Time2 */ "time2",
+ /* 167 425 T_Timer */ "timer",
+ /* 168 426 T_Timingstats */ "timingstats",
+ /* 169 427 T_Tinker */ "tinker",
+ /* 170 428 T_Tos */ "tos",
+ /* 171 429 T_Trap */ "trap",
+ /* 172 430 T_True */ "true",
+ /* 173 431 T_Trustedkey */ "trustedkey",
+ /* 174 432 T_Ttl */ "ttl",
+ /* 175 433 T_Type */ "type",
+ /* 176 434 T_U_int */ NULL,
+ /* 177 435 T_UEcrypto */ "unpeer_crypto_early",
+ /* 178 436 T_UEcryptonak */ "unpeer_crypto_nak_early",
+ /* 179 437 T_UEdigest */ "unpeer_digest_early",
+ /* 180 438 T_Unconfig */ "unconfig",
+ /* 181 439 T_Unpeer */ "unpeer",
+ /* 182 440 T_Version */ "version",
+ /* 183 441 T_WanderThreshold */ NULL,
+ /* 184 442 T_Week */ "week",
+ /* 185 443 T_Wildcard */ "wildcard",
+ /* 186 444 T_Xleave */ "xleave",
+ /* 187 445 T_Year */ "year",
+ /* 188 446 T_Flag */ NULL,
+ /* 189 447 T_EOC */ NULL,
+ /* 190 448 T_Simulate */ "simulate",
+ /* 191 449 T_Beep_Delay */ "beep_delay",
+ /* 192 450 T_Sim_Duration */ "simulation_duration",
+ /* 193 451 T_Server_Offset */ "server_offset",
+ /* 194 452 T_Duration */ "duration",
+ /* 195 453 T_Freq_Offset */ "freq_offset",
+ /* 196 454 T_Wander */ "wander",
+ /* 197 455 T_Jitter */ "jitter",
+ /* 198 456 T_Prop_Delay */ "prop_delay",
+ /* 199 457 T_Proc_Delay */ "proc_delay"
+};
+
+#define SCANNER_INIT_S 940
+
+const scan_state sst[943] = {
+/*SS_T( ch, f-by, match, other ), */
+ 0, /* 0 */
+ S_ST( '-', 3, 327, 0 ), /* 1 */
+ S_ST( '.', 3, 3, 1 ), /* 2 */
+ S_ST( '.', 3, 293, 0 ), /* 3 . */
+ S_ST( 'a', 3, 23, 2 ), /* 4 */
+ S_ST( 'b', 3, 6, 0 ), /* 5 a */
+ S_ST( 'b', 3, 7, 0 ), /* 6 ab */
+ S_ST( 'r', 3, 8, 0 ), /* 7 abb */
+ S_ST( 'e', 3, 258, 0 ), /* 8 abbr */
+ S_ST( 'g', 3, 259, 5 ), /* 9 a */
+ S_ST( 'l', 3, 260, 9 ), /* 10 a */
+ S_ST( 'a', 3, 261, 0 ), /* 11 all */
+ S_ST( 'p', 3, 13, 11 ), /* 12 all */
+ S_ST( 'e', 3, 14, 0 ), /* 13 allp */
+ S_ST( 'e', 3, 15, 0 ), /* 14 allpe */
+ S_ST( 'r', 3, 262, 0 ), /* 15 allpee */
+ S_ST( 'u', 3, 17, 10 ), /* 16 a */
+ S_ST( 't', 3, 18, 0 ), /* 17 au */
+ S_ST( 'o', 3, 21, 263 ), /* 18 aut */
+ S_ST( 'k', 3, 20, 0 ), /* 19 auto */
+ S_ST( 'e', 3, 264, 0 ), /* 20 autok */
+ S_ST( 'm', 3, 22, 19 ), /* 21 auto */
+ S_ST( 'a', 3, 265, 0 ), /* 22 autom */
+ S_ST( 'v', 3, 24, 16 ), /* 23 a */
+ S_ST( 'e', 3, 25, 0 ), /* 24 av */
+ S_ST( 'r', 3, 26, 0 ), /* 25 ave */
+ S_ST( 'a', 3, 27, 0 ), /* 26 aver */
+ S_ST( 'g', 3, 266, 0 ), /* 27 avera */
+ S_ST( 'b', 3, 75, 4 ), /* 28 */
+ S_ST( 'a', 3, 30, 0 ), /* 29 b */
+ S_ST( 's', 3, 31, 0 ), /* 30 ba */
+ S_ST( 'e', 3, 32, 0 ), /* 31 bas */
+ S_ST( 'd', 3, 33, 0 ), /* 32 base */
+ S_ST( 'a', 3, 34, 0 ), /* 33 based */
+ S_ST( 't', 3, 267, 0 ), /* 34 baseda */
+ S_ST( 'c', 3, 40, 29 ), /* 35 b */
+ S_ST( 'l', 3, 37, 0 ), /* 36 bc */
+ S_ST( 'i', 3, 38, 0 ), /* 37 bcl */
+ S_ST( 'e', 3, 39, 0 ), /* 38 bcli */
+ S_ST( 'n', 3, 268, 0 ), /* 39 bclie */
+ S_ST( 'p', 3, 41, 36 ), /* 40 bc */
+ S_ST( 'o', 3, 42, 0 ), /* 41 bcp */
+ S_ST( 'l', 3, 43, 0 ), /* 42 bcpo */
+ S_ST( 'l', 3, 44, 0 ), /* 43 bcpol */
+ S_ST( 'b', 3, 45, 0 ), /* 44 bcpoll */
+ S_ST( 's', 3, 46, 0 ), /* 45 bcpollb */
+ S_ST( 't', 3, 47, 0 ), /* 46 bcpollbs */
+ S_ST( 'e', 3, 269, 0 ), /* 47 bcpollbst */
+ S_ST( 'e', 3, 52, 35 ), /* 48 b */
+ S_ST( 'a', 3, 50, 0 ), /* 49 be */
+ S_ST( 'c', 3, 51, 0 ), /* 50 bea */
+ S_ST( 'o', 3, 270, 0 ), /* 51 beac */
+ S_ST( 'e', 3, 53, 49 ), /* 52 be */
+ S_ST( 'p', 3, 54, 0 ), /* 53 bee */
+ S_ST( '_', 3, 55, 0 ), /* 54 beep */
+ S_ST( 'd', 3, 56, 0 ), /* 55 beep_ */
+ S_ST( 'e', 3, 57, 0 ), /* 56 beep_d */
+ S_ST( 'l', 3, 58, 0 ), /* 57 beep_de */
+ S_ST( 'a', 3, 449, 0 ), /* 58 beep_del */
+ S_ST( 'r', 3, 60, 48 ), /* 59 b */
+ S_ST( 'o', 3, 61, 0 ), /* 60 br */
+ S_ST( 'a', 3, 62, 0 ), /* 61 bro */
+ S_ST( 'd', 3, 63, 0 ), /* 62 broa */
+ S_ST( 'c', 3, 64, 0 ), /* 63 broad */
+ S_ST( 'a', 3, 65, 0 ), /* 64 broadc */
+ S_ST( 's', 3, 271, 0 ), /* 65 broadca */
+ S_ST( 'c', 3, 67, 0 ), /* 66 broadcast */
+ S_ST( 'l', 3, 68, 0 ), /* 67 broadcastc */
+ S_ST( 'i', 3, 69, 0 ), /* 68 broadcastcl */
+ S_ST( 'e', 3, 70, 0 ), /* 69 broadcastcli */
+ S_ST( 'n', 3, 272, 0 ), /* 70 broadcastclie */
+ S_ST( 'd', 3, 72, 66 ), /* 71 broadcast */
+ S_ST( 'e', 3, 73, 0 ), /* 72 broadcastd */
+ S_ST( 'l', 3, 74, 0 ), /* 73 broadcastde */
+ S_ST( 'a', 3, 273, 0 ), /* 74 broadcastdel */
+ S_ST( 'u', 3, 76, 59 ), /* 75 b */
+ S_ST( 'r', 3, 77, 0 ), /* 76 bu */
+ S_ST( 's', 3, 274, 0 ), /* 77 bur */
+ S_ST( 'c', 3, 118, 28 ), /* 78 */
+ S_ST( 'a', 3, 80, 0 ), /* 79 c */
+ S_ST( 'l', 3, 81, 0 ), /* 80 ca */
+ S_ST( 'i', 3, 82, 0 ), /* 81 cal */
+ S_ST( 'b', 3, 83, 0 ), /* 82 cali */
+ S_ST( 'r', 3, 84, 0 ), /* 83 calib */
+ S_ST( 'a', 3, 85, 0 ), /* 84 calibr */
+ S_ST( 't', 3, 275, 0 ), /* 85 calibra */
+ S_ST( 'e', 3, 87, 79 ), /* 86 c */
+ S_ST( 'i', 3, 88, 0 ), /* 87 ce */
+ S_ST( 'l', 3, 89, 0 ), /* 88 cei */
+ S_ST( 'i', 3, 90, 0 ), /* 89 ceil */
+ S_ST( 'n', 3, 276, 0 ), /* 90 ceili */
+ S_ST( 'l', 3, 92, 86 ), /* 91 c */
+ S_ST( 'o', 3, 93, 0 ), /* 92 cl */
+ S_ST( 'c', 3, 94, 0 ), /* 93 clo */
+ S_ST( 'k', 3, 95, 0 ), /* 94 cloc */
+ S_ST( 's', 3, 96, 0 ), /* 95 clock */
+ S_ST( 't', 3, 97, 0 ), /* 96 clocks */
+ S_ST( 'a', 3, 98, 0 ), /* 97 clockst */
+ S_ST( 't', 3, 277, 0 ), /* 98 clocksta */
+ S_ST( 'o', 3, 103, 91 ), /* 99 c */
+ S_ST( 'h', 3, 101, 0 ), /* 100 co */
+ S_ST( 'o', 3, 102, 0 ), /* 101 coh */
+ S_ST( 'r', 3, 278, 0 ), /* 102 coho */
+ S_ST( 'n', 3, 104, 100 ), /* 103 co */
+ S_ST( 't', 3, 105, 0 ), /* 104 con */
+ S_ST( 'r', 3, 106, 0 ), /* 105 cont */
+ S_ST( 'o', 3, 107, 0 ), /* 106 contr */
+ S_ST( 'l', 3, 108, 0 ), /* 107 contro */
+ S_ST( 'k', 3, 109, 0 ), /* 108 control */
+ S_ST( 'e', 3, 279, 0 ), /* 109 controlk */
+ S_ST( 'r', 3, 111, 99 ), /* 110 c */
+ S_ST( 'y', 3, 112, 0 ), /* 111 cr */
+ S_ST( 'p', 3, 113, 0 ), /* 112 cry */
+ S_ST( 't', 3, 280, 0 ), /* 113 cryp */
+ S_ST( 's', 3, 115, 0 ), /* 114 crypto */
+ S_ST( 't', 3, 116, 0 ), /* 115 cryptos */
+ S_ST( 'a', 3, 117, 0 ), /* 116 cryptost */
+ S_ST( 't', 3, 281, 0 ), /* 117 cryptosta */
+ S_ST( 't', 3, 282, 110 ), /* 118 c */
+ S_ST( 'd', 3, 153, 78 ), /* 119 */
+ S_ST( 'a', 3, 283, 0 ), /* 120 d */
+ S_ST( 'e', 3, 122, 120 ), /* 121 d */
+ S_ST( 'f', 3, 123, 0 ), /* 122 de */
+ S_ST( 'a', 3, 124, 0 ), /* 123 def */
+ S_ST( 'u', 3, 125, 0 ), /* 124 defa */
+ S_ST( 'l', 3, 284, 0 ), /* 125 defau */
+ S_ST( 'i', 3, 130, 121 ), /* 126 d */
+ S_ST( 'g', 3, 128, 0 ), /* 127 di */
+ S_ST( 'e', 3, 129, 0 ), /* 128 dig */
+ S_ST( 's', 3, 285, 0 ), /* 129 dige */
+ S_ST( 's', 3, 137, 127 ), /* 130 di */
+ S_ST( 'a', 3, 132, 0 ), /* 131 dis */
+ S_ST( 'b', 3, 133, 0 ), /* 132 disa */
+ S_ST( 'l', 3, 286, 0 ), /* 133 disab */
+ S_ST( 'c', 3, 135, 131 ), /* 134 dis */
+ S_ST( 'a', 3, 136, 0 ), /* 135 disc */
+ S_ST( 'r', 3, 287, 0 ), /* 136 disca */
+ S_ST( 'p', 3, 138, 134 ), /* 137 dis */
+ S_ST( 'e', 3, 139, 0 ), /* 138 disp */
+ S_ST( 'r', 3, 140, 0 ), /* 139 dispe */
+ S_ST( 's', 3, 141, 0 ), /* 140 disper */
+ S_ST( 'i', 3, 142, 0 ), /* 141 dispers */
+ S_ST( 'o', 3, 288, 0 ), /* 142 dispersi */
+ S_ST( 'r', 3, 150, 126 ), /* 143 d */
+ S_ST( 'i', 3, 145, 0 ), /* 144 dr */
+ S_ST( 'f', 3, 146, 0 ), /* 145 dri */
+ S_ST( 't', 3, 147, 0 ), /* 146 drif */
+ S_ST( 'f', 3, 148, 0 ), /* 147 drift */
+ S_ST( 'i', 3, 149, 0 ), /* 148 driftf */
+ S_ST( 'l', 3, 290, 0 ), /* 149 driftfi */
+ S_ST( 'o', 3, 291, 144 ), /* 150 dr */
+ S_ST( 's', 3, 152, 143 ), /* 151 d */
+ S_ST( 'c', 3, 292, 0 ), /* 152 ds */
+ S_ST( 'u', 3, 154, 151 ), /* 153 d */
+ S_ST( 'r', 3, 155, 0 ), /* 154 du */
+ S_ST( 'a', 3, 156, 0 ), /* 155 dur */
+ S_ST( 't', 3, 157, 0 ), /* 156 dura */
+ S_ST( 'i', 3, 158, 0 ), /* 157 durat */
+ S_ST( 'o', 3, 452, 0 ), /* 158 durati */
+ S_ST( 'e', 3, 164, 119 ), /* 159 */
+ S_ST( 'n', 3, 295, 0 ), /* 160 e */
+ S_ST( 'a', 3, 162, 0 ), /* 161 en */
+ S_ST( 'b', 3, 163, 0 ), /* 162 ena */
+ S_ST( 'l', 3, 294, 0 ), /* 163 enab */
+ S_ST( 'p', 3, 165, 160 ), /* 164 e */
+ S_ST( 'e', 3, 166, 0 ), /* 165 ep */
+ S_ST( 'e', 3, 296, 0 ), /* 166 epe */
+ S_ST( 'f', 3, 188, 159 ), /* 167 */
+ S_ST( 'i', 3, 169, 0 ), /* 168 f */
+ S_ST( 'l', 3, 298, 0 ), /* 169 fi */
+ S_ST( 'g', 3, 171, 0 ), /* 170 file */
+ S_ST( 'e', 3, 299, 0 ), /* 171 fileg */
+ S_ST( 'n', 3, 173, 170 ), /* 172 file */
+ S_ST( 'u', 3, 300, 0 ), /* 173 filen */
+ S_ST( 'l', 3, 178, 168 ), /* 174 f */
+ S_ST( 'a', 3, 177, 0 ), /* 175 fl */
+ S_ST( 'g', 3, 304, 0 ), /* 176 fla */
+ S_ST( 'k', 3, 305, 176 ), /* 177 fla */
+ S_ST( 'o', 3, 179, 175 ), /* 178 fl */
+ S_ST( 'o', 3, 306, 0 ), /* 179 flo */
+ S_ST( 'r', 3, 181, 174 ), /* 180 f */
+ S_ST( 'e', 3, 307, 0 ), /* 181 fr */
+ S_ST( '_', 3, 183, 0 ), /* 182 freq */
+ S_ST( 'o', 3, 184, 0 ), /* 183 freq_ */
+ S_ST( 'f', 3, 185, 0 ), /* 184 freq_o */
+ S_ST( 'f', 3, 186, 0 ), /* 185 freq_of */
+ S_ST( 's', 3, 187, 0 ), /* 186 freq_off */
+ S_ST( 'e', 3, 453, 0 ), /* 187 freq_offs */
+ S_ST( 'u', 3, 189, 180 ), /* 188 f */
+ S_ST( 'd', 3, 190, 0 ), /* 189 fu */
+ S_ST( 'g', 3, 308, 0 ), /* 190 fud */
+ S_ST( 'h', 3, 194, 167 ), /* 191 */
+ S_ST( 'o', 3, 193, 0 ), /* 192 h */
+ S_ST( 's', 3, 309, 0 ), /* 193 ho */
+ S_ST( 'u', 3, 195, 192 ), /* 194 h */
+ S_ST( 'f', 3, 196, 0 ), /* 195 hu */
+ S_ST( 'f', 3, 197, 0 ), /* 196 huf */
+ S_ST( 'p', 3, 198, 0 ), /* 197 huff */
+ S_ST( 'u', 3, 199, 0 ), /* 198 huffp */
+ S_ST( 'f', 3, 310, 0 ), /* 199 huffpu */
+ S_ST( 'i', 3, 241, 191 ), /* 200 */
+ S_ST( 'b', 3, 202, 0 ), /* 201 i */
+ S_ST( 'u', 3, 203, 0 ), /* 202 ib */
+ S_ST( 'r', 3, 204, 0 ), /* 203 ibu */
+ S_ST( 's', 3, 311, 0 ), /* 204 ibur */
+ S_ST( 'd', 3, 206, 201 ), /* 205 i */
+ S_ST( 'e', 3, 207, 0 ), /* 206 id */
+ S_ST( 'n', 3, 312, 0 ), /* 207 ide */
+ S_ST( 'g', 3, 209, 205 ), /* 208 i */
+ S_ST( 'n', 3, 210, 0 ), /* 209 ig */
+ S_ST( 'o', 3, 211, 0 ), /* 210 ign */
+ S_ST( 'r', 3, 313, 0 ), /* 211 igno */
+ S_ST( 'n', 3, 235, 208 ), /* 212 i */
+ S_ST( 'c', 3, 225, 0 ), /* 213 in */
+ S_ST( 'a', 3, 215, 0 ), /* 214 inc */
+ S_ST( 'l', 3, 216, 0 ), /* 215 inca */
+ S_ST( 'l', 3, 217, 0 ), /* 216 incal */
+ S_ST( 'o', 3, 314, 0 ), /* 217 incall */
+ S_ST( 'l', 3, 219, 214 ), /* 218 inc */
+ S_ST( 'u', 3, 220, 0 ), /* 219 incl */
+ S_ST( 'd', 3, 221, 0 ), /* 220 inclu */
+ S_ST( 'e', 3, 222, 0 ), /* 221 includ */
+ S_ST( 'f', 3, 223, 0 ), /* 222 include */
+ S_ST( 'i', 3, 224, 0 ), /* 223 includef */
+ S_ST( 'l', 3, 318, 0 ), /* 224 includefi */
+ S_ST( 'm', 3, 226, 218 ), /* 225 inc */
+ S_ST( 'e', 3, 315, 0 ), /* 226 incm */
+ S_ST( 'i', 3, 228, 213 ), /* 227 in */
+ S_ST( 't', 3, 233, 0 ), /* 228 ini */
+ S_ST( 'a', 3, 230, 0 ), /* 229 init */
+ S_ST( 'l', 3, 231, 0 ), /* 230 inita */
+ S_ST( 'l', 3, 232, 0 ), /* 231 inital */
+ S_ST( 'o', 3, 316, 0 ), /* 232 initall */
+ S_ST( 'm', 3, 234, 229 ), /* 233 init */
+ S_ST( 'e', 3, 317, 0 ), /* 234 initm */
+ S_ST( 't', 3, 236, 227 ), /* 235 in */
+ S_ST( 'e', 3, 237, 0 ), /* 236 int */
+ S_ST( 'r', 3, 238, 0 ), /* 237 inte */
+ S_ST( 'f', 3, 239, 0 ), /* 238 inter */
+ S_ST( 'a', 3, 240, 0 ), /* 239 interf */
+ S_ST( 'c', 3, 320, 0 ), /* 240 interfa */
+ S_ST( 'p', 3, 250, 322 ), /* 241 i */
+ S_ST( 'p', 3, 243, 0 ), /* 242 ip */
+ S_ST( 'e', 3, 244, 0 ), /* 243 ipp */
+ S_ST( 'e', 3, 245, 0 ), /* 244 ippe */
+ S_ST( 'r', 3, 246, 0 ), /* 245 ippee */
+ S_ST( 'l', 3, 247, 0 ), /* 246 ippeer */
+ S_ST( 'i', 3, 248, 0 ), /* 247 ippeerl */
+ S_ST( 'm', 3, 249, 0 ), /* 248 ippeerli */
+ S_ST( 'i', 3, 323, 0 ), /* 249 ippeerlim */
+ S_ST( 'v', 3, 326, 242 ), /* 250 ip */
+ S_ST( 'j', 3, 252, 200 ), /* 251 */
+ S_ST( 'i', 3, 253, 0 ), /* 252 j */
+ S_ST( 't', 3, 254, 0 ), /* 253 ji */
+ S_ST( 't', 3, 255, 0 ), /* 254 jit */
+ S_ST( 'e', 3, 455, 0 ), /* 255 jitt */
+ S_ST( 'k', 3, 434, 251 ), /* 256 */
+ S_ST( 'e', 3, 329, 0 ), /* 257 k */
+ S_ST( 'v', 1, 0, 0 ), /* 258 T_Abbrev */
+ S_ST( 'e', 0, 0, 0 ), /* 259 T_Age */
+ S_ST( 'l', 0, 12, 0 ), /* 260 T_All */
+ S_ST( 'n', 0, 0, 0 ), /* 261 T_Allan */
+ S_ST( 's', 0, 0, 0 ), /* 262 T_Allpeers */
+ S_ST( 'h', 0, 0, 0 ), /* 263 T_Auth */
+ S_ST( 'y', 0, 0, 0 ), /* 264 T_Autokey */
+ S_ST( 'x', 0, 0, 0 ), /* 265 T_Automax */
+ S_ST( 'e', 0, 0, 0 ), /* 266 T_Average */
+ S_ST( 'e', 1, 0, 0 ), /* 267 T_Basedate */
+ S_ST( 't', 0, 0, 0 ), /* 268 T_Bclient */
+ S_ST( 'p', 0, 0, 0 ), /* 269 T_Bcpollbstep */
+ S_ST( 'n', 0, 0, 0 ), /* 270 T_Beacon */
+ S_ST( 't', 1, 71, 0 ), /* 271 T_Broadcast */
+ S_ST( 't', 0, 0, 0 ), /* 272 T_Broadcastclient */
+ S_ST( 'y', 0, 0, 0 ), /* 273 T_Broadcastdelay */
+ S_ST( 't', 0, 0, 0 ), /* 274 T_Burst */
+ S_ST( 'e', 0, 0, 0 ), /* 275 T_Calibrate */
+ S_ST( 'g', 0, 0, 0 ), /* 276 T_Ceiling */
+ S_ST( 's', 0, 0, 0 ), /* 277 T_Clockstats */
+ S_ST( 't', 0, 0, 0 ), /* 278 T_Cohort */
+ S_ST( 'y', 0, 0, 0 ), /* 279 T_ControlKey */
+ S_ST( 'o', 0, 114, 0 ), /* 280 T_Crypto */
+ S_ST( 's', 0, 0, 0 ), /* 281 T_Cryptostats */
+ S_ST( 'l', 0, 0, 0 ), /* 282 T_Ctl */
+ S_ST( 'y', 0, 0, 0 ), /* 283 T_Day */
+ S_ST( 't', 0, 0, 0 ), /* 284 T_Default */
+ S_ST( 't', 1, 0, 0 ), /* 285 T_Digest */
+ S_ST( 'e', 0, 0, 0 ), /* 286 T_Disable */
+ S_ST( 'd', 0, 0, 0 ), /* 287 T_Discard */
+ S_ST( 'n', 0, 0, 0 ), /* 288 T_Dispersion */
+ S_ST( 'r', 3, 297, 0 ), /* 289 ke */
+ S_ST( 'e', 1, 0, 0 ), /* 290 T_Driftfile */
+ S_ST( 'p', 0, 0, 0 ), /* 291 T_Drop */
+ S_ST( 'p', 0, 0, 0 ), /* 292 T_Dscp */
+ S_ST( '.', 0, 0, 0 ), /* 293 T_Ellipsis */
+ S_ST( 'e', 0, 0, 0 ), /* 294 T_Enable */
+ S_ST( 'd', 0, 0, 161 ), /* 295 T_End */
+ S_ST( 'r', 0, 0, 0 ), /* 296 T_Epeer */
+ S_ST( 'n', 3, 319, 0 ), /* 297 ker */
+ S_ST( 'e', 1, 172, 0 ), /* 298 T_File */
+ S_ST( 'n', 0, 0, 0 ), /* 299 T_Filegen */
+ S_ST( 'm', 0, 0, 0 ), /* 300 T_Filenum */
+ S_ST( '1', 0, 0, 0 ), /* 301 T_Flag1 */
+ S_ST( '2', 0, 0, 301 ), /* 302 T_Flag2 */
+ S_ST( '3', 0, 0, 302 ), /* 303 T_Flag3 */
+ S_ST( '4', 0, 0, 303 ), /* 304 T_Flag4 */
+ S_ST( 'e', 0, 0, 0 ), /* 305 T_Flake */
+ S_ST( 'r', 0, 0, 0 ), /* 306 T_Floor */
+ S_ST( 'q', 0, 182, 0 ), /* 307 T_Freq */
+ S_ST( 'e', 1, 0, 0 ), /* 308 T_Fudge */
+ S_ST( 't', 1, 0, 0 ), /* 309 T_Host */
+ S_ST( 'f', 0, 0, 0 ), /* 310 T_Huffpuff */
+ S_ST( 't', 0, 0, 0 ), /* 311 T_Iburst */
+ S_ST( 't', 1, 0, 0 ), /* 312 T_Ident */
+ S_ST( 'e', 0, 0, 0 ), /* 313 T_Ignore */
+ S_ST( 'c', 0, 0, 0 ), /* 314 T_Incalloc */
+ S_ST( 'm', 0, 0, 0 ), /* 315 T_Incmem */
+ S_ST( 'c', 0, 0, 0 ), /* 316 T_Initalloc */
+ S_ST( 'm', 0, 0, 0 ), /* 317 T_Initmem */
+ S_ST( 'e', 1, 0, 0 ), /* 318 T_Includefile */
+ S_ST( 'e', 3, 328, 0 ), /* 319 kern */
+ S_ST( 'e', 0, 0, 0 ), /* 320 T_Interface */
+ S_ST( 'd', 3, 419, 0 ), /* 321 keys */
+ S_ST( 'o', 0, 0, 212 ), /* 322 T_Io */
+ S_ST( 't', 0, 0, 0 ), /* 323 T_Ippeerlimit */
+ S_ST( '4', 0, 0, 0 ), /* 324 T_Ipv4 */
+ S_ST( '4', 0, 0, 0 ), /* 325 T_Ipv4_flag */
+ S_ST( '6', 0, 0, 324 ), /* 326 T_Ipv6 */
+ S_ST( '6', 0, 0, 325 ), /* 327 T_Ipv6_flag */
+ S_ST( 'l', 0, 0, 0 ), /* 328 T_Kernel */
+ S_ST( 'y', 0, 330, 289 ), /* 329 T_Key */
+ S_ST( 's', 1, 321, 0 ), /* 330 T_Keys */
+ S_ST( 'r', 1, 0, 0 ), /* 331 T_Keysdir */
+ S_ST( 'd', 0, 0, 0 ), /* 332 T_Kod */
+ S_ST( 'p', 0, 0, 0 ), /* 333 T_Mssntp */
+ S_ST( 'e', 1, 0, 0 ), /* 334 T_Leapfile */
+ S_ST( 'l', 0, 0, 0 ), /* 335 T_Leapsmearinterval */
+ S_ST( 'd', 0, 0, 0 ), /* 336 T_Limited */
+ S_ST( 'k', 0, 0, 0 ), /* 337 T_Link */
+ S_ST( 'n', 0, 0, 0 ), /* 338 T_Listen */
+ S_ST( 'g', 2, 0, 0 ), /* 339 T_Logconfig */
+ S_ST( 'e', 1, 0, 0 ), /* 340 T_Logfile */
+ S_ST( 's', 0, 0, 0 ), /* 341 T_Loopstats */
+ S_ST( 'p', 0, 0, 0 ), /* 342 T_Lowpriotrap */
+ S_ST( 't', 1, 0, 0 ), /* 343 T_Manycastclient */
+ S_ST( 'r', 2, 0, 0 ), /* 344 T_Manycastserver */
+ S_ST( 'k', 0, 0, 0 ), /* 345 T_Mask */
+ S_ST( 'e', 0, 0, 0 ), /* 346 T_Maxage */
+ S_ST( 'k', 0, 0, 0 ), /* 347 T_Maxclock */
+ S_ST( 'h', 0, 0, 0 ), /* 348 T_Maxdepth */
+ S_ST( 't', 0, 0, 0 ), /* 349 T_Maxdist */
+ S_ST( 'm', 0, 0, 0 ), /* 350 T_Maxmem */
+ S_ST( 'l', 0, 0, 0 ), /* 351 T_Maxpoll */
+ S_ST( 's', 0, 0, 0 ), /* 352 T_Mdnstries */
+ S_ST( 'm', 0, 552, 0 ), /* 353 T_Mem */
+ S_ST( 'k', 0, 0, 0 ), /* 354 T_Memlock */
+ S_ST( 'k', 0, 0, 0 ), /* 355 T_Minclock */
+ S_ST( 'h', 0, 0, 0 ), /* 356 T_Mindepth */
+ S_ST( 't', 0, 0, 0 ), /* 357 T_Mindist */
+ S_ST( 'm', 0, 0, 0 ), /* 358 T_Minimum */
+ S_ST( 'l', 0, 0, 0 ), /* 359 T_Minpoll */
+ S_ST( 'e', 0, 0, 0 ), /* 360 T_Minsane */
+ S_ST( 'e', 0, 362, 0 ), /* 361 T_Mode */
+ S_ST( '7', 0, 0, 0 ), /* 362 T_Mode7 */
+ S_ST( 'r', 0, 0, 0 ), /* 363 T_Monitor */
+ S_ST( 'h', 0, 0, 0 ), /* 364 T_Month */
+ S_ST( 'u', 0, 0, 0 ), /* 365 T_Mru */
+ S_ST( 't', 2, 0, 0 ), /* 366 T_Multicastclient */
+ S_ST( 'c', 0, 0, 0 ), /* 367 T_Nic */
+ S_ST( 'k', 0, 0, 0 ), /* 368 T_Nolink */
+ S_ST( 'y', 0, 0, 0 ), /* 369 T_Nomodify */
+ S_ST( 't', 0, 0, 0 ), /* 370 T_Nomrulist */
+ S_ST( 'e', 0, 0, 0 ), /* 371 T_None */
+ S_ST( 'e', 0, 0, 0 ), /* 372 T_Nonvolatile */
+ S_ST( 'r', 0, 0, 0 ), /* 373 T_Noepeer */
+ S_ST( 'r', 0, 0, 0 ), /* 374 T_Nopeer */
+ S_ST( 'y', 0, 0, 0 ), /* 375 T_Noquery */
+ S_ST( 't', 0, 0, 0 ), /* 376 T_Noselect */
+ S_ST( 'e', 0, 0, 0 ), /* 377 T_Noserve */
+ S_ST( 'p', 0, 0, 0 ), /* 378 T_Notrap */
+ S_ST( 't', 0, 0, 0 ), /* 379 T_Notrust */
+ S_ST( 'p', 0, 652, 0 ), /* 380 T_Ntp */
+ S_ST( 't', 0, 0, 0 ), /* 381 T_Ntpport */
+ S_ST( 't', 1, 0, 0 ), /* 382 T_NtpSignDsocket */
+ S_ST( 'n', 0, 667, 0 ), /* 383 T_Orphan */
+ S_ST( 't', 0, 0, 0 ), /* 384 T_Orphanwait */
+ S_ST( 'y', 0, 0, 0 ), /* 385 T_PCEdigest */
+ S_ST( 'c', 0, 0, 0 ), /* 386 T_Panic */
+ S_ST( 'r', 1, 694, 0 ), /* 387 T_Peer */
+ S_ST( 's', 0, 0, 0 ), /* 388 T_Peerstats */
+ S_ST( 'e', 2, 0, 0 ), /* 389 T_Phone */
+ S_ST( 'd', 0, 702, 0 ), /* 390 T_Pid */
+ S_ST( 'e', 1, 0, 0 ), /* 391 T_Pidfile */
+ S_ST( 'l', 1, 0, 0 ), /* 392 T_Pool */
+ S_ST( 't', 0, 0, 0 ), /* 393 T_Port */
+ S_ST( 't', 0, 0, 0 ), /* 394 T_Preempt */
+ S_ST( 'r', 0, 0, 0 ), /* 395 T_Prefer */
+ S_ST( 's', 0, 0, 0 ), /* 396 T_Protostats */
+ S_ST( 'w', 1, 0, 708 ), /* 397 T_Pw */
+ S_ST( 'e', 1, 0, 0 ), /* 398 T_Randfile */
+ S_ST( 's', 0, 0, 0 ), /* 399 T_Rawstats */
+ S_ST( 'd', 1, 0, 0 ), /* 400 T_Refid */
+ S_ST( 'y', 0, 0, 0 ), /* 401 T_Requestkey */
+ S_ST( 't', 0, 0, 0 ), /* 402 T_Reset */
+ S_ST( 't', 0, 0, 0 ), /* 403 T_Restrict */
+ S_ST( 'e', 0, 0, 0 ), /* 404 T_Revoke */
+ S_ST( 't', 0, 0, 0 ), /* 405 T_Rlimit */
+ S_ST( 'r', 1, 0, 0 ), /* 406 T_Saveconfigdir */
+ S_ST( 'r', 1, 785, 0 ), /* 407 T_Server */
+ S_ST( 'r', 1, 0, 0 ), /* 408 T_Setvar */
+ S_ST( 'e', 0, 0, 0 ), /* 409 T_Source */
+ S_ST( 'e', 0, 0, 0 ), /* 410 T_Stacksize */
+ S_ST( 's', 0, 0, 0 ), /* 411 T_Statistics */
+ S_ST( 's', 0, 828, 823 ), /* 412 T_Stats */
+ S_ST( 'r', 1, 0, 0 ), /* 413 T_Statsdir */
+ S_ST( 'p', 0, 836, 0 ), /* 414 T_Step */
+ S_ST( 'k', 0, 0, 0 ), /* 415 T_Stepback */
+ S_ST( 'd', 0, 0, 0 ), /* 416 T_Stepfwd */
+ S_ST( 't', 0, 0, 0 ), /* 417 T_Stepout */
+ S_ST( 'm', 0, 0, 0 ), /* 418 T_Stratum */
+ S_ST( 'i', 3, 331, 0 ), /* 419 keysd */
+ S_ST( 's', 0, 843, 0 ), /* 420 T_Sys */
+ S_ST( 's', 0, 0, 0 ), /* 421 T_Sysstats */
+ S_ST( 'k', 0, 0, 0 ), /* 422 T_Tick */
+ S_ST( '1', 0, 0, 0 ), /* 423 T_Time1 */
+ S_ST( '2', 0, 0, 423 ), /* 424 T_Time2 */
+ S_ST( 'r', 0, 0, 424 ), /* 425 T_Timer */
+ S_ST( 's', 0, 0, 0 ), /* 426 T_Timingstats */
+ S_ST( 'r', 0, 0, 0 ), /* 427 T_Tinker */
+ S_ST( 's', 0, 0, 0 ), /* 428 T_Tos */
+ S_ST( 'p', 1, 0, 0 ), /* 429 T_Trap */
+ S_ST( 'e', 0, 0, 0 ), /* 430 T_True */
+ S_ST( 'y', 0, 0, 0 ), /* 431 T_Trustedkey */
+ S_ST( 'l', 0, 0, 0 ), /* 432 T_Ttl */
+ S_ST( 'e', 0, 0, 0 ), /* 433 T_Type */
+ S_ST( 'o', 3, 332, 257 ), /* 434 k */
+ S_ST( 'y', 0, 0, 0 ), /* 435 T_UEcrypto */
+ S_ST( 'y', 0, 0, 0 ), /* 436 T_UEcryptonak */
+ S_ST( 'y', 0, 0, 0 ), /* 437 T_UEdigest */
+ S_ST( 'g', 1, 0, 0 ), /* 438 T_Unconfig */
+ S_ST( 'r', 1, 885, 0 ), /* 439 T_Unpeer */
+ S_ST( 'n', 0, 0, 0 ), /* 440 T_Version */
+ S_ST( 'l', 3, 483, 256 ), /* 441 */
+ S_ST( 'k', 0, 0, 0 ), /* 442 T_Week */
+ S_ST( 'd', 0, 0, 0 ), /* 443 T_Wildcard */
+ S_ST( 'e', 0, 0, 0 ), /* 444 T_Xleave */
+ S_ST( 'r', 0, 0, 0 ), /* 445 T_Year */
+ S_ST( 'e', 3, 447, 0 ), /* 446 l */
+ S_ST( 'a', 3, 458, 0 ), /* 447 le */
+ S_ST( 'e', 0, 0, 0 ), /* 448 T_Simulate */
+ S_ST( 'y', 0, 0, 0 ), /* 449 T_Beep_Delay */
+ S_ST( 'n', 0, 0, 0 ), /* 450 T_Sim_Duration */
+ S_ST( 't', 0, 0, 0 ), /* 451 T_Server_Offset */
+ S_ST( 'n', 0, 0, 0 ), /* 452 T_Duration */
+ S_ST( 't', 0, 0, 0 ), /* 453 T_Freq_Offset */
+ S_ST( 'r', 0, 0, 0 ), /* 454 T_Wander */
+ S_ST( 'r', 0, 0, 0 ), /* 455 T_Jitter */
+ S_ST( 'y', 0, 0, 0 ), /* 456 T_Prop_Delay */
+ S_ST( 'y', 0, 0, 0 ), /* 457 T_Proc_Delay */
+ S_ST( 'p', 3, 462, 0 ), /* 458 lea */
+ S_ST( 'f', 3, 460, 0 ), /* 459 leap */
+ S_ST( 'i', 3, 461, 0 ), /* 460 leapf */
+ S_ST( 'l', 3, 334, 0 ), /* 461 leapfi */
+ S_ST( 's', 3, 463, 459 ), /* 462 leap */
+ S_ST( 'm', 3, 464, 0 ), /* 463 leaps */
+ S_ST( 'e', 3, 465, 0 ), /* 464 leapsm */
+ S_ST( 'a', 3, 466, 0 ), /* 465 leapsme */
+ S_ST( 'r', 3, 467, 0 ), /* 466 leapsmea */
+ S_ST( 'i', 3, 468, 0 ), /* 467 leapsmear */
+ S_ST( 'n', 3, 469, 0 ), /* 468 leapsmeari */
+ S_ST( 't', 3, 470, 0 ), /* 469 leapsmearin */
+ S_ST( 'e', 3, 471, 0 ), /* 470 leapsmearint */
+ S_ST( 'r', 3, 472, 0 ), /* 471 leapsmearinte */
+ S_ST( 'v', 3, 473, 0 ), /* 472 leapsmearinter */
+ S_ST( 'a', 3, 335, 0 ), /* 473 leapsmearinterv */
+ S_ST( 'i', 3, 480, 446 ), /* 474 l */
+ S_ST( 'm', 3, 476, 0 ), /* 475 li */
+ S_ST( 'i', 3, 477, 0 ), /* 476 lim */
+ S_ST( 't', 3, 478, 0 ), /* 477 limi */
+ S_ST( 'e', 3, 336, 0 ), /* 478 limit */
+ S_ST( 'n', 3, 337, 475 ), /* 479 li */
+ S_ST( 's', 3, 481, 479 ), /* 480 li */
+ S_ST( 't', 3, 482, 0 ), /* 481 lis */
+ S_ST( 'e', 3, 338, 0 ), /* 482 list */
+ S_ST( 'o', 3, 499, 474 ), /* 483 l */
+ S_ST( 'g', 3, 490, 0 ), /* 484 lo */
+ S_ST( 'c', 3, 486, 0 ), /* 485 log */
+ S_ST( 'o', 3, 487, 0 ), /* 486 logc */
+ S_ST( 'n', 3, 488, 0 ), /* 487 logco */
+ S_ST( 'f', 3, 489, 0 ), /* 488 logcon */
+ S_ST( 'i', 3, 339, 0 ), /* 489 logconf */
+ S_ST( 'f', 3, 491, 485 ), /* 490 log */
+ S_ST( 'i', 3, 492, 0 ), /* 491 logf */
+ S_ST( 'l', 3, 340, 0 ), /* 492 logfi */
+ S_ST( 'o', 3, 494, 484 ), /* 493 lo */
+ S_ST( 'p', 3, 495, 0 ), /* 494 loo */
+ S_ST( 's', 3, 496, 0 ), /* 495 loop */
+ S_ST( 't', 3, 497, 0 ), /* 496 loops */
+ S_ST( 'a', 3, 498, 0 ), /* 497 loopst */
+ S_ST( 't', 3, 341, 0 ), /* 498 loopsta */
+ S_ST( 'w', 3, 500, 493 ), /* 499 lo */
+ S_ST( 'p', 3, 501, 0 ), /* 500 low */
+ S_ST( 'r', 3, 502, 0 ), /* 501 lowp */
+ S_ST( 'i', 3, 503, 0 ), /* 502 lowpr */
+ S_ST( 'o', 3, 504, 0 ), /* 503 lowpri */
+ S_ST( 't', 3, 505, 0 ), /* 504 lowprio */
+ S_ST( 'r', 3, 506, 0 ), /* 505 lowpriot */
+ S_ST( 'a', 3, 342, 0 ), /* 506 lowpriotr */
+ S_ST( 'm', 3, 588, 441 ), /* 507 */
+ S_ST( 'a', 3, 526, 0 ), /* 508 m */
+ S_ST( 'n', 3, 510, 0 ), /* 509 ma */
+ S_ST( 'y', 3, 511, 0 ), /* 510 man */
+ S_ST( 'c', 3, 512, 0 ), /* 511 many */
+ S_ST( 'a', 3, 513, 0 ), /* 512 manyc */
+ S_ST( 's', 3, 514, 0 ), /* 513 manyca */
+ S_ST( 't', 3, 520, 0 ), /* 514 manycas */
+ S_ST( 'c', 3, 516, 0 ), /* 515 manycast */
+ S_ST( 'l', 3, 517, 0 ), /* 516 manycastc */
+ S_ST( 'i', 3, 518, 0 ), /* 517 manycastcl */
+ S_ST( 'e', 3, 519, 0 ), /* 518 manycastcli */
+ S_ST( 'n', 3, 343, 0 ), /* 519 manycastclie */
+ S_ST( 's', 3, 521, 515 ), /* 520 manycast */
+ S_ST( 'e', 3, 522, 0 ), /* 521 manycasts */
+ S_ST( 'r', 3, 523, 0 ), /* 522 manycastse */
+ S_ST( 'v', 3, 524, 0 ), /* 523 manycastser */
+ S_ST( 'e', 3, 344, 0 ), /* 524 manycastserv */
+ S_ST( 's', 3, 345, 509 ), /* 525 ma */
+ S_ST( 'x', 3, 541, 525 ), /* 526 ma */
+ S_ST( 'a', 3, 528, 0 ), /* 527 max */
+ S_ST( 'g', 3, 346, 0 ), /* 528 maxa */
+ S_ST( 'c', 3, 530, 527 ), /* 529 max */
+ S_ST( 'l', 3, 531, 0 ), /* 530 maxc */
+ S_ST( 'o', 3, 532, 0 ), /* 531 maxcl */
+ S_ST( 'c', 3, 347, 0 ), /* 532 maxclo */
+ S_ST( 'd', 3, 537, 529 ), /* 533 max */
+ S_ST( 'e', 3, 535, 0 ), /* 534 maxd */
+ S_ST( 'p', 3, 536, 0 ), /* 535 maxde */
+ S_ST( 't', 3, 348, 0 ), /* 536 maxdep */
+ S_ST( 'i', 3, 538, 534 ), /* 537 maxd */
+ S_ST( 's', 3, 349, 0 ), /* 538 maxdi */
+ S_ST( 'm', 3, 540, 533 ), /* 539 max */
+ S_ST( 'e', 3, 350, 0 ), /* 540 maxm */
+ S_ST( 'p', 3, 542, 539 ), /* 541 max */
+ S_ST( 'o', 3, 543, 0 ), /* 542 maxp */
+ S_ST( 'l', 3, 351, 0 ), /* 543 maxpo */
+ S_ST( 'd', 3, 545, 508 ), /* 544 m */
+ S_ST( 'n', 3, 546, 0 ), /* 545 md */
+ S_ST( 's', 3, 547, 0 ), /* 546 mdn */
+ S_ST( 't', 3, 548, 0 ), /* 547 mdns */
+ S_ST( 'r', 3, 549, 0 ), /* 548 mdnst */
+ S_ST( 'i', 3, 550, 0 ), /* 549 mdnstr */
+ S_ST( 'e', 3, 352, 0 ), /* 550 mdnstri */
+ S_ST( 'e', 3, 353, 544 ), /* 551 m */
+ S_ST( 'l', 3, 553, 0 ), /* 552 mem */
+ S_ST( 'o', 3, 554, 0 ), /* 553 meml */
+ S_ST( 'c', 3, 354, 0 ), /* 554 memlo */
+ S_ST( 'i', 3, 556, 551 ), /* 555 m */
+ S_ST( 'n', 3, 573, 0 ), /* 556 mi */
+ S_ST( 'c', 3, 558, 0 ), /* 557 min */
+ S_ST( 'l', 3, 559, 0 ), /* 558 minc */
+ S_ST( 'o', 3, 560, 0 ), /* 559 mincl */
+ S_ST( 'c', 3, 355, 0 ), /* 560 minclo */
+ S_ST( 'd', 3, 565, 557 ), /* 561 min */
+ S_ST( 'e', 3, 563, 0 ), /* 562 mind */
+ S_ST( 'p', 3, 564, 0 ), /* 563 minde */
+ S_ST( 't', 3, 356, 0 ), /* 564 mindep */
+ S_ST( 'i', 3, 566, 562 ), /* 565 mind */
+ S_ST( 's', 3, 357, 0 ), /* 566 mindi */
+ S_ST( 'i', 3, 568, 561 ), /* 567 min */
+ S_ST( 'm', 3, 569, 0 ), /* 568 mini */
+ S_ST( 'u', 3, 358, 0 ), /* 569 minim */
+ S_ST( 'p', 3, 571, 567 ), /* 570 min */
+ S_ST( 'o', 3, 572, 0 ), /* 571 minp */
+ S_ST( 'l', 3, 359, 0 ), /* 572 minpo */
+ S_ST( 's', 3, 574, 570 ), /* 573 min */
+ S_ST( 'a', 3, 575, 0 ), /* 574 mins */
+ S_ST( 'n', 3, 360, 0 ), /* 575 minsa */
+ S_ST( 'o', 3, 578, 555 ), /* 576 m */
+ S_ST( 'd', 3, 361, 0 ), /* 577 mo */
+ S_ST( 'n', 3, 582, 577 ), /* 578 mo */
+ S_ST( 'i', 3, 580, 0 ), /* 579 mon */
+ S_ST( 't', 3, 581, 0 ), /* 580 moni */
+ S_ST( 'o', 3, 363, 0 ), /* 581 monit */
+ S_ST( 't', 3, 364, 579 ), /* 582 mon */
+ S_ST( 'r', 3, 365, 576 ), /* 583 m */
+ S_ST( 's', 3, 585, 583 ), /* 584 m */
+ S_ST( 's', 3, 586, 0 ), /* 585 ms */
+ S_ST( 'n', 3, 587, 0 ), /* 586 mss */
+ S_ST( 't', 3, 333, 0 ), /* 587 mssn */
+ S_ST( 'u', 3, 589, 584 ), /* 588 m */
+ S_ST( 'l', 3, 590, 0 ), /* 589 mu */
+ S_ST( 't', 3, 591, 0 ), /* 590 mul */
+ S_ST( 'i', 3, 592, 0 ), /* 591 mult */
+ S_ST( 'c', 3, 593, 0 ), /* 592 multi */
+ S_ST( 'a', 3, 594, 0 ), /* 593 multic */
+ S_ST( 's', 3, 595, 0 ), /* 594 multica */
+ S_ST( 't', 3, 596, 0 ), /* 595 multicas */
+ S_ST( 'c', 3, 597, 0 ), /* 596 multicast */
+ S_ST( 'l', 3, 598, 0 ), /* 597 multicastc */
+ S_ST( 'i', 3, 599, 0 ), /* 598 multicastcl */
+ S_ST( 'e', 3, 600, 0 ), /* 599 multicastcli */
+ S_ST( 'n', 3, 366, 0 ), /* 600 multicastclie */
+ S_ST( 'n', 3, 648, 507 ), /* 601 */
+ S_ST( 'i', 3, 367, 0 ), /* 602 n */
+ S_ST( 'o', 3, 643, 602 ), /* 603 n */
+ S_ST( 'e', 3, 605, 0 ), /* 604 no */
+ S_ST( 'p', 3, 606, 0 ), /* 605 noe */
+ S_ST( 'e', 3, 607, 0 ), /* 606 noep */
+ S_ST( 'e', 3, 373, 0 ), /* 607 noepe */
+ S_ST( 'l', 3, 609, 604 ), /* 608 no */
+ S_ST( 'i', 3, 610, 0 ), /* 609 nol */
+ S_ST( 'n', 3, 368, 0 ), /* 610 noli */
+ S_ST( 'm', 3, 616, 608 ), /* 611 no */
+ S_ST( 'o', 3, 613, 0 ), /* 612 nom */
+ S_ST( 'd', 3, 614, 0 ), /* 613 nomo */
+ S_ST( 'i', 3, 615, 0 ), /* 614 nomod */
+ S_ST( 'f', 3, 369, 0 ), /* 615 nomodi */
+ S_ST( 'r', 3, 617, 612 ), /* 616 nom */
+ S_ST( 'u', 3, 618, 0 ), /* 617 nomr */
+ S_ST( 'l', 3, 619, 0 ), /* 618 nomru */
+ S_ST( 'i', 3, 620, 0 ), /* 619 nomrul */
+ S_ST( 's', 3, 370, 0 ), /* 620 nomruli */
+ S_ST( 'n', 3, 622, 611 ), /* 621 no */
+ S_ST( 'v', 3, 623, 371 ), /* 622 non */
+ S_ST( 'o', 3, 624, 0 ), /* 623 nonv */
+ S_ST( 'l', 3, 625, 0 ), /* 624 nonvo */
+ S_ST( 'a', 3, 626, 0 ), /* 625 nonvol */
+ S_ST( 't', 3, 627, 0 ), /* 626 nonvola */
+ S_ST( 'i', 3, 628, 0 ), /* 627 nonvolat */
+ S_ST( 'l', 3, 372, 0 ), /* 628 nonvolati */
+ S_ST( 'p', 3, 630, 621 ), /* 629 no */
+ S_ST( 'e', 3, 631, 0 ), /* 630 nop */
+ S_ST( 'e', 3, 374, 0 ), /* 631 nope */
+ S_ST( 'q', 3, 633, 629 ), /* 632 no */
+ S_ST( 'u', 3, 634, 0 ), /* 633 noq */
+ S_ST( 'e', 3, 635, 0 ), /* 634 noqu */
+ S_ST( 'r', 3, 375, 0 ), /* 635 noque */
+ S_ST( 's', 3, 637, 632 ), /* 636 no */
+ S_ST( 'e', 3, 641, 0 ), /* 637 nos */
+ S_ST( 'l', 3, 639, 0 ), /* 638 nose */
+ S_ST( 'e', 3, 640, 0 ), /* 639 nosel */
+ S_ST( 'c', 3, 376, 0 ), /* 640 nosele */
+ S_ST( 'r', 3, 642, 638 ), /* 641 nose */
+ S_ST( 'v', 3, 377, 0 ), /* 642 noser */
+ S_ST( 't', 3, 644, 636 ), /* 643 no */
+ S_ST( 'r', 3, 646, 0 ), /* 644 not */
+ S_ST( 'a', 3, 378, 0 ), /* 645 notr */
+ S_ST( 'u', 3, 647, 645 ), /* 646 notr */
+ S_ST( 's', 3, 379, 0 ), /* 647 notru */
+ S_ST( 't', 3, 380, 603 ), /* 648 n */
+ S_ST( 'p', 3, 650, 0 ), /* 649 ntp */
+ S_ST( 'o', 3, 651, 0 ), /* 650 ntpp */
+ S_ST( 'r', 3, 381, 0 ), /* 651 ntppo */
+ S_ST( 's', 3, 653, 649 ), /* 652 ntp */
+ S_ST( 'i', 3, 654, 0 ), /* 653 ntps */
+ S_ST( 'g', 3, 655, 0 ), /* 654 ntpsi */
+ S_ST( 'n', 3, 656, 0 ), /* 655 ntpsig */
+ S_ST( 'd', 3, 657, 0 ), /* 656 ntpsign */
+ S_ST( 's', 3, 658, 0 ), /* 657 ntpsignd */
+ S_ST( 'o', 3, 659, 0 ), /* 658 ntpsignds */
+ S_ST( 'c', 3, 660, 0 ), /* 659 ntpsigndso */
+ S_ST( 'k', 3, 661, 0 ), /* 660 ntpsigndsoc */
+ S_ST( 'e', 3, 382, 0 ), /* 661 ntpsigndsock */
+ S_ST( 'o', 3, 663, 601 ), /* 662 */
+ S_ST( 'r', 3, 664, 0 ), /* 663 o */
+ S_ST( 'p', 3, 665, 0 ), /* 664 or */
+ S_ST( 'h', 3, 666, 0 ), /* 665 orp */
+ S_ST( 'a', 3, 383, 0 ), /* 666 orph */
+ S_ST( 'w', 3, 668, 0 ), /* 667 orphan */
+ S_ST( 'a', 3, 669, 0 ), /* 668 orphanw */
+ S_ST( 'i', 3, 384, 0 ), /* 669 orphanwa */
+ S_ST( 'p', 3, 397, 662 ), /* 670 */
+ S_ST( 'a', 3, 672, 0 ), /* 671 p */
+ S_ST( 'n', 3, 673, 0 ), /* 672 pa */
+ S_ST( 'i', 3, 386, 0 ), /* 673 pan */
+ S_ST( 'e', 3, 675, 671 ), /* 674 p */
+ S_ST( 'e', 3, 387, 0 ), /* 675 pe */
+ S_ST( '_', 3, 677, 0 ), /* 676 peer */
+ S_ST( 'c', 3, 678, 0 ), /* 677 peer_ */
+ S_ST( 'l', 3, 679, 0 ), /* 678 peer_c */
+ S_ST( 'e', 3, 680, 0 ), /* 679 peer_cl */
+ S_ST( 'a', 3, 681, 0 ), /* 680 peer_cle */
+ S_ST( 'r', 3, 682, 0 ), /* 681 peer_clea */
+ S_ST( '_', 3, 683, 0 ), /* 682 peer_clear */
+ S_ST( 'd', 3, 684, 0 ), /* 683 peer_clear_ */
+ S_ST( 'i', 3, 685, 0 ), /* 684 peer_clear_d */
+ S_ST( 'g', 3, 686, 0 ), /* 685 peer_clear_di */
+ S_ST( 'e', 3, 687, 0 ), /* 686 peer_clear_dig */
+ S_ST( 's', 3, 688, 0 ), /* 687 peer_clear_dige */
+ S_ST( 't', 3, 689, 0 ), /* 688 peer_clear_diges */
+ S_ST( '_', 3, 690, 0 ), /* 689 peer_clear_digest */
+ S_ST( 'e', 3, 691, 0 ), /* 690 peer_clear_digest_ */
+ S_ST( 'a', 3, 692, 0 ), /* 691 peer_clear_digest_e */
+ S_ST( 'r', 3, 693, 0 ), /* 692 peer_clear_digest_ea */
+ S_ST( 'l', 3, 385, 0 ), /* 693 peer_clear_digest_ear */
+ S_ST( 's', 3, 695, 676 ), /* 694 peer */
+ S_ST( 't', 3, 696, 0 ), /* 695 peers */
+ S_ST( 'a', 3, 697, 0 ), /* 696 peerst */
+ S_ST( 't', 3, 388, 0 ), /* 697 peersta */
+ S_ST( 'h', 3, 699, 674 ), /* 698 p */
+ S_ST( 'o', 3, 700, 0 ), /* 699 ph */
+ S_ST( 'n', 3, 389, 0 ), /* 700 pho */
+ S_ST( 'i', 3, 390, 698 ), /* 701 p */
+ S_ST( 'f', 3, 703, 0 ), /* 702 pid */
+ S_ST( 'i', 3, 704, 0 ), /* 703 pidf */
+ S_ST( 'l', 3, 391, 0 ), /* 704 pidfi */
+ S_ST( 'o', 3, 707, 701 ), /* 705 p */
+ S_ST( 'o', 3, 392, 0 ), /* 706 po */
+ S_ST( 'r', 3, 393, 706 ), /* 707 po */
+ S_ST( 'r', 3, 715, 705 ), /* 708 p */
+ S_ST( 'e', 3, 713, 0 ), /* 709 pr */
+ S_ST( 'e', 3, 711, 0 ), /* 710 pre */
+ S_ST( 'm', 3, 712, 0 ), /* 711 pree */
+ S_ST( 'p', 3, 394, 0 ), /* 712 preem */
+ S_ST( 'f', 3, 714, 710 ), /* 713 pre */
+ S_ST( 'e', 3, 395, 0 ), /* 714 pref */
+ S_ST( 'o', 3, 728, 709 ), /* 715 pr */
+ S_ST( 'c', 3, 717, 0 ), /* 716 pro */
+ S_ST( '_', 3, 718, 0 ), /* 717 proc */
+ S_ST( 'd', 3, 719, 0 ), /* 718 proc_ */
+ S_ST( 'e', 3, 720, 0 ), /* 719 proc_d */
+ S_ST( 'l', 3, 721, 0 ), /* 720 proc_de */
+ S_ST( 'a', 3, 457, 0 ), /* 721 proc_del */
+ S_ST( 'p', 3, 723, 716 ), /* 722 pro */
+ S_ST( '_', 3, 724, 0 ), /* 723 prop */
+ S_ST( 'd', 3, 725, 0 ), /* 724 prop_ */
+ S_ST( 'e', 3, 726, 0 ), /* 725 prop_d */
+ S_ST( 'l', 3, 727, 0 ), /* 726 prop_de */
+ S_ST( 'a', 3, 456, 0 ), /* 727 prop_del */
+ S_ST( 't', 3, 729, 722 ), /* 728 pro */
+ S_ST( 'o', 3, 730, 0 ), /* 729 prot */
+ S_ST( 's', 3, 731, 0 ), /* 730 proto */
+ S_ST( 't', 3, 732, 0 ), /* 731 protos */
+ S_ST( 'a', 3, 733, 0 ), /* 732 protost */
+ S_ST( 't', 3, 396, 0 ), /* 733 protosta */
+ S_ST( 'r', 3, 765, 670 ), /* 734 */
+ S_ST( 'a', 3, 741, 0 ), /* 735 r */
+ S_ST( 'n', 3, 737, 0 ), /* 736 ra */
+ S_ST( 'd', 3, 738, 0 ), /* 737 ran */
+ S_ST( 'f', 3, 739, 0 ), /* 738 rand */
+ S_ST( 'i', 3, 740, 0 ), /* 739 randf */
+ S_ST( 'l', 3, 398, 0 ), /* 740 randfi */
+ S_ST( 'w', 3, 742, 736 ), /* 741 ra */
+ S_ST( 's', 3, 743, 0 ), /* 742 raw */
+ S_ST( 't', 3, 744, 0 ), /* 743 raws */
+ S_ST( 'a', 3, 745, 0 ), /* 744 rawst */
+ S_ST( 't', 3, 399, 0 ), /* 745 rawsta */
+ S_ST( 'e', 3, 762, 735 ), /* 746 r */
+ S_ST( 'f', 3, 748, 0 ), /* 747 re */
+ S_ST( 'i', 3, 400, 0 ), /* 748 ref */
+ S_ST( 'q', 3, 750, 747 ), /* 749 re */
+ S_ST( 'u', 3, 751, 0 ), /* 750 req */
+ S_ST( 'e', 3, 752, 0 ), /* 751 requ */
+ S_ST( 's', 3, 753, 0 ), /* 752 reque */
+ S_ST( 't', 3, 754, 0 ), /* 753 reques */
+ S_ST( 'k', 3, 755, 0 ), /* 754 request */
+ S_ST( 'e', 3, 401, 0 ), /* 755 requestk */
+ S_ST( 's', 3, 758, 749 ), /* 756 re */
+ S_ST( 'e', 3, 402, 0 ), /* 757 res */
+ S_ST( 't', 3, 759, 757 ), /* 758 res */
+ S_ST( 'r', 3, 760, 0 ), /* 759 rest */
+ S_ST( 'i', 3, 761, 0 ), /* 760 restr */
+ S_ST( 'c', 3, 403, 0 ), /* 761 restri */
+ S_ST( 'v', 3, 763, 756 ), /* 762 re */
+ S_ST( 'o', 3, 764, 0 ), /* 763 rev */
+ S_ST( 'k', 3, 404, 0 ), /* 764 revo */
+ S_ST( 'l', 3, 766, 746 ), /* 765 r */
+ S_ST( 'i', 3, 767, 0 ), /* 766 rl */
+ S_ST( 'm', 3, 768, 0 ), /* 767 rli */
+ S_ST( 'i', 3, 405, 0 ), /* 768 rlim */
+ S_ST( 's', 3, 842, 734 ), /* 769 */
+ S_ST( 'a', 3, 771, 0 ), /* 770 s */
+ S_ST( 'v', 3, 772, 0 ), /* 771 sa */
+ S_ST( 'e', 3, 773, 0 ), /* 772 sav */
+ S_ST( 'c', 3, 774, 0 ), /* 773 save */
+ S_ST( 'o', 3, 775, 0 ), /* 774 savec */
+ S_ST( 'n', 3, 776, 0 ), /* 775 saveco */
+ S_ST( 'f', 3, 777, 0 ), /* 776 savecon */
+ S_ST( 'i', 3, 778, 0 ), /* 777 saveconf */
+ S_ST( 'g', 3, 779, 0 ), /* 778 saveconfi */
+ S_ST( 'd', 3, 780, 0 ), /* 779 saveconfig */
+ S_ST( 'i', 3, 406, 0 ), /* 780 saveconfigd */
+ S_ST( 'e', 3, 791, 770 ), /* 781 s */
+ S_ST( 'r', 3, 783, 0 ), /* 782 se */
+ S_ST( 'v', 3, 784, 0 ), /* 783 ser */
+ S_ST( 'e', 3, 407, 0 ), /* 784 serv */
+ S_ST( '_', 3, 786, 0 ), /* 785 server */
+ S_ST( 'o', 3, 787, 0 ), /* 786 server_ */
+ S_ST( 'f', 3, 788, 0 ), /* 787 server_o */
+ S_ST( 'f', 3, 789, 0 ), /* 788 server_of */
+ S_ST( 's', 3, 790, 0 ), /* 789 server_off */
+ S_ST( 'e', 3, 451, 0 ), /* 790 server_offs */
+ S_ST( 't', 3, 792, 782 ), /* 791 se */
+ S_ST( 'v', 3, 793, 0 ), /* 792 set */
+ S_ST( 'a', 3, 408, 0 ), /* 793 setv */
+ S_ST( 'i', 3, 795, 781 ), /* 794 s */
+ S_ST( 'm', 3, 796, 0 ), /* 795 si */
+ S_ST( 'u', 3, 797, 0 ), /* 796 sim */
+ S_ST( 'l', 3, 798, 0 ), /* 797 simu */
+ S_ST( 'a', 3, 799, 0 ), /* 798 simul */
+ S_ST( 't', 3, 800, 0 ), /* 799 simula */
+ S_ST( 'i', 3, 801, 448 ), /* 800 simulat */
+ S_ST( 'o', 3, 802, 0 ), /* 801 simulati */
+ S_ST( 'n', 3, 803, 0 ), /* 802 simulatio */
+ S_ST( '_', 3, 804, 0 ), /* 803 simulation */
+ S_ST( 'd', 3, 805, 0 ), /* 804 simulation_ */
+ S_ST( 'u', 3, 806, 0 ), /* 805 simulation_d */
+ S_ST( 'r', 3, 807, 0 ), /* 806 simulation_du */
+ S_ST( 'a', 3, 808, 0 ), /* 807 simulation_dur */
+ S_ST( 't', 3, 809, 0 ), /* 808 simulation_dura */
+ S_ST( 'i', 3, 810, 0 ), /* 809 simulation_durat */
+ S_ST( 'o', 3, 450, 0 ), /* 810 simulation_durati */
+ S_ST( 'o', 3, 812, 794 ), /* 811 s */
+ S_ST( 'u', 3, 813, 0 ), /* 812 so */
+ S_ST( 'r', 3, 814, 0 ), /* 813 sou */
+ S_ST( 'c', 3, 409, 0 ), /* 814 sour */
+ S_ST( 't', 3, 838, 811 ), /* 815 s */
+ S_ST( 'a', 3, 822, 0 ), /* 816 st */
+ S_ST( 'c', 3, 818, 0 ), /* 817 sta */
+ S_ST( 'k', 3, 819, 0 ), /* 818 stac */
+ S_ST( 's', 3, 820, 0 ), /* 819 stack */
+ S_ST( 'i', 3, 821, 0 ), /* 820 stacks */
+ S_ST( 'z', 3, 410, 0 ), /* 821 stacksi */
+ S_ST( 't', 3, 412, 817 ), /* 822 sta */
+ S_ST( 'i', 3, 824, 0 ), /* 823 stat */
+ S_ST( 's', 3, 825, 0 ), /* 824 stati */
+ S_ST( 't', 3, 826, 0 ), /* 825 statis */
+ S_ST( 'i', 3, 827, 0 ), /* 826 statist */
+ S_ST( 'c', 3, 411, 0 ), /* 827 statisti */
+ S_ST( 'd', 3, 829, 0 ), /* 828 stats */
+ S_ST( 'i', 3, 413, 0 ), /* 829 statsd */
+ S_ST( 'e', 3, 414, 816 ), /* 830 st */
+ S_ST( 'b', 3, 832, 0 ), /* 831 step */
+ S_ST( 'a', 3, 833, 0 ), /* 832 stepb */
+ S_ST( 'c', 3, 415, 0 ), /* 833 stepba */
+ S_ST( 'f', 3, 835, 831 ), /* 834 step */
+ S_ST( 'w', 3, 416, 0 ), /* 835 stepf */
+ S_ST( 'o', 3, 837, 834 ), /* 836 step */
+ S_ST( 'u', 3, 417, 0 ), /* 837 stepo */
+ S_ST( 'r', 3, 839, 830 ), /* 838 st */
+ S_ST( 'a', 3, 840, 0 ), /* 839 str */
+ S_ST( 't', 3, 841, 0 ), /* 840 stra */
+ S_ST( 'u', 3, 418, 0 ), /* 841 strat */
+ S_ST( 'y', 3, 420, 815 ), /* 842 s */
+ S_ST( 's', 3, 844, 0 ), /* 843 sys */
+ S_ST( 't', 3, 845, 0 ), /* 844 syss */
+ S_ST( 'a', 3, 846, 0 ), /* 845 sysst */
+ S_ST( 't', 3, 421, 0 ), /* 846 syssta */
+ S_ST( 't', 3, 873, 769 ), /* 847 */
+ S_ST( 'i', 3, 859, 0 ), /* 848 t */
+ S_ST( 'c', 3, 422, 0 ), /* 849 ti */
+ S_ST( 'm', 3, 852, 849 ), /* 850 ti */
+ S_ST( 'e', 3, 425, 0 ), /* 851 tim */
+ S_ST( 'i', 3, 853, 851 ), /* 852 tim */
+ S_ST( 'n', 3, 854, 0 ), /* 853 timi */
+ S_ST( 'g', 3, 855, 0 ), /* 854 timin */
+ S_ST( 's', 3, 856, 0 ), /* 855 timing */
+ S_ST( 't', 3, 857, 0 ), /* 856 timings */
+ S_ST( 'a', 3, 858, 0 ), /* 857 timingst */
+ S_ST( 't', 3, 426, 0 ), /* 858 timingsta */
+ S_ST( 'n', 3, 860, 850 ), /* 859 ti */
+ S_ST( 'k', 3, 861, 0 ), /* 860 tin */
+ S_ST( 'e', 3, 427, 0 ), /* 861 tink */
+ S_ST( 'o', 3, 428, 848 ), /* 862 t */
+ S_ST( 'r', 3, 865, 862 ), /* 863 t */
+ S_ST( 'a', 3, 429, 0 ), /* 864 tr */
+ S_ST( 'u', 3, 866, 864 ), /* 865 tr */
+ S_ST( 's', 3, 867, 430 ), /* 866 tru */
+ S_ST( 't', 3, 868, 0 ), /* 867 trus */
+ S_ST( 'e', 3, 869, 0 ), /* 868 trust */
+ S_ST( 'd', 3, 870, 0 ), /* 869 truste */
+ S_ST( 'k', 3, 871, 0 ), /* 870 trusted */
+ S_ST( 'e', 3, 431, 0 ), /* 871 trustedk */
+ S_ST( 't', 3, 432, 863 ), /* 872 t */
+ S_ST( 'y', 3, 874, 872 ), /* 873 t */
+ S_ST( 'p', 3, 433, 0 ), /* 874 ty */
+ S_ST( 'u', 3, 876, 847 ), /* 875 */
+ S_ST( 'n', 3, 882, 0 ), /* 876 u */
+ S_ST( 'c', 3, 878, 0 ), /* 877 un */
+ S_ST( 'o', 3, 879, 0 ), /* 878 unc */
+ S_ST( 'n', 3, 880, 0 ), /* 879 unco */
+ S_ST( 'f', 3, 881, 0 ), /* 880 uncon */
+ S_ST( 'i', 3, 438, 0 ), /* 881 unconf */
+ S_ST( 'p', 3, 883, 877 ), /* 882 un */
+ S_ST( 'e', 3, 884, 0 ), /* 883 unp */
+ S_ST( 'e', 3, 439, 0 ), /* 884 unpe */
+ S_ST( '_', 3, 905, 0 ), /* 885 unpeer */
+ S_ST( 'c', 3, 887, 0 ), /* 886 unpeer_ */
+ S_ST( 'r', 3, 888, 0 ), /* 887 unpeer_c */
+ S_ST( 'y', 3, 889, 0 ), /* 888 unpeer_cr */
+ S_ST( 'p', 3, 890, 0 ), /* 889 unpeer_cry */
+ S_ST( 't', 3, 891, 0 ), /* 890 unpeer_cryp */
+ S_ST( 'o', 3, 892, 0 ), /* 891 unpeer_crypt */
+ S_ST( '_', 3, 897, 0 ), /* 892 unpeer_crypto */
+ S_ST( 'e', 3, 894, 0 ), /* 893 unpeer_crypto_ */
+ S_ST( 'a', 3, 895, 0 ), /* 894 unpeer_crypto_e */
+ S_ST( 'r', 3, 896, 0 ), /* 895 unpeer_crypto_ea */
+ S_ST( 'l', 3, 435, 0 ), /* 896 unpeer_crypto_ear */
+ S_ST( 'n', 3, 898, 893 ), /* 897 unpeer_crypto_ */
+ S_ST( 'a', 3, 899, 0 ), /* 898 unpeer_crypto_n */
+ S_ST( 'k', 3, 900, 0 ), /* 899 unpeer_crypto_na */
+ S_ST( '_', 3, 901, 0 ), /* 900 unpeer_crypto_nak */
+ S_ST( 'e', 3, 902, 0 ), /* 901 unpeer_crypto_nak_ */
+ S_ST( 'a', 3, 903, 0 ), /* 902 unpeer_crypto_nak_e */
+ S_ST( 'r', 3, 904, 0 ), /* 903 unpeer_crypto_nak_ea */
+ S_ST( 'l', 3, 436, 0 ), /* 904 unpeer_crypto_nak_ear */
+ S_ST( 'd', 3, 906, 886 ), /* 905 unpeer_ */
+ S_ST( 'i', 3, 907, 0 ), /* 906 unpeer_d */
+ S_ST( 'g', 3, 908, 0 ), /* 907 unpeer_di */
+ S_ST( 'e', 3, 909, 0 ), /* 908 unpeer_dig */
+ S_ST( 's', 3, 910, 0 ), /* 909 unpeer_dige */
+ S_ST( 't', 3, 911, 0 ), /* 910 unpeer_diges */
+ S_ST( '_', 3, 912, 0 ), /* 911 unpeer_digest */
+ S_ST( 'e', 3, 913, 0 ), /* 912 unpeer_digest_ */
+ S_ST( 'a', 3, 914, 0 ), /* 913 unpeer_digest_e */
+ S_ST( 'r', 3, 915, 0 ), /* 914 unpeer_digest_ea */
+ S_ST( 'l', 3, 437, 0 ), /* 915 unpeer_digest_ear */
+ S_ST( 'v', 3, 917, 875 ), /* 916 */
+ S_ST( 'e', 3, 918, 0 ), /* 917 v */
+ S_ST( 'r', 3, 919, 0 ), /* 918 ve */
+ S_ST( 's', 3, 920, 0 ), /* 919 ver */
+ S_ST( 'i', 3, 921, 0 ), /* 920 vers */
+ S_ST( 'o', 3, 440, 0 ), /* 921 versi */
+ S_ST( 'w', 3, 929, 916 ), /* 922 */
+ S_ST( 'a', 3, 924, 0 ), /* 923 w */
+ S_ST( 'n', 3, 925, 0 ), /* 924 wa */
+ S_ST( 'd', 3, 926, 0 ), /* 925 wan */
+ S_ST( 'e', 3, 454, 0 ), /* 926 wand */
+ S_ST( 'e', 3, 928, 923 ), /* 927 w */
+ S_ST( 'e', 3, 442, 0 ), /* 928 we */
+ S_ST( 'i', 3, 930, 927 ), /* 929 w */
+ S_ST( 'l', 3, 931, 0 ), /* 930 wi */
+ S_ST( 'd', 3, 932, 0 ), /* 931 wil */
+ S_ST( 'c', 3, 933, 0 ), /* 932 wild */
+ S_ST( 'a', 3, 934, 0 ), /* 933 wildc */
+ S_ST( 'r', 3, 443, 0 ), /* 934 wildca */
+ S_ST( 'x', 3, 936, 922 ), /* 935 */
+ S_ST( 'l', 3, 937, 0 ), /* 936 x */
+ S_ST( 'e', 3, 938, 0 ), /* 937 xl */
+ S_ST( 'a', 3, 939, 0 ), /* 938 xle */
+ S_ST( 'v', 3, 444, 0 ), /* 939 xlea */
+ S_ST( 'y', 3, 941, 935 ), /* 940 [initial state] */
+ S_ST( 'e', 3, 942, 0 ), /* 941 y */
+ S_ST( 'a', 3, 445, 0 ) /* 942 ye */
+};
+
diff --git a/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_leapsec.c b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_leapsec.c
new file mode 100644
index 0000000..c1af557
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_leapsec.c
@@ -0,0 +1,1198 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * ntp_leapsec.c - leap second processing for NTPD
+ *
+ * Written by Juergen Perlinger (perlinger@ntp.org) for the NTP project.
+ * The contents of 'html/copyright.html' apply.
+ * ----------------------------------------------------------------------
+ * This is an attempt to get the leap second handling into a dedicated
+ * module to make the somewhat convoluted logic testable.
+ */
+
+#include <config.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <ctype.h>
+
+#include "ntp_types.h"
+#include "ntp_fp.h"
+#include "ntp_stdlib.h"
+#include "ntp_calendar.h"
+#include "ntp_leapsec.h"
+#include "ntp.h"
+#include "vint64ops.h"
+#include "lib_strbuf.h"
+
+#include "isc/sha1.h"
+
+static const char * const logPrefix = "leapsecond file";
+
+/* ---------------------------------------------------------------------
+ * GCC is rather sticky with its 'const' attribute. We have to do it more
+ * explicit than with a cast if we want to get rid of a CONST qualifier.
+ * Greetings from the PASCAL world, where casting was only possible via
+ * untagged unions...
+ */
+static inline void*
+noconst(
+ const void* ptr
+ )
+{
+ union {
+ const void * cp;
+ void * vp;
+ } tmp;
+ tmp.cp = ptr;
+ return tmp.vp;
+}
+
+/* ---------------------------------------------------------------------
+ * Our internal data structure
+ */
+#define MAX_HIST 10 /* history of leap seconds */
+
+struct leap_info {
+ vint64 ttime; /* transition time (after the step, ntp scale) */
+ uint32_t stime; /* schedule limit (a month before transition) */
+ int16_t taiof; /* TAI offset on and after the transition */
+ uint8_t dynls; /* dynamic: inserted on peer/clock request */
+};
+typedef struct leap_info leap_info_t;
+
+struct leap_head {
+ vint64 update; /* time of information update */
+ vint64 expire; /* table expiration time */
+ uint16_t size; /* number of infos in table */
+ int16_t base_tai; /* total leaps before first entry */
+ int16_t this_tai; /* current TAI offset */
+ int16_t next_tai; /* TAI offset after 'when' */
+ vint64 dtime; /* due time (current era end) */
+ vint64 ttime; /* nominal transition time (next era start) */
+ vint64 stime; /* schedule time (when we take notice) */
+ vint64 ebase; /* base time of this leap era */
+ uint8_t dynls; /* next leap is dynamic (by peer request) */
+};
+typedef struct leap_head leap_head_t;
+
+struct leap_table {
+ leap_signature_t lsig;
+ leap_head_t head;
+ leap_info_t info[MAX_HIST];
+};
+
+/* Where we store our tables */
+static leap_table_t _ltab[2], *_lptr;
+static int/*BOOL*/ _electric;
+
+/* Forward decls of local helpers */
+static int add_range(leap_table_t*, const leap_info_t*);
+static char * get_line(leapsec_reader, void*, char*, size_t);
+static char * skipws(const char*);
+static int parsefail(const char * cp, const char * ep);
+static void reload_limits(leap_table_t*, const vint64*);
+static void fetch_leap_era(leap_era_t*, const leap_table_t*,
+ const vint64*);
+static int betweenu32(uint32_t, uint32_t, uint32_t);
+static void reset_times(leap_table_t*);
+static int leapsec_add(leap_table_t*, const vint64*, int);
+static int leapsec_raw(leap_table_t*, const vint64 *, int, int);
+static const char * lstostr(const vint64 * ts);
+
+/* =====================================================================
+ * Get & Set the current leap table
+ */
+
+/* ------------------------------------------------------------------ */
+leap_table_t *
+leapsec_get_table(
+ int alternate)
+{
+ leap_table_t *p1, *p2;
+
+ p1 = _lptr;
+ if (p1 == &_ltab[0]) {
+ p2 = &_ltab[1];
+ } else if (p1 == &_ltab[1]) {
+ p2 = &_ltab[0];
+ } else {
+ p1 = &_ltab[0];
+ p2 = &_ltab[1];
+ reset_times(p1);
+ reset_times(p2);
+ _lptr = p1;
+ }
+ if (alternate) {
+ memcpy(p2, p1, sizeof(leap_table_t));
+ p1 = p2;
+ }
+
+ return p1;
+}
+
+/* ------------------------------------------------------------------ */
+int/*BOOL*/
+leapsec_set_table(
+ leap_table_t * pt)
+{
+ if (pt == &_ltab[0] || pt == &_ltab[1])
+ _lptr = pt;
+ return _lptr == pt;
+}
+
+/* ------------------------------------------------------------------ */
+int/*BOOL*/
+leapsec_electric(
+ int/*BOOL*/ on)
+{
+ int res = _electric;
+ if (on < 0)
+ return res;
+
+ _electric = (on != 0);
+ if (_electric == res)
+ return res;
+
+ if (_lptr == &_ltab[0] || _lptr == &_ltab[1])
+ reset_times(_lptr);
+
+ return res;
+}
+
+/* =====================================================================
+ * API functions that operate on tables
+ */
+
+/* ---------------------------------------------------------------------
+ * Clear all leap second data. Use it for init & cleanup
+ */
+void
+leapsec_clear(
+ leap_table_t * pt)
+{
+ memset(&pt->lsig, 0, sizeof(pt->lsig));
+ memset(&pt->head, 0, sizeof(pt->head));
+ reset_times(pt);
+}
+
+/* ---------------------------------------------------------------------
+ * Load a leap second file and check expiration on the go
+ */
+int/*BOOL*/
+leapsec_load(
+ leap_table_t * pt ,
+ leapsec_reader func,
+ void * farg,
+ int use_build_limit)
+{
+ char *cp, *ep, linebuf[50];
+ vint64 ttime, limit;
+ long taiof;
+ struct calendar build;
+
+ leapsec_clear(pt);
+ if (use_build_limit && ntpcal_get_build_date(&build)) {
+ /* don't prune everything -- permit the last 10yrs
+ * before build.
+ */
+ build.year -= 10;
+ limit = ntpcal_date_to_ntp64(&build);
+ } else {
+ memset(&limit, 0, sizeof(limit));
+ }
+
+ while (get_line(func, farg, linebuf, sizeof(linebuf))) {
+ cp = linebuf;
+ if (*cp == '#') {
+ cp++;
+ if (*cp == '@') {
+ cp = skipws(cp+1);
+ pt->head.expire = strtouv64(cp, &ep, 10);
+ if (parsefail(cp, ep))
+ goto fail_read;
+ pt->lsig.etime = pt->head.expire.D_s.lo;
+ } else if (*cp == '$') {
+ cp = skipws(cp+1);
+ pt->head.update = strtouv64(cp, &ep, 10);
+ if (parsefail(cp, ep))
+ goto fail_read;
+ }
+ } else if (isdigit((u_char)*cp)) {
+ ttime = strtouv64(cp, &ep, 10);
+ if (parsefail(cp, ep))
+ goto fail_read;
+ cp = skipws(ep);
+ taiof = strtol(cp, &ep, 10);
+ if ( parsefail(cp, ep)
+ || taiof > SHRT_MAX || taiof < SHRT_MIN)
+ goto fail_read;
+ if (ucmpv64(&ttime, &limit) >= 0) {
+ if (!leapsec_raw(pt, &ttime,
+ taiof, FALSE))
+ goto fail_insn;
+ } else {
+ pt->head.base_tai = (int16_t)taiof;
+ }
+ pt->lsig.ttime = ttime.D_s.lo;
+ pt->lsig.taiof = (int16_t)taiof;
+ }
+ }
+ return TRUE;
+
+fail_read:
+ errno = EILSEQ;
+fail_insn:
+ leapsec_clear(pt);
+ return FALSE;
+}
+
+/* ---------------------------------------------------------------------
+ * Dump a table in human-readable format. Use 'fprintf' and a FILE
+ * pointer if you want to get it printed into a stream.
+ */
+void
+leapsec_dump(
+ const leap_table_t * pt ,
+ leapsec_dumper func,
+ void * farg)
+{
+ int idx;
+ vint64 ts;
+ struct calendar atb, ttb;
+
+ ntpcal_ntp64_to_date(&ttb, &pt->head.expire);
+ (*func)(farg, "leap table (%u entries) expires at %04u-%02u-%02u:\n",
+ pt->head.size,
+ ttb.year, ttb.month, ttb.monthday);
+ idx = pt->head.size;
+ while (idx-- != 0) {
+ ts = pt->info[idx].ttime;
+ ntpcal_ntp64_to_date(&ttb, &ts);
+ ts = subv64u32(&ts, pt->info[idx].stime);
+ ntpcal_ntp64_to_date(&atb, &ts);
+
+ (*func)(farg, "%04u-%02u-%02u [%c] (%04u-%02u-%02u) - %d\n",
+ ttb.year, ttb.month, ttb.monthday,
+ "-*"[pt->info[idx].dynls != 0],
+ atb.year, atb.month, atb.monthday,
+ pt->info[idx].taiof);
+ }
+}
+
+/* =====================================================================
+ * usecase driven API functions
+ */
+
+int/*BOOL*/
+leapsec_query(
+ leap_result_t * qr ,
+ uint32_t ts32 ,
+ const time_t * pivot)
+{
+ leap_table_t * pt;
+ vint64 ts64, last, next;
+ uint32_t due32;
+ int fired;
+
+ /* preset things we use later on... */
+ fired = FALSE;
+ ts64 = ntpcal_ntp_to_ntp(ts32, pivot);
+ pt = leapsec_get_table(FALSE);
+ memset(qr, 0, sizeof(leap_result_t));
+
+ if (ucmpv64(&ts64, &pt->head.ebase) < 0) {
+ /* Most likely after leap frame reset. Could also be a
+ * backstep of the system clock. Anyway, get the new
+ * leap era frame.
+ */
+ reload_limits(pt, &ts64);
+ } else if (ucmpv64(&ts64, &pt->head.dtime) >= 0) {
+ /* Boundary crossed in forward direction. This might
+ * indicate a leap transition, so we prepare for that
+ * case.
+ *
+ * Some operations below are actually NOPs in electric
+ * mode, but having only one code path that works for
+ * both modes is easier to maintain.
+ *
+ * There's another quirk we must keep looking out for:
+ * If we just stepped the clock, the step might have
+ * crossed a leap boundary. As with backward steps, we
+ * do not want to raise the 'fired' event in that case.
+ * So we raise the 'fired' event only if we're close to
+ * the transition and just reload the limits otherwise.
+ */
+ last = addv64i32(&pt->head.dtime, 3); /* get boundary */
+ if (ucmpv64(&ts64, &last) >= 0) {
+ /* that was likely a query after a step */
+ reload_limits(pt, &ts64);
+ } else {
+ /* close enough for deeper examination */
+ last = pt->head.ttime;
+ qr->warped = (int16_t)(last.D_s.lo -
+ pt->head.dtime.D_s.lo);
+ next = addv64i32(&ts64, qr->warped);
+ reload_limits(pt, &next);
+ fired = ucmpv64(&pt->head.ebase, &last) == 0;
+ if (fired) {
+ ts64 = next;
+ ts32 = next.D_s.lo;
+ } else {
+ qr->warped = 0;
+ }
+ }
+ }
+
+ qr->tai_offs = pt->head.this_tai;
+ qr->ebase = pt->head.ebase;
+ qr->ttime = pt->head.ttime;
+
+ /* If before the next scheduling alert, we're done. */
+ if (ucmpv64(&ts64, &pt->head.stime) < 0)
+ return fired;
+
+ /* now start to collect the remaining data */
+ due32 = pt->head.dtime.D_s.lo;
+
+ qr->tai_diff = pt->head.next_tai - pt->head.this_tai;
+ qr->ddist = due32 - ts32;
+ qr->dynamic = pt->head.dynls;
+ qr->proximity = LSPROX_SCHEDULE;
+
+ /* if not in the last day before transition, we're done. */
+ if (!betweenu32(due32 - SECSPERDAY, ts32, due32))
+ return fired;
+
+ qr->proximity = LSPROX_ANNOUNCE;
+ if (!betweenu32(due32 - 10, ts32, due32))
+ return fired;
+
+ /* The last 10s before the transition. Prepare for action! */
+ qr->proximity = LSPROX_ALERT;
+ return fired;
+}
+
+/* ------------------------------------------------------------------ */
+int/*BOOL*/
+leapsec_query_era(
+ leap_era_t * qr ,
+ uint32_t ntpts,
+ const time_t * pivot)
+{
+ const leap_table_t * pt;
+ vint64 ts64;
+
+ pt = leapsec_get_table(FALSE);
+ ts64 = ntpcal_ntp_to_ntp(ntpts, pivot);
+ fetch_leap_era(qr, pt, &ts64);
+ return TRUE;
+}
+
+/* ------------------------------------------------------------------ */
+int/*BOOL*/
+leapsec_frame(
+ leap_result_t *qr)
+{
+ const leap_table_t * pt;
+
+ memset(qr, 0, sizeof(leap_result_t));
+ pt = leapsec_get_table(FALSE);
+
+ qr->tai_offs = pt->head.this_tai;
+ qr->tai_diff = pt->head.next_tai - pt->head.this_tai;
+ qr->ebase = pt->head.ebase;
+ qr->ttime = pt->head.ttime;
+ qr->dynamic = pt->head.dynls;
+
+ return ucmpv64(&pt->head.ttime, &pt->head.stime) >= 0;
+}
+
+/* ------------------------------------------------------------------ */
+/* Reset the current leap frame */
+void
+leapsec_reset_frame(void)
+{
+ reset_times(leapsec_get_table(FALSE));
+}
+
+/* ------------------------------------------------------------------ */
+/* load a file from a FILE pointer. Note: If hcheck is true, load
+ * only after successful signature check. The stream must be seekable
+ * or this will fail.
+ */
+int/*BOOL*/
+leapsec_load_stream(
+ FILE * ifp ,
+ const char * fname,
+ int/*BOOL*/ logall)
+{
+ leap_table_t *pt;
+ int rcheck;
+
+ if (NULL == fname)
+ fname = "<unknown>";
+
+ rcheck = leapsec_validate((leapsec_reader)getc, ifp);
+ if (logall)
+ switch (rcheck)
+ {
+ case LSVALID_GOODHASH:
+ msyslog(LOG_NOTICE, "%s ('%s'): good hash signature",
+ logPrefix, fname);
+ break;
+
+ case LSVALID_NOHASH:
+ msyslog(LOG_ERR, "%s ('%s'): no hash signature",
+ logPrefix, fname);
+ break;
+ case LSVALID_BADHASH:
+ msyslog(LOG_ERR, "%s ('%s'): signature mismatch",
+ logPrefix, fname);
+ break;
+ case LSVALID_BADFORMAT:
+ msyslog(LOG_ERR, "%s ('%s'): malformed hash signature",
+ logPrefix, fname);
+ break;
+ default:
+ msyslog(LOG_ERR, "%s ('%s'): unknown error code %d",
+ logPrefix, fname, rcheck);
+ break;
+ }
+ if (rcheck < 0)
+ return FALSE;
+
+ rewind(ifp);
+ pt = leapsec_get_table(TRUE);
+ if (!leapsec_load(pt, (leapsec_reader)getc, ifp, TRUE)) {
+ switch (errno) {
+ case EINVAL:
+ msyslog(LOG_ERR, "%s ('%s'): bad transition time",
+ logPrefix, fname);
+ break;
+ case ERANGE:
+ msyslog(LOG_ERR, "%s ('%s'): times not ascending",
+ logPrefix, fname);
+ break;
+ default:
+ msyslog(LOG_ERR, "%s ('%s'): parsing error",
+ logPrefix, fname);
+ break;
+ }
+ return FALSE;
+ }
+
+ if (pt->head.size)
+ msyslog(LOG_NOTICE, "%s ('%s'): loaded, expire=%s last=%s ofs=%d",
+ logPrefix, fname, lstostr(&pt->head.expire),
+ lstostr(&pt->info[0].ttime), pt->info[0].taiof);
+ else
+ msyslog(LOG_NOTICE,
+ "%s ('%s'): loaded, expire=%s ofs=%d (no entries after build date)",
+ logPrefix, fname, lstostr(&pt->head.expire),
+ pt->head.base_tai);
+
+ return leapsec_set_table(pt);
+}
+
+/* ------------------------------------------------------------------ */
+int/*BOOL*/
+leapsec_load_file(
+ const char * fname,
+ struct stat * sb_old,
+ int/*BOOL*/ force,
+ int/*BOOL*/ logall)
+{
+ FILE * fp;
+ struct stat sb_new;
+ int rc;
+
+ /* just do nothing if there is no leap file */
+ if ( !(fname && *fname) )
+ return FALSE;
+
+ /* try to stat the leapfile */
+ if (0 != stat(fname, &sb_new)) {
+ if (logall)
+ msyslog(LOG_ERR, "%s ('%s'): stat failed: %m",
+ logPrefix, fname);
+ return FALSE;
+ }
+
+ /* silently skip to postcheck if no new file found */
+ if (NULL != sb_old) {
+ if (!force
+ && sb_old->st_mtime == sb_new.st_mtime
+ && sb_old->st_ctime == sb_new.st_ctime
+ )
+ return FALSE;
+ *sb_old = sb_new;
+ }
+
+ /* try to open the leap file, complain if that fails
+ *
+ * [perlinger@ntp.org]
+ * coverity raises a TOCTOU (time-of-check/time-of-use) issue
+ * here, which is not entirely helpful: While there is indeed a
+ * possible race condition between the 'stat()' call above and
+ * the 'fopen)' call below, I intentionally want to omit the
+ * overhead of opening the file and calling 'fstat()', because
+ * in most cases the file would have be to closed anyway without
+ * reading the contents. I chose to disable the coverity
+ * warning instead.
+ *
+ * So unless someone comes up with a reasonable argument why
+ * this could be a real issue, I'll just try to silence coverity
+ * on that topic.
+ */
+ /* coverity[toctou] */
+ if ((fp = fopen(fname, "r")) == NULL) {
+ if (logall)
+ msyslog(LOG_ERR,
+ "%s ('%s'): open failed: %m",
+ logPrefix, fname);
+ return FALSE;
+ }
+
+ rc = leapsec_load_stream(fp, fname, logall);
+ fclose(fp);
+ return rc;
+}
+
+/* ------------------------------------------------------------------ */
+void
+leapsec_getsig(
+ leap_signature_t * psig)
+{
+ const leap_table_t * pt;
+
+ pt = leapsec_get_table(FALSE);
+ memcpy(psig, &pt->lsig, sizeof(leap_signature_t));
+}
+
+/* ------------------------------------------------------------------ */
+int/*BOOL*/
+leapsec_expired(
+ uint32_t when,
+ const time_t * tpiv)
+{
+ const leap_table_t * pt;
+ vint64 limit;
+
+ pt = leapsec_get_table(FALSE);
+ limit = ntpcal_ntp_to_ntp(when, tpiv);
+ return ucmpv64(&limit, &pt->head.expire) >= 0;
+}
+
+/* ------------------------------------------------------------------ */
+int32_t
+leapsec_daystolive(
+ uint32_t when,
+ const time_t * tpiv)
+{
+ const leap_table_t * pt;
+ vint64 limit;
+
+ pt = leapsec_get_table(FALSE);
+ limit = ntpcal_ntp_to_ntp(when, tpiv);
+ limit = subv64(&pt->head.expire, &limit);
+ return ntpcal_daysplit(&limit).hi;
+}
+
+/* ------------------------------------------------------------------ */
+#if 0 /* currently unused -- possibly revived later */
+int/*BOOL*/
+leapsec_add_fix(
+ int total,
+ uint32_t ttime,
+ uint32_t etime,
+ const time_t * pivot)
+{
+ time_t tpiv;
+ leap_table_t * pt;
+ vint64 tt64, et64;
+
+ if (pivot == NULL) {
+ time(&tpiv);
+ pivot = &tpiv;
+ }
+
+ et64 = ntpcal_ntp_to_ntp(etime, pivot);
+ tt64 = ntpcal_ntp_to_ntp(ttime, pivot);
+ pt = leapsec_get_table(TRUE);
+
+ if ( ucmpv64(&et64, &pt->head.expire) <= 0
+ || !leapsec_raw(pt, &tt64, total, FALSE) )
+ return FALSE;
+
+ pt->lsig.etime = etime;
+ pt->lsig.ttime = ttime;
+ pt->lsig.taiof = (int16_t)total;
+
+ pt->head.expire = et64;
+
+ return leapsec_set_table(pt);
+}
+#endif
+
+/* ------------------------------------------------------------------ */
+int/*BOOL*/
+leapsec_add_dyn(
+ int insert,
+ uint32_t ntpnow,
+ const time_t * pivot )
+{
+ leap_table_t * pt;
+ vint64 now64;
+
+ pt = leapsec_get_table(TRUE);
+ now64 = ntpcal_ntp_to_ntp(ntpnow, pivot);
+ return ( leapsec_add(pt, &now64, (insert != 0))
+ && leapsec_set_table(pt));
+}
+
+/* ------------------------------------------------------------------ */
+int/*BOOL*/
+leapsec_autokey_tai(
+ int tai_offset,
+ uint32_t ntpnow ,
+ const time_t * pivot )
+{
+ leap_table_t * pt;
+ leap_era_t era;
+ vint64 now64;
+ int idx;
+
+ (void)tai_offset;
+ pt = leapsec_get_table(FALSE);
+
+ /* Bail out if the basic offset is not zero and the putative
+ * offset is bigger than 10s. That was in 1972 -- we don't want
+ * to go back that far!
+ */
+ if (pt->head.base_tai != 0 || tai_offset < 10)
+ return FALSE;
+
+ /* If there's already data in the table, check if an update is
+ * possible. Update is impossible if there are static entries
+ * (since this indicates a valid leapsecond file) or if we're
+ * too close to a leapsecond transition: We do not know on what
+ * side the transition the sender might have been, so we use a
+ * dead zone around the transition.
+ */
+
+ /* Check for static entries */
+ for (idx = 0; idx != pt->head.size; idx++)
+ if ( ! pt->info[idx].dynls)
+ return FALSE;
+
+ /* get the fulll time stamp and leap era for it */
+ now64 = ntpcal_ntp_to_ntp(ntpnow, pivot);
+ fetch_leap_era(&era, pt, &now64);
+
+ /* check the limits with 20s dead band */
+ era.ebase = addv64i32(&era.ebase, 20);
+ if (ucmpv64(&now64, &era.ebase) < 0)
+ return FALSE;
+
+ era.ttime = addv64i32(&era.ttime, -20);
+ if (ucmpv64(&now64, &era.ttime) > 0)
+ return FALSE;
+
+ /* Here we can proceed. Calculate the delta update. */
+ tai_offset -= era.taiof;
+
+ /* Shift the header info offsets. */
+ pt->head.base_tai += tai_offset;
+ pt->head.this_tai += tai_offset;
+ pt->head.next_tai += tai_offset;
+
+ /* Shift table entry offsets (if any) */
+ for (idx = 0; idx != pt->head.size; idx++)
+ pt->info[idx].taiof += tai_offset;
+
+ /* claim success... */
+ return TRUE;
+}
+
+
+/* =====================================================================
+ * internal helpers
+ */
+
+/* [internal] Reset / init the time window in the leap processor to
+ * force reload on next query. Since a leap transition cannot take place
+ * at an odd second, the value chosen avoids spurious leap transition
+ * triggers. Making all three times equal forces a reload. Using the
+ * maximum value for unsigned 64 bits makes finding the next leap frame
+ * a bit easier.
+ */
+static void
+reset_times(
+ leap_table_t * pt)
+{
+ memset(&pt->head.ebase, 0xFF, sizeof(vint64));
+ pt->head.stime = pt->head.ebase;
+ pt->head.ttime = pt->head.ebase;
+ pt->head.dtime = pt->head.ebase;
+}
+
+/* [internal] Add raw data to the table, removing old entries on the
+ * fly. This cannot fail currently.
+ */
+static int/*BOOL*/
+add_range(
+ leap_table_t * pt,
+ const leap_info_t * pi)
+{
+ /* If the table is full, make room by throwing out the oldest
+ * entry. But remember the accumulated leap seconds!
+ *
+ * Setting the first entry is a bit tricky, too: Simply assuming
+ * it is an insertion is wrong if the first entry is a dynamic
+ * leap second removal. So we decide on the sign -- if the first
+ * entry has a negative offset, we assume that it is a leap
+ * second removal. In both cases the table base offset is set
+ * accordingly to reflect the decision.
+ *
+ * In practice starting with a removal can only happen if the
+ * first entry is a dynamic request without having a leap file
+ * for the history proper.
+ */
+ if (pt->head.size == 0) {
+ if (pi->taiof >= 0)
+ pt->head.base_tai = pi->taiof - 1;
+ else
+ pt->head.base_tai = pi->taiof + 1;
+ } else if (pt->head.size >= MAX_HIST) {
+ pt->head.size = MAX_HIST - 1;
+ pt->head.base_tai = pt->info[pt->head.size].taiof;
+ }
+
+ /* make room in lower end and insert item */
+ memmove(pt->info+1, pt->info, pt->head.size*sizeof(*pt->info));
+ pt->info[0] = *pi;
+ pt->head.size++;
+
+ /* invalidate the cached limit data -- we might have news ;-)
+ *
+ * This blocks a spurious transition detection. OTOH, if you add
+ * a value after the last query before a leap transition was
+ * expected to occur, this transition trigger is lost. But we
+ * can probably live with that.
+ */
+ reset_times(pt);
+ return TRUE;
+}
+
+/* [internal] given a reader function, read characters into a buffer
+ * until either EOL or EOF is reached. Makes sure that the buffer is
+ * always NUL terminated, but silently truncates excessive data. The
+ * EOL-marker ('\n') is *not* stored in the buffer.
+ *
+ * Returns the pointer to the buffer, unless EOF was reached when trying
+ * to read the first character of a line.
+ */
+static char *
+get_line(
+ leapsec_reader func,
+ void * farg,
+ char * buff,
+ size_t size)
+{
+ int ch;
+ char *ptr;
+
+ /* if we cannot even store the delimiter, declare failure */
+ if (buff == NULL || size == 0)
+ return NULL;
+
+ ptr = buff;
+ while (EOF != (ch = (*func)(farg)) && '\n' != ch)
+ if (size > 1) {
+ size--;
+ *ptr++ = (char)ch;
+ }
+ /* discard trailing whitespace */
+ while (ptr != buff && isspace((u_char)ptr[-1]))
+ ptr--;
+ *ptr = '\0';
+ return (ptr == buff && ch == EOF) ? NULL : buff;
+}
+
+/* [internal] skips whitespace characters from a character buffer. */
+static char *
+skipws(
+ const char *ptr)
+{
+ while (isspace((u_char)*ptr))
+ ptr++;
+ return (char*)noconst(ptr);
+}
+
+/* [internal] check if a strtoXYZ ended at EOL or whitespace and
+ * converted something at all. Return TRUE if something went wrong.
+ */
+static int/*BOOL*/
+parsefail(
+ const char * cp,
+ const char * ep)
+{
+ return (cp == ep)
+ || (*ep && *ep != '#' && !isspace((u_char)*ep));
+}
+
+/* [internal] reload the table limits around the given time stamp. This
+ * is where the real work is done when it comes to table lookup and
+ * evaluation. Some care has been taken to have correct code for dealing
+ * with boundary conditions and empty tables.
+ *
+ * In electric mode, transition and trip time are the same. In dumb
+ * mode, the difference of the TAI offsets must be taken into account
+ * and trip time and transition time become different. The difference
+ * becomes the warping distance when the trip time is reached.
+ */
+static void
+reload_limits(
+ leap_table_t * pt,
+ const vint64 * ts)
+{
+ int idx;
+
+ /* Get full time and search the true lower bound. Use a
+ * simple loop here, since the number of entries does
+ * not warrant a binary search. This also works for an empty
+ * table, so there is no shortcut for that case.
+ */
+ for (idx = 0; idx != pt->head.size; idx++)
+ if (ucmpv64(ts, &pt->info[idx].ttime) >= 0)
+ break;
+
+ /* get time limits with proper bound conditions. Note that the
+ * bounds of the table will be observed even if the table is
+ * empty -- no undefined condition must arise from this code.
+ */
+ if (idx >= pt->head.size) {
+ memset(&pt->head.ebase, 0x00, sizeof(vint64));
+ pt->head.this_tai = pt->head.base_tai;
+ } else {
+ pt->head.ebase = pt->info[idx].ttime;
+ pt->head.this_tai = pt->info[idx].taiof;
+ }
+ if (--idx >= 0) {
+ pt->head.next_tai = pt->info[idx].taiof;
+ pt->head.dynls = pt->info[idx].dynls;
+ pt->head.ttime = pt->info[idx].ttime;
+
+ if (_electric)
+ pt->head.dtime = pt->head.ttime;
+ else
+ pt->head.dtime = addv64i32(
+ &pt->head.ttime,
+ pt->head.next_tai - pt->head.this_tai);
+
+ pt->head.stime = subv64u32(
+ &pt->head.ttime, pt->info[idx].stime);
+
+ } else {
+ memset(&pt->head.ttime, 0xFF, sizeof(vint64));
+ pt->head.stime = pt->head.ttime;
+ pt->head.dtime = pt->head.ttime;
+ pt->head.next_tai = pt->head.this_tai;
+ pt->head.dynls = 0;
+ }
+}
+
+/* [internal] fetch the leap era for a given time stamp.
+ * This is a cut-down version the algorithm used to reload the table
+ * limits, but it does not update any global state and provides just the
+ * era information for a given time stamp.
+ */
+static void
+fetch_leap_era(
+ leap_era_t * into,
+ const leap_table_t * pt ,
+ const vint64 * ts )
+{
+ int idx;
+
+ /* Simple search loop, also works with empty table. */
+ for (idx = 0; idx != pt->head.size; idx++)
+ if (ucmpv64(ts, &pt->info[idx].ttime) >= 0)
+ break;
+ /* fetch era data, keeping an eye on boundary conditions */
+ if (idx >= pt->head.size) {
+ memset(&into->ebase, 0x00, sizeof(vint64));
+ into->taiof = pt->head.base_tai;
+ } else {
+ into->ebase = pt->info[idx].ttime;
+ into->taiof = pt->info[idx].taiof;
+ }
+ if (--idx >= 0)
+ into->ttime = pt->info[idx].ttime;
+ else
+ memset(&into->ttime, 0xFF, sizeof(vint64));
+}
+
+/* [internal] Take a time stamp and create a leap second frame for
+ * it. This will schedule a leap second for the beginning of the next
+ * month, midnight UTC. The 'insert' argument tells if a leap second is
+ * added (!=0) or removed (==0). We do not handle multiple inserts
+ * (yet?)
+ *
+ * Returns 1 if the insert worked, 0 otherwise. (It's not possible to
+ * insert a leap second into the current history -- only appending
+ * towards the future is allowed!)
+ */
+static int/*BOOL*/
+leapsec_add(
+ leap_table_t* pt ,
+ const vint64 * now64 ,
+ int insert)
+{
+ vint64 ttime, starttime;
+ struct calendar fts;
+ leap_info_t li;
+
+ /* Check against the table expiration and the latest available
+ * leap entry. Do not permit inserts, only appends, and only if
+ * the extend the table beyond the expiration!
+ */
+ if ( ucmpv64(now64, &pt->head.expire) < 0
+ || (pt->head.size && ucmpv64(now64, &pt->info[0].ttime) <= 0)) {
+ errno = ERANGE;
+ return FALSE;
+ }
+
+ ntpcal_ntp64_to_date(&fts, now64);
+ /* To guard against dangling leap flags: do not accept leap
+ * second request on the 1st hour of the 1st day of the month.
+ */
+ if (fts.monthday == 1 && fts.hour == 0) {
+ errno = EINVAL;
+ return FALSE;
+ }
+
+ /* Ok, do the remaining calculations */
+ fts.monthday = 1;
+ fts.hour = 0;
+ fts.minute = 0;
+ fts.second = 0;
+ starttime = ntpcal_date_to_ntp64(&fts);
+ fts.month++;
+ ttime = ntpcal_date_to_ntp64(&fts);
+
+ li.ttime = ttime;
+ li.stime = ttime.D_s.lo - starttime.D_s.lo;
+ li.taiof = (pt->head.size ? pt->info[0].taiof : pt->head.base_tai)
+ + (insert ? 1 : -1);
+ li.dynls = 1;
+ return add_range(pt, &li);
+}
+
+/* [internal] Given a time stamp for a leap insertion (the exact begin
+ * of the new leap era), create new leap frame and put it into the
+ * table. This is the work horse for reading a leap file and getting a
+ * leap second update via authenticated network packet.
+ */
+int/*BOOL*/
+leapsec_raw(
+ leap_table_t * pt,
+ const vint64 * ttime,
+ int taiof,
+ int dynls)
+{
+ vint64 starttime;
+ struct calendar fts;
+ leap_info_t li;
+
+ /* Check that we either extend the table or get a duplicate of
+ * the latest entry. The latter is a benevolent overwrite with
+ * identical data and could happen if we get an autokey message
+ * that extends the lifetime of the current leapsecond table.
+ * Otherwise paranoia rulez!
+ */
+ if (pt->head.size) {
+ int cmp = ucmpv64(ttime, &pt->info[0].ttime);
+ if (cmp == 0)
+ cmp -= (taiof != pt->info[0].taiof);
+ if (cmp < 0) {
+ errno = ERANGE;
+ return FALSE;
+ }
+ if (cmp == 0)
+ return TRUE;
+ }
+
+ ntpcal_ntp64_to_date(&fts, ttime);
+ /* If this does not match the exact month start, bail out. */
+ if (fts.monthday != 1 || fts.hour || fts.minute || fts.second) {
+ errno = EINVAL;
+ return FALSE;
+ }
+ fts.month--; /* was in range 1..12, no overflow here! */
+ starttime = ntpcal_date_to_ntp64(&fts);
+ li.ttime = *ttime;
+ li.stime = ttime->D_s.lo - starttime.D_s.lo;
+ li.taiof = (int16_t)taiof;
+ li.dynls = (dynls != 0);
+ return add_range(pt, &li);
+}
+
+/* [internal] Do a wrap-around save range inclusion check.
+ * Returns TRUE if x in [lo,hi[ (intervall open on right side) with full
+ * handling of an overflow / wrap-around.
+ */
+static int/*BOOL*/
+betweenu32(
+ uint32_t lo,
+ uint32_t x,
+ uint32_t hi)
+{
+ int rc;
+
+ if (lo <= hi)
+ rc = (lo <= x) && (x < hi);
+ else
+ rc = (lo <= x) || (x < hi);
+ return rc;
+}
+
+/* =====================================================================
+ * validation stuff
+ */
+
+typedef struct {
+ unsigned char hv[ISC_SHA1_DIGESTLENGTH];
+} sha1_digest;
+
+/* [internal] parse a digest line to get the hash signature
+ * The NIST code creating the hash writes them out as 5 hex integers
+ * without leading zeros. This makes reading them back as hex-encoded
+ * BLOB impossible, because there might be less than 40 hex digits.
+ *
+ * The solution is to read the values back as integers, and then do the
+ * byte twiddle necessary to get it into an array of 20 chars. The
+ * drawback is that it permits any acceptable number syntax provided by
+ * 'scanf()' and 'strtoul()', including optional signs and '0x'
+ * prefixes.
+ */
+static int/*BOOL*/
+do_leap_hash(
+ sha1_digest * mac,
+ char const * cp )
+{
+ int wi, di, num, len;
+ unsigned long tmp[5];
+
+ memset(mac, 0, sizeof(*mac));
+ num = sscanf(cp, " %lx %lx %lx %lx %lx%n",
+ &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4],
+ &len);
+ if (num != 5 || cp[len] > ' ')
+ return FALSE;
+
+ /* now do the byte twiddle */
+ for (wi=0; wi < 5; ++wi)
+ for (di=3; di >= 0; --di) {
+ mac->hv[wi*4 + di] =
+ (unsigned char)(tmp[wi] & 0x0FF);
+ tmp[wi] >>= 8;
+ }
+ return TRUE;
+}
+
+/* [internal] add the digits of a data line to the hash, stopping at the
+ * next hash ('#') character.
+ */
+static void
+do_hash_data(
+ isc_sha1_t * mdctx,
+ char const * cp )
+{
+ unsigned char text[32]; // must be power of two!
+ unsigned int tlen = 0;
+ unsigned char ch;
+
+ while ('\0' != (ch = *cp++) && '#' != ch)
+ if (isdigit(ch)) {
+ text[tlen++] = ch;
+ tlen &= (sizeof(text)-1);
+ if (0 == tlen)
+ isc_sha1_update(
+ mdctx, text, sizeof(text));
+ }
+
+ if (0 < tlen)
+ isc_sha1_update(mdctx, text, tlen);
+}
+
+/* given a reader and a reader arg, calculate and validate the the hash
+ * signature of a NIST leap second file.
+ */
+int
+leapsec_validate(
+ leapsec_reader func,
+ void * farg)
+{
+ isc_sha1_t mdctx;
+ sha1_digest rdig, ldig; /* remote / local digests */
+ char line[50];
+ int hlseen = -1;
+
+ isc_sha1_init(&mdctx);
+ while (get_line(func, farg, line, sizeof(line))) {
+ if (!strncmp(line, "#h", 2))
+ hlseen = do_leap_hash(&rdig, line+2);
+ else if (!strncmp(line, "#@", 2))
+ do_hash_data(&mdctx, line+2);
+ else if (!strncmp(line, "#$", 2))
+ do_hash_data(&mdctx, line+2);
+ else if (isdigit((unsigned char)line[0]))
+ do_hash_data(&mdctx, line);
+ }
+ isc_sha1_final(&mdctx, ldig.hv);
+ isc_sha1_invalidate(&mdctx);
+
+ if (0 > hlseen)
+ return LSVALID_NOHASH;
+ if (0 == hlseen)
+ return LSVALID_BADFORMAT;
+ if (0 != memcmp(&rdig, &ldig, sizeof(sha1_digest)))
+ return LSVALID_BADHASH;
+ return LSVALID_GOODHASH;
+}
+
+/*
+ * lstostr - prettyprint NTP seconds
+ */
+static const char *
+lstostr(
+ const vint64 * ts)
+{
+ char * buf;
+ struct calendar tm;
+
+ LIB_GETBUF(buf);
+
+ if ( ! (ts->d_s.hi >= 0 && ntpcal_ntp64_to_date(&tm, ts) >= 0))
+ snprintf(buf, LIB_BUFLENGTH, "%s", "9999-12-31T23:59:59Z");
+ else
+ snprintf(buf, LIB_BUFLENGTH, "%04d-%02d-%02dT%02d:%02d:%02dZ",
+ tm.year, tm.month, tm.monthday,
+ tm.hour, tm.minute, tm.second);
+
+ return buf;
+}
+
+/* reset the global state for unit tests */
+void
+leapsec_ut_pristine(void)
+{
+ memset(_ltab, 0, sizeof(_ltab));
+ _lptr = NULL;
+ _electric = 0;
+}
+
+
+
+/* -*- that's all folks! -*- */
diff --git a/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_leapsec.h b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_leapsec.h
new file mode 100644
index 0000000..120b75f
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_leapsec.h
@@ -0,0 +1,276 @@
+/*
+ * ntp_leapsec.h - leap second processing for NTPD
+ *
+ * Written by Juergen Perlinger (perlinger@ntp.org) for the NTP project.
+ * The contents of 'html/copyright.html' apply.
+ * ----------------------------------------------------------------------
+ * This is an attempt to get the leap second handling into a dedicated
+ * module to make the somewhat convoluted logic testable.
+ */
+
+#ifndef NTP_LEAPSEC_H
+#define NTP_LEAPSEC_H
+
+struct stat;
+
+
+/* function pointer types. Note that 'fprintf' and 'getc' can be casted
+ * to the dumper resp. reader type, provided the auxiliary argument is a
+ * valid FILE pointer in hat case.
+ */
+typedef void (*leapsec_dumper)(void*, const char *fmt, ...);
+typedef int (*leapsec_reader)(void*);
+
+struct leap_table;
+typedef struct leap_table leap_table_t;
+
+/* Validate a stream containing a leap second file in the NIST / NTPD
+ * format that can also be loaded via 'leapsec_load()'. This uses
+ * the SHA1 hash and preprocessing as described in the NIST leapsecond
+ * file.
+ */
+#define LSVALID_GOODHASH 1 /* valid signature */
+#define LSVALID_NOHASH 0 /* no signature in file */
+#define LSVALID_BADHASH -1 /* signature mismatch */
+#define LSVALID_BADFORMAT -2 /* signature not parseable */
+
+extern int leapsec_validate(leapsec_reader, void*);
+
+
+/* Set/get electric mode
+ * Electric mode is defined as the operation mode where the system clock
+ * automagically manages the leap second, so we don't have to care about
+ * stepping the clock. (This should be the case with most systems,
+ * including the current implementation of the Win32 timekeeping.)
+ *
+ * The consequence of electric mode is that we do not 'see' the leap
+ * second, and no client actions are needed when crossing the leap era
+ * boundary. In manual (aka non-electric) mode the clock will simply
+ * step forward untill *we* (that is, this module) tells the client app
+ * to step at the right time. This needs a slightly different type of
+ * processing, so switching between those two modes should not be done
+ * too close to a leap second. The transition might be lost in that
+ * case. (The limit is actual 2 sec before transition.)
+ *
+ * OTOH, this is a system characteristic, so it's expected to be set
+ * properly somewhere after system start and retain the value.
+ *
+ * Simply querying the state or setting it to the same value as before
+ * does not have any unwanted side effects. You can query by giving a
+ * negative value for the switch.
+ */
+extern int/*BOOL*/ leapsec_electric(int/*BOOL*/ on);
+
+/* Query result for a leap era. This is the minimal stateless
+ * information available for a time stamp in UTC.
+ */
+struct leap_era {
+ vint64 ebase; /* era base (UTC of start) */
+ vint64 ttime; /* era end (UTC of next leap second) */
+ int16_t taiof; /* offset to TAI in this era */
+};
+typedef struct leap_era leap_era_t;
+
+/* Query result for a leap second schedule
+ * 'ebase' is the nominal UTC time when the current leap era
+ * started. (Era base time)
+ * 'ttime' is the next transition point in full time scale. (Nominal UTC
+ * time when the next leap era starts.)
+ * 'ddist' is the distance to the transition, in clock seconds.
+ * This is the distance to the due time, which is different
+ * from the transition time if the mode is non-electric.
+ * Only valid if 'tai_diff' is not zero.
+ * 'tai_offs' is the CURRENT distance from clock (UTC) to TAI. Always
+ * valid.
+ * 'tai_diff' is the change in TAI offset after the next leap
+ * transition. Zero if nothing is pending or too far ahead.
+ * 'warped' is set only once, when the the leap second occurred between
+ * two queries. Always zero in electric mode. If non-zero,
+ * immediately step the clock.
+ * 'proximity' is a proximity warning. See definitions below. This is
+ * more useful than an absolute difference to the leap second.
+ * 'dynamic' != 0 if entry was requested by clock/peer
+ */
+struct leap_result {
+ vint64 ebase;
+ vint64 ttime;
+ uint32_t ddist;
+ int16_t tai_offs;
+ int16_t tai_diff;
+ int16_t warped;
+ uint8_t proximity;
+ uint8_t dynamic;
+};
+typedef struct leap_result leap_result_t;
+
+/* The leap signature is used in two distinct circumstances, and it has
+ * slightly different content in these cases:
+ * - it is used to indictae the time range covered by the leap second
+ * table, and then it contains the last transition, TAI offset after
+ * the final transition, and the expiration time.
+ * - it is used to query data for AUTOKEY updates, and then it contains
+ * the *current* TAI offset, the *next* transition time and the
+ * expiration time of the table.
+ */
+struct leap_signature {
+ uint32_t etime; /* expiration time */
+ uint32_t ttime; /* transition time */
+ int16_t taiof; /* total offset to TAI */
+};
+typedef struct leap_signature leap_signature_t;
+
+
+#ifdef LEAP_SMEAR
+
+struct leap_smear_info {
+ int enabled; /* not 0 if smearing is generally enabled */
+ int in_progress; /* not 0 if smearing is in progress, i.e. the offset has been computed */
+ int leap_occurred; /* not 0 if the leap second has already occurred, i.e., during the leap second */
+ double doffset; /* the current smear offset as double */
+ l_fp offset; /* the current smear offset */
+ uint32_t t_offset; /* the current time for which a smear offset has been computed */
+ long interval; /* smear interval, in [s], should be at least some hours */
+ double intv_start; /* start time of the smear interval */
+ double intv_end; /* end time of the smear interval */
+};
+typedef struct leap_smear_info leap_smear_info_t;
+
+#endif /* LEAP_SMEAR */
+
+
+#define LSPROX_NOWARN 0 /* clear radar screen */
+#define LSPROX_SCHEDULE 1 /* less than 1 month to target*/
+#define LSPROX_ANNOUNCE 2 /* less than 1 day to target */
+#define LSPROX_ALERT 3 /* less than 10 sec to target */
+
+/* Get the current or alternate table pointer. Getting the alternate
+ * pointer will automatically copy the primary table, so it can be
+ * subsequently modified.
+ */
+extern leap_table_t *leapsec_get_table(int alternate);
+
+/* Set the current leap table. Accepts only return values from
+ * 'leapsec_get_table()', so it's hard to do something wrong. Returns
+ * TRUE if the current table is the requested one.
+ */
+extern int/*BOOL*/ leapsec_set_table(leap_table_t *);
+
+/* Clear all leap second data. Use it for init & cleanup */
+extern void leapsec_clear(leap_table_t*);
+
+/* Load a leap second file. If 'blimit' is set, do not store (but
+ * register with their TAI offset) leap entries before the build date.
+ * Update the leap signature data on the fly.
+ */
+extern int/*BOOL*/ leapsec_load(leap_table_t*, leapsec_reader,
+ void*, int blimit);
+
+/* Dump the current leap table in readable format, using the provided
+ * dump formatter function.
+ */
+extern void leapsec_dump(const leap_table_t*, leapsec_dumper func, void *farg);
+
+/* Read a leap second file from stream. This is a convenience wrapper
+ * around the generic load function, 'leapsec_load()'.
+ */
+extern int/*BOOL*/ leapsec_load_stream(FILE * fp, const char * fname,
+ int/*BOOL*/logall);
+
+/* Read a leap second file from file. It checks that the file exists and
+ * (if 'force' is not applied) the ctime/mtime has changed since the
+ * last load. If the file has to be loaded, either due to 'force' or
+ * changed time stamps, the 'stat()' results of the file are stored in
+ * '*sb' for the next cycle. Returns TRUE on successful load, FALSE
+ * otherwise. Uses 'leapsec_load_stream()' internally.
+ */
+extern int/*BOOL*/ leapsec_load_file(const char * fname, struct stat * sb,
+ int/*BOOL*/force, int/*BOOL*/logall);
+
+/* Get the current leap data signature. This consists of the last
+ * ransition, the table expiration, and the total TAI difference at the
+ * last transition. This is valid even if the leap transition itself was
+ * culled due to the build date limit.
+ */
+extern void leapsec_getsig(leap_signature_t * psig);
+
+/* Check if the leap table is expired at the given time.
+ */
+extern int/*BOOL*/ leapsec_expired(uint32_t when, const time_t * pivot);
+
+/* Get the distance to expiration in days.
+ * Returns negative values if expired, zero if there are less than 24hrs
+ * left, and positive numbers otherwise.
+ */
+extern int32_t leapsec_daystolive(uint32_t when, const time_t * pivot);
+
+/* Reset the current leap frame, so the next query will do proper table
+ * lookup from fresh. Suppresses a possible leap era transition detection
+ * for the next query.
+ */
+extern void leapsec_reset_frame(void);
+
+#if 0 /* currently unused -- possibly revived later */
+/* Given a transition time, the TAI offset valid after that and an
+ * expiration time, try to establish a system leap transition. Only
+ * works if the existing table is extended. On success, updates the
+ * signature data.
+ */
+extern int/*BOOL*/ leapsec_add_fix(int offset, uint32_t ttime, uint32_t etime,
+ const time_t * pivot);
+#endif
+
+/* Take a time stamp and create a leap second frame for it. This will
+ * schedule a leap second for the beginning of the next month, midnight
+ * UTC. The 'insert' argument tells if a leap second is added (!=0) or
+ * removed (==0). We do not handle multiple inserts (yet?)
+ *
+ * Returns 1 if the insert worked, 0 otherwise. (It's not possible to
+ * insert a leap second into the current history -- only appending
+ * towards the future is allowed!)
+ *
+ * 'ntp_now' is subject to era unfolding. The entry is marked
+ * dynamic. The leap signature is NOT updated.
+ */
+extern int/*BOOL*/ leapsec_add_dyn(int/*BOOL*/ insert, uint32_t ntp_now,
+ const time_t * pivot);
+
+/* Take a time stamp and get the associated leap information. The time
+ * stamp is subject to era unfolding around the pivot or the current
+ * system time if pivot is NULL. Sets the information in '*qr' and
+ * returns TRUE if a leap second era boundary was crossed between the
+ * last and the current query. In that case, qr->warped contains the
+ * required clock stepping, which is always zero in electric mode.
+ */
+extern int/*BOOL*/ leapsec_query(leap_result_t * qr, uint32_t ntpts,
+ const time_t * pivot);
+
+/* For a given time stamp, fetch the data for the bracketing leap
+ * era. The time stamp is subject to NTP era unfolding.
+ */
+extern int/*BOOL*/ leapsec_query_era(leap_era_t * qr, uint32_t ntpts,
+ const time_t * pivot);
+
+/* Get the current leap frame info. Returns TRUE if the result contains
+ * useable data, FALSE if there is currently no leap second frame.
+ * This merely replicates some results from a previous query, but since
+ * it does not check the current time, only the following entries are
+ * meaningful:
+ * qr->ttime;
+ * qr->tai_offs;
+ * qr->tai_diff;
+ * qr->dynamic;
+ */
+extern int/*BOOL*/ leapsec_frame(leap_result_t *qr);
+
+
+/* Process a AUTOKEY TAI offset information. This *might* augment the
+ * current leap data table with the given TAI offset.
+ * Returns TRUE if action was taken, FALSE otherwise.
+ */
+extern int/*BOOL*/ leapsec_autokey_tai(int tai_offset, uint32_t ntpnow,
+ const time_t * pivot);
+
+/* reset global state for unit tests */
+extern void leapsec_ut_pristine(void);
+
+#endif /* !defined(NTP_LEAPSEC_H) */
diff --git a/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_loopfilter.c b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_loopfilter.c
new file mode 100644
index 0000000..07ec14c
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_loopfilter.c
@@ -0,0 +1,1397 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * ntp_loopfilter.c - implements the NTP loop filter algorithm
+ *
+ * ATTENTION: Get approval from Dave Mills on all changes to this file!
+ *
+ */
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef USE_SNPRINTB
+# include <util.h>
+#endif
+#include "ntpd.h"
+#include "ntp_io.h"
+#include "ntp_unixtime.h"
+#include "ntp_stdlib.h"
+
+#include <limits.h>
+#include <stdio.h>
+#include <ctype.h>
+
+#include <signal.h>
+#include <setjmp.h>
+
+#ifdef KERNEL_PLL
+#include "ntp_syscall.h"
+#endif /* KERNEL_PLL */
+
+/*
+ * This is an implementation of the clock discipline algorithm described
+ * in UDel TR 97-4-3, as amended. It operates as an adaptive parameter,
+ * hybrid phase/frequency-lock loop. A number of sanity checks are
+ * included to protect against timewarps, timespikes and general mayhem.
+ * All units are in s and s/s, unless noted otherwise.
+ */
+#define CLOCK_MAX .128 /* default step threshold (s) */
+#define CLOCK_MINSTEP 300. /* default stepout threshold (s) */
+#define CLOCK_PANIC 1000. /* default panic threshold (s) */
+#define CLOCK_PHI 15e-6 /* max frequency error (s/s) */
+#define CLOCK_PLL 16. /* PLL loop gain (log2) */
+#define CLOCK_AVG 8. /* parameter averaging constant */
+#define CLOCK_FLL .25 /* FLL loop gain */
+#define CLOCK_FLOOR .0005 /* startup offset floor (s) */
+#define CLOCK_ALLAN 11 /* Allan intercept (log2 s) */
+#define CLOCK_LIMIT 30 /* poll-adjust threshold */
+#define CLOCK_PGATE 4. /* poll-adjust gate */
+#define PPS_MAXAGE 120 /* kernel pps signal timeout (s) */
+#define FREQTOD(x) ((x) / 65536e6) /* NTP to double */
+#define DTOFREQ(x) ((int32)((x) * 65536e6)) /* double to NTP */
+
+/*
+ * Clock discipline state machine. This is used to control the
+ * synchronization behavior during initialization and following a
+ * timewarp.
+ *
+ * State < step > step Comments
+ * ========================================================
+ * NSET FREQ step, FREQ freq not set
+ *
+ * FSET SYNC step, SYNC freq set
+ *
+ * FREQ if (mu < 900) if (mu < 900) set freq direct
+ * ignore ignore
+ * else else
+ * freq, SYNC freq, step, SYNC
+ *
+ * SYNC SYNC SPIK, ignore adjust phase/freq
+ *
+ * SPIK SYNC if (mu < 900) adjust phase/freq
+ * ignore
+ * step, SYNC
+ */
+/*
+ * Kernel PLL/PPS state machine. This is used with the kernel PLL
+ * modifications described in the documentation.
+ *
+ * If kernel support for the ntp_adjtime() system call is available, the
+ * ntp_control flag is set. The ntp_enable and kern_enable flags can be
+ * set at configuration time or run time using ntpdc. If ntp_enable is
+ * false, the discipline loop is unlocked and no corrections of any kind
+ * are made. If both ntp_control and kern_enable are set, the kernel
+ * support is used as described above; if false, the kernel is bypassed
+ * entirely and the daemon discipline used instead.
+ *
+ * There have been three versions of the kernel discipline code. The
+ * first (microkernel) now in Solaris discipilnes the microseconds. The
+ * second and third (nanokernel) disciplines the clock in nanoseconds.
+ * These versions are identifed if the symbol STA_PLL is present in the
+ * header file /usr/include/sys/timex.h. The third and current version
+ * includes TAI offset and is identified by the symbol NTP_API with
+ * value 4.
+ *
+ * Each PPS time/frequency discipline can be enabled by the atom driver
+ * or another driver. If enabled, the STA_PPSTIME and STA_FREQ bits are
+ * set in the kernel status word; otherwise, these bits are cleared.
+ * These bits are also cleard if the kernel reports an error.
+ *
+ * If an external clock is present, the clock driver sets STA_CLK in the
+ * status word. When the local clock driver sees this bit, it updates
+ * via this routine, which then calls ntp_adjtime() with the STA_PLL bit
+ * set to zero, in which case the system clock is not adjusted. This is
+ * also a signal for the external clock driver to discipline the system
+ * clock. Unless specified otherwise, all times are in seconds.
+ */
+/*
+ * Program variables that can be tinkered.
+ */
+double clock_max_back = CLOCK_MAX; /* step threshold */
+double clock_max_fwd = CLOCK_MAX; /* step threshold */
+double clock_minstep = CLOCK_MINSTEP; /* stepout threshold */
+double clock_panic = CLOCK_PANIC; /* panic threshold */
+double clock_phi = CLOCK_PHI; /* dispersion rate (s/s) */
+u_char allan_xpt = CLOCK_ALLAN; /* Allan intercept (log2 s) */
+
+/*
+ * Program variables
+ */
+static double clock_offset; /* offset */
+double clock_jitter; /* offset jitter */
+double drift_comp; /* frequency (s/s) */
+static double init_drift_comp; /* initial frequency (PPM) */
+double clock_stability; /* frequency stability (wander) (s/s) */
+double clock_codec; /* audio codec frequency (samples/s) */
+static u_long clock_epoch; /* last update */
+u_int sys_tai; /* TAI offset from UTC */
+static int loop_started; /* TRUE after LOOP_DRIFTINIT */
+static void rstclock (int, double); /* transition function */
+static double direct_freq(double); /* direct set frequency */
+static void set_freq(double); /* set frequency */
+#ifndef PATH_MAX
+# define PATH_MAX MAX_PATH
+#endif
+static char relative_path[PATH_MAX + 1]; /* relative path per recursive make */
+static char *this_file = NULL;
+
+#ifdef KERNEL_PLL
+static struct timex ntv; /* ntp_adjtime() parameters */
+int pll_status; /* last kernel status bits */
+#if defined(STA_NANO) && NTP_API == 4
+static u_int loop_tai; /* last TAI offset */
+#endif /* STA_NANO */
+static void start_kern_loop(void);
+static void stop_kern_loop(void);
+#endif /* KERNEL_PLL */
+
+/*
+ * Clock state machine control flags
+ */
+int ntp_enable = TRUE; /* clock discipline enabled */
+int pll_control; /* kernel support available */
+int kern_enable = TRUE; /* kernel support enabled */
+int hardpps_enable; /* kernel PPS discipline enabled */
+int ext_enable; /* external clock enabled */
+int pps_stratum; /* pps stratum */
+int kernel_status; /* from ntp_adjtime */
+int force_step_once = FALSE; /* always step time once at startup (-G) */
+int mode_ntpdate = FALSE; /* exit on first clock set (-q) */
+int freq_cnt; /* initial frequency clamp */
+int freq_set; /* initial set frequency switch */
+
+/*
+ * Clock state machine variables
+ */
+int state = 0; /* clock discipline state */
+u_char sys_poll; /* time constant/poll (log2 s) */
+int tc_counter; /* jiggle counter */
+double last_offset; /* last offset (s) */
+
+/*
+ * Huff-n'-puff filter variables
+ */
+static double *sys_huffpuff; /* huff-n'-puff filter */
+static int sys_hufflen; /* huff-n'-puff filter stages */
+static int sys_huffptr; /* huff-n'-puff filter pointer */
+static double sys_mindly; /* huff-n'-puff filter min delay */
+
+#if defined(KERNEL_PLL)
+/* Emacs cc-mode goes nuts if we split the next line... */
+#define MOD_BITS (MOD_OFFSET | MOD_MAXERROR | MOD_ESTERROR | \
+ MOD_STATUS | MOD_TIMECONST)
+#ifdef __rtems__
+/* ntp_adjtime() is supposed to work on RTEMS */
+#undef SIGSYS
+#endif /* __rtems__ */
+#ifdef SIGSYS
+static void pll_trap (int); /* configuration trap */
+static struct sigaction sigsys; /* current sigaction status */
+static struct sigaction newsigsys; /* new sigaction status */
+static sigjmp_buf env; /* environment var. for pll_trap() */
+#endif /* SIGSYS */
+#endif /* KERNEL_PLL */
+
+static void
+sync_status(const char *what, int ostatus, int nstatus)
+{
+ char obuf[256], nbuf[256], tbuf[1024];
+#if defined(USE_SNPRINTB) && defined (STA_FMT)
+ snprintb(obuf, sizeof(obuf), STA_FMT, ostatus);
+ snprintb(nbuf, sizeof(nbuf), STA_FMT, nstatus);
+#else
+ snprintf(obuf, sizeof(obuf), "%04x", ostatus);
+ snprintf(nbuf, sizeof(nbuf), "%04x", nstatus);
+#endif
+ snprintf(tbuf, sizeof(tbuf), "%s status: %s -> %s", what, obuf, nbuf);
+ report_event(EVNT_KERN, NULL, tbuf);
+}
+
+/*
+ * file_name - return pointer to non-relative portion of this C file pathname
+ */
+static char *file_name(void)
+{
+ if (this_file == NULL) {
+ (void)strncpy(relative_path, __FILE__, PATH_MAX);
+ for (this_file=relative_path;
+ *this_file && ! isalnum((unsigned char)*this_file);
+ this_file++) ;
+ }
+ return this_file;
+}
+
+/*
+ * init_loopfilter - initialize loop filter data
+ */
+void
+init_loopfilter(void)
+{
+ /*
+ * Initialize state variables.
+ */
+ sys_poll = ntp_minpoll;
+ clock_jitter = LOGTOD(sys_precision);
+ freq_cnt = (int)clock_minstep;
+}
+
+#ifdef KERNEL_PLL
+/*
+ * ntp_adjtime_error_handler - process errors from ntp_adjtime
+ */
+static void
+ntp_adjtime_error_handler(
+ const char *caller, /* name of calling function */
+ struct timex *ptimex, /* pointer to struct timex */
+ int ret, /* return value from ntp_adjtime */
+ int saved_errno, /* value of errno when ntp_adjtime returned */
+ int pps_call, /* ntp_adjtime call was PPS-related */
+ int tai_call, /* ntp_adjtime call was TAI-related */
+ int line /* line number of ntp_adjtime call */
+ )
+{
+ char des[1024] = ""; /* Decoded Error Status */
+ char *dbp, *ebp;
+
+ dbp = des;
+ ebp = dbp + sizeof(des);
+
+ switch (ret) {
+ case -1:
+ switch (saved_errno) {
+ case EFAULT:
+ msyslog(LOG_ERR, "%s: %s line %d: invalid struct timex pointer: 0x%lx",
+ caller, file_name(), line,
+ (long)((void *)ptimex)
+ );
+ break;
+ case EINVAL:
+ msyslog(LOG_ERR, "%s: %s line %d: invalid struct timex \"constant\" element value: %ld",
+ caller, file_name(), line,
+ (long)(ptimex->constant)
+ );
+ break;
+ case EPERM:
+ if (tai_call) {
+ errno = saved_errno;
+ msyslog(LOG_ERR,
+ "%s: ntp_adjtime(TAI) failed: %m",
+ caller);
+ }
+ errno = saved_errno;
+ msyslog(LOG_ERR, "%s: %s line %d: ntp_adjtime: %m",
+ caller, file_name(), line
+ );
+ break;
+ default:
+ msyslog(LOG_NOTICE, "%s: %s line %d: unhandled errno value %d after failed ntp_adjtime call",
+ caller, file_name(), line,
+ saved_errno
+ );
+ break;
+ }
+ break;
+#ifdef TIME_OK
+ case TIME_OK: /* 0: synchronized, no leap second warning */
+ /* msyslog(LOG_INFO, "kernel reports time is synchronized normally"); */
+ break;
+#else
+# warning TIME_OK is not defined
+#endif
+#ifdef TIME_INS
+ case TIME_INS: /* 1: positive leap second warning */
+ msyslog(LOG_INFO, "kernel reports leap second insertion scheduled");
+ break;
+#else
+# warning TIME_INS is not defined
+#endif
+#ifdef TIME_DEL
+ case TIME_DEL: /* 2: negative leap second warning */
+ msyslog(LOG_INFO, "kernel reports leap second deletion scheduled");
+ break;
+#else
+# warning TIME_DEL is not defined
+#endif
+#ifdef TIME_OOP
+ case TIME_OOP: /* 3: leap second in progress */
+ msyslog(LOG_INFO, "kernel reports leap second in progress");
+ break;
+#else
+# warning TIME_OOP is not defined
+#endif
+#ifdef TIME_WAIT
+ case TIME_WAIT: /* 4: leap second has occured */
+ msyslog(LOG_INFO, "kernel reports leap second has occurred");
+ break;
+#else
+# warning TIME_WAIT is not defined
+#endif
+#ifdef TIME_ERROR
+#if 0
+
+from the reference implementation of ntp_gettime():
+
+ // Hardware or software error
+ if ((time_status & (STA_UNSYNC | STA_CLOCKERR))
+
+ /*
+ * PPS signal lost when either time or frequency synchronization
+ * requested
+ */
+ || (time_status & (STA_PPSFREQ | STA_PPSTIME)
+ && !(time_status & STA_PPSSIGNAL))
+
+ /*
+ * PPS jitter exceeded when time synchronization requested
+ */
+ || (time_status & STA_PPSTIME &&
+ time_status & STA_PPSJITTER)
+
+ /*
+ * PPS wander exceeded or calibration error when frequency
+ * synchronization requested
+ */
+ || (time_status & STA_PPSFREQ &&
+ time_status & (STA_PPSWANDER | STA_PPSERROR)))
+ return (TIME_ERROR);
+
+or, from ntp_adjtime():
+
+ if ( (time_status & (STA_UNSYNC | STA_CLOCKERR))
+ || (time_status & (STA_PPSFREQ | STA_PPSTIME)
+ && !(time_status & STA_PPSSIGNAL))
+ || (time_status & STA_PPSTIME
+ && time_status & STA_PPSJITTER)
+ || (time_status & STA_PPSFREQ
+ && time_status & (STA_PPSWANDER | STA_PPSERROR))
+ )
+ return (TIME_ERROR);
+#endif
+
+ case TIME_ERROR: /* 5: unsynchronized, or loss of synchronization */
+ /* error (see status word) */
+
+ if (ptimex->status & STA_UNSYNC)
+ xsbprintf(&dbp, ebp, "%sClock Unsynchronized",
+ (*des) ? "; " : "");
+
+ if (ptimex->status & STA_CLOCKERR)
+ xsbprintf(&dbp, ebp, "%sClock Error",
+ (*des) ? "; " : "");
+
+ if (!(ptimex->status & STA_PPSSIGNAL)
+ && ptimex->status & STA_PPSFREQ)
+ xsbprintf(&dbp, ebp, "%sPPS Frequency Sync wanted but no PPS",
+ (*des) ? "; " : "");
+
+ if (!(ptimex->status & STA_PPSSIGNAL)
+ && ptimex->status & STA_PPSTIME)
+ xsbprintf(&dbp, ebp, "%sPPS Time Sync wanted but no PPS signal",
+ (*des) ? "; " : "");
+
+ if ( ptimex->status & STA_PPSTIME
+ && ptimex->status & STA_PPSJITTER)
+ xsbprintf(&dbp, ebp, "%sPPS Time Sync wanted but PPS Jitter exceeded",
+ (*des) ? "; " : "");
+
+ if ( ptimex->status & STA_PPSFREQ
+ && ptimex->status & STA_PPSWANDER)
+ xsbprintf(&dbp, ebp, "%sPPS Frequency Sync wanted but PPS Wander exceeded",
+ (*des) ? "; " : "");
+
+ if ( ptimex->status & STA_PPSFREQ
+ && ptimex->status & STA_PPSERROR)
+ xsbprintf(&dbp, ebp, "%sPPS Frequency Sync wanted but Calibration error detected",
+ (*des) ? "; " : "");
+
+ if (pps_call && !(ptimex->status & STA_PPSSIGNAL))
+ report_event(EVNT_KERN, NULL,
+ "no PPS signal");
+ DPRINTF(1, ("kernel loop status %#x (%s)\n",
+ ptimex->status, des));
+ /*
+ * This code may be returned when ntp_adjtime() has just
+ * been called for the first time, quite a while after
+ * startup, when ntpd just starts to discipline the kernel
+ * time. In this case the occurrence of this message
+ * can be pretty confusing.
+ *
+ * HMS: How about a message when we begin kernel processing:
+ * Determining kernel clock state...
+ * so an initial TIME_ERROR message is less confising,
+ * or skipping the first message (ugh),
+ * or ???
+ * msyslog(LOG_INFO, "kernel reports time synchronization lost");
+ */
+ msyslog(LOG_INFO, "kernel reports TIME_ERROR: %#x: %s",
+ ptimex->status, des);
+ break;
+#else
+# warning TIME_ERROR is not defined
+#endif
+ default:
+ msyslog(LOG_NOTICE, "%s: %s line %d: unhandled return value %d from ntp_adjtime() in %s at line %d",
+ caller, file_name(), line,
+ ret,
+ __func__, __LINE__
+ );
+ break;
+ }
+ return;
+}
+#endif
+
+/*
+ * local_clock - the NTP logical clock loop filter.
+ *
+ * Return codes:
+ * -1 update ignored: exceeds panic threshold
+ * 0 update ignored: popcorn or exceeds step threshold
+ * 1 clock was slewed
+ * 2 clock was stepped
+ *
+ * LOCKCLOCK: The only thing this routine does is set the
+ * sys_rootdisp variable equal to the peer dispersion.
+ */
+int
+local_clock(
+ struct peer *peer, /* synch source peer structure */
+ double fp_offset /* clock offset (s) */
+ )
+{
+ int rval; /* return code */
+ int osys_poll; /* old system poll */
+ int ntp_adj_ret; /* returned by ntp_adjtime */
+ double mu; /* interval since last update */
+ double clock_frequency; /* clock frequency */
+ double dtemp, etemp; /* double temps */
+ char tbuf[80]; /* report buffer */
+
+ (void)ntp_adj_ret; /* not always used below... */
+ /*
+ * If the loop is opened or the NIST LOCKCLOCK is in use,
+ * monitor and record the offsets anyway in order to determine
+ * the open-loop response and then go home.
+ */
+#ifndef LOCKCLOCK
+ if (!ntp_enable)
+#endif /* not LOCKCLOCK */
+ {
+ record_loop_stats(fp_offset, drift_comp, clock_jitter,
+ clock_stability, sys_poll);
+ return (0);
+ }
+
+#ifndef LOCKCLOCK
+ /*
+ * If the clock is way off, panic is declared. The clock_panic
+ * defaults to 1000 s; if set to zero, the panic will never
+ * occur. The allow_panic defaults to FALSE, so the first panic
+ * will exit. It can be set TRUE by a command line option, in
+ * which case the clock will be set anyway and time marches on.
+ * But, allow_panic will be set FALSE when the update is less
+ * than the step threshold; so, subsequent panics will exit.
+ */
+ if (fabs(fp_offset) > clock_panic && clock_panic > 0 &&
+ !allow_panic) {
+ snprintf(tbuf, sizeof(tbuf),
+ "%+.0f s; set clock manually within %.0f s.",
+ fp_offset, clock_panic);
+ report_event(EVNT_SYSFAULT, NULL, tbuf);
+ return (-1);
+ }
+
+ allow_panic = FALSE;
+
+ /*
+ * This section simulates ntpdate. If the offset exceeds the
+ * step threshold (128 ms), step the clock to that time and
+ * exit. Otherwise, slew the clock to that time and exit. Note
+ * that the slew will persist and eventually complete beyond the
+ * life of this program. Note that while ntpdate is active, the
+ * terminal does not detach, so the termination message prints
+ * directly to the terminal.
+ */
+ if (mode_ntpdate) {
+ if ( ( fp_offset > clock_max_fwd && clock_max_fwd > 0)
+ || (-fp_offset > clock_max_back && clock_max_back > 0)) {
+ step_systime(fp_offset);
+ msyslog(LOG_NOTICE, "ntpd: time set %+.6f s",
+ fp_offset);
+ printf("ntpd: time set %+.6fs\n", fp_offset);
+ } else {
+ adj_systime(fp_offset);
+ msyslog(LOG_NOTICE, "ntpd: time slew %+.6f s",
+ fp_offset);
+ printf("ntpd: time slew %+.6fs\n", fp_offset);
+ }
+ record_loop_stats(fp_offset, drift_comp, clock_jitter,
+ clock_stability, sys_poll);
+ exit (0);
+ }
+
+ /*
+ * The huff-n'-puff filter finds the lowest delay in the recent
+ * interval. This is used to correct the offset by one-half the
+ * difference between the sample delay and minimum delay. This
+ * is most effective if the delays are highly assymetric and
+ * clockhopping is avoided and the clock frequency wander is
+ * relatively small.
+ */
+ if (sys_huffpuff != NULL) {
+ if (peer->delay < sys_huffpuff[sys_huffptr])
+ sys_huffpuff[sys_huffptr] = peer->delay;
+ if (peer->delay < sys_mindly)
+ sys_mindly = peer->delay;
+ if (fp_offset > 0)
+ dtemp = -(peer->delay - sys_mindly) / 2;
+ else
+ dtemp = (peer->delay - sys_mindly) / 2;
+ fp_offset += dtemp;
+ DPRINTF(1, ("local_clock: size %d mindly %.6f huffpuff %.6f\n",
+ sys_hufflen, sys_mindly, dtemp));
+ }
+
+ /*
+ * Clock state machine transition function which defines how the
+ * system reacts to large phase and frequency excursion. There
+ * are two main regimes: when the offset exceeds the step
+ * threshold (128 ms) and when it does not. Under certain
+ * conditions updates are suspended until the stepout theshold
+ * (900 s) is exceeded. See the documentation on how these
+ * thresholds interact with commands and command line options.
+ *
+ * Note the kernel is disabled if step is disabled or greater
+ * than 0.5 s or in ntpdate mode.
+ */
+ osys_poll = sys_poll;
+ if (sys_poll < peer->minpoll)
+ sys_poll = peer->minpoll;
+ if (sys_poll > peer->maxpoll)
+ sys_poll = peer->maxpoll;
+ mu = current_time - clock_epoch;
+ clock_frequency = drift_comp;
+ rval = 1;
+ if ( ( fp_offset > clock_max_fwd && clock_max_fwd > 0)
+ || (-fp_offset > clock_max_back && clock_max_back > 0)
+ || force_step_once ) {
+ if (force_step_once) {
+ force_step_once = FALSE; /* we want this only once after startup */
+ msyslog(LOG_NOTICE, "Doing intital time step" );
+ }
+
+ switch (state) {
+
+ /*
+ * In SYNC state we ignore the first outlier and switch
+ * to SPIK state.
+ */
+ case EVNT_SYNC:
+ snprintf(tbuf, sizeof(tbuf), "%+.6f s",
+ fp_offset);
+ report_event(EVNT_SPIK, NULL, tbuf);
+ state = EVNT_SPIK;
+ return (0);
+
+ /*
+ * In FREQ state we ignore outliers and inlyers. At the
+ * first outlier after the stepout threshold, compute
+ * the apparent frequency correction and step the phase.
+ */
+ case EVNT_FREQ:
+ if (mu < clock_minstep)
+ return (0);
+
+ clock_frequency = direct_freq(fp_offset);
+
+ /* fall through to EVNT_SPIK */
+
+ /*
+ * In SPIK state we ignore succeeding outliers until
+ * either an inlyer is found or the stepout threshold is
+ * exceeded.
+ */
+ case EVNT_SPIK:
+ if (mu < clock_minstep)
+ return (0);
+
+ /* fall through to default */
+
+ /*
+ * We get here by default in NSET and FSET states and
+ * from above in FREQ or SPIK states.
+ *
+ * In NSET state an initial frequency correction is not
+ * available, usually because the frequency file has not
+ * yet been written. Since the time is outside the step
+ * threshold, the clock is stepped. The frequency will
+ * be set directly following the stepout interval.
+ *
+ * In FSET state the initial frequency has been set from
+ * the frequency file. Since the time is outside the
+ * step threshold, the clock is stepped immediately,
+ * rather than after the stepout interval. Guys get
+ * nervous if it takes 15 minutes to set the clock for
+ * the first time.
+ *
+ * In FREQ and SPIK states the stepout threshold has
+ * expired and the phase is still above the step
+ * threshold. Note that a single spike greater than the
+ * step threshold is always suppressed, even with a
+ * long time constant.
+ */
+ default:
+ snprintf(tbuf, sizeof(tbuf), "%+.6f s",
+ fp_offset);
+ report_event(EVNT_CLOCKRESET, NULL, tbuf);
+ step_systime(fp_offset);
+#ifndef __rtems__
+ reinit_timer();
+#endif /* __rtems__ */
+ tc_counter = 0;
+ clock_jitter = LOGTOD(sys_precision);
+ rval = 2;
+ if (state == EVNT_NSET) {
+ rstclock(EVNT_FREQ, 0);
+ return (rval);
+ }
+ break;
+ }
+ rstclock(EVNT_SYNC, 0);
+ } else {
+ /*
+ * The offset is less than the step threshold. Calculate
+ * the jitter as the exponentially weighted offset
+ * differences.
+ */
+ etemp = SQUARE(clock_jitter);
+ dtemp = SQUARE(max(fabs(fp_offset - last_offset),
+ LOGTOD(sys_precision)));
+ clock_jitter = SQRT(etemp + (dtemp - etemp) /
+ CLOCK_AVG);
+ switch (state) {
+
+ /*
+ * In NSET state this is the first update received and
+ * the frequency has not been initialized. Adjust the
+ * phase, but do not adjust the frequency until after
+ * the stepout threshold.
+ */
+ case EVNT_NSET:
+ adj_systime(fp_offset);
+ rstclock(EVNT_FREQ, fp_offset);
+ break;
+
+ /*
+ * In FREQ state ignore updates until the stepout
+ * threshold. After that, compute the new frequency, but
+ * do not adjust the frequency until the holdoff counter
+ * decrements to zero.
+ */
+ case EVNT_FREQ:
+ if (mu < clock_minstep)
+ return (0);
+
+ clock_frequency = direct_freq(fp_offset);
+ /* fall through */
+
+ /*
+ * We get here by default in FSET, SPIK and SYNC states.
+ * Here compute the frequency update due to PLL and FLL
+ * contributions. Note, we avoid frequency discipline at
+ * startup until the initial transient has subsided.
+ */
+ default:
+ if (freq_cnt == 0) {
+
+ /*
+ * The FLL and PLL frequency gain constants
+ * depend on the time constant and Allan
+ * intercept. The PLL is always used, but
+ * becomes ineffective above the Allan intercept
+ * where the FLL becomes effective.
+ */
+ if (sys_poll >= allan_xpt)
+ clock_frequency +=
+ (fp_offset - clock_offset)
+ / ( max(ULOGTOD(sys_poll), mu)
+ * CLOCK_FLL);
+
+ /*
+ * The PLL frequency gain (numerator) depends on
+ * the minimum of the update interval and Allan
+ * intercept. This reduces the PLL gain when the
+ * FLL becomes effective.
+ */
+ etemp = min(ULOGTOD(allan_xpt), mu);
+ dtemp = 4 * CLOCK_PLL * ULOGTOD(sys_poll);
+ clock_frequency +=
+ fp_offset * etemp / (dtemp * dtemp);
+ }
+ rstclock(EVNT_SYNC, fp_offset);
+ if (fabs(fp_offset) < CLOCK_FLOOR)
+ freq_cnt = 0;
+ break;
+ }
+ }
+
+#ifdef KERNEL_PLL
+ /*
+ * This code segment works when clock adjustments are made using
+ * precision time kernel support and the ntp_adjtime() system
+ * call. This support is available in Solaris 2.6 and later,
+ * Digital Unix 4.0 and later, FreeBSD, Linux and specially
+ * modified kernels for HP-UX 9 and Ultrix 4. In the case of the
+ * DECstation 5000/240 and Alpha AXP, additional kernel
+ * modifications provide a true microsecond clock and nanosecond
+ * clock, respectively.
+ *
+ * Important note: The kernel discipline is used only if the
+ * step threshold is less than 0.5 s, as anything higher can
+ * lead to overflow problems. This might occur if some misguided
+ * lad set the step threshold to something ridiculous.
+ */
+ if (pll_control && kern_enable && freq_cnt == 0) {
+
+ /*
+ * We initialize the structure for the ntp_adjtime()
+ * system call. We have to convert everything to
+ * microseconds or nanoseconds first. Do not update the
+ * system variables if the ext_enable flag is set. In
+ * this case, the external clock driver will update the
+ * variables, which will be read later by the local
+ * clock driver. Afterwards, remember the time and
+ * frequency offsets for jitter and stability values and
+ * to update the frequency file.
+ */
+ ZERO(ntv);
+ if (ext_enable) {
+ ntv.modes = MOD_STATUS;
+ } else {
+#ifdef STA_NANO
+ ntv.modes = MOD_BITS | MOD_NANO;
+#else /* STA_NANO */
+ ntv.modes = MOD_BITS;
+#endif /* STA_NANO */
+ if (clock_offset < 0)
+ dtemp = -.5;
+ else
+ dtemp = .5;
+#ifdef STA_NANO
+ ntv.offset = (int32)(clock_offset * 1e9 +
+ dtemp);
+ ntv.constant = sys_poll;
+#else /* STA_NANO */
+ ntv.offset = (int32)(clock_offset * 1e6 +
+ dtemp);
+ ntv.constant = sys_poll - 4;
+#endif /* STA_NANO */
+ if (ntv.constant < 0)
+ ntv.constant = 0;
+
+ ntv.esterror = (u_int32)(clock_jitter * 1e6);
+ ntv.maxerror = (u_int32)((sys_rootdelay / 2 +
+ sys_rootdisp) * 1e6);
+ ntv.status = STA_PLL;
+
+ /*
+ * Enable/disable the PPS if requested.
+ */
+ if (hardpps_enable) {
+ ntv.status |= (STA_PPSTIME | STA_PPSFREQ);
+ if (!(pll_status & STA_PPSTIME))
+ sync_status("PPS enabled",
+ pll_status,
+ ntv.status);
+ } else {
+ ntv.status &= ~(STA_PPSTIME | STA_PPSFREQ);
+ if (pll_status & STA_PPSTIME)
+ sync_status("PPS disabled",
+ pll_status,
+ ntv.status);
+ }
+ if (sys_leap == LEAP_ADDSECOND)
+ ntv.status |= STA_INS;
+ else if (sys_leap == LEAP_DELSECOND)
+ ntv.status |= STA_DEL;
+ }
+
+ /*
+ * Pass the stuff to the kernel. If it squeals, turn off
+ * the pps. In any case, fetch the kernel offset,
+ * frequency and jitter.
+ */
+ ntp_adj_ret = ntp_adjtime(&ntv);
+ /*
+ * A squeal is a return status < 0, or a state change.
+ */
+ if ((0 > ntp_adj_ret) || (ntp_adj_ret != kernel_status)) {
+ kernel_status = ntp_adj_ret;
+ ntp_adjtime_error_handler(__func__, &ntv, ntp_adj_ret, errno, hardpps_enable, 0, __LINE__ - 1);
+ }
+ pll_status = ntv.status;
+#ifdef STA_NANO
+ clock_offset = ntv.offset / 1e9;
+#else /* STA_NANO */
+ clock_offset = ntv.offset / 1e6;
+#endif /* STA_NANO */
+ clock_frequency = FREQTOD(ntv.freq);
+
+ /*
+ * If the kernel PPS is lit, monitor its performance.
+ */
+ if (ntv.status & STA_PPSTIME) {
+#ifdef STA_NANO
+ clock_jitter = ntv.jitter / 1e9;
+#else /* STA_NANO */
+ clock_jitter = ntv.jitter / 1e6;
+#endif /* STA_NANO */
+ }
+
+#if defined(STA_NANO) && NTP_API == 4
+ /*
+ * If the TAI changes, update the kernel TAI.
+ */
+ if (loop_tai != sys_tai) {
+ loop_tai = sys_tai;
+ ntv.modes = MOD_TAI;
+ ntv.constant = sys_tai;
+ if ((ntp_adj_ret = ntp_adjtime(&ntv)) != 0) {
+ ntp_adjtime_error_handler(__func__, &ntv, ntp_adj_ret, errno, 0, 1, __LINE__ - 1);
+ }
+ }
+#endif /* STA_NANO */
+ }
+#endif /* KERNEL_PLL */
+
+ /*
+ * Clamp the frequency within the tolerance range and calculate
+ * the frequency difference since the last update.
+ */
+ if (fabs(clock_frequency) > NTP_MAXFREQ)
+ msyslog(LOG_NOTICE,
+ "frequency error %.0f PPM exceeds tolerance %.0f PPM",
+ clock_frequency * 1e6, NTP_MAXFREQ * 1e6);
+ dtemp = SQUARE(clock_frequency - drift_comp);
+ if (clock_frequency > NTP_MAXFREQ)
+ drift_comp = NTP_MAXFREQ;
+ else if (clock_frequency < -NTP_MAXFREQ)
+ drift_comp = -NTP_MAXFREQ;
+ else
+ drift_comp = clock_frequency;
+
+ /*
+ * Calculate the wander as the exponentially weighted RMS
+ * frequency differences. Record the change for the frequency
+ * file update.
+ */
+ etemp = SQUARE(clock_stability);
+ clock_stability = SQRT(etemp + (dtemp - etemp) / CLOCK_AVG);
+
+ /*
+ * Here we adjust the time constant by comparing the current
+ * offset with the clock jitter. If the offset is less than the
+ * clock jitter times a constant, then the averaging interval is
+ * increased, otherwise it is decreased. A bit of hysteresis
+ * helps calm the dance. Works best using burst mode. Don't
+ * fiddle with the poll during the startup clamp period.
+ */
+ if (freq_cnt > 0) {
+ tc_counter = 0;
+ } else if (fabs(clock_offset) < CLOCK_PGATE * clock_jitter) {
+ tc_counter += sys_poll;
+ if (tc_counter > CLOCK_LIMIT) {
+ tc_counter = CLOCK_LIMIT;
+ if (sys_poll < peer->maxpoll) {
+ tc_counter = 0;
+ sys_poll++;
+ }
+ }
+ } else {
+ tc_counter -= sys_poll << 1;
+ if (tc_counter < -CLOCK_LIMIT) {
+ tc_counter = -CLOCK_LIMIT;
+ if (sys_poll > peer->minpoll) {
+ tc_counter = 0;
+ sys_poll--;
+ }
+ }
+ }
+
+ /*
+ * If the time constant has changed, update the poll variables.
+ */
+ if (osys_poll != sys_poll)
+ poll_update(peer, sys_poll);
+
+ /*
+ * Yibbidy, yibbbidy, yibbidy; that'h all folks.
+ */
+ record_loop_stats(clock_offset, drift_comp, clock_jitter,
+ clock_stability, sys_poll);
+ DPRINTF(1, ("local_clock: offset %.9f jit %.9f freq %.3f stab %.3f poll %d\n",
+ clock_offset, clock_jitter, drift_comp * 1e6,
+ clock_stability * 1e6, sys_poll));
+ return (rval);
+#endif /* not LOCKCLOCK */
+}
+
+
+/*
+ * adj_host_clock - Called once every second to update the local clock.
+ *
+ * LOCKCLOCK: The only thing this routine does is increment the
+ * sys_rootdisp variable.
+ */
+void
+adj_host_clock(
+ void
+ )
+{
+ double offset_adj;
+ double freq_adj;
+
+ /*
+ * Update the dispersion since the last update. In contrast to
+ * NTPv3, NTPv4 does not declare unsynchronized after one day,
+ * since the dispersion check serves this function. Also,
+ * since the poll interval can exceed one day, the old test
+ * would be counterproductive. During the startup clamp period, the
+ * time constant is clamped at 2.
+ */
+ sys_rootdisp += clock_phi;
+#ifndef LOCKCLOCK
+ if (!ntp_enable || mode_ntpdate)
+ return;
+ /*
+ * Determine the phase adjustment. The gain factor (denominator)
+ * increases with poll interval, so is dominated by the FLL
+ * above the Allan intercept. Note the reduced time constant at
+ * startup.
+ */
+ if (state != EVNT_SYNC) {
+ offset_adj = 0.;
+ } else if (freq_cnt > 0) {
+ offset_adj = clock_offset / (CLOCK_PLL * ULOGTOD(1));
+ freq_cnt--;
+#ifdef KERNEL_PLL
+ } else if (pll_control && kern_enable) {
+ offset_adj = 0.;
+#endif /* KERNEL_PLL */
+ } else {
+ offset_adj = clock_offset / (CLOCK_PLL * ULOGTOD(sys_poll));
+ }
+
+ /*
+ * If the kernel discipline is enabled the frequency correction
+ * drift_comp has already been engaged via ntp_adjtime() in
+ * set_freq(). Otherwise it is a component of the adj_systime()
+ * offset.
+ */
+#ifdef KERNEL_PLL
+ if (pll_control && kern_enable)
+ freq_adj = 0.;
+ else
+#endif /* KERNEL_PLL */
+ freq_adj = drift_comp;
+
+ /* Bound absolute value of total adjustment to NTP_MAXFREQ. */
+ if (offset_adj + freq_adj > NTP_MAXFREQ)
+ offset_adj = NTP_MAXFREQ - freq_adj;
+ else if (offset_adj + freq_adj < -NTP_MAXFREQ)
+ offset_adj = -NTP_MAXFREQ - freq_adj;
+
+ clock_offset -= offset_adj;
+ /*
+ * Windows port adj_systime() must be called each second,
+ * even if the argument is zero, to ease emulation of
+ * adjtime() using Windows' slew API which controls the rate
+ * but does not automatically stop slewing when an offset
+ * has decayed to zero.
+ */
+ DEBUG_INSIST(enable_panic_check == TRUE);
+ enable_panic_check = FALSE;
+ adj_systime(offset_adj + freq_adj);
+ enable_panic_check = TRUE;
+#endif /* LOCKCLOCK */
+}
+
+
+/*
+ * Clock state machine. Enter new state and set state variables.
+ */
+static void
+rstclock(
+ int trans, /* new state */
+ double offset /* new offset */
+ )
+{
+ DPRINTF(2, ("rstclock: mu %lu state %d poll %d count %d\n",
+ current_time - clock_epoch, trans, sys_poll,
+ tc_counter));
+ if (trans != state && trans != EVNT_FSET)
+ report_event(trans, NULL, NULL);
+ state = trans;
+ last_offset = clock_offset = offset;
+ clock_epoch = current_time;
+}
+
+
+/*
+ * calc_freq - calculate frequency directly
+ *
+ * This is very carefully done. When the offset is first computed at the
+ * first update, a residual frequency component results. Subsequently,
+ * updates are suppresed until the end of the measurement interval while
+ * the offset is amortized. At the end of the interval the frequency is
+ * calculated from the current offset, residual offset, length of the
+ * interval and residual frequency component. At the same time the
+ * frequenchy file is armed for update at the next hourly stats.
+ */
+static double
+direct_freq(
+ double fp_offset
+ )
+{
+ set_freq(fp_offset / (current_time - clock_epoch));
+
+ return drift_comp;
+}
+
+
+/*
+ * set_freq - set clock frequency correction
+ *
+ * Used to step the frequency correction at startup, possibly again once
+ * the frequency is measured (that is, transitioning from EVNT_NSET to
+ * EVNT_FSET), and finally to switch between daemon and kernel loop
+ * discipline at runtime.
+ *
+ * When the kernel loop discipline is available but the daemon loop is
+ * in use, the kernel frequency correction is disabled (set to 0) to
+ * ensure drift_comp is applied by only one of the loops.
+ */
+static void
+set_freq(
+ double freq /* frequency update */
+ )
+{
+ const char * loop_desc;
+ int ntp_adj_ret;
+
+ (void)ntp_adj_ret; /* not always used below... */
+ drift_comp = freq;
+ loop_desc = "ntpd";
+#ifdef KERNEL_PLL
+ if (pll_control) {
+ ZERO(ntv);
+ ntv.modes = MOD_FREQUENCY;
+ if (kern_enable) {
+ loop_desc = "kernel";
+ ntv.freq = DTOFREQ(drift_comp);
+ }
+ if ((ntp_adj_ret = ntp_adjtime(&ntv)) != 0) {
+ ntp_adjtime_error_handler(__func__, &ntv, ntp_adj_ret, errno, 0, 0, __LINE__ - 1);
+ }
+ }
+#endif /* KERNEL_PLL */
+ mprintf_event(EVNT_FSET, NULL, "%s %.3f PPM", loop_desc,
+ drift_comp * 1e6);
+}
+
+
+#ifdef KERNEL_PLL
+static void
+start_kern_loop(void)
+{
+ static int atexit_done;
+ int ntp_adj_ret;
+
+ pll_control = TRUE;
+ ZERO(ntv);
+ ntv.modes = MOD_BITS;
+ ntv.status = STA_PLL | STA_UNSYNC;
+ ntv.maxerror = MAXDISPERSE * 1.0e6;
+ ntv.esterror = MAXDISPERSE * 1.0e6;
+ ntv.constant = sys_poll;
+ /* ^^^^^^^^ why is it that here constant is
+ * unconditionally set to sys_poll, whereas elsewhere is is
+ * modified depending on nanosecond vs. microsecond kernel?
+ */
+#ifdef SIGSYS
+ /*
+ * Use sigsetjmp() to save state and then call ntp_adjtime(); if
+ * it fails, then pll_trap() will set pll_control FALSE before
+ * returning control using siglogjmp().
+ */
+ newsigsys.sa_handler = pll_trap;
+ newsigsys.sa_flags = 0;
+ if (sigaction(SIGSYS, &newsigsys, &sigsys)) {
+ msyslog(LOG_ERR, "sigaction() trap SIGSYS: %m");
+ pll_control = FALSE;
+ } else {
+ if (sigsetjmp(env, 1) == 0) {
+ if ((ntp_adj_ret = ntp_adjtime(&ntv)) != 0) {
+ ntp_adjtime_error_handler(__func__, &ntv, ntp_adj_ret, errno, 0, 0, __LINE__ - 1);
+ }
+ }
+ if (sigaction(SIGSYS, &sigsys, NULL)) {
+ msyslog(LOG_ERR,
+ "sigaction() restore SIGSYS: %m");
+ pll_control = FALSE;
+ }
+ }
+#else /* SIGSYS */
+ if ((ntp_adj_ret = ntp_adjtime(&ntv)) != 0) {
+ ntp_adjtime_error_handler(__func__, &ntv, ntp_adj_ret, errno, 0, 0, __LINE__ - 1);
+ }
+#endif /* SIGSYS */
+
+ /*
+ * Save the result status and light up an external clock
+ * if available.
+ */
+ pll_status = ntv.status;
+ if (pll_control) {
+ if (!atexit_done) {
+ atexit_done = TRUE;
+ atexit(&stop_kern_loop);
+ }
+#ifdef STA_NANO
+ if (pll_status & STA_CLK)
+ ext_enable = TRUE;
+#endif /* STA_NANO */
+ report_event(EVNT_KERN, NULL,
+ "kernel time sync enabled");
+ }
+}
+#endif /* KERNEL_PLL */
+
+
+#ifdef KERNEL_PLL
+static void
+stop_kern_loop(void)
+{
+ if (pll_control && kern_enable)
+ report_event(EVNT_KERN, NULL,
+ "kernel time sync disabled");
+}
+#endif /* KERNEL_PLL */
+
+
+/*
+ * select_loop() - choose kernel or daemon loop discipline.
+ */
+void
+select_loop(
+ int use_kern_loop
+ )
+{
+ if (kern_enable == use_kern_loop)
+ return;
+#ifdef KERNEL_PLL
+ if (pll_control && !use_kern_loop)
+ stop_kern_loop();
+#endif
+ kern_enable = use_kern_loop;
+#ifdef KERNEL_PLL
+ if (pll_control && use_kern_loop)
+ start_kern_loop();
+#endif
+ /*
+ * If this loop selection change occurs after initial startup,
+ * call set_freq() to switch the frequency compensation to or
+ * from the kernel loop.
+ */
+#ifdef KERNEL_PLL
+ if (pll_control && loop_started)
+ set_freq(drift_comp);
+#endif
+}
+
+
+/*
+ * huff-n'-puff filter
+ */
+void
+huffpuff(void)
+{
+ int i;
+
+ if (sys_huffpuff == NULL)
+ return;
+
+ sys_huffptr = (sys_huffptr + 1) % sys_hufflen;
+ sys_huffpuff[sys_huffptr] = 1e9;
+ sys_mindly = 1e9;
+ for (i = 0; i < sys_hufflen; i++) {
+ if (sys_huffpuff[i] < sys_mindly)
+ sys_mindly = sys_huffpuff[i];
+ }
+}
+
+
+/*
+ * loop_config - configure the loop filter
+ *
+ * LOCKCLOCK: The LOOP_DRIFTINIT and LOOP_DRIFTCOMP cases are no-ops.
+ */
+void
+loop_config(
+ int item,
+ double freq
+ )
+{
+ int i;
+ double ftemp;
+
+ DPRINTF(2, ("loop_config: item %d freq %f\n", item, freq));
+ switch (item) {
+
+ /*
+ * We first assume the kernel supports the ntp_adjtime()
+ * syscall. If that syscall works, initialize the kernel time
+ * variables. Otherwise, continue leaving no harm behind.
+ */
+ case LOOP_DRIFTINIT:
+#ifndef LOCKCLOCK
+#ifdef KERNEL_PLL
+ if (mode_ntpdate)
+ break;
+
+ start_kern_loop();
+#endif /* KERNEL_PLL */
+
+ /*
+ * Initialize frequency if given; otherwise, begin frequency
+ * calibration phase.
+ */
+ ftemp = init_drift_comp / 1e6;
+ if (ftemp > NTP_MAXFREQ)
+ ftemp = NTP_MAXFREQ;
+ else if (ftemp < -NTP_MAXFREQ)
+ ftemp = -NTP_MAXFREQ;
+ set_freq(ftemp);
+ if (freq_set)
+ rstclock(EVNT_FSET, 0);
+ else
+ rstclock(EVNT_NSET, 0);
+ loop_started = TRUE;
+#endif /* LOCKCLOCK */
+ break;
+
+ case LOOP_KERN_CLEAR:
+#if 0 /* XXX: needs more review, and how can we get here? */
+#ifndef LOCKCLOCK
+# ifdef KERNEL_PLL
+ if (pll_control && kern_enable) {
+ memset((char *)&ntv, 0, sizeof(ntv));
+ ntv.modes = MOD_STATUS;
+ ntv.status = STA_UNSYNC;
+ ntp_adjtime(&ntv);
+ sync_status("kernel time sync disabled",
+ pll_status,
+ ntv.status);
+ }
+# endif /* KERNEL_PLL */
+#endif /* LOCKCLOCK */
+#endif
+ break;
+
+ /*
+ * Tinker command variables for Ulrich Windl. Very dangerous.
+ */
+ case LOOP_ALLAN: /* Allan intercept (log2) (allan) */
+ allan_xpt = (u_char)freq;
+ break;
+
+ case LOOP_CODEC: /* audio codec frequency (codec) */
+ clock_codec = freq / 1e6;
+ break;
+
+ case LOOP_PHI: /* dispersion threshold (dispersion) */
+ clock_phi = freq / 1e6;
+ break;
+
+ case LOOP_FREQ: /* initial frequency (freq) */
+ init_drift_comp = freq;
+ freq_set++;
+ break;
+
+ case LOOP_HUFFPUFF: /* huff-n'-puff length (huffpuff) */
+ if (freq < HUFFPUFF)
+ freq = HUFFPUFF;
+ sys_hufflen = (int)(freq / HUFFPUFF);
+ sys_huffpuff = eallocarray(sys_hufflen, sizeof(sys_huffpuff[0]));
+ for (i = 0; i < sys_hufflen; i++)
+ sys_huffpuff[i] = 1e9;
+ sys_mindly = 1e9;
+ break;
+
+ case LOOP_PANIC: /* panic threshold (panic) */
+ clock_panic = freq;
+ break;
+
+ case LOOP_MAX: /* step threshold (step) */
+ clock_max_fwd = clock_max_back = freq;
+ if (freq == 0 || freq > 0.5)
+ select_loop(FALSE);
+ break;
+
+ case LOOP_MAX_BACK: /* step threshold (step) */
+ clock_max_back = freq;
+ /*
+ * Leave using the kernel discipline code unless both
+ * limits are massive. This assumes the reason to stop
+ * using it is that it's pointless, not that it goes wrong.
+ */
+ if ( (clock_max_back == 0 || clock_max_back > 0.5)
+ || (clock_max_fwd == 0 || clock_max_fwd > 0.5))
+ select_loop(FALSE);
+ break;
+
+ case LOOP_MAX_FWD: /* step threshold (step) */
+ clock_max_fwd = freq;
+ if ( (clock_max_back == 0 || clock_max_back > 0.5)
+ || (clock_max_fwd == 0 || clock_max_fwd > 0.5))
+ select_loop(FALSE);
+ break;
+
+ case LOOP_MINSTEP: /* stepout threshold (stepout) */
+ if (freq < CLOCK_MINSTEP)
+ clock_minstep = CLOCK_MINSTEP;
+ else
+ clock_minstep = freq;
+ break;
+
+ case LOOP_TICK: /* tick increment (tick) */
+ set_sys_tick_precision(freq);
+ break;
+
+ case LOOP_LEAP: /* not used, fall through */
+ default:
+ msyslog(LOG_NOTICE,
+ "loop_config: unsupported option %d", item);
+ }
+}
+
+
+#if defined(KERNEL_PLL) && defined(SIGSYS)
+/*
+ * _trap - trap processor for undefined syscalls
+ *
+ * This nugget is called by the kernel when the SYS_ntp_adjtime()
+ * syscall bombs because the silly thing has not been implemented in
+ * the kernel. In this case the phase-lock loop is emulated by
+ * the stock adjtime() syscall and a lot of indelicate abuse.
+ */
+static RETSIGTYPE
+pll_trap(
+ int arg
+ )
+{
+ pll_control = FALSE;
+ siglongjmp(env, 1);
+}
+#endif /* KERNEL_PLL && SIGSYS */
diff --git a/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_monitor.c b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_monitor.c
new file mode 100644
index 0000000..c0e4359
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_monitor.c
@@ -0,0 +1,502 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * ntp_monitor - monitor ntpd statistics
+ */
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "ntpd.h"
+#include "ntp_io.h"
+#include "ntp_if.h"
+#include "ntp_lists.h"
+#include "ntp_stdlib.h"
+#include <ntp_random.h>
+
+#include <stdio.h>
+#include <signal.h>
+#ifdef HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif
+
+/*
+ * Record statistics based on source address, mode and version. The
+ * receive procedure calls us with the incoming rbufp before it does
+ * anything else. While at it, implement rate controls for inbound
+ * traffic.
+ *
+ * Each entry is doubly linked into two lists, a hash table and a most-
+ * recently-used (MRU) list. When a packet arrives it is looked up in
+ * the hash table. If found, the statistics are updated and the entry
+ * relinked at the head of the MRU list. If not found, a new entry is
+ * allocated, initialized and linked into both the hash table and at the
+ * head of the MRU list.
+ *
+ * Memory is usually allocated by grabbing a big chunk of new memory and
+ * cutting it up into littler pieces. The exception to this when we hit
+ * the memory limit. Then we free memory by grabbing entries off the
+ * tail for the MRU list, unlinking from the hash table, and
+ * reinitializing.
+ *
+ * INC_MONLIST is the default allocation granularity in entries.
+ * INIT_MONLIST is the default initial allocation in entries.
+ */
+#ifdef MONMEMINC /* old name */
+# define INC_MONLIST MONMEMINC
+#elif !defined(INC_MONLIST)
+# define INC_MONLIST (4 * 1024 / sizeof(mon_entry))
+#endif
+#ifndef INIT_MONLIST
+# define INIT_MONLIST (4 * 1024 / sizeof(mon_entry))
+#endif
+#ifndef MRU_MAXDEPTH_DEF
+# define MRU_MAXDEPTH_DEF (1024 * 1024 / sizeof(mon_entry))
+#endif
+
+/*
+ * Hashing stuff
+ */
+u_char mon_hash_bits;
+
+/*
+ * Pointers to the hash table and the MRU list. Memory for the hash
+ * table is allocated only if monitoring is enabled.
+ */
+mon_entry ** mon_hash; /* MRU hash table */
+mon_entry mon_mru_list; /* mru listhead */
+
+/*
+ * List of free structures structures, and counters of in-use and total
+ * structures. The free structures are linked with the hash_next field.
+ */
+static mon_entry *mon_free; /* free list or null if none */
+ u_int mru_alloc; /* mru list + free list count */
+ u_int mru_entries; /* mru list count */
+ u_int mru_peakentries; /* highest mru_entries seen */
+ u_int mru_initalloc = INIT_MONLIST;/* entries to preallocate */
+ u_int mru_incalloc = INC_MONLIST;/* allocation batch factor */
+static u_int mon_mem_increments; /* times called malloc() */
+
+/*
+ * Parameters of the RES_LIMITED restriction option. We define headway
+ * as the idle time between packets. A packet is discarded if the
+ * headway is less than the minimum, as well as if the average headway
+ * is less than eight times the increment.
+ */
+int ntp_minpkt = NTP_MINPKT; /* minimum (log 2 s) */
+u_char ntp_minpoll = NTP_MINPOLL; /* increment (log 2 s) */
+
+/*
+ * Initialization state. We may be monitoring, we may not. If
+ * we aren't, we may not even have allocated any memory yet.
+ */
+ u_int mon_enabled; /* enable switch */
+ u_int mru_mindepth = 600; /* preempt above this */
+ int mru_maxage = 64; /* for entries older than */
+ u_int mru_maxdepth = /* MRU count hard limit */
+ MRU_MAXDEPTH_DEF;
+ int mon_age = 3000; /* preemption limit */
+
+static void mon_getmoremem(void);
+static void remove_from_hash(mon_entry *);
+static inline void mon_free_entry(mon_entry *);
+static inline void mon_reclaim_entry(mon_entry *);
+
+
+/*
+ * init_mon - initialize monitoring global data
+ */
+void
+init_mon(void)
+{
+ /*
+ * Don't do much of anything here. We don't allocate memory
+ * until mon_start().
+ */
+ mon_enabled = MON_OFF;
+ INIT_DLIST(mon_mru_list, mru);
+}
+
+
+/*
+ * remove_from_hash - removes an entry from the address hash table and
+ * decrements mru_entries.
+ */
+static void
+remove_from_hash(
+ mon_entry *mon
+ )
+{
+ u_int hash;
+ mon_entry *punlinked;
+
+ mru_entries--;
+ hash = MON_HASH(&mon->rmtadr);
+ UNLINK_SLIST(punlinked, mon_hash[hash], mon, hash_next,
+ mon_entry);
+ ENSURE(punlinked == mon);
+}
+
+
+static inline void
+mon_free_entry(
+ mon_entry *m
+ )
+{
+ ZERO(*m);
+ LINK_SLIST(mon_free, m, hash_next);
+}
+
+
+/*
+ * mon_reclaim_entry - Remove an entry from the MRU list and from the
+ * hash array, then zero-initialize it. Indirectly
+ * decrements mru_entries.
+
+ * The entry is prepared to be reused. Before return, in
+ * remove_from_hash(), mru_entries is decremented. It is the caller's
+ * responsibility to increment it again.
+ */
+static inline void
+mon_reclaim_entry(
+ mon_entry *m
+ )
+{
+ DEBUG_INSIST(NULL != m);
+
+ UNLINK_DLIST(m, mru);
+ remove_from_hash(m);
+ ZERO(*m);
+}
+
+
+/*
+ * mon_getmoremem - get more memory and put it on the free list
+ */
+static void
+mon_getmoremem(void)
+{
+ mon_entry *chunk;
+ u_int entries;
+
+ entries = (0 == mon_mem_increments)
+ ? mru_initalloc
+ : mru_incalloc;
+
+ if (entries) {
+ chunk = eallocarray(entries, sizeof(*chunk));
+ mru_alloc += entries;
+ for (chunk += entries; entries; entries--)
+ mon_free_entry(--chunk);
+
+ mon_mem_increments++;
+ }
+}
+
+
+/*
+ * mon_start - start up the monitoring software
+ */
+void
+mon_start(
+ int mode
+ )
+{
+ size_t octets;
+ u_int min_hash_slots;
+
+ if (MON_OFF == mode) /* MON_OFF is 0 */
+ return;
+ if (mon_enabled) {
+ mon_enabled |= mode;
+ return;
+ }
+ if (0 == mon_mem_increments)
+ mon_getmoremem();
+ /*
+ * Select the MRU hash table size to limit the average count
+ * per bucket at capacity (mru_maxdepth) to 8, if possible
+ * given our hash is limited to 16 bits.
+ */
+ min_hash_slots = (mru_maxdepth / 8) + 1;
+ mon_hash_bits = 0;
+ while (min_hash_slots >>= 1)
+ mon_hash_bits++;
+ mon_hash_bits = max(4, mon_hash_bits);
+ mon_hash_bits = min(16, mon_hash_bits);
+ octets = sizeof(*mon_hash) * MON_HASH_SIZE;
+ mon_hash = erealloc_zero(mon_hash, octets, 0);
+
+ mon_enabled = mode;
+}
+
+
+/*
+ * mon_stop - stop the monitoring software
+ */
+void
+mon_stop(
+ int mode
+ )
+{
+ mon_entry *mon;
+
+ if (MON_OFF == mon_enabled)
+ return;
+ if ((mon_enabled & mode) == 0 || mode == MON_OFF)
+ return;
+
+ mon_enabled &= ~mode;
+ if (mon_enabled != MON_OFF)
+ return;
+
+ /*
+ * Move everything on the MRU list to the free list quickly,
+ * without bothering to remove each from either the MRU list or
+ * the hash table.
+ */
+ ITER_DLIST_BEGIN(mon_mru_list, mon, mru, mon_entry)
+ mon_free_entry(mon);
+ ITER_DLIST_END()
+
+ /* empty the MRU list and hash table. */
+ mru_entries = 0;
+ INIT_DLIST(mon_mru_list, mru);
+ zero_mem(mon_hash, sizeof(*mon_hash) * MON_HASH_SIZE);
+}
+
+
+/*
+ * mon_clearinterface -- remove mru entries referring to a local address
+ * which is going away.
+ */
+void
+mon_clearinterface(
+ endpt *lcladr
+ )
+{
+ mon_entry *mon;
+
+ /* iterate mon over mon_mru_list */
+ ITER_DLIST_BEGIN(mon_mru_list, mon, mru, mon_entry)
+ if (mon->lcladr == lcladr) {
+ /* remove from mru list */
+ UNLINK_DLIST(mon, mru);
+ /* remove from hash list, adjust mru_entries */
+ remove_from_hash(mon);
+ /* put on free list */
+ mon_free_entry(mon);
+ }
+ ITER_DLIST_END()
+}
+
+
+/*
+ * ntp_monitor - record stats about this packet
+ *
+ * Returns supplied restriction flags, with RES_LIMITED and RES_KOD
+ * cleared unless the packet should not be responded to normally
+ * (RES_LIMITED) and possibly should trigger a KoD response (RES_KOD).
+ * The returned flags are saved in the MRU entry, so that it reflects
+ * whether the last packet from that source triggered rate limiting,
+ * and if so, possible KoD response. This implies you can not tell
+ * whether a given address is eligible for rate limiting/KoD from the
+ * monlist restrict bits, only whether or not the last packet triggered
+ * such responses. ntpdc -c reslist lets you see whether RES_LIMITED
+ * or RES_KOD is lit for a particular address before ntp_monitor()'s
+ * typical dousing.
+ */
+u_short
+ntp_monitor(
+ struct recvbuf *rbufp,
+ u_short flags
+ )
+{
+ l_fp interval_fp;
+ struct pkt * pkt;
+ mon_entry * mon;
+ mon_entry * oldest;
+ int oldest_age;
+ u_int hash;
+ u_short restrict_mask;
+ u_char mode;
+ u_char version;
+ int interval;
+ int head; /* headway increment */
+ int leak; /* new headway */
+ int limit; /* average threshold */
+
+ REQUIRE(rbufp != NULL);
+
+ if (mon_enabled == MON_OFF)
+ return ~(RES_LIMITED | RES_KOD) & flags;
+
+ pkt = &rbufp->recv_pkt;
+ hash = MON_HASH(&rbufp->recv_srcadr);
+ mode = PKT_MODE(pkt->li_vn_mode);
+ version = PKT_VERSION(pkt->li_vn_mode);
+ mon = mon_hash[hash];
+
+ /*
+ * We keep track of all traffic for a given IP in one entry,
+ * otherwise cron'ed ntpdate or similar evades RES_LIMITED.
+ */
+
+ for (; mon != NULL; mon = mon->hash_next)
+ if (SOCK_EQ(&mon->rmtadr, &rbufp->recv_srcadr))
+ break;
+
+ if (mon != NULL) {
+ interval_fp = rbufp->recv_time;
+ L_SUB(&interval_fp, &mon->last);
+ /* add one-half second to round up */
+ L_ADDUF(&interval_fp, 0x80000000);
+ interval = interval_fp.l_i;
+ mon->last = rbufp->recv_time;
+ NSRCPORT(&mon->rmtadr) = NSRCPORT(&rbufp->recv_srcadr);
+ mon->count++;
+ restrict_mask = flags;
+ mon->vn_mode = VN_MODE(version, mode);
+
+ /* Shuffle to the head of the MRU list. */
+ UNLINK_DLIST(mon, mru);
+ LINK_DLIST(mon_mru_list, mon, mru);
+
+ /*
+ * At this point the most recent arrival is first in the
+ * MRU list. Decrease the counter by the headway, but
+ * not less than zero.
+ */
+ mon->leak -= interval;
+ mon->leak = max(0, mon->leak);
+ head = 1 << ntp_minpoll;
+ leak = mon->leak + head;
+ limit = NTP_SHIFT * head;
+
+ DPRINTF(2, ("MRU: interval %d headway %d limit %d\n",
+ interval, leak, limit));
+
+ /*
+ * If the minimum and average thresholds are not
+ * exceeded, douse the RES_LIMITED and RES_KOD bits and
+ * increase the counter by the headway increment. Note
+ * that we give a 1-s grace for the minimum threshold
+ * and a 2-s grace for the headway increment. If one or
+ * both thresholds are exceeded and the old counter is
+ * less than the average threshold, set the counter to
+ * the average threshold plus the increment and leave
+ * the RES_LIMITED and RES_KOD bits lit. Otherwise,
+ * leave the counter alone and douse the RES_KOD bit.
+ * This rate-limits the KoDs to no less than the average
+ * headway.
+ */
+ if (interval + 1 >= ntp_minpkt && leak < limit) {
+ mon->leak = leak - 2;
+ restrict_mask &= ~(RES_LIMITED | RES_KOD);
+ } else if (mon->leak < limit)
+ mon->leak = limit + head;
+ else
+ restrict_mask &= ~RES_KOD;
+
+ mon->flags = restrict_mask;
+
+ return mon->flags;
+ }
+
+ /*
+ * If we got here, this is the first we've heard of this
+ * guy. Get him some memory, either from the free list
+ * or from the tail of the MRU list.
+ *
+ * The following ntp.conf "mru" knobs come into play determining
+ * the depth (or count) of the MRU list:
+ * - mru_mindepth ("mru mindepth") is a floor beneath which
+ * entries are kept without regard to their age. The
+ * default is 600 which matches the longtime implementation
+ * limit on the total number of entries.
+ * - mru_maxage ("mru maxage") is a ceiling on the age in
+ * seconds of entries. Entries older than this are
+ * reclaimed once mon_mindepth is exceeded. 64s default.
+ * Note that entries older than this can easily survive
+ * as they are reclaimed only as needed.
+ * - mru_maxdepth ("mru maxdepth") is a hard limit on the
+ * number of entries.
+ * - "mru maxmem" sets mru_maxdepth to the number of entries
+ * which fit in the given number of kilobytes. The default is
+ * 1024, or 1 megabyte.
+ * - mru_initalloc ("mru initalloc" sets the count of the
+ * initial allocation of MRU entries.
+ * - "mru initmem" sets mru_initalloc in units of kilobytes.
+ * The default is 4.
+ * - mru_incalloc ("mru incalloc" sets the number of entries to
+ * allocate on-demand each time the free list is empty.
+ * - "mru incmem" sets mru_incalloc in units of kilobytes.
+ * The default is 4.
+ * Whichever of "mru maxmem" or "mru maxdepth" occurs last in
+ * ntp.conf controls. Similarly for "mru initalloc" and "mru
+ * initmem", and for "mru incalloc" and "mru incmem".
+ */
+ if (mru_entries < mru_mindepth) {
+ if (NULL == mon_free)
+ mon_getmoremem();
+ UNLINK_HEAD_SLIST(mon, mon_free, hash_next);
+ } else {
+ oldest = TAIL_DLIST(mon_mru_list, mru);
+ oldest_age = 0; /* silence uninit warning */
+ if (oldest != NULL) {
+ interval_fp = rbufp->recv_time;
+ L_SUB(&interval_fp, &oldest->last);
+ /* add one-half second to round up */
+ L_ADDUF(&interval_fp, 0x80000000);
+ oldest_age = interval_fp.l_i;
+ }
+ /* note -1 is legal for mru_maxage (disables) */
+ if (oldest != NULL && mru_maxage < oldest_age) {
+ mon_reclaim_entry(oldest);
+ mon = oldest;
+ } else if (mon_free != NULL || mru_alloc <
+ mru_maxdepth) {
+ if (NULL == mon_free)
+ mon_getmoremem();
+ UNLINK_HEAD_SLIST(mon, mon_free, hash_next);
+ /* Preempt from the MRU list if old enough. */
+ } else if (ntp_random() / (2. * FRAC) >
+ (double)oldest_age / mon_age) {
+ return ~(RES_LIMITED | RES_KOD) & flags;
+ } else {
+ mon_reclaim_entry(oldest);
+ mon = oldest;
+ }
+ }
+
+ INSIST(mon != NULL);
+
+ /*
+ * Got one, initialize it
+ */
+ mru_entries++;
+ mru_peakentries = max(mru_peakentries, mru_entries);
+ mon->last = rbufp->recv_time;
+ mon->first = mon->last;
+ mon->count = 1;
+ mon->flags = ~(RES_LIMITED | RES_KOD) & flags;
+ mon->leak = 0;
+ memcpy(&mon->rmtadr, &rbufp->recv_srcadr, sizeof(mon->rmtadr));
+ mon->vn_mode = VN_MODE(version, mode);
+ mon->lcladr = rbufp->dstadr;
+ mon->cast_flags = (u_char)(((rbufp->dstadr->flags &
+ INT_MCASTOPEN) && rbufp->fd == mon->lcladr->fd) ? MDF_MCAST
+ : rbufp->fd == mon->lcladr->bfd ? MDF_BCAST : MDF_UCAST);
+
+ /*
+ * Drop him into front of the hash table. Also put him on top of
+ * the MRU list.
+ */
+ LINK_SLIST(mon_hash[hash], mon, hash_next);
+ LINK_DLIST(mon_mru_list, mon, mru);
+
+ return mon->flags;
+}
+
+
diff --git a/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_parser.c b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_parser.c
new file mode 100644
index 0000000..9c907cd
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_parser.c
@@ -0,0 +1,3747 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/* A Bison parser, made by GNU Bison 3.0.4. */
+
+/* Bison implementation for Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+ simplifying the original so-called "semantic" parser. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Bison version. */
+#define YYBISON_VERSION "3.0.4"
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 0
+
+/* Push parsers. */
+#define YYPUSH 0
+
+/* Pull parsers. */
+#define YYPULL 1
+
+
+
+
+/* Copy the first part of user declarations. */
+#line 11 "ntp_parser.y" /* yacc.c:339 */
+
+ #ifdef HAVE_CONFIG_H
+ # include <config.h>
+ #endif
+
+ #include "ntp.h"
+ #include "ntpd.h"
+ #include "ntp_machine.h"
+ #include "ntp_stdlib.h"
+ #include "ntp_filegen.h"
+ #include "ntp_scanner.h"
+ #include "ntp_config.h"
+ #include "ntp_crypto.h"
+ #include "ntp_calendar.h"
+
+ #include "ntpsim.h" /* HMS: Do we really want this all the time? */
+ /* SK: It might be a good idea to always
+ include the simulator code. That way
+ someone can use the same configuration file
+ for both the simulator and the daemon
+ */
+
+ #define YYMALLOC emalloc
+ #define YYFREE free
+ #define YYERROR_VERBOSE
+ #define YYMAXDEPTH 1000 /* stop the madness sooner */
+ void yyerror(const char *msg);
+
+ #ifdef SIM
+ # define ONLY_SIM(a) (a)
+ #else
+ # define ONLY_SIM(a) NULL
+ #endif
+
+#line 101 "ntp_parser.c" /* yacc.c:339 */
+
+# ifndef YY_NULLPTR
+# if defined __cplusplus && 201103L <= __cplusplus
+# define YY_NULLPTR nullptr
+# else
+# define YY_NULLPTR 0
+# endif
+# endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+/* In a future release of Bison, this section will be replaced
+ by #include "y.tab.h". */
+#ifndef YY_YY_NTP_PARSER_H_INCLUDED
+# define YY_YY_NTP_PARSER_H_INCLUDED
+/* Debug traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 1
+#endif
+#if YYDEBUG
+extern int yydebug;
+#endif
+
+/* Token type. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ enum yytokentype
+ {
+ T_Abbrev = 258,
+ T_Age = 259,
+ T_All = 260,
+ T_Allan = 261,
+ T_Allpeers = 262,
+ T_Auth = 263,
+ T_Autokey = 264,
+ T_Automax = 265,
+ T_Average = 266,
+ T_Basedate = 267,
+ T_Bclient = 268,
+ T_Bcpollbstep = 269,
+ T_Beacon = 270,
+ T_Broadcast = 271,
+ T_Broadcastclient = 272,
+ T_Broadcastdelay = 273,
+ T_Burst = 274,
+ T_Calibrate = 275,
+ T_Ceiling = 276,
+ T_Clockstats = 277,
+ T_Cohort = 278,
+ T_ControlKey = 279,
+ T_Crypto = 280,
+ T_Cryptostats = 281,
+ T_Ctl = 282,
+ T_Day = 283,
+ T_Default = 284,
+ T_Digest = 285,
+ T_Disable = 286,
+ T_Discard = 287,
+ T_Dispersion = 288,
+ T_Double = 289,
+ T_Driftfile = 290,
+ T_Drop = 291,
+ T_Dscp = 292,
+ T_Ellipsis = 293,
+ T_Enable = 294,
+ T_End = 295,
+ T_Epeer = 296,
+ T_False = 297,
+ T_File = 298,
+ T_Filegen = 299,
+ T_Filenum = 300,
+ T_Flag1 = 301,
+ T_Flag2 = 302,
+ T_Flag3 = 303,
+ T_Flag4 = 304,
+ T_Flake = 305,
+ T_Floor = 306,
+ T_Freq = 307,
+ T_Fudge = 308,
+ T_Host = 309,
+ T_Huffpuff = 310,
+ T_Iburst = 311,
+ T_Ident = 312,
+ T_Ignore = 313,
+ T_Incalloc = 314,
+ T_Incmem = 315,
+ T_Initalloc = 316,
+ T_Initmem = 317,
+ T_Includefile = 318,
+ T_Integer = 319,
+ T_Interface = 320,
+ T_Intrange = 321,
+ T_Io = 322,
+ T_Ippeerlimit = 323,
+ T_Ipv4 = 324,
+ T_Ipv4_flag = 325,
+ T_Ipv6 = 326,
+ T_Ipv6_flag = 327,
+ T_Kernel = 328,
+ T_Key = 329,
+ T_Keys = 330,
+ T_Keysdir = 331,
+ T_Kod = 332,
+ T_Mssntp = 333,
+ T_Leapfile = 334,
+ T_Leapsmearinterval = 335,
+ T_Limited = 336,
+ T_Link = 337,
+ T_Listen = 338,
+ T_Logconfig = 339,
+ T_Logfile = 340,
+ T_Loopstats = 341,
+ T_Lowpriotrap = 342,
+ T_Manycastclient = 343,
+ T_Manycastserver = 344,
+ T_Mask = 345,
+ T_Maxage = 346,
+ T_Maxclock = 347,
+ T_Maxdepth = 348,
+ T_Maxdist = 349,
+ T_Maxmem = 350,
+ T_Maxpoll = 351,
+ T_Mdnstries = 352,
+ T_Mem = 353,
+ T_Memlock = 354,
+ T_Minclock = 355,
+ T_Mindepth = 356,
+ T_Mindist = 357,
+ T_Minimum = 358,
+ T_Minpoll = 359,
+ T_Minsane = 360,
+ T_Mode = 361,
+ T_Mode7 = 362,
+ T_Monitor = 363,
+ T_Month = 364,
+ T_Mru = 365,
+ T_Multicastclient = 366,
+ T_Nic = 367,
+ T_Nolink = 368,
+ T_Nomodify = 369,
+ T_Nomrulist = 370,
+ T_None = 371,
+ T_Nonvolatile = 372,
+ T_Noepeer = 373,
+ T_Nopeer = 374,
+ T_Noquery = 375,
+ T_Noselect = 376,
+ T_Noserve = 377,
+ T_Notrap = 378,
+ T_Notrust = 379,
+ T_Ntp = 380,
+ T_Ntpport = 381,
+ T_NtpSignDsocket = 382,
+ T_Orphan = 383,
+ T_Orphanwait = 384,
+ T_PCEdigest = 385,
+ T_Panic = 386,
+ T_Peer = 387,
+ T_Peerstats = 388,
+ T_Phone = 389,
+ T_Pid = 390,
+ T_Pidfile = 391,
+ T_Pool = 392,
+ T_Port = 393,
+ T_Preempt = 394,
+ T_Prefer = 395,
+ T_Protostats = 396,
+ T_Pw = 397,
+ T_Randfile = 398,
+ T_Rawstats = 399,
+ T_Refid = 400,
+ T_Requestkey = 401,
+ T_Reset = 402,
+ T_Restrict = 403,
+ T_Revoke = 404,
+ T_Rlimit = 405,
+ T_Saveconfigdir = 406,
+ T_Server = 407,
+ T_Setvar = 408,
+ T_Source = 409,
+ T_Stacksize = 410,
+ T_Statistics = 411,
+ T_Stats = 412,
+ T_Statsdir = 413,
+ T_Step = 414,
+ T_Stepback = 415,
+ T_Stepfwd = 416,
+ T_Stepout = 417,
+ T_Stratum = 418,
+ T_String = 419,
+ T_Sys = 420,
+ T_Sysstats = 421,
+ T_Tick = 422,
+ T_Time1 = 423,
+ T_Time2 = 424,
+ T_Timer = 425,
+ T_Timingstats = 426,
+ T_Tinker = 427,
+ T_Tos = 428,
+ T_Trap = 429,
+ T_True = 430,
+ T_Trustedkey = 431,
+ T_Ttl = 432,
+ T_Type = 433,
+ T_U_int = 434,
+ T_UEcrypto = 435,
+ T_UEcryptonak = 436,
+ T_UEdigest = 437,
+ T_Unconfig = 438,
+ T_Unpeer = 439,
+ T_Version = 440,
+ T_WanderThreshold = 441,
+ T_Week = 442,
+ T_Wildcard = 443,
+ T_Xleave = 444,
+ T_Year = 445,
+ T_Flag = 446,
+ T_EOC = 447,
+ T_Simulate = 448,
+ T_Beep_Delay = 449,
+ T_Sim_Duration = 450,
+ T_Server_Offset = 451,
+ T_Duration = 452,
+ T_Freq_Offset = 453,
+ T_Wander = 454,
+ T_Jitter = 455,
+ T_Prop_Delay = 456,
+ T_Proc_Delay = 457
+ };
+#endif
+/* Tokens. */
+#define T_Abbrev 258
+#define T_Age 259
+#define T_All 260
+#define T_Allan 261
+#define T_Allpeers 262
+#define T_Auth 263
+#define T_Autokey 264
+#define T_Automax 265
+#define T_Average 266
+#define T_Basedate 267
+#define T_Bclient 268
+#define T_Bcpollbstep 269
+#define T_Beacon 270
+#define T_Broadcast 271
+#define T_Broadcastclient 272
+#define T_Broadcastdelay 273
+#define T_Burst 274
+#define T_Calibrate 275
+#define T_Ceiling 276
+#define T_Clockstats 277
+#define T_Cohort 278
+#define T_ControlKey 279
+#define T_Crypto 280
+#define T_Cryptostats 281
+#define T_Ctl 282
+#define T_Day 283
+#define T_Default 284
+#define T_Digest 285
+#define T_Disable 286
+#define T_Discard 287
+#define T_Dispersion 288
+#define T_Double 289
+#define T_Driftfile 290
+#define T_Drop 291
+#define T_Dscp 292
+#define T_Ellipsis 293
+#define T_Enable 294
+#define T_End 295
+#define T_Epeer 296
+#define T_False 297
+#define T_File 298
+#define T_Filegen 299
+#define T_Filenum 300
+#define T_Flag1 301
+#define T_Flag2 302
+#define T_Flag3 303
+#define T_Flag4 304
+#define T_Flake 305
+#define T_Floor 306
+#define T_Freq 307
+#define T_Fudge 308
+#define T_Host 309
+#define T_Huffpuff 310
+#define T_Iburst 311
+#define T_Ident 312
+#define T_Ignore 313
+#define T_Incalloc 314
+#define T_Incmem 315
+#define T_Initalloc 316
+#define T_Initmem 317
+#define T_Includefile 318
+#define T_Integer 319
+#define T_Interface 320
+#define T_Intrange 321
+#define T_Io 322
+#define T_Ippeerlimit 323
+#define T_Ipv4 324
+#define T_Ipv4_flag 325
+#define T_Ipv6 326
+#define T_Ipv6_flag 327
+#define T_Kernel 328
+#define T_Key 329
+#define T_Keys 330
+#define T_Keysdir 331
+#define T_Kod 332
+#define T_Mssntp 333
+#define T_Leapfile 334
+#define T_Leapsmearinterval 335
+#define T_Limited 336
+#define T_Link 337
+#define T_Listen 338
+#define T_Logconfig 339
+#define T_Logfile 340
+#define T_Loopstats 341
+#define T_Lowpriotrap 342
+#define T_Manycastclient 343
+#define T_Manycastserver 344
+#define T_Mask 345
+#define T_Maxage 346
+#define T_Maxclock 347
+#define T_Maxdepth 348
+#define T_Maxdist 349
+#define T_Maxmem 350
+#define T_Maxpoll 351
+#define T_Mdnstries 352
+#define T_Mem 353
+#define T_Memlock 354
+#define T_Minclock 355
+#define T_Mindepth 356
+#define T_Mindist 357
+#define T_Minimum 358
+#define T_Minpoll 359
+#define T_Minsane 360
+#define T_Mode 361
+#define T_Mode7 362
+#define T_Monitor 363
+#define T_Month 364
+#define T_Mru 365
+#define T_Multicastclient 366
+#define T_Nic 367
+#define T_Nolink 368
+#define T_Nomodify 369
+#define T_Nomrulist 370
+#define T_None 371
+#define T_Nonvolatile 372
+#define T_Noepeer 373
+#define T_Nopeer 374
+#define T_Noquery 375
+#define T_Noselect 376
+#define T_Noserve 377
+#define T_Notrap 378
+#define T_Notrust 379
+#define T_Ntp 380
+#define T_Ntpport 381
+#define T_NtpSignDsocket 382
+#define T_Orphan 383
+#define T_Orphanwait 384
+#define T_PCEdigest 385
+#define T_Panic 386
+#define T_Peer 387
+#define T_Peerstats 388
+#define T_Phone 389
+#define T_Pid 390
+#define T_Pidfile 391
+#define T_Pool 392
+#define T_Port 393
+#define T_Preempt 394
+#define T_Prefer 395
+#define T_Protostats 396
+#define T_Pw 397
+#define T_Randfile 398
+#define T_Rawstats 399
+#define T_Refid 400
+#define T_Requestkey 401
+#define T_Reset 402
+#define T_Restrict 403
+#define T_Revoke 404
+#define T_Rlimit 405
+#define T_Saveconfigdir 406
+#define T_Server 407
+#define T_Setvar 408
+#define T_Source 409
+#define T_Stacksize 410
+#define T_Statistics 411
+#define T_Stats 412
+#define T_Statsdir 413
+#define T_Step 414
+#define T_Stepback 415
+#define T_Stepfwd 416
+#define T_Stepout 417
+#define T_Stratum 418
+#define T_String 419
+#define T_Sys 420
+#define T_Sysstats 421
+#define T_Tick 422
+#define T_Time1 423
+#define T_Time2 424
+#define T_Timer 425
+#define T_Timingstats 426
+#define T_Tinker 427
+#define T_Tos 428
+#define T_Trap 429
+#define T_True 430
+#define T_Trustedkey 431
+#define T_Ttl 432
+#define T_Type 433
+#define T_U_int 434
+#define T_UEcrypto 435
+#define T_UEcryptonak 436
+#define T_UEdigest 437
+#define T_Unconfig 438
+#define T_Unpeer 439
+#define T_Version 440
+#define T_WanderThreshold 441
+#define T_Week 442
+#define T_Wildcard 443
+#define T_Xleave 444
+#define T_Year 445
+#define T_Flag 446
+#define T_EOC 447
+#define T_Simulate 448
+#define T_Beep_Delay 449
+#define T_Sim_Duration 450
+#define T_Server_Offset 451
+#define T_Duration 452
+#define T_Freq_Offset 453
+#define T_Wander 454
+#define T_Jitter 455
+#define T_Prop_Delay 456
+#define T_Proc_Delay 457
+
+/* Value type. */
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+
+union YYSTYPE
+{
+#line 52 "ntp_parser.y" /* yacc.c:355 */
+
+ char * String;
+ double Double;
+ int Integer;
+ unsigned U_int;
+ gen_fifo * Generic_fifo;
+ attr_val * Attr_val;
+ attr_val_fifo * Attr_val_fifo;
+ int_fifo * Int_fifo;
+ string_fifo * String_fifo;
+ address_node * Address_node;
+ address_fifo * Address_fifo;
+ setvar_node * Set_var;
+ server_info * Sim_server;
+ server_info_fifo * Sim_server_fifo;
+ script_info * Sim_script;
+ script_info_fifo * Sim_script_fifo;
+
+#line 564 "ntp_parser.c" /* yacc.c:355 */
+};
+
+typedef union YYSTYPE YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+
+extern YYSTYPE yylval;
+
+int yyparse (void);
+
+#endif /* !YY_YY_NTP_PARSER_H_INCLUDED */
+
+/* Copy the second part of user declarations. */
+
+#line 581 "ntp_parser.c" /* yacc.c:358 */
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#else
+typedef signed char yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+# define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+# define YYSIZE_T size_t
+# elif ! defined YYSIZE_T
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# else
+# define YYSIZE_T unsigned int
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if defined YYENABLE_NLS && YYENABLE_NLS
+# if ENABLE_NLS
+# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_(Msgid) dgettext ("bison-runtime", Msgid)
+# endif
+# endif
+# ifndef YY_
+# define YY_(Msgid) Msgid
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE
+# if (defined __GNUC__ \
+ && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \
+ || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
+# define YY_ATTRIBUTE(Spec) __attribute__(Spec)
+# else
+# define YY_ATTRIBUTE(Spec) /* empty */
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE_PURE
+# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__))
+#endif
+
+#ifndef YY_ATTRIBUTE_UNUSED
+# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
+#endif
+
+#if !defined _Noreturn \
+ && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
+# if defined _MSC_VER && 1200 <= _MSC_VER
+# define _Noreturn __declspec (noreturn)
+# else
+# define _Noreturn YY_ATTRIBUTE ((__noreturn__))
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E. */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(E) ((void) (E))
+#else
+# define YYUSE(E) /* empty */
+#endif
+
+#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+/* Suppress an incorrect diagnostic about yylval being uninitialized. */
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+ _Pragma ("GCC diagnostic push") \
+ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
+ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
+ _Pragma ("GCC diagnostic pop")
+#else
+# define YY_INITIAL_VALUE(Value) Value
+#endif
+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END
+#endif
+#ifndef YY_INITIAL_VALUE
+# define YY_INITIAL_VALUE(Value) /* Nothing. */
+#endif
+
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# elif defined __BUILTIN_VA_ARG_INCR
+# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+# elif defined _AIX
+# define YYSTACK_ALLOC __alloca
+# elif defined _MSC_VER
+# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+# define alloca _alloca
+# else
+# define YYSTACK_ALLOC alloca
+# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+ /* Use EXIT_SUCCESS as a witness for stdlib.h. */
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+# endif
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's 'empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+# ifndef YYSTACK_ALLOC_MAXIMUM
+ /* The OS might guarantee only one guard page at the bottom of the stack,
+ and a page size can be as small as 4096 bytes. So we cannot safely
+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
+ to allow for a few compiler-allocated temporary stack slots. */
+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+# endif
+# else
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
+# ifndef YYSTACK_ALLOC_MAXIMUM
+# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+# endif
+# if (defined __cplusplus && ! defined EXIT_SUCCESS \
+ && ! ((defined YYMALLOC || defined malloc) \
+ && (defined YYFREE || defined free)))
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+# endif
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# if ! defined malloc && ! defined EXIT_SUCCESS
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# ifndef YYFREE
+# define YYFREE free
+# if ! defined free && ! defined EXIT_SUCCESS
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# endif
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+
+
+#if (! defined yyoverflow \
+ && (! defined __cplusplus \
+ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ yytype_int16 yyss_alloc;
+ YYSTYPE yyvs_alloc;
+};
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
+ + YYSTACK_GAP_MAXIMUM)
+
+# define YYCOPY_NEEDED 1
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
+ Stack = &yyptr->Stack_alloc; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (0)
+
+#endif
+
+#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
+/* Copy COUNT objects from SRC to DST. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if defined __GNUC__ && 1 < __GNUC__
+# define YYCOPY(Dst, Src, Count) \
+ __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
+# else
+# define YYCOPY(Dst, Src, Count) \
+ do \
+ { \
+ YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (Dst)[yyi] = (Src)[yyi]; \
+ } \
+ while (0)
+# endif
+# endif
+#endif /* !YYCOPY_NEEDED */
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 216
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 662
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 208
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 107
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 324
+/* YYNSTATES -- Number of states. */
+#define YYNSTATES 436
+
+/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
+ by yylex, with out-of-bounds checking. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 457
+
+#define YYTRANSLATE(YYX) \
+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
+ as returned by yylex, without out-of-bounds checking. */
+static const yytype_uint8 yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 204, 205, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 203, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 206, 2, 207, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
+ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
+ 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
+ 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
+ 125, 126, 127, 128, 129, 130, 131, 132, 133, 134,
+ 135, 136, 137, 138, 139, 140, 141, 142, 143, 144,
+ 145, 146, 147, 148, 149, 150, 151, 152, 153, 154,
+ 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,
+ 165, 166, 167, 168, 169, 170, 171, 172, 173, 174,
+ 175, 176, 177, 178, 179, 180, 181, 182, 183, 184,
+ 185, 186, 187, 188, 189, 190, 191, 192, 193, 194,
+ 195, 196, 197, 198, 199, 200, 201, 202
+};
+
+#if YYDEBUG
+ /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
+static const yytype_uint16 yyrline[] =
+{
+ 0, 378, 378, 382, 383, 384, 399, 400, 401, 402,
+ 403, 404, 405, 406, 407, 408, 409, 410, 411, 412,
+ 420, 430, 431, 432, 433, 434, 438, 439, 444, 449,
+ 451, 457, 458, 466, 467, 468, 472, 477, 478, 479,
+ 480, 481, 482, 483, 484, 488, 490, 495, 496, 497,
+ 498, 499, 500, 504, 509, 518, 528, 529, 539, 541,
+ 543, 545, 556, 563, 565, 570, 572, 574, 576, 578,
+ 588, 594, 595, 603, 605, 617, 618, 619, 620, 621,
+ 630, 635, 640, 648, 650, 652, 654, 659, 660, 661,
+ 662, 663, 664, 665, 666, 667, 671, 672, 681, 683,
+ 692, 702, 707, 715, 716, 717, 718, 719, 720, 721,
+ 722, 727, 728, 736, 746, 755, 770, 775, 776, 780,
+ 781, 785, 786, 787, 788, 789, 790, 791, 800, 804,
+ 808, 816, 824, 832, 847, 862, 875, 876, 896, 897,
+ 905, 906, 907, 908, 909, 910, 911, 912, 913, 914,
+ 915, 916, 917, 918, 919, 920, 921, 925, 930, 938,
+ 943, 944, 945, 949, 954, 962, 967, 968, 969, 970,
+ 971, 972, 973, 974, 982, 992, 997, 1005, 1007, 1009,
+ 1018, 1020, 1025, 1026, 1030, 1031, 1032, 1033, 1041, 1046,
+ 1051, 1059, 1064, 1065, 1066, 1075, 1077, 1082, 1087, 1095,
+ 1097, 1114, 1115, 1116, 1117, 1118, 1119, 1123, 1124, 1125,
+ 1126, 1127, 1128, 1136, 1141, 1146, 1154, 1159, 1160, 1161,
+ 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1177, 1178, 1179,
+ 1186, 1193, 1200, 1216, 1235, 1237, 1239, 1241, 1243, 1245,
+ 1252, 1257, 1258, 1259, 1263, 1267, 1276, 1277, 1281, 1282,
+ 1283, 1287, 1298, 1316, 1328, 1333, 1335, 1340, 1341, 1349,
+ 1351, 1359, 1364, 1372, 1397, 1404, 1414, 1415, 1419, 1420,
+ 1421, 1422, 1426, 1427, 1428, 1432, 1437, 1442, 1450, 1451,
+ 1452, 1453, 1454, 1455, 1456, 1466, 1471, 1479, 1484, 1492,
+ 1494, 1498, 1503, 1508, 1516, 1521, 1529, 1538, 1539, 1543,
+ 1544, 1548, 1556, 1574, 1578, 1583, 1591, 1596, 1597, 1601,
+ 1606, 1614, 1619, 1624, 1629, 1634, 1642, 1647, 1652, 1660,
+ 1665, 1666, 1667, 1668, 1669
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || 1
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "$end", "error", "$undefined", "T_Abbrev", "T_Age", "T_All", "T_Allan",
+ "T_Allpeers", "T_Auth", "T_Autokey", "T_Automax", "T_Average",
+ "T_Basedate", "T_Bclient", "T_Bcpollbstep", "T_Beacon", "T_Broadcast",
+ "T_Broadcastclient", "T_Broadcastdelay", "T_Burst", "T_Calibrate",
+ "T_Ceiling", "T_Clockstats", "T_Cohort", "T_ControlKey", "T_Crypto",
+ "T_Cryptostats", "T_Ctl", "T_Day", "T_Default", "T_Digest", "T_Disable",
+ "T_Discard", "T_Dispersion", "T_Double", "T_Driftfile", "T_Drop",
+ "T_Dscp", "T_Ellipsis", "T_Enable", "T_End", "T_Epeer", "T_False",
+ "T_File", "T_Filegen", "T_Filenum", "T_Flag1", "T_Flag2", "T_Flag3",
+ "T_Flag4", "T_Flake", "T_Floor", "T_Freq", "T_Fudge", "T_Host",
+ "T_Huffpuff", "T_Iburst", "T_Ident", "T_Ignore", "T_Incalloc",
+ "T_Incmem", "T_Initalloc", "T_Initmem", "T_Includefile", "T_Integer",
+ "T_Interface", "T_Intrange", "T_Io", "T_Ippeerlimit", "T_Ipv4",
+ "T_Ipv4_flag", "T_Ipv6", "T_Ipv6_flag", "T_Kernel", "T_Key", "T_Keys",
+ "T_Keysdir", "T_Kod", "T_Mssntp", "T_Leapfile", "T_Leapsmearinterval",
+ "T_Limited", "T_Link", "T_Listen", "T_Logconfig", "T_Logfile",
+ "T_Loopstats", "T_Lowpriotrap", "T_Manycastclient", "T_Manycastserver",
+ "T_Mask", "T_Maxage", "T_Maxclock", "T_Maxdepth", "T_Maxdist",
+ "T_Maxmem", "T_Maxpoll", "T_Mdnstries", "T_Mem", "T_Memlock",
+ "T_Minclock", "T_Mindepth", "T_Mindist", "T_Minimum", "T_Minpoll",
+ "T_Minsane", "T_Mode", "T_Mode7", "T_Monitor", "T_Month", "T_Mru",
+ "T_Multicastclient", "T_Nic", "T_Nolink", "T_Nomodify", "T_Nomrulist",
+ "T_None", "T_Nonvolatile", "T_Noepeer", "T_Nopeer", "T_Noquery",
+ "T_Noselect", "T_Noserve", "T_Notrap", "T_Notrust", "T_Ntp", "T_Ntpport",
+ "T_NtpSignDsocket", "T_Orphan", "T_Orphanwait", "T_PCEdigest", "T_Panic",
+ "T_Peer", "T_Peerstats", "T_Phone", "T_Pid", "T_Pidfile", "T_Pool",
+ "T_Port", "T_Preempt", "T_Prefer", "T_Protostats", "T_Pw", "T_Randfile",
+ "T_Rawstats", "T_Refid", "T_Requestkey", "T_Reset", "T_Restrict",
+ "T_Revoke", "T_Rlimit", "T_Saveconfigdir", "T_Server", "T_Setvar",
+ "T_Source", "T_Stacksize", "T_Statistics", "T_Stats", "T_Statsdir",
+ "T_Step", "T_Stepback", "T_Stepfwd", "T_Stepout", "T_Stratum",
+ "T_String", "T_Sys", "T_Sysstats", "T_Tick", "T_Time1", "T_Time2",
+ "T_Timer", "T_Timingstats", "T_Tinker", "T_Tos", "T_Trap", "T_True",
+ "T_Trustedkey", "T_Ttl", "T_Type", "T_U_int", "T_UEcrypto",
+ "T_UEcryptonak", "T_UEdigest", "T_Unconfig", "T_Unpeer", "T_Version",
+ "T_WanderThreshold", "T_Week", "T_Wildcard", "T_Xleave", "T_Year",
+ "T_Flag", "T_EOC", "T_Simulate", "T_Beep_Delay", "T_Sim_Duration",
+ "T_Server_Offset", "T_Duration", "T_Freq_Offset", "T_Wander", "T_Jitter",
+ "T_Prop_Delay", "T_Proc_Delay", "'='", "'('", "')'", "'{'", "'}'",
+ "$accept", "configuration", "command_list", "command", "server_command",
+ "client_type", "address", "ip_address", "address_fam", "option_list",
+ "option", "option_flag", "option_flag_keyword", "option_int",
+ "option_int_keyword", "option_str", "option_str_keyword",
+ "unpeer_command", "unpeer_keyword", "other_mode_command",
+ "authentication_command", "crypto_command_list", "crypto_command",
+ "crypto_str_keyword", "orphan_mode_command", "tos_option_list",
+ "tos_option", "tos_option_int_keyword", "tos_option_dbl_keyword",
+ "monitoring_command", "stats_list", "stat", "filegen_option_list",
+ "filegen_option", "link_nolink", "enable_disable", "filegen_type",
+ "access_control_command", "res_ippeerlimit", "ac_flag_list",
+ "access_control_flag", "discard_option_list", "discard_option",
+ "discard_option_keyword", "mru_option_list", "mru_option",
+ "mru_option_keyword", "fudge_command", "fudge_factor_list",
+ "fudge_factor", "fudge_factor_dbl_keyword", "fudge_factor_bool_keyword",
+ "rlimit_command", "rlimit_option_list", "rlimit_option",
+ "rlimit_option_keyword", "system_option_command", "system_option_list",
+ "system_option", "system_option_flag_keyword",
+ "system_option_local_flag_keyword", "tinker_command",
+ "tinker_option_list", "tinker_option", "tinker_option_keyword",
+ "miscellaneous_command", "misc_cmd_dbl_keyword", "misc_cmd_int_keyword",
+ "misc_cmd_str_keyword", "misc_cmd_str_lcl_keyword", "drift_parm",
+ "variable_assign", "t_default_or_zero", "trap_option_list",
+ "trap_option", "log_config_list", "log_config_command",
+ "interface_command", "interface_nic", "nic_rule_class",
+ "nic_rule_action", "reset_command", "counter_set_list",
+ "counter_set_keyword", "integer_list", "integer_list_range",
+ "integer_list_range_elt", "integer_range", "string_list", "address_list",
+ "boolean", "number", "basedate", "simulate_command", "sim_conf_start",
+ "sim_init_statement_list", "sim_init_statement", "sim_init_keyword",
+ "sim_server_list", "sim_server", "sim_server_offset", "sim_server_name",
+ "sim_act_list", "sim_act", "sim_act_stmt_list", "sim_act_stmt",
+ "sim_act_keyword", YY_NULLPTR
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[NUM] -- (External) token number corresponding to the
+ (internal) symbol number NUM (which must be that of a token). */
+static const yytype_uint16 yytoknum[] =
+{
+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
+ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
+ 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
+ 295, 296, 297, 298, 299, 300, 301, 302, 303, 304,
+ 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
+ 315, 316, 317, 318, 319, 320, 321, 322, 323, 324,
+ 325, 326, 327, 328, 329, 330, 331, 332, 333, 334,
+ 335, 336, 337, 338, 339, 340, 341, 342, 343, 344,
+ 345, 346, 347, 348, 349, 350, 351, 352, 353, 354,
+ 355, 356, 357, 358, 359, 360, 361, 362, 363, 364,
+ 365, 366, 367, 368, 369, 370, 371, 372, 373, 374,
+ 375, 376, 377, 378, 379, 380, 381, 382, 383, 384,
+ 385, 386, 387, 388, 389, 390, 391, 392, 393, 394,
+ 395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+ 405, 406, 407, 408, 409, 410, 411, 412, 413, 414,
+ 415, 416, 417, 418, 419, 420, 421, 422, 423, 424,
+ 425, 426, 427, 428, 429, 430, 431, 432, 433, 434,
+ 435, 436, 437, 438, 439, 440, 441, 442, 443, 444,
+ 445, 446, 447, 448, 449, 450, 451, 452, 453, 454,
+ 455, 456, 457, 61, 40, 41, 123, 125
+};
+# endif
+
+#define YYPACT_NINF -215
+
+#define yypact_value_is_default(Yystate) \
+ (!!((Yystate) == (-215)))
+
+#define YYTABLE_NINF -7
+
+#define yytable_value_is_error(Yytable_value) \
+ 0
+
+ /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+static const yytype_int16 yypact[] =
+{
+ 11, -175, 2, -215, -215, -215, 3, -215, 93, 9,
+ -138, -215, 93, -215, 66, -40, -215, -93, -215, -87,
+ -82, -215, -215, -81, -215, -215, -40, 20, 210, -40,
+ -215, -215, -70, -215, -67, -215, -215, 34, 6, -13,
+ 47, -6, -215, -215, -48, 66, -45, -215, 412, 483,
+ -39, -60, 62, -215, -215, -215, 127, 203, -63, -215,
+ -40, -215, -40, -215, -215, -215, -215, -215, -215, -215,
+ -215, -215, -215, -11, 75, -24, -22, -215, -18, -215,
+ -215, -53, -215, -215, -215, 48, -215, -215, -215, -215,
+ -215, -215, -215, -215, -215, -215, -215, -215, 93, -215,
+ -215, -215, -215, -215, -215, 9, -215, 82, 120, -215,
+ 93, -215, -215, -215, -215, -215, -215, -215, -215, -215,
+ -215, -215, -215, 86, -215, 4, 373, -215, -215, -215,
+ -81, -215, -215, -40, -215, -215, -215, -215, -215, -215,
+ -215, -215, -215, 210, -215, 106, -40, -215, -215, 15,
+ -215, -215, -215, -215, -215, -215, -215, -215, 6, -215,
+ 105, 146, 151, 105, -30, -215, -215, -215, -215, -6,
+ -215, 117, -21, -215, 66, -215, -215, -215, -215, -215,
+ -215, -215, -215, -215, -215, -215, -215, 412, -215, -11,
+ 22, -215, -215, -215, -20, -215, -215, -215, -215, -215,
+ -215, -215, -215, 483, -215, 128, -11, -215, -215, -215,
+ 129, -60, -215, -215, -215, 132, -215, 10, -215, -215,
+ -215, -215, -215, -215, -215, -215, -215, -215, -215, -215,
+ 1, -133, -215, -215, -215, -215, -215, 134, -215, 41,
+ -215, -215, -215, -215, -28, 42, -215, -215, -215, -215,
+ 45, 148, -215, -215, 86, -215, -11, -20, -215, -215,
+ -215, -215, -215, -215, -215, -215, 150, -215, 105, 105,
+ -215, -39, -215, -215, -215, 51, -215, -215, -215, -215,
+ -215, -215, -215, -215, -215, -215, -215, -57, 178, -215,
+ -215, -215, 288, -215, -215, -215, -215, -215, -215, -215,
+ -215, -115, 25, 23, -215, -215, -215, -215, 61, -215,
+ -215, 21, -215, -215, -215, -215, -215, -215, -215, -215,
+ -215, -215, 477, -215, -215, 477, 105, 477, 201, -39,
+ 169, -215, 172, -215, -215, -215, -215, -215, -215, -215,
+ -215, -215, -215, -215, -215, -215, -215, -215, -215, -215,
+ -215, -215, -59, -215, 77, 36, 52, -100, -215, 39,
+ -215, -11, -215, -215, -215, -215, -215, -215, -215, -215,
+ -215, -215, -215, -215, -215, -215, -215, -215, -215, -215,
+ -215, -215, -215, -215, -215, -215, -215, -215, -215, 477,
+ 477, -215, -215, -215, -215, -215, 43, -215, -215, -215,
+ -40, -215, -215, -215, 55, -215, 477, -215, -215, 49,
+ 56, -11, 54, -166, -215, 67, -11, -215, -215, -215,
+ 70, 63, -215, -215, -215, -215, -215, 124, 85, 64,
+ -215, 89, -215, -11, -215, -215
+};
+
+ /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
+ Performed when YYTABLE does not specify something else to do. Zero
+ means the default is an error. */
+static const yytype_uint16 yydefact[] =
+{
+ 0, 0, 0, 24, 58, 241, 0, 71, 0, 0,
+ 253, 244, 0, 234, 0, 0, 246, 0, 266, 0,
+ 0, 247, 245, 0, 248, 25, 0, 0, 0, 0,
+ 267, 242, 0, 23, 0, 249, 22, 0, 0, 0,
+ 0, 0, 250, 21, 0, 0, 0, 243, 0, 0,
+ 0, 0, 0, 56, 57, 303, 0, 2, 0, 7,
+ 0, 8, 0, 9, 10, 13, 11, 12, 14, 15,
+ 16, 17, 18, 0, 0, 0, 0, 227, 0, 228,
+ 19, 0, 5, 62, 63, 64, 201, 202, 203, 204,
+ 207, 205, 206, 208, 209, 210, 211, 212, 196, 198,
+ 199, 200, 160, 161, 162, 128, 158, 0, 251, 235,
+ 195, 103, 104, 105, 106, 110, 107, 108, 109, 111,
+ 29, 30, 28, 0, 26, 0, 6, 65, 66, 263,
+ 236, 262, 295, 59, 61, 166, 167, 168, 169, 170,
+ 171, 172, 173, 129, 164, 0, 60, 70, 293, 237,
+ 67, 278, 279, 280, 281, 282, 283, 284, 275, 277,
+ 136, 29, 30, 136, 136, 68, 194, 192, 193, 188,
+ 190, 0, 0, 238, 98, 102, 99, 217, 218, 219,
+ 220, 221, 222, 223, 224, 225, 226, 213, 215, 0,
+ 0, 87, 88, 89, 0, 90, 91, 97, 92, 96,
+ 93, 94, 95, 80, 82, 0, 0, 86, 257, 289,
+ 0, 69, 288, 290, 286, 240, 1, 0, 4, 31,
+ 55, 300, 299, 229, 230, 231, 232, 274, 273, 272,
+ 0, 0, 79, 75, 76, 77, 78, 0, 72, 0,
+ 197, 157, 159, 252, 100, 0, 184, 185, 186, 187,
+ 0, 0, 182, 183, 174, 176, 0, 0, 27, 233,
+ 261, 294, 163, 165, 292, 276, 0, 138, 136, 136,
+ 138, 0, 138, 189, 191, 0, 101, 214, 216, 301,
+ 298, 296, 297, 85, 81, 83, 84, 239, 0, 287,
+ 285, 3, 20, 268, 269, 270, 265, 271, 264, 307,
+ 308, 0, 0, 0, 74, 73, 120, 119, 0, 117,
+ 118, 0, 112, 115, 116, 180, 181, 179, 175, 177,
+ 178, 137, 132, 138, 138, 135, 136, 130, 256, 0,
+ 0, 258, 0, 37, 38, 39, 54, 47, 49, 48,
+ 51, 40, 41, 42, 43, 50, 52, 44, 32, 33,
+ 36, 34, 0, 35, 0, 0, 0, 0, 310, 0,
+ 305, 0, 113, 127, 123, 125, 121, 122, 124, 126,
+ 114, 140, 141, 142, 143, 144, 145, 146, 148, 149,
+ 147, 150, 151, 152, 153, 154, 155, 156, 139, 133,
+ 134, 138, 255, 254, 260, 259, 0, 45, 46, 53,
+ 0, 304, 302, 309, 0, 306, 131, 291, 313, 0,
+ 0, 0, 0, 0, 315, 0, 0, 311, 314, 312,
+ 0, 0, 320, 321, 322, 323, 324, 0, 0, 0,
+ 316, 0, 318, 0, 317, 319
+};
+
+ /* YYPGOTO[NTERM-NUM]. */
+static const yytype_int16 yypgoto[] =
+{
+ -215, -215, -215, -23, -215, -215, -15, -49, -215, -215,
+ -215, -215, -215, -215, -215, -215, -215, -215, -215, -215,
+ -215, -215, -215, -215, -215, -215, 81, -215, -215, -215,
+ -215, -38, -215, -215, -215, -215, -215, -215, -154, -214,
+ -215, -215, 153, -215, -215, 142, -215, -215, -215, 32,
+ -215, -215, -215, -215, 121, -215, -215, 277, -35, -215,
+ -215, -215, -215, 107, -215, -215, -215, -215, -215, -215,
+ -215, -215, -215, -215, -215, -215, 163, -215, -215, -215,
+ -215, -215, -215, 137, -215, -215, 87, -215, -215, 267,
+ 53, -187, -215, -215, -215, -215, -2, -215, -215, -55,
+ -215, -215, -215, -109, -215, -121, -215
+};
+
+ /* YYDEFGOTO[NTERM-NUM]. */
+static const yytype_int16 yydefgoto[] =
+{
+ -1, 56, 57, 58, 59, 60, 132, 124, 125, 292,
+ 348, 349, 350, 351, 352, 353, 354, 61, 62, 63,
+ 64, 85, 238, 239, 65, 203, 204, 205, 206, 66,
+ 174, 119, 244, 312, 313, 314, 370, 67, 267, 322,
+ 388, 105, 106, 107, 143, 144, 145, 68, 254, 255,
+ 256, 257, 69, 169, 170, 171, 70, 98, 99, 100,
+ 101, 71, 187, 188, 189, 72, 73, 74, 75, 76,
+ 109, 173, 393, 287, 331, 130, 131, 77, 78, 298,
+ 230, 79, 158, 159, 215, 211, 212, 213, 149, 133,
+ 283, 223, 207, 80, 81, 301, 302, 303, 357, 358,
+ 410, 359, 413, 414, 427, 428, 429
+};
+
+ /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule whose
+ number is the opposite. If YYTABLE_NINF, syntax error. */
+static const yytype_int16 yytable[] =
+{
+ 123, 208, 278, 306, 209, 397, 293, 175, 329, 270,
+ 272, 307, 1, 151, 152, 308, 160, 82, 227, 286,
+ 102, 2, 280, 221, 164, 363, 108, 3, 4, 5,
+ 120, 412, 121, 153, 217, 6, 7, 355, 266, 166,
+ 228, 417, 8, 9, 281, 219, 10, 220, 11, 364,
+ 12, 13, 355, 222, 309, 14, 325, 161, 327, 162,
+ 271, 299, 300, 240, 15, 229, 83, 84, 16, 319,
+ 294, 126, 295, 154, 17, 240, 18, 127, 232, 299,
+ 300, 330, 128, 129, 134, 310, 19, 20, 111, 245,
+ 21, 22, 112, 167, 147, 23, 24, 148, 150, 25,
+ 26, 86, 233, 259, 155, 234, 87, 402, 27, 389,
+ 390, 165, 103, 88, 323, 324, 172, 104, 261, 176,
+ 398, 28, 29, 30, 122, 122, 214, 216, 31, 218,
+ 365, 261, 246, 247, 248, 249, 276, 366, 32, 224,
+ 225, 163, 226, 33, 210, 34, 242, 35, 36, 168,
+ 311, 122, 113, 231, 243, 282, 367, 37, 38, 39,
+ 40, 41, 42, 43, 44, 296, 89, 45, 258, 46,
+ 263, 156, 391, 266, 405, 268, 157, 406, 47, 264,
+ 269, 274, 275, 48, 49, 50, 279, 51, 52, 297,
+ 235, 236, 285, 288, 53, 54, 290, 237, 304, 114,
+ 90, 91, 291, -6, 55, 305, 315, 115, 368, 316,
+ 116, 369, 317, 2, 321, 328, 332, 360, 92, 3,
+ 4, 5, 326, 93, 415, 362, 361, 6, 7, 420,
+ 392, 250, 117, 395, 8, 9, 396, 118, 10, 400,
+ 11, 399, 12, 13, 401, 404, 435, 14, 407, 251,
+ 94, 409, 411, 412, 252, 253, 15, 416, 241, 419,
+ 16, 422, 423, 424, 425, 426, 17, 433, 18, 135,
+ 136, 137, 138, 95, 96, 97, 421, 432, 19, 20,
+ 394, 434, 21, 22, 284, 262, 318, 23, 24, 110,
+ 273, 25, 26, 260, 277, 265, 146, 333, 289, 356,
+ 27, 139, 403, 140, 418, 141, 431, 334, 0, 0,
+ 320, 142, 0, 28, 29, 30, 0, 0, 0, 0,
+ 31, 0, 422, 423, 424, 425, 426, 0, 0, 0,
+ 32, 430, 0, 0, 0, 33, 0, 34, 0, 35,
+ 36, 0, 0, 0, 335, 336, 0, 0, 0, 37,
+ 38, 39, 40, 41, 42, 43, 44, 0, 0, 45,
+ 0, 46, 337, 0, 0, 0, 0, 0, 0, 0,
+ 47, 0, 0, 0, 0, 48, 49, 50, 0, 51,
+ 52, 0, 0, 2, 338, 408, 53, 54, 0, 3,
+ 4, 5, 339, 0, 340, -6, 55, 6, 7, 0,
+ 0, 0, 0, 0, 8, 9, 0, 0, 10, 341,
+ 11, 0, 12, 13, 0, 0, 0, 14, 177, 0,
+ 0, 0, 0, 0, 0, 0, 15, 342, 343, 0,
+ 16, 0, 0, 0, 0, 0, 17, 0, 18, 0,
+ 0, 0, 0, 0, 0, 178, 0, 0, 19, 20,
+ 0, 0, 21, 22, 0, 0, 0, 23, 24, 0,
+ 0, 25, 26, 344, 179, 345, 0, 180, 0, 0,
+ 27, 0, 0, 346, 0, 0, 0, 347, 0, 0,
+ 0, 0, 0, 28, 29, 30, 0, 0, 0, 0,
+ 31, 0, 0, 0, 0, 190, 0, 191, 192, 0,
+ 32, 0, 0, 0, 193, 33, 194, 34, 0, 35,
+ 36, 0, 0, 0, 0, 0, 0, 0, 371, 37,
+ 38, 39, 40, 41, 42, 43, 44, 372, 0, 45,
+ 0, 46, 0, 0, 195, 373, 0, 0, 0, 0,
+ 47, 0, 0, 181, 0, 48, 49, 50, 0, 51,
+ 52, 0, 0, 0, 374, 375, 53, 54, 376, 0,
+ 0, 0, 0, 0, 377, 0, 55, 0, 0, 0,
+ 0, 182, 183, 184, 185, 196, 0, 197, 0, 186,
+ 0, 0, 0, 198, 0, 199, 0, 0, 200, 0,
+ 0, 378, 379, 0, 0, 380, 381, 382, 0, 383,
+ 384, 385, 0, 386, 0, 0, 0, 0, 0, 0,
+ 0, 201, 202, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 387
+};
+
+static const yytype_int16 yycheck[] =
+{
+ 15, 50, 189, 31, 64, 64, 5, 45, 65, 163,
+ 164, 39, 1, 7, 8, 43, 29, 192, 36, 206,
+ 11, 10, 42, 34, 39, 4, 164, 16, 17, 18,
+ 70, 197, 72, 27, 57, 24, 25, 152, 68, 45,
+ 58, 207, 31, 32, 64, 60, 35, 62, 37, 28,
+ 39, 40, 152, 64, 82, 44, 270, 70, 272, 72,
+ 90, 194, 195, 98, 53, 83, 64, 64, 57, 256,
+ 69, 164, 71, 67, 63, 110, 65, 164, 30, 194,
+ 195, 138, 164, 164, 64, 113, 75, 76, 22, 3,
+ 79, 80, 26, 99, 164, 84, 85, 164, 64, 88,
+ 89, 8, 54, 126, 98, 57, 13, 207, 97, 323,
+ 324, 64, 103, 20, 268, 269, 164, 108, 133, 164,
+ 179, 110, 111, 112, 164, 164, 64, 0, 117, 192,
+ 109, 146, 46, 47, 48, 49, 174, 116, 127, 64,
+ 164, 154, 164, 132, 204, 134, 64, 136, 137, 155,
+ 178, 164, 86, 206, 34, 175, 135, 146, 147, 148,
+ 149, 150, 151, 152, 153, 164, 73, 156, 164, 158,
+ 64, 165, 326, 68, 361, 29, 170, 391, 167, 164,
+ 29, 64, 203, 172, 173, 174, 164, 176, 177, 188,
+ 142, 143, 64, 64, 183, 184, 64, 149, 64, 133,
+ 107, 108, 192, 192, 193, 164, 164, 141, 187, 164,
+ 144, 190, 64, 10, 64, 164, 38, 192, 125, 16,
+ 17, 18, 271, 130, 411, 164, 203, 24, 25, 416,
+ 29, 145, 166, 64, 31, 32, 64, 171, 35, 203,
+ 37, 164, 39, 40, 192, 206, 433, 44, 205, 163,
+ 157, 196, 203, 197, 168, 169, 53, 203, 105, 192,
+ 57, 198, 199, 200, 201, 202, 63, 203, 65, 59,
+ 60, 61, 62, 180, 181, 182, 206, 192, 75, 76,
+ 329, 192, 79, 80, 203, 143, 254, 84, 85, 12,
+ 169, 88, 89, 130, 187, 158, 29, 9, 211, 301,
+ 97, 91, 357, 93, 413, 95, 427, 19, -1, -1,
+ 257, 101, -1, 110, 111, 112, -1, -1, -1, -1,
+ 117, -1, 198, 199, 200, 201, 202, -1, -1, -1,
+ 127, 207, -1, -1, -1, 132, -1, 134, -1, 136,
+ 137, -1, -1, -1, 56, 57, -1, -1, -1, 146,
+ 147, 148, 149, 150, 151, 152, 153, -1, -1, 156,
+ -1, 158, 74, -1, -1, -1, -1, -1, -1, -1,
+ 167, -1, -1, -1, -1, 172, 173, 174, -1, 176,
+ 177, -1, -1, 10, 96, 400, 183, 184, -1, 16,
+ 17, 18, 104, -1, 106, 192, 193, 24, 25, -1,
+ -1, -1, -1, -1, 31, 32, -1, -1, 35, 121,
+ 37, -1, 39, 40, -1, -1, -1, 44, 6, -1,
+ -1, -1, -1, -1, -1, -1, 53, 139, 140, -1,
+ 57, -1, -1, -1, -1, -1, 63, -1, 65, -1,
+ -1, -1, -1, -1, -1, 33, -1, -1, 75, 76,
+ -1, -1, 79, 80, -1, -1, -1, 84, 85, -1,
+ -1, 88, 89, 175, 52, 177, -1, 55, -1, -1,
+ 97, -1, -1, 185, -1, -1, -1, 189, -1, -1,
+ -1, -1, -1, 110, 111, 112, -1, -1, -1, -1,
+ 117, -1, -1, -1, -1, 12, -1, 14, 15, -1,
+ 127, -1, -1, -1, 21, 132, 23, 134, -1, 136,
+ 137, -1, -1, -1, -1, -1, -1, -1, 41, 146,
+ 147, 148, 149, 150, 151, 152, 153, 50, -1, 156,
+ -1, 158, -1, -1, 51, 58, -1, -1, -1, -1,
+ 167, -1, -1, 131, -1, 172, 173, 174, -1, 176,
+ 177, -1, -1, -1, 77, 78, 183, 184, 81, -1,
+ -1, -1, -1, -1, 87, -1, 193, -1, -1, -1,
+ -1, 159, 160, 161, 162, 92, -1, 94, -1, 167,
+ -1, -1, -1, 100, -1, 102, -1, -1, 105, -1,
+ -1, 114, 115, -1, -1, 118, 119, 120, -1, 122,
+ 123, 124, -1, 126, -1, -1, -1, -1, -1, -1,
+ -1, 128, 129, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 185
+};
+
+ /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const yytype_uint16 yystos[] =
+{
+ 0, 1, 10, 16, 17, 18, 24, 25, 31, 32,
+ 35, 37, 39, 40, 44, 53, 57, 63, 65, 75,
+ 76, 79, 80, 84, 85, 88, 89, 97, 110, 111,
+ 112, 117, 127, 132, 134, 136, 137, 146, 147, 148,
+ 149, 150, 151, 152, 153, 156, 158, 167, 172, 173,
+ 174, 176, 177, 183, 184, 193, 209, 210, 211, 212,
+ 213, 225, 226, 227, 228, 232, 237, 245, 255, 260,
+ 264, 269, 273, 274, 275, 276, 277, 285, 286, 289,
+ 301, 302, 192, 64, 64, 229, 8, 13, 20, 73,
+ 107, 108, 125, 130, 157, 180, 181, 182, 265, 266,
+ 267, 268, 11, 103, 108, 249, 250, 251, 164, 278,
+ 265, 22, 26, 86, 133, 141, 144, 166, 171, 239,
+ 70, 72, 164, 214, 215, 216, 164, 164, 164, 164,
+ 283, 284, 214, 297, 64, 59, 60, 61, 62, 91,
+ 93, 95, 101, 252, 253, 254, 297, 164, 164, 296,
+ 64, 7, 8, 27, 67, 98, 165, 170, 290, 291,
+ 29, 70, 72, 154, 214, 64, 45, 99, 155, 261,
+ 262, 263, 164, 279, 238, 239, 164, 6, 33, 52,
+ 55, 131, 159, 160, 161, 162, 167, 270, 271, 272,
+ 12, 14, 15, 21, 23, 51, 92, 94, 100, 102,
+ 105, 128, 129, 233, 234, 235, 236, 300, 215, 64,
+ 204, 293, 294, 295, 64, 292, 0, 211, 192, 214,
+ 214, 34, 64, 299, 64, 164, 164, 36, 58, 83,
+ 288, 206, 30, 54, 57, 142, 143, 149, 230, 231,
+ 266, 250, 64, 34, 240, 3, 46, 47, 48, 49,
+ 145, 163, 168, 169, 256, 257, 258, 259, 164, 211,
+ 284, 214, 253, 64, 164, 291, 68, 246, 29, 29,
+ 246, 90, 246, 262, 64, 203, 239, 271, 299, 164,
+ 42, 64, 175, 298, 234, 64, 299, 281, 64, 294,
+ 64, 192, 217, 5, 69, 71, 164, 188, 287, 194,
+ 195, 303, 304, 305, 64, 164, 31, 39, 43, 82,
+ 113, 178, 241, 242, 243, 164, 164, 64, 257, 299,
+ 298, 64, 247, 246, 246, 247, 215, 247, 164, 65,
+ 138, 282, 38, 9, 19, 56, 57, 74, 96, 104,
+ 106, 121, 139, 140, 175, 177, 185, 189, 218, 219,
+ 220, 221, 222, 223, 224, 152, 304, 306, 307, 309,
+ 192, 203, 164, 4, 28, 109, 116, 135, 187, 190,
+ 244, 41, 50, 58, 77, 78, 81, 87, 114, 115,
+ 118, 119, 120, 122, 123, 124, 126, 185, 248, 247,
+ 247, 246, 29, 280, 215, 64, 64, 64, 179, 164,
+ 203, 192, 207, 307, 206, 299, 247, 205, 214, 196,
+ 308, 203, 197, 310, 311, 299, 203, 207, 311, 192,
+ 299, 206, 198, 199, 200, 201, 202, 312, 313, 314,
+ 207, 313, 192, 203, 192, 299
+};
+
+ /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const yytype_uint16 yyr1[] =
+{
+ 0, 208, 209, 210, 210, 210, 211, 211, 211, 211,
+ 211, 211, 211, 211, 211, 211, 211, 211, 211, 211,
+ 212, 213, 213, 213, 213, 213, 214, 214, 215, 216,
+ 216, 217, 217, 218, 218, 218, 219, 220, 220, 220,
+ 220, 220, 220, 220, 220, 221, 221, 222, 222, 222,
+ 222, 222, 222, 223, 224, 225, 226, 226, 227, 227,
+ 227, 227, 228, 228, 228, 228, 228, 228, 228, 228,
+ 228, 229, 229, 230, 230, 231, 231, 231, 231, 231,
+ 232, 233, 233, 234, 234, 234, 234, 235, 235, 235,
+ 235, 235, 235, 235, 235, 235, 236, 236, 237, 237,
+ 237, 238, 238, 239, 239, 239, 239, 239, 239, 239,
+ 239, 240, 240, 241, 241, 241, 241, 242, 242, 243,
+ 243, 244, 244, 244, 244, 244, 244, 244, 245, 245,
+ 245, 245, 245, 245, 245, 245, 246, 246, 247, 247,
+ 248, 248, 248, 248, 248, 248, 248, 248, 248, 248,
+ 248, 248, 248, 248, 248, 248, 248, 249, 249, 250,
+ 251, 251, 251, 252, 252, 253, 254, 254, 254, 254,
+ 254, 254, 254, 254, 255, 256, 256, 257, 257, 257,
+ 257, 257, 258, 258, 259, 259, 259, 259, 260, 261,
+ 261, 262, 263, 263, 263, 264, 264, 265, 265, 266,
+ 266, 267, 267, 267, 267, 267, 267, 268, 268, 268,
+ 268, 268, 268, 269, 270, 270, 271, 272, 272, 272,
+ 272, 272, 272, 272, 272, 272, 272, 273, 273, 273,
+ 273, 273, 273, 273, 273, 273, 273, 273, 273, 273,
+ 273, 274, 274, 274, 275, 275, 276, 276, 277, 277,
+ 277, 278, 278, 278, 279, 280, 280, 281, 281, 282,
+ 282, 283, 283, 284, 285, 285, 286, 286, 287, 287,
+ 287, 287, 288, 288, 288, 289, 290, 290, 291, 291,
+ 291, 291, 291, 291, 291, 292, 292, 293, 293, 294,
+ 294, 295, 296, 296, 297, 297, 298, 298, 298, 299,
+ 299, 300, 301, 302, 303, 303, 304, 305, 305, 306,
+ 306, 307, 308, 309, 310, 310, 311, 312, 312, 313,
+ 314, 314, 314, 314, 314
+};
+
+ /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
+static const yytype_uint8 yyr2[] =
+{
+ 0, 2, 1, 3, 2, 2, 0, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 3, 1, 1, 1, 1, 1, 1, 2, 1, 1,
+ 1, 0, 2, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 2, 2, 1, 1, 1,
+ 1, 1, 1, 2, 1, 2, 1, 1, 1, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 0, 2, 2, 2, 1, 1, 1, 1, 1,
+ 2, 2, 1, 2, 2, 2, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
+ 3, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 0, 2, 2, 2, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
+ 4, 6, 4, 5, 5, 4, 0, 2, 0, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 2, 1, 2,
+ 1, 1, 1, 2, 1, 2, 1, 1, 1, 1,
+ 1, 1, 1, 1, 3, 2, 1, 2, 2, 2,
+ 2, 2, 1, 1, 1, 1, 1, 1, 2, 2,
+ 1, 2, 1, 1, 1, 2, 2, 2, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 2, 2, 1, 2, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
+ 2, 2, 2, 3, 1, 2, 2, 2, 2, 3,
+ 2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 2, 0, 4, 1, 0, 0, 2, 2,
+ 2, 2, 1, 1, 3, 3, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 2, 2, 1, 1, 1,
+ 1, 1, 1, 1, 1, 2, 1, 2, 1, 1,
+ 1, 5, 2, 1, 2, 1, 1, 1, 1, 1,
+ 1, 2, 5, 1, 3, 2, 3, 1, 1, 2,
+ 1, 5, 4, 3, 2, 1, 6, 3, 2, 3,
+ 1, 1, 1, 1, 1
+};
+
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY (-2)
+#define YYEOF 0
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
+
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ YYPOPSTACK (yylen); \
+ yystate = *yyssp; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror (YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+while (0)
+
+/* Error token number */
+#define YYTERROR 1
+#define YYERRCODE 256
+
+
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (0)
+
+/* This macro is provided for backward compatibility. */
+#ifndef YY_LOCATION_PRINT
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+#endif
+
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yy_symbol_print (stderr, \
+ Type, Value); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (0)
+
+
+/*----------------------------------------.
+| Print this symbol's value on YYOUTPUT. |
+`----------------------------------------*/
+
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+{
+ FILE *yyo = yyoutput;
+ YYUSE (yyo);
+ if (!yyvaluep)
+ return;
+# ifdef YYPRINT
+ if (yytype < YYNTOKENS)
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# endif
+ YYUSE (yytype);
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+{
+ YYFPRINTF (yyoutput, "%s %s (",
+ yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
+
+ yy_symbol_value_print (yyoutput, yytype, yyvaluep);
+ YYFPRINTF (yyoutput, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+static void
+yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (; yybottom <= yytop; yybottom++)
+ {
+ int yybot = *yybottom;
+ YYFPRINTF (stderr, " %d", yybot);
+ }
+ YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+do { \
+ if (yydebug) \
+ yy_stack_print ((Bottom), (Top)); \
+} while (0)
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+static void
+yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule)
+{
+ unsigned long int yylno = yyrline[yyrule];
+ int yynrhs = yyr2[yyrule];
+ int yyi;
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+ yyrule - 1, yylno);
+ /* The symbols being reduced. */
+ for (yyi = 0; yyi < yynrhs; yyi++)
+ {
+ YYFPRINTF (stderr, " $%d = ", yyi + 1);
+ yy_symbol_print (stderr,
+ yystos[yyssp[yyi + 1 - yynrhs]],
+ &(yyvsp[(yyi + 1) - (yynrhs)])
+ );
+ YYFPRINTF (stderr, "\n");
+ }
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (yyssp, yyvsp, Rule); \
+} while (0)
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined __GLIBC__ && defined _STRING_H
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+static YYSIZE_T
+yystrlen (const char *yystr)
+{
+ YYSIZE_T yylen;
+ for (yylen = 0; yystr[yylen]; yylen++)
+ continue;
+ return yylen;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+{
+ char *yyd = yydest;
+ const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+ quotes and backslashes, so that it's suitable for yyerror. The
+ heuristic is that double-quoting is unnecessary unless the string
+ contains an apostrophe, a comma, or backslash (other than
+ backslash-backslash). YYSTR is taken from yytname. If YYRES is
+ null, do not copy; instead, return the length of what the result
+ would have been. */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+ if (*yystr == '"')
+ {
+ YYSIZE_T yyn = 0;
+ char const *yyp = yystr;
+
+ for (;;)
+ switch (*++yyp)
+ {
+ case '\'':
+ case ',':
+ goto do_not_strip_quotes;
+
+ case '\\':
+ if (*++yyp != '\\')
+ goto do_not_strip_quotes;
+ /* Fall through. */
+ default:
+ if (yyres)
+ yyres[yyn] = *yyp;
+ yyn++;
+ break;
+
+ case '"':
+ if (yyres)
+ yyres[yyn] = '\0';
+ return yyn;
+ }
+ do_not_strip_quotes: ;
+ }
+
+ if (! yyres)
+ return yystrlen (yystr);
+
+ return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
+ about the unexpected token YYTOKEN for the state stack whose top is
+ YYSSP.
+
+ Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is
+ not large enough to hold the message. In that case, also set
+ *YYMSG_ALLOC to the required number of bytes. Return 2 if the
+ required number of bytes is too large to store. */
+static int
+yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
+ yytype_int16 *yyssp, int yytoken)
+{
+ YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
+ YYSIZE_T yysize = yysize0;
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ /* Internationalized format string. */
+ const char *yyformat = YY_NULLPTR;
+ /* Arguments of yyformat. */
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ /* Number of reported tokens (one for the "unexpected", one per
+ "expected"). */
+ int yycount = 0;
+
+ /* There are many possibilities here to consider:
+ - If this state is a consistent state with a default action, then
+ the only way this function was invoked is if the default action
+ is an error action. In that case, don't check for expected
+ tokens because there are none.
+ - The only way there can be no lookahead present (in yychar) is if
+ this state is a consistent state with a default action. Thus,
+ detecting the absence of a lookahead is sufficient to determine
+ that there is no unexpected or expected token to report. In that
+ case, just report a simple "syntax error".
+ - Don't assume there isn't a lookahead just because this state is a
+ consistent state with a default action. There might have been a
+ previous inconsistent state, consistent state with a non-default
+ action, or user semantic action that manipulated yychar.
+ - Of course, the expected token list depends on states to have
+ correct lookahead information, and it depends on the parser not
+ to perform extra reductions after fetching a lookahead from the
+ scanner and before detecting a syntax error. Thus, state merging
+ (from LALR or IELR) and default reductions corrupt the expected
+ token list. However, the list is correct for canonical LR with
+ one exception: it will still contain any token that will not be
+ accepted due to an error action in a later state.
+ */
+ if (yytoken != YYEMPTY)
+ {
+ int yyn = yypact[*yyssp];
+ yyarg[yycount++] = yytname[yytoken];
+ if (!yypact_value_is_default (yyn))
+ {
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. In other words, skip the first -YYN actions for
+ this state because they are default actions. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn + 1;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yyx;
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
+ && !yytable_value_is_error (yytable[yyx + yyn]))
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ {
+ YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
+ if (! (yysize <= yysize1
+ && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ return 2;
+ yysize = yysize1;
+ }
+ }
+ }
+ }
+
+ switch (yycount)
+ {
+# define YYCASE_(N, S) \
+ case N: \
+ yyformat = S; \
+ break
+ YYCASE_(0, YY_("syntax error"));
+ YYCASE_(1, YY_("syntax error, unexpected %s"));
+ YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
+ YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
+ YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
+ YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
+# undef YYCASE_
+ }
+
+ {
+ YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
+ if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ return 2;
+ yysize = yysize1;
+ }
+
+ if (*yymsg_alloc < yysize)
+ {
+ *yymsg_alloc = 2 * yysize;
+ if (! (yysize <= *yymsg_alloc
+ && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
+ *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
+ return 1;
+ }
+
+ /* Avoid sprintf, as that infringes on the user's name space.
+ Don't have undefined behavior even if the translation
+ produced a string with the wrong number of "%s"s. */
+ {
+ char *yyp = *yymsg;
+ int yyi = 0;
+ while ((*yyp = *yyformat) != '\0')
+ if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyformat += 2;
+ }
+ else
+ {
+ yyp++;
+ yyformat++;
+ }
+ }
+ return 0;
+}
+#endif /* YYERROR_VERBOSE */
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
+{
+ YYUSE (yyvaluep);
+ if (!yymsg)
+ yymsg = "Deleting";
+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ YYUSE (yytype);
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+}
+
+
+
+
+/* The lookahead symbol. */
+int yychar;
+
+/* The semantic value of the lookahead symbol. */
+YYSTYPE yylval;
+/* Number of syntax errors so far. */
+int yynerrs;
+
+
+/*----------.
+| yyparse. |
+`----------*/
+
+int
+yyparse (void)
+{
+ int yystate;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+
+ /* The stacks and their tools:
+ 'yyss': related to states.
+ 'yyvs': related to semantic values.
+
+ Refer to the stacks through separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ yytype_int16 yyssa[YYINITDEPTH];
+ yytype_int16 *yyss;
+ yytype_int16 *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs;
+ YYSTYPE *yyvsp;
+
+ YYSIZE_T yystacksize;
+
+ int yyn;
+ int yyresult;
+ /* Lookahead token as an internal (translated) token number. */
+ int yytoken = 0;
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+
+#if YYERROR_VERBOSE
+ /* Buffer for error messages, and its allocated size. */
+ char yymsgbuf[128];
+ char *yymsg = yymsgbuf;
+ YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
+
+ /* The number of symbols on the RHS of the reduced rule.
+ Keep to zero when no symbol should be popped. */
+ int yylen = 0;
+
+ yyssp = yyss = yyssa;
+ yyvsp = yyvs = yyvsa;
+ yystacksize = YYINITDEPTH;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+ yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. So pushing a state here evens the stacks. */
+ yyssp++;
+
+ yysetstate:
+ *yyssp = yystate;
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ yytype_int16 *yyss1 = yyss;
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow (YY_("memory exhausted"),
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+ &yystacksize);
+
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyexhaustedlab;
+# else
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ goto yyexhaustedlab;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ yytype_int16 *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyexhaustedlab;
+ YYSTACK_RELOCATE (yyss_alloc, yyss);
+ YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long int) yystacksize));
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+ if (yystate == YYFINAL)
+ YYACCEPT;
+
+ goto yybackup;
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+
+ /* Do appropriate processing given the current state. Read a
+ lookahead token if we need one and don't already have one. */
+
+ /* First try to decide what to do without reference to lookahead token. */
+ yyn = yypact[yystate];
+ if (yypact_value_is_default (yyn))
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = yylex ();
+ }
+
+ if (yychar <= YYEOF)
+ {
+ yychar = yytoken = YYEOF;
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yytoken = YYTRANSLATE (yychar);
+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+ }
+
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yytable_value_is_error (yyn))
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ /* Shift the lookahead token. */
+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+ /* Discard the shifted token. */
+ yychar = YYEMPTY;
+
+ yystate = yyn;
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ *++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+
+ goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ '$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+
+ YY_REDUCE_PRINT (yyn);
+ switch (yyn)
+ {
+ case 5:
+#line 385 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ /* I will need to incorporate much more fine grained
+ * error messages. The following should suffice for
+ * the time being.
+ */
+ struct FILE_INFO * ip_ctx = lex_current();
+ msyslog(LOG_ERR,
+ "syntax error in %s line %d, column %d",
+ ip_ctx->fname,
+ ip_ctx->errpos.nline,
+ ip_ctx->errpos.ncol);
+ }
+#line 2144 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 20:
+#line 421 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ peer_node *my_node;
+
+ my_node = create_peer_node((yyvsp[-2].Integer), (yyvsp[-1].Address_node), (yyvsp[0].Attr_val_fifo));
+ APPEND_G_FIFO(cfgt.peers, my_node);
+ }
+#line 2155 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 27:
+#line 440 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Address_node) = create_address_node((yyvsp[0].String), (yyvsp[-1].Integer)); }
+#line 2161 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 28:
+#line 445 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Address_node) = create_address_node((yyvsp[0].String), AF_UNSPEC); }
+#line 2167 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 29:
+#line 450 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Integer) = AF_INET; }
+#line 2173 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 30:
+#line 452 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Integer) = AF_INET6; }
+#line 2179 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 31:
+#line 457 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Attr_val_fifo) = NULL; }
+#line 2185 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 32:
+#line 459 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Attr_val_fifo) = (yyvsp[-1].Attr_val_fifo);
+ APPEND_G_FIFO((yyval.Attr_val_fifo), (yyvsp[0].Attr_val));
+ }
+#line 2194 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 36:
+#line 473 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Attr_val) = create_attr_ival(T_Flag, (yyvsp[0].Integer)); }
+#line 2200 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 45:
+#line 489 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Attr_val) = create_attr_ival((yyvsp[-1].Integer), (yyvsp[0].Integer)); }
+#line 2206 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 46:
+#line 491 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Attr_val) = create_attr_uval((yyvsp[-1].Integer), (yyvsp[0].Integer)); }
+#line 2212 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 53:
+#line 505 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Attr_val) = create_attr_sval((yyvsp[-1].Integer), (yyvsp[0].String)); }
+#line 2218 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 55:
+#line 519 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ unpeer_node *my_node;
+
+ my_node = create_unpeer_node((yyvsp[0].Address_node));
+ if (my_node)
+ APPEND_G_FIFO(cfgt.unpeers, my_node);
+ }
+#line 2230 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 58:
+#line 540 "ntp_parser.y" /* yacc.c:1646 */
+ { cfgt.broadcastclient = 1; }
+#line 2236 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 59:
+#line 542 "ntp_parser.y" /* yacc.c:1646 */
+ { CONCAT_G_FIFOS(cfgt.manycastserver, (yyvsp[0].Address_fifo)); }
+#line 2242 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 60:
+#line 544 "ntp_parser.y" /* yacc.c:1646 */
+ { CONCAT_G_FIFOS(cfgt.multicastclient, (yyvsp[0].Address_fifo)); }
+#line 2248 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 61:
+#line 546 "ntp_parser.y" /* yacc.c:1646 */
+ { cfgt.mdnstries = (yyvsp[0].Integer); }
+#line 2254 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 62:
+#line 557 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ attr_val *atrv;
+
+ atrv = create_attr_ival((yyvsp[-1].Integer), (yyvsp[0].Integer));
+ APPEND_G_FIFO(cfgt.vars, atrv);
+ }
+#line 2265 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 63:
+#line 564 "ntp_parser.y" /* yacc.c:1646 */
+ { cfgt.auth.control_key = (yyvsp[0].Integer); }
+#line 2271 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 64:
+#line 566 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ cfgt.auth.cryptosw++;
+ CONCAT_G_FIFOS(cfgt.auth.crypto_cmd_list, (yyvsp[0].Attr_val_fifo));
+ }
+#line 2280 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 65:
+#line 571 "ntp_parser.y" /* yacc.c:1646 */
+ { cfgt.auth.keys = (yyvsp[0].String); }
+#line 2286 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 66:
+#line 573 "ntp_parser.y" /* yacc.c:1646 */
+ { cfgt.auth.keysdir = (yyvsp[0].String); }
+#line 2292 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 67:
+#line 575 "ntp_parser.y" /* yacc.c:1646 */
+ { cfgt.auth.request_key = (yyvsp[0].Integer); }
+#line 2298 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 68:
+#line 577 "ntp_parser.y" /* yacc.c:1646 */
+ { cfgt.auth.revoke = (yyvsp[0].Integer); }
+#line 2304 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 69:
+#line 579 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ /* [Bug 948] leaves it open if appending or
+ * replacing the trusted key list is the right
+ * way. In any case, either alternative should
+ * be coded correctly!
+ */
+ DESTROY_G_FIFO(cfgt.auth.trusted_key_list, destroy_attr_val); /* remove for append */
+ CONCAT_G_FIFOS(cfgt.auth.trusted_key_list, (yyvsp[0].Attr_val_fifo));
+ }
+#line 2318 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 70:
+#line 589 "ntp_parser.y" /* yacc.c:1646 */
+ { cfgt.auth.ntp_signd_socket = (yyvsp[0].String); }
+#line 2324 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 71:
+#line 594 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Attr_val_fifo) = NULL; }
+#line 2330 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 72:
+#line 596 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Attr_val_fifo) = (yyvsp[-1].Attr_val_fifo);
+ APPEND_G_FIFO((yyval.Attr_val_fifo), (yyvsp[0].Attr_val));
+ }
+#line 2339 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 73:
+#line 604 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Attr_val) = create_attr_sval((yyvsp[-1].Integer), (yyvsp[0].String)); }
+#line 2345 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 74:
+#line 606 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Attr_val) = NULL;
+ cfgt.auth.revoke = (yyvsp[0].Integer);
+ msyslog(LOG_WARNING,
+ "'crypto revoke %d' is deprecated, "
+ "please use 'revoke %d' instead.",
+ cfgt.auth.revoke, cfgt.auth.revoke);
+ }
+#line 2358 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 80:
+#line 631 "ntp_parser.y" /* yacc.c:1646 */
+ { CONCAT_G_FIFOS(cfgt.orphan_cmds, (yyvsp[0].Attr_val_fifo)); }
+#line 2364 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 81:
+#line 636 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Attr_val_fifo) = (yyvsp[-1].Attr_val_fifo);
+ APPEND_G_FIFO((yyval.Attr_val_fifo), (yyvsp[0].Attr_val));
+ }
+#line 2373 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 82:
+#line 641 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Attr_val_fifo) = NULL;
+ APPEND_G_FIFO((yyval.Attr_val_fifo), (yyvsp[0].Attr_val));
+ }
+#line 2382 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 83:
+#line 649 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Attr_val) = create_attr_dval((yyvsp[-1].Integer), (double)(yyvsp[0].Integer)); }
+#line 2388 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 84:
+#line 651 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Attr_val) = create_attr_dval((yyvsp[-1].Integer), (yyvsp[0].Double)); }
+#line 2394 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 85:
+#line 653 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Attr_val) = create_attr_dval((yyvsp[-1].Integer), (double)(yyvsp[0].Integer)); }
+#line 2400 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 86:
+#line 655 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Attr_val) = create_attr_ival(T_Basedate, (yyvsp[0].Integer)); }
+#line 2406 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 98:
+#line 682 "ntp_parser.y" /* yacc.c:1646 */
+ { CONCAT_G_FIFOS(cfgt.stats_list, (yyvsp[0].Int_fifo)); }
+#line 2412 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 99:
+#line 684 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ if (lex_from_file()) {
+ cfgt.stats_dir = (yyvsp[0].String);
+ } else {
+ YYFREE((yyvsp[0].String));
+ yyerror("statsdir remote configuration ignored");
+ }
+ }
+#line 2425 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 100:
+#line 693 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ filegen_node *fgn;
+
+ fgn = create_filegen_node((yyvsp[-1].Integer), (yyvsp[0].Attr_val_fifo));
+ APPEND_G_FIFO(cfgt.filegen_opts, fgn);
+ }
+#line 2436 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 101:
+#line 703 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Int_fifo) = (yyvsp[-1].Int_fifo);
+ APPEND_G_FIFO((yyval.Int_fifo), create_int_node((yyvsp[0].Integer)));
+ }
+#line 2445 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 102:
+#line 708 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Int_fifo) = NULL;
+ APPEND_G_FIFO((yyval.Int_fifo), create_int_node((yyvsp[0].Integer)));
+ }
+#line 2454 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 111:
+#line 727 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Attr_val_fifo) = NULL; }
+#line 2460 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 112:
+#line 729 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Attr_val_fifo) = (yyvsp[-1].Attr_val_fifo);
+ APPEND_G_FIFO((yyval.Attr_val_fifo), (yyvsp[0].Attr_val));
+ }
+#line 2469 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 113:
+#line 737 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ if (lex_from_file()) {
+ (yyval.Attr_val) = create_attr_sval((yyvsp[-1].Integer), (yyvsp[0].String));
+ } else {
+ (yyval.Attr_val) = NULL;
+ YYFREE((yyvsp[0].String));
+ yyerror("filegen file remote config ignored");
+ }
+ }
+#line 2483 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 114:
+#line 747 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ if (lex_from_file()) {
+ (yyval.Attr_val) = create_attr_ival((yyvsp[-1].Integer), (yyvsp[0].Integer));
+ } else {
+ (yyval.Attr_val) = NULL;
+ yyerror("filegen type remote config ignored");
+ }
+ }
+#line 2496 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 115:
+#line 756 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ const char *err;
+
+ if (lex_from_file()) {
+ (yyval.Attr_val) = create_attr_ival(T_Flag, (yyvsp[0].Integer));
+ } else {
+ (yyval.Attr_val) = NULL;
+ if (T_Link == (yyvsp[0].Integer))
+ err = "filegen link remote config ignored";
+ else
+ err = "filegen nolink remote config ignored";
+ yyerror(err);
+ }
+ }
+#line 2515 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 116:
+#line 771 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Attr_val) = create_attr_ival(T_Flag, (yyvsp[0].Integer)); }
+#line 2521 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 128:
+#line 801 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ CONCAT_G_FIFOS(cfgt.discard_opts, (yyvsp[0].Attr_val_fifo));
+ }
+#line 2529 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 129:
+#line 805 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ CONCAT_G_FIFOS(cfgt.mru_opts, (yyvsp[0].Attr_val_fifo));
+ }
+#line 2537 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 130:
+#line 809 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ restrict_node *rn;
+
+ rn = create_restrict_node((yyvsp[-2].Address_node), NULL, (yyvsp[-1].Integer), (yyvsp[0].Int_fifo),
+ lex_current()->curpos.nline);
+ APPEND_G_FIFO(cfgt.restrict_opts, rn);
+ }
+#line 2549 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 131:
+#line 817 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ restrict_node *rn;
+
+ rn = create_restrict_node((yyvsp[-4].Address_node), (yyvsp[-2].Address_node), (yyvsp[-1].Integer), (yyvsp[0].Int_fifo),
+ lex_current()->curpos.nline);
+ APPEND_G_FIFO(cfgt.restrict_opts, rn);
+ }
+#line 2561 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 132:
+#line 825 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ restrict_node *rn;
+
+ rn = create_restrict_node(NULL, NULL, (yyvsp[-1].Integer), (yyvsp[0].Int_fifo),
+ lex_current()->curpos.nline);
+ APPEND_G_FIFO(cfgt.restrict_opts, rn);
+ }
+#line 2573 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 133:
+#line 833 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ restrict_node *rn;
+
+ rn = create_restrict_node(
+ create_address_node(
+ estrdup("0.0.0.0"),
+ AF_INET),
+ create_address_node(
+ estrdup("0.0.0.0"),
+ AF_INET),
+ (yyvsp[-1].Integer), (yyvsp[0].Int_fifo),
+ lex_current()->curpos.nline);
+ APPEND_G_FIFO(cfgt.restrict_opts, rn);
+ }
+#line 2592 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 134:
+#line 848 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ restrict_node *rn;
+
+ rn = create_restrict_node(
+ create_address_node(
+ estrdup("::"),
+ AF_INET6),
+ create_address_node(
+ estrdup("::"),
+ AF_INET6),
+ (yyvsp[-1].Integer), (yyvsp[0].Int_fifo),
+ lex_current()->curpos.nline);
+ APPEND_G_FIFO(cfgt.restrict_opts, rn);
+ }
+#line 2611 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 135:
+#line 863 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ restrict_node * rn;
+
+ APPEND_G_FIFO((yyvsp[0].Int_fifo), create_int_node((yyvsp[-2].Integer)));
+ rn = create_restrict_node(
+ NULL, NULL, (yyvsp[-1].Integer), (yyvsp[0].Int_fifo), lex_current()->curpos.nline);
+ APPEND_G_FIFO(cfgt.restrict_opts, rn);
+ }
+#line 2624 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 136:
+#line 875 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Integer) = -1; }
+#line 2630 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 137:
+#line 877 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ if (((yyvsp[0].Integer) < -1) || ((yyvsp[0].Integer) > 100)) {
+ struct FILE_INFO * ip_ctx;
+
+ ip_ctx = lex_current();
+ msyslog(LOG_ERR,
+ "Unreasonable ippeerlimit value (%d) in %s line %d, column %d. Using 0.",
+ (yyvsp[0].Integer),
+ ip_ctx->fname,
+ ip_ctx->errpos.nline,
+ ip_ctx->errpos.ncol);
+ (yyvsp[0].Integer) = 0;
+ }
+ (yyval.Integer) = (yyvsp[0].Integer);
+ }
+#line 2650 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 138:
+#line 896 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Int_fifo) = NULL; }
+#line 2656 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 139:
+#line 898 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Int_fifo) = (yyvsp[-1].Int_fifo);
+ APPEND_G_FIFO((yyval.Int_fifo), create_int_node((yyvsp[0].Integer)));
+ }
+#line 2665 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 157:
+#line 926 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Attr_val_fifo) = (yyvsp[-1].Attr_val_fifo);
+ APPEND_G_FIFO((yyval.Attr_val_fifo), (yyvsp[0].Attr_val));
+ }
+#line 2674 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 158:
+#line 931 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Attr_val_fifo) = NULL;
+ APPEND_G_FIFO((yyval.Attr_val_fifo), (yyvsp[0].Attr_val));
+ }
+#line 2683 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 159:
+#line 939 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Attr_val) = create_attr_ival((yyvsp[-1].Integer), (yyvsp[0].Integer)); }
+#line 2689 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 163:
+#line 950 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Attr_val_fifo) = (yyvsp[-1].Attr_val_fifo);
+ APPEND_G_FIFO((yyval.Attr_val_fifo), (yyvsp[0].Attr_val));
+ }
+#line 2698 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 164:
+#line 955 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Attr_val_fifo) = NULL;
+ APPEND_G_FIFO((yyval.Attr_val_fifo), (yyvsp[0].Attr_val));
+ }
+#line 2707 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 165:
+#line 963 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Attr_val) = create_attr_ival((yyvsp[-1].Integer), (yyvsp[0].Integer)); }
+#line 2713 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 174:
+#line 983 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ addr_opts_node *aon;
+
+ aon = create_addr_opts_node((yyvsp[-1].Address_node), (yyvsp[0].Attr_val_fifo));
+ APPEND_G_FIFO(cfgt.fudge, aon);
+ }
+#line 2724 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 175:
+#line 993 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Attr_val_fifo) = (yyvsp[-1].Attr_val_fifo);
+ APPEND_G_FIFO((yyval.Attr_val_fifo), (yyvsp[0].Attr_val));
+ }
+#line 2733 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 176:
+#line 998 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Attr_val_fifo) = NULL;
+ APPEND_G_FIFO((yyval.Attr_val_fifo), (yyvsp[0].Attr_val));
+ }
+#line 2742 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 177:
+#line 1006 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Attr_val) = create_attr_dval((yyvsp[-1].Integer), (yyvsp[0].Double)); }
+#line 2748 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 178:
+#line 1008 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Attr_val) = create_attr_ival((yyvsp[-1].Integer), (yyvsp[0].Integer)); }
+#line 2754 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 179:
+#line 1010 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ if ((yyvsp[0].Integer) >= 0 && (yyvsp[0].Integer) <= 16) {
+ (yyval.Attr_val) = create_attr_ival((yyvsp[-1].Integer), (yyvsp[0].Integer));
+ } else {
+ (yyval.Attr_val) = NULL;
+ yyerror("fudge factor: stratum value not in [0..16], ignored");
+ }
+ }
+#line 2767 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 180:
+#line 1019 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Attr_val) = create_attr_sval((yyvsp[-1].Integer), (yyvsp[0].String)); }
+#line 2773 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 181:
+#line 1021 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Attr_val) = create_attr_sval((yyvsp[-1].Integer), (yyvsp[0].String)); }
+#line 2779 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 188:
+#line 1042 "ntp_parser.y" /* yacc.c:1646 */
+ { CONCAT_G_FIFOS(cfgt.rlimit, (yyvsp[0].Attr_val_fifo)); }
+#line 2785 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 189:
+#line 1047 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Attr_val_fifo) = (yyvsp[-1].Attr_val_fifo);
+ APPEND_G_FIFO((yyval.Attr_val_fifo), (yyvsp[0].Attr_val));
+ }
+#line 2794 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 190:
+#line 1052 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Attr_val_fifo) = NULL;
+ APPEND_G_FIFO((yyval.Attr_val_fifo), (yyvsp[0].Attr_val));
+ }
+#line 2803 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 191:
+#line 1060 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Attr_val) = create_attr_ival((yyvsp[-1].Integer), (yyvsp[0].Integer)); }
+#line 2809 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 195:
+#line 1076 "ntp_parser.y" /* yacc.c:1646 */
+ { CONCAT_G_FIFOS(cfgt.enable_opts, (yyvsp[0].Attr_val_fifo)); }
+#line 2815 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 196:
+#line 1078 "ntp_parser.y" /* yacc.c:1646 */
+ { CONCAT_G_FIFOS(cfgt.disable_opts, (yyvsp[0].Attr_val_fifo)); }
+#line 2821 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 197:
+#line 1083 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Attr_val_fifo) = (yyvsp[-1].Attr_val_fifo);
+ APPEND_G_FIFO((yyval.Attr_val_fifo), (yyvsp[0].Attr_val));
+ }
+#line 2830 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 198:
+#line 1088 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Attr_val_fifo) = NULL;
+ APPEND_G_FIFO((yyval.Attr_val_fifo), (yyvsp[0].Attr_val));
+ }
+#line 2839 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 199:
+#line 1096 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Attr_val) = create_attr_ival(T_Flag, (yyvsp[0].Integer)); }
+#line 2845 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 200:
+#line 1098 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ if (lex_from_file()) {
+ (yyval.Attr_val) = create_attr_ival(T_Flag, (yyvsp[0].Integer));
+ } else {
+ char err_str[128];
+
+ (yyval.Attr_val) = NULL;
+ snprintf(err_str, sizeof(err_str),
+ "enable/disable %s remote configuration ignored",
+ keyword((yyvsp[0].Integer)));
+ yyerror(err_str);
+ }
+ }
+#line 2863 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 213:
+#line 1137 "ntp_parser.y" /* yacc.c:1646 */
+ { CONCAT_G_FIFOS(cfgt.tinker, (yyvsp[0].Attr_val_fifo)); }
+#line 2869 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 214:
+#line 1142 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Attr_val_fifo) = (yyvsp[-1].Attr_val_fifo);
+ APPEND_G_FIFO((yyval.Attr_val_fifo), (yyvsp[0].Attr_val));
+ }
+#line 2878 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 215:
+#line 1147 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Attr_val_fifo) = NULL;
+ APPEND_G_FIFO((yyval.Attr_val_fifo), (yyvsp[0].Attr_val));
+ }
+#line 2887 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 216:
+#line 1155 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Attr_val) = create_attr_dval((yyvsp[-1].Integer), (yyvsp[0].Double)); }
+#line 2893 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 229:
+#line 1180 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ attr_val *av;
+
+ av = create_attr_dval((yyvsp[-1].Integer), (yyvsp[0].Double));
+ APPEND_G_FIFO(cfgt.vars, av);
+ }
+#line 2904 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 230:
+#line 1187 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ attr_val *av;
+
+ av = create_attr_ival((yyvsp[-1].Integer), (yyvsp[0].Integer));
+ APPEND_G_FIFO(cfgt.vars, av);
+ }
+#line 2915 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 231:
+#line 1194 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ attr_val *av;
+
+ av = create_attr_sval((yyvsp[-1].Integer), (yyvsp[0].String));
+ APPEND_G_FIFO(cfgt.vars, av);
+ }
+#line 2926 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 232:
+#line 1201 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ char error_text[64];
+ attr_val *av;
+
+ if (lex_from_file()) {
+ av = create_attr_sval((yyvsp[-1].Integer), (yyvsp[0].String));
+ APPEND_G_FIFO(cfgt.vars, av);
+ } else {
+ YYFREE((yyvsp[0].String));
+ snprintf(error_text, sizeof(error_text),
+ "%s remote config ignored",
+ keyword((yyvsp[-1].Integer)));
+ yyerror(error_text);
+ }
+ }
+#line 2946 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 233:
+#line 1217 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ if (!lex_from_file()) {
+ YYFREE((yyvsp[-1].String)); /* avoid leak */
+ yyerror("remote includefile ignored");
+ break;
+ }
+ if (lex_level() > MAXINCLUDELEVEL) {
+ fprintf(stderr, "getconfig: Maximum include file level exceeded.\n");
+ msyslog(LOG_ERR, "getconfig: Maximum include file level exceeded.");
+ } else {
+ const char * path = FindConfig((yyvsp[-1].String)); /* might return $2! */
+ if (!lex_push_file(path, "r")) {
+ fprintf(stderr, "getconfig: Couldn't open <%s>\n", path);
+ msyslog(LOG_ERR, "getconfig: Couldn't open <%s>", path);
+ }
+ }
+ YYFREE((yyvsp[-1].String)); /* avoid leak */
+ }
+#line 2969 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 234:
+#line 1236 "ntp_parser.y" /* yacc.c:1646 */
+ { lex_flush_stack(); }
+#line 2975 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 235:
+#line 1238 "ntp_parser.y" /* yacc.c:1646 */
+ { /* see drift_parm below for actions */ }
+#line 2981 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 236:
+#line 1240 "ntp_parser.y" /* yacc.c:1646 */
+ { CONCAT_G_FIFOS(cfgt.logconfig, (yyvsp[0].Attr_val_fifo)); }
+#line 2987 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 237:
+#line 1242 "ntp_parser.y" /* yacc.c:1646 */
+ { CONCAT_G_FIFOS(cfgt.phone, (yyvsp[0].String_fifo)); }
+#line 2993 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 238:
+#line 1244 "ntp_parser.y" /* yacc.c:1646 */
+ { APPEND_G_FIFO(cfgt.setvar, (yyvsp[0].Set_var)); }
+#line 2999 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 239:
+#line 1246 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ addr_opts_node *aon;
+
+ aon = create_addr_opts_node((yyvsp[-1].Address_node), (yyvsp[0].Attr_val_fifo));
+ APPEND_G_FIFO(cfgt.trap, aon);
+ }
+#line 3010 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 240:
+#line 1253 "ntp_parser.y" /* yacc.c:1646 */
+ { CONCAT_G_FIFOS(cfgt.ttl, (yyvsp[0].Attr_val_fifo)); }
+#line 3016 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 245:
+#line 1268 "ntp_parser.y" /* yacc.c:1646 */
+ {
+#ifndef LEAP_SMEAR
+ yyerror("Built without LEAP_SMEAR support.");
+#endif
+ }
+#line 3026 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 251:
+#line 1288 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ if (lex_from_file()) {
+ attr_val *av;
+ av = create_attr_sval(T_Driftfile, (yyvsp[0].String));
+ APPEND_G_FIFO(cfgt.vars, av);
+ } else {
+ YYFREE((yyvsp[0].String));
+ yyerror("driftfile remote configuration ignored");
+ }
+ }
+#line 3041 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 252:
+#line 1299 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ if (lex_from_file()) {
+ attr_val *av;
+ av = create_attr_sval(T_Driftfile, (yyvsp[-1].String));
+ APPEND_G_FIFO(cfgt.vars, av);
+ av = create_attr_dval(T_WanderThreshold, (yyvsp[0].Double));
+ APPEND_G_FIFO(cfgt.vars, av);
+ msyslog(LOG_WARNING,
+ "'driftfile FILENAME WanderValue' is deprecated, "
+ "please use separate 'driftfile FILENAME' and "
+ "'nonvolatile WanderValue' lines instead.");
+ } else {
+ YYFREE((yyvsp[-1].String));
+ yyerror("driftfile remote configuration ignored");
+ }
+ }
+#line 3062 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 253:
+#line 1316 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ if (lex_from_file()) {
+ attr_val *av;
+ av = create_attr_sval(T_Driftfile, estrdup(""));
+ APPEND_G_FIFO(cfgt.vars, av);
+ } else {
+ yyerror("driftfile remote configuration ignored");
+ }
+ }
+#line 3076 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 254:
+#line 1329 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Set_var) = create_setvar_node((yyvsp[-3].String), (yyvsp[-1].String), (yyvsp[0].Integer)); }
+#line 3082 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 256:
+#line 1335 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Integer) = 0; }
+#line 3088 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 257:
+#line 1340 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Attr_val_fifo) = NULL; }
+#line 3094 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 258:
+#line 1342 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Attr_val_fifo) = (yyvsp[-1].Attr_val_fifo);
+ APPEND_G_FIFO((yyval.Attr_val_fifo), (yyvsp[0].Attr_val));
+ }
+#line 3103 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 259:
+#line 1350 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Attr_val) = create_attr_ival((yyvsp[-1].Integer), (yyvsp[0].Integer)); }
+#line 3109 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 260:
+#line 1352 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Attr_val) = create_attr_sval((yyvsp[-1].Integer), estrdup((yyvsp[0].Address_node)->address));
+ destroy_address_node((yyvsp[0].Address_node));
+ }
+#line 3118 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 261:
+#line 1360 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Attr_val_fifo) = (yyvsp[-1].Attr_val_fifo);
+ APPEND_G_FIFO((yyval.Attr_val_fifo), (yyvsp[0].Attr_val));
+ }
+#line 3127 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 262:
+#line 1365 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Attr_val_fifo) = NULL;
+ APPEND_G_FIFO((yyval.Attr_val_fifo), (yyvsp[0].Attr_val));
+ }
+#line 3136 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 263:
+#line 1373 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ char prefix;
+ char * type;
+
+ switch ((yyvsp[0].String)[0]) {
+
+ case '+':
+ case '-':
+ case '=':
+ prefix = (yyvsp[0].String)[0];
+ type = (yyvsp[0].String) + 1;
+ break;
+
+ default:
+ prefix = '=';
+ type = (yyvsp[0].String);
+ }
+
+ (yyval.Attr_val) = create_attr_sval(prefix, estrdup(type));
+ YYFREE((yyvsp[0].String));
+ }
+#line 3162 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 264:
+#line 1398 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ nic_rule_node *nrn;
+
+ nrn = create_nic_rule_node((yyvsp[0].Integer), NULL, (yyvsp[-1].Integer));
+ APPEND_G_FIFO(cfgt.nic_rules, nrn);
+ }
+#line 3173 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 265:
+#line 1405 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ nic_rule_node *nrn;
+
+ nrn = create_nic_rule_node(0, (yyvsp[0].String), (yyvsp[-1].Integer));
+ APPEND_G_FIFO(cfgt.nic_rules, nrn);
+ }
+#line 3184 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 275:
+#line 1433 "ntp_parser.y" /* yacc.c:1646 */
+ { CONCAT_G_FIFOS(cfgt.reset_counters, (yyvsp[0].Int_fifo)); }
+#line 3190 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 276:
+#line 1438 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Int_fifo) = (yyvsp[-1].Int_fifo);
+ APPEND_G_FIFO((yyval.Int_fifo), create_int_node((yyvsp[0].Integer)));
+ }
+#line 3199 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 277:
+#line 1443 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Int_fifo) = NULL;
+ APPEND_G_FIFO((yyval.Int_fifo), create_int_node((yyvsp[0].Integer)));
+ }
+#line 3208 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 285:
+#line 1467 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Attr_val_fifo) = (yyvsp[-1].Attr_val_fifo);
+ APPEND_G_FIFO((yyval.Attr_val_fifo), create_int_node((yyvsp[0].Integer)));
+ }
+#line 3217 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 286:
+#line 1472 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Attr_val_fifo) = NULL;
+ APPEND_G_FIFO((yyval.Attr_val_fifo), create_int_node((yyvsp[0].Integer)));
+ }
+#line 3226 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 287:
+#line 1480 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Attr_val_fifo) = (yyvsp[-1].Attr_val_fifo);
+ APPEND_G_FIFO((yyval.Attr_val_fifo), (yyvsp[0].Attr_val));
+ }
+#line 3235 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 288:
+#line 1485 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Attr_val_fifo) = NULL;
+ APPEND_G_FIFO((yyval.Attr_val_fifo), (yyvsp[0].Attr_val));
+ }
+#line 3244 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 289:
+#line 1493 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Attr_val) = create_attr_ival('i', (yyvsp[0].Integer)); }
+#line 3250 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 291:
+#line 1499 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Attr_val) = create_attr_rangeval('-', (yyvsp[-3].Integer), (yyvsp[-1].Integer)); }
+#line 3256 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 292:
+#line 1504 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.String_fifo) = (yyvsp[-1].String_fifo);
+ APPEND_G_FIFO((yyval.String_fifo), create_string_node((yyvsp[0].String)));
+ }
+#line 3265 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 293:
+#line 1509 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.String_fifo) = NULL;
+ APPEND_G_FIFO((yyval.String_fifo), create_string_node((yyvsp[0].String)));
+ }
+#line 3274 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 294:
+#line 1517 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Address_fifo) = (yyvsp[-1].Address_fifo);
+ APPEND_G_FIFO((yyval.Address_fifo), (yyvsp[0].Address_node));
+ }
+#line 3283 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 295:
+#line 1522 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Address_fifo) = NULL;
+ APPEND_G_FIFO((yyval.Address_fifo), (yyvsp[0].Address_node));
+ }
+#line 3292 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 296:
+#line 1530 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ if ((yyvsp[0].Integer) != 0 && (yyvsp[0].Integer) != 1) {
+ yyerror("Integer value is not boolean (0 or 1). Assuming 1");
+ (yyval.Integer) = 1;
+ } else {
+ (yyval.Integer) = (yyvsp[0].Integer);
+ }
+ }
+#line 3305 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 297:
+#line 1538 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Integer) = 1; }
+#line 3311 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 298:
+#line 1539 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Integer) = 0; }
+#line 3317 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 299:
+#line 1543 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Double) = (double)(yyvsp[0].Integer); }
+#line 3323 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 301:
+#line 1549 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Integer) = basedate_eval_string((yyvsp[0].String)); YYFREE((yyvsp[0].String)); }
+#line 3329 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 302:
+#line 1557 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ sim_node *sn;
+
+ sn = create_sim_node((yyvsp[-2].Attr_val_fifo), (yyvsp[-1].Sim_server_fifo));
+ APPEND_G_FIFO(cfgt.sim_details, sn);
+
+ /* Revert from ; to \n for end-of-command */
+ old_config_style = 1;
+ }
+#line 3343 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 303:
+#line 1574 "ntp_parser.y" /* yacc.c:1646 */
+ { old_config_style = 0; }
+#line 3349 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 304:
+#line 1579 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Attr_val_fifo) = (yyvsp[-2].Attr_val_fifo);
+ APPEND_G_FIFO((yyval.Attr_val_fifo), (yyvsp[-1].Attr_val));
+ }
+#line 3358 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 305:
+#line 1584 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Attr_val_fifo) = NULL;
+ APPEND_G_FIFO((yyval.Attr_val_fifo), (yyvsp[-1].Attr_val));
+ }
+#line 3367 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 306:
+#line 1592 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Attr_val) = create_attr_dval((yyvsp[-2].Integer), (yyvsp[0].Double)); }
+#line 3373 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 309:
+#line 1602 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Sim_server_fifo) = (yyvsp[-1].Sim_server_fifo);
+ APPEND_G_FIFO((yyval.Sim_server_fifo), (yyvsp[0].Sim_server));
+ }
+#line 3382 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 310:
+#line 1607 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Sim_server_fifo) = NULL;
+ APPEND_G_FIFO((yyval.Sim_server_fifo), (yyvsp[0].Sim_server));
+ }
+#line 3391 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 311:
+#line 1615 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Sim_server) = ONLY_SIM(create_sim_server((yyvsp[-4].Address_node), (yyvsp[-2].Double), (yyvsp[-1].Sim_script_fifo))); }
+#line 3397 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 312:
+#line 1620 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Double) = (yyvsp[-1].Double); }
+#line 3403 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 313:
+#line 1625 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Address_node) = (yyvsp[0].Address_node); }
+#line 3409 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 314:
+#line 1630 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Sim_script_fifo) = (yyvsp[-1].Sim_script_fifo);
+ APPEND_G_FIFO((yyval.Sim_script_fifo), (yyvsp[0].Sim_script));
+ }
+#line 3418 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 315:
+#line 1635 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Sim_script_fifo) = NULL;
+ APPEND_G_FIFO((yyval.Sim_script_fifo), (yyvsp[0].Sim_script));
+ }
+#line 3427 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 316:
+#line 1643 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Sim_script) = ONLY_SIM(create_sim_script_info((yyvsp[-3].Double), (yyvsp[-1].Attr_val_fifo))); }
+#line 3433 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 317:
+#line 1648 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Attr_val_fifo) = (yyvsp[-2].Attr_val_fifo);
+ APPEND_G_FIFO((yyval.Attr_val_fifo), (yyvsp[-1].Attr_val));
+ }
+#line 3442 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 318:
+#line 1653 "ntp_parser.y" /* yacc.c:1646 */
+ {
+ (yyval.Attr_val_fifo) = NULL;
+ APPEND_G_FIFO((yyval.Attr_val_fifo), (yyvsp[-1].Attr_val));
+ }
+#line 3451 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+ case 319:
+#line 1661 "ntp_parser.y" /* yacc.c:1646 */
+ { (yyval.Attr_val) = create_attr_dval((yyvsp[-2].Integer), (yyvsp[0].Double)); }
+#line 3457 "ntp_parser.c" /* yacc.c:1646 */
+ break;
+
+
+#line 3461 "ntp_parser.c" /* yacc.c:1646 */
+ default: break;
+ }
+ /* User semantic actions sometimes alter yychar, and that requires
+ that yytoken be updated with the new translation. We take the
+ approach of translating immediately before every use of yytoken.
+ One alternative is translating here after every semantic action,
+ but that translation would be missed if the semantic action invokes
+ YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
+ if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
+ incorrect destructor might then be invoked immediately. In the
+ case of YYERROR or YYBACKUP, subsequent parser actions might lead
+ to an incorrect destructor call or verbose syntax error message
+ before the lookahead is translated. */
+ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+
+ *++yyvsp = yyval;
+
+ /* Now 'shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTOKENS];
+
+ goto yynewstate;
+
+
+/*--------------------------------------.
+| yyerrlab -- here on detecting error. |
+`--------------------------------------*/
+yyerrlab:
+ /* Make sure we have latest lookahead translation. See comments at
+ user semantic actions for why this is necessary. */
+ yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
+
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+#if ! YYERROR_VERBOSE
+ yyerror (YY_("syntax error"));
+#else
+# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
+ yyssp, yytoken)
+ {
+ char const *yymsgp = YY_("syntax error");
+ int yysyntax_error_status;
+ yysyntax_error_status = YYSYNTAX_ERROR;
+ if (yysyntax_error_status == 0)
+ yymsgp = yymsg;
+ else if (yysyntax_error_status == 1)
+ {
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+ yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
+ if (!yymsg)
+ {
+ yymsg = yymsgbuf;
+ yymsg_alloc = sizeof yymsgbuf;
+ yysyntax_error_status = 2;
+ }
+ else
+ {
+ yysyntax_error_status = YYSYNTAX_ERROR;
+ yymsgp = yymsg;
+ }
+ }
+ yyerror (yymsgp);
+ if (yysyntax_error_status == 2)
+ goto yyexhaustedlab;
+ }
+# undef YYSYNTAX_ERROR
+#endif
+ }
+
+
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ if (yychar <= YYEOF)
+ {
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ YYABORT;
+ }
+ else
+ {
+ yydestruct ("Error: discarding",
+ yytoken, &yylval);
+ yychar = YYEMPTY;
+ }
+ }
+
+ /* Else will try to reuse lookahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
+
+ /* Pacify compilers like GCC when the user code never invokes
+ YYERROR and the label yyerrorlab therefore never appears in user
+ code. */
+ if (/*CONSTCOND*/ 0)
+ goto yyerrorlab;
+
+ /* Do not reclaim the symbols of the rule whose action triggered
+ this YYERROR. */
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+ yystate = *yyssp;
+ goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (!yypact_value_is_default (yyn))
+ {
+ yyn += YYTERROR;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+
+ yydestruct ("Error: popping",
+ yystos[yystate], yyvsp);
+ YYPOPSTACK (1);
+ yystate = *yyssp;
+ YY_STACK_PRINT (yyss, yyssp);
+ }
+
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ *++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+
+
+ /* Shift the error token. */
+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+#if !defined yyoverflow || YYERROR_VERBOSE
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here. |
+`-------------------------------------------------*/
+yyexhaustedlab:
+ yyerror (YY_("memory exhausted"));
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+yyreturn:
+ if (yychar != YYEMPTY)
+ {
+ /* Make sure we have latest lookahead translation. See comments at
+ user semantic actions for why this is necessary. */
+ yytoken = YYTRANSLATE (yychar);
+ yydestruct ("Cleanup: discarding lookahead",
+ yytoken, &yylval);
+ }
+ /* Do not reclaim the symbols of the rule whose action triggered
+ this YYABORT or YYACCEPT. */
+ YYPOPSTACK (yylen);
+ YY_STACK_PRINT (yyss, yyssp);
+ while (yyssp != yyss)
+ {
+ yydestruct ("Cleanup: popping",
+ yystos[*yyssp], yyvsp);
+ YYPOPSTACK (1);
+ }
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+#endif
+ return yyresult;
+}
+#line 1672 "ntp_parser.y" /* yacc.c:1906 */
+
+
+void
+yyerror(
+ const char *msg
+ )
+{
+ int retval;
+ struct FILE_INFO * ip_ctx;
+
+ ip_ctx = lex_current();
+ ip_ctx->errpos = ip_ctx->tokpos;
+
+ msyslog(LOG_ERR, "line %d column %d %s",
+ ip_ctx->errpos.nline, ip_ctx->errpos.ncol, msg);
+ if (!lex_from_file()) {
+ /* Save the error message in the correct buffer */
+ retval = snprintf(remote_config.err_msg + remote_config.err_pos,
+ MAXLINE - remote_config.err_pos,
+ "column %d %s",
+ ip_ctx->errpos.ncol, msg);
+
+ /* Increment the value of err_pos */
+ if (retval > 0)
+ remote_config.err_pos += retval;
+
+ /* Increment the number of errors */
+ ++remote_config.no_errors;
+ }
+}
+
+
+/*
+ * token_name - convert T_ token integers to text
+ * example: token_name(T_Server) returns "T_Server"
+ */
+const char *
+token_name(
+ int token
+ )
+{
+ return yytname[YYTRANSLATE(token)];
+}
+
+
+/* Initial Testing function -- ignore */
+#if 0
+int main(int argc, char *argv[])
+{
+ ip_file = FOPEN(argv[1], "r");
+ if (!ip_file)
+ fprintf(stderr, "ERROR!! Could not open file: %s\n", argv[1]);
+ yyparse();
+ return 0;
+}
+#endif
+
diff --git a/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_parser.h b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_parser.h
new file mode 100644
index 0000000..e24b3f4
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_parser.h
@@ -0,0 +1,489 @@
+/* A Bison parser, made by GNU Bison 3.0.4. */
+
+/* Bison interface for Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+#ifndef YY_YY_NTP_PARSER_H_INCLUDED
+# define YY_YY_NTP_PARSER_H_INCLUDED
+/* Debug traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 1
+#endif
+#if YYDEBUG
+extern int yydebug;
+#endif
+
+/* Token type. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ enum yytokentype
+ {
+ T_Abbrev = 258,
+ T_Age = 259,
+ T_All = 260,
+ T_Allan = 261,
+ T_Allpeers = 262,
+ T_Auth = 263,
+ T_Autokey = 264,
+ T_Automax = 265,
+ T_Average = 266,
+ T_Basedate = 267,
+ T_Bclient = 268,
+ T_Bcpollbstep = 269,
+ T_Beacon = 270,
+ T_Broadcast = 271,
+ T_Broadcastclient = 272,
+ T_Broadcastdelay = 273,
+ T_Burst = 274,
+ T_Calibrate = 275,
+ T_Ceiling = 276,
+ T_Clockstats = 277,
+ T_Cohort = 278,
+ T_ControlKey = 279,
+ T_Crypto = 280,
+ T_Cryptostats = 281,
+ T_Ctl = 282,
+ T_Day = 283,
+ T_Default = 284,
+ T_Digest = 285,
+ T_Disable = 286,
+ T_Discard = 287,
+ T_Dispersion = 288,
+ T_Double = 289,
+ T_Driftfile = 290,
+ T_Drop = 291,
+ T_Dscp = 292,
+ T_Ellipsis = 293,
+ T_Enable = 294,
+ T_End = 295,
+ T_Epeer = 296,
+ T_False = 297,
+ T_File = 298,
+ T_Filegen = 299,
+ T_Filenum = 300,
+ T_Flag1 = 301,
+ T_Flag2 = 302,
+ T_Flag3 = 303,
+ T_Flag4 = 304,
+ T_Flake = 305,
+ T_Floor = 306,
+ T_Freq = 307,
+ T_Fudge = 308,
+ T_Host = 309,
+ T_Huffpuff = 310,
+ T_Iburst = 311,
+ T_Ident = 312,
+ T_Ignore = 313,
+ T_Incalloc = 314,
+ T_Incmem = 315,
+ T_Initalloc = 316,
+ T_Initmem = 317,
+ T_Includefile = 318,
+ T_Integer = 319,
+ T_Interface = 320,
+ T_Intrange = 321,
+ T_Io = 322,
+ T_Ippeerlimit = 323,
+ T_Ipv4 = 324,
+ T_Ipv4_flag = 325,
+ T_Ipv6 = 326,
+ T_Ipv6_flag = 327,
+ T_Kernel = 328,
+ T_Key = 329,
+ T_Keys = 330,
+ T_Keysdir = 331,
+ T_Kod = 332,
+ T_Mssntp = 333,
+ T_Leapfile = 334,
+ T_Leapsmearinterval = 335,
+ T_Limited = 336,
+ T_Link = 337,
+ T_Listen = 338,
+ T_Logconfig = 339,
+ T_Logfile = 340,
+ T_Loopstats = 341,
+ T_Lowpriotrap = 342,
+ T_Manycastclient = 343,
+ T_Manycastserver = 344,
+ T_Mask = 345,
+ T_Maxage = 346,
+ T_Maxclock = 347,
+ T_Maxdepth = 348,
+ T_Maxdist = 349,
+ T_Maxmem = 350,
+ T_Maxpoll = 351,
+ T_Mdnstries = 352,
+ T_Mem = 353,
+ T_Memlock = 354,
+ T_Minclock = 355,
+ T_Mindepth = 356,
+ T_Mindist = 357,
+ T_Minimum = 358,
+ T_Minpoll = 359,
+ T_Minsane = 360,
+ T_Mode = 361,
+ T_Mode7 = 362,
+ T_Monitor = 363,
+ T_Month = 364,
+ T_Mru = 365,
+ T_Multicastclient = 366,
+ T_Nic = 367,
+ T_Nolink = 368,
+ T_Nomodify = 369,
+ T_Nomrulist = 370,
+ T_None = 371,
+ T_Nonvolatile = 372,
+ T_Noepeer = 373,
+ T_Nopeer = 374,
+ T_Noquery = 375,
+ T_Noselect = 376,
+ T_Noserve = 377,
+ T_Notrap = 378,
+ T_Notrust = 379,
+ T_Ntp = 380,
+ T_Ntpport = 381,
+ T_NtpSignDsocket = 382,
+ T_Orphan = 383,
+ T_Orphanwait = 384,
+ T_PCEdigest = 385,
+ T_Panic = 386,
+ T_Peer = 387,
+ T_Peerstats = 388,
+ T_Phone = 389,
+ T_Pid = 390,
+ T_Pidfile = 391,
+ T_Pool = 392,
+ T_Port = 393,
+ T_Preempt = 394,
+ T_Prefer = 395,
+ T_Protostats = 396,
+ T_Pw = 397,
+ T_Randfile = 398,
+ T_Rawstats = 399,
+ T_Refid = 400,
+ T_Requestkey = 401,
+ T_Reset = 402,
+ T_Restrict = 403,
+ T_Revoke = 404,
+ T_Rlimit = 405,
+ T_Saveconfigdir = 406,
+ T_Server = 407,
+ T_Setvar = 408,
+ T_Source = 409,
+ T_Stacksize = 410,
+ T_Statistics = 411,
+ T_Stats = 412,
+ T_Statsdir = 413,
+ T_Step = 414,
+ T_Stepback = 415,
+ T_Stepfwd = 416,
+ T_Stepout = 417,
+ T_Stratum = 418,
+ T_String = 419,
+ T_Sys = 420,
+ T_Sysstats = 421,
+ T_Tick = 422,
+ T_Time1 = 423,
+ T_Time2 = 424,
+ T_Timer = 425,
+ T_Timingstats = 426,
+ T_Tinker = 427,
+ T_Tos = 428,
+ T_Trap = 429,
+ T_True = 430,
+ T_Trustedkey = 431,
+ T_Ttl = 432,
+ T_Type = 433,
+ T_U_int = 434,
+ T_UEcrypto = 435,
+ T_UEcryptonak = 436,
+ T_UEdigest = 437,
+ T_Unconfig = 438,
+ T_Unpeer = 439,
+ T_Version = 440,
+ T_WanderThreshold = 441,
+ T_Week = 442,
+ T_Wildcard = 443,
+ T_Xleave = 444,
+ T_Year = 445,
+ T_Flag = 446,
+ T_EOC = 447,
+ T_Simulate = 448,
+ T_Beep_Delay = 449,
+ T_Sim_Duration = 450,
+ T_Server_Offset = 451,
+ T_Duration = 452,
+ T_Freq_Offset = 453,
+ T_Wander = 454,
+ T_Jitter = 455,
+ T_Prop_Delay = 456,
+ T_Proc_Delay = 457
+ };
+#endif
+/* Tokens. */
+#define T_Abbrev 258
+#define T_Age 259
+#define T_All 260
+#define T_Allan 261
+#define T_Allpeers 262
+#define T_Auth 263
+#define T_Autokey 264
+#define T_Automax 265
+#define T_Average 266
+#define T_Basedate 267
+#define T_Bclient 268
+#define T_Bcpollbstep 269
+#define T_Beacon 270
+#define T_Broadcast 271
+#define T_Broadcastclient 272
+#define T_Broadcastdelay 273
+#define T_Burst 274
+#define T_Calibrate 275
+#define T_Ceiling 276
+#define T_Clockstats 277
+#define T_Cohort 278
+#define T_ControlKey 279
+#define T_Crypto 280
+#define T_Cryptostats 281
+#define T_Ctl 282
+#define T_Day 283
+#define T_Default 284
+#define T_Digest 285
+#define T_Disable 286
+#define T_Discard 287
+#define T_Dispersion 288
+#define T_Double 289
+#define T_Driftfile 290
+#define T_Drop 291
+#define T_Dscp 292
+#define T_Ellipsis 293
+#define T_Enable 294
+#define T_End 295
+#define T_Epeer 296
+#define T_False 297
+#define T_File 298
+#define T_Filegen 299
+#define T_Filenum 300
+#define T_Flag1 301
+#define T_Flag2 302
+#define T_Flag3 303
+#define T_Flag4 304
+#define T_Flake 305
+#define T_Floor 306
+#define T_Freq 307
+#define T_Fudge 308
+#define T_Host 309
+#define T_Huffpuff 310
+#define T_Iburst 311
+#define T_Ident 312
+#define T_Ignore 313
+#define T_Incalloc 314
+#define T_Incmem 315
+#define T_Initalloc 316
+#define T_Initmem 317
+#define T_Includefile 318
+#define T_Integer 319
+#define T_Interface 320
+#define T_Intrange 321
+#define T_Io 322
+#define T_Ippeerlimit 323
+#define T_Ipv4 324
+#define T_Ipv4_flag 325
+#define T_Ipv6 326
+#define T_Ipv6_flag 327
+#define T_Kernel 328
+#define T_Key 329
+#define T_Keys 330
+#define T_Keysdir 331
+#define T_Kod 332
+#define T_Mssntp 333
+#define T_Leapfile 334
+#define T_Leapsmearinterval 335
+#define T_Limited 336
+#define T_Link 337
+#define T_Listen 338
+#define T_Logconfig 339
+#define T_Logfile 340
+#define T_Loopstats 341
+#define T_Lowpriotrap 342
+#define T_Manycastclient 343
+#define T_Manycastserver 344
+#define T_Mask 345
+#define T_Maxage 346
+#define T_Maxclock 347
+#define T_Maxdepth 348
+#define T_Maxdist 349
+#define T_Maxmem 350
+#define T_Maxpoll 351
+#define T_Mdnstries 352
+#define T_Mem 353
+#define T_Memlock 354
+#define T_Minclock 355
+#define T_Mindepth 356
+#define T_Mindist 357
+#define T_Minimum 358
+#define T_Minpoll 359
+#define T_Minsane 360
+#define T_Mode 361
+#define T_Mode7 362
+#define T_Monitor 363
+#define T_Month 364
+#define T_Mru 365
+#define T_Multicastclient 366
+#define T_Nic 367
+#define T_Nolink 368
+#define T_Nomodify 369
+#define T_Nomrulist 370
+#define T_None 371
+#define T_Nonvolatile 372
+#define T_Noepeer 373
+#define T_Nopeer 374
+#define T_Noquery 375
+#define T_Noselect 376
+#define T_Noserve 377
+#define T_Notrap 378
+#define T_Notrust 379
+#define T_Ntp 380
+#define T_Ntpport 381
+#define T_NtpSignDsocket 382
+#define T_Orphan 383
+#define T_Orphanwait 384
+#define T_PCEdigest 385
+#define T_Panic 386
+#define T_Peer 387
+#define T_Peerstats 388
+#define T_Phone 389
+#define T_Pid 390
+#define T_Pidfile 391
+#define T_Pool 392
+#define T_Port 393
+#define T_Preempt 394
+#define T_Prefer 395
+#define T_Protostats 396
+#define T_Pw 397
+#define T_Randfile 398
+#define T_Rawstats 399
+#define T_Refid 400
+#define T_Requestkey 401
+#define T_Reset 402
+#define T_Restrict 403
+#define T_Revoke 404
+#define T_Rlimit 405
+#define T_Saveconfigdir 406
+#define T_Server 407
+#define T_Setvar 408
+#define T_Source 409
+#define T_Stacksize 410
+#define T_Statistics 411
+#define T_Stats 412
+#define T_Statsdir 413
+#define T_Step 414
+#define T_Stepback 415
+#define T_Stepfwd 416
+#define T_Stepout 417
+#define T_Stratum 418
+#define T_String 419
+#define T_Sys 420
+#define T_Sysstats 421
+#define T_Tick 422
+#define T_Time1 423
+#define T_Time2 424
+#define T_Timer 425
+#define T_Timingstats 426
+#define T_Tinker 427
+#define T_Tos 428
+#define T_Trap 429
+#define T_True 430
+#define T_Trustedkey 431
+#define T_Ttl 432
+#define T_Type 433
+#define T_U_int 434
+#define T_UEcrypto 435
+#define T_UEcryptonak 436
+#define T_UEdigest 437
+#define T_Unconfig 438
+#define T_Unpeer 439
+#define T_Version 440
+#define T_WanderThreshold 441
+#define T_Week 442
+#define T_Wildcard 443
+#define T_Xleave 444
+#define T_Year 445
+#define T_Flag 446
+#define T_EOC 447
+#define T_Simulate 448
+#define T_Beep_Delay 449
+#define T_Sim_Duration 450
+#define T_Server_Offset 451
+#define T_Duration 452
+#define T_Freq_Offset 453
+#define T_Wander 454
+#define T_Jitter 455
+#define T_Prop_Delay 456
+#define T_Proc_Delay 457
+
+/* Value type. */
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+
+union YYSTYPE
+{
+#line 52 "ntp_parser.y" /* yacc.c:1909 */
+
+ char * String;
+ double Double;
+ int Integer;
+ unsigned U_int;
+ gen_fifo * Generic_fifo;
+ attr_val * Attr_val;
+ attr_val_fifo * Attr_val_fifo;
+ int_fifo * Int_fifo;
+ string_fifo * String_fifo;
+ address_node * Address_node;
+ address_fifo * Address_fifo;
+ setvar_node * Set_var;
+ server_info * Sim_server;
+ server_info_fifo * Sim_server_fifo;
+ script_info * Sim_script;
+ script_info_fifo * Sim_script_fifo;
+
+#line 477 "ntp_parser.h" /* yacc.c:1909 */
+};
+
+typedef union YYSTYPE YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+
+extern YYSTYPE yylval;
+
+int yyparse (void);
+
+#endif /* !YY_YY_NTP_PARSER_H_INCLUDED */
diff --git a/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_peer.c b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_peer.c
new file mode 100644
index 0000000..e2c2152
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_peer.c
@@ -0,0 +1,1119 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * ntp_peer.c - management of data maintained for peer associations
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+
+#include "ntpd.h"
+#include "ntp_lists.h"
+#include "ntp_stdlib.h"
+#include "ntp_control.h"
+#include <ntp_random.h>
+
+/*
+ * Table of valid association combinations
+ * ---------------------------------------
+ *
+ * packet->mode
+ * peer->mode | UNSPEC ACTIVE PASSIVE CLIENT SERVER BCAST
+ * ---------- | ---------------------------------------------
+ * NO_PEER | e 1 0 1 1 1
+ * ACTIVE | e 1 1 0 0 0
+ * PASSIVE | e 1 e 0 0 0
+ * CLIENT | e 0 0 0 1 0
+ * SERVER | e 0 0 0 0 0
+ * BCAST | e 0 0 0 0 0
+ * BCLIENT | e 0 0 0 e 1
+ *
+ * One point to note here: a packet in BCAST mode can potentially match
+ * a peer in CLIENT mode, but we that is a special case and we check for
+ * that early in the decision process. This avoids having to keep track
+ * of what kind of associations are possible etc... We actually
+ * circumvent that problem by requiring that the first b(m)roadcast
+ * received after the change back to BCLIENT mode sets the clock.
+ */
+#define AM_MODES 7 /* number of rows and columns */
+#define NO_PEER 0 /* action when no peer is found */
+
+int AM[AM_MODES][AM_MODES] = {
+/* packet->mode */
+/* peer { UNSPEC, ACTIVE, PASSIVE, CLIENT, SERVER, BCAST } */
+/* mode */
+/*NONE*/{ AM_ERR, AM_NEWPASS, AM_NOMATCH, AM_FXMIT, AM_MANYCAST, AM_NEWBCL},
+
+/*A*/ { AM_ERR, AM_PROCPKT, AM_PROCPKT, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH},
+
+/*P*/ { AM_ERR, AM_PROCPKT, AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH},
+
+/*C*/ { AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_PROCPKT, AM_NOMATCH},
+
+/*S*/ { AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH},
+
+/*BCST*/{ AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH},
+
+/*BCL*/ { AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_PROCPKT},
+};
+
+#define MATCH_ASSOC(x, y) AM[(x)][(y)]
+
+/*
+ * These routines manage the allocation of memory to peer structures
+ * and the maintenance of three data structures involving all peers:
+ *
+ * - peer_list is a single list with all peers, suitable for scanning
+ * operations over all peers.
+ * - peer_adr_hash is an array of lists indexed by hashed peer address.
+ * - peer_aid_hash is an array of lists indexed by hashed associd.
+ *
+ * They also maintain a free list of peer structures, peer_free.
+ *
+ * The three main entry points are findpeer(), which looks for matching
+ * peer structures in the peer list, newpeer(), which allocates a new
+ * peer structure and adds it to the list, and unpeer(), which
+ * demobilizes the association and deallocates the structure.
+ */
+/*
+ * Peer hash tables
+ */
+struct peer *peer_hash[NTP_HASH_SIZE]; /* peer hash table */
+int peer_hash_count[NTP_HASH_SIZE]; /* peers in each bucket */
+struct peer *assoc_hash[NTP_HASH_SIZE]; /* association ID hash table */
+int assoc_hash_count[NTP_HASH_SIZE];/* peers in each bucket */
+struct peer *peer_list; /* peer structures list */
+static struct peer *peer_free; /* peer structures free list */
+int peer_free_count; /* count of free structures */
+
+/*
+ * Association ID. We initialize this value randomly, then assign a new
+ * value every time an association is mobilized.
+ */
+static associd_t current_association_ID; /* association ID */
+static associd_t initial_association_ID; /* association ID */
+
+/*
+ * Memory allocation watermarks.
+ */
+#define INIT_PEER_ALLOC 8 /* static preallocation */
+#define INC_PEER_ALLOC 4 /* add N more when empty */
+
+/*
+ * Miscellaneous statistic counters which may be queried.
+ */
+u_long peer_timereset; /* time stat counters zeroed */
+u_long findpeer_calls; /* calls to findpeer */
+u_long assocpeer_calls; /* calls to findpeerbyassoc */
+u_long peer_allocations; /* allocations from free list */
+u_long peer_demobilizations; /* structs freed to free list */
+int total_peer_structs; /* peer structs */
+int peer_associations; /* mobilized associations */
+int peer_preempt; /* preemptable associations */
+static struct peer init_peer_alloc[INIT_PEER_ALLOC]; /* init alloc */
+
+static struct peer * findexistingpeer_name(const char *, u_short,
+ struct peer *, int);
+static struct peer * findexistingpeer_addr(sockaddr_u *,
+ struct peer *, int,
+ u_char, int *);
+static void free_peer(struct peer *, int);
+static void getmorepeermem(void);
+static int score(struct peer *);
+
+
+/*
+ * init_peer - initialize peer data structures and counters
+ *
+ * N.B. We use the random number routine in here. It had better be
+ * initialized prior to getting here.
+ */
+void
+init_peer(void)
+{
+ int i;
+
+ /*
+ * Initialize peer free list from static allocation.
+ */
+ for (i = COUNTOF(init_peer_alloc) - 1; i >= 0; i--)
+ LINK_SLIST(peer_free, &init_peer_alloc[i], p_link);
+ total_peer_structs = COUNTOF(init_peer_alloc);
+ peer_free_count = COUNTOF(init_peer_alloc);
+
+ /*
+ * Initialize our first association ID
+ */
+ do
+ current_association_ID = ntp_random() & ASSOCID_MAX;
+ while (!current_association_ID);
+ initial_association_ID = current_association_ID;
+}
+
+
+/*
+ * getmorepeermem - add more peer structures to the free list
+ */
+static void
+getmorepeermem(void)
+{
+ int i;
+ struct peer *peers;
+
+ peers = eallocarray(INC_PEER_ALLOC, sizeof(*peers));
+
+ for (i = INC_PEER_ALLOC - 1; i >= 0; i--)
+ LINK_SLIST(peer_free, &peers[i], p_link);
+
+ total_peer_structs += INC_PEER_ALLOC;
+ peer_free_count += INC_PEER_ALLOC;
+}
+
+
+static struct peer *
+findexistingpeer_name(
+ const char * hostname,
+ u_short hname_fam,
+ struct peer * start_peer,
+ int mode
+ )
+{
+ struct peer *p;
+
+ if (NULL == start_peer)
+ p = peer_list;
+ else
+ p = start_peer->p_link;
+ for (; p != NULL; p = p->p_link)
+ if (p->hostname != NULL
+ && (-1 == mode || p->hmode == mode)
+ && (AF_UNSPEC == hname_fam
+ || AF_UNSPEC == AF(&p->srcadr)
+ || hname_fam == AF(&p->srcadr))
+ && !strcasecmp(p->hostname, hostname))
+ break;
+ return p;
+}
+
+
+static
+struct peer *
+findexistingpeer_addr(
+ sockaddr_u * addr,
+ struct peer * start_peer,
+ int mode,
+ u_char cast_flags,
+ int * ip_count
+ )
+{
+ struct peer *peer;
+
+ DPRINTF(2, ("findexistingpeer_addr(%s, %s, %d, 0x%x, %p)\n",
+ sptoa(addr),
+ (start_peer)
+ ? sptoa(&start_peer->srcadr)
+ : "NULL",
+ mode, (u_int)cast_flags, ip_count));
+
+ /*
+ * start_peer is included so we can locate instances of the
+ * same peer through different interfaces in the hash table.
+ * Without MDF_BCLNT, a match requires the same mode and remote
+ * address. MDF_BCLNT associations start out as MODE_CLIENT
+ * if broadcastdelay is not specified, and switch to
+ * MODE_BCLIENT after estimating the one-way delay. Duplicate
+ * associations are expanded in definition to match any other
+ * MDF_BCLNT with the same srcadr (remote, unicast address).
+ */
+ if (NULL == start_peer)
+ peer = peer_hash[NTP_HASH_ADDR(addr)];
+ else
+ peer = start_peer->adr_link;
+
+ while (peer != NULL) {
+ DPRINTF(3, ("%s %s %d %d 0x%x 0x%x ", sptoa(addr),
+ sptoa(&peer->srcadr), mode, peer->hmode,
+ (u_int)cast_flags, (u_int)peer->cast_flags));
+ if (ip_count) {
+ if (SOCK_EQ(addr, &peer->srcadr)) {
+ (*ip_count)++;
+ }
+ }
+ if ((-1 == mode || peer->hmode == mode ||
+ ((MDF_BCLNT & peer->cast_flags) &&
+ (MDF_BCLNT & cast_flags))) &&
+ ADDR_PORT_EQ(addr, &peer->srcadr)) {
+ DPRINTF(3, ("found.\n"));
+ break;
+ }
+ DPRINTF(3, ("\n"));
+ peer = peer->adr_link;
+ }
+
+ return peer;
+}
+
+
+/*
+ * findexistingpeer - search by address and return a pointer to a peer.
+ */
+struct peer *
+findexistingpeer(
+ sockaddr_u * addr,
+ const char * hostname,
+ struct peer * start_peer,
+ int mode,
+ u_char cast_flags,
+ int * ip_count
+ )
+{
+ if (hostname != NULL)
+ return findexistingpeer_name(hostname, AF(addr),
+ start_peer, mode);
+ else
+ return findexistingpeer_addr(addr, start_peer, mode,
+ cast_flags, ip_count);
+}
+
+
+/*
+ * findpeer - find and return a peer match for a received datagram in
+ * the peer_hash table.
+ *
+ * [Bug 3072] To faciliate a faster reorganisation after routing changes
+ * the original code re-assigned the peer address to be the destination
+ * of the received packet and initiated another round on a mismatch.
+ * Unfortunately this leaves us wide open for a DoS attack where the
+ * attacker directs a packet with forged destination address to us --
+ * this results in a wrong interface assignment, actually creating a DoS
+ * situation.
+ *
+ * This condition would persist until the next update of the interface
+ * list, but a continued attack would put us out of business again soon
+ * enough. Authentication alone does not help here, since it does not
+ * protect the UDP layer and leaves us open for a replay attack.
+ *
+ * So we do not update the adresses and wait until the next interface
+ * list update does the right thing for us.
+ */
+struct peer *
+findpeer(
+ struct recvbuf *rbufp,
+ int pkt_mode,
+ int * action
+ )
+{
+ struct peer * p;
+ sockaddr_u * srcadr;
+ u_int hash;
+ struct pkt * pkt;
+ l_fp pkt_org;
+
+ findpeer_calls++;
+ srcadr = &rbufp->recv_srcadr;
+ hash = NTP_HASH_ADDR(srcadr);
+ for (p = peer_hash[hash]; p != NULL; p = p->adr_link) {
+
+ /* [Bug 3072] ensure interface of peer matches */
+ /* [Bug 3356] ... if NOT a broadcast peer! */
+ if (p->hmode != MODE_BCLIENT && p->dstadr != rbufp->dstadr)
+ continue;
+
+ /* ensure peer source address matches */
+ if ( ! ADDR_PORT_EQ(srcadr, &p->srcadr))
+ continue;
+
+ /* If the association matching rules determine that this
+ * is not a valid combination, then look for the next
+ * valid peer association.
+ */
+ *action = MATCH_ASSOC(p->hmode, pkt_mode);
+
+ /* A response to our manycastclient solicitation might
+ * be misassociated with an ephemeral peer already spun
+ * for the server. If the packet's org timestamp
+ * doesn't match the peer's, check if it matches the
+ * ACST prototype peer's. If so it is a redundant
+ * solicitation response, return AM_ERR to discard it.
+ * [Bug 1762]
+ */
+ if (MODE_SERVER == pkt_mode && AM_PROCPKT == *action) {
+ pkt = &rbufp->recv_pkt;
+ NTOHL_FP(&pkt->org, &pkt_org);
+ if (!L_ISEQU(&p->aorg, &pkt_org) &&
+ findmanycastpeer(rbufp))
+ *action = AM_ERR;
+ }
+
+ /* if an error was returned, exit back right here. */
+ if (*action == AM_ERR)
+ return NULL;
+
+ /* if a match is found, we stop our search. */
+ if (*action != AM_NOMATCH)
+ break;
+ }
+
+ /* If no matching association is found... */
+ if (NULL == p)
+ *action = MATCH_ASSOC(NO_PEER, pkt_mode);
+
+ return p;
+}
+
+/*
+ * findpeerbyassoc - find and return a peer using his association ID
+ */
+struct peer *
+findpeerbyassoc(
+ associd_t assoc
+ )
+{
+ struct peer *p;
+ u_int hash;
+
+ assocpeer_calls++;
+ hash = assoc & NTP_HASH_MASK;
+ for (p = assoc_hash[hash]; p != NULL; p = p->aid_link)
+ if (assoc == p->associd)
+ break;
+ return p;
+}
+
+
+/*
+ * clear_all - flush all time values for all associations
+ */
+void
+clear_all(void)
+{
+ struct peer *p;
+
+ /*
+ * This routine is called when the clock is stepped, and so all
+ * previously saved time values are untrusted.
+ */
+ for (p = peer_list; p != NULL; p = p->p_link)
+ if (!(MDF_TXONLY_MASK & p->cast_flags))
+ peer_clear(p, "STEP");
+
+ DPRINTF(1, ("clear_all: at %lu\n", current_time));
+}
+
+
+/*
+ * score_all() - determine if an association can be demobilized
+ */
+int
+score_all(
+ struct peer *peer /* peer structure pointer */
+ )
+{
+ struct peer *speer;
+ int temp, tamp;
+ int x;
+
+ /*
+ * This routine finds the minimum score for all preemptible
+ * associations and returns > 0 if the association can be
+ * demobilized.
+ */
+ tamp = score(peer);
+ temp = 100;
+ for (speer = peer_list; speer != NULL; speer = speer->p_link)
+ if (speer->flags & FLAG_PREEMPT) {
+ x = score(speer);
+ if (x < temp)
+ temp = x;
+ }
+ DPRINTF(1, ("score_all: at %lu score %d min %d\n",
+ current_time, tamp, temp));
+
+ if (tamp != temp)
+ temp = 0;
+
+ return temp;
+}
+
+
+/*
+ * score() - calculate preemption score
+ */
+static int
+score(
+ struct peer *peer /* peer structure pointer */
+ )
+{
+ int temp;
+
+ /*
+ * This routine calculates the premption score from the peer
+ * error bits and status. Increasing values are more cherished.
+ */
+ temp = 0;
+ if (!(peer->flash & TEST10))
+ temp++; /* 1 good synch and stratum */
+ if (!(peer->flash & TEST13))
+ temp++; /* 2 reachable */
+ if (!(peer->flash & TEST12))
+ temp++; /* 3 no loop */
+ if (!(peer->flash & TEST11))
+ temp++; /* 4 good distance */
+ if (peer->status >= CTL_PST_SEL_SELCAND)
+ temp++; /* 5 in the hunt */
+ if (peer->status != CTL_PST_SEL_EXCESS)
+ temp++; /* 6 not spare tire */
+ return (temp); /* selection status */
+}
+
+
+/*
+ * free_peer - internal routine to free memory referred to by a struct
+ * peer and return it to the peer free list. If unlink is
+ * nonzero, unlink from the various lists.
+ */
+static void
+free_peer(
+ struct peer * p,
+ int unlink_peer
+ )
+{
+ struct peer * unlinked;
+ int hash;
+
+ if (unlink_peer) {
+ hash = NTP_HASH_ADDR(&p->srcadr);
+ peer_hash_count[hash]--;
+
+ UNLINK_SLIST(unlinked, peer_hash[hash], p, adr_link,
+ struct peer);
+ if (NULL == unlinked) {
+ peer_hash_count[hash]++;
+ msyslog(LOG_ERR, "peer %s not in address table!",
+ stoa(&p->srcadr));
+ }
+
+ /*
+ * Remove him from the association hash as well.
+ */
+ hash = p->associd & NTP_HASH_MASK;
+ assoc_hash_count[hash]--;
+
+ UNLINK_SLIST(unlinked, assoc_hash[hash], p, aid_link,
+ struct peer);
+ if (NULL == unlinked) {
+ assoc_hash_count[hash]++;
+ msyslog(LOG_ERR,
+ "peer %s not in association ID table!",
+ stoa(&p->srcadr));
+ }
+
+ /* Remove him from the overall list. */
+ UNLINK_SLIST(unlinked, peer_list, p, p_link,
+ struct peer);
+ if (NULL == unlinked)
+ msyslog(LOG_ERR, "%s not in peer list!",
+ stoa(&p->srcadr));
+ }
+
+ if (p->hostname != NULL)
+ free(p->hostname);
+
+ if (p->ident != NULL)
+ free(p->ident);
+
+ if (p->addrs != NULL)
+ free(p->addrs); /* from copy_addrinfo_list() */
+
+ /* Add his corporeal form to peer free list */
+ ZERO(*p);
+ LINK_SLIST(peer_free, p, p_link);
+ peer_free_count++;
+}
+
+
+/*
+ * unpeer - remove peer structure from hash table and free structure
+ */
+void
+unpeer(
+ struct peer *peer
+ )
+{
+ mprintf_event(PEVNT_DEMOBIL, peer, "assoc %u", peer->associd);
+ restrict_source(&peer->srcadr, 1, 0);
+ set_peerdstadr(peer, NULL);
+ peer_demobilizations++;
+ peer_associations--;
+ if (FLAG_PREEMPT & peer->flags)
+ peer_preempt--;
+#ifdef REFCLOCK
+ /*
+ * If this peer is actually a clock, shut it down first
+ */
+ if (FLAG_REFCLOCK & peer->flags)
+ refclock_unpeer(peer);
+#endif
+
+ free_peer(peer, TRUE);
+}
+
+
+/*
+ * peer_config - configure a new association
+ */
+struct peer *
+peer_config(
+ sockaddr_u * srcadr,
+ const char * hostname,
+ endpt * dstadr,
+ int ippeerlimit,
+ u_char hmode,
+ u_char version,
+ u_char minpoll,
+ u_char maxpoll,
+ u_int flags,
+ u_int32 ttl,
+ keyid_t key,
+ const char * ident /* autokey group */
+ )
+{
+ u_char cast_flags;
+
+ /*
+ * We do a dirty little jig to figure the cast flags. This is
+ * probably not the best place to do this, at least until the
+ * configure code is rebuilt. Note only one flag can be set.
+ */
+ switch (hmode) {
+ case MODE_BROADCAST:
+ if (IS_MCAST(srcadr))
+ cast_flags = MDF_MCAST;
+ else
+ cast_flags = MDF_BCAST;
+ break;
+
+ case MODE_CLIENT:
+ if (hostname != NULL && SOCK_UNSPEC(srcadr))
+ cast_flags = MDF_POOL;
+ else if (IS_MCAST(srcadr))
+ cast_flags = MDF_ACAST;
+ else
+ cast_flags = MDF_UCAST;
+ break;
+
+ default:
+ cast_flags = MDF_UCAST;
+ }
+
+ /*
+ * Mobilize the association and initialize its variables. If
+ * emulating ntpdate, force iburst. For pool and manycastclient
+ * strip FLAG_PREEMPT as the prototype associations are not
+ * themselves preemptible, though the resulting associations
+ * are.
+ */
+ flags |= FLAG_CONFIG;
+ if (mode_ntpdate)
+ flags |= FLAG_IBURST;
+ if ((MDF_ACAST | MDF_POOL) & cast_flags)
+ flags &= ~FLAG_PREEMPT;
+ return newpeer(srcadr, hostname, dstadr, ippeerlimit, hmode, version,
+ minpoll, maxpoll, flags, cast_flags, ttl, key, ident);
+}
+
+/*
+ * setup peer dstadr field keeping it in sync with the interface
+ * structures
+ */
+void
+set_peerdstadr(
+ struct peer * p,
+ endpt * dstadr
+ )
+{
+ struct peer * unlinked;
+
+ DEBUG_INSIST(p != NULL);
+
+ if (p == NULL)
+ return;
+
+ /* check for impossible or identical assignment */
+ if (p->dstadr == dstadr)
+ return;
+
+ /*
+ * Don't accept updates to a separate multicast receive-only
+ * endpt while a BCLNT peer is running its unicast protocol.
+ */
+ if (dstadr != NULL && (FLAG_BC_VOL & p->flags) &&
+ (INT_MCASTIF & dstadr->flags) && MODE_CLIENT == p->hmode) {
+ return;
+ }
+
+ /* unlink from list if we have an address prior to assignment */
+ if (p->dstadr != NULL) {
+ p->dstadr->peercnt--;
+ UNLINK_SLIST(unlinked, p->dstadr->peers, p, ilink,
+ struct peer);
+ msyslog(LOG_INFO, "%s local addr %s -> %s",
+ stoa(&p->srcadr), latoa(p->dstadr),
+ latoa(dstadr));
+ }
+
+ p->dstadr = dstadr;
+
+ /* link to list if we have an address after assignment */
+ if (p->dstadr != NULL) {
+ LINK_SLIST(dstadr->peers, p, ilink);
+ dstadr->peercnt++;
+ }
+}
+
+/*
+ * attempt to re-rebind interface if necessary
+ */
+static void
+peer_refresh_interface(
+ struct peer *p
+ )
+{
+ endpt * niface;
+ endpt * piface;
+
+ niface = select_peerinterface(p, &p->srcadr, NULL);
+
+ DPRINTF(4, (
+ "peer_refresh_interface: %s->%s mode %d vers %d poll %d %d flags 0x%x 0x%x ttl %u key %08x: new interface: ",
+ p->dstadr == NULL ? "<null>" :
+ stoa(&p->dstadr->sin), stoa(&p->srcadr), p->hmode,
+ p->version, p->minpoll, p->maxpoll, p->flags, p->cast_flags,
+ p->ttl, p->keyid));
+ if (niface != NULL) {
+ DPRINTF(4, (
+ "fd=%d, bfd=%d, name=%.16s, flags=0x%x, ifindex=%u, sin=%s",
+ niface->fd, niface->bfd, niface->name,
+ niface->flags, niface->ifindex,
+ stoa(&niface->sin)));
+ if (niface->flags & INT_BROADCAST)
+ DPRINTF(4, (", bcast=%s",
+ stoa(&niface->bcast)));
+ DPRINTF(4, (", mask=%s\n", stoa(&niface->mask)));
+ } else {
+ DPRINTF(4, ("<NONE>\n"));
+ }
+
+ piface = p->dstadr;
+ set_peerdstadr(p, niface);
+ if (p->dstadr != NULL) {
+ /*
+ * clear crypto if we change the local address
+ */
+ if (p->dstadr != piface && !(MDF_ACAST & p->cast_flags)
+ && MODE_BROADCAST != p->pmode)
+ peer_clear(p, "XFAC");
+
+ /*
+ * Broadcast needs the socket enabled for broadcast
+ */
+ if (MDF_BCAST & p->cast_flags)
+ enable_broadcast(p->dstadr, &p->srcadr);
+
+ /*
+ * Multicast needs the socket interface enabled for
+ * multicast
+ */
+ if (MDF_MCAST & p->cast_flags)
+ enable_multicast_if(p->dstadr, &p->srcadr);
+ }
+}
+
+
+/*
+ * refresh_all_peerinterfaces - see that all interface bindings are up
+ * to date
+ */
+void
+refresh_all_peerinterfaces(void)
+{
+ struct peer *p;
+
+ /*
+ * this is called when the interface list has changed
+ * give all peers a chance to find a better interface
+ * but only if either they don't have an address already
+ * or if the one they have hasn't worked for a while.
+ */
+ for (p = peer_list; p != NULL; p = p->p_link) {
+ if (!(p->dstadr && (p->reach & 0x3))) // Bug 2849 XOR 2043
+ peer_refresh_interface(p);
+ }
+}
+
+
+/*
+ * newpeer - initialize a new peer association
+ */
+struct peer *
+newpeer(
+ sockaddr_u * srcadr,
+ const char * hostname,
+ endpt * dstadr,
+ int ippeerlimit,
+ u_char hmode,
+ u_char version,
+ u_char minpoll,
+ u_char maxpoll,
+ u_int flags,
+ u_char cast_flags,
+ u_int32 ttl,
+ keyid_t key,
+ const char * ident
+ )
+{
+ struct peer * peer;
+ u_int hash;
+ int ip_count = 0;
+
+
+ DEBUG_REQUIRE(srcadr);
+
+#ifdef AUTOKEY
+ /*
+ * If Autokey is requested but not configured, complain loudly.
+ */
+ if (!crypto_flags) {
+ if (key > NTP_MAXKEY) {
+ return (NULL);
+
+ } else if (flags & FLAG_SKEY) {
+ msyslog(LOG_ERR, "Autokey not configured");
+ return (NULL);
+ }
+ }
+#endif /* AUTOKEY */
+
+ /*
+ * For now only pool associations have a hostname.
+ */
+ INSIST(NULL == hostname || (MDF_POOL & cast_flags));
+
+ /*
+ * First search from the beginning for an association with given
+ * remote address and mode. If an interface is given, search
+ * from there to find the association which matches that
+ * destination. If the given interface is "any", track down the
+ * actual interface, because that's what gets put into the peer
+ * structure.
+ */
+ if (dstadr != NULL) {
+ peer = findexistingpeer(srcadr, hostname, NULL, hmode,
+ cast_flags, &ip_count);
+ while (peer != NULL) {
+ if ( peer->dstadr == dstadr
+ || ( (MDF_BCLNT & cast_flags)
+ && (MDF_BCLNT & peer->cast_flags)))
+ break;
+
+ if (dstadr == ANY_INTERFACE_CHOOSE(srcadr) &&
+ peer->dstadr == findinterface(srcadr))
+ break;
+
+ peer = findexistingpeer(srcadr, hostname, peer,
+ hmode, cast_flags, &ip_count);
+ }
+ } else {
+ /* no endpt address given */
+ peer = findexistingpeer(srcadr, hostname, NULL, hmode,
+ cast_flags, &ip_count);
+ }
+
+ /*
+ * If a peer is found, this would be a duplicate and we don't
+ * allow that. This avoids duplicate ephemeral (broadcast/
+ * multicast) and preemptible (manycast and pool) client
+ * associations.
+ */
+ if (peer != NULL) {
+ DPRINTF(2, ("newpeer(%s) found existing association\n",
+ (hostname)
+ ? hostname
+ : stoa(srcadr)));
+ return NULL;
+ }
+
+DPRINTF(1, ("newpeer(%s) found no existing and %d other associations\n",
+ (hostname)
+ ? hostname
+ : stoa(srcadr),
+ ip_count));
+
+ /* Check ippeerlimit wrt ip_count */
+ if (ippeerlimit > -1) {
+ if (ip_count + 1 > ippeerlimit) {
+ DPRINTF(2, ("newpeer(%s) denied - ippeerlimit %d\n",
+ (hostname)
+ ? hostname
+ : stoa(srcadr),
+ ippeerlimit));
+ return NULL;
+ }
+ } else {
+ DPRINTF(1, ("newpeer(%s) - ippeerlimit %d ignored\n",
+ (hostname)
+ ? hostname
+ : stoa(srcadr),
+ ippeerlimit));
+ }
+
+ /*
+ * Allocate a new peer structure. Some dirt here, since some of
+ * the initialization requires knowlege of our system state.
+ */
+ if (peer_free_count == 0)
+ getmorepeermem();
+ UNLINK_HEAD_SLIST(peer, peer_free, p_link);
+ INSIST(peer != NULL);
+ peer_free_count--;
+ peer_associations++;
+ if (FLAG_PREEMPT & flags)
+ peer_preempt++;
+
+ /*
+ * Assign an association ID and increment the system variable.
+ */
+ peer->associd = current_association_ID;
+ if (++current_association_ID == 0)
+ ++current_association_ID;
+
+ peer->srcadr = *srcadr;
+ if (hostname != NULL)
+ peer->hostname = estrdup(hostname);
+ peer->hmode = hmode;
+ peer->version = version;
+ peer->flags = flags;
+ peer->cast_flags = cast_flags;
+ set_peerdstadr(peer,
+ select_peerinterface(peer, srcadr, dstadr));
+
+ /*
+ * It is an error to set minpoll less than NTP_MINPOLL or to
+ * set maxpoll greater than NTP_MAXPOLL. However, minpoll is
+ * clamped not greater than NTP_MAXPOLL and maxpoll is clamped
+ * not less than NTP_MINPOLL without complaint. Finally,
+ * minpoll is clamped not greater than maxpoll.
+ */
+ if (minpoll == 0)
+ peer->minpoll = NTP_MINDPOLL;
+ else
+ peer->minpoll = min(minpoll, NTP_MAXPOLL);
+ if (maxpoll == 0)
+ peer->maxpoll = NTP_MAXDPOLL;
+ else
+ peer->maxpoll = max(maxpoll, NTP_MINPOLL);
+ if (peer->minpoll > peer->maxpoll)
+ peer->minpoll = peer->maxpoll;
+
+ if (peer->dstadr != NULL)
+ DPRINTF(3, ("newpeer(%s): using fd %d and our addr %s\n",
+ stoa(srcadr), peer->dstadr->fd,
+ stoa(&peer->dstadr->sin)));
+ else
+ DPRINTF(3, ("newpeer(%s): local interface currently not bound\n",
+ stoa(srcadr)));
+
+ /*
+ * Broadcast needs the socket enabled for broadcast
+ */
+ if ((MDF_BCAST & cast_flags) && peer->dstadr != NULL)
+ enable_broadcast(peer->dstadr, srcadr);
+
+ /*
+ * Multicast needs the socket interface enabled for multicast
+ */
+ if ((MDF_MCAST & cast_flags) && peer->dstadr != NULL)
+ enable_multicast_if(peer->dstadr, srcadr);
+
+#ifdef AUTOKEY
+ if (key > NTP_MAXKEY)
+ peer->flags |= FLAG_SKEY;
+#endif /* AUTOKEY */
+ peer->ttl = ttl;
+ peer->keyid = key;
+ if (ident != NULL)
+ peer->ident = estrdup(ident);
+ peer->precision = sys_precision;
+ peer->hpoll = peer->minpoll;
+ if (cast_flags & MDF_ACAST)
+ peer_clear(peer, "ACST");
+ else if (cast_flags & MDF_POOL)
+ peer_clear(peer, "POOL");
+ else if (cast_flags & MDF_MCAST)
+ peer_clear(peer, "MCST");
+ else if (cast_flags & MDF_BCAST)
+ peer_clear(peer, "BCST");
+ else
+ peer_clear(peer, "INIT");
+ if (mode_ntpdate)
+ peer_ntpdate++;
+
+ /*
+ * Note time on statistics timers.
+ */
+ peer->timereset = current_time;
+ peer->timereachable = current_time;
+ peer->timereceived = current_time;
+
+ if (ISREFCLOCKADR(&peer->srcadr)) {
+#ifdef REFCLOCK
+ /*
+ * We let the reference clock support do clock
+ * dependent initialization. This includes setting
+ * the peer timer, since the clock may have requirements
+ * for this.
+ */
+ if (maxpoll == 0)
+ peer->maxpoll = peer->minpoll;
+ if (!refclock_newpeer(peer)) {
+ /*
+ * Dump it, something screwed up
+ */
+ set_peerdstadr(peer, NULL);
+ free_peer(peer, 0);
+ return NULL;
+ }
+#else /* REFCLOCK */
+ msyslog(LOG_ERR, "refclock %s isn't supported. ntpd was compiled without refclock support.",
+ stoa(&peer->srcadr));
+ set_peerdstadr(peer, NULL);
+ free_peer(peer, 0);
+ return NULL;
+#endif /* REFCLOCK */
+ }
+
+ /*
+ * Put the new peer in the hash tables.
+ */
+ hash = NTP_HASH_ADDR(&peer->srcadr);
+ LINK_SLIST(peer_hash[hash], peer, adr_link);
+ peer_hash_count[hash]++;
+ hash = peer->associd & NTP_HASH_MASK;
+ LINK_SLIST(assoc_hash[hash], peer, aid_link);
+ assoc_hash_count[hash]++;
+ LINK_SLIST(peer_list, peer, p_link);
+
+ restrict_source(&peer->srcadr, 0, 0);
+ mprintf_event(PEVNT_MOBIL, peer, "assoc %d", peer->associd);
+ DPRINTF(1, ("newpeer: %s->%s mode %u vers %u poll %u %u flags 0x%x 0x%x ttl %u key %08x\n",
+ latoa(peer->dstadr), stoa(&peer->srcadr), peer->hmode,
+ peer->version, peer->minpoll, peer->maxpoll, peer->flags,
+ peer->cast_flags, peer->ttl, peer->keyid));
+ return peer;
+}
+
+
+/*
+ * peer_clr_stats - clear peer module statistics counters
+ */
+void
+peer_clr_stats(void)
+{
+ findpeer_calls = 0;
+ assocpeer_calls = 0;
+ peer_allocations = 0;
+ peer_demobilizations = 0;
+ peer_timereset = current_time;
+}
+
+
+/*
+ * peer_reset - reset statistics counters
+ */
+void
+peer_reset(
+ struct peer *peer
+ )
+{
+ if (peer == NULL)
+ return;
+
+ peer->timereset = current_time;
+ peer->sent = 0;
+ peer->received = 0;
+ peer->processed = 0;
+ peer->badauth = 0;
+ peer->bogusorg = 0;
+ peer->oldpkt = 0;
+ peer->seldisptoolarge = 0;
+ peer->selbroken = 0;
+}
+
+
+/*
+ * peer_all_reset - reset all peer statistics counters
+ */
+void
+peer_all_reset(void)
+{
+ struct peer *peer;
+
+ for (peer = peer_list; peer != NULL; peer = peer->p_link)
+ peer_reset(peer);
+}
+
+
+/*
+ * findmanycastpeer - find and return a manycastclient or pool
+ * association matching a received response.
+ */
+struct peer *
+findmanycastpeer(
+ struct recvbuf *rbufp /* receive buffer pointer */
+ )
+{
+ struct peer *peer;
+ struct pkt *pkt;
+ l_fp p_org;
+
+ /*
+ * This routine is called upon arrival of a server-mode response
+ * to a manycastclient multicast solicitation, or to a pool
+ * server unicast solicitation. Search the peer list for a
+ * manycastclient association where the last transmit timestamp
+ * matches the response packet's originate timestamp. There can
+ * be multiple manycastclient associations, or multiple pool
+ * solicitation assocations, so this assumes the transmit
+ * timestamps are unique for such.
+ */
+ pkt = &rbufp->recv_pkt;
+ for (peer = peer_list; peer != NULL; peer = peer->p_link)
+ if (MDF_SOLICIT_MASK & peer->cast_flags) {
+ NTOHL_FP(&pkt->org, &p_org);
+ if (L_ISEQU(&p_org, &peer->aorg))
+ break;
+ }
+
+ return peer;
+}
+
+/* peer_cleanup - clean peer list prior to shutdown */
+void peer_cleanup(void)
+{
+ struct peer *peer;
+ associd_t assoc;
+
+ for (assoc = initial_association_ID; assoc != current_association_ID; assoc++) {
+ if (assoc != 0U) {
+ peer = findpeerbyassoc(assoc);
+ if (peer != NULL)
+ unpeer(peer);
+ }
+ }
+ peer = findpeerbyassoc(current_association_ID);
+ if (peer != NULL)
+ unpeer(peer);
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_proto.c b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_proto.c
new file mode 100644
index 0000000..e4312db
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_proto.c
@@ -0,0 +1,5219 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * ntp_proto.c - NTP version 4 protocol machinery
+ *
+ * ATTENTION: Get approval from Harlan on all changes to this file!
+ * (Harlan will be discussing these changes with Dave Mills.)
+ *
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "ntpd.h"
+#include "ntp_stdlib.h"
+#include "ntp_unixtime.h"
+#include "ntp_control.h"
+#include "ntp_string.h"
+#include "ntp_leapsec.h"
+#include "refidsmear.h"
+#include "lib_strbuf.h"
+
+#include <stdio.h>
+#ifdef HAVE_LIBSCF_H
+#include <libscf.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+/* [Bug 3031] define automatic broadcastdelay cutoff preset */
+#ifndef BDELAY_DEFAULT
+# define BDELAY_DEFAULT (-0.050)
+#endif
+
+/*
+ * This macro defines the authentication state. If x is 1 authentication
+ * is required; otherwise it is optional.
+ */
+#define AUTH(x, y) ((x) ? (y) == AUTH_OK \
+ : (y) == AUTH_OK || (y) == AUTH_NONE)
+
+typedef enum
+auth_state {
+ AUTH_UNKNOWN = -1, /* Unknown */
+ AUTH_NONE, /* authentication not required */
+ AUTH_OK, /* authentication OK */
+ AUTH_ERROR, /* authentication error */
+ AUTH_CRYPTO /* crypto_NAK */
+} auth_code;
+
+/*
+ * Set up Kiss Code values
+ */
+
+typedef enum
+kiss_codes {
+ NOKISS, /* No Kiss Code */
+ RATEKISS, /* Rate limit Kiss Code */
+ DENYKISS, /* Deny Kiss */
+ RSTRKISS, /* Restricted Kiss */
+ XKISS /* Experimental Kiss */
+} kiss_code;
+
+typedef enum
+nak_error_codes {
+ NONAK, /* No NAK seen */
+ INVALIDNAK, /* NAK cannot be used */
+ VALIDNAK /* NAK is valid */
+} nak_code;
+
+/*
+ * traffic shaping parameters
+ */
+#define NTP_IBURST 6 /* packets in iburst */
+#define RESP_DELAY 1 /* refclock burst delay (s) */
+
+/*
+ * pool soliciting restriction duration (s)
+ */
+#define POOL_SOLICIT_WINDOW 8
+
+/*
+ * peer_select groups statistics for a peer used by clock_select() and
+ * clock_cluster().
+ */
+typedef struct peer_select_tag {
+ struct peer * peer;
+ double synch; /* sync distance */
+ double error; /* jitter */
+ double seljit; /* selection jitter */
+} peer_select;
+
+/*
+ * System variables are declared here. Unless specified otherwise, all
+ * times are in seconds.
+ */
+u_char sys_leap; /* system leap indicator, use set_sys_leap() to change this */
+u_char xmt_leap; /* leap indicator sent in client requests, set up by set_sys_leap() */
+u_char sys_stratum; /* system stratum */
+s_char sys_precision; /* local clock precision (log2 s) */
+double sys_rootdelay; /* roundtrip delay to primary source */
+double sys_rootdisp; /* dispersion to primary source */
+u_int32 sys_refid; /* reference id (network byte order) */
+l_fp sys_reftime; /* last update time */
+struct peer *sys_peer; /* current peer */
+
+#ifdef LEAP_SMEAR
+struct leap_smear_info leap_smear;
+#endif
+int leap_sec_in_progress;
+
+/*
+ * Rate controls. Leaky buckets are used to throttle the packet
+ * transmission rates in order to protect busy servers such as at NIST
+ * and USNO. There is a counter for each association and another for KoD
+ * packets. The association counter decrements each second, but not
+ * below zero. Each time a packet is sent the counter is incremented by
+ * a configurable value representing the average interval between
+ * packets. A packet is delayed as long as the counter is greater than
+ * zero. Note this does not affect the time value computations.
+ */
+/*
+ * Nonspecified system state variables
+ */
+int sys_bclient; /* broadcast client enable */
+double sys_bdelay; /* broadcast client default delay */
+int sys_authenticate; /* requre authentication for config */
+l_fp sys_authdelay; /* authentication delay */
+double sys_offset; /* current local clock offset */
+double sys_mindisp = MINDISPERSE; /* minimum distance (s) */
+double sys_maxdist = MAXDISTANCE; /* selection threshold */
+double sys_jitter; /* system jitter */
+u_long sys_epoch; /* last clock update time */
+static double sys_clockhop; /* clockhop threshold */
+static int leap_vote_ins; /* leap consensus for insert */
+static int leap_vote_del; /* leap consensus for delete */
+keyid_t sys_private; /* private value for session seed */
+int sys_manycastserver; /* respond to manycast client pkts */
+int ntp_mode7; /* respond to ntpdc (mode7) */
+int peer_ntpdate; /* active peers in ntpdate mode */
+int sys_survivors; /* truest of the truechimers */
+char *sys_ident = NULL; /* identity scheme */
+
+/*
+ * TOS and multicast mapping stuff
+ */
+int sys_floor = 0; /* cluster stratum floor */
+u_char sys_bcpollbstep = 0; /* Broadcast Poll backstep gate */
+int sys_ceiling = STRATUM_UNSPEC - 1; /* cluster stratum ceiling */
+int sys_minsane = 1; /* minimum candidates */
+int sys_minclock = NTP_MINCLOCK; /* minimum candidates */
+int sys_maxclock = NTP_MAXCLOCK; /* maximum candidates */
+int sys_cohort = 0; /* cohort switch */
+int sys_orphan = STRATUM_UNSPEC + 1; /* orphan stratum */
+int sys_orphwait = NTP_ORPHWAIT; /* orphan wait */
+int sys_beacon = BEACON; /* manycast beacon interval */
+u_int sys_ttlmax; /* max ttl mapping vector index */
+u_char sys_ttl[MAX_TTL]; /* ttl mapping vector */
+
+/*
+ * Statistics counters - first the good, then the bad
+ */
+u_long sys_stattime; /* elapsed time */
+u_long sys_received; /* packets received */
+u_long sys_processed; /* packets for this host */
+u_long sys_newversion; /* current version */
+u_long sys_oldversion; /* old version */
+u_long sys_restricted; /* access denied */
+u_long sys_badlength; /* bad length or format */
+u_long sys_badauth; /* bad authentication */
+u_long sys_declined; /* declined */
+u_long sys_limitrejected; /* rate exceeded */
+u_long sys_kodsent; /* KoD sent */
+
+/*
+ * Mechanism knobs: how soon do we peer_clear() or unpeer()?
+ *
+ * The default way is "on-receipt". If this was a packet from a
+ * well-behaved source, on-receipt will offer the fastest recovery.
+ * If this was from a DoS attack, the default way makes it easier
+ * for a bad-guy to DoS us. So look and see what bites you harder
+ * and choose according to your environment.
+ */
+int peer_clear_digest_early = 1; /* bad digest (TEST5) and Autokey */
+int unpeer_crypto_early = 1; /* bad crypto (TEST9) */
+int unpeer_crypto_nak_early = 1; /* crypto_NAK (TEST5) */
+int unpeer_digest_early = 1; /* bad digest (TEST5) */
+
+int dynamic_interleave = DYNAMIC_INTERLEAVE; /* Bug 2978 mitigation */
+
+int kiss_code_check(u_char hisleap, u_char hisstratum, u_char hismode, u_int32 refid);
+nak_code valid_NAK (struct peer *peer, struct recvbuf *rbufp, u_char hismode);
+static double root_distance (struct peer *);
+static void clock_combine (peer_select *, int, int);
+static void peer_xmit (struct peer *);
+static void fast_xmit (struct recvbuf *, int, keyid_t, int);
+static void pool_xmit (struct peer *);
+static void clock_update (struct peer *);
+static void measure_precision(void);
+static double measure_tick_fuzz(void);
+static int local_refid (struct peer *);
+static int peer_unfit (struct peer *);
+#ifdef AUTOKEY
+static int group_test (char *, char *);
+#endif /* AUTOKEY */
+#ifdef WORKER
+void pool_name_resolved (int, int, void *, const char *,
+ const char *, const struct addrinfo *,
+ const struct addrinfo *);
+#endif /* WORKER */
+
+const char * amtoa (int am);
+
+
+void
+set_sys_leap(
+ u_char new_sys_leap
+ )
+{
+ sys_leap = new_sys_leap;
+ xmt_leap = sys_leap;
+
+ /*
+ * Under certain conditions we send faked leap bits to clients, so
+ * eventually change xmt_leap below, but never change LEAP_NOTINSYNC.
+ */
+ if (xmt_leap != LEAP_NOTINSYNC) {
+ if (leap_sec_in_progress) {
+ /* always send "not sync" */
+ xmt_leap = LEAP_NOTINSYNC;
+ }
+#ifdef LEAP_SMEAR
+ else {
+ /*
+ * If leap smear is enabled in general we must
+ * never send a leap second warning to clients,
+ * so make sure we only send "in sync".
+ */
+ if (leap_smear.enabled)
+ xmt_leap = LEAP_NOWARNING;
+ }
+#endif /* LEAP_SMEAR */
+ }
+}
+
+
+/*
+ * Kiss Code check
+ */
+int
+kiss_code_check(
+ u_char hisleap,
+ u_char hisstratum,
+ u_char hismode,
+ u_int32 refid
+ )
+{
+
+ if ( hismode == MODE_SERVER
+ && hisleap == LEAP_NOTINSYNC
+ && hisstratum == STRATUM_UNSPEC) {
+ if(memcmp(&refid,"RATE", 4) == 0) {
+ return (RATEKISS);
+ } else if(memcmp(&refid,"DENY", 4) == 0) {
+ return (DENYKISS);
+ } else if(memcmp(&refid,"RSTR", 4) == 0) {
+ return (RSTRKISS);
+ } else if(memcmp(&refid,"X", 1) == 0) {
+ return (XKISS);
+ }
+ }
+ return (NOKISS);
+}
+
+
+/*
+ * Check that NAK is valid
+ */
+nak_code
+valid_NAK(
+ struct peer *peer,
+ struct recvbuf *rbufp,
+ u_char hismode
+ )
+{
+ int base_packet_length = MIN_V4_PKT_LEN;
+ int remainder_size;
+ struct pkt * rpkt;
+ int keyid;
+ l_fp p_org; /* origin timestamp */
+ const l_fp * myorg; /* selected peer origin */
+
+ /*
+ * Check to see if there is something beyond the basic packet
+ */
+ if (rbufp->recv_length == base_packet_length) {
+ return NONAK;
+ }
+
+ remainder_size = rbufp->recv_length - base_packet_length;
+ /*
+ * Is this a potential NAK?
+ */
+ if (remainder_size != 4) {
+ return NONAK;
+ }
+
+ /*
+ * Only server responses can contain NAK's
+ */
+
+ if (hismode != MODE_SERVER &&
+ hismode != MODE_ACTIVE &&
+ hismode != MODE_PASSIVE
+ ) {
+ return INVALIDNAK;
+ }
+
+ /*
+ * Make sure that the extra field in the packet is all zeros
+ */
+ rpkt = &rbufp->recv_pkt;
+ keyid = ntohl(((u_int32 *)rpkt)[base_packet_length / 4]);
+ if (keyid != 0) {
+ return INVALIDNAK;
+ }
+
+ /*
+ * During the first few packets of the autokey dance there will
+ * not (yet) be a keyid, but in this case FLAG_SKEY is set.
+ * So the NAK is invalid if either there's no peer, or
+ * if the keyid is 0 and FLAG_SKEY is not set.
+ */
+ if (!peer || (!peer->keyid && !(peer->flags & FLAG_SKEY))) {
+ return INVALIDNAK;
+ }
+
+ /*
+ * The ORIGIN must match, or this cannot be a valid NAK, either.
+ */
+ NTOHL_FP(&rpkt->org, &p_org);
+ if (peer->flip > 0)
+ myorg = &peer->borg;
+ else
+ myorg = &peer->aorg;
+
+ if (L_ISZERO(&p_org) ||
+ L_ISZERO( myorg) ||
+ !L_ISEQU(&p_org, myorg)) {
+ return INVALIDNAK;
+ }
+
+ /* If we ever passed all that checks, we should be safe. Well,
+ * as safe as we can ever be with an unauthenticated crypto-nak.
+ */
+ return VALIDNAK;
+}
+
+
+/*
+ * transmit - transmit procedure called by poll timeout
+ */
+void
+transmit(
+ struct peer *peer /* peer structure pointer */
+ )
+{
+ u_char hpoll;
+
+ /*
+ * The polling state machine. There are two kinds of machines,
+ * those that never expect a reply (broadcast and manycast
+ * server modes) and those that do (all other modes). The dance
+ * is intricate...
+ */
+ hpoll = peer->hpoll;
+
+ /*
+ * If we haven't received anything (even if unsync) since last
+ * send, reset ppoll.
+ */
+ if (peer->outdate > peer->timelastrec && !peer->reach)
+ peer->ppoll = peer->maxpoll;
+
+ /*
+ * In broadcast mode the poll interval is never changed from
+ * minpoll.
+ */
+ if (peer->cast_flags & (MDF_BCAST | MDF_MCAST)) {
+ peer->outdate = current_time;
+ poll_update(peer, hpoll);
+ if (sys_leap != LEAP_NOTINSYNC)
+ peer_xmit(peer);
+ return;
+ }
+
+ /*
+ * In manycast mode we start with unity ttl. The ttl is
+ * increased by one for each poll until either sys_maxclock
+ * servers have been found or the maximum ttl is reached. When
+ * sys_maxclock servers are found we stop polling until one or
+ * more servers have timed out or until less than sys_minclock
+ * associations turn up. In this case additional better servers
+ * are dragged in and preempt the existing ones. Once every
+ * sys_beacon seconds we are to transmit unconditionally, but
+ * this code is not quite right -- peer->unreach counts polls
+ * and is being compared with sys_beacon, so the beacons happen
+ * every sys_beacon polls.
+ */
+ if (peer->cast_flags & MDF_ACAST) {
+ peer->outdate = current_time;
+ poll_update(peer, hpoll);
+ if (peer->unreach > sys_beacon) {
+ peer->unreach = 0;
+ peer->ttl = 0;
+ peer_xmit(peer);
+ } else if ( sys_survivors < sys_minclock
+ || peer_associations < sys_maxclock) {
+ if (peer->ttl < sys_ttlmax)
+ peer->ttl++;
+ peer_xmit(peer);
+ }
+ peer->unreach++;
+ return;
+ }
+
+ /*
+ * Pool associations transmit unicast solicitations when there
+ * are less than a hard limit of 2 * sys_maxclock associations,
+ * and either less than sys_minclock survivors or less than
+ * sys_maxclock associations. The hard limit prevents unbounded
+ * growth in associations if the system clock or network quality
+ * result in survivor count dipping below sys_minclock often.
+ * This was observed testing with pool, where sys_maxclock == 12
+ * resulted in 60 associations without the hard limit. A
+ * similar hard limit on manycastclient ephemeral associations
+ * may be appropriate.
+ */
+ if (peer->cast_flags & MDF_POOL) {
+ peer->outdate = current_time;
+ poll_update(peer, hpoll);
+ if ( (peer_associations <= 2 * sys_maxclock)
+ && ( peer_associations < sys_maxclock
+ || sys_survivors < sys_minclock))
+ pool_xmit(peer);
+ return;
+ }
+
+ /*
+ * In unicast modes the dance is much more intricate. It is
+ * designed to back off whenever possible to minimize network
+ * traffic.
+ */
+ if (peer->burst == 0) {
+ u_char oreach;
+
+ /*
+ * Update the reachability status. If not heard for
+ * three consecutive polls, stuff infinity in the clock
+ * filter.
+ */
+ oreach = peer->reach;
+ peer->outdate = current_time;
+ peer->unreach++;
+ peer->reach <<= 1;
+ if (!peer->reach) {
+
+ /*
+ * Here the peer is unreachable. If it was
+ * previously reachable raise a trap. Send a
+ * burst if enabled.
+ */
+ clock_filter(peer, 0., 0., MAXDISPERSE);
+ if (oreach) {
+ peer_unfit(peer);
+ report_event(PEVNT_UNREACH, peer, NULL);
+ }
+ if ( (peer->flags & FLAG_IBURST)
+ && peer->retry == 0)
+ peer->retry = NTP_RETRY;
+ } else {
+
+ /*
+ * Here the peer is reachable. Send a burst if
+ * enabled and the peer is fit. Reset unreach
+ * for persistent and ephemeral associations.
+ * Unreach is also reset for survivors in
+ * clock_select().
+ */
+ hpoll = sys_poll;
+ if (!(peer->flags & FLAG_PREEMPT))
+ peer->unreach = 0;
+ if ( (peer->flags & FLAG_BURST)
+ && peer->retry == 0
+ && !peer_unfit(peer))
+ peer->retry = NTP_RETRY;
+ }
+
+ /*
+ * Watch for timeout. If ephemeral, toss the rascal;
+ * otherwise, bump the poll interval. Note the
+ * poll_update() routine will clamp it to maxpoll.
+ * If preemptible and we have more peers than maxclock,
+ * and this peer has the minimum score of preemptibles,
+ * demobilize.
+ */
+ if (peer->unreach >= NTP_UNREACH) {
+ hpoll++;
+ /* ephemeral: no FLAG_CONFIG nor FLAG_PREEMPT */
+ if (!(peer->flags & (FLAG_CONFIG | FLAG_PREEMPT))) {
+ report_event(PEVNT_RESTART, peer, "timeout");
+ peer_clear(peer, "TIME");
+ unpeer(peer);
+ return;
+ }
+ if ( (peer->flags & FLAG_PREEMPT)
+ && (peer_associations > sys_maxclock)
+ && score_all(peer)) {
+ report_event(PEVNT_RESTART, peer, "timeout");
+ peer_clear(peer, "TIME");
+ unpeer(peer);
+ return;
+ }
+ }
+ } else {
+ peer->burst--;
+ if (peer->burst == 0) {
+
+ /*
+ * If ntpdate mode and the clock has not been
+ * set and all peers have completed the burst,
+ * we declare a successful failure.
+ */
+ if (mode_ntpdate) {
+ peer_ntpdate--;
+ if (peer_ntpdate == 0) {
+ msyslog(LOG_NOTICE,
+ "ntpd: no servers found");
+ if (!msyslog_term)
+ printf(
+ "ntpd: no servers found\n");
+ exit (0);
+ }
+ }
+ }
+ }
+ if (peer->retry > 0)
+ peer->retry--;
+
+ /*
+ * Do not transmit if in broadcast client mode.
+ */
+ poll_update(peer, hpoll);
+ if (peer->hmode != MODE_BCLIENT)
+ peer_xmit(peer);
+
+ return;
+}
+
+
+const char *
+amtoa(
+ int am
+ )
+{
+ char *bp;
+
+ switch(am) {
+ case AM_ERR: return "AM_ERR";
+ case AM_NOMATCH: return "AM_NOMATCH";
+ case AM_PROCPKT: return "AM_PROCPKT";
+ case AM_BCST: return "AM_BCST";
+ case AM_FXMIT: return "AM_FXMIT";
+ case AM_MANYCAST: return "AM_MANYCAST";
+ case AM_NEWPASS: return "AM_NEWPASS";
+ case AM_NEWBCL: return "AM_NEWBCL";
+ case AM_POSSBCL: return "AM_POSSBCL";
+ default:
+ LIB_GETBUF(bp);
+ snprintf(bp, LIB_BUFLENGTH, "AM_#%d", am);
+ return bp;
+ }
+}
+
+
+/*
+ * receive - receive procedure called for each packet received
+ */
+void
+receive(
+ struct recvbuf *rbufp
+ )
+{
+ register struct peer *peer; /* peer structure pointer */
+ register struct pkt *pkt; /* receive packet pointer */
+ u_char hisversion; /* packet version */
+ u_char hisleap; /* packet leap indicator */
+ u_char hismode; /* packet mode */
+ u_char hisstratum; /* packet stratum */
+ r4addr r4a; /* address restrictions */
+ u_short restrict_mask; /* restrict bits */
+ const char *hm_str; /* hismode string */
+ const char *am_str; /* association match string */
+ int kissCode = NOKISS; /* Kiss Code */
+ int has_mac; /* length of MAC field */
+ int authlen; /* offset of MAC field */
+ auth_code is_authentic = AUTH_UNKNOWN; /* Was AUTH_NONE */
+ nak_code crypto_nak_test; /* result of crypto-NAK check */
+ int retcode = AM_NOMATCH; /* match code */
+ keyid_t skeyid = 0; /* key IDs */
+ u_int32 opcode = 0; /* extension field opcode */
+ sockaddr_u *dstadr_sin; /* active runway */
+ struct peer *peer2; /* aux peer structure pointer */
+ endpt *match_ep; /* newpeer() local address */
+ l_fp p_org; /* origin timestamp */
+ l_fp p_rec; /* receive timestamp */
+ l_fp p_xmt; /* transmit timestamp */
+#ifdef AUTOKEY
+ char hostname[NTP_MAXSTRLEN + 1];
+ char *groupname = NULL;
+ struct autokey *ap; /* autokey structure pointer */
+ int rval; /* cookie snatcher */
+ keyid_t pkeyid = 0, tkeyid = 0; /* key IDs */
+#endif /* AUTOKEY */
+#ifdef HAVE_NTP_SIGND
+ static unsigned char zero_key[16];
+#endif /* HAVE_NTP_SIGND */
+
+ /*
+ * Note that there are many places we do not call record_raw_stats().
+ *
+ * We only want to call it *after* we've sent a response, or perhaps
+ * when we've decided to drop a packet.
+ */
+
+ /*
+ * Monitor the packet and get restrictions. Note that the packet
+ * length for control and private mode packets must be checked
+ * by the service routines. Some restrictions have to be handled
+ * later in order to generate a kiss-o'-death packet.
+ */
+ /*
+ * Bogus port check is before anything, since it probably
+ * reveals a clogging attack.
+ */
+ sys_received++;
+ if (0 == SRCPORT(&rbufp->recv_srcadr)) {
+ sys_badlength++;
+ return; /* bogus port */
+ }
+ restrictions(&rbufp->recv_srcadr, &r4a);
+ restrict_mask = r4a.rflags;
+
+ pkt = &rbufp->recv_pkt;
+ hisversion = PKT_VERSION(pkt->li_vn_mode);
+ hisleap = PKT_LEAP(pkt->li_vn_mode);
+ hismode = (int)PKT_MODE(pkt->li_vn_mode);
+ hisstratum = PKT_TO_STRATUM(pkt->stratum);
+ DPRINTF(1, ("receive: at %ld %s<-%s ippeerlimit %d mode %d iflags %s restrict %s org %#010x.%08x xmt %#010x.%08x\n",
+ current_time, stoa(&rbufp->dstadr->sin),
+ stoa(&rbufp->recv_srcadr), r4a.ippeerlimit, hismode,
+ build_iflags(rbufp->dstadr->flags),
+ build_rflags(restrict_mask),
+ ntohl(pkt->org.l_ui), ntohl(pkt->org.l_uf),
+ ntohl(pkt->xmt.l_ui), ntohl(pkt->xmt.l_uf)));
+
+ /* See basic mode and broadcast checks, below */
+ INSIST(0 != hisstratum);
+
+ if (restrict_mask & RES_IGNORE) {
+ DPRINTF(2, ("receive: drop: RES_IGNORE\n"));
+ sys_restricted++;
+ return; /* ignore everything */
+ }
+ if (hismode == MODE_PRIVATE) {
+ if (!ntp_mode7 || (restrict_mask & RES_NOQUERY)) {
+ DPRINTF(2, ("receive: drop: RES_NOQUERY\n"));
+ sys_restricted++;
+ return; /* no query private */
+ }
+ process_private(rbufp, ((restrict_mask &
+ RES_NOMODIFY) == 0));
+ return;
+ }
+ if (hismode == MODE_CONTROL) {
+ if (restrict_mask & RES_NOQUERY) {
+ DPRINTF(2, ("receive: drop: RES_NOQUERY\n"));
+ sys_restricted++;
+ return; /* no query control */
+ }
+ process_control(rbufp, restrict_mask);
+ return;
+ }
+ if (restrict_mask & RES_DONTSERVE) {
+ DPRINTF(2, ("receive: drop: RES_DONTSERVE\n"));
+ sys_restricted++;
+ return; /* no time serve */
+ }
+
+ /*
+ * This is for testing. If restricted drop ten percent of
+ * surviving packets.
+ */
+ if (restrict_mask & RES_FLAKE) {
+ if ((double)ntp_random() / 0x7fffffff < .1) {
+ DPRINTF(2, ("receive: drop: RES_FLAKE\n"));
+ sys_restricted++;
+ return; /* no flakeway */
+ }
+ }
+
+ /*
+ ** Format Layer Checks
+ **
+ ** Validate the packet format. The packet size, packet header,
+ ** and any extension field lengths are checked. We identify
+ ** the beginning of the MAC, to identify the upper limit of
+ ** of the hash computation.
+ **
+ ** In case of a format layer check violation, the packet is
+ ** discarded with no further processing.
+ */
+
+ /*
+ * Version check must be after the query packets, since they
+ * intentionally use an early version.
+ */
+ if (hisversion == NTP_VERSION) {
+ sys_newversion++; /* new version */
+ } else if ( !(restrict_mask & RES_VERSION)
+ && hisversion >= NTP_OLDVERSION) {
+ sys_oldversion++; /* previous version */
+ } else {
+ DPRINTF(2, ("receive: drop: RES_VERSION\n"));
+ sys_badlength++;
+ return; /* old version */
+ }
+
+ /*
+ * Figure out his mode and validate the packet. This has some
+ * legacy raunch that probably should be removed. In very early
+ * NTP versions mode 0 was equivalent to what later versions
+ * would interpret as client mode.
+ */
+ if (hismode == MODE_UNSPEC) {
+ if (hisversion == NTP_OLDVERSION) {
+ hismode = MODE_CLIENT;
+ } else {
+ DPRINTF(2, ("receive: drop: MODE_UNSPEC\n"));
+ sys_badlength++;
+ return; /* invalid mode */
+ }
+ }
+
+ /*
+ * Parse the extension field if present. We figure out whether
+ * an extension field is present by measuring the MAC size. If
+ * the number of words following the packet header is 0, no MAC
+ * is present and the packet is not authenticated. If 1, the
+ * packet is a crypto-NAK; if 3, the packet is authenticated
+ * with DES; if 5, the packet is authenticated with MD5; if 6,
+ * the packet is authenticated with SHA. If 2 or * 4, the packet
+ * is a runt and discarded forthwith. If greater than 6, an
+ * extension field is present, so we subtract the length of the
+ * field and go around again.
+ *
+ * Note the above description is lame. We should/could also check
+ * the two bytes that make up the EF type and subtype, and then
+ * check the two bytes that tell us the EF length. A legacy MAC
+ * has a 4 byte keyID, and for conforming symmetric keys its value
+ * must be <= 64k, meaning the top two bytes will always be zero.
+ * Since the EF Type of 0 is reserved/unused, there's no way a
+ * conforming legacy MAC could ever be misinterpreted as an EF.
+ *
+ * There is more, but this isn't the place to document it.
+ */
+
+ authlen = LEN_PKT_NOMAC;
+ has_mac = rbufp->recv_length - authlen;
+ while (has_mac > 0) {
+ u_int32 len;
+#ifdef AUTOKEY
+ u_int32 hostlen;
+ struct exten *ep;
+#endif /*AUTOKEY */
+
+ if (has_mac % 4 != 0 || has_mac < (int)MIN_MAC_LEN) {
+ DPRINTF(2, ("receive: drop: bad post-packet length\n"));
+ sys_badlength++;
+ return; /* bad length */
+ }
+ /*
+ * This next test is clearly wrong - it needlessly
+ * prohibits short EFs (which don't yet exist)
+ */
+ if (has_mac <= (int)MAX_MAC_LEN) {
+ skeyid = ntohl(((u_int32 *)pkt)[authlen / 4]);
+ break;
+
+ } else {
+ opcode = ntohl(((u_int32 *)pkt)[authlen / 4]);
+ len = opcode & 0xffff;
+ if ( len % 4 != 0
+ || len < 4
+ || (int)len + authlen > rbufp->recv_length) {
+ DPRINTF(2, ("receive: drop: bad EF length\n"));
+ sys_badlength++;
+ return; /* bad length */
+ }
+#ifdef AUTOKEY
+ /*
+ * Extract calling group name for later. If
+ * sys_groupname is non-NULL, there must be
+ * a group name provided to elicit a response.
+ */
+ if ( (opcode & 0x3fff0000) == CRYPTO_ASSOC
+ && sys_groupname != NULL) {
+ ep = (struct exten *)&((u_int32 *)pkt)[authlen / 4];
+ hostlen = ntohl(ep->vallen);
+ if ( hostlen >= sizeof(hostname)
+ || hostlen > len -
+ offsetof(struct exten, pkt)) {
+ DPRINTF(2, ("receive: drop: bad autokey hostname length\n"));
+ sys_badlength++;
+ return; /* bad length */
+ }
+ memcpy(hostname, &ep->pkt, hostlen);
+ hostname[hostlen] = '\0';
+ groupname = strchr(hostname, '@');
+ if (groupname == NULL) {
+ DPRINTF(2, ("receive: drop: empty autokey groupname\n"));
+ sys_declined++;
+ return;
+ }
+ groupname++;
+ }
+#endif /* AUTOKEY */
+ authlen += len;
+ has_mac -= len;
+ }
+ }
+
+ /*
+ * If has_mac is < 0 we had a malformed packet.
+ */
+ if (has_mac < 0) {
+ DPRINTF(2, ("receive: drop: post-packet under-read\n"));
+ sys_badlength++;
+ return; /* bad length */
+ }
+
+ /*
+ ** Packet Data Verification Layer
+ **
+ ** This layer verifies the packet data content. If
+ ** authentication is required, a MAC must be present.
+ ** If a MAC is present, it must validate.
+ ** Crypto-NAK? Look - a shiny thing!
+ **
+ ** If authentication fails, we're done.
+ */
+
+ /*
+ * If authentication is explicitly required, a MAC must be present.
+ */
+ if (restrict_mask & RES_DONTTRUST && has_mac == 0) {
+ DPRINTF(2, ("receive: drop: RES_DONTTRUST\n"));
+ sys_restricted++;
+ return; /* access denied */
+ }
+
+ /*
+ * Update the MRU list and finger the cloggers. It can be a
+ * little expensive, so turn it off for production use.
+ * RES_LIMITED and RES_KOD will be cleared in the returned
+ * restrict_mask unless one or both actions are warranted.
+ */
+ restrict_mask = ntp_monitor(rbufp, restrict_mask);
+ if (restrict_mask & RES_LIMITED) {
+ sys_limitrejected++;
+ if ( !(restrict_mask & RES_KOD)
+ || MODE_BROADCAST == hismode
+ || MODE_SERVER == hismode) {
+ if (MODE_SERVER == hismode) {
+ DPRINTF(1, ("Possibly self-induced rate limiting of MODE_SERVER from %s\n",
+ stoa(&rbufp->recv_srcadr)));
+ } else {
+ DPRINTF(2, ("receive: drop: RES_KOD\n"));
+ }
+ return; /* rate exceeded */
+ }
+ if (hismode == MODE_CLIENT)
+ fast_xmit(rbufp, MODE_SERVER, skeyid,
+ restrict_mask);
+ else
+ fast_xmit(rbufp, MODE_ACTIVE, skeyid,
+ restrict_mask);
+ return; /* rate exceeded */
+ }
+ restrict_mask &= ~RES_KOD;
+
+ /*
+ * We have tossed out as many buggy packets as possible early in
+ * the game to reduce the exposure to a clogging attack. Now we
+ * have to burn some cycles to find the association and
+ * authenticate the packet if required. Note that we burn only
+ * digest cycles, again to reduce exposure. There may be no
+ * matching association and that's okay.
+ *
+ * More on the autokey mambo. Normally the local interface is
+ * found when the association was mobilized with respect to a
+ * designated remote address. We assume packets arriving from
+ * the remote address arrive via this interface and the local
+ * address used to construct the autokey is the unicast address
+ * of the interface. However, if the sender is a broadcaster,
+ * the interface broadcast address is used instead.
+ * Notwithstanding this technobabble, if the sender is a
+ * multicaster, the broadcast address is null, so we use the
+ * unicast address anyway. Don't ask.
+ */
+
+ peer = findpeer(rbufp, hismode, &retcode);
+ dstadr_sin = &rbufp->dstadr->sin;
+ NTOHL_FP(&pkt->org, &p_org);
+ NTOHL_FP(&pkt->rec, &p_rec);
+ NTOHL_FP(&pkt->xmt, &p_xmt);
+ hm_str = modetoa(hismode);
+ am_str = amtoa(retcode);
+
+ /*
+ * Authentication is conditioned by three switches:
+ *
+ * NOPEER (RES_NOPEER) do not mobilize an association unless
+ * authenticated
+ * NOTRUST (RES_DONTTRUST) do not allow access unless
+ * authenticated (implies NOPEER)
+ * enable (sys_authenticate) master NOPEER switch, by default
+ * on
+ *
+ * The NOPEER and NOTRUST can be specified on a per-client basis
+ * using the restrict command. The enable switch if on implies
+ * NOPEER for all clients. There are four outcomes:
+ *
+ * NONE The packet has no MAC.
+ * OK the packet has a MAC and authentication succeeds
+ * ERROR the packet has a MAC and authentication fails
+ * CRYPTO crypto-NAK. The MAC has four octets only.
+ *
+ * Note: The AUTH(x, y) macro is used to filter outcomes. If x
+ * is zero, acceptable outcomes of y are NONE and OK. If x is
+ * one, the only acceptable outcome of y is OK.
+ */
+ crypto_nak_test = valid_NAK(peer, rbufp, hismode);
+
+ /*
+ * Drop any invalid crypto-NAKs
+ */
+ if (crypto_nak_test == INVALIDNAK) {
+ report_event(PEVNT_AUTH, peer, "Invalid_NAK");
+ if (0 != peer) {
+ peer->badNAK++;
+ }
+ msyslog(LOG_ERR, "Invalid-NAK error at %ld %s<-%s",
+ current_time, stoa(dstadr_sin), stoa(&rbufp->recv_srcadr));
+ return;
+ }
+
+ if (has_mac == 0) {
+ restrict_mask &= ~RES_MSSNTP;
+ is_authentic = AUTH_NONE; /* not required */
+ DPRINTF(1, ("receive: at %ld %s<-%s mode %d/%s:%s len %d org %#010x.%08x xmt %#010x.%08x NOMAC\n",
+ current_time, stoa(dstadr_sin),
+ stoa(&rbufp->recv_srcadr), hismode, hm_str, am_str,
+ authlen,
+ ntohl(pkt->org.l_ui), ntohl(pkt->org.l_uf),
+ ntohl(pkt->xmt.l_ui), ntohl(pkt->xmt.l_uf)));
+ } else if (crypto_nak_test == VALIDNAK) {
+ restrict_mask &= ~RES_MSSNTP;
+ is_authentic = AUTH_CRYPTO; /* crypto-NAK */
+ DPRINTF(1, ("receive: at %ld %s<-%s mode %d/%s:%s keyid %08x len %d auth %d org %#010x.%08x xmt %#010x.%08x CRYPTONAK\n",
+ current_time, stoa(dstadr_sin),
+ stoa(&rbufp->recv_srcadr), hismode, hm_str, am_str,
+ skeyid, authlen + has_mac, is_authentic,
+ ntohl(pkt->org.l_ui), ntohl(pkt->org.l_uf),
+ ntohl(pkt->xmt.l_ui), ntohl(pkt->xmt.l_uf)));
+
+#ifdef HAVE_NTP_SIGND
+ /*
+ * If the signature is 20 bytes long, the last 16 of
+ * which are zero, then this is a Microsoft client
+ * wanting AD-style authentication of the server's
+ * reply.
+ *
+ * This is described in Microsoft's WSPP docs, in MS-SNTP:
+ * http://msdn.microsoft.com/en-us/library/cc212930.aspx
+ */
+ } else if ( has_mac == MAX_MD5_LEN
+ && (restrict_mask & RES_MSSNTP)
+ && (retcode == AM_FXMIT || retcode == AM_NEWPASS)
+ && (memcmp(zero_key, (char *)pkt + authlen + 4,
+ MAX_MD5_LEN - 4) == 0)) {
+ is_authentic = AUTH_NONE;
+ DPRINTF(1, ("receive: at %ld %s<-%s mode %d/%s:%s len %d org %#010x.%08x xmt %#010x.%08x SIGND\n",
+ current_time, stoa(dstadr_sin),
+ stoa(&rbufp->recv_srcadr), hismode, hm_str, am_str,
+ authlen,
+ ntohl(pkt->org.l_ui), ntohl(pkt->org.l_uf),
+ ntohl(pkt->xmt.l_ui), ntohl(pkt->xmt.l_uf)));
+#endif /* HAVE_NTP_SIGND */
+
+ } else {
+ /*
+ * has_mac is not 0
+ * Not a VALID_NAK
+ * Not an MS-SNTP SIGND packet
+ *
+ * So there is a MAC here.
+ */
+
+ restrict_mask &= ~RES_MSSNTP;
+#ifdef AUTOKEY
+ /*
+ * For autokey modes, generate the session key
+ * and install in the key cache. Use the socket
+ * broadcast or unicast address as appropriate.
+ */
+ if (crypto_flags && skeyid > NTP_MAXKEY) {
+
+ /*
+ * More on the autokey dance (AKD). A cookie is
+ * constructed from public and private values.
+ * For broadcast packets, the cookie is public
+ * (zero). For packets that match no
+ * association, the cookie is hashed from the
+ * addresses and private value. For server
+ * packets, the cookie was previously obtained
+ * from the server. For symmetric modes, the
+ * cookie was previously constructed using an
+ * agreement protocol; however, should PKI be
+ * unavailable, we construct a fake agreement as
+ * the EXOR of the peer and host cookies.
+ *
+ * hismode ephemeral persistent
+ * =======================================
+ * active 0 cookie#
+ * passive 0% cookie#
+ * client sys cookie 0%
+ * server 0% sys cookie
+ * broadcast 0 0
+ *
+ * # if unsync, 0
+ * % can't happen
+ */
+ if (has_mac < (int)MAX_MD5_LEN) {
+ DPRINTF(2, ("receive: drop: MD5 digest too short\n"));
+ sys_badauth++;
+ return;
+ }
+ if (hismode == MODE_BROADCAST) {
+
+ /*
+ * For broadcaster, use the interface
+ * broadcast address when available;
+ * otherwise, use the unicast address
+ * found when the association was
+ * mobilized. However, if this is from
+ * the wildcard interface, game over.
+ */
+ if ( crypto_flags
+ && rbufp->dstadr ==
+ ANY_INTERFACE_CHOOSE(&rbufp->recv_srcadr)) {
+ DPRINTF(2, ("receive: drop: BCAST from wildcard\n"));
+ sys_restricted++;
+ return; /* no wildcard */
+ }
+ pkeyid = 0;
+ if (!SOCK_UNSPEC(&rbufp->dstadr->bcast))
+ dstadr_sin =
+ &rbufp->dstadr->bcast;
+ } else if (peer == NULL) {
+ pkeyid = session_key(
+ &rbufp->recv_srcadr, dstadr_sin, 0,
+ sys_private, 0);
+ } else {
+ pkeyid = peer->pcookie;
+ }
+
+ /*
+ * The session key includes both the public
+ * values and cookie. In case of an extension
+ * field, the cookie used for authentication
+ * purposes is zero. Note the hash is saved for
+ * use later in the autokey mambo.
+ */
+ if (authlen > (int)LEN_PKT_NOMAC && pkeyid != 0) {
+ session_key(&rbufp->recv_srcadr,
+ dstadr_sin, skeyid, 0, 2);
+ tkeyid = session_key(
+ &rbufp->recv_srcadr, dstadr_sin,
+ skeyid, pkeyid, 0);
+ } else {
+ tkeyid = session_key(
+ &rbufp->recv_srcadr, dstadr_sin,
+ skeyid, pkeyid, 2);
+ }
+
+ }
+#endif /* AUTOKEY */
+
+ /*
+ * Compute the cryptosum. Note a clogging attack may
+ * succeed in bloating the key cache. If an autokey,
+ * purge it immediately, since we won't be needing it
+ * again. If the packet is authentic, it can mobilize an
+ * association. Note that there is no key zero.
+ */
+ if (!authdecrypt(skeyid, (u_int32 *)pkt, authlen,
+ has_mac))
+ is_authentic = AUTH_ERROR;
+ else
+ is_authentic = AUTH_OK;
+#ifdef AUTOKEY
+ if (crypto_flags && skeyid > NTP_MAXKEY)
+ authtrust(skeyid, 0);
+#endif /* AUTOKEY */
+ DPRINTF(1, ("receive: at %ld %s<-%s mode %d/%s:%s keyid %08x len %d auth %d org %#010x.%08x xmt %#010x.%08x MAC\n",
+ current_time, stoa(dstadr_sin),
+ stoa(&rbufp->recv_srcadr), hismode, hm_str, am_str,
+ skeyid, authlen + has_mac, is_authentic,
+ ntohl(pkt->org.l_ui), ntohl(pkt->org.l_uf),
+ ntohl(pkt->xmt.l_ui), ntohl(pkt->xmt.l_uf)));
+ }
+
+
+ /*
+ * Bug 3454:
+ *
+ * Now come at this from a different perspective:
+ * - If we expect a MAC and it's not there, we drop it.
+ * - If we expect one keyID and get another, we drop it.
+ * - If we have a MAC ahd it hasn't been validated yet, try.
+ * - if the provided MAC doesn't validate, we drop it.
+ *
+ * There might be more to this.
+ */
+ if (0 != peer && 0 != peer->keyid) {
+ /* Should we msyslog() any of these? */
+
+ /*
+ * This should catch:
+ * - no keyID where one is expected,
+ * - different keyID than what we expect.
+ */
+ if (peer->keyid != skeyid) {
+ DPRINTF(2, ("receive: drop: Wanted keyID %d, got %d from %s\n",
+ peer->keyid, skeyid,
+ stoa(&rbufp->recv_srcadr)));
+ sys_restricted++;
+ return; /* drop: access denied */
+ }
+
+ /*
+ * if has_mac != 0 ...
+ * - If it has not yet been validated, do so.
+ * (under what circumstances might that happen?)
+ * - if missing or bad MAC, log and drop.
+ */
+ if (0 != has_mac) {
+ if (is_authentic == AUTH_UNKNOWN) {
+ /* How can this happen? */
+ DPRINTF(2, ("receive: 3454 check: AUTH_UNKNOWN from %s\n",
+ stoa(&rbufp->recv_srcadr)));
+ if (!authdecrypt(skeyid, (u_int32 *)pkt, authlen,
+ has_mac)) {
+ /* MAC invalid or not found */
+ is_authentic = AUTH_ERROR;
+ } else {
+ is_authentic = AUTH_OK;
+ }
+ }
+ if (is_authentic != AUTH_OK) {
+ DPRINTF(2, ("receive: drop: missing or bad MAC from %s\n",
+ stoa(&rbufp->recv_srcadr)));
+ sys_restricted++;
+ return; /* drop: access denied */
+ }
+ }
+ }
+ /**/
+
+ /*
+ ** On-Wire Protocol Layer
+ **
+ ** Verify protocol operations consistent with the on-wire protocol.
+ ** The protocol discards bogus and duplicate packets as well as
+ ** minimizes disruptions doe to protocol restarts and dropped
+ ** packets. The operations are controlled by two timestamps:
+ ** the transmit timestamp saved in the client state variables,
+ ** and the origin timestamp in the server packet header. The
+ ** comparison of these two timestamps is called the loopback test.
+ ** The transmit timestamp functions as a nonce to verify that the
+ ** response corresponds to the original request. The transmit
+ ** timestamp also serves to discard replays of the most recent
+ ** packet. Upon failure of either test, the packet is discarded
+ ** with no further action.
+ */
+
+ /*
+ * The association matching rules are implemented by a set of
+ * routines and an association table. A packet matching an
+ * association is processed by the peer process for that
+ * association. If there are no errors, an ephemeral association
+ * is mobilized: a broadcast packet mobilizes a broadcast client
+ * aassociation; a manycast server packet mobilizes a manycast
+ * client association; a symmetric active packet mobilizes a
+ * symmetric passive association.
+ */
+ DPRINTF(1, ("receive: MATCH_ASSOC dispatch: mode %d/%s:%s \n",
+ hismode, hm_str, am_str));
+ switch (retcode) {
+
+ /*
+ * This is a client mode packet not matching any association. If
+ * an ordinary client, simply toss a server mode packet back
+ * over the fence. If a manycast client, we have to work a
+ * little harder.
+ *
+ * There are cases here where we do not call record_raw_stats().
+ */
+ case AM_FXMIT:
+
+ /*
+ * If authentication OK, send a server reply; otherwise,
+ * send a crypto-NAK.
+ */
+ if (!(rbufp->dstadr->flags & INT_MCASTOPEN)) {
+ /* HMS: would be nice to log FAST_XMIT|BADAUTH|RESTRICTED */
+ record_raw_stats(&rbufp->recv_srcadr,
+ &rbufp->dstadr->sin,
+ &p_org, &p_rec, &p_xmt, &rbufp->recv_time,
+ PKT_LEAP(pkt->li_vn_mode),
+ PKT_VERSION(pkt->li_vn_mode),
+ PKT_MODE(pkt->li_vn_mode),
+ PKT_TO_STRATUM(pkt->stratum),
+ pkt->ppoll,
+ pkt->precision,
+ FPTOD(NTOHS_FP(pkt->rootdelay)),
+ FPTOD(NTOHS_FP(pkt->rootdisp)),
+ pkt->refid,
+ rbufp->recv_length - MIN_V4_PKT_LEN, (u_char *)&pkt->exten);
+
+ if (AUTH(restrict_mask & RES_DONTTRUST,
+ is_authentic)) {
+ fast_xmit(rbufp, MODE_SERVER, skeyid,
+ restrict_mask);
+ } else if (is_authentic == AUTH_ERROR) {
+ fast_xmit(rbufp, MODE_SERVER, 0,
+ restrict_mask);
+ sys_badauth++;
+ } else {
+ DPRINTF(2, ("receive: AM_FXMIT drop: !mcast restricted\n"));
+ sys_restricted++;
+ }
+
+ return; /* hooray */
+ }
+
+ /*
+ * This must be manycast. Do not respond if not
+ * configured as a manycast server.
+ */
+ if (!sys_manycastserver) {
+ DPRINTF(2, ("receive: AM_FXMIT drop: Not manycastserver\n"));
+ sys_restricted++;
+ return; /* not enabled */
+ }
+
+#ifdef AUTOKEY
+ /*
+ * Do not respond if not the same group.
+ */
+ if (group_test(groupname, NULL)) {
+ DPRINTF(2, ("receive: AM_FXMIT drop: empty groupname\n"));
+ sys_declined++;
+ return;
+ }
+#endif /* AUTOKEY */
+
+ /*
+ * Do not respond if we are not synchronized or our
+ * stratum is greater than the manycaster or the
+ * manycaster has already synchronized to us.
+ */
+ if ( sys_leap == LEAP_NOTINSYNC
+ || sys_stratum >= hisstratum
+ || (!sys_cohort && sys_stratum == hisstratum + 1)
+ || rbufp->dstadr->addr_refid == pkt->refid) {
+ DPRINTF(2, ("receive: AM_FXMIT drop: LEAP_NOTINSYNC || stratum || loop\n"));
+ sys_declined++;
+ return; /* no help */
+ }
+
+ /*
+ * Respond only if authentication succeeds. Don't do a
+ * crypto-NAK, as that would not be useful.
+ */
+ if (AUTH(restrict_mask & RES_DONTTRUST, is_authentic)) {
+ record_raw_stats(&rbufp->recv_srcadr,
+ &rbufp->dstadr->sin,
+ &p_org, &p_rec, &p_xmt, &rbufp->recv_time,
+ PKT_LEAP(pkt->li_vn_mode),
+ PKT_VERSION(pkt->li_vn_mode),
+ PKT_MODE(pkt->li_vn_mode),
+ PKT_TO_STRATUM(pkt->stratum),
+ pkt->ppoll,
+ pkt->precision,
+ FPTOD(NTOHS_FP(pkt->rootdelay)),
+ FPTOD(NTOHS_FP(pkt->rootdisp)),
+ pkt->refid,
+ rbufp->recv_length - MIN_V4_PKT_LEN, (u_char *)&pkt->exten);
+
+ fast_xmit(rbufp, MODE_SERVER, skeyid,
+ restrict_mask);
+ }
+ return; /* hooray */
+
+ /*
+ * This is a server mode packet returned in response to a client
+ * mode packet sent to a multicast group address (for
+ * manycastclient) or to a unicast address (for pool). The
+ * origin timestamp is a good nonce to reliably associate the
+ * reply with what was sent. If there is no match, that's
+ * curious and could be an intruder attempting to clog, so we
+ * just ignore it.
+ *
+ * If the packet is authentic and the manycastclient or pool
+ * association is found, we mobilize a client association and
+ * copy pertinent variables from the manycastclient or pool
+ * association to the new client association. If not, just
+ * ignore the packet.
+ *
+ * There is an implosion hazard at the manycast client, since
+ * the manycast servers send the server packet immediately. If
+ * the guy is already here, don't fire up a duplicate.
+ *
+ * There are cases here where we do not call record_raw_stats().
+ */
+ case AM_MANYCAST:
+
+#ifdef AUTOKEY
+ /*
+ * Do not respond if not the same group.
+ */
+ if (group_test(groupname, NULL)) {
+ DPRINTF(2, ("receive: AM_MANYCAST drop: empty groupname\n"));
+ sys_declined++;
+ return;
+ }
+#endif /* AUTOKEY */
+ if ((peer2 = findmanycastpeer(rbufp)) == NULL) {
+ DPRINTF(2, ("receive: AM_MANYCAST drop: No manycast peer\n"));
+ sys_restricted++;
+ return; /* not enabled */
+ }
+ if (!AUTH( (!(peer2->cast_flags & MDF_POOL)
+ && sys_authenticate)
+ || (restrict_mask & (RES_NOPEER |
+ RES_DONTTRUST)), is_authentic)
+ /* MC: RES_NOEPEER? */
+ ) {
+ DPRINTF(2, ("receive: AM_MANYCAST drop: bad auth || (NOPEER|DONTTRUST)\n"));
+ sys_restricted++;
+ return; /* access denied */
+ }
+
+ /*
+ * Do not respond if unsynchronized or stratum is below
+ * the floor or at or above the ceiling.
+ */
+ if ( hisleap == LEAP_NOTINSYNC
+ || hisstratum < sys_floor
+ || hisstratum >= sys_ceiling) {
+ DPRINTF(2, ("receive: AM_MANYCAST drop: unsync/stratum\n"));
+ sys_declined++;
+ return; /* no help */
+ }
+ peer = newpeer(&rbufp->recv_srcadr, NULL, rbufp->dstadr,
+ r4a.ippeerlimit, MODE_CLIENT, hisversion,
+ peer2->minpoll, peer2->maxpoll,
+ FLAG_PREEMPT | (FLAG_IBURST & peer2->flags),
+ MDF_UCAST | MDF_UCLNT, 0, skeyid, sys_ident);
+ if (NULL == peer) {
+ DPRINTF(2, ("receive: AM_MANYCAST drop: duplicate\n"));
+ sys_declined++;
+ return; /* ignore duplicate */
+ }
+
+ /*
+ * After each ephemeral pool association is spun,
+ * accelerate the next poll for the pool solicitor so
+ * the pool will fill promptly.
+ */
+ if (peer2->cast_flags & MDF_POOL)
+ peer2->nextdate = current_time + 1;
+
+ /*
+ * Further processing of the solicitation response would
+ * simply detect its origin timestamp as bogus for the
+ * brand-new association (it matches the prototype
+ * association) and tinker with peer->nextdate delaying
+ * first sync.
+ */
+ return; /* solicitation response handled */
+
+ /*
+ * This is the first packet received from a broadcast server. If
+ * the packet is authentic and we are enabled as broadcast
+ * client, mobilize a broadcast client association. We don't
+ * kiss any frogs here.
+ *
+ * There are cases here where we do not call record_raw_stats().
+ */
+ case AM_NEWBCL:
+
+#ifdef AUTOKEY
+ /*
+ * Do not respond if not the same group.
+ */
+ if (group_test(groupname, sys_ident)) {
+ DPRINTF(2, ("receive: AM_NEWBCL drop: groupname mismatch\n"));
+ sys_declined++;
+ return;
+ }
+#endif /* AUTOKEY */
+ if (sys_bclient == 0) {
+ DPRINTF(2, ("receive: AM_NEWBCL drop: not a bclient\n"));
+ sys_restricted++;
+ return; /* not enabled */
+ }
+ if (!AUTH(sys_authenticate | (restrict_mask &
+ (RES_NOPEER | RES_DONTTRUST)), is_authentic)
+ /* NEWBCL: RES_NOEPEER? */
+ ) {
+ DPRINTF(2, ("receive: AM_NEWBCL drop: AUTH failed\n"));
+ sys_restricted++;
+ return; /* access denied */
+ }
+
+ /*
+ * Do not respond if unsynchronized or stratum is below
+ * the floor or at or above the ceiling.
+ */
+ if ( hisleap == LEAP_NOTINSYNC
+ || hisstratum < sys_floor
+ || hisstratum >= sys_ceiling) {
+ DPRINTF(2, ("receive: AM_NEWBCL drop: Unsync or bad stratum\n"));
+ sys_declined++;
+ return; /* no help */
+ }
+
+#ifdef AUTOKEY
+ /*
+ * Do not respond if Autokey and the opcode is not a
+ * CRYPTO_ASSOC response with association ID.
+ */
+ if ( crypto_flags && skeyid > NTP_MAXKEY
+ && (opcode & 0xffff0000) != (CRYPTO_ASSOC | CRYPTO_RESP)) {
+ DPRINTF(2, ("receive: AM_NEWBCL drop: Autokey but not CRYPTO_ASSOC\n"));
+ sys_declined++;
+ return; /* protocol error */
+ }
+#endif /* AUTOKEY */
+
+ /*
+ * Broadcasts received via a multicast address may
+ * arrive after a unicast volley has begun
+ * with the same remote address. newpeer() will not
+ * find duplicate associations on other local endpoints
+ * if a non-NULL endpoint is supplied. multicastclient
+ * ephemeral associations are unique across all local
+ * endpoints.
+ */
+ if (!(INT_MCASTOPEN & rbufp->dstadr->flags))
+ match_ep = rbufp->dstadr;
+ else
+ match_ep = NULL;
+
+ /*
+ * Determine whether to execute the initial volley.
+ */
+ if (sys_bdelay > 0.0) {
+#ifdef AUTOKEY
+ /*
+ * If a two-way exchange is not possible,
+ * neither is Autokey.
+ */
+ if (crypto_flags && skeyid > NTP_MAXKEY) {
+ sys_restricted++;
+ DPRINTF(2, ("receive: AM_NEWBCL drop: Autokey but not 2-way\n"));
+ return; /* no autokey */
+ }
+#endif /* AUTOKEY */
+
+ /*
+ * Do not execute the volley. Start out in
+ * broadcast client mode.
+ */
+ peer = newpeer(&rbufp->recv_srcadr, NULL, match_ep,
+ r4a.ippeerlimit, MODE_BCLIENT, hisversion,
+ pkt->ppoll, pkt->ppoll,
+ FLAG_PREEMPT, MDF_BCLNT, 0, skeyid, sys_ident);
+ if (NULL == peer) {
+ DPRINTF(2, ("receive: AM_NEWBCL drop: duplicate\n"));
+ sys_restricted++;
+ return; /* ignore duplicate */
+
+ } else {
+ peer->delay = sys_bdelay;
+ peer->bxmt = p_xmt;
+ }
+ break;
+ }
+
+ /*
+ * Execute the initial volley in order to calibrate the
+ * propagation delay and run the Autokey protocol.
+ *
+ * Note that the minpoll is taken from the broadcast
+ * packet, normally 6 (64 s) and that the poll interval
+ * is fixed at this value.
+ */
+ peer = newpeer(&rbufp->recv_srcadr, NULL, match_ep,
+ r4a.ippeerlimit, MODE_CLIENT, hisversion,
+ pkt->ppoll, pkt->ppoll,
+ FLAG_BC_VOL | FLAG_IBURST | FLAG_PREEMPT, MDF_BCLNT,
+ 0, skeyid, sys_ident);
+ if (NULL == peer) {
+ DPRINTF(2, ("receive: AM_NEWBCL drop: empty newpeer() failed\n"));
+ sys_restricted++;
+ return; /* ignore duplicate */
+ }
+ peer->bxmt = p_xmt;
+#ifdef AUTOKEY
+ if (skeyid > NTP_MAXKEY)
+ crypto_recv(peer, rbufp);
+#endif /* AUTOKEY */
+
+ return; /* hooray */
+
+ /*
+ * This is the first packet received from a potential ephemeral
+ * symmetric active peer. First, deal with broken Windows clients.
+ * Then, if NOEPEER is enabled, drop it. If the packet meets our
+ * authenticty requirements and is the first he sent, mobilize
+ * a passive association.
+ * Otherwise, kiss the frog.
+ *
+ * There are cases here where we do not call record_raw_stats().
+ */
+ case AM_NEWPASS:
+
+ DEBUG_REQUIRE(MODE_ACTIVE == hismode);
+
+#ifdef AUTOKEY
+ /*
+ * Do not respond if not the same group.
+ */
+ if (group_test(groupname, sys_ident)) {
+ DPRINTF(2, ("receive: AM_NEWPASS drop: Autokey group mismatch\n"));
+ sys_declined++;
+ return;
+ }
+#endif /* AUTOKEY */
+ if (!AUTH(sys_authenticate | (restrict_mask &
+ (RES_NOPEER | RES_DONTTRUST)), is_authentic)
+ ) {
+ /*
+ * If authenticated but cannot mobilize an
+ * association, send a symmetric passive
+ * response without mobilizing an association.
+ * This is for drat broken Windows clients. See
+ * Microsoft KB 875424 for preferred workaround.
+ */
+ if (AUTH(restrict_mask & RES_DONTTRUST,
+ is_authentic)) {
+ fast_xmit(rbufp, MODE_PASSIVE, skeyid,
+ restrict_mask);
+ return; /* hooray */
+ }
+ /* HMS: Why is this next set of lines a feature? */
+ if (is_authentic == AUTH_ERROR) {
+ fast_xmit(rbufp, MODE_PASSIVE, 0,
+ restrict_mask);
+ sys_restricted++;
+ return;
+ }
+
+ if (restrict_mask & RES_NOEPEER) {
+ DPRINTF(2, ("receive: AM_NEWPASS drop: NOEPEER\n"));
+ sys_declined++;
+ return;
+ }
+
+ /* [Bug 2941]
+ * If we got here, the packet isn't part of an
+ * existing association, either isn't correctly
+ * authenticated or it is but we are refusing
+ * ephemeral peer requests, and it didn't meet
+ * either of the previous two special cases so we
+ * should just drop it on the floor. For example,
+ * crypto-NAKs (is_authentic == AUTH_CRYPTO)
+ * will make it this far. This is just
+ * debug-printed and not logged to avoid log
+ * flooding.
+ */
+ DPRINTF(2, ("receive: at %ld refusing to mobilize passive association"
+ " with unknown peer %s mode %d/%s:%s keyid %08x len %d auth %d\n",
+ current_time, stoa(&rbufp->recv_srcadr),
+ hismode, hm_str, am_str, skeyid,
+ (authlen + has_mac), is_authentic));
+ sys_declined++;
+ return;
+ }
+
+ if (restrict_mask & RES_NOEPEER) {
+ DPRINTF(2, ("receive: AM_NEWPASS drop: NOEPEER\n"));
+ sys_declined++;
+ return;
+ }
+
+ /*
+ * Do not respond if synchronized and if stratum is
+ * below the floor or at or above the ceiling. Note,
+ * this allows an unsynchronized peer to synchronize to
+ * us. It would be very strange if he did and then was
+ * nipped, but that could only happen if we were
+ * operating at the top end of the range. It also means
+ * we will spin an ephemeral association in response to
+ * MODE_ACTIVE KoDs, which will time out eventually.
+ */
+ if ( hisleap != LEAP_NOTINSYNC
+ && (hisstratum < sys_floor || hisstratum >= sys_ceiling)) {
+ DPRINTF(2, ("receive: AM_NEWPASS drop: Autokey group mismatch\n"));
+ sys_declined++;
+ return; /* no help */
+ }
+
+ /*
+ * The message is correctly authenticated and allowed.
+ * Mobilize a symmetric passive association, if we won't
+ * exceed the ippeerlimit.
+ */
+ if ((peer = newpeer(&rbufp->recv_srcadr, NULL, rbufp->dstadr,
+ r4a.ippeerlimit, MODE_PASSIVE, hisversion,
+ pkt->ppoll, NTP_MAXDPOLL, 0, MDF_UCAST, 0,
+ skeyid, sys_ident)) == NULL) {
+ DPRINTF(2, ("receive: AM_NEWPASS drop: newpeer() failed\n"));
+ sys_declined++;
+ return; /* ignore duplicate */
+ }
+ break;
+
+
+ /*
+ * Process regular packet. Nothing special.
+ *
+ * There are cases here where we do not call record_raw_stats().
+ */
+ case AM_PROCPKT:
+
+#ifdef AUTOKEY
+ /*
+ * Do not respond if not the same group.
+ */
+ if (group_test(groupname, peer->ident)) {
+ DPRINTF(2, ("receive: AM_PROCPKT drop: Autokey group mismatch\n"));
+ sys_declined++;
+ return;
+ }
+#endif /* AUTOKEY */
+
+ if (MODE_BROADCAST == hismode) {
+ int bail = 0;
+ l_fp tdiff;
+ u_long deadband;
+
+ DPRINTF(2, ("receive: PROCPKT/BROADCAST: prev pkt %ld seconds ago, ppoll: %d, %d secs\n",
+ (current_time - peer->timelastrec),
+ peer->ppoll, (1 << peer->ppoll)
+ ));
+ /* Things we can check:
+ *
+ * Did the poll interval change?
+ * Is the poll interval in the packet in-range?
+ * Did this packet arrive too soon?
+ * Is the timestamp in this packet monotonic
+ * with respect to the previous packet?
+ */
+
+ /* This is noteworthy, not error-worthy */
+ if (pkt->ppoll != peer->ppoll) {
+ msyslog(LOG_INFO, "receive: broadcast poll from %s changed from %u to %u",
+ stoa(&rbufp->recv_srcadr),
+ peer->ppoll, pkt->ppoll);
+ }
+
+ /* This is error-worthy */
+ if ( pkt->ppoll < peer->minpoll
+ || pkt->ppoll > peer->maxpoll) {
+ msyslog(LOG_INFO, "receive: broadcast poll of %u from %s is out-of-range (%d to %d)!",
+ pkt->ppoll, stoa(&rbufp->recv_srcadr),
+ peer->minpoll, peer->maxpoll);
+ ++bail;
+ }
+
+ /* too early? worth an error, too!
+ *
+ * [Bug 3113] Ensure that at least one poll
+ * interval has elapsed since the last **clean**
+ * packet was received. We limit the check to
+ * **clean** packets to prevent replayed packets
+ * and incorrectly authenticated packets, which
+ * we'll discard, from being used to create a
+ * denial of service condition.
+ */
+ deadband = (1u << pkt->ppoll);
+ if (FLAG_BC_VOL & peer->flags)
+ deadband -= 3; /* allow greater fuzz after volley */
+ if ((current_time - peer->timereceived) < deadband) {
+ msyslog(LOG_INFO, "receive: broadcast packet from %s arrived after %lu, not %lu seconds!",
+ stoa(&rbufp->recv_srcadr),
+ (current_time - peer->timereceived),
+ deadband);
+ ++bail;
+ }
+
+ /* Alert if time from the server is non-monotonic.
+ *
+ * [Bug 3114] is about Broadcast mode replay DoS.
+ *
+ * Broadcast mode *assumes* a trusted network.
+ * Even so, it's nice to be robust in the face
+ * of attacks.
+ *
+ * If we get an authenticated broadcast packet
+ * with an "earlier" timestamp, it means one of
+ * two things:
+ *
+ * - the broadcast server had a backward step.
+ *
+ * - somebody is trying a replay attack.
+ *
+ * deadband: By default, we assume the broadcast
+ * network is trustable, so we take our accepted
+ * broadcast packets as we receive them. But
+ * some folks might want to take additional poll
+ * delays before believing a backward step.
+ */
+ if (sys_bcpollbstep) {
+ /* pkt->ppoll or peer->ppoll ? */
+ deadband = (1u << pkt->ppoll)
+ * sys_bcpollbstep + 2;
+ } else {
+ deadband = 0;
+ }
+
+ if (L_ISZERO(&peer->bxmt)) {
+ tdiff.l_ui = tdiff.l_uf = 0;
+ } else {
+ tdiff = p_xmt;
+ L_SUB(&tdiff, &peer->bxmt);
+ }
+ if ( tdiff.l_i < 0
+ && (current_time - peer->timereceived) < deadband)
+ {
+ msyslog(LOG_INFO, "receive: broadcast packet from %s contains non-monotonic timestamp: %#010x.%08x -> %#010x.%08x",
+ stoa(&rbufp->recv_srcadr),
+ peer->bxmt.l_ui, peer->bxmt.l_uf,
+ p_xmt.l_ui, p_xmt.l_uf
+ );
+ ++bail;
+ }
+
+ if (bail) {
+ DPRINTF(2, ("receive: AM_PROCPKT drop: bail\n"));
+ peer->timelastrec = current_time;
+ sys_declined++;
+ return;
+ }
+ }
+
+ break;
+
+ /*
+ * A passive packet matches a passive association. This is
+ * usually the result of reconfiguring a client on the fly. As
+ * this association might be legitimate and this packet an
+ * attempt to deny service, just ignore it.
+ */
+ case AM_ERR:
+ DPRINTF(2, ("receive: AM_ERR drop.\n"));
+ sys_declined++;
+ return;
+
+ /*
+ * For everything else there is the bit bucket.
+ */
+ default:
+ DPRINTF(2, ("receive: default drop.\n"));
+ sys_declined++;
+ return;
+ }
+
+#ifdef AUTOKEY
+ /*
+ * If the association is configured for Autokey, the packet must
+ * have a public key ID; if not, the packet must have a
+ * symmetric key ID.
+ */
+ if ( is_authentic != AUTH_CRYPTO
+ && ( ((peer->flags & FLAG_SKEY) && skeyid <= NTP_MAXKEY)
+ || (!(peer->flags & FLAG_SKEY) && skeyid > NTP_MAXKEY))) {
+ DPRINTF(2, ("receive: drop: Autokey but wrong/bad auth\n"));
+ sys_badauth++;
+ return;
+ }
+#endif /* AUTOKEY */
+
+ peer->received++;
+ peer->flash &= ~PKT_TEST_MASK;
+ if (peer->flags & FLAG_XBOGUS) {
+ peer->flags &= ~FLAG_XBOGUS;
+ peer->flash |= TEST3;
+ }
+
+ /*
+ * Next comes a rigorous schedule of timestamp checking. If the
+ * transmit timestamp is zero, the server has not initialized in
+ * interleaved modes or is horribly broken.
+ *
+ * A KoD packet we pay attention to cannot have a 0 transmit
+ * timestamp.
+ */
+
+ kissCode = kiss_code_check(hisleap, hisstratum, hismode, pkt->refid);
+
+ if (L_ISZERO(&p_xmt)) {
+ peer->flash |= TEST3; /* unsynch */
+ if (kissCode != NOKISS) { /* KoD packet */
+ peer->bogusorg++; /* for TEST2 or TEST3 */
+ msyslog(LOG_INFO,
+ "receive: Unexpected zero transmit timestamp in KoD from %s",
+ ntoa(&peer->srcadr));
+ return;
+ }
+
+ /*
+ * If the transmit timestamp duplicates our previous one, the
+ * packet is a replay. This prevents the bad guys from replaying
+ * the most recent packet, authenticated or not.
+ */
+ } else if (L_ISEQU(&peer->xmt, &p_xmt)) {
+ DPRINTF(2, ("receive: drop: Duplicate xmit\n"));
+ peer->flash |= TEST1; /* duplicate */
+ peer->oldpkt++;
+ return;
+
+ /*
+ * If this is a broadcast mode packet, make sure hisstratum
+ * is appropriate. Don't do anything else here - we wait to
+ * see if this is an interleave broadcast packet until after
+ * we've validated the MAC that SHOULD be provided.
+ *
+ * hisstratum cannot be 0 - see assertion above.
+ * If hisstratum is 15, then we'll advertise as UNSPEC but
+ * at least we'll be able to sync with the broadcast server.
+ */
+ } else if (hismode == MODE_BROADCAST) {
+ /* 0 is unexpected too, and impossible */
+ if (STRATUM_UNSPEC <= hisstratum) {
+ /* Is this a ++sys_declined or ??? */
+ msyslog(LOG_INFO,
+ "receive: Unexpected stratum (%d) in broadcast from %s",
+ hisstratum, ntoa(&peer->srcadr));
+ return;
+ }
+
+ /*
+ * Basic KoD validation checking:
+ *
+ * KoD packets are a mixed-blessing. Forged KoD packets
+ * are DoS attacks. There are rare situations where we might
+ * get a valid KoD response, though. Since KoD packets are
+ * a special case that complicate the checks we do next, we
+ * handle the basic KoD checks here.
+ *
+ * Note that we expect the incoming KoD packet to have its
+ * (nonzero) org, rec, and xmt timestamps set to the xmt timestamp
+ * that we have previously sent out. Watch interleave mode.
+ */
+ } else if (kissCode != NOKISS) {
+ DEBUG_INSIST(!L_ISZERO(&p_xmt));
+ if ( L_ISZERO(&p_org) /* We checked p_xmt above */
+ || L_ISZERO(&p_rec)) {
+ peer->bogusorg++;
+ msyslog(LOG_INFO,
+ "receive: KoD packet from %s has a zero org or rec timestamp. Ignoring.",
+ ntoa(&peer->srcadr));
+ return;
+ }
+
+ if ( !L_ISEQU(&p_xmt, &p_org)
+ || !L_ISEQU(&p_xmt, &p_rec)) {
+ peer->bogusorg++;
+ msyslog(LOG_INFO,
+ "receive: KoD packet from %s has inconsistent xmt/org/rec timestamps. Ignoring.",
+ ntoa(&peer->srcadr));
+ return;
+ }
+
+ /* Be conservative */
+ if (peer->flip == 0 && !L_ISEQU(&p_org, &peer->aorg)) {
+ peer->bogusorg++;
+ msyslog(LOG_INFO,
+ "receive: flip 0 KoD origin timestamp %#010x.%08x from %s does not match %#010x.%08x - ignoring.",
+ p_org.l_ui, p_org.l_uf,
+ ntoa(&peer->srcadr),
+ peer->aorg.l_ui, peer->aorg.l_uf);
+ return;
+ } else if (peer->flip == 1 && !L_ISEQU(&p_org, &peer->borg)) {
+ peer->bogusorg++;
+ msyslog(LOG_INFO,
+ "receive: flip 1 KoD origin timestamp %#010x.%08x from %s does not match interleave %#010x.%08x - ignoring.",
+ p_org.l_ui, p_org.l_uf,
+ ntoa(&peer->srcadr),
+ peer->borg.l_ui, peer->borg.l_uf);
+ return;
+ }
+
+ /*
+ * Basic mode checks:
+ *
+ * If there is no origin timestamp, it's either an initial packet
+ * or we've already received a response to our query. Of course,
+ * should 'aorg' be all-zero because this really was the original
+ * transmit timestamp, we'll ignore this reply. There is a window
+ * of one nanosecond once every 136 years' time where this is
+ * possible. We currently ignore this situation, as a completely
+ * zero timestamp is (quietly?) disallowed.
+ *
+ * Otherwise, check for bogus packet in basic mode.
+ * If it is bogus, switch to interleaved mode and resynchronize,
+ * but only after confirming the packet is not bogus in
+ * symmetric interleaved mode.
+ *
+ * This could also mean somebody is forging packets claiming to
+ * be from us, attempting to cause our server to KoD us.
+ *
+ * We have earlier asserted that hisstratum cannot be 0.
+ * If hisstratum is STRATUM_UNSPEC, it means he's not sync'd.
+ */
+ } else if (peer->flip == 0) {
+ if (0) {
+ } else if (L_ISZERO(&p_org)) {
+ const char *action;
+
+#ifdef BUG3361
+ msyslog(LOG_INFO,
+ "receive: BUG 3361: Clearing peer->aorg ");
+ L_CLR(&peer->aorg);
+#endif
+ /**/
+ switch (hismode) {
+ /* We allow 0org for: */
+ case UCHAR_MAX:
+ action = "Allow";
+ break;
+ /* We disallow 0org for: */
+ case MODE_UNSPEC:
+ case MODE_ACTIVE:
+ case MODE_PASSIVE:
+ case MODE_CLIENT:
+ case MODE_SERVER:
+ case MODE_BROADCAST:
+ action = "Drop";
+ peer->bogusorg++;
+ peer->flash |= TEST2; /* bogus */
+ break;
+ default:
+ action = ""; /* for cranky compilers / MSVC */
+ INSIST(!"receive(): impossible hismode");
+ break;
+ }
+ /**/
+ msyslog(LOG_INFO,
+ "receive: %s 0 origin timestamp from %s@%s xmt %#010x.%08x",
+ action, hm_str, ntoa(&peer->srcadr),
+ ntohl(pkt->xmt.l_ui), ntohl(pkt->xmt.l_uf));
+ } else if (!L_ISEQU(&p_org, &peer->aorg)) {
+ /* are there cases here where we should bail? */
+ /* Should we set TEST2 if we decide to try xleave? */
+ peer->bogusorg++;
+ peer->flash |= TEST2; /* bogus */
+ msyslog(LOG_INFO,
+ "receive: Unexpected origin timestamp %#010x.%08x does not match aorg %#010x.%08x from %s@%s xmt %#010x.%08x",
+ ntohl(pkt->org.l_ui), ntohl(pkt->org.l_uf),
+ peer->aorg.l_ui, peer->aorg.l_uf,
+ hm_str, ntoa(&peer->srcadr),
+ ntohl(pkt->xmt.l_ui), ntohl(pkt->xmt.l_uf));
+ if ( !L_ISZERO(&peer->dst)
+ && L_ISEQU(&p_org, &peer->dst)) {
+ /* Might be the start of an interleave */
+ if (dynamic_interleave) {
+ peer->flip = 1;
+ report_event(PEVNT_XLEAVE, peer, NULL);
+ } else {
+ msyslog(LOG_INFO,
+ "receive: Dynamic interleave from %s@%s denied",
+ hm_str, ntoa(&peer->srcadr));
+ }
+ }
+ } else {
+ L_CLR(&peer->aorg);
+ }
+
+ /*
+ * Check for valid nonzero timestamp fields.
+ */
+ } else if ( L_ISZERO(&p_org)
+ || L_ISZERO(&p_rec)
+ || L_ISZERO(&peer->dst)) {
+ peer->flash |= TEST3; /* unsynch */
+
+ /*
+ * Check for bogus packet in interleaved symmetric mode. This
+ * can happen if a packet is lost, duplicated or crossed. If
+ * found, flip and resynchronize.
+ */
+ } else if ( !L_ISZERO(&peer->dst)
+ && !L_ISEQU(&p_org, &peer->dst)) {
+ DPRINTF(2, ("receive: drop: Bogus packet in interleaved symmetric mode\n"));
+ peer->bogusorg++;
+ peer->flags |= FLAG_XBOGUS;
+ peer->flash |= TEST2; /* bogus */
+#ifdef BUG3453
+ return; /* Bogus packet, we are done */
+#endif
+ }
+
+ /**/
+
+ /*
+ * If this is a crypto_NAK, the server cannot authenticate a
+ * client packet. The server might have just changed keys. Clear
+ * the association and restart the protocol.
+ */
+ if (crypto_nak_test == VALIDNAK) {
+ report_event(PEVNT_AUTH, peer, "crypto_NAK");
+ peer->flash |= TEST5; /* bad auth */
+ peer->badauth++;
+ if (peer->flags & FLAG_PREEMPT) {
+ if (unpeer_crypto_nak_early) {
+ unpeer(peer);
+ }
+ DPRINTF(2, ("receive: drop: PREEMPT crypto_NAK\n"));
+ return;
+ }
+#ifdef AUTOKEY
+ if (peer->crypto) {
+ peer_clear(peer, "AUTH");
+ }
+#endif /* AUTOKEY */
+ DPRINTF(2, ("receive: drop: crypto_NAK\n"));
+ return;
+
+ /*
+ * If the digest fails or it's missing for authenticated
+ * associations, the client cannot authenticate a server
+ * reply to a client packet previously sent. The loopback check
+ * is designed to avoid a bait-and-switch attack, which was
+ * possible in past versions. If symmetric modes, return a
+ * crypto-NAK. The peer should restart the protocol.
+ */
+ } else if (!AUTH(peer->keyid || has_mac ||
+ (restrict_mask & RES_DONTTRUST), is_authentic)) {
+
+ if (peer->flash & PKT_TEST_MASK) {
+ msyslog(LOG_INFO,
+ "receive: Bad auth in packet with bad timestamps from %s denied - spoof?",
+ ntoa(&peer->srcadr));
+ return;
+ }
+
+ report_event(PEVNT_AUTH, peer, "digest");
+ peer->flash |= TEST5; /* bad auth */
+ peer->badauth++;
+ if ( has_mac
+ && ( hismode == MODE_ACTIVE
+ || hismode == MODE_PASSIVE))
+ fast_xmit(rbufp, MODE_ACTIVE, 0, restrict_mask);
+ if (peer->flags & FLAG_PREEMPT) {
+ if (unpeer_digest_early) {
+ unpeer(peer);
+ }
+ }
+#ifdef AUTOKEY
+ else if (peer_clear_digest_early && peer->crypto) {
+ peer_clear(peer, "AUTH");
+ }
+#endif /* AUTOKEY */
+ DPRINTF(2, ("receive: drop: Bad or missing AUTH\n"));
+ return;
+ }
+
+ /*
+ * For broadcast packets:
+ *
+ * HMS: This next line never made much sense to me, even
+ * when it was up higher:
+ * If an initial volley, bail out now and let the
+ * client do its stuff.
+ *
+ * If the packet has not failed authentication, then
+ * - if the origin timestamp is nonzero this is an
+ * interleaved broadcast, so restart the protocol.
+ * - else, this is not an interleaved broadcast packet.
+ */
+ if (hismode == MODE_BROADCAST) {
+ if ( is_authentic == AUTH_OK
+ || is_authentic == AUTH_NONE) {
+ if (!L_ISZERO(&p_org)) {
+ if (!(peer->flags & FLAG_XB)) {
+ msyslog(LOG_INFO,
+ "receive: Broadcast server at %s is in interleave mode",
+ ntoa(&peer->srcadr));
+ peer->flags |= FLAG_XB;
+ peer->aorg = p_xmt;
+ peer->borg = rbufp->recv_time;
+ report_event(PEVNT_XLEAVE, peer, NULL);
+ return;
+ }
+ } else if (peer->flags & FLAG_XB) {
+ msyslog(LOG_INFO,
+ "receive: Broadcast server at %s is no longer in interleave mode",
+ ntoa(&peer->srcadr));
+ peer->flags &= ~FLAG_XB;
+ }
+ } else {
+ msyslog(LOG_INFO,
+ "receive: Bad broadcast auth (%d) from %s",
+ is_authentic, ntoa(&peer->srcadr));
+ }
+
+ /*
+ * Now that we know the packet is correctly authenticated,
+ * update peer->bxmt.
+ */
+ peer->bxmt = p_xmt;
+ }
+
+
+ /*
+ ** Update the state variables.
+ */
+ if (peer->flip == 0) {
+ if (hismode != MODE_BROADCAST)
+ peer->rec = p_xmt;
+ peer->dst = rbufp->recv_time;
+ }
+ peer->xmt = p_xmt;
+
+ /*
+ * Set the peer ppoll to the maximum of the packet ppoll and the
+ * peer minpoll. If a kiss-o'-death, set the peer minpoll to
+ * this maximum and advance the headway to give the sender some
+ * headroom. Very intricate.
+ */
+
+ /*
+ * Check for any kiss codes. Note this is only used when a server
+ * responds to a packet request.
+ */
+
+ /*
+ * Check to see if this is a RATE Kiss Code
+ * Currently this kiss code will accept whatever poll
+ * rate that the server sends
+ */
+ peer->ppoll = max(peer->minpoll, pkt->ppoll);
+ if (kissCode == RATEKISS) {
+ peer->selbroken++; /* Increment the KoD count */
+ report_event(PEVNT_RATE, peer, NULL);
+ if (pkt->ppoll > peer->minpoll)
+ peer->minpoll = peer->ppoll;
+ peer->burst = peer->retry = 0;
+ peer->throttle = (NTP_SHIFT + 1) * (1 << peer->minpoll);
+ poll_update(peer, pkt->ppoll);
+ return; /* kiss-o'-death */
+ }
+ if (kissCode != NOKISS) {
+ peer->selbroken++; /* Increment the KoD count */
+ return; /* Drop any other kiss code packets */
+ }
+
+
+ /*
+ * XXX
+ */
+
+
+ /*
+ * If:
+ * - this is a *cast (uni-, broad-, or m-) server packet
+ * - and it's symmetric-key authenticated
+ * then see if the sender's IP is trusted for this keyid.
+ * If it is, great - nothing special to do here.
+ * Otherwise, we should report and bail.
+ *
+ * Autokey-authenticated packets are accepted.
+ */
+
+ switch (hismode) {
+ case MODE_SERVER: /* server mode */
+ case MODE_BROADCAST: /* broadcast mode */
+ case MODE_ACTIVE: /* symmetric active mode */
+ case MODE_PASSIVE: /* symmetric passive mode */
+ if ( is_authentic == AUTH_OK
+ && skeyid
+ && skeyid <= NTP_MAXKEY
+ && !authistrustedip(skeyid, &peer->srcadr)) {
+ report_event(PEVNT_AUTH, peer, "authIP");
+ peer->badauth++;
+ return;
+ }
+ break;
+
+ case MODE_CLIENT: /* client mode */
+#if 0 /* At this point, MODE_CONTROL is overloaded by MODE_BCLIENT */
+ case MODE_CONTROL: /* control mode */
+#endif
+ case MODE_PRIVATE: /* private mode */
+ case MODE_BCLIENT: /* broadcast client mode */
+ break;
+
+ case MODE_UNSPEC: /* unspecified (old version) */
+ default:
+ msyslog(LOG_INFO,
+ "receive: Unexpected mode (%d) in packet from %s",
+ hismode, ntoa(&peer->srcadr));
+ break;
+ }
+
+
+ /*
+ * That was hard and I am sweaty, but the packet is squeaky
+ * clean. Get on with real work.
+ */
+ peer->timereceived = current_time;
+ peer->timelastrec = current_time;
+ if (is_authentic == AUTH_OK)
+ peer->flags |= FLAG_AUTHENTIC;
+ else
+ peer->flags &= ~FLAG_AUTHENTIC;
+
+#ifdef AUTOKEY
+ /*
+ * More autokey dance. The rules of the cha-cha are as follows:
+ *
+ * 1. If there is no key or the key is not auto, do nothing.
+ *
+ * 2. If this packet is in response to the one just previously
+ * sent or from a broadcast server, do the extension fields.
+ * Otherwise, assume bogosity and bail out.
+ *
+ * 3. If an extension field contains a verified signature, it is
+ * self-authenticated and we sit the dance.
+ *
+ * 4. If this is a server reply, check only to see that the
+ * transmitted key ID matches the received key ID.
+ *
+ * 5. Check to see that one or more hashes of the current key ID
+ * matches the previous key ID or ultimate original key ID
+ * obtained from the broadcaster or symmetric peer. If no
+ * match, sit the dance and call for new autokey values.
+ *
+ * In case of crypto error, fire the orchestra, stop dancing and
+ * restart the protocol.
+ */
+ if (peer->flags & FLAG_SKEY) {
+ /*
+ * Decrement remaining autokey hashes. This isn't
+ * perfect if a packet is lost, but results in no harm.
+ */
+ ap = (struct autokey *)peer->recval.ptr;
+ if (ap != NULL) {
+ if (ap->seq > 0)
+ ap->seq--;
+ }
+ peer->flash |= TEST8;
+ rval = crypto_recv(peer, rbufp);
+ if (rval == XEVNT_OK) {
+ peer->unreach = 0;
+ } else {
+ if (rval == XEVNT_ERR) {
+ report_event(PEVNT_RESTART, peer,
+ "crypto error");
+ peer_clear(peer, "CRYP");
+ peer->flash |= TEST9; /* bad crypt */
+ if (peer->flags & FLAG_PREEMPT) {
+ if (unpeer_crypto_early) {
+ unpeer(peer);
+ }
+ }
+ }
+ return;
+ }
+
+ /*
+ * If server mode, verify the receive key ID matches
+ * the transmit key ID.
+ */
+ if (hismode == MODE_SERVER) {
+ if (skeyid == peer->keyid)
+ peer->flash &= ~TEST8;
+
+ /*
+ * If an extension field is present, verify only that it
+ * has been correctly signed. We don't need a sequence
+ * check here, but the sequence continues.
+ */
+ } else if (!(peer->flash & TEST8)) {
+ peer->pkeyid = skeyid;
+
+ /*
+ * Now the fun part. Here, skeyid is the current ID in
+ * the packet, pkeyid is the ID in the last packet and
+ * tkeyid is the hash of skeyid. If the autokey values
+ * have not been received, this is an automatic error.
+ * If so, check that the tkeyid matches pkeyid. If not,
+ * hash tkeyid and try again. If the number of hashes
+ * exceeds the number remaining in the sequence, declare
+ * a successful failure and refresh the autokey values.
+ */
+ } else if (ap != NULL) {
+ int i;
+
+ for (i = 0; ; i++) {
+ if ( tkeyid == peer->pkeyid
+ || tkeyid == ap->key) {
+ peer->flash &= ~TEST8;
+ peer->pkeyid = skeyid;
+ ap->seq -= i;
+ break;
+ }
+ if (i > ap->seq) {
+ peer->crypto &=
+ ~CRYPTO_FLAG_AUTO;
+ break;
+ }
+ tkeyid = session_key(
+ &rbufp->recv_srcadr, dstadr_sin,
+ tkeyid, pkeyid, 0);
+ }
+ if (peer->flash & TEST8)
+ report_event(PEVNT_AUTH, peer, "keylist");
+ }
+ if (!(peer->crypto & CRYPTO_FLAG_PROV)) /* test 9 */
+ peer->flash |= TEST8; /* bad autokey */
+
+ /*
+ * The maximum lifetime of the protocol is about one
+ * week before restarting the Autokey protocol to
+ * refresh certificates and leapseconds values.
+ */
+ if (current_time > peer->refresh) {
+ report_event(PEVNT_RESTART, peer,
+ "crypto refresh");
+ peer_clear(peer, "TIME");
+ return;
+ }
+ }
+#endif /* AUTOKEY */
+
+ /*
+ * The dance is complete and the flash bits have been lit. Toss
+ * the packet over the fence for processing, which may light up
+ * more flashers.
+ */
+ process_packet(peer, pkt, rbufp->recv_length);
+
+ /*
+ * In interleaved mode update the state variables. Also adjust the
+ * transmit phase to avoid crossover.
+ */
+ if (peer->flip != 0) {
+ peer->rec = p_rec;
+ peer->dst = rbufp->recv_time;
+ if (peer->nextdate - current_time < (1U << min(peer->ppoll,
+ peer->hpoll)) / 2)
+ peer->nextdate++;
+ else
+ peer->nextdate--;
+ }
+}
+
+
+/*
+ * process_packet - Packet Procedure, a la Section 3.4.4 of RFC-1305
+ * Or almost, at least. If we're in here we have a reasonable
+ * expectation that we will be having a long term
+ * relationship with this host.
+ */
+void
+process_packet(
+ register struct peer *peer,
+ register struct pkt *pkt,
+ u_int len
+ )
+{
+ double t34, t21;
+ double p_offset, p_del, p_disp;
+ l_fp p_rec, p_xmt, p_org, p_reftime, ci;
+ u_char pmode, pleap, pversion, pstratum;
+ char statstr[NTP_MAXSTRLEN];
+#ifdef ASSYM
+ int itemp;
+ double etemp, ftemp, td;
+#endif /* ASSYM */
+
+#if 0
+ sys_processed++;
+ peer->processed++;
+#endif
+ p_del = FPTOD(NTOHS_FP(pkt->rootdelay));
+ p_offset = 0;
+ p_disp = FPTOD(NTOHS_FP(pkt->rootdisp));
+ NTOHL_FP(&pkt->reftime, &p_reftime);
+ NTOHL_FP(&pkt->org, &p_org);
+ NTOHL_FP(&pkt->rec, &p_rec);
+ NTOHL_FP(&pkt->xmt, &p_xmt);
+ pmode = PKT_MODE(pkt->li_vn_mode);
+ pleap = PKT_LEAP(pkt->li_vn_mode);
+ pversion = PKT_VERSION(pkt->li_vn_mode);
+ pstratum = PKT_TO_STRATUM(pkt->stratum);
+
+ /**/
+
+ /**/
+
+ /*
+ * Verify the server is synchronized; that is, the leap bits,
+ * stratum and root distance are valid.
+ */
+ if ( pleap == LEAP_NOTINSYNC /* test 6 */
+ || pstratum < sys_floor || pstratum >= sys_ceiling)
+ peer->flash |= TEST6; /* bad synch or strat */
+ if (p_del / 2 + p_disp >= MAXDISPERSE) /* test 7 */
+ peer->flash |= TEST7; /* bad header */
+
+ /*
+ * If any tests fail at this point, the packet is discarded.
+ * Note that some flashers may have already been set in the
+ * receive() routine.
+ */
+ if (peer->flash & PKT_TEST_MASK) {
+ peer->seldisptoolarge++;
+ DPRINTF(1, ("packet: flash header %04x\n",
+ peer->flash));
+ poll_update(peer, peer->hpoll); /* ppoll updated? */
+ return;
+ }
+
+ /**/
+
+#if 1
+ sys_processed++;
+ peer->processed++;
+#endif
+
+ /*
+ * Capture the header values in the client/peer association..
+ */
+ record_raw_stats(&peer->srcadr,
+ peer->dstadr ? &peer->dstadr->sin : NULL,
+ &p_org, &p_rec, &p_xmt, &peer->dst,
+ pleap, pversion, pmode, pstratum, pkt->ppoll, pkt->precision,
+ p_del, p_disp, pkt->refid,
+ len - MIN_V4_PKT_LEN, (u_char *)&pkt->exten);
+ peer->leap = pleap;
+ peer->stratum = min(pstratum, STRATUM_UNSPEC);
+ peer->pmode = pmode;
+ peer->precision = pkt->precision;
+ peer->rootdelay = p_del;
+ peer->rootdisp = p_disp;
+ peer->refid = pkt->refid; /* network byte order */
+ peer->reftime = p_reftime;
+
+ /*
+ * First, if either burst mode is armed, enable the burst.
+ * Compute the headway for the next packet and delay if
+ * necessary to avoid exceeding the threshold.
+ */
+ if (peer->retry > 0) {
+ peer->retry = 0;
+ if (peer->reach)
+ peer->burst = min(1 << (peer->hpoll -
+ peer->minpoll), NTP_SHIFT) - 1;
+ else
+ peer->burst = NTP_IBURST - 1;
+ if (peer->burst > 0)
+ peer->nextdate = current_time;
+ }
+ poll_update(peer, peer->hpoll);
+
+ /**/
+
+ /*
+ * If the peer was previously unreachable, raise a trap. In any
+ * case, mark it reachable.
+ */
+ if (!peer->reach) {
+ report_event(PEVNT_REACH, peer, NULL);
+ peer->timereachable = current_time;
+ }
+ peer->reach |= 1;
+
+ /*
+ * For a client/server association, calculate the clock offset,
+ * roundtrip delay and dispersion. The equations are reordered
+ * from the spec for more efficient use of temporaries. For a
+ * broadcast association, offset the last measurement by the
+ * computed delay during the client/server volley. Note the
+ * computation of dispersion includes the system precision plus
+ * that due to the frequency error since the origin time.
+ *
+ * It is very important to respect the hazards of overflow. The
+ * only permitted operation on raw timestamps is subtraction,
+ * where the result is a signed quantity spanning from 68 years
+ * in the past to 68 years in the future. To avoid loss of
+ * precision, these calculations are done using 64-bit integer
+ * arithmetic. However, the offset and delay calculations are
+ * sums and differences of these first-order differences, which
+ * if done using 64-bit integer arithmetic, would be valid over
+ * only half that span. Since the typical first-order
+ * differences are usually very small, they are converted to 64-
+ * bit doubles and all remaining calculations done in floating-
+ * double arithmetic. This preserves the accuracy while
+ * retaining the 68-year span.
+ *
+ * There are three interleaving schemes, basic, interleaved
+ * symmetric and interleaved broadcast. The timestamps are
+ * idioscyncratically different. See the onwire briefing/white
+ * paper at www.eecis.udel.edu/~mills for details.
+ *
+ * Interleaved symmetric mode
+ * t1 = peer->aorg/borg, t2 = peer->rec, t3 = p_xmt,
+ * t4 = peer->dst
+ */
+ if (peer->flip != 0) {
+ ci = p_xmt; /* t3 - t4 */
+ L_SUB(&ci, &peer->dst);
+ LFPTOD(&ci, t34);
+ ci = p_rec; /* t2 - t1 */
+ if (peer->flip > 0)
+ L_SUB(&ci, &peer->borg);
+ else
+ L_SUB(&ci, &peer->aorg);
+ LFPTOD(&ci, t21);
+ p_del = t21 - t34;
+ p_offset = (t21 + t34) / 2.;
+ if (p_del < 0 || p_del > 1.) {
+ snprintf(statstr, sizeof(statstr),
+ "t21 %.6f t34 %.6f", t21, t34);
+ report_event(PEVNT_XERR, peer, statstr);
+ return;
+ }
+
+ /*
+ * Broadcast modes
+ */
+ } else if (peer->pmode == MODE_BROADCAST) {
+
+ /*
+ * Interleaved broadcast mode. Use interleaved timestamps.
+ * t1 = peer->borg, t2 = p_org, t3 = p_org, t4 = aorg
+ */
+ if (peer->flags & FLAG_XB) {
+ ci = p_org; /* delay */
+ L_SUB(&ci, &peer->aorg);
+ LFPTOD(&ci, t34);
+ ci = p_org; /* t2 - t1 */
+ L_SUB(&ci, &peer->borg);
+ LFPTOD(&ci, t21);
+ peer->aorg = p_xmt;
+ peer->borg = peer->dst;
+ if (t34 < 0 || t34 > 1.) {
+ /* drop all if in the initial volley */
+ if (FLAG_BC_VOL & peer->flags)
+ goto bcc_init_volley_fail;
+ snprintf(statstr, sizeof(statstr),
+ "offset %.6f delay %.6f", t21, t34);
+ report_event(PEVNT_XERR, peer, statstr);
+ return;
+ }
+ p_offset = t21;
+ peer->xleave = t34;
+
+ /*
+ * Basic broadcast - use direct timestamps.
+ * t3 = p_xmt, t4 = peer->dst
+ */
+ } else {
+ ci = p_xmt; /* t3 - t4 */
+ L_SUB(&ci, &peer->dst);
+ LFPTOD(&ci, t34);
+ p_offset = t34;
+ }
+
+ /*
+ * When calibration is complete and the clock is
+ * synchronized, the bias is calculated as the difference
+ * between the unicast timestamp and the broadcast
+ * timestamp. This works for both basic and interleaved
+ * modes.
+ * [Bug 3031] Don't keep this peer when the delay
+ * calculation gives reason to suspect clock steps.
+ * This is assumed for delays > 50ms.
+ */
+ if (FLAG_BC_VOL & peer->flags) {
+ peer->flags &= ~FLAG_BC_VOL;
+ peer->delay = fabs(peer->offset - p_offset) * 2;
+ DPRINTF(2, ("broadcast volley: initial delay=%.6f\n",
+ peer->delay));
+ if (peer->delay > fabs(sys_bdelay)) {
+ bcc_init_volley_fail:
+ DPRINTF(2, ("%s", "broadcast volley: initial delay exceeds limit\n"));
+ unpeer(peer);
+ return;
+ }
+ }
+ peer->nextdate = current_time + (1u << peer->ppoll) - 2u;
+ p_del = peer->delay;
+ p_offset += p_del / 2;
+
+
+ /*
+ * Basic mode, otherwise known as the old fashioned way.
+ *
+ * t1 = p_org, t2 = p_rec, t3 = p_xmt, t4 = peer->dst
+ */
+ } else {
+ ci = p_xmt; /* t3 - t4 */
+ L_SUB(&ci, &peer->dst);
+ LFPTOD(&ci, t34);
+ ci = p_rec; /* t2 - t1 */
+ L_SUB(&ci, &p_org);
+ LFPTOD(&ci, t21);
+ p_del = fabs(t21 - t34);
+ p_offset = (t21 + t34) / 2.;
+ }
+ p_del = max(p_del, LOGTOD(sys_precision));
+ p_disp = LOGTOD(sys_precision) + LOGTOD(peer->precision) +
+ clock_phi * p_del;
+
+#if ASSYM
+ /*
+ * This code calculates the outbound and inbound data rates by
+ * measuring the differences between timestamps at different
+ * packet lengths. This is helpful in cases of large asymmetric
+ * delays commonly experienced on deep space communication
+ * links.
+ */
+ if (peer->t21_last > 0 && peer->t34_bytes > 0) {
+ itemp = peer->t21_bytes - peer->t21_last;
+ if (itemp > 25) {
+ etemp = t21 - peer->t21;
+ if (fabs(etemp) > 1e-6) {
+ ftemp = itemp / etemp;
+ if (ftemp > 1000.)
+ peer->r21 = ftemp;
+ }
+ }
+ itemp = len - peer->t34_bytes;
+ if (itemp > 25) {
+ etemp = -t34 - peer->t34;
+ if (fabs(etemp) > 1e-6) {
+ ftemp = itemp / etemp;
+ if (ftemp > 1000.)
+ peer->r34 = ftemp;
+ }
+ }
+ }
+
+ /*
+ * The following section compensates for different data rates on
+ * the outbound (d21) and inbound (t34) directions. To do this,
+ * it finds t such that r21 * t - r34 * (d - t) = 0, where d is
+ * the roundtrip delay. Then it calculates the correction as a
+ * fraction of d.
+ */
+ peer->t21 = t21;
+ peer->t21_last = peer->t21_bytes;
+ peer->t34 = -t34;
+ peer->t34_bytes = len;
+ DPRINTF(2, ("packet: t21 %.9lf %d t34 %.9lf %d\n", peer->t21,
+ peer->t21_bytes, peer->t34, peer->t34_bytes));
+ if (peer->r21 > 0 && peer->r34 > 0 && p_del > 0) {
+ if (peer->pmode != MODE_BROADCAST)
+ td = (peer->r34 / (peer->r21 + peer->r34) -
+ .5) * p_del;
+ else
+ td = 0;
+
+ /*
+ * Unfortunately, in many cases the errors are
+ * unacceptable, so for the present the rates are not
+ * used. In future, we might find conditions where the
+ * calculations are useful, so this should be considered
+ * a work in progress.
+ */
+ t21 -= td;
+ t34 -= td;
+ DPRINTF(2, ("packet: del %.6lf r21 %.1lf r34 %.1lf %.6lf\n",
+ p_del, peer->r21 / 1e3, peer->r34 / 1e3,
+ td));
+ }
+#endif /* ASSYM */
+
+ /*
+ * That was awesome. Now hand off to the clock filter.
+ */
+ clock_filter(peer, p_offset + peer->bias, p_del, p_disp);
+
+ /*
+ * If we are in broadcast calibrate mode, return to broadcast
+ * client mode when the client is fit and the autokey dance is
+ * complete.
+ */
+ if ( (FLAG_BC_VOL & peer->flags)
+ && MODE_CLIENT == peer->hmode
+ && !(TEST11 & peer_unfit(peer))) { /* distance exceeded */
+#ifdef AUTOKEY
+ if (peer->flags & FLAG_SKEY) {
+ if (!(~peer->crypto & CRYPTO_FLAG_ALL))
+ peer->hmode = MODE_BCLIENT;
+ } else {
+ peer->hmode = MODE_BCLIENT;
+ }
+#else /* !AUTOKEY follows */
+ peer->hmode = MODE_BCLIENT;
+#endif /* !AUTOKEY */
+ }
+}
+
+
+/*
+ * clock_update - Called at system process update intervals.
+ */
+static void
+clock_update(
+ struct peer *peer /* peer structure pointer */
+ )
+{
+ double dtemp;
+ l_fp now;
+#ifdef HAVE_LIBSCF_H
+ char *fmri;
+#endif /* HAVE_LIBSCF_H */
+
+ /*
+ * Update the system state variables. We do this very carefully,
+ * as the poll interval might need to be clamped differently.
+ */
+ sys_peer = peer;
+ sys_epoch = peer->epoch;
+ if (sys_poll < peer->minpoll)
+ sys_poll = peer->minpoll;
+ if (sys_poll > peer->maxpoll)
+ sys_poll = peer->maxpoll;
+ poll_update(peer, sys_poll);
+ sys_stratum = min(peer->stratum + 1, STRATUM_UNSPEC);
+ if ( peer->stratum == STRATUM_REFCLOCK
+ || peer->stratum == STRATUM_UNSPEC)
+ sys_refid = peer->refid;
+ else
+ sys_refid = addr2refid(&peer->srcadr);
+ /*
+ * Root Dispersion (E) is defined (in RFC 5905) as:
+ *
+ * E = p.epsilon_r + p.epsilon + p.psi + PHI*(s.t - p.t) + |THETA|
+ *
+ * where:
+ * p.epsilon_r is the PollProc's root dispersion
+ * p.epsilon is the PollProc's dispersion
+ * p.psi is the PollProc's jitter
+ * THETA is the combined offset
+ *
+ * NB: Think Hard about where these numbers come from and
+ * what they mean. When did peer->update happen? Has anything
+ * interesting happened since then? What values are the most
+ * defensible? Why?
+ *
+ * DLM thinks this equation is probably the best of all worse choices.
+ */
+ dtemp = peer->rootdisp
+ + peer->disp
+ + sys_jitter
+ + clock_phi * (current_time - peer->update)
+ + fabs(sys_offset);
+
+ if (dtemp > sys_mindisp)
+ sys_rootdisp = dtemp;
+ else
+ sys_rootdisp = sys_mindisp;
+ sys_rootdelay = peer->delay + peer->rootdelay;
+ sys_reftime = peer->dst;
+
+ DPRINTF(1, ("clock_update: at %lu sample %lu associd %d\n",
+ current_time, peer->epoch, peer->associd));
+
+ /*
+ * Comes now the moment of truth. Crank the clock discipline and
+ * see what comes out.
+ */
+ switch (local_clock(peer, sys_offset)) {
+
+ /*
+ * Clock exceeds panic threshold. Life as we know it ends.
+ */
+ case -1:
+#ifdef HAVE_LIBSCF_H
+ /*
+ * For Solaris enter the maintenance mode.
+ */
+ if ((fmri = getenv("SMF_FMRI")) != NULL) {
+ if (smf_maintain_instance(fmri, 0) < 0) {
+ printf("smf_maintain_instance: %s\n",
+ scf_strerror(scf_error()));
+ exit(1);
+ }
+ /*
+ * Sleep until SMF kills us.
+ */
+ for (;;)
+ pause();
+ }
+#endif /* HAVE_LIBSCF_H */
+ exit (-1);
+ /* not reached */
+
+ /*
+ * Clock was stepped. Flush all time values of all peers.
+ */
+ case 2:
+ clear_all();
+ set_sys_leap(LEAP_NOTINSYNC);
+ sys_stratum = STRATUM_UNSPEC;
+ memcpy(&sys_refid, "STEP", 4);
+ sys_rootdelay = 0;
+ sys_rootdisp = 0;
+ L_CLR(&sys_reftime);
+ sys_jitter = LOGTOD(sys_precision);
+ leapsec_reset_frame();
+ break;
+
+ /*
+ * Clock was slewed. Handle the leapsecond stuff.
+ */
+ case 1:
+
+ /*
+ * If this is the first time the clock is set, reset the
+ * leap bits. If crypto, the timer will goose the setup
+ * process.
+ */
+ if (sys_leap == LEAP_NOTINSYNC) {
+ set_sys_leap(LEAP_NOWARNING);
+#ifdef AUTOKEY
+ if (crypto_flags)
+ crypto_update();
+#endif /* AUTOKEY */
+ /*
+ * If our parent process is waiting for the
+ * first clock sync, send them home satisfied.
+ */
+#ifdef HAVE_WORKING_FORK
+ if (waitsync_fd_to_close != -1) {
+ close(waitsync_fd_to_close);
+ waitsync_fd_to_close = -1;
+ DPRINTF(1, ("notified parent --wait-sync is done\n"));
+ }
+#endif /* HAVE_WORKING_FORK */
+
+ }
+
+ /*
+ * If there is no leap second pending and the number of
+ * survivor leap bits is greater than half the number of
+ * survivors, try to schedule a leap for the end of the
+ * current month. (This only works if no leap second for
+ * that range is in the table, so doing this more than
+ * once is mostly harmless.)
+ */
+ if (leapsec == LSPROX_NOWARN) {
+ if ( leap_vote_ins > leap_vote_del
+ && leap_vote_ins > sys_survivors / 2) {
+ get_systime(&now);
+ leapsec_add_dyn(TRUE, now.l_ui, NULL);
+ }
+ if ( leap_vote_del > leap_vote_ins
+ && leap_vote_del > sys_survivors / 2) {
+ get_systime(&now);
+ leapsec_add_dyn(FALSE, now.l_ui, NULL);
+ }
+ }
+ break;
+
+ /*
+ * Popcorn spike or step threshold exceeded. Pretend it never
+ * happened.
+ */
+ default:
+ break;
+ }
+}
+
+
+/*
+ * poll_update - update peer poll interval
+ */
+void
+poll_update(
+ struct peer *peer, /* peer structure pointer */
+ u_char mpoll
+ )
+{
+ u_long next, utemp;
+ u_char hpoll;
+
+ /*
+ * This routine figures out when the next poll should be sent.
+ * That turns out to be wickedly complicated. One problem is
+ * that sometimes the time for the next poll is in the past when
+ * the poll interval is reduced. We watch out for races here
+ * between the receive process and the poll process.
+ *
+ * Clamp the poll interval between minpoll and maxpoll.
+ */
+ hpoll = max(min(peer->maxpoll, mpoll), peer->minpoll);
+
+#ifdef AUTOKEY
+ /*
+ * If during the crypto protocol the poll interval has changed,
+ * the lifetimes in the key list are probably bogus. Purge the
+ * the key list and regenerate it later.
+ */
+ if ((peer->flags & FLAG_SKEY) && hpoll != peer->hpoll)
+ key_expire(peer);
+#endif /* AUTOKEY */
+ peer->hpoll = hpoll;
+
+ /*
+ * There are three variables important for poll scheduling, the
+ * current time (current_time), next scheduled time (nextdate)
+ * and the earliest time (utemp). The earliest time is 2 s
+ * seconds, but could be more due to rate management. When
+ * sending in a burst, use the earliest time. When not in a
+ * burst but with a reply pending, send at the earliest time
+ * unless the next scheduled time has not advanced. This can
+ * only happen if multiple replies are pending in the same
+ * response interval. Otherwise, send at the later of the next
+ * scheduled time and the earliest time.
+ *
+ * Now we figure out if there is an override. If a burst is in
+ * progress and we get called from the receive process, just
+ * slink away. If called from the poll process, delay 1 s for a
+ * reference clock, otherwise 2 s.
+ */
+ utemp = current_time + max(peer->throttle - (NTP_SHIFT - 1) *
+ (1 << peer->minpoll), ntp_minpkt);
+ if (peer->burst > 0) {
+ if (peer->nextdate > current_time)
+ return;
+#ifdef REFCLOCK
+ else if (peer->flags & FLAG_REFCLOCK)
+ peer->nextdate = current_time + RESP_DELAY;
+#endif /* REFCLOCK */
+ else
+ peer->nextdate = utemp;
+
+#ifdef AUTOKEY
+ /*
+ * If a burst is not in progress and a crypto response message
+ * is pending, delay 2 s, but only if this is a new interval.
+ */
+ } else if (peer->cmmd != NULL) {
+ if (peer->nextdate > current_time) {
+ if (peer->nextdate + ntp_minpkt != utemp)
+ peer->nextdate = utemp;
+ } else {
+ peer->nextdate = utemp;
+ }
+#endif /* AUTOKEY */
+
+ /*
+ * The ordinary case. If a retry, use minpoll; if unreachable,
+ * use host poll; otherwise, use the minimum of host and peer
+ * polls; In other words, oversampling is okay but
+ * understampling is evil. Use the maximum of this value and the
+ * headway. If the average headway is greater than the headway
+ * threshold, increase the headway by the minimum interval.
+ */
+ } else {
+ if (peer->retry > 0)
+ hpoll = peer->minpoll;
+ else
+ hpoll = min(peer->ppoll, peer->hpoll);
+#ifdef REFCLOCK
+ if (peer->flags & FLAG_REFCLOCK)
+ next = 1 << hpoll;
+ else
+#endif /* REFCLOCK */
+ next = ((0x1000UL | (ntp_random() & 0x0ff)) <<
+ hpoll) >> 12;
+ next += peer->outdate;
+ if (next > utemp)
+ peer->nextdate = next;
+ else
+ peer->nextdate = utemp;
+ if (peer->throttle > (1 << peer->minpoll))
+ peer->nextdate += ntp_minpkt;
+ }
+ DPRINTF(2, ("poll_update: at %lu %s poll %d burst %d retry %d head %d early %lu next %lu\n",
+ current_time, ntoa(&peer->srcadr), peer->hpoll,
+ peer->burst, peer->retry, peer->throttle,
+ utemp - current_time, peer->nextdate -
+ current_time));
+}
+
+
+/*
+ * peer_clear - clear peer filter registers. See Section 3.4.8 of the
+ * spec.
+ */
+void
+peer_clear(
+ struct peer *peer, /* peer structure */
+ const char *ident /* tally lights */
+ )
+{
+ u_char u;
+ l_fp bxmt = peer->bxmt; /* bcast clients retain this! */
+
+#ifdef AUTOKEY
+ /*
+ * If cryptographic credentials have been acquired, toss them to
+ * Valhalla. Note that autokeys are ephemeral, in that they are
+ * tossed immediately upon use. Therefore, the keylist can be
+ * purged anytime without needing to preserve random keys. Note
+ * that, if the peer is purged, the cryptographic variables are
+ * purged, too. This makes it much harder to sneak in some
+ * unauthenticated data in the clock filter.
+ */
+ key_expire(peer);
+ if (peer->iffval != NULL)
+ BN_free(peer->iffval);
+ value_free(&peer->cookval);
+ value_free(&peer->recval);
+ value_free(&peer->encrypt);
+ value_free(&peer->sndval);
+ if (peer->cmmd != NULL)
+ free(peer->cmmd);
+ if (peer->subject != NULL)
+ free(peer->subject);
+ if (peer->issuer != NULL)
+ free(peer->issuer);
+#endif /* AUTOKEY */
+
+ /*
+ * Clear all values, including the optional crypto values above.
+ */
+ memset(CLEAR_TO_ZERO(peer), 0, LEN_CLEAR_TO_ZERO(peer));
+ peer->ppoll = peer->maxpoll;
+ peer->hpoll = peer->minpoll;
+ peer->disp = MAXDISPERSE;
+ peer->flash = peer_unfit(peer);
+ peer->jitter = LOGTOD(sys_precision);
+
+ /* Don't throw away our broadcast replay protection */
+ if (peer->hmode == MODE_BCLIENT)
+ peer->bxmt = bxmt;
+
+ /*
+ * If interleave mode, initialize the alternate origin switch.
+ */
+ if (peer->flags & FLAG_XLEAVE)
+ peer->flip = 1;
+ for (u = 0; u < NTP_SHIFT; u++) {
+ peer->filter_order[u] = u;
+ peer->filter_disp[u] = MAXDISPERSE;
+ }
+#ifdef REFCLOCK
+ if (!(peer->flags & FLAG_REFCLOCK)) {
+#endif
+ peer->leap = LEAP_NOTINSYNC;
+ peer->stratum = STRATUM_UNSPEC;
+ memcpy(&peer->refid, ident, 4);
+#ifdef REFCLOCK
+ } else {
+ /* Clear refclock sample filter */
+ peer->procptr->codeproc = 0;
+ peer->procptr->coderecv = 0;
+ }
+#endif
+
+ /*
+ * During initialization use the association count to spread out
+ * the polls at one-second intervals. Passive associations'
+ * first poll is delayed by the "discard minimum" to avoid rate
+ * limiting. Other post-startup new or cleared associations
+ * randomize the first poll over the minimum poll interval to
+ * avoid implosion.
+ */
+ peer->nextdate = peer->update = peer->outdate = current_time;
+ if (initializing) {
+ peer->nextdate += peer_associations;
+ } else if (MODE_PASSIVE == peer->hmode) {
+ peer->nextdate += ntp_minpkt;
+ } else {
+ peer->nextdate += ntp_random() % peer->minpoll;
+ }
+#ifdef AUTOKEY
+ peer->refresh = current_time + (1 << NTP_REFRESH);
+#endif /* AUTOKEY */
+ DPRINTF(1, ("peer_clear: at %ld next %ld associd %d refid %s\n",
+ current_time, peer->nextdate, peer->associd,
+ ident));
+}
+
+
+/*
+ * clock_filter - add incoming clock sample to filter register and run
+ * the filter procedure to find the best sample.
+ */
+void
+clock_filter(
+ struct peer *peer, /* peer structure pointer */
+ double sample_offset, /* clock offset */
+ double sample_delay, /* roundtrip delay */
+ double sample_disp /* dispersion */
+ )
+{
+ double dst[NTP_SHIFT]; /* distance vector */
+ int ord[NTP_SHIFT]; /* index vector */
+ int i, j, k, m;
+ double dtemp, etemp;
+ char tbuf[80];
+
+ /*
+ * A sample consists of the offset, delay, dispersion and epoch
+ * of arrival. The offset and delay are determined by the on-
+ * wire protocol. The dispersion grows from the last outbound
+ * packet to the arrival of this one increased by the sum of the
+ * peer precision and the system precision as required by the
+ * error budget. First, shift the new arrival into the shift
+ * register discarding the oldest one.
+ */
+ j = peer->filter_nextpt;
+ peer->filter_offset[j] = sample_offset;
+ peer->filter_delay[j] = sample_delay;
+ peer->filter_disp[j] = sample_disp;
+ peer->filter_epoch[j] = current_time;
+ j = (j + 1) % NTP_SHIFT;
+ peer->filter_nextpt = j;
+
+ /*
+ * Update dispersions since the last update and at the same
+ * time initialize the distance and index lists. Since samples
+ * become increasingly uncorrelated beyond the Allan intercept,
+ * only under exceptional cases will an older sample be used.
+ * Therefore, the distance list uses a compound metric. If the
+ * dispersion is greater than the maximum dispersion, clamp the
+ * distance at that value. If the time since the last update is
+ * less than the Allan intercept use the delay; otherwise, use
+ * the sum of the delay and dispersion.
+ */
+ dtemp = clock_phi * (current_time - peer->update);
+ peer->update = current_time;
+ for (i = NTP_SHIFT - 1; i >= 0; i--) {
+ if (i != 0)
+ peer->filter_disp[j] += dtemp;
+ if (peer->filter_disp[j] >= MAXDISPERSE) {
+ peer->filter_disp[j] = MAXDISPERSE;
+ dst[i] = MAXDISPERSE;
+ } else if (peer->update - peer->filter_epoch[j] >
+ (u_long)ULOGTOD(allan_xpt)) {
+ dst[i] = peer->filter_delay[j] +
+ peer->filter_disp[j];
+ } else {
+ dst[i] = peer->filter_delay[j];
+ }
+ ord[i] = j;
+ j = (j + 1) % NTP_SHIFT;
+ }
+
+ /*
+ * If the clock has stabilized, sort the samples by distance.
+ */
+ if (freq_cnt == 0) {
+ for (i = 1; i < NTP_SHIFT; i++) {
+ for (j = 0; j < i; j++) {
+ if (dst[j] > dst[i]) {
+ k = ord[j];
+ ord[j] = ord[i];
+ ord[i] = k;
+ etemp = dst[j];
+ dst[j] = dst[i];
+ dst[i] = etemp;
+ }
+ }
+ }
+ }
+
+ /*
+ * Copy the index list to the association structure so ntpq
+ * can see it later. Prune the distance list to leave only
+ * samples less than the maximum dispersion, which disfavors
+ * uncorrelated samples older than the Allan intercept. To
+ * further improve the jitter estimate, of the remainder leave
+ * only samples less than the maximum distance, but keep at
+ * least two samples for jitter calculation.
+ */
+ m = 0;
+ for (i = 0; i < NTP_SHIFT; i++) {
+ peer->filter_order[i] = (u_char) ord[i];
+ if ( dst[i] >= MAXDISPERSE
+ || (m >= 2 && dst[i] >= sys_maxdist))
+ continue;
+ m++;
+ }
+
+ /*
+ * Compute the dispersion and jitter. The dispersion is weighted
+ * exponentially by NTP_FWEIGHT (0.5) so it is normalized close
+ * to 1.0. The jitter is the RMS differences relative to the
+ * lowest delay sample.
+ */
+ peer->disp = peer->jitter = 0;
+ k = ord[0];
+ for (i = NTP_SHIFT - 1; i >= 0; i--) {
+ j = ord[i];
+ peer->disp = NTP_FWEIGHT * (peer->disp +
+ peer->filter_disp[j]);
+ if (i < m)
+ peer->jitter += DIFF(peer->filter_offset[j],
+ peer->filter_offset[k]);
+ }
+
+ /*
+ * If no acceptable samples remain in the shift register,
+ * quietly tiptoe home leaving only the dispersion. Otherwise,
+ * save the offset, delay and jitter. Note the jitter must not
+ * be less than the precision.
+ */
+ if (m == 0) {
+ clock_select();
+ return;
+ }
+ etemp = fabs(peer->offset - peer->filter_offset[k]);
+ peer->offset = peer->filter_offset[k];
+ peer->delay = peer->filter_delay[k];
+ if (m > 1)
+ peer->jitter /= m - 1;
+ peer->jitter = max(SQRT(peer->jitter), LOGTOD(sys_precision));
+
+ /*
+ * If the the new sample and the current sample are both valid
+ * and the difference between their offsets exceeds CLOCK_SGATE
+ * (3) times the jitter and the interval between them is less
+ * than twice the host poll interval, consider the new sample
+ * a popcorn spike and ignore it.
+ */
+ if ( peer->disp < sys_maxdist
+ && peer->filter_disp[k] < sys_maxdist
+ && etemp > CLOCK_SGATE * peer->jitter
+ && peer->filter_epoch[k] - peer->epoch
+ < 2. * ULOGTOD(peer->hpoll)) {
+ snprintf(tbuf, sizeof(tbuf), "%.6f s", etemp);
+ report_event(PEVNT_POPCORN, peer, tbuf);
+ return;
+ }
+
+ /*
+ * A new minimum sample is useful only if it is later than the
+ * last one used. In this design the maximum lifetime of any
+ * sample is not greater than eight times the poll interval, so
+ * the maximum interval between minimum samples is eight
+ * packets.
+ */
+ if (peer->filter_epoch[k] <= peer->epoch) {
+ DPRINTF(2, ("clock_filter: old sample %lu\n", current_time -
+ peer->filter_epoch[k]));
+ return;
+ }
+ peer->epoch = peer->filter_epoch[k];
+
+ /*
+ * The mitigated sample statistics are saved for later
+ * processing. If not synchronized or not in a burst, tickle the
+ * clock select algorithm.
+ */
+ record_peer_stats(&peer->srcadr, ctlpeerstatus(peer),
+ peer->offset, peer->delay, peer->disp, peer->jitter);
+ DPRINTF(1, ("clock_filter: n %d off %.6f del %.6f dsp %.6f jit %.6f\n",
+ m, peer->offset, peer->delay, peer->disp,
+ peer->jitter));
+ if (peer->burst == 0 || sys_leap == LEAP_NOTINSYNC)
+ clock_select();
+}
+
+
+/*
+ * clock_select - find the pick-of-the-litter clock
+ *
+ * LOCKCLOCK: (1) If the local clock is the prefer peer, it will always
+ * be enabled, even if declared falseticker, (2) only the prefer peer
+ * can be selected as the system peer, (3) if the external source is
+ * down, the system leap bits are set to 11 and the stratum set to
+ * infinity.
+ */
+void
+clock_select(void)
+{
+ struct peer *peer;
+ int i, j, k, n;
+ int nlist, nl2;
+ int allow;
+ int speer;
+ double d, e, f, g;
+ double high, low;
+ double speermet;
+ double orphmet = 2.0 * U_INT32_MAX; /* 2x is greater than */
+ struct endpoint endp;
+ struct peer *osys_peer;
+ struct peer *sys_prefer = NULL; /* prefer peer */
+ struct peer *typesystem = NULL;
+ struct peer *typeorphan = NULL;
+#ifdef REFCLOCK
+ struct peer *typeacts = NULL;
+ struct peer *typelocal = NULL;
+ struct peer *typepps = NULL;
+#endif /* REFCLOCK */
+ static struct endpoint *endpoint = NULL;
+ static int *indx = NULL;
+ static peer_select *peers = NULL;
+ static u_int endpoint_size = 0;
+ static u_int peers_size = 0;
+ static u_int indx_size = 0;
+ size_t octets;
+
+ /*
+ * Initialize and create endpoint, index and peer lists big
+ * enough to handle all associations.
+ */
+ osys_peer = sys_peer;
+ sys_survivors = 0;
+#ifdef LOCKCLOCK
+ set_sys_leap(LEAP_NOTINSYNC);
+ sys_stratum = STRATUM_UNSPEC;
+ memcpy(&sys_refid, "DOWN", 4);
+#endif /* LOCKCLOCK */
+
+ /*
+ * Allocate dynamic space depending on the number of
+ * associations.
+ */
+ nlist = 1;
+ for (peer = peer_list; peer != NULL; peer = peer->p_link)
+ nlist++;
+ endpoint_size = ALIGNED_SIZE(nlist * 2 * sizeof(*endpoint));
+ peers_size = ALIGNED_SIZE(nlist * sizeof(*peers));
+ indx_size = ALIGNED_SIZE(nlist * 2 * sizeof(*indx));
+ octets = endpoint_size + peers_size + indx_size;
+ endpoint = erealloc(endpoint, octets);
+ peers = INC_ALIGNED_PTR(endpoint, endpoint_size);
+ indx = INC_ALIGNED_PTR(peers, peers_size);
+
+ /*
+ * Initially, we populate the island with all the rifraff peers
+ * that happen to be lying around. Those with seriously
+ * defective clocks are immediately booted off the island. Then,
+ * the falsetickers are culled and put to sea. The truechimers
+ * remaining are subject to repeated rounds where the most
+ * unpopular at each round is kicked off. When the population
+ * has dwindled to sys_minclock, the survivors split a million
+ * bucks and collectively crank the chimes.
+ */
+ nlist = nl2 = 0; /* none yet */
+ for (peer = peer_list; peer != NULL; peer = peer->p_link) {
+ peer->new_status = CTL_PST_SEL_REJECT;
+
+ /*
+ * Leave the island immediately if the peer is
+ * unfit to synchronize.
+ */
+ if (peer_unfit(peer)) {
+ continue;
+ }
+
+ /*
+ * If this peer is an orphan parent, elect the
+ * one with the lowest metric defined as the
+ * IPv4 address or the first 64 bits of the
+ * hashed IPv6 address. To ensure convergence
+ * on the same selected orphan, consider as
+ * well that this system may have the lowest
+ * metric and be the orphan parent. If this
+ * system wins, sys_peer will be NULL to trigger
+ * orphan mode in timer().
+ */
+ if (peer->stratum == sys_orphan) {
+ u_int32 localmet;
+ u_int32 peermet;
+
+ if (peer->dstadr != NULL)
+ localmet = ntohl(peer->dstadr->addr_refid);
+ else
+ localmet = U_INT32_MAX;
+ peermet = ntohl(addr2refid(&peer->srcadr));
+ if (peermet < localmet && peermet < orphmet) {
+ typeorphan = peer;
+ orphmet = peermet;
+ }
+ continue;
+ }
+
+ /*
+ * If this peer could have the orphan parent
+ * as a synchronization ancestor, exclude it
+ * from selection to avoid forming a
+ * synchronization loop within the orphan mesh,
+ * triggering stratum climb to infinity
+ * instability. Peers at stratum higher than
+ * the orphan stratum could have the orphan
+ * parent in ancestry so are excluded.
+ * See http://bugs.ntp.org/2050
+ */
+ if (peer->stratum > sys_orphan) {
+ continue;
+ }
+#ifdef REFCLOCK
+ /*
+ * The following are special cases. We deal
+ * with them later.
+ */
+ if (!(peer->flags & FLAG_PREFER)) {
+ switch (peer->refclktype) {
+ case REFCLK_LOCALCLOCK:
+ if ( current_time > orphwait
+ && typelocal == NULL)
+ typelocal = peer;
+ continue;
+
+ case REFCLK_ACTS:
+ if ( current_time > orphwait
+ && typeacts == NULL)
+ typeacts = peer;
+ continue;
+ }
+ }
+#endif /* REFCLOCK */
+
+ /*
+ * If we get this far, the peer can stay on the
+ * island, but does not yet have the immunity
+ * idol.
+ */
+ peer->new_status = CTL_PST_SEL_SANE;
+ f = root_distance(peer);
+ peers[nlist].peer = peer;
+ peers[nlist].error = peer->jitter;
+ peers[nlist].synch = f;
+ nlist++;
+
+ /*
+ * Insert each interval endpoint on the unsorted
+ * endpoint[] list.
+ */
+ e = peer->offset;
+ endpoint[nl2].type = -1; /* lower end */
+ endpoint[nl2].val = e - f;
+ nl2++;
+ endpoint[nl2].type = 1; /* upper end */
+ endpoint[nl2].val = e + f;
+ nl2++;
+ }
+ /*
+ * Construct sorted indx[] of endpoint[] indexes ordered by
+ * offset.
+ */
+ for (i = 0; i < nl2; i++)
+ indx[i] = i;
+ for (i = 0; i < nl2; i++) {
+ endp = endpoint[indx[i]];
+ e = endp.val;
+ k = i;
+ for (j = i + 1; j < nl2; j++) {
+ endp = endpoint[indx[j]];
+ if (endp.val < e) {
+ e = endp.val;
+ k = j;
+ }
+ }
+ if (k != i) {
+ j = indx[k];
+ indx[k] = indx[i];
+ indx[i] = j;
+ }
+ }
+ for (i = 0; i < nl2; i++)
+ DPRINTF(3, ("select: endpoint %2d %.6f\n",
+ endpoint[indx[i]].type, endpoint[indx[i]].val));
+
+ /*
+ * This is the actual algorithm that cleaves the truechimers
+ * from the falsetickers. The original algorithm was described
+ * in Keith Marzullo's dissertation, but has been modified for
+ * better accuracy.
+ *
+ * Briefly put, we first assume there are no falsetickers, then
+ * scan the candidate list first from the low end upwards and
+ * then from the high end downwards. The scans stop when the
+ * number of intersections equals the number of candidates less
+ * the number of falsetickers. If this doesn't happen for a
+ * given number of falsetickers, we bump the number of
+ * falsetickers and try again. If the number of falsetickers
+ * becomes equal to or greater than half the number of
+ * candidates, the Albanians have won the Byzantine wars and
+ * correct synchronization is not possible.
+ *
+ * Here, nlist is the number of candidates and allow is the
+ * number of falsetickers. Upon exit, the truechimers are the
+ * survivors with offsets not less than low and not greater than
+ * high. There may be none of them.
+ */
+ low = 1e9;
+ high = -1e9;
+ for (allow = 0; 2 * allow < nlist; allow++) {
+
+ /*
+ * Bound the interval (low, high) as the smallest
+ * interval containing points from the most sources.
+ */
+ n = 0;
+ for (i = 0; i < nl2; i++) {
+ low = endpoint[indx[i]].val;
+ n -= endpoint[indx[i]].type;
+ if (n >= nlist - allow)
+ break;
+ }
+ n = 0;
+ for (j = nl2 - 1; j >= 0; j--) {
+ high = endpoint[indx[j]].val;
+ n += endpoint[indx[j]].type;
+ if (n >= nlist - allow)
+ break;
+ }
+
+ /*
+ * If an interval containing truechimers is found, stop.
+ * If not, increase the number of falsetickers and go
+ * around again.
+ */
+ if (high > low)
+ break;
+ }
+
+ /*
+ * Clustering algorithm. Whittle candidate list of falsetickers,
+ * who leave the island immediately. The TRUE peer is always a
+ * truechimer. We must leave at least one peer to collect the
+ * million bucks.
+ *
+ * We assert the correct time is contained in the interval, but
+ * the best offset estimate for the interval might not be
+ * contained in the interval. For this purpose, a truechimer is
+ * defined as the midpoint of an interval that overlaps the
+ * intersection interval.
+ */
+ j = 0;
+ for (i = 0; i < nlist; i++) {
+ double h;
+
+ peer = peers[i].peer;
+ h = peers[i].synch;
+ if (( high <= low
+ || peer->offset + h < low
+ || peer->offset - h > high
+ ) && !(peer->flags & FLAG_TRUE))
+ continue;
+
+#ifdef REFCLOCK
+ /*
+ * Eligible PPS peers must survive the intersection
+ * algorithm. Use the first one found, but don't
+ * include any of them in the cluster population.
+ */
+ if (peer->flags & FLAG_PPS) {
+ if (typepps == NULL)
+ typepps = peer;
+ if (!(peer->flags & FLAG_TSTAMP_PPS))
+ continue;
+ }
+#endif /* REFCLOCK */
+
+ if (j != i)
+ peers[j] = peers[i];
+ j++;
+ }
+ nlist = j;
+
+ /*
+ * If no survivors remain at this point, check if the modem
+ * driver, local driver or orphan parent in that order. If so,
+ * nominate the first one found as the only survivor.
+ * Otherwise, give up and leave the island to the rats.
+ */
+ if (nlist == 0) {
+ peers[0].error = 0;
+ peers[0].synch = sys_mindisp;
+#ifdef REFCLOCK
+ if (typeacts != NULL) {
+ peers[0].peer = typeacts;
+ nlist = 1;
+ } else if (typelocal != NULL) {
+ peers[0].peer = typelocal;
+ nlist = 1;
+ } else
+#endif /* REFCLOCK */
+ if (typeorphan != NULL) {
+ peers[0].peer = typeorphan;
+ nlist = 1;
+ }
+ }
+
+ /*
+ * Mark the candidates at this point as truechimers.
+ */
+ for (i = 0; i < nlist; i++) {
+ peers[i].peer->new_status = CTL_PST_SEL_SELCAND;
+ DPRINTF(2, ("select: survivor %s %f\n",
+ stoa(&peers[i].peer->srcadr), peers[i].synch));
+ }
+
+ /*
+ * Now, vote outliers off the island by select jitter weighted
+ * by root distance. Continue voting as long as there are more
+ * than sys_minclock survivors and the select jitter of the peer
+ * with the worst metric is greater than the minimum peer
+ * jitter. Stop if we are about to discard a TRUE or PREFER
+ * peer, who of course have the immunity idol.
+ */
+ while (1) {
+ d = 1e9;
+ e = -1e9;
+ g = 0;
+ k = 0;
+ for (i = 0; i < nlist; i++) {
+ if (peers[i].error < d)
+ d = peers[i].error;
+ peers[i].seljit = 0;
+ if (nlist > 1) {
+ f = 0;
+ for (j = 0; j < nlist; j++)
+ f += DIFF(peers[j].peer->offset,
+ peers[i].peer->offset);
+ peers[i].seljit = SQRT(f / (nlist - 1));
+ }
+ if (peers[i].seljit * peers[i].synch > e) {
+ g = peers[i].seljit;
+ e = peers[i].seljit * peers[i].synch;
+ k = i;
+ }
+ }
+ g = max(g, LOGTOD(sys_precision));
+ if ( nlist <= max(1, sys_minclock)
+ || g <= d
+ || ((FLAG_TRUE | FLAG_PREFER) & peers[k].peer->flags))
+ break;
+
+ DPRINTF(3, ("select: drop %s seljit %.6f jit %.6f\n",
+ ntoa(&peers[k].peer->srcadr), g, d));
+ if (nlist > sys_maxclock)
+ peers[k].peer->new_status = CTL_PST_SEL_EXCESS;
+ for (j = k + 1; j < nlist; j++)
+ peers[j - 1] = peers[j];
+ nlist--;
+ }
+
+ /*
+ * What remains is a list usually not greater than sys_minclock
+ * peers. Note that unsynchronized peers cannot survive this
+ * far. Count and mark these survivors.
+ *
+ * While at it, count the number of leap warning bits found.
+ * This will be used later to vote the system leap warning bit.
+ * If a leap warning bit is found on a reference clock, the vote
+ * is always won.
+ *
+ * Choose the system peer using a hybrid metric composed of the
+ * selection jitter scaled by the root distance augmented by
+ * stratum scaled by sys_mindisp (.001 by default). The goal of
+ * the small stratum factor is to avoid clockhop between a
+ * reference clock and a network peer which has a refclock and
+ * is using an older ntpd, which does not floor sys_rootdisp at
+ * sys_mindisp.
+ *
+ * In contrast, ntpd 4.2.6 and earlier used stratum primarily
+ * in selecting the system peer, using a weight of 1 second of
+ * additional root distance per stratum. This heavy bias is no
+ * longer appropriate, as the scaled root distance provides a
+ * more rational metric carrying the cumulative error budget.
+ */
+ e = 1e9;
+ speer = 0;
+ leap_vote_ins = 0;
+ leap_vote_del = 0;
+ for (i = 0; i < nlist; i++) {
+ peer = peers[i].peer;
+ peer->unreach = 0;
+ peer->new_status = CTL_PST_SEL_SYNCCAND;
+ sys_survivors++;
+ if (peer->leap == LEAP_ADDSECOND) {
+ if (peer->flags & FLAG_REFCLOCK)
+ leap_vote_ins = nlist;
+ else if (leap_vote_ins < nlist)
+ leap_vote_ins++;
+ }
+ if (peer->leap == LEAP_DELSECOND) {
+ if (peer->flags & FLAG_REFCLOCK)
+ leap_vote_del = nlist;
+ else if (leap_vote_del < nlist)
+ leap_vote_del++;
+ }
+ if (peer->flags & FLAG_PREFER)
+ sys_prefer = peer;
+ speermet = peers[i].seljit * peers[i].synch +
+ peer->stratum * sys_mindisp;
+ if (speermet < e) {
+ e = speermet;
+ speer = i;
+ }
+ }
+
+ /*
+ * Unless there are at least sys_misane survivors, leave the
+ * building dark. Otherwise, do a clockhop dance. Ordinarily,
+ * use the selected survivor speer. However, if the current
+ * system peer is not speer, stay with the current system peer
+ * as long as it doesn't get too old or too ugly.
+ */
+ if (nlist > 0 && nlist >= sys_minsane) {
+ double x;
+
+ typesystem = peers[speer].peer;
+ if (osys_peer == NULL || osys_peer == typesystem) {
+ sys_clockhop = 0;
+ } else if ((x = fabs(typesystem->offset -
+ osys_peer->offset)) < sys_mindisp) {
+ if (sys_clockhop == 0)
+ sys_clockhop = sys_mindisp;
+ else
+ sys_clockhop *= .5;
+ DPRINTF(1, ("select: clockhop %d %.6f %.6f\n",
+ j, x, sys_clockhop));
+ if (fabs(x) < sys_clockhop)
+ typesystem = osys_peer;
+ else
+ sys_clockhop = 0;
+ } else {
+ sys_clockhop = 0;
+ }
+ }
+
+ /*
+ * Mitigation rules of the game. We have the pick of the
+ * litter in typesystem if any survivors are left. If
+ * there is a prefer peer, use its offset and jitter.
+ * Otherwise, use the combined offset and jitter of all kitters.
+ */
+ if (typesystem != NULL) {
+ if (sys_prefer == NULL) {
+ typesystem->new_status = CTL_PST_SEL_SYSPEER;
+ clock_combine(peers, sys_survivors, speer);
+ } else {
+ typesystem = sys_prefer;
+ sys_clockhop = 0;
+ typesystem->new_status = CTL_PST_SEL_SYSPEER;
+ sys_offset = typesystem->offset;
+ sys_jitter = typesystem->jitter;
+ }
+ DPRINTF(1, ("select: combine offset %.9f jitter %.9f\n",
+ sys_offset, sys_jitter));
+ }
+#ifdef REFCLOCK
+ /*
+ * If a PPS driver is lit and the combined offset is less than
+ * 0.4 s, select the driver as the PPS peer and use its offset
+ * and jitter. However, if this is the atom driver, use it only
+ * if there is a prefer peer or there are no survivors and none
+ * are required.
+ */
+ if ( typepps != NULL
+ && fabs(sys_offset) < 0.4
+ && ( typepps->refclktype != REFCLK_ATOM_PPS
+ || ( typepps->refclktype == REFCLK_ATOM_PPS
+ && ( sys_prefer != NULL
+ || (typesystem == NULL && sys_minsane == 0))))) {
+ typesystem = typepps;
+ sys_clockhop = 0;
+ typesystem->new_status = CTL_PST_SEL_PPS;
+ sys_offset = typesystem->offset;
+ sys_jitter = typesystem->jitter;
+ DPRINTF(1, ("select: pps offset %.9f jitter %.9f\n",
+ sys_offset, sys_jitter));
+ }
+#endif /* REFCLOCK */
+
+ /*
+ * If there are no survivors at this point, there is no
+ * system peer. If so and this is an old update, keep the
+ * current statistics, but do not update the clock.
+ */
+ if (typesystem == NULL) {
+ if (osys_peer != NULL) {
+ if (sys_orphwait > 0)
+ orphwait = current_time + sys_orphwait;
+ report_event(EVNT_NOPEER, NULL, NULL);
+ }
+ sys_peer = NULL;
+ for (peer = peer_list; peer != NULL; peer = peer->p_link)
+ peer->status = peer->new_status;
+ return;
+ }
+
+ /*
+ * Do not use old data, as this may mess up the clock discipline
+ * stability.
+ */
+ if (typesystem->epoch <= sys_epoch)
+ return;
+
+ /*
+ * We have found the alpha male. Wind the clock.
+ */
+ if (osys_peer != typesystem)
+ report_event(PEVNT_NEWPEER, typesystem, NULL);
+ for (peer = peer_list; peer != NULL; peer = peer->p_link)
+ peer->status = peer->new_status;
+ clock_update(typesystem);
+}
+
+
+static void
+clock_combine(
+ peer_select * peers, /* survivor list */
+ int npeers, /* number of survivors */
+ int syspeer /* index of sys.peer */
+ )
+{
+ int i;
+ double x, y, z, w;
+
+ y = z = w = 0;
+ for (i = 0; i < npeers; i++) {
+ x = 1. / peers[i].synch;
+ y += x;
+ z += x * peers[i].peer->offset;
+ w += x * DIFF(peers[i].peer->offset,
+ peers[syspeer].peer->offset);
+ }
+ sys_offset = z / y;
+ sys_jitter = SQRT(w / y + SQUARE(peers[syspeer].seljit));
+}
+
+
+/*
+ * root_distance - compute synchronization distance from peer to root
+ */
+static double
+root_distance(
+ struct peer *peer /* peer structure pointer */
+ )
+{
+ double dtemp;
+
+ /*
+ * Root Distance (LAMBDA) is defined as:
+ * (delta + DELTA)/2 + epsilon + EPSILON + D
+ *
+ * where:
+ * delta is the round-trip delay
+ * DELTA is the root delay
+ * epsilon is the peer dispersion
+ * + (15 usec each second)
+ * EPSILON is the root dispersion
+ * D is sys_jitter
+ *
+ * NB: Think hard about why we are using these values, and what
+ * the alternatives are, and the various pros/cons.
+ *
+ * DLM thinks these are probably the best choices from any of the
+ * other worse choices.
+ */
+ dtemp = (peer->delay + peer->rootdelay) / 2
+ + peer->disp
+ + clock_phi * (current_time - peer->update)
+ + peer->rootdisp
+ + peer->jitter;
+ /*
+ * Careful squeak here. The value returned must be greater than
+ * the minimum root dispersion in order to avoid clockhop with
+ * highly precise reference clocks. Note that the root distance
+ * cannot exceed the sys_maxdist, as this is the cutoff by the
+ * selection algorithm.
+ */
+ if (dtemp < sys_mindisp)
+ dtemp = sys_mindisp;
+ return (dtemp);
+}
+
+
+/*
+ * peer_xmit - send packet for persistent association.
+ */
+static void
+peer_xmit(
+ struct peer *peer /* peer structure pointer */
+ )
+{
+ struct pkt xpkt; /* transmit packet */
+ size_t sendlen, authlen;
+ keyid_t xkeyid = 0; /* transmit key ID */
+ l_fp xmt_tx, xmt_ty;
+
+ if (!peer->dstadr) /* drop peers without interface */
+ return;
+
+ xpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap, peer->version,
+ peer->hmode);
+ xpkt.stratum = STRATUM_TO_PKT(sys_stratum);
+ xpkt.ppoll = peer->hpoll;
+ xpkt.precision = sys_precision;
+ xpkt.refid = sys_refid;
+ xpkt.rootdelay = HTONS_FP(DTOFP(sys_rootdelay));
+ xpkt.rootdisp = HTONS_FP(DTOUFP(sys_rootdisp));
+ HTONL_FP(&sys_reftime, &xpkt.reftime);
+ HTONL_FP(&peer->rec, &xpkt.org);
+ HTONL_FP(&peer->dst, &xpkt.rec);
+
+ /*
+ * If the received packet contains a MAC, the transmitted packet
+ * is authenticated and contains a MAC. If not, the transmitted
+ * packet is not authenticated.
+ *
+ * It is most important when autokey is in use that the local
+ * interface IP address be known before the first packet is
+ * sent. Otherwise, it is not possible to compute a correct MAC
+ * the recipient will accept. Thus, the I/O semantics have to do
+ * a little more work. In particular, the wildcard interface
+ * might not be usable.
+ */
+ sendlen = LEN_PKT_NOMAC;
+ if (
+#ifdef AUTOKEY
+ !(peer->flags & FLAG_SKEY) &&
+#endif /* !AUTOKEY */
+ peer->keyid == 0) {
+
+ /*
+ * Transmit a-priori timestamps
+ */
+ get_systime(&xmt_tx);
+ if (peer->flip == 0) { /* basic mode */
+ peer->aorg = xmt_tx;
+ HTONL_FP(&xmt_tx, &xpkt.xmt);
+ } else { /* interleaved modes */
+ if (peer->hmode == MODE_BROADCAST) { /* bcst */
+ HTONL_FP(&xmt_tx, &xpkt.xmt);
+ if (peer->flip > 0)
+ HTONL_FP(&peer->borg,
+ &xpkt.org);
+ else
+ HTONL_FP(&peer->aorg,
+ &xpkt.org);
+ } else { /* symmetric */
+ if (peer->flip > 0)
+ HTONL_FP(&peer->borg,
+ &xpkt.xmt);
+ else
+ HTONL_FP(&peer->aorg,
+ &xpkt.xmt);
+ }
+ }
+ peer->t21_bytes = sendlen;
+ sendpkt(&peer->srcadr, peer->dstadr,
+ sys_ttl[(peer->ttl >= sys_ttlmax) ? sys_ttlmax : peer->ttl],
+ &xpkt, sendlen);
+ peer->sent++;
+ peer->throttle += (1 << peer->minpoll) - 2;
+
+ /*
+ * Capture a-posteriori timestamps
+ */
+ get_systime(&xmt_ty);
+ if (peer->flip != 0) { /* interleaved modes */
+ if (peer->flip > 0)
+ peer->aorg = xmt_ty;
+ else
+ peer->borg = xmt_ty;
+ peer->flip = -peer->flip;
+ }
+ L_SUB(&xmt_ty, &xmt_tx);
+ LFPTOD(&xmt_ty, peer->xleave);
+ DPRINTF(1, ("peer_xmit: at %ld %s->%s mode %d len %zu xmt %#010x.%08x\n",
+ current_time,
+ peer->dstadr ? stoa(&peer->dstadr->sin) : "-",
+ stoa(&peer->srcadr), peer->hmode, sendlen,
+ xmt_tx.l_ui, xmt_tx.l_uf));
+ return;
+ }
+
+ /*
+ * Authentication is enabled, so the transmitted packet must be
+ * authenticated. If autokey is enabled, fuss with the various
+ * modes; otherwise, symmetric key cryptography is used.
+ */
+#ifdef AUTOKEY
+ if (peer->flags & FLAG_SKEY) {
+ struct exten *exten; /* extension field */
+
+ /*
+ * The Public Key Dance (PKD): Cryptographic credentials
+ * are contained in extension fields, each including a
+ * 4-octet length/code word followed by a 4-octet
+ * association ID and optional additional data. Optional
+ * data includes a 4-octet data length field followed by
+ * the data itself. Request messages are sent from a
+ * configured association; response messages can be sent
+ * from a configured association or can take the fast
+ * path without ever matching an association. Response
+ * messages have the same code as the request, but have
+ * a response bit and possibly an error bit set. In this
+ * implementation, a message may contain no more than
+ * one command and one or more responses.
+ *
+ * Cryptographic session keys include both a public and
+ * a private componet. Request and response messages
+ * using extension fields are always sent with the
+ * private component set to zero. Packets without
+ * extension fields indlude the private component when
+ * the session key is generated.
+ */
+ while (1) {
+
+ /*
+ * Allocate and initialize a keylist if not
+ * already done. Then, use the list in inverse
+ * order, discarding keys once used. Keep the
+ * latest key around until the next one, so
+ * clients can use client/server packets to
+ * compute propagation delay.
+ *
+ * Note that once a key is used from the list,
+ * it is retained in the key cache until the
+ * next key is used. This is to allow a client
+ * to retrieve the encrypted session key
+ * identifier to verify authenticity.
+ *
+ * If for some reason a key is no longer in the
+ * key cache, a birthday has happened or the key
+ * has expired, so the pseudo-random sequence is
+ * broken. In that case, purge the keylist and
+ * regenerate it.
+ */
+ if (peer->keynumber == 0)
+ make_keylist(peer, peer->dstadr);
+ else
+ peer->keynumber--;
+ xkeyid = peer->keylist[peer->keynumber];
+ if (authistrusted(xkeyid))
+ break;
+ else
+ key_expire(peer);
+ }
+ peer->keyid = xkeyid;
+ exten = NULL;
+ switch (peer->hmode) {
+
+ /*
+ * In broadcast server mode the autokey values are
+ * required by the broadcast clients. Push them when a
+ * new keylist is generated; otherwise, push the
+ * association message so the client can request them at
+ * other times.
+ */
+ case MODE_BROADCAST:
+ if (peer->flags & FLAG_ASSOC)
+ exten = crypto_args(peer, CRYPTO_AUTO |
+ CRYPTO_RESP, peer->associd, NULL);
+ else
+ exten = crypto_args(peer, CRYPTO_ASSOC |
+ CRYPTO_RESP, peer->associd, NULL);
+ break;
+
+ /*
+ * In symmetric modes the parameter, certificate,
+ * identity, cookie and autokey exchanges are
+ * required. The leapsecond exchange is optional. But, a
+ * peer will not believe the other peer until the other
+ * peer has synchronized, so the certificate exchange
+ * might loop until then. If a peer finds a broken
+ * autokey sequence, it uses the autokey exchange to
+ * retrieve the autokey values. In any case, if a new
+ * keylist is generated, the autokey values are pushed.
+ */
+ case MODE_ACTIVE:
+ case MODE_PASSIVE:
+
+ /*
+ * Parameter, certificate and identity.
+ */
+ if (!peer->crypto)
+ exten = crypto_args(peer, CRYPTO_ASSOC,
+ peer->associd, hostval.ptr);
+ else if (!(peer->crypto & CRYPTO_FLAG_CERT))
+ exten = crypto_args(peer, CRYPTO_CERT,
+ peer->associd, peer->issuer);
+ else if (!(peer->crypto & CRYPTO_FLAG_VRFY))
+ exten = crypto_args(peer,
+ crypto_ident(peer), peer->associd,
+ NULL);
+
+ /*
+ * Cookie and autokey. We request the cookie
+ * only when the this peer and the other peer
+ * are synchronized. But, this peer needs the
+ * autokey values when the cookie is zero. Any
+ * time we regenerate the key list, we offer the
+ * autokey values without being asked. If for
+ * some reason either peer finds a broken
+ * autokey sequence, the autokey exchange is
+ * used to retrieve the autokey values.
+ */
+ else if ( sys_leap != LEAP_NOTINSYNC
+ && peer->leap != LEAP_NOTINSYNC
+ && !(peer->crypto & CRYPTO_FLAG_COOK))
+ exten = crypto_args(peer, CRYPTO_COOK,
+ peer->associd, NULL);
+ else if (!(peer->crypto & CRYPTO_FLAG_AUTO))
+ exten = crypto_args(peer, CRYPTO_AUTO,
+ peer->associd, NULL);
+ else if ( peer->flags & FLAG_ASSOC
+ && peer->crypto & CRYPTO_FLAG_SIGN)
+ exten = crypto_args(peer, CRYPTO_AUTO |
+ CRYPTO_RESP, peer->assoc, NULL);
+
+ /*
+ * Wait for clock sync, then sign the
+ * certificate and retrieve the leapsecond
+ * values.
+ */
+ else if (sys_leap == LEAP_NOTINSYNC)
+ break;
+
+ else if (!(peer->crypto & CRYPTO_FLAG_SIGN))
+ exten = crypto_args(peer, CRYPTO_SIGN,
+ peer->associd, hostval.ptr);
+ else if (!(peer->crypto & CRYPTO_FLAG_LEAP))
+ exten = crypto_args(peer, CRYPTO_LEAP,
+ peer->associd, NULL);
+ break;
+
+ /*
+ * In client mode the parameter, certificate, identity,
+ * cookie and sign exchanges are required. The
+ * leapsecond exchange is optional. If broadcast client
+ * mode the same exchanges are required, except that the
+ * autokey exchange is substitutes for the cookie
+ * exchange, since the cookie is always zero. If the
+ * broadcast client finds a broken autokey sequence, it
+ * uses the autokey exchange to retrieve the autokey
+ * values.
+ */
+ case MODE_CLIENT:
+
+ /*
+ * Parameter, certificate and identity.
+ */
+ if (!peer->crypto)
+ exten = crypto_args(peer, CRYPTO_ASSOC,
+ peer->associd, hostval.ptr);
+ else if (!(peer->crypto & CRYPTO_FLAG_CERT))
+ exten = crypto_args(peer, CRYPTO_CERT,
+ peer->associd, peer->issuer);
+ else if (!(peer->crypto & CRYPTO_FLAG_VRFY))
+ exten = crypto_args(peer,
+ crypto_ident(peer), peer->associd,
+ NULL);
+
+ /*
+ * Cookie and autokey. These are requests, but
+ * we use the peer association ID with autokey
+ * rather than our own.
+ */
+ else if (!(peer->crypto & CRYPTO_FLAG_COOK))
+ exten = crypto_args(peer, CRYPTO_COOK,
+ peer->associd, NULL);
+ else if (!(peer->crypto & CRYPTO_FLAG_AUTO))
+ exten = crypto_args(peer, CRYPTO_AUTO,
+ peer->assoc, NULL);
+
+ /*
+ * Wait for clock sync, then sign the
+ * certificate and retrieve the leapsecond
+ * values.
+ */
+ else if (sys_leap == LEAP_NOTINSYNC)
+ break;
+
+ else if (!(peer->crypto & CRYPTO_FLAG_SIGN))
+ exten = crypto_args(peer, CRYPTO_SIGN,
+ peer->associd, hostval.ptr);
+ else if (!(peer->crypto & CRYPTO_FLAG_LEAP))
+ exten = crypto_args(peer, CRYPTO_LEAP,
+ peer->associd, NULL);
+ break;
+ }
+
+ /*
+ * Add a queued extension field if present. This is
+ * always a request message, so the reply ID is already
+ * in the message. If an error occurs, the error bit is
+ * lit in the response.
+ */
+ if (peer->cmmd != NULL) {
+ u_int32 temp32;
+
+ temp32 = CRYPTO_RESP;
+ peer->cmmd->opcode |= htonl(temp32);
+ sendlen += crypto_xmit(peer, &xpkt, NULL,
+ sendlen, peer->cmmd, 0);
+ free(peer->cmmd);
+ peer->cmmd = NULL;
+ }
+
+ /*
+ * Add an extension field created above. All but the
+ * autokey response message are request messages.
+ */
+ if (exten != NULL) {
+ if (exten->opcode != 0)
+ sendlen += crypto_xmit(peer, &xpkt,
+ NULL, sendlen, exten, 0);
+ free(exten);
+ }
+
+ /*
+ * Calculate the next session key. Since extension
+ * fields are present, the cookie value is zero.
+ */
+ if (sendlen > (int)LEN_PKT_NOMAC) {
+ session_key(&peer->dstadr->sin, &peer->srcadr,
+ xkeyid, 0, 2);
+ }
+ }
+#endif /* AUTOKEY */
+
+ /*
+ * Transmit a-priori timestamps
+ */
+ get_systime(&xmt_tx);
+ if (peer->flip == 0) { /* basic mode */
+ peer->aorg = xmt_tx;
+ HTONL_FP(&xmt_tx, &xpkt.xmt);
+ } else { /* interleaved modes */
+ if (peer->hmode == MODE_BROADCAST) { /* bcst */
+ HTONL_FP(&xmt_tx, &xpkt.xmt);
+ if (peer->flip > 0)
+ HTONL_FP(&peer->borg, &xpkt.org);
+ else
+ HTONL_FP(&peer->aorg, &xpkt.org);
+ } else { /* symmetric */
+ if (peer->flip > 0)
+ HTONL_FP(&peer->borg, &xpkt.xmt);
+ else
+ HTONL_FP(&peer->aorg, &xpkt.xmt);
+ }
+ }
+ xkeyid = peer->keyid;
+ authlen = authencrypt(xkeyid, (u_int32 *)&xpkt, sendlen);
+ if (authlen == 0) {
+ report_event(PEVNT_AUTH, peer, "no key");
+ peer->flash |= TEST5; /* auth error */
+ peer->badauth++;
+ return;
+ }
+ sendlen += authlen;
+#ifdef AUTOKEY
+ if (xkeyid > NTP_MAXKEY)
+ authtrust(xkeyid, 0);
+#endif /* AUTOKEY */
+ if (sendlen > sizeof(xpkt)) {
+ msyslog(LOG_ERR, "peer_xmit: buffer overflow %zu", sendlen);
+ exit (-1);
+ }
+ peer->t21_bytes = sendlen;
+ sendpkt(&peer->srcadr, peer->dstadr,
+ sys_ttl[(peer->ttl >= sys_ttlmax) ? sys_ttlmax : peer->ttl],
+ &xpkt, sendlen);
+ peer->sent++;
+ peer->throttle += (1 << peer->minpoll) - 2;
+
+ /*
+ * Capture a-posteriori timestamps
+ */
+ get_systime(&xmt_ty);
+ if (peer->flip != 0) { /* interleaved modes */
+ if (peer->flip > 0)
+ peer->aorg = xmt_ty;
+ else
+ peer->borg = xmt_ty;
+ peer->flip = -peer->flip;
+ }
+ L_SUB(&xmt_ty, &xmt_tx);
+ LFPTOD(&xmt_ty, peer->xleave);
+#ifdef AUTOKEY
+ DPRINTF(1, ("peer_xmit: at %ld %s->%s mode %d keyid %08x len %zu index %d\n",
+ current_time, latoa(peer->dstadr),
+ ntoa(&peer->srcadr), peer->hmode, xkeyid, sendlen,
+ peer->keynumber));
+#else /* !AUTOKEY follows */
+ DPRINTF(1, ("peer_xmit: at %ld %s->%s mode %d keyid %08x len %zu\n",
+ current_time, peer->dstadr ?
+ ntoa(&peer->dstadr->sin) : "-",
+ ntoa(&peer->srcadr), peer->hmode, xkeyid, sendlen));
+#endif /* !AUTOKEY */
+
+ return;
+}
+
+
+#ifdef LEAP_SMEAR
+
+static void
+leap_smear_add_offs(
+ l_fp *t,
+ l_fp *t_recv
+ )
+{
+
+ L_ADD(t, &leap_smear.offset);
+
+ /*
+ ** XXX: Should the smear be added to the root dispersion?
+ */
+
+ return;
+}
+
+#endif /* LEAP_SMEAR */
+
+
+/*
+ * fast_xmit - Send packet for nonpersistent association. Note that
+ * neither the source or destination can be a broadcast address.
+ */
+static void
+fast_xmit(
+ struct recvbuf *rbufp, /* receive packet pointer */
+ int xmode, /* receive mode */
+ keyid_t xkeyid, /* transmit key ID */
+ int flags /* restrict mask */
+ )
+{
+ struct pkt xpkt; /* transmit packet structure */
+ struct pkt *rpkt; /* receive packet structure */
+ l_fp xmt_tx, xmt_ty;
+ size_t sendlen;
+#ifdef AUTOKEY
+ u_int32 temp32;
+#endif
+
+ /*
+ * Initialize transmit packet header fields from the receive
+ * buffer provided. We leave the fields intact as received, but
+ * set the peer poll at the maximum of the receive peer poll and
+ * the system minimum poll (ntp_minpoll). This is for KoD rate
+ * control and not strictly specification compliant, but doesn't
+ * break anything.
+ *
+ * If the gazinta was from a multicast address, the gazoutta
+ * must go out another way.
+ */
+ rpkt = &rbufp->recv_pkt;
+ if (rbufp->dstadr->flags & INT_MCASTOPEN)
+ rbufp->dstadr = findinterface(&rbufp->recv_srcadr);
+
+ /*
+ * If this is a kiss-o'-death (KoD) packet, show leap
+ * unsynchronized, stratum zero, reference ID the four-character
+ * kiss code and system root delay. Note we don't reveal the
+ * local time, so these packets can't be used for
+ * synchronization.
+ */
+ if (flags & RES_KOD) {
+ sys_kodsent++;
+ xpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOTINSYNC,
+ PKT_VERSION(rpkt->li_vn_mode), xmode);
+ xpkt.stratum = STRATUM_PKT_UNSPEC;
+ xpkt.ppoll = max(rpkt->ppoll, ntp_minpoll);
+ xpkt.precision = rpkt->precision;
+ memcpy(&xpkt.refid, "RATE", 4);
+ xpkt.rootdelay = rpkt->rootdelay;
+ xpkt.rootdisp = rpkt->rootdisp;
+ xpkt.reftime = rpkt->reftime;
+ xpkt.org = rpkt->xmt;
+ xpkt.rec = rpkt->xmt;
+ xpkt.xmt = rpkt->xmt;
+
+ /*
+ * This is a normal packet. Use the system variables.
+ */
+ } else {
+#ifdef LEAP_SMEAR
+ /*
+ * Make copies of the variables which can be affected by smearing.
+ */
+ l_fp this_ref_time;
+ l_fp this_recv_time;
+#endif
+
+ /*
+ * If we are inside the leap smear interval we add the current smear offset to
+ * the packet receive time, to the packet transmit time, and eventually to the
+ * reftime to make sure the reftime isn't later than the transmit/receive times.
+ */
+ xpkt.li_vn_mode = PKT_LI_VN_MODE(xmt_leap,
+ PKT_VERSION(rpkt->li_vn_mode), xmode);
+
+ xpkt.stratum = STRATUM_TO_PKT(sys_stratum);
+ xpkt.ppoll = max(rpkt->ppoll, ntp_minpoll);
+ xpkt.precision = sys_precision;
+ xpkt.refid = sys_refid;
+ xpkt.rootdelay = HTONS_FP(DTOFP(sys_rootdelay));
+ xpkt.rootdisp = HTONS_FP(DTOUFP(sys_rootdisp));
+
+#ifdef LEAP_SMEAR
+ this_ref_time = sys_reftime;
+ if (leap_smear.in_progress) {
+ leap_smear_add_offs(&this_ref_time, NULL);
+ xpkt.refid = convertLFPToRefID(leap_smear.offset);
+ DPRINTF(2, ("fast_xmit: leap_smear.in_progress: refid %8x, smear %s\n",
+ ntohl(xpkt.refid),
+ lfptoa(&leap_smear.offset, 8)
+ ));
+ }
+ HTONL_FP(&this_ref_time, &xpkt.reftime);
+#else
+ HTONL_FP(&sys_reftime, &xpkt.reftime);
+#endif
+
+ xpkt.org = rpkt->xmt;
+
+#ifdef LEAP_SMEAR
+ this_recv_time = rbufp->recv_time;
+ if (leap_smear.in_progress)
+ leap_smear_add_offs(&this_recv_time, NULL);
+ HTONL_FP(&this_recv_time, &xpkt.rec);
+#else
+ HTONL_FP(&rbufp->recv_time, &xpkt.rec);
+#endif
+
+ get_systime(&xmt_tx);
+#ifdef LEAP_SMEAR
+ if (leap_smear.in_progress)
+ leap_smear_add_offs(&xmt_tx, &this_recv_time);
+#endif
+ HTONL_FP(&xmt_tx, &xpkt.xmt);
+ }
+
+#ifdef HAVE_NTP_SIGND
+ if (flags & RES_MSSNTP) {
+ send_via_ntp_signd(rbufp, xmode, xkeyid, flags, &xpkt);
+ return;
+ }
+#endif /* HAVE_NTP_SIGND */
+
+ /*
+ * If the received packet contains a MAC, the transmitted packet
+ * is authenticated and contains a MAC. If not, the transmitted
+ * packet is not authenticated.
+ */
+ sendlen = LEN_PKT_NOMAC;
+ if (rbufp->recv_length == sendlen) {
+ sendpkt(&rbufp->recv_srcadr, rbufp->dstadr, 0, &xpkt,
+ sendlen);
+ DPRINTF(1, ("fast_xmit: at %ld %s->%s mode %d len %lu\n",
+ current_time, stoa(&rbufp->dstadr->sin),
+ stoa(&rbufp->recv_srcadr), xmode,
+ (u_long)sendlen));
+ return;
+ }
+
+ /*
+ * The received packet contains a MAC, so the transmitted packet
+ * must be authenticated. For symmetric key cryptography, use
+ * the predefined and trusted symmetric keys to generate the
+ * cryptosum. For autokey cryptography, use the server private
+ * value to generate the cookie, which is unique for every
+ * source-destination-key ID combination.
+ */
+#ifdef AUTOKEY
+ if (xkeyid > NTP_MAXKEY) {
+ keyid_t cookie;
+
+ /*
+ * The only way to get here is a reply to a legitimate
+ * client request message, so the mode must be
+ * MODE_SERVER. If an extension field is present, there
+ * can be only one and that must be a command. Do what
+ * needs, but with private value of zero so the poor
+ * jerk can decode it. If no extension field is present,
+ * use the cookie to generate the session key.
+ */
+ cookie = session_key(&rbufp->recv_srcadr,
+ &rbufp->dstadr->sin, 0, sys_private, 0);
+ if ((size_t)rbufp->recv_length > sendlen + MAX_MAC_LEN) {
+ session_key(&rbufp->dstadr->sin,
+ &rbufp->recv_srcadr, xkeyid, 0, 2);
+ temp32 = CRYPTO_RESP;
+ rpkt->exten[0] |= htonl(temp32);
+ sendlen += crypto_xmit(NULL, &xpkt, rbufp,
+ sendlen, (struct exten *)rpkt->exten,
+ cookie);
+ } else {
+ session_key(&rbufp->dstadr->sin,
+ &rbufp->recv_srcadr, xkeyid, cookie, 2);
+ }
+ }
+#endif /* AUTOKEY */
+ get_systime(&xmt_tx);
+ sendlen += authencrypt(xkeyid, (u_int32 *)&xpkt, sendlen);
+#ifdef AUTOKEY
+ if (xkeyid > NTP_MAXKEY)
+ authtrust(xkeyid, 0);
+#endif /* AUTOKEY */
+ sendpkt(&rbufp->recv_srcadr, rbufp->dstadr, 0, &xpkt, sendlen);
+ get_systime(&xmt_ty);
+ L_SUB(&xmt_ty, &xmt_tx);
+ sys_authdelay = xmt_ty;
+ DPRINTF(1, ("fast_xmit: at %ld %s->%s mode %d keyid %08x len %lu\n",
+ current_time, ntoa(&rbufp->dstadr->sin),
+ ntoa(&rbufp->recv_srcadr), xmode, xkeyid,
+ (u_long)sendlen));
+}
+
+
+/*
+ * pool_xmit - resolve hostname or send unicast solicitation for pool.
+ */
+static void
+pool_xmit(
+ struct peer *pool /* pool solicitor association */
+ )
+{
+#ifdef WORKER
+ struct pkt xpkt; /* transmit packet structure */
+ struct addrinfo hints;
+ int rc;
+ struct interface * lcladr;
+ sockaddr_u * rmtadr;
+ r4addr r4a;
+ int restrict_mask;
+ struct peer * p;
+ l_fp xmt_tx;
+
+ if (NULL == pool->ai) {
+ if (pool->addrs != NULL) {
+ /* free() is used with copy_addrinfo_list() */
+ free(pool->addrs);
+ pool->addrs = NULL;
+ }
+ ZERO(hints);
+ hints.ai_family = AF(&pool->srcadr);
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_protocol = IPPROTO_UDP;
+ /* ignore getaddrinfo_sometime() errors, we will retry */
+ rc = getaddrinfo_sometime(
+ pool->hostname,
+ "ntp",
+ &hints,
+ 0, /* no retry */
+ &pool_name_resolved,
+ (void *)(intptr_t)pool->associd);
+ if (!rc)
+ DPRINTF(1, ("pool DNS lookup %s started\n",
+ pool->hostname));
+ else
+ msyslog(LOG_ERR,
+ "unable to start pool DNS %s: %m",
+ pool->hostname);
+ return;
+ }
+
+ do {
+ /* copy_addrinfo_list ai_addr points to a sockaddr_u */
+ rmtadr = (sockaddr_u *)(void *)pool->ai->ai_addr;
+ pool->ai = pool->ai->ai_next;
+ p = findexistingpeer(rmtadr, NULL, NULL, MODE_CLIENT, 0, NULL);
+ } while (p != NULL && pool->ai != NULL);
+ if (p != NULL)
+ return; /* out of addresses, re-query DNS next poll */
+ restrictions(rmtadr, &r4a);
+ restrict_mask = r4a.rflags;
+ if (RES_FLAGS & restrict_mask)
+ restrict_source(rmtadr, 0,
+ current_time + POOL_SOLICIT_WINDOW + 1);
+ lcladr = findinterface(rmtadr);
+ memset(&xpkt, 0, sizeof(xpkt));
+ xpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap, pool->version,
+ MODE_CLIENT);
+ xpkt.stratum = STRATUM_TO_PKT(sys_stratum);
+ xpkt.ppoll = pool->hpoll;
+ xpkt.precision = sys_precision;
+ xpkt.refid = sys_refid;
+ xpkt.rootdelay = HTONS_FP(DTOFP(sys_rootdelay));
+ xpkt.rootdisp = HTONS_FP(DTOUFP(sys_rootdisp));
+ HTONL_FP(&sys_reftime, &xpkt.reftime);
+ get_systime(&xmt_tx);
+ pool->aorg = xmt_tx;
+ HTONL_FP(&xmt_tx, &xpkt.xmt);
+ sendpkt(rmtadr, lcladr,
+ sys_ttl[(pool->ttl >= sys_ttlmax) ? sys_ttlmax : pool->ttl],
+ &xpkt, LEN_PKT_NOMAC);
+ pool->sent++;
+ pool->throttle += (1 << pool->minpoll) - 2;
+ DPRINTF(1, ("pool_xmit: at %ld %s->%s pool\n",
+ current_time, latoa(lcladr), stoa(rmtadr)));
+ msyslog(LOG_INFO, "Soliciting pool server %s", stoa(rmtadr));
+#endif /* WORKER */
+}
+
+
+#ifdef AUTOKEY
+ /*
+ * group_test - test if this is the same group
+ *
+ * host assoc return action
+ * none none 0 mobilize *
+ * none group 0 mobilize *
+ * group none 0 mobilize *
+ * group group 1 mobilize
+ * group different 1 ignore
+ * * ignore if notrust
+ */
+int
+group_test(
+ char *grp,
+ char *ident
+ )
+{
+ if (grp == NULL)
+ return (0);
+
+ if (strcmp(grp, sys_groupname) == 0)
+ return (0);
+
+ if (ident == NULL)
+ return (1);
+
+ if (strcmp(grp, ident) == 0)
+ return (0);
+
+ return (1);
+}
+#endif /* AUTOKEY */
+
+
+#ifdef WORKER
+void
+pool_name_resolved(
+ int rescode,
+ int gai_errno,
+ void * context,
+ const char * name,
+ const char * service,
+ const struct addrinfo * hints,
+ const struct addrinfo * res
+ )
+{
+ struct peer * pool; /* pool solicitor association */
+ associd_t assoc;
+
+ if (rescode) {
+ msyslog(LOG_ERR,
+ "error resolving pool %s: %s (%d)",
+ name, gai_strerror(rescode), rescode);
+ return;
+ }
+
+ assoc = (associd_t)(intptr_t)context;
+ pool = findpeerbyassoc(assoc);
+ if (NULL == pool) {
+ msyslog(LOG_ERR,
+ "Could not find assoc %u for pool DNS %s",
+ assoc, name);
+ return;
+ }
+ DPRINTF(1, ("pool DNS %s completed\n", name));
+ pool->addrs = copy_addrinfo_list(res);
+ pool->ai = pool->addrs;
+ pool_xmit(pool);
+
+}
+#endif /* WORKER */
+
+
+#ifdef AUTOKEY
+/*
+ * key_expire - purge the key list
+ */
+void
+key_expire(
+ struct peer *peer /* peer structure pointer */
+ )
+{
+ int i;
+
+ if (peer->keylist != NULL) {
+ for (i = 0; i <= peer->keynumber; i++)
+ authtrust(peer->keylist[i], 0);
+ free(peer->keylist);
+ peer->keylist = NULL;
+ }
+ value_free(&peer->sndval);
+ peer->keynumber = 0;
+ peer->flags &= ~FLAG_ASSOC;
+ DPRINTF(1, ("key_expire: at %lu associd %d\n", current_time,
+ peer->associd));
+}
+#endif /* AUTOKEY */
+
+
+/*
+ * local_refid(peer) - check peer refid to avoid selecting peers
+ * currently synced to this ntpd.
+ */
+static int
+local_refid(
+ struct peer * p
+ )
+{
+ endpt * unicast_ep;
+
+ if (p->dstadr != NULL && !(INT_MCASTIF & p->dstadr->flags))
+ unicast_ep = p->dstadr;
+ else
+ unicast_ep = findinterface(&p->srcadr);
+
+ if (unicast_ep != NULL && p->refid == unicast_ep->addr_refid)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+
+/*
+ * Determine if the peer is unfit for synchronization
+ *
+ * A peer is unfit for synchronization if
+ * > TEST10 bad leap or stratum below floor or at or above ceiling
+ * > TEST11 root distance exceeded for remote peer
+ * > TEST12 a direct or indirect synchronization loop would form
+ * > TEST13 unreachable or noselect
+ */
+int /* FALSE if fit, TRUE if unfit */
+peer_unfit(
+ struct peer *peer /* peer structure pointer */
+ )
+{
+ int rval = 0;
+
+ /*
+ * A stratum error occurs if (1) the server has never been
+ * synchronized, (2) the server stratum is below the floor or
+ * greater than or equal to the ceiling.
+ */
+ if ( peer->leap == LEAP_NOTINSYNC
+ || peer->stratum < sys_floor
+ || peer->stratum >= sys_ceiling) {
+ rval |= TEST10; /* bad synch or stratum */
+ }
+
+ /*
+ * A distance error for a remote peer occurs if the root
+ * distance is greater than or equal to the distance threshold
+ * plus the increment due to one host poll interval.
+ */
+ if ( !(peer->flags & FLAG_REFCLOCK)
+ && root_distance(peer) >= sys_maxdist
+ + clock_phi * ULOGTOD(peer->hpoll)) {
+ rval |= TEST11; /* distance exceeded */
+ }
+
+ /*
+ * A loop error occurs if the remote peer is synchronized to the
+ * local peer or if the remote peer is synchronized to the same
+ * server as the local peer but only if the remote peer is
+ * neither a reference clock nor an orphan.
+ */
+ if (peer->stratum > 1 && local_refid(peer)) {
+ rval |= TEST12; /* synchronization loop */
+ }
+
+ /*
+ * An unreachable error occurs if the server is unreachable or
+ * the noselect bit is set.
+ */
+ if (!peer->reach || (peer->flags & FLAG_NOSELECT)) {
+ rval |= TEST13; /* unreachable */
+ }
+
+ peer->flash &= ~PEER_TEST_MASK;
+ peer->flash |= rval;
+ return (rval);
+}
+
+
+/*
+ * Find the precision of this particular machine
+ */
+#define MINSTEP 20e-9 /* minimum clock increment (s) */
+#define MAXSTEP 1 /* maximum clock increment (s) */
+#define MINCHANGES 12 /* minimum number of step samples */
+#define MAXLOOPS ((int)(1. / MINSTEP)) /* avoid infinite loop */
+
+/*
+ * This routine measures the system precision defined as the minimum of
+ * a sequence of differences between successive readings of the system
+ * clock. However, if a difference is less than MINSTEP, the clock has
+ * been read more than once during a clock tick and the difference is
+ * ignored. We set MINSTEP greater than zero in case something happens
+ * like a cache miss, and to tolerate underlying system clocks which
+ * ensure each reading is strictly greater than prior readings while
+ * using an underlying stepping (not interpolated) clock.
+ *
+ * sys_tick and sys_precision represent the time to read the clock for
+ * systems with high-precision clocks, and the tick interval or step
+ * size for lower-precision stepping clocks.
+ *
+ * This routine also measures the time to read the clock on stepping
+ * system clocks by counting the number of readings between changes of
+ * the underlying clock. With either type of clock, the minimum time
+ * to read the clock is saved as sys_fuzz, and used to ensure the
+ * get_systime() readings always increase and are fuzzed below sys_fuzz.
+ */
+void
+measure_precision(void)
+{
+ /*
+ * With sys_fuzz set to zero, get_systime() fuzzing of low bits
+ * is effectively disabled. trunc_os_clock is FALSE to disable
+ * get_ostime() simulation of a low-precision system clock.
+ */
+ set_sys_fuzz(0.);
+ trunc_os_clock = FALSE;
+ measured_tick = measure_tick_fuzz();
+ set_sys_tick_precision(measured_tick);
+ msyslog(LOG_INFO, "proto: precision = %.3f usec (%d)",
+ sys_tick * 1e6, sys_precision);
+ if (sys_fuzz < sys_tick) {
+ msyslog(LOG_NOTICE, "proto: fuzz beneath %.3f usec",
+ sys_fuzz * 1e6);
+ }
+}
+
+
+/*
+ * measure_tick_fuzz()
+ *
+ * measures the minimum time to read the clock (stored in sys_fuzz)
+ * and returns the tick, the larger of the minimum increment observed
+ * between successive clock readings and the time to read the clock.
+ */
+double
+measure_tick_fuzz(void)
+{
+ l_fp minstep; /* MINSTEP as l_fp */
+ l_fp val; /* current seconds fraction */
+ l_fp last; /* last seconds fraction */
+ l_fp ldiff; /* val - last */
+ double tick; /* computed tick value */
+ double diff;
+ long repeats;
+ long max_repeats;
+ int changes;
+ int i; /* log2 precision */
+
+ tick = MAXSTEP;
+ max_repeats = 0;
+ repeats = 0;
+ changes = 0;
+ DTOLFP(MINSTEP, &minstep);
+ get_systime(&last);
+ for (i = 0; i < MAXLOOPS && changes < MINCHANGES; i++) {
+ get_systime(&val);
+ ldiff = val;
+ L_SUB(&ldiff, &last);
+ last = val;
+ if (L_ISGT(&ldiff, &minstep)) {
+ max_repeats = max(repeats, max_repeats);
+ repeats = 0;
+ changes++;
+ LFPTOD(&ldiff, diff);
+ tick = min(diff, tick);
+ } else {
+ repeats++;
+ }
+ }
+ if (changes < MINCHANGES) {
+ msyslog(LOG_ERR, "Fatal error: precision could not be measured (MINSTEP too large?)");
+ exit(1);
+ }
+
+ if (0 == max_repeats) {
+ set_sys_fuzz(tick);
+ } else {
+ set_sys_fuzz(tick / max_repeats);
+ }
+
+ return tick;
+}
+
+
+void
+set_sys_tick_precision(
+ double tick
+ )
+{
+ int i;
+
+ if (tick > 1.) {
+ msyslog(LOG_ERR,
+ "unsupported tick %.3f > 1s ignored", tick);
+ return;
+ }
+ if (tick < measured_tick) {
+ msyslog(LOG_ERR,
+ "proto: tick %.3f less than measured tick %.3f, ignored",
+ tick, measured_tick);
+ return;
+ } else if (tick > measured_tick) {
+ trunc_os_clock = TRUE;
+ msyslog(LOG_NOTICE,
+ "proto: truncating system clock to multiples of %.9f",
+ tick);
+ }
+ sys_tick = tick;
+
+ /*
+ * Find the nearest power of two.
+ */
+ for (i = 0; tick <= 1; i--)
+ tick *= 2;
+ if (tick - 1 > 1 - tick / 2)
+ i++;
+
+ sys_precision = (s_char)i;
+}
+
+
+/*
+ * init_proto - initialize the protocol module's data
+ */
+void
+init_proto(void)
+{
+ l_fp dummy;
+ int i;
+
+ /*
+ * Fill in the sys_* stuff. Default is don't listen to
+ * broadcasting, require authentication.
+ */
+ set_sys_leap(LEAP_NOTINSYNC);
+ sys_stratum = STRATUM_UNSPEC;
+ memcpy(&sys_refid, "INIT", 4);
+ sys_peer = NULL;
+ sys_rootdelay = 0;
+ sys_rootdisp = 0;
+ L_CLR(&sys_reftime);
+ sys_jitter = 0;
+ measure_precision();
+ get_systime(&dummy);
+ sys_survivors = 0;
+ sys_manycastserver = 0;
+ sys_bclient = 0;
+ sys_bdelay = BDELAY_DEFAULT; /*[Bug 3031] delay cutoff */
+ sys_authenticate = 1;
+ sys_stattime = current_time;
+ orphwait = current_time + sys_orphwait;
+ proto_clr_stats();
+ for (i = 0; i < MAX_TTL; ++i)
+ sys_ttl[i] = (u_char)((i * 256) / MAX_TTL);
+ sys_ttlmax = (MAX_TTL - 1);
+ hardpps_enable = 0;
+ stats_control = 1;
+}
+
+
+/*
+ * proto_config - configure the protocol module
+ */
+void
+proto_config(
+ int item,
+ u_long value,
+ double dvalue,
+ sockaddr_u *svalue
+ )
+{
+ /*
+ * Figure out what he wants to change, then do it
+ */
+ DPRINTF(2, ("proto_config: code %d value %lu dvalue %lf\n",
+ item, value, dvalue));
+
+ switch (item) {
+
+ /*
+ * enable and disable commands - arguments are Boolean.
+ */
+ case PROTO_AUTHENTICATE: /* authentication (auth) */
+ sys_authenticate = value;
+ break;
+
+ case PROTO_BROADCLIENT: /* broadcast client (bclient) */
+ sys_bclient = (int)value;
+ if (sys_bclient == 0)
+ io_unsetbclient();
+ else
+ io_setbclient();
+ break;
+
+#ifdef REFCLOCK
+ case PROTO_CAL: /* refclock calibrate (calibrate) */
+ cal_enable = value;
+ break;
+#endif /* REFCLOCK */
+
+ case PROTO_KERNEL: /* kernel discipline (kernel) */
+ select_loop(value);
+ break;
+
+ case PROTO_MONITOR: /* monitoring (monitor) */
+ if (value)
+ mon_start(MON_ON);
+ else {
+ mon_stop(MON_ON);
+ if (mon_enabled)
+ msyslog(LOG_WARNING,
+ "restrict: 'monitor' cannot be disabled while 'limited' is enabled");
+ }
+ break;
+
+ case PROTO_NTP: /* NTP discipline (ntp) */
+ ntp_enable = value;
+ break;
+
+ case PROTO_MODE7: /* mode7 management (ntpdc) */
+ ntp_mode7 = value;
+ break;
+
+ case PROTO_PPS: /* PPS discipline (pps) */
+ hardpps_enable = value;
+ break;
+
+ case PROTO_FILEGEN: /* statistics (stats) */
+ stats_control = value;
+ break;
+
+ /*
+ * tos command - arguments are double, sometimes cast to int
+ */
+
+ case PROTO_BCPOLLBSTEP: /* Broadcast Poll Backstep gate (bcpollbstep) */
+ sys_bcpollbstep = (u_char)dvalue;
+ break;
+
+ case PROTO_BEACON: /* manycast beacon (beacon) */
+ sys_beacon = (int)dvalue;
+ break;
+
+ case PROTO_BROADDELAY: /* default broadcast delay (bdelay) */
+ sys_bdelay = (dvalue ? dvalue : BDELAY_DEFAULT);
+ break;
+
+ case PROTO_CEILING: /* stratum ceiling (ceiling) */
+ sys_ceiling = (int)dvalue;
+ break;
+
+ case PROTO_COHORT: /* cohort switch (cohort) */
+ sys_cohort = (int)dvalue;
+ break;
+
+ case PROTO_FLOOR: /* stratum floor (floor) */
+ sys_floor = (int)dvalue;
+ break;
+
+ case PROTO_MAXCLOCK: /* maximum candidates (maxclock) */
+ sys_maxclock = (int)dvalue;
+ break;
+
+ case PROTO_MAXDIST: /* select threshold (maxdist) */
+ sys_maxdist = dvalue;
+ break;
+
+ case PROTO_CALLDELAY: /* modem call delay (mdelay) */
+ break; /* NOT USED */
+
+ case PROTO_MINCLOCK: /* minimum candidates (minclock) */
+ sys_minclock = (int)dvalue;
+ break;
+
+ case PROTO_MINDISP: /* minimum distance (mindist) */
+ sys_mindisp = dvalue;
+ break;
+
+ case PROTO_MINSANE: /* minimum survivors (minsane) */
+ sys_minsane = (int)dvalue;
+ break;
+
+ case PROTO_ORPHAN: /* orphan stratum (orphan) */
+ sys_orphan = (int)dvalue;
+ break;
+
+ case PROTO_ORPHWAIT: /* orphan wait (orphwait) */
+ orphwait -= sys_orphwait;
+ sys_orphwait = (int)dvalue;
+ orphwait += sys_orphwait;
+ break;
+
+ /*
+ * Miscellaneous commands
+ */
+ case PROTO_MULTICAST_ADD: /* add group address */
+ if (svalue != NULL)
+ io_multicast_add(svalue);
+ sys_bclient = 1;
+ break;
+
+ case PROTO_MULTICAST_DEL: /* delete group address */
+ if (svalue != NULL)
+ io_multicast_del(svalue);
+ break;
+
+ /*
+ * Peer_clear Early policy choices
+ */
+
+ case PROTO_PCEDIGEST: /* Digest */
+ peer_clear_digest_early = value;
+ break;
+
+ /*
+ * Unpeer Early policy choices
+ */
+
+ case PROTO_UECRYPTO: /* Crypto */
+ unpeer_crypto_early = value;
+ break;
+
+ case PROTO_UECRYPTONAK: /* Crypto_NAK */
+ unpeer_crypto_nak_early = value;
+ break;
+
+ case PROTO_UEDIGEST: /* Digest */
+ unpeer_digest_early = value;
+ break;
+
+ default:
+ msyslog(LOG_NOTICE,
+ "proto: unsupported option %d", item);
+ }
+}
+
+
+/*
+ * proto_clr_stats - clear protocol stat counters
+ */
+void
+proto_clr_stats(void)
+{
+ sys_stattime = current_time;
+ sys_received = 0;
+ sys_processed = 0;
+ sys_newversion = 0;
+ sys_oldversion = 0;
+ sys_declined = 0;
+ sys_restricted = 0;
+ sys_badlength = 0;
+ sys_badauth = 0;
+ sys_limitrejected = 0;
+ sys_kodsent = 0;
+ sys_lamport = 0;
+ sys_tsrounding = 0;
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_refclock.c b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_refclock.c
new file mode 100644
index 0000000..ae57a52
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_refclock.c
@@ -0,0 +1,1382 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * ntp_refclock - processing support for reference clocks
+ */
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "ntpd.h"
+#include "ntp_io.h"
+#include "ntp_unixtime.h"
+#include "ntp_tty.h"
+#include "ntp_refclock.h"
+#include "ntp_stdlib.h"
+#include "ntp_assert.h"
+
+#include <stdio.h>
+
+#ifdef HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif /* HAVE_SYS_IOCTL_H */
+
+#ifdef REFCLOCK
+
+#ifdef KERNEL_PLL
+#include "ntp_syscall.h"
+#endif /* KERNEL_PLL */
+
+#ifdef HAVE_PPSAPI
+#include "ppsapi_timepps.h"
+#include "refclock_atom.h"
+#endif /* HAVE_PPSAPI */
+
+/*
+ * Reference clock support is provided here by maintaining the fiction
+ * that the clock is actually a peer. As no packets are exchanged with
+ * a reference clock, however, we replace the transmit, receive and
+ * packet procedures with separate code to simulate them. Routines
+ * refclock_transmit() and refclock_receive() maintain the peer
+ * variables in a state analogous to an actual peer and pass reference
+ * clock data on through the filters. Routines refclock_peer() and
+ * refclock_unpeer() are called to initialize and terminate reference
+ * clock associations. A set of utility routines is included to open
+ * serial devices, process sample data, and to perform various debugging
+ * functions.
+ *
+ * The main interface used by these routines is the refclockproc
+ * structure, which contains for most drivers the decimal equivalants
+ * of the year, day, month, hour, second and millisecond/microsecond
+ * decoded from the ASCII timecode. Additional information includes
+ * the receive timestamp, exception report, statistics tallies, etc.
+ * In addition, there may be a driver-specific unit structure used for
+ * local control of the device.
+ *
+ * The support routines are passed a pointer to the peer structure,
+ * which is used for all peer-specific processing and contains a
+ * pointer to the refclockproc structure, which in turn contains a
+ * pointer to the unit structure, if used. The peer structure is
+ * identified by an interface address in the dotted quad form
+ * 127.127.t.u, where t is the clock type and u the unit.
+ */
+#define FUDGEFAC .1 /* fudge correction factor */
+#define LF 0x0a /* ASCII LF */
+
+int cal_enable; /* enable refclock calibrate */
+
+/*
+ * Forward declarations
+ */
+static int refclock_cmpl_fp (const void *, const void *);
+static int refclock_sample (struct refclockproc *);
+static int refclock_ioctl(int, u_int);
+
+
+/*
+ * refclock_report - note the occurance of an event
+ *
+ * This routine presently just remembers the report and logs it, but
+ * does nothing heroic for the trap handler. It tries to be a good
+ * citizen and bothers the system log only if things change.
+ */
+void
+refclock_report(
+ struct peer *peer,
+ int code
+ )
+{
+ struct refclockproc *pp;
+
+ pp = peer->procptr;
+ if (pp == NULL)
+ return;
+
+ switch (code) {
+
+ case CEVNT_TIMEOUT:
+ pp->noreply++;
+ break;
+
+ case CEVNT_BADREPLY:
+ pp->badformat++;
+ break;
+
+ case CEVNT_FAULT:
+ break;
+
+ case CEVNT_BADDATE:
+ case CEVNT_BADTIME:
+ pp->baddata++;
+ break;
+
+ default:
+ /* ignore others */
+ break;
+ }
+ if ((code != CEVNT_NOMINAL) && (pp->lastevent < 15))
+ pp->lastevent++;
+ if (pp->currentstatus != code) {
+ pp->currentstatus = (u_char)code;
+ report_event(PEVNT_CLOCK, peer, ceventstr(code));
+ }
+}
+
+
+/*
+ * init_refclock - initialize the reference clock drivers
+ *
+ * This routine calls each of the drivers in turn to initialize internal
+ * variables, if necessary. Most drivers have nothing to say at this
+ * point.
+ */
+void
+init_refclock(void)
+{
+ int i;
+
+ for (i = 0; i < (int)num_refclock_conf; i++)
+ if (refclock_conf[i]->clock_init != noentry)
+ (refclock_conf[i]->clock_init)();
+}
+
+
+/*
+ * refclock_newpeer - initialize and start a reference clock
+ *
+ * This routine allocates and initializes the interface structure which
+ * supports a reference clock in the form of an ordinary NTP peer. A
+ * driver-specific support routine completes the initialization, if
+ * used. Default peer variables which identify the clock and establish
+ * its reference ID and stratum are set here. It returns one if success
+ * and zero if the clock address is invalid or already running,
+ * insufficient resources are available or the driver declares a bum
+ * rap.
+ */
+int
+refclock_newpeer(
+ struct peer *peer /* peer structure pointer */
+ )
+{
+ struct refclockproc *pp;
+ u_char clktype;
+ int unit;
+
+ /*
+ * Check for valid clock address. If already running, shut it
+ * down first.
+ */
+ if (!ISREFCLOCKADR(&peer->srcadr)) {
+ msyslog(LOG_ERR,
+ "refclock_newpeer: clock address %s invalid",
+ stoa(&peer->srcadr));
+ return (0);
+ }
+ clktype = (u_char)REFCLOCKTYPE(&peer->srcadr);
+ unit = REFCLOCKUNIT(&peer->srcadr);
+ if (clktype >= num_refclock_conf ||
+ refclock_conf[clktype]->clock_start == noentry) {
+ msyslog(LOG_ERR,
+ "refclock_newpeer: clock type %d invalid\n",
+ clktype);
+ return (0);
+ }
+
+ /*
+ * Allocate and initialize interface structure
+ */
+ pp = emalloc_zero(sizeof(*pp));
+ peer->procptr = pp;
+
+ /*
+ * Initialize structures
+ */
+ peer->refclktype = clktype;
+ peer->refclkunit = (u_char)unit;
+ peer->flags |= FLAG_REFCLOCK;
+ peer->leap = LEAP_NOTINSYNC;
+ peer->stratum = STRATUM_REFCLOCK;
+ peer->ppoll = peer->maxpoll;
+ pp->type = clktype;
+ pp->conf = refclock_conf[clktype];
+ pp->timestarted = current_time;
+ pp->io.fd = -1;
+
+ /*
+ * Set peer.pmode based on the hmode. For appearances only.
+ */
+ switch (peer->hmode) {
+ case MODE_ACTIVE:
+ peer->pmode = MODE_PASSIVE;
+ break;
+
+ default:
+ peer->pmode = MODE_SERVER;
+ break;
+ }
+
+ /*
+ * Do driver dependent initialization. The above defaults
+ * can be wiggled, then finish up for consistency.
+ */
+ if (!((refclock_conf[clktype]->clock_start)(unit, peer))) {
+ refclock_unpeer(peer);
+ return (0);
+ }
+ peer->refid = pp->refid;
+ return (1);
+}
+
+
+/*
+ * refclock_unpeer - shut down a clock
+ */
+void
+refclock_unpeer(
+ struct peer *peer /* peer structure pointer */
+ )
+{
+ u_char clktype;
+ int unit;
+
+ /*
+ * Wiggle the driver to release its resources, then give back
+ * the interface structure.
+ */
+ if (NULL == peer->procptr)
+ return;
+
+ clktype = peer->refclktype;
+ unit = peer->refclkunit;
+ if (refclock_conf[clktype]->clock_shutdown != noentry)
+ (refclock_conf[clktype]->clock_shutdown)(unit, peer);
+ free(peer->procptr);
+ peer->procptr = NULL;
+}
+
+
+/*
+ * refclock_timer - called once per second for housekeeping.
+ */
+void
+refclock_timer(
+ struct peer *p
+ )
+{
+ struct refclockproc * pp;
+ int unit;
+
+ unit = p->refclkunit;
+ pp = p->procptr;
+ if (pp->conf->clock_timer != noentry)
+ (*pp->conf->clock_timer)(unit, p);
+ if (pp->action != NULL && pp->nextaction <= current_time)
+ (*pp->action)(p);
+}
+
+
+/*
+ * refclock_transmit - simulate the transmit procedure
+ *
+ * This routine implements the NTP transmit procedure for a reference
+ * clock. This provides a mechanism to call the driver at the NTP poll
+ * interval, as well as provides a reachability mechanism to detect a
+ * broken radio or other madness.
+ */
+void
+refclock_transmit(
+ struct peer *peer /* peer structure pointer */
+ )
+{
+ u_char clktype;
+ int unit;
+
+ clktype = peer->refclktype;
+ unit = peer->refclkunit;
+ peer->sent++;
+ get_systime(&peer->xmt);
+
+ /*
+ * This is a ripoff of the peer transmit routine, but
+ * specialized for reference clocks. We do a little less
+ * protocol here and call the driver-specific transmit routine.
+ */
+ if (peer->burst == 0) {
+ u_char oreach;
+#ifdef DEBUG
+ if (debug)
+ printf("refclock_transmit: at %ld %s\n",
+ current_time, stoa(&(peer->srcadr)));
+#endif
+
+ /*
+ * Update reachability and poll variables like the
+ * network code.
+ */
+ oreach = peer->reach & 0xfe;
+ peer->reach <<= 1;
+ if (!(peer->reach & 0x0f))
+ clock_filter(peer, 0., 0., MAXDISPERSE);
+ peer->outdate = current_time;
+ if (!peer->reach) {
+ if (oreach) {
+ report_event(PEVNT_UNREACH, peer, NULL);
+ peer->timereachable = current_time;
+ }
+ } else {
+ if (peer->flags & FLAG_BURST)
+ peer->burst = NSTAGE;
+ }
+ } else {
+ peer->burst--;
+ }
+ if (refclock_conf[clktype]->clock_poll != noentry)
+ (refclock_conf[clktype]->clock_poll)(unit, peer);
+ poll_update(peer, peer->hpoll);
+}
+
+
+/*
+ * Compare two doubles - used with qsort()
+ */
+static int
+refclock_cmpl_fp(
+ const void *p1,
+ const void *p2
+ )
+{
+ const double *dp1 = (const double *)p1;
+ const double *dp2 = (const double *)p2;
+
+ if (*dp1 < *dp2)
+ return -1;
+ if (*dp1 > *dp2)
+ return 1;
+ return 0;
+}
+
+
+/*
+ * refclock_process_offset - update median filter
+ *
+ * This routine uses the given offset and timestamps to construct a new
+ * entry in the median filter circular buffer. Samples that overflow the
+ * filter are quietly discarded.
+ */
+void
+refclock_process_offset(
+ struct refclockproc *pp, /* refclock structure pointer */
+ l_fp lasttim, /* last timecode timestamp */
+ l_fp lastrec, /* last receive timestamp */
+ double fudge
+ )
+{
+ l_fp lftemp;
+ double doffset;
+
+ pp->lastrec = lastrec;
+ lftemp = lasttim;
+ L_SUB(&lftemp, &lastrec);
+ LFPTOD(&lftemp, doffset);
+ SAMPLE(doffset + fudge);
+}
+
+
+/*
+ * refclock_process - process a sample from the clock
+ * refclock_process_f - refclock_process with other than time1 fudge
+ *
+ * This routine converts the timecode in the form days, hours, minutes,
+ * seconds and milliseconds/microseconds to internal timestamp format,
+ * then constructs a new entry in the median filter circular buffer.
+ * Return success (1) if the data are correct and consistent with the
+ * converntional calendar.
+ *
+ * Important for PPS users: Normally, the pp->lastrec is set to the
+ * system time when the on-time character is received and the pp->year,
+ * ..., pp->second decoded and the seconds fraction pp->nsec in
+ * nanoseconds). When a PPS offset is available, pp->nsec is forced to
+ * zero and the fraction for pp->lastrec is set to the PPS offset.
+ */
+int
+refclock_process_f(
+ struct refclockproc *pp, /* refclock structure pointer */
+ double fudge
+ )
+{
+ l_fp offset, ltemp;
+
+ /*
+ * Compute the timecode timestamp from the days, hours, minutes,
+ * seconds and milliseconds/microseconds of the timecode. Use
+ * clocktime() for the aggregate seconds and the msec/usec for
+ * the fraction, when present. Note that this code relies on the
+ * filesystem time for the years and does not use the years of
+ * the timecode.
+ */
+ if (!clocktime(pp->day, pp->hour, pp->minute, pp->second, GMT,
+ pp->lastrec.l_ui, &pp->yearstart, &offset.l_ui))
+ return (0);
+
+ offset.l_uf = 0;
+ DTOLFP(pp->nsec / 1e9, &ltemp);
+ L_ADD(&offset, &ltemp);
+ refclock_process_offset(pp, offset, pp->lastrec, fudge);
+ return (1);
+}
+
+
+int
+refclock_process(
+ struct refclockproc *pp /* refclock structure pointer */
+)
+{
+ return refclock_process_f(pp, pp->fudgetime1);
+}
+
+
+/*
+ * refclock_sample - process a pile of samples from the clock
+ *
+ * This routine implements a recursive median filter to suppress spikes
+ * in the data, as well as determine a performance statistic. It
+ * calculates the mean offset and RMS jitter. A time adjustment
+ * fudgetime1 can be added to the final offset to compensate for various
+ * systematic errors. The routine returns the number of samples
+ * processed, which could be zero.
+ */
+static int
+refclock_sample(
+ struct refclockproc *pp /* refclock structure pointer */
+ )
+{
+ size_t i, j, k, m, n;
+ double off[MAXSTAGE];
+ double offset;
+
+ /*
+ * Copy the raw offsets and sort into ascending order. Don't do
+ * anything if the buffer is empty.
+ */
+ n = 0;
+ while (pp->codeproc != pp->coderecv) {
+ pp->codeproc = (pp->codeproc + 1) % MAXSTAGE;
+ off[n] = pp->filter[pp->codeproc];
+ n++;
+ }
+ if (n == 0)
+ return (0);
+
+ if (n > 1)
+ qsort(off, n, sizeof(off[0]), refclock_cmpl_fp);
+
+ /*
+ * Reject the furthest from the median of the samples until
+ * approximately 60 percent of the samples remain.
+ */
+ i = 0; j = n;
+ m = n - (n * 4) / 10;
+ while ((j - i) > m) {
+ offset = off[(j + i) / 2];
+ if (off[j - 1] - offset < offset - off[i])
+ i++; /* reject low end */
+ else
+ j--; /* reject high end */
+ }
+
+ /*
+ * Determine the offset and jitter.
+ */
+ pp->offset = 0;
+ pp->jitter = 0;
+ for (k = i; k < j; k++) {
+ pp->offset += off[k];
+ if (k > i)
+ pp->jitter += SQUARE(off[k] - off[k - 1]);
+ }
+ pp->offset /= m;
+ pp->jitter = max(SQRT(pp->jitter / m), LOGTOD(sys_precision));
+#ifdef DEBUG
+ if (debug)
+ printf(
+ "refclock_sample: n %d offset %.6f disp %.6f jitter %.6f\n",
+ (int)n, pp->offset, pp->disp, pp->jitter);
+#endif
+ return (int)n;
+}
+
+
+/*
+ * refclock_receive - simulate the receive and packet procedures
+ *
+ * This routine simulates the NTP receive and packet procedures for a
+ * reference clock. This provides a mechanism in which the ordinary NTP
+ * filter, selection and combining algorithms can be used to suppress
+ * misbehaving radios and to mitigate between them when more than one is
+ * available for backup.
+ */
+void
+refclock_receive(
+ struct peer *peer /* peer structure pointer */
+ )
+{
+ struct refclockproc *pp;
+
+#ifdef DEBUG
+ if (debug)
+ printf("refclock_receive: at %lu %s\n",
+ current_time, stoa(&peer->srcadr));
+#endif
+
+ /*
+ * Do a little sanity dance and update the peer structure. Groom
+ * the median filter samples and give the data to the clock
+ * filter.
+ */
+ pp = peer->procptr;
+ peer->leap = pp->leap;
+ if (peer->leap == LEAP_NOTINSYNC)
+ return;
+
+ peer->received++;
+ peer->timereceived = current_time;
+ if (!peer->reach) {
+ report_event(PEVNT_REACH, peer, NULL);
+ peer->timereachable = current_time;
+ }
+ peer->reach |= 1;
+ peer->reftime = pp->lastref;
+ peer->aorg = pp->lastrec;
+ peer->rootdisp = pp->disp;
+ get_systime(&peer->dst);
+ if (!refclock_sample(pp))
+ return;
+
+ clock_filter(peer, pp->offset, 0., pp->jitter);
+ if (cal_enable && fabs(last_offset) < sys_mindisp && sys_peer !=
+ NULL) {
+ if (sys_peer->refclktype == REFCLK_ATOM_PPS &&
+ peer->refclktype != REFCLK_ATOM_PPS)
+ pp->fudgetime1 -= pp->offset * FUDGEFAC;
+ }
+}
+
+
+/*
+ * refclock_gtlin - groom next input line and extract timestamp
+ *
+ * This routine processes the timecode received from the clock and
+ * strips the parity bit and control characters. It returns the number
+ * of characters in the line followed by a NULL character ('\0'), which
+ * is not included in the count. In case of an empty line, the previous
+ * line is preserved.
+ */
+int
+refclock_gtlin(
+ struct recvbuf *rbufp, /* receive buffer pointer */
+ char *lineptr, /* current line pointer */
+ int bmax, /* remaining characters in line */
+ l_fp *tsptr /* pointer to timestamp returned */
+ )
+{
+ const char *sp, *spend;
+ char *dp, *dpend;
+ int dlen;
+
+ if (bmax <= 0)
+ return (0);
+
+ dp = lineptr;
+ dpend = dp + bmax - 1; /* leave room for NUL pad */
+ sp = (const char *)rbufp->recv_buffer;
+ spend = sp + rbufp->recv_length;
+
+ while (sp != spend && dp != dpend) {
+ char c;
+
+ c = *sp++ & 0x7f;
+ if (c >= 0x20 && c < 0x7f)
+ *dp++ = c;
+ }
+ /* Get length of data written to the destination buffer. If
+ * zero, do *not* place a NUL byte to preserve the previous
+ * buffer content.
+ */
+ dlen = dp - lineptr;
+ if (dlen)
+ *dp = '\0';
+ *tsptr = rbufp->recv_time;
+ DPRINTF(2, ("refclock_gtlin: fd %d time %s timecode %d %s\n",
+ rbufp->fd, ulfptoa(&rbufp->recv_time, 6), dlen,
+ (dlen != 0)
+ ? lineptr
+ : ""));
+ return (dlen);
+}
+
+
+/*
+ * refclock_gtraw - get next line/chunk of data
+ *
+ * This routine returns the raw data received from the clock in both
+ * canonical or raw modes. The terminal interface routines map CR to LF.
+ * In canonical mode this results in two lines, one containing data
+ * followed by LF and another containing only LF. In raw mode the
+ * interface routines can deliver arbitraty chunks of data from one
+ * character to a maximum specified by the calling routine. In either
+ * mode the routine returns the number of characters in the line
+ * followed by a NULL character ('\0'), which is not included in the
+ * count.
+ *
+ * *tsptr receives a copy of the buffer timestamp.
+ */
+int
+refclock_gtraw(
+ struct recvbuf *rbufp, /* receive buffer pointer */
+ char *lineptr, /* current line pointer */
+ int bmax, /* remaining characters in line */
+ l_fp *tsptr /* pointer to timestamp returned */
+ )
+{
+ if (bmax <= 0)
+ return (0);
+ bmax -= 1; /* leave room for trailing NUL */
+ if (bmax > rbufp->recv_length)
+ bmax = rbufp->recv_length;
+ memcpy(lineptr, rbufp->recv_buffer, bmax);
+ lineptr[bmax] = '\0';
+
+ *tsptr = rbufp->recv_time;
+ DPRINTF(2, ("refclock_gtraw: fd %d time %s timecode %d %s\n",
+ rbufp->fd, ulfptoa(&rbufp->recv_time, 6), bmax,
+ lineptr));
+ return (bmax);
+}
+
+
+/*
+ * indicate_refclock_packet()
+ *
+ * Passes a fragment of refclock input read from the device to the
+ * driver direct input routine, which may consume it (batch it for
+ * queuing once a logical unit is assembled). If it is not so
+ * consumed, queue it for the driver's receive entrypoint.
+ *
+ * The return value is TRUE if the data has been consumed as a fragment
+ * and should not be counted as a received packet.
+ */
+int
+indicate_refclock_packet(
+ struct refclockio * rio,
+ struct recvbuf * rb
+ )
+{
+ /* Does this refclock use direct input routine? */
+ if (rio->io_input != NULL && (*rio->io_input)(rb) == 0) {
+ /*
+ * data was consumed - nothing to pass up
+ * into block input machine
+ */
+ freerecvbuf(rb);
+
+ return TRUE;
+ }
+ add_full_recv_buffer(rb);
+
+ return FALSE;
+}
+
+
+/*
+ * process_refclock_packet()
+ *
+ * Used for deferred processing of 'io_input' on systems where threading
+ * is used (notably Windows). This is acting as a trampoline to make the
+ * real calls to the refclock functions.
+ */
+#ifdef HAVE_IO_COMPLETION_PORT
+void
+process_refclock_packet(
+ struct recvbuf * rb
+ )
+{
+ struct refclockio * rio;
+
+ /* get the refclockio structure from the receive buffer */
+ rio = &rb->recv_peer->procptr->io;
+
+ /* call 'clock_recv' if either there is no input function or the
+ * raw input function tells us to feed the packet to the
+ * receiver.
+ */
+ if (rio->io_input == NULL || (*rio->io_input)(rb) != 0) {
+ rio->recvcount++;
+ packets_received++;
+ handler_pkts++;
+ (*rio->clock_recv)(rb);
+ }
+}
+#endif /* HAVE_IO_COMPLETION_PORT */
+
+
+/*
+ * The following code does not apply to WINNT & VMS ...
+ */
+#if !defined(SYS_VXWORKS) && !defined(SYS_WINNT)
+#if defined(HAVE_TERMIOS) || defined(HAVE_SYSV_TTYS) || defined(HAVE_BSD_TTYS)
+
+/*
+ * refclock_open - open serial port for reference clock
+ *
+ * This routine opens a serial port for I/O and sets default options. It
+ * returns the file descriptor if successful, or logs an error and
+ * returns -1.
+ */
+int
+refclock_open(
+ const char *dev, /* device name pointer */
+ u_int speed, /* serial port speed (code) */
+ u_int lflags /* line discipline flags */
+ )
+{
+ int fd;
+ int omode;
+#ifdef O_NONBLOCK
+ char trash[128]; /* litter bin for old input data */
+#endif
+
+ /*
+ * Open serial port and set default options
+ */
+ omode = O_RDWR;
+#ifdef O_NONBLOCK
+ omode |= O_NONBLOCK;
+#endif
+#ifdef O_NOCTTY
+ omode |= O_NOCTTY;
+#endif
+
+ fd = open(dev, omode, 0777);
+ /* refclock_open() long returned 0 on failure, avoid it. */
+ if (0 == fd) {
+ fd = dup(0);
+ SAVE_ERRNO(
+ close(0);
+ )
+ }
+ if (fd < 0) {
+ SAVE_ERRNO(
+ msyslog(LOG_ERR, "refclock_open %s: %m", dev);
+ )
+ return -1;
+ }
+ if (!refclock_setup(fd, speed, lflags)) {
+ close(fd);
+ return -1;
+ }
+ if (!refclock_ioctl(fd, lflags)) {
+ close(fd);
+ return -1;
+ }
+#ifdef O_NONBLOCK
+ /*
+ * We want to make sure there is no pending trash in the input
+ * buffer. Since we have non-blocking IO available, this is a
+ * good moment to read and dump all available outdated stuff
+ * that might have become toxic for the driver.
+ */
+ while (read(fd, trash, sizeof(trash)) > 0 || errno == EINTR)
+ /*NOP*/;
+#endif
+ return fd;
+}
+
+
+/*
+ * refclock_setup - initialize terminal interface structure
+ */
+int
+refclock_setup(
+ int fd, /* file descriptor */
+ u_int speed, /* serial port speed (code) */
+ u_int lflags /* line discipline flags */
+ )
+{
+ int i;
+ TTY ttyb, *ttyp;
+
+ /*
+ * By default, the serial line port is initialized in canonical
+ * (line-oriented) mode at specified line speed, 8 bits and no
+ * parity. LF ends the line and CR is mapped to LF. The break,
+ * erase and kill functions are disabled. There is a different
+ * section for each terminal interface, as selected at compile
+ * time. The flag bits can be used to set raw mode and echo.
+ */
+ ttyp = &ttyb;
+#ifdef HAVE_TERMIOS
+
+ /*
+ * POSIX serial line parameters (termios interface)
+ */
+ if (tcgetattr(fd, ttyp) < 0) {
+ SAVE_ERRNO(
+ msyslog(LOG_ERR,
+ "refclock_setup fd %d tcgetattr: %m",
+ fd);
+ )
+ return FALSE;
+ }
+
+ /*
+ * Set canonical mode and local connection; set specified speed,
+ * 8 bits and no parity; map CR to NL; ignore break.
+ */
+ if (speed) {
+ u_int ltemp = 0;
+
+ ttyp->c_iflag = IGNBRK | IGNPAR | ICRNL;
+ ttyp->c_oflag = 0;
+ ttyp->c_cflag = CS8 | CLOCAL | CREAD;
+ if (lflags & LDISC_7O1) {
+ /* HP Z3801A needs 7-bit, odd parity */
+ ttyp->c_cflag = CS7 | PARENB | PARODD | CLOCAL | CREAD;
+ }
+ cfsetispeed(&ttyb, speed);
+ cfsetospeed(&ttyb, speed);
+ for (i = 0; i < NCCS; ++i)
+ ttyp->c_cc[i] = '\0';
+
+#if defined(TIOCMGET) && !defined(SCO5_CLOCK)
+
+ /*
+ * If we have modem control, check to see if modem leads
+ * are active; if so, set remote connection. This is
+ * necessary for the kernel pps mods to work.
+ */
+ if (ioctl(fd, TIOCMGET, (char *)&ltemp) < 0)
+ msyslog(LOG_ERR,
+ "refclock_setup fd %d TIOCMGET: %m", fd);
+#ifdef DEBUG
+ if (debug)
+ printf("refclock_setup fd %d modem status: 0x%x\n",
+ fd, ltemp);
+#endif
+ if (ltemp & TIOCM_DSR && lflags & LDISC_REMOTE)
+ ttyp->c_cflag &= ~CLOCAL;
+#endif /* TIOCMGET */
+ }
+
+ /*
+ * Set raw and echo modes. These can be changed on-fly.
+ */
+ ttyp->c_lflag = ICANON;
+ if (lflags & LDISC_RAW) {
+ ttyp->c_lflag = 0;
+ ttyp->c_iflag = 0;
+ ttyp->c_cc[VMIN] = 1;
+ }
+ if (lflags & LDISC_ECHO)
+ ttyp->c_lflag |= ECHO;
+ if (tcsetattr(fd, TCSANOW, ttyp) < 0) {
+ SAVE_ERRNO(
+ msyslog(LOG_ERR,
+ "refclock_setup fd %d TCSANOW: %m",
+ fd);
+ )
+ return FALSE;
+ }
+
+ /*
+ * flush input and output buffers to discard any outdated stuff
+ * that might have become toxic for the driver. Failing to do so
+ * is logged, but we keep our fingers crossed otherwise.
+ */
+ if (tcflush(fd, TCIOFLUSH) < 0)
+ msyslog(LOG_ERR, "refclock_setup fd %d tcflush(): %m",
+ fd);
+#endif /* HAVE_TERMIOS */
+
+#ifdef HAVE_SYSV_TTYS
+
+ /*
+ * System V serial line parameters (termio interface)
+ *
+ */
+ if (ioctl(fd, TCGETA, ttyp) < 0) {
+ SAVE_ERRNO(
+ msyslog(LOG_ERR,
+ "refclock_setup fd %d TCGETA: %m",
+ fd);
+ )
+ return FALSE;
+ }
+
+ /*
+ * Set canonical mode and local connection; set specified speed,
+ * 8 bits and no parity; map CR to NL; ignore break.
+ */
+ if (speed) {
+ u_int ltemp = 0;
+
+ ttyp->c_iflag = IGNBRK | IGNPAR | ICRNL;
+ ttyp->c_oflag = 0;
+ ttyp->c_cflag = speed | CS8 | CLOCAL | CREAD;
+ for (i = 0; i < NCCS; ++i)
+ ttyp->c_cc[i] = '\0';
+
+#if defined(TIOCMGET) && !defined(SCO5_CLOCK)
+
+ /*
+ * If we have modem control, check to see if modem leads
+ * are active; if so, set remote connection. This is
+ * necessary for the kernel pps mods to work.
+ */
+ if (ioctl(fd, TIOCMGET, (char *)&ltemp) < 0)
+ msyslog(LOG_ERR,
+ "refclock_setup fd %d TIOCMGET: %m", fd);
+#ifdef DEBUG
+ if (debug)
+ printf("refclock_setup fd %d modem status: %x\n",
+ fd, ltemp);
+#endif
+ if (ltemp & TIOCM_DSR)
+ ttyp->c_cflag &= ~CLOCAL;
+#endif /* TIOCMGET */
+ }
+
+ /*
+ * Set raw and echo modes. These can be changed on-fly.
+ */
+ ttyp->c_lflag = ICANON;
+ if (lflags & LDISC_RAW) {
+ ttyp->c_lflag = 0;
+ ttyp->c_iflag = 0;
+ ttyp->c_cc[VMIN] = 1;
+ }
+ if (ioctl(fd, TCSETA, ttyp) < 0) {
+ SAVE_ERRNO(
+ msyslog(LOG_ERR,
+ "refclock_setup fd %d TCSETA: %m", fd);
+ )
+ return FALSE;
+ }
+#endif /* HAVE_SYSV_TTYS */
+
+#ifdef HAVE_BSD_TTYS
+
+ /*
+ * 4.3bsd serial line parameters (sgttyb interface)
+ */
+ if (ioctl(fd, TIOCGETP, (char *)ttyp) < 0) {
+ SAVE_ERRNO(
+ msyslog(LOG_ERR,
+ "refclock_setup fd %d TIOCGETP: %m",
+ fd);
+ )
+ return FALSE;
+ }
+ if (speed)
+ ttyp->sg_ispeed = ttyp->sg_ospeed = speed;
+ ttyp->sg_flags = EVENP | ODDP | CRMOD;
+ if (ioctl(fd, TIOCSETP, (char *)ttyp) < 0) {
+ SAVE_ERRNO(
+ msyslog(LOG_ERR, "refclock_setup TIOCSETP: %m");
+ )
+ return FALSE;
+ }
+#endif /* HAVE_BSD_TTYS */
+ return(1);
+}
+#endif /* HAVE_TERMIOS || HAVE_SYSV_TTYS || HAVE_BSD_TTYS */
+
+
+/*
+ * refclock_ioctl - set serial port control functions
+ *
+ * This routine attempts to hide the internal, system-specific details
+ * of serial ports. It can handle POSIX (termios), SYSV (termio) and BSD
+ * (sgtty) interfaces with varying degrees of success. The routine sets
+ * up optional features such as tty_clk. The routine returns TRUE if
+ * successful.
+ */
+int
+refclock_ioctl(
+ int fd, /* file descriptor */
+ u_int lflags /* line discipline flags */
+ )
+{
+ /*
+ * simply return TRUE if no UNIX line discipline is supported
+ */
+ DPRINTF(1, ("refclock_ioctl: fd %d flags 0x%x\n", fd, lflags));
+
+ return TRUE;
+}
+#endif /* !defined(SYS_VXWORKS) && !defined(SYS_WINNT) */
+
+
+/*
+ * refclock_control - set and/or return clock values
+ *
+ * This routine is used mainly for debugging. It returns designated
+ * values from the interface structure that can be displayed using
+ * ntpdc and the clockstat command. It can also be used to initialize
+ * configuration variables, such as fudgetimes, fudgevalues, reference
+ * ID and stratum.
+ */
+void
+refclock_control(
+ sockaddr_u *srcadr,
+ const struct refclockstat *in,
+ struct refclockstat *out
+ )
+{
+ struct peer *peer;
+ struct refclockproc *pp;
+ u_char clktype;
+ int unit;
+
+ /*
+ * Check for valid address and running peer
+ */
+ if (!ISREFCLOCKADR(srcadr))
+ return;
+
+ clktype = (u_char)REFCLOCKTYPE(srcadr);
+ unit = REFCLOCKUNIT(srcadr);
+
+ peer = findexistingpeer(srcadr, NULL, NULL, -1, 0, NULL);
+
+ if (NULL == peer)
+ return;
+
+ INSIST(peer->procptr != NULL);
+ pp = peer->procptr;
+
+ /*
+ * Initialize requested data
+ */
+ if (in != NULL) {
+ if (in->haveflags & CLK_HAVETIME1)
+ pp->fudgetime1 = in->fudgetime1;
+ if (in->haveflags & CLK_HAVETIME2)
+ pp->fudgetime2 = in->fudgetime2;
+ if (in->haveflags & CLK_HAVEVAL1)
+ peer->stratum = pp->stratum = (u_char)in->fudgeval1;
+ if (in->haveflags & CLK_HAVEVAL2)
+ peer->refid = pp->refid = in->fudgeval2;
+ if (in->haveflags & CLK_HAVEFLAG1) {
+ pp->sloppyclockflag &= ~CLK_FLAG1;
+ pp->sloppyclockflag |= in->flags & CLK_FLAG1;
+ }
+ if (in->haveflags & CLK_HAVEFLAG2) {
+ pp->sloppyclockflag &= ~CLK_FLAG2;
+ pp->sloppyclockflag |= in->flags & CLK_FLAG2;
+ }
+ if (in->haveflags & CLK_HAVEFLAG3) {
+ pp->sloppyclockflag &= ~CLK_FLAG3;
+ pp->sloppyclockflag |= in->flags & CLK_FLAG3;
+ }
+ if (in->haveflags & CLK_HAVEFLAG4) {
+ pp->sloppyclockflag &= ~CLK_FLAG4;
+ pp->sloppyclockflag |= in->flags & CLK_FLAG4;
+ }
+ }
+
+ /*
+ * Readback requested data
+ */
+ if (out != NULL) {
+ out->fudgeval1 = pp->stratum;
+ out->fudgeval2 = pp->refid;
+ out->haveflags = CLK_HAVEVAL1 | CLK_HAVEVAL2;
+ out->fudgetime1 = pp->fudgetime1;
+ if (0.0 != out->fudgetime1)
+ out->haveflags |= CLK_HAVETIME1;
+ out->fudgetime2 = pp->fudgetime2;
+ if (0.0 != out->fudgetime2)
+ out->haveflags |= CLK_HAVETIME2;
+ out->flags = (u_char) pp->sloppyclockflag;
+ if (CLK_FLAG1 & out->flags)
+ out->haveflags |= CLK_HAVEFLAG1;
+ if (CLK_FLAG2 & out->flags)
+ out->haveflags |= CLK_HAVEFLAG2;
+ if (CLK_FLAG3 & out->flags)
+ out->haveflags |= CLK_HAVEFLAG3;
+ if (CLK_FLAG4 & out->flags)
+ out->haveflags |= CLK_HAVEFLAG4;
+
+ out->timereset = current_time - pp->timestarted;
+ out->polls = pp->polls;
+ out->noresponse = pp->noreply;
+ out->badformat = pp->badformat;
+ out->baddata = pp->baddata;
+
+ out->lastevent = pp->lastevent;
+ out->currentstatus = pp->currentstatus;
+ out->type = pp->type;
+ out->clockdesc = pp->clockdesc;
+ out->lencode = (u_short)pp->lencode;
+ out->p_lastcode = pp->a_lastcode;
+ }
+
+ /*
+ * Give the stuff to the clock
+ */
+ if (refclock_conf[clktype]->clock_control != noentry)
+ (refclock_conf[clktype]->clock_control)(unit, in, out, peer);
+}
+
+
+/*
+ * refclock_buginfo - return debugging info
+ *
+ * This routine is used mainly for debugging. It returns designated
+ * values from the interface structure that can be displayed using
+ * ntpdc and the clkbug command.
+ */
+void
+refclock_buginfo(
+ sockaddr_u *srcadr, /* clock address */
+ struct refclockbug *bug /* output structure */
+ )
+{
+ struct peer *peer;
+ struct refclockproc *pp;
+ int clktype;
+ int unit;
+ unsigned u;
+
+ /*
+ * Check for valid address and peer structure
+ */
+ if (!ISREFCLOCKADR(srcadr))
+ return;
+
+ clktype = (u_char) REFCLOCKTYPE(srcadr);
+ unit = REFCLOCKUNIT(srcadr);
+
+ peer = findexistingpeer(srcadr, NULL, NULL, -1, 0, NULL);
+
+ if (NULL == peer || NULL == peer->procptr)
+ return;
+
+ pp = peer->procptr;
+
+ /*
+ * Copy structure values
+ */
+ bug->nvalues = 8;
+ bug->svalues = 0x0000003f;
+ bug->values[0] = pp->year;
+ bug->values[1] = pp->day;
+ bug->values[2] = pp->hour;
+ bug->values[3] = pp->minute;
+ bug->values[4] = pp->second;
+ bug->values[5] = pp->nsec;
+ bug->values[6] = pp->yearstart;
+ bug->values[7] = pp->coderecv;
+ bug->stimes = 0xfffffffc;
+ bug->times[0] = pp->lastref;
+ bug->times[1] = pp->lastrec;
+ for (u = 2; u < bug->ntimes; u++)
+ DTOLFP(pp->filter[u - 2], &bug->times[u]);
+
+ /*
+ * Give the stuff to the clock
+ */
+ if (refclock_conf[clktype]->clock_buginfo != noentry)
+ (refclock_conf[clktype]->clock_buginfo)(unit, bug, peer);
+}
+
+
+#ifdef HAVE_PPSAPI
+/*
+ * refclock_ppsapi - initialize/update ppsapi
+ *
+ * This routine is called after the fudge command to open the PPSAPI
+ * interface for later parameter setting after the fudge command.
+ */
+int
+refclock_ppsapi(
+ int fddev, /* fd device */
+ struct refclock_atom *ap /* atom structure pointer */
+ )
+{
+ if (ap->handle == 0) {
+ if (time_pps_create(fddev, &ap->handle) < 0) {
+ msyslog(LOG_ERR,
+ "refclock_ppsapi: time_pps_create: %m");
+ return (0);
+ }
+ ZERO(ap->ts); /* [Bug 2689] defined INIT state */
+ }
+ return (1);
+}
+
+
+/*
+ * refclock_params - set ppsapi parameters
+ *
+ * This routine is called to set the PPSAPI parameters after the fudge
+ * command.
+ */
+int
+refclock_params(
+ int mode, /* mode bits */
+ struct refclock_atom *ap /* atom structure pointer */
+ )
+{
+ ZERO(ap->pps_params);
+ ap->pps_params.api_version = PPS_API_VERS_1;
+
+ /*
+ * Solaris serial ports provide PPS pulse capture only on the
+ * assert edge. FreeBSD serial ports provide capture on the
+ * clear edge, while FreeBSD parallel ports provide capture
+ * on the assert edge. Your mileage may vary.
+ */
+ if (mode & CLK_FLAG2)
+ ap->pps_params.mode = PPS_TSFMT_TSPEC | PPS_CAPTURECLEAR;
+ else
+ ap->pps_params.mode = PPS_TSFMT_TSPEC | PPS_CAPTUREASSERT;
+ if (time_pps_setparams(ap->handle, &ap->pps_params) < 0) {
+ msyslog(LOG_ERR,
+ "refclock_params: time_pps_setparams: %m");
+ return (0);
+ }
+
+ /*
+ * If flag3 is lit, select the kernel PPS if we can.
+ *
+ * Note: EOPNOTSUPP is the only 'legal' error code we deal with;
+ * it is part of the 'if we can' strategy. Any other error
+ * indicates something more sinister and makes this function fail.
+ */
+ if (mode & CLK_FLAG3) {
+ if (time_pps_kcbind(ap->handle, PPS_KC_HARDPPS,
+ ap->pps_params.mode & ~PPS_TSFMT_TSPEC,
+ PPS_TSFMT_TSPEC) < 0)
+ {
+ if (errno != EOPNOTSUPP) {
+ msyslog(LOG_ERR,
+ "refclock_params: time_pps_kcbind: %m");
+ return (0);
+ }
+ } else {
+ hardpps_enable = 1;
+ }
+ }
+ return (1);
+}
+
+
+/*
+ * refclock_pps - called once per second
+ *
+ * This routine is called once per second. It snatches the PPS
+ * timestamp from the kernel and saves the sign-extended fraction in
+ * a circular buffer for processing at the next poll event.
+ */
+int
+refclock_pps(
+ struct peer *peer, /* peer structure pointer */
+ struct refclock_atom *ap, /* atom structure pointer */
+ int mode /* mode bits */
+ )
+{
+ struct refclockproc *pp;
+ pps_info_t pps_info;
+ struct timespec timeout;
+ double dtemp, dcorr, trash;
+
+ /*
+ * We require the clock to be synchronized before setting the
+ * parameters. When the parameters have been set, fetch the
+ * most recent PPS timestamp.
+ */
+ pp = peer->procptr;
+ if (ap->handle == 0)
+ return (0);
+
+ if (ap->pps_params.mode == 0 && sys_leap != LEAP_NOTINSYNC) {
+ if (refclock_params(pp->sloppyclockflag, ap) < 1)
+ return (0);
+ }
+ ZERO(timeout);
+ ZERO(pps_info);
+ if (time_pps_fetch(ap->handle, PPS_TSFMT_TSPEC, &pps_info,
+ &timeout) < 0) {
+ refclock_report(peer, CEVNT_FAULT);
+ return (0);
+ }
+ timeout = ap->ts; /* save old timestamp for check */
+ if (ap->pps_params.mode & PPS_CAPTUREASSERT)
+ ap->ts = pps_info.assert_timestamp;
+ else if (ap->pps_params.mode & PPS_CAPTURECLEAR)
+ ap->ts = pps_info.clear_timestamp;
+ else
+ return (0);
+
+ /* [Bug 2689] Discard the first sample we read -- if the PPS
+ * source is currently down / disconnected, we have read a
+ * potentially *very* stale value here. So if our old TS value
+ * is all-zero, we consider this sample unrealiable and drop it.
+ *
+ * Note 1: a better check would compare the PPS time stamp to
+ * the current system time and drop it if it's more than say 3s
+ * away.
+ *
+ * Note 2: If we ever again get an all-zero PPS sample, the next
+ * one will be discarded. This can happen every 136yrs and is
+ * unlikely to be ever observed.
+ */
+ if (0 == (timeout.tv_sec | timeout.tv_nsec))
+ return (0);
+
+ /* If the PPS source fails to deliver a new sample between
+ * polls, it regurgitates the last sample. We do not want to
+ * process the same sample multiple times.
+ */
+ if (0 == memcmp(&timeout, &ap->ts, sizeof(timeout)))
+ return (0);
+
+ /*
+ * Convert to signed fraction offset, apply fudge and properly
+ * fold the correction into the [-0.5s,0.5s] range. Handle
+ * excessive fudge times, too.
+ */
+ dtemp = ap->ts.tv_nsec / 1e9;
+ dcorr = modf((pp->fudgetime1 - dtemp), &trash);
+ if (dcorr > 0.5)
+ dcorr -= 1.0;
+ else if (dcorr < -0.5)
+ dcorr += 1.0;
+
+ /* phase gate check: avoid wobbling by +/-1s when too close to
+ * the switch-over point. We allow +/-400ms max phase deviation.
+ * The trade-off is clear: The smaller the limit, the less
+ * sensitive to sampling noise the clock becomes. OTOH the
+ * system must get into phase gate range by other means for the
+ * PPS clock to lock in.
+ */
+ if (fabs(dcorr) > 0.4)
+ return (0);
+
+ /*
+ * record this time stamp and stuff in median filter
+ */
+ pp->lastrec.l_ui = (u_int32)ap->ts.tv_sec + JAN_1970;
+ pp->lastrec.l_uf = (u_int32)(dtemp * FRAC);
+ SAMPLE(dcorr);
+
+#ifdef DEBUG
+ if (debug > 1)
+ printf("refclock_pps: %lu %f %f\n", current_time,
+ dcorr, pp->fudgetime1);
+#endif
+ return (1);
+}
+#endif /* HAVE_PPSAPI */
+#endif /* REFCLOCK */
diff --git a/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_request.c b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_request.c
new file mode 100644
index 0000000..0c8e7b3
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_request.c
@@ -0,0 +1,2789 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * ntp_request.c - respond to information requests
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "ntpd.h"
+#include "ntp_io.h"
+#include "ntp_request.h"
+#include "ntp_control.h"
+#include "ntp_refclock.h"
+#include "ntp_if.h"
+#include "ntp_stdlib.h"
+#include "ntp_assert.h"
+
+#include <stdio.h>
+#include <stddef.h>
+#include <signal.h>
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#include <arpa/inet.h>
+
+#include "recvbuff.h"
+
+#ifdef KERNEL_PLL
+#include "ntp_syscall.h"
+#endif /* KERNEL_PLL */
+
+/*
+ * Structure to hold request procedure information
+ */
+#define NOAUTH 0
+#define AUTH 1
+
+#define NO_REQUEST (-1)
+/*
+ * Because we now have v6 addresses in the messages, we need to compensate
+ * for the larger size. Therefore, we introduce the alternate size to
+ * keep us friendly with older implementations. A little ugly.
+ */
+static int client_v6_capable = 0; /* the client can handle longer messages */
+
+#define v6sizeof(type) (client_v6_capable ? sizeof(type) : v4sizeof(type))
+
+struct req_proc {
+ short request_code; /* defined request code */
+ short needs_auth; /* true when authentication needed */
+ short sizeofitem; /* size of request data item (older size)*/
+ short v6_sizeofitem; /* size of request data item (new size)*/
+ void (*handler) (sockaddr_u *, endpt *,
+ struct req_pkt *); /* routine to handle request */
+};
+
+/*
+ * Universal request codes
+ */
+static const struct req_proc univ_codes[] = {
+ { NO_REQUEST, NOAUTH, 0, 0, NULL }
+};
+
+static void req_ack (sockaddr_u *, endpt *, struct req_pkt *, int);
+static void * prepare_pkt (sockaddr_u *, endpt *,
+ struct req_pkt *, size_t);
+static void * more_pkt (void);
+static void flush_pkt (void);
+static void list_peers (sockaddr_u *, endpt *, struct req_pkt *);
+static void list_peers_sum (sockaddr_u *, endpt *, struct req_pkt *);
+static void peer_info (sockaddr_u *, endpt *, struct req_pkt *);
+static void peer_stats (sockaddr_u *, endpt *, struct req_pkt *);
+static void sys_info (sockaddr_u *, endpt *, struct req_pkt *);
+static void sys_stats (sockaddr_u *, endpt *, struct req_pkt *);
+static void mem_stats (sockaddr_u *, endpt *, struct req_pkt *);
+static void io_stats (sockaddr_u *, endpt *, struct req_pkt *);
+static void timer_stats (sockaddr_u *, endpt *, struct req_pkt *);
+static void loop_info (sockaddr_u *, endpt *, struct req_pkt *);
+static void do_conf (sockaddr_u *, endpt *, struct req_pkt *);
+static void do_unconf (sockaddr_u *, endpt *, struct req_pkt *);
+static void set_sys_flag (sockaddr_u *, endpt *, struct req_pkt *);
+static void clr_sys_flag (sockaddr_u *, endpt *, struct req_pkt *);
+static void setclr_flags (sockaddr_u *, endpt *, struct req_pkt *, u_long);
+static void list_restrict4 (const restrict_u *, struct info_restrict **);
+static void list_restrict6 (const restrict_u *, struct info_restrict **);
+static void list_restrict (sockaddr_u *, endpt *, struct req_pkt *);
+static void do_resaddflags (sockaddr_u *, endpt *, struct req_pkt *);
+static void do_ressubflags (sockaddr_u *, endpt *, struct req_pkt *);
+static void do_unrestrict (sockaddr_u *, endpt *, struct req_pkt *);
+static void do_restrict (sockaddr_u *, endpt *, struct req_pkt *, restrict_op);
+static void mon_getlist (sockaddr_u *, endpt *, struct req_pkt *);
+static void reset_stats (sockaddr_u *, endpt *, struct req_pkt *);
+static void reset_peer (sockaddr_u *, endpt *, struct req_pkt *);
+static void do_key_reread (sockaddr_u *, endpt *, struct req_pkt *);
+static void trust_key (sockaddr_u *, endpt *, struct req_pkt *);
+static void untrust_key (sockaddr_u *, endpt *, struct req_pkt *);
+static void do_trustkey (sockaddr_u *, endpt *, struct req_pkt *, u_long);
+static void get_auth_info (sockaddr_u *, endpt *, struct req_pkt *);
+static void req_get_traps (sockaddr_u *, endpt *, struct req_pkt *);
+static void req_set_trap (sockaddr_u *, endpt *, struct req_pkt *);
+static void req_clr_trap (sockaddr_u *, endpt *, struct req_pkt *);
+static void do_setclr_trap (sockaddr_u *, endpt *, struct req_pkt *, int);
+static void set_request_keyid (sockaddr_u *, endpt *, struct req_pkt *);
+static void set_control_keyid (sockaddr_u *, endpt *, struct req_pkt *);
+static void get_ctl_stats (sockaddr_u *, endpt *, struct req_pkt *);
+static void get_if_stats (sockaddr_u *, endpt *, struct req_pkt *);
+static void do_if_reload (sockaddr_u *, endpt *, struct req_pkt *);
+#ifdef KERNEL_PLL
+static void get_kernel_info (sockaddr_u *, endpt *, struct req_pkt *);
+#endif /* KERNEL_PLL */
+#ifdef REFCLOCK
+static void get_clock_info (sockaddr_u *, endpt *, struct req_pkt *);
+static void set_clock_fudge (sockaddr_u *, endpt *, struct req_pkt *);
+#endif /* REFCLOCK */
+#ifdef REFCLOCK
+static void get_clkbug_info (sockaddr_u *, endpt *, struct req_pkt *);
+#endif /* REFCLOCK */
+
+/*
+ * ntpd request codes
+ */
+static const struct req_proc ntp_codes[] = {
+ { REQ_PEER_LIST, NOAUTH, 0, 0, list_peers },
+ { REQ_PEER_LIST_SUM, NOAUTH, 0, 0, list_peers_sum },
+ { REQ_PEER_INFO, NOAUTH, v4sizeof(struct info_peer_list),
+ sizeof(struct info_peer_list), peer_info},
+ { REQ_PEER_STATS, NOAUTH, v4sizeof(struct info_peer_list),
+ sizeof(struct info_peer_list), peer_stats},
+ { REQ_SYS_INFO, NOAUTH, 0, 0, sys_info },
+ { REQ_SYS_STATS, NOAUTH, 0, 0, sys_stats },
+ { REQ_IO_STATS, NOAUTH, 0, 0, io_stats },
+ { REQ_MEM_STATS, NOAUTH, 0, 0, mem_stats },
+ { REQ_LOOP_INFO, NOAUTH, 0, 0, loop_info },
+ { REQ_TIMER_STATS, NOAUTH, 0, 0, timer_stats },
+ { REQ_CONFIG, AUTH, v4sizeof(struct conf_peer),
+ sizeof(struct conf_peer), do_conf },
+ { REQ_UNCONFIG, AUTH, v4sizeof(struct conf_unpeer),
+ sizeof(struct conf_unpeer), do_unconf },
+ { REQ_SET_SYS_FLAG, AUTH, sizeof(struct conf_sys_flags),
+ sizeof(struct conf_sys_flags), set_sys_flag },
+ { REQ_CLR_SYS_FLAG, AUTH, sizeof(struct conf_sys_flags),
+ sizeof(struct conf_sys_flags), clr_sys_flag },
+ { REQ_GET_RESTRICT, NOAUTH, 0, 0, list_restrict },
+ { REQ_RESADDFLAGS, AUTH, v4sizeof(struct conf_restrict),
+ sizeof(struct conf_restrict), do_resaddflags },
+ { REQ_RESSUBFLAGS, AUTH, v4sizeof(struct conf_restrict),
+ sizeof(struct conf_restrict), do_ressubflags },
+ { REQ_UNRESTRICT, AUTH, v4sizeof(struct conf_restrict),
+ sizeof(struct conf_restrict), do_unrestrict },
+ { REQ_MON_GETLIST, NOAUTH, 0, 0, mon_getlist },
+ { REQ_MON_GETLIST_1, NOAUTH, 0, 0, mon_getlist },
+ { REQ_RESET_STATS, AUTH, sizeof(struct reset_flags), 0, reset_stats },
+ { REQ_RESET_PEER, AUTH, v4sizeof(struct conf_unpeer),
+ sizeof(struct conf_unpeer), reset_peer },
+ { REQ_REREAD_KEYS, AUTH, 0, 0, do_key_reread },
+ { REQ_TRUSTKEY, AUTH, sizeof(u_long), sizeof(u_long), trust_key },
+ { REQ_UNTRUSTKEY, AUTH, sizeof(u_long), sizeof(u_long), untrust_key },
+ { REQ_AUTHINFO, NOAUTH, 0, 0, get_auth_info },
+ { REQ_TRAPS, NOAUTH, 0, 0, req_get_traps },
+ { REQ_ADD_TRAP, AUTH, v4sizeof(struct conf_trap),
+ sizeof(struct conf_trap), req_set_trap },
+ { REQ_CLR_TRAP, AUTH, v4sizeof(struct conf_trap),
+ sizeof(struct conf_trap), req_clr_trap },
+ { REQ_REQUEST_KEY, AUTH, sizeof(u_long), sizeof(u_long),
+ set_request_keyid },
+ { REQ_CONTROL_KEY, AUTH, sizeof(u_long), sizeof(u_long),
+ set_control_keyid },
+ { REQ_GET_CTLSTATS, NOAUTH, 0, 0, get_ctl_stats },
+#ifdef KERNEL_PLL
+ { REQ_GET_KERNEL, NOAUTH, 0, 0, get_kernel_info },
+#endif
+#ifdef REFCLOCK
+ { REQ_GET_CLOCKINFO, NOAUTH, sizeof(u_int32), sizeof(u_int32),
+ get_clock_info },
+ { REQ_SET_CLKFUDGE, AUTH, sizeof(struct conf_fudge),
+ sizeof(struct conf_fudge), set_clock_fudge },
+ { REQ_GET_CLKBUGINFO, NOAUTH, sizeof(u_int32), sizeof(u_int32),
+ get_clkbug_info },
+#endif
+ { REQ_IF_STATS, AUTH, 0, 0, get_if_stats },
+ { REQ_IF_RELOAD, AUTH, 0, 0, do_if_reload },
+
+ { NO_REQUEST, NOAUTH, 0, 0, 0 }
+};
+
+
+/*
+ * Authentication keyid used to authenticate requests. Zero means we
+ * don't allow writing anything.
+ */
+keyid_t info_auth_keyid;
+
+/*
+ * Statistic counters to keep track of requests and responses.
+ */
+u_long numrequests; /* number of requests we've received */
+u_long numresppkts; /* number of resp packets sent with data */
+
+/*
+ * lazy way to count errors, indexed by the error code
+ */
+u_long errorcounter[MAX_INFO_ERR + 1];
+
+/*
+ * A hack. To keep the authentication module clear of ntp-ism's, we
+ * include a time reset variable for its stats here.
+ */
+u_long auth_timereset;
+
+/*
+ * Response packet used by these routines. Also some state information
+ * so that we can handle packet formatting within a common set of
+ * subroutines. Note we try to enter data in place whenever possible,
+ * but the need to set the more bit correctly means we occasionally
+ * use the extra buffer and copy.
+ */
+static struct resp_pkt rpkt;
+static int reqver;
+static int seqno;
+static int nitems;
+static int itemsize;
+static int databytes;
+static char exbuf[RESP_DATA_SIZE];
+static int usingexbuf;
+static sockaddr_u *toaddr;
+static endpt *frominter;
+
+/*
+ * init_request - initialize request data
+ */
+void
+init_request (void)
+{
+ size_t i;
+
+ numrequests = 0;
+ numresppkts = 0;
+ auth_timereset = 0;
+ info_auth_keyid = 0; /* by default, can't do this */
+
+ for (i = 0; i < sizeof(errorcounter)/sizeof(errorcounter[0]); i++)
+ errorcounter[i] = 0;
+}
+
+
+/*
+ * req_ack - acknowledge request with no data
+ */
+static void
+req_ack(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt,
+ int errcode
+ )
+{
+ /*
+ * fill in the fields
+ */
+ rpkt.rm_vn_mode = RM_VN_MODE(RESP_BIT, 0, reqver);
+ rpkt.auth_seq = AUTH_SEQ(0, 0);
+ rpkt.implementation = inpkt->implementation;
+ rpkt.request = inpkt->request;
+ rpkt.err_nitems = ERR_NITEMS(errcode, 0);
+ rpkt.mbz_itemsize = MBZ_ITEMSIZE(0);
+
+ /*
+ * send packet and bump counters
+ */
+ sendpkt(srcadr, inter, -1, (struct pkt *)&rpkt, RESP_HEADER_SIZE);
+ errorcounter[errcode]++;
+}
+
+
+/*
+ * prepare_pkt - prepare response packet for transmission, return pointer
+ * to storage for data item.
+ */
+static void *
+prepare_pkt(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *pkt,
+ size_t structsize
+ )
+{
+ DPRINTF(4, ("request: preparing pkt\n"));
+
+ /*
+ * Fill in the implementation, request and itemsize fields
+ * since these won't change.
+ */
+ rpkt.implementation = pkt->implementation;
+ rpkt.request = pkt->request;
+ rpkt.mbz_itemsize = MBZ_ITEMSIZE(structsize);
+
+ /*
+ * Compute the static data needed to carry on.
+ */
+ toaddr = srcadr;
+ frominter = inter;
+ seqno = 0;
+ nitems = 0;
+ itemsize = structsize;
+ databytes = 0;
+ usingexbuf = 0;
+
+ /*
+ * return the beginning of the packet buffer.
+ */
+ return &rpkt.u;
+}
+
+
+/*
+ * more_pkt - return a data pointer for a new item.
+ */
+static void *
+more_pkt(void)
+{
+ /*
+ * If we were using the extra buffer, send the packet.
+ */
+ if (usingexbuf) {
+ DPRINTF(3, ("request: sending pkt\n"));
+ rpkt.rm_vn_mode = RM_VN_MODE(RESP_BIT, MORE_BIT, reqver);
+ rpkt.auth_seq = AUTH_SEQ(0, seqno);
+ rpkt.err_nitems = htons((u_short)nitems);
+ sendpkt(toaddr, frominter, -1, (struct pkt *)&rpkt,
+ RESP_HEADER_SIZE + databytes);
+ numresppkts++;
+
+ /*
+ * Copy data out of exbuf into the packet.
+ */
+ memcpy(&rpkt.u.data[0], exbuf, (unsigned)itemsize);
+ seqno++;
+ databytes = 0;
+ nitems = 0;
+ usingexbuf = 0;
+ }
+
+ databytes += itemsize;
+ nitems++;
+ if (databytes + itemsize <= RESP_DATA_SIZE) {
+ DPRINTF(4, ("request: giving him more data\n"));
+ /*
+ * More room in packet. Give him the
+ * next address.
+ */
+ return &rpkt.u.data[databytes];
+ } else {
+ /*
+ * No room in packet. Give him the extra
+ * buffer unless this was the last in the sequence.
+ */
+ DPRINTF(4, ("request: into extra buffer\n"));
+ if (seqno == MAXSEQ)
+ return NULL;
+ else {
+ usingexbuf = 1;
+ return exbuf;
+ }
+ }
+}
+
+
+/*
+ * flush_pkt - we're done, return remaining information.
+ */
+static void
+flush_pkt(void)
+{
+ DPRINTF(3, ("request: flushing packet, %d items\n", nitems));
+ /*
+ * Must send the last packet. If nothing in here and nothing
+ * has been sent, send an error saying no data to be found.
+ */
+ if (seqno == 0 && nitems == 0)
+ req_ack(toaddr, frominter, (struct req_pkt *)&rpkt,
+ INFO_ERR_NODATA);
+ else {
+ rpkt.rm_vn_mode = RM_VN_MODE(RESP_BIT, 0, reqver);
+ rpkt.auth_seq = AUTH_SEQ(0, seqno);
+ rpkt.err_nitems = htons((u_short)nitems);
+ sendpkt(toaddr, frominter, -1, (struct pkt *)&rpkt,
+ RESP_HEADER_SIZE+databytes);
+ numresppkts++;
+ }
+}
+
+
+
+/*
+ * Given a buffer, return the packet mode
+ */
+int
+get_packet_mode(struct recvbuf *rbufp)
+{
+ struct req_pkt *inpkt = (struct req_pkt *)&rbufp->recv_pkt;
+ return (INFO_MODE(inpkt->rm_vn_mode));
+}
+
+
+/*
+ * process_private - process private mode (7) packets
+ */
+void
+process_private(
+ struct recvbuf *rbufp,
+ int mod_okay
+ )
+{
+ static u_long quiet_until;
+ struct req_pkt *inpkt;
+ struct req_pkt_tail *tailinpkt;
+ sockaddr_u *srcadr;
+ endpt *inter;
+ const struct req_proc *proc;
+ int ec;
+ short temp_size;
+ l_fp ftmp;
+ double dtemp;
+ size_t recv_len;
+ size_t noslop_len;
+ size_t mac_len;
+
+ /*
+ * Initialize pointers, for convenience
+ */
+ recv_len = rbufp->recv_length;
+ inpkt = (struct req_pkt *)&rbufp->recv_pkt;
+ srcadr = &rbufp->recv_srcadr;
+ inter = rbufp->dstadr;
+
+ DPRINTF(3, ("process_private: impl %d req %d\n",
+ inpkt->implementation, inpkt->request));
+
+ /*
+ * Do some sanity checks on the packet. Return a format
+ * error if it fails.
+ */
+ ec = 0;
+ if ( (++ec, ISRESPONSE(inpkt->rm_vn_mode))
+ || (++ec, ISMORE(inpkt->rm_vn_mode))
+ || (++ec, INFO_VERSION(inpkt->rm_vn_mode) > NTP_VERSION)
+ || (++ec, INFO_VERSION(inpkt->rm_vn_mode) < NTP_OLDVERSION)
+ || (++ec, INFO_SEQ(inpkt->auth_seq) != 0)
+ || (++ec, INFO_ERR(inpkt->err_nitems) != 0)
+ || (++ec, INFO_MBZ(inpkt->mbz_itemsize) != 0)
+ || (++ec, rbufp->recv_length < (int)REQ_LEN_HDR)
+ ) {
+ NLOG(NLOG_SYSEVENT)
+ if (current_time >= quiet_until) {
+ msyslog(LOG_ERR,
+ "process_private: drop test %d"
+ " failed, pkt from %s",
+ ec, stoa(srcadr));
+ quiet_until = current_time + 60;
+ }
+ return;
+ }
+
+ reqver = INFO_VERSION(inpkt->rm_vn_mode);
+
+ /*
+ * Get the appropriate procedure list to search.
+ */
+ if (inpkt->implementation == IMPL_UNIV)
+ proc = univ_codes;
+ else if ((inpkt->implementation == IMPL_XNTPD) ||
+ (inpkt->implementation == IMPL_XNTPD_OLD))
+ proc = ntp_codes;
+ else {
+ req_ack(srcadr, inter, inpkt, INFO_ERR_IMPL);
+ return;
+ }
+
+ /*
+ * Search the list for the request codes. If it isn't one
+ * we know, return an error.
+ */
+ while (proc->request_code != NO_REQUEST) {
+ if (proc->request_code == (short) inpkt->request)
+ break;
+ proc++;
+ }
+ if (proc->request_code == NO_REQUEST) {
+ req_ack(srcadr, inter, inpkt, INFO_ERR_REQ);
+ return;
+ }
+
+ DPRINTF(4, ("found request in tables\n"));
+
+ /*
+ * If we need data, check to see if we have some. If we
+ * don't, check to see that there is none (picky, picky).
+ */
+
+ /* This part is a bit tricky, we want to be sure that the size
+ * returned is either the old or the new size. We also can find
+ * out if the client can accept both types of messages this way.
+ *
+ * Handle the exception of REQ_CONFIG. It can have two data sizes.
+ */
+ temp_size = INFO_ITEMSIZE(inpkt->mbz_itemsize);
+ if ((temp_size != proc->sizeofitem &&
+ temp_size != proc->v6_sizeofitem) &&
+ !(inpkt->implementation == IMPL_XNTPD &&
+ inpkt->request == REQ_CONFIG &&
+ temp_size == sizeof(struct old_conf_peer))) {
+ DPRINTF(3, ("process_private: wrong item size, received %d, should be %d or %d\n",
+ temp_size, proc->sizeofitem, proc->v6_sizeofitem));
+ req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
+ return;
+ }
+ if ((proc->sizeofitem != 0) &&
+ ((size_t)(temp_size * INFO_NITEMS(inpkt->err_nitems)) >
+ (recv_len - REQ_LEN_HDR))) {
+ DPRINTF(3, ("process_private: not enough data\n"));
+ req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
+ return;
+ }
+
+ switch (inpkt->implementation) {
+ case IMPL_XNTPD:
+ client_v6_capable = 1;
+ break;
+ case IMPL_XNTPD_OLD:
+ client_v6_capable = 0;
+ break;
+ default:
+ req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
+ return;
+ }
+
+ /*
+ * If we need to authenticate, do so. Note that an
+ * authenticatable packet must include a mac field, must
+ * have used key info_auth_keyid and must have included
+ * a time stamp in the appropriate field. The time stamp
+ * must be within INFO_TS_MAXSKEW of the receive
+ * time stamp.
+ */
+ if (proc->needs_auth && sys_authenticate) {
+
+ if (recv_len < (REQ_LEN_HDR +
+ (INFO_ITEMSIZE(inpkt->mbz_itemsize) *
+ INFO_NITEMS(inpkt->err_nitems)) +
+ REQ_TAIL_MIN)) {
+ req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
+ return;
+ }
+
+ /*
+ * For 16-octet digests, regardless of itemsize and
+ * nitems, authenticated requests are a fixed size
+ * with the timestamp, key ID, and digest located
+ * at the end of the packet. Because the key ID
+ * determining the digest size precedes the digest,
+ * for larger digests the fixed size request scheme
+ * is abandoned and the timestamp, key ID, and digest
+ * are located relative to the start of the packet,
+ * with the digest size determined by the packet size.
+ */
+ noslop_len = REQ_LEN_HDR
+ + INFO_ITEMSIZE(inpkt->mbz_itemsize) *
+ INFO_NITEMS(inpkt->err_nitems)
+ + sizeof(inpkt->tstamp);
+ /* 32-bit alignment */
+ noslop_len = (noslop_len + 3) & ~3;
+ if (recv_len > (noslop_len + MAX_MAC_LEN))
+ mac_len = 20;
+ else
+ mac_len = recv_len - noslop_len;
+
+ tailinpkt = (void *)((char *)inpkt + recv_len -
+ (mac_len + sizeof(inpkt->tstamp)));
+
+ /*
+ * If this guy is restricted from doing this, don't let
+ * him. If the wrong key was used, or packet doesn't
+ * have mac, return.
+ */
+ /* XXX: Use authistrustedip(), or equivalent. */
+ if (!INFO_IS_AUTH(inpkt->auth_seq) || !info_auth_keyid
+ || ntohl(tailinpkt->keyid) != info_auth_keyid) {
+ DPRINTF(5, ("failed auth %d info_auth_keyid %u pkt keyid %u maclen %lu\n",
+ INFO_IS_AUTH(inpkt->auth_seq),
+ info_auth_keyid,
+ ntohl(tailinpkt->keyid), (u_long)mac_len));
+#ifdef DEBUG
+ msyslog(LOG_DEBUG,
+ "process_private: failed auth %d info_auth_keyid %u pkt keyid %u maclen %lu\n",
+ INFO_IS_AUTH(inpkt->auth_seq),
+ info_auth_keyid,
+ ntohl(tailinpkt->keyid), (u_long)mac_len);
+#endif
+ req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH);
+ return;
+ }
+ if (recv_len > REQ_LEN_NOMAC + MAX_MAC_LEN) {
+ DPRINTF(5, ("bad pkt length %zu\n", recv_len));
+ msyslog(LOG_ERR,
+ "process_private: bad pkt length %zu",
+ recv_len);
+ req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
+ return;
+ }
+ if (!mod_okay || !authhavekey(info_auth_keyid)) {
+ DPRINTF(5, ("failed auth mod_okay %d\n",
+ mod_okay));
+#ifdef DEBUG
+ msyslog(LOG_DEBUG,
+ "process_private: failed auth mod_okay %d\n",
+ mod_okay);
+#endif
+ if (!mod_okay) {
+ sys_restricted++;
+ }
+ req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH);
+ return;
+ }
+
+ /*
+ * calculate absolute time difference between xmit time stamp
+ * and receive time stamp. If too large, too bad.
+ */
+ NTOHL_FP(&tailinpkt->tstamp, &ftmp);
+ L_SUB(&ftmp, &rbufp->recv_time);
+ LFPTOD(&ftmp, dtemp);
+ if (fabs(dtemp) > INFO_TS_MAXSKEW) {
+ /*
+ * He's a loser. Tell him.
+ */
+ DPRINTF(5, ("xmit/rcv timestamp delta %g > INFO_TS_MAXSKEW %g\n",
+ dtemp, INFO_TS_MAXSKEW));
+ req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH);
+ return;
+ }
+
+ /*
+ * So far so good. See if decryption works out okay.
+ */
+ if (!authdecrypt(info_auth_keyid, (u_int32 *)inpkt,
+ recv_len - mac_len, mac_len)) {
+ DPRINTF(5, ("authdecrypt failed\n"));
+ req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH);
+ return;
+ }
+ }
+
+ DPRINTF(3, ("process_private: all okay, into handler\n"));
+ /*
+ * Packet is okay. Call the handler to send him data.
+ */
+ (proc->handler)(srcadr, inter, inpkt);
+}
+
+
+/*
+ * list_peers - send a list of the peers
+ */
+static void
+list_peers(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt
+ )
+{
+ struct info_peer_list * ip;
+ const struct peer * pp;
+
+ ip = (struct info_peer_list *)prepare_pkt(srcadr, inter, inpkt,
+ v6sizeof(struct info_peer_list));
+ for (pp = peer_list; pp != NULL && ip != NULL; pp = pp->p_link) {
+ if (IS_IPV6(&pp->srcadr)) {
+ if (!client_v6_capable)
+ continue;
+ ip->addr6 = SOCK_ADDR6(&pp->srcadr);
+ ip->v6_flag = 1;
+ } else {
+ ip->addr = NSRCADR(&pp->srcadr);
+ if (client_v6_capable)
+ ip->v6_flag = 0;
+ }
+
+ ip->port = NSRCPORT(&pp->srcadr);
+ ip->hmode = pp->hmode;
+ ip->flags = 0;
+ if (pp->flags & FLAG_CONFIG)
+ ip->flags |= INFO_FLAG_CONFIG;
+ if (pp == sys_peer)
+ ip->flags |= INFO_FLAG_SYSPEER;
+ if (pp->status == CTL_PST_SEL_SYNCCAND)
+ ip->flags |= INFO_FLAG_SEL_CANDIDATE;
+ if (pp->status >= CTL_PST_SEL_SYSPEER)
+ ip->flags |= INFO_FLAG_SHORTLIST;
+ ip = (struct info_peer_list *)more_pkt();
+ } /* for pp */
+
+ flush_pkt();
+}
+
+
+/*
+ * list_peers_sum - return extended peer list
+ */
+static void
+list_peers_sum(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt
+ )
+{
+ struct info_peer_summary * ips;
+ const struct peer * pp;
+ l_fp ltmp;
+
+ DPRINTF(3, ("wants peer list summary\n"));
+
+ ips = (struct info_peer_summary *)prepare_pkt(srcadr, inter, inpkt,
+ v6sizeof(struct info_peer_summary));
+ for (pp = peer_list; pp != NULL && ips != NULL; pp = pp->p_link) {
+ DPRINTF(4, ("sum: got one\n"));
+ /*
+ * Be careful here not to return v6 peers when we
+ * want only v4.
+ */
+ if (IS_IPV6(&pp->srcadr)) {
+ if (!client_v6_capable)
+ continue;
+ ips->srcadr6 = SOCK_ADDR6(&pp->srcadr);
+ ips->v6_flag = 1;
+ if (pp->dstadr)
+ ips->dstadr6 = SOCK_ADDR6(&pp->dstadr->sin);
+ else
+ ZERO(ips->dstadr6);
+ } else {
+ ips->srcadr = NSRCADR(&pp->srcadr);
+ if (client_v6_capable)
+ ips->v6_flag = 0;
+
+ if (pp->dstadr) {
+ if (!pp->processed)
+ ips->dstadr = NSRCADR(&pp->dstadr->sin);
+ else {
+ if (MDF_BCAST == pp->cast_flags)
+ ips->dstadr = NSRCADR(&pp->dstadr->bcast);
+ else if (pp->cast_flags) {
+ ips->dstadr = NSRCADR(&pp->dstadr->sin);
+ if (!ips->dstadr)
+ ips->dstadr = NSRCADR(&pp->dstadr->bcast);
+ }
+ }
+ } else {
+ ips->dstadr = 0;
+ }
+ }
+
+ ips->srcport = NSRCPORT(&pp->srcadr);
+ ips->stratum = pp->stratum;
+ ips->hpoll = pp->hpoll;
+ ips->ppoll = pp->ppoll;
+ ips->reach = pp->reach;
+ ips->flags = 0;
+ if (pp == sys_peer)
+ ips->flags |= INFO_FLAG_SYSPEER;
+ if (pp->flags & FLAG_CONFIG)
+ ips->flags |= INFO_FLAG_CONFIG;
+ if (pp->flags & FLAG_REFCLOCK)
+ ips->flags |= INFO_FLAG_REFCLOCK;
+ if (pp->flags & FLAG_PREFER)
+ ips->flags |= INFO_FLAG_PREFER;
+ if (pp->flags & FLAG_BURST)
+ ips->flags |= INFO_FLAG_BURST;
+ if (pp->status == CTL_PST_SEL_SYNCCAND)
+ ips->flags |= INFO_FLAG_SEL_CANDIDATE;
+ if (pp->status >= CTL_PST_SEL_SYSPEER)
+ ips->flags |= INFO_FLAG_SHORTLIST;
+ ips->hmode = pp->hmode;
+ ips->delay = HTONS_FP(DTOFP(pp->delay));
+ DTOLFP(pp->offset, &ltmp);
+ HTONL_FP(&ltmp, &ips->offset);
+ ips->dispersion = HTONS_FP(DTOUFP(SQRT(pp->disp)));
+
+ ips = (struct info_peer_summary *)more_pkt();
+ } /* for pp */
+
+ flush_pkt();
+}
+
+
+/*
+ * peer_info - send information for one or more peers
+ */
+static void
+peer_info (
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt
+ )
+{
+ u_short items;
+ size_t item_sz;
+ char * datap;
+ struct info_peer_list ipl;
+ struct peer * pp;
+ struct info_peer * ip;
+ int i;
+ int j;
+ sockaddr_u addr;
+ l_fp ltmp;
+
+ items = INFO_NITEMS(inpkt->err_nitems);
+ item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize);
+ datap = inpkt->u.data;
+ if (item_sz != sizeof(ipl)) {
+ req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
+ return;
+ }
+ ip = prepare_pkt(srcadr, inter, inpkt,
+ v6sizeof(struct info_peer));
+ while (items-- > 0 && ip != NULL) {
+ ZERO(ipl);
+ memcpy(&ipl, datap, item_sz);
+ ZERO_SOCK(&addr);
+ NSRCPORT(&addr) = ipl.port;
+ if (client_v6_capable && ipl.v6_flag) {
+ AF(&addr) = AF_INET6;
+ SOCK_ADDR6(&addr) = ipl.addr6;
+ } else {
+ AF(&addr) = AF_INET;
+ NSRCADR(&addr) = ipl.addr;
+ }
+#ifdef ISC_PLATFORM_HAVESALEN
+ addr.sa.sa_len = SOCKLEN(&addr);
+#endif
+ datap += item_sz;
+
+ pp = findexistingpeer(&addr, NULL, NULL, -1, 0, NULL);
+ if (NULL == pp)
+ continue;
+ if (IS_IPV6(srcadr)) {
+ if (pp->dstadr)
+ ip->dstadr6 =
+ (MDF_BCAST == pp->cast_flags)
+ ? SOCK_ADDR6(&pp->dstadr->bcast)
+ : SOCK_ADDR6(&pp->dstadr->sin);
+ else
+ ZERO(ip->dstadr6);
+
+ ip->srcadr6 = SOCK_ADDR6(&pp->srcadr);
+ ip->v6_flag = 1;
+ } else {
+ if (pp->dstadr) {
+ if (!pp->processed)
+ ip->dstadr = NSRCADR(&pp->dstadr->sin);
+ else {
+ if (MDF_BCAST == pp->cast_flags)
+ ip->dstadr = NSRCADR(&pp->dstadr->bcast);
+ else if (pp->cast_flags) {
+ ip->dstadr = NSRCADR(&pp->dstadr->sin);
+ if (!ip->dstadr)
+ ip->dstadr = NSRCADR(&pp->dstadr->bcast);
+ }
+ }
+ } else
+ ip->dstadr = 0;
+
+ ip->srcadr = NSRCADR(&pp->srcadr);
+ if (client_v6_capable)
+ ip->v6_flag = 0;
+ }
+ ip->srcport = NSRCPORT(&pp->srcadr);
+ ip->flags = 0;
+ if (pp == sys_peer)
+ ip->flags |= INFO_FLAG_SYSPEER;
+ if (pp->flags & FLAG_CONFIG)
+ ip->flags |= INFO_FLAG_CONFIG;
+ if (pp->flags & FLAG_REFCLOCK)
+ ip->flags |= INFO_FLAG_REFCLOCK;
+ if (pp->flags & FLAG_PREFER)
+ ip->flags |= INFO_FLAG_PREFER;
+ if (pp->flags & FLAG_BURST)
+ ip->flags |= INFO_FLAG_BURST;
+ if (pp->status == CTL_PST_SEL_SYNCCAND)
+ ip->flags |= INFO_FLAG_SEL_CANDIDATE;
+ if (pp->status >= CTL_PST_SEL_SYSPEER)
+ ip->flags |= INFO_FLAG_SHORTLIST;
+ ip->leap = pp->leap;
+ ip->hmode = pp->hmode;
+ ip->pmode = pp->pmode;
+ ip->keyid = pp->keyid;
+ ip->stratum = pp->stratum;
+ ip->ppoll = pp->ppoll;
+ ip->hpoll = pp->hpoll;
+ ip->precision = pp->precision;
+ ip->version = pp->version;
+ ip->reach = pp->reach;
+ ip->unreach = (u_char)pp->unreach;
+ ip->flash = (u_char)pp->flash;
+ ip->flash2 = (u_short)pp->flash;
+ ip->estbdelay = HTONS_FP(DTOFP(pp->delay));
+ ip->ttl = (u_char)pp->ttl;
+ ip->associd = htons(pp->associd);
+ ip->rootdelay = HTONS_FP(DTOUFP(pp->rootdelay));
+ ip->rootdispersion = HTONS_FP(DTOUFP(pp->rootdisp));
+ ip->refid = pp->refid;
+ HTONL_FP(&pp->reftime, &ip->reftime);
+ HTONL_FP(&pp->aorg, &ip->org);
+ HTONL_FP(&pp->rec, &ip->rec);
+ HTONL_FP(&pp->xmt, &ip->xmt);
+ j = pp->filter_nextpt - 1;
+ for (i = 0; i < NTP_SHIFT; i++, j--) {
+ if (j < 0)
+ j = NTP_SHIFT-1;
+ ip->filtdelay[i] = HTONS_FP(DTOFP(pp->filter_delay[j]));
+ DTOLFP(pp->filter_offset[j], &ltmp);
+ HTONL_FP(&ltmp, &ip->filtoffset[i]);
+ ip->order[i] = (u_char)((pp->filter_nextpt +
+ NTP_SHIFT - 1) -
+ pp->filter_order[i]);
+ if (ip->order[i] >= NTP_SHIFT)
+ ip->order[i] -= NTP_SHIFT;
+ }
+ DTOLFP(pp->offset, &ltmp);
+ HTONL_FP(&ltmp, &ip->offset);
+ ip->delay = HTONS_FP(DTOFP(pp->delay));
+ ip->dispersion = HTONS_FP(DTOUFP(SQRT(pp->disp)));
+ ip->selectdisp = HTONS_FP(DTOUFP(SQRT(pp->jitter)));
+ ip = more_pkt();
+ }
+ flush_pkt();
+}
+
+
+/*
+ * peer_stats - send statistics for one or more peers
+ */
+static void
+peer_stats (
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt
+ )
+{
+ u_short items;
+ size_t item_sz;
+ char * datap;
+ struct info_peer_list ipl;
+ struct peer * pp;
+ struct info_peer_stats *ip;
+ sockaddr_u addr;
+
+ DPRINTF(1, ("peer_stats: called\n"));
+ items = INFO_NITEMS(inpkt->err_nitems);
+ item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize);
+ datap = inpkt->u.data;
+ if (item_sz > sizeof(ipl)) {
+ req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
+ return;
+ }
+ ip = prepare_pkt(srcadr, inter, inpkt,
+ v6sizeof(struct info_peer_stats));
+ while (items-- > 0 && ip != NULL) {
+ ZERO(ipl);
+ memcpy(&ipl, datap, item_sz);
+ ZERO(addr);
+ NSRCPORT(&addr) = ipl.port;
+ if (client_v6_capable && ipl.v6_flag) {
+ AF(&addr) = AF_INET6;
+ SOCK_ADDR6(&addr) = ipl.addr6;
+ } else {
+ AF(&addr) = AF_INET;
+ NSRCADR(&addr) = ipl.addr;
+ }
+#ifdef ISC_PLATFORM_HAVESALEN
+ addr.sa.sa_len = SOCKLEN(&addr);
+#endif
+ DPRINTF(1, ("peer_stats: looking for %s, %d, %d\n",
+ stoa(&addr), ipl.port, NSRCPORT(&addr)));
+
+ datap += item_sz;
+
+ pp = findexistingpeer(&addr, NULL, NULL, -1, 0, NULL);
+ if (NULL == pp)
+ continue;
+
+ DPRINTF(1, ("peer_stats: found %s\n", stoa(&addr)));
+
+ if (IS_IPV4(&pp->srcadr)) {
+ if (pp->dstadr) {
+ if (!pp->processed)
+ ip->dstadr = NSRCADR(&pp->dstadr->sin);
+ else {
+ if (MDF_BCAST == pp->cast_flags)
+ ip->dstadr = NSRCADR(&pp->dstadr->bcast);
+ else if (pp->cast_flags) {
+ ip->dstadr = NSRCADR(&pp->dstadr->sin);
+ if (!ip->dstadr)
+ ip->dstadr = NSRCADR(&pp->dstadr->bcast);
+ }
+ }
+ } else
+ ip->dstadr = 0;
+
+ ip->srcadr = NSRCADR(&pp->srcadr);
+ if (client_v6_capable)
+ ip->v6_flag = 0;
+ } else {
+ if (pp->dstadr)
+ ip->dstadr6 =
+ (MDF_BCAST == pp->cast_flags)
+ ? SOCK_ADDR6(&pp->dstadr->bcast)
+ : SOCK_ADDR6(&pp->dstadr->sin);
+ else
+ ZERO(ip->dstadr6);
+
+ ip->srcadr6 = SOCK_ADDR6(&pp->srcadr);
+ ip->v6_flag = 1;
+ }
+ ip->srcport = NSRCPORT(&pp->srcadr);
+ ip->flags = 0;
+ if (pp == sys_peer)
+ ip->flags |= INFO_FLAG_SYSPEER;
+ if (pp->flags & FLAG_CONFIG)
+ ip->flags |= INFO_FLAG_CONFIG;
+ if (pp->flags & FLAG_REFCLOCK)
+ ip->flags |= INFO_FLAG_REFCLOCK;
+ if (pp->flags & FLAG_PREFER)
+ ip->flags |= INFO_FLAG_PREFER;
+ if (pp->flags & FLAG_BURST)
+ ip->flags |= INFO_FLAG_BURST;
+ if (pp->flags & FLAG_IBURST)
+ ip->flags |= INFO_FLAG_IBURST;
+ if (pp->status == CTL_PST_SEL_SYNCCAND)
+ ip->flags |= INFO_FLAG_SEL_CANDIDATE;
+ if (pp->status >= CTL_PST_SEL_SYSPEER)
+ ip->flags |= INFO_FLAG_SHORTLIST;
+ ip->flags = htons(ip->flags);
+ ip->timereceived = htonl((u_int32)(current_time - pp->timereceived));
+ ip->timetosend = htonl(pp->nextdate - current_time);
+ ip->timereachable = htonl((u_int32)(current_time - pp->timereachable));
+ ip->sent = htonl((u_int32)(pp->sent));
+ ip->processed = htonl((u_int32)(pp->processed));
+ ip->badauth = htonl((u_int32)(pp->badauth));
+ ip->bogusorg = htonl((u_int32)(pp->bogusorg));
+ ip->oldpkt = htonl((u_int32)(pp->oldpkt));
+ ip->seldisp = htonl((u_int32)(pp->seldisptoolarge));
+ ip->selbroken = htonl((u_int32)(pp->selbroken));
+ ip->candidate = pp->status;
+ ip = (struct info_peer_stats *)more_pkt();
+ }
+ flush_pkt();
+}
+
+
+/*
+ * sys_info - return system info
+ */
+static void
+sys_info(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt
+ )
+{
+ register struct info_sys *is;
+
+ is = (struct info_sys *)prepare_pkt(srcadr, inter, inpkt,
+ v6sizeof(struct info_sys));
+
+ if (sys_peer) {
+ if (IS_IPV4(&sys_peer->srcadr)) {
+ is->peer = NSRCADR(&sys_peer->srcadr);
+ if (client_v6_capable)
+ is->v6_flag = 0;
+ } else if (client_v6_capable) {
+ is->peer6 = SOCK_ADDR6(&sys_peer->srcadr);
+ is->v6_flag = 1;
+ }
+ is->peer_mode = sys_peer->hmode;
+ } else {
+ is->peer = 0;
+ if (client_v6_capable) {
+ is->v6_flag = 0;
+ }
+ is->peer_mode = 0;
+ }
+
+ is->leap = sys_leap;
+ is->stratum = sys_stratum;
+ is->precision = sys_precision;
+ is->rootdelay = htonl(DTOFP(sys_rootdelay));
+ is->rootdispersion = htonl(DTOUFP(sys_rootdisp));
+ is->frequency = htonl(DTOFP(sys_jitter));
+ is->stability = htonl(DTOUFP(clock_stability * 1e6));
+ is->refid = sys_refid;
+ HTONL_FP(&sys_reftime, &is->reftime);
+
+ is->poll = sys_poll;
+
+ is->flags = 0;
+ if (sys_authenticate)
+ is->flags |= INFO_FLAG_AUTHENTICATE;
+ if (sys_bclient)
+ is->flags |= INFO_FLAG_BCLIENT;
+#ifdef REFCLOCK
+ if (cal_enable)
+ is->flags |= INFO_FLAG_CAL;
+#endif /* REFCLOCK */
+ if (kern_enable)
+ is->flags |= INFO_FLAG_KERNEL;
+ if (mon_enabled != MON_OFF)
+ is->flags |= INFO_FLAG_MONITOR;
+ if (ntp_enable)
+ is->flags |= INFO_FLAG_NTP;
+ if (hardpps_enable)
+ is->flags |= INFO_FLAG_PPS_SYNC;
+ if (stats_control)
+ is->flags |= INFO_FLAG_FILEGEN;
+ is->bdelay = HTONS_FP(DTOFP(sys_bdelay));
+ HTONL_UF(sys_authdelay.l_uf, &is->authdelay);
+ (void) more_pkt();
+ flush_pkt();
+}
+
+
+/*
+ * sys_stats - return system statistics
+ */
+static void
+sys_stats(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt
+ )
+{
+ register struct info_sys_stats *ss;
+
+ ss = (struct info_sys_stats *)prepare_pkt(srcadr, inter, inpkt,
+ sizeof(struct info_sys_stats));
+ ss->timeup = htonl((u_int32)current_time);
+ ss->timereset = htonl((u_int32)(current_time - sys_stattime));
+ ss->denied = htonl((u_int32)sys_restricted);
+ ss->oldversionpkt = htonl((u_int32)sys_oldversion);
+ ss->newversionpkt = htonl((u_int32)sys_newversion);
+ ss->unknownversion = htonl((u_int32)sys_declined);
+ ss->badlength = htonl((u_int32)sys_badlength);
+ ss->processed = htonl((u_int32)sys_processed);
+ ss->badauth = htonl((u_int32)sys_badauth);
+ ss->limitrejected = htonl((u_int32)sys_limitrejected);
+ ss->received = htonl((u_int32)sys_received);
+ ss->lamport = htonl((u_int32)sys_lamport);
+ ss->tsrounding = htonl((u_int32)sys_tsrounding);
+ (void) more_pkt();
+ flush_pkt();
+}
+
+
+/*
+ * mem_stats - return memory statistics
+ */
+static void
+mem_stats(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt
+ )
+{
+ register struct info_mem_stats *ms;
+ register int i;
+
+ ms = (struct info_mem_stats *)prepare_pkt(srcadr, inter, inpkt,
+ sizeof(struct info_mem_stats));
+
+ ms->timereset = htonl((u_int32)(current_time - peer_timereset));
+ ms->totalpeermem = htons((u_short)total_peer_structs);
+ ms->freepeermem = htons((u_short)peer_free_count);
+ ms->findpeer_calls = htonl((u_int32)findpeer_calls);
+ ms->allocations = htonl((u_int32)peer_allocations);
+ ms->demobilizations = htonl((u_int32)peer_demobilizations);
+
+ for (i = 0; i < NTP_HASH_SIZE; i++)
+ ms->hashcount[i] = (u_char)
+ max((u_int)peer_hash_count[i], UCHAR_MAX);
+
+ (void) more_pkt();
+ flush_pkt();
+}
+
+
+/*
+ * io_stats - return io statistics
+ */
+static void
+io_stats(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt
+ )
+{
+ struct info_io_stats *io;
+
+ io = (struct info_io_stats *)prepare_pkt(srcadr, inter, inpkt,
+ sizeof(struct info_io_stats));
+
+ io->timereset = htonl((u_int32)(current_time - io_timereset));
+ io->totalrecvbufs = htons((u_short) total_recvbuffs());
+ io->freerecvbufs = htons((u_short) free_recvbuffs());
+ io->fullrecvbufs = htons((u_short) full_recvbuffs());
+ io->lowwater = htons((u_short) lowater_additions());
+ io->dropped = htonl((u_int32)packets_dropped);
+ io->ignored = htonl((u_int32)packets_ignored);
+ io->received = htonl((u_int32)packets_received);
+ io->sent = htonl((u_int32)packets_sent);
+ io->notsent = htonl((u_int32)packets_notsent);
+ io->interrupts = htonl((u_int32)handler_calls);
+ io->int_received = htonl((u_int32)handler_pkts);
+
+ (void) more_pkt();
+ flush_pkt();
+}
+
+
+/*
+ * timer_stats - return timer statistics
+ */
+static void
+timer_stats(
+ sockaddr_u * srcadr,
+ endpt * inter,
+ struct req_pkt * inpkt
+ )
+{
+ struct info_timer_stats * ts;
+ u_long sincereset;
+
+ ts = (struct info_timer_stats *)prepare_pkt(srcadr, inter,
+ inpkt, sizeof(*ts));
+
+ sincereset = current_time - timer_timereset;
+ ts->timereset = htonl((u_int32)sincereset);
+ ts->alarms = ts->timereset;
+ ts->overflows = htonl((u_int32)alarm_overflow);
+ ts->xmtcalls = htonl((u_int32)timer_xmtcalls);
+
+ (void) more_pkt();
+ flush_pkt();
+}
+
+
+/*
+ * loop_info - return the current state of the loop filter
+ */
+static void
+loop_info(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt
+ )
+{
+ struct info_loop *li;
+ l_fp ltmp;
+
+ li = (struct info_loop *)prepare_pkt(srcadr, inter, inpkt,
+ sizeof(struct info_loop));
+
+ DTOLFP(last_offset, &ltmp);
+ HTONL_FP(&ltmp, &li->last_offset);
+ DTOLFP(drift_comp * 1e6, &ltmp);
+ HTONL_FP(&ltmp, &li->drift_comp);
+ li->compliance = htonl((u_int32)(tc_counter));
+ li->watchdog_timer = htonl((u_int32)(current_time - sys_epoch));
+
+ (void) more_pkt();
+ flush_pkt();
+}
+
+
+/*
+ * do_conf - add a peer to the configuration list
+ */
+static void
+do_conf(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt
+ )
+{
+ u_short items;
+ size_t item_sz;
+ u_int fl;
+ char * datap;
+ struct conf_peer temp_cp;
+ sockaddr_u peeraddr;
+
+ /*
+ * Do a check of everything to see that it looks
+ * okay. If not, complain about it. Note we are
+ * very picky here.
+ */
+ items = INFO_NITEMS(inpkt->err_nitems);
+ item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize);
+ datap = inpkt->u.data;
+ if (item_sz > sizeof(temp_cp)) {
+ req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
+ return;
+ }
+
+ while (items-- > 0) {
+ ZERO(temp_cp);
+ memcpy(&temp_cp, datap, item_sz);
+ ZERO_SOCK(&peeraddr);
+
+ fl = 0;
+ if (temp_cp.flags & CONF_FLAG_PREFER)
+ fl |= FLAG_PREFER;
+ if (temp_cp.flags & CONF_FLAG_BURST)
+ fl |= FLAG_BURST;
+ if (temp_cp.flags & CONF_FLAG_IBURST)
+ fl |= FLAG_IBURST;
+#ifdef AUTOKEY
+ if (temp_cp.flags & CONF_FLAG_SKEY)
+ fl |= FLAG_SKEY;
+#endif /* AUTOKEY */
+ if (client_v6_capable && temp_cp.v6_flag) {
+ AF(&peeraddr) = AF_INET6;
+ SOCK_ADDR6(&peeraddr) = temp_cp.peeraddr6;
+ } else {
+ AF(&peeraddr) = AF_INET;
+ NSRCADR(&peeraddr) = temp_cp.peeraddr;
+ /*
+ * Make sure the address is valid
+ */
+ if (!ISREFCLOCKADR(&peeraddr) &&
+ ISBADADR(&peeraddr)) {
+ req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
+ return;
+ }
+
+ }
+ NSRCPORT(&peeraddr) = htons(NTP_PORT);
+#ifdef ISC_PLATFORM_HAVESALEN
+ peeraddr.sa.sa_len = SOCKLEN(&peeraddr);
+#endif
+
+ /* check mode value: 0 <= hmode <= 6
+ *
+ * There's no good global define for that limit, and
+ * using a magic define is as good (or bad, actually) as
+ * a magic number. So we use the highest possible peer
+ * mode, and that is MODE_BCLIENT.
+ *
+ * [Bug 3009] claims that a problem occurs for hmode > 7,
+ * but the code in ntp_peer.c indicates trouble for any
+ * hmode > 6 ( --> MODE_BCLIENT).
+ */
+ if (temp_cp.hmode > MODE_BCLIENT) {
+ req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
+ return;
+ }
+
+ /* Any more checks on the values? Unchecked at this
+ * point:
+ * - version
+ * - ttl
+ * - keyid
+ *
+ * - minpoll/maxpoll, but they are treated properly
+ * for all cases internally. Checking not necessary.
+ *
+ * Note that we ignore any previously-specified ippeerlimit.
+ * If we're told to create the peer, we create the peer.
+ */
+
+ /* finally create the peer */
+ if (peer_config(&peeraddr, NULL, NULL, -1,
+ temp_cp.hmode, temp_cp.version, temp_cp.minpoll,
+ temp_cp.maxpoll, fl, temp_cp.ttl, temp_cp.keyid,
+ NULL) == 0)
+ {
+ req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
+ return;
+ }
+
+ datap += item_sz;
+ }
+ req_ack(srcadr, inter, inpkt, INFO_OKAY);
+}
+
+
+/*
+ * do_unconf - remove a peer from the configuration list
+ */
+static void
+do_unconf(
+ sockaddr_u * srcadr,
+ endpt * inter,
+ struct req_pkt *inpkt
+ )
+{
+ u_short items;
+ size_t item_sz;
+ char * datap;
+ struct conf_unpeer temp_cp;
+ struct peer * p;
+ sockaddr_u peeraddr;
+ int loops;
+
+ /*
+ * This is a bit unstructured, but I like to be careful.
+ * We check to see that every peer exists and is actually
+ * configured. If so, we remove them. If not, we return
+ * an error.
+ *
+ * [Bug 3011] Even if we checked all peers given in the request
+ * in a dry run, there's still a chance that the caller played
+ * unfair and gave the same peer multiple times. So we still
+ * have to be prepared for nasty surprises in the second run ;)
+ */
+
+ /* basic consistency checks */
+ item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize);
+ if (item_sz > sizeof(temp_cp)) {
+ req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
+ return;
+ }
+
+ /* now do two runs: first a dry run, then a busy one */
+ for (loops = 0; loops != 2; ++loops) {
+ items = INFO_NITEMS(inpkt->err_nitems);
+ datap = inpkt->u.data;
+ while (items-- > 0) {
+ /* copy from request to local */
+ ZERO(temp_cp);
+ memcpy(&temp_cp, datap, item_sz);
+ /* get address structure */
+ ZERO_SOCK(&peeraddr);
+ if (client_v6_capable && temp_cp.v6_flag) {
+ AF(&peeraddr) = AF_INET6;
+ SOCK_ADDR6(&peeraddr) = temp_cp.peeraddr6;
+ } else {
+ AF(&peeraddr) = AF_INET;
+ NSRCADR(&peeraddr) = temp_cp.peeraddr;
+ }
+ SET_PORT(&peeraddr, NTP_PORT);
+#ifdef ISC_PLATFORM_HAVESALEN
+ peeraddr.sa.sa_len = SOCKLEN(&peeraddr);
+#endif
+ DPRINTF(1, ("searching for %s\n",
+ stoa(&peeraddr)));
+
+ /* search for matching configred(!) peer */
+ p = NULL;
+ do {
+ p = findexistingpeer(
+ &peeraddr, NULL, p, -1, 0, NULL);
+ } while (p && !(FLAG_CONFIG & p->flags));
+
+ if (!loops && !p) {
+ /* Item not found in dry run -- bail! */
+ req_ack(srcadr, inter, inpkt,
+ INFO_ERR_NODATA);
+ return;
+ } else if (loops && p) {
+ /* Item found in busy run -- remove! */
+ peer_clear(p, "GONE");
+ unpeer(p);
+ }
+ datap += item_sz;
+ }
+ }
+
+ /* report success */
+ req_ack(srcadr, inter, inpkt, INFO_OKAY);
+}
+
+
+/*
+ * set_sys_flag - set system flags
+ */
+static void
+set_sys_flag(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt
+ )
+{
+ setclr_flags(srcadr, inter, inpkt, 1);
+}
+
+
+/*
+ * clr_sys_flag - clear system flags
+ */
+static void
+clr_sys_flag(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt
+ )
+{
+ setclr_flags(srcadr, inter, inpkt, 0);
+}
+
+
+/*
+ * setclr_flags - do the grunge work of flag setting/clearing
+ */
+static void
+setclr_flags(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt,
+ u_long set
+ )
+{
+ struct conf_sys_flags *sf;
+ u_int32 flags;
+
+ if (INFO_NITEMS(inpkt->err_nitems) > 1) {
+ msyslog(LOG_ERR, "setclr_flags: err_nitems > 1");
+ req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
+ return;
+ }
+
+ sf = (struct conf_sys_flags *)&inpkt->u;
+ flags = ntohl(sf->flags);
+
+ if (flags & ~(SYS_FLAG_BCLIENT | SYS_FLAG_PPS |
+ SYS_FLAG_NTP | SYS_FLAG_KERNEL | SYS_FLAG_MONITOR |
+ SYS_FLAG_FILEGEN | SYS_FLAG_AUTH | SYS_FLAG_CAL)) {
+ msyslog(LOG_ERR, "setclr_flags: extra flags: %#x",
+ flags & ~(SYS_FLAG_BCLIENT | SYS_FLAG_PPS |
+ SYS_FLAG_NTP | SYS_FLAG_KERNEL |
+ SYS_FLAG_MONITOR | SYS_FLAG_FILEGEN |
+ SYS_FLAG_AUTH | SYS_FLAG_CAL));
+ req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
+ return;
+ }
+
+ if (flags & SYS_FLAG_BCLIENT)
+ proto_config(PROTO_BROADCLIENT, set, 0., NULL);
+ if (flags & SYS_FLAG_PPS)
+ proto_config(PROTO_PPS, set, 0., NULL);
+ if (flags & SYS_FLAG_NTP)
+ proto_config(PROTO_NTP, set, 0., NULL);
+ if (flags & SYS_FLAG_KERNEL)
+ proto_config(PROTO_KERNEL, set, 0., NULL);
+ if (flags & SYS_FLAG_MONITOR)
+ proto_config(PROTO_MONITOR, set, 0., NULL);
+ if (flags & SYS_FLAG_FILEGEN)
+ proto_config(PROTO_FILEGEN, set, 0., NULL);
+ if (flags & SYS_FLAG_AUTH)
+ proto_config(PROTO_AUTHENTICATE, set, 0., NULL);
+ if (flags & SYS_FLAG_CAL)
+ proto_config(PROTO_CAL, set, 0., NULL);
+ req_ack(srcadr, inter, inpkt, INFO_OKAY);
+}
+
+/* There have been some issues with the restrict list processing,
+ * ranging from problems with deep recursion (resulting in stack
+ * overflows) and overfull reply buffers.
+ *
+ * To avoid this trouble the list reversal is done iteratively using a
+ * scratch pad.
+ */
+typedef struct RestrictStack RestrictStackT;
+struct RestrictStack {
+ RestrictStackT *link;
+ size_t fcnt;
+ const restrict_u *pres[63];
+};
+
+static size_t
+getStackSheetSize(
+ RestrictStackT *sp
+ )
+{
+ if (sp)
+ return sizeof(sp->pres)/sizeof(sp->pres[0]);
+ return 0u;
+}
+
+static int/*BOOL*/
+pushRestriction(
+ RestrictStackT **spp,
+ const restrict_u *ptr
+ )
+{
+ RestrictStackT *sp;
+
+ if (NULL == (sp = *spp) || 0 == sp->fcnt) {
+ /* need another sheet in the scratch pad */
+ sp = emalloc(sizeof(*sp));
+ sp->link = *spp;
+ sp->fcnt = getStackSheetSize(sp);
+ *spp = sp;
+ }
+ sp->pres[--sp->fcnt] = ptr;
+ return TRUE;
+}
+
+static int/*BOOL*/
+popRestriction(
+ RestrictStackT **spp,
+ const restrict_u **opp
+ )
+{
+ RestrictStackT *sp;
+
+ if (NULL == (sp = *spp) || sp->fcnt >= getStackSheetSize(sp))
+ return FALSE;
+
+ *opp = sp->pres[sp->fcnt++];
+ if (sp->fcnt >= getStackSheetSize(sp)) {
+ /* discard sheet from scratch pad */
+ *spp = sp->link;
+ free(sp);
+ }
+ return TRUE;
+}
+
+static void
+flushRestrictionStack(
+ RestrictStackT **spp
+ )
+{
+ RestrictStackT *sp;
+
+ while (NULL != (sp = *spp)) {
+ *spp = sp->link;
+ free(sp);
+ }
+}
+
+/*
+ * list_restrict4 - iterative helper for list_restrict dumps IPv4
+ * restriction list in reverse order.
+ */
+static void
+list_restrict4(
+ const restrict_u * res,
+ struct info_restrict ** ppir
+ )
+{
+ RestrictStackT * rpad;
+ struct info_restrict * pir;
+
+ pir = *ppir;
+ for (rpad = NULL; res; res = res->link)
+ if (!pushRestriction(&rpad, res))
+ break;
+
+ while (pir && popRestriction(&rpad, &res)) {
+ pir->addr = htonl(res->u.v4.addr);
+ if (client_v6_capable)
+ pir->v6_flag = 0;
+ pir->mask = htonl(res->u.v4.mask);
+ pir->count = htonl(res->count);
+ pir->rflags = htons(res->rflags);
+ pir->mflags = htons(res->mflags);
+ pir = (struct info_restrict *)more_pkt();
+ }
+ flushRestrictionStack(&rpad);
+ *ppir = pir;
+}
+
+/*
+ * list_restrict6 - iterative helper for list_restrict dumps IPv6
+ * restriction list in reverse order.
+ */
+static void
+list_restrict6(
+ const restrict_u * res,
+ struct info_restrict ** ppir
+ )
+{
+ RestrictStackT * rpad;
+ struct info_restrict * pir;
+
+ pir = *ppir;
+ for (rpad = NULL; res; res = res->link)
+ if (!pushRestriction(&rpad, res))
+ break;
+
+ while (pir && popRestriction(&rpad, &res)) {
+ pir->addr6 = res->u.v6.addr;
+ pir->mask6 = res->u.v6.mask;
+ pir->v6_flag = 1;
+ pir->count = htonl(res->count);
+ pir->rflags = htons(res->rflags);
+ pir->mflags = htons(res->mflags);
+ pir = (struct info_restrict *)more_pkt();
+ }
+ flushRestrictionStack(&rpad);
+ *ppir = pir;
+}
+
+
+/*
+ * list_restrict - return the restrict list
+ */
+static void
+list_restrict(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt
+ )
+{
+ struct info_restrict *ir;
+
+ DPRINTF(3, ("wants restrict list summary\n"));
+
+ ir = (struct info_restrict *)prepare_pkt(srcadr, inter, inpkt,
+ v6sizeof(struct info_restrict));
+
+ /*
+ * The restriction lists are kept sorted in the reverse order
+ * than they were originally. To preserve the output semantics,
+ * dump each list in reverse order. The workers take care of that.
+ */
+ list_restrict4(restrictlist4, &ir);
+ if (client_v6_capable)
+ list_restrict6(restrictlist6, &ir);
+ flush_pkt();
+}
+
+
+/*
+ * do_resaddflags - add flags to a restrict entry (or create one)
+ */
+static void
+do_resaddflags(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt
+ )
+{
+ do_restrict(srcadr, inter, inpkt, RESTRICT_FLAGS);
+}
+
+
+
+/*
+ * do_ressubflags - remove flags from a restrict entry
+ */
+static void
+do_ressubflags(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt
+ )
+{
+ do_restrict(srcadr, inter, inpkt, RESTRICT_UNFLAG);
+}
+
+
+/*
+ * do_unrestrict - remove a restrict entry from the list
+ */
+static void
+do_unrestrict(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt
+ )
+{
+ do_restrict(srcadr, inter, inpkt, RESTRICT_REMOVE);
+}
+
+
+/*
+ * do_restrict - do the dirty stuff of dealing with restrictions
+ */
+static void
+do_restrict(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt,
+ restrict_op op
+ )
+{
+ char * datap;
+ struct conf_restrict cr;
+ u_short items;
+ size_t item_sz;
+ sockaddr_u matchaddr;
+ sockaddr_u matchmask;
+ int bad;
+
+ switch(op) {
+ case RESTRICT_FLAGS:
+ case RESTRICT_UNFLAG:
+ case RESTRICT_REMOVE:
+ case RESTRICT_REMOVEIF:
+ break;
+
+ default:
+ req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
+ return;
+ }
+
+ /*
+ * Do a check of the flags to make sure that only
+ * the NTPPORT flag is set, if any. If not, complain
+ * about it. Note we are very picky here.
+ */
+ items = INFO_NITEMS(inpkt->err_nitems);
+ item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize);
+ datap = inpkt->u.data;
+ if (item_sz > sizeof(cr)) {
+ req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
+ return;
+ }
+
+ bad = 0;
+ while (items-- > 0 && !bad) {
+ memcpy(&cr, datap, item_sz);
+ cr.flags = ntohs(cr.flags);
+ cr.mflags = ntohs(cr.mflags);
+ if (~RESM_NTPONLY & cr.mflags)
+ bad |= 1;
+ if (~RES_ALLFLAGS & cr.flags)
+ bad |= 2;
+ if (INADDR_ANY != cr.mask) {
+ if (client_v6_capable && cr.v6_flag) {
+ if (IN6_IS_ADDR_UNSPECIFIED(&cr.addr6))
+ bad |= 4;
+ } else {
+ if (INADDR_ANY == cr.addr)
+ bad |= 8;
+ }
+ }
+ datap += item_sz;
+ }
+
+ if (bad) {
+ msyslog(LOG_ERR, "do_restrict: bad = %#x", bad);
+ req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
+ return;
+ }
+
+ /*
+ * Looks okay, try it out. Needs to reload data pointer and
+ * item counter. (Talos-CAN-0052)
+ */
+ ZERO_SOCK(&matchaddr);
+ ZERO_SOCK(&matchmask);
+ items = INFO_NITEMS(inpkt->err_nitems);
+ datap = inpkt->u.data;
+
+ while (items-- > 0) {
+ memcpy(&cr, datap, item_sz);
+ cr.flags = ntohs(cr.flags);
+ cr.mflags = ntohs(cr.mflags);
+ cr.ippeerlimit = ntohs(cr.ippeerlimit);
+ if (client_v6_capable && cr.v6_flag) {
+ AF(&matchaddr) = AF_INET6;
+ AF(&matchmask) = AF_INET6;
+ SOCK_ADDR6(&matchaddr) = cr.addr6;
+ SOCK_ADDR6(&matchmask) = cr.mask6;
+ } else {
+ AF(&matchaddr) = AF_INET;
+ AF(&matchmask) = AF_INET;
+ NSRCADR(&matchaddr) = cr.addr;
+ NSRCADR(&matchmask) = cr.mask;
+ }
+ hack_restrict(op, &matchaddr, &matchmask, cr.mflags,
+ cr.ippeerlimit, cr.flags, 0);
+ datap += item_sz;
+ }
+
+ req_ack(srcadr, inter, inpkt, INFO_OKAY);
+}
+
+
+/*
+ * mon_getlist - return monitor data
+ */
+static void
+mon_getlist(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt
+ )
+{
+ req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
+}
+
+
+/*
+ * Module entry points and the flags they correspond with
+ */
+struct reset_entry {
+ int flag; /* flag this corresponds to */
+ void (*handler)(void); /* routine to handle request */
+};
+
+struct reset_entry reset_entries[] = {
+ { RESET_FLAG_ALLPEERS, peer_all_reset },
+ { RESET_FLAG_IO, io_clr_stats },
+ { RESET_FLAG_SYS, proto_clr_stats },
+ { RESET_FLAG_MEM, peer_clr_stats },
+ { RESET_FLAG_TIMER, timer_clr_stats },
+ { RESET_FLAG_AUTH, reset_auth_stats },
+ { RESET_FLAG_CTL, ctl_clr_stats },
+ { 0, 0 }
+};
+
+/*
+ * reset_stats - reset statistic counters here and there
+ */
+static void
+reset_stats(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt
+ )
+{
+ struct reset_flags *rflags;
+ u_long flags;
+ struct reset_entry *rent;
+
+ if (INFO_NITEMS(inpkt->err_nitems) > 1) {
+ msyslog(LOG_ERR, "reset_stats: err_nitems > 1");
+ req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
+ return;
+ }
+
+ rflags = (struct reset_flags *)&inpkt->u;
+ flags = ntohl(rflags->flags);
+
+ if (flags & ~RESET_ALLFLAGS) {
+ msyslog(LOG_ERR, "reset_stats: reset leaves %#lx",
+ flags & ~RESET_ALLFLAGS);
+ req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
+ return;
+ }
+
+ for (rent = reset_entries; rent->flag != 0; rent++) {
+ if (flags & rent->flag)
+ (*rent->handler)();
+ }
+ req_ack(srcadr, inter, inpkt, INFO_OKAY);
+}
+
+
+/*
+ * reset_peer - clear a peer's statistics
+ */
+static void
+reset_peer(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt
+ )
+{
+ u_short items;
+ size_t item_sz;
+ char * datap;
+ struct conf_unpeer cp;
+ struct peer * p;
+ sockaddr_u peeraddr;
+ int bad;
+
+ /*
+ * We check first to see that every peer exists. If not,
+ * we return an error.
+ */
+
+ items = INFO_NITEMS(inpkt->err_nitems);
+ item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize);
+ datap = inpkt->u.data;
+ if (item_sz > sizeof(cp)) {
+ req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
+ return;
+ }
+
+ bad = FALSE;
+ while (items-- > 0 && !bad) {
+ ZERO(cp);
+ memcpy(&cp, datap, item_sz);
+ ZERO_SOCK(&peeraddr);
+ if (client_v6_capable && cp.v6_flag) {
+ AF(&peeraddr) = AF_INET6;
+ SOCK_ADDR6(&peeraddr) = cp.peeraddr6;
+ } else {
+ AF(&peeraddr) = AF_INET;
+ NSRCADR(&peeraddr) = cp.peeraddr;
+ }
+
+#ifdef ISC_PLATFORM_HAVESALEN
+ peeraddr.sa.sa_len = SOCKLEN(&peeraddr);
+#endif
+ p = findexistingpeer(&peeraddr, NULL, NULL, -1, 0, NULL);
+ if (NULL == p)
+ bad++;
+ datap += item_sz;
+ }
+
+ if (bad) {
+ req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
+ return;
+ }
+
+ /*
+ * Now do it in earnest. Needs to reload data pointer and item
+ * counter. (Talos-CAN-0052)
+ */
+
+ items = INFO_NITEMS(inpkt->err_nitems);
+ datap = inpkt->u.data;
+ while (items-- > 0) {
+ ZERO(cp);
+ memcpy(&cp, datap, item_sz);
+ ZERO_SOCK(&peeraddr);
+ if (client_v6_capable && cp.v6_flag) {
+ AF(&peeraddr) = AF_INET6;
+ SOCK_ADDR6(&peeraddr) = cp.peeraddr6;
+ } else {
+ AF(&peeraddr) = AF_INET;
+ NSRCADR(&peeraddr) = cp.peeraddr;
+ }
+ SET_PORT(&peeraddr, 123);
+#ifdef ISC_PLATFORM_HAVESALEN
+ peeraddr.sa.sa_len = SOCKLEN(&peeraddr);
+#endif
+ p = findexistingpeer(&peeraddr, NULL, NULL, -1, 0, NULL);
+ while (p != NULL) {
+ peer_reset(p);
+ p = findexistingpeer(&peeraddr, NULL, p, -1, 0, NULL);
+ }
+ datap += item_sz;
+ }
+
+ req_ack(srcadr, inter, inpkt, INFO_OKAY);
+}
+
+
+/*
+ * do_key_reread - reread the encryption key file
+ */
+static void
+do_key_reread(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt
+ )
+{
+ rereadkeys();
+ req_ack(srcadr, inter, inpkt, INFO_OKAY);
+}
+
+
+/*
+ * trust_key - make one or more keys trusted
+ */
+static void
+trust_key(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt
+ )
+{
+ do_trustkey(srcadr, inter, inpkt, 1);
+}
+
+
+/*
+ * untrust_key - make one or more keys untrusted
+ */
+static void
+untrust_key(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt
+ )
+{
+ do_trustkey(srcadr, inter, inpkt, 0);
+}
+
+
+/*
+ * do_trustkey - make keys either trustable or untrustable
+ */
+static void
+do_trustkey(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt,
+ u_long trust
+ )
+{
+ register uint32_t *kp;
+ register int items;
+
+ items = INFO_NITEMS(inpkt->err_nitems);
+ kp = (uint32_t *)&inpkt->u;
+ while (items-- > 0) {
+ authtrust(*kp, trust);
+ kp++;
+ }
+
+ req_ack(srcadr, inter, inpkt, INFO_OKAY);
+}
+
+
+/*
+ * get_auth_info - return some stats concerning the authentication module
+ */
+static void
+get_auth_info(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt
+ )
+{
+ register struct info_auth *ia;
+
+ ia = (struct info_auth *)prepare_pkt(srcadr, inter, inpkt,
+ sizeof(struct info_auth));
+
+ ia->numkeys = htonl((u_int32)authnumkeys);
+ ia->numfreekeys = htonl((u_int32)authnumfreekeys);
+ ia->keylookups = htonl((u_int32)authkeylookups);
+ ia->keynotfound = htonl((u_int32)authkeynotfound);
+ ia->encryptions = htonl((u_int32)authencryptions);
+ ia->decryptions = htonl((u_int32)authdecryptions);
+ ia->keyuncached = htonl((u_int32)authkeyuncached);
+ ia->expired = htonl((u_int32)authkeyexpired);
+ ia->timereset = htonl((u_int32)(current_time - auth_timereset));
+
+ (void) more_pkt();
+ flush_pkt();
+}
+
+
+
+/*
+ * reset_auth_stats - reset the authentication stat counters. Done here
+ * to keep ntp-isms out of the authentication module
+ */
+void
+reset_auth_stats(void)
+{
+ authkeylookups = 0;
+ authkeynotfound = 0;
+ authencryptions = 0;
+ authdecryptions = 0;
+ authkeyuncached = 0;
+ auth_timereset = current_time;
+}
+
+
+/*
+ * req_get_traps - return information about current trap holders
+ */
+static void
+req_get_traps(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt
+ )
+{
+ struct info_trap *it;
+ struct ctl_trap *tr;
+ size_t i;
+
+ if (num_ctl_traps == 0) {
+ req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
+ return;
+ }
+
+ it = (struct info_trap *)prepare_pkt(srcadr, inter, inpkt,
+ v6sizeof(struct info_trap));
+
+ for (i = 0, tr = ctl_traps; it && i < COUNTOF(ctl_traps); i++, tr++) {
+ if (tr->tr_flags & TRAP_INUSE) {
+ if (IS_IPV4(&tr->tr_addr)) {
+ if (tr->tr_localaddr == any_interface)
+ it->local_address = 0;
+ else
+ it->local_address
+ = NSRCADR(&tr->tr_localaddr->sin);
+ it->trap_address = NSRCADR(&tr->tr_addr);
+ if (client_v6_capable)
+ it->v6_flag = 0;
+ } else {
+ if (!client_v6_capable)
+ continue;
+ it->local_address6
+ = SOCK_ADDR6(&tr->tr_localaddr->sin);
+ it->trap_address6 = SOCK_ADDR6(&tr->tr_addr);
+ it->v6_flag = 1;
+ }
+ it->trap_port = NSRCPORT(&tr->tr_addr);
+ it->sequence = htons(tr->tr_sequence);
+ it->settime = htonl((u_int32)(current_time - tr->tr_settime));
+ it->origtime = htonl((u_int32)(current_time - tr->tr_origtime));
+ it->resets = htonl((u_int32)tr->tr_resets);
+ it->flags = htonl((u_int32)tr->tr_flags);
+ it = (struct info_trap *)more_pkt();
+ }
+ }
+ flush_pkt();
+}
+
+
+/*
+ * req_set_trap - configure a trap
+ */
+static void
+req_set_trap(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt
+ )
+{
+ do_setclr_trap(srcadr, inter, inpkt, 1);
+}
+
+
+
+/*
+ * req_clr_trap - unconfigure a trap
+ */
+static void
+req_clr_trap(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt
+ )
+{
+ do_setclr_trap(srcadr, inter, inpkt, 0);
+}
+
+
+
+/*
+ * do_setclr_trap - do the grunge work of (un)configuring a trap
+ */
+static void
+do_setclr_trap(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt,
+ int set
+ )
+{
+ register struct conf_trap *ct;
+ register endpt *linter;
+ int res;
+ sockaddr_u laddr;
+
+ /*
+ * Prepare sockaddr
+ */
+ ZERO_SOCK(&laddr);
+ AF(&laddr) = AF(srcadr);
+ SET_PORT(&laddr, NTP_PORT);
+
+ /*
+ * Restrict ourselves to one item only. This eliminates
+ * the error reporting problem.
+ */
+ if (INFO_NITEMS(inpkt->err_nitems) > 1) {
+ msyslog(LOG_ERR, "do_setclr_trap: err_nitems > 1");
+ req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
+ return;
+ }
+ ct = (struct conf_trap *)&inpkt->u;
+
+ /*
+ * Look for the local interface. If none, use the default.
+ */
+ if (ct->local_address == 0) {
+ linter = any_interface;
+ } else {
+ if (IS_IPV4(&laddr))
+ NSRCADR(&laddr) = ct->local_address;
+ else
+ SOCK_ADDR6(&laddr) = ct->local_address6;
+ linter = findinterface(&laddr);
+ if (NULL == linter) {
+ req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
+ return;
+ }
+ }
+
+ if (IS_IPV4(&laddr))
+ NSRCADR(&laddr) = ct->trap_address;
+ else
+ SOCK_ADDR6(&laddr) = ct->trap_address6;
+ if (ct->trap_port)
+ NSRCPORT(&laddr) = ct->trap_port;
+ else
+ SET_PORT(&laddr, TRAPPORT);
+
+ if (set) {
+ res = ctlsettrap(&laddr, linter, 0,
+ INFO_VERSION(inpkt->rm_vn_mode));
+ } else {
+ res = ctlclrtrap(&laddr, linter, 0);
+ }
+
+ if (!res) {
+ req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
+ } else {
+ req_ack(srcadr, inter, inpkt, INFO_OKAY);
+ }
+ return;
+}
+
+/*
+ * Validate a request packet for a new request or control key:
+ * - only one item allowed
+ * - key must be valid (that is, known, and not in the autokey range)
+ */
+static void
+set_keyid_checked(
+ keyid_t *into,
+ const char *what,
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt
+ )
+{
+ keyid_t *pkeyid;
+ keyid_t tmpkey;
+
+ /* restrict ourselves to one item only */
+ if (INFO_NITEMS(inpkt->err_nitems) > 1) {
+ msyslog(LOG_ERR, "set_keyid_checked[%s]: err_nitems > 1",
+ what);
+ req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
+ return;
+ }
+
+ /* plug the new key from the packet */
+ pkeyid = (keyid_t *)&inpkt->u;
+ tmpkey = ntohl(*pkeyid);
+
+ /* validate the new key id, claim data error on failure */
+ if (tmpkey < 1 || tmpkey > NTP_MAXKEY || !auth_havekey(tmpkey)) {
+ msyslog(LOG_ERR, "set_keyid_checked[%s]: invalid key id: %ld",
+ what, (long)tmpkey);
+ req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
+ return;
+ }
+
+ /* if we arrive here, the key is good -- use it */
+ *into = tmpkey;
+ req_ack(srcadr, inter, inpkt, INFO_OKAY);
+}
+
+/*
+ * set_request_keyid - set the keyid used to authenticate requests
+ */
+static void
+set_request_keyid(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt
+ )
+{
+ set_keyid_checked(&info_auth_keyid, "request",
+ srcadr, inter, inpkt);
+}
+
+
+
+/*
+ * set_control_keyid - set the keyid used to authenticate requests
+ */
+static void
+set_control_keyid(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt
+ )
+{
+ set_keyid_checked(&ctl_auth_keyid, "control",
+ srcadr, inter, inpkt);
+}
+
+
+
+/*
+ * get_ctl_stats - return some stats concerning the control message module
+ */
+static void
+get_ctl_stats(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt
+ )
+{
+ register struct info_control *ic;
+
+ ic = (struct info_control *)prepare_pkt(srcadr, inter, inpkt,
+ sizeof(struct info_control));
+
+ ic->ctltimereset = htonl((u_int32)(current_time - ctltimereset));
+ ic->numctlreq = htonl((u_int32)numctlreq);
+ ic->numctlbadpkts = htonl((u_int32)numctlbadpkts);
+ ic->numctlresponses = htonl((u_int32)numctlresponses);
+ ic->numctlfrags = htonl((u_int32)numctlfrags);
+ ic->numctlerrors = htonl((u_int32)numctlerrors);
+ ic->numctltooshort = htonl((u_int32)numctltooshort);
+ ic->numctlinputresp = htonl((u_int32)numctlinputresp);
+ ic->numctlinputfrag = htonl((u_int32)numctlinputfrag);
+ ic->numctlinputerr = htonl((u_int32)numctlinputerr);
+ ic->numctlbadoffset = htonl((u_int32)numctlbadoffset);
+ ic->numctlbadversion = htonl((u_int32)numctlbadversion);
+ ic->numctldatatooshort = htonl((u_int32)numctldatatooshort);
+ ic->numctlbadop = htonl((u_int32)numctlbadop);
+ ic->numasyncmsgs = htonl((u_int32)numasyncmsgs);
+
+ (void) more_pkt();
+ flush_pkt();
+}
+
+
+#ifdef KERNEL_PLL
+/*
+ * get_kernel_info - get kernel pll/pps information
+ */
+static void
+get_kernel_info(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt
+ )
+{
+ register struct info_kernel *ik;
+ struct timex ntx;
+
+ if (!pll_control) {
+ req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
+ return;
+ }
+
+ ZERO(ntx);
+ if (ntp_adjtime(&ntx) < 0)
+ msyslog(LOG_ERR, "get_kernel_info: ntp_adjtime() failed: %m");
+ ik = (struct info_kernel *)prepare_pkt(srcadr, inter, inpkt,
+ sizeof(struct info_kernel));
+
+ /*
+ * pll variables
+ */
+ ik->offset = htonl((u_int32)ntx.offset);
+ ik->freq = htonl((u_int32)ntx.freq);
+ ik->maxerror = htonl((u_int32)ntx.maxerror);
+ ik->esterror = htonl((u_int32)ntx.esterror);
+ ik->status = htons(ntx.status);
+ ik->constant = htonl((u_int32)ntx.constant);
+ ik->precision = htonl((u_int32)ntx.precision);
+ ik->tolerance = htonl((u_int32)ntx.tolerance);
+
+ /*
+ * pps variables
+ */
+ ik->ppsfreq = htonl((u_int32)ntx.ppsfreq);
+ ik->jitter = htonl((u_int32)ntx.jitter);
+ ik->shift = htons(ntx.shift);
+ ik->stabil = htonl((u_int32)ntx.stabil);
+ ik->jitcnt = htonl((u_int32)ntx.jitcnt);
+ ik->calcnt = htonl((u_int32)ntx.calcnt);
+ ik->errcnt = htonl((u_int32)ntx.errcnt);
+ ik->stbcnt = htonl((u_int32)ntx.stbcnt);
+
+ (void) more_pkt();
+ flush_pkt();
+}
+#endif /* KERNEL_PLL */
+
+
+#ifdef REFCLOCK
+/*
+ * get_clock_info - get info about a clock
+ */
+static void
+get_clock_info(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt
+ )
+{
+ register struct info_clock *ic;
+ register u_int32 *clkaddr;
+ register int items;
+ struct refclockstat clock_stat;
+ sockaddr_u addr;
+ l_fp ltmp;
+
+ ZERO_SOCK(&addr);
+ AF(&addr) = AF_INET;
+#ifdef ISC_PLATFORM_HAVESALEN
+ addr.sa.sa_len = SOCKLEN(&addr);
+#endif
+ SET_PORT(&addr, NTP_PORT);
+ items = INFO_NITEMS(inpkt->err_nitems);
+ clkaddr = &inpkt->u.u32[0];
+
+ ic = (struct info_clock *)prepare_pkt(srcadr, inter, inpkt,
+ sizeof(struct info_clock));
+
+ while (items-- > 0 && ic) {
+ NSRCADR(&addr) = *clkaddr++;
+ if (!ISREFCLOCKADR(&addr) || NULL ==
+ findexistingpeer(&addr, NULL, NULL, -1, 0, NULL)) {
+ req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
+ return;
+ }
+
+ clock_stat.kv_list = (struct ctl_var *)0;
+
+ refclock_control(&addr, NULL, &clock_stat);
+
+ ic->clockadr = NSRCADR(&addr);
+ ic->type = clock_stat.type;
+ ic->flags = clock_stat.flags;
+ ic->lastevent = clock_stat.lastevent;
+ ic->currentstatus = clock_stat.currentstatus;
+ ic->polls = htonl((u_int32)clock_stat.polls);
+ ic->noresponse = htonl((u_int32)clock_stat.noresponse);
+ ic->badformat = htonl((u_int32)clock_stat.badformat);
+ ic->baddata = htonl((u_int32)clock_stat.baddata);
+ ic->timestarted = htonl((u_int32)clock_stat.timereset);
+ DTOLFP(clock_stat.fudgetime1, &ltmp);
+ HTONL_FP(&ltmp, &ic->fudgetime1);
+ DTOLFP(clock_stat.fudgetime2, &ltmp);
+ HTONL_FP(&ltmp, &ic->fudgetime2);
+ ic->fudgeval1 = htonl((u_int32)clock_stat.fudgeval1);
+ /* [Bug3527] Backward Incompatible: ic->fudgeval2 is
+ * a string, instantiated via memcpy() so there is no
+ * endian issue to correct.
+ */
+#ifdef DISABLE_BUG3527_FIX
+ ic->fudgeval2 = htonl(clock_stat.fudgeval2);
+#else
+ ic->fudgeval2 = clock_stat.fudgeval2;
+#endif
+
+ free_varlist(clock_stat.kv_list);
+
+ ic = (struct info_clock *)more_pkt();
+ }
+ flush_pkt();
+}
+
+
+
+/*
+ * set_clock_fudge - get a clock's fudge factors
+ */
+static void
+set_clock_fudge(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt
+ )
+{
+ register struct conf_fudge *cf;
+ register int items;
+ struct refclockstat clock_stat;
+ sockaddr_u addr;
+ l_fp ltmp;
+
+ ZERO(addr);
+ ZERO(clock_stat);
+ items = INFO_NITEMS(inpkt->err_nitems);
+ cf = (struct conf_fudge *)&inpkt->u;
+
+ while (items-- > 0) {
+ AF(&addr) = AF_INET;
+ NSRCADR(&addr) = cf->clockadr;
+#ifdef ISC_PLATFORM_HAVESALEN
+ addr.sa.sa_len = SOCKLEN(&addr);
+#endif
+ SET_PORT(&addr, NTP_PORT);
+ if (!ISREFCLOCKADR(&addr) || NULL ==
+ findexistingpeer(&addr, NULL, NULL, -1, 0, NULL)) {
+ req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
+ return;
+ }
+
+ switch(ntohl(cf->which)) {
+ case FUDGE_TIME1:
+ NTOHL_FP(&cf->fudgetime, &ltmp);
+ LFPTOD(&ltmp, clock_stat.fudgetime1);
+ clock_stat.haveflags = CLK_HAVETIME1;
+ break;
+ case FUDGE_TIME2:
+ NTOHL_FP(&cf->fudgetime, &ltmp);
+ LFPTOD(&ltmp, clock_stat.fudgetime2);
+ clock_stat.haveflags = CLK_HAVETIME2;
+ break;
+ case FUDGE_VAL1:
+ clock_stat.fudgeval1 = ntohl(cf->fudgeval_flags);
+ clock_stat.haveflags = CLK_HAVEVAL1;
+ break;
+ case FUDGE_VAL2:
+ clock_stat.fudgeval2 = ntohl(cf->fudgeval_flags);
+ clock_stat.haveflags = CLK_HAVEVAL2;
+ break;
+ case FUDGE_FLAGS:
+ clock_stat.flags = (u_char) (ntohl(cf->fudgeval_flags) & 0xf);
+ clock_stat.haveflags =
+ (CLK_HAVEFLAG1|CLK_HAVEFLAG2|CLK_HAVEFLAG3|CLK_HAVEFLAG4);
+ break;
+ default:
+ msyslog(LOG_ERR, "set_clock_fudge: default!");
+ req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
+ return;
+ }
+
+ refclock_control(&addr, &clock_stat, (struct refclockstat *)0);
+ }
+
+ req_ack(srcadr, inter, inpkt, INFO_OKAY);
+}
+#endif
+
+#ifdef REFCLOCK
+/*
+ * get_clkbug_info - get debugging info about a clock
+ */
+static void
+get_clkbug_info(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt
+ )
+{
+ register int i;
+ register struct info_clkbug *ic;
+ register u_int32 *clkaddr;
+ register int items;
+ struct refclockbug bug;
+ sockaddr_u addr;
+
+ ZERO_SOCK(&addr);
+ AF(&addr) = AF_INET;
+#ifdef ISC_PLATFORM_HAVESALEN
+ addr.sa.sa_len = SOCKLEN(&addr);
+#endif
+ SET_PORT(&addr, NTP_PORT);
+ items = INFO_NITEMS(inpkt->err_nitems);
+ clkaddr = (u_int32 *)&inpkt->u;
+
+ ic = (struct info_clkbug *)prepare_pkt(srcadr, inter, inpkt,
+ sizeof(struct info_clkbug));
+
+ while (items-- > 0 && ic) {
+ NSRCADR(&addr) = *clkaddr++;
+ if (!ISREFCLOCKADR(&addr) || NULL ==
+ findexistingpeer(&addr, NULL, NULL, -1, 0, NULL)) {
+ req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
+ return;
+ }
+
+ ZERO(bug);
+ refclock_buginfo(&addr, &bug);
+ if (bug.nvalues == 0 && bug.ntimes == 0) {
+ req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
+ return;
+ }
+
+ ic->clockadr = NSRCADR(&addr);
+ i = bug.nvalues;
+ if (i > NUMCBUGVALUES)
+ i = NUMCBUGVALUES;
+ ic->nvalues = (u_char)i;
+ ic->svalues = htons((u_short) (bug.svalues & ((1<<i)-1)));
+ while (--i >= 0)
+ ic->values[i] = htonl(bug.values[i]);
+
+ i = bug.ntimes;
+ if (i > NUMCBUGTIMES)
+ i = NUMCBUGTIMES;
+ ic->ntimes = (u_char)i;
+ ic->stimes = htonl(bug.stimes);
+ while (--i >= 0) {
+ HTONL_FP(&bug.times[i], &ic->times[i]);
+ }
+
+ ic = (struct info_clkbug *)more_pkt();
+ }
+ flush_pkt();
+}
+#endif
+
+/*
+ * receiver of interface structures
+ */
+static void
+fill_info_if_stats(void *data, interface_info_t *interface_info)
+{
+ struct info_if_stats **ifsp = (struct info_if_stats **)data;
+ struct info_if_stats *ifs = *ifsp;
+ endpt *ep = interface_info->ep;
+
+ if (NULL == ifs)
+ return;
+
+ ZERO(*ifs);
+
+ if (IS_IPV6(&ep->sin)) {
+ if (!client_v6_capable)
+ return;
+ ifs->v6_flag = 1;
+ ifs->unaddr.addr6 = SOCK_ADDR6(&ep->sin);
+ ifs->unbcast.addr6 = SOCK_ADDR6(&ep->bcast);
+ ifs->unmask.addr6 = SOCK_ADDR6(&ep->mask);
+ } else {
+ ifs->v6_flag = 0;
+ ifs->unaddr.addr = SOCK_ADDR4(&ep->sin);
+ ifs->unbcast.addr = SOCK_ADDR4(&ep->bcast);
+ ifs->unmask.addr = SOCK_ADDR4(&ep->mask);
+ }
+ ifs->v6_flag = htonl(ifs->v6_flag);
+ strlcpy(ifs->name, ep->name, sizeof(ifs->name));
+ ifs->family = htons(ep->family);
+ ifs->flags = htonl(ep->flags);
+ ifs->last_ttl = htonl(ep->last_ttl);
+ ifs->num_mcast = htonl(ep->num_mcast);
+ ifs->received = htonl(ep->received);
+ ifs->sent = htonl(ep->sent);
+ ifs->notsent = htonl(ep->notsent);
+ ifs->ifindex = htonl(ep->ifindex);
+ /* scope no longer in endpt, in in6_addr typically */
+ ifs->scopeid = ifs->ifindex;
+ ifs->ifnum = htonl(ep->ifnum);
+ ifs->uptime = htonl(current_time - ep->starttime);
+ ifs->ignore_packets = ep->ignore_packets;
+ ifs->peercnt = htonl(ep->peercnt);
+ ifs->action = interface_info->action;
+
+ *ifsp = (struct info_if_stats *)more_pkt();
+}
+
+/*
+ * get_if_stats - get interface statistics
+ */
+static void
+get_if_stats(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt
+ )
+{
+ struct info_if_stats *ifs;
+
+ DPRINTF(3, ("wants interface statistics\n"));
+
+ ifs = (struct info_if_stats *)prepare_pkt(srcadr, inter, inpkt,
+ v6sizeof(struct info_if_stats));
+
+ interface_enumerate(fill_info_if_stats, &ifs);
+
+ flush_pkt();
+}
+
+static void
+do_if_reload(
+ sockaddr_u *srcadr,
+ endpt *inter,
+ struct req_pkt *inpkt
+ )
+{
+ struct info_if_stats *ifs;
+
+ DPRINTF(3, ("wants interface reload\n"));
+
+ ifs = (struct info_if_stats *)prepare_pkt(srcadr, inter, inpkt,
+ v6sizeof(struct info_if_stats));
+
+ interface_update(fill_info_if_stats, &ifs);
+
+ flush_pkt();
+}
+
diff --git a/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_restrict.c b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_restrict.c
new file mode 100644
index 0000000..077d4e3
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_restrict.c
@@ -0,0 +1,804 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * ntp_restrict.c - determine host restrictions
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+
+#include "ntpd.h"
+#include "ntp_if.h"
+#include "ntp_lists.h"
+#include "ntp_stdlib.h"
+#include "ntp_assert.h"
+
+/*
+ * This code keeps a simple address-and-mask list of hosts we want
+ * to place restrictions on (or remove them from). The restrictions
+ * are implemented as a set of flags which tell you what the host
+ * can't do. There is a subroutine entry to return the flags. The
+ * list is kept sorted to reduce the average number of comparisons
+ * and make sure you get the set of restrictions most specific to
+ * the address.
+ *
+ * The algorithm is that, when looking up a host, it is first assumed
+ * that the default set of restrictions will apply. It then searches
+ * down through the list. Whenever it finds a match it adopts the
+ * match's flags instead. When you hit the point where the sorted
+ * address is greater than the target, you return with the last set of
+ * flags you found. Because of the ordering of the list, the most
+ * specific match will provide the final set of flags.
+ *
+ * This was originally intended to restrict you from sync'ing to your
+ * own broadcasts when you are doing that, by restricting yourself from
+ * your own interfaces. It was also thought it would sometimes be useful
+ * to keep a misbehaving host or two from abusing your primary clock. It
+ * has been expanded, however, to suit the needs of those with more
+ * restrictive access policies.
+ */
+/*
+ * We will use two lists, one for IPv4 addresses and one for IPv6
+ * addresses. This is not protocol-independant but for now I can't
+ * find a way to respect this. We'll check this later... JFB 07/2001
+ */
+#define MASK_IPV6_ADDR(dst, src, msk) \
+ do { \
+ int idx; \
+ for (idx = 0; idx < (int)COUNTOF((dst)->s6_addr); idx++) { \
+ (dst)->s6_addr[idx] = (src)->s6_addr[idx] \
+ & (msk)->s6_addr[idx]; \
+ } \
+ } while (0)
+
+/*
+ * We allocate INC_RESLIST{4|6} entries to the free list whenever empty.
+ * Auto-tune these to be just less than 1KB (leaving at least 16 bytes
+ * for allocator overhead).
+ */
+#define INC_RESLIST4 ((1024 - 16) / V4_SIZEOF_RESTRICT_U)
+#define INC_RESLIST6 ((1024 - 16) / V6_SIZEOF_RESTRICT_U)
+
+/*
+ * The restriction list
+ */
+restrict_u *restrictlist4;
+restrict_u *restrictlist6;
+static int restrictcount; /* count in the restrict lists */
+
+/*
+ * The free list and associated counters. Also some uninteresting
+ * stat counters.
+ */
+static restrict_u *resfree4; /* available entries (free list) */
+static restrict_u *resfree6;
+
+static u_long res_calls;
+static u_long res_found;
+static u_long res_not_found;
+
+/*
+ * Count number of restriction entries referring to RES_LIMITED, to
+ * control implicit activation/deactivation of the MRU monlist.
+ */
+static u_long res_limited_refcnt;
+
+/*
+ * Our default entries.
+ *
+ * We can make this cleaner with c99 support: see init_restrict().
+ */
+static restrict_u restrict_def4;
+static restrict_u restrict_def6;
+
+/*
+ * "restrict source ..." enabled knob and restriction bits.
+ */
+static int restrict_source_enabled;
+static u_short restrict_source_rflags;
+static u_short restrict_source_mflags;
+static short restrict_source_ippeerlimit;
+
+/*
+ * private functions
+ */
+static restrict_u * alloc_res4(void);
+static restrict_u * alloc_res6(void);
+static void free_res(restrict_u *, int);
+static void inc_res_limited(void);
+static void dec_res_limited(void);
+static restrict_u * match_restrict4_addr(u_int32, u_short);
+static restrict_u * match_restrict6_addr(const struct in6_addr *,
+ u_short);
+static restrict_u * match_restrict_entry(const restrict_u *, int);
+static int res_sorts_before4(restrict_u *, restrict_u *);
+static int res_sorts_before6(restrict_u *, restrict_u *);
+static char * roptoa(restrict_op op);
+
+
+void dump_restricts(void);
+
+/*
+ * dump_restrict - spit out a restrict_u
+ */
+static void
+dump_restrict(
+ restrict_u * res,
+ int is_ipv6
+ )
+{
+ char as[INET6_ADDRSTRLEN];
+ char ms[INET6_ADDRSTRLEN];
+
+ if (is_ipv6) {
+ inet_ntop(AF_INET6, &res->u.v6.addr, as, sizeof as);
+ inet_ntop(AF_INET6, &res->u.v6.mask, ms, sizeof ms);
+ } else {
+ struct in_addr sia = { htonl(res->u.v4.addr) };
+ struct in_addr sim = { htonl(res->u.v4.mask) };
+
+ inet_ntop(AF_INET, &sia, as, sizeof as);
+ inet_ntop(AF_INET, &sim, ms, sizeof ms);
+ }
+ mprintf("restrict node at %p: %s/%s count %d, rflags %05x, mflags %05x, ippeerlimit %d, expire %lu, next %p\n",
+ res, as, ms, res->count, res->rflags, res->mflags,
+ res->ippeerlimit, res->expire, res->link);
+ return;
+}
+
+
+/*
+ * dump_restricts - spit out the 'restrict' lines
+ */
+void
+dump_restricts(void)
+{
+ int defaultv4_done = 0;
+ int defaultv6_done = 0;
+ restrict_u * res;
+ restrict_u * next;
+
+ mprintf("dump_restrict: restrict_def4: %p\n", &restrict_def4);
+ /* Spit out 'restrict {,-4,-6} default ...' lines, if needed */
+ for (res = &restrict_def4; res != NULL; res = next) {
+ dump_restrict(res, 0);
+ next = res->link;
+ }
+
+ mprintf("dump_restrict: restrict_def6: %p\n", &restrict_def6);
+ for (res = &restrict_def6; res != NULL; res = next) {
+ dump_restrict(res, 1);
+ next = res->link;
+ }
+
+ /* Spit out the IPv4 list */
+ mprintf("dump_restrict: restrictlist4: %p\n", &restrictlist4);
+ for (res = restrictlist4; res != NULL; res = next) {
+ dump_restrict(res, 0);
+ next = res->link;
+ }
+
+ /* Spit out the IPv6 list */
+ mprintf("dump_restrict: restrictlist6: %p\n", &restrictlist6);
+ for (res = restrictlist6; res != NULL; res = next) {
+ dump_restrict(res, 1);
+ next = res->link;
+ }
+
+ return;
+}
+
+/*
+ * init_restrict - initialize the restriction data structures
+ */
+void
+init_restrict(void)
+{
+ /*
+ * The restriction lists begin with a default entry with address
+ * and mask 0, which will match any entry. The lists are kept
+ * sorted by descending address followed by descending mask:
+ *
+ * address mask
+ * 192.168.0.0 255.255.255.0 kod limited noquery nopeer
+ * 192.168.0.0 255.255.0.0 kod limited
+ * 0.0.0.0 0.0.0.0 kod limited noquery
+ *
+ * The first entry which matches an address is used. With the
+ * example restrictions above, 192.168.0.0/24 matches the first
+ * entry, the rest of 192.168.0.0/16 matches the second, and
+ * everything else matches the third (default).
+ *
+ * Note this achieves the same result a little more efficiently
+ * than the documented behavior, which is to keep the lists
+ * sorted by ascending address followed by ascending mask, with
+ * the _last_ matching entry used.
+ *
+ * An additional wrinkle is we may have multiple entries with
+ * the same address and mask but differing match flags (mflags).
+ * At present there is only one, RESM_NTPONLY. Entries with
+ * RESM_NTPONLY are sorted earlier so they take precedence over
+ * any otherwise similar entry without. Again, this is the same
+ * behavior as but reversed implementation compared to the docs.
+ *
+ */
+
+ restrict_def4.ippeerlimit = -1; /* Cleaner if we have C99 */
+ restrict_def6.ippeerlimit = -1; /* Cleaner if we have C99 */
+
+ LINK_SLIST(restrictlist4, &restrict_def4, link);
+ LINK_SLIST(restrictlist6, &restrict_def6, link);
+ restrictcount = 2;
+}
+
+
+static restrict_u *
+alloc_res4(void)
+{
+ const size_t cb = V4_SIZEOF_RESTRICT_U;
+ const size_t count = INC_RESLIST4;
+ restrict_u * rl;
+ restrict_u * res;
+ size_t i;
+
+ UNLINK_HEAD_SLIST(res, resfree4, link);
+ if (res != NULL)
+ return res;
+
+ rl = eallocarray(count, cb);
+ /* link all but the first onto free list */
+ res = (void *)((char *)rl + (count - 1) * cb);
+ for (i = count - 1; i > 0; i--) {
+ LINK_SLIST(resfree4, res, link);
+ res = (void *)((char *)res - cb);
+ }
+ INSIST(rl == res);
+ /* allocate the first */
+ return res;
+}
+
+
+static restrict_u *
+alloc_res6(void)
+{
+ const size_t cb = V6_SIZEOF_RESTRICT_U;
+ const size_t count = INC_RESLIST6;
+ restrict_u * rl;
+ restrict_u * res;
+ size_t i;
+
+ UNLINK_HEAD_SLIST(res, resfree6, link);
+ if (res != NULL)
+ return res;
+
+ rl = eallocarray(count, cb);
+ /* link all but the first onto free list */
+ res = (void *)((char *)rl + (count - 1) * cb);
+ for (i = count - 1; i > 0; i--) {
+ LINK_SLIST(resfree6, res, link);
+ res = (void *)((char *)res - cb);
+ }
+ INSIST(rl == res);
+ /* allocate the first */
+ return res;
+}
+
+
+static void
+free_res(
+ restrict_u * res,
+ int v6
+ )
+{
+ restrict_u ** plisthead;
+ restrict_u * unlinked;
+
+ restrictcount--;
+ if (RES_LIMITED & res->rflags)
+ dec_res_limited();
+
+ if (v6)
+ plisthead = &restrictlist6;
+ else
+ plisthead = &restrictlist4;
+ UNLINK_SLIST(unlinked, *plisthead, res, link, restrict_u);
+ INSIST(unlinked == res);
+
+ if (v6) {
+ zero_mem(res, V6_SIZEOF_RESTRICT_U);
+ plisthead = &resfree6;
+ } else {
+ zero_mem(res, V4_SIZEOF_RESTRICT_U);
+ plisthead = &resfree4;
+ }
+ LINK_SLIST(*plisthead, res, link);
+}
+
+
+static void
+inc_res_limited(void)
+{
+ if (!res_limited_refcnt)
+ mon_start(MON_RES);
+ res_limited_refcnt++;
+}
+
+
+static void
+dec_res_limited(void)
+{
+ res_limited_refcnt--;
+ if (!res_limited_refcnt)
+ mon_stop(MON_RES);
+}
+
+
+static restrict_u *
+match_restrict4_addr(
+ u_int32 addr,
+ u_short port
+ )
+{
+ const int v6 = 0;
+ restrict_u * res;
+ restrict_u * next;
+
+ for (res = restrictlist4; res != NULL; res = next) {
+ struct in_addr sia = { htonl(res->u.v4.addr) };
+
+ next = res->link;
+ DPRINTF(2, ("match_restrict4_addr: Checking %s, port %d ... ",
+ inet_ntoa(sia), port));
+ if ( res->expire
+ && res->expire <= current_time)
+ free_res(res, v6); /* zeroes the contents */
+ if ( res->u.v4.addr == (addr & res->u.v4.mask)
+ && ( !(RESM_NTPONLY & res->mflags)
+ || NTP_PORT == port)) {
+ DPRINTF(2, ("MATCH: ippeerlimit %d\n", res->ippeerlimit));
+ break;
+ }
+ DPRINTF(2, ("doesn't match: ippeerlimit %d\n", res->ippeerlimit));
+ }
+ return res;
+}
+
+
+static restrict_u *
+match_restrict6_addr(
+ const struct in6_addr * addr,
+ u_short port
+ )
+{
+ const int v6 = 1;
+ restrict_u * res;
+ restrict_u * next;
+ struct in6_addr masked;
+
+ for (res = restrictlist6; res != NULL; res = next) {
+ next = res->link;
+ INSIST(next != res);
+ if (res->expire &&
+ res->expire <= current_time)
+ free_res(res, v6);
+ MASK_IPV6_ADDR(&masked, addr, &res->u.v6.mask);
+ if (ADDR6_EQ(&masked, &res->u.v6.addr)
+ && (!(RESM_NTPONLY & res->mflags)
+ || NTP_PORT == (int)port))
+ break;
+ }
+ return res;
+}
+
+
+/*
+ * match_restrict_entry - find an exact match on a restrict list.
+ *
+ * Exact match is addr, mask, and mflags all equal.
+ * In order to use more common code for IPv4 and IPv6, this routine
+ * requires the caller to populate a restrict_u with mflags and either
+ * the v4 or v6 address and mask as appropriate. Other fields in the
+ * input restrict_u are ignored.
+ */
+static restrict_u *
+match_restrict_entry(
+ const restrict_u * pmatch,
+ int v6
+ )
+{
+ restrict_u *res;
+ restrict_u *rlist;
+ size_t cb;
+
+ if (v6) {
+ rlist = restrictlist6;
+ cb = sizeof(pmatch->u.v6);
+ } else {
+ rlist = restrictlist4;
+ cb = sizeof(pmatch->u.v4);
+ }
+
+ for (res = rlist; res != NULL; res = res->link)
+ if (res->mflags == pmatch->mflags &&
+ !memcmp(&res->u, &pmatch->u, cb))
+ break;
+ return res;
+}
+
+
+/*
+ * res_sorts_before4 - compare two restrict4 entries
+ *
+ * Returns nonzero if r1 sorts before r2. We sort by descending
+ * address, then descending mask, then descending mflags, so sorting
+ * before means having a higher value.
+ */
+static int
+res_sorts_before4(
+ restrict_u *r1,
+ restrict_u *r2
+ )
+{
+ int r1_before_r2;
+
+ if (r1->u.v4.addr > r2->u.v4.addr)
+ r1_before_r2 = 1;
+ else if (r1->u.v4.addr < r2->u.v4.addr)
+ r1_before_r2 = 0;
+ else if (r1->u.v4.mask > r2->u.v4.mask)
+ r1_before_r2 = 1;
+ else if (r1->u.v4.mask < r2->u.v4.mask)
+ r1_before_r2 = 0;
+ else if (r1->mflags > r2->mflags)
+ r1_before_r2 = 1;
+ else
+ r1_before_r2 = 0;
+
+ return r1_before_r2;
+}
+
+
+/*
+ * res_sorts_before6 - compare two restrict6 entries
+ *
+ * Returns nonzero if r1 sorts before r2. We sort by descending
+ * address, then descending mask, then descending mflags, so sorting
+ * before means having a higher value.
+ */
+static int
+res_sorts_before6(
+ restrict_u *r1,
+ restrict_u *r2
+ )
+{
+ int r1_before_r2;
+ int cmp;
+
+ cmp = ADDR6_CMP(&r1->u.v6.addr, &r2->u.v6.addr);
+ if (cmp > 0) /* r1->addr > r2->addr */
+ r1_before_r2 = 1;
+ else if (cmp < 0) /* r2->addr > r1->addr */
+ r1_before_r2 = 0;
+ else {
+ cmp = ADDR6_CMP(&r1->u.v6.mask, &r2->u.v6.mask);
+ if (cmp > 0) /* r1->mask > r2->mask*/
+ r1_before_r2 = 1;
+ else if (cmp < 0) /* r2->mask > r1->mask */
+ r1_before_r2 = 0;
+ else if (r1->mflags > r2->mflags)
+ r1_before_r2 = 1;
+ else
+ r1_before_r2 = 0;
+ }
+
+ return r1_before_r2;
+}
+
+
+/*
+ * restrictions - return restrictions for this host in *r4a
+ */
+void
+restrictions(
+ sockaddr_u *srcadr,
+ r4addr *r4a
+ )
+{
+ restrict_u *match;
+ struct in6_addr *pin6;
+
+ REQUIRE(NULL != r4a);
+
+ res_calls++;
+ r4a->rflags = RES_IGNORE;
+ r4a->ippeerlimit = 0;
+
+ DPRINTF(1, ("restrictions: looking up %s\n", stoa(srcadr)));
+
+ /* IPv4 source address */
+ if (IS_IPV4(srcadr)) {
+ /*
+ * Ignore any packets with a multicast source address
+ * (this should be done early in the receive process,
+ * not later!)
+ */
+ if (IN_CLASSD(SRCADR(srcadr))) {
+ DPRINTF(1, ("restrictions: srcadr %s is multicast\n", stoa(srcadr)));
+ r4a->ippeerlimit = 2; /* XXX: we should use a better value */
+ return;
+ }
+
+ match = match_restrict4_addr(SRCADR(srcadr),
+ SRCPORT(srcadr));
+
+ INSIST(match != NULL);
+
+ match->count++;
+ /*
+ * res_not_found counts only use of the final default
+ * entry, not any "restrict default ntpport ...", which
+ * would be just before the final default.
+ */
+ if (&restrict_def4 == match)
+ res_not_found++;
+ else
+ res_found++;
+ r4a->rflags = match->rflags;
+ r4a->ippeerlimit = match->ippeerlimit;
+ }
+
+ /* IPv6 source address */
+ if (IS_IPV6(srcadr)) {
+ pin6 = PSOCK_ADDR6(srcadr);
+
+ /*
+ * Ignore any packets with a multicast source address
+ * (this should be done early in the receive process,
+ * not later!)
+ */
+ if (IN6_IS_ADDR_MULTICAST(pin6))
+ return;
+
+ match = match_restrict6_addr(pin6, SRCPORT(srcadr));
+ INSIST(match != NULL);
+ match->count++;
+ if (&restrict_def6 == match)
+ res_not_found++;
+ else
+ res_found++;
+ r4a->rflags = match->rflags;
+ r4a->ippeerlimit = match->ippeerlimit;
+ }
+ return;
+}
+
+
+/*
+ * roptoa - convert a restrict_op to a string
+ */
+char *
+roptoa(restrict_op op) {
+ static char sb[30];
+
+ switch(op) {
+ case RESTRICT_FLAGS: return "RESTRICT_FLAGS";
+ case RESTRICT_UNFLAG: return "RESTRICT_UNFLAGS";
+ case RESTRICT_REMOVE: return "RESTRICT_REMOVE";
+ case RESTRICT_REMOVEIF: return "RESTRICT_REMOVEIF";
+ default:
+ snprintf(sb, sizeof sb, "**RESTRICT_#%d**", op);
+ return sb;
+ }
+}
+
+
+/*
+ * hack_restrict - add/subtract/manipulate entries on the restrict list
+ */
+void
+hack_restrict(
+ restrict_op op,
+ sockaddr_u * resaddr,
+ sockaddr_u * resmask,
+ short ippeerlimit,
+ u_short mflags,
+ u_short rflags,
+ u_long expire
+ )
+{
+ int v6;
+ restrict_u match;
+ restrict_u * res;
+ restrict_u ** plisthead;
+
+ DPRINTF(1, ("hack_restrict: op %s addr %s mask %s ippeerlimit %d mflags %08x rflags %08x\n",
+ roptoa(op), stoa(resaddr), stoa(resmask), ippeerlimit, mflags, rflags));
+
+ if (NULL == resaddr) {
+ REQUIRE(NULL == resmask);
+ REQUIRE(RESTRICT_FLAGS == op);
+ restrict_source_rflags = rflags;
+ restrict_source_mflags = mflags;
+ restrict_source_ippeerlimit = ippeerlimit;
+ restrict_source_enabled = 1;
+ return;
+ }
+
+ ZERO(match);
+
+#if 0
+ /* silence VC9 potentially uninit warnings */
+ // HMS: let's use a compiler-specific "enable" for this.
+ res = NULL;
+ v6 = 0;
+#endif
+
+ if (IS_IPV4(resaddr)) {
+ v6 = 0;
+ /*
+ * Get address and mask in host byte order for easy
+ * comparison as u_int32
+ */
+ match.u.v4.addr = SRCADR(resaddr);
+ match.u.v4.mask = SRCADR(resmask);
+ match.u.v4.addr &= match.u.v4.mask;
+
+ } else if (IS_IPV6(resaddr)) {
+ v6 = 1;
+ /*
+ * Get address and mask in network byte order for easy
+ * comparison as byte sequences (e.g. memcmp())
+ */
+ match.u.v6.mask = SOCK_ADDR6(resmask);
+ MASK_IPV6_ADDR(&match.u.v6.addr, PSOCK_ADDR6(resaddr),
+ &match.u.v6.mask);
+
+ } else /* not IPv4 nor IPv6 */
+ REQUIRE(0);
+
+ match.rflags = rflags;
+ match.mflags = mflags;
+ match.ippeerlimit = ippeerlimit;
+ match.expire = expire;
+ res = match_restrict_entry(&match, v6);
+
+ switch (op) {
+
+ case RESTRICT_FLAGS:
+ /*
+ * Here we add bits to the rflags. If this is a
+ * new restriction add it.
+ */
+ if (NULL == res) {
+ if (v6) {
+ res = alloc_res6();
+ memcpy(res, &match,
+ V6_SIZEOF_RESTRICT_U);
+ plisthead = &restrictlist6;
+ } else {
+ res = alloc_res4();
+ memcpy(res, &match,
+ V4_SIZEOF_RESTRICT_U);
+ plisthead = &restrictlist4;
+ }
+ LINK_SORT_SLIST(
+ *plisthead, res,
+ (v6)
+ ? res_sorts_before6(res, L_S_S_CUR())
+ : res_sorts_before4(res, L_S_S_CUR()),
+ link, restrict_u);
+ restrictcount++;
+ if (RES_LIMITED & rflags)
+ inc_res_limited();
+ } else {
+ if ( (RES_LIMITED & rflags)
+ && !(RES_LIMITED & res->rflags))
+ inc_res_limited();
+ res->rflags |= rflags;
+ }
+
+ res->ippeerlimit = match.ippeerlimit;
+
+ break;
+
+ case RESTRICT_UNFLAG:
+ /*
+ * Remove some bits from the rflags. If we didn't
+ * find this one, just return.
+ */
+ if (res != NULL) {
+ if ( (RES_LIMITED & res->rflags)
+ && (RES_LIMITED & rflags))
+ dec_res_limited();
+ res->rflags &= ~rflags;
+ }
+ break;
+
+ case RESTRICT_REMOVE:
+ case RESTRICT_REMOVEIF:
+ /*
+ * Remove an entry from the table entirely if we
+ * found one. Don't remove the default entry and
+ * don't remove an interface entry.
+ */
+ if (res != NULL
+ && (RESTRICT_REMOVEIF == op
+ || !(RESM_INTERFACE & res->mflags))
+ && res != &restrict_def4
+ && res != &restrict_def6)
+ free_res(res, v6);
+ break;
+
+ default: /* unknown op */
+ INSIST(0);
+ break;
+ }
+
+}
+
+
+/*
+ * restrict_source - maintains dynamic "restrict source ..." entries as
+ * peers come and go.
+ */
+void
+restrict_source(
+ sockaddr_u * addr,
+ int farewell, /* 0 to add, 1 to remove */
+ u_long expire /* 0 is infinite, valid until */
+ )
+{
+ sockaddr_u onesmask;
+ restrict_u * res;
+ int found_specific;
+
+ if (!restrict_source_enabled || SOCK_UNSPEC(addr) ||
+ IS_MCAST(addr) || ISREFCLOCKADR(addr))
+ return;
+
+ REQUIRE(AF_INET == AF(addr) || AF_INET6 == AF(addr));
+
+ SET_HOSTMASK(&onesmask, AF(addr));
+ if (farewell) {
+ hack_restrict(RESTRICT_REMOVE, addr, &onesmask,
+ -2, 0, 0, 0);
+ DPRINTF(1, ("restrict_source: %s removed", stoa(addr)));
+ return;
+ }
+
+ /*
+ * If there is a specific entry for this address, hands
+ * off, as it is condidered more specific than "restrict
+ * server ...".
+ * However, if the specific entry found is a fleeting one
+ * added by pool_xmit() before soliciting, replace it
+ * immediately regardless of the expire value to make way
+ * for the more persistent entry.
+ */
+ if (IS_IPV4(addr)) {
+ res = match_restrict4_addr(SRCADR(addr), SRCPORT(addr));
+ INSIST(res != NULL);
+ found_specific = (SRCADR(&onesmask) == res->u.v4.mask);
+ } else {
+ res = match_restrict6_addr(&SOCK_ADDR6(addr),
+ SRCPORT(addr));
+ INSIST(res != NULL);
+ found_specific = ADDR6_EQ(&res->u.v6.mask,
+ &SOCK_ADDR6(&onesmask));
+ }
+ if (!expire && found_specific && res->expire) {
+ found_specific = 0;
+ free_res(res, IS_IPV6(addr));
+ }
+ if (found_specific)
+ return;
+
+ hack_restrict(RESTRICT_FLAGS, addr, &onesmask,
+ restrict_source_ippeerlimit, restrict_source_mflags,
+ restrict_source_rflags, expire);
+ DPRINTF(1, ("restrict_source: %s host restriction added\n",
+ stoa(addr)));
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_scanner.c b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_scanner.c
new file mode 100644
index 0000000..728b39b
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_scanner.c
@@ -0,0 +1,937 @@
+#include <machine/rtems-bsd-user-space.h>
+
+
+/* ntp_scanner.c
+ *
+ * The source code for a simple lexical analyzer.
+ *
+ * Written By: Sachin Kamboj
+ * University of Delaware
+ * Newark, DE 19711
+ * Copyright (c) 2006
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+
+#include "ntpd.h"
+#include "ntp_config.h"
+#include "ntpsim.h"
+#include "ntp_scanner.h"
+#include "ntp_parser.h"
+
+/* ntp_keyword.h declares finite state machine and token text */
+#include "ntp_keyword.h"
+
+
+
+/* SCANNER GLOBAL VARIABLES
+ * ------------------------
+ */
+
+#define MAX_LEXEME (1024 + 1) /* The maximum size of a lexeme */
+char yytext[MAX_LEXEME]; /* Buffer for storing the input text/lexeme */
+u_int32 conf_file_sum; /* Simple sum of characters read */
+
+static struct FILE_INFO * lex_stack = NULL;
+
+
+
+/* CONSTANTS
+ * ---------
+ */
+
+
+/* SCANNER GLOBAL VARIABLES
+ * ------------------------
+ */
+const char special_chars[] = "{}(),;|=";
+
+
+/* FUNCTIONS
+ * ---------
+ */
+
+static int is_keyword(char *lexeme, follby *pfollowedby);
+
+
+/*
+ * keyword() - Return the keyword associated with token T_ identifier.
+ * See also token_name() for the string-ized T_ identifier.
+ * Example: keyword(T_Server) returns "server"
+ * token_name(T_Server) returns "T_Server"
+ */
+const char *
+keyword(
+ int token
+ )
+{
+ size_t i;
+ const char *text;
+
+ i = token - LOWEST_KEYWORD_ID;
+
+ if (i < COUNTOF(keyword_text))
+ text = keyword_text[i];
+ else
+ text = NULL;
+
+ return (text != NULL)
+ ? text
+ : "(keyword not found)";
+}
+
+
+/* FILE & STRING BUFFER INTERFACE
+ * ------------------------------
+ *
+ * This set out as a couple of wrapper functions around the standard C
+ * fgetc and ungetc functions in order to include positional
+ * bookkeeping. Alas, this is no longer a good solution with nested
+ * input files and the possibility to send configuration commands via
+ * 'ntpdc' and 'ntpq'.
+ *
+ * Now there are a few functions to maintain a stack of nested input
+ * sources (though nesting is only allowd for disk files) and from the
+ * scanner / parser point of view there's no difference between both
+ * types of sources.
+ *
+ * The 'fgetc()' / 'ungetc()' replacements now operate on a FILE_INFO
+ * structure. Instead of trying different 'ungetc()' strategies for file
+ * and buffer based parsing, we keep the backup char in our own
+ * FILE_INFO structure. This is sufficient, as the parser does *not*
+ * jump around via 'seek' or the like, and there's no need to
+ * check/clear the backup store in other places than 'lex_getch()'.
+ */
+
+/*
+ * Allocate an info structure and attach it to a file.
+ *
+ * Note: When 'mode' is NULL, then the INFO block will be set up to
+ * contain a NULL file pointer, as suited for remote config command
+ * parsing. Otherwise having a NULL file pointer is considered an error,
+ * and a NULL info block pointer is returned to indicate failure!
+ *
+ * Note: We use a variable-sized structure to hold a copy of the file
+ * name (or, more proper, the input source description). This is more
+ * secure than keeping a reference to some other storage that might go
+ * out of scope.
+ */
+static struct FILE_INFO *
+lex_open(
+ const char *path,
+ const char *mode
+ )
+{
+ struct FILE_INFO *stream;
+ size_t nnambuf;
+
+ nnambuf = strlen(path);
+ stream = emalloc_zero(sizeof(*stream) + nnambuf);
+ stream->curpos.nline = 1;
+ stream->backch = EOF;
+ /* copy name with memcpy -- trailing NUL already there! */
+ memcpy(stream->fname, path, nnambuf);
+
+ if (NULL != mode) {
+ stream->fpi = fopen(path, mode);
+ if (NULL == stream->fpi) {
+ free(stream);
+ stream = NULL;
+ }
+ }
+ return stream;
+}
+
+/* get next character from buffer or file. This will return any putback
+ * character first; it will also make sure the last line is at least
+ * virtually terminated with a '\n'.
+ */
+static int
+lex_getch(
+ struct FILE_INFO *stream
+ )
+{
+ int ch;
+
+ if (NULL == stream || stream->force_eof)
+ return EOF;
+
+ if (EOF != stream->backch) {
+ ch = stream->backch;
+ stream->backch = EOF;
+ if (stream->fpi)
+ conf_file_sum += ch;
+ stream->curpos.ncol++;
+ } else if (stream->fpi) {
+ /* fetch next 7-bit ASCII char (or EOF) from file */
+ while ((ch = fgetc(stream->fpi)) != EOF && ch > SCHAR_MAX)
+ stream->curpos.ncol++;
+ if (EOF != ch) {
+ conf_file_sum += ch;
+ stream->curpos.ncol++;
+ }
+ } else {
+ /* fetch next 7-bit ASCII char from buffer */
+ const char * scan;
+ scan = &remote_config.buffer[remote_config.pos];
+ while ((ch = (u_char)*scan) > SCHAR_MAX) {
+ scan++;
+ stream->curpos.ncol++;
+ }
+ if ('\0' != ch) {
+ scan++;
+ stream->curpos.ncol++;
+ } else {
+ ch = EOF;
+ }
+ remote_config.pos = (int)(scan - remote_config.buffer);
+ }
+
+ /* If the last line ends without '\n', generate one. This
+ * happens most likely on Windows, where editors often have a
+ * sloppy concept of a line.
+ */
+ if (EOF == ch && stream->curpos.ncol != 0)
+ ch = '\n';
+
+ /* update scan position tallies */
+ if (ch == '\n') {
+ stream->bakpos = stream->curpos;
+ stream->curpos.nline++;
+ stream->curpos.ncol = 0;
+ }
+
+ return ch;
+}
+
+/* Note: lex_ungetch will fail to track more than one line of push
+ * back. But since it guarantees only one char of back storage anyway,
+ * this should not be a problem.
+ */
+static int
+lex_ungetch(
+ int ch,
+ struct FILE_INFO *stream
+ )
+{
+ /* check preconditions */
+ if (NULL == stream || stream->force_eof)
+ return EOF;
+ if (EOF != stream->backch || EOF == ch)
+ return EOF;
+
+ /* keep for later reference and update checksum */
+ stream->backch = (u_char)ch;
+ if (stream->fpi)
+ conf_file_sum -= stream->backch;
+
+ /* update position */
+ if (stream->backch == '\n') {
+ stream->curpos = stream->bakpos;
+ stream->bakpos.ncol = -1;
+ }
+ stream->curpos.ncol--;
+ return stream->backch;
+}
+
+/* dispose of an input structure. If the file pointer is not NULL, close
+ * the file. This function does not check the result of 'fclose()'.
+ */
+static void
+lex_close(
+ struct FILE_INFO *stream
+ )
+{
+ if (NULL != stream) {
+ if (NULL != stream->fpi)
+ fclose(stream->fpi);
+ free(stream);
+ }
+}
+
+/* INPUT STACK
+ * -----------
+ *
+ * Nested input sources are a bit tricky at first glance. We deal with
+ * this problem using a stack of input sources, that is, a forward
+ * linked list of FILE_INFO structs.
+ *
+ * This stack is never empty during parsing; while an encounter with EOF
+ * can and will remove nested input sources, removing the last element
+ * in the stack will not work during parsing, and the EOF condition of
+ * the outermost input file remains until the parser folds up.
+ */
+
+static struct FILE_INFO *
+_drop_stack_do(
+ struct FILE_INFO * head
+ )
+{
+ struct FILE_INFO * tail;
+ while (NULL != head) {
+ tail = head->st_next;
+ lex_close(head);
+ head = tail;
+ }
+ return head;
+}
+
+
+
+/* Create a singleton input source on an empty lexer stack. This will
+ * fail if there is already an input source, or if the underlying disk
+ * file cannot be opened.
+ *
+ * Returns TRUE if a new input object was successfully created.
+ */
+int/*BOOL*/
+lex_init_stack(
+ const char * path,
+ const char * mode
+ )
+{
+ if (NULL != lex_stack || NULL == path)
+ return FALSE;
+
+ lex_stack = lex_open(path, mode);
+ return (NULL != lex_stack);
+}
+
+/* This removes *all* input sources from the stack, leaving the head
+ * pointer as NULL. Any attempt to parse in that state is likely to bomb
+ * with segmentation faults or the like.
+ *
+ * In other words: Use this to clean up after parsing, and do not parse
+ * anything until the next 'lex_init_stack()' succeeded.
+ */
+void
+lex_drop_stack()
+{
+ lex_stack = _drop_stack_do(lex_stack);
+}
+
+/* Flush the lexer input stack: This will nip all input objects on the
+ * stack (but keeps the current top-of-stack) and marks the top-of-stack
+ * as inactive. Any further calls to lex_getch yield only EOF, and it's
+ * no longer possible to push something back.
+ *
+ * Returns TRUE if there is a head element (top-of-stack) that was not
+ * in the force-eof mode before this call.
+ */
+int/*BOOL*/
+lex_flush_stack()
+{
+ int retv = FALSE;
+
+ if (NULL != lex_stack) {
+ retv = !lex_stack->force_eof;
+ lex_stack->force_eof = TRUE;
+ lex_stack->st_next = _drop_stack_do(
+ lex_stack->st_next);
+ }
+ return retv;
+}
+
+/* Push another file on the parsing stack. If the mode is NULL, create a
+ * FILE_INFO suitable for in-memory parsing; otherwise, create a
+ * FILE_INFO that is bound to a local/disc file. Note that 'path' must
+ * not be NULL, or the function will fail.
+ *
+ * Returns TRUE if a new info record was pushed onto the stack.
+ */
+int/*BOOL*/ lex_push_file(
+ const char * path,
+ const char * mode
+ )
+{
+ struct FILE_INFO * next = NULL;
+
+ if (NULL != path) {
+ next = lex_open(path, mode);
+ if (NULL != next) {
+ next->st_next = lex_stack;
+ lex_stack = next;
+ }
+ }
+ return (NULL != next);
+}
+
+/* Pop, close & free the top of the include stack, unless the stack
+ * contains only a singleton input object. In that case the function
+ * fails, because the parser does not expect the input stack to be
+ * empty.
+ *
+ * Returns TRUE if an object was successfuly popped from the stack.
+ */
+int/*BOOL*/
+lex_pop_file(void)
+{
+ struct FILE_INFO * head = lex_stack;
+ struct FILE_INFO * tail = NULL;
+
+ if (NULL != head) {
+ tail = head->st_next;
+ if (NULL != tail) {
+ lex_stack = tail;
+ lex_close(head);
+ }
+ }
+ return (NULL != tail);
+}
+
+/* Get include nesting level. This currently loops over the stack and
+ * counts elements; but since this is of concern only with an include
+ * statement and the nesting depth has a small limit, there's no
+ * bottleneck expected here.
+ *
+ * Returns the nesting level of includes, that is, the current depth of
+ * the lexer input stack.
+ *
+ * Note:
+ */
+size_t
+lex_level(void)
+{
+ size_t cnt = 0;
+ struct FILE_INFO *ipf = lex_stack;
+
+ while (NULL != ipf) {
+ cnt++;
+ ipf = ipf->st_next;
+ }
+ return cnt;
+}
+
+/* check if the current input is from a file */
+int/*BOOL*/
+lex_from_file(void)
+{
+ return (NULL != lex_stack) && (NULL != lex_stack->fpi);
+}
+
+struct FILE_INFO *
+lex_current()
+{
+ /* this became so simple, it could be a macro. But then,
+ * lex_stack needed to be global...
+ */
+ return lex_stack;
+}
+
+
+/* STATE MACHINES
+ * --------------
+ */
+
+/* Keywords */
+static int
+is_keyword(
+ char *lexeme,
+ follby *pfollowedby
+ )
+{
+ follby fb;
+ int curr_s; /* current state index */
+ int token;
+ int i;
+
+ curr_s = SCANNER_INIT_S;
+ token = 0;
+
+ for (i = 0; lexeme[i]; i++) {
+ while (curr_s && (lexeme[i] != SS_CH(sst[curr_s])))
+ curr_s = SS_OTHER_N(sst[curr_s]);
+
+ if (curr_s && (lexeme[i] == SS_CH(sst[curr_s]))) {
+ if ('\0' == lexeme[i + 1]
+ && FOLLBY_NON_ACCEPTING
+ != SS_FB(sst[curr_s])) {
+ fb = SS_FB(sst[curr_s]);
+ *pfollowedby = fb;
+ token = curr_s;
+ break;
+ }
+ curr_s = SS_MATCH_N(sst[curr_s]);
+ } else
+ break;
+ }
+
+ return token;
+}
+
+
+/* Integer */
+static int
+is_integer(
+ char *lexeme
+ )
+{
+ int i;
+ int is_neg;
+ u_int u_val;
+
+ i = 0;
+
+ /* Allow a leading minus sign */
+ if (lexeme[i] == '-') {
+ i++;
+ is_neg = TRUE;
+ } else {
+ is_neg = FALSE;
+ }
+
+ /* Check that all the remaining characters are digits */
+ for (; lexeme[i] != '\0'; i++) {
+ if (!isdigit((u_char)lexeme[i]))
+ return FALSE;
+ }
+
+ if (is_neg)
+ return TRUE;
+
+ /* Reject numbers that fit in unsigned but not in signed int */
+ if (1 == sscanf(lexeme, "%u", &u_val))
+ return (u_val <= INT_MAX);
+ else
+ return FALSE;
+}
+
+
+/* U_int -- assumes is_integer() has returned FALSE */
+static int
+is_u_int(
+ char *lexeme
+ )
+{
+ int i;
+ int is_hex;
+
+ i = 0;
+ if ('0' == lexeme[i] && 'x' == tolower((u_char)lexeme[i + 1])) {
+ i += 2;
+ is_hex = TRUE;
+ } else {
+ is_hex = FALSE;
+ }
+
+ /* Check that all the remaining characters are digits */
+ for (; lexeme[i] != '\0'; i++) {
+ if (is_hex && !isxdigit((u_char)lexeme[i]))
+ return FALSE;
+ if (!is_hex && !isdigit((u_char)lexeme[i]))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/* Double */
+static int
+is_double(
+ char *lexeme
+ )
+{
+ u_int num_digits = 0; /* Number of digits read */
+ u_int i;
+
+ i = 0;
+
+ /* Check for an optional '+' or '-' */
+ if ('+' == lexeme[i] || '-' == lexeme[i])
+ i++;
+
+ /* Read the integer part */
+ for (; lexeme[i] && isdigit((u_char)lexeme[i]); i++)
+ num_digits++;
+
+ /* Check for the optional decimal point */
+ if ('.' == lexeme[i]) {
+ i++;
+ /* Check for any digits after the decimal point */
+ for (; lexeme[i] && isdigit((u_char)lexeme[i]); i++)
+ num_digits++;
+ }
+
+ /*
+ * The number of digits in both the decimal part and the
+ * fraction part must not be zero at this point
+ */
+ if (!num_digits)
+ return 0;
+
+ /* Check if we are done */
+ if (!lexeme[i])
+ return 1;
+
+ /* There is still more input, read the exponent */
+ if ('e' == tolower((u_char)lexeme[i]))
+ i++;
+ else
+ return 0;
+
+ /* Read an optional Sign */
+ if ('+' == lexeme[i] || '-' == lexeme[i])
+ i++;
+
+ /* Now read the exponent part */
+ while (lexeme[i] && isdigit((u_char)lexeme[i]))
+ i++;
+
+ /* Check if we are done */
+ if (!lexeme[i])
+ return 1;
+ else
+ return 0;
+}
+
+
+/* is_special() - Test whether a character is a token */
+static inline int
+is_special(
+ int ch
+ )
+{
+ return strchr(special_chars, ch) != NULL;
+}
+
+
+static int
+is_EOC(
+ int ch
+ )
+{
+ if ((old_config_style && (ch == '\n')) ||
+ (!old_config_style && (ch == ';')))
+ return 1;
+ return 0;
+}
+
+
+char *
+quote_if_needed(char *str)
+{
+ char *ret;
+ size_t len;
+ size_t octets;
+
+ len = strlen(str);
+ octets = len + 2 + 1;
+ ret = emalloc(octets);
+ if ('"' != str[0]
+ && (strcspn(str, special_chars) < len
+ || strchr(str, ' ') != NULL)) {
+ snprintf(ret, octets, "\"%s\"", str);
+ } else
+ strlcpy(ret, str, octets);
+
+ return ret;
+}
+
+
+static int
+create_string_token(
+ char *lexeme
+ )
+{
+ char *pch;
+
+ /*
+ * ignore end of line whitespace
+ */
+ pch = lexeme;
+ while (*pch && isspace((u_char)*pch))
+ pch++;
+
+ if (!*pch) {
+ yylval.Integer = T_EOC;
+ return yylval.Integer;
+ }
+
+ yylval.String = estrdup(lexeme);
+ return T_String;
+}
+
+
+/*
+ * yylex() - function that does the actual scanning.
+ * Bison expects this function to be called yylex and for it to take no
+ * input and return an int.
+ * Conceptually yylex "returns" yylval as well as the actual return
+ * value representing the token or type.
+ */
+int
+yylex(void)
+{
+ static follby followedby = FOLLBY_TOKEN;
+ size_t i;
+ int instring;
+ int yylval_was_set;
+ int converted;
+ int token; /* The return value */
+ int ch;
+
+ instring = FALSE;
+ yylval_was_set = FALSE;
+
+ do {
+ /* Ignore whitespace at the beginning */
+ while (EOF != (ch = lex_getch(lex_stack)) &&
+ isspace(ch) &&
+ !is_EOC(ch))
+
+ ; /* Null Statement */
+
+ if (EOF == ch) {
+
+ if ( ! lex_pop_file())
+ return 0;
+ token = T_EOC;
+ goto normal_return;
+
+ } else if (is_EOC(ch)) {
+
+ /* end FOLLBY_STRINGS_TO_EOC effect */
+ followedby = FOLLBY_TOKEN;
+ token = T_EOC;
+ goto normal_return;
+
+ } else if (is_special(ch) && FOLLBY_TOKEN == followedby) {
+ /* special chars are their own token values */
+ token = ch;
+ /*
+ * '=' outside simulator configuration implies
+ * a single string following as in:
+ * setvar Owner = "The Boss" default
+ */
+ if ('=' == ch && old_config_style)
+ followedby = FOLLBY_STRING;
+ yytext[0] = (char)ch;
+ yytext[1] = '\0';
+ goto normal_return;
+ } else
+ lex_ungetch(ch, lex_stack);
+
+ /* save the position of start of the token */
+ lex_stack->tokpos = lex_stack->curpos;
+
+ /* Read in the lexeme */
+ i = 0;
+ while (EOF != (ch = lex_getch(lex_stack))) {
+
+ yytext[i] = (char)ch;
+
+ /* Break on whitespace or a special character */
+ if (isspace(ch) || is_EOC(ch)
+ || '"' == ch
+ || (FOLLBY_TOKEN == followedby
+ && is_special(ch)))
+ break;
+
+ /* Read the rest of the line on reading a start
+ of comment character */
+ if ('#' == ch) {
+ while (EOF != (ch = lex_getch(lex_stack))
+ && '\n' != ch)
+ ; /* Null Statement */
+ break;
+ }
+
+ i++;
+ if (i >= COUNTOF(yytext))
+ goto lex_too_long;
+ }
+ /* Pick up all of the string inside between " marks, to
+ * end of line. If we make it to EOL without a
+ * terminating " assume it for them.
+ *
+ * XXX - HMS: I'm not sure we want to assume the closing "
+ */
+ if ('"' == ch) {
+ instring = TRUE;
+ while (EOF != (ch = lex_getch(lex_stack)) &&
+ ch != '"' && ch != '\n') {
+ yytext[i++] = (char)ch;
+ if (i >= COUNTOF(yytext))
+ goto lex_too_long;
+ }
+ /*
+ * yytext[i] will be pushed back as not part of
+ * this lexeme, but any closing quote should
+ * not be pushed back, so we read another char.
+ */
+ if ('"' == ch)
+ ch = lex_getch(lex_stack);
+ }
+ /* Pushback the last character read that is not a part
+ * of this lexeme. This fails silently if ch is EOF,
+ * but then the EOF condition persists and is handled on
+ * the next turn by the include stack mechanism.
+ */
+ lex_ungetch(ch, lex_stack);
+
+ yytext[i] = '\0';
+ } while (i == 0);
+
+ /* Now return the desired token */
+
+ /* First make sure that the parser is *not* expecting a string
+ * as the next token (based on the previous token that was
+ * returned) and that we haven't read a string.
+ */
+
+ if (followedby == FOLLBY_TOKEN && !instring) {
+ token = is_keyword(yytext, &followedby);
+ if (token) {
+ /*
+ * T_Server is exceptional as it forces the
+ * following token to be a string in the
+ * non-simulator parts of the configuration,
+ * but in the simulator configuration section,
+ * "server" is followed by "=" which must be
+ * recognized as a token not a string.
+ */
+ if (T_Server == token && !old_config_style)
+ followedby = FOLLBY_TOKEN;
+ goto normal_return;
+ } else if (is_integer(yytext)) {
+ yylval_was_set = TRUE;
+ errno = 0;
+ if ((yylval.Integer = strtol(yytext, NULL, 10)) == 0
+ && ((errno == EINVAL) || (errno == ERANGE))) {
+ msyslog(LOG_ERR,
+ "Integer cannot be represented: %s",
+ yytext);
+ if (lex_from_file()) {
+ exit(1);
+ } else {
+ /* force end of parsing */
+ yylval.Integer = 0;
+ return 0;
+ }
+ }
+ token = T_Integer;
+ goto normal_return;
+ } else if (is_u_int(yytext)) {
+ yylval_was_set = TRUE;
+ if ('0' == yytext[0] &&
+ 'x' == tolower((unsigned long)yytext[1]))
+ converted = sscanf(&yytext[2], "%x",
+ &yylval.U_int);
+ else
+ converted = sscanf(yytext, "%u",
+ &yylval.U_int);
+ if (1 != converted) {
+ msyslog(LOG_ERR,
+ "U_int cannot be represented: %s",
+ yytext);
+ if (lex_from_file()) {
+ exit(1);
+ } else {
+ /* force end of parsing */
+ yylval.Integer = 0;
+ return 0;
+ }
+ }
+ token = T_U_int;
+ goto normal_return;
+ } else if (is_double(yytext)) {
+ yylval_was_set = TRUE;
+ errno = 0;
+ if ((yylval.Double = atof(yytext)) == 0 && errno == ERANGE) {
+ msyslog(LOG_ERR,
+ "Double too large to represent: %s",
+ yytext);
+ exit(1);
+ } else {
+ token = T_Double;
+ goto normal_return;
+ }
+ } else {
+ /* Default: Everything is a string */
+ yylval_was_set = TRUE;
+ token = create_string_token(yytext);
+ goto normal_return;
+ }
+ }
+
+ /*
+ * Either followedby is not FOLLBY_TOKEN or this lexeme is part
+ * of a string. Hence, we need to return T_String.
+ *
+ * _Except_ we might have a -4 or -6 flag on a an association
+ * configuration line (server, peer, pool, etc.).
+ *
+ * This is a terrible hack, but the grammar is ambiguous so we
+ * don't have a choice. [SK]
+ *
+ * The ambiguity is in the keyword scanner, not ntp_parser.y.
+ * We do not require server addresses be quoted in ntp.conf,
+ * complicating the scanner's job. To avoid trying (and
+ * failing) to match an IP address or DNS name to a keyword,
+ * the association keywords use FOLLBY_STRING in the keyword
+ * table, which tells the scanner to force the next token to be
+ * a T_String, so it does not try to match a keyword but rather
+ * expects a string when -4/-6 modifiers to server, peer, etc.
+ * are encountered.
+ * restrict -4 and restrict -6 parsing works correctly without
+ * this hack, as restrict uses FOLLBY_TOKEN. [DH]
+ */
+ if ('-' == yytext[0]) {
+ if ('4' == yytext[1]) {
+ token = T_Ipv4_flag;
+ goto normal_return;
+ } else if ('6' == yytext[1]) {
+ token = T_Ipv6_flag;
+ goto normal_return;
+ }
+ }
+
+ if (FOLLBY_STRING == followedby)
+ followedby = FOLLBY_TOKEN;
+
+ yylval_was_set = TRUE;
+ token = create_string_token(yytext);
+
+normal_return:
+ if (T_EOC == token)
+ DPRINTF(4,("\t<end of command>\n"));
+ else
+ DPRINTF(4, ("yylex: lexeme '%s' -> %s\n", yytext,
+ token_name(token)));
+
+ if (!yylval_was_set)
+ yylval.Integer = token;
+
+ return token;
+
+lex_too_long:
+ yytext[min(sizeof(yytext) - 1, 50)] = 0;
+ msyslog(LOG_ERR,
+ "configuration item on line %d longer than limit of %lu, began with '%s'",
+ lex_stack->curpos.nline, (u_long)min(sizeof(yytext) - 1, 50),
+ yytext);
+
+ /*
+ * If we hit the length limit reading the startup configuration
+ * file, abort.
+ */
+ if (lex_from_file())
+ exit(sizeof(yytext) - 1);
+
+ /*
+ * If it's runtime configuration via ntpq :config treat it as
+ * if the configuration text ended before the too-long lexeme,
+ * hostname, or string.
+ */
+ yylval.Integer = 0;
+ return 0;
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_scanner.h b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_scanner.h
new file mode 100644
index 0000000..11bbfe9
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_scanner.h
@@ -0,0 +1,142 @@
+/* ntp_scanner.h
+ *
+ * The header file for a simple lexical analyzer.
+ *
+ * Written By: Sachin Kamboj
+ * University of Delaware
+ * Newark, DE 19711
+ * Copyright (c) 2006
+ */
+
+#ifndef NTP_SCANNER_H
+#define NTP_SCANNER_H
+
+#include "ntp_config.h"
+
+/*
+ * ntp.conf syntax is slightly irregular in that some tokens such as
+ * hostnames do not require quoting even if they might otherwise be
+ * recognized as T_ terminal tokens. This hand-crafted lexical scanner
+ * uses a "followed by" value associated with each keyword to indicate
+ * normal scanning of the next token, forced scanning of the next token
+ * alone as a T_String, or forced scanning of all tokens to the end of
+ * the command as T_String.
+ * In the past the identifiers for this functionality ended in _ARG:
+ *
+ * NO_ARG -> FOLLBY_TOKEN
+ * SINGLE_ARG -> FOLLBY_STRING
+ * MULTIPLE_ARG -> FOLLBY_STRINGS_TO_EOC
+ *
+ * Note that some tokens use FOLLBY_TOKEN even though they sometimes
+ * are followed by strings. FOLLBY_STRING is used only when needed to
+ * avoid the keyword scanner matching a token where a string is needed.
+ *
+ * FOLLBY_NON_ACCEPT is an overloading of this field to distinguish
+ * non-accepting states (where the state number does not match a T_
+ * value).
+ */
+typedef enum {
+ FOLLBY_TOKEN = 0,
+ FOLLBY_STRING,
+ FOLLBY_STRINGS_TO_EOC,
+ FOLLBY_NON_ACCEPTING
+} follby;
+
+#define MAXLINE 1024 /* maximum length of line */
+#define MAXINCLUDELEVEL 5 /* maximum include file levels */
+
+/* STRUCTURES
+ * ----------
+ */
+
+/*
+ * Define a structure to hold the FSA for the keywords.
+ * The structure is actually a trie.
+ *
+ * To save space, a single u_int32 encodes four fields, and a fifth
+ * (the token completed for terminal states) is implied by the index of
+ * the rule within the scan state array, taking advantage of the fact
+ * there are more scan states than the highest T_ token number.
+ *
+ * The lowest 8 bits hold the character the state matches on.
+ * Bits 8 and 9 hold the followedby value (0 - 3). For non-accepting
+ * states (which do not match a completed token) the followedby
+ * value 3 (FOLLBY_NONACCEPTING) denotes that fact. For accepting
+ * states, values 0 - 2 control whether the scanner forces the
+ * following token(s) to strings.
+ * Bits 10 through 20 hold the next state to check not matching
+ * this state's character.
+ * Bits 21 through 31 hold the next state to check matching the char.
+ */
+
+#define S_ST(ch, fb, match_n, other_n) ( \
+ (u_char)((ch) & 0xff) | \
+ ((u_int32)(fb) << 8) | \
+ ((u_int32)(match_n) << 10) | \
+ ((u_int32)(other_n) << 21) \
+)
+
+#define SS_CH(ss) ((char)(u_char)((ss) & 0xff))
+#define SS_FB(ss) (((u_int)(ss) >> 8) & 0x3)
+#define SS_MATCH_N(ss) (((u_int)(ss) >> 10) & 0x7ff)
+#define SS_OTHER_N(ss) (((u_int)(ss) >> 21) & 0x7ff)
+
+typedef u_int32 scan_state;
+
+struct LCPOS {
+ int nline;
+ int ncol;
+};
+
+/* Structure to hold a filename, file pointer and positional info.
+ * Instances are dynamically allocated, and the file name is copied by
+ * value into a dynamic extension of the 'fname' array. (Which *must* be
+ * the last field for that reason!)
+ */
+struct FILE_INFO {
+ struct FILE_INFO * st_next; /* next on stack */
+ FILE * fpi; /* File Descriptor */
+ int force_eof; /* locked or not */
+ int backch; /* ungetch buffer */
+
+ struct LCPOS curpos; /* current scan position */
+ struct LCPOS bakpos; /* last line end for ungetc */
+ struct LCPOS tokpos; /* current token position */
+ struct LCPOS errpos; /* error position */
+
+ char fname[1]; /* (formal only) buffered name */
+};
+
+
+/* SCANNER GLOBAL VARIABLES
+ * ------------------------
+ */
+extern config_tree cfgt; /* Parser output stored here */
+
+/* VARIOUS EXTERNAL DECLARATIONS
+ * -----------------------------
+ */
+extern int old_config_style;
+
+/* VARIOUS SUBROUTINE DECLARATIONS
+ * -------------------------------
+ */
+extern const char *keyword(int token);
+extern char *quote_if_needed(char *str);
+int yylex(void);
+
+/* managing the input source stack itself */
+extern int/*BOOL*/ lex_init_stack(const char * path, const char * mode);
+extern void lex_drop_stack(void);
+extern int/*BOOL*/ lex_flush_stack(void);
+
+/* add/remove a nested input source */
+extern int/*BOOL*/ lex_push_file(const char * path, const char * mode);
+extern int/*BOOL*/ lex_pop_file(void);
+
+/* input stack state query functions */
+extern size_t lex_level(void);
+extern int/*BOOL*/ lex_from_file(void);
+extern struct FILE_INFO * lex_current(void);
+
+#endif /* NTP_SCANNER_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_signd.c b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_signd.c
new file mode 100644
index 0000000..032706d
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_signd.c
@@ -0,0 +1,242 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/* Copyright 2008, Red Hat, Inc.
+ Copyright 2008, Andrew Tridgell.
+ Licenced under the same terms as NTP itself.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_NTP_SIGND
+
+#include "ntpd.h"
+#include "ntp_io.h"
+#include "ntp_stdlib.h"
+#include "ntp_unixtime.h"
+#include "ntp_control.h"
+#include "ntp_string.h"
+
+#include <stdio.h>
+#include <stddef.h>
+#ifdef HAVE_LIBSCF_H
+#include <libscf.h>
+#include <unistd.h>
+#endif /* HAVE_LIBSCF_H */
+
+#include <sys/un.h>
+
+/* socket routines by tridge - from junkcode.samba.org */
+
+/*
+ connect to a unix domain socket
+*/
+static int
+ux_socket_connect(const char *name)
+{
+ int fd;
+ struct sockaddr_un addr;
+ if (!name) {
+ return -1;
+ }
+
+ ZERO(addr);
+ addr.sun_family = AF_UNIX;
+ strlcpy(addr.sun_path, name, sizeof(addr.sun_path));
+
+ fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (fd == -1) {
+ return -1;
+ }
+
+ if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
+ close(fd);
+ return -1;
+ }
+
+ return fd;
+}
+
+
+/*
+ keep writing until its all sent
+*/
+static int
+write_all(int fd, const void *buf, size_t len)
+{
+ size_t total = 0;
+ while (len) {
+ int n = write(fd, buf, len);
+ if (n <= 0) return total;
+ buf = n + (const char *)buf;
+ len -= n;
+ total += n;
+ }
+ return total;
+}
+
+/*
+ keep reading until its all read
+*/
+static int
+read_all(int fd, void *buf, size_t len)
+{
+ size_t total = 0;
+ while (len) {
+ int n = read(fd, buf, len);
+ if (n <= 0) return total;
+ buf = n + (char *)buf;
+ len -= n;
+ total += n;
+ }
+ return total;
+}
+
+/*
+ send a packet in length prefix format
+*/
+static int
+send_packet(int fd, const char *buf, uint32_t len)
+{
+ uint32_t net_len = htonl(len);
+ if (write_all(fd, &net_len, sizeof(net_len)) != sizeof(net_len)) return -1;
+ if (write_all(fd, buf, len) != len) return -1;
+ return 0;
+}
+
+/*
+ receive a packet in length prefix format
+*/
+static int
+recv_packet(int fd, char **buf, uint32_t *len)
+{
+ if (read_all(fd, len, sizeof(*len)) != sizeof(*len)) return -1;
+ *len = ntohl(*len);
+ *buf = emalloc(*len);
+ if (read_all(fd, *buf, *len) != *len) {
+ free(*buf);
+ *buf = NULL;
+ return -1;
+ }
+ return 0;
+}
+
+void
+send_via_ntp_signd(
+ struct recvbuf *rbufp, /* receive packet pointer */
+ int xmode,
+ keyid_t xkeyid,
+ int flags,
+ struct pkt *xpkt
+ )
+{
+
+ /* We are here because it was detected that the client
+ * sent an all-zero signature, and we therefore know
+ * it's windows trying to talk to an AD server
+ *
+ * Because we don't want to dive into Samba's secrets
+ * database just to find the long-term kerberos key
+ * that is re-used as the NTP key, we instead hand the
+ * packet over to Samba to sign, and return to us.
+ *
+ * The signing method Samba will use is described by
+ * Microsoft in MS-SNTP, found here:
+ * http://msdn.microsoft.com/en-us/library/cc212930.aspx
+ */
+
+ int fd, sendlen;
+ struct samba_key_in {
+ uint32_t version;
+ uint32_t op;
+ uint32_t packet_id;
+ uint32_t key_id_le;
+ struct pkt pkt;
+ } samba_pkt;
+
+ struct samba_key_out {
+ uint32_t version;
+ uint32_t op;
+ uint32_t packet_id;
+ struct pkt pkt;
+ } samba_reply;
+
+ char full_socket[256];
+
+ char *reply = NULL;
+ uint32_t reply_len;
+
+ ZERO(samba_pkt);
+ samba_pkt.op = 0; /* Sign message */
+ /* This will be echoed into the reply - a different
+ * impelementation might want multiple packets
+ * awaiting signing */
+
+ samba_pkt.packet_id = 1;
+
+ /* Swap the byte order back - it's actually little
+ * endian on the wire, but it was read above as
+ * network byte order */
+ samba_pkt.key_id_le = htonl(xkeyid);
+ samba_pkt.pkt = *xpkt;
+
+ snprintf(full_socket, sizeof(full_socket), "%s/socket", ntp_signd_socket);
+
+ fd = ux_socket_connect(full_socket);
+ /* Only continue with this if we can talk to Samba */
+ if (fd != -1) {
+ /* Send old packet to Samba, expect response */
+ /* Packet to Samba is quite simple:
+ All values BIG endian except key ID as noted
+ [packet size as BE] - 4 bytes
+ [protocol version (0)] - 4 bytes
+ [packet ID] - 4 bytes
+ [operation (sign message=0)] - 4 bytes
+ [key id] - LITTLE endian (as on wire) - 4 bytes
+ [message to sign] - as marshalled, without signature
+ */
+
+ if (send_packet(fd, (char *)&samba_pkt, offsetof(struct samba_key_in, pkt) + LEN_PKT_NOMAC) != 0) {
+ /* Huh? could not talk to Samba... */
+ close(fd);
+ return;
+ }
+
+ if (recv_packet(fd, &reply, &reply_len) != 0) {
+ if (reply) {
+ free(reply);
+ }
+ close(fd);
+ return;
+ }
+ /* Return packet is also simple:
+ [packet size] - network byte order - 4 bytes
+ [protocol version (0)] network byte order - - 4 bytes
+ [operation (signed success=3, failure=4)] network byte order - - 4 byte
+ (optional) [signed message] - as provided before, with signature appended
+ */
+
+ if (reply_len <= sizeof(samba_reply)) {
+ memcpy(&samba_reply, reply, reply_len);
+ if (ntohl(samba_reply.op) == 3 && reply_len > offsetof(struct samba_key_out, pkt)) {
+ sendlen = reply_len - offsetof(struct samba_key_out, pkt);
+ xpkt = &samba_reply.pkt;
+ sendpkt(&rbufp->recv_srcadr, rbufp->dstadr, 0, xpkt, sendlen);
+#ifdef DEBUG
+ if (debug)
+ printf(
+ "transmit ntp_signd packet: at %ld %s->%s mode %d keyid %08x len %d\n",
+ current_time, ntoa(&rbufp->dstadr->sin),
+ ntoa(&rbufp->recv_srcadr), xmode, xkeyid, sendlen);
+#endif
+ }
+ }
+
+ if (reply) {
+ free(reply);
+ }
+ close(fd);
+
+ }
+}
+#endif
diff --git a/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_timer.c b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_timer.c
new file mode 100644
index 0000000..5ff18da
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_timer.c
@@ -0,0 +1,712 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * ntp_timer.c - event timer support routines
+ */
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "ntp_machine.h"
+#include "ntpd.h"
+#include "ntp_stdlib.h"
+#include "ntp_calendar.h"
+#include "ntp_leapsec.h"
+
+#if defined(HAVE_IO_COMPLETION_PORT)
+# include "ntp_iocompletionport.h"
+# include "ntp_timer.h"
+#endif
+
+#include <stdio.h>
+#include <signal.h>
+#ifdef HAVE_SYS_SIGNAL_H
+# include <sys/signal.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#ifdef KERNEL_PLL
+#include "ntp_syscall.h"
+#endif /* KERNEL_PLL */
+
+#ifdef AUTOKEY
+#include <openssl/rand.h>
+#endif /* AUTOKEY */
+
+
+/* TC_ERR represents the timer_create() error return value. */
+#ifdef SYS_VXWORKS
+#define TC_ERR ERROR
+#else
+#define TC_ERR (-1)
+#endif
+
+
+static void check_leapsec(u_int32, const time_t*, int/*BOOL*/);
+
+/*
+ * These routines provide support for the event timer. The timer is
+ * implemented by an interrupt routine which sets a flag once every
+ * second, and a timer routine which is called when the mainline code
+ * gets around to seeing the flag. The timer routine dispatches the
+ * clock adjustment code if its time has come, then searches the timer
+ * queue for expiries which are dispatched to the transmit procedure.
+ * Finally, we call the hourly procedure to do cleanup and print a
+ * message.
+ */
+volatile int interface_interval; /* init_io() sets def. 300s */
+
+/*
+ * Initializing flag. All async routines watch this and only do their
+ * thing when it is clear.
+ */
+int initializing;
+
+/*
+ * Alarm flag. The mainline code imports this.
+ */
+volatile int alarm_flag;
+
+/*
+ * The counters and timeouts
+ */
+static u_long interface_timer; /* interface update timer */
+static u_long adjust_timer; /* second timer */
+static u_long stats_timer; /* stats timer */
+static u_long leapf_timer; /* Report leapfile problems once/day */
+static u_long huffpuff_timer; /* huff-n'-puff timer */
+static u_long worker_idle_timer;/* next check for idle intres */
+u_long leapsec; /* seconds to next leap (proximity class) */
+int leapdif; /* TAI difference step at next leap second*/
+u_long orphwait; /* orphan wait time */
+#ifdef AUTOKEY
+static u_long revoke_timer; /* keys revoke timer */
+static u_long keys_timer; /* session key timer */
+u_char sys_revoke = KEY_REVOKE; /* keys revoke timeout (log2 s) */
+u_char sys_automax = NTP_AUTOMAX; /* key list timeout (log2 s) */
+#endif /* AUTOKEY */
+
+/*
+ * Statistics counter for the interested.
+ */
+volatile u_long alarm_overflow;
+
+u_long current_time; /* seconds since startup */
+
+/*
+ * Stats. Number of overflows and number of calls to transmit().
+ */
+u_long timer_timereset;
+u_long timer_overflows;
+u_long timer_xmtcalls;
+
+#if defined(VMS)
+static int vmstimer[2]; /* time for next timer AST */
+static int vmsinc[2]; /* timer increment */
+#endif /* VMS */
+
+#ifdef SYS_WINNT
+HANDLE WaitableTimerHandle;
+#else
+static RETSIGTYPE alarming (int);
+#endif /* SYS_WINNT */
+
+#if !defined(VMS)
+# if !defined SYS_WINNT || defined(SYS_CYGWIN32)
+# ifdef HAVE_TIMER_CREATE
+static timer_t timer_id;
+typedef struct itimerspec intervaltimer;
+# define itv_frac tv_nsec
+# else
+typedef struct itimerval intervaltimer;
+# define itv_frac tv_usec
+# endif
+intervaltimer itimer;
+# endif
+#endif
+
+#if !defined(SYS_WINNT) && !defined(VMS)
+void set_timer_or_die(const intervaltimer *);
+#endif
+
+
+#if !defined(SYS_WINNT) && !defined(VMS)
+void
+set_timer_or_die(
+ const intervaltimer * ptimer
+ )
+{
+ const char * setfunc;
+ int rc;
+
+# ifdef HAVE_TIMER_CREATE
+ setfunc = "timer_settime";
+ rc = timer_settime(timer_id, 0, &itimer, NULL);
+# else
+ setfunc = "setitimer";
+ rc = setitimer(ITIMER_REAL, &itimer, NULL);
+# endif
+ if (-1 == rc) {
+ msyslog(LOG_ERR, "interval timer %s failed, %m",
+ setfunc);
+ exit(1);
+ }
+}
+#endif /* !SYS_WINNT && !VMS */
+
+
+/*
+ * reinit_timer - reinitialize interval timer after a clock step.
+ */
+void
+reinit_timer(void)
+{
+#if !defined(SYS_WINNT) && !defined(VMS)
+ ZERO(itimer);
+# ifdef HAVE_TIMER_CREATE
+ timer_gettime(timer_id, &itimer);
+# else
+ getitimer(ITIMER_REAL, &itimer);
+# endif
+ if (itimer.it_value.tv_sec < 0 ||
+ itimer.it_value.tv_sec > (1 << EVENT_TIMEOUT))
+ itimer.it_value.tv_sec = (1 << EVENT_TIMEOUT);
+ if (itimer.it_value.itv_frac < 0)
+ itimer.it_value.itv_frac = 0;
+ if (0 == itimer.it_value.tv_sec &&
+ 0 == itimer.it_value.itv_frac)
+ itimer.it_value.tv_sec = (1 << EVENT_TIMEOUT);
+ itimer.it_interval.tv_sec = (1 << EVENT_TIMEOUT);
+ itimer.it_interval.itv_frac = 0;
+ set_timer_or_die(&itimer);
+# endif /* VMS */
+}
+
+
+/*
+ * init_timer - initialize the timer data structures
+ */
+void
+init_timer(void)
+{
+ /*
+ * Initialize...
+ */
+ alarm_flag = FALSE;
+ alarm_overflow = 0;
+ adjust_timer = 1;
+ stats_timer = SECSPERHR;
+ leapf_timer = SECSPERDAY;
+ huffpuff_timer = 0;
+ interface_timer = 0;
+ current_time = 0;
+ timer_overflows = 0;
+ timer_xmtcalls = 0;
+ timer_timereset = 0;
+
+#ifndef SYS_WINNT
+ /*
+ * Set up the alarm interrupt. The first comes 2**EVENT_TIMEOUT
+ * seconds from now and they continue on every 2**EVENT_TIMEOUT
+ * seconds.
+ */
+# ifndef VMS
+# ifdef HAVE_TIMER_CREATE
+ if (TC_ERR == timer_create(CLOCK_REALTIME, NULL, &timer_id)) {
+ msyslog(LOG_ERR, "timer_create failed, %m");
+ exit(1);
+ }
+# endif
+ signal_no_reset(SIGALRM, alarming);
+ itimer.it_interval.tv_sec =
+ itimer.it_value.tv_sec = (1 << EVENT_TIMEOUT);
+ itimer.it_interval.itv_frac = itimer.it_value.itv_frac = 0;
+ set_timer_or_die(&itimer);
+# else /* VMS follows */
+ vmsinc[0] = 10000000; /* 1 sec */
+ vmsinc[1] = 0;
+ lib$emul(&(1<<EVENT_TIMEOUT), &vmsinc, &0, &vmsinc);
+
+ sys$gettim(&vmstimer); /* that's "now" as abstime */
+
+ lib$addx(&vmsinc, &vmstimer, &vmstimer);
+ sys$setimr(0, &vmstimer, alarming, alarming, 0);
+# endif /* VMS */
+#else /* SYS_WINNT follows */
+ /*
+ * Set up timer interrupts for every 2**EVENT_TIMEOUT seconds
+ * Under Windows/NT,
+ */
+
+ WaitableTimerHandle = CreateWaitableTimer(NULL, FALSE, NULL);
+ if (WaitableTimerHandle == NULL) {
+ msyslog(LOG_ERR, "CreateWaitableTimer failed: %m");
+ exit(1);
+ }
+ else {
+ DWORD Period;
+ LARGE_INTEGER DueTime;
+ BOOL rc;
+
+ Period = (1 << EVENT_TIMEOUT) * 1000;
+ DueTime.QuadPart = Period * 10000i64;
+ rc = SetWaitableTimer(WaitableTimerHandle, &DueTime,
+ Period, NULL, NULL, FALSE);
+ if (!rc) {
+ msyslog(LOG_ERR, "SetWaitableTimer failed: %m");
+ exit(1);
+ }
+ }
+
+#endif /* SYS_WINNT */
+}
+
+
+/*
+ * intres_timeout_req(s) is invoked in the parent to schedule an idle
+ * timeout to fire in s seconds, if not reset earlier by a call to
+ * intres_timeout_req(0), which clears any pending timeout. When the
+ * timeout expires, worker_idle_timer_fired() is invoked (again, in the
+ * parent).
+ *
+ * sntp and ntpd each provide implementations adapted to their timers.
+ */
+void
+intres_timeout_req(
+ u_int seconds /* 0 cancels */
+ )
+{
+#if defined(HAVE_DROPROOT) && defined(NEED_EARLY_FORK)
+ if (droproot) {
+ worker_idle_timer = 0;
+ return;
+ }
+#endif
+ if (0 == seconds) {
+ worker_idle_timer = 0;
+ return;
+ }
+ worker_idle_timer = current_time + seconds;
+}
+
+
+/*
+ * timer - event timer
+ */
+void
+timer(void)
+{
+ struct peer * p;
+ struct peer * next_peer;
+ l_fp now;
+ time_t tnow;
+
+ /*
+ * The basic timerevent is one second. This is used to adjust the
+ * system clock in time and frequency, implement the kiss-o'-death
+ * function and the association polling function.
+ */
+ current_time++;
+ if (adjust_timer <= current_time) {
+ adjust_timer += 1;
+ adj_host_clock();
+#ifdef REFCLOCK
+ for (p = peer_list; p != NULL; p = next_peer) {
+ next_peer = p->p_link;
+ if (FLAG_REFCLOCK & p->flags)
+ refclock_timer(p);
+ }
+#endif /* REFCLOCK */
+ }
+
+ /*
+ * Now dispatch any peers whose event timer has expired. Be
+ * careful here, since the peer structure might go away as the
+ * result of the call.
+ */
+ for (p = peer_list; p != NULL; p = next_peer) {
+ next_peer = p->p_link;
+
+ /*
+ * Restrain the non-burst packet rate not more
+ * than one packet every 16 seconds. This is
+ * usually tripped using iburst and minpoll of
+ * 128 s or less.
+ */
+ if (p->throttle > 0)
+ p->throttle--;
+ if (p->nextdate <= current_time) {
+#ifdef REFCLOCK
+ if (FLAG_REFCLOCK & p->flags)
+ refclock_transmit(p);
+ else
+#endif /* REFCLOCK */
+ transmit(p);
+ }
+ }
+
+ /*
+ * Orphan mode is active when enabled and when no servers less
+ * than the orphan stratum are available. A server with no other
+ * synchronization source is an orphan. It shows offset zero and
+ * reference ID the loopback address.
+ */
+ if (sys_orphan < STRATUM_UNSPEC && sys_peer == NULL &&
+ current_time > orphwait) {
+ if (sys_leap == LEAP_NOTINSYNC) {
+ set_sys_leap(LEAP_NOWARNING);
+#ifdef AUTOKEY
+ if (crypto_flags)
+ crypto_update();
+#endif /* AUTOKEY */
+ }
+ sys_stratum = (u_char)sys_orphan;
+ if (sys_stratum > 1)
+ sys_refid = htonl(LOOPBACKADR);
+ else
+ memcpy(&sys_refid, "LOOP", 4);
+ sys_offset = 0;
+ sys_rootdelay = 0;
+ sys_rootdisp = 0;
+ }
+
+ get_systime(&now);
+ time(&tnow);
+
+ /*
+ * Leapseconds. Get time and defer to worker if either something
+ * is imminent or every 8th second.
+ */
+ if (leapsec > LSPROX_NOWARN || 0 == (current_time & 7))
+ check_leapsec(now.l_ui, &tnow,
+ (sys_leap == LEAP_NOTINSYNC));
+ if (sys_leap != LEAP_NOTINSYNC) {
+ if (leapsec >= LSPROX_ANNOUNCE && leapdif) {
+ if (leapdif > 0)
+ set_sys_leap(LEAP_ADDSECOND);
+ else
+ set_sys_leap(LEAP_DELSECOND);
+ } else {
+ set_sys_leap(LEAP_NOWARNING);
+ }
+ }
+
+ /*
+ * Update huff-n'-puff filter.
+ */
+ if (huffpuff_timer <= current_time) {
+ huffpuff_timer += HUFFPUFF;
+ huffpuff();
+ }
+
+#ifdef AUTOKEY
+ /*
+ * Garbage collect expired keys.
+ */
+ if (keys_timer <= current_time) {
+ keys_timer += (1UL << sys_automax);
+ auth_agekeys();
+ }
+
+ /*
+ * Generate new private value. This causes all associations
+ * to regenerate cookies.
+ */
+ if (revoke_timer && revoke_timer <= current_time) {
+ revoke_timer += (1UL << sys_revoke);
+ RAND_bytes((u_char *)&sys_private, 4);
+ }
+#endif /* AUTOKEY */
+
+ /*
+ * Interface update timer
+ */
+ if (interface_interval && interface_timer <= current_time) {
+ timer_interfacetimeout(current_time +
+ interface_interval);
+ DPRINTF(2, ("timer: interface update\n"));
+ interface_update(NULL, NULL);
+ }
+
+ if (worker_idle_timer && worker_idle_timer <= current_time)
+ worker_idle_timer_fired();
+
+ /*
+ * Finally, write hourly stats and do the hourly
+ * and daily leapfile checks.
+ */
+ if (stats_timer <= current_time) {
+ stats_timer += SECSPERHR;
+ write_stats();
+ if (leapf_timer <= current_time) {
+ leapf_timer += SECSPERDAY;
+ check_leap_file(TRUE, now.l_ui, &tnow);
+ } else {
+ check_leap_file(FALSE, now.l_ui, &tnow);
+ }
+ }
+}
+
+
+#ifndef SYS_WINNT
+/*
+ * alarming - tell the world we've been alarmed
+ */
+static RETSIGTYPE
+alarming(
+ int sig
+ )
+{
+# ifdef DEBUG
+ const char *msg = "alarming: initializing TRUE\n";
+# endif
+
+ if (!initializing) {
+ if (alarm_flag) {
+ alarm_overflow++;
+# ifdef DEBUG
+ msg = "alarming: overflow\n";
+# endif
+ } else {
+# ifndef VMS
+ alarm_flag++;
+# else
+ /* VMS AST routine, increment is no good */
+ alarm_flag = 1;
+# endif
+# ifdef DEBUG
+ msg = "alarming: normal\n";
+# endif
+ }
+ }
+# ifdef VMS
+ lib$addx(&vmsinc, &vmstimer, &vmstimer);
+ sys$setimr(0, &vmstimer, alarming, alarming, 0);
+# endif
+# ifdef DEBUG
+ if (debug >= 4)
+ (void)(-1 == write(1, msg, strlen(msg)));
+# endif
+}
+#endif /* SYS_WINNT */
+
+
+void
+timer_interfacetimeout(u_long timeout)
+{
+ interface_timer = timeout;
+}
+
+
+/*
+ * timer_clr_stats - clear timer module stat counters
+ */
+void
+timer_clr_stats(void)
+{
+ timer_overflows = 0;
+ timer_xmtcalls = 0;
+ timer_timereset = current_time;
+}
+
+
+static void
+check_leap_sec_in_progress( const leap_result_t *lsdata ) {
+ int prv_leap_sec_in_progress = leap_sec_in_progress;
+ leap_sec_in_progress = lsdata->tai_diff && (lsdata->ddist < 3);
+
+ /* if changed we may have to update the leap status sent to clients */
+ if (leap_sec_in_progress != prv_leap_sec_in_progress)
+ set_sys_leap(sys_leap);
+}
+
+
+static void
+check_leapsec(
+ u_int32 now ,
+ const time_t * tpiv ,
+ int/*BOOL*/ reset)
+{
+ static const char leapmsg_p_step[] =
+ "Positive leap second, stepped backward.";
+ static const char leapmsg_p_slew[] =
+ "Positive leap second, no step correction. "
+ "System clock will be inaccurate for a long time.";
+
+ static const char leapmsg_n_step[] =
+ "Negative leap second, stepped forward.";
+ static const char leapmsg_n_slew[] =
+ "Negative leap second, no step correction. "
+ "System clock will be inaccurate for a long time.";
+
+ leap_result_t lsdata;
+ u_int32 lsprox;
+#ifdef AUTOKEY
+ int/*BOOL*/ update_autokey = FALSE;
+#endif
+
+#ifndef SYS_WINNT /* WinNT port has its own leap second handling */
+# ifdef KERNEL_PLL
+ leapsec_electric(pll_control && kern_enable);
+# else
+ leapsec_electric(0);
+# endif
+#endif
+#ifdef LEAP_SMEAR
+ leap_smear.enabled = leap_smear_intv != 0;
+#endif
+ if (reset) {
+ lsprox = LSPROX_NOWARN;
+ leapsec_reset_frame();
+ memset(&lsdata, 0, sizeof(lsdata));
+ } else {
+ int fired;
+
+ fired = leapsec_query(&lsdata, now, tpiv);
+
+ DPRINTF(3, ("*** leapsec_query: fired %i, now %u (0x%08X), tai_diff %i, ddist %u\n",
+ fired, now, now, lsdata.tai_diff, lsdata.ddist));
+
+#ifdef LEAP_SMEAR
+ leap_smear.in_progress = 0;
+ leap_smear.doffset = 0.0;
+
+ if (leap_smear.enabled) {
+ if (lsdata.tai_diff) {
+ if (leap_smear.interval == 0) {
+ leap_smear.interval = leap_smear_intv;
+ leap_smear.intv_end = lsdata.ttime.Q_s;
+ leap_smear.intv_start = leap_smear.intv_end - leap_smear.interval;
+ DPRINTF(1, ("*** leapsec_query: setting leap_smear interval %li, begin %.0f, end %.0f\n",
+ leap_smear.interval, leap_smear.intv_start, leap_smear.intv_end));
+ }
+ } else {
+ if (leap_smear.interval)
+ DPRINTF(1, ("*** leapsec_query: clearing leap_smear interval\n"));
+ leap_smear.interval = 0;
+ }
+
+ if (leap_smear.interval) {
+ double dtemp = now;
+ if (dtemp >= leap_smear.intv_start && dtemp <= leap_smear.intv_end) {
+ double leap_smear_time = dtemp - leap_smear.intv_start;
+ /*
+ * For now we just do a linear interpolation over the smear interval
+ */
+#if 0
+ // linear interpolation
+ leap_smear.doffset = -(leap_smear_time * lsdata.tai_diff / leap_smear.interval);
+#else
+ // Google approach: lie(t) = (1.0 - cos(pi * t / w)) / 2.0
+ leap_smear.doffset = -((double) lsdata.tai_diff - cos( M_PI * leap_smear_time / leap_smear.interval)) / 2.0;
+#endif
+ /*
+ * TODO see if we're inside an inserted leap second, so we need to compute
+ * leap_smear.doffset = 1.0 - leap_smear.doffset
+ */
+ leap_smear.in_progress = 1;
+#if 0 && defined( DEBUG )
+ msyslog(LOG_NOTICE, "*** leapsec_query: [%.0f:%.0f] (%li), now %u (%.0f), smear offset %.6f ms\n",
+ leap_smear.intv_start, leap_smear.intv_end, leap_smear.interval,
+ now, leap_smear_time, leap_smear.doffset);
+#else
+ DPRINTF(1, ("*** leapsec_query: [%.0f:%.0f] (%li), now %u (%.0f), smear offset %.6f ms\n",
+ leap_smear.intv_start, leap_smear.intv_end, leap_smear.interval,
+ now, leap_smear_time, leap_smear.doffset));
+#endif
+
+ }
+ }
+ }
+ else
+ leap_smear.interval = 0;
+
+ /*
+ * Update the current leap smear offset, eventually 0.0 if outside smear interval.
+ */
+ DTOLFP(leap_smear.doffset, &leap_smear.offset);
+
+#endif /* LEAP_SMEAR */
+
+ if (fired) {
+ /* Full hit. Eventually step the clock, but always
+ * announce the leap event has happened.
+ */
+ const char *leapmsg = NULL;
+ double lswarp = lsdata.warped;
+ if (lswarp < 0.0) {
+ if (clock_max_back > 0.0 &&
+ clock_max_back < -lswarp) {
+ step_systime(lswarp);
+ leapmsg = leapmsg_p_step;
+ } else {
+ leapmsg = leapmsg_p_slew;
+ }
+ } else if (lswarp > 0.0) {
+ if (clock_max_fwd > 0.0 &&
+ clock_max_fwd < lswarp) {
+ step_systime(lswarp);
+ leapmsg = leapmsg_n_step;
+ } else {
+ leapmsg = leapmsg_n_slew;
+ }
+ }
+ if (leapmsg)
+ msyslog(LOG_NOTICE, "%s", leapmsg);
+ report_event(EVNT_LEAP, NULL, NULL);
+#ifdef AUTOKEY
+ update_autokey = TRUE;
+#endif
+ lsprox = LSPROX_NOWARN;
+ leapsec = LSPROX_NOWARN;
+ sys_tai = lsdata.tai_offs;
+ } else {
+#ifdef AUTOKEY
+ update_autokey = (sys_tai != (u_int)lsdata.tai_offs);
+#endif
+ lsprox = lsdata.proximity;
+ sys_tai = lsdata.tai_offs;
+ }
+ }
+
+ /* We guard against panic alarming during the red alert phase.
+ * Strange and evil things might happen if we go from stone cold
+ * to piping hot in one step. If things are already that wobbly,
+ * we let the normal clock correction take over, even if a jump
+ * is involved.
+ * Also make sure the alarming events are edge-triggered, that is,
+ * ceated only when the threshold is crossed.
+ */
+ if ( (leapsec > 0 || lsprox < LSPROX_ALERT)
+ && leapsec < lsprox ) {
+ if ( leapsec < LSPROX_SCHEDULE
+ && lsprox >= LSPROX_SCHEDULE) {
+ if (lsdata.dynamic)
+ report_event(PEVNT_ARMED, sys_peer, NULL);
+ else
+ report_event(EVNT_ARMED, NULL, NULL);
+ }
+ leapsec = lsprox;
+ }
+ if (leapsec > lsprox) {
+ if ( leapsec >= LSPROX_SCHEDULE
+ && lsprox < LSPROX_SCHEDULE) {
+ report_event(EVNT_DISARMED, NULL, NULL);
+ }
+ leapsec = lsprox;
+ }
+
+ if (leapsec >= LSPROX_SCHEDULE)
+ leapdif = lsdata.tai_diff;
+ else
+ leapdif = 0;
+
+ check_leap_sec_in_progress(&lsdata);
+
+#ifdef AUTOKEY
+ if (update_autokey)
+ crypto_update_taichange();
+#endif
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_util.c b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_util.c
new file mode 100644
index 0000000..a999c20
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/ntpd/ntp_util.c
@@ -0,0 +1,1047 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * ntp_util.c - stuff I didn't have any other place for
+ */
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "ntpd.h"
+#include "ntp_unixtime.h"
+#include "ntp_filegen.h"
+#include "ntp_if.h"
+#include "ntp_stdlib.h"
+#include "ntp_assert.h"
+#include "ntp_calendar.h"
+#include "ntp_leapsec.h"
+#include "lib_strbuf.h"
+
+#include <stdio.h>
+#include <ctype.h>
+#include <sys/types.h>
+#ifdef HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#include <sys/stat.h>
+
+#ifdef HAVE_IEEEFP_H
+# include <ieeefp.h>
+#endif
+#ifdef HAVE_MATH_H
+# include <math.h>
+#endif
+
+#if defined(VMS)
+# include <descrip.h>
+#endif /* VMS */
+
+/*
+ * Defines used by the leapseconds stuff
+ */
+#define MAX_TAI 100 /* max TAI offset (s) */
+#define L_DAY 86400UL /* seconds per day */
+#define L_YEAR (L_DAY * 365) /* days per year */
+#define L_LYEAR (L_YEAR + L_DAY) /* days per leap year */
+#define L_4YEAR (L_LYEAR + 3 * L_YEAR) /* days per leap cycle */
+#define L_CENT (L_4YEAR * 25) /* days per century */
+
+/*
+ * This contains odds and ends, including the hourly stats, various
+ * configuration items, leapseconds stuff, etc.
+ */
+/*
+ * File names
+ */
+static char *key_file_name; /* keys file name */
+static char *leapfile_name; /* leapseconds file name */
+static struct stat leapfile_stat; /* leapseconds file stat() buffer */
+static int /*BOOL*/have_leapfile = FALSE;
+char *stats_drift_file; /* frequency file name */
+static char *stats_temp_file; /* temp frequency file name */
+static double wander_resid; /* last frequency update */
+double wander_threshold = 1e-7; /* initial frequency threshold */
+
+/*
+ * Statistics file stuff
+ */
+#ifndef NTP_VAR
+# ifndef SYS_WINNT
+# define NTP_VAR "/var/NTP/" /* NOTE the trailing '/' */
+# else
+# define NTP_VAR "c:\\var\\ntp\\" /* NOTE the trailing '\\' */
+# endif /* SYS_WINNT */
+#endif
+
+
+char statsdir[MAXFILENAME] = NTP_VAR;
+static FILEGEN peerstats;
+static FILEGEN loopstats;
+static FILEGEN clockstats;
+static FILEGEN rawstats;
+static FILEGEN sysstats;
+static FILEGEN protostats;
+static FILEGEN cryptostats;
+static FILEGEN timingstats;
+
+/*
+ * This controls whether stats are written to the fileset. Provided
+ * so that ntpdc can turn off stats when the file system fills up.
+ */
+int stats_control;
+
+/*
+ * Last frequency written to file.
+ */
+static double prev_drift_comp; /* last frequency update */
+
+/*
+ * Function prototypes
+ */
+static void record_sys_stats(void);
+ void ntpd_time_stepped(void);
+static void check_leap_expiration(int, uint32_t, const time_t*);
+
+/*
+ * Prototypes
+ */
+#ifdef DEBUG
+void uninit_util(void);
+#endif
+
+/*
+ * uninit_util - free memory allocated by init_util
+ */
+#ifdef DEBUG
+void
+uninit_util(void)
+{
+#if defined(_MSC_VER) && defined (_DEBUG)
+ _CrtCheckMemory();
+#endif
+ if (stats_drift_file) {
+ free(stats_drift_file);
+ free(stats_temp_file);
+ stats_drift_file = NULL;
+ stats_temp_file = NULL;
+ }
+ if (key_file_name) {
+ free(key_file_name);
+ key_file_name = NULL;
+ }
+ filegen_unregister("peerstats");
+ filegen_unregister("loopstats");
+ filegen_unregister("clockstats");
+ filegen_unregister("rawstats");
+ filegen_unregister("sysstats");
+ filegen_unregister("protostats");
+#ifdef AUTOKEY
+ filegen_unregister("cryptostats");
+#endif /* AUTOKEY */
+#ifdef DEBUG_TIMING
+ filegen_unregister("timingstats");
+#endif /* DEBUG_TIMING */
+
+#if defined(_MSC_VER) && defined (_DEBUG)
+ _CrtCheckMemory();
+#endif
+}
+#endif /* DEBUG */
+
+
+/*
+ * init_util - initialize the util module of ntpd
+ */
+void
+init_util(void)
+{
+ filegen_register(statsdir, "peerstats", &peerstats);
+ filegen_register(statsdir, "loopstats", &loopstats);
+ filegen_register(statsdir, "clockstats", &clockstats);
+ filegen_register(statsdir, "rawstats", &rawstats);
+ filegen_register(statsdir, "sysstats", &sysstats);
+ filegen_register(statsdir, "protostats", &protostats);
+ filegen_register(statsdir, "cryptostats", &cryptostats);
+ filegen_register(statsdir, "timingstats", &timingstats);
+ /*
+ * register with libntp ntp_set_tod() to call us back
+ * when time is stepped.
+ */
+ step_callback = &ntpd_time_stepped;
+#ifdef DEBUG
+ atexit(&uninit_util);
+#endif /* DEBUG */
+}
+
+
+/*
+ * hourly_stats - print some interesting stats
+ */
+void
+write_stats(void)
+{
+ FILE *fp;
+#ifdef DOSYNCTODR
+ struct timeval tv;
+#if !defined(VMS)
+ int prio_set;
+#endif
+#ifdef HAVE_GETCLOCK
+ struct timespec ts;
+#endif
+ int o_prio;
+
+ /*
+ * Sometimes having a Sun can be a drag.
+ *
+ * The kernel variable dosynctodr controls whether the system's
+ * soft clock is kept in sync with the battery clock. If it
+ * is zero, then the soft clock is not synced, and the battery
+ * clock is simply left to rot. That means that when the system
+ * reboots, the battery clock (which has probably gone wacky)
+ * sets the soft clock. That means ntpd starts off with a very
+ * confused idea of what time it is. It then takes a large
+ * amount of time to figure out just how wacky the battery clock
+ * has made things drift, etc, etc. The solution is to make the
+ * battery clock sync up to system time. The way to do THAT is
+ * to simply set the time of day to the current time of day, but
+ * as quickly as possible. This may, or may not be a sensible
+ * thing to do.
+ *
+ * CAVEAT: settimeofday() steps the sun clock by about 800 us,
+ * so setting DOSYNCTODR seems a bad idea in the
+ * case of us resolution
+ */
+
+#if !defined(VMS)
+ /*
+ * (prr) getpriority returns -1 on error, but -1 is also a valid
+ * return value (!), so instead we have to zero errno before the
+ * call and check it for non-zero afterwards.
+ */
+ errno = 0;
+ prio_set = 0;
+ o_prio = getpriority(PRIO_PROCESS,0); /* Save setting */
+
+ /*
+ * (prr) if getpriority succeeded, call setpriority to raise
+ * scheduling priority as high as possible. If that succeeds
+ * as well, set the prio_set flag so we remember to reset
+ * priority to its previous value below. Note that on Solaris
+ * 2.6 (and beyond?), both getpriority and setpriority will fail
+ * with ESRCH, because sched_setscheduler (called from main) put
+ * us in the real-time scheduling class which setpriority
+ * doesn't know about. Being in the real-time class is better
+ * than anything setpriority can do, anyhow, so this error is
+ * silently ignored.
+ */
+ if ((errno == 0) && (setpriority(PRIO_PROCESS,0,-20) == 0))
+ prio_set = 1; /* overdrive */
+#endif /* VMS */
+#ifdef HAVE_GETCLOCK
+ (void) getclock(TIMEOFDAY, &ts);
+ tv.tv_sec = ts.tv_sec;
+ tv.tv_usec = ts.tv_nsec / 1000;
+#else /* not HAVE_GETCLOCK */
+ GETTIMEOFDAY(&tv,(struct timezone *)NULL);
+#endif /* not HAVE_GETCLOCK */
+ if (ntp_set_tod(&tv,(struct timezone *)NULL) != 0)
+ msyslog(LOG_ERR, "can't sync battery time: %m");
+#if !defined(VMS)
+ if (prio_set)
+ setpriority(PRIO_PROCESS, 0, o_prio); /* downshift */
+#endif /* VMS */
+#endif /* DOSYNCTODR */
+ record_sys_stats();
+ if (stats_drift_file != 0) {
+
+ /*
+ * When the frequency file is written, initialize the
+ * prev_drift_comp and wander_resid. Thereafter,
+ * reduce the wander_resid by half each hour. When
+ * the difference between the prev_drift_comp and
+ * drift_comp is less than the wander_resid, update
+ * the frequncy file. This minimizes the file writes to
+ * nonvolaile storage.
+ */
+#ifdef DEBUG
+ if (debug)
+ printf("write_stats: frequency %.6lf thresh %.6lf, freq %.6lf\n",
+ (prev_drift_comp - drift_comp) * 1e6, wander_resid *
+ 1e6, drift_comp * 1e6);
+#endif
+ if (fabs(prev_drift_comp - drift_comp) < wander_resid) {
+ wander_resid *= 0.5;
+ return;
+ }
+ prev_drift_comp = drift_comp;
+ wander_resid = wander_threshold;
+ if ((fp = fopen(stats_temp_file, "w")) == NULL) {
+ msyslog(LOG_ERR, "frequency file %s: %m",
+ stats_temp_file);
+ return;
+ }
+ fprintf(fp, "%.3f\n", drift_comp * 1e6);
+ (void)fclose(fp);
+ /* atomic */
+#ifdef SYS_WINNT
+ if (_unlink(stats_drift_file)) /* rename semantics differ under NT */
+ msyslog(LOG_WARNING,
+ "Unable to remove prior drift file %s, %m",
+ stats_drift_file);
+#endif /* SYS_WINNT */
+
+#ifndef NO_RENAME
+ if (rename(stats_temp_file, stats_drift_file))
+ msyslog(LOG_WARNING,
+ "Unable to rename temp drift file %s to %s, %m",
+ stats_temp_file, stats_drift_file);
+#else
+ /* we have no rename NFS of ftp in use */
+ if ((fp = fopen(stats_drift_file, "w")) ==
+ NULL) {
+ msyslog(LOG_ERR,
+ "frequency file %s: %m",
+ stats_drift_file);
+ return;
+ }
+#endif
+
+#if defined(VMS)
+ /* PURGE */
+ {
+ $DESCRIPTOR(oldvers,";-1");
+ struct dsc$descriptor driftdsc = {
+ strlen(stats_drift_file), 0, 0,
+ stats_drift_file };
+ while(lib$delete_file(&oldvers,
+ &driftdsc) & 1);
+ }
+#endif
+ }
+}
+
+
+/*
+ * stats_config - configure the stats operation
+ */
+void
+stats_config(
+ int item,
+ const char *invalue /* only one type so far */
+ )
+{
+ FILE *fp;
+ const char *value;
+ size_t len;
+ double old_drift;
+ l_fp now;
+ time_t ttnow;
+#ifndef VMS
+ const char temp_ext[] = ".TEMP";
+#else
+ const char temp_ext[] = "-TEMP";
+#endif
+
+ /*
+ * Expand environment strings under Windows NT, since the
+ * command interpreter doesn't do this, the program must.
+ */
+#ifdef SYS_WINNT
+ char newvalue[MAX_PATH], parameter[MAX_PATH];
+
+ if (!ExpandEnvironmentStrings(invalue, newvalue, MAX_PATH)) {
+ switch (item) {
+ case STATS_FREQ_FILE:
+ strlcpy(parameter, "STATS_FREQ_FILE",
+ sizeof(parameter));
+ break;
+
+ case STATS_LEAP_FILE:
+ strlcpy(parameter, "STATS_LEAP_FILE",
+ sizeof(parameter));
+ break;
+
+ case STATS_STATSDIR:
+ strlcpy(parameter, "STATS_STATSDIR",
+ sizeof(parameter));
+ break;
+
+ case STATS_PID_FILE:
+ strlcpy(parameter, "STATS_PID_FILE",
+ sizeof(parameter));
+ break;
+
+ default:
+ strlcpy(parameter, "UNKNOWN",
+ sizeof(parameter));
+ break;
+ }
+ value = invalue;
+ msyslog(LOG_ERR,
+ "ExpandEnvironmentStrings(%s) failed: %m\n",
+ parameter);
+ } else {
+ value = newvalue;
+ }
+#else
+ value = invalue;
+#endif /* SYS_WINNT */
+
+ switch (item) {
+
+ /*
+ * Open and read frequency file.
+ */
+ case STATS_FREQ_FILE:
+ if (!value || (len = strlen(value)) == 0)
+ break;
+
+ stats_drift_file = erealloc(stats_drift_file, len + 1);
+ stats_temp_file = erealloc(stats_temp_file,
+ len + sizeof(".TEMP"));
+ memcpy(stats_drift_file, value, (size_t)(len+1));
+ memcpy(stats_temp_file, value, (size_t)len);
+ memcpy(stats_temp_file + len, temp_ext, sizeof(temp_ext));
+
+ /*
+ * Open drift file and read frequency. If the file is
+ * missing or contains errors, tell the loop to reset.
+ */
+ if ((fp = fopen(stats_drift_file, "r")) == NULL)
+ break;
+
+ if (fscanf(fp, "%lf", &old_drift) != 1) {
+ msyslog(LOG_ERR,
+ "format error frequency file %s",
+ stats_drift_file);
+ fclose(fp);
+ break;
+
+ }
+ fclose(fp);
+ loop_config(LOOP_FREQ, old_drift);
+ prev_drift_comp = drift_comp;
+ break;
+
+ /*
+ * Specify statistics directory.
+ */
+ case STATS_STATSDIR:
+
+ /* - 1 since value may be missing the DIR_SEP. */
+ if (strlen(value) >= sizeof(statsdir) - 1) {
+ msyslog(LOG_ERR,
+ "statsdir too long (>%d, sigh)",
+ (int)sizeof(statsdir) - 2);
+ } else {
+ int add_dir_sep;
+ size_t value_l;
+
+ /* Add a DIR_SEP unless we already have one. */
+ value_l = strlen(value);
+ if (0 == value_l)
+ add_dir_sep = FALSE;
+ else
+ add_dir_sep = (DIR_SEP !=
+ value[value_l - 1]);
+
+ if (add_dir_sep)
+ snprintf(statsdir, sizeof(statsdir),
+ "%s%c", value, DIR_SEP);
+ else
+ snprintf(statsdir, sizeof(statsdir),
+ "%s", value);
+ filegen_statsdir();
+ }
+ break;
+
+ /*
+ * Open pid file.
+ */
+ case STATS_PID_FILE:
+ if ((fp = fopen(value, "w")) == NULL) {
+ msyslog(LOG_ERR, "pid file %s: %m",
+ value);
+ break;
+ }
+ fprintf(fp, "%d", (int)getpid());
+ fclose(fp);
+ break;
+
+ /*
+ * Read leapseconds file.
+ *
+ * Note: Currently a leap file without SHA1 signature is
+ * accepted, but if there is a signature line, the signature
+ * must be valid or the file is rejected.
+ */
+ case STATS_LEAP_FILE:
+ if (!value || (len = strlen(value)) == 0)
+ break;
+
+ leapfile_name = erealloc(leapfile_name, len + 1);
+ memcpy(leapfile_name, value, len + 1);
+
+ if (leapsec_load_file(
+ leapfile_name, &leapfile_stat, TRUE, TRUE))
+ {
+ leap_signature_t lsig;
+
+ get_systime(&now);
+ time(&ttnow);
+ leapsec_getsig(&lsig);
+ mprintf_event(EVNT_TAI, NULL,
+ "%d leap %s %s %s",
+ lsig.taiof,
+ fstostr(lsig.ttime),
+ leapsec_expired(now.l_ui, NULL)
+ ? "expired"
+ : "expires",
+ fstostr(lsig.etime));
+
+ have_leapfile = TRUE;
+
+ /* force an immediate daily expiration check of
+ * the leap seconds table
+ */
+ check_leap_expiration(TRUE, now.l_ui, &ttnow);
+ }
+ break;
+
+ default:
+ /* oh well */
+ break;
+ }
+}
+
+
+/*
+ * record_peer_stats - write peer statistics to file
+ *
+ * file format:
+ * day (MJD)
+ * time (s past UTC midnight)
+ * IP address
+ * status word (hex)
+ * offset
+ * delay
+ * dispersion
+ * jitter
+*/
+void
+record_peer_stats(
+ sockaddr_u *addr,
+ int status,
+ double offset, /* offset */
+ double delay, /* delay */
+ double dispersion, /* dispersion */
+ double jitter /* jitter */
+ )
+{
+ l_fp now;
+ u_long day;
+
+ if (!stats_control)
+ return;
+
+ get_systime(&now);
+ filegen_setup(&peerstats, now.l_ui);
+ day = now.l_ui / 86400 + MJD_1900;
+ now.l_ui %= 86400;
+ if (peerstats.fp != NULL) {
+ fprintf(peerstats.fp,
+ "%lu %s %s %x %.9f %.9f %.9f %.9f\n", day,
+ ulfptoa(&now, 3), stoa(addr), status, offset,
+ delay, dispersion, jitter);
+ fflush(peerstats.fp);
+ }
+}
+
+
+/*
+ * record_loop_stats - write loop filter statistics to file
+ *
+ * file format:
+ * day (MJD)
+ * time (s past midnight)
+ * offset
+ * frequency (PPM)
+ * jitter
+ * wnder (PPM)
+ * time constant (log2)
+ */
+void
+record_loop_stats(
+ double offset, /* offset */
+ double freq, /* frequency (PPM) */
+ double jitter, /* jitter */
+ double wander, /* wander (PPM) */
+ int spoll
+ )
+{
+ l_fp now;
+ u_long day;
+
+ if (!stats_control)
+ return;
+
+ get_systime(&now);
+ filegen_setup(&loopstats, now.l_ui);
+ day = now.l_ui / 86400 + MJD_1900;
+ now.l_ui %= 86400;
+ if (loopstats.fp != NULL) {
+ fprintf(loopstats.fp, "%lu %s %.9f %.3f %.9f %.6f %d\n",
+ day, ulfptoa(&now, 3), offset, freq * 1e6, jitter,
+ wander * 1e6, spoll);
+ fflush(loopstats.fp);
+ }
+}
+
+
+/*
+ * record_clock_stats - write clock statistics to file
+ *
+ * file format:
+ * day (MJD)
+ * time (s past midnight)
+ * IP address
+ * text message
+ */
+void
+record_clock_stats(
+ sockaddr_u *addr,
+ const char *text /* timecode string */
+ )
+{
+ l_fp now;
+ u_long day;
+
+ if (!stats_control)
+ return;
+
+ get_systime(&now);
+ filegen_setup(&clockstats, now.l_ui);
+ day = now.l_ui / 86400 + MJD_1900;
+ now.l_ui %= 86400;
+ if (clockstats.fp != NULL) {
+ fprintf(clockstats.fp, "%lu %s %s %s\n", day,
+ ulfptoa(&now, 3), stoa(addr), text);
+ fflush(clockstats.fp);
+ }
+}
+
+
+/*
+ * mprintf_clock_stats - write clock statistics to file with
+ * msnprintf-style formatting.
+ */
+int
+mprintf_clock_stats(
+ sockaddr_u *addr,
+ const char *fmt,
+ ...
+ )
+{
+ va_list ap;
+ int rc;
+ char msg[512];
+
+ va_start(ap, fmt);
+ rc = mvsnprintf(msg, sizeof(msg), fmt, ap);
+ va_end(ap);
+ if (stats_control)
+ record_clock_stats(addr, msg);
+
+ return rc;
+}
+
+/*
+ * record_raw_stats - write raw timestamps to file
+ *
+ * file format
+ * day (MJD)
+ * time (s past midnight)
+ * peer ip address
+ * IP address
+ * t1 t2 t3 t4 timestamps
+ * leap, version, mode, stratum, ppoll, precision, root delay, root dispersion, REFID
+ * length and hex dump of any EFs and any legacy MAC.
+ */
+void
+record_raw_stats(
+ sockaddr_u *srcadr,
+ sockaddr_u *dstadr,
+ l_fp *t1, /* originate timestamp */
+ l_fp *t2, /* receive timestamp */
+ l_fp *t3, /* transmit timestamp */
+ l_fp *t4, /* destination timestamp */
+ int leap,
+ int version,
+ int mode,
+ int stratum,
+ int ppoll,
+ int precision,
+ double root_delay, /* seconds */
+ double root_dispersion,/* seconds */
+ u_int32 refid,
+ int len,
+ u_char *extra
+ )
+{
+ l_fp now;
+ u_long day;
+
+ if (!stats_control)
+ return;
+
+ get_systime(&now);
+ filegen_setup(&rawstats, now.l_ui);
+ day = now.l_ui / 86400 + MJD_1900;
+ now.l_ui %= 86400;
+ if (rawstats.fp != NULL) {
+ fprintf(rawstats.fp, "%lu %s %s %s %s %s %s %s %d %d %d %d %d %d %.6f %.6f %s",
+ day, ulfptoa(&now, 3),
+ srcadr ? stoa(srcadr) : "-",
+ dstadr ? stoa(dstadr) : "-",
+ ulfptoa(t1, 9), ulfptoa(t2, 9),
+ ulfptoa(t3, 9), ulfptoa(t4, 9),
+ leap, version, mode, stratum, ppoll, precision,
+ root_delay, root_dispersion, refid_str(refid, stratum));
+ if (len > 0) {
+ int i;
+
+ fprintf(rawstats.fp, " %d: ", len);
+ for (i = 0; i < len; ++i) {
+ fprintf(rawstats.fp, "%02x", extra[i]);
+ }
+ }
+ fprintf(rawstats.fp, "\n");
+ fflush(rawstats.fp);
+ }
+}
+
+
+/*
+ * record_sys_stats - write system statistics to file
+ *
+ * file format
+ * day (MJD)
+ * time (s past midnight)
+ * time since reset
+ * packets recieved
+ * packets for this host
+ * current version
+ * old version
+ * access denied
+ * bad length or format
+ * bad authentication
+ * declined
+ * rate exceeded
+ * KoD sent
+ */
+void
+record_sys_stats(void)
+{
+ l_fp now;
+ u_long day;
+
+ if (!stats_control)
+ return;
+
+ get_systime(&now);
+ filegen_setup(&sysstats, now.l_ui);
+ day = now.l_ui / 86400 + MJD_1900;
+ now.l_ui %= 86400;
+ if (sysstats.fp != NULL) {
+ fprintf(sysstats.fp,
+ "%lu %s %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu\n",
+ day, ulfptoa(&now, 3), current_time - sys_stattime,
+ sys_received, sys_processed, sys_newversion,
+ sys_oldversion, sys_restricted, sys_badlength,
+ sys_badauth, sys_declined, sys_limitrejected,
+ sys_kodsent);
+ fflush(sysstats.fp);
+ proto_clr_stats();
+ }
+}
+
+
+/*
+ * record_proto_stats - write system statistics to file
+ *
+ * file format
+ * day (MJD)
+ * time (s past midnight)
+ * text message
+ */
+void
+record_proto_stats(
+ char *str /* text string */
+ )
+{
+ l_fp now;
+ u_long day;
+
+ if (!stats_control)
+ return;
+
+ get_systime(&now);
+ filegen_setup(&protostats, now.l_ui);
+ day = now.l_ui / 86400 + MJD_1900;
+ now.l_ui %= 86400;
+ if (protostats.fp != NULL) {
+ fprintf(protostats.fp, "%lu %s %s\n", day,
+ ulfptoa(&now, 3), str);
+ fflush(protostats.fp);
+ }
+}
+
+
+#ifdef AUTOKEY
+/*
+ * record_crypto_stats - write crypto statistics to file
+ *
+ * file format:
+ * day (mjd)
+ * time (s past midnight)
+ * peer ip address
+ * text message
+ */
+void
+record_crypto_stats(
+ sockaddr_u *addr,
+ const char *text /* text message */
+ )
+{
+ l_fp now;
+ u_long day;
+
+ if (!stats_control)
+ return;
+
+ get_systime(&now);
+ filegen_setup(&cryptostats, now.l_ui);
+ day = now.l_ui / 86400 + MJD_1900;
+ now.l_ui %= 86400;
+ if (cryptostats.fp != NULL) {
+ if (addr == NULL)
+ fprintf(cryptostats.fp, "%lu %s 0.0.0.0 %s\n",
+ day, ulfptoa(&now, 3), text);
+ else
+ fprintf(cryptostats.fp, "%lu %s %s %s\n",
+ day, ulfptoa(&now, 3), stoa(addr), text);
+ fflush(cryptostats.fp);
+ }
+}
+#endif /* AUTOKEY */
+
+
+#ifdef DEBUG_TIMING
+/*
+ * record_timing_stats - write timing statistics to file
+ *
+ * file format:
+ * day (mjd)
+ * time (s past midnight)
+ * text message
+ */
+void
+record_timing_stats(
+ const char *text /* text message */
+ )
+{
+ static unsigned int flshcnt;
+ l_fp now;
+ u_long day;
+
+ if (!stats_control)
+ return;
+
+ get_systime(&now);
+ filegen_setup(&timingstats, now.l_ui);
+ day = now.l_ui / 86400 + MJD_1900;
+ now.l_ui %= 86400;
+ if (timingstats.fp != NULL) {
+ fprintf(timingstats.fp, "%lu %s %s\n", day, lfptoa(&now,
+ 3), text);
+ if (++flshcnt % 100 == 0)
+ fflush(timingstats.fp);
+ }
+}
+#endif
+
+
+/*
+ * check_leap_file - See if the leapseconds file has been updated.
+ *
+ * Returns: n/a
+ *
+ * Note: This loads a new leapfile on the fly. Currently a leap file
+ * without SHA1 signature is accepted, but if there is a signature line,
+ * the signature must be valid or the file is rejected.
+ */
+void
+check_leap_file(
+ int is_daily_check,
+ uint32_t ntptime ,
+ const time_t *systime
+ )
+{
+ /* just do nothing if there is no leap file */
+ if ( ! (leapfile_name && *leapfile_name))
+ return;
+
+ /* try to load leapfile, force it if no leapfile loaded yet */
+ if (leapsec_load_file(
+ leapfile_name, &leapfile_stat,
+ !have_leapfile, is_daily_check))
+ have_leapfile = TRUE;
+ else if (!have_leapfile)
+ return;
+
+ check_leap_expiration(is_daily_check, ntptime, systime);
+}
+
+/*
+ * check expiration of a loaded leap table
+ */
+static void
+check_leap_expiration(
+ int is_daily_check,
+ uint32_t ntptime ,
+ const time_t *systime
+ )
+{
+ static const char * const logPrefix = "leapsecond file";
+ int rc;
+
+ /* test the expiration of the leap data and log with proper
+ * level and frequency (once/hour or once/day, depending on the
+ * state.
+ */
+ rc = leapsec_daystolive(ntptime, systime);
+ if (rc == 0) {
+ msyslog(LOG_WARNING,
+ "%s ('%s'): will expire in less than one day",
+ logPrefix, leapfile_name);
+ } else if (is_daily_check && rc < 28) {
+ if (rc < 0)
+ msyslog(LOG_ERR,
+ "%s ('%s'): expired less than %d day%s ago",
+ logPrefix, leapfile_name, -rc, (rc == -1 ? "" : "s"));
+ else
+ msyslog(LOG_WARNING,
+ "%s ('%s'): will expire in less than %d days",
+ logPrefix, leapfile_name, 1+rc);
+ }
+}
+
+
+/*
+ * getauthkeys - read the authentication keys from the specified file
+ */
+void
+getauthkeys(
+ const char *keyfile
+ )
+{
+ size_t len;
+
+ len = strlen(keyfile);
+ if (!len)
+ return;
+
+#ifndef SYS_WINNT
+ key_file_name = erealloc(key_file_name, len + 1);
+ memcpy(key_file_name, keyfile, len + 1);
+#else
+ key_file_name = erealloc(key_file_name, _MAX_PATH);
+ if (len + 1 > _MAX_PATH)
+ return;
+ if (!ExpandEnvironmentStrings(keyfile, key_file_name,
+ _MAX_PATH)) {
+ msyslog(LOG_ERR,
+ "ExpandEnvironmentStrings(KEY_FILE) failed: %m");
+ strlcpy(key_file_name, keyfile, _MAX_PATH);
+ }
+ key_file_name = erealloc(key_file_name,
+ 1 + strlen(key_file_name));
+#endif /* SYS_WINNT */
+
+ authreadkeys(key_file_name);
+}
+
+
+/*
+ * rereadkeys - read the authentication key file over again.
+ */
+void
+rereadkeys(void)
+{
+ if (NULL != key_file_name)
+ authreadkeys(key_file_name);
+}
+
+
+#if notyet
+/*
+ * ntp_exit - document explicitly that ntpd has exited
+ */
+void
+ntp_exit(int retval)
+{
+ msyslog(LOG_ERR, "EXITING with return code %d", retval);
+ exit(retval);
+}
+#endif
+
+/*
+ * fstostr - prettyprint NTP seconds
+ */
+char * fstostr(
+ time_t ntp_stamp
+ )
+{
+ char * buf;
+ struct calendar tm;
+
+ LIB_GETBUF(buf);
+ if (ntpcal_ntp_to_date(&tm, (u_int32)ntp_stamp, NULL) < 0)
+ snprintf(buf, LIB_BUFLENGTH, "ntpcal_ntp_to_date: %ld: range error",
+ (long)ntp_stamp);
+ else
+ snprintf(buf, LIB_BUFLENGTH, "%04d%02d%02d%02d%02d",
+ tm.year, tm.month, tm.monthday,
+ tm.hour, tm.minute);
+ return buf;
+}
+
+
+/*
+ * ntpd_time_stepped is called back by step_systime(), allowing ntpd
+ * to do any one-time processing necessitated by the step.
+ */
+void
+ntpd_time_stepped(void)
+{
+ u_int saved_mon_enabled;
+
+ /*
+ * flush the monitor MRU list which contains l_fp timestamps
+ * which should not be compared across the step.
+ */
+ if (MON_OFF != mon_enabled) {
+ saved_mon_enabled = mon_enabled;
+ mon_stop(MON_OFF);
+ mon_start(saved_mon_enabled);
+ }
+
+ /* inform interpolating Windows code to allow time to go back */
+#ifdef SYS_WINNT
+ win_time_stepped();
+#endif
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/ntpd/ntpd-opts.c b/sebhbsd/freebsd/contrib/ntp/ntpd/ntpd-opts.c
new file mode 100644
index 0000000..95f22d4
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/ntpd/ntpd-opts.c
@@ -0,0 +1,1986 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * EDIT THIS FILE WITH CAUTION (ntpd-opts.c)
+ *
+ * It has been AutoGen-ed February 20, 2019 at 09:56:15 AM by AutoGen 5.18.5
+ * From the definitions ntpd-opts.def
+ * and the template file options
+ *
+ * Generated from AutoOpts 41:1:16 templates.
+ *
+ * AutoOpts is a copyrighted work. This source file is not encumbered
+ * by AutoOpts licensing, but is provided under the licensing terms chosen
+ * by the ntpd author or copyright holder. AutoOpts is
+ * licensed under the terms of the LGPL. The redistributable library
+ * (``libopts'') is licensed under the terms of either the LGPL or, at the
+ * users discretion, the BSD license. See the AutoOpts and/or libopts sources
+ * for details.
+ *
+ * The ntpd program is copyrighted and licensed
+ * under the following terms:
+ *
+ * Copyright (C) 1992-2017 The University of Delaware and Network Time Foundation, all rights reserved.
+ * This is free software. It is licensed for use, modification and
+ * redistribution under the terms of the NTP License, copies of which
+ * can be seen at:
+ * <http://ntp.org/license>
+ * <http://opensource.org/licenses/ntp-license.php>
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose with or without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and that
+ * both the copyright notice and this permission notice appear in
+ * supporting documentation, and that the name The University of Delaware not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. The University of Delaware and Network Time Foundation makes no
+ * representations about the suitability this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ */
+
+#ifndef __doxygen__
+#define OPTION_CODE_COMPILE 1
+#include "ntpd-opts.h"
+#include <sys/types.h>
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern FILE * option_usage_fp;
+#define zCopyright (ntpd_opt_strs+0)
+#define zLicenseDescrip (ntpd_opt_strs+341)
+
+/*
+ * global included definitions
+ */
+#ifdef __windows
+ extern int atoi(const char *);
+#else
+# include <stdlib.h>
+#endif
+
+#ifdef __windows
+ extern int atoi(const char*);
+#else
+# include <stdlib.h>
+#endif
+
+#ifndef NULL
+# define NULL 0
+#endif
+
+/**
+ * static const strings for ntpd options
+ */
+static char const ntpd_opt_strs[3132] =
+/* 0 */ "ntpd 4.2.8p13\n"
+ "Copyright (C) 1992-2017 The University of Delaware and Network Time Foundation, all rights reserved.\n"
+ "This is free software. It is licensed for use, modification and\n"
+ "redistribution under the terms of the NTP License, copies of which\n"
+ "can be seen at:\n"
+ " <http://ntp.org/license>\n"
+ " <http://opensource.org/licenses/ntp-license.php>\n\0"
+/* 341 */ "Permission to use, copy, modify, and distribute this software and its\n"
+ "documentation for any purpose with or without fee is hereby granted,\n"
+ "provided that the above copyright notice appears in all copies and that\n"
+ "both the copyright notice and this permission notice appear in supporting\n"
+ "documentation, and that the name The University of Delaware not be used in\n"
+ "advertising or publicity pertaining to distribution of the software without\n"
+ "specific, written prior permission. The University of Delaware and Network\n"
+ "Time Foundation makes no representations about the suitability this\n"
+ "software for any purpose. It is provided \"as is\" without express or\n"
+ "implied warranty.\n\0"
+/* 1009 */ "Force IPv4 DNS name resolution\0"
+/* 1040 */ "IPV4\0"
+/* 1045 */ "ipv4\0"
+/* 1050 */ "Force IPv6 DNS name resolution\0"
+/* 1081 */ "IPV6\0"
+/* 1086 */ "ipv6\0"
+/* 1091 */ "Require crypto authentication\0"
+/* 1121 */ "AUTHREQ\0"
+/* 1129 */ "authreq\0"
+/* 1137 */ "Do not require crypto authentication\0"
+/* 1174 */ "AUTHNOREQ\0"
+/* 1184 */ "authnoreq\0"
+/* 1194 */ "Allow us to sync to broadcast servers\0"
+/* 1232 */ "BCASTSYNC\0"
+/* 1242 */ "bcastsync\0"
+/* 1252 */ "configuration file name\0"
+/* 1276 */ "CONFIGFILE\0"
+/* 1287 */ "configfile\0"
+/* 1298 */ "Increase debug verbosity level\0"
+/* 1329 */ "DEBUG_LEVEL\0"
+/* 1341 */ "debug-level\0"
+/* 1353 */ "Set the debug verbosity level\0"
+/* 1383 */ "SET_DEBUG_LEVEL\0"
+/* 1399 */ "set-debug-level\0"
+/* 1415 */ "frequency drift file name\0"
+/* 1441 */ "DRIFTFILE\0"
+/* 1451 */ "driftfile\0"
+/* 1461 */ "Allow the first adjustment to be Big\0"
+/* 1498 */ "PANICGATE\0"
+/* 1508 */ "panicgate\0"
+/* 1518 */ "Step any initial offset correction.\0"
+/* 1554 */ "FORCE_STEP_ONCE\0"
+/* 1570 */ "force-step-once\0"
+/* 1586 */ "Jail directory\0"
+/* 1601 */ "JAILDIR\0"
+/* 1609 */ "jaildir\0"
+/* 1617 */ "built without --enable-clockctl or --enable-linuxcaps or --enable-solarisprivs\0"
+/* 1696 */ "Listen on an interface name or address\0"
+/* 1735 */ "INTERFACE\0"
+/* 1745 */ "interface\0"
+/* 1755 */ "path to symmetric keys\0"
+/* 1778 */ "KEYFILE\0"
+/* 1786 */ "keyfile\0"
+/* 1794 */ "path to the log file\0"
+/* 1815 */ "LOGFILE\0"
+/* 1823 */ "logfile\0"
+/* 1831 */ "Do not listen to virtual interfaces\0"
+/* 1867 */ "NOVIRTUALIPS\0"
+/* 1880 */ "novirtualips\0"
+/* 1893 */ "Modify Multimedia Timer (Windows only)\0"
+/* 1932 */ "MODIFYMMTIMER\0"
+/* 1946 */ "modifymmtimer\0"
+/* 1960 */ "Do not fork\0"
+/* 1972 */ "NOFORK\0"
+/* 1979 */ "nofork\0"
+/* 1986 */ "Run at high priority\0"
+/* 2007 */ "NICE\0"
+/* 2012 */ "nice\0"
+/* 2017 */ "path to the PID file\0"
+/* 2038 */ "PIDFILE\0"
+/* 2046 */ "pidfile\0"
+/* 2054 */ "Process priority\0"
+/* 2071 */ "PRIORITY\0"
+/* 2080 */ "priority\0"
+/* 2089 */ "Set the time and quit\0"
+/* 2111 */ "QUIT\0"
+/* 2116 */ "quit\0"
+/* 2121 */ "Broadcast/propagation delay\0"
+/* 2149 */ "PROPAGATIONDELAY\0"
+/* 2166 */ "propagationdelay\0"
+/* 2183 */ "Save parsed configuration and quit\0"
+/* 2218 */ "SAVECONFIGQUIT\0"
+/* 2233 */ "saveconfigquit\0"
+/* 2248 */ "Statistics file location\0"
+/* 2273 */ "STATSDIR\0"
+/* 2282 */ "statsdir\0"
+/* 2291 */ "Trusted key number\0"
+/* 2310 */ "TRUSTEDKEY\0"
+/* 2321 */ "trustedkey\0"
+/* 2332 */ "Run as userid (or userid:groupid)\0"
+/* 2366 */ "USER\0"
+/* 2371 */ "user\0"
+/* 2376 */ "interval in seconds between scans for new or dropped interfaces\0"
+/* 2440 */ "UPDATEINTERVAL\0"
+/* 2455 */ "updateinterval\0"
+/* 2470 */ "make ARG an ntp variable (RW)\0"
+/* 2500 */ "VAR\0"
+/* 2504 */ "var\0"
+/* 2508 */ "make ARG an ntp variable (RW|DEF)\0"
+/* 2542 */ "DVAR\0"
+/* 2547 */ "dvar\0"
+/* 2552 */ "Seconds to wait for first clock sync\0"
+/* 2589 */ "WAIT_SYNC\0"
+/* 2599 */ "wait-sync\0"
+/* 2609 */ "Slew up to 600 seconds\0"
+/* 2632 */ "SLEW\0"
+/* 2637 */ "slew\0"
+/* 2642 */ "Use CPU cycle counter (Windows only)\0"
+/* 2679 */ "USEPCC\0"
+/* 2686 */ "usepcc\0"
+/* 2693 */ "Force CPU cycle counter use (Windows only)\0"
+/* 2736 */ "PCCFREQ\0"
+/* 2744 */ "pccfreq\0"
+/* 2752 */ "Register with mDNS as a NTP server\0"
+/* 2787 */ "MDNS\0"
+/* 2792 */ "mdns\0"
+/* 2797 */ "display extended usage information and exit\0"
+/* 2841 */ "help\0"
+/* 2846 */ "extended usage information passed thru pager\0"
+/* 2891 */ "more-help\0"
+/* 2901 */ "output version information and exit\0"
+/* 2937 */ "version\0"
+/* 2945 */ "NTPD\0"
+/* 2950 */ "ntpd - NTP daemon program - Ver. 4.2.8p13\n"
+ "Usage: %s [ -<flag> [<val>] | --<name>[{=| }<val>] ]... \\\n"
+ "\t\t[ <server1> ... <serverN> ]\n\0"
+/* 3082 */ "http://bugs.ntp.org, bugs@ntp.org\0"
+/* 3116 */ "\n\0"
+/* 3118 */ "ntpd 4.2.8p13";
+
+/**
+ * ipv4 option description with
+ * "Must also have options" and "Incompatible options":
+ */
+/** Descriptive text for the ipv4 option */
+#define IPV4_DESC (ntpd_opt_strs+1009)
+/** Upper-cased name for the ipv4 option */
+#define IPV4_NAME (ntpd_opt_strs+1040)
+/** Name string for the ipv4 option */
+#define IPV4_name (ntpd_opt_strs+1045)
+/** Other options that appear in conjunction with the ipv4 option */
+static int const aIpv4CantList[] = {
+ INDEX_OPT_IPV6, NO_EQUIVALENT };
+/** Compiled in flag settings for the ipv4 option */
+#define IPV4_FLAGS (OPTST_DISABLED)
+
+/**
+ * ipv6 option description with
+ * "Must also have options" and "Incompatible options":
+ */
+/** Descriptive text for the ipv6 option */
+#define IPV6_DESC (ntpd_opt_strs+1050)
+/** Upper-cased name for the ipv6 option */
+#define IPV6_NAME (ntpd_opt_strs+1081)
+/** Name string for the ipv6 option */
+#define IPV6_name (ntpd_opt_strs+1086)
+/** Other options that appear in conjunction with the ipv6 option */
+static int const aIpv6CantList[] = {
+ INDEX_OPT_IPV4, NO_EQUIVALENT };
+/** Compiled in flag settings for the ipv6 option */
+#define IPV6_FLAGS (OPTST_DISABLED)
+
+/**
+ * authreq option description with
+ * "Must also have options" and "Incompatible options":
+ */
+/** Descriptive text for the authreq option */
+#define AUTHREQ_DESC (ntpd_opt_strs+1091)
+/** Upper-cased name for the authreq option */
+#define AUTHREQ_NAME (ntpd_opt_strs+1121)
+/** Name string for the authreq option */
+#define AUTHREQ_name (ntpd_opt_strs+1129)
+/** Other options that appear in conjunction with the authreq option */
+static int const aAuthreqCantList[] = {
+ INDEX_OPT_AUTHNOREQ, NO_EQUIVALENT };
+/** Compiled in flag settings for the authreq option */
+#define AUTHREQ_FLAGS (OPTST_DISABLED)
+
+/**
+ * authnoreq option description with
+ * "Must also have options" and "Incompatible options":
+ */
+/** Descriptive text for the authnoreq option */
+#define AUTHNOREQ_DESC (ntpd_opt_strs+1137)
+/** Upper-cased name for the authnoreq option */
+#define AUTHNOREQ_NAME (ntpd_opt_strs+1174)
+/** Name string for the authnoreq option */
+#define AUTHNOREQ_name (ntpd_opt_strs+1184)
+/** Other options that appear in conjunction with the authnoreq option */
+static int const aAuthnoreqCantList[] = {
+ INDEX_OPT_AUTHREQ, NO_EQUIVALENT };
+/** Compiled in flag settings for the authnoreq option */
+#define AUTHNOREQ_FLAGS (OPTST_DISABLED)
+
+/**
+ * bcastsync option description:
+ */
+/** Descriptive text for the bcastsync option */
+#define BCASTSYNC_DESC (ntpd_opt_strs+1194)
+/** Upper-cased name for the bcastsync option */
+#define BCASTSYNC_NAME (ntpd_opt_strs+1232)
+/** Name string for the bcastsync option */
+#define BCASTSYNC_name (ntpd_opt_strs+1242)
+/** Compiled in flag settings for the bcastsync option */
+#define BCASTSYNC_FLAGS (OPTST_DISABLED)
+
+/**
+ * configfile option description:
+ */
+/** Descriptive text for the configfile option */
+#define CONFIGFILE_DESC (ntpd_opt_strs+1252)
+/** Upper-cased name for the configfile option */
+#define CONFIGFILE_NAME (ntpd_opt_strs+1276)
+/** Name string for the configfile option */
+#define CONFIGFILE_name (ntpd_opt_strs+1287)
+/** Compiled in flag settings for the configfile option */
+#define CONFIGFILE_FLAGS (OPTST_DISABLED \
+ | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
+
+/**
+ * debug-level option description:
+ */
+/** Descriptive text for the debug-level option */
+#define DEBUG_LEVEL_DESC (ntpd_opt_strs+1298)
+/** Upper-cased name for the debug-level option */
+#define DEBUG_LEVEL_NAME (ntpd_opt_strs+1329)
+/** Name string for the debug-level option */
+#define DEBUG_LEVEL_name (ntpd_opt_strs+1341)
+/** Compiled in flag settings for the debug-level option */
+#define DEBUG_LEVEL_FLAGS (OPTST_DISABLED)
+
+/**
+ * set-debug-level option description:
+ */
+/** Descriptive text for the set-debug-level option */
+#define SET_DEBUG_LEVEL_DESC (ntpd_opt_strs+1353)
+/** Upper-cased name for the set-debug-level option */
+#define SET_DEBUG_LEVEL_NAME (ntpd_opt_strs+1383)
+/** Name string for the set-debug-level option */
+#define SET_DEBUG_LEVEL_name (ntpd_opt_strs+1399)
+/** Compiled in flag settings for the set-debug-level option */
+#define SET_DEBUG_LEVEL_FLAGS (OPTST_DISABLED \
+ | OPTST_SET_ARGTYPE(OPARG_TYPE_NUMERIC))
+
+/**
+ * driftfile option description:
+ */
+/** Descriptive text for the driftfile option */
+#define DRIFTFILE_DESC (ntpd_opt_strs+1415)
+/** Upper-cased name for the driftfile option */
+#define DRIFTFILE_NAME (ntpd_opt_strs+1441)
+/** Name string for the driftfile option */
+#define DRIFTFILE_name (ntpd_opt_strs+1451)
+/** Compiled in flag settings for the driftfile option */
+#define DRIFTFILE_FLAGS (OPTST_DISABLED \
+ | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
+
+/**
+ * panicgate option description:
+ */
+/** Descriptive text for the panicgate option */
+#define PANICGATE_DESC (ntpd_opt_strs+1461)
+/** Upper-cased name for the panicgate option */
+#define PANICGATE_NAME (ntpd_opt_strs+1498)
+/** Name string for the panicgate option */
+#define PANICGATE_name (ntpd_opt_strs+1508)
+/** Compiled in flag settings for the panicgate option */
+#define PANICGATE_FLAGS (OPTST_DISABLED)
+
+/**
+ * force_step_once option description:
+ */
+/** Descriptive text for the force_step_once option */
+#define FORCE_STEP_ONCE_DESC (ntpd_opt_strs+1518)
+/** Upper-cased name for the force_step_once option */
+#define FORCE_STEP_ONCE_NAME (ntpd_opt_strs+1554)
+/** Name string for the force_step_once option */
+#define FORCE_STEP_ONCE_name (ntpd_opt_strs+1570)
+/** Compiled in flag settings for the force_step_once option */
+#define FORCE_STEP_ONCE_FLAGS (OPTST_DISABLED)
+
+/**
+ * jaildir option description:
+ */
+#ifdef HAVE_DROPROOT
+/** Descriptive text for the jaildir option */
+#define JAILDIR_DESC (ntpd_opt_strs+1586)
+/** Upper-cased name for the jaildir option */
+#define JAILDIR_NAME (ntpd_opt_strs+1601)
+/** Name string for the jaildir option */
+#define JAILDIR_name (ntpd_opt_strs+1609)
+/** Compiled in flag settings for the jaildir option */
+#define JAILDIR_FLAGS (OPTST_DISABLED \
+ | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
+
+#else /* disable jaildir */
+#define JAILDIR_FLAGS (OPTST_OMITTED | OPTST_NO_INIT)
+#define JAILDIR_NAME NULL
+/** Descriptive text for the jaildir option */
+#define JAILDIR_DESC (ntpd_opt_strs+1617)
+#define JAILDIR_name (ntpd_opt_strs+1609)
+#endif /* HAVE_DROPROOT */
+
+/**
+ * interface option description:
+ */
+/** Descriptive text for the interface option */
+#define INTERFACE_DESC (ntpd_opt_strs+1696)
+/** Upper-cased name for the interface option */
+#define INTERFACE_NAME (ntpd_opt_strs+1735)
+/** Name string for the interface option */
+#define INTERFACE_name (ntpd_opt_strs+1745)
+/** Compiled in flag settings for the interface option */
+#define INTERFACE_FLAGS (OPTST_DISABLED | OPTST_STACKED \
+ | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
+
+/**
+ * keyfile option description:
+ */
+/** Descriptive text for the keyfile option */
+#define KEYFILE_DESC (ntpd_opt_strs+1755)
+/** Upper-cased name for the keyfile option */
+#define KEYFILE_NAME (ntpd_opt_strs+1778)
+/** Name string for the keyfile option */
+#define KEYFILE_name (ntpd_opt_strs+1786)
+/** Compiled in flag settings for the keyfile option */
+#define KEYFILE_FLAGS (OPTST_DISABLED \
+ | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
+
+/**
+ * logfile option description:
+ */
+/** Descriptive text for the logfile option */
+#define LOGFILE_DESC (ntpd_opt_strs+1794)
+/** Upper-cased name for the logfile option */
+#define LOGFILE_NAME (ntpd_opt_strs+1815)
+/** Name string for the logfile option */
+#define LOGFILE_name (ntpd_opt_strs+1823)
+/** Compiled in flag settings for the logfile option */
+#define LOGFILE_FLAGS (OPTST_DISABLED \
+ | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
+
+/**
+ * novirtualips option description:
+ */
+/** Descriptive text for the novirtualips option */
+#define NOVIRTUALIPS_DESC (ntpd_opt_strs+1831)
+/** Upper-cased name for the novirtualips option */
+#define NOVIRTUALIPS_NAME (ntpd_opt_strs+1867)
+/** Name string for the novirtualips option */
+#define NOVIRTUALIPS_name (ntpd_opt_strs+1880)
+/** Compiled in flag settings for the novirtualips option */
+#define NOVIRTUALIPS_FLAGS (OPTST_DISABLED)
+
+/**
+ * modifymmtimer option description:
+ */
+#ifdef SYS_WINNT
+/** Descriptive text for the modifymmtimer option */
+#define MODIFYMMTIMER_DESC (ntpd_opt_strs+1893)
+/** Upper-cased name for the modifymmtimer option */
+#define MODIFYMMTIMER_NAME (ntpd_opt_strs+1932)
+/** Name string for the modifymmtimer option */
+#define MODIFYMMTIMER_name (ntpd_opt_strs+1946)
+/** Compiled in flag settings for the modifymmtimer option */
+#define MODIFYMMTIMER_FLAGS (OPTST_DISABLED)
+
+#else /* disable modifymmtimer */
+#define MODIFYMMTIMER_FLAGS (OPTST_OMITTED | OPTST_NO_INIT)
+#define MODIFYMMTIMER_NAME NULL
+#define MODIFYMMTIMER_DESC NULL
+#define MODIFYMMTIMER_name NULL
+#endif /* SYS_WINNT */
+
+/**
+ * nofork option description with
+ * "Must also have options" and "Incompatible options":
+ */
+/** Descriptive text for the nofork option */
+#define NOFORK_DESC (ntpd_opt_strs+1960)
+/** Upper-cased name for the nofork option */
+#define NOFORK_NAME (ntpd_opt_strs+1972)
+/** Name string for the nofork option */
+#define NOFORK_name (ntpd_opt_strs+1979)
+/** Other options that appear in conjunction with the nofork option */
+static int const aNoforkCantList[] = {
+ INDEX_OPT_WAIT_SYNC, NO_EQUIVALENT };
+/** Compiled in flag settings for the nofork option */
+#define NOFORK_FLAGS (OPTST_DISABLED)
+
+/**
+ * nice option description:
+ */
+/** Descriptive text for the nice option */
+#define NICE_DESC (ntpd_opt_strs+1986)
+/** Upper-cased name for the nice option */
+#define NICE_NAME (ntpd_opt_strs+2007)
+/** Name string for the nice option */
+#define NICE_name (ntpd_opt_strs+2012)
+/** Compiled in flag settings for the nice option */
+#define NICE_FLAGS (OPTST_DISABLED)
+
+/**
+ * pidfile option description:
+ */
+/** Descriptive text for the pidfile option */
+#define PIDFILE_DESC (ntpd_opt_strs+2017)
+/** Upper-cased name for the pidfile option */
+#define PIDFILE_NAME (ntpd_opt_strs+2038)
+/** Name string for the pidfile option */
+#define PIDFILE_name (ntpd_opt_strs+2046)
+/** Compiled in flag settings for the pidfile option */
+#define PIDFILE_FLAGS (OPTST_DISABLED \
+ | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
+
+/**
+ * priority option description:
+ */
+/** Descriptive text for the priority option */
+#define PRIORITY_DESC (ntpd_opt_strs+2054)
+/** Upper-cased name for the priority option */
+#define PRIORITY_NAME (ntpd_opt_strs+2071)
+/** Name string for the priority option */
+#define PRIORITY_name (ntpd_opt_strs+2080)
+/** Compiled in flag settings for the priority option */
+#define PRIORITY_FLAGS (OPTST_DISABLED \
+ | OPTST_SET_ARGTYPE(OPARG_TYPE_NUMERIC))
+
+/**
+ * quit option description with
+ * "Must also have options" and "Incompatible options":
+ */
+/** Descriptive text for the quit option */
+#define QUIT_DESC (ntpd_opt_strs+2089)
+/** Upper-cased name for the quit option */
+#define QUIT_NAME (ntpd_opt_strs+2111)
+/** Name string for the quit option */
+#define QUIT_name (ntpd_opt_strs+2116)
+/** Other options that appear in conjunction with the quit option */
+static int const aQuitCantList[] = {
+ INDEX_OPT_SAVECONFIGQUIT,
+ INDEX_OPT_WAIT_SYNC, NO_EQUIVALENT };
+/** Compiled in flag settings for the quit option */
+#define QUIT_FLAGS (OPTST_DISABLED)
+
+/**
+ * propagationdelay option description:
+ */
+/** Descriptive text for the propagationdelay option */
+#define PROPAGATIONDELAY_DESC (ntpd_opt_strs+2121)
+/** Upper-cased name for the propagationdelay option */
+#define PROPAGATIONDELAY_NAME (ntpd_opt_strs+2149)
+/** Name string for the propagationdelay option */
+#define PROPAGATIONDELAY_name (ntpd_opt_strs+2166)
+/** Compiled in flag settings for the propagationdelay option */
+#define PROPAGATIONDELAY_FLAGS (OPTST_DISABLED \
+ | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
+
+/**
+ * saveconfigquit option description with
+ * "Must also have options" and "Incompatible options":
+ */
+#ifdef SAVECONFIG
+/** Descriptive text for the saveconfigquit option */
+#define SAVECONFIGQUIT_DESC (ntpd_opt_strs+2183)
+/** Upper-cased name for the saveconfigquit option */
+#define SAVECONFIGQUIT_NAME (ntpd_opt_strs+2218)
+/** Name string for the saveconfigquit option */
+#define SAVECONFIGQUIT_name (ntpd_opt_strs+2233)
+/** Other options that appear in conjunction with the saveconfigquit option */
+static int const aSaveconfigquitCantList[] = {
+ INDEX_OPT_QUIT,
+ INDEX_OPT_WAIT_SYNC, NO_EQUIVALENT };
+/** Compiled in flag settings for the saveconfigquit option */
+#define SAVECONFIGQUIT_FLAGS (OPTST_DISABLED \
+ | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
+
+#else /* disable saveconfigquit */
+#define SAVECONFIGQUIT_FLAGS (OPTST_OMITTED | OPTST_NO_INIT)
+#define aSaveconfigquitCantList NULL
+#define SAVECONFIGQUIT_NAME NULL
+#define SAVECONFIGQUIT_DESC NULL
+#define SAVECONFIGQUIT_name NULL
+#endif /* SAVECONFIG */
+
+/**
+ * statsdir option description:
+ */
+/** Descriptive text for the statsdir option */
+#define STATSDIR_DESC (ntpd_opt_strs+2248)
+/** Upper-cased name for the statsdir option */
+#define STATSDIR_NAME (ntpd_opt_strs+2273)
+/** Name string for the statsdir option */
+#define STATSDIR_name (ntpd_opt_strs+2282)
+/** Compiled in flag settings for the statsdir option */
+#define STATSDIR_FLAGS (OPTST_DISABLED \
+ | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
+
+/**
+ * trustedkey option description:
+ */
+/** Descriptive text for the trustedkey option */
+#define TRUSTEDKEY_DESC (ntpd_opt_strs+2291)
+/** Upper-cased name for the trustedkey option */
+#define TRUSTEDKEY_NAME (ntpd_opt_strs+2310)
+/** Name string for the trustedkey option */
+#define TRUSTEDKEY_name (ntpd_opt_strs+2321)
+/** Compiled in flag settings for the trustedkey option */
+#define TRUSTEDKEY_FLAGS (OPTST_DISABLED | OPTST_STACKED \
+ | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
+
+/**
+ * user option description:
+ */
+#ifdef HAVE_DROPROOT
+/** Descriptive text for the user option */
+#define USER_DESC (ntpd_opt_strs+2332)
+/** Upper-cased name for the user option */
+#define USER_NAME (ntpd_opt_strs+2366)
+/** Name string for the user option */
+#define USER_name (ntpd_opt_strs+2371)
+/** Compiled in flag settings for the user option */
+#define USER_FLAGS (OPTST_DISABLED \
+ | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
+
+#else /* disable user */
+#define USER_FLAGS (OPTST_OMITTED | OPTST_NO_INIT)
+#define USER_NAME NULL
+/** Descriptive text for the user option */
+#define USER_DESC (ntpd_opt_strs+1617)
+#define USER_name (ntpd_opt_strs+2371)
+#endif /* HAVE_DROPROOT */
+
+/**
+ * updateinterval option description:
+ */
+/** Descriptive text for the updateinterval option */
+#define UPDATEINTERVAL_DESC (ntpd_opt_strs+2376)
+/** Upper-cased name for the updateinterval option */
+#define UPDATEINTERVAL_NAME (ntpd_opt_strs+2440)
+/** Name string for the updateinterval option */
+#define UPDATEINTERVAL_name (ntpd_opt_strs+2455)
+/** Compiled in flag settings for the updateinterval option */
+#define UPDATEINTERVAL_FLAGS (OPTST_DISABLED \
+ | OPTST_SET_ARGTYPE(OPARG_TYPE_NUMERIC))
+
+/**
+ * var option description:
+ */
+/** Descriptive text for the var option */
+#define VAR_DESC (ntpd_opt_strs+2470)
+/** Upper-cased name for the var option */
+#define VAR_NAME (ntpd_opt_strs+2500)
+/** Name string for the var option */
+#define VAR_name (ntpd_opt_strs+2504)
+/** Compiled in flag settings for the var option */
+#define VAR_FLAGS (OPTST_DISABLED | OPTST_STACKED \
+ | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
+
+/**
+ * dvar option description:
+ */
+/** Descriptive text for the dvar option */
+#define DVAR_DESC (ntpd_opt_strs+2508)
+/** Upper-cased name for the dvar option */
+#define DVAR_NAME (ntpd_opt_strs+2542)
+/** Name string for the dvar option */
+#define DVAR_name (ntpd_opt_strs+2547)
+/** Compiled in flag settings for the dvar option */
+#define DVAR_FLAGS (OPTST_DISABLED | OPTST_STACKED \
+ | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
+
+/**
+ * wait-sync option description with
+ * "Must also have options" and "Incompatible options":
+ */
+#ifdef HAVE_WORKING_FORK
+/** Descriptive text for the wait-sync option */
+#define WAIT_SYNC_DESC (ntpd_opt_strs+2552)
+/** Upper-cased name for the wait-sync option */
+#define WAIT_SYNC_NAME (ntpd_opt_strs+2589)
+/** Name string for the wait-sync option */
+#define WAIT_SYNC_name (ntpd_opt_strs+2599)
+/** Other options that appear in conjunction with the wait-sync option */
+static int const aWait_SyncCantList[] = {
+ INDEX_OPT_NOFORK,
+ INDEX_OPT_QUIT,
+ INDEX_OPT_SAVECONFIGQUIT, NO_EQUIVALENT };
+/** Compiled in flag settings for the wait-sync option */
+#define WAIT_SYNC_FLAGS (OPTST_DISABLED \
+ | OPTST_SET_ARGTYPE(OPARG_TYPE_NUMERIC))
+
+#else /* disable wait-sync */
+#define WAIT_SYNC_FLAGS (OPTST_OMITTED | OPTST_NO_INIT)
+#define aWait_SyncCantList NULL
+#define WAIT_SYNC_NAME NULL
+#define WAIT_SYNC_DESC NULL
+#define WAIT_SYNC_name NULL
+#endif /* HAVE_WORKING_FORK */
+
+/**
+ * slew option description:
+ */
+/** Descriptive text for the slew option */
+#define SLEW_DESC (ntpd_opt_strs+2609)
+/** Upper-cased name for the slew option */
+#define SLEW_NAME (ntpd_opt_strs+2632)
+/** Name string for the slew option */
+#define SLEW_name (ntpd_opt_strs+2637)
+/** Compiled in flag settings for the slew option */
+#define SLEW_FLAGS (OPTST_DISABLED)
+
+/**
+ * usepcc option description:
+ */
+#ifdef SYS_WINNT
+/** Descriptive text for the usepcc option */
+#define USEPCC_DESC (ntpd_opt_strs+2642)
+/** Upper-cased name for the usepcc option */
+#define USEPCC_NAME (ntpd_opt_strs+2679)
+/** Name string for the usepcc option */
+#define USEPCC_name (ntpd_opt_strs+2686)
+/** Compiled in flag settings for the usepcc option */
+#define USEPCC_FLAGS (OPTST_DISABLED)
+
+#else /* disable usepcc */
+#define USEPCC_FLAGS (OPTST_OMITTED | OPTST_NO_INIT)
+#define USEPCC_NAME NULL
+#define USEPCC_DESC NULL
+#define USEPCC_name NULL
+#endif /* SYS_WINNT */
+
+/**
+ * pccfreq option description:
+ */
+#ifdef SYS_WINNT
+/** Descriptive text for the pccfreq option */
+#define PCCFREQ_DESC (ntpd_opt_strs+2693)
+/** Upper-cased name for the pccfreq option */
+#define PCCFREQ_NAME (ntpd_opt_strs+2736)
+/** Name string for the pccfreq option */
+#define PCCFREQ_name (ntpd_opt_strs+2744)
+/** Compiled in flag settings for the pccfreq option */
+#define PCCFREQ_FLAGS (OPTST_DISABLED \
+ | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
+
+#else /* disable pccfreq */
+#define PCCFREQ_FLAGS (OPTST_OMITTED | OPTST_NO_INIT)
+#define PCCFREQ_NAME NULL
+#define PCCFREQ_DESC NULL
+#define PCCFREQ_name NULL
+#endif /* SYS_WINNT */
+
+/**
+ * mdns option description:
+ */
+#ifdef HAVE_DNSREGISTRATION
+/** Descriptive text for the mdns option */
+#define MDNS_DESC (ntpd_opt_strs+2752)
+/** Upper-cased name for the mdns option */
+#define MDNS_NAME (ntpd_opt_strs+2787)
+/** Name string for the mdns option */
+#define MDNS_name (ntpd_opt_strs+2792)
+/** Compiled in flag settings for the mdns option */
+#define MDNS_FLAGS (OPTST_DISABLED)
+
+#else /* disable mdns */
+#define MDNS_FLAGS (OPTST_OMITTED | OPTST_NO_INIT)
+#define MDNS_NAME NULL
+#define MDNS_DESC NULL
+#define MDNS_name NULL
+#endif /* HAVE_DNSREGISTRATION */
+
+/*
+ * Help/More_Help/Version option descriptions:
+ */
+#define HELP_DESC (ntpd_opt_strs+2797)
+#define HELP_name (ntpd_opt_strs+2841)
+#ifdef HAVE_WORKING_FORK
+#define MORE_HELP_DESC (ntpd_opt_strs+2846)
+#define MORE_HELP_name (ntpd_opt_strs+2891)
+#define MORE_HELP_FLAGS (OPTST_IMM | OPTST_NO_INIT)
+#else
+#define MORE_HELP_DESC HELP_DESC
+#define MORE_HELP_name HELP_name
+#define MORE_HELP_FLAGS (OPTST_OMITTED | OPTST_NO_INIT)
+#endif
+#ifdef NO_OPTIONAL_OPT_ARGS
+# define VER_FLAGS (OPTST_IMM | OPTST_NO_INIT)
+#else
+# define VER_FLAGS (OPTST_SET_ARGTYPE(OPARG_TYPE_STRING) | \
+ OPTST_ARG_OPTIONAL | OPTST_IMM | OPTST_NO_INIT)
+#endif
+#define VER_DESC (ntpd_opt_strs+2901)
+#define VER_name (ntpd_opt_strs+2937)
+/**
+ * Declare option callback procedures
+ */
+extern tOptProc
+ ntpOptionPrintVersion, optionBooleanVal, optionNestedVal,
+ optionNumericVal, optionPagedUsage, optionResetOpt,
+ optionStackArg, optionTimeDate, optionTimeVal,
+ optionUnstackArg, optionVendorOption;
+static tOptProc
+ doOptDebug_Level, doUsageOpt;
+#define VER_PROC ntpOptionPrintVersion
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/**
+ * Define the ntpd Option Descriptions.
+ * This is an array of OPTION_CT entries, one for each
+ * option that the ntpd program responds to.
+ */
+static tOptDesc optDesc[OPTION_CT] = {
+ { /* entry idx, value */ 0, VALUE_OPT_IPV4,
+ /* equiv idx, value */ 0, VALUE_OPT_IPV4,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ IPV4_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --ipv4 */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, aIpv4CantList,
+ /* option proc */ NULL,
+ /* desc, NAME, name */ IPV4_DESC, IPV4_NAME, IPV4_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ 1, VALUE_OPT_IPV6,
+ /* equiv idx, value */ 1, VALUE_OPT_IPV6,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ IPV6_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --ipv6 */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, aIpv6CantList,
+ /* option proc */ NULL,
+ /* desc, NAME, name */ IPV6_DESC, IPV6_NAME, IPV6_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ 2, VALUE_OPT_AUTHREQ,
+ /* equiv idx, value */ 2, VALUE_OPT_AUTHREQ,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ AUTHREQ_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --authreq */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, aAuthreqCantList,
+ /* option proc */ NULL,
+ /* desc, NAME, name */ AUTHREQ_DESC, AUTHREQ_NAME, AUTHREQ_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ 3, VALUE_OPT_AUTHNOREQ,
+ /* equiv idx, value */ 3, VALUE_OPT_AUTHNOREQ,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ AUTHNOREQ_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --authnoreq */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, aAuthnoreqCantList,
+ /* option proc */ NULL,
+ /* desc, NAME, name */ AUTHNOREQ_DESC, AUTHNOREQ_NAME, AUTHNOREQ_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ 4, VALUE_OPT_BCASTSYNC,
+ /* equiv idx, value */ 4, VALUE_OPT_BCASTSYNC,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ BCASTSYNC_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --bcastsync */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, NULL,
+ /* option proc */ NULL,
+ /* desc, NAME, name */ BCASTSYNC_DESC, BCASTSYNC_NAME, BCASTSYNC_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ 5, VALUE_OPT_CONFIGFILE,
+ /* equiv idx, value */ 5, VALUE_OPT_CONFIGFILE,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ CONFIGFILE_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --configfile */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, NULL,
+ /* option proc */ NULL,
+ /* desc, NAME, name */ CONFIGFILE_DESC, CONFIGFILE_NAME, CONFIGFILE_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ 6, VALUE_OPT_DEBUG_LEVEL,
+ /* equiv idx, value */ 6, VALUE_OPT_DEBUG_LEVEL,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, NOLIMIT, 0,
+ /* opt state flags */ DEBUG_LEVEL_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --debug-level */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, NULL,
+ /* option proc */ doOptDebug_Level,
+ /* desc, NAME, name */ DEBUG_LEVEL_DESC, DEBUG_LEVEL_NAME, DEBUG_LEVEL_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ 7, VALUE_OPT_SET_DEBUG_LEVEL,
+ /* equiv idx, value */ 7, VALUE_OPT_SET_DEBUG_LEVEL,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, NOLIMIT, 0,
+ /* opt state flags */ SET_DEBUG_LEVEL_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --set-debug-level */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, NULL,
+ /* option proc */ optionNumericVal,
+ /* desc, NAME, name */ SET_DEBUG_LEVEL_DESC, SET_DEBUG_LEVEL_NAME, SET_DEBUG_LEVEL_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ 8, VALUE_OPT_DRIFTFILE,
+ /* equiv idx, value */ 8, VALUE_OPT_DRIFTFILE,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ DRIFTFILE_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --driftfile */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, NULL,
+ /* option proc */ NULL,
+ /* desc, NAME, name */ DRIFTFILE_DESC, DRIFTFILE_NAME, DRIFTFILE_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ 9, VALUE_OPT_PANICGATE,
+ /* equiv idx, value */ 9, VALUE_OPT_PANICGATE,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, NOLIMIT, 0,
+ /* opt state flags */ PANICGATE_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --panicgate */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, NULL,
+ /* option proc */ NULL,
+ /* desc, NAME, name */ PANICGATE_DESC, PANICGATE_NAME, PANICGATE_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ 10, VALUE_OPT_FORCE_STEP_ONCE,
+ /* equiv idx, value */ 10, VALUE_OPT_FORCE_STEP_ONCE,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ FORCE_STEP_ONCE_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --force_step_once */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, NULL,
+ /* option proc */ NULL,
+ /* desc, NAME, name */ FORCE_STEP_ONCE_DESC, FORCE_STEP_ONCE_NAME, FORCE_STEP_ONCE_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ 11, VALUE_OPT_JAILDIR,
+ /* equiv idx, value */ 11, VALUE_OPT_JAILDIR,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ JAILDIR_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --jaildir */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, NULL,
+ /* option proc */ NULL,
+ /* desc, NAME, name */ JAILDIR_DESC, JAILDIR_NAME, JAILDIR_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ 12, VALUE_OPT_INTERFACE,
+ /* equiv idx, value */ 12, VALUE_OPT_INTERFACE,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, NOLIMIT, 0,
+ /* opt state flags */ INTERFACE_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --interface */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, NULL,
+ /* option proc */ optionStackArg,
+ /* desc, NAME, name */ INTERFACE_DESC, INTERFACE_NAME, INTERFACE_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ 13, VALUE_OPT_KEYFILE,
+ /* equiv idx, value */ 13, VALUE_OPT_KEYFILE,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ KEYFILE_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --keyfile */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, NULL,
+ /* option proc */ NULL,
+ /* desc, NAME, name */ KEYFILE_DESC, KEYFILE_NAME, KEYFILE_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ 14, VALUE_OPT_LOGFILE,
+ /* equiv idx, value */ 14, VALUE_OPT_LOGFILE,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ LOGFILE_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --logfile */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, NULL,
+ /* option proc */ NULL,
+ /* desc, NAME, name */ LOGFILE_DESC, LOGFILE_NAME, LOGFILE_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ 15, VALUE_OPT_NOVIRTUALIPS,
+ /* equiv idx, value */ 15, VALUE_OPT_NOVIRTUALIPS,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ NOVIRTUALIPS_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --novirtualips */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, NULL,
+ /* option proc */ NULL,
+ /* desc, NAME, name */ NOVIRTUALIPS_DESC, NOVIRTUALIPS_NAME, NOVIRTUALIPS_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ 16, VALUE_OPT_MODIFYMMTIMER,
+ /* equiv idx, value */ 16, VALUE_OPT_MODIFYMMTIMER,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ MODIFYMMTIMER_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --modifymmtimer */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, NULL,
+ /* option proc */ NULL,
+ /* desc, NAME, name */ MODIFYMMTIMER_DESC, MODIFYMMTIMER_NAME, MODIFYMMTIMER_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ 17, VALUE_OPT_NOFORK,
+ /* equiv idx, value */ 17, VALUE_OPT_NOFORK,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ NOFORK_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --nofork */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, aNoforkCantList,
+ /* option proc */ NULL,
+ /* desc, NAME, name */ NOFORK_DESC, NOFORK_NAME, NOFORK_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ 18, VALUE_OPT_NICE,
+ /* equiv idx, value */ 18, VALUE_OPT_NICE,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ NICE_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --nice */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, NULL,
+ /* option proc */ NULL,
+ /* desc, NAME, name */ NICE_DESC, NICE_NAME, NICE_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ 19, VALUE_OPT_PIDFILE,
+ /* equiv idx, value */ 19, VALUE_OPT_PIDFILE,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ PIDFILE_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --pidfile */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, NULL,
+ /* option proc */ NULL,
+ /* desc, NAME, name */ PIDFILE_DESC, PIDFILE_NAME, PIDFILE_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ 20, VALUE_OPT_PRIORITY,
+ /* equiv idx, value */ 20, VALUE_OPT_PRIORITY,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ PRIORITY_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --priority */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, NULL,
+ /* option proc */ optionNumericVal,
+ /* desc, NAME, name */ PRIORITY_DESC, PRIORITY_NAME, PRIORITY_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ 21, VALUE_OPT_QUIT,
+ /* equiv idx, value */ 21, VALUE_OPT_QUIT,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ QUIT_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --quit */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, aQuitCantList,
+ /* option proc */ NULL,
+ /* desc, NAME, name */ QUIT_DESC, QUIT_NAME, QUIT_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ 22, VALUE_OPT_PROPAGATIONDELAY,
+ /* equiv idx, value */ 22, VALUE_OPT_PROPAGATIONDELAY,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ PROPAGATIONDELAY_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --propagationdelay */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, NULL,
+ /* option proc */ NULL,
+ /* desc, NAME, name */ PROPAGATIONDELAY_DESC, PROPAGATIONDELAY_NAME, PROPAGATIONDELAY_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ 23, VALUE_OPT_SAVECONFIGQUIT,
+ /* equiv idx, value */ 23, VALUE_OPT_SAVECONFIGQUIT,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ SAVECONFIGQUIT_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --saveconfigquit */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, aSaveconfigquitCantList,
+ /* option proc */ NULL,
+ /* desc, NAME, name */ SAVECONFIGQUIT_DESC, SAVECONFIGQUIT_NAME, SAVECONFIGQUIT_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ 24, VALUE_OPT_STATSDIR,
+ /* equiv idx, value */ 24, VALUE_OPT_STATSDIR,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ STATSDIR_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --statsdir */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, NULL,
+ /* option proc */ NULL,
+ /* desc, NAME, name */ STATSDIR_DESC, STATSDIR_NAME, STATSDIR_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ 25, VALUE_OPT_TRUSTEDKEY,
+ /* equiv idx, value */ 25, VALUE_OPT_TRUSTEDKEY,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, NOLIMIT, 0,
+ /* opt state flags */ TRUSTEDKEY_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --trustedkey */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, NULL,
+ /* option proc */ optionStackArg,
+ /* desc, NAME, name */ TRUSTEDKEY_DESC, TRUSTEDKEY_NAME, TRUSTEDKEY_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ 26, VALUE_OPT_USER,
+ /* equiv idx, value */ 26, VALUE_OPT_USER,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ USER_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --user */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, NULL,
+ /* option proc */ NULL,
+ /* desc, NAME, name */ USER_DESC, USER_NAME, USER_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ 27, VALUE_OPT_UPDATEINTERVAL,
+ /* equiv idx, value */ 27, VALUE_OPT_UPDATEINTERVAL,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ UPDATEINTERVAL_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --updateinterval */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, NULL,
+ /* option proc */ optionNumericVal,
+ /* desc, NAME, name */ UPDATEINTERVAL_DESC, UPDATEINTERVAL_NAME, UPDATEINTERVAL_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ 28, VALUE_OPT_VAR,
+ /* equiv idx, value */ 28, VALUE_OPT_VAR,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, NOLIMIT, 0,
+ /* opt state flags */ VAR_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --var */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, NULL,
+ /* option proc */ optionStackArg,
+ /* desc, NAME, name */ VAR_DESC, VAR_NAME, VAR_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ 29, VALUE_OPT_DVAR,
+ /* equiv idx, value */ 29, VALUE_OPT_DVAR,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, NOLIMIT, 0,
+ /* opt state flags */ DVAR_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --dvar */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, NULL,
+ /* option proc */ optionStackArg,
+ /* desc, NAME, name */ DVAR_DESC, DVAR_NAME, DVAR_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ 30, VALUE_OPT_WAIT_SYNC,
+ /* equiv idx, value */ 30, VALUE_OPT_WAIT_SYNC,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ WAIT_SYNC_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --wait-sync */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, aWait_SyncCantList,
+ /* option proc */ optionNumericVal,
+ /* desc, NAME, name */ WAIT_SYNC_DESC, WAIT_SYNC_NAME, WAIT_SYNC_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ 31, VALUE_OPT_SLEW,
+ /* equiv idx, value */ 31, VALUE_OPT_SLEW,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ SLEW_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --slew */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, NULL,
+ /* option proc */ NULL,
+ /* desc, NAME, name */ SLEW_DESC, SLEW_NAME, SLEW_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ 32, VALUE_OPT_USEPCC,
+ /* equiv idx, value */ 32, VALUE_OPT_USEPCC,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ USEPCC_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --usepcc */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, NULL,
+ /* option proc */ NULL,
+ /* desc, NAME, name */ USEPCC_DESC, USEPCC_NAME, USEPCC_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ 33, VALUE_OPT_PCCFREQ,
+ /* equiv idx, value */ 33, VALUE_OPT_PCCFREQ,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ PCCFREQ_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --pccfreq */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, NULL,
+ /* option proc */ NULL,
+ /* desc, NAME, name */ PCCFREQ_DESC, PCCFREQ_NAME, PCCFREQ_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ 34, VALUE_OPT_MDNS,
+ /* equiv idx, value */ 34, VALUE_OPT_MDNS,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ MDNS_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --mdns */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, NULL,
+ /* option proc */ NULL,
+ /* desc, NAME, name */ MDNS_DESC, MDNS_NAME, MDNS_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ INDEX_OPT_VERSION, VALUE_OPT_VERSION,
+ /* equiv idx value */ NO_EQUIVALENT, VALUE_OPT_VERSION,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ VER_FLAGS, AOUSE_VERSION,
+ /* last opt argumnt */ { NULL },
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, NULL,
+ /* option proc */ VER_PROC,
+ /* desc, NAME, name */ VER_DESC, NULL, VER_name,
+ /* disablement strs */ NULL, NULL },
+
+
+
+ { /* entry idx, value */ INDEX_OPT_HELP, VALUE_OPT_HELP,
+ /* equiv idx value */ NO_EQUIVALENT, VALUE_OPT_HELP,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ OPTST_IMM | OPTST_NO_INIT, AOUSE_HELP,
+ /* last opt argumnt */ { NULL },
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, NULL,
+ /* option proc */ doUsageOpt,
+ /* desc, NAME, name */ HELP_DESC, NULL, HELP_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ INDEX_OPT_MORE_HELP, VALUE_OPT_MORE_HELP,
+ /* equiv idx value */ NO_EQUIVALENT, VALUE_OPT_MORE_HELP,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ MORE_HELP_FLAGS, AOUSE_MORE_HELP,
+ /* last opt argumnt */ { NULL },
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, NULL,
+ /* option proc */ optionPagedUsage,
+ /* desc, NAME, name */ MORE_HELP_DESC, NULL, MORE_HELP_name,
+ /* disablement strs */ NULL, NULL }
+};
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/** Reference to the upper cased version of ntpd. */
+#define zPROGNAME (ntpd_opt_strs+2945)
+/** Reference to the title line for ntpd usage. */
+#define zUsageTitle (ntpd_opt_strs+2950)
+/** There is no ntpd configuration file. */
+#define zRcName NULL
+/** There are no directories to search for ntpd config files. */
+#define apzHomeList NULL
+/** The ntpd program bug email address. */
+#define zBugsAddr (ntpd_opt_strs+3082)
+/** Clarification/explanation of what ntpd does. */
+#define zExplain (ntpd_opt_strs+3116)
+/** Extra detail explaining what ntpd does. */
+#define zDetail (NULL)
+/** The full version string for ntpd. */
+#define zFullVersion (ntpd_opt_strs+3118)
+/* extracted from optcode.tlib near line 364 */
+
+#if defined(ENABLE_NLS)
+# define OPTPROC_BASE OPTPROC_TRANSLATE
+ static tOptionXlateProc translate_option_strings;
+#else
+# define OPTPROC_BASE OPTPROC_NONE
+# define translate_option_strings NULL
+#endif /* ENABLE_NLS */
+
+#define ntpd_full_usage (NULL)
+#define ntpd_short_usage (NULL)
+
+#endif /* not defined __doxygen__ */
+
+/*
+ * Create the static procedure(s) declared above.
+ */
+/**
+ * The callout function that invokes the optionUsage function.
+ *
+ * @param[in] opts the AutoOpts option description structure
+ * @param[in] od the descriptor for the "help" (usage) option.
+ * @noreturn
+ */
+static void
+doUsageOpt(tOptions * opts, tOptDesc * od)
+{
+ int ex_code;
+ ex_code = NTPD_EXIT_SUCCESS;
+ optionUsage(&ntpdOptions, ex_code);
+ /* NOTREACHED */
+ exit(1);
+ (void)opts;
+ (void)od;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/**
+ * Code to handle the debug-level option.
+ *
+ * @param[in] pOptions the ntpd options data structure
+ * @param[in,out] pOptDesc the option descriptor for this option.
+ */
+static void
+doOptDebug_Level(tOptions* pOptions, tOptDesc* pOptDesc)
+{
+ /*
+ * Be sure the flag-code[0] handles special values for the options pointer
+ * viz. (poptions <= OPTPROC_EMIT_LIMIT) *and also* the special flag bit
+ * ((poptdesc->fOptState & OPTST_RESET) != 0) telling the option to
+ * reset its state.
+ */
+ /* extracted from debug-opt.def, line 15 */
+OPT_VALUE_SET_DEBUG_LEVEL++;
+ (void)pOptDesc;
+ (void)pOptions;
+}
+/* extracted from optmain.tlib near line 1250 */
+
+/**
+ * The directory containing the data associated with ntpd.
+ */
+#ifndef PKGDATADIR
+# define PKGDATADIR ""
+#endif
+
+/**
+ * Information about the person or institution that packaged ntpd
+ * for the current distribution.
+ */
+#ifndef WITH_PACKAGER
+# define ntpd_packager_info NULL
+#else
+/** Packager information for ntpd. */
+static char const ntpd_packager_info[] =
+ "Packaged by " WITH_PACKAGER
+
+# ifdef WITH_PACKAGER_VERSION
+ " ("WITH_PACKAGER_VERSION")"
+# endif
+
+# ifdef WITH_PACKAGER_BUG_REPORTS
+ "\nReport ntpd bugs to " WITH_PACKAGER_BUG_REPORTS
+# endif
+ "\n";
+#endif
+#ifndef __doxygen__
+
+#endif /* __doxygen__ */
+/**
+ * The option definitions for ntpd. The one structure that
+ * binds them all.
+ */
+tOptions ntpdOptions = {
+ OPTIONS_STRUCT_VERSION,
+ 0, NULL, /* original argc + argv */
+ ( OPTPROC_BASE
+ + OPTPROC_ERRSTOP
+ + OPTPROC_SHORTOPT
+ + OPTPROC_LONGOPT
+ + OPTPROC_NO_REQ_OPT
+ + OPTPROC_ENVIRON
+ + OPTPROC_MISUSE ),
+ 0, NULL, /* current option index, current option */
+ NULL, NULL, zPROGNAME,
+ zRcName, zCopyright, zLicenseDescrip,
+ zFullVersion, apzHomeList, zUsageTitle,
+ zExplain, zDetail, optDesc,
+ zBugsAddr, /* address to send bugs to */
+ NULL, NULL, /* extensions/saved state */
+ optionUsage, /* usage procedure */
+ translate_option_strings, /* translation procedure */
+ /*
+ * Indexes to special options
+ */
+ { INDEX_OPT_MORE_HELP, /* more-help option index */
+ NO_EQUIVALENT, /* save option index */
+ NO_EQUIVALENT, /* '-#' option index */
+ NO_EQUIVALENT /* index of default opt */
+ },
+ 38 /* full option count */, 35 /* user option count */,
+ ntpd_full_usage, ntpd_short_usage,
+ NULL, NULL,
+ PKGDATADIR, ntpd_packager_info
+};
+
+#if ENABLE_NLS
+/**
+ * This code is designed to translate translatable option text for the
+ * ntpd program. These translations happen upon entry
+ * to optionProcess().
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#ifdef HAVE_DCGETTEXT
+# include <gettext.h>
+#endif
+#include <autoopts/usage-txt.h>
+
+static char * AO_gettext(char const * pz);
+static void coerce_it(void ** s);
+
+/**
+ * AutoGen specific wrapper function for gettext. It relies on the macro _()
+ * to convert from English to the target language, then strdup-duplicates the
+ * result string. It tries the "libopts" domain first, then whatever has been
+ * set via the \a textdomain(3) call.
+ *
+ * @param[in] pz the input text used as a lookup key.
+ * @returns the translated text (if there is one),
+ * or the original text (if not).
+ */
+static char *
+AO_gettext(char const * pz)
+{
+ char * res;
+ if (pz == NULL)
+ return NULL;
+#ifdef HAVE_DCGETTEXT
+ /*
+ * While processing the option_xlateable_txt data, try to use the
+ * "libopts" domain. Once we switch to the option descriptor data,
+ * do *not* use that domain.
+ */
+ if (option_xlateable_txt.field_ct != 0) {
+ res = dgettext("libopts", pz);
+ if (res == pz)
+ res = (char *)VOIDP(_(pz));
+ } else
+ res = (char *)VOIDP(_(pz));
+#else
+ res = (char *)VOIDP(_(pz));
+#endif
+ if (res == pz)
+ return res;
+ res = strdup(res);
+ if (res == NULL) {
+ fputs(_("No memory for duping translated strings\n"), stderr);
+ exit(NTPD_EXIT_FAILURE);
+ }
+ return res;
+}
+
+/**
+ * All the pointers we use are marked "* const", but they are stored in
+ * writable memory. Coerce the mutability and set the pointer.
+ */
+static void coerce_it(void ** s) { *s = AO_gettext(*s);
+}
+
+/**
+ * Translate all the translatable strings in the ntpdOptions
+ * structure defined above. This is done only once.
+ */
+static void
+translate_option_strings(void)
+{
+ tOptions * const opts = &ntpdOptions;
+
+ /*
+ * Guard against re-translation. It won't work. The strings will have
+ * been changed by the first pass through this code. One shot only.
+ */
+ if (option_xlateable_txt.field_ct != 0) {
+ /*
+ * Do the translations. The first pointer follows the field count
+ * field. The field count field is the size of a pointer.
+ */
+ char ** ppz = (char**)VOIDP(&(option_xlateable_txt));
+ int ix = option_xlateable_txt.field_ct;
+
+ do {
+ ppz++; /* skip over field_ct */
+ *ppz = AO_gettext(*ppz);
+ } while (--ix > 0);
+ /* prevent re-translation and disable "libopts" domain lookup */
+ option_xlateable_txt.field_ct = 0;
+
+ coerce_it(VOIDP(&(opts->pzCopyright)));
+ coerce_it(VOIDP(&(opts->pzCopyNotice)));
+ coerce_it(VOIDP(&(opts->pzFullVersion)));
+ coerce_it(VOIDP(&(opts->pzUsageTitle)));
+ coerce_it(VOIDP(&(opts->pzExplain)));
+ coerce_it(VOIDP(&(opts->pzDetail)));
+ {
+ tOptDesc * od = opts->pOptDesc;
+ for (ix = opts->optCt; ix > 0; ix--, od++)
+ coerce_it(VOIDP(&(od->pzText)));
+ }
+ }
+}
+#endif /* ENABLE_NLS */
+
+#ifdef DO_NOT_COMPILE_THIS_CODE_IT_IS_FOR_GETTEXT
+/** I18N function strictly for xgettext. Do not compile. */
+static void bogus_function(void) {
+ /* TRANSLATORS:
+
+ The following dummy function was crated solely so that xgettext can
+ extract the correct strings. These strings are actually referenced
+ by a field name in the ntpdOptions structure noted in the
+ comments below. The literal text is defined in ntpd_opt_strs.
+
+ NOTE: the strings below are segmented with respect to the source string
+ ntpd_opt_strs. The strings above are handed off for translation
+ at run time a paragraph at a time. Consequently, they are presented here
+ for translation a paragraph at a time.
+
+ ALSO: often the description for an option will reference another option
+ by name. These are set off with apostrophe quotes (I hope). Do not
+ translate option names.
+ */
+ /* referenced via ntpdOptions.pzCopyright */
+ puts(_("ntpd 4.2.8p13\n\
+Copyright (C) 1992-2017 The University of Delaware and Network Time Foundation, all rights reserved.\n\
+This is free software. It is licensed for use, modification and\n\
+redistribution under the terms of the NTP License, copies of which\n\
+can be seen at:\n"));
+ puts(_(" <http://ntp.org/license>\n\
+ <http://opensource.org/licenses/ntp-license.php>\n"));
+
+ /* referenced via ntpdOptions.pzCopyNotice */
+ puts(_("Permission to use, copy, modify, and distribute this software and its\n\
+documentation for any purpose with or without fee is hereby granted,\n\
+provided that the above copyright notice appears in all copies and that\n\
+both the copyright notice and this permission notice appear in supporting\n\
+documentation, and that the name The University of Delaware not be used in\n\
+advertising or publicity pertaining to distribution of the software without\n\
+specific, written prior permission. The University of Delaware and Network\n\
+Time Foundation makes no representations about the suitability this\n\
+software for any purpose. It is provided \"as is\" without express or\n\
+implied warranty.\n"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("Force IPv4 DNS name resolution"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("Force IPv6 DNS name resolution"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("Require crypto authentication"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("Do not require crypto authentication"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("Allow us to sync to broadcast servers"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("configuration file name"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("Increase debug verbosity level"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("Set the debug verbosity level"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("frequency drift file name"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("Allow the first adjustment to be Big"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("Step any initial offset correction."));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("Jail directory"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("built without --enable-clockctl or --enable-linuxcaps or --enable-solarisprivs"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("Listen on an interface name or address"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("path to symmetric keys"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("path to the log file"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("Do not listen to virtual interfaces"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("Modify Multimedia Timer (Windows only)"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("Do not fork"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("Run at high priority"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("path to the PID file"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("Process priority"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("Set the time and quit"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("Broadcast/propagation delay"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("Save parsed configuration and quit"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("Statistics file location"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("Trusted key number"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("Run as userid (or userid:groupid)"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("built without --enable-clockctl or --enable-linuxcaps or --enable-solarisprivs"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("interval in seconds between scans for new or dropped interfaces"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("make ARG an ntp variable (RW)"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("make ARG an ntp variable (RW|DEF)"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("Seconds to wait for first clock sync"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("Slew up to 600 seconds"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("Use CPU cycle counter (Windows only)"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("Force CPU cycle counter use (Windows only)"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("Register with mDNS as a NTP server"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("display extended usage information and exit"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("extended usage information passed thru pager"));
+
+ /* referenced via ntpdOptions.pOptDesc->pzText */
+ puts(_("output version information and exit"));
+
+ /* referenced via ntpdOptions.pzUsageTitle */
+ puts(_("ntpd - NTP daemon program - Ver. 4.2.8p13\n\
+Usage: %s [ -<flag> [<val>] | --<name>[{=| }<val>] ]... \\\n\
+\t\t[ <server1> ... <serverN> ]\n"));
+
+ /* referenced via ntpdOptions.pzExplain */
+ puts(_("\n"));
+
+ /* referenced via ntpdOptions.pzFullVersion */
+ puts(_("ntpd 4.2.8p13"));
+
+ /* referenced via ntpdOptions.pzFullUsage */
+ puts(_("<<<NOT-FOUND>>>"));
+
+ /* referenced via ntpdOptions.pzShortUsage */
+ puts(_("<<<NOT-FOUND>>>"));
+ /* LIBOPTS-MESSAGES: */
+#line 67 "../autoopts.c"
+ puts(_("allocation of %d bytes failed\n"));
+#line 93 "../autoopts.c"
+ puts(_("allocation of %d bytes failed\n"));
+#line 53 "../init.c"
+ puts(_("AutoOpts function called without option descriptor\n"));
+#line 86 "../init.c"
+ puts(_("\tThis exceeds the compiled library version: "));
+#line 84 "../init.c"
+ puts(_("Automated Options Processing Error!\n"
+ "\t%s called AutoOpts function with structure version %d:%d:%d.\n"));
+#line 80 "../autoopts.c"
+ puts(_("realloc of %d bytes at 0x%p failed\n"));
+#line 88 "../init.c"
+ puts(_("\tThis is less than the minimum library version: "));
+#line 121 "../version.c"
+ puts(_("Automated Options version %s\n"
+ "\tCopyright (C) 1999-2014 by Bruce Korb - all rights reserved\n"));
+#line 87 "../makeshell.c"
+ puts(_("(AutoOpts bug): %s.\n"));
+#line 90 "../reset.c"
+ puts(_("optionResetOpt() called, but reset-option not configured"));
+#line 292 "../usage.c"
+ puts(_("could not locate the 'help' option"));
+#line 336 "../autoopts.c"
+ puts(_("optionProcess() was called with invalid data"));
+#line 748 "../usage.c"
+ puts(_("invalid argument type specified"));
+#line 598 "../find.c"
+ puts(_("defaulted to option with optional arg"));
+#line 76 "../alias.c"
+ puts(_("aliasing option is out of range."));
+#line 234 "../enum.c"
+ puts(_("%s error: the keyword '%s' is ambiguous for %s\n"));
+#line 108 "../find.c"
+ puts(_(" The following options match:\n"));
+#line 293 "../find.c"
+ puts(_("%s: ambiguous option name: %s (matches %d options)\n"));
+#line 161 "../check.c"
+ puts(_("%s: Command line arguments required\n"));
+#line 43 "../alias.c"
+ puts(_("%d %s%s options allowed\n"));
+#line 94 "../makeshell.c"
+ puts(_("%s error %d (%s) calling %s for '%s'\n"));
+#line 306 "../makeshell.c"
+ puts(_("interprocess pipe"));
+#line 168 "../version.c"
+ puts(_("error: version option argument '%c' invalid. Use:\n"
+ "\t'v' - version only\n"
+ "\t'c' - version and copyright\n"
+ "\t'n' - version and full copyright notice\n"));
+#line 58 "../check.c"
+ puts(_("%s error: the '%s' and '%s' options conflict\n"));
+#line 217 "../find.c"
+ puts(_("%s: The '%s' option has been disabled."));
+#line 430 "../find.c"
+ puts(_("%s: The '%s' option has been disabled."));
+#line 38 "../alias.c"
+ puts(_("-equivalence"));
+#line 469 "../find.c"
+ puts(_("%s: illegal option -- %c\n"));
+#line 110 "../reset.c"
+ puts(_("%s: illegal option -- %c\n"));
+#line 271 "../find.c"
+ puts(_("%s: illegal option -- %s\n"));
+#line 755 "../find.c"
+ puts(_("%s: illegal option -- %s\n"));
+#line 118 "../reset.c"
+ puts(_("%s: illegal option -- %s\n"));
+#line 335 "../find.c"
+ puts(_("%s: unknown vendor extension option -- %s\n"));
+#line 159 "../enum.c"
+ puts(_(" or an integer from %d through %d\n"));
+#line 169 "../enum.c"
+ puts(_(" or an integer from %d through %d\n"));
+#line 747 "../usage.c"
+ puts(_("%s error: invalid option descriptor for %s\n"));
+#line 1081 "../usage.c"
+ puts(_("%s error: invalid option descriptor for %s\n"));
+#line 385 "../find.c"
+ puts(_("%s: invalid option name: %s\n"));
+#line 527 "../find.c"
+ puts(_("%s: The '%s' option requires an argument.\n"));
+#line 156 "../autoopts.c"
+ puts(_("(AutoOpts bug): Equivalenced option '%s' was equivalenced to both\n"
+ "\t'%s' and '%s'."));
+#line 94 "../check.c"
+ puts(_("%s error: The %s option is required\n"));
+#line 632 "../find.c"
+ puts(_("%s: The '%s' option cannot have an argument.\n"));
+#line 151 "../check.c"
+ puts(_("%s: Command line arguments are not allowed.\n"));
+#line 535 "../save.c"
+ puts(_("error %d (%s) creating %s\n"));
+#line 234 "../enum.c"
+ puts(_("%s error: '%s' does not match any %s keywords.\n"));
+#line 93 "../reset.c"
+ puts(_("%s error: The '%s' option requires an argument.\n"));
+#line 184 "../save.c"
+ puts(_("error %d (%s) stat-ing %s\n"));
+#line 238 "../save.c"
+ puts(_("error %d (%s) stat-ing %s\n"));
+#line 143 "../restore.c"
+ puts(_("%s error: no saved option state\n"));
+#line 231 "../autoopts.c"
+ puts(_("'%s' is not a command line option.\n"));
+#line 111 "../time.c"
+ puts(_("%s error: '%s' is not a recognizable date/time.\n"));
+#line 132 "../save.c"
+ puts(_("'%s' not defined\n"));
+#line 50 "../time.c"
+ puts(_("%s error: '%s' is not a recognizable time duration.\n"));
+#line 92 "../check.c"
+ puts(_("%s error: The %s option must appear %d times.\n"));
+#line 164 "../numeric.c"
+ puts(_("%s error: '%s' is not a recognizable number.\n"));
+#line 200 "../enum.c"
+ puts(_("%s error: %s exceeds %s keyword count\n"));
+#line 330 "../usage.c"
+ puts(_("Try '%s %s' for more information.\n"));
+#line 45 "../alias.c"
+ puts(_("one %s%s option allowed\n"));
+#line 208 "../makeshell.c"
+ puts(_("standard output"));
+#line 943 "../makeshell.c"
+ puts(_("standard output"));
+#line 274 "../usage.c"
+ puts(_("standard output"));
+#line 415 "../usage.c"
+ puts(_("standard output"));
+#line 625 "../usage.c"
+ puts(_("standard output"));
+#line 175 "../version.c"
+ puts(_("standard output"));
+#line 274 "../usage.c"
+ puts(_("standard error"));
+#line 415 "../usage.c"
+ puts(_("standard error"));
+#line 625 "../usage.c"
+ puts(_("standard error"));
+#line 175 "../version.c"
+ puts(_("standard error"));
+#line 208 "../makeshell.c"
+ puts(_("write"));
+#line 943 "../makeshell.c"
+ puts(_("write"));
+#line 273 "../usage.c"
+ puts(_("write"));
+#line 414 "../usage.c"
+ puts(_("write"));
+#line 624 "../usage.c"
+ puts(_("write"));
+#line 174 "../version.c"
+ puts(_("write"));
+#line 60 "../numeric.c"
+ puts(_("%s error: %s option value %ld is out of range.\n"));
+#line 44 "../check.c"
+ puts(_("%s error: %s option requires the %s option\n"));
+#line 131 "../save.c"
+ puts(_("%s warning: cannot save options - %s not regular file\n"));
+#line 183 "../save.c"
+ puts(_("%s warning: cannot save options - %s not regular file\n"));
+#line 237 "../save.c"
+ puts(_("%s warning: cannot save options - %s not regular file\n"));
+#line 256 "../save.c"
+ puts(_("%s warning: cannot save options - %s not regular file\n"));
+#line 534 "../save.c"
+ puts(_("%s warning: cannot save options - %s not regular file\n"));
+ /* END-LIBOPTS-MESSAGES */
+
+ /* USAGE-TEXT: */
+#line 873 "../usage.c"
+ puts(_("\t\t\t\t- an alternate for '%s'\n"));
+#line 1148 "../usage.c"
+ puts(_("Version, usage and configuration options:"));
+#line 924 "../usage.c"
+ puts(_("\t\t\t\t- default option for unnamed options\n"));
+#line 837 "../usage.c"
+ puts(_("\t\t\t\t- disabled as '--%s'\n"));
+#line 1117 "../usage.c"
+ puts(_(" --- %-14s %s\n"));
+#line 1115 "../usage.c"
+ puts(_("This option has been disabled"));
+#line 864 "../usage.c"
+ puts(_("\t\t\t\t- enabled by default\n"));
+#line 40 "../alias.c"
+ puts(_("%s error: only "));
+#line 1194 "../usage.c"
+ puts(_(" - examining environment variables named %s_*\n"));
+#line 168 "../file.c"
+ puts(_("\t\t\t\t- file must not pre-exist\n"));
+#line 172 "../file.c"
+ puts(_("\t\t\t\t- file must pre-exist\n"));
+#line 380 "../usage.c"
+ puts(_("Options are specified by doubled hyphens and their name or by a single\n"
+ "hyphen and the flag character.\n"));
+#line 921 "../makeshell.c"
+ puts(_("\n"
+ "= = = = = = = =\n\n"
+ "This incarnation of genshell will produce\n"
+ "a shell script to parse the options for %s:\n\n"));
+#line 166 "../enum.c"
+ puts(_(" or an integer mask with any of the lower %d bits set\n"));
+#line 897 "../usage.c"
+ puts(_("\t\t\t\t- is a set membership option\n"));
+#line 918 "../usage.c"
+ puts(_("\t\t\t\t- must appear between %d and %d times\n"));
+#line 382 "../usage.c"
+ puts(_("Options are specified by single or double hyphens and their name.\n"));
+#line 904 "../usage.c"
+ puts(_("\t\t\t\t- may appear multiple times\n"));
+#line 891 "../usage.c"
+ puts(_("\t\t\t\t- may not be preset\n"));
+#line 1309 "../usage.c"
+ puts(_(" Arg Option-Name Description\n"));
+#line 1245 "../usage.c"
+ puts(_(" Flg Arg Option-Name Description\n"));
+#line 1303 "../usage.c"
+ puts(_(" Flg Arg Option-Name Description\n"));
+#line 1304 "../usage.c"
+ puts(_(" %3s %s"));
+#line 1310 "../usage.c"
+ puts(_(" %3s %s"));
+#line 387 "../usage.c"
+ puts(_("The '-#<number>' option may omit the hash char\n"));
+#line 383 "../usage.c"
+ puts(_("All arguments are named options.\n"));
+#line 971 "../usage.c"
+ puts(_(" - reading file %s"));
+#line 409 "../usage.c"
+ puts(_("\n"
+ "Please send bug reports to: <%s>\n"));
+#line 100 "../version.c"
+ puts(_("\n"
+ "Please send bug reports to: <%s>\n"));
+#line 129 "../version.c"
+ puts(_("\n"
+ "Please send bug reports to: <%s>\n"));
+#line 903 "../usage.c"
+ puts(_("\t\t\t\t- may NOT appear - preset only\n"));
+#line 944 "../usage.c"
+ puts(_("\n"
+ "The following option preset mechanisms are supported:\n"));
+#line 1192 "../usage.c"
+ puts(_("\n"
+ "The following option preset mechanisms are supported:\n"));
+#line 682 "../usage.c"
+ puts(_("prohibits these options:\n"));
+#line 677 "../usage.c"
+ puts(_("prohibits the option '%s'\n"));
+#line 81 "../numeric.c"
+ puts(_("%s%ld to %ld"));
+#line 79 "../numeric.c"
+ puts(_("%sgreater than or equal to %ld"));
+#line 75 "../numeric.c"
+ puts(_("%s%ld exactly"));
+#line 68 "../numeric.c"
+ puts(_("%sit must lie in one of the ranges:\n"));
+#line 68 "../numeric.c"
+ puts(_("%sit must be in the range:\n"));
+#line 88 "../numeric.c"
+ puts(_(", or\n"));
+#line 66 "../numeric.c"
+ puts(_("%sis scalable with a suffix: k/K/m/M/g/G/t/T\n"));
+#line 77 "../numeric.c"
+ puts(_("%sless than or equal to %ld"));
+#line 390 "../usage.c"
+ puts(_("Operands and options may be intermixed. They will be reordered.\n"));
+#line 652 "../usage.c"
+ puts(_("requires the option '%s'\n"));
+#line 655 "../usage.c"
+ puts(_("requires these options:\n"));
+#line 1321 "../usage.c"
+ puts(_(" Arg Option-Name Req? Description\n"));
+#line 1315 "../usage.c"
+ puts(_(" Flg Arg Option-Name Req? Description\n"));
+#line 167 "../enum.c"
+ puts(_("or you may use a numeric representation. Preceding these with a '!'\n"
+ "will clear the bits, specifying 'none' will clear all bits, and 'all'\n"
+ "will set them all. Multiple entries may be passed as an option\n"
+ "argument list.\n"));
+#line 910 "../usage.c"
+ puts(_("\t\t\t\t- may appear up to %d times\n"));
+#line 77 "../enum.c"
+ puts(_("The valid \"%s\" option keywords are:\n"));
+#line 1152 "../usage.c"
+ puts(_("The next option supports vendor supported extra options:"));
+#line 773 "../usage.c"
+ puts(_("These additional options are:"));
+ /* END-USAGE-TEXT */
+}
+#endif /* uncompilable code */
+#ifdef __cplusplus
+}
+#endif
+/* ntpd-opts.c ends here */
diff --git a/sebhbsd/freebsd/contrib/ntp/ntpd/ntpd-opts.h b/sebhbsd/freebsd/contrib/ntp/ntpd/ntpd-opts.h
new file mode 100644
index 0000000..e7e8a60
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/ntpd/ntpd-opts.h
@@ -0,0 +1,465 @@
+/*
+ * EDIT THIS FILE WITH CAUTION (ntpd-opts.h)
+ *
+ * It has been AutoGen-ed February 20, 2019 at 09:56:15 AM by AutoGen 5.18.5
+ * From the definitions ntpd-opts.def
+ * and the template file options
+ *
+ * Generated from AutoOpts 41:1:16 templates.
+ *
+ * AutoOpts is a copyrighted work. This header file is not encumbered
+ * by AutoOpts licensing, but is provided under the licensing terms chosen
+ * by the ntpd author or copyright holder. AutoOpts is
+ * licensed under the terms of the LGPL. The redistributable library
+ * (``libopts'') is licensed under the terms of either the LGPL or, at the
+ * users discretion, the BSD license. See the AutoOpts and/or libopts sources
+ * for details.
+ *
+ * The ntpd program is copyrighted and licensed
+ * under the following terms:
+ *
+ * Copyright (C) 1992-2017 The University of Delaware and Network Time Foundation, all rights reserved.
+ * This is free software. It is licensed for use, modification and
+ * redistribution under the terms of the NTP License, copies of which
+ * can be seen at:
+ * <http://ntp.org/license>
+ * <http://opensource.org/licenses/ntp-license.php>
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose with or without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and that
+ * both the copyright notice and this permission notice appear in
+ * supporting documentation, and that the name The University of Delaware not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. The University of Delaware and Network Time Foundation makes no
+ * representations about the suitability this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ */
+/**
+ * This file contains the programmatic interface to the Automated
+ * Options generated for the ntpd program.
+ * These macros are documented in the AutoGen info file in the
+ * "AutoOpts" chapter. Please refer to that doc for usage help.
+ */
+#ifndef AUTOOPTS_NTPD_OPTS_H_GUARD
+#define AUTOOPTS_NTPD_OPTS_H_GUARD 1
+#include "config.h"
+#include <autoopts/options.h>
+
+/**
+ * Ensure that the library used for compiling this generated header is at
+ * least as new as the version current when the header template was released
+ * (not counting patch version increments). Also ensure that the oldest
+ * tolerable version is at least as old as what was current when the header
+ * template was released.
+ */
+#define AO_TEMPLATE_VERSION 167937
+#if (AO_TEMPLATE_VERSION < OPTIONS_MINIMUM_VERSION) \
+ || (AO_TEMPLATE_VERSION > OPTIONS_STRUCT_VERSION)
+# error option template version mismatches autoopts/options.h header
+ Choke Me.
+#endif
+
+/**
+ * Enumeration of each option type for ntpd
+ */
+typedef enum {
+ INDEX_OPT_IPV4 = 0,
+ INDEX_OPT_IPV6 = 1,
+ INDEX_OPT_AUTHREQ = 2,
+ INDEX_OPT_AUTHNOREQ = 3,
+ INDEX_OPT_BCASTSYNC = 4,
+ INDEX_OPT_CONFIGFILE = 5,
+ INDEX_OPT_DEBUG_LEVEL = 6,
+ INDEX_OPT_SET_DEBUG_LEVEL = 7,
+ INDEX_OPT_DRIFTFILE = 8,
+ INDEX_OPT_PANICGATE = 9,
+ INDEX_OPT_FORCE_STEP_ONCE = 10,
+ INDEX_OPT_JAILDIR = 11,
+ INDEX_OPT_INTERFACE = 12,
+ INDEX_OPT_KEYFILE = 13,
+ INDEX_OPT_LOGFILE = 14,
+ INDEX_OPT_NOVIRTUALIPS = 15,
+ INDEX_OPT_MODIFYMMTIMER = 16,
+ INDEX_OPT_NOFORK = 17,
+ INDEX_OPT_NICE = 18,
+ INDEX_OPT_PIDFILE = 19,
+ INDEX_OPT_PRIORITY = 20,
+ INDEX_OPT_QUIT = 21,
+ INDEX_OPT_PROPAGATIONDELAY = 22,
+ INDEX_OPT_SAVECONFIGQUIT = 23,
+ INDEX_OPT_STATSDIR = 24,
+ INDEX_OPT_TRUSTEDKEY = 25,
+ INDEX_OPT_USER = 26,
+ INDEX_OPT_UPDATEINTERVAL = 27,
+ INDEX_OPT_VAR = 28,
+ INDEX_OPT_DVAR = 29,
+ INDEX_OPT_WAIT_SYNC = 30,
+ INDEX_OPT_SLEW = 31,
+ INDEX_OPT_USEPCC = 32,
+ INDEX_OPT_PCCFREQ = 33,
+ INDEX_OPT_MDNS = 34,
+ INDEX_OPT_VERSION = 35,
+ INDEX_OPT_HELP = 36,
+ INDEX_OPT_MORE_HELP = 37
+} teOptIndex;
+/** count of all options for ntpd */
+#define OPTION_CT 38
+/** ntpd version */
+#define NTPD_VERSION "4.2.8p13"
+/** Full ntpd version text */
+#define NTPD_FULL_VERSION "ntpd 4.2.8p13"
+
+/**
+ * Interface defines for all options. Replace "n" with the UPPER_CASED
+ * option name (as in the teOptIndex enumeration above).
+ * e.g. HAVE_OPT(IPV4)
+ */
+#define DESC(n) (ntpdOptions.pOptDesc[INDEX_OPT_## n])
+/** 'true' if an option has been specified in any way */
+#define HAVE_OPT(n) (! UNUSED_OPT(& DESC(n)))
+/** The string argument to an option. The argument type must be \"string\". */
+#define OPT_ARG(n) (DESC(n).optArg.argString)
+/** Mask the option state revealing how an option was specified.
+ * It will be one and only one of \a OPTST_SET, \a OPTST_PRESET,
+ * \a OPTST_DEFINED, \a OPTST_RESET or zero.
+ */
+#define STATE_OPT(n) (DESC(n).fOptState & OPTST_SET_MASK)
+/** Count of option's occurrances *on the command line*. */
+#define COUNT_OPT(n) (DESC(n).optOccCt)
+/** mask of \a OPTST_SET and \a OPTST_DEFINED. */
+#define ISSEL_OPT(n) (SELECTED_OPT(&DESC(n)))
+/** 'true' if \a HAVE_OPT would yield 'false'. */
+#define ISUNUSED_OPT(n) (UNUSED_OPT(& DESC(n)))
+/** 'true' if OPTST_DISABLED bit not set. */
+#define ENABLED_OPT(n) (! DISABLED_OPT(& DESC(n)))
+/** number of stacked option arguments.
+ * Valid only for stacked option arguments. */
+#define STACKCT_OPT(n) (((tArgList*)(DESC(n).optCookie))->useCt)
+/** stacked argument vector.
+ * Valid only for stacked option arguments. */
+#define STACKLST_OPT(n) (((tArgList*)(DESC(n).optCookie))->apzArgs)
+/** Reset an option. */
+#define CLEAR_OPT(n) STMTS( \
+ DESC(n).fOptState &= OPTST_PERSISTENT_MASK; \
+ if ((DESC(n).fOptState & OPTST_INITENABLED) == 0) \
+ DESC(n).fOptState |= OPTST_DISABLED; \
+ DESC(n).optCookie = NULL )
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/**
+ * Enumeration of ntpd exit codes
+ */
+typedef enum {
+ NTPD_EXIT_SUCCESS = 0,
+ NTPD_EXIT_FAILURE = 1,
+ NTPD_EXIT_USAGE_ERROR = 64,
+ NTPD_EXIT_LIBOPTS_FAILURE = 70
+} ntpd_exit_code_t;
+/** @} */
+/**
+ * Make sure there are no #define name conflicts with the option names
+ */
+#ifndef NO_OPTION_NAME_WARNINGS
+# ifdef IPV4
+# warning undefining IPV4 due to option name conflict
+# undef IPV4
+# endif
+# ifdef IPV6
+# warning undefining IPV6 due to option name conflict
+# undef IPV6
+# endif
+# ifdef AUTHREQ
+# warning undefining AUTHREQ due to option name conflict
+# undef AUTHREQ
+# endif
+# ifdef AUTHNOREQ
+# warning undefining AUTHNOREQ due to option name conflict
+# undef AUTHNOREQ
+# endif
+# ifdef BCASTSYNC
+# warning undefining BCASTSYNC due to option name conflict
+# undef BCASTSYNC
+# endif
+# ifdef CONFIGFILE
+# warning undefining CONFIGFILE due to option name conflict
+# undef CONFIGFILE
+# endif
+# ifdef DEBUG_LEVEL
+# warning undefining DEBUG_LEVEL due to option name conflict
+# undef DEBUG_LEVEL
+# endif
+# ifdef SET_DEBUG_LEVEL
+# warning undefining SET_DEBUG_LEVEL due to option name conflict
+# undef SET_DEBUG_LEVEL
+# endif
+# ifdef DRIFTFILE
+# warning undefining DRIFTFILE due to option name conflict
+# undef DRIFTFILE
+# endif
+# ifdef PANICGATE
+# warning undefining PANICGATE due to option name conflict
+# undef PANICGATE
+# endif
+# ifdef FORCE_STEP_ONCE
+# warning undefining FORCE_STEP_ONCE due to option name conflict
+# undef FORCE_STEP_ONCE
+# endif
+# ifdef JAILDIR
+# warning undefining JAILDIR due to option name conflict
+# undef JAILDIR
+# endif
+# ifdef INTERFACE
+# warning undefining INTERFACE due to option name conflict
+# undef INTERFACE
+# endif
+# ifdef KEYFILE
+# warning undefining KEYFILE due to option name conflict
+# undef KEYFILE
+# endif
+# ifdef LOGFILE
+# warning undefining LOGFILE due to option name conflict
+# undef LOGFILE
+# endif
+# ifdef NOVIRTUALIPS
+# warning undefining NOVIRTUALIPS due to option name conflict
+# undef NOVIRTUALIPS
+# endif
+# ifdef MODIFYMMTIMER
+# warning undefining MODIFYMMTIMER due to option name conflict
+# undef MODIFYMMTIMER
+# endif
+# ifdef NOFORK
+# warning undefining NOFORK due to option name conflict
+# undef NOFORK
+# endif
+# ifdef NICE
+# warning undefining NICE due to option name conflict
+# undef NICE
+# endif
+# ifdef PIDFILE
+# warning undefining PIDFILE due to option name conflict
+# undef PIDFILE
+# endif
+# ifdef PRIORITY
+# warning undefining PRIORITY due to option name conflict
+# undef PRIORITY
+# endif
+# ifdef QUIT
+# warning undefining QUIT due to option name conflict
+# undef QUIT
+# endif
+# ifdef PROPAGATIONDELAY
+# warning undefining PROPAGATIONDELAY due to option name conflict
+# undef PROPAGATIONDELAY
+# endif
+# ifdef SAVECONFIGQUIT
+# warning undefining SAVECONFIGQUIT due to option name conflict
+# undef SAVECONFIGQUIT
+# endif
+# ifdef STATSDIR
+# warning undefining STATSDIR due to option name conflict
+# undef STATSDIR
+# endif
+# ifdef TRUSTEDKEY
+# warning undefining TRUSTEDKEY due to option name conflict
+# undef TRUSTEDKEY
+# endif
+# ifdef USER
+# warning undefining USER due to option name conflict
+# undef USER
+# endif
+# ifdef UPDATEINTERVAL
+# warning undefining UPDATEINTERVAL due to option name conflict
+# undef UPDATEINTERVAL
+# endif
+# ifdef VAR
+# warning undefining VAR due to option name conflict
+# undef VAR
+# endif
+# ifdef DVAR
+# warning undefining DVAR due to option name conflict
+# undef DVAR
+# endif
+# ifdef WAIT_SYNC
+# warning undefining WAIT_SYNC due to option name conflict
+# undef WAIT_SYNC
+# endif
+# ifdef SLEW
+# warning undefining SLEW due to option name conflict
+# undef SLEW
+# endif
+# ifdef USEPCC
+# warning undefining USEPCC due to option name conflict
+# undef USEPCC
+# endif
+# ifdef PCCFREQ
+# warning undefining PCCFREQ due to option name conflict
+# undef PCCFREQ
+# endif
+# ifdef MDNS
+# warning undefining MDNS due to option name conflict
+# undef MDNS
+# endif
+#else /* NO_OPTION_NAME_WARNINGS */
+# undef IPV4
+# undef IPV6
+# undef AUTHREQ
+# undef AUTHNOREQ
+# undef BCASTSYNC
+# undef CONFIGFILE
+# undef DEBUG_LEVEL
+# undef SET_DEBUG_LEVEL
+# undef DRIFTFILE
+# undef PANICGATE
+# undef FORCE_STEP_ONCE
+# undef JAILDIR
+# undef INTERFACE
+# undef KEYFILE
+# undef LOGFILE
+# undef NOVIRTUALIPS
+# undef MODIFYMMTIMER
+# undef NOFORK
+# undef NICE
+# undef PIDFILE
+# undef PRIORITY
+# undef QUIT
+# undef PROPAGATIONDELAY
+# undef SAVECONFIGQUIT
+# undef STATSDIR
+# undef TRUSTEDKEY
+# undef USER
+# undef UPDATEINTERVAL
+# undef VAR
+# undef DVAR
+# undef WAIT_SYNC
+# undef SLEW
+# undef USEPCC
+# undef PCCFREQ
+# undef MDNS
+#endif /* NO_OPTION_NAME_WARNINGS */
+
+/**
+ * Interface defines for specific options.
+ * @{
+ */
+#define VALUE_OPT_IPV4 '4'
+#define VALUE_OPT_IPV6 '6'
+#define VALUE_OPT_AUTHREQ 'a'
+#define VALUE_OPT_AUTHNOREQ 'A'
+#define VALUE_OPT_BCASTSYNC 'b'
+#define VALUE_OPT_CONFIGFILE 'c'
+#define VALUE_OPT_DEBUG_LEVEL 'd'
+#define VALUE_OPT_SET_DEBUG_LEVEL 'D'
+
+#define OPT_VALUE_SET_DEBUG_LEVEL (DESC(SET_DEBUG_LEVEL).optArg.argInt)
+#define VALUE_OPT_DRIFTFILE 'f'
+#define VALUE_OPT_PANICGATE 'g'
+#define VALUE_OPT_FORCE_STEP_ONCE 'G'
+#define VALUE_OPT_JAILDIR 'i'
+#define VALUE_OPT_INTERFACE 'I'
+#define VALUE_OPT_KEYFILE 'k'
+#define VALUE_OPT_LOGFILE 'l'
+#define VALUE_OPT_NOVIRTUALIPS 'L'
+#define VALUE_OPT_MODIFYMMTIMER 'M'
+#define VALUE_OPT_NOFORK 'n'
+#define VALUE_OPT_NICE 'N'
+#define VALUE_OPT_PIDFILE 'p'
+#define VALUE_OPT_PRIORITY 'P'
+
+#define OPT_VALUE_PRIORITY (DESC(PRIORITY).optArg.argInt)
+#define VALUE_OPT_QUIT 'q'
+#define VALUE_OPT_PROPAGATIONDELAY 'r'
+#define VALUE_OPT_SAVECONFIGQUIT 0x1001
+#define VALUE_OPT_STATSDIR 's'
+#define VALUE_OPT_TRUSTEDKEY 't'
+#define VALUE_OPT_USER 'u'
+#define VALUE_OPT_UPDATEINTERVAL 'U'
+
+#define OPT_VALUE_UPDATEINTERVAL (DESC(UPDATEINTERVAL).optArg.argInt)
+#define VALUE_OPT_VAR 0x1002
+#define VALUE_OPT_DVAR 0x1003
+#define VALUE_OPT_WAIT_SYNC 'w'
+#ifdef HAVE_WORKING_FORK
+#define OPT_VALUE_WAIT_SYNC (DESC(WAIT_SYNC).optArg.argInt)
+#endif /* HAVE_WORKING_FORK */
+#define VALUE_OPT_SLEW 'x'
+#define VALUE_OPT_USEPCC 0x1004
+#define VALUE_OPT_PCCFREQ 0x1005
+#define VALUE_OPT_MDNS 'm'
+/** option flag (value) for help-value option */
+#define VALUE_OPT_HELP '?'
+/** option flag (value) for more-help-value option */
+#define VALUE_OPT_MORE_HELP '!'
+/** option flag (value) for version-value option */
+#define VALUE_OPT_VERSION 0x1006
+/*
+ * Interface defines not associated with particular options
+ */
+#define ERRSKIP_OPTERR STMTS(ntpdOptions.fOptSet &= ~OPTPROC_ERRSTOP)
+#define ERRSTOP_OPTERR STMTS(ntpdOptions.fOptSet |= OPTPROC_ERRSTOP)
+#define RESTART_OPT(n) STMTS( \
+ ntpdOptions.curOptIdx = (n); \
+ ntpdOptions.pzCurOpt = NULL )
+#define START_OPT RESTART_OPT(1)
+#define USAGE(c) (*ntpdOptions.pUsageProc)(&ntpdOptions, c)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* * * * * *
+ *
+ * Declare the ntpd option descriptor.
+ */
+extern tOptions ntpdOptions;
+
+#if defined(ENABLE_NLS)
+# ifndef _
+# include <stdio.h>
+# ifndef HAVE_GETTEXT
+ extern char * gettext(char const *);
+# else
+# include <libintl.h>
+# endif
+
+# ifndef ATTRIBUTE_FORMAT_ARG
+# define ATTRIBUTE_FORMAT_ARG(_a)
+# endif
+
+static inline char* aoGetsText(char const* pz) ATTRIBUTE_FORMAT_ARG(1);
+static inline char* aoGetsText(char const* pz) {
+ if (pz == NULL) return NULL;
+ return (char*)gettext(pz);
+}
+# define _(s) aoGetsText(s)
+# endif /* _() */
+
+# define OPT_NO_XLAT_CFG_NAMES STMTS(ntpdOptions.fOptSet |= \
+ OPTPROC_NXLAT_OPT_CFG;)
+# define OPT_NO_XLAT_OPT_NAMES STMTS(ntpdOptions.fOptSet |= \
+ OPTPROC_NXLAT_OPT|OPTPROC_NXLAT_OPT_CFG;)
+
+# define OPT_XLAT_CFG_NAMES STMTS(ntpdOptions.fOptSet &= \
+ ~(OPTPROC_NXLAT_OPT|OPTPROC_NXLAT_OPT_CFG);)
+# define OPT_XLAT_OPT_NAMES STMTS(ntpdOptions.fOptSet &= \
+ ~OPTPROC_NXLAT_OPT;)
+
+#else /* ENABLE_NLS */
+# define OPT_NO_XLAT_CFG_NAMES
+# define OPT_NO_XLAT_OPT_NAMES
+
+# define OPT_XLAT_CFG_NAMES
+# define OPT_XLAT_OPT_NAMES
+
+# ifndef _
+# define _(_s) _s
+# endif
+#endif /* ENABLE_NLS */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* AUTOOPTS_NTPD_OPTS_H_GUARD */
+
+/* ntpd-opts.h ends here */
diff --git a/sebhbsd/freebsd/contrib/ntp/ntpd/ntpd.c b/sebhbsd/freebsd/contrib/ntp/ntpd/ntpd.c
new file mode 100644
index 0000000..e9e1ba5
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/ntpd/ntpd.c
@@ -0,0 +1,1804 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * ntpd.c - main program for the fixed point NTP daemon
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "ntp_machine.h"
+#include "ntpd.h"
+#include "ntp_io.h"
+#include "ntp_stdlib.h"
+#include <ntp_random.h>
+
+#include "ntp_config.h"
+#include "ntp_syslog.h"
+#include "ntp_assert.h"
+#include "isc/error.h"
+#include "isc/strerror.h"
+#include "isc/formatcheck.h"
+#include "iosignal.h"
+
+#ifdef SIM
+# include "ntpsim.h"
+#endif
+
+#include "ntp_libopts.h"
+#include "ntpd-opts.h"
+
+/* there's a short treatise below what the thread stuff is for.
+ * [Bug 2954] enable the threading warm-up only for Linux.
+ */
+#if defined(HAVE_PTHREADS) && HAVE_PTHREADS && !defined(NO_THREADS)
+# ifdef HAVE_PTHREAD_H
+# include <pthread.h>
+# endif
+# if defined(linux)
+# define NEED_PTHREAD_WARMUP
+# endif
+#endif
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#include <stdio.h>
+#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif
+#ifdef HAVE_SYS_SIGNAL_H
+# include <sys/signal.h>
+#else
+# include <signal.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif /* HAVE_SYS_IOCTL_H */
+#if defined(HAVE_RTPRIO)
+# ifdef HAVE_SYS_LOCK_H
+# include <sys/lock.h>
+# endif
+# include <sys/rtprio.h>
+#else
+# ifdef HAVE_PLOCK
+# ifdef HAVE_SYS_LOCK_H
+# include <sys/lock.h>
+# endif
+# endif
+#endif
+#if defined(HAVE_SCHED_SETSCHEDULER)
+# ifdef HAVE_SCHED_H
+# include <sched.h>
+# else
+# ifdef HAVE_SYS_SCHED_H
+# include <sys/sched.h>
+# endif
+# endif
+#endif
+#if defined(HAVE_SYS_MMAN_H)
+# include <sys/mman.h>
+#endif
+
+#ifdef HAVE_TERMIOS_H
+# include <termios.h>
+#endif
+
+#ifdef SYS_DOMAINOS
+# include <apollo/base.h>
+#endif /* SYS_DOMAINOS */
+
+
+#include "recvbuff.h"
+#include "ntp_cmdargs.h"
+
+#if 0 /* HMS: I don't think we need this. 961223 */
+#ifdef LOCK_PROCESS
+# ifdef SYS_SOLARIS
+# include <sys/mman.h>
+# else
+# include <sys/lock.h>
+# endif
+#endif
+#endif
+
+#ifdef SYS_WINNT
+# include "ntservice.h"
+#endif
+
+#ifdef _AIX
+# include <ulimit.h>
+#endif /* _AIX */
+
+#ifdef SCO5_CLOCK
+# include <sys/ci/ciioctl.h>
+#endif
+
+#ifdef HAVE_DROPROOT
+# include <ctype.h>
+# include <grp.h>
+# include <pwd.h>
+#ifdef HAVE_LINUX_CAPABILITIES
+# include <sys/capability.h>
+# include <sys/prctl.h>
+#endif /* HAVE_LINUX_CAPABILITIES */
+#if defined(HAVE_PRIV_H) && defined(HAVE_SOLARIS_PRIVS)
+# include <priv.h>
+#endif /* HAVE_PRIV_H */
+#if defined(HAVE_TRUSTEDBSD_MAC)
+# include <sys/mac.h>
+#endif /* HAVE_TRUSTEDBSD_MAC */
+#endif /* HAVE_DROPROOT */
+
+#if defined (LIBSECCOMP) && (KERN_SECCOMP)
+/* # include <sys/types.h> */
+# include <sys/resource.h>
+# include <seccomp.h>
+#endif /* LIBSECCOMP and KERN_SECCOMP */
+
+#ifndef __rtems__
+#ifdef __FreeBSD__
+#include <sys/procctl.h>
+#ifndef PROC_STACKGAP_CTL
+/*
+ * Even if we compile on an older system we can still run on a newer one.
+ */
+#define PROC_STACKGAP_CTL 17
+#define PROC_STACKGAP_DISABLE 0x0002
+#endif
+#endif
+#else /* __rtems__ */
+#include <rtems/ntpd.h>
+#endif /* __rtems__ */
+
+#ifdef HAVE_DNSREGISTRATION
+# include <dns_sd.h>
+DNSServiceRef mdns;
+#endif
+
+#ifdef HAVE_SETPGRP_0
+# define ntp_setpgrp(x, y) setpgrp()
+#else
+# define ntp_setpgrp(x, y) setpgrp(x, y)
+#endif
+
+#ifdef HAVE_SOLARIS_PRIVS
+# define LOWPRIVS "basic,sys_time,net_privaddr,proc_setid,!proc_info,!proc_session,!proc_exec"
+static priv_set_t *lowprivs = NULL;
+static priv_set_t *highprivs = NULL;
+#endif /* HAVE_SOLARIS_PRIVS */
+/*
+ * Scheduling priority we run at
+ */
+#define NTPD_PRIO (-12)
+
+int priority_done = 2; /* 0 - Set priority */
+ /* 1 - priority is OK where it is */
+ /* 2 - Don't set priority */
+ /* 1 and 2 are pretty much the same */
+
+int listen_to_virtual_ips = TRUE;
+
+/*
+ * No-fork flag. If set, we do not become a background daemon.
+ */
+int nofork; /* Fork by default */
+
+#ifdef HAVE_DNSREGISTRATION
+/*
+ * mDNS registration flag. If set, we attempt to register with the mDNS system, but only
+ * after we have synched the first time. If the attempt fails, then try again once per
+ * minute for up to 5 times. After all, we may be starting before mDNS.
+ */
+int mdnsreg = FALSE;
+int mdnstries = 5;
+#endif /* HAVE_DNSREGISTRATION */
+
+#ifdef HAVE_DROPROOT
+int droproot;
+int root_dropped;
+char *user; /* User to switch to */
+char *group; /* group to switch to */
+const char *chrootdir; /* directory to chroot to */
+uid_t sw_uid;
+gid_t sw_gid;
+struct group *gr;
+struct passwd *pw;
+#endif /* HAVE_DROPROOT */
+
+#ifdef HAVE_WORKING_FORK
+int waitsync_fd_to_close = -1; /* -w/--wait-sync */
+#endif
+
+/*
+ * Version declaration
+ */
+extern const char *Version;
+
+char const *progname;
+
+int was_alarmed;
+
+#ifdef DECL_SYSCALL
+/*
+ * We put this here, since the argument profile is syscall-specific
+ */
+extern int syscall (int, ...);
+#endif /* DECL_SYSCALL */
+
+
+#if !defined(SIM) && defined(SIGDIE1)
+static volatile int signalled = 0;
+static volatile int signo = 0;
+
+/* In an ideal world, 'finish_safe()' would declared as noreturn... */
+static void finish_safe (int);
+static RETSIGTYPE finish (int);
+#endif
+
+#if !defined(SIM) && defined(HAVE_WORKING_FORK)
+static int wait_child_sync_if (int, long);
+#endif
+
+#if !defined(SIM) && !defined(SYS_WINNT)
+# ifdef DEBUG
+static RETSIGTYPE moredebug (int);
+static RETSIGTYPE lessdebug (int);
+# else /* !DEBUG follows */
+static RETSIGTYPE no_debug (int);
+# endif /* !DEBUG */
+#endif /* !SIM && !SYS_WINNT */
+
+#ifndef WORK_FORK
+int saved_argc;
+char ** saved_argv;
+#endif
+
+#ifndef SIM
+#ifdef __rtems__
+static
+#endif /* __rtems__ */
+int ntpdmain (int, char **);
+static void set_process_priority (void);
+static void assertion_failed (const char *, int,
+ isc_assertiontype_t,
+ const char *)
+ __attribute__ ((__noreturn__));
+static void library_fatal_error (const char *, int,
+ const char *, va_list)
+ ISC_FORMAT_PRINTF(3, 0);
+static void library_unexpected_error(const char *, int,
+ const char *, va_list)
+ ISC_FORMAT_PRINTF(3, 0);
+#endif /* !SIM */
+
+
+/* Bug2332 unearthed a problem in the interaction of reduced user
+ * privileges, the limits on memory usage and some versions of the
+ * pthread library on Linux systems. The 'pthread_cancel()' function and
+ * likely some others need to track the stack of the thread involved,
+ * and uses a function that comes from GCC (--> libgcc_s.so) to do
+ * this. Unfortunately the developers of glibc decided to load the
+ * library on demand, which speeds up program start but can cause
+ * trouble here: Due to all the things NTPD does to limit its resource
+ * usage, this deferred load of libgcc_s does not always work once the
+ * restrictions are in effect.
+ *
+ * One way out of this was attempting a forced link against libgcc_s
+ * when possible because it makes the library available immediately
+ * without deferred load. (The symbol resolution would still be dynamic
+ * and on demand, but the code would already be in the process image.)
+ *
+ * This is a tricky thing to do, since it's not necessary everywhere,
+ * not possible everywhere, has shown to break the build of other
+ * programs in the NTP suite and is now generally frowned upon.
+ *
+ * So we take a different approach here: We creat a worker thread that does
+ * actually nothing except waiting for cancellation and cancel it. If
+ * this is done before all the limitations are put in place, the
+ * machinery is pre-heated and all the runtime stuff should be in place
+ * and useable when needed.
+ *
+ * This uses only the standard pthread API and should work with all
+ * implementations of pthreads. It is not necessary everywhere, but it's
+ * cheap enough to go on nearly unnoticed.
+ *
+ * Addendum: Bug 2954 showed that the assumption that this should work
+ * with all OS is wrong -- at least FreeBSD bombs heavily.
+ */
+#ifdef NEED_PTHREAD_WARMUP
+
+/* simple thread function: sleep until cancelled, just to exercise
+ * thread cancellation.
+ */
+static void*
+my_pthread_warmup_worker(
+ void *thread_args)
+{
+ (void)thread_args;
+ for (;;)
+ sleep(10);
+ return NULL;
+}
+
+/* pre-heat threading: create a thread and cancel it, just to exercise
+ * thread cancellation.
+ */
+static void
+my_pthread_warmup(void)
+{
+ pthread_t thread;
+ pthread_attr_t thr_attr;
+ int rc;
+
+ pthread_attr_init(&thr_attr);
+#if defined(HAVE_PTHREAD_ATTR_GETSTACKSIZE) && \
+ defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE) && \
+ defined(PTHREAD_STACK_MIN)
+ {
+ size_t ssmin = 32*1024; /* 32kB should be minimum */
+ if (ssmin < PTHREAD_STACK_MIN)
+ ssmin = PTHREAD_STACK_MIN;
+ rc = pthread_attr_setstacksize(&thr_attr, ssmin);
+ if (0 != rc)
+ msyslog(LOG_ERR,
+ "my_pthread_warmup: pthread_attr_setstacksize() -> %s",
+ strerror(rc));
+ }
+#endif
+ rc = pthread_create(
+ &thread, &thr_attr, my_pthread_warmup_worker, NULL);
+ pthread_attr_destroy(&thr_attr);
+ if (0 != rc) {
+ msyslog(LOG_ERR,
+ "my_pthread_warmup: pthread_create() -> %s",
+ strerror(rc));
+ } else {
+ pthread_cancel(thread);
+ pthread_join(thread, NULL);
+ }
+}
+
+#endif /*defined(NEED_PTHREAD_WARMUP)*/
+
+#ifdef NEED_EARLY_FORK
+static void
+dummy_callback(void) { return; }
+
+static void
+fork_nonchroot_worker(void) {
+ getaddrinfo_sometime("localhost", "ntp", NULL, INITIAL_DNS_RETRY,
+ (gai_sometime_callback)&dummy_callback, NULL);
+}
+#endif /* NEED_EARLY_FORK */
+
+void
+parse_cmdline_opts(
+ int * pargc,
+ char ***pargv
+ )
+{
+ static int parsed;
+ static int optct;
+
+ if (!parsed)
+ optct = ntpOptionProcess(&ntpdOptions, *pargc, *pargv);
+
+ parsed = 1;
+
+ *pargc -= optct;
+ *pargv += optct;
+}
+
+
+#ifndef __rtems__
+#ifdef SIM
+int
+main(
+ int argc,
+ char *argv[]
+ )
+{
+ progname = argv[0];
+ parse_cmdline_opts(&argc, &argv);
+#ifdef DEBUG
+ debug = OPT_VALUE_SET_DEBUG_LEVEL;
+ DPRINTF(1, ("%s\n", Version));
+#endif
+
+ return ntpsim(argc, argv);
+}
+#else /* !SIM follows */
+#ifdef NO_MAIN_ALLOWED
+CALL(ntpd,"ntpd",ntpdmain);
+#else /* !NO_MAIN_ALLOWED follows */
+#ifndef SYS_WINNT
+int
+main(
+ int argc,
+ char *argv[]
+ )
+{
+#ifdef __FreeBSD__
+ {
+ /*
+ * We Must disable ASLR stack gap on FreeBSD to avoid a
+ * segfault. See PR/241421 and PR/241960.
+ */
+ int aslr_var = PROC_STACKGAP_DISABLE;
+
+ pid_t my_pid = getpid();
+ procctl(P_PID, my_pid, PROC_STACKGAP_CTL, &aslr_var);
+ }
+#endif
+ return ntpdmain(argc, argv);
+}
+#endif /* !SYS_WINNT */
+#endif /* !NO_MAIN_ALLOWED */
+#endif /* !SIM */
+#endif /* __rtems__ */
+
+#ifdef _AIX
+/*
+ * OK. AIX is different than solaris in how it implements plock().
+ * If you do NOT adjust the stack limit, you will get the MAXIMUM
+ * stack size allocated and PINNED with you program. To check the
+ * value, use ulimit -a.
+ *
+ * To fix this, we create an automatic variable and set our stack limit
+ * to that PLUS 32KB of extra space (we need some headroom).
+ *
+ * This subroutine gets the stack address.
+ *
+ * Grover Davidson and Matt Ladendorf
+ *
+ */
+static char *
+get_aix_stack(void)
+{
+ char ch;
+ return (&ch);
+}
+
+/*
+ * Signal handler for SIGDANGER.
+ */
+static void
+catch_danger(int signo)
+{
+ msyslog(LOG_INFO, "ntpd: setpgid(): %m");
+ /* Make the system believe we'll free something, but don't do it! */
+ return;
+}
+#endif /* _AIX */
+
+/*
+ * Set the process priority
+ */
+#ifndef SIM
+static void
+set_process_priority(void)
+{
+
+# ifdef DEBUG
+ if (debug > 1)
+ msyslog(LOG_DEBUG, "set_process_priority: %s: priority_done is <%d>",
+ ((priority_done)
+ ? "Leave priority alone"
+ : "Attempt to set priority"
+ ),
+ priority_done);
+# endif /* DEBUG */
+
+# if defined(HAVE_SCHED_SETSCHEDULER)
+ if (!priority_done) {
+ extern int config_priority_override, config_priority;
+ int pmax, pmin;
+ struct sched_param sched;
+
+ pmax = sched_get_priority_max(SCHED_FIFO);
+ sched.sched_priority = pmax;
+ if ( config_priority_override ) {
+ pmin = sched_get_priority_min(SCHED_FIFO);
+ if ( config_priority > pmax )
+ sched.sched_priority = pmax;
+ else if ( config_priority < pmin )
+ sched.sched_priority = pmin;
+ else
+ sched.sched_priority = config_priority;
+ }
+ if ( sched_setscheduler(0, SCHED_FIFO, &sched) == -1 )
+ msyslog(LOG_ERR, "sched_setscheduler(): %m");
+ else
+ ++priority_done;
+ }
+# endif /* HAVE_SCHED_SETSCHEDULER */
+# ifdef HAVE_RTPRIO
+# ifdef RTP_SET
+ if (!priority_done) {
+ struct rtprio srtp;
+
+ srtp.type = RTP_PRIO_REALTIME; /* was: RTP_PRIO_NORMAL */
+ srtp.prio = 0; /* 0 (hi) -> RTP_PRIO_MAX (31,lo) */
+
+ if (rtprio(RTP_SET, getpid(), &srtp) < 0)
+ msyslog(LOG_ERR, "rtprio() error: %m");
+ else
+ ++priority_done;
+ }
+# else /* !RTP_SET follows */
+ if (!priority_done) {
+ if (rtprio(0, 120) < 0)
+ msyslog(LOG_ERR, "rtprio() error: %m");
+ else
+ ++priority_done;
+ }
+# endif /* !RTP_SET */
+# endif /* HAVE_RTPRIO */
+# if defined(NTPD_PRIO) && NTPD_PRIO != 0
+# ifdef HAVE_ATT_NICE
+ if (!priority_done) {
+ errno = 0;
+ if (-1 == nice (NTPD_PRIO) && errno != 0)
+ msyslog(LOG_ERR, "nice() error: %m");
+ else
+ ++priority_done;
+ }
+# endif /* HAVE_ATT_NICE */
+# ifdef HAVE_BSD_NICE
+ if (!priority_done) {
+ if (-1 == setpriority(PRIO_PROCESS, 0, NTPD_PRIO))
+ msyslog(LOG_ERR, "setpriority() error: %m");
+ else
+ ++priority_done;
+ }
+# endif /* HAVE_BSD_NICE */
+# endif /* NTPD_PRIO && NTPD_PRIO != 0 */
+ if (!priority_done)
+ msyslog(LOG_ERR, "set_process_priority: No way found to improve our priority");
+}
+#endif /* !SIM */
+
+#if !defined(SIM) && !defined(SYS_WINNT)
+/*
+ * Detach from terminal (much like daemon())
+ * Nothe that this function calls exit()
+ */
+# ifdef HAVE_WORKING_FORK
+static void
+detach_from_terminal(
+ int pipe_fds[2],
+ long wait_sync,
+ const char *logfilename
+ )
+{
+ int rc;
+ int exit_code;
+# if !defined(HAVE_SETSID) && !defined (HAVE_SETPGID) && defined(TIOCNOTTY)
+ int fid;
+# endif
+# ifdef _AIX
+ struct sigaction sa;
+# endif
+
+ rc = fork();
+ if (-1 == rc) {
+ exit_code = (errno) ? errno : -1;
+ msyslog(LOG_ERR, "fork: %m");
+ exit(exit_code);
+ }
+ if (rc > 0) {
+ /* parent */
+ exit_code = wait_child_sync_if(pipe_fds[0],
+ wait_sync);
+ exit(exit_code);
+ }
+
+ /*
+ * child/daemon
+ * close all open files excepting waitsync_fd_to_close.
+ * msyslog() unreliable until after init_logging().
+ */
+ closelog();
+ if (syslog_file != NULL) {
+ fclose(syslog_file);
+ syslog_file = NULL;
+ syslogit = TRUE;
+ }
+ close_all_except(waitsync_fd_to_close);
+ INSIST(0 == open("/dev/null", 0) && 1 == dup2(0, 1) \
+ && 2 == dup2(0, 2));
+
+ init_logging(progname, 0, TRUE);
+ /* we lost our logfile (if any) daemonizing */
+ setup_logfile(logfilename);
+
+# ifdef SYS_DOMAINOS
+ {
+ uid_$t puid;
+ status_$t st;
+
+ proc2_$who_am_i(&puid);
+ proc2_$make_server(&puid, &st);
+ }
+# endif /* SYS_DOMAINOS */
+# ifdef HAVE_SETSID
+ if (setsid() == (pid_t)-1)
+ msyslog(LOG_ERR, "setsid(): %m");
+# elif defined(HAVE_SETPGID)
+ if (setpgid(0, 0) == -1)
+ msyslog(LOG_ERR, "setpgid(): %m");
+# else /* !HAVE_SETSID && !HAVE_SETPGID follows */
+# ifdef TIOCNOTTY
+ fid = open("/dev/tty", 2);
+ if (fid >= 0) {
+ ioctl(fid, (u_long)TIOCNOTTY, NULL);
+ close(fid);
+ }
+# endif /* TIOCNOTTY */
+ ntp_setpgrp(0, getpid());
+# endif /* !HAVE_SETSID && !HAVE_SETPGID */
+# ifdef _AIX
+ /* Don't get killed by low-on-memory signal. */
+ sa.sa_handler = catch_danger;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_RESTART;
+ sigaction(SIGDANGER, &sa, NULL);
+# endif /* _AIX */
+
+ return;
+}
+# endif /* HAVE_WORKING_FORK */
+
+#ifdef HAVE_DROPROOT
+/*
+ * Map user name/number to user ID
+*/
+static int
+map_user(
+ )
+{
+ char *endp;
+
+ if (isdigit((unsigned char)*user)) {
+ sw_uid = (uid_t)strtoul(user, &endp, 0);
+ if (*endp != '\0')
+ goto getuser;
+
+ if ((pw = getpwuid(sw_uid)) != NULL) {
+ free(user);
+ user = estrdup(pw->pw_name);
+ sw_gid = pw->pw_gid;
+ } else {
+ errno = 0;
+ msyslog(LOG_ERR, "Cannot find user ID %s", user);
+ return 0;
+ }
+
+ } else {
+getuser:
+ errno = 0;
+ if ((pw = getpwnam(user)) != NULL) {
+ sw_uid = pw->pw_uid;
+ sw_gid = pw->pw_gid;
+ } else {
+ if (errno)
+ msyslog(LOG_ERR, "getpwnam(%s) failed: %m", user);
+ else
+ msyslog(LOG_ERR, "Cannot find user `%s'", user);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+/*
+ * Map group name/number to group ID
+*/
+static int
+map_group(void)
+{
+ char *endp;
+
+ if (isdigit((unsigned char)*group)) {
+ sw_gid = (gid_t)strtoul(group, &endp, 0);
+ if (*endp != '\0')
+ goto getgroup;
+ } else {
+getgroup:
+ if ((gr = getgrnam(group)) != NULL) {
+ sw_gid = gr->gr_gid;
+ } else {
+ errno = 0;
+ msyslog(LOG_ERR, "Cannot find group `%s'", group);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+static int
+set_group_ids(void)
+{
+ if (user && initgroups(user, sw_gid)) {
+ msyslog(LOG_ERR, "Cannot initgroups() to user `%s': %m", user);
+ return 0;
+ }
+ if (group && setgid(sw_gid)) {
+ msyslog(LOG_ERR, "Cannot setgid() to group `%s': %m", group);
+ return 0;
+ }
+ if (group && setegid(sw_gid)) {
+ msyslog(LOG_ERR, "Cannot setegid() to group `%s': %m", group);
+ return 0;
+ }
+ if (group) {
+ if (0 != setgroups(1, &sw_gid)) {
+ msyslog(LOG_ERR, "setgroups(1, %d) failed: %m", sw_gid);
+ return 0;
+ }
+ }
+ else if (pw)
+ if (0 != initgroups(pw->pw_name, pw->pw_gid)) {
+ msyslog(LOG_ERR, "initgroups(<%s>, %d) filed: %m", pw->pw_name, pw->pw_gid);
+ return 0;
+ }
+ return 1;
+}
+
+static int
+set_user_ids(void)
+{
+ if (user && setuid(sw_uid)) {
+ msyslog(LOG_ERR, "Cannot setuid() to user `%s': %m", user);
+ return 0;
+ }
+ if (user && seteuid(sw_uid)) {
+ msyslog(LOG_ERR, "Cannot seteuid() to user `%s': %m", user);
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * Change (effective) user and group IDs, also initialize the supplementary group access list
+ */
+int set_user_group_ids(void);
+int
+set_user_group_ids(void)
+{
+ /* If the the user was already mapped, no need to map it again */
+ if ((NULL != user) && (0 == sw_uid)) {
+ if (0 == map_user())
+ exit (-1);
+ }
+ /* same applies for the group */
+ if ((NULL != group) && (0 == sw_gid)) {
+ if (0 == map_group())
+ exit (-1);
+ }
+
+ if (getegid() != sw_gid && 0 == set_group_ids())
+ return 0;
+ if (geteuid() != sw_uid && 0 == set_user_ids())
+ return 0;
+
+ return 1;
+}
+#endif /* HAVE_DROPROOT */
+#endif /* !SIM */
+
+/*
+ * Main program. Initialize us, disconnect us from the tty if necessary,
+ * and loop waiting for I/O and/or timer expiries.
+ */
+#ifndef SIM
+int
+ntpdmain(
+ int argc,
+ char *argv[]
+ )
+{
+ l_fp now;
+ struct recvbuf *rbuf;
+ const char * logfilename;
+# ifdef HAVE_UMASK
+ mode_t uv;
+# endif
+# if defined(HAVE_GETUID) && !defined(MPE) /* MPE lacks the concept of root */
+ uid_t uid;
+# endif
+# if defined(HAVE_WORKING_FORK)
+ long wait_sync = 0;
+ int pipe_fds[2];
+ int rc;
+ int exit_code;
+# endif /* HAVE_WORKING_FORK*/
+# ifdef SCO5_CLOCK
+ int fd;
+ int zero;
+# endif
+
+# ifdef NEED_PTHREAD_WARMUP
+ my_pthread_warmup();
+# endif
+
+# ifdef HAVE_UMASK
+ uv = umask(0);
+ if (uv)
+ umask(uv);
+ else
+ umask(022);
+# endif
+ saved_argc = argc;
+ saved_argv = argv;
+ progname = argv[0];
+ initializing = TRUE; /* mark that we are initializing */
+ parse_cmdline_opts(&argc, &argv);
+# ifdef DEBUG
+ debug = OPT_VALUE_SET_DEBUG_LEVEL;
+# ifdef HAVE_SETLINEBUF
+ setlinebuf(stdout);
+# endif
+# endif
+
+ if (HAVE_OPT(NOFORK) || HAVE_OPT(QUIT)
+# ifdef DEBUG
+ || debug
+# endif
+ || HAVE_OPT(SAVECONFIGQUIT))
+ nofork = TRUE;
+
+ init_logging(progname, NLOG_SYNCMASK, TRUE);
+ /* honor -l/--logfile option to log to a file */
+ if (HAVE_OPT(LOGFILE)) {
+ logfilename = OPT_ARG(LOGFILE);
+ syslogit = FALSE;
+ change_logfile(logfilename, FALSE);
+ } else {
+ logfilename = NULL;
+ if (nofork)
+ msyslog_term = TRUE;
+ if (HAVE_OPT(SAVECONFIGQUIT))
+ syslogit = FALSE;
+ }
+ msyslog(LOG_NOTICE, "%s: Starting", Version);
+
+ {
+ int i;
+ char buf[1024]; /* Secret knowledge of msyslog buf length */
+ char *cp = buf;
+
+ /* Note that every arg has an initial space character */
+ snprintf(cp, sizeof(buf), "Command line:");
+ cp += strlen(cp);
+
+ for (i = 0; i < saved_argc ; ++i) {
+ snprintf(cp, sizeof(buf) - (cp - buf),
+ " %s", saved_argv[i]);
+ cp += strlen(cp);
+ }
+ msyslog(LOG_INFO, "%s", buf);
+ }
+
+ /*
+ * Install trap handlers to log errors and assertion failures.
+ * Default handlers print to stderr which doesn't work if detached.
+ */
+ isc_assertion_setcallback(assertion_failed);
+ isc_error_setfatal(library_fatal_error);
+ isc_error_setunexpected(library_unexpected_error);
+
+ /* MPE lacks the concept of root */
+# if defined(HAVE_GETUID) && !defined(MPE)
+ uid = getuid();
+ if (uid && !HAVE_OPT( SAVECONFIGQUIT )
+# if defined(HAVE_TRUSTEDBSD_MAC)
+ /* We can run as non-root if the mac_ntpd policy is enabled. */
+ && mac_is_present("ntpd") != 1
+# endif
+ ) {
+ msyslog_term = TRUE;
+ msyslog(LOG_ERR,
+ "must be run as root, not uid %ld", (long)uid);
+ exit(1);
+ }
+# endif
+
+/*
+ * Enable the Multi-Media Timer for Windows?
+ */
+# ifdef SYS_WINNT
+ if (HAVE_OPT( MODIFYMMTIMER ))
+ set_mm_timer(MM_TIMER_HIRES);
+# endif
+
+#ifdef HAVE_DNSREGISTRATION
+/*
+ * Enable mDNS registrations?
+ */
+ if (HAVE_OPT( MDNS )) {
+ mdnsreg = TRUE;
+ }
+#endif /* HAVE_DNSREGISTRATION */
+
+ if (HAVE_OPT( NOVIRTUALIPS ))
+ listen_to_virtual_ips = 0;
+
+ /*
+ * --interface, listen on specified interfaces
+ */
+ if (HAVE_OPT( INTERFACE )) {
+ int ifacect = STACKCT_OPT( INTERFACE );
+ const char** ifaces = STACKLST_OPT( INTERFACE );
+ sockaddr_u addr;
+
+ while (ifacect-- > 0) {
+ add_nic_rule(
+ is_ip_address(*ifaces, AF_UNSPEC, &addr)
+ ? MATCH_IFADDR
+ : MATCH_IFNAME,
+ *ifaces, -1, ACTION_LISTEN);
+ ifaces++;
+ }
+ }
+
+ if (HAVE_OPT( NICE ))
+ priority_done = 0;
+
+# ifdef HAVE_SCHED_SETSCHEDULER
+ if (HAVE_OPT( PRIORITY )) {
+ config_priority = OPT_VALUE_PRIORITY;
+ config_priority_override = 1;
+ priority_done = 0;
+ }
+# endif
+
+# ifdef HAVE_WORKING_FORK
+ /* make sure the FDs are initialised */
+ pipe_fds[0] = -1;
+ pipe_fds[1] = -1;
+ do { /* 'loop' once */
+ if (!HAVE_OPT( WAIT_SYNC ))
+ break;
+ wait_sync = OPT_VALUE_WAIT_SYNC;
+ if (wait_sync <= 0) {
+ wait_sync = 0;
+ break;
+ }
+ /* -w requires a fork() even with debug > 0 */
+ nofork = FALSE;
+ if (pipe(pipe_fds)) {
+ exit_code = (errno) ? errno : -1;
+ msyslog(LOG_ERR,
+ "Pipe creation failed for --wait-sync: %m");
+ exit(exit_code);
+ }
+ waitsync_fd_to_close = pipe_fds[1];
+ } while (0); /* 'loop' once */
+# endif /* HAVE_WORKING_FORK */
+
+ init_lib();
+# ifdef SYS_WINNT
+ /*
+ * Make sure the service is initialized before we do anything else
+ */
+ ntservice_init();
+
+ /*
+ * Start interpolation thread, must occur before first
+ * get_systime()
+ */
+ init_winnt_time();
+# endif
+ /*
+ * Initialize random generator and public key pair
+ */
+ get_systime(&now);
+
+ ntp_srandom((int)(now.l_i * now.l_uf));
+
+ /*
+ * Detach us from the terminal. May need an #ifndef GIZMO.
+ */
+ if (!nofork) {
+
+# ifdef HAVE_WORKING_FORK
+ detach_from_terminal(pipe_fds, wait_sync, logfilename);
+# endif /* HAVE_WORKING_FORK */
+ }
+
+# ifdef SCO5_CLOCK
+ /*
+ * SCO OpenServer's system clock offers much more precise timekeeping
+ * on the base CPU than the other CPUs (for multiprocessor systems),
+ * so we must lock to the base CPU.
+ */
+ fd = open("/dev/at1", O_RDONLY);
+ if (fd >= 0) {
+ zero = 0;
+ if (ioctl(fd, ACPU_LOCK, &zero) < 0)
+ msyslog(LOG_ERR, "cannot lock to base CPU: %m");
+ close(fd);
+ }
+# endif
+
+ /* Setup stack size in preparation for locking pages in memory. */
+# if defined(HAVE_MLOCKALL)
+# ifdef HAVE_SETRLIMIT
+ ntp_rlimit(RLIMIT_STACK, DFLT_RLIMIT_STACK * 4096, 4096, "4k");
+# if defined(RLIMIT_MEMLOCK) && defined(DFLT_RLIMIT_MEMLOCK) && DFLT_RLIMIT_MEMLOCK != -1
+ /*
+ * The default RLIMIT_MEMLOCK is very low on Linux systems.
+ * Unless we increase this limit malloc calls are likely to
+ * fail if we drop root privilege. To be useful the value
+ * has to be larger than the largest ntpd resident set size.
+ */
+ ntp_rlimit(RLIMIT_MEMLOCK, DFLT_RLIMIT_MEMLOCK * 1024 * 1024, 1024 * 1024, "MB");
+# endif /* RLIMIT_MEMLOCK */
+# endif /* HAVE_SETRLIMIT */
+# else /* !HAVE_MLOCKALL follows */
+# ifdef HAVE_PLOCK
+# ifdef PROCLOCK
+# ifdef _AIX
+ /*
+ * set the stack limit for AIX for plock().
+ * see get_aix_stack() for more info.
+ */
+ if (ulimit(SET_STACKLIM, (get_aix_stack() - 8 * 4096)) < 0)
+ msyslog(LOG_ERR,
+ "Cannot adjust stack limit for plock: %m");
+# endif /* _AIX */
+# endif /* PROCLOCK */
+# endif /* HAVE_PLOCK */
+# endif /* !HAVE_MLOCKALL */
+
+ /*
+ * Set up signals we pay attention to locally.
+ */
+# ifdef SIGDIE1
+ signal_no_reset(SIGDIE1, finish);
+ signal_no_reset(SIGDIE2, finish);
+ signal_no_reset(SIGDIE3, finish);
+ signal_no_reset(SIGDIE4, finish);
+# endif
+# ifdef SIGBUS
+ signal_no_reset(SIGBUS, finish);
+# endif
+
+# if !defined(SYS_WINNT) && !defined(VMS)
+# ifdef DEBUG
+ (void) signal_no_reset(MOREDEBUGSIG, moredebug);
+ (void) signal_no_reset(LESSDEBUGSIG, lessdebug);
+# else
+ (void) signal_no_reset(MOREDEBUGSIG, no_debug);
+ (void) signal_no_reset(LESSDEBUGSIG, no_debug);
+# endif /* DEBUG */
+# endif /* !SYS_WINNT && !VMS */
+
+ /*
+ * Set up signals we should never pay attention to.
+ */
+# ifdef SIGPIPE
+ signal_no_reset(SIGPIPE, SIG_IGN);
+# endif
+
+ /*
+ * Call the init_ routines to initialize the data structures.
+ *
+ * Exactly what command-line options are we expecting here?
+ */
+ INIT_SSL();
+ init_auth();
+ init_util();
+ init_restrict();
+ init_mon();
+#ifndef __rtems__
+ init_timer();
+#endif /* __rtems__ */
+ init_request();
+ init_control();
+ init_peer();
+# ifdef REFCLOCK
+ init_refclock();
+# endif
+ set_process_priority();
+ init_proto(); /* Call at high priority */
+ init_io();
+ init_loopfilter();
+ mon_start(MON_ON); /* monitor on by default now */
+ /* turn off in config if unwanted */
+
+ /*
+ * Get the configuration. This is done in a separate module
+ * since this will definitely be different for the gizmo board.
+ */
+ getconfig(argc, argv);
+
+ if (-1 == cur_memlock) {
+# if defined(HAVE_MLOCKALL)
+ /*
+ * lock the process into memory
+ */
+ if ( !HAVE_OPT(SAVECONFIGQUIT)
+# ifdef RLIMIT_MEMLOCK
+ && -1 != DFLT_RLIMIT_MEMLOCK
+# endif
+ && 0 != mlockall(MCL_CURRENT|MCL_FUTURE))
+ msyslog(LOG_ERR, "mlockall(): %m");
+# else /* !HAVE_MLOCKALL follows */
+# ifdef HAVE_PLOCK
+# ifdef PROCLOCK
+ /*
+ * lock the process into memory
+ */
+ if (!HAVE_OPT(SAVECONFIGQUIT) && 0 != plock(PROCLOCK))
+ msyslog(LOG_ERR, "plock(PROCLOCK): %m");
+# else /* !PROCLOCK follows */
+# ifdef TXTLOCK
+ /*
+ * Lock text into ram
+ */
+ if (!HAVE_OPT(SAVECONFIGQUIT) && 0 != plock(TXTLOCK))
+ msyslog(LOG_ERR, "plock(TXTLOCK) error: %m");
+# else /* !TXTLOCK follows */
+ msyslog(LOG_ERR, "plock() - don't know what to lock!");
+# endif /* !TXTLOCK */
+# endif /* !PROCLOCK */
+# endif /* HAVE_PLOCK */
+# endif /* !HAVE_MLOCKALL */
+ }
+
+ loop_config(LOOP_DRIFTINIT, 0);
+ report_event(EVNT_SYSRESTART, NULL, NULL);
+ initializing = FALSE;
+
+# ifdef HAVE_DROPROOT
+ if (droproot) {
+
+#ifdef NEED_EARLY_FORK
+ fork_nonchroot_worker();
+#endif
+
+ /* Drop super-user privileges and chroot now if the OS supports this */
+
+# ifdef HAVE_LINUX_CAPABILITIES
+ /* set flag: keep privileges accross setuid() call (we only really need cap_sys_time): */
+ if (prctl( PR_SET_KEEPCAPS, 1L, 0L, 0L, 0L ) == -1) {
+ msyslog( LOG_ERR, "prctl( PR_SET_KEEPCAPS, 1L ) failed: %m" );
+ exit(-1);
+ }
+# elif HAVE_SOLARIS_PRIVS
+ /* Nothing to do here */
+# else
+ /* we need a user to switch to */
+ if (user == NULL) {
+ msyslog(LOG_ERR, "Need user name to drop root privileges (see -u flag!)" );
+ exit(-1);
+ }
+# endif /* HAVE_LINUX_CAPABILITIES || HAVE_SOLARIS_PRIVS */
+
+ if (user != NULL) {
+ if (0 == map_user())
+ exit (-1);
+ }
+ if (group != NULL) {
+ if (0 == map_group())
+ exit (-1);
+ }
+
+ if (chrootdir ) {
+ /* make sure cwd is inside the jail: */
+ if (chdir(chrootdir)) {
+ msyslog(LOG_ERR, "Cannot chdir() to `%s': %m", chrootdir);
+ exit (-1);
+ }
+ if (chroot(chrootdir)) {
+ msyslog(LOG_ERR, "Cannot chroot() to `%s': %m", chrootdir);
+ exit (-1);
+ }
+ if (chdir("/")) {
+ msyslog(LOG_ERR, "Cannot chdir() to`root after chroot(): %m");
+ exit (-1);
+ }
+ }
+# ifdef HAVE_SOLARIS_PRIVS
+ if ((lowprivs = priv_str_to_set(LOWPRIVS, ",", NULL)) == NULL) {
+ msyslog(LOG_ERR, "priv_str_to_set() failed:%m");
+ exit(-1);
+ }
+ if ((highprivs = priv_allocset()) == NULL) {
+ msyslog(LOG_ERR, "priv_allocset() failed:%m");
+ exit(-1);
+ }
+ (void) getppriv(PRIV_PERMITTED, highprivs);
+ (void) priv_intersect(highprivs, lowprivs);
+ if (setppriv(PRIV_SET, PRIV_PERMITTED, lowprivs) == -1) {
+ msyslog(LOG_ERR, "setppriv() failed:%m");
+ exit(-1);
+ }
+# endif /* HAVE_SOLARIS_PRIVS */
+ if (0 == set_user_group_ids())
+ exit(-1);
+
+# if defined(HAVE_TRUSTEDBSD_MAC)
+ /*
+ * To manipulate system time and (re-)bind to NTP_PORT as needed
+ * following interface changes, we must either run as uid 0 or
+ * the mac_ntpd policy module must be enabled.
+ */
+ if (sw_uid != 0 && mac_is_present("ntpd") != 1) {
+ msyslog(LOG_ERR, "Need MAC 'ntpd' policy enabled to drop root privileges");
+ exit (-1);
+ }
+# elif !defined(HAVE_LINUX_CAPABILITIES) && !defined(HAVE_SOLARIS_PRIVS)
+ /*
+ * for now assume that the privilege to bind to privileged ports
+ * is associated with running with uid 0 - should be refined on
+ * ports that allow binding to NTP_PORT with uid != 0
+ */
+ disable_dynamic_updates |= (sw_uid != 0); /* also notifies routing message listener */
+# endif /* !HAVE_LINUX_CAPABILITIES && !HAVE_SOLARIS_PRIVS */
+
+ if (disable_dynamic_updates && interface_interval) {
+ interface_interval = 0;
+ msyslog(LOG_INFO, "running as non-root disables dynamic interface tracking");
+ }
+
+# ifdef HAVE_LINUX_CAPABILITIES
+ {
+ /*
+ * We may be running under non-root uid now, but we still hold full root privileges!
+ * We drop all of them, except for the crucial one or two: cap_sys_time and
+ * cap_net_bind_service if doing dynamic interface tracking.
+ */
+ cap_t caps;
+ char *captext;
+
+ captext = (0 != interface_interval)
+ ? "cap_sys_time,cap_net_bind_service=pe"
+ : "cap_sys_time=pe";
+ caps = cap_from_text(captext);
+ if (!caps) {
+ msyslog(LOG_ERR,
+ "cap_from_text(%s) failed: %m",
+ captext);
+ exit(-1);
+ }
+ if (-1 == cap_set_proc(caps)) {
+ msyslog(LOG_ERR,
+ "cap_set_proc() failed to drop root privs: %m");
+ exit(-1);
+ }
+ cap_free(caps);
+ }
+# endif /* HAVE_LINUX_CAPABILITIES */
+# ifdef HAVE_SOLARIS_PRIVS
+ if (priv_delset(lowprivs, "proc_setid") == -1) {
+ msyslog(LOG_ERR, "priv_delset() failed:%m");
+ exit(-1);
+ }
+ if (setppriv(PRIV_SET, PRIV_PERMITTED, lowprivs) == -1) {
+ msyslog(LOG_ERR, "setppriv() failed:%m");
+ exit(-1);
+ }
+ priv_freeset(lowprivs);
+ priv_freeset(highprivs);
+# endif /* HAVE_SOLARIS_PRIVS */
+ root_dropped = TRUE;
+ fork_deferred_worker();
+ } /* if (droproot) */
+# endif /* HAVE_DROPROOT */
+
+/* libssecomp sandboxing */
+#if defined (LIBSECCOMP) && (KERN_SECCOMP)
+ scmp_filter_ctx ctx;
+
+ if ((ctx = seccomp_init(SCMP_ACT_KILL)) < 0)
+ msyslog(LOG_ERR, "%s: seccomp_init(SCMP_ACT_KILL) failed: %m", __func__);
+ else {
+ msyslog(LOG_DEBUG, "%s: seccomp_init(SCMP_ACT_KILL) succeeded", __func__);
+ }
+
+#ifdef __x86_64__
+int scmp_sc[] = {
+ SCMP_SYS(adjtimex),
+ SCMP_SYS(bind),
+ SCMP_SYS(brk),
+ SCMP_SYS(chdir),
+ SCMP_SYS(clock_gettime),
+ SCMP_SYS(clock_settime),
+ SCMP_SYS(close),
+ SCMP_SYS(connect),
+ SCMP_SYS(exit_group),
+ SCMP_SYS(fstat),
+ SCMP_SYS(fsync),
+ SCMP_SYS(futex),
+ SCMP_SYS(getitimer),
+ SCMP_SYS(getsockname),
+ SCMP_SYS(ioctl),
+ SCMP_SYS(lseek),
+ SCMP_SYS(madvise),
+ SCMP_SYS(mmap),
+ SCMP_SYS(munmap),
+ SCMP_SYS(open),
+ SCMP_SYS(poll),
+ SCMP_SYS(read),
+ SCMP_SYS(recvmsg),
+ SCMP_SYS(rename),
+ SCMP_SYS(rt_sigaction),
+ SCMP_SYS(rt_sigprocmask),
+ SCMP_SYS(rt_sigreturn),
+ SCMP_SYS(select),
+ SCMP_SYS(sendto),
+ SCMP_SYS(setitimer),
+ SCMP_SYS(setsid),
+ SCMP_SYS(socket),
+ SCMP_SYS(stat),
+ SCMP_SYS(time),
+ SCMP_SYS(write),
+};
+#endif
+#ifdef __i386__
+int scmp_sc[] = {
+ SCMP_SYS(_newselect),
+ SCMP_SYS(adjtimex),
+ SCMP_SYS(brk),
+ SCMP_SYS(chdir),
+ SCMP_SYS(clock_gettime),
+ SCMP_SYS(clock_settime),
+ SCMP_SYS(close),
+ SCMP_SYS(exit_group),
+ SCMP_SYS(fsync),
+ SCMP_SYS(futex),
+ SCMP_SYS(getitimer),
+ SCMP_SYS(madvise),
+ SCMP_SYS(mmap),
+ SCMP_SYS(mmap2),
+ SCMP_SYS(munmap),
+ SCMP_SYS(open),
+ SCMP_SYS(poll),
+ SCMP_SYS(read),
+ SCMP_SYS(rename),
+ SCMP_SYS(rt_sigaction),
+ SCMP_SYS(rt_sigprocmask),
+ SCMP_SYS(select),
+ SCMP_SYS(setitimer),
+ SCMP_SYS(setsid),
+ SCMP_SYS(sigprocmask),
+ SCMP_SYS(sigreturn),
+ SCMP_SYS(socketcall),
+ SCMP_SYS(stat64),
+ SCMP_SYS(time),
+ SCMP_SYS(write),
+};
+#endif
+ {
+ int i;
+
+ for (i = 0; i < COUNTOF(scmp_sc); i++) {
+ if (seccomp_rule_add(ctx,
+ SCMP_ACT_ALLOW, scmp_sc[i], 0) < 0) {
+ msyslog(LOG_ERR,
+ "%s: seccomp_rule_add() failed: %m",
+ __func__);
+ }
+ }
+ }
+
+ if (seccomp_load(ctx) < 0)
+ msyslog(LOG_ERR, "%s: seccomp_load() failed: %m",
+ __func__);
+ else {
+ msyslog(LOG_DEBUG, "%s: seccomp_load() succeeded", __func__);
+ }
+#endif /* LIBSECCOMP and KERN_SECCOMP */
+
+#ifdef SYS_WINNT
+ ntservice_isup();
+#endif
+
+# ifdef HAVE_IO_COMPLETION_PORT
+
+ for (;;) {
+#if !defined(SIM) && defined(SIGDIE1)
+ if (signalled)
+ finish_safe(signo);
+#endif
+ GetReceivedBuffers();
+# else /* normal I/O */
+
+ BLOCK_IO_AND_ALARM();
+ was_alarmed = FALSE;
+
+ for (;;) {
+#if !defined(SIM) && defined(SIGDIE1)
+ if (signalled)
+ finish_safe(signo);
+#endif
+ if (alarm_flag) { /* alarmed? */
+ was_alarmed = TRUE;
+ alarm_flag = FALSE;
+ }
+
+ /* collect async name/addr results */
+ if (!was_alarmed)
+ harvest_blocking_responses();
+
+ if (!was_alarmed && !has_full_recv_buffer()) {
+ /*
+ * Nothing to do. Wait for something.
+ */
+ io_handler();
+ }
+
+ if (alarm_flag) { /* alarmed? */
+ was_alarmed = TRUE;
+ alarm_flag = FALSE;
+ }
+
+ if (was_alarmed) {
+ UNBLOCK_IO_AND_ALARM();
+ /*
+ * Out here, signals are unblocked. Call timer routine
+ * to process expiry.
+ */
+ timer();
+ was_alarmed = FALSE;
+ BLOCK_IO_AND_ALARM();
+ }
+
+# endif /* !HAVE_IO_COMPLETION_PORT */
+
+# ifdef DEBUG_TIMING
+ {
+ l_fp pts;
+ l_fp tsa, tsb;
+ int bufcount = 0;
+
+ get_systime(&pts);
+ tsa = pts;
+# endif
+ rbuf = get_full_recv_buffer();
+ while (rbuf != NULL) {
+ if (alarm_flag) {
+ was_alarmed = TRUE;
+ alarm_flag = FALSE;
+ }
+ UNBLOCK_IO_AND_ALARM();
+
+ if (was_alarmed) {
+ /* avoid timer starvation during lengthy I/O handling */
+ timer();
+ was_alarmed = FALSE;
+ }
+
+ /*
+ * Call the data procedure to handle each received
+ * packet.
+ */
+ if (rbuf->receiver != NULL) {
+# ifdef DEBUG_TIMING
+ l_fp dts = pts;
+
+ L_SUB(&dts, &rbuf->recv_time);
+ DPRINTF(2, ("processing timestamp delta %s (with prec. fuzz)\n", lfptoa(&dts, 9)));
+ collect_timing(rbuf, "buffer processing delay", 1, &dts);
+ bufcount++;
+# endif
+ (*rbuf->receiver)(rbuf);
+ } else {
+ msyslog(LOG_ERR, "fatal: receive buffer callback NULL");
+ abort();
+ }
+
+ BLOCK_IO_AND_ALARM();
+ freerecvbuf(rbuf);
+ rbuf = get_full_recv_buffer();
+ }
+# ifdef DEBUG_TIMING
+ get_systime(&tsb);
+ L_SUB(&tsb, &tsa);
+ if (bufcount) {
+ collect_timing(NULL, "processing", bufcount, &tsb);
+ DPRINTF(2, ("processing time for %d buffers %s\n", bufcount, lfptoa(&tsb, 9)));
+ }
+ }
+# endif
+
+ /*
+ * Go around again
+ */
+
+# ifdef HAVE_DNSREGISTRATION
+ if (mdnsreg && (current_time - mdnsreg ) > 60 && mdnstries && sys_leap != LEAP_NOTINSYNC) {
+ mdnsreg = current_time;
+ msyslog(LOG_INFO, "Attempting to register mDNS");
+ if ( DNSServiceRegister (&mdns, 0, 0, NULL, "_ntp._udp", NULL, NULL,
+ htons(NTP_PORT), 0, NULL, NULL, NULL) != kDNSServiceErr_NoError ) {
+ if (!--mdnstries) {
+ msyslog(LOG_ERR, "Unable to register mDNS, giving up.");
+ } else {
+ msyslog(LOG_INFO, "Unable to register mDNS, will try later.");
+ }
+ } else {
+ msyslog(LOG_INFO, "mDNS service registered.");
+ mdnsreg = FALSE;
+ }
+ }
+# endif /* HAVE_DNSREGISTRATION */
+
+ }
+ UNBLOCK_IO_AND_ALARM();
+ return 1;
+}
+#ifdef __rtems__
+int
+rtems_ntpd_run(int argc, char **argv)
+{
+
+ return (rtems_bsd_program_call_main("ntpd", ntpdmain, argc, argv));
+}
+#endif /* __rtems__ */
+#endif /* !SIM */
+
+
+#if !defined(SIM) && defined(SIGDIE1)
+/*
+ * finish - exit gracefully
+ */
+static void
+finish_safe(
+ int sig
+ )
+{
+ const char *sig_desc;
+
+ sig_desc = NULL;
+#ifdef HAVE_STRSIGNAL
+ sig_desc = strsignal(sig);
+#endif
+ if (sig_desc == NULL)
+ sig_desc = "";
+ msyslog(LOG_NOTICE, "%s exiting on signal %d (%s)", progname,
+ sig, sig_desc);
+ /* See Bug 2513 and Bug 2522 re the unlink of PIDFILE */
+# ifdef HAVE_DNSREGISTRATION
+ if (mdns != NULL)
+ DNSServiceRefDeallocate(mdns);
+# endif
+ peer_cleanup();
+ exit(0);
+}
+
+static RETSIGTYPE
+finish(
+ int sig
+ )
+{
+ signalled = 1;
+ signo = sig;
+}
+
+#endif /* !SIM && SIGDIE1 */
+
+
+#ifndef SIM
+/*
+ * wait_child_sync_if - implements parent side of -w/--wait-sync
+ */
+# ifdef HAVE_WORKING_FORK
+static int
+wait_child_sync_if(
+ int pipe_read_fd,
+ long wait_sync
+ )
+{
+ int rc;
+ int exit_code;
+ time_t wait_end_time;
+ time_t cur_time;
+ time_t wait_rem;
+ fd_set readset;
+ struct timeval wtimeout;
+
+ if (0 == wait_sync)
+ return 0;
+
+ /* waitsync_fd_to_close used solely by child */
+ close(waitsync_fd_to_close);
+ wait_end_time = time(NULL) + wait_sync;
+ do {
+ cur_time = time(NULL);
+ wait_rem = (wait_end_time > cur_time)
+ ? (wait_end_time - cur_time)
+ : 0;
+ wtimeout.tv_sec = wait_rem;
+ wtimeout.tv_usec = 0;
+ FD_ZERO(&readset);
+ FD_SET(pipe_read_fd, &readset);
+ rc = select(pipe_read_fd + 1, &readset, NULL, NULL,
+ &wtimeout);
+ if (-1 == rc) {
+ if (EINTR == errno)
+ continue;
+ exit_code = (errno) ? errno : -1;
+ msyslog(LOG_ERR,
+ "--wait-sync select failed: %m");
+ return exit_code;
+ }
+ if (0 == rc) {
+ /*
+ * select() indicated a timeout, but in case
+ * its timeouts are affected by a step of the
+ * system clock, select() again with a zero
+ * timeout to confirm.
+ */
+ FD_ZERO(&readset);
+ FD_SET(pipe_read_fd, &readset);
+ wtimeout.tv_sec = 0;
+ wtimeout.tv_usec = 0;
+ rc = select(pipe_read_fd + 1, &readset, NULL,
+ NULL, &wtimeout);
+ if (0 == rc) /* select() timeout */
+ break;
+ else /* readable */
+ return 0;
+ } else /* readable */
+ return 0;
+ } while (wait_rem > 0);
+
+ fprintf(stderr, "%s: -w/--wait-sync %ld timed out.\n",
+ progname, wait_sync);
+ return ETIMEDOUT;
+}
+# endif /* HAVE_WORKING_FORK */
+
+
+/*
+ * assertion_failed - Redirect assertion failures to msyslog().
+ */
+static void
+assertion_failed(
+ const char *file,
+ int line,
+ isc_assertiontype_t type,
+ const char *cond
+ )
+{
+ isc_assertion_setcallback(NULL); /* Avoid recursion */
+
+ msyslog(LOG_ERR, "%s:%d: %s(%s) failed",
+ file, line, isc_assertion_typetotext(type), cond);
+ msyslog(LOG_ERR, "exiting (due to assertion failure)");
+
+#if defined(DEBUG) && defined(SYS_WINNT)
+ if (debug)
+ DebugBreak();
+#endif
+
+ abort();
+}
+
+
+/*
+ * library_fatal_error - Handle fatal errors from our libraries.
+ */
+static void
+library_fatal_error(
+ const char *file,
+ int line,
+ const char *format,
+ va_list args
+ )
+{
+ char errbuf[256];
+
+ isc_error_setfatal(NULL); /* Avoid recursion */
+
+ msyslog(LOG_ERR, "%s:%d: fatal error:", file, line);
+ vsnprintf(errbuf, sizeof(errbuf), format, args);
+ msyslog(LOG_ERR, "%s", errbuf);
+ msyslog(LOG_ERR, "exiting (due to fatal error in library)");
+
+#if defined(DEBUG) && defined(SYS_WINNT)
+ if (debug)
+ DebugBreak();
+#endif
+
+ abort();
+}
+
+
+/*
+ * library_unexpected_error - Handle non fatal errors from our libraries.
+ */
+# define MAX_UNEXPECTED_ERRORS 100
+int unexpected_error_cnt = 0;
+static void
+library_unexpected_error(
+ const char *file,
+ int line,
+ const char *format,
+ va_list args
+ )
+{
+ char errbuf[256];
+
+ if (unexpected_error_cnt >= MAX_UNEXPECTED_ERRORS)
+ return; /* avoid clutter in log */
+
+ msyslog(LOG_ERR, "%s:%d: unexpected error:", file, line);
+ vsnprintf(errbuf, sizeof(errbuf), format, args);
+ msyslog(LOG_ERR, "%s", errbuf);
+
+ if (++unexpected_error_cnt == MAX_UNEXPECTED_ERRORS)
+ msyslog(LOG_ERR, "Too many errors. Shutting up.");
+
+}
+#endif /* !SIM */
+
+#if !defined(SIM) && !defined(SYS_WINNT)
+# ifdef DEBUG
+
+/*
+ * moredebug - increase debugging verbosity
+ */
+static RETSIGTYPE
+moredebug(
+ int sig
+ )
+{
+ int saved_errno = errno;
+
+ if (debug < 255)
+ {
+ debug++;
+ msyslog(LOG_DEBUG, "debug raised to %d", debug);
+ }
+ errno = saved_errno;
+}
+
+
+/*
+ * lessdebug - decrease debugging verbosity
+ */
+static RETSIGTYPE
+lessdebug(
+ int sig
+ )
+{
+ int saved_errno = errno;
+
+ if (debug > 0)
+ {
+ debug--;
+ msyslog(LOG_DEBUG, "debug lowered to %d", debug);
+ }
+ errno = saved_errno;
+}
+
+# else /* !DEBUG follows */
+
+
+/*
+ * no_debug - We don't do the debug here.
+ */
+static RETSIGTYPE
+no_debug(
+ int sig
+ )
+{
+ int saved_errno = errno;
+
+ msyslog(LOG_DEBUG, "ntpd not compiled for debugging (signal %d)", sig);
+ errno = saved_errno;
+}
+# endif /* !DEBUG */
+#endif /* !SIM && !SYS_WINNT */
diff --git a/sebhbsd/freebsd/contrib/ntp/ntpd/ntpsim.c b/sebhbsd/freebsd/contrib/ntp/ntpd/ntpsim.c
new file mode 100644
index 0000000..6f637d3
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/ntpd/ntpsim.c
@@ -0,0 +1,660 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/* ntpdsim.c
+ *
+ * The source code for the ntp discrete event simulator.
+ *
+ * Written By: Sachin Kamboj
+ * University of Delaware
+ * Newark, DE 19711
+ * Copyright (c) 2006
+ * (Some code shamelessly based on the original NTP discrete event simulator)
+ */
+
+#include <config.h>
+#ifdef SIM
+#include "ntpd.h"
+#include "ntp_config.h"
+
+/* forward prototypes */
+int determine_event_ordering(const Event *e1, const Event *e2);
+int determine_recv_buf_ordering(const struct recvbuf *b1,
+ const struct recvbuf *b2);
+void create_server_associations(void);
+void init_sim_io(void);
+
+/* Global Variable Definitions */
+sim_info simulation; /* Simulation Control Variables */
+local_clock_info simclock; /* Local Clock Variables */
+queue *event_queue; /* Event Queue */
+queue *recv_queue; /* Receive Queue */
+static double sys_residual = 0; /* adjustment residue (s) */
+
+void (*event_ptr[]) (Event *) = {
+ sim_event_beep, sim_update_clocks, sim_event_timer, sim_event_recv_packet
+}; /* Function pointer to the events */
+
+
+/*
+ * Define a function to compare two events to determine which one occurs
+ * first.
+ */
+int
+determine_event_ordering(
+ const Event *e1,
+ const Event *e2
+ )
+{
+ return (e1->time - e2->time);
+}
+
+
+/*
+ * Define a function to compare two received packets to determine which
+ * one is received first.
+ */
+int
+determine_recv_buf_ordering(
+ const struct recvbuf *b1,
+ const struct recvbuf *b2
+ )
+{
+ double recv_time1;
+ double recv_time2;
+
+ /* Simply convert the time received to double and subtract */
+ LFPTOD(&b1->recv_time, recv_time1);
+ LFPTOD(&b2->recv_time, recv_time2);
+
+ return (int)(recv_time1 - recv_time2);
+}
+
+
+/* Define a function to create the server associations */
+void create_server_associations(void)
+{
+ int i;
+
+ for (i = 0; i < simulation.num_of_servers; ++i) {
+ printf("%s\n", stoa(simulation.servers[i].addr));
+ if (peer_config(simulation.servers[i].addr,
+ NULL,
+ loopback_interface,
+ MODE_CLIENT,
+ -1,
+ NTP_VERSION,
+ NTP_MINDPOLL,
+ NTP_MAXDPOLL,
+ 0, /* peerflags */
+ 0, /* ttl */
+ 0, /* peerkey */
+ NULL /* group ident */) == 0) {
+ fprintf(stderr,
+ "ERROR!! Could not create association for: %s\n",
+ stoa(simulation.servers[i].addr));
+ }
+ }
+}
+
+
+/* Main Simulator Code */
+
+int
+ntpsim(
+ int argc,
+ char * argv[]
+ )
+{
+ Event * curr_event;
+ struct timeval seed;
+
+ /* Initialize the local Clock */
+ simclock.local_time = 0;
+ simclock.adj = 0;
+ simclock.slew = 500e-6;
+
+ /* Initialize the simulation */
+ simulation.num_of_servers = 0;
+ simulation.beep_delay = BEEP_DLY;
+ simulation.sim_time = 0;
+ simulation.end_time = SIM_TIME;
+
+ /* Initialize ntp modules */
+ initializing = TRUE;
+ msyslog_term = TRUE;
+ init_sim_io();
+ init_auth();
+ init_util();
+ init_restrict();
+ init_mon();
+ init_timer();
+ init_lib();
+ init_request();
+ init_control();
+ init_peer();
+ init_proto();
+ init_loopfilter();
+ mon_start(MON_OFF);
+
+ /* Call getconfig to parse the configuration file */
+ getconfig(argc, argv);
+ loop_config(LOOP_DRIFTINIT, 0);
+ initializing = FALSE;
+
+ /*
+ * Watch out here, we want the real time, not the silly stuff.
+ */
+ gettimeofday(&seed, NULL);
+ ntp_srandom(seed.tv_usec);
+
+ /* Initialize the event queue */
+ event_queue = create_priority_queue((q_order_func)
+ determine_event_ordering);
+
+ /* Initialize the receive queue */
+ recv_queue = create_priority_queue((q_order_func)
+ determine_recv_buf_ordering);
+
+ /* Push a beep and a timer on the event queue */
+ enqueue(event_queue, event(0, BEEP));
+ enqueue(event_queue, event(simulation.sim_time + 1.0, TIMER));
+
+ /*
+ * Pop the queue until nothing is left or time is exceeded
+ */
+ /* maxtime = simulation.sim_time + simulation.end_time;*/
+ while (simulation.sim_time <= simulation.end_time &&
+ (!empty(event_queue))) {
+ curr_event = dequeue(event_queue);
+ /* Update all the clocks to the time on the event */
+ sim_update_clocks(curr_event);
+
+ /* Execute the function associated with the event */
+ (*event_ptr[curr_event->function])(curr_event);
+ free_node(curr_event);
+ }
+ printf("sys_received: %lu\n", sys_received);
+ printf("sys_badlength: %lu\n", sys_badlength);
+ printf("sys_declined: %lu\n", sys_declined);
+ printf("sys_restricted: %lu\n", sys_restricted);
+ printf("sys_newversion: %lu\n", sys_newversion);
+ printf("sys_oldversion: %lu\n", sys_oldversion);
+ printf("sys_limitrejected: %lu\n", sys_limitrejected);
+ printf("sys_badauth: %lu\n", sys_badauth);
+
+ return (0);
+}
+
+
+void
+init_sim_io(void)
+{
+ loopback_interface = emalloc_zero(sizeof(*loopback_interface));
+ ep_list = loopback_interface;
+ strlcpy(loopback_interface->name, "IPv4loop",
+ sizeof(loopback_interface->name));
+ loopback_interface->flags = INT_UP | INT_LOOPBACK;
+ loopback_interface->fd = -1;
+ loopback_interface->bfd = -1;
+ loopback_interface->ifnum = 1;
+ loopback_interface->family = AF_INET;
+ AF(&loopback_interface->sin) = AF_INET;
+ SET_ADDR4(&loopback_interface->sin, LOOPBACKADR);
+ SET_PORT(&loopback_interface->sin, NTP_PORT);
+ AF(&loopback_interface->mask) = AF_INET;
+ SET_ADDR4(&loopback_interface->mask, LOOPNETMASK);
+}
+
+
+/* Define a function to create an return an Event */
+
+Event *event(double t, funcTkn f)
+{
+ Event *e;
+
+ if ((e = get_node(sizeof(*e))) == NULL)
+ abortsim("get_node failed in event");
+ e->time = t;
+ e->function = f;
+ return (e);
+}
+
+/* NTP SIMULATION FUNCTIONS */
+
+/* Define a function for processing a timer interrupt.
+ * On every timer interrupt, call the NTP timer to send packets and process
+ * the clock and then call the receive function to receive packets.
+ */
+void sim_event_timer(Event *e)
+{
+ struct recvbuf *rbuf;
+
+ /* Call the NTP timer.
+ * This will be responsible for actually "sending the packets."
+ * Since this is a simulation, the packets sent over the network
+ * will be processed by the simulate_server routine below.
+ */
+ timer();
+
+ /* Process received buffers */
+ while (!empty(recv_queue)) {
+ rbuf = (struct recvbuf *)dequeue(recv_queue);
+ (*rbuf->receiver)(rbuf);
+ free_node(rbuf);
+ }
+
+ /* Arm the next timer interrupt. */
+ enqueue(event_queue,
+ event(simulation.sim_time + (1 << EVENT_TIMEOUT), TIMER));
+}
+
+
+
+/* Define a function to simulate a server.
+ * This function processes the sent packet according to the server script,
+ * creates a reply packet and pushes the reply packet onto the event queue
+ */
+int simulate_server(
+ sockaddr_u *serv_addr, /* Address of the server */
+ endpt * inter, /* Interface on which the reply should
+ be inserted */
+ struct pkt *rpkt /* Packet sent to the server that
+ needs to be processed. */
+ )
+{
+ struct pkt xpkt; /* Packet to be transmitted back
+ to the client */
+ struct recvbuf rbuf; /* Buffer for the received packet */
+ Event *e; /* Packet receive event */
+ server_info *server; /* Pointer to the server being simulated */
+ script_info *curr_script; /* Current script being processed */
+ int i;
+ double d1, d2, d3; /* Delays while the packet is enroute */
+ double t1, t2, t3, t4; /* The four timestamps in the packet */
+ l_fp lfp_host; /* host-order l_fp */
+
+ ZERO(xpkt);
+ ZERO(rbuf);
+
+ /* Search for the server with the desired address */
+ server = NULL;
+ for (i = 0; i < simulation.num_of_servers; ++i) {
+ if (memcmp(simulation.servers[i].addr, serv_addr,
+ sizeof(*serv_addr)) == 0) {
+ server = &simulation.servers[i];
+ break;
+ }
+ }
+
+ fprintf(stderr, "Received packet from %s on %s\n",
+ stoa(serv_addr), latoa(inter));
+ if (server == NULL)
+ abortsim("Server with specified address not found!!!");
+
+ /* Get the current script for the server */
+ curr_script = server->curr_script;
+
+ /* Create a server reply packet.
+ * Masquerade the reply as a stratum-1 server with a GPS clock
+ */
+ xpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING, NTP_VERSION,
+ MODE_SERVER);
+ xpkt.stratum = STRATUM_TO_PKT(((u_char)1));
+ memcpy(&xpkt.refid, "GPS", 4);
+ xpkt.ppoll = rpkt->ppoll;
+ xpkt.precision = rpkt->precision;
+ xpkt.rootdelay = 0;
+ xpkt.rootdisp = 0;
+
+ /* TIMESTAMP CALCULATIONS
+ t1 t4
+ \ /
+ d1 \ / d3
+ \ /
+ t2 ----------------- t3
+ d2
+ */
+ /* Compute the delays */
+ d1 = poisson(curr_script->prop_delay, curr_script->jitter);
+ d2 = poisson(curr_script->proc_delay, 0);
+ d3 = poisson(curr_script->prop_delay, curr_script->jitter);
+
+ /* Note: In the transmitted packet:
+ * 1. t1 and t4 are times in the client according to the local clock.
+ * 2. t2 and t3 are server times according to the simulated server.
+ * Compute t1, t2, t3 and t4
+ * Note: This function is called at time t1.
+ */
+
+ NTOHL_FP(&rpkt->xmt, &lfp_host);
+ LFPTOD(&lfp_host, t1);
+ t2 = server->server_time + d1;
+ t3 = server->server_time + d1 + d2;
+ t4 = t1 + d1 + d2 + d3;
+
+ /* Save the timestamps */
+ xpkt.org = rpkt->xmt;
+ DTOLFP(t2, &lfp_host);
+ HTONL_FP(&lfp_host, &xpkt.rec);
+ DTOLFP(t3, &lfp_host);
+ HTONL_FP(&lfp_host, &xpkt.xmt);
+ xpkt.reftime = xpkt.xmt;
+
+ /*
+ * Ok, we are done with the packet. Now initialize the receive
+ * buffer for the packet.
+ */
+ rbuf.used = 1;
+ rbuf.receiver = &receive; /* callback to process the packet */
+ rbuf.recv_length = LEN_PKT_NOMAC;
+ rbuf.recv_pkt = xpkt;
+ rbuf.dstadr = inter;
+ rbuf.fd = inter->fd;
+ memcpy(&rbuf.srcadr, serv_addr, sizeof(rbuf.srcadr));
+ memcpy(&rbuf.recv_srcadr, serv_addr, sizeof(rbuf.recv_srcadr));
+
+ /*
+ * Create a packet event and insert it onto the event_queue at the
+ * arrival time (t4) of the packet at the client
+ */
+ e = event(t4, PACKET);
+ e->rcv_buf = rbuf;
+ enqueue(event_queue, e);
+
+ /*
+ * Check if the time of the script has expired. If yes, delete it.
+ */
+ if (curr_script->duration > simulation.sim_time &&
+ NULL == HEAD_PFIFO(server->script)) {
+ printf("Hello\n");
+ /*
+ * For some reason freeing up the curr_script memory kills the
+ * simulation. Further debugging is needed to determine why.
+ * free(curr_script);
+ */
+ UNLINK_FIFO(curr_script, *server->script, link);
+ }
+
+ return (0);
+}
+
+
+/* Define a function to update all the clocks
+ * Most of the code is modified from the systime.c file by Prof. Mills
+ */
+
+void sim_update_clocks(Event *e)
+{
+ double time_gap;
+ double adj;
+ int i;
+
+ /* Compute the time between the last update event and this update */
+ time_gap = e->time - simulation.sim_time;
+
+ if (time_gap < 0)
+ printf("WARNING: e->time %.6g comes before sim_time %.6g (gap %+.6g)\n",
+ e->time, simulation.sim_time, time_gap);
+
+ /* Advance the client clock */
+ if (e->time + time_gap < simclock.local_time)
+ printf("WARNING: e->time + gap %.6g comes before local_time %.6g\n",
+ e->time + time_gap, simclock.local_time);
+ simclock.local_time = e->time + time_gap;
+
+ /* Advance the simulation time */
+ simulation.sim_time = e->time;
+
+ /* Advance the server clocks adjusted for systematic and random frequency
+ * errors. The random error is a random walk computed as the
+ * integral of samples from a Gaussian distribution.
+ */
+ for (i = 0; i < simulation.num_of_servers; ++i) {
+ simulation.servers[i].curr_script->freq_offset +=
+ gauss(0, time_gap * simulation.servers[i].curr_script->wander);
+
+ simulation.servers[i].server_time += time_gap *
+ (1 + simulation.servers[i].curr_script->freq_offset);
+ }
+
+ /* Perform the adjtime() function. If the adjustment completed
+ * in the previous interval, amortize the entire amount; if not,
+ * carry the leftover to the next interval.
+ */
+
+ adj = time_gap * simclock.slew;
+ if (adj < fabs(simclock.adj)) {
+ if (simclock.adj < 0) {
+ simclock.adj += adj;
+ simclock.local_time -= adj;
+ } else {
+ simclock.adj -= adj;
+ simclock.local_time += adj;
+ }
+ } else {
+ simclock.local_time += simclock.adj;
+ simclock.adj = 0;
+ }
+}
+
+
+/* Define a function that processes a receive packet event.
+ * This function simply inserts the packet received onto the receive queue
+ */
+
+void sim_event_recv_packet(Event *e)
+{
+ struct recvbuf *rbuf;
+
+ /* Allocate a receive buffer and copy the packet to it */
+ if ((rbuf = get_node(sizeof(*rbuf))) == NULL)
+ abortsim("get_node failed in sim_event_recv_packet");
+ memcpy(rbuf, &e->rcv_buf, sizeof(*rbuf));
+
+ /* Store the local time in the received packet */
+ DTOLFP(simclock.local_time, &rbuf->recv_time);
+
+ /* Insert the packet received onto the receive queue */
+ enqueue(recv_queue, rbuf);
+}
+
+
+
+/* Define a function to output simulation statistics on a beep event
+ */
+
+/*** TODO: Need to decide on how to output for multiple servers ***/
+void sim_event_beep(Event *e)
+{
+#if 0
+ static int first_time = 1;
+ char *dash = "-----------------";
+#endif
+
+ fprintf(stderr, "BEEP!!!\n");
+ enqueue(event_queue, event(e->time + simulation.beep_delay, BEEP));
+#if 0
+ if(simulation.beep_delay > 0) {
+ if (first_time) {
+ printf("\t%4c T %4c\t%4c T+ERR %3c\t%5cT+ERR+NTP\n",
+ ' ', ' ', ' ', ' ',' ');
+ printf("\t%s\t%s\t%s\n", dash, dash, dash);
+ first_time = 0;
+
+ printf("\t%16.6f\t%16.6f\t%16.6f\n",
+ n->time, n->clk_time, n->ntp_time);
+ return;
+ }
+ printf("\t%16.6f\t%16.6f\t%16.6f\n",
+ simclock.local_time,
+ n->time, n->clk_time, n->ntp_time);
+#endif
+
+}
+
+
+/* Define a function to abort the simulation on an error and spit out an
+ * error message
+ */
+
+void abortsim(char *errmsg)
+{
+ perror(errmsg);
+ exit(1);
+}
+
+
+
+/* CODE ORIGINALLY IN libntp/systime.c
+ * -----------------------------------
+ * This code was a part of the original NTP simulator and originally
+ * had its home in the libntp/systime.c file.
+ *
+ * It has been shamelessly moved to here and has been modified for the
+ * purposes of the current simulator.
+ */
+
+
+/*
+ * get_systime - return the system time in NTP timestamp format
+ */
+void
+get_systime(
+ l_fp *now /* current system time in l_fp */ )
+{
+ /*
+ * To fool the code that determines the local clock precision,
+ * we advance the clock a minimum of 200 nanoseconds on every
+ * clock read. This is appropriate for a typical modern machine
+ * with nanosecond clocks. Note we make no attempt here to
+ * simulate reading error, since the error is so small. This may
+ * change when the need comes to implement picosecond clocks.
+ */
+ if (simclock.local_time == simclock.last_read_time)
+ simclock.local_time += 200e-9;
+
+ simclock.last_read_time = simclock.local_time;
+ DTOLFP(simclock.local_time, now);
+/* OLD Code
+ if (ntp_node.ntp_time == ntp_node.last_time)
+ ntp_node.ntp_time += 200e-9;
+ ntp_node.last_time = ntp_node.ntp_time;
+ DTOLFP(ntp_node.ntp_time, now);
+*/
+}
+
+
+/*
+ * adj_systime - advance or retard the system clock exactly like the
+ * real thng.
+ */
+int /* always succeeds */
+adj_systime(
+ double now /* time adjustment (s) */
+ )
+{
+ struct timeval adjtv; /* new adjustment */
+ double dtemp;
+ long ticks;
+ int isneg = 0;
+
+ /*
+ * Most Unix adjtime() implementations adjust the system clock
+ * in microsecond quanta, but some adjust in 10-ms quanta. We
+ * carefully round the adjustment to the nearest quantum, then
+ * adjust in quanta and keep the residue for later.
+ */
+ dtemp = now + sys_residual;
+ if (dtemp < 0) {
+ isneg = 1;
+ dtemp = -dtemp;
+ }
+ adjtv.tv_sec = (long)dtemp;
+ dtemp -= adjtv.tv_sec;
+ ticks = (long)(dtemp / sys_tick + .5);
+ adjtv.tv_usec = (long)(ticks * sys_tick * 1e6);
+ dtemp -= adjtv.tv_usec / 1e6;
+ sys_residual = dtemp;
+
+ /*
+ * Convert to signed seconds and microseconds for the Unix
+ * adjtime() system call. Note we purposely lose the adjtime()
+ * leftover.
+ */
+ if (isneg) {
+ adjtv.tv_sec = -adjtv.tv_sec;
+ adjtv.tv_usec = -adjtv.tv_usec;
+ sys_residual = -sys_residual;
+ }
+ simclock.adj = now;
+/* ntp_node.adj = now; */
+ return (1);
+}
+
+
+/*
+ * step_systime - step the system clock. We are religious here.
+ */
+int /* always succeeds */
+step_systime(
+ double now /* step adjustment (s) */
+ )
+{
+#ifdef DEBUG
+ if (debug)
+ printf("step_systime: time %.6f adj %.6f\n",
+ simclock.local_time, now);
+#endif
+ simclock.local_time += now;
+ return (1);
+}
+
+/*
+ * gauss() - returns samples from a gaussion distribution
+ */
+double /* Gaussian sample */
+gauss(
+ double m, /* sample mean */
+ double s /* sample standard deviation (sigma) */
+ )
+{
+ double q1, q2;
+
+ /*
+ * Roll a sample from a Gaussian distribution with mean m and
+ * standard deviation s. For m = 0, s = 1, mean(y) = 0,
+ * std(y) = 1.
+ */
+ if (s == 0)
+ return (m);
+ while ((q1 = drand48()) == 0)
+ /* empty statement */;
+ q2 = drand48();
+ return (m + s * sqrt(-2. * log(q1)) * cos(2. * PI * q2));
+}
+
+
+/*
+ * poisson() - returns samples from a network delay distribution
+ */
+double /* delay sample (s) */
+poisson(
+ double m, /* fixed propagation delay (s) */
+ double s /* exponential parameter (mu) */
+ )
+{
+ double q1;
+
+ /*
+ * Roll a sample from a composite distribution with propagation
+ * delay m and exponential distribution time with parameter s.
+ * For m = 0, s = 1, mean(y) = std(y) = 1.
+ */
+ if (s == 0)
+ return (m);
+ while ((q1 = drand48()) == 0)
+ /* empty statement */;
+ return (m - s * log(q1 * s));
+}
+
+#endif
diff --git a/sebhbsd/freebsd/contrib/ntp/ntpd/ppsapi_timepps.h b/sebhbsd/freebsd/contrib/ntp/ntpd/ppsapi_timepps.h
new file mode 100644
index 0000000..8adaf62
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/ntpd/ppsapi_timepps.h
@@ -0,0 +1,26 @@
+/* ppsapi_timepps.h */
+
+/*
+ * This logic first tries to get the timepps.h file from a standard
+ * location, and then from our include/ subdirectory.
+ */
+
+#ifdef HAVE_TIMEPPS_H
+# include <timepps.h>
+#else
+# ifdef HAVE_SYS_TIMEPPS_H
+# include <sys/timepps.h>
+# else
+# ifdef HAVE_CIOGETEV
+# include "timepps-SunOS.h"
+# else
+# ifdef HAVE_TIOCGPPSEV
+# include "timepps-Solaris.h"
+# else
+# ifdef TIOCDCDTIMESTAMP
+# include "timepps-SCO.h"
+# endif
+# endif
+# endif
+# endif
+#endif
diff --git a/sebhbsd/freebsd/contrib/ntp/ntpd/rc_cmdlength.c b/sebhbsd/freebsd/contrib/ntp/ntpd/rc_cmdlength.c
new file mode 100644
index 0000000..8e6ca69
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/ntpd/rc_cmdlength.c
@@ -0,0 +1,40 @@
+#include <machine/rtems-bsd-user-space.h>
+
+#include <config.h>
+#include <rc_cmdlength.h>
+
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+// XXX: Move to header.
+size_t remoteconfig_cmdlength( const char *, const char *);
+
+/* Bug 2853 */
+/* evaluate the length of the command sequence. This breaks at the first
+ * char that is not >= SPACE and <= 127 after trimming from the right.
+ */
+size_t
+remoteconfig_cmdlength(
+ const char *src_buf,
+ const char *src_end
+ )
+{
+ const char *scan;
+ unsigned char ch;
+
+ /* trim whitespace & garbage from the right */
+ while (src_end != src_buf) {
+ ch = src_end[-1];
+ if (ch > ' ' && ch < 128)
+ break;
+ --src_end;
+ }
+ /* now do a forward scan */
+ for (scan = src_buf; scan != src_end; ++scan) {
+ ch = scan[0];
+ if ((ch < ' ' || ch >= 128) && ch != '\t')
+ break;
+ }
+ return (size_t)(scan - src_buf);
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/ntpd/refclock_palisade.h b/sebhbsd/freebsd/contrib/ntp/ntpd/refclock_palisade.h
new file mode 100644
index 0000000..3782a5e
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/ntpd/refclock_palisade.h
@@ -0,0 +1,202 @@
+/*
+ * This software was developed by the Software and Component Technologies
+ * group of Trimble Navigation, Ltd.
+ *
+ * Copyright (c) 1997, 1998, 1999, 2000 Trimble Navigation Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Trimble Navigation, Ltd.
+ * 4. The name of Trimble Navigation Ltd. may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TRIMBLE NAVIGATION LTD. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL TRIMBLE NAVIGATION LTD. BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * refclock_palisade - clock driver for the Trimble Palisade GPS
+ * timing receiver
+ *
+ * For detailed information on this program, please refer to the html
+ * Refclock 29 page accompanying the NTP distribution.
+ *
+ * for questions / bugs / comments, contact:
+ * sven_dietrich@trimble.com
+ *
+ * Sven-Thorsten Dietrich
+ * 645 North Mary Avenue
+ * Post Office Box 3642
+ * Sunnyvale, CA 94088-3642
+ *
+ */
+
+#ifndef REFCLOCK_PALISADE_H
+#define REFCLOCK_PALISADE_H
+
+#if defined HAVE_SYS_MODEM_H
+#include <sys/modem.h>
+#ifndef __QNXNTO__
+#define TIOCMSET MCSETA
+#define TIOCMGET MCGETA
+#define TIOCM_RTS MRTS
+#endif
+#endif
+
+#ifdef HAVE_TERMIOS_H
+# ifdef TERMIOS_NEEDS__SVID3
+# define _SVID3
+# endif
+# include <termios.h>
+# include <sys/stat.h>
+# ifdef TERMIOS_NEEDS__SVID3
+# undef _SVID3
+# endif
+#endif
+
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
+#include "ntpd.h"
+#include "ntp_io.h"
+#include "ntp_control.h"
+#include "ntp_refclock.h"
+#include "ntp_unixtime.h"
+#include "ntp_stdlib.h"
+
+/*
+ * GPS Definitions
+ */
+#define DESCRIPTION "Trimble Palisade GPS" /* Long name */
+#define PRECISION (-20) /* precision assumed (about 1 us) */
+#define REFID "GPS\0" /* reference ID */
+#define TRMB_MINPOLL 4 /* 16 seconds */
+#define TRMB_MAXPOLL 5 /* 32 seconds */
+
+/*
+ * I/O Definitions
+ */
+#define DEVICE "/dev/palisade%d" /* device name and unit */
+#define SPEED232 B9600 /* uart speed (9600 baud) */
+
+/*
+ * TSIP Report Definitions
+ */
+#define LENCODE_8F0B 74 /* Length of TSIP 8F-0B Packet & header */
+#define LENCODE_NTP 22 /* Length of Palisade NTP Packet */
+
+#define LENCODE_8FAC 68 /* Length of Thunderbolt 8F-AC Position Packet*/
+#define LENCODE_8FAB 17 /* Length of Thunderbolt Primary Timing Packet*/
+
+/* Allowed Sub-Packet ID's */
+#define PACKET_8F0B 0x0B
+#define PACKET_NTP 0xAD
+
+/* Thunderbolt Packets */
+#define PACKET_8FAC 0xAC /* Supplementary Thunderbolt Time Packet */
+#define PACKET_8FAB 0xAB /* Primary Thunderbolt Time Packet */
+#define PACKET_6D 0x6D /* Supplementary Thunderbolt Tracking Stats */
+#define PACKET_41 0x41 /* Thunderbolt I dont know what this packet is, it's not documented on my manual*/
+
+/* Acutime Packets */
+#define PACKET_41A 0x41 /* GPS time */
+#define PACKET_46 0x46 /* Receiver Health */
+
+#define DLE 0x10
+#define ETX 0x03
+
+/* parse states */
+#define TSIP_PARSED_EMPTY 0
+#define TSIP_PARSED_FULL 1
+#define TSIP_PARSED_DLE_1 2
+#define TSIP_PARSED_DATA 3
+#define TSIP_PARSED_DLE_2 4
+
+/*
+ * Leap-Insert and Leap-Delete are encoded as follows:
+ * PALISADE_UTC_TIME set and PALISADE_LEAP_PENDING set: INSERT leap
+ */
+
+#define PALISADE_LEAP_INPROGRESS 0x08 /* This is the leap flag */
+#define PALISADE_LEAP_WARNING 0x04 /* GPS Leap Warning (see ICD-200) */
+#define PALISADE_LEAP_PENDING 0x02 /* Leap Pending (24 hours) */
+#define PALISADE_UTC_TIME 0x01 /* UTC time available */
+
+#define mb(_X_) (up->rpt_buf[(_X_ + 1)]) /* shortcut for buffer access */
+
+/* Conversion Definitions */
+#define GPS_PI (3.1415926535898)
+#define R2D (180.0/GPS_PI)
+
+/*
+ * Structure for build data packets for send (thunderbolt uses it only)
+ * taken from Markus Prosch
+ */
+struct packettx
+{
+ short size;
+ u_char *data;
+};
+
+/*
+ * Palisade unit control structure.
+ */
+struct palisade_unit {
+ short unit; /* NTP refclock unit number */
+ int polled; /* flag to detect noreplies */
+ char leap_status; /* leap second flag */
+ char rpt_status; /* TSIP Parser State */
+ short rpt_cnt; /* TSIP packet length so far */
+ char rpt_buf[BMAX]; /* packet assembly buffer */
+ int type; /* Clock mode type */
+ int month; /* for LEAP filter */
+};
+
+/*
+ * Function prototypes
+ */
+
+static int palisade_start (int, struct peer *);
+static void palisade_shutdown (int, struct peer *);
+static void palisade_receive (struct peer *);
+static void palisade_poll (int, struct peer *);
+static void palisade_io (struct recvbuf *);
+int palisade_configure (int, struct peer *);
+int TSIP_decode (struct peer *);
+long HW_poll (struct refclockproc *);
+static double getdbl (u_char *);
+static short getint (u_char *);
+static int32 getlong (u_char *);
+
+
+#ifdef PALISADE_SENDCMD_RESURRECTED
+static void sendcmd (struct packettx *buffer, int c);
+#endif
+static void sendsupercmd (struct packettx *buffer, int c1, int c2);
+static void sendbyte (struct packettx *buffer, int b);
+static void sendint (struct packettx *buffer, int a);
+static int sendetx (struct packettx *buffer, int fd);
+static void init_thunderbolt (int fd);
+static void init_acutime (int fd);
+
+#endif /* REFCLOCK_PALISADE_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/ntpd/version.c b/sebhbsd/freebsd/contrib/ntp/ntpd/version.c
new file mode 100644
index 0000000..fbb74cb
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/ntpd/version.c
@@ -0,0 +1,5 @@
+/*
+ * version file for ntpd
+ */
+#include <config.h>
+const char * _ntp_Version = "ntpd 4.2.8p12";
diff --git a/sebhbsd/freebsd/contrib/ntp/ntpdc/ntpdc.h b/sebhbsd/freebsd/contrib/ntp/ntpdc/ntpdc.h
new file mode 100644
index 0000000..4dfd1eb
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/ntpdc/ntpdc.h
@@ -0,0 +1,67 @@
+/*
+ * ntpdc.h - definitions of interest to ntpdc
+ */
+#include "ntp_fp.h"
+#include "ntp.h"
+#include "ntp_request.h"
+#include "ntp_string.h"
+#include "ntp_malloc.h"
+
+/*
+ * Maximum number of arguments
+ */
+#define MAXARGS 4
+#define MOREARGS 10
+
+/*
+ * Flags for forming descriptors.
+ */
+#define OPT 0x80 /* this argument is optional, or'd with type */
+
+#define NO 0x0
+#define NTP_STR 0x1 /* string argument */
+#define NTP_UINT 0x2 /* unsigned integer */
+#define NTP_INT 0x3 /* signed integer */
+#define NTP_ADD 0x4 /* IP network address */
+#define IP_VERSION 0x5 /* IP version */
+
+/*
+ * Arguments are returned in a struct - no
+ * union space saving is attempted.
+ */
+typedef struct {
+ u_char type;
+ char *string;
+ long ival;
+ u_long uval;
+ sockaddr_u netnum;
+} arg_v;
+
+/*
+ * Structure for passing parsed command line
+ */
+struct parse {
+ char *keyword;
+ arg_v argval[MAXARGS + MOREARGS];
+ size_t nargs;
+};
+
+/*
+ * ntpdc includes a command parser which could charitably be called
+ * crude. The following structure is used to define the command
+ * syntax.
+ */
+struct xcmd {
+ const char *keyword; /* command key word */
+ void (*handler) (struct parse *, FILE *); /* command handler */
+ u_char arg[MAXARGS]; /* descriptors for arguments */
+ const char *desc[MAXARGS]; /* descriptions for arguments */
+ const char *comment;
+};
+
+extern int impl_ver;
+extern int showhostnames;
+extern int s_port;
+
+extern int doquery (int, int, int, size_t, size_t, const char *, size_t *, size_t *, const char **, int, int);
+extern const char * nntohost (sockaddr_u *);
diff --git a/sebhbsd/freebsd/contrib/ntp/ntpdc/ntpdc_ops.c b/sebhbsd/freebsd/contrib/ntp/ntpdc/ntpdc_ops.c
new file mode 100644
index 0000000..f24163b
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/ntpdc/ntpdc_ops.c
@@ -0,0 +1,3153 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * ntpdc_ops.c - subroutines which are called to perform operations by
+ * ntpdc
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stddef.h>
+
+#include "ntpdc.h"
+#include "ntp_net.h"
+#include "ntp_control.h"
+#include "ntp_refclock.h"
+#include "ntp_stdlib.h"
+
+#include <ctype.h>
+#ifdef HAVE_SYS_TIMEX_H
+# include <sys/timex.h>
+#endif
+#if !defined(__bsdi__) && !defined(apollo)
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#endif
+
+#include <arpa/inet.h>
+
+/*
+ * utility functions
+ */
+static int checkitems (size_t, FILE *);
+static int checkitemsize (size_t, size_t);
+static int check1item (size_t, FILE *);
+
+/*
+ * Declarations for command handlers in here
+ */
+static void peerlist (struct parse *, FILE *);
+static void peers (struct parse *, FILE *);
+static void doconfig (struct parse *pcmd, FILE *fp, int mode, int refc);
+static void dmpeers (struct parse *, FILE *);
+static void dopeers (struct parse *, FILE *, int);
+static void printpeer (struct info_peer *, FILE *);
+static void showpeer (struct parse *, FILE *);
+static void peerstats (struct parse *, FILE *);
+static void loopinfo (struct parse *, FILE *);
+static void sysinfo (struct parse *, FILE *);
+static void sysstats (struct parse *, FILE *);
+static void iostats (struct parse *, FILE *);
+static void memstats (struct parse *, FILE *);
+static void timerstats (struct parse *, FILE *);
+static void addpeer (struct parse *, FILE *);
+static void addserver (struct parse *, FILE *);
+static void addrefclock (struct parse *, FILE *);
+static void broadcast (struct parse *, FILE *);
+static void doconfig (struct parse *, FILE *, int, int);
+static void unconfig (struct parse *, FILE *);
+static void set (struct parse *, FILE *);
+static void sys_clear (struct parse *, FILE *);
+static void doset (struct parse *, FILE *, int);
+static void reslist (struct parse *, FILE *);
+static void new_restrict (struct parse *, FILE *);
+static void unrestrict (struct parse *, FILE *);
+static void delrestrict (struct parse *, FILE *);
+static void do_restrict (struct parse *, FILE *, int);
+static void monlist (struct parse *, FILE *);
+static void reset (struct parse *, FILE *);
+static void preset (struct parse *, FILE *);
+static void readkeys (struct parse *, FILE *);
+static void trustkey (struct parse *, FILE *);
+static void untrustkey (struct parse *, FILE *);
+static void do_trustkey (struct parse *, FILE *, int);
+static void authinfo (struct parse *, FILE *);
+static void traps (struct parse *, FILE *);
+static void addtrap (struct parse *, FILE *);
+static void clrtrap (struct parse *, FILE *);
+static void do_addclr_trap (struct parse *, FILE *, int);
+static void requestkey (struct parse *, FILE *);
+static void controlkey (struct parse *, FILE *);
+static void do_changekey (struct parse *, FILE *, int);
+static void ctlstats (struct parse *, FILE *);
+static void clockstat (struct parse *, FILE *);
+static void fudge (struct parse *, FILE *);
+static void clkbug (struct parse *, FILE *);
+static void kerninfo (struct parse *, FILE *);
+static void get_if_stats (struct parse *, FILE *);
+static void do_if_reload (struct parse *, FILE *);
+
+/*
+ * Commands we understand. Ntpdc imports this.
+ */
+struct xcmd opcmds[] = {
+ { "listpeers", peerlist, { OPT|IP_VERSION, NO, NO, NO },
+ { "-4|-6", "", "", "" },
+ "display list of peers the server knows about [IP Version]" },
+ { "peers", peers, { OPT|IP_VERSION, NO, NO, NO },
+ { "-4|-6", "", "", "" },
+ "display peer summary information [IP Version]" },
+ { "dmpeers", dmpeers, { OPT|IP_VERSION, NO, NO, NO },
+ { "-4|-6", "", "", "" },
+ "display peer summary info the way Dave Mills likes it (IP Version)" },
+ { "showpeer", showpeer, { NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD},
+ { "peer_address", "peer2_addr", "peer3_addr", "peer4_addr" },
+ "display detailed information for one or more peers" },
+ { "pstats", peerstats, { NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD },
+ { "peer_address", "peer2_addr", "peer3_addr", "peer4_addr" },
+ "display statistical information for one or more peers" },
+ { "loopinfo", loopinfo, { OPT|NTP_STR, NO, NO, NO },
+ { "oneline|multiline", "", "", "" },
+ "display loop filter information" },
+ { "sysinfo", sysinfo, { NO, NO, NO, NO },
+ { "", "", "", "" },
+ "display local server information" },
+ { "sysstats", sysstats, { NO, NO, NO, NO },
+ { "", "", "", "" },
+ "display local server statistics" },
+ { "memstats", memstats, { NO, NO, NO, NO },
+ { "", "", "", "" },
+ "display peer memory usage statistics" },
+ { "iostats", iostats, { NO, NO, NO, NO },
+ { "", "", "", "" },
+ "display I/O subsystem statistics" },
+ { "timerstats", timerstats, { NO, NO, NO, NO },
+ { "", "", "", "" },
+ "display event timer subsystem statistics" },
+ { "addpeer", addpeer, { NTP_ADD, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR },
+ { "addr", "keyid", "version", "minpoll#|prefer|burst|iburst|'minpoll N'|'maxpoll N'|'keyid N'|'version N' ..." },
+ "configure a new peer association" },
+ { "addserver", addserver, { NTP_ADD, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR },
+ { "addr", "keyid", "version", "minpoll#|prefer|burst|iburst|'minpoll N'|'maxpoll N'|'keyid N'|'version N' ..." },
+ "configure a new server" },
+ { "addrefclock",addrefclock, { NTP_ADD, OPT|NTP_UINT, OPT|NTP_STR, OPT|NTP_STR },
+ { "addr", "mode", "minpoll|prefer", "minpoll|prefer" },
+ "configure a new server" },
+ { "broadcast", broadcast, { NTP_ADD, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR },
+ { "addr", "keyid", "version", "minpoll" },
+ "configure broadcasting time service" },
+ { "unconfig", unconfig, { NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD },
+ { "peer_address", "peer2_addr", "peer3_addr", "peer4_addr" },
+ "unconfigure existing peer assocations" },
+ { "enable", set, { NTP_STR, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR },
+ { "auth|bclient|monitor|pll|kernel|stats", "...", "...", "..." },
+ "set a system flag (auth, bclient, monitor, pll, kernel, stats)" },
+ { "disable", sys_clear, { NTP_STR, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR },
+ { "auth|bclient|monitor|pll|kernel|stats", "...", "...", "..." },
+ "clear a system flag (auth, bclient, monitor, pll, kernel, stats)" },
+ { "reslist", reslist, {OPT|IP_VERSION, NO, NO, NO },
+ { "-4|-6", "", "", "" },
+ "display the server's restrict list" },
+ { "restrict", new_restrict, { NTP_ADD, NTP_ADD, NTP_STR, OPT|NTP_STR },
+ { "address", "mask",
+ "ntpport|ignore|noserve|notrust|noquery|nomodify|nopeer|version|kod",
+ "..." },
+ "create restrict entry/add flags to entry" },
+ { "unrestrict", unrestrict, { NTP_ADD, NTP_ADD, NTP_STR, OPT|NTP_STR },
+ { "address", "mask",
+ "ntpport|ignore|noserve|notrust|noquery|nomodify|nopeer|version|kod",
+ "..." },
+ "remove flags from a restrict entry" },
+ { "delrestrict", delrestrict, { NTP_ADD, NTP_ADD, OPT|NTP_STR, NO },
+ { "address", "mask", "ntpport", "" },
+ "delete a restrict entry" },
+ { "monlist", monlist, { OPT|NTP_INT, NO, NO, NO },
+ { "version", "", "", "" },
+ "display data the server's monitor routines have collected" },
+ { "reset", reset, { NTP_STR, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR },
+ { "io|sys|mem|timer|auth|ctl|allpeers", "...", "...", "..." },
+ "reset various subsystem statistics counters" },
+ { "preset", preset, { NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD },
+ { "peer_address", "peer2_addr", "peer3_addr", "peer4_addr" },
+ "reset stat counters associated with particular peer(s)" },
+ { "readkeys", readkeys, { NO, NO, NO, NO },
+ { "", "", "", "" },
+ "request a reread of the keys file and re-init of system keys" },
+ { "trustedkey", trustkey, { NTP_UINT, OPT|NTP_UINT, OPT|NTP_UINT, OPT|NTP_UINT },
+ { "keyid", "keyid", "keyid", "keyid" },
+ "add one or more key ID's to the trusted list" },
+ { "untrustedkey", untrustkey, { NTP_UINT, OPT|NTP_UINT, OPT|NTP_UINT, OPT|NTP_UINT },
+ { "keyid", "keyid", "keyid", "keyid" },
+ "remove one or more key ID's from the trusted list" },
+ { "authinfo", authinfo, { NO, NO, NO, NO },
+ { "", "", "", "" },
+ "display the state of the authentication code" },
+ { "traps", traps, { NO, NO, NO, NO },
+ { "", "", "", "" },
+ "display the traps set in the server" },
+ { "addtrap", addtrap, { NTP_ADD, OPT|NTP_UINT, OPT|NTP_ADD, NO },
+ { "address", "port", "interface", "" },
+ "configure a trap in the server" },
+ { "clrtrap", clrtrap, { NTP_ADD, OPT|NTP_UINT, OPT|NTP_ADD, NO },
+ { "address", "port", "interface", "" },
+ "remove a trap (configured or otherwise) from the server" },
+ { "requestkey", requestkey, { NTP_UINT, NO, NO, NO },
+ { "keyid", "", "", "" },
+ "change the keyid the server uses to authenticate requests" },
+ { "controlkey", controlkey, { NTP_UINT, NO, NO, NO },
+ { "keyid", "", "", "" },
+ "change the keyid the server uses to authenticate control messages" },
+ { "ctlstats", ctlstats, { NO, NO, NO, NO },
+ { "", "", "", "" },
+ "display packet count statistics from the control module" },
+ { "clockstat", clockstat, { NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD },
+ { "address", "address", "address", "address" },
+ "display clock status information" },
+ { "fudge", fudge, { NTP_ADD, NTP_STR, NTP_STR, NO },
+ { "address", "time1|time2|val1|val2|flags", "value", "" },
+ "set/change one of a clock's fudge factors" },
+ { "clkbug", clkbug, { NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD },
+ { "address", "address", "address", "address" },
+ "display clock debugging information" },
+ { "kerninfo", kerninfo, { NO, NO, NO, NO },
+ { "", "", "", "" },
+ "display the kernel pll/pps variables" },
+ { "ifstats", get_if_stats, { NO, NO, NO, NO },
+ { "", "", "", "" },
+ "list interface statistics" },
+ { "ifreload", do_if_reload, { NO, NO, NO, NO },
+ { "", "", "", "" },
+ "reload interface configuration" },
+ { 0, 0, { NO, NO, NO, NO },
+ { "", "", "", "" }, "" }
+};
+
+/*
+ * For quick string comparisons
+ */
+#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0)
+
+/*
+ * SET_SS_LEN_IF_PRESENT - used by SET_ADDR, SET_ADDRS macros
+ */
+
+#ifdef ISC_PLATFORM_HAVESALEN
+#define SET_SS_LEN_IF_PRESENT(psau) \
+ do { \
+ (psau)->sa.sa_len = SOCKLEN(psau); \
+ } while (0)
+#else
+#define SET_SS_LEN_IF_PRESENT(psau) do { } while (0)
+#endif
+
+/*
+ * SET_ADDR - setup address for v4/v6 as needed
+ */
+#define SET_ADDR(address, v6flag, v4addr, v6addr) \
+do { \
+ ZERO(address); \
+ if (v6flag) { \
+ AF(&(address)) = AF_INET6; \
+ SOCK_ADDR6(&(address)) = (v6addr); \
+ } else { \
+ AF(&(address)) = AF_INET; \
+ NSRCADR(&(address)) = (v4addr); \
+ } \
+ SET_SS_LEN_IF_PRESENT(&(address)); \
+} while (0)
+
+
+/*
+ * SET_ADDRS - setup source and destination addresses for
+ * v4/v6 as needed
+ */
+#define SET_ADDRS(a1, a2, info, a1prefix, a2prefix) \
+do { \
+ ZERO(a1); \
+ ZERO(a2); \
+ if ((info)->v6_flag) { \
+ AF(&(a1)) = AF_INET6; \
+ AF(&(a2)) = AF_INET6; \
+ SOCK_ADDR6(&(a1)) = (info)->a1prefix##6; \
+ SOCK_ADDR6(&(a2)) = (info)->a2prefix##6; \
+ } else { \
+ AF(&(a1)) = AF_INET; \
+ AF(&(a2)) = AF_INET; \
+ NSRCADR(&(a1)) = (info)->a1prefix; \
+ NSRCADR(&(a2)) = (info)->a2prefix; \
+ } \
+ SET_SS_LEN_IF_PRESENT(&(a1)); \
+ SET_SS_LEN_IF_PRESENT(&(a2)); \
+} while (0)
+
+
+/*
+ * checkitems - utility to print a message if no items were returned
+ */
+static int
+checkitems(
+ size_t items,
+ FILE *fp
+ )
+{
+ if (items == 0) {
+ (void) fprintf(fp, "No data returned in response to query\n");
+ return 0;
+ }
+ return 1;
+}
+
+
+/*
+ * checkitemsize - utility to print a message if the item size is wrong
+ */
+static int
+checkitemsize(
+ size_t itemsize,
+ size_t expected
+ )
+{
+ if (itemsize != expected) {
+ (void) fprintf(stderr,
+ "***Incorrect item size returned by remote host (%lu should be %lu)\n",
+ (u_long)itemsize, (u_long)expected);
+ return 0;
+ }
+ return 1;
+}
+
+
+/*
+ * check1item - check to make sure we have exactly one item
+ */
+static int
+check1item(
+ size_t items,
+ FILE *fp
+ )
+{
+ if (items == 0) {
+ (void) fprintf(fp, "No data returned in response to query\n");
+ return 0;
+ }
+ if (items > 1) {
+ (void) fprintf(fp, "Expected one item in response, got %lu\n",
+ (u_long)items);
+ return 0;
+ }
+ return 1;
+}
+
+
+/*
+ * peerlist - get a short list of peers
+ */
+/*ARGSUSED*/
+static void
+peerlist(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ struct info_peer_list *plist;
+ sockaddr_u paddr;
+ size_t items;
+ size_t itemsize;
+ int res;
+
+again:
+ res = doquery(impl_ver, REQ_PEER_LIST, 0, 0, 0, (char *)NULL, &items,
+ &itemsize, (void *)&plist, 0,
+ sizeof(struct info_peer_list));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res != 0)
+ return;
+
+ if (!checkitems(items, fp))
+ return;
+
+ if (!checkitemsize(itemsize, sizeof(struct info_peer_list)) &&
+ !checkitemsize(itemsize, v4sizeof(struct info_peer_list)))
+ return;
+
+ while (items > 0) {
+ SET_ADDR(paddr, plist->v6_flag, plist->addr, plist->addr6);
+ if ((pcmd->nargs == 0) ||
+ ((pcmd->argval->ival == 6) && (plist->v6_flag != 0)) ||
+ ((pcmd->argval->ival == 4) && (plist->v6_flag == 0)))
+ (void) fprintf(fp, "%-9s %s\n",
+ modetoa(plist->hmode),
+ nntohost(&paddr));
+ plist++;
+ items--;
+ }
+}
+
+
+/*
+ * peers - show peer summary
+ */
+static void
+peers(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ dopeers(pcmd, fp, 0);
+}
+
+/*
+ * dmpeers - show peer summary, Dave Mills style
+ */
+static void
+dmpeers(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ dopeers(pcmd, fp, 1);
+}
+
+
+/*
+ * peers - show peer summary
+ */
+/*ARGSUSED*/
+static void
+dopeers(
+ struct parse *pcmd,
+ FILE *fp,
+ int dmstyle
+ )
+{
+ struct info_peer_summary *plist;
+ sockaddr_u dstadr;
+ sockaddr_u srcadr;
+ size_t items;
+ size_t itemsize;
+ int ntp_poll;
+ int res;
+ int c;
+ l_fp tempts;
+
+again:
+ res = doquery(impl_ver, REQ_PEER_LIST_SUM, 0, 0, 0, (char *)NULL,
+ &items, &itemsize, (void *)&plist, 0,
+ sizeof(struct info_peer_summary));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res != 0)
+ return;
+
+ if (!checkitems(items, fp))
+ return;
+
+ if (!checkitemsize(itemsize, sizeof(struct info_peer_summary)) &&
+ !checkitemsize(itemsize, v4sizeof(struct info_peer_summary)))
+ return;
+
+ (void) fprintf(fp,
+ " remote local st poll reach delay offset disp\n");
+ (void) fprintf(fp,
+ "=======================================================================\n");
+ while (items > 0) {
+ if (!dmstyle) {
+ if (plist->flags & INFO_FLAG_SYSPEER)
+ c = '*';
+ else if (plist->hmode == MODE_ACTIVE)
+ c = '+';
+ else if (plist->hmode == MODE_PASSIVE)
+ c = '-';
+ else if (plist->hmode == MODE_CLIENT)
+ c = '=';
+ else if (plist->hmode == MODE_BROADCAST)
+ c = '^';
+ else if (plist->hmode == MODE_BCLIENT)
+ c = '~';
+ else
+ c = ' ';
+ } else {
+ if (plist->flags & INFO_FLAG_SYSPEER)
+ c = '*';
+ else if (plist->flags & INFO_FLAG_SHORTLIST)
+ c = '+';
+ else if (plist->flags & INFO_FLAG_SEL_CANDIDATE)
+ c = '.';
+ else
+ c = ' ';
+ }
+ NTOHL_FP(&(plist->offset), &tempts);
+ ntp_poll = 1<<max(min3(plist->ppoll, plist->hpoll, NTP_MAXPOLL),
+ NTP_MINPOLL);
+ SET_ADDRS(dstadr, srcadr, plist, dstadr, srcadr);
+ if ((pcmd->nargs == 0) ||
+ ((pcmd->argval->ival == 6) && (plist->v6_flag != 0)) ||
+ ((pcmd->argval->ival == 4) && (plist->v6_flag == 0)))
+ (void) fprintf(fp,
+ "%c%-15.15s %-15.15s %2u %4d %3o %7.7s %9.9s %7.7s\n",
+ c, nntohost(&srcadr), stoa(&dstadr),
+ plist->stratum, ntp_poll, plist->reach,
+ fptoa(NTOHS_FP(plist->delay), 5),
+ lfptoa(&tempts, 6),
+ ufptoa(NTOHS_FP(plist->dispersion), 5));
+ plist++;
+ items--;
+ }
+}
+
+/* Convert a refid & stratum (in host order) to a string */
+static char *
+refid_string(
+ u_int32 refid,
+ int stratum
+ )
+{
+ if (stratum <= 1) {
+ static char junk[5];
+ junk[4] = 0;
+ memcpy(junk, &refid, 4);
+ return junk;
+ }
+
+ return numtoa(refid);
+}
+
+static void
+print_pflag(
+ FILE * fp,
+ u_int32 flags
+ )
+{
+ static const char none[] = "";
+ static const char comma[] = ",";
+ const char *dlim;
+
+ if (0 == flags) {
+ fprintf(fp, " none\n");
+ return;
+ }
+ dlim = none;
+ if (flags & INFO_FLAG_SYSPEER) {
+ fprintf(fp, " system_peer");
+ dlim = comma;
+ }
+ if (flags & INFO_FLAG_CONFIG) {
+ fprintf(fp, "%s config", dlim);
+ dlim = comma;
+ }
+ if (flags & INFO_FLAG_REFCLOCK) {
+ fprintf(fp, "%s refclock", dlim);
+ dlim = comma;
+ }
+ if (flags & INFO_FLAG_AUTHENABLE) {
+ fprintf(fp, "%s auth", dlim);
+ dlim = comma;
+ }
+ if (flags & INFO_FLAG_PREFER) {
+ fprintf(fp, "%s prefer", dlim);
+ dlim = comma;
+ }
+ if (flags & INFO_FLAG_IBURST) {
+ fprintf(fp, "%s iburst", dlim);
+ dlim = comma;
+ }
+ if (flags & INFO_FLAG_BURST) {
+ fprintf(fp, "%s burst", dlim);
+ dlim = comma;
+ }
+ if (flags & INFO_FLAG_SEL_CANDIDATE) {
+ fprintf(fp, "%s candidate", dlim);
+ dlim = comma;
+ }
+ if (flags & INFO_FLAG_SHORTLIST) {
+ fprintf(fp, "%s shortlist", dlim);
+ dlim = comma;
+ }
+ fprintf(fp, "\n");
+}
+/*
+ * printpeer - print detail information for a peer
+ */
+static void
+printpeer(
+ register struct info_peer *pp,
+ FILE *fp
+ )
+{
+ register int i;
+ l_fp tempts;
+ sockaddr_u srcadr, dstadr;
+
+ SET_ADDRS(dstadr, srcadr, pp, dstadr, srcadr);
+
+ (void) fprintf(fp, "remote %s, local %s\n",
+ stoa(&srcadr), stoa(&dstadr));
+ (void) fprintf(fp, "hmode %s, pmode %s, stratum %d, precision %d\n",
+ modetoa(pp->hmode), modetoa(pp->pmode),
+ pp->stratum, pp->precision);
+
+ (void) fprintf(fp,
+ "leap %c%c, refid [%s], rootdistance %s, rootdispersion %s\n",
+ pp->leap & 0x2 ? '1' : '0',
+ pp->leap & 0x1 ? '1' : '0',
+ refid_string(pp->refid, pp->stratum), fptoa(NTOHS_FP(pp->rootdelay), 5),
+ ufptoa(NTOHS_FP(pp->rootdispersion), 5));
+
+ (void) fprintf(fp,
+ "ppoll %d, hpoll %d, keyid %lu, version %d, association %u\n",
+ pp->ppoll, pp->hpoll, (u_long)pp->keyid, pp->version, ntohs(pp->associd));
+
+ (void) fprintf(fp,
+ "reach %03o, unreach %d, flash 0x%04x, ",
+ pp->reach, pp->unreach, pp->flash2);
+
+ (void) fprintf(fp, "boffset %s, ttl/mode %d\n",
+ fptoa(NTOHS_FP(pp->estbdelay), 5), pp->ttl);
+
+ (void) fprintf(fp, "timer %lds, flags", (long)ntohl(pp->timer));
+ print_pflag(fp, pp->flags);
+
+ NTOHL_FP(&pp->reftime, &tempts);
+ (void) fprintf(fp, "reference time: %s\n",
+ prettydate(&tempts));
+ NTOHL_FP(&pp->org, &tempts);
+ (void) fprintf(fp, "originate timestamp: %s\n",
+ prettydate(&tempts));
+ NTOHL_FP(&pp->rec, &tempts);
+ (void) fprintf(fp, "receive timestamp: %s\n",
+ prettydate(&tempts));
+ NTOHL_FP(&pp->xmt, &tempts);
+ (void) fprintf(fp, "transmit timestamp: %s\n",
+ prettydate(&tempts));
+
+ (void) fprintf(fp, "filter delay: ");
+ for (i = 0; i < NTP_SHIFT; i++) {
+ (void) fprintf(fp, " %-8.8s",
+ fptoa(NTOHS_FP(pp->filtdelay[i]), 5));
+ if (i == (NTP_SHIFT>>1)-1)
+ (void) fprintf(fp, "\n ");
+ }
+ (void) fprintf(fp, "\n");
+
+ (void) fprintf(fp, "filter offset:");
+ for (i = 0; i < NTP_SHIFT; i++) {
+ NTOHL_FP(&pp->filtoffset[i], &tempts);
+ (void) fprintf(fp, " %-8.8s", lfptoa(&tempts, 6));
+ if (i == (NTP_SHIFT>>1)-1)
+ (void) fprintf(fp, "\n ");
+ }
+ (void) fprintf(fp, "\n");
+
+ (void) fprintf(fp, "filter order: ");
+ for (i = 0; i < NTP_SHIFT; i++) {
+ (void) fprintf(fp, " %-8d", pp->order[i]);
+ if (i == (NTP_SHIFT>>1)-1)
+ (void) fprintf(fp, "\n ");
+ }
+ (void) fprintf(fp, "\n");
+
+
+ NTOHL_FP(&pp->offset, &tempts);
+ (void) fprintf(fp,
+ "offset %s, delay %s, error bound %s, filter error %s\n",
+ lfptoa(&tempts, 6), fptoa(NTOHS_FP(pp->delay), 5),
+ ufptoa(NTOHS_FP(pp->dispersion), 5),
+ ufptoa(NTOHS_FP(pp->selectdisp), 5));
+}
+
+
+/*
+ * showpeer - show detailed information for a peer
+ */
+static void
+showpeer(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ struct info_peer *pp;
+ /* 4 is the maximum number of peers which will fit in a packet */
+ struct info_peer_list *pl, plist[min(MAXARGS, 4)];
+ size_t qitemlim;
+ size_t qitems;
+ size_t items;
+ size_t itemsize;
+ int res;
+ int sendsize;
+
+again:
+ if (impl_ver == IMPL_XNTPD)
+ sendsize = sizeof(struct info_peer_list);
+ else
+ sendsize = v4sizeof(struct info_peer_list);
+
+ qitemlim = min(pcmd->nargs, COUNTOF(plist));
+ for (qitems = 0, pl = plist; qitems < qitemlim; qitems++) {
+ if (IS_IPV4(&pcmd->argval[qitems].netnum)) {
+ pl->addr = NSRCADR(&pcmd->argval[qitems].netnum);
+ if (impl_ver == IMPL_XNTPD)
+ pl->v6_flag = 0;
+ } else {
+ if (impl_ver == IMPL_XNTPD_OLD) {
+ fprintf(stderr,
+ "***Server doesn't understand IPv6 addresses\n");
+ return;
+ }
+ pl->addr6 = SOCK_ADDR6(&pcmd->argval[qitems].netnum);
+ pl->v6_flag = 1;
+ }
+ pl->port = (u_short)s_port;
+ pl->hmode = pl->flags = 0;
+ pl = (void *)((char *)pl + sendsize);
+ }
+
+ res = doquery(impl_ver, REQ_PEER_INFO, 0, qitems,
+ sendsize, (char *)plist, &items,
+ &itemsize, (void *)&pp, 0, sizeof(struct info_peer));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res != 0)
+ return;
+
+ if (!checkitems(items, fp))
+ return;
+
+ if (!checkitemsize(itemsize, sizeof(struct info_peer)) &&
+ !checkitemsize(itemsize, v4sizeof(struct info_peer)))
+ return;
+
+ while (items-- > 0) {
+ printpeer(pp, fp);
+ if (items > 0)
+ fprintf(fp, "\n");
+ pp++;
+ }
+}
+
+
+/*
+ * peerstats - return statistics for a peer
+ */
+static void
+peerstats(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ struct info_peer_stats *pp;
+ /* 4 is the maximum number of peers which will fit in a packet */
+ struct info_peer_list *pl, plist[min(MAXARGS, 4)];
+ sockaddr_u src, dst;
+ size_t qitemlim;
+ size_t qitems;
+ size_t items;
+ size_t itemsize;
+ int res;
+ size_t sendsize;
+
+again:
+ if (impl_ver == IMPL_XNTPD)
+ sendsize = sizeof(struct info_peer_list);
+ else
+ sendsize = v4sizeof(struct info_peer_list);
+
+ ZERO(plist);
+
+ qitemlim = min(pcmd->nargs, COUNTOF(plist));
+ for (qitems = 0, pl = plist; qitems < qitemlim; qitems++) {
+ if (IS_IPV4(&pcmd->argval[qitems].netnum)) {
+ pl->addr = NSRCADR(&pcmd->argval[qitems].netnum);
+ if (impl_ver == IMPL_XNTPD)
+ pl->v6_flag = 0;
+ } else {
+ if (impl_ver == IMPL_XNTPD_OLD) {
+ fprintf(stderr,
+ "***Server doesn't understand IPv6 addresses\n");
+ return;
+ }
+ pl->addr6 = SOCK_ADDR6(&pcmd->argval[qitems].netnum);
+ pl->v6_flag = 1;
+ }
+ pl->port = (u_short)s_port;
+ pl->hmode = plist[qitems].flags = 0;
+ pl = (void *)((char *)pl + sendsize);
+ }
+
+ res = doquery(impl_ver, REQ_PEER_STATS, 0, qitems,
+ sendsize, (char *)plist, &items,
+ &itemsize, (void *)&pp, 0,
+ sizeof(struct info_peer_stats));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res != 0)
+ return;
+
+ if (!checkitems(items, fp))
+ return;
+
+ if (!checkitemsize(itemsize, sizeof(struct info_peer_stats)) &&
+ !checkitemsize(itemsize, v4sizeof(struct info_peer_stats)))
+ return;
+
+ while (items-- > 0) {
+ ZERO_SOCK(&dst);
+ ZERO_SOCK(&src);
+ if (pp->v6_flag != 0) {
+ AF(&dst) = AF_INET6;
+ AF(&src) = AF_INET6;
+ SOCK_ADDR6(&dst) = pp->dstadr6;
+ SOCK_ADDR6(&src) = pp->srcadr6;
+ } else {
+ AF(&dst) = AF_INET;
+ AF(&src) = AF_INET;
+ NSRCADR(&dst) = pp->dstadr;
+ NSRCADR(&src) = pp->srcadr;
+ }
+#ifdef ISC_PLATFORM_HAVESALEN
+ src.sa.sa_len = SOCKLEN(&src);
+ dst.sa.sa_len = SOCKLEN(&dst);
+#endif
+ fprintf(fp, "remote host: %s\n",
+ nntohost(&src));
+ fprintf(fp, "local interface: %s\n",
+ stoa(&dst));
+ fprintf(fp, "time last received: %lus\n",
+ (u_long)ntohl(pp->timereceived));
+ fprintf(fp, "time until next send: %lus\n",
+ (u_long)ntohl(pp->timetosend));
+ fprintf(fp, "reachability change: %lus\n",
+ (u_long)ntohl(pp->timereachable));
+ fprintf(fp, "packets sent: %lu\n",
+ (u_long)ntohl(pp->sent));
+ fprintf(fp, "packets received: %lu\n",
+ (u_long)ntohl(pp->processed));
+ fprintf(fp, "bad authentication: %lu\n",
+ (u_long)ntohl(pp->badauth));
+ fprintf(fp, "bogus origin: %lu\n",
+ (u_long)ntohl(pp->bogusorg));
+ fprintf(fp, "duplicate: %lu\n",
+ (u_long)ntohl(pp->oldpkt));
+ fprintf(fp, "bad dispersion: %lu\n",
+ (u_long)ntohl(pp->seldisp));
+ fprintf(fp, "bad reference time: %lu\n",
+ (u_long)ntohl(pp->selbroken));
+ fprintf(fp, "candidate order: %u\n",
+ pp->candidate);
+ if (items > 0)
+ fprintf(fp, "\n");
+ fprintf(fp, "flags: ");
+ print_pflag(fp, ntohs(pp->flags));
+ pp++;
+ }
+}
+
+
+/*
+ * loopinfo - show loop filter information
+ */
+static void
+loopinfo(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ struct info_loop *il;
+ size_t items;
+ size_t itemsize;
+ int oneline = 0;
+ int res;
+ l_fp tempts;
+
+ if (pcmd->nargs > 0) {
+ if (STREQ(pcmd->argval[0].string, "oneline"))
+ oneline = 1;
+ else if (STREQ(pcmd->argval[0].string, "multiline"))
+ oneline = 0;
+ else {
+ (void) fprintf(stderr, "How many lines?\n");
+ return;
+ }
+ }
+
+again:
+ res = doquery(impl_ver, REQ_LOOP_INFO, 0, 0, 0, (char *)NULL,
+ &items, &itemsize, (void *)&il, 0,
+ sizeof(struct info_loop));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res != 0)
+ return;
+
+ if (!check1item(items, fp))
+ return;
+
+ if (!checkitemsize(itemsize, sizeof(struct info_loop)))
+ return;
+
+ if (oneline) {
+ l_fp temp2ts;
+
+ NTOHL_FP(&il->last_offset, &tempts);
+ NTOHL_FP(&il->drift_comp, &temp2ts);
+
+ (void) fprintf(fp,
+ "offset %s, frequency %s, time_const %ld, watchdog %ld\n",
+ lfptoa(&tempts, 6),
+ lfptoa(&temp2ts, 3),
+ (long)(int32)ntohl((u_long)il->compliance),
+ (u_long)ntohl((u_long)il->watchdog_timer));
+ } else {
+ NTOHL_FP(&il->last_offset, &tempts);
+ (void) fprintf(fp, "offset: %s s\n",
+ lfptoa(&tempts, 6));
+ NTOHL_FP(&il->drift_comp, &tempts);
+ (void) fprintf(fp, "frequency: %s ppm\n",
+ lfptoa(&tempts, 3));
+ (void) fprintf(fp, "poll adjust: %ld\n",
+ (long)(int32)ntohl(il->compliance));
+ (void) fprintf(fp, "watchdog timer: %ld s\n",
+ (u_long)ntohl(il->watchdog_timer));
+ }
+}
+
+
+/*
+ * sysinfo - show current system state
+ */
+/*ARGSUSED*/
+static void
+sysinfo(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ struct info_sys *is;
+ sockaddr_u peeraddr;
+ size_t items;
+ size_t itemsize;
+ int res;
+ l_fp tempts;
+
+again:
+ res = doquery(impl_ver, REQ_SYS_INFO, 0, 0, 0, (char *)NULL,
+ &items, &itemsize, (void *)&is, 0,
+ sizeof(struct info_sys));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res != 0)
+ return;
+
+ if (!check1item(items, fp))
+ return;
+
+ if (!checkitemsize(itemsize, sizeof(struct info_sys)) &&
+ !checkitemsize(itemsize, v4sizeof(struct info_sys)))
+ return;
+
+ SET_ADDR(peeraddr, is->v6_flag, is->peer, is->peer6);
+
+ (void) fprintf(fp, "system peer: %s\n", nntohost(&peeraddr));
+ (void) fprintf(fp, "system peer mode: %s\n", modetoa(is->peer_mode));
+ (void) fprintf(fp, "leap indicator: %c%c\n",
+ is->leap & 0x2 ? '1' : '0',
+ is->leap & 0x1 ? '1' : '0');
+ (void) fprintf(fp, "stratum: %d\n", (int)is->stratum);
+ (void) fprintf(fp, "precision: %d\n", (int)is->precision);
+ (void) fprintf(fp, "root distance: %s s\n",
+ fptoa(NTOHS_FP(is->rootdelay), 5));
+ (void) fprintf(fp, "root dispersion: %s s\n",
+ ufptoa(NTOHS_FP(is->rootdispersion), 5));
+ (void) fprintf(fp, "reference ID: [%s]\n",
+ refid_string(is->refid, is->stratum));
+ NTOHL_FP(&is->reftime, &tempts);
+ (void) fprintf(fp, "reference time: %s\n", prettydate(&tempts));
+
+ (void) fprintf(fp, "system flags: ");
+ if ((is->flags & (INFO_FLAG_BCLIENT | INFO_FLAG_AUTHENABLE |
+ INFO_FLAG_NTP | INFO_FLAG_KERNEL| INFO_FLAG_CAL |
+ INFO_FLAG_PPS_SYNC | INFO_FLAG_MONITOR | INFO_FLAG_FILEGEN)) == 0) {
+ (void) fprintf(fp, "none\n");
+ } else {
+ if (is->flags & INFO_FLAG_BCLIENT)
+ (void) fprintf(fp, "bclient ");
+ if (is->flags & INFO_FLAG_AUTHENTICATE)
+ (void) fprintf(fp, "auth ");
+ if (is->flags & INFO_FLAG_MONITOR)
+ (void) fprintf(fp, "monitor ");
+ if (is->flags & INFO_FLAG_NTP)
+ (void) fprintf(fp, "ntp ");
+ if (is->flags & INFO_FLAG_KERNEL)
+ (void) fprintf(fp, "kernel ");
+ if (is->flags & INFO_FLAG_FILEGEN)
+ (void) fprintf(fp, "stats ");
+ if (is->flags & INFO_FLAG_CAL)
+ (void) fprintf(fp, "calibrate ");
+ if (is->flags & INFO_FLAG_PPS_SYNC)
+ (void) fprintf(fp, "pps ");
+ (void) fprintf(fp, "\n");
+ }
+ (void) fprintf(fp, "jitter: %s s\n",
+ fptoa(ntohl(is->frequency), 6));
+ (void) fprintf(fp, "stability: %s ppm\n",
+ ufptoa(ntohl(is->stability), 3));
+ (void) fprintf(fp, "broadcastdelay: %s s\n",
+ fptoa(NTOHS_FP(is->bdelay), 6));
+ NTOHL_FP(&is->authdelay, &tempts);
+ (void) fprintf(fp, "authdelay: %s s\n", lfptoa(&tempts, 6));
+}
+
+
+/*
+ * sysstats - print system statistics
+ */
+/*ARGSUSED*/
+static void
+sysstats(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ struct info_sys_stats *ss;
+ size_t items;
+ size_t itemsize;
+ int res;
+
+again:
+ res = doquery(impl_ver, REQ_SYS_STATS, 0, 0, 0, (char *)NULL,
+ &items, &itemsize, (void *)&ss, 0,
+ sizeof(struct info_sys_stats));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res != 0)
+ return;
+
+ if (!check1item(items, fp))
+ return;
+
+ if (itemsize != sizeof(struct info_sys_stats) &&
+ itemsize != sizeof(struct old_info_sys_stats)) {
+ /* issue warning according to new structure size */
+ checkitemsize(itemsize, sizeof(struct info_sys_stats));
+ return;
+ }
+ fprintf(fp, "time since restart: %lu\n",
+ (u_long)ntohl(ss->timeup));
+ fprintf(fp, "time since reset: %lu\n",
+ (u_long)ntohl(ss->timereset));
+ fprintf(fp, "packets received: %lu\n",
+ (u_long)ntohl(ss->received));
+ fprintf(fp, "packets processed: %lu\n",
+ (u_long)ntohl(ss->processed));
+ fprintf(fp, "current version: %lu\n",
+ (u_long)ntohl(ss->newversionpkt));
+ fprintf(fp, "previous version: %lu\n",
+ (u_long)ntohl(ss->oldversionpkt));
+ fprintf(fp, "declined: %lu\n",
+ (u_long)ntohl(ss->unknownversion));
+ fprintf(fp, "access denied: %lu\n",
+ (u_long)ntohl(ss->denied));
+ fprintf(fp, "bad length or format: %lu\n",
+ (u_long)ntohl(ss->badlength));
+ fprintf(fp, "bad authentication: %lu\n",
+ (u_long)ntohl(ss->badauth));
+ if (itemsize != sizeof(struct info_sys_stats))
+ return;
+
+ fprintf(fp, "rate exceeded: %lu\n",
+ (u_long)ntohl(ss->limitrejected));
+}
+
+
+
+/*
+ * iostats - print I/O statistics
+ */
+/*ARGSUSED*/
+static void
+iostats(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ struct info_io_stats *io;
+ size_t items;
+ size_t itemsize;
+ int res;
+
+again:
+ res = doquery(impl_ver, REQ_IO_STATS, 0, 0, 0, NULL, &items,
+ &itemsize, (void *)&io, 0, sizeof(*io));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res != 0)
+ return;
+
+ if (!check1item(items, fp))
+ return;
+
+ if (!checkitemsize(itemsize, sizeof(*io)))
+ return;
+
+ fprintf(fp, "time since reset: %lu\n",
+ (u_long)ntohl(io->timereset));
+ fprintf(fp, "receive buffers: %u\n",
+ (u_int)ntohs(io->totalrecvbufs));
+ fprintf(fp, "free receive buffers: %u\n",
+ (u_int)ntohs(io->freerecvbufs));
+ fprintf(fp, "used receive buffers: %u\n",
+ (u_int)ntohs(io->fullrecvbufs));
+ fprintf(fp, "low water refills: %u\n",
+ (u_int)ntohs(io->lowwater));
+ fprintf(fp, "dropped packets: %lu\n",
+ (u_long)ntohl(io->dropped));
+ fprintf(fp, "ignored packets: %lu\n",
+ (u_long)ntohl(io->ignored));
+ fprintf(fp, "received packets: %lu\n",
+ (u_long)ntohl(io->received));
+ fprintf(fp, "packets sent: %lu\n",
+ (u_long)ntohl(io->sent));
+ fprintf(fp, "packets not sent: %lu\n",
+ (u_long)ntohl(io->notsent));
+ fprintf(fp, "interrupts handled: %lu\n",
+ (u_long)ntohl(io->interrupts));
+ fprintf(fp, "received by int: %lu\n",
+ (u_long)ntohl(io->int_received));
+}
+
+
+/*
+ * memstats - print peer memory statistics
+ */
+/*ARGSUSED*/
+static void
+memstats(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ struct info_mem_stats *mem;
+ int i;
+ size_t items;
+ size_t itemsize;
+ int res;
+
+again:
+ res = doquery(impl_ver, REQ_MEM_STATS, 0, 0, 0, NULL, &items,
+ &itemsize, (void *)&mem, 0, sizeof(*mem));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res != 0)
+ return;
+
+ if (!check1item(items, fp))
+ return;
+
+ if (!checkitemsize(itemsize, sizeof(*mem)))
+ return;
+
+ fprintf(fp, "time since reset: %lu\n",
+ (u_long)ntohl(mem->timereset));
+ fprintf(fp, "total peer memory: %u\n",
+ (u_int)ntohs(mem->totalpeermem));
+ fprintf(fp, "free peer memory: %u\n",
+ (u_int)ntohs(mem->freepeermem));
+ fprintf(fp, "calls to findpeer: %lu\n",
+ (u_long)ntohl(mem->findpeer_calls));
+ fprintf(fp, "new peer allocations: %lu\n",
+ (u_long)ntohl(mem->allocations));
+ fprintf(fp, "peer demobilizations: %lu\n",
+ (u_long)ntohl(mem->demobilizations));
+
+ fprintf(fp, "hash table counts: ");
+ for (i = 0; i < NTP_HASH_SIZE; i++) {
+ fprintf(fp, "%4d", (int)mem->hashcount[i]);
+ if ((i % 8) == 7 && i != (NTP_HASH_SIZE-1))
+ fprintf(fp, "\n ");
+ }
+ fprintf(fp, "\n");
+}
+
+
+
+/*
+ * timerstats - print timer statistics
+ */
+/*ARGSUSED*/
+static void
+timerstats(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ struct info_timer_stats *tim;
+ size_t items;
+ size_t itemsize;
+ int res;
+
+again:
+ res = doquery(impl_ver, REQ_TIMER_STATS, 0, 0, 0, NULL, &items,
+ &itemsize, (void *)&tim, 0, sizeof(*tim));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res != 0)
+ return;
+
+ if (!check1item(items, fp))
+ return;
+
+ if (!checkitemsize(itemsize, sizeof(*tim)))
+ return;
+
+ fprintf(fp, "time since reset: %lu\n",
+ (u_long)ntohl(tim->timereset));
+ fprintf(fp, "alarms handled: %lu\n",
+ (u_long)ntohl(tim->alarms));
+ fprintf(fp, "alarm overruns: %lu\n",
+ (u_long)ntohl(tim->overflows));
+ fprintf(fp, "calls to transmit: %lu\n",
+ (u_long)ntohl(tim->xmtcalls));
+}
+
+
+/*
+ * addpeer - configure an active mode association
+ */
+static void
+addpeer(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ doconfig(pcmd, fp, MODE_ACTIVE, 0);
+}
+
+
+/*
+ * addserver - configure a client mode association
+ */
+static void
+addserver(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ doconfig(pcmd, fp, MODE_CLIENT, 0);
+}
+
+/*
+ * addrefclock - configure a reference clock association
+ */
+static void
+addrefclock(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ doconfig(pcmd, fp, MODE_CLIENT, 1);
+}
+
+/*
+ * broadcast - configure a broadcast mode association
+ */
+static void
+broadcast(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ doconfig(pcmd, fp, MODE_BROADCAST, 0);
+}
+
+
+/*
+ * config - configure a new peer association
+ */
+static void
+doconfig(
+ struct parse *pcmd,
+ FILE *fp,
+ int mode,
+ int refc
+ )
+{
+ struct conf_peer cpeer;
+ size_t items;
+ size_t itemsize;
+ const char *dummy;
+ u_long keyid;
+ u_int version;
+ u_char minpoll;
+ u_char maxpoll;
+ u_int flags;
+ u_char cmode;
+ int res;
+ int sendsize;
+ int numtyp;
+ long val;
+
+again:
+ keyid = 0;
+ version = 3;
+ flags = 0;
+ res = FALSE;
+ cmode = 0;
+ minpoll = NTP_MINDPOLL;
+ maxpoll = NTP_MAXDPOLL;
+ numtyp = 1;
+ if (refc)
+ numtyp = 5;
+
+ if (impl_ver == IMPL_XNTPD)
+ sendsize = sizeof(struct conf_peer);
+ else
+ sendsize = v4sizeof(struct conf_peer);
+
+ items = 1;
+ while (pcmd->nargs > (size_t)items) {
+ if (STREQ(pcmd->argval[items].string, "prefer"))
+ flags |= CONF_FLAG_PREFER;
+ else if (STREQ(pcmd->argval[items].string, "burst"))
+ flags |= CONF_FLAG_BURST;
+ else if (STREQ(pcmd->argval[items].string, "iburst"))
+ flags |= CONF_FLAG_IBURST;
+ else if (!refc && STREQ(pcmd->argval[items].string, "keyid"))
+ numtyp = 1;
+ else if (!refc && STREQ(pcmd->argval[items].string, "version"))
+ numtyp = 2;
+ else if (STREQ(pcmd->argval[items].string, "minpoll"))
+ numtyp = 3;
+ else if (STREQ(pcmd->argval[items].string, "maxpoll"))
+ numtyp = 4;
+ else {
+ if (!atoint(pcmd->argval[items].string, &val))
+ numtyp = 0;
+ switch (numtyp) {
+ case 1:
+ keyid = val;
+ numtyp = 2;
+ break;
+
+ case 2:
+ version = (u_int)val;
+ numtyp = 0;
+ break;
+
+ case 3:
+ minpoll = (u_char)val;
+ numtyp = 0;
+ break;
+
+ case 4:
+ maxpoll = (u_char)val;
+ numtyp = 0;
+ break;
+
+ case 5:
+ cmode = (u_char)val;
+ numtyp = 0;
+ break;
+
+ default:
+ fprintf(fp, "*** '%s' not understood\n",
+ pcmd->argval[items].string);
+ res = TRUE;
+ numtyp = 0;
+ }
+ if (val < 0) {
+ fprintf(stderr,
+ "*** Value '%s' should be unsigned\n",
+ pcmd->argval[items].string);
+ res = TRUE;
+ }
+ }
+ items++;
+ }
+ if (keyid > 0)
+ flags |= CONF_FLAG_AUTHENABLE;
+ if (version > NTP_VERSION || version < NTP_OLDVERSION) {
+ fprintf(fp, "***invalid version number: %u\n",
+ version);
+ res = TRUE;
+ }
+ if (minpoll < NTP_MINPOLL || minpoll > NTP_MAXPOLL ||
+ maxpoll < NTP_MINPOLL || maxpoll > NTP_MAXPOLL ||
+ minpoll > maxpoll) {
+ fprintf(fp, "***min/max-poll must be within %d..%d\n",
+ NTP_MINPOLL, NTP_MAXPOLL);
+ res = TRUE;
+ }
+
+ if (res)
+ return;
+
+ ZERO(cpeer);
+
+ if (IS_IPV4(&pcmd->argval[0].netnum)) {
+ cpeer.peeraddr = NSRCADR(&pcmd->argval[0].netnum);
+ if (impl_ver == IMPL_XNTPD)
+ cpeer.v6_flag = 0;
+ } else {
+ if (impl_ver == IMPL_XNTPD_OLD) {
+ fprintf(stderr,
+ "***Server doesn't understand IPv6 addresses\n");
+ return;
+ }
+ cpeer.peeraddr6 = SOCK_ADDR6(&pcmd->argval[0].netnum);
+ cpeer.v6_flag = 1;
+ }
+ cpeer.hmode = (u_char) mode;
+ cpeer.keyid = keyid;
+ cpeer.version = (u_char) version;
+ cpeer.minpoll = minpoll;
+ cpeer.maxpoll = maxpoll;
+ cpeer.flags = (u_char)flags;
+ cpeer.ttl = cmode;
+
+ res = doquery(impl_ver, REQ_CONFIG, 1, 1,
+ sendsize, (char *)&cpeer, &items,
+ &itemsize, &dummy, 0, sizeof(struct conf_peer));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res == INFO_ERR_FMT) {
+ (void) fprintf(fp,
+ "***Retrying command with old conf_peer size\n");
+ res = doquery(impl_ver, REQ_CONFIG, 1, 1,
+ sizeof(struct old_conf_peer), (char *)&cpeer,
+ &items, &itemsize, &dummy, 0,
+ sizeof(struct conf_peer));
+ }
+ if (res == 0)
+ (void) fprintf(fp, "done!\n");
+ return;
+}
+
+
+/*
+ * unconfig - unconfigure some associations
+ */
+static void
+unconfig(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ /* 8 is the maximum number of peers which will fit in a packet */
+ struct conf_unpeer *pl, plist[min(MAXARGS, 8)];
+ size_t qitemlim;
+ size_t qitems;
+ size_t items;
+ size_t itemsize;
+ const char *dummy;
+ int res;
+ size_t sendsize;
+
+again:
+ if (impl_ver == IMPL_XNTPD)
+ sendsize = sizeof(struct conf_unpeer);
+ else
+ sendsize = v4sizeof(struct conf_unpeer);
+
+ qitemlim = min(pcmd->nargs, COUNTOF(plist));
+ for (qitems = 0, pl = plist; qitems < qitemlim; qitems++) {
+ if (IS_IPV4(&pcmd->argval[0].netnum)) {
+ pl->peeraddr = NSRCADR(&pcmd->argval[qitems].netnum);
+ if (impl_ver == IMPL_XNTPD)
+ pl->v6_flag = 0;
+ } else {
+ if (impl_ver == IMPL_XNTPD_OLD) {
+ fprintf(stderr,
+ "***Server doesn't understand IPv6 addresses\n");
+ return;
+ }
+ pl->peeraddr6 =
+ SOCK_ADDR6(&pcmd->argval[qitems].netnum);
+ pl->v6_flag = 1;
+ }
+ pl = (void *)((char *)pl + sendsize);
+ }
+
+ res = doquery(impl_ver, REQ_UNCONFIG, 1, qitems,
+ sendsize, (char *)plist, &items,
+ &itemsize, &dummy, 0, sizeof(struct conf_unpeer));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res == 0)
+ (void) fprintf(fp, "done!\n");
+}
+
+
+/*
+ * set - set some system flags
+ */
+static void
+set(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ doset(pcmd, fp, REQ_SET_SYS_FLAG);
+}
+
+
+/*
+ * clear - clear some system flags
+ */
+static void
+sys_clear(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ doset(pcmd, fp, REQ_CLR_SYS_FLAG);
+}
+
+
+/*
+ * doset - set/clear system flags
+ */
+static void
+doset(
+ struct parse *pcmd,
+ FILE *fp,
+ int req
+ )
+{
+ struct conf_sys_flags sys;
+ size_t items;
+ size_t itemsize;
+ const char *dummy;
+ int res;
+
+ sys.flags = 0;
+ res = 0;
+ for (items = 0; (size_t)items < pcmd->nargs; items++) {
+ if (STREQ(pcmd->argval[items].string, "auth"))
+ sys.flags |= SYS_FLAG_AUTH;
+ else if (STREQ(pcmd->argval[items].string, "bclient"))
+ sys.flags |= SYS_FLAG_BCLIENT;
+ else if (STREQ(pcmd->argval[items].string, "calibrate"))
+ sys.flags |= SYS_FLAG_CAL;
+ else if (STREQ(pcmd->argval[items].string, "kernel"))
+ sys.flags |= SYS_FLAG_KERNEL;
+ else if (STREQ(pcmd->argval[items].string, "monitor"))
+ sys.flags |= SYS_FLAG_MONITOR;
+ else if (STREQ(pcmd->argval[items].string, "ntp"))
+ sys.flags |= SYS_FLAG_NTP;
+ else if (STREQ(pcmd->argval[items].string, "pps"))
+ sys.flags |= SYS_FLAG_PPS;
+ else if (STREQ(pcmd->argval[items].string, "stats"))
+ sys.flags |= SYS_FLAG_FILEGEN;
+ else {
+ (void) fprintf(fp, "Unknown flag %s\n",
+ pcmd->argval[items].string);
+ res = 1;
+ }
+ }
+
+ sys.flags = htonl(sys.flags);
+ if (res || sys.flags == 0)
+ return;
+
+again:
+ res = doquery(impl_ver, req, 1, 1,
+ sizeof(struct conf_sys_flags), (char *)&sys, &items,
+ &itemsize, &dummy, 0, sizeof(struct conf_sys_flags));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res == 0)
+ (void) fprintf(fp, "done!\n");
+}
+
+
+/*
+ * data for printing/interrpreting the restrict flags
+ */
+struct resflags {
+ const char *str;
+ int bit;
+};
+
+/* XXX: HMS: we apparently don't report set bits we do not recognize. */
+
+static struct resflags resflagsV2[] = {
+ { "ignore", 0x001 },
+ { "noserve", 0x002 },
+ { "notrust", 0x004 },
+ { "noquery", 0x008 },
+ { "nomodify", 0x010 },
+ { "nopeer", 0x020 },
+ { "notrap", 0x040 },
+ { "lptrap", 0x080 },
+ { "limited", 0x100 },
+ { "", 0 }
+};
+
+static struct resflags resflagsV3[] = {
+ { "ignore", RES_IGNORE },
+ { "noserve", RES_DONTSERVE },
+ { "notrust", RES_DONTTRUST },
+ { "noquery", RES_NOQUERY },
+ { "nomodify", RES_NOMODIFY },
+ { "nopeer", RES_NOPEER },
+ { "notrap", RES_NOTRAP },
+ { "lptrap", RES_LPTRAP },
+ { "limited", RES_LIMITED },
+ { "version", RES_VERSION },
+ { "kod", RES_KOD },
+ { "flake", RES_FLAKE },
+
+ { "", 0 }
+};
+
+static struct resflags resmflags[] = {
+ { "ntpport", RESM_NTPONLY },
+ { "interface", RESM_INTERFACE },
+ { "source", RESM_SOURCE },
+ { "", 0 }
+};
+
+
+/*
+ * reslist - obtain and print the server's restrict list
+ */
+/*ARGSUSED*/
+static void
+reslist(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ struct info_restrict *rl;
+ sockaddr_u resaddr;
+ sockaddr_u maskaddr;
+ size_t items;
+ size_t itemsize;
+ int res;
+ int skip;
+ const char *addr;
+ const char *mask;
+ struct resflags *rf;
+ u_int32 count;
+ u_short rflags;
+ u_short mflags;
+ char flagstr[300];
+ static const char *comma = ", ";
+
+again:
+ res = doquery(impl_ver, REQ_GET_RESTRICT, 0, 0, 0, (char *)NULL,
+ &items, &itemsize, (void *)&rl, 0,
+ sizeof(struct info_restrict));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res != 0)
+ return;
+
+ if (!checkitems(items, fp))
+ return;
+
+ if (!checkitemsize(itemsize, sizeof(struct info_restrict)) &&
+ !checkitemsize(itemsize, v4sizeof(struct info_restrict)))
+ return;
+
+ fprintf(fp,
+ " address mask count flags\n");
+ fprintf(fp,
+ "=====================================================================\n");
+
+ while (items > 0) {
+ SET_ADDRS(resaddr, maskaddr, rl, addr, mask);
+ if (rl->v6_flag != 0) {
+ addr = nntohost(&resaddr);
+ } else {
+ if (rl->mask == (u_int32)0xffffffff)
+ addr = nntohost(&resaddr);
+ else
+ addr = stoa(&resaddr);
+ }
+ mask = stoa(&maskaddr);
+ skip = 1;
+ if ((pcmd->nargs == 0) ||
+ ((pcmd->argval->ival == 6) && (rl->v6_flag != 0)) ||
+ ((pcmd->argval->ival == 4) && (rl->v6_flag == 0)))
+ skip = 0;
+ count = ntohl(rl->count);
+ rflags = ntohs(rl->rflags);
+ mflags = ntohs(rl->mflags);
+ flagstr[0] = '\0';
+
+ res = 1;
+ rf = &resmflags[0];
+ while (rf->bit != 0) {
+ if (mflags & rf->bit) {
+ if (!res)
+ strlcat(flagstr, comma,
+ sizeof(flagstr));
+ res = 0;
+ strlcat(flagstr, rf->str,
+ sizeof(flagstr));
+ }
+ rf++;
+ }
+
+ rf = (impl_ver == IMPL_XNTPD_OLD)
+ ? &resflagsV2[0]
+ : &resflagsV3[0];
+
+ while (rf->bit != 0) {
+ if (rflags & rf->bit) {
+ if (!res)
+ strlcat(flagstr, comma,
+ sizeof(flagstr));
+ res = 0;
+ strlcat(flagstr, rf->str,
+ sizeof(flagstr));
+ }
+ rf++;
+ }
+
+ if (flagstr[0] == '\0')
+ strlcpy(flagstr, "none", sizeof(flagstr));
+
+ if (!skip)
+ fprintf(fp, "%-15.15s %-15.15s %9lu %s\n",
+ addr, mask, (u_long)count, flagstr);
+ rl++;
+ items--;
+ }
+}
+
+
+
+/*
+ * new_restrict - create/add a set of restrictions
+ */
+static void
+new_restrict(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ do_restrict(pcmd, fp, REQ_RESADDFLAGS);
+}
+
+
+/*
+ * unrestrict - remove restriction flags from existing entry
+ */
+static void
+unrestrict(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ do_restrict(pcmd, fp, REQ_RESSUBFLAGS);
+}
+
+
+/*
+ * delrestrict - delete an existing restriction
+ */
+static void
+delrestrict(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ do_restrict(pcmd, fp, REQ_UNRESTRICT);
+}
+
+
+/*
+ * do_restrict - decode commandline restrictions and make the request
+ */
+static void
+do_restrict(
+ struct parse *pcmd,
+ FILE *fp,
+ int req_code
+ )
+{
+ struct conf_restrict cres;
+ size_t items;
+ size_t itemsize;
+ const char *dummy;
+ u_int32 num;
+ u_long bit;
+ int i;
+ size_t res;
+ int err;
+ int sendsize;
+
+ /* Initialize cres */
+ cres.addr = 0;
+ cres.mask = 0;
+ cres.flags = 0;
+ cres.mflags = 0;
+ cres.v6_flag = 0;
+
+again:
+ if (impl_ver == IMPL_XNTPD)
+ sendsize = sizeof(struct conf_restrict);
+ else
+ sendsize = v4sizeof(struct conf_restrict);
+
+ if (IS_IPV4(&pcmd->argval[0].netnum)) {
+ cres.addr = NSRCADR(&pcmd->argval[0].netnum);
+ cres.mask = NSRCADR(&pcmd->argval[1].netnum);
+ if (impl_ver == IMPL_XNTPD)
+ cres.v6_flag = 0;
+ } else {
+ if (impl_ver == IMPL_XNTPD_OLD) {
+ fprintf(stderr,
+ "***Server doesn't understand IPv6 addresses\n");
+ return;
+ }
+ cres.addr6 = SOCK_ADDR6(&pcmd->argval[0].netnum);
+ cres.v6_flag = 1;
+ }
+ cres.flags = 0;
+ cres.mflags = 0;
+ err = FALSE;
+ for (res = 2; res < pcmd->nargs; res++) {
+ if (STREQ(pcmd->argval[res].string, "ntpport")) {
+ cres.mflags |= RESM_NTPONLY;
+ } else {
+ for (i = 0; resflagsV3[i].bit != 0; i++) {
+ if (STREQ(pcmd->argval[res].string,
+ resflagsV3[i].str))
+ break;
+ }
+ if (resflagsV3[i].bit != 0) {
+ cres.flags |= resflagsV3[i].bit;
+ if (req_code == REQ_UNRESTRICT) {
+ fprintf(fp,
+ "Flag %s inappropriate\n",
+ resflagsV3[i].str);
+ err = TRUE;
+ }
+ } else {
+ fprintf(fp, "Unknown flag %s\n",
+ pcmd->argval[res].string);
+ err = TRUE;
+ }
+ }
+ }
+ cres.flags = htons(cres.flags);
+ cres.mflags = htons(cres.mflags);
+
+ /*
+ * Make sure mask for default address is zero. Otherwise,
+ * make sure mask bits are contiguous.
+ */
+ if (IS_IPV4(&pcmd->argval[0].netnum)) {
+ if (cres.addr == 0) {
+ cres.mask = 0;
+ } else {
+ num = ntohl(cres.mask);
+ for (bit = 0x80000000; bit != 0; bit >>= 1)
+ if ((num & bit) == 0)
+ break;
+ for ( ; bit != 0; bit >>= 1)
+ if ((num & bit) != 0)
+ break;
+ if (bit != 0) {
+ fprintf(fp, "Invalid mask %s\n",
+ numtoa(cres.mask));
+ err = TRUE;
+ }
+ }
+ } else {
+ /* XXX IPv6 sanity checking stuff */
+ }
+
+ if (err)
+ return;
+
+ res = doquery(impl_ver, req_code, 1, 1, sendsize, (char *)&cres,
+ &items, &itemsize, &dummy, 0, sizeof(cres));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res == 0)
+ (void) fprintf(fp, "done!\n");
+ return;
+}
+
+
+/*
+ * monlist - obtain and print the server's monitor data
+ */
+/*ARGSUSED*/
+static void
+monlist(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ const char *struct_star;
+ const struct info_monitor *ml;
+ const struct info_monitor_1 *m1;
+ const struct old_info_monitor *oml;
+ sockaddr_u addr;
+ sockaddr_u dstadr;
+ size_t items;
+ size_t itemsize;
+ int res;
+ int version = -1;
+
+ if (pcmd->nargs > 0)
+ version = pcmd->argval[0].ival;
+
+again:
+ res = doquery(impl_ver,
+ (version == 1 || version == -1) ? REQ_MON_GETLIST_1 :
+ REQ_MON_GETLIST, 0, 0, 0, NULL,
+ &items, &itemsize, &struct_star,
+ (version < 0) ? (1 << INFO_ERR_REQ) : 0,
+ sizeof(struct info_monitor_1));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res == INFO_ERR_REQ && version < 0)
+ res = doquery(impl_ver, REQ_MON_GETLIST, 0, 0, 0, NULL,
+ &items, &itemsize, &struct_star, 0,
+ sizeof(struct info_monitor));
+
+ if (res != 0)
+ return;
+
+ if (!checkitems(items, fp))
+ return;
+
+ if (itemsize == sizeof(struct info_monitor_1) ||
+ itemsize == v4sizeof(struct info_monitor_1)) {
+
+ m1 = (const void*)struct_star;
+ fprintf(fp,
+ "remote address port local address count m ver rstr avgint lstint\n");
+ fprintf(fp,
+ "===============================================================================\n");
+ while (items > 0) {
+ SET_ADDRS(dstadr, addr, m1, daddr, addr);
+ if ((pcmd->nargs == 0) ||
+ ((pcmd->argval->ival == 6) && (m1->v6_flag != 0)) ||
+ ((pcmd->argval->ival == 4) && (m1->v6_flag == 0)))
+ fprintf(fp,
+ "%-22.22s %5d %-15s %8lu %1u %1u %6lx %6lu %7lu\n",
+ nntohost(&addr),
+ ntohs(m1->port),
+ stoa(&dstadr),
+ (u_long)ntohl(m1->count),
+ m1->mode,
+ m1->version,
+ (u_long)ntohl(m1->restr),
+ (u_long)ntohl(m1->avg_int),
+ (u_long)ntohl(m1->last_int));
+ m1++;
+ items--;
+ }
+ } else if (itemsize == sizeof(struct info_monitor) ||
+ itemsize == v4sizeof(struct info_monitor)) {
+
+ ml = (const void *)struct_star;
+ fprintf(fp,
+ " address port count mode ver rstr avgint lstint\n");
+ fprintf(fp,
+ "===============================================================================\n");
+ while (items > 0) {
+ SET_ADDR(dstadr, ml->v6_flag, ml->addr, ml->addr6);
+ if ((pcmd->nargs == 0) ||
+ ((pcmd->argval->ival == 6) && (ml->v6_flag != 0)) ||
+ ((pcmd->argval->ival == 4) && (ml->v6_flag == 0)))
+ fprintf(fp,
+ "%-25.25s %5u %9lu %4u %2u %9lx %9lu %9lu\n",
+ nntohost(&dstadr),
+ ntohs(ml->port),
+ (u_long)ntohl(ml->count),
+ ml->mode,
+ ml->version,
+ (u_long)ntohl(ml->restr),
+ (u_long)ntohl(ml->avg_int),
+ (u_long)ntohl(ml->last_int));
+ ml++;
+ items--;
+ }
+ } else if (itemsize == sizeof(struct old_info_monitor)) {
+
+ oml = (const void *)struct_star;
+ fprintf(fp,
+ " address port count mode version lasttime firsttime\n");
+ fprintf(fp,
+ "======================================================================\n");
+ while (items > 0) {
+ SET_ADDR(dstadr, oml->v6_flag, oml->addr, oml->addr6);
+ fprintf(fp, "%-20.20s %5u %9lu %4u %3u %9lu %9lu\n",
+ nntohost(&dstadr),
+ ntohs(oml->port),
+ (u_long)ntohl(oml->count),
+ oml->mode,
+ oml->version,
+ (u_long)ntohl(oml->lasttime),
+ (u_long)ntohl(oml->firsttime));
+ oml++;
+ items--;
+ }
+ } else {
+ /* issue warning according to new info_monitor size */
+ checkitemsize(itemsize, sizeof(struct info_monitor));
+ }
+}
+
+
+/*
+ * Mapping between command line strings and stat reset flags
+ */
+struct statreset {
+ const char * const str;
+ const int flag;
+} sreset[] = {
+ { "allpeers", RESET_FLAG_ALLPEERS },
+ { "io", RESET_FLAG_IO },
+ { "sys", RESET_FLAG_SYS },
+ { "mem", RESET_FLAG_MEM },
+ { "timer", RESET_FLAG_TIMER },
+ { "auth", RESET_FLAG_AUTH },
+ { "ctl", RESET_FLAG_CTL },
+ { "", 0 }
+};
+
+/*
+ * reset - reset statistic counters
+ */
+static void
+reset(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ struct reset_flags rflags;
+ size_t items;
+ size_t itemsize;
+ const char *dummy;
+ int i;
+ size_t res;
+ int err;
+
+ err = 0;
+ rflags.flags = 0;
+ for (res = 0; res < pcmd->nargs; res++) {
+ for (i = 0; sreset[i].flag != 0; i++) {
+ if (STREQ(pcmd->argval[res].string, sreset[i].str))
+ break;
+ }
+ if (sreset[i].flag == 0) {
+ fprintf(fp, "Flag %s unknown\n",
+ pcmd->argval[res].string);
+ err = 1;
+ } else {
+ rflags.flags |= sreset[i].flag;
+ }
+ }
+ rflags.flags = htonl(rflags.flags);
+
+ if (err) {
+ (void) fprintf(fp, "Not done due to errors\n");
+ return;
+ }
+
+again:
+ res = doquery(impl_ver, REQ_RESET_STATS, 1, 1,
+ sizeof(struct reset_flags), (char *)&rflags, &items,
+ &itemsize, &dummy, 0, sizeof(struct reset_flags));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res == 0)
+ (void) fprintf(fp, "done!\n");
+ return;
+}
+
+
+
+/*
+ * preset - reset stat counters for particular peers
+ */
+static void
+preset(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ /* 8 is the maximum number of peers which will fit in a packet */
+ struct conf_unpeer *pl, plist[min(MAXARGS, 8)];
+ size_t qitemlim;
+ size_t qitems;
+ size_t items;
+ size_t itemsize;
+ const char *dummy;
+ int res;
+ size_t sendsize;
+
+again:
+ if (impl_ver == IMPL_XNTPD)
+ sendsize = sizeof(struct conf_unpeer);
+ else
+ sendsize = v4sizeof(struct conf_unpeer);
+
+ qitemlim = min(pcmd->nargs, COUNTOF(plist));
+ for (qitems = 0, pl = plist; qitems < qitemlim; qitems++) {
+ if (IS_IPV4(&pcmd->argval[qitems].netnum)) {
+ pl->peeraddr = NSRCADR(&pcmd->argval[qitems].netnum);
+ if (impl_ver == IMPL_XNTPD)
+ pl->v6_flag = 0;
+ } else {
+ if (impl_ver == IMPL_XNTPD_OLD) {
+ fprintf(stderr,
+ "***Server doesn't understand IPv6 addresses\n");
+ return;
+ }
+ pl->peeraddr6 =
+ SOCK_ADDR6(&pcmd->argval[qitems].netnum);
+ pl->v6_flag = 1;
+ }
+ pl = (void *)((char *)pl + sendsize);
+ }
+
+ res = doquery(impl_ver, REQ_RESET_PEER, 1, qitems,
+ sendsize, (char *)plist, &items,
+ &itemsize, &dummy, 0, sizeof(struct conf_unpeer));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res == 0)
+ (void) fprintf(fp, "done!\n");
+}
+
+
+/*
+ * readkeys - request the server to reread the keys file
+ */
+/*ARGSUSED*/
+static void
+readkeys(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ size_t items;
+ size_t itemsize;
+ const char *dummy;
+ int res;
+
+again:
+ res = doquery(impl_ver, REQ_REREAD_KEYS, 1, 0, 0, (char *)0,
+ &items, &itemsize, &dummy, 0, sizeof(dummy));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res == 0)
+ (void) fprintf(fp, "done!\n");
+ return;
+}
+
+
+/*
+ * trustkey - add some keys to the trusted key list
+ */
+static void
+trustkey(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ do_trustkey(pcmd, fp, REQ_TRUSTKEY);
+}
+
+
+/*
+ * untrustkey - remove some keys from the trusted key list
+ */
+static void
+untrustkey(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ do_trustkey(pcmd, fp, REQ_UNTRUSTKEY);
+}
+
+
+/*
+ * do_trustkey - do grunge work of adding/deleting keys
+ */
+static void
+do_trustkey(
+ struct parse *pcmd,
+ FILE *fp,
+ int req
+ )
+{
+ u_long keyids[MAXARGS];
+ size_t i;
+ size_t items;
+ size_t itemsize;
+ const char *dummy;
+ int ritems;
+ int res;
+
+ ritems = 0;
+ for (i = 0; i < pcmd->nargs; i++) {
+ keyids[ritems++] = pcmd->argval[i].uval;
+ }
+
+again:
+ res = doquery(impl_ver, req, 1, ritems, sizeof(u_long),
+ (char *)keyids, &items, &itemsize, &dummy, 0,
+ sizeof(dummy));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res == 0)
+ (void) fprintf(fp, "done!\n");
+ return;
+}
+
+
+
+/*
+ * authinfo - obtain and print info about authentication
+ */
+/*ARGSUSED*/
+static void
+authinfo(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ struct info_auth *ia;
+ size_t items;
+ size_t itemsize;
+ int res;
+
+again:
+ res = doquery(impl_ver, REQ_AUTHINFO, 0, 0, 0, NULL, &items,
+ &itemsize, (void *)&ia, 0, sizeof(*ia));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res != 0)
+ return;
+
+ if (!check1item(items, fp))
+ return;
+
+ if (!checkitemsize(itemsize, sizeof(*ia)))
+ return;
+
+ fprintf(fp, "time since reset: %lu\n",
+ (u_long)ntohl(ia->timereset));
+ fprintf(fp, "stored keys: %lu\n",
+ (u_long)ntohl(ia->numkeys));
+ fprintf(fp, "free keys: %lu\n",
+ (u_long)ntohl(ia->numfreekeys));
+ fprintf(fp, "key lookups: %lu\n",
+ (u_long)ntohl(ia->keylookups));
+ fprintf(fp, "keys not found: %lu\n",
+ (u_long)ntohl(ia->keynotfound));
+ fprintf(fp, "uncached keys: %lu\n",
+ (u_long)ntohl(ia->keyuncached));
+ fprintf(fp, "encryptions: %lu\n",
+ (u_long)ntohl(ia->encryptions));
+ fprintf(fp, "decryptions: %lu\n",
+ (u_long)ntohl(ia->decryptions));
+ fprintf(fp, "expired keys: %lu\n",
+ (u_long)ntohl(ia->expired));
+}
+
+
+
+/*
+ * traps - obtain and print a list of traps
+ */
+/*ARGSUSED*/
+static void
+traps(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ size_t i;
+ struct info_trap *it;
+ sockaddr_u trap_addr, local_addr;
+ size_t items;
+ size_t itemsize;
+ int res;
+
+again:
+ res = doquery(impl_ver, REQ_TRAPS, 0, 0, 0, NULL, &items,
+ &itemsize, (void *)&it, 0, sizeof(*it));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res != 0)
+ return;
+
+ if (!checkitems(items, fp))
+ return;
+
+ if (!checkitemsize(itemsize, sizeof(struct info_trap)) &&
+ !checkitemsize(itemsize, v4sizeof(struct info_trap)))
+ return;
+
+ for (i = 0; i < items; i++ ) {
+ SET_ADDRS(trap_addr, local_addr, it, trap_address, local_address);
+ fprintf(fp, "%saddress %s, port %d\n",
+ (0 == i)
+ ? ""
+ : "\n",
+ stoa(&trap_addr), ntohs(it->trap_port));
+ fprintf(fp, "interface: %s, ",
+ (0 == it->local_address)
+ ? "wildcard"
+ : stoa(&local_addr));
+ if (ntohl(it->flags) & TRAP_CONFIGURED)
+ fprintf(fp, "configured\n");
+ else if (ntohl(it->flags) & TRAP_NONPRIO)
+ fprintf(fp, "low priority\n");
+ else
+ fprintf(fp, "normal priority\n");
+
+ fprintf(fp, "set for %ld secs, last set %ld secs ago\n",
+ (long)ntohl(it->origtime),
+ (long)ntohl(it->settime));
+ fprintf(fp, "sequence %d, number of resets %ld\n",
+ ntohs(it->sequence), (long)ntohl(it->resets));
+ }
+}
+
+
+/*
+ * addtrap - configure a trap
+ */
+static void
+addtrap(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ do_addclr_trap(pcmd, fp, REQ_ADD_TRAP);
+}
+
+
+/*
+ * clrtrap - clear a trap from the server
+ */
+static void
+clrtrap(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ do_addclr_trap(pcmd, fp, REQ_CLR_TRAP);
+}
+
+
+/*
+ * do_addclr_trap - do grunge work of adding/deleting traps
+ */
+static void
+do_addclr_trap(
+ struct parse *pcmd,
+ FILE *fp,
+ int req
+ )
+{
+ struct conf_trap ctrap;
+ size_t items;
+ size_t itemsize;
+ const char *dummy;
+ int res;
+ int sendsize;
+
+again:
+ if (impl_ver == IMPL_XNTPD)
+ sendsize = sizeof(struct conf_trap);
+ else
+ sendsize = v4sizeof(struct conf_trap);
+
+ if (IS_IPV4(&pcmd->argval[0].netnum)) {
+ ctrap.trap_address = NSRCADR(&pcmd->argval[0].netnum);
+ if (impl_ver == IMPL_XNTPD)
+ ctrap.v6_flag = 0;
+ } else {
+ if (impl_ver == IMPL_XNTPD_OLD) {
+ fprintf(stderr,
+ "***Server doesn't understand IPv6 addresses\n");
+ return;
+ }
+ ctrap.trap_address6 = SOCK_ADDR6(&pcmd->argval[0].netnum);
+ ctrap.v6_flag = 1;
+ }
+ ctrap.local_address = 0;
+ ctrap.trap_port = htons(TRAPPORT);
+ ctrap.unused = 0;
+
+ if (pcmd->nargs > 1) {
+ ctrap.trap_port = htons((u_short)pcmd->argval[1].uval);
+ if (pcmd->nargs > 2) {
+ if (AF(&pcmd->argval[2].netnum) !=
+ AF(&pcmd->argval[0].netnum)) {
+ fprintf(stderr,
+ "***Cannot mix IPv4 and IPv6 addresses\n");
+ return;
+ }
+ if (IS_IPV4(&pcmd->argval[2].netnum))
+ ctrap.local_address = NSRCADR(&pcmd->argval[2].netnum);
+ else
+ ctrap.local_address6 = SOCK_ADDR6(&pcmd->argval[2].netnum);
+ }
+ }
+
+ res = doquery(impl_ver, req, 1, 1, sendsize,
+ (char *)&ctrap, &items, &itemsize, &dummy, 0,
+ sizeof(struct conf_trap));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res == 0)
+ (void) fprintf(fp, "done!\n");
+ return;
+}
+
+
+
+/*
+ * requestkey - change the server's request key (a dangerous request)
+ */
+static void
+requestkey(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ do_changekey(pcmd, fp, REQ_REQUEST_KEY);
+}
+
+
+/*
+ * controlkey - change the server's control key
+ */
+static void
+controlkey(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ do_changekey(pcmd, fp, REQ_CONTROL_KEY);
+}
+
+
+
+/*
+ * do_changekey - do grunge work of changing keys
+ */
+static void
+do_changekey(
+ struct parse *pcmd,
+ FILE *fp,
+ int req
+ )
+{
+ u_long key;
+ size_t items;
+ size_t itemsize;
+ const char *dummy;
+ int res;
+
+
+ key = htonl((u_int32)pcmd->argval[0].uval);
+
+again:
+ res = doquery(impl_ver, req, 1, 1, sizeof(u_int32),
+ (char *)&key, &items, &itemsize, &dummy, 0,
+ sizeof(dummy));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res == 0)
+ (void) fprintf(fp, "done!\n");
+ return;
+}
+
+
+
+/*
+ * ctlstats - obtain and print info about authentication
+ */
+/*ARGSUSED*/
+static void
+ctlstats(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ struct info_control *ic;
+ size_t items;
+ size_t itemsize;
+ int res;
+
+again:
+ res = doquery(impl_ver, REQ_GET_CTLSTATS, 0, 0, 0, NULL, &items,
+ &itemsize, (void *)&ic, 0, sizeof(*ic));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res != 0)
+ return;
+
+ if (!check1item(items, fp))
+ return;
+
+ if (!checkitemsize(itemsize, sizeof(*ic)))
+ return;
+
+ fprintf(fp, "time since reset: %lu\n",
+ (u_long)ntohl(ic->ctltimereset));
+ fprintf(fp, "requests received: %lu\n",
+ (u_long)ntohl(ic->numctlreq));
+ fprintf(fp, "responses sent: %lu\n",
+ (u_long)ntohl(ic->numctlresponses));
+ fprintf(fp, "fragments sent: %lu\n",
+ (u_long)ntohl(ic->numctlfrags));
+ fprintf(fp, "async messages sent: %lu\n",
+ (u_long)ntohl(ic->numasyncmsgs));
+ fprintf(fp, "error msgs sent: %lu\n",
+ (u_long)ntohl(ic->numctlerrors));
+ fprintf(fp, "total bad pkts: %lu\n",
+ (u_long)ntohl(ic->numctlbadpkts));
+ fprintf(fp, "packet too short: %lu\n",
+ (u_long)ntohl(ic->numctltooshort));
+ fprintf(fp, "response on input: %lu\n",
+ (u_long)ntohl(ic->numctlinputresp));
+ fprintf(fp, "fragment on input: %lu\n",
+ (u_long)ntohl(ic->numctlinputfrag));
+ fprintf(fp, "error set on input: %lu\n",
+ (u_long)ntohl(ic->numctlinputerr));
+ fprintf(fp, "bad offset on input: %lu\n",
+ (u_long)ntohl(ic->numctlbadoffset));
+ fprintf(fp, "bad version packets: %lu\n",
+ (u_long)ntohl(ic->numctlbadversion));
+ fprintf(fp, "data in pkt too short: %lu\n",
+ (u_long)ntohl(ic->numctldatatooshort));
+ fprintf(fp, "unknown op codes: %lu\n",
+ (u_long)ntohl(ic->numctlbadop));
+}
+
+
+/*
+ * clockstat - get and print clock status information
+ */
+static void
+clockstat(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ struct info_clock *cl;
+ /* 8 is the maximum number of clocks which will fit in a packet */
+ u_long clist[min(MAXARGS, 8)];
+ size_t qitemlim;
+ size_t qitems;
+ size_t items;
+ size_t itemsize;
+ int res;
+ l_fp ts;
+ struct clktype *clk;
+
+ qitemlim = min(pcmd->nargs, COUNTOF(clist));
+ for (qitems = 0; qitems < qitemlim; qitems++)
+ clist[qitems] = NSRCADR(&pcmd->argval[qitems].netnum);
+
+again:
+ res = doquery(impl_ver, REQ_GET_CLOCKINFO, 0, qitems,
+ sizeof(u_int32), (char *)clist, &items,
+ &itemsize, (void *)&cl, 0, sizeof(struct info_clock));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res != 0)
+ return;
+
+ if (!checkitems(items, fp))
+ return;
+
+ if (!checkitemsize(itemsize, sizeof(struct info_clock)))
+ return;
+
+ while (items-- > 0) {
+ (void) fprintf(fp, "clock address: %s\n",
+ numtoa(cl->clockadr));
+ for (clk = clktypes; clk->code >= 0; clk++)
+ if (clk->code == cl->type)
+ break;
+ if (clk->code >= 0)
+ (void) fprintf(fp, "clock type: %s\n",
+ clk->clocktype);
+ else
+ (void) fprintf(fp, "clock type: unknown type (%d)\n",
+ cl->type);
+ (void) fprintf(fp, "last event: %d\n",
+ cl->lastevent);
+ (void) fprintf(fp, "current status: %d\n",
+ cl->currentstatus);
+ (void) fprintf(fp, "number of polls: %lu\n",
+ (u_long)ntohl(cl->polls));
+ (void) fprintf(fp, "no response to poll: %lu\n",
+ (u_long)ntohl(cl->noresponse));
+ (void) fprintf(fp, "bad format responses: %lu\n",
+ (u_long)ntohl(cl->badformat));
+ (void) fprintf(fp, "bad data responses: %lu\n",
+ (u_long)ntohl(cl->baddata));
+ (void) fprintf(fp, "running time: %lu\n",
+ (u_long)ntohl(cl->timestarted));
+ NTOHL_FP(&cl->fudgetime1, &ts);
+ (void) fprintf(fp, "fudge time 1: %s\n",
+ lfptoa(&ts, 6));
+ NTOHL_FP(&cl->fudgetime2, &ts);
+ (void) fprintf(fp, "fudge time 2: %s\n",
+ lfptoa(&ts, 6));
+ (void) fprintf(fp, "stratum: %ld\n",
+ (u_long)ntohl(cl->fudgeval1));
+ /* [Bug3527] Backward Incompatible: cl->fudgeval2 is
+ * a string, instantiated via memcpy() so there is no
+ * endian issue to correct.
+ */
+#ifdef DISABLE_BUG3527_FIX
+ (void) fprintf(fp, "reference ID: %s\n",
+ refid_string(ntohl(cl->fudgeval2), 0));
+#else
+ (void) fprintf(fp, "reference ID: %s\n",
+ refid_string(cl->fudgeval2, 0));
+#endif
+ (void) fprintf(fp, "fudge flags: 0x%x\n",
+ cl->flags);
+
+ if (items > 0)
+ (void) fprintf(fp, "\n");
+ cl++;
+ }
+}
+
+
+/*
+ * fudge - set clock fudge factors
+ */
+static void
+fudge(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ struct conf_fudge fudgedata;
+ size_t items;
+ size_t itemsize;
+ const char *dummy;
+ l_fp ts;
+ int res;
+ long val;
+ u_long u_val;
+ int err;
+
+
+ err = 0;
+ ZERO(fudgedata);
+ fudgedata.clockadr = NSRCADR(&pcmd->argval[0].netnum);
+
+ if (STREQ(pcmd->argval[1].string, "time1")) {
+ fudgedata.which = htonl(FUDGE_TIME1);
+ if (!atolfp(pcmd->argval[2].string, &ts))
+ err = 1;
+ else
+ NTOHL_FP(&ts, &fudgedata.fudgetime);
+ } else if (STREQ(pcmd->argval[1].string, "time2")) {
+ fudgedata.which = htonl(FUDGE_TIME2);
+ if (!atolfp(pcmd->argval[2].string, &ts))
+ err = 1;
+ else
+ NTOHL_FP(&ts, &fudgedata.fudgetime);
+ } else if (STREQ(pcmd->argval[1].string, "val1")) {
+ fudgedata.which = htonl(FUDGE_VAL1);
+ if (!atoint(pcmd->argval[2].string, &val))
+ err = 1;
+ else
+ fudgedata.fudgeval_flags = htonl(val);
+ } else if (STREQ(pcmd->argval[1].string, "val2")) {
+ fudgedata.which = htonl(FUDGE_VAL2);
+ if (!atoint(pcmd->argval[2].string, &val))
+ err = 1;
+ else
+ fudgedata.fudgeval_flags = htonl((u_int32)val);
+ } else if (STREQ(pcmd->argval[1].string, "flags")) {
+ fudgedata.which = htonl(FUDGE_FLAGS);
+ if (!hextoint(pcmd->argval[2].string, &u_val))
+ err = 1;
+ else
+ fudgedata.fudgeval_flags = htonl((u_int32)(u_val & 0xf));
+ } else {
+ (void) fprintf(stderr, "What fudge is %s?\n",
+ pcmd->argval[1].string);
+ return;
+ }
+
+ if (err) {
+ (void) fprintf(stderr, "Unknown fudge parameter %s\n",
+ pcmd->argval[2].string);
+ return;
+ }
+
+again:
+ res = doquery(impl_ver, REQ_SET_CLKFUDGE, 1, 1,
+ sizeof(struct conf_fudge), (char *)&fudgedata, &items,
+ &itemsize, &dummy, 0, sizeof(dummy));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res == 0)
+ (void) fprintf(fp, "done!\n");
+ return;
+}
+
+/*
+ * clkbug - get and print clock debugging information
+ */
+static void
+clkbug(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ register int i;
+ register int n;
+ register u_int32 s;
+ struct info_clkbug *cl;
+ /* 8 is the maximum number of clocks which will fit in a packet */
+ u_long clist[min(MAXARGS, 8)];
+ u_int32 ltemp;
+ size_t qitemlim;
+ size_t qitems;
+ size_t items;
+ size_t itemsize;
+ int res;
+ int needsp;
+ l_fp ts;
+
+ qitemlim = min(pcmd->nargs, COUNTOF(clist));
+ for (qitems = 0; qitems < qitemlim; qitems++)
+ clist[qitems] = NSRCADR(&pcmd->argval[qitems].netnum);
+
+again:
+ res = doquery(impl_ver, REQ_GET_CLKBUGINFO, 0, qitems,
+ sizeof(u_int32), (char *)clist, &items,
+ &itemsize, (void *)&cl, 0, sizeof(struct info_clkbug));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res != 0)
+ return;
+
+ if (!checkitems(items, fp))
+ return;
+
+ if (!checkitemsize(itemsize, sizeof(struct info_clkbug)))
+ return;
+
+ while (items-- > 0) {
+ (void) fprintf(fp, "clock address: %s\n",
+ numtoa(cl->clockadr));
+ n = (int)cl->nvalues;
+ (void) fprintf(fp, "values: %d", n);
+ s = ntohs(cl->svalues);
+ if (n > NUMCBUGVALUES)
+ n = NUMCBUGVALUES;
+ for (i = 0; i < n; i++) {
+ ltemp = ntohl(cl->values[i]);
+ ltemp &= 0xffffffff; /* HMS: This does nothing now */
+ if ((i & 0x3) == 0)
+ (void) fprintf(fp, "\n");
+ if (s & (1 << i))
+ (void) fprintf(fp, "%12ld", (u_long)ltemp);
+ else
+ (void) fprintf(fp, "%12lu", (u_long)ltemp);
+ }
+ (void) fprintf(fp, "\n");
+
+ n = (int)cl->ntimes;
+ (void) fprintf(fp, "times: %d", n);
+ s = ntohl(cl->stimes);
+ if (n > NUMCBUGTIMES)
+ n = NUMCBUGTIMES;
+ needsp = 0;
+ for (i = 0; i < n; i++) {
+ if ((i & 0x1) == 0) {
+ (void) fprintf(fp, "\n");
+ } else {
+ for (;needsp > 0; needsp--)
+ putc(' ', fp);
+ }
+ NTOHL_FP(&cl->times[i], &ts);
+ if (s & (1 << i)) {
+ (void) fprintf(fp, "%17s",
+ lfptoa(&ts, 6));
+ needsp = 22;
+ } else {
+ (void) fprintf(fp, "%37s",
+ uglydate(&ts));
+ needsp = 2;
+ }
+ }
+ (void) fprintf(fp, "\n");
+ if (items > 0) {
+ cl++;
+ (void) fprintf(fp, "\n");
+ }
+ }
+}
+
+
+/*
+ * kerninfo - display the kernel pll/pps variables
+ */
+static void
+kerninfo(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ struct info_kernel *ik;
+ size_t items;
+ size_t itemsize;
+ int res;
+ unsigned status;
+ double tscale_usec = 1e-6, tscale_unano = 1e-6;
+
+again:
+ res = doquery(impl_ver, REQ_GET_KERNEL, 0, 0, 0, (char *)NULL,
+ &items, &itemsize, (void *)&ik, 0,
+ sizeof(struct info_kernel));
+
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res != 0)
+ return;
+ if (!check1item(items, fp))
+ return;
+ if (!checkitemsize(itemsize, sizeof(struct info_kernel)))
+ return;
+
+ status = ntohs(ik->status) & 0xffff;
+ /*
+ * pll variables. We know more than we should about the NANO bit.
+ */
+#ifdef STA_NANO
+ if (status & STA_NANO)
+ tscale_unano = 1e-9;
+#endif
+ (void)fprintf(fp, "pll offset: %g s\n",
+ (int32)ntohl(ik->offset) * tscale_unano);
+ (void)fprintf(fp, "pll frequency: %s ppm\n",
+ fptoa((s_fp)ntohl(ik->freq), 3));
+ (void)fprintf(fp, "maximum error: %g s\n",
+ (u_long)ntohl(ik->maxerror) * tscale_usec);
+ (void)fprintf(fp, "estimated error: %g s\n",
+ (u_long)ntohl(ik->esterror) * tscale_usec);
+ (void)fprintf(fp, "status: %04x ", status);
+#ifdef STA_PLL
+ if (status & STA_PLL) (void)fprintf(fp, " pll");
+#endif
+#ifdef STA_PPSFREQ
+ if (status & STA_PPSFREQ) (void)fprintf(fp, " ppsfreq");
+#endif
+#ifdef STA_PPSTIME
+ if (status & STA_PPSTIME) (void)fprintf(fp, " ppstime");
+#endif
+#ifdef STA_FLL
+ if (status & STA_FLL) (void)fprintf(fp, " fll");
+#endif
+#ifdef STA_INS
+ if (status & STA_INS) (void)fprintf(fp, " ins");
+#endif
+#ifdef STA_DEL
+ if (status & STA_DEL) (void)fprintf(fp, " del");
+#endif
+#ifdef STA_UNSYNC
+ if (status & STA_UNSYNC) (void)fprintf(fp, " unsync");
+#endif
+#ifdef STA_FREQHOLD
+ if (status & STA_FREQHOLD) (void)fprintf(fp, " freqhold");
+#endif
+#ifdef STA_PPSSIGNAL
+ if (status & STA_PPSSIGNAL) (void)fprintf(fp, " ppssignal");
+#endif
+#ifdef STA_PPSJITTER
+ if (status & STA_PPSJITTER) (void)fprintf(fp, " ppsjitter");
+#endif
+#ifdef STA_PPSWANDER
+ if (status & STA_PPSWANDER) (void)fprintf(fp, " ppswander");
+#endif
+#ifdef STA_PPSERROR
+ if (status & STA_PPSERROR) (void)fprintf(fp, " ppserror");
+#endif
+#ifdef STA_CLOCKERR
+ if (status & STA_CLOCKERR) (void)fprintf(fp, " clockerr");
+#endif
+#ifdef STA_NANO
+ if (status & STA_NANO) (void)fprintf(fp, " nano");
+#endif
+#ifdef STA_MODE
+ if (status & STA_MODE) (void)fprintf(fp, " mode=fll");
+#endif
+#ifdef STA_CLK
+ if (status & STA_CLK) (void)fprintf(fp, " src=B");
+#endif
+ (void)fprintf(fp, "\n");
+ (void)fprintf(fp, "pll time constant: %ld\n",
+ (u_long)ntohl(ik->constant));
+ (void)fprintf(fp, "precision: %g s\n",
+ (u_long)ntohl(ik->precision) * tscale_usec);
+ (void)fprintf(fp, "frequency tolerance: %s ppm\n",
+ fptoa((s_fp)ntohl(ik->tolerance), 0));
+
+ /*
+ * For backwards compatibility (ugh), we find the pps variables
+ * only if the shift member is nonzero.
+ */
+ if (!ik->shift)
+ return;
+
+ /*
+ * pps variables
+ */
+ (void)fprintf(fp, "pps frequency: %s ppm\n",
+ fptoa((s_fp)ntohl(ik->ppsfreq), 3));
+ (void)fprintf(fp, "pps stability: %s ppm\n",
+ fptoa((s_fp)ntohl(ik->stabil), 3));
+ (void)fprintf(fp, "pps jitter: %g s\n",
+ (u_long)ntohl(ik->jitter) * tscale_unano);
+ (void)fprintf(fp, "calibration interval: %d s\n",
+ 1 << ntohs(ik->shift));
+ (void)fprintf(fp, "calibration cycles: %ld\n",
+ (u_long)ntohl(ik->calcnt));
+ (void)fprintf(fp, "jitter exceeded: %ld\n",
+ (u_long)ntohl(ik->jitcnt));
+ (void)fprintf(fp, "stability exceeded: %ld\n",
+ (u_long)ntohl(ik->stbcnt));
+ (void)fprintf(fp, "calibration errors: %ld\n",
+ (u_long)ntohl(ik->errcnt));
+}
+
+#define IF_LIST_FMT "%2d %c %48s %c %c %12.12s %03lx %3lu %2lu %5lu %5lu %5lu %2lu %3lu %7lu\n"
+#define IF_LIST_FMT_STR "%2s %c %48s %c %c %12.12s %3s %3s %2s %5s %5s %5s %2s %3s %7s\n"
+#define IF_LIST_AFMT_STR " %48s %c\n"
+#define IF_LIST_LABELS "#", 'A', "Address/Mask/Broadcast", 'T', 'E', "IF name", "Flg", "TL", "#M", "recv", "sent", "drop", "S", "PC", "uptime"
+#define IF_LIST_LINE "==================================================================================================================\n"
+
+static void
+iflist(
+ FILE *fp,
+ struct info_if_stats *ifs,
+ size_t items,
+ size_t itemsize,
+ int res
+ )
+{
+ static const char *actions = "?.+-";
+ sockaddr_u saddr;
+
+ if (res != 0)
+ return;
+
+ if (!checkitems(items, fp))
+ return;
+
+ if (!checkitemsize(itemsize, sizeof(struct info_if_stats)))
+ return;
+
+ fprintf(fp, IF_LIST_FMT_STR, IF_LIST_LABELS);
+ fprintf(fp, IF_LIST_LINE);
+
+ while (items > 0) {
+ SET_ADDR(saddr, ntohl(ifs->v6_flag),
+ ifs->unaddr.addr.s_addr, ifs->unaddr.addr6);
+ fprintf(fp, IF_LIST_FMT,
+ ntohl(ifs->ifnum),
+ actions[(ifs->action >= 1 && ifs->action < 4) ? ifs->action : 0],
+ stoa((&saddr)), 'A',
+ ifs->ignore_packets ? 'D' : 'E',
+ ifs->name,
+ (u_long)ntohl(ifs->flags),
+ (u_long)ntohl(ifs->last_ttl),
+ (u_long)ntohl(ifs->num_mcast),
+ (u_long)ntohl(ifs->received),
+ (u_long)ntohl(ifs->sent),
+ (u_long)ntohl(ifs->notsent),
+ (u_long)ntohl(ifs->scopeid),
+ (u_long)ntohl(ifs->peercnt),
+ (u_long)ntohl(ifs->uptime));
+
+ SET_ADDR(saddr, ntohl(ifs->v6_flag),
+ ifs->unmask.addr.s_addr, ifs->unmask.addr6);
+ fprintf(fp, IF_LIST_AFMT_STR, stoa(&saddr), 'M');
+
+ if (!ntohl(ifs->v6_flag) && ntohl(ifs->flags) & (INT_BCASTOPEN)) {
+ SET_ADDR(saddr, ntohl(ifs->v6_flag),
+ ifs->unbcast.addr.s_addr, ifs->unbcast.addr6);
+ fprintf(fp, IF_LIST_AFMT_STR, stoa(&saddr), 'B');
+
+ }
+
+ ifs++;
+ items--;
+ }
+}
+
+/*ARGSUSED*/
+static void
+get_if_stats(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ struct info_if_stats *ifs;
+ size_t items;
+ size_t itemsize;
+ int res;
+
+ res = doquery(impl_ver, REQ_IF_STATS, 1, 0, 0, (char *)NULL, &items,
+ &itemsize, (void *)&ifs, 0,
+ sizeof(struct info_if_stats));
+ iflist(fp, ifs, items, itemsize, res);
+}
+
+/*ARGSUSED*/
+static void
+do_if_reload(
+ struct parse *pcmd,
+ FILE *fp
+ )
+{
+ struct info_if_stats *ifs;
+ size_t items;
+ size_t itemsize;
+ int res;
+
+ res = doquery(impl_ver, REQ_IF_RELOAD, 1, 0, 0, (char *)NULL, &items,
+ &itemsize, (void *)&ifs, 0,
+ sizeof(struct info_if_stats));
+ iflist(fp, ifs, items, itemsize, res);
+}
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/ag-char-map.h b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/ag-char-map.h
new file mode 100644
index 0000000..e905118
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/ag-char-map.h
@@ -0,0 +1,526 @@
+/*
+ * 29 bits for 46 character classifications
+ * generated by char-mapper on 04/25/15 at 09:53:03
+ *
+ * This file contains the character classifications
+ * used by AutoGen and AutoOpts for identifying tokens.
+ * The table is static scope, so %guard is empty.
+ *
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
+ *
+ * AutoOpts is available under any one of two licenses. The license
+ * in use must be one of these two and the choice is under the control
+ * of the user of the license.
+ *
+ * The GNU Lesser General Public License, version 3 or later
+ * See the files "COPYING.lgplv3" and "COPYING.gplv3"
+ *
+ * The Modified Berkeley Software Distribution License
+ * See the file "COPYING.mbsd"
+ *
+ * These files have the following sha256 sums:
+ *
+ * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
+ * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
+ * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
+ */
+#ifndef AG_CHAR_MAP_H_GUARD
+#define AG_CHAR_MAP_H_GUARD 1
+
+#ifdef HAVE_CONFIG_H
+# if defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+
+# elif defined(HAVE_STDINT_H)
+# include <stdint.h>
+
+# elif !defined(HAVE_UINT32_T)
+# if SIZEOF_INT == 4
+ typedef unsigned int uint32_t;
+# elif SIZEOF_LONG == 4
+ typedef unsigned long uint32_t;
+# endif
+# endif /* HAVE_*INT*_H header */
+
+#else /* not HAVE_CONFIG_H -- */
+# include <inttypes.h>
+#endif /* HAVE_CONFIG_H */
+
+#if 0 /* mapping specification source (from autogen.map) */
+//
+// %guard
+// %file ag-char-map.h
+// %backup
+// %optimize
+//
+// %comment -- see above
+// %
+//
+// newline "\n"
+// nul-byte "\x00"
+// dir-sep "/\\"
+// percent "%"
+// comma ","
+// colon ":"
+// underscore "_"
+// plus "+"
+// dollar "$"
+// option-marker "-"
+//
+// horiz-white "\t "
+// alt-white "\v\f\r\b"
+// whitespace +horiz-white +newline +alt-white
+// non-nl-white +horiz-white +alt-white
+// quote "'\""
+// parentheses "()"
+//
+// graphic "!-~"
+// inversion "~-"
+// oct-digit "0-7"
+// dec-digit "89" +oct-digit
+// hex-digit "a-fA-F" +dec-digit
+// lower-case "a-z"
+// upper-case "A-Z"
+// alphabetic +lower-case +upper-case
+// alphanumeric +alphabetic +dec-digit
+// var-first +underscore +alphabetic
+// variable-name +var-first +dec-digit
+// option-name "^-" +variable-name
+// value-name +colon +option-name
+// name-sep "[.]"
+// compound-name +value-name +name-sep +horiz-white
+// scheme-note +parentheses +quote
+//
+// unquotable "!-~" -"#,;<=>[\\]`{}?*" -quote -parentheses
+// end-xml-token "/>" +whitespace
+// plus-n-space +plus +whitespace
+// punctuation "!-~" -alphanumeric -"_"
+// suffix "-._" +alphanumeric
+// suffix-fmt +percent +suffix +dir-sep
+// false-type "nNfF0" +nul-byte
+// file-name +dir-sep +suffix
+// end-token +nul-byte +whitespace
+// end-list-entry +comma +end-token
+// set-separator "|+-!" +end-list-entry
+// signed-number +inversion +dec-digit
+// make-script +dollar +newline
+// load-line-skip +horiz-white +option-marker
+//
+#endif /* 0 -- mapping spec. source */
+
+
+typedef uint32_t ag_char_map_mask_t;
+
+#define IS_NEWLINE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000001)
+#define SPN_NEWLINE_CHARS(_s) spn_ag_char_map_chars(_s, 0)
+#define BRK_NEWLINE_CHARS(_s) brk_ag_char_map_chars(_s, 0)
+#define SPN_NEWLINE_BACK(s,e) spn_ag_char_map_back(s, e, 0)
+#define BRK_NEWLINE_BACK(s,e) brk_ag_char_map_back(s, e, 0)
+#define IS_NUL_BYTE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000002)
+#define SPN_NUL_BYTE_CHARS(_s) spn_ag_char_map_chars(_s, 1)
+#define BRK_NUL_BYTE_CHARS(_s) brk_ag_char_map_chars(_s, 1)
+#define SPN_NUL_BYTE_BACK(s,e) spn_ag_char_map_back(s, e, 1)
+#define BRK_NUL_BYTE_BACK(s,e) brk_ag_char_map_back(s, e, 1)
+#define IS_DIR_SEP_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000004)
+#define SPN_DIR_SEP_CHARS(_s) spn_ag_char_map_chars(_s, 2)
+#define BRK_DIR_SEP_CHARS(_s) brk_ag_char_map_chars(_s, 2)
+#define SPN_DIR_SEP_BACK(s,e) spn_ag_char_map_back(s, e, 2)
+#define BRK_DIR_SEP_BACK(s,e) brk_ag_char_map_back(s, e, 2)
+#define IS_PERCENT_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000008)
+#define SPN_PERCENT_CHARS(_s) spn_ag_char_map_chars(_s, 3)
+#define BRK_PERCENT_CHARS(_s) brk_ag_char_map_chars(_s, 3)
+#define SPN_PERCENT_BACK(s,e) spn_ag_char_map_back(s, e, 3)
+#define BRK_PERCENT_BACK(s,e) brk_ag_char_map_back(s, e, 3)
+#define IS_COMMA_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000010)
+#define SPN_COMMA_CHARS(_s) spn_ag_char_map_chars(_s, 4)
+#define BRK_COMMA_CHARS(_s) brk_ag_char_map_chars(_s, 4)
+#define SPN_COMMA_BACK(s,e) spn_ag_char_map_back(s, e, 4)
+#define BRK_COMMA_BACK(s,e) brk_ag_char_map_back(s, e, 4)
+#define IS_COLON_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000020)
+#define SPN_COLON_CHARS(_s) spn_ag_char_map_chars(_s, 5)
+#define BRK_COLON_CHARS(_s) brk_ag_char_map_chars(_s, 5)
+#define SPN_COLON_BACK(s,e) spn_ag_char_map_back(s, e, 5)
+#define BRK_COLON_BACK(s,e) brk_ag_char_map_back(s, e, 5)
+#define IS_UNDERSCORE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000040)
+#define SPN_UNDERSCORE_CHARS(_s) spn_ag_char_map_chars(_s, 6)
+#define BRK_UNDERSCORE_CHARS(_s) brk_ag_char_map_chars(_s, 6)
+#define SPN_UNDERSCORE_BACK(s,e) spn_ag_char_map_back(s, e, 6)
+#define BRK_UNDERSCORE_BACK(s,e) brk_ag_char_map_back(s, e, 6)
+#define IS_PLUS_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000080)
+#define SPN_PLUS_CHARS(_s) spn_ag_char_map_chars(_s, 7)
+#define BRK_PLUS_CHARS(_s) brk_ag_char_map_chars(_s, 7)
+#define SPN_PLUS_BACK(s,e) spn_ag_char_map_back(s, e, 7)
+#define BRK_PLUS_BACK(s,e) brk_ag_char_map_back(s, e, 7)
+#define IS_DOLLAR_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000100)
+#define SPN_DOLLAR_CHARS(_s) spn_ag_char_map_chars(_s, 8)
+#define BRK_DOLLAR_CHARS(_s) brk_ag_char_map_chars(_s, 8)
+#define SPN_DOLLAR_BACK(s,e) spn_ag_char_map_back(s, e, 8)
+#define BRK_DOLLAR_BACK(s,e) brk_ag_char_map_back(s, e, 8)
+#define IS_OPTION_MARKER_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000200)
+#define SPN_OPTION_MARKER_CHARS(_s) spn_ag_char_map_chars(_s, 9)
+#define BRK_OPTION_MARKER_CHARS(_s) brk_ag_char_map_chars(_s, 9)
+#define SPN_OPTION_MARKER_BACK(s,e) spn_ag_char_map_back(s, e, 9)
+#define BRK_OPTION_MARKER_BACK(s,e) brk_ag_char_map_back(s, e, 9)
+#define IS_HORIZ_WHITE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000400)
+#define SPN_HORIZ_WHITE_CHARS(_s) spn_ag_char_map_chars(_s, 10)
+#define BRK_HORIZ_WHITE_CHARS(_s) brk_ag_char_map_chars(_s, 10)
+#define SPN_HORIZ_WHITE_BACK(s,e) spn_ag_char_map_back(s, e, 10)
+#define BRK_HORIZ_WHITE_BACK(s,e) brk_ag_char_map_back(s, e, 10)
+#define IS_ALT_WHITE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000800)
+#define SPN_ALT_WHITE_CHARS(_s) spn_ag_char_map_chars(_s, 11)
+#define BRK_ALT_WHITE_CHARS(_s) brk_ag_char_map_chars(_s, 11)
+#define SPN_ALT_WHITE_BACK(s,e) spn_ag_char_map_back(s, e, 11)
+#define BRK_ALT_WHITE_BACK(s,e) brk_ag_char_map_back(s, e, 11)
+#define IS_WHITESPACE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000C01)
+#define SPN_WHITESPACE_CHARS(_s) spn_ag_char_map_chars(_s, 12)
+#define BRK_WHITESPACE_CHARS(_s) brk_ag_char_map_chars(_s, 12)
+#define SPN_WHITESPACE_BACK(s,e) spn_ag_char_map_back(s, e, 12)
+#define BRK_WHITESPACE_BACK(s,e) brk_ag_char_map_back(s, e, 12)
+#define IS_NON_NL_WHITE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000C00)
+#define SPN_NON_NL_WHITE_CHARS(_s) spn_ag_char_map_chars(_s, 13)
+#define BRK_NON_NL_WHITE_CHARS(_s) brk_ag_char_map_chars(_s, 13)
+#define SPN_NON_NL_WHITE_BACK(s,e) spn_ag_char_map_back(s, e, 13)
+#define BRK_NON_NL_WHITE_BACK(s,e) brk_ag_char_map_back(s, e, 13)
+#define IS_QUOTE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00001000)
+#define SPN_QUOTE_CHARS(_s) spn_ag_char_map_chars(_s, 14)
+#define BRK_QUOTE_CHARS(_s) brk_ag_char_map_chars(_s, 14)
+#define SPN_QUOTE_BACK(s,e) spn_ag_char_map_back(s, e, 14)
+#define BRK_QUOTE_BACK(s,e) brk_ag_char_map_back(s, e, 14)
+#define IS_PARENTHESES_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00002000)
+#define SPN_PARENTHESES_CHARS(_s) spn_ag_char_map_chars(_s, 15)
+#define BRK_PARENTHESES_CHARS(_s) brk_ag_char_map_chars(_s, 15)
+#define SPN_PARENTHESES_BACK(s,e) spn_ag_char_map_back(s, e, 15)
+#define BRK_PARENTHESES_BACK(s,e) brk_ag_char_map_back(s, e, 15)
+#define IS_GRAPHIC_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00004000)
+#define SPN_GRAPHIC_CHARS(_s) spn_ag_char_map_chars(_s, 16)
+#define BRK_GRAPHIC_CHARS(_s) brk_ag_char_map_chars(_s, 16)
+#define SPN_GRAPHIC_BACK(s,e) spn_ag_char_map_back(s, e, 16)
+#define BRK_GRAPHIC_BACK(s,e) brk_ag_char_map_back(s, e, 16)
+#define IS_INVERSION_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00008000)
+#define SPN_INVERSION_CHARS(_s) spn_ag_char_map_chars(_s, 17)
+#define BRK_INVERSION_CHARS(_s) brk_ag_char_map_chars(_s, 17)
+#define SPN_INVERSION_BACK(s,e) spn_ag_char_map_back(s, e, 17)
+#define BRK_INVERSION_BACK(s,e) brk_ag_char_map_back(s, e, 17)
+#define IS_OCT_DIGIT_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00010000)
+#define SPN_OCT_DIGIT_CHARS(_s) spn_ag_char_map_chars(_s, 18)
+#define BRK_OCT_DIGIT_CHARS(_s) brk_ag_char_map_chars(_s, 18)
+#define SPN_OCT_DIGIT_BACK(s,e) spn_ag_char_map_back(s, e, 18)
+#define BRK_OCT_DIGIT_BACK(s,e) brk_ag_char_map_back(s, e, 18)
+#define IS_DEC_DIGIT_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00030000)
+#define SPN_DEC_DIGIT_CHARS(_s) spn_ag_char_map_chars(_s, 19)
+#define BRK_DEC_DIGIT_CHARS(_s) brk_ag_char_map_chars(_s, 19)
+#define SPN_DEC_DIGIT_BACK(s,e) spn_ag_char_map_back(s, e, 19)
+#define BRK_DEC_DIGIT_BACK(s,e) brk_ag_char_map_back(s, e, 19)
+#define IS_HEX_DIGIT_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00070000)
+#define SPN_HEX_DIGIT_CHARS(_s) spn_ag_char_map_chars(_s, 20)
+#define BRK_HEX_DIGIT_CHARS(_s) brk_ag_char_map_chars(_s, 20)
+#define SPN_HEX_DIGIT_BACK(s,e) spn_ag_char_map_back(s, e, 20)
+#define BRK_HEX_DIGIT_BACK(s,e) brk_ag_char_map_back(s, e, 20)
+#define IS_LOWER_CASE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00080000)
+#define SPN_LOWER_CASE_CHARS(_s) spn_ag_char_map_chars(_s, 21)
+#define BRK_LOWER_CASE_CHARS(_s) brk_ag_char_map_chars(_s, 21)
+#define SPN_LOWER_CASE_BACK(s,e) spn_ag_char_map_back(s, e, 21)
+#define BRK_LOWER_CASE_BACK(s,e) brk_ag_char_map_back(s, e, 21)
+#define IS_UPPER_CASE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00100000)
+#define SPN_UPPER_CASE_CHARS(_s) spn_ag_char_map_chars(_s, 22)
+#define BRK_UPPER_CASE_CHARS(_s) brk_ag_char_map_chars(_s, 22)
+#define SPN_UPPER_CASE_BACK(s,e) spn_ag_char_map_back(s, e, 22)
+#define BRK_UPPER_CASE_BACK(s,e) brk_ag_char_map_back(s, e, 22)
+#define IS_ALPHABETIC_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00180000)
+#define SPN_ALPHABETIC_CHARS(_s) spn_ag_char_map_chars(_s, 23)
+#define BRK_ALPHABETIC_CHARS(_s) brk_ag_char_map_chars(_s, 23)
+#define SPN_ALPHABETIC_BACK(s,e) spn_ag_char_map_back(s, e, 23)
+#define BRK_ALPHABETIC_BACK(s,e) brk_ag_char_map_back(s, e, 23)
+#define IS_ALPHANUMERIC_CHAR( _c) is_ag_char_map_char((char)(_c), 0x001B0000)
+#define SPN_ALPHANUMERIC_CHARS(_s) spn_ag_char_map_chars(_s, 24)
+#define BRK_ALPHANUMERIC_CHARS(_s) brk_ag_char_map_chars(_s, 24)
+#define SPN_ALPHANUMERIC_BACK(s,e) spn_ag_char_map_back(s, e, 24)
+#define BRK_ALPHANUMERIC_BACK(s,e) brk_ag_char_map_back(s, e, 24)
+#define IS_VAR_FIRST_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00180040)
+#define SPN_VAR_FIRST_CHARS(_s) spn_ag_char_map_chars(_s, 25)
+#define BRK_VAR_FIRST_CHARS(_s) brk_ag_char_map_chars(_s, 25)
+#define SPN_VAR_FIRST_BACK(s,e) spn_ag_char_map_back(s, e, 25)
+#define BRK_VAR_FIRST_BACK(s,e) brk_ag_char_map_back(s, e, 25)
+#define IS_VARIABLE_NAME_CHAR( _c) is_ag_char_map_char((char)(_c), 0x001B0040)
+#define SPN_VARIABLE_NAME_CHARS(_s) spn_ag_char_map_chars(_s, 26)
+#define BRK_VARIABLE_NAME_CHARS(_s) brk_ag_char_map_chars(_s, 26)
+#define SPN_VARIABLE_NAME_BACK(s,e) spn_ag_char_map_back(s, e, 26)
+#define BRK_VARIABLE_NAME_BACK(s,e) brk_ag_char_map_back(s, e, 26)
+#define IS_OPTION_NAME_CHAR( _c) is_ag_char_map_char((char)(_c), 0x003B0040)
+#define SPN_OPTION_NAME_CHARS(_s) spn_ag_char_map_chars(_s, 27)
+#define BRK_OPTION_NAME_CHARS(_s) brk_ag_char_map_chars(_s, 27)
+#define SPN_OPTION_NAME_BACK(s,e) spn_ag_char_map_back(s, e, 27)
+#define BRK_OPTION_NAME_BACK(s,e) brk_ag_char_map_back(s, e, 27)
+#define IS_VALUE_NAME_CHAR( _c) is_ag_char_map_char((char)(_c), 0x003B0060)
+#define SPN_VALUE_NAME_CHARS(_s) spn_ag_char_map_chars(_s, 28)
+#define BRK_VALUE_NAME_CHARS(_s) brk_ag_char_map_chars(_s, 28)
+#define SPN_VALUE_NAME_BACK(s,e) spn_ag_char_map_back(s, e, 28)
+#define BRK_VALUE_NAME_BACK(s,e) brk_ag_char_map_back(s, e, 28)
+#define IS_NAME_SEP_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00400000)
+#define SPN_NAME_SEP_CHARS(_s) spn_ag_char_map_chars(_s, 29)
+#define BRK_NAME_SEP_CHARS(_s) brk_ag_char_map_chars(_s, 29)
+#define SPN_NAME_SEP_BACK(s,e) spn_ag_char_map_back(s, e, 29)
+#define BRK_NAME_SEP_BACK(s,e) brk_ag_char_map_back(s, e, 29)
+#define IS_COMPOUND_NAME_CHAR( _c) is_ag_char_map_char((char)(_c), 0x007B0460)
+#define SPN_COMPOUND_NAME_CHARS(_s) spn_ag_char_map_chars(_s, 30)
+#define BRK_COMPOUND_NAME_CHARS(_s) brk_ag_char_map_chars(_s, 30)
+#define SPN_COMPOUND_NAME_BACK(s,e) spn_ag_char_map_back(s, e, 30)
+#define BRK_COMPOUND_NAME_BACK(s,e) brk_ag_char_map_back(s, e, 30)
+#define IS_SCHEME_NOTE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00003000)
+#define SPN_SCHEME_NOTE_CHARS(_s) spn_ag_char_map_chars(_s, 31)
+#define BRK_SCHEME_NOTE_CHARS(_s) brk_ag_char_map_chars(_s, 31)
+#define SPN_SCHEME_NOTE_BACK(s,e) spn_ag_char_map_back(s, e, 31)
+#define BRK_SCHEME_NOTE_BACK(s,e) brk_ag_char_map_back(s, e, 31)
+#define IS_UNQUOTABLE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00800000)
+#define SPN_UNQUOTABLE_CHARS(_s) spn_ag_char_map_chars(_s, 32)
+#define BRK_UNQUOTABLE_CHARS(_s) brk_ag_char_map_chars(_s, 32)
+#define SPN_UNQUOTABLE_BACK(s,e) spn_ag_char_map_back(s, e, 32)
+#define BRK_UNQUOTABLE_BACK(s,e) brk_ag_char_map_back(s, e, 32)
+#define IS_END_XML_TOKEN_CHAR( _c) is_ag_char_map_char((char)(_c), 0x01000C01)
+#define SPN_END_XML_TOKEN_CHARS(_s) spn_ag_char_map_chars(_s, 33)
+#define BRK_END_XML_TOKEN_CHARS(_s) brk_ag_char_map_chars(_s, 33)
+#define SPN_END_XML_TOKEN_BACK(s,e) spn_ag_char_map_back(s, e, 33)
+#define BRK_END_XML_TOKEN_BACK(s,e) brk_ag_char_map_back(s, e, 33)
+#define IS_PLUS_N_SPACE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000C81)
+#define SPN_PLUS_N_SPACE_CHARS(_s) spn_ag_char_map_chars(_s, 34)
+#define BRK_PLUS_N_SPACE_CHARS(_s) brk_ag_char_map_chars(_s, 34)
+#define SPN_PLUS_N_SPACE_BACK(s,e) spn_ag_char_map_back(s, e, 34)
+#define BRK_PLUS_N_SPACE_BACK(s,e) brk_ag_char_map_back(s, e, 34)
+#define IS_PUNCTUATION_CHAR( _c) is_ag_char_map_char((char)(_c), 0x02000000)
+#define SPN_PUNCTUATION_CHARS(_s) spn_ag_char_map_chars(_s, 35)
+#define BRK_PUNCTUATION_CHARS(_s) brk_ag_char_map_chars(_s, 35)
+#define SPN_PUNCTUATION_BACK(s,e) spn_ag_char_map_back(s, e, 35)
+#define BRK_PUNCTUATION_BACK(s,e) brk_ag_char_map_back(s, e, 35)
+#define IS_SUFFIX_CHAR( _c) is_ag_char_map_char((char)(_c), 0x041B0000)
+#define SPN_SUFFIX_CHARS(_s) spn_ag_char_map_chars(_s, 36)
+#define BRK_SUFFIX_CHARS(_s) brk_ag_char_map_chars(_s, 36)
+#define SPN_SUFFIX_BACK(s,e) spn_ag_char_map_back(s, e, 36)
+#define BRK_SUFFIX_BACK(s,e) brk_ag_char_map_back(s, e, 36)
+#define IS_SUFFIX_FMT_CHAR( _c) is_ag_char_map_char((char)(_c), 0x041B000C)
+#define SPN_SUFFIX_FMT_CHARS(_s) spn_ag_char_map_chars(_s, 37)
+#define BRK_SUFFIX_FMT_CHARS(_s) brk_ag_char_map_chars(_s, 37)
+#define SPN_SUFFIX_FMT_BACK(s,e) spn_ag_char_map_back(s, e, 37)
+#define BRK_SUFFIX_FMT_BACK(s,e) brk_ag_char_map_back(s, e, 37)
+#define IS_FALSE_TYPE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x08000002)
+#define SPN_FALSE_TYPE_CHARS(_s) spn_ag_char_map_chars(_s, 38)
+#define BRK_FALSE_TYPE_CHARS(_s) brk_ag_char_map_chars(_s, 38)
+#define SPN_FALSE_TYPE_BACK(s,e) spn_ag_char_map_back(s, e, 38)
+#define BRK_FALSE_TYPE_BACK(s,e) brk_ag_char_map_back(s, e, 38)
+#define IS_FILE_NAME_CHAR( _c) is_ag_char_map_char((char)(_c), 0x041B0004)
+#define SPN_FILE_NAME_CHARS(_s) spn_ag_char_map_chars(_s, 39)
+#define BRK_FILE_NAME_CHARS(_s) brk_ag_char_map_chars(_s, 39)
+#define SPN_FILE_NAME_BACK(s,e) spn_ag_char_map_back(s, e, 39)
+#define BRK_FILE_NAME_BACK(s,e) brk_ag_char_map_back(s, e, 39)
+#define IS_END_TOKEN_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000C03)
+#define SPN_END_TOKEN_CHARS(_s) spn_ag_char_map_chars(_s, 40)
+#define BRK_END_TOKEN_CHARS(_s) brk_ag_char_map_chars(_s, 40)
+#define SPN_END_TOKEN_BACK(s,e) spn_ag_char_map_back(s, e, 40)
+#define BRK_END_TOKEN_BACK(s,e) brk_ag_char_map_back(s, e, 40)
+#define IS_END_LIST_ENTRY_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000C13)
+#define SPN_END_LIST_ENTRY_CHARS(_s) spn_ag_char_map_chars(_s, 41)
+#define BRK_END_LIST_ENTRY_CHARS(_s) brk_ag_char_map_chars(_s, 41)
+#define SPN_END_LIST_ENTRY_BACK(s,e) spn_ag_char_map_back(s, e, 41)
+#define BRK_END_LIST_ENTRY_BACK(s,e) brk_ag_char_map_back(s, e, 41)
+#define IS_SET_SEPARATOR_CHAR( _c) is_ag_char_map_char((char)(_c), 0x10000C13)
+#define SPN_SET_SEPARATOR_CHARS(_s) spn_ag_char_map_chars(_s, 42)
+#define BRK_SET_SEPARATOR_CHARS(_s) brk_ag_char_map_chars(_s, 42)
+#define SPN_SET_SEPARATOR_BACK(s,e) spn_ag_char_map_back(s, e, 42)
+#define BRK_SET_SEPARATOR_BACK(s,e) brk_ag_char_map_back(s, e, 42)
+#define IS_SIGNED_NUMBER_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00038000)
+#define SPN_SIGNED_NUMBER_CHARS(_s) spn_ag_char_map_chars(_s, 43)
+#define BRK_SIGNED_NUMBER_CHARS(_s) brk_ag_char_map_chars(_s, 43)
+#define SPN_SIGNED_NUMBER_BACK(s,e) spn_ag_char_map_back(s, e, 43)
+#define BRK_SIGNED_NUMBER_BACK(s,e) brk_ag_char_map_back(s, e, 43)
+#define IS_MAKE_SCRIPT_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000101)
+#define SPN_MAKE_SCRIPT_CHARS(_s) spn_ag_char_map_chars(_s, 44)
+#define BRK_MAKE_SCRIPT_CHARS(_s) brk_ag_char_map_chars(_s, 44)
+#define SPN_MAKE_SCRIPT_BACK(s,e) spn_ag_char_map_back(s, e, 44)
+#define BRK_MAKE_SCRIPT_BACK(s,e) brk_ag_char_map_back(s, e, 44)
+#define IS_LOAD_LINE_SKIP_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000600)
+#define SPN_LOAD_LINE_SKIP_CHARS(_s) spn_ag_char_map_chars(_s, 45)
+#define BRK_LOAD_LINE_SKIP_CHARS(_s) brk_ag_char_map_chars(_s, 45)
+#define SPN_LOAD_LINE_SKIP_BACK(s,e) spn_ag_char_map_back(s, e, 45)
+#define BRK_LOAD_LINE_SKIP_BACK(s,e) brk_ag_char_map_back(s, e, 45)
+
+static ag_char_map_mask_t const ag_char_map_table[128] = {
+ /*NUL*/ 0x00000002, /*x01*/ 0x00000000, /*x02*/ 0x00000000, /*x03*/ 0x00000000,
+ /*x04*/ 0x00000000, /*x05*/ 0x00000000, /*x06*/ 0x00000000, /*BEL*/ 0x00000000,
+ /* BS*/ 0x00000800, /* HT*/ 0x00000400, /* NL*/ 0x00000001, /* VT*/ 0x00000800,
+ /* FF*/ 0x00000800, /* CR*/ 0x00000800, /*x0E*/ 0x00000000, /*x0F*/ 0x00000000,
+ /*x10*/ 0x00000000, /*x11*/ 0x00000000, /*x12*/ 0x00000000, /*x13*/ 0x00000000,
+ /*x14*/ 0x00000000, /*x15*/ 0x00000000, /*x16*/ 0x00000000, /*x17*/ 0x00000000,
+ /*x18*/ 0x00000000, /*x19*/ 0x00000000, /*x1A*/ 0x00000000, /*ESC*/ 0x00000000,
+ /*x1C*/ 0x00000000, /*x1D*/ 0x00000000, /*x1E*/ 0x00000000, /*x1F*/ 0x00000000,
+ /* */ 0x00000400, /* ! */ 0x02804000, /* " */ 0x02005000, /* # */ 0x02004000,
+ /* $ */ 0x02804100, /* % */ 0x02804008, /* & */ 0x02804000, /* ' */ 0x02005000,
+ /* ( */ 0x02006000, /* ) */ 0x02006000, /* * */ 0x02004000, /* + */ 0x12804080,
+ /* , */ 0x02004010, /* - */ 0x06A0C200, /* . */ 0x06C04000, /* / */ 0x03804004,
+ /* 0 */ 0x08814000, /* 1 */ 0x00814000, /* 2 */ 0x00814000, /* 3 */ 0x00814000,
+ /* 4 */ 0x00814000, /* 5 */ 0x00814000, /* 6 */ 0x00814000, /* 7 */ 0x00814000,
+ /* 8 */ 0x00824000, /* 9 */ 0x00824000, /* : */ 0x02804020, /* ; */ 0x02004000,
+ /* < */ 0x02004000, /* = */ 0x02004000, /* > */ 0x03004000, /* ? */ 0x02004000,
+ /* @ */ 0x02804000, /* A */ 0x00944000, /* B */ 0x00944000, /* C */ 0x00944000,
+ /* D */ 0x00944000, /* E */ 0x00944000, /* F */ 0x08944000, /* G */ 0x00904000,
+ /* H */ 0x00904000, /* I */ 0x00904000, /* J */ 0x00904000, /* K */ 0x00904000,
+ /* L */ 0x00904000, /* M */ 0x00904000, /* N */ 0x08904000, /* O */ 0x00904000,
+ /* P */ 0x00904000, /* Q */ 0x00904000, /* R */ 0x00904000, /* S */ 0x00904000,
+ /* T */ 0x00904000, /* U */ 0x00904000, /* V */ 0x00904000, /* W */ 0x00904000,
+ /* X */ 0x00904000, /* Y */ 0x00904000, /* Z */ 0x00904000, /* [ */ 0x02404000,
+ /* \ */ 0x02004004, /* ] */ 0x02404000, /* ^ */ 0x02A04000, /* _ */ 0x04804040,
+ /* ` */ 0x02004000, /* a */ 0x008C4000, /* b */ 0x008C4000, /* c */ 0x008C4000,
+ /* d */ 0x008C4000, /* e */ 0x008C4000, /* f */ 0x088C4000, /* g */ 0x00884000,
+ /* h */ 0x00884000, /* i */ 0x00884000, /* j */ 0x00884000, /* k */ 0x00884000,
+ /* l */ 0x00884000, /* m */ 0x00884000, /* n */ 0x08884000, /* o */ 0x00884000,
+ /* p */ 0x00884000, /* q */ 0x00884000, /* r */ 0x00884000, /* s */ 0x00884000,
+ /* t */ 0x00884000, /* u */ 0x00884000, /* v */ 0x00884000, /* w */ 0x00884000,
+ /* x */ 0x00884000, /* y */ 0x00884000, /* z */ 0x00884000, /* { */ 0x02004000,
+ /* | */ 0x12804000, /* } */ 0x02004000, /* ~ */ 0x0280C000, /*x7F*/ 0x00000000
+};
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef _
+# define _(_s) _s
+#endif
+
+static unsigned char const * ag_char_map_spanners[46];
+/**
+ * Character category masks. Some categories may have multiple bits,
+ * if their definition incorporates other character categories.
+ * This mask array is only used by calc_ag_char_map_spanners().
+ */
+static ag_char_map_mask_t const ag_char_map_masks[46] = {
+ 0x00000001, /* NEWLINE */
+ 0x00000002, /* NUL_BYTE */
+ 0x00000004, /* DIR_SEP */
+ 0x00000008, /* PERCENT */
+ 0x00000010, /* COMMA */
+ 0x00000020, /* COLON */
+ 0x00000040, /* UNDERSCORE */
+ 0x00000080, /* PLUS */
+ 0x00000100, /* DOLLAR */
+ 0x00000200, /* OPTION_MARKER */
+ 0x00000400, /* HORIZ_WHITE */
+ 0x00000800, /* ALT_WHITE */
+ 0x00000C01, /* WHITESPACE */
+ 0x00000C00, /* NON_NL_WHITE */
+ 0x00001000, /* QUOTE */
+ 0x00002000, /* PARENTHESES */
+ 0x00004000, /* GRAPHIC */
+ 0x00008000, /* INVERSION */
+ 0x00010000, /* OCT_DIGIT */
+ 0x00030000, /* DEC_DIGIT */
+ 0x00070000, /* HEX_DIGIT */
+ 0x00080000, /* LOWER_CASE */
+ 0x00100000, /* UPPER_CASE */
+ 0x00180000, /* ALPHABETIC */
+ 0x001B0000, /* ALPHANUMERIC */
+ 0x00180040, /* VAR_FIRST */
+ 0x001B0040, /* VARIABLE_NAME */
+ 0x003B0040, /* OPTION_NAME */
+ 0x003B0060, /* VALUE_NAME */
+ 0x00400000, /* NAME_SEP */
+ 0x007B0460, /* COMPOUND_NAME */
+ 0x00003000, /* SCHEME_NOTE */
+ 0x00800000, /* UNQUOTABLE */
+ 0x01000C01, /* END_XML_TOKEN */
+ 0x00000C81, /* PLUS_N_SPACE */
+ 0x02000000, /* PUNCTUATION */
+ 0x041B0000, /* SUFFIX */
+ 0x041B000C, /* SUFFIX_FMT */
+ 0x08000002, /* FALSE_TYPE */
+ 0x041B0004, /* FILE_NAME */
+ 0x00000C03, /* END_TOKEN */
+ 0x00000C13, /* END_LIST_ENTRY */
+ 0x10000C13, /* SET_SEPARATOR */
+ 0x00038000, /* SIGNED_NUMBER */
+ 0x00000101, /* MAKE_SCRIPT */
+ 0x00000600, /* LOAD_LINE_SKIP */
+};
+#undef LOCK_SPANNER_TABLES
+
+static unsigned char const *
+calc_ag_char_map_spanners(unsigned int mask_ix)
+{
+#ifdef LOCK_SPANNER_TABLES
+ if (ag_char_map_spanners[mask_ix] != NULL)
+ return ag_char_map_spanners[mask_ix];
+
+ pthread_mutex_lock(&ag_char_map_mutex);
+ if (ag_char_map_spanners[mask_ix] == NULL)
+#endif
+ {
+ int ix = 1;
+ ag_char_map_mask_t mask = ag_char_map_masks[mask_ix];
+ unsigned char * res = malloc(256 /* 1 << NBBY */);
+ if (res == NULL) {
+ fputs(_("no memory for char-mapper span map\n"), stderr);
+ exit(EXIT_FAILURE);
+ }
+
+ memset(res, 0, 256);
+ for (; ix < 128; ix++)
+ if (ag_char_map_table[ix] & mask)
+ res[ix] = 1;
+ ag_char_map_spanners[mask_ix] = res;
+ }
+#ifdef LOCK_SPANNER_TABLES
+ pthread_mutex_unlock(&ag_char_map_mutex);
+#endif
+ return ag_char_map_spanners[mask_ix];
+}
+#define ag_char_map_masks POISONED_ag_char_map_masks
+
+static inline int
+is_ag_char_map_char(char ch, ag_char_map_mask_t mask)
+{
+ unsigned int ix = (unsigned char)ch;
+ return ((ix < 128) && ((ag_char_map_table[ix] & mask) != 0));
+}
+
+static inline char *
+spn_ag_char_map_chars(char const * p, unsigned int mask_ix)
+{
+ unsigned char const * v = ag_char_map_spanners[mask_ix];
+ if (v == NULL)
+ v = calc_ag_char_map_spanners(mask_ix);
+ while (v[(unsigned char)*p]) p++;
+ return (char *)(uintptr_t)p;
+}
+
+static inline char *
+brk_ag_char_map_chars(char const * p, unsigned int mask_ix)
+{
+ unsigned char const * v = ag_char_map_spanners[mask_ix];
+ if (v == NULL)
+ v = calc_ag_char_map_spanners(mask_ix);
+ while ((*p != '\0') && (! v[(unsigned char)*p])) p++;
+ return (char *)(uintptr_t)p;
+}
+
+static inline char *
+spn_ag_char_map_back(char const * s, char const * e, unsigned int mask_ix)
+{
+ unsigned char const * v = ag_char_map_spanners[mask_ix];
+ if (v == NULL)
+ v = calc_ag_char_map_spanners(mask_ix);
+ if (s >= e) e = s + strlen(s);
+ while ((e > s) && v[(unsigned char)e[-1]]) e--;
+ return (char *)(uintptr_t)e;
+}
+
+static inline char *
+brk_ag_char_map_back(char const * s, char const * e, unsigned int mask_ix)
+{
+ unsigned char const * v = ag_char_map_spanners[mask_ix];
+ if (v == NULL)
+ v = calc_ag_char_map_spanners(mask_ix);
+ if (s == e) e += strlen(e);
+ while ((e > s) && (! v[(unsigned char)e[-1]])) e--;
+ return (char *)(uintptr_t)e;
+}
+#endif /* AG_CHAR_MAP_H_GUARD */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/alias.c b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/alias.c
new file mode 100644
index 0000000..49e1f1f
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/alias.c
@@ -0,0 +1,116 @@
+
+/**
+ * \file alias.c
+ *
+ * Handle options that are aliases for another option.
+ *
+ * @addtogroup autoopts
+ * @{
+ */
+/*
+ * This routine will forward an option alias to the correct option code.
+ *
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
+ *
+ * AutoOpts is available under any one of two licenses. The license
+ * in use must be one of these two and the choice is under the control
+ * of the user of the license.
+ *
+ * The GNU Lesser General Public License, version 3 or later
+ * See the files "COPYING.lgplv3" and "COPYING.gplv3"
+ *
+ * The Modified Berkeley Software Distribution License
+ * See the file "COPYING.mbsd"
+ *
+ * These files have the following sha256 sums:
+ *
+ * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
+ * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
+ * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
+ */
+
+LOCAL tSuccess
+too_many_occurrences(tOptions * opts, tOptDesc * od)
+{
+ if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) {
+ char const * eqv = (od->optEquivIndex != NO_EQUIVALENT) ? zequiv : zNil;
+
+ fprintf(stderr, ztoo_often_fmt, opts->pzProgName);
+
+ if (od->optMaxCt > 1)
+ fprintf(stderr, zat_most, od->optMaxCt, od->pz_Name, eqv);
+ else
+ fprintf(stderr, zonly_one, od->pz_Name, eqv);
+ (*opts->pUsageProc)(opts, EXIT_FAILURE);
+ /* NOTREACHED */
+ }
+
+ return FAILURE;
+}
+
+/*=export_func optionAlias
+ * private:
+ *
+ * what: relay an option to its alias
+ * arg: + tOptions * + opts + program options descriptor +
+ * arg: + tOptDesc * + old_od + the descriptor for this arg +
+ * arg: + unsigned int + alias + the aliased-to option index +
+ * ret-type: int
+ *
+ * doc:
+ * Handle one option as if it had been specified as another. Exactly.
+ * Returns "-1" if the aliased-to option has appeared too many times.
+=*/
+int
+optionAlias(tOptions * opts, tOptDesc * old_od, unsigned int alias)
+{
+ tOptDesc * new_od;
+
+ if (opts <= OPTPROC_EMIT_LIMIT)
+ return 0;
+
+ new_od = opts->pOptDesc + alias;
+ if ((unsigned)opts->optCt <= alias) {
+ fputs(zbad_alias_id, stderr);
+ option_exits(EXIT_FAILURE);
+ }
+
+ /*
+ * Copy over the option instance flags
+ */
+ new_od->fOptState &= OPTST_PERSISTENT_MASK;
+ new_od->fOptState |= (old_od->fOptState & ~OPTST_PERSISTENT_MASK);
+ new_od->optArg.argString = old_od->optArg.argString;
+
+ /*
+ * Keep track of count only for DEFINED (command line) options.
+ * IF we have too many, build up an error message and bail.
+ */
+ if ( (new_od->fOptState & OPTST_DEFINED)
+ && (++new_od->optOccCt > new_od->optMaxCt) )
+ return too_many_occurrences(opts, new_od);
+
+ /*
+ * Clear the state bits and counters
+ */
+ old_od->fOptState &= OPTST_PERSISTENT_MASK;
+ old_od->optOccCt = 0;
+
+ /*
+ * If there is a procedure to call, call it
+ */
+ if (new_od->pOptProc != NULL)
+ (*new_od->pOptProc)(opts, new_od);
+ return 0;
+}
+
+/** @}
+ *
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of autoopts/alias.c */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/ao-strs.c b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/ao-strs.c
new file mode 100644
index 0000000..857aa73
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/ao-strs.c
@@ -0,0 +1,374 @@
+/* -*- buffer-read-only: t -*- vi: set ro:
+ *
+ * DO NOT EDIT THIS FILE (ao-strs.c)
+ *
+ * It has been AutoGen-ed
+ * From the definitions ao-strs.def
+ * and the template file strings
+ *
+ * Copyright (C) 2011-2015 Bruce Korb, all rights reserved.
+ * This is free software. It is licensed for use, modification and
+ * redistribution under the terms of the
+ * Modified (3 clause) Berkeley Software Distribution License
+ * <http://www.xfree86.org/3.3.6/COPYRIGHT2.html>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name ``Bruce Korb'' nor the name of any other
+ * contributor may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * strings IS PROVIDED BY Bruce Korb ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Bruce Korb OR ANY OTHER CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "ao-strs.h"
+
+char const ao_strs_strtable[6633] =
+/* 0 */ "-_^\0"
+/* 4 */ " %s%s\n\0"
+/* 12 */ "auto-options\0"
+/* 25 */ "program\0"
+/* 33 */ "%%-%ds %%s\n\0"
+/* 45 */ "\n"
+ "%s\n\n\0"
+/* 51 */ "=file\0"
+/* 57 */ "=Mbr\0"
+/* 62 */ "=Cplx\0"
+/* 68 */ "[=arg]\0"
+/* 75 */ "--%2$s%1$s\0"
+/* 86 */ "=Tim\0"
+/* 91 */ "none\0"
+/* 96 */ "# preset/initialization file\n"
+ "# %s#\n\0"
+/* 134 */ " %3s %-14s %s\0"
+/* 148 */ "%s\0"
+/* 151 */ "T/F\0"
+/* 155 */ "\n"
+ "%s\n\n"
+ "%s\0"
+/* 163 */ "Fil\0"
+/* 167 */ "KWd\0"
+/* 171 */ "Mbr\0"
+/* 175 */ "Cpx\0"
+/* 179 */ "no \0"
+/* 183 */ "Num\0"
+/* 187 */ "opt\0"
+/* 191 */ "YES\0"
+/* 195 */ "Str\0"
+/* 199 */ "Tim\0"
+/* 203 */ "\t\t\t\t- \0"
+/* 210 */ "\t\t\t\t \0"
+/* 217 */ "\t\t\t\t-- and \0"
+/* 229 */ "\t\t\t\t%s\n\0"
+/* 237 */ " \0"
+/* 244 */ " \0"
+/* 250 */ " \0"
+/* 254 */ " \0"
+/* 257 */ "all\0"
+/* 261 */ " \t\n"
+ ":=\0"
+/* 267 */ "%s_%s_%d=\0"
+/* 277 */ "''\0"
+/* 280 */ " ;;\n\n\0"
+/* 293 */ "'\n\n\0"
+/* 297 */ "</%s>\n\0"
+/* 304 */ " %s\n\0"
+/* 310 */ "%%-%ds\0"
+/* 317 */ "\n"
+ "export %s_%s_%d\n\0"
+/* 335 */ "false\0"
+/* 341 */ " -* )\n\0"
+/* 351 */ "flag\0"
+/* 356 */ "INVALID-%d\0"
+/* 367 */ "*INVALID*\0"
+/* 377 */ "\\n\\\n\0"
+/* 382 */ " --* )\n\0"
+/* 393 */ "--\0"
+/* 396 */ "LONGUSAGE\0"
+/* 406 */ " %s\n\0"
+/* 422 */ "\\%03o\0"
+/* 428 */ "more\0"
+/* 433 */ "<%s type=nested>\n\0"
+/* 451 */ "%s\n\0"
+/* 455 */ "%s\n"
+ " \0"
+/* 461 */ "OPT_ARG_NEEDED=NO\0"
+/* 479 */ "<%s/>\n\0"
+/* 486 */ "OPT_ARG_NEEDED=OK\0"
+/* 504 */ "\t\0"
+/* 506 */ "<%s>\0"
+/* 511 */ "option\0"
+/* 518 */ "\n"
+ "export %s_%s\n\0"
+/* 533 */ "%s_%s=\0"
+/* 540 */ " | \0"
+/* 544 */ "PAGER\0"
+/* 550 */ " + \0"
+/* 554 */ " puts(_(%s));\n\0"
+/* 570 */ "\\'\0"
+/* 573 */ "'%s'\0"
+/* 578 */ " -- %s\0"
+/* 585 */ "%s_%s_TEXT='\0"
+/* 598 */ "#! %s\n\0"
+/* 605 */ "\n"
+ "env | grep '^%s_'\n\0"
+/* 625 */ "=%1$lu # 0x%1$lX\n\0"
+/* 643 */ "stdout\0"
+/* 650 */ "%A %B %e, %Y at %r %Z\0"
+/* 672 */ "%s/use-%u.XXXXXX\0"
+/* 689 */ "true\0"
+/* 694 */ "<%s type=%s>\0"
+/* 707 */ "VERSION\0"
+/* 715 */ "#x%02X;\0"
+/* 723 */ "OPT_ARG_NEEDED=YES\0"
+/* 742 */ "'\\''\0"
+/* 747 */ " '%s'\0"
+/* 753 */ "\n"
+ "OPTION_CT=0\n\0"
+/* 767 */ "set --\0"
+/* 774 */ " ;;\n\n\0"
+/* 791 */ " '%c' )\n\0"
+/* 807 */ " '%s' )\n\0"
+/* 823 */ " '%s' | \\\n\0"
+/* 841 */ "TMPDIR\0"
+/* 848 */ "/tmp\0"
+/* 853 */ "%1$s %2$s ; rm -f %2$s\0"
+/* 876 */ "<%1$s type=boolean>%2$s</%1$s>\n\0"
+/* 908 */ "# From the %s option definitions\n"
+ "#\n\0"
+/* 945 */ "echo 'Warning: Cannot load options files' >&2\0"
+/* 992 */ "echo 'Warning: Cannot save options files' >&2\0"
+/* 1039 */ "echo 'Warning: Cannot suppress the loading of options files' >&2\0"
+/* 1105 */ "<%1$s type=integer>0x%2$lX</%1$s>\n\0"
+/* 1140 */ "%1$s_%2$s_TEXT='no %2$s text'\n\0"
+/* 1171 */ "%1$s_%2$s_MODE='%3$s'\n"
+ "export %1$s_%2$s_MODE\n\0"
+/* 1216 */ "%1$s_%2$s='%3$s'\n"
+ "export %1$s_%2$s\n\0"
+/* 1251 */ "%1$s_%2$s_CT=%3$d\n"
+ "export %1$s_%2$s_CT\n\0"
+/* 1290 */ "OPTION_CT=%d\n"
+ "export OPTION_CT\n\0"
+/* 1321 */ "%1$s_%2$s=%3$s\n"
+ "export %1$s_%2$s\n\0"
+/* 1354 */ "%1$s_%2$s=%3$d # 0x%3$X\n"
+ "export %1$s_%2$s\n\0"
+/* 1396 */ " case \"${OPT_CODE}\" in\n\0"
+/* 1427 */ " if [ $%1$s_%2$s_CT -gt %3$u ] ; then\n"
+ " echo 'Error: more than %3$d %2$s options'\n"
+ " echo \"$%1$s_USAGE_TEXT\"\n"
+ " exit 1\n"
+ " fi >&2\n\0"
+/* 1618 */ "test ${%1$s_%2$s_CT-0} -ge %3$u || {\n"
+ " echo %1$s_%2$s has not been set\n"
+ " exit 1\n"
+ "} 1>&2\n\0"
+/* 1710 */ "test -n \"$%1$s_%2$s\" || {\n"
+ " echo %1$s_%2$s has not been set\n"
+ " exit 1\n"
+ "} 1>&2\n\0"
+/* 1791 */ " echo \"$%s_%s_TEXT\"\n"
+ " exit 0\n\0"
+/* 1842 */ "\n"
+ "# # # # # # # # # #\n"
+ "#\n"
+ "# END OF AUTOMATED OPTION PROCESSING\n"
+ "#\n"
+ "# # # # # # # # # # -- do not modify this marker --\n\0"
+/* 1958 */ " if [ -n \"${OPT_ARG_VAL}\" ]\n"
+ " then\n"
+ " eval %1$s_${OPT_NAME}${OPT_ELEMENT}=\"'${OPT_ARG_VAL}'\"\n"
+ " export %1$s_${OPT_NAME}${OPT_ELEMENT}\n"
+ " fi\n"
+ "done\n"
+ "OPTION_COUNT=`expr $ARG_COUNT - $#`\n"
+ "OPERAND_COUNT=$#\n"
+ "unset OPT_PROCESS || :\n"
+ "unset OPT_ELEMENT || :\n"
+ "unset OPT_ARG || :\n"
+ "unset OPT_ARG_NEEDED || :\n"
+ "unset OPT_NAME || :\n"
+ "unset OPT_CODE || :\n"
+ "unset OPT_ARG_VAL || :\n\0"
+/* 2337 */ " OPT_CODE=`echo \"X${OPT_ARG}\"|sed 's/^X-*//'`\n"
+ " shift\n"
+ " OPT_ARG=$1\n"
+ " case \"${OPT_CODE}\" in *=* )\n"
+ " OPT_ARG_VAL=`echo \"${OPT_CODE}\"|sed 's/^[^=]*=//'`\n"
+ " OPT_CODE=`echo \"${OPT_CODE}\"|sed 's/=.*$//'` ;; esac\n\0"
+/* 2588 */ " OPT_CODE=`echo \"X${OPT_ARG}\" | sed 's/X-\\(.\\).*/\\1/'`\n"
+ " OPT_ARG=` echo \"X${OPT_ARG}\" | sed 's/X-.//'`\n\0"
+/* 2705 */ "\n"
+ "ARG_COUNT=$#\n"
+ "OPT_PROCESS=true\n"
+ "OPT_ARG=$1\n"
+ "while ${OPT_PROCESS} && [ $# -gt 0 ]\n"
+ "do\n"
+ " OPT_ELEMENT=''\n"
+ " OPT_ARG_VAL=''\n\n"
+ " case \"${OPT_ARG}\" in\n"
+ " -- )\n"
+ " OPT_PROCESS=false\n"
+ " shift\n"
+ " ;;\n\0"
+/* 2912 */ " case \"${OPT_ARG_NEEDED}\" in\n"
+ " NO )\n"
+ " OPT_ARG_VAL=''\n"
+ " ;;\n"
+ " YES )\n"
+ " if [ -z \"${OPT_ARG_VAL}\" ]\n"
+ " then\n"
+ " if [ $# -eq 0 ]\n"
+ " then\n"
+ " echo No argument provided for ${OPT_NAME} option\n"
+ " echo \"$%s_USAGE_TEXT\"\n"
+ " exit 1\n"
+ " fi >&2\n"
+ " OPT_ARG_VAL=${OPT_ARG}\n"
+ " shift\n"
+ " OPT_ARG=$1\n"
+ " fi\n"
+ " ;;\n"
+ " OK )\n"
+ " if [ -z \"${OPT_ARG_VAL}\" ] && [ $# -gt 0 ]\n"
+ " then\n"
+ " case \"${OPT_ARG}\" in -* ) ;; * )\n"
+ " OPT_ARG_VAL=${OPT_ARG}\n"
+ " shift\n"
+ " OPT_ARG=$1 ;; esac\n"
+ " fi\n"
+ " ;;\n"
+ " esac\n\0"
+/* 3691 */ " %1$s_%2$s_CT=`expr ${%1$s_%2$s_CT} + 1`\n"
+ " OPT_ELEMENT=\"_${%1$s_%2$s_CT}\"\n"
+ " OPT_NAME='%2$s'\n\0"
+/* 3815 */ "\n"
+ "if test -z \"${%1$s_%2$s}\"\n"
+ "then\n"
+ " %1$s_%2$s_CT=0\n"
+ " export %1$s_%2$s_CT\n"
+ "else\n"
+ " %1$s_%2$s_CT=1\n"
+ " %1$s_%2$s_1=${%1$s_%2$s}\n"
+ " export %1$s_%2$s_CT %1$s_%2$s_1\n"
+ "fi\n\0"
+/* 3973 */ " * )\n"
+ " OPT_PROCESS=false\n"
+ " ;;\n"
+ " esac\n\0"
+/* 4030 */ " %1$s_%2$s_CT=0\n"
+ " OPT_ELEMENT=''\n"
+ " %1$s_%2$s='%3$s'\n"
+ " export %1$s_%2$s\n"
+ " OPT_NAME='%2$s'\n\0"
+/* 4171 */ " if [ -n \"${%1$s_%2$s}\" ] && ${%1$s_%2$s_set} ; then\n"
+ " echo 'Error: duplicate %2$s option'\n"
+ " echo \"$%1$s_USAGE_TEXT\"\n"
+ " exit 1\n"
+ " fi >&2\n"
+ " %1$s_%2$s_set=true\n"
+ " %1$s_%2$s='%3$s'\n"
+ " export %1$s_%2$s\n"
+ " OPT_NAME='%2$s'\n\0"
+/* 4488 */ "\n"
+ "ARG_COUNT=$#\n"
+ "OPT_ARG=$1\n"
+ "while [ $# -gt 0 ]\n"
+ "do\n"
+ " OPT_ELEMENT=''\n"
+ " OPT_ARG_VAL=''\n"
+ " OPT_ARG=${1}\n\0"
+/* 4591 */ " case \"${OPT_ARG_NEEDED}\" in\n"
+ " NO )\n"
+ " if [ -n \"${OPT_ARG}\" ]\n"
+ " then\n"
+ " OPT_ARG=-${OPT_ARG}\n"
+ " else\n"
+ " shift\n"
+ " OPT_ARG=$1\n"
+ " fi\n"
+ " ;;\n"
+ " YES )\n"
+ " if [ -n \"${OPT_ARG}\" ]\n"
+ " then\n"
+ " OPT_ARG_VAL=${OPT_ARG}\n"
+ " else\n"
+ " if [ $# -eq 0 ]\n"
+ " then\n"
+ " echo No argument provided for ${OPT_NAME} option\n"
+ " echo \"$%s_USAGE_TEXT\"\n"
+ " exit 1\n"
+ " fi >&2\n"
+ " shift\n"
+ " OPT_ARG_VAL=$1\n"
+ " fi\n"
+ " shift\n"
+ " OPT_ARG=$1\n"
+ " ;;\n"
+ " OK )\n"
+ " if [ -n \"${OPT_ARG}\" ]\n"
+ " then\n"
+ " OPT_ARG_VAL=${OPT_ARG}\n"
+ " shift\n"
+ " OPT_ARG=$1\n"
+ " else\n"
+ " shift\n"
+ " if [ $# -gt 0 ]\n"
+ " then\n"
+ " case \"$1\" in -* ) ;; * )\n"
+ " OPT_ARG_VAL=$1\n"
+ " shift ;; esac\n"
+ " OPT_ARG=$1\n"
+ " fi\n"
+ " fi\n"
+ " ;;\n"
+ " esac\n\0"
+/* 5745 */ " echo \"$%s_LONGUSAGE_TEXT\" | ${PAGER-more}\n"
+ " exit 0\n\0"
+/* 5819 */ "%s OF %s\n"
+ "#\n"
+ "# From here to the next `-- do not modify this marker --',\n"
+ "# the text has been generated %s\n\0"
+/* 5925 */ " eval %1$s_%2$s${OPT_ELEMENT}=true\n"
+ " export %1$s_%2$s${OPT_ELEMENT}\n\0"
+/* 6015 */ " if [ -n \"${%1$s_%2$s}\" ] && ${%1$s_%2$s_set} ; then\n"
+ " echo 'Error: duplicate %2$s option'\n"
+ " echo \"$%1$s_USAGE_TEXT\"\n"
+ " exit 1\n"
+ " fi >&2\n"
+ " %1$s_%2$s_set=true\n"
+ " OPT_NAME='%2$s'\n\0"
+/* 6274 */ "\n"
+ "%1$s_%2$s=${%1$s_%2$s-'%3$s'}\n"
+ "%1$s_%2$s_set=false\n"
+ "export %1$s_%2$s\n\0"
+/* 6343 */ "\n"
+ "%1$s_%2$s=${%1$s_%2$s}\n"
+ "%1$s_%2$s_set=false\n"
+ "export %1$s_%2$s\n\0"
+/* 6405 */ "# # # # # # # # # # -- do not modify this marker --\n"
+ "#\n"
+ "# DO NOT EDIT THIS SECTION\n\0"
+/* 6488 */ " * )\n"
+ " echo Unknown %s: \"${OPT_CODE}\" >&2\n"
+ " echo \"$%s_USAGE_TEXT\" >&2\n"
+ " exit 1\n"
+ " ;;\n"
+ " esac\n";
+
+/* end of ao-strs.c */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/ao-strs.h b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/ao-strs.h
new file mode 100644
index 0000000..864fc48
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/ao-strs.h
@@ -0,0 +1,330 @@
+/* -*- buffer-read-only: t -*- vi: set ro:
+ *
+ * DO NOT EDIT THIS FILE (ao-strs.h)
+ *
+ * It has been AutoGen-ed
+ * From the definitions ao-strs.def
+ * and the template file strings
+ *
+ * Copyright (C) 2011-2015 Bruce Korb, all rights reserved.
+ * This is free software. It is licensed for use, modification and
+ * redistribution under the terms of the
+ * Modified (3 clause) Berkeley Software Distribution License
+ * <http://www.xfree86.org/3.3.6/COPYRIGHT2.html>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name ``Bruce Korb'' nor the name of any other
+ * contributor may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * strings IS PROVIDED BY Bruce Korb ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Bruce Korb OR ANY OTHER CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef STRINGS_AO_STRS_H_GUARD
+#define STRINGS_AO_STRS_H_GUARD 1
+/*
+ * 142 strings in ao_strs_strtable string table
+ */
+#define ARG_BREAK_STR (ao_strs_strtable+261)
+#define ARG_BREAK_STR_LEN 5
+#define ARG_BY_NUM_FMT (ao_strs_strtable+267)
+#define ARG_BY_NUM_FMT_LEN 9
+#define BOOL_ATR_FMT (ao_strs_strtable+876)
+#define BOOL_ATR_FMT_LEN 31
+#define CHK_MAX_COUNT (ao_strs_strtable+1427)
+#define CHK_MAX_COUNT_LEN 190
+#define CHK_MIN_COUNT (ao_strs_strtable+1618)
+#define CHK_MIN_COUNT_LEN 91
+#define CHK_ONE_REQUIRED (ao_strs_strtable+1710)
+#define CHK_ONE_REQUIRED_LEN 80
+#define ECHO_N_EXIT (ao_strs_strtable+1791)
+#define ECHO_N_EXIT_LEN 50
+#define EMPTY_ARG (ao_strs_strtable+277)
+#define EMPTY_ARG_LEN 2
+#define END_MARK (ao_strs_strtable+1842)
+#define END_MARK_LEN 115
+#define END_OPT_SEL_STR (ao_strs_strtable+280)
+#define END_OPT_SEL_STR_LEN 12
+#define END_PRE_FMT (ao_strs_strtable+908)
+#define END_PRE_FMT_LEN 36
+#define END_SET_TEXT (ao_strs_strtable+293)
+#define END_SET_TEXT_LEN 3
+#define END_XML_FMT (ao_strs_strtable+297)
+#define END_XML_FMT_LEN 6
+#define ENUM_ERR_LINE (ao_strs_strtable+304)
+#define ENUM_ERR_LINE_LEN 5
+#define ENUM_ERR_WIDTH (ao_strs_strtable+310)
+#define ENUM_ERR_WIDTH_LEN 6
+#define EXPORT_ARG_FMT (ao_strs_strtable+317)
+#define EXPORT_ARG_FMT_LEN 17
+#define FALSE_STR (ao_strs_strtable+335)
+#define FALSE_STR_LEN 5
+#define FINISH_LOOP (ao_strs_strtable+1958)
+#define FINISH_LOOP_LEN 378
+#define FLAG_OPT_MARK (ao_strs_strtable+341)
+#define FLAG_OPT_MARK_LEN 9
+#define FLAG_STR (ao_strs_strtable+351)
+#define FLAG_STR_LEN 4
+#define INIT_LOPT_STR (ao_strs_strtable+2337)
+#define INIT_LOPT_STR_LEN 250
+#define INIT_OPT_STR (ao_strs_strtable+2588)
+#define INIT_OPT_STR_LEN 116
+#define INVALID_FMT (ao_strs_strtable+356)
+#define INVALID_FMT_LEN 10
+#define INVALID_STR (ao_strs_strtable+367)
+#define INVALID_STR_LEN 9
+#define LINE_SPLICE (ao_strs_strtable+377)
+#define LINE_SPLICE_LEN 4
+#define LONG_OPT_MARK (ao_strs_strtable+382)
+#define LONG_OPT_MARKER (ao_strs_strtable+393)
+#define LONG_OPT_MARKER_LEN 2
+#define LONG_OPT_MARK_LEN 10
+#define LONG_USE_STR (ao_strs_strtable+396)
+#define LONG_USE_STR_LEN 9
+#define LOOP_STR (ao_strs_strtable+2705)
+#define LOOP_STR_LEN 206
+#define LOPT_ARG_FMT (ao_strs_strtable+2912)
+#define LOPT_ARG_FMT_LEN 778
+#define LVL3_CMD (ao_strs_strtable+406)
+#define LVL3_CMD_LEN 15
+#define MK_STR_OCT_FMT (ao_strs_strtable+422)
+#define MK_STR_OCT_FMT_LEN 5
+#define MORE_STR (ao_strs_strtable+428)
+#define MORE_STR_LEN 4
+#define MULTI_ARG_FMT (ao_strs_strtable+3691)
+#define MULTI_ARG_FMT_LEN 123
+#define MULTI_DEF_FMT (ao_strs_strtable+3815)
+#define MULTI_DEF_FMT_LEN 157
+#define NESTED_OPT_FMT (ao_strs_strtable+433)
+#define NESTED_OPT_FMT_LEN 17
+#define NLSTR_FMT (ao_strs_strtable+451)
+#define NLSTR_FMT_LEN 3
+#define NLSTR_SPACE_FMT (ao_strs_strtable+455)
+#define NLSTR_SPACE_FMT_LEN 5
+#define NONE_STR (ao_strs_strtable+91)
+#define NONE_STR_LEN 4
+#define NOT_FOUND_STR (ao_strs_strtable+3973)
+#define NOT_FOUND_STR_LEN 56
+#define NO_ARG_NEEDED (ao_strs_strtable+461)
+#define NO_ARG_NEEDED_LEN 17
+#define NO_LOAD_WARN (ao_strs_strtable+945)
+#define NO_LOAD_WARN_LEN 46
+#define NO_MULTI_ARG_FMT (ao_strs_strtable+4030)
+#define NO_MULTI_ARG_FMT_LEN 140
+#define NO_SAVE_OPTS (ao_strs_strtable+992)
+#define NO_SAVE_OPTS_LEN 46
+#define NO_SGL_ARG_FMT (ao_strs_strtable+4171)
+#define NO_SGL_ARG_FMT_LEN 316
+#define NO_SUPPRESS_LOAD (ao_strs_strtable+1039)
+#define NO_SUPPRESS_LOAD_LEN 65
+#define NULL_ATR_FMT (ao_strs_strtable+479)
+#define NULL_ATR_FMT_LEN 6
+#define NUMB_ATR_FMT (ao_strs_strtable+1105)
+#define NUMB_ATR_FMT_LEN 34
+#define OK_NEED_OPT_ARG (ao_strs_strtable+486)
+#define OK_NEED_OPT_ARG_LEN 17
+#define ONE_TAB_STR (ao_strs_strtable+504)
+#define ONE_TAB_STR_LEN 1
+#define ONLY_OPTS_LOOP (ao_strs_strtable+4488)
+#define ONLY_OPTS_LOOP_LEN 102
+#define OPEN_CLOSE_FMT (ao_strs_strtable+479)
+#define OPEN_CLOSE_FMT_LEN 6
+#define OPEN_XML_FMT (ao_strs_strtable+506)
+#define OPEN_XML_FMT_LEN 4
+#define OPTION_STR (ao_strs_strtable+511)
+#define OPTION_STR_LEN 6
+#define OPT_ARG_FMT (ao_strs_strtable+4591)
+#define OPT_ARG_FMT_LEN 1153
+#define OPT_END_FMT (ao_strs_strtable+518)
+#define OPT_END_FMT_LEN 14
+#define OPT_VAL_FMT (ao_strs_strtable+533)
+#define OPT_VAL_FMT_LEN 6
+#define OR_STR (ao_strs_strtable+540)
+#define OR_STR_LEN 3
+#define PAGER_NAME (ao_strs_strtable+544)
+#define PAGER_NAME_LEN 5
+#define PAGE_USAGE_FMT (ao_strs_strtable+853)
+#define PAGE_USAGE_FMT_LEN 22
+#define PAGE_USAGE_TEXT (ao_strs_strtable+5745)
+#define PAGE_USAGE_TEXT_LEN 73
+#define PLUS_STR (ao_strs_strtable+550)
+#define PLUS_STR_LEN 3
+#define PREAMBLE_FMT (ao_strs_strtable+5819)
+#define PREAMBLE_FMT_LEN 105
+#define PUTS_FMT (ao_strs_strtable+554)
+#define PUTS_FMT_LEN 15
+#define QUOT_APOS (ao_strs_strtable+570)
+#define QUOT_APOS_LEN 2
+#define QUOT_ARG_FMT (ao_strs_strtable+573)
+#define QUOT_ARG_FMT_LEN 4
+#define SET_MULTI_ARG (ao_strs_strtable+5925)
+#define SET_MULTI_ARG_LEN 89
+#define SET_NO_TEXT_FMT (ao_strs_strtable+1140)
+#define SET_NO_TEXT_FMT_LEN 30
+#define SET_OFF_FMT (ao_strs_strtable+578)
+#define SET_OFF_FMT_LEN 6
+#define SET_TEXT_FMT (ao_strs_strtable+585)
+#define SET_TEXT_FMT_LEN 12
+#define SGL_ARG_FMT (ao_strs_strtable+6015)
+#define SGL_ARG_FMT_LEN 258
+#define SGL_DEF_FMT (ao_strs_strtable+6274)
+#define SGL_DEF_FMT_LEN 68
+#define SGL_NO_DEF_FMT (ao_strs_strtable+6343)
+#define SGL_NO_DEF_FMT_LEN 61
+#define SHELL_MAGIC (ao_strs_strtable+598)
+#define SHELL_MAGIC_LEN 6
+#define SHOW_PROG_ENV (ao_strs_strtable+605)
+#define SHOW_PROG_ENV_LEN 19
+#define SHOW_VAL_FMT (ao_strs_strtable+625)
+#define SHOW_VAL_FMT_LEN 17
+#define START_MARK (ao_strs_strtable+6405)
+#define START_MARK_LEN 82
+#define STDOUT (ao_strs_strtable+643)
+#define STDOUT_LEN 6
+#define TIME_FMT (ao_strs_strtable+650)
+#define TIME_FMT_LEN 21
+#define TMPDIR (ao_strs_strtable+841)
+#define TMPDIR_LEN 6
+#define TMP_FILE_FMT (ao_strs_strtable+672)
+#define TMP_FILE_FMT_LEN 16
+#define TMP_USAGE_FMT (ao_strs_strtable+672)
+#define TMP_USAGE_FMT_LEN 16
+#define TRUE_STR (ao_strs_strtable+689)
+#define TRUE_STR_LEN 4
+#define TWO_SPACES_STR (ao_strs_strtable+254)
+#define TWO_SPACES_STR_LEN 2
+#define TYPE_ATR_FMT (ao_strs_strtable+694)
+#define TYPE_ATR_FMT_LEN 12
+#define UNK_OPT_FMT (ao_strs_strtable+6488)
+#define UNK_OPT_FMT_LEN 144
+#define VER_STR (ao_strs_strtable+707)
+#define VER_STR_LEN 7
+#define XML_HEX_BYTE_FMT (ao_strs_strtable+715)
+#define XML_HEX_BYTE_FMT_LEN 7
+#define YES_NEED_OPT_ARG (ao_strs_strtable+723)
+#define YES_NEED_OPT_ARG_LEN 18
+#define apostrophe (ao_strs_strtable+742)
+#define apostrophe_LEN 4
+#define arg_fmt (ao_strs_strtable+747)
+#define arg_fmt_LEN 5
+#define init_optct (ao_strs_strtable+753)
+#define init_optct_LEN 13
+#define set_dash (ao_strs_strtable+767)
+#define set_dash_LEN 6
+#define tmp_dir (ao_strs_strtable+848)
+#define tmp_dir_LEN 4
+#define zAll (ao_strs_strtable+257)
+#define zAll_LEN 3
+#define zCfgAO_Flags (ao_strs_strtable+12)
+#define zCfgAO_Flags_LEN 12
+#define zCfgProg (ao_strs_strtable+25)
+#define zCfgProg_LEN 7
+#define zEquivMode (ao_strs_strtable+1171)
+#define zEquivMode_LEN 44
+#define zFiveSpaces (ao_strs_strtable+244)
+#define zFiveSpaces_LEN 5
+#define zFmtFmt (ao_strs_strtable+33)
+#define zFmtFmt_LEN 11
+#define zFullOptFmt (ao_strs_strtable+1216)
+#define zFullOptFmt_LEN 34
+#define zGnuBreak (ao_strs_strtable+45)
+#define zGnuBreak_LEN 5
+#define zGnuFileArg (ao_strs_strtable+51)
+#define zGnuFileArg_LEN 5
+#define zGnuKeyLArg (ao_strs_strtable+57)
+#define zGnuKeyLArg_LEN 4
+#define zGnuNestArg (ao_strs_strtable+62)
+#define zGnuNestArg_LEN 5
+#define zGnuOptArg (ao_strs_strtable+68)
+#define zGnuOptArg_LEN 6
+#define zGnuOptFmt (ao_strs_strtable+75)
+#define zGnuOptFmt_LEN 10
+#define zGnuTimeArg (ao_strs_strtable+86)
+#define zGnuTimeArg_LEN 4
+#define zNone (ao_strs_strtable+91)
+#define zNone_LEN 4
+#define zOptCookieCt (ao_strs_strtable+1251)
+#define zOptCookieCt_LEN 38
+#define zOptCtFmt (ao_strs_strtable+1290)
+#define zOptCtFmt_LEN 30
+#define zOptDisabl (ao_strs_strtable+1321)
+#define zOptDisabl_LEN 32
+#define zOptNumFmt (ao_strs_strtable+1354)
+#define zOptNumFmt_LEN 41
+#define zOptionCase (ao_strs_strtable+1396)
+#define zOptionCase_LEN 30
+#define zOptionEndSelect (ao_strs_strtable+774)
+#define zOptionEndSelect_LEN 16
+#define zOptionFlag (ao_strs_strtable+791)
+#define zOptionFlag_LEN 15
+#define zOptionFullName (ao_strs_strtable+807)
+#define zOptionFullName_LEN 15
+#define zOptionPartName (ao_strs_strtable+823)
+#define zOptionPartName_LEN 17
+#define zPresetFile (ao_strs_strtable+96)
+#define zPresetFile_LEN 37
+#define zReqOptFmt (ao_strs_strtable+134)
+#define zReqOptFmt_LEN 13
+#define zSepChars (ao_strs_strtable+0)
+#define zSepChars_LEN 3
+#define zShrtGnuOptFmt (ao_strs_strtable+148)
+#define zShrtGnuOptFmt_LEN 2
+#define zSixSpaces (ao_strs_strtable+237)
+#define zSixSpaces_LEN 6
+#define zStdBoolArg (ao_strs_strtable+151)
+#define zStdBoolArg_LEN 3
+#define zStdBreak (ao_strs_strtable+155)
+#define zStdBreak_LEN 7
+#define zStdFileArg (ao_strs_strtable+163)
+#define zStdFileArg_LEN 3
+#define zStdKeyArg (ao_strs_strtable+167)
+#define zStdKeyArg_LEN 3
+#define zStdKeyLArg (ao_strs_strtable+171)
+#define zStdKeyLArg_LEN 3
+#define zStdNestArg (ao_strs_strtable+175)
+#define zStdNestArg_LEN 3
+#define zStdNoArg (ao_strs_strtable+179)
+#define zStdNoArg_LEN 3
+#define zStdNumArg (ao_strs_strtable+183)
+#define zStdNumArg_LEN 3
+#define zStdOptArg (ao_strs_strtable+187)
+#define zStdOptArg_LEN 3
+#define zStdReqArg (ao_strs_strtable+191)
+#define zStdReqArg_LEN 3
+#define zStdStrArg (ao_strs_strtable+195)
+#define zStdStrArg_LEN 3
+#define zStdTimeArg (ao_strs_strtable+199)
+#define zStdTimeArg_LEN 3
+#define zTabHyp (ao_strs_strtable+203)
+#define zTabHypAnd (ao_strs_strtable+217)
+#define zTabHypAnd_LEN 11
+#define zTabHyp_LEN 6
+#define zTabSpace (ao_strs_strtable+210)
+#define zTabSpace_LEN 6
+#define zTabout (ao_strs_strtable+229)
+#define zTabout_LEN 7
+#define zThreeSpaces (ao_strs_strtable+250)
+#define zThreeSpaces_LEN 3
+#define zTwoSpaces (ao_strs_strtable+254)
+#define zTwoSpaces_LEN 2
+#define zambig_file (ao_strs_strtable+4)
+#define zambig_file_LEN 7
+extern char const ao_strs_strtable[6633];
+
+#endif /* STRINGS_AO_STRS_H_GUARD */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/autoopts.c b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/autoopts.c
new file mode 100644
index 0000000..4b15aca
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/autoopts.c
@@ -0,0 +1,397 @@
+
+/**
+ * \file autoopts.c
+ *
+ * This file contains all of the routines that must be linked into
+ * an executable to use the generated option processing. The optional
+ * routines are in separately compiled modules so that they will not
+ * necessarily be linked in.
+ *
+ * @addtogroup autoopts
+ * @{
+ */
+/*
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
+ *
+ * AutoOpts is available under any one of two licenses. The license
+ * in use must be one of these two and the choice is under the control
+ * of the user of the license.
+ *
+ * The GNU Lesser General Public License, version 3 or later
+ * See the files "COPYING.lgplv3" and "COPYING.gplv3"
+ *
+ * The Modified Berkeley Software Distribution License
+ * See the file "COPYING.mbsd"
+ *
+ * These files have the following sha256 sums:
+ *
+ * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
+ * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
+ * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
+ */
+
+/**
+ * The number of tab characters to skip when printing continuation lines.
+ */
+static unsigned int tab_skip_ct = 0;
+
+#ifndef HAVE_PATHFIND
+# define pathfind(_p, _n, _m) option_pathfind(_p, _n, _m)
+# include "compat/pathfind.c"
+#endif
+
+#ifndef HAVE_SNPRINTF
+# define vsnprintf option_vsnprintf
+# define snprintf option_snprintf
+# include "compat/snprintf.c"
+#endif
+
+#ifndef HAVE_STRDUP
+# define strdup(_s) option_strdup(_s)
+# include "compat/strdup.c"
+#endif
+
+#ifndef HAVE_STRCHR
+# define strrchr(_s, _c) option_strrchr(_s, _c)
+# define strchr(_s, _c) option_strchr(_s, _c)
+# include "compat/strchr.c"
+#endif
+
+LOCAL void *
+ao_malloc(size_t sz)
+{
+ void * res = malloc(sz);
+ if (res == NULL) {
+ fprintf(stderr, zalloc_fail, (int)sz);
+ option_exits(EXIT_FAILURE);
+ }
+ return res;
+}
+#undef malloc
+#define malloc(_s) ao_malloc(_s)
+
+LOCAL void *
+ao_realloc(void *p, size_t sz)
+{
+ void * res = (p == NULL) ? malloc(sz) : realloc(p, sz);
+ if (res == NULL) {
+ fprintf(stderr, zrealloc_fail, (int)sz, p);
+ option_exits(EXIT_FAILURE);
+ }
+ return res;
+}
+#undef realloc
+#define realloc(_p,_s) ao_realloc(_p,_s)
+
+LOCAL char *
+ao_strdup(char const *str)
+{
+ char * res = strdup(str);
+ if (res == NULL) {
+ fprintf(stderr, zalloc_fail, (int)strlen(str));
+ option_exits(EXIT_FAILURE);
+ }
+ return res;
+}
+#undef strdup
+#define strdup(_p) ao_strdup(_p)
+
+/**
+ * handle an option.
+ *
+ * This routine handles equivalencing, sets the option state flags and
+ * invokes the handler procedure, if any.
+ */
+LOCAL tSuccess
+handle_opt(tOptions * opts, tOptState * o_st)
+{
+ /*
+ * Save a copy of the option procedure pointer.
+ * If this is an equivalence class option, we still want this proc.
+ */
+ tOptDesc * od = o_st->pOD;
+ tOptProc * opt_proc = od->pOptProc;
+ if (od->fOptState & OPTST_ALLOC_ARG)
+ AGFREE(od->optArg.argString);
+
+ od->optArg.argString = o_st->pzOptArg;
+
+ /*
+ * IF we are presetting options, then we will ignore any un-presettable
+ * options. They are the ones either marked as such.
+ */
+ if ( ((opts->fOptSet & OPTPROC_PRESETTING) != 0)
+ && ((od->fOptState & OPTST_NO_INIT) != 0)
+ )
+ return PROBLEM;
+
+ /*
+ * IF this is an equivalence class option,
+ * THEN
+ * Save the option value that got us to this option
+ * entry. (It may not be od->optChar[0], if this is an
+ * equivalence entry.)
+ * set the pointer to the equivalence class base
+ */
+ if (od->optEquivIndex != NO_EQUIVALENT) {
+ tOptDesc * eqv_od = opts->pOptDesc + od->optEquivIndex;
+
+ /*
+ * IF the current option state has not been defined (set on the
+ * command line), THEN we will allow continued resetting of
+ * the value. Once "defined", then it must not change.
+ */
+ if ((od->fOptState & OPTST_DEFINED) != 0) {
+ /*
+ * The equivalenced-to option has been found on the command
+ * line before. Make sure new occurrences are the same type.
+ *
+ * IF this option has been previously equivalenced and
+ * it was not the same equivalenced-to option,
+ * THEN we have a usage problem.
+ */
+ if (eqv_od->optActualIndex != od->optIndex) {
+ fprintf(stderr, zmultiway_bug, eqv_od->pz_Name, od->pz_Name,
+ (opts->pOptDesc + eqv_od->optActualIndex)->pz_Name);
+ return FAILURE;
+ }
+ } else {
+ /*
+ * Set the equivalenced-to actual option index to no-equivalent
+ * so that we set all the entries below. This option may either
+ * never have been selected before, or else it was selected by
+ * some sort of "presetting" mechanism.
+ */
+ eqv_od->optActualIndex = NO_EQUIVALENT;
+ }
+
+ if (eqv_od->optActualIndex != od->optIndex) {
+ /*
+ * First time through, copy over the state
+ * and add in the equivalence flag
+ */
+ eqv_od->optActualValue = od->optValue;
+ eqv_od->optActualIndex = od->optIndex;
+ o_st->flags |= OPTST_EQUIVALENCE;
+ }
+
+ /*
+ * Copy the most recent option argument. set membership state
+ * is kept in 'eqv_od->optCookie'. Do not overwrite.
+ */
+ eqv_od->optArg.argString = od->optArg.argString;
+ od = eqv_od;
+
+ } else {
+ od->optActualValue = od->optValue;
+ od->optActualIndex = od->optIndex;
+ }
+
+ od->fOptState &= OPTST_PERSISTENT_MASK;
+ od->fOptState |= (o_st->flags & ~OPTST_PERSISTENT_MASK);
+
+ /*
+ * Keep track of count only for DEFINED (command line) options.
+ * IF we have too many, build up an error message and bail.
+ */
+ if ( (od->fOptState & OPTST_DEFINED)
+ && (++od->optOccCt > od->optMaxCt) )
+ return too_many_occurrences(opts, od);
+ /*
+ * If provided a procedure to call, call it
+ */
+ if (opt_proc != NULL)
+ (*opt_proc)(opts, od);
+
+ return SUCCESS;
+}
+
+/**
+ * Find the option descriptor and option argument (if any) for the
+ * next command line argument. DO NOT modify the descriptor. Put
+ * all the state in the state argument so that the option can be skipped
+ * without consequence (side effect).
+ *
+ * @param opts the program option descriptor
+ * @param o_st the state of the next found option
+ */
+LOCAL tSuccess
+next_opt(tOptions * opts, tOptState * o_st)
+{
+ {
+ tSuccess res = find_opt(opts, o_st);
+ if (! SUCCESSFUL(res))
+ return res;
+ }
+
+ if ( ((o_st->flags & OPTST_DEFINED) != 0)
+ && ((o_st->pOD->fOptState & OPTST_NO_COMMAND) != 0)) {
+ fprintf(stderr, zNotCmdOpt, o_st->pOD->pz_Name);
+ return FAILURE;
+ }
+
+ return get_opt_arg(opts, o_st);
+}
+
+/**
+ * Process all the options from our current position onward. (This allows
+ * interspersed options and arguments for the few non-standard programs that
+ * require it.) Thus, do not rewind option indexes because some programs
+ * choose to re-invoke after a non-option.
+ *
+ * @param[in,out] opts program options descriptor
+ * @returns SUCCESS or FAILURE
+ */
+LOCAL tSuccess
+regular_opts(tOptions * opts)
+{
+ /* assert: opts->fOptSet & OPTPROC_IMMEDIATE == 0 */
+ for (;;) {
+ tOptState opt_st = OPTSTATE_INITIALIZER(DEFINED);
+
+ switch (next_opt(opts, &opt_st)) {
+ case FAILURE: goto failed_option;
+ case PROBLEM: return SUCCESS; /* no more args */
+ case SUCCESS: break;
+ }
+
+ /*
+ * IF this is an immediate action option,
+ * THEN skip it (unless we are supposed to do it a second time).
+ */
+ if (! DO_NORMALLY(opt_st.flags)) {
+ if (! DO_SECOND_TIME(opt_st.flags))
+ continue;
+ opt_st.pOD->optOccCt--; /* don't count this repetition */
+ }
+
+ if (! SUCCESSFUL(handle_opt(opts, &opt_st)))
+ break;
+ } failed_option:;
+
+ if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0)
+ (*opts->pUsageProc)(opts, EXIT_FAILURE);
+
+ return FAILURE;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * THESE ROUTINES ARE CALLABLE FROM THE GENERATED OPTION PROCESSING CODE
+ */
+/*=--subblock=arg=arg_type,arg_name,arg_desc =*/
+/*=*
+ * library: opts
+ * header: your-opts.h
+ *
+ * lib_description:
+ *
+ * These are the routines that libopts users may call directly from their
+ * code. There are several other routines that can be called by code
+ * generated by the libopts option templates, but they are not to be
+ * called from any other user code. The @file{options.h} header is
+ * fairly clear about this, too.
+=*/
+
+/*=export_func optionProcess
+ *
+ * what: this is the main option processing routine
+ *
+ * arg: + tOptions * + opts + program options descriptor +
+ * arg: + int + a_ct + program arg count +
+ * arg: + char ** + a_v + program arg vector +
+ *
+ * ret_type: int
+ * ret_desc: the count of the arguments processed
+ *
+ * doc:
+ *
+ * This is the main entry point for processing options. It is intended
+ * that this procedure be called once at the beginning of the execution of
+ * a program. Depending on options selected earlier, it is sometimes
+ * necessary to stop and restart option processing, or to select completely
+ * different sets of options. This can be done easily, but you generally
+ * do not want to do this.
+ *
+ * The number of arguments processed always includes the program name.
+ * If one of the arguments is "--", then it is counted and the processing
+ * stops. If an error was encountered and errors are to be tolerated, then
+ * the returned value is the index of the argument causing the error.
+ * A hyphen by itself ("-") will also cause processing to stop and will
+ * @emph{not} be counted among the processed arguments. A hyphen by itself
+ * is treated as an operand. Encountering an operand stops option
+ * processing.
+ *
+ * err: Errors will cause diagnostics to be printed. @code{exit(3)} may
+ * or may not be called. It depends upon whether or not the options
+ * were generated with the "allow-errors" attribute, or if the
+ * ERRSKIP_OPTERR or ERRSTOP_OPTERR macros were invoked.
+=*/
+int
+optionProcess(tOptions * opts, int a_ct, char ** a_v)
+{
+ if (! SUCCESSFUL(validate_struct(opts, a_v[0])))
+ ao_bug(zbad_data_msg);
+
+ /*
+ * Establish the real program name, the program full path,
+ * and do all the presetting the first time thru only.
+ */
+ if (! ao_initialize(opts, a_ct, a_v))
+ return 0;
+
+ /*
+ * IF we are (re)starting,
+ * THEN reset option location
+ */
+ if (opts->curOptIdx <= 0) {
+ opts->curOptIdx = 1;
+ opts->pzCurOpt = NULL;
+ }
+
+ if (! SUCCESSFUL(regular_opts(opts)))
+ return (int)opts->origArgCt;
+
+ /*
+ * IF there were no errors
+ * AND we have RC/INI files
+ * AND there is a request to save the files
+ * THEN do that now before testing for conflicts.
+ * (conflicts are ignored in preset options)
+ */
+ switch (opts->specOptIdx.save_opts) {
+ case 0:
+ case NO_EQUIVALENT:
+ break;
+ default:
+ {
+ tOptDesc * od = opts->pOptDesc + opts->specOptIdx.save_opts;
+
+ if (SELECTED_OPT(od)) {
+ optionSaveFile(opts);
+ option_exits(EXIT_SUCCESS);
+ }
+ }
+ }
+
+ /*
+ * IF we are checking for errors,
+ * THEN look for too few occurrences of required options
+ */
+ if (((opts->fOptSet & OPTPROC_ERRSTOP) != 0)
+ && (! is_consistent(opts)))
+ (*opts->pUsageProc)(opts, EXIT_FAILURE);
+
+ return (int)opts->curOptIdx;
+}
+
+/** @}
+ *
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of autoopts/autoopts.c */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/autoopts.h b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/autoopts.h
new file mode 100644
index 0000000..6f75f9e
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/autoopts.h
@@ -0,0 +1,484 @@
+
+/*
+ * \file autoopts.h
+ *
+ * This file defines all the global structures and special values
+ * used in the automated option processing library.
+ *
+ * @group autoopts
+ * @{
+ */
+/*
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
+ *
+ * AutoOpts is available under any one of two licenses. The license
+ * in use must be one of these two and the choice is under the control
+ * of the user of the license.
+ *
+ * The GNU Lesser General Public License, version 3 or later
+ * See the files "COPYING.lgplv3" and "COPYING.gplv3"
+ *
+ * The Modified Berkeley Software Distribution License
+ * See the file "COPYING.mbsd"
+ *
+ * These files have the following sha256 sums:
+ *
+ * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
+ * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
+ * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
+ */
+
+#ifndef AUTOGEN_AUTOOPTS_H
+#define AUTOGEN_AUTOOPTS_H
+#include <stdnoreturn.h>
+
+#define AO_NAME_LIMIT 127
+#define AO_NAME_SIZE ((size_t)(AO_NAME_LIMIT + 1))
+
+#ifndef AG_PATH_MAX
+# ifdef PATH_MAX
+# define AG_PATH_MAX ((size_t)PATH_MAX)
+# else
+# define AG_PATH_MAX ((size_t)4096)
+# endif
+#else
+# if defined(PATH_MAX) && (PATH_MAX > MAXPATHLEN)
+# undef AG_PATH_MAX
+# define AG_PATH_MAX ((size_t)PATH_MAX)
+# endif
+#endif
+
+#undef EXPORT
+#define EXPORT
+
+#ifndef NUL
+#define NUL '\0'
+#endif
+#define BEL '\a'
+#define BS '\b'
+#define HT '\t'
+#define LF '\n'
+#define VT '\v'
+#define FF '\f'
+#define CR '\r'
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+# define DIRCH '\\'
+#else
+# define DIRCH '/'
+#endif
+
+#ifndef EX_USAGE
+ /**
+ * Command line usage problem
+ */
+# define EX_USAGE 64
+#endif
+#ifndef EX_DATAERR
+ /**
+ * The input data was incorrect in some way.
+ */
+# define EX_DATAERR 64
+#endif
+#ifndef EX_NOINPUT
+ /**
+ * option state was requested from a file that cannot be loaded.
+ */
+# define EX_NOINPUT 66
+#endif
+#ifndef EX_SOFTWARE
+ /**
+ * AutoOpts Software failure.
+ */
+# define EX_SOFTWARE 70
+#endif
+#ifndef EX_OSERR
+ /**
+ * Command line usage problem
+ */
+# define EX_OSERR 71
+#endif
+
+#define NL '\n'
+#ifndef C
+/**
+ * Coercive cast. Compel an address to be interpreted as the type
+ * of the first argument. No complaints, just do it.
+ */
+#define C(_t,_p) ((_t)VOIDP(_p))
+#endif
+
+/* The __attribute__((__warn_unused_result__)) feature
+ is available in gcc versions 3.4 and newer,
+ while the typeof feature has been available since 2.7 at least. */
+# if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 4)
+# define ignore_val(x) ((void) (x))
+# else
+# define ignore_val(x) (({ __typeof__ (x) __x = (x); (void) __x; }))
+# endif
+
+/*
+ * Convert the number to a list usable in a printf call
+ */
+#define NUM_TO_VER(n) ((n) >> 12), ((n) >> 7) & 0x001F, (n) & 0x007F
+
+#define NAMED_OPTS(po) \
+ (((po)->fOptSet & (OPTPROC_SHORTOPT | OPTPROC_LONGOPT)) == 0)
+
+#define SKIP_OPT(p) (((p)->fOptState & OPTST_IMMUTABLE_MASK) != 0)
+
+typedef int tDirection;
+/**
+ * handling option presets. Start with command line and work through
+ * config settings in reverse order.
+ */
+#define DIRECTION_PRESET -1
+/**
+ * handling normal options. Start with first config file, then environment
+ * variables and finally the command line.
+ */
+#define DIRECTION_PROCESS 1
+/**
+ * An initialzation phase or an option being loaded from program sources.
+ */
+#define DIRECTION_CALLED 0
+
+#define PROCESSING(d) ((d)>0)
+#define PRESETTING(d) ((d)<0)
+#define CALLED(d) ((d)==0)
+
+/**
+ * When loading a line (or block) of text as an option, the value can
+ * be processed in any of several modes.
+ */
+typedef enum {
+ /**
+ * If the value looks like a quoted string, then process it. Double
+ * quoted strings are processed the way strings are in "C" programs,
+ * except they are treated as regular characters if the following
+ * character is not a well-established escape sequence. Single quoted
+ * strings (quoted with apostrophies) are handled the way strings are
+ * handled in shell scripts, *except* that backslash escapes are
+ * honored before backslash escapes and apostrophies.
+ */
+ OPTION_LOAD_COOKED,
+
+ /**
+ * Even if the value begins with quote characters, do not do quote
+ * processing. Strip leading and trailing white space.
+ */
+ OPTION_LOAD_UNCOOKED,
+
+ /**
+ * Keep every part of the value between the delimiters.
+ */
+ OPTION_LOAD_KEEP
+} tOptionLoadMode;
+
+static tOptionLoadMode option_load_mode;
+
+/**
+ * The pager state is used by optionPagedUsage() procedure.
+ * When it runs, it sets itself up to be called again on exit.
+ * If, however, a routine needs a child process to do some work
+ * before it is done, then 'pagerState' must be set to
+ * 'PAGER_STATE_CHILD' so that optionPagedUsage() will not try
+ * to run the pager program before its time.
+ */
+typedef enum {
+ PAGER_STATE_INITIAL, //@< initial option paging state
+
+ /**
+ * temp file created and optionPagedUsage is scheduled to run at exit
+ */
+ PAGER_STATE_READY,
+
+ /**
+ * This is a child process used in creating shell script usage.
+ */
+ PAGER_STATE_CHILD
+} tePagerState;
+
+typedef enum {
+ ENV_ALL,
+ ENV_IMM,
+ ENV_NON_IMM
+} teEnvPresetType;
+
+typedef enum {
+ TOPT_UNDEFINED = 0,
+ TOPT_SHORT,
+ TOPT_LONG,
+ TOPT_DEFAULT
+} teOptType;
+
+typedef struct {
+ tOptDesc * pOD;
+ char const * pzOptArg;
+ opt_state_mask_t flags;
+ teOptType optType;
+} tOptState;
+#define OPTSTATE_INITIALIZER(st) \
+ { NULL, NULL, OPTST_ ## st, TOPT_UNDEFINED }
+
+#define TEXTTO_TABLE \
+ _TT_(LONGUSAGE) \
+ _TT_(USAGE) \
+ _TT_(VERSION)
+#define _TT_(n) \
+ TT_ ## n ,
+
+typedef enum { TEXTTO_TABLE COUNT_TT } teTextTo;
+
+#undef _TT_
+
+/**
+ * option argument types. Used to create usage information for
+ * particular options.
+ */
+typedef struct {
+ char const * pzStr;
+ char const * pzReq;
+ char const * pzNum;
+ char const * pzFile;
+ char const * pzKey;
+ char const * pzKeyL;
+ char const * pzBool;
+ char const * pzNest;
+ char const * pzOpt;
+ char const * pzNo;
+ char const * pzBrk;
+ char const * pzNoF;
+ char const * pzSpc;
+ char const * pzOptFmt;
+ char const * pzTime;
+} arg_types_t;
+
+#define AGALOC(_c, _w) ao_malloc((size_t)_c)
+#define AGREALOC(_p, _c, _w) ao_realloc(VOIDP(_p), (size_t)_c)
+#define AGFREE(_p) free(VOIDP(_p))
+#define AGDUPSTR(_p, _s, _w) (_p = ao_strdup(_s))
+
+static void *
+ao_malloc(size_t sz);
+
+static void *
+ao_realloc(void *p, size_t sz);
+
+#define ao_free(_p) free(VOIDP(_p))
+
+static char *
+ao_strdup(char const * str);
+
+/**
+ * DO option handling?
+ *
+ * Options are examined at two times: at immediate handling time and at
+ * normal handling time. If an option is disabled, the timing may be
+ * different from the handling of the undisabled option. The OPTST_DIABLED
+ * bit indicates the state of the currently discovered option.
+ * So, here's how it works:
+ *
+ * A) handling at "immediate" time, either 1 or 2:
+ *
+ * 1. OPTST_DISABLED is not set:
+ * IMM must be set
+ * DISABLE_IMM don't care
+ * TWICE don't care
+ * DISABLE_TWICE don't care
+ * 0 -and- 1 x x x
+ *
+ * 2. OPTST_DISABLED is set:
+ * IMM don't care
+ * DISABLE_IMM must be set
+ * TWICE don't care
+ * DISABLE_TWICE don't care
+ * 1 -and- x 1 x x
+ */
+#define DO_IMMEDIATELY(_flg) \
+ ( (((_flg) & (OPTST_DISABLED|OPTST_IMM)) == OPTST_IMM) \
+ || ( ((_flg) & (OPTST_DISABLED|OPTST_DISABLE_IMM)) \
+ == (OPTST_DISABLED|OPTST_DISABLE_IMM) ))
+
+/**
+ * B) handling at "regular" time because it was not immediate
+ *
+ * 1. OPTST_DISABLED is not set:
+ * IMM must *NOT* be set
+ * DISABLE_IMM don't care
+ * TWICE don't care
+ * DISABLE_TWICE don't care
+ * 0 -and- 0 x x x
+ *
+ * 2. OPTST_DISABLED is set:
+ * IMM don't care
+ * DISABLE_IMM don't care
+ * TWICE must be set
+ * DISABLE_TWICE don't care
+ * 1 -and- x x 1 x
+ */
+#define DO_NORMALLY(_flg) ( \
+ (((_flg) & (OPTST_DISABLED|OPTST_IMM)) == 0) \
+ || (((_flg) & (OPTST_DISABLED|OPTST_DISABLE_IMM)) == \
+ OPTST_DISABLED) )
+
+/**
+ * C) handling at "regular" time because it is to be handled twice.
+ * The immediate bit was already tested and found to be set:
+ *
+ * 3. OPTST_DISABLED is not set:
+ * IMM is set (but don't care)
+ * DISABLE_IMM don't care
+ * TWICE must be set
+ * DISABLE_TWICE don't care
+ * 0 -and- ? x 1 x
+ *
+ * 4. OPTST_DISABLED is set:
+ * IMM don't care
+ * DISABLE_IMM is set (but don't care)
+ * TWICE don't care
+ * DISABLE_TWICE must be set
+ * 1 -and- x ? x 1
+ */
+#define DO_SECOND_TIME(_flg) ( \
+ (((_flg) & (OPTST_DISABLED|OPTST_TWICE)) == \
+ OPTST_TWICE) \
+ || (((_flg) & (OPTST_DISABLED|OPTST_DISABLE_TWICE)) == \
+ (OPTST_DISABLED|OPTST_DISABLE_TWICE) ))
+
+/*
+ * text_mmap structure. Only active on platforms with mmap(2).
+ */
+#ifdef HAVE_SYS_MMAN_H
+# include <sys/mman.h>
+#else
+# ifndef PROT_READ
+# define PROT_READ 0x01
+# endif
+# ifndef PROT_WRITE
+# define PROT_WRITE 0x02
+# endif
+# ifndef MAP_SHARED
+# define MAP_SHARED 0x01
+# endif
+# ifndef MAP_PRIVATE
+# define MAP_PRIVATE 0x02
+# endif
+#endif
+
+#ifndef MAP_FAILED
+# define MAP_FAILED VOIDP(-1)
+#endif
+
+#ifndef _SC_PAGESIZE
+# ifdef _SC_PAGE_SIZE
+# define _SC_PAGESIZE _SC_PAGE_SIZE
+# endif
+#endif
+
+#ifndef HAVE_STRCHR
+extern char * strchr(char const * s, int c);
+extern char * strrchr(char const * s, int c);
+#endif
+
+/**
+ * INQUERY_CALL() tests whether the option handling function has been
+ * called by an inquery (help text needed, or option being reset),
+ * or called by a set-the-option operation.
+ */
+#define INQUERY_CALL(_o, _d) ( \
+ ((_o) <= OPTPROC_EMIT_LIMIT) \
+ || ((_d) == NULL) \
+ || (((_d)->fOptState & OPTST_RESET) != 0) )
+
+/**
+ * Define and initialize all the user visible strings.
+ * We do not do translations. If translations are to be done, then
+ * the client will provide a callback for that purpose.
+ */
+#undef DO_TRANSLATIONS
+#include "autoopts/usage-txt.h"
+
+/**
+ * File pointer for usage output
+ */
+FILE * option_usage_fp;
+/**
+ * If provided in the option structure
+ */
+static char const * program_pkgdatadir;
+/**
+ * privately exported functions
+ */
+extern tOptProc optionPrintVersion, optionPagedUsage, optionLoadOpt;
+
+#ifdef AUTOOPTS_INTERNAL
+
+#ifndef PKGDATADIR
+# define PKGDATADIR ""
+#endif
+#define APOSTROPHE '\''
+
+#define OPTPROC_L_N_S (OPTPROC_LONGOPT | OPTPROC_SHORTOPT)
+#if defined(ENABLE_NLS) && defined(HAVE_LIBINTL_H)
+# include <libintl.h>
+#endif
+
+typedef struct {
+ size_t fnm_len;
+ uint32_t fnm_mask;
+ char const * fnm_name;
+} ao_flag_names_t;
+
+/**
+ * Automated Options Usage Flags.
+ * NB: no entry may be a prefix of another entry
+ */
+#define AOFLAG_TABLE \
+ _aof_(gnu, OPTPROC_GNUUSAGE ) \
+ _aof_(autoopts, ~OPTPROC_GNUUSAGE) \
+ _aof_(no_misuse_usage, OPTPROC_MISUSE ) \
+ _aof_(misuse_usage, ~OPTPROC_MISUSE ) \
+ _aof_(compute, OPTPROC_COMPUTE )
+
+#define _aof_(_n, _f) AOUF_ ## _n ## _ID,
+typedef enum { AOFLAG_TABLE AOUF_COUNT } ao_flag_id_t;
+#undef _aof_
+
+#define _aof_(_n, _f) AOUF_ ## _n = (1 << AOUF_ ## _n ## _ID),
+typedef enum { AOFLAG_TABLE } ao_flags_t;
+#undef _aof_
+
+static char const zNil[] = "";
+static arg_types_t argTypes = { NULL };
+static char line_fmt_buf[32];
+static bool displayEnum = false;
+static char const pkgdatadir_default[] = PKGDATADIR;
+static char const * program_pkgdatadir = pkgdatadir_default;
+static tOptionLoadMode option_load_mode = OPTION_LOAD_UNCOOKED;
+static tePagerState pagerState = PAGER_STATE_INITIAL;
+
+ FILE * option_usage_fp = NULL;
+
+static char const * pz_enum_err_fmt;
+
+tOptions * optionParseShellOptions = NULL;
+
+static char const * shell_prog = NULL;
+static char * script_leader = NULL;
+static char * script_trailer = NULL;
+static char * script_text = NULL;
+static bool print_exit = false;
+#endif /* AUTOOPTS_INTERNAL */
+
+#endif /* AUTOGEN_AUTOOPTS_H */
+/**
+ * @}
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of autoopts/autoopts.h */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/autoopts/options.h b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/autoopts/options.h
new file mode 100644
index 0000000..09aac10
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/autoopts/options.h
@@ -0,0 +1,1261 @@
+/* -*- buffer-read-only: t -*- vi: set ro:
+ *
+ * DO NOT EDIT THIS FILE (options.h)
+ *
+ * It has been AutoGen-ed
+ * From the definitions funcs.def
+ * and the template file options_h
+ *
+ * This file defines all the global structures and special values
+ * used in the automated option processing library.
+ *
+ * Automated Options Copyright (C) 1992-2015 by Bruce Korb
+ *
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
+ *
+ * AutoOpts is available under any one of two licenses. The license
+ * in use must be one of these two and the choice is under the control
+ * of the user of the license.
+ *
+ * The GNU Lesser General Public License, version 3 or later
+ * See the files "COPYING.lgplv3" and "COPYING.gplv3"
+ *
+ * The Modified Berkeley Software Distribution License
+ * See the file "COPYING.mbsd"
+ *
+ * These files have the following sha256 sums:
+ *
+ * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
+ * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
+ * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
+ */
+#ifndef AUTOOPTS_OPTIONS_H_GUARD
+#define AUTOOPTS_OPTIONS_H_GUARD 1
+/** \file options.h
+ *
+ * @addtogroup autoopts
+ * @{
+ */
+#include <sys/types.h>
+#include <stdio.h>
+
+#ifndef COMPAT_H_GUARD
+/*
+ * This is needed for test compilations where the "compat.h"
+ * header is not usually available.
+ */
+# if defined(HAVE_STDINT_H)
+# include <stdint.h>
+# elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+# endif /* HAVE_STDINT/INTTYPES_H */
+
+# if defined(HAVE_LIMITS_H)
+# include <limits.h>
+# elif defined(HAVE_SYS_LIMITS_H)
+# include <sys/limits.h>
+# endif /* HAVE_LIMITS/SYS_LIMITS_H */
+
+# if defined(HAVE_SYSEXITS_H)
+# include <sysexits.h>
+# endif /* HAVE_SYSEXITS_H */
+
+# if defined(HAVE_STDBOOL_H)
+# include <stdbool.h>
+# else
+ typedef enum { false = 0, true = 1 } _Bool;
+# define bool _Bool
+
+ /* The other macros must be usable in preprocessor directives. */
+# define false 0
+# define true 1
+# endif /* HAVE_SYSEXITS_H */
+#endif /* COMPAT_H_GUARD */
+// END-CONFIGURED-HEADERS
+
+/**
+ * Defined to abnormal value of EX_USAGE. Used to indicate that paged usage
+ * was requested. It is used to distinguish a --usage from a --help request.
+ * --usage is abbreviated and --help gives as much help as possible.
+ */
+#define AO_EXIT_REQ_USAGE 10064
+
+#undef VOIDP
+/**
+ * Coerce a value into a void pointer with no const or volatile attributes.
+ * Somewhere along the line, the above set of includes need to set up
+ * the "uintptr_t" type.
+ */
+#define VOIDP(_a) ((void *)(uintptr_t)(_a))
+
+/**
+ * PUBLIC DEFINES
+ *
+ * The following defines may be used in applications that need to test the
+ * state of an option. To test against these masks and values, a pointer
+ * to an option descriptor must be obtained. There are two ways:
+ *
+ * 1. inside an option processing procedure, it is the second argument,
+ * conventionally "tOptDesc * pOD".
+ *
+ * 2. Outside of an option procedure (or to reference a different option
+ * descriptor), use either "&DESC( opt_name )" or "&pfx_DESC( opt_name )".
+ *
+ * See the relevant generated header file to determine which and what
+ * values for "opt_name" are available.
+ * @group version
+ * @{
+ */
+/// autoopts structure version
+#define OPTIONS_STRUCT_VERSION 167937
+/// autoopts structure version string
+#define OPTIONS_VERSION_STRING "41:0:16"
+/// minimum version the autoopts library supports
+#define OPTIONS_MINIMUM_VERSION 102400
+/// minimum version the autoopts library supports as a string
+#define OPTIONS_MIN_VER_STRING "25:0:0"
+/// the display version of the autoopts library, as a string
+#define OPTIONS_DOTTED_VERSION "41.0"
+/// convert a version/release number pair to an integer value
+#define OPTIONS_VER_TO_NUM(_v, _r) (((_v) * 4096) + (_r))
+/// @}
+
+/**
+ * Option argument types. This must fit in the OPTST_ARG_TYPE_MASK
+ * field of the fOptState field of an option descriptor (tOptDesc).
+ * It will be a problem to extend beyond 4 bits.
+ */
+typedef enum {
+ OPARG_TYPE_NONE = 0, ///< does not take an argument
+ OPARG_TYPE_STRING = 1, ///< default type/ vanilla string
+ OPARG_TYPE_ENUMERATION = 2, ///< opt arg is an enum (keyword list)
+ OPARG_TYPE_BOOLEAN = 3, ///< opt arg is boolean-valued
+ OPARG_TYPE_MEMBERSHIP = 4, ///< opt arg sets set membership bits
+ OPARG_TYPE_NUMERIC = 5, ///< opt arg is a long int
+ OPARG_TYPE_HIERARCHY = 6, ///< option arg is hierarchical value
+ OPARG_TYPE_FILE = 7, ///< option arg names a file
+ OPARG_TYPE_TIME = 8, ///< opt arg is a time duration
+ OPARG_TYPE_FLOAT = 9, ///< opt arg is a floating point num
+ OPARG_TYPE_DOUBLE = 10, ///< opt arg is a double prec. float
+ OPARG_TYPE_LONG_DOUBLE = 11, ///< opt arg is a long double prec.
+ OPARG_TYPE_LONG_LONG = 12 ///< opt arg is a long long int
+} teOptArgType;
+
+/**
+ * value descriptor for sub options
+ */
+typedef struct optionValue {
+ teOptArgType valType; ///< which argument type
+ char * pzName; ///< name of the sub-option
+ union {
+ char strVal[1]; ///< OPARG_TYPE_STRING
+ unsigned int enumVal; ///< OPARG_TYPE_ENUMERATION
+ unsigned int boolVal; ///< OPARG_TYPE_BOOLEAN
+ unsigned long setVal; ///< OPARG_TYPE_MEMBERSHIP
+ long longVal; ///< OPARG_TYPE_NUMERIC
+ void * nestVal; ///< OPARG_TYPE_HIERARCHY
+ } v;
+} tOptionValue;
+
+/**
+ * file argument state and handling.
+ */
+typedef enum {
+ FTYPE_MODE_MAY_EXIST = 0x00, ///< may or may not exist
+ FTYPE_MODE_MUST_EXIST = 0x01, ///< must pre-exist
+ FTYPE_MODE_MUST_NOT_EXIST = 0x02, ///< must *not* pre-exist
+ FTYPE_MODE_EXIST_MASK = 0x03, ///< mask for these bits
+ FTYPE_MODE_NO_OPEN = 0x00, ///< leave file closed
+ FTYPE_MODE_OPEN_FD = 0x10, ///< call open(2)
+ FTYPE_MODE_FOPEN_FP = 0x20, ///< call fopen(3)
+ FTYPE_MODE_OPEN_MASK = 0x30 ///< open/fopen/not open
+} teOptFileType;
+
+/**
+ * the open flag bits or the mode string, depending on the open type.
+ */
+typedef union {
+ int file_flags; ///< open(2) flag bits
+ char const * file_mode; ///< fopen(3) mode string
+} tuFileMode;
+
+/// initial number of option argument holders to allocate
+#define MIN_ARG_ALLOC_CT 6
+/// amount by which to increment the argument holder allocation.
+#define INCR_ARG_ALLOC_CT 8
+/**
+ * an argument list. When an option appears multiple times and
+ * the values get "stacked". \a apzArgs holds 8 pointers initially
+ * and is incremented by \a INCR_ARG_ALLOC_CT as needed.
+ */
+typedef struct {
+ int useCt; ///< elements in use
+
+ /// allocated elements, mininum \a MIN_ARG_ALLOC_CT
+ /// steps by \a INCR_ARG_ALLOC_CT
+ int allocCt;
+ char const * apzArgs[MIN_ARG_ALLOC_CT]; ///< element array
+} tArgList;
+
+/**
+ * Bits in the fOptState option descriptor field.
+ * @{
+ */
+
+/** integral type for holding opt_state masks */
+typedef uint32_t opt_state_mask_t;
+
+#define OPTST_ARG_TYPE_SHIFT 12
+/** bits defined for opt_state_mask_t */
+/** Set via the "SET_OPT()" macro */
+#define OPTST_SET 0x0000001U
+/** Set via an RC/INI file */
+#define OPTST_PRESET 0x0000002U
+/** Set via a command line option */
+#define OPTST_DEFINED 0x0000004U
+/** Reset via command line option */
+#define OPTST_RESET 0x0000008U
+/** selected by equiv'ed option */
+#define OPTST_EQUIVALENCE 0x0000010U
+/** option is in disabled state */
+#define OPTST_DISABLED 0x0000020U
+/** pzOptArg was allocated */
+#define OPTST_ALLOC_ARG 0x0000040U
+/** option cannot be preset */
+#define OPTST_NO_INIT 0x0000100U
+/** opt value (flag) is any digit */
+#define OPTST_NUMBER_OPT 0x0000200U
+/** opt uses optionStackArg proc */
+#define OPTST_STACKED 0x0000400U
+/** option defaults to enabled */
+#define OPTST_INITENABLED 0x0000800U
+/** bit 1 of arg type enum */
+#define OPTST_ARG_TYPE_1 0x0001000U
+/** bit 2 of arg type enum */
+#define OPTST_ARG_TYPE_2 0x0002000U
+/** bit 3 of arg type enum */
+#define OPTST_ARG_TYPE_3 0x0004000U
+/** bit 4 of arg type enum */
+#define OPTST_ARG_TYPE_4 0x0008000U
+/** the option arg not required */
+#define OPTST_ARG_OPTIONAL 0x0010000U
+/** process opt on first pass */
+#define OPTST_IMM 0x0020000U
+/** process disablement immed. */
+#define OPTST_DISABLE_IMM 0x0040000U
+/** compiled out of program */
+#define OPTST_OMITTED 0x0080000U
+/** must be set or pre-set */
+#define OPTST_MUST_SET 0x0100000U
+/** opt is for doc only */
+#define OPTST_DOCUMENT 0x0200000U
+/** process opt twice - imm + reg */
+#define OPTST_TWICE 0x0400000U
+/** process disabled option twice */
+#define OPTST_DISABLE_TWICE 0x0800000U
+/** scaled integer value */
+#define OPTST_SCALED_NUM 0x1000000U
+/** disable from cmd line */
+#define OPTST_NO_COMMAND 0x2000000U
+/** support is being removed */
+#define OPTST_DEPRECATED 0x4000000U
+/** alias for other option */
+#define OPTST_ALIAS 0x8000000U
+
+/** bits in SET mask:
+ * set preset reset defined */
+#define OPTST_SET_MASK 0x000000FU
+
+/** bits in MUTABLE mask:
+ * set preset reset defined equivalence disabled
+ * alloc_arg */
+#define OPTST_MUTABLE_MASK 0x000007FU
+
+/** bits omitted from PERSISTENT mask:
+ * mutable_mask */
+#define OPTST_PERSISTENT_MASK 0xFFFFF00U
+
+/** bits in SELECTED mask:
+ * set defined */
+#define OPTST_SELECTED_MASK 0x0000005U
+
+/** bits in ARG_TYPE mask:
+ * arg_type_1 arg_type_2 arg_type_3 arg_type_4 */
+#define OPTST_ARG_TYPE_MASK 0x000F000U
+
+/** bits in NO_USAGE mask:
+ * omitted no_command deprecated */
+#define OPTST_NO_USAGE_MASK 0x6080000U
+
+/** bits in IMMUTABLE mask:
+ * document omitted */
+#define OPTST_IMMUTABLE_MASK 0x0280000U
+
+/** bits in DO_NOT_SAVE mask:
+ * document omitted no_init */
+#define OPTST_DO_NOT_SAVE_MASK 0x0280100U
+
+/** bits in NO_OUTPUT mask:
+ * document omitted alias */
+#define OPTST_NO_OUTPUT_MASK 0x8280000U
+
+/** all bits in opt_state_mask_t masks */
+#define OPTST_MASK_ALL 0xFFFFF7FU
+
+/** no bits in opt_state_mask_t */
+#define OPTST_INIT 0x0000000U
+/** @} */
+
+#ifdef NO_OPTIONAL_OPT_ARGS
+# undef OPTST_ARG_OPTIONAL
+# define OPTST_ARG_OPTIONAL 0
+#endif
+
+#define VENDOR_OPTION_VALUE 'W'
+
+#define SELECTED_OPT(_od) ((_od)->fOptState & OPTST_SELECTED_MASK)
+#define UNUSED_OPT( _od) (((_od)->fOptState & OPTST_SET_MASK) == 0)
+#define DISABLED_OPT(_od) ((_od)->fOptState & OPTST_DISABLED)
+#define OPTION_STATE(_od) ((_od)->fOptState)
+#define OPTST_SET_ARGTYPE(_n) ((_n) << OPTST_ARG_TYPE_SHIFT)
+#define OPTST_GET_ARGTYPE(_f) \
+ (((_f)&OPTST_ARG_TYPE_MASK) >> OPTST_ARG_TYPE_SHIFT)
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * PRIVATE INTERFACES
+ *
+ * The following values are used in the generated code to communicate
+ * with the option library procedures. They are not for public use
+ * and may be subject to change.
+ */
+
+/**
+ * Define the processing state flags
+ * @{
+ */
+
+/** integral type for holding proc_state masks */
+typedef uint32_t proc_state_mask_t;
+
+/** bits defined for proc_state_mask_t */
+/** Process long style options */
+#define OPTPROC_LONGOPT 0x000001U
+/** Process short style "flags" */
+#define OPTPROC_SHORTOPT 0x000002U
+/** Stop on argument errors */
+#define OPTPROC_ERRSTOP 0x000004U
+/** Current option is disabled */
+#define OPTPROC_DISABLEDOPT 0x000008U
+/** no options are required */
+#define OPTPROC_NO_REQ_OPT 0x000010U
+/** there is a number option */
+#define OPTPROC_NUM_OPT 0x000020U
+/** have inits been done? */
+#define OPTPROC_INITDONE 0x000040U
+/** any negation options? */
+#define OPTPROC_NEGATIONS 0x000080U
+/** check environment? */
+#define OPTPROC_ENVIRON 0x000100U
+/** Disallow remaining arguments */
+#define OPTPROC_NO_ARGS 0x000200U
+/** Require args after options */
+#define OPTPROC_ARGS_REQ 0x000400U
+/** reorder operands after opts */
+#define OPTPROC_REORDER 0x000800U
+/** emit usage in GNU style */
+#define OPTPROC_GNUUSAGE 0x001000U
+/** Translate strings in tOptions */
+#define OPTPROC_TRANSLATE 0x002000U
+/** no usage on usage error */
+#define OPTPROC_MISUSE 0x004000U
+/** immediate options active */
+#define OPTPROC_IMMEDIATE 0x008000U
+/** suppress for config only */
+#define OPTPROC_NXLAT_OPT_CFG 0x010000U
+/** suppress xlation always */
+#define OPTPROC_NXLAT_OPT 0x020000U
+/** vendor options active */
+#define OPTPROC_VENDOR_OPT 0x040000U
+/** opt processing in preset state */
+#define OPTPROC_PRESETTING 0x080000U
+/** Ignore pzFullUsage, compute usage text */
+#define OPTPROC_COMPUTE 0x100000U
+/** Program outputs digested option state for shell scripts. Usage text
+ * always written to stderr */
+#define OPTPROC_SHELL_OUTPUT 0x200000U
+
+/** bits in NO_XLAT mask:
+ * nxlat_opt_cfg nxlat_opt */
+#define OPTPROC_NO_XLAT_MASK 0x030000U
+
+/** all bits in proc_state_mask_t masks */
+#define OPTPROC_MASK_ALL 0x3FFFFFU
+
+/** no bits in proc_state_mask_t */
+#define OPTPROC_NONE 0x000000U
+/** @} */
+
+#define STMTS(s) do { s; } while (false)
+
+/**
+ * Abbreviation for const memory character.
+ */
+#define tCC char const
+
+/**
+ * Magical values for the program's option pointer
+ * @{
+ */
+typedef enum {
+ OP_VAL_EMIT_USAGE = 1, ///< request for usage
+ OP_VAL_EMIT_SHELL = 2, ///< emit value for Bourne shell evaluation
+ OP_VAL_RETURN_VALNAME = 3, ///< return the value as a string
+ OP_VAL_EMIT_LIMIT = 15 ///< limit for magic values
+} opt_proc_vals_t;
+
+/// \a OPT_VAL_EMIT_USAGE cast as a pointer
+#define OPTPROC_EMIT_USAGE ((tOptions *)OP_VAL_EMIT_USAGE)
+
+/// \a OPT_VAL_EMIT_SHELL cast as a pointer
+#define OPTPROC_EMIT_SHELL ((tOptions *)OP_VAL_EMIT_SHELL)
+
+/// \a OPT_VAL_RETURN_VALNAME cast as a pointer
+#define OPTPROC_RETURN_VALNAME ((tOptions *)OP_VAL_RETURN_VALNAME)
+
+/// \a OPT_VAL_EMIT_LIMIT cast as a pointer
+#define OPTPROC_EMIT_LIMIT ((tOptions *)OP_VAL_EMIT_LIMIT)
+/** @} */
+
+/** group option processing procedure types
+ * @{
+ */
+/** forward declaration for tOptDesc */
+typedef struct opt_desc tOptDesc;
+/** forward declaration for tOptiond */
+typedef struct options tOptions;
+
+/**
+ * The option procedures do the special processing for each
+ * option flag that needs it.
+ */
+typedef void (tOptProc)(tOptions * pOpts, tOptDesc * pOptDesc);
+
+/**
+ * a pointer to an option processing procedure
+ */
+typedef tOptProc * tpOptProc;
+
+/**
+ * The usage procedure will never return. It calls "exit(2)"
+ * with the "exitCode" argument passed to it.
+ */
+// coverity[+kill]
+typedef void (tUsageProc)(tOptions * pOpts, int exitCode);
+
+/**
+ * a pointer to a procedure that prints usage and exits.
+ */
+typedef tUsageProc * tpUsageProc;
+/** @} */
+
+/**
+ * Special definitions. "NOLIMIT" is the 'max' value to use when
+ * a flag may appear multiple times without limit. "NO_EQUIVALENT"
+ * is an illegal value for 'optIndex' (option description index).
+ * @{
+ */
+#define NOLIMIT USHRT_MAX ///< no occurrance count limit
+#define OPTION_LIMIT SHRT_MAX ///< maximum number of option types
+/// option index to indicate no equivalance or alias
+#define NO_EQUIVALENT (OPTION_LIMIT+1)
+/** @} */
+
+/**
+ * Option argument value. Which is valid is determined by:
+ * (fOptState & OPTST_ARG_TYPE_MASK) >> OPTST_ARG_TYPE_SHIFT
+ * which will yield one of the teOptArgType values.
+ */
+typedef union {
+ char const * argString; ///< as a string
+ uintptr_t argEnum; ///< as an enumeration value
+ uintptr_t argIntptr; ///< as an integer big enough to hold pointer
+ long argInt; ///< as a long integer
+ unsigned long argUint; ///< as an unsigned long ingeger
+ unsigned int argBool; ///< as a boolean value
+ FILE * argFp; ///< as a FILE * pointer
+ int argFd; ///< as a file descriptor (int)
+} opt_arg_union_t;
+
+/// Compatibility define: \a pzLastArg is now \a optArg.argString
+#define pzLastArg optArg.argString
+/// The old amorphous argument bucket is now the opt_arg_union_t union.
+#define optArgBucket_t opt_arg_union_t
+
+/**
+ * Enumeration of AutoOpts defined options. The enumeration is used in
+ * marking each option that is defined by AutoOpts so libopts can find
+ * the correct descriptor. This renders \a option_spec_idx_t redundant.
+ */
+typedef enum {
+ AOUSE_USER_DEFINED = 0, ///< user specified option
+ AOUSE_RESET_OPTION, ///< reset option state option
+ AOUSE_VERSION, ///< request version
+ AOUSE_HELP, ///< request usage help
+ AOUSE_MORE_HELP, ///< request paged usage
+ AOUSE_USAGE, ///< request short usage
+ AOUSE_SAVE_OPTS, ///< save option state
+ AOUSE_LOAD_OPTS, ///< load options from file
+ AOUSE_VENDOR_OPT ///< specify a vendor option
+} opt_usage_t;
+
+/**
+ * Descriptor structure for each option.
+ * Only the fields marked "PUBLIC" are for public use.
+ */
+struct opt_desc {
+ /// Public, the index of this descriptor
+ uint16_t const optIndex;
+ /// Public, the flag character (value)
+ uint16_t const optValue;
+ /// Public, the index of the option used to activate option
+ uint16_t optActualIndex;
+ /// Public, the flag character of the activating option
+ uint16_t optActualValue;
+
+ /// Public, the index of the equivalenced-to option.
+ /// This is NO_EQUIVALENT unless activated.
+ uint16_t const optEquivIndex;
+ /// Private, the minimum occurrance count
+ uint16_t const optMinCt;
+ /// Private, the maximum occurrance count (NOLIMIT, if unlimited)
+ uint16_t const optMaxCt;
+ /// Public, the actual occurrance count
+ uint16_t optOccCt;
+
+ /// Public, the option processing state
+ opt_state_mask_t fOptState;
+ /// Private, how the option is used (opt_usage_t)
+ uint32_t optUsage;
+ /// Public, The current option argument value
+ opt_arg_union_t optArg;
+ /// Public, data that is actually private to the code that handles
+ /// this particular option. It is public IFF you have your own
+ /// handling function.
+ void * optCookie;
+
+ /// Private, a list of options that must be specified when this option
+ /// has been specified
+ int const * const pOptMust;
+
+ /// Private, a list of options that cannot be specified when this option
+ /// has been specified
+ int const * const pOptCant;
+
+ /// Private, the function to call for handling this option
+ tpOptProc const pOptProc;
+
+ /// Private, usage information about this option
+ char const * const pzText;
+
+ /// Public, the UPPER CASE, shell variable name syntax name of the option
+ char const * const pz_NAME;
+
+ /// the unmodified name of the option
+ char const * const pz_Name;
+
+ /// the option name to use to disable the option. Long options names
+ /// must be active.
+ char const * const pz_DisableName;
+
+ /// the special prefix that makes the normal option name become the
+ /// disablement name.
+ char const * const pz_DisablePfx;
+};
+
+/**
+ * Some options need special processing, so we store their
+ * indexes in a known place.
+ */
+typedef struct {
+ uint16_t const more_help; ///< passes help text through pager
+ uint16_t const save_opts; ///< stores option state to a file
+ uint16_t const number_option; ///< the option "name" is an integer
+ /// all arguments are options, this is the default option that must
+ /// take an argument. That argument is the unrecognized option.
+ uint16_t const default_opt;
+} option_spec_idx_t;
+
+/**
+ * The procedure generated for translating option text
+ */
+typedef void (tOptionXlateProc)(void);
+
+/**
+ * Everything marked "PUBLIC" is also marked "const". Public access is not
+ * a license to modify. Other fields are used and modified by the library.
+ * They are also subject to change without any notice.
+ * Do not even look at these outside of libopts.
+ */
+struct options {
+ int const structVersion; ///< The version of this struct
+ unsigned int origArgCt; ///< program argument count
+ char ** origArgVect; ///< program argument vector
+ proc_state_mask_t fOptSet; ///< option proc. state flags
+ unsigned int curOptIdx; ///< current option index
+ char * pzCurOpt; ///< current option text
+
+ /// Public, the full path of the program
+ char const * const pzProgPath;
+ /// Public, the name of the executable, without any path
+ char const * const pzProgName;
+ /// Public, the upper-cased, shell variable syntax-ed program name
+ char const * const pzPROGNAME;
+ /// the name of the "rc file" (configuration file)
+ char const * const pzRcName;
+ /// the copyright text
+ char const * const pzCopyright;
+ /// the full copyright notice
+ char const * const pzCopyNotice;
+ /// a string with the program name, project name and version
+ char const * const pzFullVersion;
+ /// a list of pointers to directories to search for the config file
+ char const * const * const papzHomeList;
+ /// the title line for usage
+ char const * const pzUsageTitle;
+ /// some added explanation for what this program is trying to do
+ char const * const pzExplain;
+ /// a detailed explanation of the program's purpose, for use when
+ /// full help has been requested
+ char const * const pzDetail;
+ /// The public array of option descriptors
+ tOptDesc * const pOptDesc;
+ /// the email address for reporting bugs
+ char const * const pzBugAddr;
+
+ /// Reserved for future use
+ void * pExtensions;
+ /// A copy of the option state when optionSaveState was called.
+ void * pSavedState;
+
+ /// The procedure to call to print usage text
+ // coverity[+kill]
+ tpUsageProc pUsageProc;
+ /// The procedure to call to translate translatable option messages
+ tOptionXlateProc * pTransProc;
+
+ /// Special option indexes.
+ option_spec_idx_t specOptIdx;
+ /// the total number of options for the program
+ int const optCt;
+ /// The number of "presettable" options, though some may be marked
+ /// "no-preset". Includes all user specified options, plus a few
+ /// that are specified by AutoOpts.
+ int const presetOptCt;
+ /// user specified full usage text
+ char const * pzFullUsage;
+ /// user specifed short usage (usage error triggered) message
+ char const * pzShortUsage;
+ /// The option argument settings active when optionSaveState was called
+ opt_arg_union_t const * const originalOptArgArray;
+ /// any saved cookie value
+ void * const * const originalOptArgCookie;
+ /// the package data directory (e.g. global configuration files)
+ char const * const pzPkgDataDir;
+ /// email address of the project packager
+ char const * const pzPackager;
+};
+
+/*
+ * Versions where in various fields first appear:
+ * ($AO_CURRENT * 4096 + $AO_REVISION, but $AO_REVISION must be zero)
+ */
+/**
+ * The version that first stored the original argument vector
+ */
+#define originalOptArgArray_STRUCT_VERSION 0x20000 /* AO_CURRENT = 32 */
+#define HAS_originalOptArgArray(_opt) \
+ ((_opt)->structVersion >= originalOptArgArray_STRUCT_VERSION)
+
+/**
+ * The version that first stored the package data directory
+ */
+#define pzPkgDataDir_STRUCT_VERSION 0x22000 /* AO_CURRENT = 34 */
+#define HAS_pzPkgDataDir(_opt) \
+ ((_opt)->structVersion >= pzPkgDataDir_STRUCT_VERSION)
+
+/**
+ * The version that first stored the option usage in each option descriptor
+ */
+#define opt_usage_t_STRUCT_VERSION 0x26000 /* AO_CURRENT = 38 */
+#define HAS_opt_usage_t(_opt) \
+ ((_opt)->structVersion >= opt_usage_t_STRUCT_VERSION)
+
+/**
+ * "token list" structure returned by "string_tokenize()"
+ */
+typedef struct {
+ unsigned long tkn_ct; ///< number of tokens found
+ unsigned char * tkn_list[1]; ///< array of pointers to tokens
+} token_list_t;
+
+/*
+ * Hide the interface - it pollutes a POSIX claim, but leave it for
+ * anyone #include-ing this header
+ */
+#define strneqvcmp option_strneqvcmp
+#define streqvcmp option_streqvcmp
+#define streqvmap option_streqvmap
+#define strequate option_strequate
+#define strtransform option_strtransform
+
+/**
+ * Everything needed to be known about an mmap-ed file.
+ *
+ * This is an output only structure used by text_mmap and text_munmap.
+ * Clients must not alter the contents and must provide it to both
+ * the text_mmap and text_munmap procedures. BE ADVISED: if you are
+ * mapping the file with PROT_WRITE the NUL byte at the end MIGHT NOT
+ * BE WRITABLE. In any event, that byte is not be written back
+ * to the source file. ALSO: if "txt_data" is valid and "txt_errno"
+ * is not zero, then there *may* not be a terminating NUL.
+ */
+typedef struct {
+ void * txt_data; ///< text file data
+ size_t txt_size; ///< actual file size
+ size_t txt_full_size; ///< mmaped mem size
+ int txt_fd; ///< file descriptor
+ int txt_zero_fd; ///< fd for /dev/zero
+ int txt_errno; ///< warning code
+ int txt_prot; ///< "prot" flags
+ int txt_flags; ///< mapping type
+} tmap_info_t;
+
+/**
+ * mmap result wrapper that yields "true" when mmap has failed.
+ */
+#define TEXT_MMAP_FAILED_ADDR(a) (VOIDP(a) == VOIDP(MAP_FAILED))
+
+#ifdef __cplusplus
+#define CPLUSPLUS_OPENER extern "C" {
+CPLUSPLUS_OPENER
+#define CPLUSPLUS_CLOSER }
+#else
+#define CPLUSPLUS_CLOSER
+#endif
+
+/**
+ * The following routines may be coded into AutoOpts client code:
+ */
+
+/**
+ * ao_string_tokenize - tokenize an input string
+ *
+ * This function will convert one input string into a list of strings.
+ * The list of strings is derived by separating the input based on
+ * white space separation. However, if the input contains either single
+ * or double quote characters, then the text after that character up to
+ * a matching quote will become the string in the list.
+ *
+ * The returned pointer should be deallocated with @code{free(3C)} when
+ * are done using the data. The data are placed in a single block of
+ * allocated memory. Do not deallocate individual token/strings.
+ *
+ * The structure pointed to will contain at least these two fields:
+ * @table @samp
+ * @item tkn_ct
+ * The number of tokens found in the input string.
+ * @item tok_list
+ * An array of @code{tkn_ct + 1} pointers to substring tokens, with
+ * the last pointer set to NULL.
+ * @end table
+ *
+ * There are two types of quoted strings: single quoted (@code{'}) and
+ * double quoted (@code{"}). Singly quoted strings are fairly raw in that
+ * escape characters (@code{\\}) are simply another character, except when
+ * preceding the following characters:
+ * @example
+ * @code{\\} double backslashes reduce to one
+ * @code{'} incorporates the single quote into the string
+ * @code{\n} suppresses both the backslash and newline character
+ * @end example
+ *
+ * Double quote strings are formed according to the rules of string
+ * constants in ANSI-C programs.
+ *
+ * @param string string to be tokenized
+ *
+ * @return token_list_t * - pointer to a structure that lists each token
+ */
+extern token_list_t * ao_string_tokenize(char const *);
+
+
+/**
+ * configFileLoad - parse a configuration file
+ *
+ * This routine will load a named configuration file and parse the
+ * text as a hierarchically valued option. The option descriptor
+ * created from an option definition file is not used via this interface.
+ * The returned value is "named" with the input file name and is of
+ * type "@code{OPARG_TYPE_HIERARCHY}". It may be used in calls to
+ * @code{optionGetValue()}, @code{optionNextValue()} and
+ * @code{optionUnloadNested()}.
+ *
+ * @param fname the file to load
+ *
+ * @return const tOptionValue * - An allocated, compound value structure
+ */
+extern const tOptionValue * configFileLoad(char const *);
+
+
+/**
+ * optionFileLoad - Load the locatable config files, in order
+ *
+ * This function looks in all the specified directories for a configuration
+ * file ("rc" file or "ini" file) and processes any found twice. The first
+ * time through, they are processed in reverse order (last file first). At
+ * that time, only "immediate action" configurables are processed. For
+ * example, if the last named file specifies not processing any more
+ * configuration files, then no more configuration files will be processed.
+ * Such an option in the @strong{first} named directory will have no effect.
+ *
+ * Once the immediate action configurables have been handled, then the
+ * directories are handled in normal, forward order. In that way, later
+ * config files can override the settings of earlier config files.
+ *
+ * See the AutoOpts documentation for a thorough discussion of the
+ * config file format.
+ *
+ * Configuration files not found or not decipherable are simply ignored.
+ *
+ * @param opts program options descriptor
+ * @param prog program name
+ *
+ * @return int - 0 -> SUCCESS, -1 -> FAILURE
+ */
+extern int optionFileLoad(tOptions *, char const *);
+
+
+/**
+ * optionFindNextValue - find a hierarcicaly valued option instance
+ *
+ * This routine will find the next entry in a nested value option or
+ * configurable. It will search through the list and return the next entry
+ * that matches the criteria.
+ *
+ * @param odesc an option with a nested arg type
+ * @param pPrevVal the last entry
+ * @param name name of value to find
+ * @param value the matching value
+ *
+ * @return const tOptionValue * - a compound value structure
+ */
+extern const tOptionValue * optionFindNextValue(const tOptDesc *, const tOptionValue *, char const *, char const *);
+
+
+/**
+ * optionFindValue - find a hierarcicaly valued option instance
+ *
+ * This routine will find an entry in a nested value option or configurable.
+ * It will search through the list and return a matching entry.
+ *
+ * @param odesc an option with a nested arg type
+ * @param name name of value to find
+ * @param val the matching value
+ *
+ * @return const tOptionValue * - a compound value structure
+ */
+extern const tOptionValue * optionFindValue(const tOptDesc *, char const *, char const *);
+
+
+/**
+ * optionFree - free allocated option processing memory
+ *
+ * AutoOpts sometimes allocates memory and puts pointers to it in the
+ * option state structures. This routine deallocates all such memory.
+ *
+ * @param pOpts program options descriptor
+ */
+extern void optionFree(tOptions *);
+
+
+/**
+ * optionGetValue - get a specific value from a hierarcical list
+ *
+ * This routine will find an entry in a nested value option or configurable.
+ * If "valueName" is NULL, then the first entry is returned. Otherwise,
+ * the first entry with a name that exactly matches the argument will be
+ * returned. If there is no matching value, NULL is returned and errno is
+ * set to ENOENT. If the provided option value is not a hierarchical value,
+ * NULL is also returned and errno is set to EINVAL.
+ *
+ * @param pOptValue a hierarchcal value
+ * @param valueName name of value to get
+ *
+ * @return const tOptionValue * - a compound value structure
+ */
+extern const tOptionValue * optionGetValue(const tOptionValue *, char const *);
+
+
+/**
+ * optionLoadLine - process a string for an option name and value
+ *
+ * This is a client program callable routine for setting options from, for
+ * example, the contents of a file that they read in. Only one option may
+ * appear in the text. It will be treated as a normal (non-preset) option.
+ *
+ * When passed a pointer to the option struct and a string, it will find
+ * the option named by the first token on the string and set the option
+ * argument to the remainder of the string. The caller must NUL terminate
+ * the string. The caller need not skip over any introductory hyphens.
+ * Any embedded new lines will be included in the option
+ * argument. If the input looks like one or more quoted strings, then the
+ * input will be "cooked". The "cooking" is identical to the string
+ * formation used in AutoGen definition files (@pxref{basic expression}),
+ * except that you may not use backquotes.
+ *
+ * @param opts program options descriptor
+ * @param line NUL-terminated text
+ */
+extern void optionLoadLine(tOptions *, char const *);
+
+
+/**
+ * optionMemberList - Get the list of members of a bit mask set
+ *
+ * This converts the OPT_VALUE_name mask value to a allocated string.
+ * It is the caller's responsibility to free the string.
+ *
+ * @param od the set membership option description
+ *
+ * @return char * - the names of the set bits
+ */
+extern char * optionMemberList(tOptDesc *);
+
+
+/**
+ * optionNextValue - get the next value from a hierarchical list
+ *
+ * This routine will return the next entry after the entry passed in. At the
+ * end of the list, NULL will be returned. If the entry is not found on the
+ * list, NULL will be returned and "@var{errno}" will be set to EINVAL.
+ * The "@var{pOldValue}" must have been gotten from a prior call to this
+ * routine or to "@code{opitonGetValue()}".
+ *
+ * @param pOptValue a hierarchcal list value
+ * @param pOldValue a value from this list
+ *
+ * @return const tOptionValue * - a compound value structure
+ */
+extern const tOptionValue * optionNextValue(const tOptionValue *, const tOptionValue *);
+
+
+/**
+ * optionOnlyUsage - Print usage text for just the options
+ *
+ * This routine will print only the usage for each option.
+ * This function may be used when the emitted usage must incorporate
+ * information not available to AutoOpts.
+ *
+ * @param pOpts program options descriptor
+ * @param ex_code exit code for calling exit(3)
+ */
+extern void optionOnlyUsage(tOptions *, int);
+
+
+/**
+ * optionPrintVersion - Print the program version
+ *
+ * This routine will print the version to stdout.
+ *
+ * @param opts program options descriptor
+ * @param od the descriptor for this arg
+ */
+extern void optionPrintVersion(tOptions *, tOptDesc *);
+
+
+/**
+ * optionPrintVersionAndReturn - Print the program version
+ *
+ * This routine will print the version to stdout and return
+ * instead of exiting. Please see the source for the
+ * @code{print_ver} funtion for details on selecting how
+ * verbose to be after this function returns.
+ *
+ * @param opts program options descriptor
+ * @param od the descriptor for this arg
+ */
+extern void optionPrintVersionAndReturn(tOptions *, tOptDesc *);
+
+
+/**
+ * optionProcess - this is the main option processing routine
+ *
+ * This is the main entry point for processing options. It is intended
+ * that this procedure be called once at the beginning of the execution of
+ * a program. Depending on options selected earlier, it is sometimes
+ * necessary to stop and restart option processing, or to select completely
+ * different sets of options. This can be done easily, but you generally
+ * do not want to do this.
+ *
+ * The number of arguments processed always includes the program name.
+ * If one of the arguments is "--", then it is counted and the processing
+ * stops. If an error was encountered and errors are to be tolerated, then
+ * the returned value is the index of the argument causing the error.
+ * A hyphen by itself ("-") will also cause processing to stop and will
+ * @emph{not} be counted among the processed arguments. A hyphen by itself
+ * is treated as an operand. Encountering an operand stops option
+ * processing.
+ *
+ * @param opts program options descriptor
+ * @param a_ct program arg count
+ * @param a_v program arg vector
+ *
+ * @return int - the count of the arguments processed
+ */
+extern int optionProcess(tOptions *, int, char **);
+
+
+/**
+ * optionRestore - restore option state from memory copy
+ *
+ * Copy back the option state from saved memory.
+ * The allocated memory is left intact, so this routine can be
+ * called repeatedly without having to call optionSaveState again.
+ * If you are restoring a state that was saved before the first call
+ * to optionProcess(3AO), then you may change the contents of the
+ * argc/argv parameters to optionProcess.
+ *
+ * @param pOpts program options descriptor
+ */
+extern void optionRestore(tOptions *);
+
+
+/**
+ * optionSaveFile - saves the option state to a file
+ *
+ * This routine will save the state of option processing to a file. The name
+ * of that file can be specified with the argument to the @code{--save-opts}
+ * option, or by appending the @code{rcfile} attribute to the last
+ * @code{homerc} attribute. If no @code{rcfile} attribute was specified, it
+ * will default to @code{.@i{programname}rc}. If you wish to specify another
+ * file, you should invoke the @code{SET_OPT_SAVE_OPTS(@i{filename})} macro.
+ *
+ * The recommend usage is as follows:
+ * @example
+ * optionProcess(&progOptions, argc, argv);
+ * if (i_want_a_non_standard_place_for_this)
+ * SET_OPT_SAVE_OPTS("myfilename");
+ * optionSaveFile(&progOptions);
+ * @end example
+ *
+ * @param opts program options descriptor
+ */
+extern void optionSaveFile(tOptions *);
+
+
+/**
+ * optionSaveState - saves the option state to memory
+ *
+ * This routine will allocate enough memory to save the current option
+ * processing state. If this routine has been called before, that memory
+ * will be reused. You may only save one copy of the option state. This
+ * routine may be called before optionProcess(3AO). If you do call it
+ * before the first call to optionProcess, then you may also change the
+ * contents of argc/argv after you call optionRestore(3AO)
+ *
+ * In fact, more strongly put: it is safest to only use this function
+ * before having processed any options. In particular, the saving and
+ * restoring of stacked string arguments and hierarchical values is
+ * disabled. The values are not saved.
+ *
+ * @param pOpts program options descriptor
+ */
+extern void optionSaveState(tOptions *);
+
+
+/**
+ * optionUnloadNested - Deallocate the memory for a nested value
+ *
+ * A nested value needs to be deallocated. The pointer passed in should
+ * have been gotten from a call to @code{configFileLoad()} (See
+ * @pxref{libopts-configFileLoad}).
+ *
+ * @param pOptVal the hierarchical value
+ */
+extern void optionUnloadNested(tOptionValue const *);
+
+
+/**
+ * optionVersion - return the compiled AutoOpts version number
+ *
+ * Returns the full version string compiled into the library.
+ * The returned string cannot be modified.
+ *
+ * @return char const * - the version string in constant memory
+ */
+extern char const * optionVersion(void);
+
+
+/**
+ * strequate - map a list of characters to the same value
+ *
+ * Each character in the input string get mapped to the first character
+ * in the string.
+ * This function name is mapped to option_strequate so as to not conflict
+ * with the POSIX name space.
+ *
+ * @param ch_list characters to equivalence
+ */
+extern void strequate(char const *);
+
+
+/**
+ * streqvcmp - compare two strings with an equivalence mapping
+ *
+ * Using a character mapping, two strings are compared for "equivalence".
+ * Each input character is mapped to a comparison character and the
+ * mapped-to characters are compared for the two NUL terminated input strings.
+ * This function name is mapped to option_streqvcmp so as to not conflict
+ * with the POSIX name space.
+ *
+ * @param str1 first string
+ * @param str2 second string
+ *
+ * @return int - the difference between two differing characters
+ */
+extern int streqvcmp(char const *, char const *);
+
+
+/**
+ * streqvmap - Set the character mappings for the streqv functions
+ *
+ * Set the character mapping. If the count (@code{ct}) is set to zero, then
+ * the map is cleared by setting all entries in the map to their index
+ * value. Otherwise, the "@code{From}" character is mapped to the "@code{To}"
+ * character. If @code{ct} is greater than 1, then @code{From} and @code{To}
+ * are incremented and the process repeated until @code{ct} entries have been
+ * set. For example,
+ * @example
+ * streqvmap('a', 'A', 26);
+ * @end example
+ * @noindent
+ * will alter the mapping so that all English lower case letters
+ * will map to upper case.
+ *
+ * This function name is mapped to option_streqvmap so as to not conflict
+ * with the POSIX name space.
+ *
+ * @param from Input character
+ * @param to Mapped-to character
+ * @param ct compare length
+ */
+extern void streqvmap(char, char, int);
+
+
+/**
+ * strneqvcmp - compare two strings with an equivalence mapping
+ *
+ * Using a character mapping, two strings are compared for "equivalence".
+ * Each input character is mapped to a comparison character and the
+ * mapped-to characters are compared for the two NUL terminated input strings.
+ * The comparison is limited to @code{ct} bytes.
+ * This function name is mapped to option_strneqvcmp so as to not conflict
+ * with the POSIX name space.
+ *
+ * @param str1 first string
+ * @param str2 second string
+ * @param ct compare length
+ *
+ * @return int - the difference between two differing characters
+ */
+extern int strneqvcmp(char const *, char const *, int);
+
+
+/**
+ * strtransform - convert a string into its mapped-to value
+ *
+ * Each character in the input string is mapped and the mapped-to
+ * character is put into the output.
+ * This function name is mapped to option_strtransform so as to not conflict
+ * with the POSIX name space.
+ *
+ * The source and destination may be the same.
+ *
+ * @param dest output string
+ * @param src input string
+ */
+extern void strtransform(char *, char const *);
+
+/* AutoOpts PRIVATE FUNCTIONS: */
+tOptProc optionStackArg, optionUnstackArg, optionBooleanVal, optionNumericVal;
+
+extern char * ao_string_cook(char *, int *);
+
+extern unsigned int ao_string_cook_escape_char(char const *, char *, unsigned int);
+
+extern void genshelloptUsage(tOptions *, int);
+
+extern int optionAlias(tOptions *, tOptDesc *, unsigned int);
+
+extern void optionBooleanVal(tOptions *, tOptDesc *);
+
+extern uintptr_t optionEnumerationVal(tOptions *, tOptDesc *, char const * const *, unsigned int);
+
+extern void optionFileCheck(tOptions *, tOptDesc *, teOptFileType, tuFileMode);
+
+extern char const * optionKeywordName(tOptDesc *, unsigned int);
+
+extern void optionLoadOpt(tOptions *, tOptDesc *);
+
+extern bool optionMakePath(char *, int, char const *, char const *);
+
+extern void optionNestedVal(tOptions *, tOptDesc *);
+
+extern void optionNumericVal(tOptions *, tOptDesc *);
+
+extern void optionPagedUsage(tOptions *, tOptDesc *);
+
+extern void optionParseShell(tOptions *);
+
+extern void optionPrintParagraphs(char const *, bool, FILE *);
+
+extern void optionPutShell(tOptions *);
+
+extern char const * optionQuoteString(char const *, char const *);
+
+extern void optionResetOpt(tOptions *, tOptDesc *);
+
+extern void optionSetMembers(tOptions *, tOptDesc *, char const * const *, unsigned int);
+
+extern void optionShowRange(tOptions *, tOptDesc *, void *, int);
+
+extern void optionStackArg(tOptions *, tOptDesc *);
+
+extern void optionTimeDate(tOptions *, tOptDesc *);
+
+extern void optionTimeVal(tOptions *, tOptDesc *);
+
+extern void optionUnstackArg(tOptions *, tOptDesc *);
+
+extern void optionUsage(tOptions *, int);
+
+extern void optionVendorOption(tOptions *, tOptDesc *);
+
+extern void optionVersionStderr(tOptions *, tOptDesc *);
+
+extern void * text_mmap(char const *, int, int, tmap_info_t *);
+
+extern int text_munmap(tmap_info_t *);
+
+CPLUSPLUS_CLOSER
+#endif /* AUTOOPTS_OPTIONS_H_GUARD */
+/** @}
+ *
+ * Local Variables:
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * options.h ends here */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/autoopts/project.h b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/autoopts/project.h
new file mode 100644
index 0000000..1e7f156
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/autoopts/project.h
@@ -0,0 +1,77 @@
+
+/**
+ * \file project.h
+ *
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
+ *
+ * AutoOpts is available under any one of two licenses. The license
+ * in use must be one of these two and the choice is under the control
+ * of the user of the license.
+ *
+ * The GNU Lesser General Public License, version 3 or later
+ * See the files "COPYING.lgplv3" and "COPYING.gplv3"
+ *
+ * The Modified Berkeley Software Distribution License
+ * See the file "COPYING.mbsd"
+ *
+ * These files have the following sha256 sums:
+ *
+ * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
+ * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
+ * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
+ */
+
+#ifndef AUTOGEN_PROJECT_H
+#define AUTOGEN_PROJECT_H
+
+#include "config.h"
+#include "compat/compat.h"
+#include "ag-char-map.h"
+
+/*
+ * Procedure success codes
+ *
+ * USAGE: define procedures to return "tSuccess". Test their results
+ * with the SUCCEEDED, FAILED and HADGLITCH macros.
+ *
+ * Microsoft sticks its nose into user space here, so for Windows' sake,
+ * make sure all of these are undefined.
+ */
+#undef SUCCESS
+#undef FAILURE
+#undef PROBLEM
+#undef SUCCEEDED
+#undef SUCCESSFUL
+#undef FAILED
+#undef HADGLITCH
+
+#define SUCCESS ((tSuccess) 0)
+#define FAILURE ((tSuccess)-1)
+#define PROBLEM ((tSuccess) 1)
+
+typedef int tSuccess;
+
+#define SUCCEEDED(p) ((p) == SUCCESS)
+#define SUCCESSFUL(p) SUCCEEDED(p)
+#define FAILED(p) ((p) < SUCCESS)
+#define HADGLITCH(p) ((p) > SUCCESS)
+
+#ifndef STR
+# define __STR(s) #s
+# define STR(s) __STR(s)
+#endif
+
+#ifdef DEFINING
+# define VALUE(s) = s
+# define MODE
+#else
+# define VALUE(s)
+# define MODE extern
+#endif
+
+#define parse_duration option_parse_duration
+
+#endif /* AUTOGEN_PROJECT_H */
+/* end of project.h */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/autoopts/usage-txt.h b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/autoopts/usage-txt.h
new file mode 100644
index 0000000..f5831e6
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/autoopts/usage-txt.h
@@ -0,0 +1,657 @@
+/* -*- buffer-read-only: t -*- vi: set ro:
+ *
+ * DO NOT EDIT THIS FILE (usage-txt.h)
+ *
+ * It has been AutoGen-ed
+ * From the definitions usage-txt.def
+ * and the template file usage-txt.tpl
+ *
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
+ *
+ * AutoOpts is available under any one of two licenses. The license
+ * in use must be one of these two and the choice is under the control
+ * of the user of the license.
+ *
+ * The GNU Lesser General Public License, version 3 or later
+ * See the files "COPYING.lgplv3" and "COPYING.gplv3"
+ *
+ * The Modified Berkeley Software Distribution License
+ * See the file "COPYING.mbsd"
+ *
+ * These files have the following sha256 sums:
+ *
+ * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
+ * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
+ * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
+ */
+/** @file usage-txt.h
+ *
+ * This file handles all the bookkeeping required for tracking all the little
+ * tiny strings used by the AutoOpts library. There are 108
+ * of them. This is not versioned because it is entirely internal to the
+ * library and accessed by client code only in a very well-controlled way:
+ * they may substitute translated strings using a procedure that steps through
+ * all the string pointers.
+ */
+#ifndef AUTOOPTS_USAGE_TXT_H_GUARD
+#define AUTOOPTS_USAGE_TXT_H_GUARD 1
+
+/*
+ * One structure to hold all the pointers to all the translatable strings.
+ */
+typedef struct {
+ int field_ct;
+ char * utpz_GnuBoolArg;
+ char * utpz_GnuKeyArg;
+ char * utpz_GnuNumArg;
+ char * utpz_GnuStrArg;
+ char const * apz_str[104];
+} usage_text_t;
+
+/*
+ * Declare the global structure with all the pointers to translatable
+ * strings and the text array containing untranslatable strings.
+ */
+extern usage_text_t option_xlateable_txt;
+extern char const option_lib_text[4285];
+
+#if defined(AUTOOPTS_INTERNAL)
+/*
+ * Provide a mapping from a short name to either the text directly
+ * (for untranslatable strings), or to pointers to the text, rendering
+ * them translatable.
+ */
+#define zalloc_fail (option_xlateable_txt.apz_str[ 0])
+#define zno_opt_arg (option_xlateable_txt.apz_str[ 1])
+#define ztoo_new (option_xlateable_txt.apz_str[ 2])
+#define zwrong_ver (option_xlateable_txt.apz_str[ 3])
+#define zrealloc_fail (option_xlateable_txt.apz_str[ 4])
+#define ztoo_old (option_xlateable_txt.apz_str[ 5])
+#define zao_ver_fmt (option_xlateable_txt.apz_str[ 6])
+#define zao_bug_msg (option_xlateable_txt.apz_str[ 7])
+#define zno_reset (option_xlateable_txt.apz_str[ 8])
+#define zmissing_help_msg (option_xlateable_txt.apz_str[ 9])
+#define zbad_data_msg (option_xlateable_txt.apz_str[ 10])
+#define zbad_arg_type_msg (option_xlateable_txt.apz_str[ 11])
+#define zbad_default_msg (option_xlateable_txt.apz_str[ 12])
+#define zbad_alias_id (option_xlateable_txt.apz_str[ 13])
+#define zambiguous_key (option_xlateable_txt.apz_str[ 14])
+#define zambig_list_msg (option_xlateable_txt.apz_str[ 15])
+#define zambig_opt_fmt (option_xlateable_txt.apz_str[ 16])
+#define zargs_must (option_xlateable_txt.apz_str[ 17])
+#define zat_most (option_xlateable_txt.apz_str[ 18])
+#define zfserr_fmt (option_xlateable_txt.apz_str[ 19])
+#define zinter_proc_pipe (option_xlateable_txt.apz_str[ 20])
+#define zBadVerArg (option_xlateable_txt.apz_str[ 21])
+#define zconflict_fmt (option_xlateable_txt.apz_str[ 22])
+#define zDisabledErr (option_xlateable_txt.apz_str[ 23])
+#define zequiv (option_xlateable_txt.apz_str[ 24])
+#define zGnuBoolArg (option_xlateable_txt.utpz_GnuBoolArg)
+#define zGnuKeyArg (option_xlateable_txt.utpz_GnuKeyArg)
+#define zGnuNumArg (option_xlateable_txt.utpz_GnuNumArg)
+#define zGnuStrArg (option_xlateable_txt.utpz_GnuStrArg)
+#define zIllOptChr (option_xlateable_txt.apz_str[ 25])
+#define zIllOptStr (option_xlateable_txt.apz_str[ 26])
+#define zIllVendOptStr (option_xlateable_txt.apz_str[ 27])
+#define zIntRange (option_xlateable_txt.apz_str[ 28])
+#define zbad_od (option_xlateable_txt.apz_str[ 29])
+#define zInvalOptName (option_xlateable_txt.apz_str[ 30])
+#define zMisArg (option_xlateable_txt.apz_str[ 31])
+#define zmultiway_bug (option_xlateable_txt.apz_str[ 32])
+#define zneed_one (option_xlateable_txt.apz_str[ 33])
+#define zNoArg (option_xlateable_txt.apz_str[ 34])
+#define zNoArgs (option_xlateable_txt.apz_str[ 35])
+#define zNoCreat (option_xlateable_txt.apz_str[ 36])
+#define zNoKey (option_xlateable_txt.apz_str[ 37])
+#define zreset_arg (option_xlateable_txt.apz_str[ 38])
+#define zNoStat (option_xlateable_txt.apz_str[ 39])
+#define zNoState (option_xlateable_txt.apz_str[ 40])
+#define zNotCmdOpt (option_xlateable_txt.apz_str[ 41])
+#define zNotDate (option_xlateable_txt.apz_str[ 42])
+#define zNotDef (option_xlateable_txt.apz_str[ 43])
+#define zNotDuration (option_xlateable_txt.apz_str[ 44])
+#define zneed_more (option_xlateable_txt.apz_str[ 45])
+#define zNotNumber (option_xlateable_txt.apz_str[ 46])
+#define znum_too_large (option_xlateable_txt.apz_str[ 47])
+#define zoffer_usage_fmt (option_xlateable_txt.apz_str[ 48])
+#define zonly_one (option_xlateable_txt.apz_str[ 49])
+#define zstdout_name (option_xlateable_txt.apz_str[ 50])
+#define zstderr_name (option_xlateable_txt.apz_str[ 51])
+#define zwriting (option_xlateable_txt.apz_str[ 52])
+#define zRangeErr (option_xlateable_txt.apz_str[ 53])
+#define zneed_fmt (option_xlateable_txt.apz_str[ 54])
+#define zsave_warn (option_xlateable_txt.apz_str[ 55])
+#define zalt_opt (option_xlateable_txt.apz_str[ 56])
+#define zAuto (option_xlateable_txt.apz_str[ 57])
+#define zDefaultOpt (option_xlateable_txt.apz_str[ 58])
+#define zDis (option_xlateable_txt.apz_str[ 59])
+#define zDisabledOpt (option_xlateable_txt.apz_str[ 60])
+#define zDisabledWhy (option_xlateable_txt.apz_str[ 61])
+#define zEnab (option_xlateable_txt.apz_str[ 62])
+#define ztoo_often_fmt (option_xlateable_txt.apz_str[ 63])
+#define zExamineFmt (option_xlateable_txt.apz_str[ 64])
+#define zFileCannotExist (option_xlateable_txt.apz_str[ 65])
+#define zFileMustExist (option_xlateable_txt.apz_str[ 66])
+#define zFlagOkay (option_xlateable_txt.apz_str[ 67])
+#define zGenshell (option_xlateable_txt.apz_str[ 68])
+#define zLowerBits (option_xlateable_txt.apz_str[ 69])
+#define zMembers (option_xlateable_txt.apz_str[ 70])
+#define zMust (option_xlateable_txt.apz_str[ 71])
+#define zNoFlags (option_xlateable_txt.apz_str[ 72])
+#define zNoLim (option_xlateable_txt.apz_str[ 73])
+#define zNoPreset (option_xlateable_txt.apz_str[ 74])
+#define zNoRq_NoShrtTtl (option_xlateable_txt.apz_str[ 75])
+#define zNoRq_ShrtTtl (option_xlateable_txt.apz_str[ 76])
+#define zNrmOptFmt (option_xlateable_txt.apz_str[ 77])
+#define zNumberOpt (option_xlateable_txt.apz_str[ 78])
+#define zOptsOnly (option_xlateable_txt.apz_str[ 79])
+#define zPathFmt (option_xlateable_txt.apz_str[ 80])
+#define zPlsSendBugs (option_xlateable_txt.apz_str[ 81])
+#define zPreset (option_xlateable_txt.apz_str[ 82])
+#define zPresetIntro (option_xlateable_txt.apz_str[ 83])
+#define zProhib (option_xlateable_txt.apz_str[ 84])
+#define zProhibOne (option_xlateable_txt.apz_str[ 85])
+#define zRange (option_xlateable_txt.apz_str[ 86])
+#define zRangeAbove (option_xlateable_txt.apz_str[ 87])
+#define zRangeExact (option_xlateable_txt.apz_str[ 88])
+#define zRangeLie (option_xlateable_txt.apz_str[ 89])
+#define zRangeOnly (option_xlateable_txt.apz_str[ 90])
+#define zRangeOr (option_xlateable_txt.apz_str[ 91])
+#define zRangeScaled (option_xlateable_txt.apz_str[ 92])
+#define zRangeUpto (option_xlateable_txt.apz_str[ 93])
+#define zReorder (option_xlateable_txt.apz_str[ 94])
+#define zReqOne (option_xlateable_txt.apz_str[ 95])
+#define zReqThese (option_xlateable_txt.apz_str[ 96])
+#define zReq_NoShrtTtl (option_xlateable_txt.apz_str[ 97])
+#define zReq_ShrtTtl (option_xlateable_txt.apz_str[ 98])
+#define zSetMemberSettings (option_xlateable_txt.apz_str[ 99])
+#define zUpTo (option_xlateable_txt.apz_str[100])
+#define zValidKeys (option_xlateable_txt.apz_str[101])
+#define zVendIntro (option_xlateable_txt.apz_str[102])
+#define zVendOptsAre (option_xlateable_txt.apz_str[103])
+
+ /*
+ * First, set up the strings. Some of these are writable. These are all in
+ * English. This gets compiled into libopts and is distributed here so that
+ * xgettext (or equivalents) can extract these strings for translation.
+ */
+static char eng_zGnuBoolArg[] = "=T/F";
+static char eng_zGnuKeyArg[] = "=KWd";
+static char eng_zGnuNumArg[] = "=num";
+static char eng_zGnuStrArg[] = "=str";
+char const option_lib_text[4285] =
+/* 0 */ "allocation of %d bytes failed\n\0"
+/* 31 */ "AutoOpts function called without option descriptor\n\0"
+/* 83 */ "\tThis exceeds the compiled library version: \0"
+/* 129 */ "Automated Options Processing Error!\n"
+ "\t%s called AutoOpts function with structure version %d:%d:%d.\n\0"
+/* 228 */ "realloc of %d bytes at 0x%p failed\n\0"
+/* 264 */ "\tThis is less than the minimum library version: \0"
+/* 314 */ "Automated Options version %s\n"
+ "\tCopyright (C) 1999-2014 by Bruce Korb - all rights reserved\n\0"
+/* 405 */ "(AutoOpts bug): %s.\n\0"
+/* 427 */ "optionResetOpt() called, but reset-option not configured\0"
+/* 484 */ "could not locate the 'help' option\0"
+/* 519 */ "optionProcess() was called with invalid data\0"
+/* 564 */ "invalid argument type specified\0"
+/* 596 */ "defaulted to option with optional arg\0"
+/* 634 */ "aliasing option is out of range.\0"
+/* 667 */ "%s error: the keyword '%s' is ambiguous for %s\n\0"
+/* 716 */ " The following options match:\n\0"
+/* 748 */ "%s: ambiguous option name: %s (matches %d options)\n\0"
+/* 800 */ "%s: Command line arguments required\n\0"
+/* 837 */ "%d %s%s options allowed\n\0"
+/* 862 */ "%s error %d (%s) calling %s for '%s'\n\0"
+/* 900 */ "interprocess pipe\0"
+/* 918 */ "error: version option argument '%c' invalid. Use:\n"
+ "\t'v' - version only\n"
+ "\t'c' - version and copyright\n"
+ "\t'n' - version and full copyright notice\n\0"
+/* 1060 */ "%s error: the '%s' and '%s' options conflict\n\0"
+/* 1107 */ "%s: The '%s' option has been disabled.\0"
+/* 1146 */ "-equivalence\0"
+/* 1159 */ "%s: illegal option -- %c\n\0"
+/* 1185 */ "%s: illegal option -- %s\n\0"
+/* 1211 */ "%s: unknown vendor extension option -- %s\n\0"
+/* 1254 */ " or an integer from %d through %d\n\0"
+/* 1290 */ "%s error: invalid option descriptor for %s\n\0"
+/* 1335 */ "%s: invalid option name: %s\n\0"
+/* 1364 */ "%s: The '%s' option requires an argument.\n\0"
+/* 1407 */ "(AutoOpts bug): Equivalenced option '%s' was equivalenced to both\n"
+ "\t'%s' and '%s'.\0"
+/* 1490 */ "%s error: The %s option is required\n\0"
+/* 1528 */ "%s: The '%s' option cannot have an argument.\n\0"
+/* 1574 */ "%s: Command line arguments are not allowed.\n\0"
+/* 1619 */ "error %d (%s) creating %s\n\0"
+/* 1646 */ "%s error: '%s' does not match any %s keywords.\n\0"
+/* 1695 */ "%s error: The '%s' option requires an argument.\n\0"
+/* 1744 */ "error %d (%s) stat-ing %s\n\0"
+/* 1771 */ "%s error: no saved option state\n\0"
+/* 1804 */ "'%s' is not a command line option.\n\0"
+/* 1840 */ "%s error: '%s' is not a recognizable date/time.\n\0"
+/* 1890 */ "'%s' not defined\n\0"
+/* 1908 */ "%s error: '%s' is not a recognizable time duration.\n\0"
+/* 1962 */ "%s error: The %s option must appear %d times.\n\0"
+/* 2010 */ "%s error: '%s' is not a recognizable number.\n\0"
+/* 2057 */ "%s error: %s exceeds %s keyword count\n\0"
+/* 2097 */ "Try '%s %s' for more information.\n\0"
+/* 2132 */ "one %s%s option allowed\n\0"
+/* 2157 */ "standard output\0"
+/* 2173 */ "standard error\0"
+/* 2188 */ "write\0"
+/* 2194 */ "%s error: %s option value %ld is out of range.\n\0"
+/* 2243 */ "%s error: %s option requires the %s option\n\0"
+/* 2288 */ "%s warning: cannot save options - %s not regular file\n\0"
+/* 2344 */ "\t\t\t\t- an alternate for '%s'\n\0"
+/* 2373 */ "Version, usage and configuration options:\0"
+/* 2415 */ "\t\t\t\t- default option for unnamed options\n\0"
+/* 2457 */ "\t\t\t\t- disabled as '--%s'\n\0"
+/* 2483 */ " --- %-14s %s\n\0"
+/* 2498 */ "This option has been disabled\0"
+/* 2528 */ "\t\t\t\t- enabled by default\n\0"
+/* 2554 */ "%s error: only \0"
+/* 2571 */ " - examining environment variables named %s_*\n\0"
+/* 2618 */ "\t\t\t\t- file must not pre-exist\n\0"
+/* 2649 */ "\t\t\t\t- file must pre-exist\n\0"
+/* 2676 */ "Options are specified by doubled hyphens and their name or by a single\n"
+ "hyphen and the flag character.\n\0"
+/* 2779 */ "\n"
+ "= = = = = = = =\n\n"
+ "This incarnation of genshell will produce\n"
+ "a shell script to parse the options for %s:\n\n\0"
+/* 2885 */ " or an integer mask with any of the lower %d bits set\n\0"
+/* 2941 */ "\t\t\t\t- is a set membership option\n\0"
+/* 2975 */ "\t\t\t\t- must appear between %d and %d times\n\0"
+/* 3018 */ "Options are specified by single or double hyphens and their name.\n\0"
+/* 3085 */ "\t\t\t\t- may appear multiple times\n\0"
+/* 3118 */ "\t\t\t\t- may not be preset\n\0"
+/* 3143 */ " Arg Option-Name Description\n\0"
+/* 3178 */ " Flg Arg Option-Name Description\n\0"
+/* 3216 */ " %3s %s\0"
+/* 3224 */ "The '-#<number>' option may omit the hash char\n\0"
+/* 3272 */ "All arguments are named options.\n\0"
+/* 3306 */ " - reading file %s\0"
+/* 3325 */ "\n"
+ "Please send bug reports to: <%s>\n\0"
+/* 3361 */ "\t\t\t\t- may NOT appear - preset only\n\0"
+/* 3397 */ "\n"
+ "The following option preset mechanisms are supported:\n\0"
+/* 3453 */ "prohibits these options:\n\0"
+/* 3479 */ "prohibits the option '%s'\n\0"
+/* 3506 */ "%s%ld to %ld\0"
+/* 3519 */ "%sgreater than or equal to %ld\0"
+/* 3550 */ "%s%ld exactly\0"
+/* 3564 */ "%sit must lie in one of the ranges:\n\0"
+/* 3601 */ "%sit must be in the range:\n\0"
+/* 3629 */ ", or\n\0"
+/* 3635 */ "%sis scalable with a suffix: k/K/m/M/g/G/t/T\n\0"
+/* 3681 */ "%sless than or equal to %ld\0"
+/* 3709 */ "Operands and options may be intermixed. They will be reordered.\n\0"
+/* 3775 */ "requires the option '%s'\n\0"
+/* 3801 */ "requires these options:\n\0"
+/* 3826 */ " Arg Option-Name Req? Description\n\0"
+/* 3866 */ " Flg Arg Option-Name Req? Description\n\0"
+/* 3909 */ "or you may use a numeric representation. Preceding these with a '!'\n"
+ "will clear the bits, specifying 'none' will clear all bits, and 'all'\n"
+ "will set them all. Multiple entries may be passed as an option\n"
+ "argument list.\n\0"
+/* 4128 */ "\t\t\t\t- may appear up to %d times\n\0"
+/* 4161 */ "The valid \"%s\" option keywords are:\n\0"
+/* 4198 */ "The next option supports vendor supported extra options:\0"
+/* 4255 */ "These additional options are:";
+
+/*
+ * Now, define (and initialize) the structure that contains
+ * the pointers to all these strings.
+ * Aren't you glad you don't maintain this by hand?
+ */
+usage_text_t option_xlateable_txt = {
+ 108,
+ eng_zGnuBoolArg, eng_zGnuKeyArg, eng_zGnuNumArg, eng_zGnuStrArg,
+ {
+ option_lib_text + 0, option_lib_text + 31, option_lib_text + 83,
+ option_lib_text + 129, option_lib_text + 228, option_lib_text + 264,
+ option_lib_text + 314, option_lib_text + 405, option_lib_text + 427,
+ option_lib_text + 484, option_lib_text + 519, option_lib_text + 564,
+ option_lib_text + 596, option_lib_text + 634, option_lib_text + 667,
+ option_lib_text + 716, option_lib_text + 748, option_lib_text + 800,
+ option_lib_text + 837, option_lib_text + 862, option_lib_text + 900,
+ option_lib_text + 918, option_lib_text + 1060, option_lib_text + 1107,
+ option_lib_text + 1146, option_lib_text + 1159, option_lib_text + 1185,
+ option_lib_text + 1211, option_lib_text + 1254, option_lib_text + 1290,
+ option_lib_text + 1335, option_lib_text + 1364, option_lib_text + 1407,
+ option_lib_text + 1490, option_lib_text + 1528, option_lib_text + 1574,
+ option_lib_text + 1619, option_lib_text + 1646, option_lib_text + 1695,
+ option_lib_text + 1744, option_lib_text + 1771, option_lib_text + 1804,
+ option_lib_text + 1840, option_lib_text + 1890, option_lib_text + 1908,
+ option_lib_text + 1962, option_lib_text + 2010, option_lib_text + 2057,
+ option_lib_text + 2097, option_lib_text + 2132, option_lib_text + 2157,
+ option_lib_text + 2173, option_lib_text + 2188, option_lib_text + 2194,
+ option_lib_text + 2243, option_lib_text + 2288, option_lib_text + 2344,
+ option_lib_text + 2373, option_lib_text + 2415, option_lib_text + 2457,
+ option_lib_text + 2483, option_lib_text + 2498, option_lib_text + 2528,
+ option_lib_text + 2554, option_lib_text + 2571, option_lib_text + 2618,
+ option_lib_text + 2649, option_lib_text + 2676, option_lib_text + 2779,
+ option_lib_text + 2885, option_lib_text + 2941, option_lib_text + 2975,
+ option_lib_text + 3018, option_lib_text + 3085, option_lib_text + 3118,
+ option_lib_text + 3143, option_lib_text + 3178, option_lib_text + 3216,
+ option_lib_text + 3224, option_lib_text + 3272, option_lib_text + 3306,
+ option_lib_text + 3325, option_lib_text + 3361, option_lib_text + 3397,
+ option_lib_text + 3453, option_lib_text + 3479, option_lib_text + 3506,
+ option_lib_text + 3519, option_lib_text + 3550, option_lib_text + 3564,
+ option_lib_text + 3601, option_lib_text + 3629, option_lib_text + 3635,
+ option_lib_text + 3681, option_lib_text + 3709, option_lib_text + 3775,
+ option_lib_text + 3801, option_lib_text + 3826, option_lib_text + 3866,
+ option_lib_text + 3909, option_lib_text + 4128, option_lib_text + 4161,
+ option_lib_text + 4198, option_lib_text + 4255
+ } };
+#endif /* AUTOOPTS_INTERNAL */
+
+#ifdef XGETTEXT_SCAN_DO_NOT_COMPILE
+do not compile this section.
+/* TRANSLATORS: The following dummy functions were crated solely so that
+ * xgettext can extract the correct strings. These strings are actually
+ * referenced where the preceding "#line" directive states, though you will
+ * not see the literal string there. The literal string is defined above in
+ * the @code{option_lib_text} table and referenced via a #define name that
+ * redirects into the @code{option_xlateable_txt} structure above. When
+ * translating is activated, the pointers in @code{option_xlateable_txt} are
+ * updated to point to translated strings.
+ */
+static void dummy_func(void) {
+ /* LIBOPTS-MESSAGES: */
+#line 67 "../autoopts.c"
+ puts(_("allocation of %d bytes failed\n"));
+#line 93 "../autoopts.c"
+ puts(_("allocation of %d bytes failed\n"));
+#line 53 "../init.c"
+ puts(_("AutoOpts function called without option descriptor\n"));
+#line 86 "../init.c"
+ puts(_("\tThis exceeds the compiled library version: "));
+#line 84 "../init.c"
+ puts(_("Automated Options Processing Error!\n"
+ "\t%s called AutoOpts function with structure version %d:%d:%d.\n"));
+#line 80 "../autoopts.c"
+ puts(_("realloc of %d bytes at 0x%p failed\n"));
+#line 88 "../init.c"
+ puts(_("\tThis is less than the minimum library version: "));
+#line 121 "../version.c"
+ puts(_("Automated Options version %s\n"
+ "\tCopyright (C) 1999-2014 by Bruce Korb - all rights reserved\n"));
+#line 87 "../makeshell.c"
+ puts(_("(AutoOpts bug): %s.\n"));
+#line 90 "../reset.c"
+ puts(_("optionResetOpt() called, but reset-option not configured"));
+#line 292 "../usage.c"
+ puts(_("could not locate the 'help' option"));
+#line 336 "../autoopts.c"
+ puts(_("optionProcess() was called with invalid data"));
+#line 748 "../usage.c"
+ puts(_("invalid argument type specified"));
+#line 598 "../find.c"
+ puts(_("defaulted to option with optional arg"));
+#line 76 "../alias.c"
+ puts(_("aliasing option is out of range."));
+#line 234 "../enum.c"
+ puts(_("%s error: the keyword '%s' is ambiguous for %s\n"));
+#line 108 "../find.c"
+ puts(_(" The following options match:\n"));
+#line 293 "../find.c"
+ puts(_("%s: ambiguous option name: %s (matches %d options)\n"));
+#line 161 "../check.c"
+ puts(_("%s: Command line arguments required\n"));
+#line 43 "../alias.c"
+ puts(_("%d %s%s options allowed\n"));
+#line 94 "../makeshell.c"
+ puts(_("%s error %d (%s) calling %s for '%s'\n"));
+#line 306 "../makeshell.c"
+ puts(_("interprocess pipe"));
+#line 168 "../version.c"
+ puts(_("error: version option argument '%c' invalid. Use:\n"
+ "\t'v' - version only\n"
+ "\t'c' - version and copyright\n"
+ "\t'n' - version and full copyright notice\n"));
+#line 58 "../check.c"
+ puts(_("%s error: the '%s' and '%s' options conflict\n"));
+#line 217 "../find.c"
+ puts(_("%s: The '%s' option has been disabled."));
+#line 430 "../find.c"
+ puts(_("%s: The '%s' option has been disabled."));
+#line 38 "../alias.c"
+ puts(_("-equivalence"));
+#line 469 "../find.c"
+ puts(_("%s: illegal option -- %c\n"));
+#line 110 "../reset.c"
+ puts(_("%s: illegal option -- %c\n"));
+#line 271 "../find.c"
+ puts(_("%s: illegal option -- %s\n"));
+#line 755 "../find.c"
+ puts(_("%s: illegal option -- %s\n"));
+#line 118 "../reset.c"
+ puts(_("%s: illegal option -- %s\n"));
+#line 335 "../find.c"
+ puts(_("%s: unknown vendor extension option -- %s\n"));
+#line 159 "../enum.c"
+ puts(_(" or an integer from %d through %d\n"));
+#line 169 "../enum.c"
+ puts(_(" or an integer from %d through %d\n"));
+#line 747 "../usage.c"
+ puts(_("%s error: invalid option descriptor for %s\n"));
+#line 1081 "../usage.c"
+ puts(_("%s error: invalid option descriptor for %s\n"));
+#line 385 "../find.c"
+ puts(_("%s: invalid option name: %s\n"));
+#line 527 "../find.c"
+ puts(_("%s: The '%s' option requires an argument.\n"));
+#line 156 "../autoopts.c"
+ puts(_("(AutoOpts bug): Equivalenced option '%s' was equivalenced to both\n"
+ "\t'%s' and '%s'."));
+#line 94 "../check.c"
+ puts(_("%s error: The %s option is required\n"));
+#line 632 "../find.c"
+ puts(_("%s: The '%s' option cannot have an argument.\n"));
+#line 151 "../check.c"
+ puts(_("%s: Command line arguments are not allowed.\n"));
+#line 535 "../save.c"
+ puts(_("error %d (%s) creating %s\n"));
+#line 234 "../enum.c"
+ puts(_("%s error: '%s' does not match any %s keywords.\n"));
+#line 93 "../reset.c"
+ puts(_("%s error: The '%s' option requires an argument.\n"));
+#line 184 "../save.c"
+ puts(_("error %d (%s) stat-ing %s\n"));
+#line 238 "../save.c"
+ puts(_("error %d (%s) stat-ing %s\n"));
+#line 143 "../restore.c"
+ puts(_("%s error: no saved option state\n"));
+#line 231 "../autoopts.c"
+ puts(_("'%s' is not a command line option.\n"));
+#line 111 "../time.c"
+ puts(_("%s error: '%s' is not a recognizable date/time.\n"));
+#line 132 "../save.c"
+ puts(_("'%s' not defined\n"));
+#line 50 "../time.c"
+ puts(_("%s error: '%s' is not a recognizable time duration.\n"));
+#line 92 "../check.c"
+ puts(_("%s error: The %s option must appear %d times.\n"));
+#line 164 "../numeric.c"
+ puts(_("%s error: '%s' is not a recognizable number.\n"));
+#line 200 "../enum.c"
+ puts(_("%s error: %s exceeds %s keyword count\n"));
+#line 330 "../usage.c"
+ puts(_("Try '%s %s' for more information.\n"));
+#line 45 "../alias.c"
+ puts(_("one %s%s option allowed\n"));
+#line 208 "../makeshell.c"
+ puts(_("standard output"));
+#line 943 "../makeshell.c"
+ puts(_("standard output"));
+#line 274 "../usage.c"
+ puts(_("standard output"));
+#line 415 "../usage.c"
+ puts(_("standard output"));
+#line 625 "../usage.c"
+ puts(_("standard output"));
+#line 175 "../version.c"
+ puts(_("standard output"));
+#line 274 "../usage.c"
+ puts(_("standard error"));
+#line 415 "../usage.c"
+ puts(_("standard error"));
+#line 625 "../usage.c"
+ puts(_("standard error"));
+#line 175 "../version.c"
+ puts(_("standard error"));
+#line 208 "../makeshell.c"
+ puts(_("write"));
+#line 943 "../makeshell.c"
+ puts(_("write"));
+#line 273 "../usage.c"
+ puts(_("write"));
+#line 414 "../usage.c"
+ puts(_("write"));
+#line 624 "../usage.c"
+ puts(_("write"));
+#line 174 "../version.c"
+ puts(_("write"));
+#line 60 "../numeric.c"
+ puts(_("%s error: %s option value %ld is out of range.\n"));
+#line 44 "../check.c"
+ puts(_("%s error: %s option requires the %s option\n"));
+#line 131 "../save.c"
+ puts(_("%s warning: cannot save options - %s not regular file\n"));
+#line 183 "../save.c"
+ puts(_("%s warning: cannot save options - %s not regular file\n"));
+#line 237 "../save.c"
+ puts(_("%s warning: cannot save options - %s not regular file\n"));
+#line 256 "../save.c"
+ puts(_("%s warning: cannot save options - %s not regular file\n"));
+#line 534 "../save.c"
+ puts(_("%s warning: cannot save options - %s not regular file\n"));
+ /* END-LIBOPTS-MESSAGES */
+
+ /* USAGE-TEXT: */
+#line 873 "../usage.c"
+ puts(_("\t\t\t\t- an alternate for '%s'\n"));
+#line 1148 "../usage.c"
+ puts(_("Version, usage and configuration options:"));
+#line 924 "../usage.c"
+ puts(_("\t\t\t\t- default option for unnamed options\n"));
+#line 837 "../usage.c"
+ puts(_("\t\t\t\t- disabled as '--%s'\n"));
+#line 1117 "../usage.c"
+ puts(_(" --- %-14s %s\n"));
+#line 1115 "../usage.c"
+ puts(_("This option has been disabled"));
+#line 864 "../usage.c"
+ puts(_("\t\t\t\t- enabled by default\n"));
+#line 40 "../alias.c"
+ puts(_("%s error: only "));
+#line 1194 "../usage.c"
+ puts(_(" - examining environment variables named %s_*\n"));
+#line 168 "../file.c"
+ puts(_("\t\t\t\t- file must not pre-exist\n"));
+#line 172 "../file.c"
+ puts(_("\t\t\t\t- file must pre-exist\n"));
+#line 380 "../usage.c"
+ puts(_("Options are specified by doubled hyphens and their name or by a single\n"
+ "hyphen and the flag character.\n"));
+#line 921 "../makeshell.c"
+ puts(_("\n"
+ "= = = = = = = =\n\n"
+ "This incarnation of genshell will produce\n"
+ "a shell script to parse the options for %s:\n\n"));
+#line 166 "../enum.c"
+ puts(_(" or an integer mask with any of the lower %d bits set\n"));
+#line 897 "../usage.c"
+ puts(_("\t\t\t\t- is a set membership option\n"));
+#line 918 "../usage.c"
+ puts(_("\t\t\t\t- must appear between %d and %d times\n"));
+#line 382 "../usage.c"
+ puts(_("Options are specified by single or double hyphens and their name.\n"));
+#line 904 "../usage.c"
+ puts(_("\t\t\t\t- may appear multiple times\n"));
+#line 891 "../usage.c"
+ puts(_("\t\t\t\t- may not be preset\n"));
+#line 1309 "../usage.c"
+ puts(_(" Arg Option-Name Description\n"));
+#line 1245 "../usage.c"
+ puts(_(" Flg Arg Option-Name Description\n"));
+#line 1303 "../usage.c"
+ puts(_(" Flg Arg Option-Name Description\n"));
+#line 1304 "../usage.c"
+ puts(_(" %3s %s"));
+#line 1310 "../usage.c"
+ puts(_(" %3s %s"));
+#line 387 "../usage.c"
+ puts(_("The '-#<number>' option may omit the hash char\n"));
+#line 383 "../usage.c"
+ puts(_("All arguments are named options.\n"));
+#line 971 "../usage.c"
+ puts(_(" - reading file %s"));
+#line 409 "../usage.c"
+ puts(_("\n"
+ "Please send bug reports to: <%s>\n"));
+#line 100 "../version.c"
+ puts(_("\n"
+ "Please send bug reports to: <%s>\n"));
+#line 129 "../version.c"
+ puts(_("\n"
+ "Please send bug reports to: <%s>\n"));
+#line 903 "../usage.c"
+ puts(_("\t\t\t\t- may NOT appear - preset only\n"));
+#line 944 "../usage.c"
+ puts(_("\n"
+ "The following option preset mechanisms are supported:\n"));
+#line 1192 "../usage.c"
+ puts(_("\n"
+ "The following option preset mechanisms are supported:\n"));
+#line 682 "../usage.c"
+ puts(_("prohibits these options:\n"));
+#line 677 "../usage.c"
+ puts(_("prohibits the option '%s'\n"));
+#line 81 "../numeric.c"
+ puts(_("%s%ld to %ld"));
+#line 79 "../numeric.c"
+ puts(_("%sgreater than or equal to %ld"));
+#line 75 "../numeric.c"
+ puts(_("%s%ld exactly"));
+#line 68 "../numeric.c"
+ puts(_("%sit must lie in one of the ranges:\n"));
+#line 68 "../numeric.c"
+ puts(_("%sit must be in the range:\n"));
+#line 88 "../numeric.c"
+ puts(_(", or\n"));
+#line 66 "../numeric.c"
+ puts(_("%sis scalable with a suffix: k/K/m/M/g/G/t/T\n"));
+#line 77 "../numeric.c"
+ puts(_("%sless than or equal to %ld"));
+#line 390 "../usage.c"
+ puts(_("Operands and options may be intermixed. They will be reordered.\n"));
+#line 652 "../usage.c"
+ puts(_("requires the option '%s'\n"));
+#line 655 "../usage.c"
+ puts(_("requires these options:\n"));
+#line 1321 "../usage.c"
+ puts(_(" Arg Option-Name Req? Description\n"));
+#line 1315 "../usage.c"
+ puts(_(" Flg Arg Option-Name Req? Description\n"));
+#line 167 "../enum.c"
+ puts(_("or you may use a numeric representation. Preceding these with a '!'\n"
+ "will clear the bits, specifying 'none' will clear all bits, and 'all'\n"
+ "will set them all. Multiple entries may be passed as an option\n"
+ "argument list.\n"));
+#line 910 "../usage.c"
+ puts(_("\t\t\t\t- may appear up to %d times\n"));
+#line 77 "../enum.c"
+ puts(_("The valid \"%s\" option keywords are:\n"));
+#line 1152 "../usage.c"
+ puts(_("The next option supports vendor supported extra options:"));
+#line 773 "../usage.c"
+ puts(_("These additional options are:"));
+ /* END-USAGE-TEXT */
+}
+#endif /* XGETTEXT_SCAN_DO_NOT_COMPILE */
+#endif /* AUTOOPTS_USAGE_TXT_H_GUARD */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/boolean.c b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/boolean.c
new file mode 100644
index 0000000..2bea8e7
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/boolean.c
@@ -0,0 +1,95 @@
+
+/**
+ * \file boolean.c
+ *
+ * Handle options with true/false values for arguments.
+ *
+ * @addtogroup autoopts
+ * @{
+ */
+/*
+ * This routine will run run-on options through a pager so the
+ * user may examine, print or edit them at their leisure.
+ *
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
+ *
+ * AutoOpts is available under any one of two licenses. The license
+ * in use must be one of these two and the choice is under the control
+ * of the user of the license.
+ *
+ * The GNU Lesser General Public License, version 3 or later
+ * See the files "COPYING.lgplv3" and "COPYING.gplv3"
+ *
+ * The Modified Berkeley Software Distribution License
+ * See the file "COPYING.mbsd"
+ *
+ * These files have the following sha256 sums:
+ *
+ * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
+ * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
+ * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
+ */
+
+/*=export_func optionBooleanVal
+ * private:
+ *
+ * what: Decipher a boolean value
+ * arg: + tOptions * + opts + program options descriptor +
+ * arg: + tOptDesc * + od + the descriptor for this arg +
+ *
+ * doc:
+ * Decipher a true or false value for a boolean valued option argument.
+ * The value is true, unless it starts with 'n' or 'f' or "#f" or
+ * it is an empty string or it is a number that evaluates to zero.
+=*/
+void
+optionBooleanVal(tOptions * opts, tOptDesc * od)
+{
+ char * pz;
+ bool res = true;
+
+ if (INQUERY_CALL(opts, od))
+ return;
+
+ if (od->optArg.argString == NULL) {
+ od->optArg.argBool = false;
+ return;
+ }
+
+ switch (*(od->optArg.argString)) {
+ case '0':
+ {
+ long val = strtol(od->optArg.argString, &pz, 0);
+ if ((val != 0) || (*pz != NUL))
+ break;
+ /* FALLTHROUGH */
+ }
+ case 'N':
+ case 'n':
+ case 'F':
+ case 'f':
+ case NUL:
+ res = false;
+ break;
+ case '#':
+ if (od->optArg.argString[1] != 'f')
+ break;
+ res = false;
+ }
+
+ if (od->fOptState & OPTST_ALLOC_ARG) {
+ AGFREE(od->optArg.argString);
+ od->fOptState &= ~OPTST_ALLOC_ARG;
+ }
+ od->optArg.argBool = res;
+}
+/** @}
+ *
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of autoopts/boolean.c */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/check.c b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/check.c
new file mode 100644
index 0000000..eff8ec0
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/check.c
@@ -0,0 +1,177 @@
+/**
+ * @file check.c
+ *
+ * @brief option consistency checks.
+ *
+ * @addtogroup autoopts
+ * @{
+ */
+/*
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
+ *
+ * AutoOpts is available under any one of two licenses. The license
+ * in use must be one of these two and the choice is under the control
+ * of the user of the license.
+ *
+ * The GNU Lesser General Public License, version 3 or later
+ * See the files "COPYING.lgplv3" and "COPYING.gplv3"
+ *
+ * The Modified Berkeley Software Distribution License
+ * See the file "COPYING.mbsd"
+ *
+ * These files have the following sha256 sums:
+ *
+ * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
+ * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
+ * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
+ */
+
+/**
+ * Check for conflicts based on "must" and "cannot" attributes.
+ */
+static bool
+has_conflict(tOptions * pOpts, tOptDesc * od)
+{
+ if (od->pOptMust != NULL) {
+ int const * must = od->pOptMust;
+
+ while (*must != NO_EQUIVALENT) {
+ tOptDesc * p = pOpts->pOptDesc + *(must++);
+ if (UNUSED_OPT(p)) {
+ const tOptDesc * ood = pOpts->pOptDesc + must[-1];
+ fprintf(stderr, zneed_fmt, pOpts->pzProgName,
+ od->pz_Name, ood->pz_Name);
+ return true;
+ }
+ }
+ }
+
+ if (od->pOptCant != NULL) {
+ int const * cant = od->pOptCant;
+
+ while (*cant != NO_EQUIVALENT) {
+ tOptDesc * p = pOpts->pOptDesc + *(cant++);
+ if (SELECTED_OPT(p)) {
+ const tOptDesc * ood = pOpts->pOptDesc + cant[-1];
+ fprintf(stderr, zconflict_fmt, pOpts->pzProgName,
+ od->pz_Name, ood->pz_Name);
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+/**
+ * Check that the option occurs often enough. Too often is already checked.
+ */
+static bool
+occurs_enough(tOptions * pOpts, tOptDesc * pOD)
+{
+ (void)pOpts;
+
+ /*
+ * IF the occurrence counts have been satisfied,
+ * THEN there is no problem.
+ */
+ if (pOD->optOccCt >= pOD->optMinCt)
+ return true;
+
+ /*
+ * IF MUST_SET means SET and PRESET are okay,
+ * so min occurrence count doesn't count
+ */
+ if ( (pOD->fOptState & OPTST_MUST_SET)
+ && (pOD->fOptState & (OPTST_PRESET | OPTST_SET)) )
+ return true;
+
+ if (pOD->optMinCt > 1)
+ fprintf(stderr, zneed_more, pOpts->pzProgName, pOD->pz_Name,
+ pOD->optMinCt);
+ else fprintf(stderr, zneed_one, pOpts->pzProgName, pOD->pz_Name);
+ return false;
+}
+
+/**
+ * Verify option consistency.
+ *
+ * Make sure that the argument list passes our consistency tests.
+ */
+LOCAL bool
+is_consistent(tOptions * pOpts)
+{
+ tOptDesc * pOD = pOpts->pOptDesc;
+ int oCt = pOpts->presetOptCt;
+
+ /*
+ * FOR each of "oCt" options, ...
+ */
+ for (;;) {
+ /*
+ * IF the current option was provided on the command line
+ * THEN ensure that any "MUST" requirements are not
+ * "DEFAULT" (unspecified) *AND* ensure that any
+ * "CANT" options have not been SET or DEFINED.
+ */
+ if (SELECTED_OPT(pOD)) {
+ if (has_conflict(pOpts, pOD))
+ return false;
+ }
+
+ /*
+ * IF this option is not equivalenced to another,
+ * OR it is equivalenced to itself (is the equiv. root)
+ * THEN we need to make sure it occurs often enough.
+ */
+ if ( (pOD->optEquivIndex == NO_EQUIVALENT)
+ || (pOD->optEquivIndex == pOD->optIndex) )
+
+ if (! occurs_enough(pOpts, pOD))
+ return false;
+
+ if (--oCt <= 0)
+ break;
+ pOD++;
+ }
+
+ /*
+ * IF we are stopping on errors, check to see if any remaining
+ * arguments are required to be there or prohibited from being there.
+ */
+ if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) {
+
+ /*
+ * Check for prohibition
+ */
+ if ((pOpts->fOptSet & OPTPROC_NO_ARGS) != 0) {
+ if (pOpts->origArgCt > pOpts->curOptIdx) {
+ fprintf(stderr, zNoArgs, pOpts->pzProgName);
+ return false;
+ }
+ }
+
+ /*
+ * ELSE not prohibited, check for being required
+ */
+ else if ((pOpts->fOptSet & OPTPROC_ARGS_REQ) != 0) {
+ if (pOpts->origArgCt <= pOpts->curOptIdx) {
+ fprintf(stderr, zargs_must, pOpts->pzProgName);
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+/** @}
+ *
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of autoopts/check.c */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/compat/compat.h b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/compat/compat.h
new file mode 100644
index 0000000..561d55d
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/compat/compat.h
@@ -0,0 +1,383 @@
+/* -*- Mode: C -*-
+ *
+ * compat.h is free software.
+ * This file is part of AutoGen and AutoOpts.
+ *
+ * AutoGen Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
+ *
+ * AutoOpts is available under any one of two licenses. The license
+ * in use must be one of these two and the choice is under the control
+ * of the user of the license.
+ *
+ * The GNU Lesser General Public License, version 3 or later
+ * See the files "COPYING.lgplv3" and "COPYING.gplv3"
+ *
+ * The Modified Berkeley Software Distribution License
+ * See the file "COPYING.mbsd"
+ *
+ * These files have the following sha256 sums:
+ *
+ * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
+ * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
+ * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
+ */
+
+/**
+ * \file compat.h
+ * fake the preprocessor into handlng stuff portability
+ */
+#ifndef COMPAT_H_GUARD
+#define COMPAT_H_GUARD 1
+
+#if defined(HAVE_CONFIG_H)
+# include <config.h>
+
+#elif defined(_WIN32) && !defined(__CYGWIN__)
+# include "windows-config.h"
+
+#else
+# error "compat.h" requires "config.h"
+ choke me.
+#endif
+
+
+#ifndef HAVE_STRSIGNAL
+# ifndef HAVE_RAW_DECL_STRSIGNAL
+ char * strsignal(int signo);
+# endif
+#endif
+
+#define _GNU_SOURCE 1 /* for strsignal in GNU's libc */
+#define __USE_GNU 1 /* exact same thing as above */
+#define __EXTENSIONS__ 1 /* and another way to call for it */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * SYSTEM HEADERS:
+ */
+#include <sys/types.h>
+#ifdef HAVE_SYS_MMAN_H
+# include <sys/mman.h>
+#endif
+#include <sys/param.h>
+#if HAVE_SYS_PROCSET_H
+# include <sys/procset.h>
+#endif
+#include <sys/stat.h>
+#ifdef HAVE_SYS_WAIT_H
+# include <sys/wait.h>
+#endif
+
+#if defined( HAVE_SOLARIS_SYSINFO )
+# include <sys/systeminfo.h>
+#elif defined( HAVE_UNAME_SYSCALL )
+# include <sys/utsname.h>
+#endif
+
+#ifdef DAEMON_ENABLED
+# if HAVE_SYS_STROPTS_H
+# include <sys/stropts.h>
+# endif
+
+# if HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+# endif
+
+# if ! defined(HAVE_SYS_POLL_H) && ! defined(HAVE_SYS_SELECT_H)
+# error This system cannot support daemon processing
+ Choke Me.
+# endif
+
+# if HAVE_SYS_POLL_H
+# include <sys/poll.h>
+# endif
+
+# if HAVE_SYS_SELECT_H
+# include <sys/select.h>
+# endif
+
+# if HAVE_NETINET_IN_H
+# include <netinet/in.h>
+# endif
+
+# if HAVE_SYS_UN_H
+# include <sys/un.h>
+# endif
+#endif
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * USER HEADERS:
+ */
+#include <stdio.h>
+#include <assert.h>
+#include <ctype.h>
+
+/*
+ * Directory opening stuff:
+ */
+# if defined (_POSIX_SOURCE)
+/* Posix does not require that the d_ino field be present, and some
+ systems do not provide it. */
+# define REAL_DIR_ENTRY(dp) 1
+# else /* !_POSIX_SOURCE */
+# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
+# endif /* !_POSIX_SOURCE */
+
+# if defined (HAVE_DIRENT_H)
+# include <dirent.h>
+# define D_NAMLEN(dirent) strlen((dirent)->d_name)
+# else /* !HAVE_DIRENT_H */
+# define dirent direct
+# define D_NAMLEN(dirent) (dirent)->d_namlen
+# if defined (HAVE_SYS_NDIR_H)
+# include <sys/ndir.h>
+# endif /* HAVE_SYS_NDIR_H */
+# if defined (HAVE_SYS_DIR_H)
+# include <sys/dir.h>
+# endif /* HAVE_SYS_DIR_H */
+# if defined (HAVE_NDIR_H)
+# include <ndir.h>
+# endif /* HAVE_NDIR_H */
+# endif /* !HAVE_DIRENT_H */
+
+#include <errno.h>
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+#ifndef O_NONBLOCK
+# define O_NONBLOCK FNDELAY
+#endif
+
+#if defined(HAVE_LIBGEN) && defined(HAVE_LIBGEN_H)
+# include <libgen.h>
+#endif
+
+#if defined(HAVE_LIMITS_H) /* this is also in options.h */
+# include <limits.h>
+#elif defined(HAVE_SYS_LIMITS_H)
+# include <sys/limits.h>
+#endif /* HAVE_LIMITS/SYS_LIMITS_H */
+
+#include <memory.h>
+#include <setjmp.h>
+#include <signal.h>
+
+#if defined(HAVE_STDINT_H)
+# include <stdint.h>
+
+#elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#ifdef HAVE_UTIME_H
+# include <utime.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+ typedef enum { false = 0, true = 1 } _Bool;
+# define bool _Bool
+
+ /* The other macros must be usable in preprocessor directives. */
+# define false 0
+# define true 1
+#endif
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * FIXUPS and CONVIENCE STUFF:
+ */
+#ifdef __cplusplus
+# define EXTERN extern "C"
+#else
+# define EXTERN extern
+#endif
+
+/* some systems #def errno! and others do not declare it!! */
+#ifndef errno
+ extern int errno;
+#endif
+
+/* Some machines forget this! */
+
+# ifndef EXIT_FAILURE
+# define EXIT_SUCCESS 0
+# define EXIT_FAILURE 1
+# endif
+
+#ifndef NUL
+# define NUL '\0'
+#endif
+
+#ifndef NULL
+# define NULL 0
+#endif
+
+#if !defined (MAXPATHLEN) && defined (HAVE_SYS_PARAM_H)
+# include <sys/param.h>
+#endif /* !MAXPATHLEN && HAVE_SYS_PARAM_H */
+
+#if !defined (MAXPATHLEN) && defined (PATH_MAX)
+# define MAXPATHLEN PATH_MAX
+#endif /* !MAXPATHLEN && PATH_MAX */
+
+#if !defined (MAXPATHLEN) && defined(_MAX_PATH)
+# define PATH_MAX _MAX_PATH
+# define MAXPATHLEN _MAX_PATH
+#endif
+
+#if !defined (MAXPATHLEN)
+# define MAXPATHLEN 4096
+#endif /* MAXPATHLEN */
+
+#define AG_PATH_MAX ((size_t)MAXPATHLEN)
+
+#ifndef LONG_MAX
+# define LONG_MAX ~(1L << (8*sizeof(long) -1))
+# define INT_MAX ~(1 << (8*sizeof(int) -1))
+#endif
+
+#ifndef ULONG_MAX
+# define ULONG_MAX ~(OUL)
+# define UINT_MAX ~(OU)
+#endif
+
+#ifndef SHORT_MAX
+# define SHORT_MAX ~(1 << (8*sizeof(short) - 1))
+#else
+# define USHORT_MAX ~(OUS)
+#endif
+
+#ifndef HAVE_INT8_T
+ typedef signed char int8_t;
+# define HAVE_INT8_T 1
+#endif
+#ifndef HAVE_UINT8_T
+ typedef unsigned char uint8_t;
+# define HAVE_UINT8_T 1
+#endif
+#ifndef HAVE_INT16_T
+ typedef signed short int16_t;
+# define HAVE_INT16_T 1
+#endif
+#ifndef HAVE_UINT16_T
+ typedef unsigned short uint16_t;
+# define HAVE_UINT16_T 1
+#endif
+
+#ifndef HAVE_INT32_T
+# if SIZEOF_INT == 4
+ typedef signed int int32_t;
+# elif SIZEOF_LONG == 4
+ typedef signed long int32_t;
+# endif
+# define HAVE_INT32_T 1
+#endif
+
+#ifndef HAVE_UINT32_T
+# if SIZEOF_INT == 4
+ typedef unsigned int uint32_t;
+# elif SIZEOF_LONG == 4
+ typedef unsigned long uint32_t;
+# else
+# error Cannot create a uint32_t type.
+ Choke Me.
+# endif
+# define HAVE_UINT32_T 1
+#endif
+
+#ifndef HAVE_INTPTR_T
+# if SIZEOF_CHARP == SIZEOF_LONG
+ typedef signed long intptr_t;
+# else
+ typedef signed int intptr_t;
+# endif
+# define HAVE_INTPTR_T 1
+#endif
+
+#ifndef HAVE_UINTPTR_T
+# if SIZEOF_CHARP == SIZEOF_LONG
+ typedef unsigned long intptr_t;
+# else
+ typedef unsigned int intptr_t;
+# endif
+# define HAVE_INTPTR_T 1
+#endif
+
+#ifndef HAVE_UINT_T
+ typedef unsigned int uint_t;
+# define HAVE_UINT_T 1
+#endif
+
+#ifndef HAVE_SIZE_T
+ typedef unsigned int size_t;
+# define HAVE_SIZE_T 1
+#endif
+#ifndef HAVE_WINT_T
+ typedef unsigned int wint_t;
+# define HAVE_WINT_T 1
+#endif
+#ifndef HAVE_PID_T
+ typedef signed int pid_t;
+# define HAVE_PID_T 1
+#endif
+
+/* redefine these for BSD style string libraries */
+#ifndef HAVE_STRCHR
+# define strchr index
+# define strrchr rindex
+#endif
+
+#ifdef USE_FOPEN_BINARY
+# ifndef FOPEN_BINARY_FLAG
+# define FOPEN_BINARY_FLAG "b"
+# endif
+# ifndef FOPEN_TEXT_FLAG
+# define FOPEN_TEXT_FLAG "t"
+# endif
+#else
+# ifndef FOPEN_BINARY_FLAG
+# define FOPEN_BINARY_FLAG
+# endif
+# ifndef FOPEN_TEXT_FLAG
+# define FOPEN_TEXT_FLAG
+# endif
+#endif
+
+#ifndef STR
+# define _STR(s) #s
+# define STR(s) _STR(s)
+#endif
+
+/* ##### Pointer sized word ##### */
+
+/* FIXME: the MAX stuff in here is broken! */
+#if SIZEOF_CHARP > SIZEOF_INT
+ typedef long t_word;
+ #define WORD_MAX LONG_MAX
+ #define WORD_MIN LONG_MIN
+#else /* SIZEOF_CHARP <= SIZEOF_INT */
+ typedef int t_word;
+ #define WORD_MAX INT_MAX
+ #define WORD_MIN INT_MIN
+#endif
+
+#endif /* COMPAT_H_GUARD */
+
+/*
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of compat/compat.h */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/compat/pathfind.c b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/compat/pathfind.c
new file mode 100644
index 0000000..d343dcc
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/compat/pathfind.c
@@ -0,0 +1,294 @@
+/* -*- Mode: C -*- */
+
+/* pathfind.c --- find a FILE MODE along PATH */
+
+/* Author: Gary V Vaughan <gvaughan@oranda.demon.co.uk> */
+
+/* Code: */
+
+static char *
+pathfind( char const * path,
+ char const * fname,
+ char const * mode );
+
+#include "compat.h"
+#ifndef HAVE_PATHFIND
+#if defined(__windows__) && !defined(__CYGWIN__)
+static char *
+pathfind( char const * path,
+ char const * fname,
+ char const * mode )
+{
+ return strdup(fname);
+}
+#else
+
+static char * make_absolute(char const * string, char const * dot_path);
+static char * canonicalize_pathname(char * path);
+static char * extract_colon_unit(char * dir, char const * string, int * p_index);
+
+/**
+ * local implementation of pathfind.
+ * @param[in] path colon separated list of directories
+ * @param[in] fname the name we are hunting for
+ * @param[in] mode the required file mode
+ * @returns an allocated string with the full path, or NULL
+ */
+static char *
+pathfind( char const * path,
+ char const * fname,
+ char const * mode )
+{
+ int p_index = 0;
+ int mode_bits = 0;
+ char * res_path = NULL;
+ char zPath[ AG_PATH_MAX + 1 ];
+
+ if (strchr( mode, 'r' )) mode_bits |= R_OK;
+ if (strchr( mode, 'w' )) mode_bits |= W_OK;
+ if (strchr( mode, 'x' )) mode_bits |= X_OK;
+
+ /*
+ * FOR each non-null entry in the colon-separated path, DO ...
+ */
+ for (;;) {
+ DIR * dirP;
+ char * colon_unit = extract_colon_unit( zPath, path, &p_index );
+
+ if (colon_unit == NULL)
+ break;
+
+ dirP = opendir( colon_unit );
+
+ /*
+ * IF the directory is inaccessable, THEN next directory
+ */
+ if (dirP == NULL)
+ continue;
+
+ for (;;) {
+ struct dirent *entP = readdir( dirP );
+
+ if (entP == (struct dirent *)NULL)
+ break;
+
+ /*
+ * IF the file name matches the one we are looking for, ...
+ */
+ if (strcmp(entP->d_name, fname) == 0) {
+ char * abs_name = make_absolute(fname, colon_unit);
+
+ /*
+ * Make sure we can access it in the way we want
+ */
+ if (access(abs_name, mode_bits) >= 0) {
+ /*
+ * We can, so normalize the name and return it below
+ */
+ res_path = canonicalize_pathname(abs_name);
+ }
+
+ free(abs_name);
+ break;
+ }
+ }
+
+ closedir( dirP );
+
+ if (res_path != NULL)
+ break;
+ }
+
+ return res_path;
+}
+
+/*
+ * Turn STRING (a pathname) into an absolute pathname, assuming that
+ * DOT_PATH contains the symbolic location of `.'. This always returns
+ * a new string, even if STRING was an absolute pathname to begin with.
+ */
+static char *
+make_absolute( char const * string, char const * dot_path )
+{
+ char * result;
+ int result_len;
+
+ if (!dot_path || *string == '/') {
+ result = strdup( string );
+ if (result == NULL) {
+ return NULL; /* couldn't allocate memory */
+ }
+ } else {
+ if (dot_path && dot_path[0]) {
+ result = malloc( 2 + strlen( dot_path ) + strlen( string ) );
+ if (result == NULL) {
+ return NULL; /* couldn't allocate memory */
+ }
+ strcpy( result, dot_path );
+ result_len = (int)strlen(result);
+ if (result[result_len - 1] != '/') {
+ result[result_len++] = '/';
+ result[result_len] = '\0';
+ }
+ } else {
+ result = malloc( 3 + strlen( string ) );
+ if (result == NULL) {
+ return NULL; /* couldn't allocate memory */
+ }
+ result[0] = '.'; result[1] = '/'; result[2] = '\0';
+ result_len = 2;
+ }
+
+ strcpy( result + result_len, string );
+ }
+
+ return result;
+}
+
+/*
+ * Canonicalize PATH, and return a new path. The new path differs from
+ * PATH in that:
+ *
+ * Multiple `/'s are collapsed to a single `/'.
+ * Leading `./'s are removed.
+ * Trailing `/.'s are removed.
+ * Trailing `/'s are removed.
+ * Non-leading `../'s and trailing `..'s are handled by removing
+ * portions of the path.
+ */
+static char *
+canonicalize_pathname( char *path )
+{
+ int i, start;
+ char stub_char, *result;
+
+ /* The result cannot be larger than the input PATH. */
+ result = strdup( path );
+ if (result == NULL) {
+ return NULL; /* couldn't allocate memory */
+ }
+ stub_char = (*path == '/') ? '/' : '.';
+
+ /* Walk along RESULT looking for things to compact. */
+ i = 0;
+ while (result[i]) {
+ while (result[i] != '\0' && result[i] != '/')
+ i++;
+
+ start = i++;
+
+ /* If we didn't find any slashes, then there is nothing left to
+ * do.
+ */
+ if (!result[start])
+ break;
+
+ /* Handle multiple `/'s in a row. */
+ while (result[i] == '/')
+ i++;
+
+#if !defined (apollo)
+ if ((start + 1) != i)
+#else
+ if ((start + 1) != i && (start != 0 || i != 2))
+#endif /* apollo */
+ {
+ strcpy( result + start + 1, result + i );
+ i = start + 1;
+ }
+
+ /* Handle backquoted `/'. */
+ if (start > 0 && result[start - 1] == '\\')
+ continue;
+
+ /* Check for trailing `/', and `.' by itself. */
+ if ((start && !result[i])
+ || (result[i] == '.' && !result[i+1])) {
+ result[--i] = '\0';
+ break;
+ }
+
+ /* Check for `../', `./' or trailing `.' by itself. */
+ if (result[i] == '.') {
+ /* Handle `./'. */
+ if (result[i + 1] == '/') {
+ strcpy( result + i, result + i + 1 );
+ i = (start < 0) ? 0 : start;
+ continue;
+ }
+
+ /* Handle `../' or trailing `..' by itself. */
+ if (result[i + 1] == '.' &&
+ (result[i + 2] == '/' || !result[i + 2])) {
+ while (--start > -1 && result[start] != '/')
+ ;
+ strcpy( result + start + 1, result + i + 2 );
+ i = (start < 0) ? 0 : start;
+ continue;
+ }
+ }
+ }
+
+ if (!*result) {
+ *result = stub_char;
+ result[1] = '\0';
+ }
+
+ return result;
+}
+
+/*
+ * Given a string containing units of information separated by colons,
+ * return the next one pointed to by (P_INDEX), or NULL if there are no
+ * more. Advance (P_INDEX) to the character after the colon.
+ */
+static char *
+extract_colon_unit(char * pzDir, char const * string, int * p_index)
+{
+ char * pzDest = pzDir;
+ int ix = *p_index;
+
+ if (string == NULL)
+ return NULL;
+
+ if ((unsigned)ix >= strlen( string ))
+ return NULL;
+
+ {
+ char const * pzSrc = string + ix;
+
+ while (*pzSrc == ':') pzSrc++;
+
+ for (;;) {
+ char ch = (*(pzDest++) = *(pzSrc++));
+ switch (ch) {
+ case ':':
+ pzDest[-1] = NUL;
+ /* FALLTHROUGH */
+ case NUL:
+ goto copy_done;
+ }
+
+ if ((unsigned long)(pzDest - pzDir) >= AG_PATH_MAX)
+ break;
+ } copy_done:;
+
+ ix = (int)(pzSrc - string);
+ }
+
+ if (*pzDir == NUL)
+ return NULL;
+
+ *p_index = ix;
+ return pzDir;
+}
+#endif /* __windows__ / __CYGWIN__ */
+#endif /* HAVE_PATHFIND */
+
+/*
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of compat/pathfind.c */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/configfile.c b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/configfile.c
new file mode 100644
index 0000000..8244371
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/configfile.c
@@ -0,0 +1,1381 @@
+/**
+ * \file configfile.c
+ *
+ * configuration/rc/ini file handling.
+ *
+ * @addtogroup autoopts
+ * @{
+ */
+/*
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
+ *
+ * AutoOpts is available under any one of two licenses. The license
+ * in use must be one of these two and the choice is under the control
+ * of the user of the license.
+ *
+ * The GNU Lesser General Public License, version 3 or later
+ * See the files "COPYING.lgplv3" and "COPYING.gplv3"
+ *
+ * The Modified Berkeley Software Distribution License
+ * See the file "COPYING.mbsd"
+ *
+ * These files have the following sha256 sums:
+ *
+ * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
+ * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
+ * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
+ */
+
+/* = = = START-STATIC-FORWARD = = = */
+static void
+file_preset(tOptions * opts, char const * fname, int dir);
+
+static char *
+handle_comment(char * txt);
+
+static char *
+handle_cfg(tOptions * opts, tOptState * ost, char * txt, int dir);
+
+static char *
+handle_directive(tOptions * opts, char * txt);
+
+static char *
+aoflags_directive(tOptions * opts, char * txt);
+
+static char *
+program_directive(tOptions * opts, char * txt);
+
+static char *
+handle_section(tOptions * opts, char * txt);
+
+static int
+parse_xml_encoding(char ** ppz);
+
+static char *
+trim_xml_text(char * intxt, char const * pznm, tOptionLoadMode mode);
+
+static void
+cook_xml_text(char * pzData);
+
+static char *
+handle_struct(tOptions * opts, tOptState * ost, char * txt, int dir);
+
+static char const *
+parse_keyword(tOptions * opts, char const * txt, tOptionValue * typ);
+
+static char const *
+parse_set_mem(tOptions * opts, char const * txt, tOptionValue * typ);
+
+static char const *
+parse_value(char const * txt, tOptionValue * typ);
+/* = = = END-STATIC-FORWARD = = = */
+
+/**
+ * Skip over some unknown attribute
+ * @param[in] txt start of skpped text
+ * @returns character after skipped text
+ */
+inline static char const *
+skip_unkn(char const * txt)
+{
+ txt = BRK_END_XML_TOKEN_CHARS(txt);
+ return (*txt == NUL) ? NULL : txt;
+}
+
+/*=export_func configFileLoad
+ *
+ * what: parse a configuration file
+ * arg: + char const * + fname + the file to load +
+ *
+ * ret_type: const tOptionValue *
+ * ret_desc: An allocated, compound value structure
+ *
+ * doc:
+ * This routine will load a named configuration file and parse the
+ * text as a hierarchically valued option. The option descriptor
+ * created from an option definition file is not used via this interface.
+ * The returned value is "named" with the input file name and is of
+ * type "@code{OPARG_TYPE_HIERARCHY}". It may be used in calls to
+ * @code{optionGetValue()}, @code{optionNextValue()} and
+ * @code{optionUnloadNested()}.
+ *
+ * err:
+ * If the file cannot be loaded or processed, @code{NULL} is returned and
+ * @var{errno} is set. It may be set by a call to either @code{open(2)}
+ * @code{mmap(2)} or other file system calls, or it may be:
+ * @itemize @bullet
+ * @item
+ * @code{ENOENT} - the file was not found.
+ * @item
+ * @code{ENOMSG} - the file was empty.
+ * @item
+ * @code{EINVAL} - the file contents are invalid -- not properly formed.
+ * @item
+ * @code{ENOMEM} - not enough memory to allocate the needed structures.
+ * @end itemize
+=*/
+const tOptionValue *
+configFileLoad(char const * fname)
+{
+ tmap_info_t cfgfile;
+ tOptionValue * res = NULL;
+ tOptionLoadMode save_mode = option_load_mode;
+
+ char * txt = text_mmap(fname, PROT_READ, MAP_PRIVATE, &cfgfile);
+
+ if (TEXT_MMAP_FAILED_ADDR(txt))
+ return NULL; /* errno is set */
+
+ option_load_mode = OPTION_LOAD_COOKED;
+ res = optionLoadNested(txt, fname, strlen(fname));
+
+ if (res == NULL) {
+ int err = errno;
+ text_munmap(&cfgfile);
+ errno = err;
+ } else
+ text_munmap(&cfgfile);
+
+ option_load_mode = save_mode;
+ return res;
+}
+
+
+/*=export_func optionFindValue
+ *
+ * what: find a hierarcicaly valued option instance
+ * arg: + const tOptDesc * + odesc + an option with a nested arg type +
+ * arg: + char const * + name + name of value to find +
+ * arg: + char const * + val + the matching value +
+ *
+ * ret_type: const tOptionValue *
+ * ret_desc: a compound value structure
+ *
+ * doc:
+ * This routine will find an entry in a nested value option or configurable.
+ * It will search through the list and return a matching entry.
+ *
+ * err:
+ * The returned result is NULL and errno is set:
+ * @itemize @bullet
+ * @item
+ * @code{EINVAL} - the @code{pOptValue} does not point to a valid
+ * hierarchical option value.
+ * @item
+ * @code{ENOENT} - no entry matched the given name.
+ * @end itemize
+=*/
+const tOptionValue *
+optionFindValue(const tOptDesc * odesc, char const * name, char const * val)
+{
+ const tOptionValue * res = NULL;
+
+ if ( (odesc == NULL)
+ || (OPTST_GET_ARGTYPE(odesc->fOptState) != OPARG_TYPE_HIERARCHY)) {
+ errno = EINVAL;
+ }
+
+ else if (odesc->optCookie == NULL) {
+ errno = ENOENT;
+ }
+
+ else do {
+ tArgList * argl = odesc->optCookie;
+ int argct = argl->useCt;
+ const void ** poptv = VOIDP(argl->apzArgs);
+
+ if (argct == 0) {
+ errno = ENOENT;
+ break;
+ }
+
+ if (name == NULL) {
+ res = (const tOptionValue *)*poptv;
+ break;
+ }
+
+ while (--argct >= 0) {
+ const tOptionValue * ov = *(poptv++);
+ const tOptionValue * rv = optionGetValue(ov, name);
+
+ if (rv == NULL)
+ continue;
+
+ if (val == NULL) {
+ res = ov;
+ break;
+ }
+ }
+ if (res == NULL)
+ errno = ENOENT;
+ } while (false);
+
+ return res;
+}
+
+
+/*=export_func optionFindNextValue
+ *
+ * FIXME: the handling of 'pzName' and 'pzVal' is just wrong.
+ *
+ * what: find a hierarcicaly valued option instance
+ * arg: + const tOptDesc * + odesc + an option with a nested arg type +
+ * arg: + const tOptionValue * + pPrevVal + the last entry +
+ * arg: + char const * + name + name of value to find +
+ * arg: + char const * + value + the matching value +
+ *
+ * ret_type: const tOptionValue *
+ * ret_desc: a compound value structure
+ *
+ * doc:
+ * This routine will find the next entry in a nested value option or
+ * configurable. It will search through the list and return the next entry
+ * that matches the criteria.
+ *
+ * err:
+ * The returned result is NULL and errno is set:
+ * @itemize @bullet
+ * @item
+ * @code{EINVAL} - the @code{pOptValue} does not point to a valid
+ * hierarchical option value.
+ * @item
+ * @code{ENOENT} - no entry matched the given name.
+ * @end itemize
+=*/
+tOptionValue const *
+optionFindNextValue(const tOptDesc * odesc, const tOptionValue * pPrevVal,
+ char const * pzName, char const * pzVal)
+{
+ bool old_found = false;
+ const tOptionValue * res = NULL;
+
+ (void)pzName;
+ (void)pzVal;
+
+ if ( (odesc == NULL)
+ || (OPTST_GET_ARGTYPE(odesc->fOptState) != OPARG_TYPE_HIERARCHY)) {
+ errno = EINVAL;
+ }
+
+ else if (odesc->optCookie == NULL) {
+ errno = ENOENT;
+ }
+
+ else do {
+ tArgList * argl = odesc->optCookie;
+ int ct = argl->useCt;
+ const void ** poptv = VOIDP(argl->apzArgs);
+
+ while (--ct >= 0) {
+ const tOptionValue * pOV = *(poptv++);
+ if (old_found) {
+ res = pOV;
+ break;
+ }
+ if (pOV == pPrevVal)
+ old_found = true;
+ }
+ if (res == NULL)
+ errno = ENOENT;
+ } while (false);
+
+ return res;
+}
+
+
+/*=export_func optionGetValue
+ *
+ * what: get a specific value from a hierarcical list
+ * arg: + const tOptionValue * + pOptValue + a hierarchcal value +
+ * arg: + char const * + valueName + name of value to get +
+ *
+ * ret_type: const tOptionValue *
+ * ret_desc: a compound value structure
+ *
+ * doc:
+ * This routine will find an entry in a nested value option or configurable.
+ * If "valueName" is NULL, then the first entry is returned. Otherwise,
+ * the first entry with a name that exactly matches the argument will be
+ * returned. If there is no matching value, NULL is returned and errno is
+ * set to ENOENT. If the provided option value is not a hierarchical value,
+ * NULL is also returned and errno is set to EINVAL.
+ *
+ * err:
+ * The returned result is NULL and errno is set:
+ * @itemize @bullet
+ * @item
+ * @code{EINVAL} - the @code{pOptValue} does not point to a valid
+ * hierarchical option value.
+ * @item
+ * @code{ENOENT} - no entry matched the given name.
+ * @end itemize
+=*/
+tOptionValue const *
+optionGetValue(tOptionValue const * oov, char const * vname)
+{
+ tArgList * arg_list;
+ const tOptionValue * res = NULL;
+
+ if ((oov == NULL) || (oov->valType != OPARG_TYPE_HIERARCHY)) {
+ errno = EINVAL;
+ return res;
+ }
+ arg_list = oov->v.nestVal;
+
+ if (arg_list->useCt > 0) {
+ int ct = arg_list->useCt;
+ const void ** ovlist = VOIDP(arg_list->apzArgs);
+
+ if (vname == NULL) {
+ res = (const tOptionValue *)*ovlist;
+
+ } else do {
+ const tOptionValue * opt_val = *(ovlist++);
+ if (strcmp(opt_val->pzName, vname) == 0) {
+ res = opt_val;
+ break;
+ }
+ } while (--ct > 0);
+ }
+ if (res == NULL)
+ errno = ENOENT;
+ return res;
+}
+
+/*=export_func optionNextValue
+ *
+ * what: get the next value from a hierarchical list
+ * arg: + const tOptionValue * + pOptValue + a hierarchcal list value +
+ * arg: + const tOptionValue * + pOldValue + a value from this list +
+ *
+ * ret_type: const tOptionValue *
+ * ret_desc: a compound value structure
+ *
+ * doc:
+ * This routine will return the next entry after the entry passed in. At the
+ * end of the list, NULL will be returned. If the entry is not found on the
+ * list, NULL will be returned and "@var{errno}" will be set to EINVAL.
+ * The "@var{pOldValue}" must have been gotten from a prior call to this
+ * routine or to "@code{opitonGetValue()}".
+ *
+ * err:
+ * The returned result is NULL and errno is set:
+ * @itemize @bullet
+ * @item
+ * @code{EINVAL} - the @code{pOptValue} does not point to a valid
+ * hierarchical option value or @code{pOldValue} does not point to a
+ * member of that option value.
+ * @item
+ * @code{ENOENT} - the supplied @code{pOldValue} pointed to the last entry.
+ * @end itemize
+=*/
+tOptionValue const *
+optionNextValue(tOptionValue const * ov_list,tOptionValue const * oov )
+{
+ tArgList * arg_list;
+ const tOptionValue * res = NULL;
+ int err = EINVAL;
+
+ if ((ov_list == NULL) || (ov_list->valType != OPARG_TYPE_HIERARCHY)) {
+ errno = EINVAL;
+ return NULL;
+ }
+ arg_list = ov_list->v.nestVal;
+ {
+ int ct = arg_list->useCt;
+ const void ** o_list = VOIDP(arg_list->apzArgs);
+
+ while (ct-- > 0) {
+ const tOptionValue * nov = *(o_list++);
+ if (nov == oov) {
+ if (ct == 0) {
+ err = ENOENT;
+
+ } else {
+ err = 0;
+ res = (const tOptionValue *)*o_list;
+ }
+ break;
+ }
+ }
+ }
+ if (err != 0)
+ errno = err;
+ return res;
+}
+
+/**
+ * Load a file containing presetting information (a configuration file).
+ */
+static void
+file_preset(tOptions * opts, char const * fname, int dir)
+{
+ tmap_info_t cfgfile;
+ tOptState optst = OPTSTATE_INITIALIZER(PRESET);
+ opt_state_mask_t st_flags = optst.flags;
+ opt_state_mask_t fl_save = opts->fOptSet;
+ char * ftext =
+ text_mmap(fname, PROT_READ|PROT_WRITE, MAP_PRIVATE, &cfgfile);
+
+ if (TEXT_MMAP_FAILED_ADDR(ftext))
+ return;
+
+ /*
+ * While processing config files, we ignore errors.
+ */
+ opts->fOptSet &= ~OPTPROC_ERRSTOP;
+
+ if (dir == DIRECTION_CALLED) {
+ st_flags = OPTST_DEFINED;
+ dir = DIRECTION_PROCESS;
+ }
+
+ /*
+ * IF this is called via "optionProcess", then we are presetting.
+ * This is the default and the PRESETTING bit will be set.
+ * If this is called via "optionFileLoad", then the bit is not set
+ * and we consider stuff set herein to be "set" by the client program.
+ */
+ if ((opts->fOptSet & OPTPROC_PRESETTING) == 0)
+ st_flags = OPTST_SET;
+
+ do {
+ optst.flags = st_flags;
+ ftext = SPN_WHITESPACE_CHARS(ftext);
+
+ if (IS_VAR_FIRST_CHAR(*ftext)) {
+ ftext = handle_cfg(opts, &optst, ftext, dir);
+
+ } else switch (*ftext) {
+ case '<':
+ if (IS_VAR_FIRST_CHAR(ftext[1]))
+ ftext = handle_struct(opts, &optst, ftext, dir);
+
+ else switch (ftext[1]) {
+ case '?':
+ ftext = handle_directive(opts, ftext);
+ break;
+
+ case '!':
+ ftext = handle_comment(ftext);
+ break;
+
+ case '/':
+ ftext = strchr(ftext + 2, '>');
+ if (ftext++ != NULL)
+ break;
+
+ default:
+ ftext = NULL;
+ }
+ if (ftext == NULL)
+ goto all_done;
+ break;
+
+ case '[':
+ ftext = handle_section(opts, ftext);
+ break;
+
+ case '#':
+ ftext = strchr(ftext + 1, NL);
+ break;
+
+ default:
+ goto all_done; /* invalid format */
+ }
+ } while (ftext != NULL);
+
+ all_done:
+ text_munmap(&cfgfile);
+ opts->fOptSet = fl_save;
+}
+
+/**
+ * "txt" points to a "<!" sequence.
+ * Theoretically, we should ensure that it begins with "<!--",
+ * but actually I don't care that much. It ends with "-->".
+ */
+static char *
+handle_comment(char * txt)
+{
+ char * pz = strstr(txt, "-->");
+ if (pz != NULL)
+ pz += 3;
+ return pz;
+}
+
+/**
+ * "txt" points to the start of some value name.
+ * The end of the entry is the end of the line that is not preceded by
+ * a backslash escape character. The string value is always processed
+ * in "cooked" mode.
+ */
+static char *
+handle_cfg(tOptions * opts, tOptState * ost, char * txt, int dir)
+{
+ char * pzName = txt++;
+ char * pzEnd = strchr(txt, NL);
+
+ if (pzEnd == NULL)
+ return txt + strlen(txt);
+
+ txt = SPN_VALUE_NAME_CHARS(txt);
+ txt = SPN_WHITESPACE_CHARS(txt);
+ if (txt > pzEnd) {
+ name_only:
+ *pzEnd++ = NUL;
+ load_opt_line(opts, ost, pzName, dir, OPTION_LOAD_UNCOOKED);
+ return pzEnd;
+ }
+
+ /*
+ * Either the first character after the name is a ':' or '=',
+ * or else we must have skipped over white space. Anything else
+ * is an invalid format and we give up parsing the text.
+ */
+ if ((*txt == '=') || (*txt == ':')) {
+ txt = SPN_WHITESPACE_CHARS(txt+1);
+ if (txt > pzEnd)
+ goto name_only;
+ } else if (! IS_WHITESPACE_CHAR(txt[-1]))
+ return NULL;
+
+ /*
+ * IF the value is continued, remove the backslash escape and push "pzEnd"
+ * on to a newline *not* preceded by a backslash.
+ */
+ if (pzEnd[-1] == '\\') {
+ char * pcD = pzEnd-1;
+ char * pcS = pzEnd;
+
+ for (;;) {
+ char ch = *(pcS++);
+ switch (ch) {
+ case NUL:
+ pcS = NULL;
+ /* FALLTHROUGH */
+
+ case NL:
+ *pcD = NUL;
+ pzEnd = pcS;
+ goto copy_done;
+
+ case '\\':
+ if (*pcS == NL)
+ ch = *(pcS++);
+ /* FALLTHROUGH */
+ default:
+ *(pcD++) = ch;
+ }
+ } copy_done:;
+
+ } else {
+ /*
+ * The newline was not preceded by a backslash. NUL it out
+ */
+ *(pzEnd++) = NUL;
+ }
+
+ /*
+ * "pzName" points to what looks like text for one option/configurable.
+ * It is NUL terminated. Process it.
+ */
+ load_opt_line(opts, ost, pzName, dir, OPTION_LOAD_UNCOOKED);
+
+ return pzEnd;
+}
+
+/**
+ * "txt" points to a "<?" sequence.
+ * We handle "<?program" and "<?auto-options" directives.
+ * All others are treated as comments.
+ *
+ * @param[in,out] opts program option descriptor
+ * @param[in] txt scanning pointer
+ * @returns the next character to look at
+ */
+static char *
+handle_directive(tOptions * opts, char * txt)
+{
+# define DIRECTIVE_TABLE \
+ _dt_(zCfgProg, program_directive) \
+ _dt_(zCfgAO_Flags, aoflags_directive)
+
+ typedef char * (directive_func_t)(tOptions *, char *);
+# define _dt_(_s, _fn) _fn,
+ static directive_func_t * dir_disp[] = {
+ DIRECTIVE_TABLE
+ };
+# undef _dt_
+
+# define _dt_(_s, _fn) 1 +
+ static int const dir_ct = DIRECTIVE_TABLE 0;
+ static char const * dir_names[DIRECTIVE_TABLE 0];
+# undef _dt_
+
+ int ix;
+
+ if (dir_names[0] == NULL) {
+ ix = 0;
+# define _dt_(_s, _fn) dir_names[ix++] = _s;
+ DIRECTIVE_TABLE;
+# undef _dt_
+ }
+
+ for (ix = 0; ix < dir_ct; ix++) {
+ size_t len = strlen(dir_names[ix]);
+ if ( (strncmp(txt + 2, dir_names[ix], len) == 0)
+ && (! IS_VALUE_NAME_CHAR(txt[len+2])) )
+ return dir_disp[ix](opts, txt + len + 2);
+ }
+
+ /*
+ * We don't know what this is. Skip it.
+ */
+ txt = strchr(txt+2, '>');
+ if (txt != NULL)
+ txt++;
+ return txt;
+# undef DIRECTIVE_TABLE
+}
+
+/**
+ * handle AutoOpts mode flags.
+ *
+ * @param[in,out] opts program option descriptor
+ * @param[in] txt scanning pointer
+ * @returns the next character to look at
+ */
+static char *
+aoflags_directive(tOptions * opts, char * txt)
+{
+ char * pz;
+
+ pz = SPN_WHITESPACE_CHARS(txt+1);
+ txt = strchr(pz, '>');
+ if (txt != NULL) {
+
+ size_t len = (unsigned)(txt - pz);
+ char * ftxt = AGALOC(len + 1, "aoflags");
+
+ memcpy(ftxt, pz, len);
+ ftxt[len] = NUL;
+ set_usage_flags(opts, ftxt);
+ AGFREE(ftxt);
+
+ txt++;
+ }
+
+ return txt;
+}
+
+/**
+ * handle program segmentation of config file.
+ *
+ * @param[in,out] opts program option descriptor
+ * @param[in] txt scanning pointer
+ * @returns the next character to look at
+ */
+static char *
+program_directive(tOptions * opts, char * txt)
+{
+ static char const ttlfmt[] = "<?";
+ size_t ttl_len = sizeof(ttlfmt) + strlen(zCfgProg);
+ char * ttl = AGALOC(ttl_len, "prog title");
+ size_t name_len = strlen(opts->pzProgName);
+
+ memcpy(ttl, ttlfmt, sizeof(ttlfmt) - 1);
+ memcpy(ttl + sizeof(ttlfmt) - 1, zCfgProg, ttl_len - (sizeof(ttlfmt) - 1));
+
+ do {
+ txt = SPN_WHITESPACE_CHARS(txt+1);
+
+ if ( (strneqvcmp(txt, opts->pzProgName, (int)name_len) == 0)
+ && (IS_END_XML_TOKEN_CHAR(txt[name_len])) ) {
+ txt += name_len;
+ break;
+ }
+
+ txt = strstr(txt, ttl);
+ } while (txt != NULL);
+
+ AGFREE(ttl);
+ if (txt != NULL)
+ for (;;) {
+ if (*txt == NUL) {
+ txt = NULL;
+ break;
+ }
+ if (*(txt++) == '>')
+ break;
+ }
+
+ return txt;
+}
+
+/**
+ * "txt" points to a '[' character.
+ * The "traditional" [PROG_NAME] segmentation of the config file.
+ * Do not ever mix with the "<?program prog-name>" variation.
+ *
+ * @param[in,out] opts program option descriptor
+ * @param[in] txt scanning pointer
+ * @returns the next character to look at
+ */
+static char *
+handle_section(tOptions * opts, char * txt)
+{
+ size_t len = strlen(opts->pzPROGNAME);
+ if ( (strncmp(txt+1, opts->pzPROGNAME, len) == 0)
+ && (txt[len+1] == ']'))
+ return strchr(txt + len + 2, NL);
+
+ if (len > 16)
+ return NULL;
+
+ {
+ char z[24];
+ sprintf(z, "[%s]", opts->pzPROGNAME);
+ txt = strstr(txt, z);
+ }
+
+ if (txt != NULL)
+ txt = strchr(txt, NL);
+ return txt;
+}
+
+/**
+ * parse XML encodings
+ */
+static int
+parse_xml_encoding(char ** ppz)
+{
+# define XMLTABLE \
+ _xmlNm_(amp, '&') \
+ _xmlNm_(lt, '<') \
+ _xmlNm_(gt, '>') \
+ _xmlNm_(ff, '\f') \
+ _xmlNm_(ht, '\t') \
+ _xmlNm_(cr, '\r') \
+ _xmlNm_(vt, '\v') \
+ _xmlNm_(bel, '\a') \
+ _xmlNm_(nl, NL) \
+ _xmlNm_(space, ' ') \
+ _xmlNm_(quot, '"') \
+ _xmlNm_(apos, '\'')
+
+ static struct {
+ char const * const nm_str;
+ unsigned short nm_len;
+ short nm_val;
+ } const xml_names[] = {
+# define _xmlNm_(_n, _v) { #_n ";", sizeof(#_n), _v },
+ XMLTABLE
+# undef _xmlNm_
+# undef XMLTABLE
+ };
+
+ static int const nm_ct = sizeof(xml_names) / sizeof(xml_names[0]);
+ int base = 10;
+
+ char * pz = *ppz;
+
+ if (*pz == '#') {
+ pz++;
+ goto parse_number;
+ }
+
+ if (IS_DEC_DIGIT_CHAR(*pz)) {
+ unsigned long v;
+
+ parse_number:
+ switch (*pz) {
+ case 'x': case 'X':
+ /*
+ * Some forms specify hex with: &#xNN;
+ */
+ base = 16;
+ pz++;
+ break;
+
+ case '0':
+ /*
+ * &#0022; is hex and &#22; is decimal. Cool.
+ * Ya gotta love it.
+ */
+ if (pz[1] == '0')
+ base = 16;
+ break;
+ }
+
+ v = strtoul(pz, &pz, base);
+ if ((*pz != ';') || (v > 0x7F))
+ return NUL;
+ *ppz = pz + 1;
+ return (int)v;
+ }
+
+ {
+ int ix = 0;
+ do {
+ if (strncmp(pz, xml_names[ix].nm_str, xml_names[ix].nm_len)
+ == 0) {
+ *ppz = pz + xml_names[ix].nm_len;
+ return xml_names[ix].nm_val;
+ }
+ } while (++ix < nm_ct);
+ }
+
+ return NUL;
+}
+
+/**
+ * Find the end marker for the named section of XML.
+ * Trim that text there, trimming trailing white space for all modes
+ * except for OPTION_LOAD_UNCOOKED.
+ */
+static char *
+trim_xml_text(char * intxt, char const * pznm, tOptionLoadMode mode)
+{
+ static char const fmt[] = "</%s>";
+ size_t len = strlen(pznm) + sizeof(fmt) - 2 /* for %s */;
+ char * etext;
+
+ {
+ char z[64], *pz = z;
+ if (len >= sizeof(z))
+ pz = AGALOC(len, "scan name");
+
+ len = (size_t)sprintf(pz, fmt, pznm);
+ *intxt = ' ';
+ etext = strstr(intxt, pz);
+ if (pz != z) AGFREE(pz);
+ }
+
+ if (etext == NULL)
+ return etext;
+
+ {
+ char * result = etext + len;
+
+ if (mode != OPTION_LOAD_UNCOOKED)
+ etext = SPN_WHITESPACE_BACK(intxt, etext);
+
+ *etext = NUL;
+ return result;
+ }
+}
+
+/**
+ */
+static void
+cook_xml_text(char * pzData)
+{
+ char * pzs = pzData;
+ char * pzd = pzData;
+ char bf[4];
+ bf[2] = NUL;
+
+ for (;;) {
+ int ch = ((int)*(pzs++)) & 0xFF;
+ switch (ch) {
+ case NUL:
+ *pzd = NUL;
+ return;
+
+ case '&':
+ ch = parse_xml_encoding(&pzs);
+ *(pzd++) = (char)ch;
+ if (ch == NUL)
+ return;
+ break;
+
+ case '%':
+ bf[0] = *(pzs++);
+ bf[1] = *(pzs++);
+ if ((bf[0] == NUL) || (bf[1] == NUL)) {
+ *pzd = NUL;
+ return;
+ }
+
+ ch = (int)strtoul(bf, NULL, 16);
+ /* FALLTHROUGH */
+
+ default:
+ *(pzd++) = (char)ch;
+ }
+ }
+}
+
+/**
+ * "txt" points to a '<' character, followed by an alpha.
+ * The end of the entry is either the "/>" following the name, or else a
+ * "</name>" string.
+ */
+static char *
+handle_struct(tOptions * opts, tOptState * ost, char * txt, int dir)
+{
+ tOptionLoadMode mode = option_load_mode;
+ tOptionValue valu;
+
+ char * pzName = ++txt;
+ char * pzData;
+ char * pcNulPoint;
+
+ txt = SPN_VALUE_NAME_CHARS(txt);
+ pcNulPoint = txt;
+ valu.valType = OPARG_TYPE_STRING;
+
+ switch (*txt) {
+ case ' ':
+ case '\t':
+ txt = VOIDP(parse_attrs(
+ opts, SPN_WHITESPACE_CHARS(txt), &mode, &valu));
+ if (txt == NULL)
+ return txt;
+ if (*txt == '>')
+ break;
+ if (*txt != '/')
+ return NULL;
+ /* FALLTHROUGH */
+
+ case '/':
+ if (txt[1] != '>')
+ return NULL;
+ *txt = NUL;
+ txt += 2;
+ load_opt_line(opts, ost, pzName, dir, mode);
+ return txt;
+
+ case '>':
+ break;
+
+ default:
+ txt = strchr(txt, '>');
+ if (txt != NULL)
+ txt++;
+ return txt;
+ }
+
+ /*
+ * If we are here, we have a value. "txt" points to a closing angle
+ * bracket. Separate the name from the value for a moment.
+ */
+ *pcNulPoint = NUL;
+ pzData = ++txt;
+ txt = trim_xml_text(txt, pzName, mode);
+ if (txt == NULL)
+ return txt;
+
+ /*
+ * Rejoin the name and value for parsing by "load_opt_line()".
+ * Erase any attributes parsed by "parse_attrs()".
+ */
+ memset(pcNulPoint, ' ', (size_t)(pzData - pcNulPoint));
+
+ /*
+ * If we are getting a "string" value that is to be cooked,
+ * then process the XML-ish &xx; XML-ish and %XX hex characters.
+ */
+ if ( (valu.valType == OPARG_TYPE_STRING)
+ && (mode == OPTION_LOAD_COOKED))
+ cook_xml_text(pzData);
+
+ /*
+ * "pzName" points to what looks like text for one option/configurable.
+ * It is NUL terminated. Process it.
+ */
+ load_opt_line(opts, ost, pzName, dir, mode);
+
+ return txt;
+}
+
+/**
+ * Load a configuration file. This may be invoked either from
+ * scanning the "homerc" list, or from a specific file request.
+ * (see "optionFileLoad()", the implementation for --load-opts)
+ */
+LOCAL void
+intern_file_load(tOptions * opts)
+{
+ uint32_t svfl;
+ int idx;
+ int inc;
+ char f_name[ AG_PATH_MAX+1 ];
+
+ if (opts->papzHomeList == NULL)
+ return;
+
+ svfl = opts->fOptSet;
+ inc = DIRECTION_PRESET;
+
+ /*
+ * Never stop on errors in config files.
+ */
+ opts->fOptSet &= ~OPTPROC_ERRSTOP;
+
+ /*
+ * Find the last RC entry (highest priority entry)
+ */
+ for (idx = 0; opts->papzHomeList[ idx+1 ] != NULL; ++idx) ;
+
+ /*
+ * For every path in the home list, ... *TWICE* We start at the last
+ * (highest priority) entry, work our way down to the lowest priority,
+ * handling the immediate options.
+ * Then we go back up, doing the normal options.
+ */
+ for (;;) {
+ struct stat sb;
+ cch_t * path;
+
+ /*
+ * IF we've reached the bottom end, change direction
+ */
+ if (idx < 0) {
+ inc = DIRECTION_PROCESS;
+ idx = 0;
+ }
+
+ path = opts->papzHomeList[ idx ];
+
+ /*
+ * IF we've reached the top end, bail out
+ */
+ if (path == NULL)
+ break;
+
+ idx += inc;
+
+ if (! optionMakePath(f_name, (int)sizeof(f_name),
+ path, opts->pzProgPath))
+ continue;
+
+ /*
+ * IF the file name we constructed is a directory,
+ * THEN append the Resource Configuration file name
+ * ELSE we must have the complete file name
+ */
+ if (stat(f_name, &sb) != 0)
+ continue; /* bogus name - skip the home list entry */
+
+ if (S_ISDIR(sb.st_mode)) {
+ size_t len = strlen(f_name);
+ size_t nln = strlen(opts->pzRcName) + 1;
+ char * pz = f_name + len;
+
+ if (len + 1 + nln >= sizeof(f_name))
+ continue;
+
+ if (pz[-1] != DIRCH)
+ *(pz++) = DIRCH;
+ memcpy(pz, opts->pzRcName, nln);
+ }
+
+ file_preset(opts, f_name, inc);
+
+ /*
+ * IF we are now to skip config files AND we are presetting,
+ * THEN change direction. We must go the other way.
+ */
+ {
+ tOptDesc * od = opts->pOptDesc + opts->specOptIdx.save_opts + 1;
+ if (DISABLED_OPT(od) && PRESETTING(inc)) {
+ idx -= inc; /* go back and reprocess current file */
+ inc = DIRECTION_PROCESS;
+ }
+ }
+ } /* twice for every path in the home list, ... */
+
+ opts->fOptSet = svfl;
+}
+
+/*=export_func optionFileLoad
+ *
+ * what: Load the locatable config files, in order
+ *
+ * arg: + tOptions * + opts + program options descriptor +
+ * arg: + char const * + prog + program name +
+ *
+ * ret_type: int
+ * ret_desc: 0 -> SUCCESS, -1 -> FAILURE
+ *
+ * doc:
+ *
+ * This function looks in all the specified directories for a configuration
+ * file ("rc" file or "ini" file) and processes any found twice. The first
+ * time through, they are processed in reverse order (last file first). At
+ * that time, only "immediate action" configurables are processed. For
+ * example, if the last named file specifies not processing any more
+ * configuration files, then no more configuration files will be processed.
+ * Such an option in the @strong{first} named directory will have no effect.
+ *
+ * Once the immediate action configurables have been handled, then the
+ * directories are handled in normal, forward order. In that way, later
+ * config files can override the settings of earlier config files.
+ *
+ * See the AutoOpts documentation for a thorough discussion of the
+ * config file format.
+ *
+ * Configuration files not found or not decipherable are simply ignored.
+ *
+ * err: Returns the value, "-1" if the program options descriptor
+ * is out of date or indecipherable. Otherwise, the value "0" will
+ * always be returned.
+=*/
+int
+optionFileLoad(tOptions * opts, char const * prog)
+{
+ if (! SUCCESSFUL(validate_struct(opts, prog)))
+ return -1;
+
+ /*
+ * The pointer to the program name is "const". However, the
+ * structure is in writable memory, so we coerce the address
+ * of this pointer to point to writable memory.
+ */
+ {
+ char const ** pp = VOIDP(&(opts->pzProgName));
+ *pp = prog;
+ }
+
+ intern_file_load(opts);
+ return 0;
+}
+
+/*=export_func optionLoadOpt
+ * private:
+ *
+ * what: Load an option rc/ini file
+ * arg: + tOptions * + opts + program options descriptor +
+ * arg: + tOptDesc * + odesc + the descriptor for this arg +
+ *
+ * doc:
+ * Processes the options found in the file named with
+ * odesc->optArg.argString.
+=*/
+void
+optionLoadOpt(tOptions * opts, tOptDesc * odesc)
+{
+ struct stat sb;
+
+ if (opts <= OPTPROC_EMIT_LIMIT)
+ return;
+
+ /*
+ * IF the option is not being disabled, THEN load the file. There must
+ * be a file. (If it is being disabled, then the disablement processing
+ * already took place. It must be done to suppress preloading of ini/rc
+ * files.)
+ */
+ if ( DISABLED_OPT(odesc)
+ || ((odesc->fOptState & OPTST_RESET) != 0))
+ return;
+
+ if (stat(odesc->optArg.argString, &sb) != 0) {
+ if ((opts->fOptSet & OPTPROC_ERRSTOP) == 0)
+ return;
+
+ fserr_exit(opts->pzProgName, "stat", odesc->optArg.argString);
+ /* NOT REACHED */
+ }
+
+ if (! S_ISREG(sb.st_mode)) {
+ if ((opts->fOptSet & OPTPROC_ERRSTOP) == 0)
+ return;
+ errno = EINVAL;
+ fserr_exit(opts->pzProgName, "stat", odesc->optArg.argString);
+ /* NOT REACHED */
+ }
+
+ file_preset(opts, odesc->optArg.argString, DIRECTION_CALLED);
+}
+
+/**
+ * Parse the various attributes of an XML-styled config file entry
+ *
+ * @returns NULL on failure, otherwise the scan point
+ */
+LOCAL char const *
+parse_attrs(tOptions * opts, char const * txt, tOptionLoadMode * pMode,
+ tOptionValue * pType)
+{
+ size_t len = 0;
+
+ for (;;) {
+ len = (size_t)(SPN_LOWER_CASE_CHARS(txt) - txt);
+
+ /*
+ * The enumeration used in this switch is derived from this switch
+ * statement itself. The "find_option_xat_attribute_cmd" function
+ * will return XAT_CMD_MEMBERS for the "txt" string value
+ * "members", etc.
+ */
+ switch (find_option_xat_attribute_cmd(txt, len)) {
+ case XAT_CMD_TYPE:
+ txt = parse_value(txt+len, pType);
+ break;
+
+ case XAT_CMD_WORDS:
+ txt = parse_keyword(opts, txt+len, pType);
+ break;
+
+ case XAT_CMD_MEMBERS:
+ txt = parse_set_mem(opts, txt+len, pType);
+ break;
+
+ case XAT_CMD_COOKED:
+ txt += len;
+ if (! IS_END_XML_TOKEN_CHAR(*txt))
+ goto invalid_kwd;
+
+ *pMode = OPTION_LOAD_COOKED;
+ break;
+
+ case XAT_CMD_UNCOOKED:
+ txt += len;
+ if (! IS_END_XML_TOKEN_CHAR(*txt))
+ goto invalid_kwd;
+
+ *pMode = OPTION_LOAD_UNCOOKED;
+ break;
+
+ case XAT_CMD_KEEP:
+ txt += len;
+ if (! IS_END_XML_TOKEN_CHAR(*txt))
+ goto invalid_kwd;
+
+ *pMode = OPTION_LOAD_KEEP;
+ break;
+
+ default:
+ case XAT_INVALID_CMD:
+ invalid_kwd:
+ pType->valType = OPARG_TYPE_NONE;
+ return skip_unkn(txt);
+ }
+
+ if (txt == NULL)
+ return NULL;
+ txt = SPN_WHITESPACE_CHARS(txt);
+ switch (*txt) {
+ case '/': pType->valType = OPARG_TYPE_NONE;
+ /* FALLTHROUGH */
+ case '>': return txt;
+ }
+ if (! IS_LOWER_CASE_CHAR(*txt))
+ return NULL;
+ }
+}
+
+/**
+ * "txt" points to the character after "words=".
+ * What should follow is a name of a keyword (enumeration) list.
+ *
+ * @param opts unused
+ * @param[in] txt keyword to skip over
+ * @param type unused value type
+ * @returns pointer after skipped text
+ */
+static char const *
+parse_keyword(tOptions * opts, char const * txt, tOptionValue * typ)
+{
+ (void)opts;
+ (void)typ;
+
+ return skip_unkn(txt);
+}
+
+/**
+ * "txt" points to the character after "members="
+ * What should follow is a name of a "set membership".
+ * A collection of bit flags.
+ *
+ * @param opts unused
+ * @param[in] txt keyword to skip over
+ * @param type unused value type
+ * @returns pointer after skipped text
+ */
+static char const *
+parse_set_mem(tOptions * opts, char const * txt, tOptionValue * typ)
+{
+ (void)opts;
+ (void)typ;
+
+ return skip_unkn(txt);
+}
+
+/**
+ * parse the type. The keyword "type" was found, now figure out
+ * the type that follows the type.
+ *
+ * @param[in] txt points to the '=' character after the "type" keyword.
+ * @param[out] typ where to store the type found
+ * @returns the next byte after the type name
+ */
+static char const *
+parse_value(char const * txt, tOptionValue * typ)
+{
+ size_t len = 0;
+
+ if (*(txt++) != '=')
+ goto woops;
+
+ len = (size_t)(SPN_OPTION_NAME_CHARS(txt) - txt);
+
+ if ((len == 0) || (! IS_END_XML_TOKEN_CHAR(txt[len]))) {
+ woops:
+ typ->valType = OPARG_TYPE_NONE;
+ return skip_unkn(txt + len);
+ }
+
+ /*
+ * The enumeration used in this switch is derived from this switch
+ * statement itself. The "find_option_value_type_cmd" function
+ * will return VTP_CMD_INTEGER for the "txt" string value
+ * "integer", etc.
+ */
+ switch (find_option_value_type_cmd(txt, len)) {
+ default:
+ case VTP_INVALID_CMD: goto woops;
+
+ case VTP_CMD_STRING:
+ typ->valType = OPARG_TYPE_STRING;
+ break;
+
+ case VTP_CMD_INTEGER:
+ typ->valType = OPARG_TYPE_NUMERIC;
+ break;
+
+ case VTP_CMD_BOOL:
+ case VTP_CMD_BOOLEAN:
+ typ->valType = OPARG_TYPE_BOOLEAN;
+ break;
+
+ case VTP_CMD_KEYWORD:
+ typ->valType = OPARG_TYPE_ENUMERATION;
+ break;
+
+ case VTP_CMD_SET:
+ case VTP_CMD_SET_MEMBERSHIP:
+ typ->valType = OPARG_TYPE_MEMBERSHIP;
+ break;
+
+ case VTP_CMD_NESTED:
+ case VTP_CMD_HIERARCHY:
+ typ->valType = OPARG_TYPE_HIERARCHY;
+ }
+
+ return txt + len;
+}
+
+/** @}
+ *
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of autoopts/configfile.c */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/cook.c b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/cook.c
new file mode 100644
index 0000000..65260a2
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/cook.c
@@ -0,0 +1,325 @@
+/**
+ * \file cook.c
+ *
+ * This file contains the routines that deal with processing quoted strings
+ * into an internal format.
+ *
+ * @addtogroup autoopts
+ * @{
+ */
+/*
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
+ *
+ * AutoOpts is available under any one of two licenses. The license
+ * in use must be one of these two and the choice is under the control
+ * of the user of the license.
+ *
+ * The GNU Lesser General Public License, version 3 or later
+ * See the files "COPYING.lgplv3" and "COPYING.gplv3"
+ *
+ * The Modified Berkeley Software Distribution License
+ * See the file "COPYING.mbsd"
+ *
+ * These files have the following sha256 sums:
+ *
+ * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
+ * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
+ * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
+ */
+
+/* = = = START-STATIC-FORWARD = = = */
+static bool
+contiguous_quote(char ** pps, char * pq, int * lnct_p);
+/* = = = END-STATIC-FORWARD = = = */
+
+/*=export_func ao_string_cook_escape_char
+ * private:
+ *
+ * what: escape-process a string fragment
+ * arg: + char const * + pzScan + points to character after the escape +
+ * arg: + char * + pRes + Where to put the result byte +
+ * arg: + unsigned int + nl_ch + replacement char if scanned char is \n +
+ *
+ * ret-type: unsigned int
+ * ret-desc: The number of bytes consumed processing the escaped character.
+ *
+ * doc:
+ *
+ * This function converts "t" into "\t" and all your other favorite
+ * escapes, including numeric ones: hex and ocatal, too.
+ * The returned result tells the caller how far to advance the
+ * scan pointer (passed in). The default is to just pass through the
+ * escaped character and advance the scan by one.
+ *
+ * Some applications need to keep an escaped newline, others need to
+ * suppress it. This is accomplished by supplying a '\n' replacement
+ * character that is different from \n, if need be. For example, use
+ * 0x7F and never emit a 0x7F.
+ *
+ * err: @code{NULL} is returned if the string is mal-formed.
+=*/
+unsigned int
+ao_string_cook_escape_char(char const * pzIn, char * pRes, uint_t nl)
+{
+ unsigned int res = 1;
+
+ switch (*pRes = *pzIn++) {
+ case NUL: /* NUL - end of input string */
+ return 0;
+ case '\r':
+ if (*pzIn != NL)
+ return 1;
+ res++;
+ /* FALLTHROUGH */
+ case NL: /* NL - emit newline */
+ *pRes = (char)nl;
+ return res;
+
+ case 'a': *pRes = '\a'; break;
+ case 'b': *pRes = '\b'; break;
+ case 'f': *pRes = '\f'; break;
+ case 'n': *pRes = NL; break;
+ case 'r': *pRes = '\r'; break;
+ case 't': *pRes = '\t'; break;
+ case 'v': *pRes = '\v'; break;
+
+ case 'x':
+ case 'X': /* HEX Escape */
+ if (IS_HEX_DIGIT_CHAR(*pzIn)) {
+ char z[4];
+ unsigned int ct = 0;
+
+ do {
+ z[ct] = pzIn[ct];
+ if (++ct >= 2)
+ break;
+ } while (IS_HEX_DIGIT_CHAR(pzIn[ct]));
+ z[ct] = NUL;
+ *pRes = (char)strtoul(z, NULL, 16);
+ return ct + 1;
+ }
+ break;
+
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ {
+ /*
+ * IF the character copied was an octal digit,
+ * THEN set the output character to an octal value.
+ * The 3 octal digit result might exceed 0xFF, so check it.
+ */
+ char z[4];
+ unsigned long val;
+ unsigned int ct = 0;
+
+ z[ct++] = *--pzIn;
+ while (IS_OCT_DIGIT_CHAR(pzIn[ct])) {
+ z[ct] = pzIn[ct];
+ if (++ct >= 3)
+ break;
+ }
+
+ z[ct] = NUL;
+ val = strtoul(z, NULL, 8);
+ if (val > 0xFF)
+ val = 0xFF;
+ *pRes = (char)val;
+ return ct;
+ }
+
+ default: /* quoted character is result character */;
+ }
+
+ return res;
+}
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * A quoted string has been found.
+ * Find the end of it and compress any escape sequences.
+ */
+static bool
+contiguous_quote(char ** pps, char * pq, int * lnct_p)
+{
+ char * ps = *pps + 1;
+
+ for (;;) {
+ while (IS_WHITESPACE_CHAR(*ps))
+ if (*(ps++) == NL)
+ (*lnct_p)++;
+
+ /*
+ * IF the next character is a quote character,
+ * THEN we will concatenate the strings.
+ */
+ switch (*ps) {
+ case '"':
+ case '\'':
+ *pq = *(ps++); /* assign new quote character and return */
+ *pps = ps;
+ return true;
+
+ case '/':
+ /*
+ * Allow for a comment embedded in the concatenated string.
+ */
+ switch (ps[1]) {
+ default:
+ *pps = NULL;
+ return false;
+
+ case '/':
+ /*
+ * Skip to end of line
+ */
+ ps = strchr(ps, NL);
+ if (ps == NULL) {
+ *pps = NULL;
+ return false;
+ }
+ break;
+
+ case '*':
+ {
+ char * p = strstr( ps+2, "*/" );
+ /*
+ * Skip to terminating star slash
+ */
+ if (p == NULL) {
+ *pps = NULL;
+ return false;
+ }
+
+ while (ps < p) {
+ if (*(ps++) == NL)
+ (*lnct_p)++;
+ }
+
+ ps = p + 2;
+ }
+ }
+ continue;
+
+ default:
+ /*
+ * The next non-whitespace character is not a quote.
+ * The series of quoted strings has come to an end.
+ */
+ *pps = ps;
+ return false;
+ }
+ }
+}
+
+/*=export_func ao_string_cook
+ * private:
+ *
+ * what: concatenate and escape-process strings
+ * arg: + char * + pzScan + The *MODIFIABLE* input buffer +
+ * arg: + int * + lnct_p + The (possibly NULL) pointer to a line count +
+ *
+ * ret-type: char *
+ * ret-desc: The address of the text following the processed strings.
+ * The return value is NULL if the strings are ill-formed.
+ *
+ * doc:
+ *
+ * A series of one or more quoted strings are concatenated together.
+ * If they are quoted with double quotes (@code{"}), then backslash
+ * escapes are processed per the C programming language. If they are
+ * single quote strings, then the backslashes are honored only when they
+ * precede another backslash or a single quote character.
+ *
+ * err: @code{NULL} is returned if the string(s) is/are mal-formed.
+=*/
+char *
+ao_string_cook(char * pzScan, int * lnct_p)
+{
+ int l = 0;
+ char q = *pzScan;
+
+ /*
+ * It is a quoted string. Process the escape sequence characters
+ * (in the set "abfnrtv") and make sure we find a closing quote.
+ */
+ char * pzD = pzScan++;
+ char * pzS = pzScan;
+
+ if (lnct_p == NULL)
+ lnct_p = &l;
+
+ for (;;) {
+ /*
+ * IF the next character is the quote character, THEN we may end the
+ * string. We end it unless the next non-blank character *after* the
+ * string happens to also be a quote. If it is, then we will change
+ * our quote character to the new quote character and continue
+ * condensing text.
+ */
+ while (*pzS == q) {
+ *pzD = NUL; /* This is probably the end of the line */
+ if (! contiguous_quote(&pzS, &q, lnct_p))
+ return pzS;
+ }
+
+ /*
+ * We are inside a quoted string. Copy text.
+ */
+ switch (*(pzD++) = *(pzS++)) {
+ case NUL:
+ return NULL;
+
+ case NL:
+ (*lnct_p)++;
+ break;
+
+ case '\\':
+ /*
+ * IF we are escaping a new line,
+ * THEN drop both the escape and the newline from
+ * the result string.
+ */
+ if (*pzS == NL) {
+ pzS++;
+ pzD--;
+ (*lnct_p)++;
+ }
+
+ /*
+ * ELSE IF the quote character is '"' or '`',
+ * THEN we do the full escape character processing
+ */
+ else if (q != '\'') {
+ unsigned int ct;
+ ct = ao_string_cook_escape_char(pzS, pzD-1, (uint_t)NL);
+ if (ct == 0)
+ return NULL;
+
+ pzS += ct;
+ } /* if (q != '\'') */
+
+ /*
+ * OTHERWISE, we only process "\\", "\'" and "\#" sequences.
+ * The latter only to easily hide preprocessing directives.
+ */
+ else switch (*pzS) {
+ case '\\':
+ case '\'':
+ case '#':
+ pzD[-1] = *pzS++;
+ }
+ } /* switch (*(pzD++) = *(pzS++)) */
+ } /* for (;;) */
+}
+
+/** @}
+ *
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of autoopts/cook.c */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/enum.c b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/enum.c
new file mode 100644
index 0000000..e9bba83
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/enum.c
@@ -0,0 +1,652 @@
+
+/**
+ * \file enumeration.c
+ *
+ * Handle options with enumeration names and bit mask bit names
+ * for their arguments.
+ *
+ * @addtogroup autoopts
+ * @{
+ */
+/*
+ * This routine will run run-on options through a pager so the
+ * user may examine, print or edit them at their leisure.
+ *
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
+ *
+ * AutoOpts is available under any one of two licenses. The license
+ * in use must be one of these two and the choice is under the control
+ * of the user of the license.
+ *
+ * The GNU Lesser General Public License, version 3 or later
+ * See the files "COPYING.lgplv3" and "COPYING.gplv3"
+ *
+ * The Modified Berkeley Software Distribution License
+ * See the file "COPYING.mbsd"
+ *
+ * These files have the following sha256 sums:
+ *
+ * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
+ * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
+ * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
+ */
+
+/* = = = START-STATIC-FORWARD = = = */
+static void
+enum_err(tOptions * pOpts, tOptDesc * pOD,
+ char const * const * paz_names, int name_ct);
+
+static uintptr_t
+find_name(char const * name, tOptions * pOpts, tOptDesc * pOD,
+ char const * const * paz_names, unsigned int name_ct);
+
+static void
+set_memb_shell(tOptions * pOpts, tOptDesc * pOD, char const * const * paz_names,
+ unsigned int name_ct);
+
+static void
+set_memb_names(tOptions * opts, tOptDesc * od, char const * const * nm_list,
+ unsigned int nm_ct);
+
+static uintptr_t
+check_membership_start(tOptDesc * od, char const ** argp, bool * invert);
+
+static uintptr_t
+find_member_bit(tOptions * opts, tOptDesc * od, char const * pz, int len,
+ char const * const * nm_list, unsigned int nm_ct);
+/* = = = END-STATIC-FORWARD = = = */
+
+static void
+enum_err(tOptions * pOpts, tOptDesc * pOD,
+ char const * const * paz_names, int name_ct)
+{
+ size_t max_len = 0;
+ size_t ttl_len = 0;
+ int ct_down = name_ct;
+ int hidden = 0;
+
+ /*
+ * A real "pOpts" pointer means someone messed up. Give a real error.
+ */
+ if (pOpts > OPTPROC_EMIT_LIMIT)
+ fprintf(option_usage_fp, pz_enum_err_fmt, pOpts->pzProgName,
+ pOD->optArg.argString, pOD->pz_Name);
+
+ fprintf(option_usage_fp, zValidKeys, pOD->pz_Name);
+
+ /*
+ * If the first name starts with this funny character, then we have
+ * a first value with an unspellable name. You cannot specify it.
+ * So, we don't list it either.
+ */
+ if (**paz_names == 0x7F) {
+ paz_names++;
+ hidden = 1;
+ ct_down = --name_ct;
+ }
+
+ /*
+ * Figure out the maximum length of any name, plus the total length
+ * of all the names.
+ */
+ {
+ char const * const * paz = paz_names;
+
+ do {
+ size_t len = strlen(*(paz++)) + 1;
+ if (len > max_len)
+ max_len = len;
+ ttl_len += len;
+ } while (--ct_down > 0);
+
+ ct_down = name_ct;
+ }
+
+ /*
+ * IF any one entry is about 1/2 line or longer, print one per line
+ */
+ if (max_len > 35) {
+ do {
+ fprintf(option_usage_fp, ENUM_ERR_LINE, *(paz_names++));
+ } while (--ct_down > 0);
+ }
+
+ /*
+ * ELSE IF they all fit on one line, then do so.
+ */
+ else if (ttl_len < 76) {
+ fputc(' ', option_usage_fp);
+ do {
+ fputc(' ', option_usage_fp);
+ fputs(*(paz_names++), option_usage_fp);
+ } while (--ct_down > 0);
+ fputc(NL, option_usage_fp);
+ }
+
+ /*
+ * Otherwise, columnize the output
+ */
+ else {
+ unsigned int ent_no = 0;
+ char zFmt[16]; /* format for all-but-last entries on a line */
+
+ sprintf(zFmt, ENUM_ERR_WIDTH, (int)max_len);
+ max_len = 78 / max_len; /* max_len is now max entries on a line */
+ fputs(TWO_SPACES_STR, option_usage_fp);
+
+ /*
+ * Loop through all but the last entry
+ */
+ ct_down = name_ct;
+ while (--ct_down > 0) {
+ if (++ent_no == max_len) {
+ /*
+ * Last entry on a line. Start next line, too.
+ */
+ fprintf(option_usage_fp, NLSTR_SPACE_FMT, *(paz_names++));
+ ent_no = 0;
+ }
+
+ else
+ fprintf(option_usage_fp, zFmt, *(paz_names++) );
+ }
+ fprintf(option_usage_fp, NLSTR_FMT, *paz_names);
+ }
+
+ if (pOpts > OPTPROC_EMIT_LIMIT) {
+ fprintf(option_usage_fp, zIntRange, hidden, name_ct - 1 + hidden);
+
+ (*(pOpts->pUsageProc))(pOpts, EXIT_FAILURE);
+ /* NOTREACHED */
+ }
+
+ if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_MEMBERSHIP) {
+ fprintf(option_usage_fp, zLowerBits, name_ct);
+ fputs(zSetMemberSettings, option_usage_fp);
+ } else {
+ fprintf(option_usage_fp, zIntRange, hidden, name_ct - 1 + hidden);
+ }
+}
+
+/**
+ * Convert a name or number into a binary number.
+ * "~0" and "-1" will be converted to the largest value in the enumeration.
+ *
+ * @param name the keyword name (number) to convert
+ * @param pOpts the program's option descriptor
+ * @param pOD the option descriptor for this option
+ * @param paz_names the list of keywords for this option
+ * @param name_ct the count of keywords
+ */
+static uintptr_t
+find_name(char const * name, tOptions * pOpts, tOptDesc * pOD,
+ char const * const * paz_names, unsigned int name_ct)
+{
+ /*
+ * Return the matching index as a pointer sized integer.
+ * The result gets stashed in a char * pointer.
+ */
+ uintptr_t res = name_ct;
+ size_t len = strlen(name);
+ uintptr_t idx;
+
+ if (IS_DEC_DIGIT_CHAR(*name)) {
+ char * pz;
+ unsigned long val = strtoul(name, &pz, 0);
+ if ((*pz == NUL) && (val < name_ct))
+ return (uintptr_t)val;
+ pz_enum_err_fmt = znum_too_large;
+ option_usage_fp = stderr;
+ enum_err(pOpts, pOD, paz_names, (int)name_ct);
+ return name_ct;
+ }
+
+ if (IS_INVERSION_CHAR(*name) && (name[2] == NUL)) {
+ if ( ((name[0] == '~') && (name[1] == '0'))
+ || ((name[0] == '-') && (name[1] == '1')))
+ return (uintptr_t)(name_ct - 1);
+ goto oops;
+ }
+
+ /*
+ * Look for an exact match, but remember any partial matches.
+ * Multiple partial matches means we have an ambiguous match.
+ */
+ for (idx = 0; idx < name_ct; idx++) {
+ if (strncmp(paz_names[idx], name, len) == 0) {
+ if (paz_names[idx][len] == NUL)
+ return idx; /* full match */
+
+ if (res == name_ct)
+ res = idx; /* save partial match */
+ else
+ res = (uintptr_t)~0; /* may yet find full match */
+ }
+ }
+
+ if (res < name_ct)
+ return res; /* partial match */
+
+ oops:
+
+ pz_enum_err_fmt = (res == name_ct) ? zNoKey : zambiguous_key;
+ option_usage_fp = stderr;
+ enum_err(pOpts, pOD, paz_names, (int)name_ct);
+ return name_ct;
+}
+
+
+/*=export_func optionKeywordName
+ * what: Convert between enumeration values and strings
+ * private:
+ *
+ * arg: tOptDesc *, pOD, enumeration option description
+ * arg: unsigned int, enum_val, the enumeration value to map
+ *
+ * ret_type: char const *
+ * ret_desc: the enumeration name from const memory
+ *
+ * doc: This converts an enumeration value into the matching string.
+=*/
+char const *
+optionKeywordName(tOptDesc * pOD, unsigned int enum_val)
+{
+ tOptDesc od = { 0 };
+ od.optArg.argEnum = enum_val;
+
+ (*(pOD->pOptProc))(OPTPROC_RETURN_VALNAME, &od );
+ return od.optArg.argString;
+}
+
+
+/*=export_func optionEnumerationVal
+ * what: Convert from a string to an enumeration value
+ * private:
+ *
+ * arg: tOptions *, pOpts, the program options descriptor
+ * arg: tOptDesc *, pOD, enumeration option description
+ * arg: char const * const *, paz_names, list of enumeration names
+ * arg: unsigned int, name_ct, number of names in list
+ *
+ * ret_type: uintptr_t
+ * ret_desc: the enumeration value
+ *
+ * doc: This converts the optArg.argString string from the option description
+ * into the index corresponding to an entry in the name list.
+ * This will match the generated enumeration value.
+ * Full matches are always accepted. Partial matches are accepted
+ * if there is only one partial match.
+=*/
+uintptr_t
+optionEnumerationVal(tOptions * pOpts, tOptDesc * pOD,
+ char const * const * paz_names, unsigned int name_ct)
+{
+ uintptr_t res = 0UL;
+
+ /*
+ * IF the program option descriptor pointer is invalid,
+ * then it is some sort of special request.
+ */
+ switch ((uintptr_t)pOpts) {
+ case (uintptr_t)OPTPROC_EMIT_USAGE:
+ /*
+ * print the list of enumeration names.
+ */
+ enum_err(pOpts, pOD, paz_names, (int)name_ct);
+ break;
+
+ case (uintptr_t)OPTPROC_EMIT_SHELL:
+ {
+ unsigned int ix = (unsigned int)pOD->optArg.argEnum;
+ /*
+ * print the name string.
+ */
+ if (ix >= name_ct)
+ printf(INVALID_FMT, ix);
+ else
+ fputs(paz_names[ ix ], stdout);
+
+ break;
+ }
+
+ case (uintptr_t)OPTPROC_RETURN_VALNAME:
+ {
+ unsigned int ix = (unsigned int)pOD->optArg.argEnum;
+ /*
+ * Replace the enumeration value with the name string.
+ */
+ if (ix >= name_ct)
+ return (uintptr_t)INVALID_STR;
+
+ pOD->optArg.argString = paz_names[ix];
+ break;
+ }
+
+ default:
+ if ((pOD->fOptState & OPTST_RESET) != 0)
+ break;
+
+ res = find_name(pOD->optArg.argString, pOpts, pOD, paz_names, name_ct);
+
+ if (pOD->fOptState & OPTST_ALLOC_ARG) {
+ AGFREE(pOD->optArg.argString);
+ pOD->fOptState &= ~OPTST_ALLOC_ARG;
+ pOD->optArg.argString = NULL;
+ }
+ }
+
+ return res;
+}
+
+static void
+set_memb_shell(tOptions * pOpts, tOptDesc * pOD, char const * const * paz_names,
+ unsigned int name_ct)
+{
+ /*
+ * print the name string.
+ */
+ unsigned int ix = 0;
+ uintptr_t bits = (uintptr_t)pOD->optCookie;
+ size_t len = 0;
+
+ (void)pOpts;
+ bits &= ((uintptr_t)1 << (uintptr_t)name_ct) - (uintptr_t)1;
+
+ while (bits != 0) {
+ if (bits & 1) {
+ if (len++ > 0) fputs(OR_STR, stdout);
+ fputs(paz_names[ix], stdout);
+ }
+ if (++ix >= name_ct) break;
+ bits >>= 1;
+ }
+}
+
+static void
+set_memb_names(tOptions * opts, tOptDesc * od, char const * const * nm_list,
+ unsigned int nm_ct)
+{
+ char * pz;
+ uintptr_t mask = (1UL << (uintptr_t)nm_ct) - 1UL;
+ uintptr_t bits = (uintptr_t)od->optCookie & mask;
+ unsigned int ix = 0;
+ size_t len = 1;
+
+ /*
+ * Replace the enumeration value with the name string.
+ * First, determine the needed length, then allocate and fill in.
+ */
+ while (bits != 0) {
+ if (bits & 1)
+ len += strlen(nm_list[ix]) + PLUS_STR_LEN + 1;
+ if (++ix >= nm_ct) break;
+ bits >>= 1;
+ }
+
+ od->optArg.argString = pz = AGALOC(len, "enum");
+ bits = (uintptr_t)od->optCookie & mask;
+ if (bits == 0) {
+ *pz = NUL;
+ return;
+ }
+
+ for (ix = 0; ; ix++) {
+ size_t nln;
+ int doit = bits & 1;
+
+ bits >>= 1;
+ if (doit == 0)
+ continue;
+
+ nln = strlen(nm_list[ix]);
+ memcpy(pz, nm_list[ix], nln);
+ pz += nln;
+ if (bits == 0)
+ break;
+ memcpy(pz, PLUS_STR, PLUS_STR_LEN);
+ pz += PLUS_STR_LEN;
+ }
+ *pz = NUL;
+ (void)opts;
+}
+
+/**
+ * Check membership start conditions. An equal character (@samp{=}) says to
+ * clear the result and not carry over any residual value. A carat
+ * (@samp{^}), which may follow the equal character, says to invert the
+ * result. The scanning pointer is advanced past these characters and any
+ * leading white space. Invalid sequences are indicated by setting the
+ * scanning pointer to NULL.
+ *
+ * @param od the set membership option description
+ * @param argp a pointer to the string scanning pointer
+ * @param invert a pointer to the boolean inversion indicator
+ *
+ * @returns either zero or the original value for the optCookie.
+ */
+static uintptr_t
+check_membership_start(tOptDesc * od, char const ** argp, bool * invert)
+{
+ uintptr_t res = (uintptr_t)od->optCookie;
+ char const * arg = SPN_WHITESPACE_CHARS(od->optArg.argString);
+ if ((arg == NULL) || (*arg == NUL))
+ goto member_start_fail;
+
+ *invert = false;
+
+ switch (*arg) {
+ case '=':
+ res = 0UL;
+ arg = SPN_WHITESPACE_CHARS(arg + 1);
+ switch (*arg) {
+ case '=': case ',':
+ goto member_start_fail;
+ case '^':
+ goto inversion;
+ default:
+ break;
+ }
+ break;
+
+ case '^':
+ inversion:
+ *invert = true;
+ arg = SPN_WHITESPACE_CHARS(arg + 1);
+ if (*arg != ',')
+ break;
+ /* FALLTHROUGH */
+
+ case ',':
+ goto member_start_fail;
+
+ default:
+ break;
+ }
+
+ *argp = arg;
+ return res;
+
+member_start_fail:
+ *argp = NULL;
+ return 0UL;
+}
+
+/**
+ * convert a name to a bit. Look up a name string to get a bit number
+ * and shift the value "1" left that number of bits.
+ *
+ * @param opts program options descriptor
+ * @param od the set membership option description
+ * @param pz address of the start of the bit name
+ * @param nm_list the list of names for this option
+ * @param nm_ct the number of entries in this list
+ *
+ * @returns 0UL on error, other an unsigned long with the correct bit set.
+ */
+static uintptr_t
+find_member_bit(tOptions * opts, tOptDesc * od, char const * pz, int len,
+ char const * const * nm_list, unsigned int nm_ct)
+{
+ char nm_buf[ AO_NAME_SIZE ];
+
+ memcpy(nm_buf, pz, len);
+ nm_buf[len] = NUL;
+
+ {
+ unsigned int shift_ct = (unsigned int)
+ find_name(nm_buf, opts, od, nm_list, nm_ct);
+ if (shift_ct >= nm_ct)
+ return 0UL;
+
+ return (uintptr_t)1U << shift_ct;
+ }
+}
+
+/*=export_func optionMemberList
+ * what: Get the list of members of a bit mask set
+ *
+ * arg: tOptDesc *, od, the set membership option description
+ *
+ * ret_type: char *
+ * ret_desc: the names of the set bits
+ *
+ * doc: This converts the OPT_VALUE_name mask value to a allocated string.
+ * It is the caller's responsibility to free the string.
+=*/
+char *
+optionMemberList(tOptDesc * od)
+{
+ uintptr_t sv = od->optArg.argIntptr;
+ char * res;
+ (*(od->pOptProc))(OPTPROC_RETURN_VALNAME, od);
+ res = VOIDP(od->optArg.argString);
+ od->optArg.argIntptr = sv;
+ return res;
+}
+
+/*=export_func optionSetMembers
+ * what: Convert between bit flag values and strings
+ * private:
+ *
+ * arg: tOptions *, opts, the program options descriptor
+ * arg: tOptDesc *, od, the set membership option description
+ * arg: char const * const *,
+ * nm_list, list of enumeration names
+ * arg: unsigned int, nm_ct, number of names in list
+ *
+ * doc: This converts the optArg.argString string from the option description
+ * into the index corresponding to an entry in the name list.
+ * This will match the generated enumeration value.
+ * Full matches are always accepted. Partial matches are accepted
+ * if there is only one partial match.
+=*/
+void
+optionSetMembers(tOptions * opts, tOptDesc * od,
+ char const * const * nm_list, unsigned int nm_ct)
+{
+ /*
+ * IF the program option descriptor pointer is invalid,
+ * then it is some sort of special request.
+ */
+ switch ((uintptr_t)opts) {
+ case (uintptr_t)OPTPROC_EMIT_USAGE:
+ enum_err(OPTPROC_EMIT_USAGE, od, nm_list, nm_ct);
+ return;
+
+ case (uintptr_t)OPTPROC_EMIT_SHELL:
+ set_memb_shell(opts, od, nm_list, nm_ct);
+ return;
+
+ case (uintptr_t)OPTPROC_RETURN_VALNAME:
+ set_memb_names(opts, od, nm_list, nm_ct);
+ return;
+
+ default:
+ break;
+ }
+
+ if ((od->fOptState & OPTST_RESET) != 0)
+ return;
+
+ {
+ char const * arg;
+ bool invert;
+ uintptr_t res = check_membership_start(od, &arg, &invert);
+ if (arg == NULL)
+ goto fail_return;
+
+ while (*arg != NUL) {
+ bool inv_val = false;
+ int len;
+
+ switch (*arg) {
+ case ',':
+ arg = SPN_WHITESPACE_CHARS(arg+1);
+ if ((*arg == ',') || (*arg == '|'))
+ goto fail_return;
+ continue;
+
+ case '-':
+ case '!':
+ inv_val = true;
+ /* FALLTHROUGH */
+
+ case '+':
+ case '|':
+ arg = SPN_WHITESPACE_CHARS(arg+1);
+ }
+
+ len = (int)(BRK_SET_SEPARATOR_CHARS(arg) - arg);
+ if (len == 0)
+ break;
+
+ if ((len == 3) && (strncmp(arg, zAll, 3) == 0)) {
+ if (inv_val)
+ res = 0;
+ else res = ~0UL;
+ }
+ else if ((len == 4) && (strncmp(arg, zNone, 4) == 0)) {
+ if (! inv_val)
+ res = 0;
+ }
+ else do {
+ char * pz;
+ uintptr_t bit = strtoul(arg, &pz, 0);
+
+ if (pz != arg + len) {
+ bit = find_member_bit(opts, od, pz, len, nm_list, nm_ct);
+ if (bit == 0UL)
+ goto fail_return;
+ }
+ if (inv_val)
+ res &= ~bit;
+ else res |= bit;
+ } while (false);
+
+ arg = SPN_WHITESPACE_CHARS(arg + len);
+ }
+
+ if (invert)
+ res ^= ~0UL;
+
+ if (nm_ct < (8 * sizeof(uintptr_t)))
+ res &= (1UL << nm_ct) - 1UL;
+
+ od->optCookie = VOIDP(res);
+ }
+ return;
+
+fail_return:
+ od->optCookie = VOIDP(0);
+}
+
+/** @}
+ *
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of autoopts/enum.c */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/env.c b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/env.c
new file mode 100644
index 0000000..36ae2e5
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/env.c
@@ -0,0 +1,267 @@
+
+/**
+ * \file environment.c
+ *
+ * This file contains all of the routines that must be linked into
+ * an executable to use the generated option processing. The optional
+ * routines are in separately compiled modules so that they will not
+ * necessarily be linked in.
+ *
+ * @addtogroup autoopts
+ * @{
+ */
+/*
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
+ *
+ * AutoOpts is available under any one of two licenses. The license
+ * in use must be one of these two and the choice is under the control
+ * of the user of the license.
+ *
+ * The GNU Lesser General Public License, version 3 or later
+ * See the files "COPYING.lgplv3" and "COPYING.gplv3"
+ *
+ * The Modified Berkeley Software Distribution License
+ * See the file "COPYING.mbsd"
+ *
+ * These files have the following sha256 sums:
+ *
+ * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
+ * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
+ * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
+ */
+
+/* = = = START-STATIC-FORWARD = = = */
+static void
+do_env_opt(tOptState * os, char * env_name,
+ tOptions * pOpts, teEnvPresetType type);
+/* = = = END-STATIC-FORWARD = = = */
+
+/*
+ * doPrognameEnv - check for preset values from the ${PROGNAME}
+ * environment variable. This is accomplished by parsing the text into
+ * tokens, temporarily replacing the arg vector and calling
+ * immediate_opts and/or regular_opts.
+ */
+LOCAL void
+doPrognameEnv(tOptions * pOpts, teEnvPresetType type)
+{
+ char const * env_opts = getenv(pOpts->pzPROGNAME);
+ token_list_t * pTL;
+ int sv_argc;
+ proc_state_mask_t sv_flag;
+ char ** sv_argv;
+
+ /*
+ * No such beast? Then bail now.
+ */
+ if (env_opts == NULL)
+ return;
+
+ /*
+ * Tokenize the string. If there's nothing of interest, we'll bail
+ * here immediately.
+ */
+ pTL = ao_string_tokenize(env_opts);
+ if (pTL == NULL)
+ return;
+
+ /*
+ * Substitute our $PROGNAME argument list for the real one
+ */
+ sv_argc = (int)pOpts->origArgCt;
+ sv_argv = pOpts->origArgVect;
+ sv_flag = pOpts->fOptSet;
+
+ /*
+ * We add a bogus pointer to the start of the list. The program name
+ * has already been pulled from "argv", so it won't get dereferenced.
+ * The option scanning code will skip the "program name" at the start
+ * of this list of tokens, so we accommodate this way ....
+ */
+ {
+ uintptr_t v = (uintptr_t)(pTL->tkn_list);
+ pOpts->origArgVect = VOIDP(v - sizeof(char *));
+ }
+ pOpts->origArgCt = (unsigned int)pTL->tkn_ct + 1;
+ pOpts->fOptSet &= ~OPTPROC_ERRSTOP;
+
+ pOpts->curOptIdx = 1;
+ pOpts->pzCurOpt = NULL;
+
+ switch (type) {
+ case ENV_IMM:
+ (void)immediate_opts(pOpts);
+ break;
+
+ case ENV_ALL:
+ (void)immediate_opts(pOpts);
+ pOpts->curOptIdx = 1;
+ pOpts->pzCurOpt = NULL;
+ /* FALLTHROUGH */
+
+ case ENV_NON_IMM:
+ (void)regular_opts(pOpts);
+ }
+
+ /*
+ * Free up the temporary arg vector and restore the original program args.
+ */
+ free(pTL);
+ pOpts->origArgVect = sv_argv;
+ pOpts->origArgCt = (unsigned int)sv_argc;
+ pOpts->fOptSet = sv_flag;
+}
+
+static void
+do_env_opt(tOptState * os, char * env_name,
+ tOptions * pOpts, teEnvPresetType type)
+{
+ os->pzOptArg = getenv(env_name);
+ if (os->pzOptArg == NULL)
+ return;
+
+ os->flags = OPTST_PRESET | OPTST_ALLOC_ARG | os->pOD->fOptState;
+ os->optType = TOPT_UNDEFINED;
+
+ if ( (os->pOD->pz_DisablePfx != NULL)
+ && (streqvcmp(os->pzOptArg, os->pOD->pz_DisablePfx) == 0)) {
+ os->flags |= OPTST_DISABLED;
+ os->pzOptArg = NULL;
+ handle_opt(pOpts, os);
+ return;
+ }
+
+ switch (type) {
+ case ENV_IMM:
+ /*
+ * Process only immediate actions
+ */
+ if (DO_IMMEDIATELY(os->flags))
+ break;
+ return;
+
+ case ENV_NON_IMM:
+ /*
+ * Process only NON immediate actions
+ */
+ if (DO_NORMALLY(os->flags) || DO_SECOND_TIME(os->flags))
+ break;
+ return;
+
+ default: /* process everything */
+ break;
+ }
+
+ /*
+ * Make sure the option value string is persistent and consistent.
+ *
+ * The interpretation of the option value depends
+ * on the type of value argument the option takes
+ */
+ if (OPTST_GET_ARGTYPE(os->pOD->fOptState) == OPARG_TYPE_NONE) {
+ /*
+ * Ignore any value.
+ */
+ os->pzOptArg = NULL;
+
+ } else if (os->pzOptArg[0] == NUL) {
+ /*
+ * If the argument is the empty string and the argument is
+ * optional, then treat it as if the option was not specified.
+ */
+ if ((os->pOD->fOptState & OPTST_ARG_OPTIONAL) == 0)
+ return;
+ os->pzOptArg = NULL;
+
+ } else {
+ AGDUPSTR(os->pzOptArg, os->pzOptArg, "option argument");
+ os->flags |= OPTST_ALLOC_ARG;
+ }
+
+ handle_opt(pOpts, os);
+}
+
+/*
+ * env_presets - check for preset values from the envrionment
+ * This routine should process in all, immediate or normal modes....
+ */
+LOCAL void
+env_presets(tOptions * pOpts, teEnvPresetType type)
+{
+ int ct;
+ tOptState st;
+ char * pzFlagName;
+ size_t spaceLeft;
+ char zEnvName[ AO_NAME_SIZE ];
+
+ /*
+ * Finally, see if we are to look at the environment
+ * variables for initial values.
+ */
+ if ((pOpts->fOptSet & OPTPROC_ENVIRON) == 0)
+ return;
+
+ doPrognameEnv(pOpts, type);
+
+ ct = pOpts->presetOptCt;
+ st.pOD = pOpts->pOptDesc;
+
+ pzFlagName = zEnvName
+ + snprintf(zEnvName, sizeof(zEnvName), "%s_", pOpts->pzPROGNAME);
+ spaceLeft = AO_NAME_SIZE - (unsigned long)(pzFlagName - zEnvName) - 1;
+
+ for (;ct-- > 0; st.pOD++) {
+ size_t nln;
+
+ /*
+ * If presetting is disallowed, then skip this entry
+ */
+ if ( ((st.pOD->fOptState & OPTST_NO_INIT) != 0)
+ || (st.pOD->optEquivIndex != NO_EQUIVALENT) )
+ continue;
+
+ /*
+ * IF there is no such environment variable,
+ * THEN skip this entry, too.
+ */
+ nln = strlen(st.pOD->pz_NAME) + 1;
+ if (nln <= spaceLeft) {
+ /*
+ * Set up the option state
+ */
+ memcpy(pzFlagName, st.pOD->pz_NAME, nln);
+ do_env_opt(&st, zEnvName, pOpts, type);
+ }
+ }
+
+ /*
+ * Special handling for ${PROGNAME_LOAD_OPTS}
+ */
+ if ( (pOpts->specOptIdx.save_opts != NO_EQUIVALENT)
+ && (pOpts->specOptIdx.save_opts != 0)) {
+ size_t nln;
+ st.pOD = pOpts->pOptDesc + pOpts->specOptIdx.save_opts + 1;
+
+ if (st.pOD->pz_NAME == NULL)
+ return;
+
+ nln = strlen(st.pOD->pz_NAME) + 1;
+
+ if (nln > spaceLeft)
+ return;
+
+ memcpy(pzFlagName, st.pOD->pz_NAME, nln);
+ do_env_opt(&st, zEnvName, pOpts, type);
+ }
+}
+
+/** @}
+ *
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of autoopts/environment.c */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/file.c b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/file.c
new file mode 100644
index 0000000..7d92875
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/file.c
@@ -0,0 +1,201 @@
+
+/**
+ * \file file.c
+ *
+ * Handle options that have file names for arguments.
+ *
+ * @addtogroup autoopts
+ * @{
+ */
+/*
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
+ *
+ * AutoOpts is available under any one of two licenses. The license
+ * in use must be one of these two and the choice is under the control
+ * of the user of the license.
+ *
+ * The GNU Lesser General Public License, version 3 or later
+ * See the files "COPYING.lgplv3" and "COPYING.gplv3"
+ *
+ * The Modified Berkeley Software Distribution License
+ * See the file "COPYING.mbsd"
+ *
+ * These files have the following sha256 sums:
+ *
+ * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
+ * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
+ * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
+ */
+
+/**
+ * Make sure the directory containing the subject file exists and that
+ * the file exists or does not exist, per the option requirements.
+ *
+ * @param ftype file existence type flags
+ * @param pOpts program option descriptor
+ * @param pOD the option descriptor
+ */
+static void
+check_existence(teOptFileType ftype, tOptions * pOpts, tOptDesc * pOD)
+{
+ char const * fname = pOD->optArg.argString;
+ struct stat sb;
+
+ errno = 0;
+
+ switch (ftype & FTYPE_MODE_EXIST_MASK) {
+ case FTYPE_MODE_MUST_NOT_EXIST:
+ if ((stat(fname, &sb) == 0) || (errno != ENOENT)) {
+ if (errno == 0)
+ errno = EINVAL;
+ fserr_exit(pOpts->pzProgName, "stat", fname);
+ /* NOTREACHED */
+ }
+ /* FALLTHROUGH */
+
+ default:
+ case FTYPE_MODE_MAY_EXIST:
+ {
+ char * p = strrchr(fname, DIRCH);
+ size_t l;
+
+ if (p == NULL)
+ /*
+ * The file may or may not exist and its directory is ".".
+ * Assume that "." exists.
+ */
+ break;
+
+ l = (size_t)(p - fname);
+ p = AGALOC(l + 1, "fname");
+ memcpy(p, fname, l);
+ p[l] = NUL;
+
+ if ((stat(p, &sb) != 0) || (errno = EINVAL, ! S_ISDIR(sb.st_mode)))
+ fserr_exit(pOpts->pzProgName, "stat", p);
+ /* NOTREACHED */
+
+ AGFREE(p);
+ break;
+ }
+
+ case FTYPE_MODE_MUST_EXIST:
+ if ( (stat(fname, &sb) != 0)
+ || (errno = EINVAL, ! S_ISREG(sb.st_mode)) )
+ fserr_exit(pOpts->pzProgName, "stat", fname);
+ /* NOTREACHED */
+
+ break;
+ }
+}
+
+/**
+ * Open the specified file with open(2) and save the FD.
+ *
+ * @param pOpts program option descriptor
+ * @param pOD the option descriptor
+ * @param mode the open mode (uses int flags value)
+ */
+static void
+open_file_fd(tOptions * pOpts, tOptDesc * pOD, tuFileMode mode)
+{
+ int fd = open(pOD->optArg.argString, mode.file_flags);
+ if (fd < 0)
+ fserr_exit(pOpts->pzProgName, "open", pOD->optArg.argString);
+ /* NOTREACHED */
+
+ if ((pOD->fOptState & OPTST_ALLOC_ARG) != 0)
+ pOD->optCookie = VOIDP(pOD->optArg.argString);
+ else
+ AGDUPSTR(pOD->optCookie, pOD->optArg.argString, "file name");
+
+ pOD->optArg.argFd = fd;
+ pOD->fOptState &= ~OPTST_ALLOC_ARG;
+}
+
+/**
+ * Open the specified file with open(2) and save the FD.
+ *
+ * @param pOpts program option descriptor
+ * @param pOD the option descriptor
+ * @param mode the open mode (uses "char *" mode value)
+ */
+static void
+fopen_file_fp(tOptions * pOpts, tOptDesc * pOD, tuFileMode mode)
+{
+ FILE * fp = fopen(pOD->optArg.argString, mode.file_mode);
+ if (fp == NULL)
+ fserr_exit(pOpts->pzProgName, "fopen", pOD->optArg.argString);
+ /* NOTREACHED */
+
+ if ((pOD->fOptState & OPTST_ALLOC_ARG) != 0)
+ pOD->optCookie = VOIDP(pOD->optArg.argString);
+ else
+ AGDUPSTR(pOD->optCookie, pOD->optArg.argString, "file name");
+
+ pOD->optArg.argFp = fp;
+ pOD->fOptState &= ~OPTST_ALLOC_ARG;
+}
+
+/*=export_func optionFileCheck
+ * private:
+ *
+ * what: Decipher a boolean value
+ * arg: + tOptions * + pOpts + program options descriptor +
+ * arg: + tOptDesc * + pOptDesc + the descriptor for this arg +
+ * arg: + teOptFileType + ftype + File handling type +
+ * arg: + tuFileMode + mode + file open mode (if needed) +
+ *
+ * doc:
+ * Make sure the named file conforms with the file type mode.
+ * The mode specifies if the file must exist, must not exist or may
+ * (or may not) exist. The mode may also specify opening the
+ * file: don't, open just the descriptor (fd), or open as a stream
+ * (FILE * pointer).
+=*/
+void
+optionFileCheck(tOptions * pOpts, tOptDesc * pOD,
+ teOptFileType ftype, tuFileMode mode)
+{
+ if (pOpts <= OPTPROC_EMIT_LIMIT) {
+ if (pOpts != OPTPROC_EMIT_USAGE)
+ return;
+
+ switch (ftype & FTYPE_MODE_EXIST_MASK) {
+ case FTYPE_MODE_MUST_NOT_EXIST:
+ fputs(zFileCannotExist + tab_skip_ct, option_usage_fp);
+ break;
+
+ case FTYPE_MODE_MUST_EXIST:
+ fputs(zFileMustExist + tab_skip_ct, option_usage_fp);
+ break;
+ }
+ return;
+ }
+
+ if ((pOD->fOptState & OPTST_RESET) != 0) {
+ if (pOD->optCookie != NULL)
+ AGFREE(pOD->optCookie);
+ return;
+ }
+
+ check_existence(ftype, pOpts, pOD);
+
+ switch (ftype & FTYPE_MODE_OPEN_MASK) {
+ default:
+ case FTYPE_MODE_NO_OPEN: break;
+ case FTYPE_MODE_OPEN_FD: open_file_fd( pOpts, pOD, mode); break;
+ case FTYPE_MODE_FOPEN_FP: fopen_file_fp(pOpts, pOD, mode); break;
+ }
+}
+
+/** @}
+ *
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of autoopts/file.c */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/find.c b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/find.c
new file mode 100644
index 0000000..97a24df
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/find.c
@@ -0,0 +1,780 @@
+/**
+ * @file check.c
+ *
+ * @brief Hunt for options in the option descriptor list
+ *
+ * This file contains the routines that deal with processing quoted strings
+ * into an internal format.
+ *
+ * @addtogroup autoopts
+ * @{
+ */
+/*
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
+ *
+ * AutoOpts is available under any one of two licenses. The license
+ * in use must be one of these two and the choice is under the control
+ * of the user of the license.
+ *
+ * The GNU Lesser General Public License, version 3 or later
+ * See the files "COPYING.lgplv3" and "COPYING.gplv3"
+ *
+ * The Modified Berkeley Software Distribution License
+ * See the file "COPYING.mbsd"
+ *
+ * These files have the following sha256 sums:
+ *
+ * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
+ * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
+ * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
+ */
+
+/* = = = START-STATIC-FORWARD = = = */
+static int
+parse_opt(char const ** nm_pp, char ** arg_pp, char * buf, size_t bufsz);
+
+static void
+opt_ambiguities(tOptions * opts, char const * name, int nm_len);
+
+static int
+opt_match_ct(tOptions * opts, char const * name, int nm_len,
+ int * ixp, bool * disable);
+
+static tSuccess
+opt_set(tOptions * opts, char * arg, int idx, bool disable, tOptState * st);
+
+static tSuccess
+opt_unknown(tOptions * opts, char const * name, char * arg, tOptState * st);
+
+static tSuccess
+opt_ambiguous(tOptions * opts, char const * name, int match_ct);
+
+static tSuccess
+get_opt_arg_must(tOptions * opts, tOptState * o_st);
+
+static tSuccess
+get_opt_arg_may(tOptions * pOpts, tOptState * o_st);
+
+static tSuccess
+get_opt_arg_none(tOptions * pOpts, tOptState * o_st);
+/* = = = END-STATIC-FORWARD = = = */
+
+/**
+ * find the name and name length we are looking for
+ */
+static int
+parse_opt(char const ** nm_pp, char ** arg_pp, char * buf, size_t bufsz)
+{
+ int res = 0;
+ char const * p = *nm_pp;
+ *arg_pp = NULL;
+
+ for (;;) {
+ switch (*(p++)) {
+ case NUL: return res;
+
+ case '=':
+ memcpy(buf, *nm_pp, (size_t)res);
+
+ buf[res] = NUL;
+ *nm_pp = buf;
+ *arg_pp = VOIDP(p);
+ return res;
+
+ default:
+ if (++res >= (int)bufsz)
+ return -1;
+ }
+ }
+}
+
+/**
+ * print out the options that match the given name.
+ *
+ * @param pOpts option data
+ * @param opt_name name of option to look for
+ */
+static void
+opt_ambiguities(tOptions * opts, char const * name, int nm_len)
+{
+ char const * const hyph =
+ NAMED_OPTS(opts) ? "" : LONG_OPT_MARKER;
+
+ tOptDesc * pOD = opts->pOptDesc;
+ int idx = 0;
+
+ fputs(zambig_list_msg, stderr);
+ do {
+ if (pOD->pz_Name == NULL)
+ continue; /* doc option */
+
+ if (strneqvcmp(name, pOD->pz_Name, nm_len) == 0)
+ fprintf(stderr, zambig_file, hyph, pOD->pz_Name);
+
+ else if ( (pOD->pz_DisableName != NULL)
+ && (strneqvcmp(name, pOD->pz_DisableName, nm_len) == 0)
+ )
+ fprintf(stderr, zambig_file, hyph, pOD->pz_DisableName);
+ } while (pOD++, (++idx < opts->optCt));
+}
+
+/**
+ * Determine the number of options that match the name
+ *
+ * @param pOpts option data
+ * @param opt_name name of option to look for
+ * @param nm_len length of provided name
+ * @param index pointer to int for option index
+ * @param disable pointer to bool to mark disabled option
+ * @return count of options that match
+ */
+static int
+opt_match_ct(tOptions * opts, char const * name, int nm_len,
+ int * ixp, bool * disable)
+{
+ int matchCt = 0;
+ int idx = 0;
+ int idxLim = opts->optCt;
+ tOptDesc * pOD = opts->pOptDesc;
+
+ do {
+ /*
+ * If option disabled or a doc option, skip to next
+ */
+ if (pOD->pz_Name == NULL)
+ continue;
+
+ if ( SKIP_OPT(pOD)
+ && (pOD->fOptState != (OPTST_OMITTED | OPTST_NO_INIT)))
+ continue;
+
+ if (strneqvcmp(name, pOD->pz_Name, nm_len) == 0) {
+ /*
+ * IF we have a complete match
+ * THEN it takes priority over any already located partial
+ */
+ if (pOD->pz_Name[ nm_len ] == NUL) {
+ *ixp = idx;
+ return 1;
+ }
+ }
+
+ /*
+ * IF there is a disable name
+ * *AND* the option name matches the disable name
+ * THEN ...
+ */
+ else if ( (pOD->pz_DisableName != NULL)
+ && (strneqvcmp(name, pOD->pz_DisableName, nm_len) == 0)
+ ) {
+ *disable = true;
+
+ /*
+ * IF we have a complete match
+ * THEN it takes priority over any already located partial
+ */
+ if (pOD->pz_DisableName[ nm_len ] == NUL) {
+ *ixp = idx;
+ return 1;
+ }
+ }
+
+ else
+ continue; /* does not match any option */
+
+ /*
+ * We found a full or partial match, either regular or disabling.
+ * Remember the index for later.
+ */
+ *ixp = idx;
+ ++matchCt;
+
+ } while (pOD++, (++idx < idxLim));
+
+ return matchCt;
+}
+
+/**
+ * Set the option to the indicated option number.
+ *
+ * @param opts option data
+ * @param arg option argument (if glued to name)
+ * @param idx option index
+ * @param disable mark disabled option
+ * @param st state about current option
+ */
+static tSuccess
+opt_set(tOptions * opts, char * arg, int idx, bool disable, tOptState * st)
+{
+ tOptDesc * pOD = opts->pOptDesc + idx;
+
+ if (SKIP_OPT(pOD)) {
+ if ((opts->fOptSet & OPTPROC_ERRSTOP) == 0)
+ return FAILURE;
+
+ fprintf(stderr, zDisabledErr, opts->pzProgName, pOD->pz_Name);
+ if (pOD->pzText != NULL)
+ fprintf(stderr, SET_OFF_FMT, pOD->pzText);
+ fputc(NL, stderr);
+ (*opts->pUsageProc)(opts, EXIT_FAILURE);
+ /* NOTREACHED */
+ _exit(EXIT_FAILURE); /* to be certain */
+ }
+
+ /*
+ * IF we found a disablement name,
+ * THEN set the bit in the callers' flag word
+ */
+ if (disable)
+ st->flags |= OPTST_DISABLED;
+
+ st->pOD = pOD;
+ st->pzOptArg = arg;
+ st->optType = TOPT_LONG;
+
+ return SUCCESS;
+}
+
+/**
+ * An option was not found. Check for default option and set it
+ * if there is one. Otherwise, handle the error.
+ *
+ * @param opts option data
+ * @param name name of option to look for
+ * @param arg option argument
+ * @param st state about current option
+ *
+ * @return success status
+ */
+static tSuccess
+opt_unknown(tOptions * opts, char const * name, char * arg, tOptState * st)
+{
+ /*
+ * IF there is no equal sign
+ * *AND* we are using named arguments
+ * *AND* there is a default named option,
+ * THEN return that option.
+ */
+ if ( (arg == NULL)
+ && NAMED_OPTS(opts)
+ && (opts->specOptIdx.default_opt != NO_EQUIVALENT)) {
+
+ st->pOD = opts->pOptDesc + opts->specOptIdx.default_opt;
+ st->pzOptArg = name;
+ st->optType = TOPT_DEFAULT;
+ return SUCCESS;
+ }
+
+ if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) {
+ fprintf(stderr, zIllOptStr, opts->pzProgPath, name);
+ (*opts->pUsageProc)(opts, EXIT_FAILURE);
+ /* NOTREACHED */
+ _exit(EXIT_FAILURE); /* to be certain */
+ }
+
+ return FAILURE;
+}
+
+/**
+ * Several options match the provided name.
+ *
+ * @param opts option data
+ * @param name name of option to look for
+ * @param match_ct number of matching options
+ *
+ * @return success status (always FAILURE, if it returns)
+ */
+static tSuccess
+opt_ambiguous(tOptions * opts, char const * name, int match_ct)
+{
+ if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) {
+ fprintf(stderr, zambig_opt_fmt, opts->pzProgPath, name, match_ct);
+ if (match_ct <= 4)
+ opt_ambiguities(opts, name, (int)strlen(name));
+ (*opts->pUsageProc)(opts, EXIT_FAILURE);
+ /* NOTREACHED */
+ _exit(EXIT_FAILURE); /* to be certain */
+ }
+ return FAILURE;
+}
+
+/*=export_func optionVendorOption
+ * private:
+ *
+ * what: Process a vendor option
+ * arg: + tOptions * + pOpts + program options descriptor +
+ * arg: + tOptDesc * + pOptDesc + the descriptor for this arg +
+ *
+ * doc:
+ * For POSIX specified utilities, the options are constrained to the options,
+ * @xref{config attributes, Program Configuration}. AutoOpts clients should
+ * never specify this directly. It gets referenced when the option
+ * definitions contain a "vendor-opt" attribute.
+=*/
+void
+optionVendorOption(tOptions * pOpts, tOptDesc * pOD)
+{
+ tOptState opt_st = OPTSTATE_INITIALIZER(PRESET);
+ char const * vopt_str = pOD->optArg.argString;
+
+ if (pOpts <= OPTPROC_EMIT_LIMIT)
+ return;
+
+ if ((pOD->fOptState & OPTST_RESET) != 0)
+ return;
+
+ if ((pOD->fOptState & OPTPROC_IMMEDIATE) == 0)
+ opt_st.flags = OPTST_DEFINED;
+
+ if ( ((pOpts->fOptSet & OPTPROC_VENDOR_OPT) == 0)
+ || ! SUCCESSFUL(opt_find_long(pOpts, vopt_str, &opt_st))
+ || ! SUCCESSFUL(get_opt_arg(pOpts, &opt_st)) )
+ {
+ fprintf(stderr, zIllVendOptStr, pOpts->pzProgName, vopt_str);
+ (*pOpts->pUsageProc)(pOpts, EXIT_FAILURE);
+ /* NOTREACHED */
+ _exit(EXIT_FAILURE); /* to be certain */
+ }
+
+ /*
+ * See if we are in immediate handling state.
+ */
+ if (pOpts->fOptSet & OPTPROC_IMMEDIATE) {
+ /*
+ * See if the enclosed option is okay with that state.
+ */
+ if (DO_IMMEDIATELY(opt_st.flags))
+ (void)handle_opt(pOpts, &opt_st);
+
+ } else {
+ /*
+ * non-immediate direction.
+ * See if the enclosed option is okay with that state.
+ */
+ if (DO_NORMALLY(opt_st.flags) || DO_SECOND_TIME(opt_st.flags))
+ (void)handle_opt(pOpts, &opt_st);
+ }
+}
+
+/**
+ * Find the option descriptor by full name.
+ *
+ * @param opts option data
+ * @param opt_name name of option to look for
+ * @param state state about current option
+ *
+ * @return success status
+ */
+LOCAL tSuccess
+opt_find_long(tOptions * opts, char const * opt_name, tOptState * state)
+{
+ char name_buf[128];
+ char * opt_arg;
+ int nm_len = parse_opt(&opt_name, &opt_arg, name_buf, sizeof(name_buf));
+
+ int idx = 0;
+ bool disable = false;
+ int ct;
+
+ if (nm_len <= 1) {
+ if ((opts->fOptSet & OPTPROC_ERRSTOP) == 0)
+ return FAILURE;
+
+ fprintf(stderr, zInvalOptName, opts->pzProgName, opt_name);
+ (*opts->pUsageProc)(opts, EXIT_FAILURE);
+ /* NOTREACHED */
+ _exit(EXIT_FAILURE); /* to be certain */
+ }
+
+ ct = opt_match_ct(opts, opt_name, nm_len, &idx, &disable);
+
+ /*
+ * See if we found one match, no matches or multiple matches.
+ */
+ switch (ct) {
+ case 1: return opt_set(opts, opt_arg, idx, disable, state);
+ case 0: return opt_unknown(opts, opt_name, opt_arg, state);
+ default: return opt_ambiguous(opts, opt_name, ct);
+ }
+}
+
+
+/**
+ * Find the short option descriptor for the current option
+ *
+ * @param pOpts option data
+ * @param optValue option flag character
+ * @param pOptState state about current option
+ */
+LOCAL tSuccess
+opt_find_short(tOptions * pOpts, uint_t optValue, tOptState * pOptState)
+{
+ tOptDesc * pRes = pOpts->pOptDesc;
+ int ct = pOpts->optCt;
+
+ /*
+ * Search the option list
+ */
+ do {
+ if (optValue != pRes->optValue)
+ continue;
+
+ if (SKIP_OPT(pRes)) {
+ if ( (pRes->fOptState == (OPTST_OMITTED | OPTST_NO_INIT))
+ && (pRes->pz_Name != NULL)) {
+ if ((pOpts->fOptSet & OPTPROC_ERRSTOP) == 0)
+ return FAILURE;
+
+ fprintf(stderr, zDisabledErr, pOpts->pzProgPath, pRes->pz_Name);
+ if (pRes->pzText != NULL)
+ fprintf(stderr, SET_OFF_FMT, pRes->pzText);
+ fputc(NL, stderr);
+ (*pOpts->pUsageProc)(pOpts, EXIT_FAILURE);
+ /* NOTREACHED */
+ _exit(EXIT_FAILURE); /* to be certain */
+ }
+ goto short_opt_error;
+ }
+
+ pOptState->pOD = pRes;
+ pOptState->optType = TOPT_SHORT;
+ return SUCCESS;
+
+ } while (pRes++, --ct > 0);
+
+ /*
+ * IF the character value is a digit
+ * AND there is a special number option ("-n")
+ * THEN the result is the "option" itself and the
+ * option is the specially marked "number" option.
+ */
+ if ( IS_DEC_DIGIT_CHAR(optValue)
+ && (pOpts->specOptIdx.number_option != NO_EQUIVALENT) ) {
+ pOptState->pOD = \
+ pRes = pOpts->pOptDesc + pOpts->specOptIdx.number_option;
+ (pOpts->pzCurOpt)--;
+ pOptState->optType = TOPT_SHORT;
+ return SUCCESS;
+ }
+
+ short_opt_error:
+
+ /*
+ * IF we are to stop on errors (the default, actually)
+ * THEN call the usage procedure.
+ */
+ if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) {
+ fprintf(stderr, zIllOptChr, pOpts->pzProgPath, optValue);
+ (*pOpts->pUsageProc)(pOpts, EXIT_FAILURE);
+ /* NOTREACHED */
+ _exit(EXIT_FAILURE); /* to be certain */
+ }
+
+ return FAILURE;
+}
+
+/**
+ * Process option with a required argument. Long options can either have a
+ * separate command line argument, or an argument attached by the '='
+ * character. Figure out which.
+ *
+ * @param[in,out] opts the program option descriptor
+ * @param[in,out] o_st the option processing state
+ * @returns SUCCESS or FAILURE
+ */
+static tSuccess
+get_opt_arg_must(tOptions * opts, tOptState * o_st)
+{
+ switch (o_st->optType) {
+ case TOPT_SHORT:
+ /*
+ * See if an arg string follows the flag character
+ */
+ if (*++(opts->pzCurOpt) == NUL)
+ opts->pzCurOpt = opts->origArgVect[ opts->curOptIdx++ ];
+ o_st->pzOptArg = opts->pzCurOpt;
+ break;
+
+ case TOPT_LONG:
+ /*
+ * See if an arg string has already been assigned (glued on
+ * with an `=' character)
+ */
+ if (o_st->pzOptArg == NULL)
+ o_st->pzOptArg = opts->origArgVect[ opts->curOptIdx++ ];
+ break;
+
+ default:
+#ifdef DEBUG
+ fputs("AutoOpts lib error: option type not selected\n", stderr);
+ option_exits(EXIT_FAILURE);
+#endif
+
+ case TOPT_DEFAULT:
+ /*
+ * The option was selected by default. The current token is
+ * the option argument.
+ */
+ break;
+ }
+
+ /*
+ * Make sure we did not overflow the argument list.
+ */
+ if (opts->curOptIdx > opts->origArgCt) {
+ fprintf(stderr, zMisArg, opts->pzProgPath, o_st->pOD->pz_Name);
+ return FAILURE;
+ }
+
+ opts->pzCurOpt = NULL; /* next time advance to next arg */
+ return SUCCESS;
+}
+
+/**
+ * Process an option with an optional argument. For short options, it looks
+ * at the character after the option character, or it consumes the next full
+ * argument. For long options, it looks for an '=' character attachment to
+ * the long option name before deciding to take the next command line
+ * argument.
+ *
+ * @param pOpts the option descriptor
+ * @param o_st a structure for managing the current processing state
+ * @returns SUCCESS or does not return
+ */
+static tSuccess
+get_opt_arg_may(tOptions * pOpts, tOptState * o_st)
+{
+ /*
+ * An option argument is optional.
+ */
+ switch (o_st->optType) {
+ case TOPT_SHORT:
+ if (*++pOpts->pzCurOpt != NUL)
+ o_st->pzOptArg = pOpts->pzCurOpt;
+ else {
+ char * pzLA = pOpts->origArgVect[ pOpts->curOptIdx ];
+
+ /*
+ * BECAUSE it is optional, we must make sure
+ * we did not find another flag and that there
+ * is such an argument.
+ */
+ if ((pzLA == NULL) || (*pzLA == '-'))
+ o_st->pzOptArg = NULL;
+ else {
+ pOpts->curOptIdx++; /* argument found */
+ o_st->pzOptArg = pzLA;
+ }
+ }
+ break;
+
+ case TOPT_LONG:
+ /*
+ * Look for an argument if we don't already have one (glued on
+ * with a `=' character) *AND* we are not in named argument mode
+ */
+ if ( (o_st->pzOptArg == NULL)
+ && (! NAMED_OPTS(pOpts))) {
+ char * pzLA = pOpts->origArgVect[ pOpts->curOptIdx ];
+
+ /*
+ * BECAUSE it is optional, we must make sure
+ * we did not find another flag and that there
+ * is such an argument.
+ */
+ if ((pzLA == NULL) || (*pzLA == '-'))
+ o_st->pzOptArg = NULL;
+ else {
+ pOpts->curOptIdx++; /* argument found */
+ o_st->pzOptArg = pzLA;
+ }
+ }
+ break;
+
+ default:
+ case TOPT_DEFAULT:
+ ao_bug(zbad_default_msg);
+ }
+
+ /*
+ * After an option with an optional argument, we will
+ * *always* start with the next option because if there
+ * were any characters following the option name/flag,
+ * they would be interpreted as the argument.
+ */
+ pOpts->pzCurOpt = NULL;
+ return SUCCESS;
+}
+
+/**
+ * Process option that does not have an argument.
+ *
+ * @param[in,out] opts the program option descriptor
+ * @param[in,out] o_st the option processing state
+ * @returns SUCCESS or FAILURE
+ */
+static tSuccess
+get_opt_arg_none(tOptions * pOpts, tOptState * o_st)
+{
+ /*
+ * No option argument. Make sure next time around we find
+ * the correct option flag character for short options
+ */
+ if (o_st->optType == TOPT_SHORT)
+ (pOpts->pzCurOpt)++;
+
+ /*
+ * It is a long option. Make sure there was no ``=xxx'' argument
+ */
+ else if (o_st->pzOptArg != NULL) {
+ fprintf(stderr, zNoArg, pOpts->pzProgPath, o_st->pOD->pz_Name);
+ return FAILURE;
+ }
+
+ /*
+ * It is a long option. Advance to next command line argument.
+ */
+ else
+ pOpts->pzCurOpt = NULL;
+ return SUCCESS;
+}
+
+/**
+ * Process option. Figure out whether or not to look for an option argument.
+ *
+ * @param[in,out] opts the program option descriptor
+ * @param[in,out] o_st the option processing state
+ * @returns SUCCESS or FAILURE
+ */
+LOCAL tSuccess
+get_opt_arg(tOptions * opts, tOptState * o_st)
+{
+ o_st->flags |= (o_st->pOD->fOptState & OPTST_PERSISTENT_MASK);
+
+ /*
+ * Disabled options and options specified to not have arguments
+ * are handled with the "none" procedure. Otherwise, check the
+ * optional flag and call either the "may" or "must" function.
+ */
+ if ( ((o_st->flags & OPTST_DISABLED) != 0)
+ || (OPTST_GET_ARGTYPE(o_st->flags) == OPARG_TYPE_NONE))
+ return get_opt_arg_none(opts, o_st);
+
+ if (o_st->flags & OPTST_ARG_OPTIONAL)
+ return get_opt_arg_may( opts, o_st);
+
+ return get_opt_arg_must(opts, o_st);
+}
+
+/**
+ * Find the option descriptor for the current option.
+ *
+ * @param[in,out] opts the program option descriptor
+ * @param[in,out] o_st the option processing state
+ * @returns SUCCESS or FAILURE
+ */
+LOCAL tSuccess
+find_opt(tOptions * opts, tOptState * o_st)
+{
+ /*
+ * IF we are continuing a short option list (e.g. -xyz...)
+ * THEN continue a single flag option.
+ * OTHERWISE see if there is room to advance and then do so.
+ */
+ if ((opts->pzCurOpt != NULL) && (*opts->pzCurOpt != NUL))
+ return opt_find_short(opts, (uint8_t)*(opts->pzCurOpt), o_st);
+
+ if (opts->curOptIdx >= opts->origArgCt)
+ return PROBLEM; /* NORMAL COMPLETION */
+
+ opts->pzCurOpt = opts->origArgVect[ opts->curOptIdx ];
+
+ /*
+ * IF all arguments must be named options, ...
+ */
+ if (NAMED_OPTS(opts)) {
+ char * pz = opts->pzCurOpt;
+ int def;
+ tSuccess res;
+ uint16_t * def_opt;
+
+ opts->curOptIdx++;
+
+ if (*pz != '-')
+ return opt_find_long(opts, pz, o_st);
+
+ /*
+ * The name is prefixed with one or more hyphens. Strip them off
+ * and disable the "default_opt" setting. Use heavy recasting to
+ * strip off the "const" quality of the "default_opt" field.
+ */
+ while (*(++pz) == '-') ;
+ def_opt = VOIDP(&(opts->specOptIdx.default_opt));
+ def = *def_opt;
+ *def_opt = NO_EQUIVALENT;
+ res = opt_find_long(opts, pz, o_st);
+ *def_opt = (uint16_t)def;
+ return res;
+ }
+
+ /*
+ * Note the kind of flag/option marker
+ */
+ if (*((opts->pzCurOpt)++) != '-')
+ return PROBLEM; /* NORMAL COMPLETION - this + rest are operands */
+
+ /*
+ * Special hack for a hyphen by itself
+ */
+ if (*(opts->pzCurOpt) == NUL)
+ return PROBLEM; /* NORMAL COMPLETION - this + rest are operands */
+
+ /*
+ * The current argument is to be processed as an option argument
+ */
+ opts->curOptIdx++;
+
+ /*
+ * We have an option marker.
+ * Test the next character for long option indication
+ */
+ if (opts->pzCurOpt[0] == '-') {
+ if (*++(opts->pzCurOpt) == NUL)
+ /*
+ * NORMAL COMPLETION - NOT this arg, but rest are operands
+ */
+ return PROBLEM;
+
+ /*
+ * We do not allow the hyphen to be used as a flag value.
+ * Therefore, if long options are not to be accepted, we punt.
+ */
+ if ((opts->fOptSet & OPTPROC_LONGOPT) == 0) {
+ fprintf(stderr, zIllOptStr, opts->pzProgPath, opts->pzCurOpt-2);
+ return FAILURE;
+ }
+
+ return opt_find_long(opts, opts->pzCurOpt, o_st);
+ }
+
+ /*
+ * If short options are not allowed, then do long
+ * option processing. Otherwise the character must be a
+ * short (i.e. single character) option.
+ */
+ if ((opts->fOptSet & OPTPROC_SHORTOPT) != 0)
+ return opt_find_short(opts, (uint8_t)*(opts->pzCurOpt), o_st);
+
+ return opt_find_long(opts, opts->pzCurOpt, o_st);
+}
+
+/** @}
+ *
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of autoopts/find.c */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/genshell.c b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/genshell.c
new file mode 100644
index 0000000..0f05b3e
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/genshell.c
@@ -0,0 +1,847 @@
+/* -*- buffer-read-only: t -*- vi: set ro:
+ *
+ * DO NOT EDIT THIS FILE (genshell.c)
+ *
+ * It has been AutoGen-ed
+ * From the definitions genshell.def
+ * and the template file options
+ *
+ * Generated from AutoOpts 41:0:16 templates.
+ *
+ * AutoOpts is a copyrighted work. This source file is not encumbered
+ * by AutoOpts licensing, but is provided under the licensing terms chosen
+ * by the genshellopt author or copyright holder. AutoOpts is
+ * licensed under the terms of the LGPL. The redistributable library
+ * (``libopts'') is licensed under the terms of either the LGPL or, at the
+ * users discretion, the BSD license. See the AutoOpts and/or libopts sources
+ * for details.
+ *
+ * The genshellopt program is copyrighted and licensed
+ * under the following terms:
+ *
+ * Copyright (C) 1999-2014 Bruce Korb, all rights reserved.
+ * This is free software. It is licensed for use, modification and
+ * redistribution under the terms of the GNU Lesser General Public License,
+ * version 2 or later <http://www.gnu.org/licenses/old-licenses/lgpl-2.0.html>
+ *
+ * The genshellopt library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/old-licenses/lgpl-2.0.html>
+ */
+
+#ifndef __doxygen__
+#define OPTION_CODE_COMPILE 1
+#include "genshell.h"
+#include <sys/types.h>
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern FILE * option_usage_fp;
+#define zCopyright (genshellopt_opt_strs+0)
+#define zLicenseDescrip (genshellopt_opt_strs+285)
+
+extern tUsageProc genshelloptUsage;
+
+#ifndef NULL
+# define NULL 0
+#endif
+
+/**
+ * static const strings for genshellopt options
+ */
+static char const genshellopt_opt_strs[1769] =
+/* 0 */ "genshellopt 1\n"
+ "Copyright (C) 1999-2014 Bruce Korb, all rights reserved.\n"
+ "This is free software. It is licensed for use, modification and\n"
+ "redistribution under the terms of the GNU Lesser General Public License,\n"
+ "version 2 or later <http://www.gnu.org/licenses/old-licenses/lgpl-2.0.html>\n\0"
+/* 285 */ "The genshellopt library is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU Library General Public License as\n"
+ "published by the Free Software Foundation; either version 2 of the License,\n"
+ "or (at your option) any later version.\n\n"
+ "This library is distributed in the hope that it will be useful, but WITHOUT\n"
+ "ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n"
+ "FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public\n"
+ "License for more details.\n\n"
+ "You should have received a copy of the GNU Library General Public License\n"
+ "along with this library; if not, see\n"
+ "<http://www.gnu.org/licenses/old-licenses/lgpl-2.0.html>\n\0"
+/* 957 */ "Output Script File\0"
+/* 976 */ "SCRIPT\0"
+/* 983 */ "script\0"
+/* 990 */ "Shell name (follows \"#!\" magic)\0"
+/* 1022 */ "SHELL\0"
+/* 1028 */ "no-shell\0"
+/* 1037 */ "no\0"
+/* 1040 */ "display extended usage information and exit\0"
+/* 1084 */ "help\0"
+/* 1089 */ "extended usage information passed thru pager\0"
+/* 1134 */ "more-help\0"
+/* 1144 */ "output version information and exit\0"
+/* 1180 */ "version\0"
+/* 1188 */ "GENSHELLOPT\0"
+/* 1200 */ "genshellopt - Generate Shell Option Processing Script - Ver. 1\n"
+ "Usage: %s [ -<flag> [<val>] | --<name>[{=| }<val>] ]...\n\0"
+/* 1321 */ "autogen-users@lists.sourceforge.net\0"
+/* 1357 */ "Note that 'shell' is only useful if the output file does not already exist.\n"
+ "If it does, then the shell name and optional first argument will be\n"
+ "extracted from the script file.\n\0"
+/* 1534 */ "If the script file already exists and contains Automated Option Processing\n"
+ "text, the second line of the file through the ending tag will be replaced\n"
+ "by the newly generated text. The first '#!' line will be regenerated.\n\0"
+/* 1755 */ "genshellopt 1";
+
+/**
+ * script option description:
+ */
+/** Descriptive text for the script option */
+#define SCRIPT_DESC (genshellopt_opt_strs+957)
+/** Upper-cased name for the script option */
+#define SCRIPT_NAME (genshellopt_opt_strs+976)
+/** Name string for the script option */
+#define SCRIPT_name (genshellopt_opt_strs+983)
+/** Compiled in flag settings for the script option */
+#define SCRIPT_FLAGS (OPTST_DISABLED \
+ | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
+
+/**
+ * shell option description:
+ */
+/** Descriptive text for the shell option */
+#define SHELL_DESC (genshellopt_opt_strs+990)
+/** Upper-cased name for the shell option */
+#define SHELL_NAME (genshellopt_opt_strs+1022)
+/** disablement name for the shell option */
+#define NOT_SHELL_name (genshellopt_opt_strs+1028)
+/** disablement prefix for the shell option */
+#define NOT_SHELL_PFX (genshellopt_opt_strs+1037)
+/** Name string for the shell option */
+#define SHELL_name (NOT_SHELL_name + 3)
+/** Compiled in flag settings for the shell option */
+#define SHELL_FLAGS (OPTST_INITENABLED \
+ | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
+
+/*
+ * Help/More_Help/Version option descriptions:
+ */
+#define HELP_DESC (genshellopt_opt_strs+1040)
+#define HELP_name (genshellopt_opt_strs+1084)
+#ifdef HAVE_WORKING_FORK
+#define MORE_HELP_DESC (genshellopt_opt_strs+1089)
+#define MORE_HELP_name (genshellopt_opt_strs+1134)
+#define MORE_HELP_FLAGS (OPTST_IMM | OPTST_NO_INIT)
+#else
+#define MORE_HELP_DESC HELP_DESC
+#define MORE_HELP_name HELP_name
+#define MORE_HELP_FLAGS (OPTST_OMITTED | OPTST_NO_INIT)
+#endif
+#ifdef NO_OPTIONAL_OPT_ARGS
+# define VER_FLAGS (OPTST_IMM | OPTST_NO_INIT)
+#else
+# define VER_FLAGS (OPTST_SET_ARGTYPE(OPARG_TYPE_STRING) | \
+ OPTST_ARG_OPTIONAL | OPTST_IMM | OPTST_NO_INIT)
+#endif
+#define VER_DESC (genshellopt_opt_strs+1144)
+#define VER_name (genshellopt_opt_strs+1180)
+/**
+ * Declare option callback procedures
+ */
+extern tOptProc
+ optionBooleanVal, optionNestedVal, optionNumericVal,
+ optionPagedUsage, optionPrintVersion, optionResetOpt,
+ optionStackArg, optionTimeDate, optionTimeVal,
+ optionUnstackArg, optionVendorOption;
+static tOptProc
+ doUsageOpt;
+#define VER_PROC optionPrintVersion
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/**
+ * Define the genshellopt Option Descriptions.
+ * This is an array of GENSHELL_OPTION_CT entries, one for each
+ * option that the genshellopt program responds to.
+ */
+static tOptDesc optDesc[GENSHELL_OPTION_CT] = {
+ { /* entry idx, value */ 0, VALUE_GENSHELL_OPT_SCRIPT,
+ /* equiv idx, value */ 0, VALUE_GENSHELL_OPT_SCRIPT,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ SCRIPT_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --script */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, NULL,
+ /* option proc */ NULL,
+ /* desc, NAME, name */ SCRIPT_DESC, SCRIPT_NAME, SCRIPT_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ 1, VALUE_GENSHELL_OPT_SHELL,
+ /* equiv idx, value */ 1, VALUE_GENSHELL_OPT_SHELL,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ SHELL_FLAGS, 0,
+ /* last opt argumnt */ { NULL }, /* --shell */
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, NULL,
+ /* option proc */ NULL,
+ /* desc, NAME, name */ SHELL_DESC, SHELL_NAME, SHELL_name,
+ /* disablement strs */ NOT_SHELL_name, NOT_SHELL_PFX },
+
+ { /* entry idx, value */ INDEX_GENSHELL_OPT_VERSION, VALUE_GENSHELL_OPT_VERSION,
+ /* equiv idx value */ NO_EQUIVALENT, VALUE_GENSHELL_OPT_VERSION,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ VER_FLAGS, AOUSE_VERSION,
+ /* last opt argumnt */ { NULL },
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, NULL,
+ /* option proc */ VER_PROC,
+ /* desc, NAME, name */ VER_DESC, NULL, VER_name,
+ /* disablement strs */ NULL, NULL },
+
+
+
+ { /* entry idx, value */ INDEX_GENSHELL_OPT_HELP, VALUE_GENSHELL_OPT_HELP,
+ /* equiv idx value */ NO_EQUIVALENT, VALUE_GENSHELL_OPT_HELP,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ OPTST_IMM | OPTST_NO_INIT, AOUSE_HELP,
+ /* last opt argumnt */ { NULL },
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, NULL,
+ /* option proc */ doUsageOpt,
+ /* desc, NAME, name */ HELP_DESC, NULL, HELP_name,
+ /* disablement strs */ NULL, NULL },
+
+ { /* entry idx, value */ INDEX_GENSHELL_OPT_MORE_HELP, VALUE_GENSHELL_OPT_MORE_HELP,
+ /* equiv idx value */ NO_EQUIVALENT, VALUE_GENSHELL_OPT_MORE_HELP,
+ /* equivalenced to */ NO_EQUIVALENT,
+ /* min, max, act ct */ 0, 1, 0,
+ /* opt state flags */ MORE_HELP_FLAGS, AOUSE_MORE_HELP,
+ /* last opt argumnt */ { NULL },
+ /* arg list/cookie */ NULL,
+ /* must/cannot opts */ NULL, NULL,
+ /* option proc */ optionPagedUsage,
+ /* desc, NAME, name */ MORE_HELP_DESC, NULL, MORE_HELP_name,
+ /* disablement strs */ NULL, NULL }
+};
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/** Reference to the upper cased version of genshellopt. */
+#define zPROGNAME (genshellopt_opt_strs+1188)
+/** Reference to the title line for genshellopt usage. */
+#define zUsageTitle (genshellopt_opt_strs+1200)
+/** There is no genshellopt configuration file. */
+#define zRcName NULL
+/** There are no directories to search for genshellopt config files. */
+#define apzHomeList NULL
+/** The genshellopt program bug email address. */
+#define zBugsAddr (genshellopt_opt_strs+1321)
+/** Clarification/explanation of what genshellopt does. */
+#define zExplain (genshellopt_opt_strs+1357)
+/** Extra detail explaining what genshellopt does. */
+#define zDetail (genshellopt_opt_strs+1534)
+/** The full version string for genshellopt. */
+#define zFullVersion (genshellopt_opt_strs+1755)
+/* extracted from optcode.tlib near line 364 */
+
+#if defined(ENABLE_NLS)
+# define OPTPROC_BASE OPTPROC_TRANSLATE
+ static tOptionXlateProc translate_option_strings;
+#else
+# define OPTPROC_BASE OPTPROC_NONE
+# define translate_option_strings NULL
+#endif /* ENABLE_NLS */
+
+#define genshellopt_full_usage (NULL)
+#define genshellopt_short_usage (NULL)
+
+#endif /* not defined __doxygen__ */
+
+/*
+ * Create the static procedure(s) declared above.
+ */
+/**
+ * The callout function that invokes the genshelloptUsage function.
+ *
+ * @param[in] opts the AutoOpts option description structure
+ * @param[in] od the descriptor for the "help" (usage) option.
+ * @noreturn
+ */
+static void
+doUsageOpt(tOptions * opts, tOptDesc * od)
+{
+ int ex_code;
+ ex_code = GENSHELLOPT_EXIT_SUCCESS;
+ genshelloptUsage(&genshelloptOptions, ex_code);
+ /* NOTREACHED */
+ exit(1);
+ (void)opts;
+ (void)od;
+}
+/* extracted from optmain.tlib near line 1250 */
+
+/**
+ * The directory containing the data associated with genshellopt.
+ */
+#ifndef PKGDATADIR
+# define PKGDATADIR ""
+#endif
+
+/**
+ * Information about the person or institution that packaged genshellopt
+ * for the current distribution.
+ */
+#ifndef WITH_PACKAGER
+# define genshellopt_packager_info NULL
+#else
+/** Packager information for genshellopt. */
+static char const genshellopt_packager_info[] =
+ "Packaged by " WITH_PACKAGER
+
+# ifdef WITH_PACKAGER_VERSION
+ " ("WITH_PACKAGER_VERSION")"
+# endif
+
+# ifdef WITH_PACKAGER_BUG_REPORTS
+ "\nReport genshellopt bugs to " WITH_PACKAGER_BUG_REPORTS
+# endif
+ "\n";
+#endif
+#ifndef __doxygen__
+
+#endif /* __doxygen__ */
+/**
+ * The option definitions for genshellopt. The one structure that
+ * binds them all.
+ */
+tOptions genshelloptOptions = {
+ OPTIONS_STRUCT_VERSION,
+ 0, NULL, /* original argc + argv */
+ ( OPTPROC_BASE
+ + OPTPROC_ERRSTOP
+ + OPTPROC_SHORTOPT
+ + OPTPROC_LONGOPT
+ + OPTPROC_NO_REQ_OPT
+ + OPTPROC_NEGATIONS
+ + OPTPROC_NO_ARGS ),
+ 0, NULL, /* current option index, current option */
+ NULL, NULL, zPROGNAME,
+ zRcName, zCopyright, zLicenseDescrip,
+ zFullVersion, apzHomeList, zUsageTitle,
+ zExplain, zDetail, optDesc,
+ zBugsAddr, /* address to send bugs to */
+ NULL, NULL, /* extensions/saved state */
+ genshelloptUsage, /* usage procedure */
+ translate_option_strings, /* translation procedure */
+ /*
+ * Indexes to special options
+ */
+ { INDEX_GENSHELL_OPT_MORE_HELP, /* more-help option index */
+ NO_EQUIVALENT, /* save option index */
+ NO_EQUIVALENT, /* '-#' option index */
+ NO_EQUIVALENT /* index of default opt */
+ },
+ 5 /* full option count */, 2 /* user option count */,
+ genshellopt_full_usage, genshellopt_short_usage,
+ NULL, NULL,
+ PKGDATADIR, genshellopt_packager_info
+};
+
+#if ENABLE_NLS
+/**
+ * This code is designed to translate translatable option text for the
+ * genshellopt program. These translations happen upon entry
+ * to optionProcess().
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#ifdef HAVE_DCGETTEXT
+# include <gettext.h>
+#endif
+#include <autoopts/usage-txt.h>
+
+static char * AO_gettext(char const * pz);
+static void coerce_it(void ** s);
+
+/**
+ * AutoGen specific wrapper function for gettext. It relies on the macro _()
+ * to convert from English to the target language, then strdup-duplicates the
+ * result string. It tries the "libopts" domain first, then whatever has been
+ * set via the \a textdomain(3) call.
+ *
+ * @param[in] pz the input text used as a lookup key.
+ * @returns the translated text (if there is one),
+ * or the original text (if not).
+ */
+static char *
+AO_gettext(char const * pz)
+{
+ char * res;
+ if (pz == NULL)
+ return NULL;
+#ifdef HAVE_DCGETTEXT
+ /*
+ * While processing the option_xlateable_txt data, try to use the
+ * "libopts" domain. Once we switch to the option descriptor data,
+ * do *not* use that domain.
+ */
+ if (option_xlateable_txt.field_ct != 0) {
+ res = dgettext("libopts", pz);
+ if (res == pz)
+ res = (char *)VOIDP(_(pz));
+ } else
+ res = (char *)VOIDP(_(pz));
+#else
+ res = (char *)VOIDP(_(pz));
+#endif
+ if (res == pz)
+ return res;
+ res = strdup(res);
+ if (res == NULL) {
+ fputs(_("No memory for duping translated strings\n"), stderr);
+ exit(GENSHELLOPT_EXIT_FAILURE);
+ }
+ return res;
+}
+
+/**
+ * All the pointers we use are marked "* const", but they are stored in
+ * writable memory. Coerce the mutability and set the pointer.
+ */
+static void coerce_it(void ** s) { *s = AO_gettext(*s);
+}
+
+/**
+ * Translate all the translatable strings in the genshelloptOptions
+ * structure defined above. This is done only once.
+ */
+static void
+translate_option_strings(void)
+{
+ tOptions * const opts = &genshelloptOptions;
+
+ /*
+ * Guard against re-translation. It won't work. The strings will have
+ * been changed by the first pass through this code. One shot only.
+ */
+ if (option_xlateable_txt.field_ct != 0) {
+ /*
+ * Do the translations. The first pointer follows the field count
+ * field. The field count field is the size of a pointer.
+ */
+ char ** ppz = (char**)VOIDP(&(option_xlateable_txt));
+ int ix = option_xlateable_txt.field_ct;
+
+ do {
+ ppz++; /* skip over field_ct */
+ *ppz = AO_gettext(*ppz);
+ } while (--ix > 0);
+ /* prevent re-translation and disable "libopts" domain lookup */
+ option_xlateable_txt.field_ct = 0;
+
+ coerce_it(VOIDP(&(opts->pzCopyright)));
+ coerce_it(VOIDP(&(opts->pzCopyNotice)));
+ coerce_it(VOIDP(&(opts->pzFullVersion)));
+ coerce_it(VOIDP(&(opts->pzUsageTitle)));
+ coerce_it(VOIDP(&(opts->pzExplain)));
+ coerce_it(VOIDP(&(opts->pzDetail)));
+ {
+ tOptDesc * od = opts->pOptDesc;
+ for (ix = opts->optCt; ix > 0; ix--, od++)
+ coerce_it(VOIDP(&(od->pzText)));
+ }
+ }
+}
+#endif /* ENABLE_NLS */
+
+#ifdef DO_NOT_COMPILE_THIS_CODE_IT_IS_FOR_GETTEXT
+/** I18N function strictly for xgettext. Do not compile. */
+static void bogus_function(void) {
+ /* TRANSLATORS:
+
+ The following dummy function was crated solely so that xgettext can
+ extract the correct strings. These strings are actually referenced
+ by a field name in the genshelloptOptions structure noted in the
+ comments below. The literal text is defined in genshellopt_opt_strs.
+
+ NOTE: the strings below are segmented with respect to the source string
+ genshellopt_opt_strs. The strings above are handed off for translation
+ at run time a paragraph at a time. Consequently, they are presented here
+ for translation a paragraph at a time.
+
+ ALSO: often the description for an option will reference another option
+ by name. These are set off with apostrophe quotes (I hope). Do not
+ translate option names.
+ */
+ /* referenced via genshelloptOptions.pzCopyright */
+ puts(_("genshellopt 1\n\
+Copyright (C) 1999-2014 Bruce Korb, all rights reserved.\n\
+This is free software. It is licensed for use, modification and\n\
+redistribution under the terms of the GNU Lesser General Public License,\n\
+version 2 or later <http://www.gnu.org/licenses/old-licenses/lgpl-2.0.html>\n"));
+
+ /* referenced via genshelloptOptions.pzCopyNotice */
+ puts(_("The genshellopt library is free software; you can redistribute it and/or\n\
+modify it under the terms of the GNU Library General Public License as\n\
+published by the Free Software Foundation; either version 2 of the License,\n\
+or (at your option) any later version.\n\n"));
+ puts(_("This library is distributed in the hope that it will be useful, but WITHOUT\n\
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n\
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public\n\
+License for more details.\n\n"));
+ puts(_("You should have received a copy of the GNU Library General Public License\n\
+along with this library; if not, see\n\
+<http://www.gnu.org/licenses/old-licenses/lgpl-2.0.html>\n"));
+
+ /* referenced via genshelloptOptions.pOptDesc->pzText */
+ puts(_("Output Script File"));
+
+ /* referenced via genshelloptOptions.pOptDesc->pzText */
+ puts(_("Shell name (follows \"#!\" magic)"));
+
+ /* referenced via genshelloptOptions.pOptDesc->pzText */
+ puts(_("display extended usage information and exit"));
+
+ /* referenced via genshelloptOptions.pOptDesc->pzText */
+ puts(_("extended usage information passed thru pager"));
+
+ /* referenced via genshelloptOptions.pOptDesc->pzText */
+ puts(_("output version information and exit"));
+
+ /* referenced via genshelloptOptions.pzUsageTitle */
+ puts(_("genshellopt - Generate Shell Option Processing Script - Ver. 1\n\
+Usage: %s [ -<flag> [<val>] | --<name>[{=| }<val>] ]...\n"));
+
+ /* referenced via genshelloptOptions.pzExplain */
+ puts(_("Note that 'shell' is only useful if the output file does not already exist.\n\
+If it does, then the shell name and optional first argument will be\n\
+extracted from the script file.\n"));
+
+ /* referenced via genshelloptOptions.pzDetail */
+ puts(_("If the script file already exists and contains Automated Option Processing\n\
+text, the second line of the file through the ending tag will be replaced\n\
+by the newly generated text. The first '#!' line will be regenerated.\n"));
+
+ /* referenced via genshelloptOptions.pzFullVersion */
+ puts(_("genshellopt 1"));
+
+ /* referenced via genshelloptOptions.pzFullUsage */
+ puts(_("<<<NOT-FOUND>>>"));
+
+ /* referenced via genshelloptOptions.pzShortUsage */
+ puts(_("<<<NOT-FOUND>>>"));
+ /* LIBOPTS-MESSAGES: */
+#line 67 "../autoopts.c"
+ puts(_("allocation of %d bytes failed\n"));
+#line 93 "../autoopts.c"
+ puts(_("allocation of %d bytes failed\n"));
+#line 53 "../init.c"
+ puts(_("AutoOpts function called without option descriptor\n"));
+#line 86 "../init.c"
+ puts(_("\tThis exceeds the compiled library version: "));
+#line 84 "../init.c"
+ puts(_("Automated Options Processing Error!\n"
+ "\t%s called AutoOpts function with structure version %d:%d:%d.\n"));
+#line 80 "../autoopts.c"
+ puts(_("realloc of %d bytes at 0x%p failed\n"));
+#line 88 "../init.c"
+ puts(_("\tThis is less than the minimum library version: "));
+#line 121 "../version.c"
+ puts(_("Automated Options version %s\n"
+ "\tCopyright (C) 1999-2014 by Bruce Korb - all rights reserved\n"));
+#line 87 "../makeshell.c"
+ puts(_("(AutoOpts bug): %s.\n"));
+#line 90 "../reset.c"
+ puts(_("optionResetOpt() called, but reset-option not configured"));
+#line 292 "../usage.c"
+ puts(_("could not locate the 'help' option"));
+#line 336 "../autoopts.c"
+ puts(_("optionProcess() was called with invalid data"));
+#line 748 "../usage.c"
+ puts(_("invalid argument type specified"));
+#line 598 "../find.c"
+ puts(_("defaulted to option with optional arg"));
+#line 76 "../alias.c"
+ puts(_("aliasing option is out of range."));
+#line 234 "../enum.c"
+ puts(_("%s error: the keyword '%s' is ambiguous for %s\n"));
+#line 108 "../find.c"
+ puts(_(" The following options match:\n"));
+#line 293 "../find.c"
+ puts(_("%s: ambiguous option name: %s (matches %d options)\n"));
+#line 161 "../check.c"
+ puts(_("%s: Command line arguments required\n"));
+#line 43 "../alias.c"
+ puts(_("%d %s%s options allowed\n"));
+#line 94 "../makeshell.c"
+ puts(_("%s error %d (%s) calling %s for '%s'\n"));
+#line 306 "../makeshell.c"
+ puts(_("interprocess pipe"));
+#line 168 "../version.c"
+ puts(_("error: version option argument '%c' invalid. Use:\n"
+ "\t'v' - version only\n"
+ "\t'c' - version and copyright\n"
+ "\t'n' - version and full copyright notice\n"));
+#line 58 "../check.c"
+ puts(_("%s error: the '%s' and '%s' options conflict\n"));
+#line 217 "../find.c"
+ puts(_("%s: The '%s' option has been disabled."));
+#line 430 "../find.c"
+ puts(_("%s: The '%s' option has been disabled."));
+#line 38 "../alias.c"
+ puts(_("-equivalence"));
+#line 469 "../find.c"
+ puts(_("%s: illegal option -- %c\n"));
+#line 110 "../reset.c"
+ puts(_("%s: illegal option -- %c\n"));
+#line 271 "../find.c"
+ puts(_("%s: illegal option -- %s\n"));
+#line 755 "../find.c"
+ puts(_("%s: illegal option -- %s\n"));
+#line 118 "../reset.c"
+ puts(_("%s: illegal option -- %s\n"));
+#line 335 "../find.c"
+ puts(_("%s: unknown vendor extension option -- %s\n"));
+#line 159 "../enum.c"
+ puts(_(" or an integer from %d through %d\n"));
+#line 169 "../enum.c"
+ puts(_(" or an integer from %d through %d\n"));
+#line 747 "../usage.c"
+ puts(_("%s error: invalid option descriptor for %s\n"));
+#line 1081 "../usage.c"
+ puts(_("%s error: invalid option descriptor for %s\n"));
+#line 385 "../find.c"
+ puts(_("%s: invalid option name: %s\n"));
+#line 527 "../find.c"
+ puts(_("%s: The '%s' option requires an argument.\n"));
+#line 156 "../autoopts.c"
+ puts(_("(AutoOpts bug): Equivalenced option '%s' was equivalenced to both\n"
+ "\t'%s' and '%s'."));
+#line 94 "../check.c"
+ puts(_("%s error: The %s option is required\n"));
+#line 632 "../find.c"
+ puts(_("%s: The '%s' option cannot have an argument.\n"));
+#line 151 "../check.c"
+ puts(_("%s: Command line arguments are not allowed.\n"));
+#line 535 "../save.c"
+ puts(_("error %d (%s) creating %s\n"));
+#line 234 "../enum.c"
+ puts(_("%s error: '%s' does not match any %s keywords.\n"));
+#line 93 "../reset.c"
+ puts(_("%s error: The '%s' option requires an argument.\n"));
+#line 184 "../save.c"
+ puts(_("error %d (%s) stat-ing %s\n"));
+#line 238 "../save.c"
+ puts(_("error %d (%s) stat-ing %s\n"));
+#line 143 "../restore.c"
+ puts(_("%s error: no saved option state\n"));
+#line 231 "../autoopts.c"
+ puts(_("'%s' is not a command line option.\n"));
+#line 111 "../time.c"
+ puts(_("%s error: '%s' is not a recognizable date/time.\n"));
+#line 132 "../save.c"
+ puts(_("'%s' not defined\n"));
+#line 50 "../time.c"
+ puts(_("%s error: '%s' is not a recognizable time duration.\n"));
+#line 92 "../check.c"
+ puts(_("%s error: The %s option must appear %d times.\n"));
+#line 164 "../numeric.c"
+ puts(_("%s error: '%s' is not a recognizable number.\n"));
+#line 200 "../enum.c"
+ puts(_("%s error: %s exceeds %s keyword count\n"));
+#line 330 "../usage.c"
+ puts(_("Try '%s %s' for more information.\n"));
+#line 45 "../alias.c"
+ puts(_("one %s%s option allowed\n"));
+#line 208 "../makeshell.c"
+ puts(_("standard output"));
+#line 943 "../makeshell.c"
+ puts(_("standard output"));
+#line 274 "../usage.c"
+ puts(_("standard output"));
+#line 415 "../usage.c"
+ puts(_("standard output"));
+#line 625 "../usage.c"
+ puts(_("standard output"));
+#line 175 "../version.c"
+ puts(_("standard output"));
+#line 274 "../usage.c"
+ puts(_("standard error"));
+#line 415 "../usage.c"
+ puts(_("standard error"));
+#line 625 "../usage.c"
+ puts(_("standard error"));
+#line 175 "../version.c"
+ puts(_("standard error"));
+#line 208 "../makeshell.c"
+ puts(_("write"));
+#line 943 "../makeshell.c"
+ puts(_("write"));
+#line 273 "../usage.c"
+ puts(_("write"));
+#line 414 "../usage.c"
+ puts(_("write"));
+#line 624 "../usage.c"
+ puts(_("write"));
+#line 174 "../version.c"
+ puts(_("write"));
+#line 60 "../numeric.c"
+ puts(_("%s error: %s option value %ld is out of range.\n"));
+#line 44 "../check.c"
+ puts(_("%s error: %s option requires the %s option\n"));
+#line 131 "../save.c"
+ puts(_("%s warning: cannot save options - %s not regular file\n"));
+#line 183 "../save.c"
+ puts(_("%s warning: cannot save options - %s not regular file\n"));
+#line 237 "../save.c"
+ puts(_("%s warning: cannot save options - %s not regular file\n"));
+#line 256 "../save.c"
+ puts(_("%s warning: cannot save options - %s not regular file\n"));
+#line 534 "../save.c"
+ puts(_("%s warning: cannot save options - %s not regular file\n"));
+ /* END-LIBOPTS-MESSAGES */
+
+ /* USAGE-TEXT: */
+#line 873 "../usage.c"
+ puts(_("\t\t\t\t- an alternate for '%s'\n"));
+#line 1148 "../usage.c"
+ puts(_("Version, usage and configuration options:"));
+#line 924 "../usage.c"
+ puts(_("\t\t\t\t- default option for unnamed options\n"));
+#line 837 "../usage.c"
+ puts(_("\t\t\t\t- disabled as '--%s'\n"));
+#line 1117 "../usage.c"
+ puts(_(" --- %-14s %s\n"));
+#line 1115 "../usage.c"
+ puts(_("This option has been disabled"));
+#line 864 "../usage.c"
+ puts(_("\t\t\t\t- enabled by default\n"));
+#line 40 "../alias.c"
+ puts(_("%s error: only "));
+#line 1194 "../usage.c"
+ puts(_(" - examining environment variables named %s_*\n"));
+#line 168 "../file.c"
+ puts(_("\t\t\t\t- file must not pre-exist\n"));
+#line 172 "../file.c"
+ puts(_("\t\t\t\t- file must pre-exist\n"));
+#line 380 "../usage.c"
+ puts(_("Options are specified by doubled hyphens and their name or by a single\n"
+ "hyphen and the flag character.\n"));
+#line 921 "../makeshell.c"
+ puts(_("\n"
+ "= = = = = = = =\n\n"
+ "This incarnation of genshell will produce\n"
+ "a shell script to parse the options for %s:\n\n"));
+#line 166 "../enum.c"
+ puts(_(" or an integer mask with any of the lower %d bits set\n"));
+#line 897 "../usage.c"
+ puts(_("\t\t\t\t- is a set membership option\n"));
+#line 918 "../usage.c"
+ puts(_("\t\t\t\t- must appear between %d and %d times\n"));
+#line 382 "../usage.c"
+ puts(_("Options are specified by single or double hyphens and their name.\n"));
+#line 904 "../usage.c"
+ puts(_("\t\t\t\t- may appear multiple times\n"));
+#line 891 "../usage.c"
+ puts(_("\t\t\t\t- may not be preset\n"));
+#line 1309 "../usage.c"
+ puts(_(" Arg Option-Name Description\n"));
+#line 1245 "../usage.c"
+ puts(_(" Flg Arg Option-Name Description\n"));
+#line 1303 "../usage.c"
+ puts(_(" Flg Arg Option-Name Description\n"));
+#line 1304 "../usage.c"
+ puts(_(" %3s %s"));
+#line 1310 "../usage.c"
+ puts(_(" %3s %s"));
+#line 387 "../usage.c"
+ puts(_("The '-#<number>' option may omit the hash char\n"));
+#line 383 "../usage.c"
+ puts(_("All arguments are named options.\n"));
+#line 971 "../usage.c"
+ puts(_(" - reading file %s"));
+#line 409 "../usage.c"
+ puts(_("\n"
+ "Please send bug reports to: <%s>\n"));
+#line 100 "../version.c"
+ puts(_("\n"
+ "Please send bug reports to: <%s>\n"));
+#line 129 "../version.c"
+ puts(_("\n"
+ "Please send bug reports to: <%s>\n"));
+#line 903 "../usage.c"
+ puts(_("\t\t\t\t- may NOT appear - preset only\n"));
+#line 944 "../usage.c"
+ puts(_("\n"
+ "The following option preset mechanisms are supported:\n"));
+#line 1192 "../usage.c"
+ puts(_("\n"
+ "The following option preset mechanisms are supported:\n"));
+#line 682 "../usage.c"
+ puts(_("prohibits these options:\n"));
+#line 677 "../usage.c"
+ puts(_("prohibits the option '%s'\n"));
+#line 81 "../numeric.c"
+ puts(_("%s%ld to %ld"));
+#line 79 "../numeric.c"
+ puts(_("%sgreater than or equal to %ld"));
+#line 75 "../numeric.c"
+ puts(_("%s%ld exactly"));
+#line 68 "../numeric.c"
+ puts(_("%sit must lie in one of the ranges:\n"));
+#line 68 "../numeric.c"
+ puts(_("%sit must be in the range:\n"));
+#line 88 "../numeric.c"
+ puts(_(", or\n"));
+#line 66 "../numeric.c"
+ puts(_("%sis scalable with a suffix: k/K/m/M/g/G/t/T\n"));
+#line 77 "../numeric.c"
+ puts(_("%sless than or equal to %ld"));
+#line 390 "../usage.c"
+ puts(_("Operands and options may be intermixed. They will be reordered.\n"));
+#line 652 "../usage.c"
+ puts(_("requires the option '%s'\n"));
+#line 655 "../usage.c"
+ puts(_("requires these options:\n"));
+#line 1321 "../usage.c"
+ puts(_(" Arg Option-Name Req? Description\n"));
+#line 1315 "../usage.c"
+ puts(_(" Flg Arg Option-Name Req? Description\n"));
+#line 167 "../enum.c"
+ puts(_("or you may use a numeric representation. Preceding these with a '!'\n"
+ "will clear the bits, specifying 'none' will clear all bits, and 'all'\n"
+ "will set them all. Multiple entries may be passed as an option\n"
+ "argument list.\n"));
+#line 910 "../usage.c"
+ puts(_("\t\t\t\t- may appear up to %d times\n"));
+#line 77 "../enum.c"
+ puts(_("The valid \"%s\" option keywords are:\n"));
+#line 1152 "../usage.c"
+ puts(_("The next option supports vendor supported extra options:"));
+#line 773 "../usage.c"
+ puts(_("These additional options are:"));
+ /* END-USAGE-TEXT */
+}
+#endif /* uncompilable code */
+#ifdef __cplusplus
+}
+#endif
+/* genshell.c ends here */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/genshell.h b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/genshell.h
new file mode 100644
index 0000000..4482556
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/genshell.h
@@ -0,0 +1,209 @@
+/* -*- buffer-read-only: t -*- vi: set ro:
+ *
+ * DO NOT EDIT THIS FILE (genshell.h)
+ *
+ * It has been AutoGen-ed
+ * From the definitions genshell.def
+ * and the template file options
+ *
+ * Generated from AutoOpts 41:0:16 templates.
+ *
+ * AutoOpts is a copyrighted work. This header file is not encumbered
+ * by AutoOpts licensing, but is provided under the licensing terms chosen
+ * by the genshellopt author or copyright holder. AutoOpts is
+ * licensed under the terms of the LGPL. The redistributable library
+ * (``libopts'') is licensed under the terms of either the LGPL or, at the
+ * users discretion, the BSD license. See the AutoOpts and/or libopts sources
+ * for details.
+ *
+ * The genshellopt program is copyrighted and licensed
+ * under the following terms:
+ *
+ * Copyright (C) 1999-2014 Bruce Korb, all rights reserved.
+ * This is free software. It is licensed for use, modification and
+ * redistribution under the terms of the GNU Lesser General Public License,
+ * version 2 or later <http://www.gnu.org/licenses/old-licenses/lgpl-2.0.html>
+ *
+ * The genshellopt library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/old-licenses/lgpl-2.0.html>
+ */
+/**
+ * This file contains the programmatic interface to the Automated
+ * Options generated for the genshellopt program.
+ * These macros are documented in the AutoGen info file in the
+ * "AutoOpts" chapter. Please refer to that doc for usage help.
+ */
+#ifndef AUTOOPTS_GENSHELL_H_GUARD
+#define AUTOOPTS_GENSHELL_H_GUARD 1
+#include <autoopts/options.h>
+
+/**
+ * Ensure that the library used for compiling this generated header is at
+ * least as new as the version current when the header template was released
+ * (not counting patch version increments). Also ensure that the oldest
+ * tolerable version is at least as old as what was current when the header
+ * template was released.
+ */
+#define AO_TEMPLATE_VERSION 167937
+#if (AO_TEMPLATE_VERSION < OPTIONS_MINIMUM_VERSION) \
+ || (AO_TEMPLATE_VERSION > OPTIONS_STRUCT_VERSION)
+# error option template version mismatches autoopts/options.h header
+ Choke Me.
+#endif
+
+/**
+ * Enumeration of each option type for genshellopt
+ */
+typedef enum {
+ INDEX_GENSHELL_OPT_SCRIPT = 0,
+ INDEX_GENSHELL_OPT_SHELL = 1,
+ INDEX_GENSHELL_OPT_VERSION = 2,
+ INDEX_GENSHELL_OPT_HELP = 3,
+ INDEX_GENSHELL_OPT_MORE_HELP = 4
+} teGenshell_OptIndex;
+/** count of all options for genshellopt */
+#define GENSHELL_OPTION_CT 5
+/** genshellopt version */
+#define GENSHELLOPT_VERSION "1"
+/** Full genshellopt version text */
+#define GENSHELLOPT_FULL_VERSION "genshellopt 1"
+
+/**
+ * Interface defines for all options. Replace "n" with the UPPER_CASED
+ * option name (as in the teGenshell_OptIndex enumeration above).
+ * e.g. HAVE_GENSHELL_OPT(SCRIPT)
+ */
+#define GENSHELL_DESC(n) (genshelloptOptions.pOptDesc[INDEX_GENSHELL_OPT_## n])
+/** 'true' if an option has been specified in any way */
+#define HAVE_GENSHELL_OPT(n) (! UNUSED_OPT(& GENSHELL_DESC(n)))
+/** The string argument to an option. The argument type must be \"string\". */
+#define GENSHELL_OPT_ARG(n) (GENSHELL_DESC(n).optArg.argString)
+/** Mask the option state revealing how an option was specified.
+ * It will be one and only one of \a OPTST_SET, \a OPTST_PRESET,
+ * \a OPTST_DEFINED, \a OPTST_RESET or zero.
+ */
+#define STATE_GENSHELL_OPT(n) (GENSHELL_DESC(n).fOptState & OPTST_SET_MASK)
+/** Count of option's occurrances *on the command line*. */
+#define COUNT_GENSHELL_OPT(n) (GENSHELL_DESC(n).optOccCt)
+/** mask of \a OPTST_SET and \a OPTST_DEFINED. */
+#define ISSEL_GENSHELL_OPT(n) (SELECTED_OPT(&GENSHELL_DESC(n)))
+/** 'true' if \a HAVE_OPT would yield 'false'. */
+#define ISUNUSED_GENSHELL_OPT(n) (UNUSED_OPT(& GENSHELL_DESC(n)))
+/** 'true' if OPTST_DISABLED bit not set. */
+#define ENABLED_GENSHELL_OPT(n) (! DISABLED_OPT(& GENSHELL_DESC(n)))
+/** number of stacked option arguments.
+ * Valid only for stacked option arguments. */
+#define STACKCT_GENSHELL_OPT(n) (((tArgList*)(GENSHELL_DESC(n).optCookie))->useCt)
+/** stacked argument vector.
+ * Valid only for stacked option arguments. */
+#define STACKLST_GENSHELL_OPT(n) (((tArgList*)(GENSHELL_DESC(n).optCookie))->apzArgs)
+/** Reset an option. */
+#define CLEAR_GENSHELL_OPT(n) STMTS( \
+ GENSHELL_DESC(n).fOptState &= OPTST_PERSISTENT_MASK; \
+ if ((GENSHELL_DESC(n).fOptState & OPTST_INITENABLED) == 0) \
+ GENSHELL_DESC(n).fOptState |= OPTST_DISABLED; \
+ GENSHELL_DESC(n).optCookie = NULL )
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/**
+ * Enumeration of genshellopt exit codes
+ */
+typedef enum {
+ GENSHELLOPT_EXIT_SUCCESS = 0,
+ GENSHELLOPT_EXIT_FAILURE = 1,
+ GENSHELLOPT_EXIT_USAGE_ERROR = 64,
+ GENSHELLOPT_EXIT_LIBOPTS_FAILURE = 70
+} genshellopt_exit_code_t;
+/**
+ * Interface defines for specific options.
+ * @{
+ */
+#define VALUE_GENSHELL_OPT_SCRIPT 'o'
+#define VALUE_GENSHELL_OPT_SHELL 's'
+/** option flag (value) for help-value option */
+#define VALUE_GENSHELL_OPT_HELP '?'
+/** option flag (value) for more-help-value option */
+#define VALUE_GENSHELL_OPT_MORE_HELP '!'
+/** option flag (value) for version-value option */
+#define VALUE_GENSHELL_OPT_VERSION 'v'
+/*
+ * Interface defines not associated with particular options
+ */
+#define ERRSKIP_GENSHELL_OPTERR STMTS(genshelloptOptions.fOptSet &= ~OPTPROC_ERRSTOP)
+#define ERRSTOP_GENSHELL_OPTERR STMTS(genshelloptOptions.fOptSet |= OPTPROC_ERRSTOP)
+#define RESTART_GENSHELL_OPT(n) STMTS( \
+ genshelloptOptions.curOptIdx = (n); \
+ genshelloptOptions.pzCurOpt = NULL )
+#define START_GENSHELL_OPT RESTART_GENSHELL_OPT(1)
+#define GENSHELL_USAGE(c) (*genshelloptOptions.pUsageProc)(&genshelloptOptions, c)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* * * * * *
+ *
+ * Declare the genshellopt option descriptor.
+ */
+extern tOptions genshelloptOptions;
+
+#if defined(ENABLE_NLS)
+# ifndef _
+# include <stdio.h>
+# ifndef HAVE_GETTEXT
+ extern char * gettext(char const *);
+# else
+# include <libintl.h>
+# endif
+
+# ifndef ATTRIBUTE_FORMAT_ARG
+# define ATTRIBUTE_FORMAT_ARG(_a)
+# endif
+
+static inline char* aoGetsText(char const* pz) ATTRIBUTE_FORMAT_ARG(1);
+static inline char* aoGetsText(char const* pz) {
+ if (pz == NULL) return NULL;
+ return (char*)gettext(pz);
+}
+# define _(s) aoGetsText(s)
+# endif /* _() */
+
+# define OPT_NO_XLAT_CFG_NAMES STMTS(genshelloptOptions.fOptSet |= \
+ OPTPROC_NXLAT_OPT_CFG;)
+# define OPT_NO_XLAT_OPT_NAMES STMTS(genshelloptOptions.fOptSet |= \
+ OPTPROC_NXLAT_OPT|OPTPROC_NXLAT_OPT_CFG;)
+
+# define OPT_XLAT_CFG_NAMES STMTS(genshelloptOptions.fOptSet &= \
+ ~(OPTPROC_NXLAT_OPT|OPTPROC_NXLAT_OPT_CFG);)
+# define OPT_XLAT_OPT_NAMES STMTS(genshelloptOptions.fOptSet &= \
+ ~OPTPROC_NXLAT_OPT;)
+
+#else /* ENABLE_NLS */
+# define OPT_NO_XLAT_CFG_NAMES
+# define OPT_NO_XLAT_OPT_NAMES
+
+# define OPT_XLAT_CFG_NAMES
+# define OPT_XLAT_OPT_NAMES
+
+# ifndef _
+# define _(_s) _s
+# endif
+#endif /* ENABLE_NLS */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* AUTOOPTS_GENSHELL_H_GUARD */
+
+/* genshell.h ends here */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/gettext.h b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/gettext.h
new file mode 100644
index 0000000..7d3ea3c
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/gettext.h
@@ -0,0 +1,288 @@
+/* Convenience header for conditional use of GNU <libintl.h>.
+ Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009-2015 Free Software
+ Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License along
+ with this program; if not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef _LIBGETTEXT_H
+#define _LIBGETTEXT_H 1
+
+/* NLS can be disabled through the configure --disable-nls option. */
+#if ENABLE_NLS
+
+/* Get declarations of GNU message catalog functions. */
+# include <libintl.h>
+
+/* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by
+ the gettext() and ngettext() macros. This is an alternative to calling
+ textdomain(), and is useful for libraries. */
+# ifdef DEFAULT_TEXT_DOMAIN
+# undef gettext
+# define gettext(Msgid) \
+ dgettext (DEFAULT_TEXT_DOMAIN, Msgid)
+# undef ngettext
+# define ngettext(Msgid1, Msgid2, N) \
+ dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N)
+# endif
+
+#else
+
+/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which
+ chokes if dcgettext is defined as a macro. So include it now, to make
+ later inclusions of <locale.h> a NOP. We don't include <libintl.h>
+ as well because people using "gettext.h" will not include <libintl.h>,
+ and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
+ is OK. */
+#if defined(__sun)
+# include <locale.h>
+#endif
+
+/* Many header files from the libstdc++ coming with g++ 3.3 or newer include
+ <libintl.h>, which chokes if dcgettext is defined as a macro. So include
+ it now, to make later inclusions of <libintl.h> a NOP. */
+#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3)
+# include <cstdlib>
+# if (__GLIBC__ >= 2 && !defined __UCLIBC__) || _GLIBCXX_HAVE_LIBINTL_H
+# include <libintl.h>
+# endif
+#endif
+
+/* Disabled NLS.
+ The casts to 'const char *' serve the purpose of producing warnings
+ for invalid uses of the value returned from these functions.
+ On pre-ANSI systems without 'const', the config.h file is supposed to
+ contain "#define const". */
+# undef gettext
+# define gettext(Msgid) ((const char *) (Msgid))
+# undef dgettext
+# define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid))
+# undef dcgettext
+# define dcgettext(Domainname, Msgid, Category) \
+ ((void) (Category), dgettext (Domainname, Msgid))
+# undef ngettext
+# define ngettext(Msgid1, Msgid2, N) \
+ ((N) == 1 \
+ ? ((void) (Msgid2), (const char *) (Msgid1)) \
+ : ((void) (Msgid1), (const char *) (Msgid2)))
+# undef dngettext
+# define dngettext(Domainname, Msgid1, Msgid2, N) \
+ ((void) (Domainname), ngettext (Msgid1, Msgid2, N))
+# undef dcngettext
+# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
+ ((void) (Category), dngettext (Domainname, Msgid1, Msgid2, N))
+# undef textdomain
+# define textdomain(Domainname) ((const char *) (Domainname))
+# undef bindtextdomain
+# define bindtextdomain(Domainname, Dirname) \
+ ((void) (Domainname), (const char *) (Dirname))
+# undef bind_textdomain_codeset
+# define bind_textdomain_codeset(Domainname, Codeset) \
+ ((void) (Domainname), (const char *) (Codeset))
+
+#endif
+
+/* Prefer gnulib's setlocale override over libintl's setlocale override. */
+#ifdef GNULIB_defined_setlocale
+# undef setlocale
+# define setlocale rpl_setlocale
+#endif
+
+/* A pseudo function call that serves as a marker for the automated
+ extraction of messages, but does not call gettext(). The run-time
+ translation is done at a different place in the code.
+ The argument, String, should be a literal string. Concatenated strings
+ and other string expressions won't work.
+ The macro's expansion is not parenthesized, so that it is suitable as
+ initializer for static 'char[]' or 'const char[]' variables. */
+#define gettext_noop(String) String
+
+/* The separator between msgctxt and msgid in a .mo file. */
+#define GETTEXT_CONTEXT_GLUE "\004"
+
+/* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a
+ MSGID. MSGCTXT and MSGID must be string literals. MSGCTXT should be
+ short and rarely need to change.
+ The letter 'p' stands for 'particular' or 'special'. */
+#ifdef DEFAULT_TEXT_DOMAIN
+# define pgettext(Msgctxt, Msgid) \
+ pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
+#else
+# define pgettext(Msgctxt, Msgid) \
+ pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
+#endif
+#define dpgettext(Domainname, Msgctxt, Msgid) \
+ pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
+#define dcpgettext(Domainname, Msgctxt, Msgid, Category) \
+ pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category)
+#ifdef DEFAULT_TEXT_DOMAIN
+# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
+ npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
+#else
+# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
+ npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
+#endif
+#define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
+ npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
+#define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \
+ npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category)
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+static const char *
+pgettext_aux (const char *domain,
+ const char *msg_ctxt_id, const char *msgid,
+ int category)
+{
+ const char *translation = dcgettext (domain, msg_ctxt_id, category);
+ if (translation == msg_ctxt_id)
+ return msgid;
+ else
+ return translation;
+}
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+static const char *
+npgettext_aux (const char *domain,
+ const char *msg_ctxt_id, const char *msgid,
+ const char *msgid_plural, unsigned long int n,
+ int category)
+{
+ const char *translation =
+ dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
+ if (translation == msg_ctxt_id || translation == msgid_plural)
+ return (n == 1 ? msgid : msgid_plural);
+ else
+ return translation;
+}
+
+/* The same thing extended for non-constant arguments. Here MSGCTXT and MSGID
+ can be arbitrary expressions. But for string literals these macros are
+ less efficient than those above. */
+
+#include <string.h>
+
+#if (((__GNUC__ >= 3 || __GNUG__ >= 2) && !defined __STRICT_ANSI__) \
+ /* || __STDC_VERSION__ >= 199901L */ )
+# define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 1
+#else
+# define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 0
+#endif
+
+#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
+#include <stdlib.h>
+#endif
+
+#define pgettext_expr(Msgctxt, Msgid) \
+ dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES)
+#define dpgettext_expr(Domainname, Msgctxt, Msgid) \
+ dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES)
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+static const char *
+dcpgettext_expr (const char *domain,
+ const char *msgctxt, const char *msgid,
+ int category)
+{
+ size_t msgctxt_len = strlen (msgctxt) + 1;
+ size_t msgid_len = strlen (msgid) + 1;
+ const char *translation;
+#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
+ char msg_ctxt_id[msgctxt_len + msgid_len];
+#else
+ char buf[1024];
+ char *msg_ctxt_id =
+ (msgctxt_len + msgid_len <= sizeof (buf)
+ ? buf
+ : (char *) malloc (msgctxt_len + msgid_len));
+ if (msg_ctxt_id != NULL)
+#endif
+ {
+ memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
+ msg_ctxt_id[msgctxt_len - 1] = '\004';
+ memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
+ translation = dcgettext (domain, msg_ctxt_id, category);
+#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
+ if (msg_ctxt_id != buf)
+ free (msg_ctxt_id);
+#endif
+ if (translation != msg_ctxt_id)
+ return translation;
+ }
+ return msgid;
+}
+
+#define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \
+ dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
+#define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
+ dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+static const char *
+dcnpgettext_expr (const char *domain,
+ const char *msgctxt, const char *msgid,
+ const char *msgid_plural, unsigned long int n,
+ int category)
+{
+ size_t msgctxt_len = strlen (msgctxt) + 1;
+ size_t msgid_len = strlen (msgid) + 1;
+ const char *translation;
+#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
+ char msg_ctxt_id[msgctxt_len + msgid_len];
+#else
+ char buf[1024];
+ char *msg_ctxt_id =
+ (msgctxt_len + msgid_len <= sizeof (buf)
+ ? buf
+ : (char *) malloc (msgctxt_len + msgid_len));
+ if (msg_ctxt_id != NULL)
+#endif
+ {
+ memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
+ msg_ctxt_id[msgctxt_len - 1] = '\004';
+ memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
+ translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
+#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
+ if (msg_ctxt_id != buf)
+ free (msg_ctxt_id);
+#endif
+ if (!(translation == msg_ctxt_id || translation == msgid_plural))
+ return translation;
+ }
+ return (n == 1 ? msgid : msgid_plural);
+}
+
+#endif /* _LIBGETTEXT_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/init.c b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/init.c
new file mode 100644
index 0000000..81d4eee
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/init.c
@@ -0,0 +1,293 @@
+/**
+ * \file initialize.c
+ *
+ * initialize the libopts data structures.
+ *
+ * @addtogroup autoopts
+ * @{
+ */
+/*
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
+ *
+ * AutoOpts is available under any one of two licenses. The license
+ * in use must be one of these two and the choice is under the control
+ * of the user of the license.
+ *
+ * The GNU Lesser General Public License, version 3 or later
+ * See the files "COPYING.lgplv3" and "COPYING.gplv3"
+ *
+ * The Modified Berkeley Software Distribution License
+ * See the file "COPYING.mbsd"
+ *
+ * These files have the following sha256 sums:
+ *
+ * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
+ * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
+ * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
+ */
+
+/* = = = START-STATIC-FORWARD = = = */
+static tSuccess
+do_presets(tOptions * opts);
+/* = = = END-STATIC-FORWARD = = = */
+
+/**
+ * Make sure the option descriptor is there and that we understand it.
+ * This should be called from any user entry point where one needs to
+ * worry about validity. (Some entry points are free to assume that
+ * the call is not the first to the library and, thus, that this has
+ * already been called.)
+ *
+ * Upon successful completion, pzProgName and pzProgPath are set.
+ *
+ * @param[in,out] opts program options descriptor
+ * @param[in] pname name of program, from argv[]
+ * @returns SUCCESS or FAILURE
+ */
+LOCAL tSuccess
+validate_struct(tOptions * opts, char const * pname)
+{
+ if (opts == NULL) {
+ fputs(zno_opt_arg, stderr);
+ return FAILURE;
+ }
+ print_exit = ((opts->fOptSet & OPTPROC_SHELL_OUTPUT) != 0);
+
+ /*
+ * IF the client has enabled translation and the translation procedure
+ * is available, then go do it.
+ */
+ if ( ((opts->fOptSet & OPTPROC_TRANSLATE) != 0)
+ && (opts->pTransProc != NULL)
+ && (option_xlateable_txt.field_ct != 0) ) {
+ /*
+ * If option names are not to be translated at all, then do not do
+ * it for configuration parsing either. (That is the bit that really
+ * gets tested anyway.)
+ */
+ if ((opts->fOptSet & OPTPROC_NO_XLAT_MASK) == OPTPROC_NXLAT_OPT)
+ opts->fOptSet |= OPTPROC_NXLAT_OPT_CFG;
+ opts->pTransProc();
+ }
+
+ /*
+ * IF the struct version is not the current, and also
+ * either too large (?!) or too small,
+ * THEN emit error message and fail-exit
+ */
+ if ( ( opts->structVersion != OPTIONS_STRUCT_VERSION )
+ && ( (opts->structVersion > OPTIONS_STRUCT_VERSION )
+ || (opts->structVersion < OPTIONS_MINIMUM_VERSION )
+ ) ) {
+ fprintf(stderr, zwrong_ver, pname, NUM_TO_VER(opts->structVersion));
+ if (opts->structVersion > OPTIONS_STRUCT_VERSION )
+ fputs(ztoo_new, stderr);
+ else
+ fputs(ztoo_old, stderr);
+
+ fwrite(ao_ver_string, sizeof(ao_ver_string) - 1, 1, stderr);
+ return FAILURE;
+ }
+
+ /*
+ * If the program name hasn't been set, then set the name and the path
+ * and the set of equivalent characters.
+ */
+ if (opts->pzProgName == NULL) {
+ char const * pz = strrchr(pname, DIRCH);
+ char const ** pp = VOIDP(&(opts->pzProgName));
+
+ if (pz != NULL)
+ *pp = pz+1;
+ else
+ *pp = pname;
+
+ pz = pathfind(getenv("PATH"), pname, "rx");
+ if (pz != NULL)
+ pname = VOIDP(pz);
+
+ pp = (char const **)VOIDP(&(opts->pzProgPath));
+ *pp = pname;
+
+ /*
+ * when comparing long names, these are equivalent
+ */
+ strequate(zSepChars);
+ }
+
+ return SUCCESS;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * DO PRESETS
+ *
+ * The next several routines do the immediate action pass on the command
+ * line options, then the environment variables, then the config files in
+ * reverse order. Once done with that, the order is reversed and all
+ * the config files and environment variables are processed again, this
+ * time only processing the non-immediate action options. do_presets()
+ * will then return for optionProcess() to do the final pass on the command
+ * line arguments.
+ */
+
+/**
+ * scan the command line for immediate action options.
+ * This is only called the first time through.
+ * While this procedure is active, the OPTPROC_IMMEDIATE is true.
+ *
+ * @param pOpts program options descriptor
+ * @returns SUCCESS or FAILURE
+ */
+LOCAL tSuccess
+immediate_opts(tOptions * opts)
+{
+ tSuccess res;
+
+ opts->fOptSet |= OPTPROC_IMMEDIATE;
+ opts->curOptIdx = 1; /* start by skipping program name */
+ opts->pzCurOpt = NULL;
+
+ /*
+ * Examine all the options from the start. We process any options that
+ * are marked for immediate processing.
+ */
+ for (;;) {
+ tOptState opt_st = OPTSTATE_INITIALIZER(PRESET);
+
+ res = next_opt(opts, &opt_st);
+ switch (res) {
+ case FAILURE: goto failed_option;
+ case PROBLEM: res = SUCCESS; goto leave;
+ case SUCCESS: break;
+ }
+
+ /*
+ * IF this is an immediate-attribute option, then do it.
+ */
+ if (! DO_IMMEDIATELY(opt_st.flags))
+ continue;
+
+ if (! SUCCESSFUL(handle_opt(opts, &opt_st)))
+ break;
+ } failed_option:;
+
+ if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0)
+ (*opts->pUsageProc)(opts, EXIT_FAILURE);
+
+ leave:
+
+ opts->fOptSet &= ~OPTPROC_IMMEDIATE;
+ return res;
+}
+
+/**
+ * check for preset values from a config files or envrionment variables
+ *
+ * @param[in,out] opts the structure with the option names to check
+ */
+static tSuccess
+do_presets(tOptions * opts)
+{
+ tOptDesc * od = NULL;
+
+ if (! SUCCESSFUL(immediate_opts(opts)))
+ return FAILURE;
+
+ /*
+ * IF this option set has a --save-opts option, then it also
+ * has a --load-opts option. See if a command line option has disabled
+ * option presetting.
+ */
+ if ( (opts->specOptIdx.save_opts != NO_EQUIVALENT)
+ && (opts->specOptIdx.save_opts != 0)) {
+ od = opts->pOptDesc + opts->specOptIdx.save_opts + 1;
+ if (DISABLED_OPT(od))
+ return SUCCESS;
+ }
+
+ /*
+ * Until we return from this procedure, disable non-presettable opts
+ */
+ opts->fOptSet |= OPTPROC_PRESETTING;
+ /*
+ * IF there are no config files,
+ * THEN do any environment presets and leave.
+ */
+ if (opts->papzHomeList == NULL) {
+ env_presets(opts, ENV_ALL);
+ }
+ else {
+ env_presets(opts, ENV_IMM);
+
+ /*
+ * Check to see if environment variables have disabled presetting.
+ */
+ if ((od != NULL) && ! DISABLED_OPT(od))
+ intern_file_load(opts);
+
+ /*
+ * ${PROGRAM_LOAD_OPTS} value of "no" cannot disable other environment
+ * variable options. Only the loading of .rc files.
+ */
+ env_presets(opts, ENV_NON_IMM);
+ }
+ opts->fOptSet &= ~OPTPROC_PRESETTING;
+
+ return SUCCESS;
+}
+
+/**
+ * AutoOpts initialization
+ *
+ * @param[in,out] opts the structure to initialize
+ * @param[in] a_ct program argument count
+ * @param[in] a_v program argument vector
+ */
+LOCAL bool
+ao_initialize(tOptions * opts, int a_ct, char ** a_v)
+{
+ if ((opts->fOptSet & OPTPROC_INITDONE) != 0)
+ return true;
+
+ opts->origArgCt = (unsigned int)a_ct;
+ opts->origArgVect = a_v;
+ opts->fOptSet |= OPTPROC_INITDONE;
+
+ if (HAS_pzPkgDataDir(opts))
+ program_pkgdatadir = opts->pzPkgDataDir;
+
+ if (! SUCCESSFUL(do_presets(opts)))
+ return false;
+
+ /*
+ * IF option name conversion was suppressed but it is not suppressed
+ * for the command line, then it's time to translate option names.
+ * Usage text will not get retranslated.
+ */
+ if ( ((opts->fOptSet & OPTPROC_TRANSLATE) != 0)
+ && (opts->pTransProc != NULL)
+ && ((opts->fOptSet & OPTPROC_NO_XLAT_MASK) == OPTPROC_NXLAT_OPT_CFG)
+ ) {
+ opts->fOptSet &= ~OPTPROC_NXLAT_OPT_CFG;
+ (*opts->pTransProc)();
+ }
+
+ if ((opts->fOptSet & OPTPROC_REORDER) != 0)
+ optionSort(opts);
+
+ opts->curOptIdx = 1;
+ opts->pzCurOpt = NULL;
+ return true;
+}
+
+/** @}
+ *
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of autoopts/initialize.c */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/intprops.h b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/intprops.h
new file mode 100644
index 0000000..2ae151b
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/intprops.h
@@ -0,0 +1,320 @@
+/* intprops.h -- properties of integer types
+
+ Copyright (C) 2001-2005, 2009-2015 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Paul Eggert. */
+
+#ifndef _GL_INTPROPS_H
+#define _GL_INTPROPS_H
+
+#include <limits.h>
+
+/* Return an integer value, converted to the same type as the integer
+ expression E after integer type promotion. V is the unconverted value. */
+#define _GL_INT_CONVERT(e, v) (0 * (e) + (v))
+
+/* Act like _GL_INT_CONVERT (E, -V) but work around a bug in IRIX 6.5 cc; see
+ <http://lists.gnu.org/archive/html/bug-gnulib/2011-05/msg00406.html>. */
+#define _GL_INT_NEGATE_CONVERT(e, v) (0 * (e) - (v))
+
+/* The extra casts in the following macros work around compiler bugs,
+ e.g., in Cray C 5.0.3.0. */
+
+/* True if the arithmetic type T is an integer type. bool counts as
+ an integer. */
+#define TYPE_IS_INTEGER(t) ((t) 1.5 == 1)
+
+/* True if negative values of the signed integer type T use two's
+ complement, ones' complement, or signed magnitude representation,
+ respectively. Much GNU code assumes two's complement, but some
+ people like to be portable to all possible C hosts. */
+#define TYPE_TWOS_COMPLEMENT(t) ((t) ~ (t) 0 == (t) -1)
+#define TYPE_ONES_COMPLEMENT(t) ((t) ~ (t) 0 == 0)
+#define TYPE_SIGNED_MAGNITUDE(t) ((t) ~ (t) 0 < (t) -1)
+
+/* True if the signed integer expression E uses two's complement. */
+#define _GL_INT_TWOS_COMPLEMENT(e) (~ _GL_INT_CONVERT (e, 0) == -1)
+
+/* True if the arithmetic type T is signed. */
+#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
+
+/* Return 1 if the integer expression E, after integer promotion, has
+ a signed type. */
+#define _GL_INT_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0)
+
+
+/* Minimum and maximum values for integer types and expressions. These
+ macros have undefined behavior if T is signed and has padding bits.
+ If this is a problem for you, please let us know how to fix it for
+ your host. */
+
+/* The maximum and minimum values for the integer type T. */
+#define TYPE_MINIMUM(t) \
+ ((t) (! TYPE_SIGNED (t) \
+ ? (t) 0 \
+ : TYPE_SIGNED_MAGNITUDE (t) \
+ ? ~ (t) 0 \
+ : ~ TYPE_MAXIMUM (t)))
+#define TYPE_MAXIMUM(t) \
+ ((t) (! TYPE_SIGNED (t) \
+ ? (t) -1 \
+ : ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1)))
+
+/* The maximum and minimum values for the type of the expression E,
+ after integer promotion. E should not have side effects. */
+#define _GL_INT_MINIMUM(e) \
+ (_GL_INT_SIGNED (e) \
+ ? - _GL_INT_TWOS_COMPLEMENT (e) - _GL_SIGNED_INT_MAXIMUM (e) \
+ : _GL_INT_CONVERT (e, 0))
+#define _GL_INT_MAXIMUM(e) \
+ (_GL_INT_SIGNED (e) \
+ ? _GL_SIGNED_INT_MAXIMUM (e) \
+ : _GL_INT_NEGATE_CONVERT (e, 1))
+#define _GL_SIGNED_INT_MAXIMUM(e) \
+ (((_GL_INT_CONVERT (e, 1) << (sizeof ((e) + 0) * CHAR_BIT - 2)) - 1) * 2 + 1)
+
+
+/* Return 1 if the __typeof__ keyword works. This could be done by
+ 'configure', but for now it's easier to do it by hand. */
+#if (2 <= __GNUC__ || defined __IBM__TYPEOF__ \
+ || (0x5110 <= __SUNPRO_C && !__STDC__))
+# define _GL_HAVE___TYPEOF__ 1
+#else
+# define _GL_HAVE___TYPEOF__ 0
+#endif
+
+/* Return 1 if the integer type or expression T might be signed. Return 0
+ if it is definitely unsigned. This macro does not evaluate its argument,
+ and expands to an integer constant expression. */
+#if _GL_HAVE___TYPEOF__
+# define _GL_SIGNED_TYPE_OR_EXPR(t) TYPE_SIGNED (__typeof__ (t))
+#else
+# define _GL_SIGNED_TYPE_OR_EXPR(t) 1
+#endif
+
+/* Bound on length of the string representing an unsigned integer
+ value representable in B bits. log10 (2.0) < 146/485. The
+ smallest value of B where this bound is not tight is 2621. */
+#define INT_BITS_STRLEN_BOUND(b) (((b) * 146 + 484) / 485)
+
+/* Bound on length of the string representing an integer type or expression T.
+ Subtract 1 for the sign bit if T is signed, and then add 1 more for
+ a minus sign if needed.
+
+ Because _GL_SIGNED_TYPE_OR_EXPR sometimes returns 0 when its argument is
+ signed, this macro may overestimate the true bound by one byte when
+ applied to unsigned types of size 2, 4, 16, ... bytes. */
+#define INT_STRLEN_BOUND(t) \
+ (INT_BITS_STRLEN_BOUND (sizeof (t) * CHAR_BIT \
+ - _GL_SIGNED_TYPE_OR_EXPR (t)) \
+ + _GL_SIGNED_TYPE_OR_EXPR (t))
+
+/* Bound on buffer size needed to represent an integer type or expression T,
+ including the terminating null. */
+#define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1)
+
+
+/* Range overflow checks.
+
+ The INT_<op>_RANGE_OVERFLOW macros return 1 if the corresponding C
+ operators might not yield numerically correct answers due to
+ arithmetic overflow. They do not rely on undefined or
+ implementation-defined behavior. Their implementations are simple
+ and straightforward, but they are a bit harder to use than the
+ INT_<op>_OVERFLOW macros described below.
+
+ Example usage:
+
+ long int i = ...;
+ long int j = ...;
+ if (INT_MULTIPLY_RANGE_OVERFLOW (i, j, LONG_MIN, LONG_MAX))
+ printf ("multiply would overflow");
+ else
+ printf ("product is %ld", i * j);
+
+ Restrictions on *_RANGE_OVERFLOW macros:
+
+ These macros do not check for all possible numerical problems or
+ undefined or unspecified behavior: they do not check for division
+ by zero, for bad shift counts, or for shifting negative numbers.
+
+ These macros may evaluate their arguments zero or multiple times,
+ so the arguments should not have side effects. The arithmetic
+ arguments (including the MIN and MAX arguments) must be of the same
+ integer type after the usual arithmetic conversions, and the type
+ must have minimum value MIN and maximum MAX. Unsigned types should
+ use a zero MIN of the proper type.
+
+ These macros are tuned for constant MIN and MAX. For commutative
+ operations such as A + B, they are also tuned for constant B. */
+
+/* Return 1 if A + B would overflow in [MIN,MAX] arithmetic.
+ See above for restrictions. */
+#define INT_ADD_RANGE_OVERFLOW(a, b, min, max) \
+ ((b) < 0 \
+ ? (a) < (min) - (b) \
+ : (max) - (b) < (a))
+
+/* Return 1 if A - B would overflow in [MIN,MAX] arithmetic.
+ See above for restrictions. */
+#define INT_SUBTRACT_RANGE_OVERFLOW(a, b, min, max) \
+ ((b) < 0 \
+ ? (max) + (b) < (a) \
+ : (a) < (min) + (b))
+
+/* Return 1 if - A would overflow in [MIN,MAX] arithmetic.
+ See above for restrictions. */
+#define INT_NEGATE_RANGE_OVERFLOW(a, min, max) \
+ ((min) < 0 \
+ ? (a) < - (max) \
+ : 0 < (a))
+
+/* Return 1 if A * B would overflow in [MIN,MAX] arithmetic.
+ See above for restrictions. Avoid && and || as they tickle
+ bugs in Sun C 5.11 2010/08/13 and other compilers; see
+ <http://lists.gnu.org/archive/html/bug-gnulib/2011-05/msg00401.html>. */
+#define INT_MULTIPLY_RANGE_OVERFLOW(a, b, min, max) \
+ ((b) < 0 \
+ ? ((a) < 0 \
+ ? (a) < (max) / (b) \
+ : (b) == -1 \
+ ? 0 \
+ : (min) / (b) < (a)) \
+ : (b) == 0 \
+ ? 0 \
+ : ((a) < 0 \
+ ? (a) < (min) / (b) \
+ : (max) / (b) < (a)))
+
+/* Return 1 if A / B would overflow in [MIN,MAX] arithmetic.
+ See above for restrictions. Do not check for division by zero. */
+#define INT_DIVIDE_RANGE_OVERFLOW(a, b, min, max) \
+ ((min) < 0 && (b) == -1 && (a) < - (max))
+
+/* Return 1 if A % B would overflow in [MIN,MAX] arithmetic.
+ See above for restrictions. Do not check for division by zero.
+ Mathematically, % should never overflow, but on x86-like hosts
+ INT_MIN % -1 traps, and the C standard permits this, so treat this
+ as an overflow too. */
+#define INT_REMAINDER_RANGE_OVERFLOW(a, b, min, max) \
+ INT_DIVIDE_RANGE_OVERFLOW (a, b, min, max)
+
+/* Return 1 if A << B would overflow in [MIN,MAX] arithmetic.
+ See above for restrictions. Here, MIN and MAX are for A only, and B need
+ not be of the same type as the other arguments. The C standard says that
+ behavior is undefined for shifts unless 0 <= B < wordwidth, and that when
+ A is negative then A << B has undefined behavior and A >> B has
+ implementation-defined behavior, but do not check these other
+ restrictions. */
+#define INT_LEFT_SHIFT_RANGE_OVERFLOW(a, b, min, max) \
+ ((a) < 0 \
+ ? (a) < (min) >> (b) \
+ : (max) >> (b) < (a))
+
+
+/* The _GL*_OVERFLOW macros have the same restrictions as the
+ *_RANGE_OVERFLOW macros, except that they do not assume that operands
+ (e.g., A and B) have the same type as MIN and MAX. Instead, they assume
+ that the result (e.g., A + B) has that type. */
+#define _GL_ADD_OVERFLOW(a, b, min, max) \
+ ((min) < 0 ? INT_ADD_RANGE_OVERFLOW (a, b, min, max) \
+ : (a) < 0 ? (b) <= (a) + (b) \
+ : (b) < 0 ? (a) <= (a) + (b) \
+ : (a) + (b) < (b))
+#define _GL_SUBTRACT_OVERFLOW(a, b, min, max) \
+ ((min) < 0 ? INT_SUBTRACT_RANGE_OVERFLOW (a, b, min, max) \
+ : (a) < 0 ? 1 \
+ : (b) < 0 ? (a) - (b) <= (a) \
+ : (a) < (b))
+#define _GL_MULTIPLY_OVERFLOW(a, b, min, max) \
+ (((min) == 0 && (((a) < 0 && 0 < (b)) || ((b) < 0 && 0 < (a)))) \
+ || INT_MULTIPLY_RANGE_OVERFLOW (a, b, min, max))
+#define _GL_DIVIDE_OVERFLOW(a, b, min, max) \
+ ((min) < 0 ? (b) == _GL_INT_NEGATE_CONVERT (min, 1) && (a) < - (max) \
+ : (a) < 0 ? (b) <= (a) + (b) - 1 \
+ : (b) < 0 && (a) + (b) <= (a))
+#define _GL_REMAINDER_OVERFLOW(a, b, min, max) \
+ ((min) < 0 ? (b) == _GL_INT_NEGATE_CONVERT (min, 1) && (a) < - (max) \
+ : (a) < 0 ? (a) % (b) != ((max) - (b) + 1) % (b) \
+ : (b) < 0 && ! _GL_UNSIGNED_NEG_MULTIPLE (a, b, max))
+
+/* Return a nonzero value if A is a mathematical multiple of B, where
+ A is unsigned, B is negative, and MAX is the maximum value of A's
+ type. A's type must be the same as (A % B)'s type. Normally (A %
+ -B == 0) suffices, but things get tricky if -B would overflow. */
+#define _GL_UNSIGNED_NEG_MULTIPLE(a, b, max) \
+ (((b) < -_GL_SIGNED_INT_MAXIMUM (b) \
+ ? (_GL_SIGNED_INT_MAXIMUM (b) == (max) \
+ ? (a) \
+ : (a) % (_GL_INT_CONVERT (a, _GL_SIGNED_INT_MAXIMUM (b)) + 1)) \
+ : (a) % - (b)) \
+ == 0)
+
+
+/* Integer overflow checks.
+
+ The INT_<op>_OVERFLOW macros return 1 if the corresponding C operators
+ might not yield numerically correct answers due to arithmetic overflow.
+ They work correctly on all known practical hosts, and do not rely
+ on undefined behavior due to signed arithmetic overflow.
+
+ Example usage:
+
+ long int i = ...;
+ long int j = ...;
+ if (INT_MULTIPLY_OVERFLOW (i, j))
+ printf ("multiply would overflow");
+ else
+ printf ("product is %ld", i * j);
+
+ These macros do not check for all possible numerical problems or
+ undefined or unspecified behavior: they do not check for division
+ by zero, for bad shift counts, or for shifting negative numbers.
+
+ These macros may evaluate their arguments zero or multiple times, so the
+ arguments should not have side effects.
+
+ These macros are tuned for their last argument being a constant.
+
+ Return 1 if the integer expressions A * B, A - B, -A, A * B, A / B,
+ A % B, and A << B would overflow, respectively. */
+
+#define INT_ADD_OVERFLOW(a, b) \
+ _GL_BINARY_OP_OVERFLOW (a, b, _GL_ADD_OVERFLOW)
+#define INT_SUBTRACT_OVERFLOW(a, b) \
+ _GL_BINARY_OP_OVERFLOW (a, b, _GL_SUBTRACT_OVERFLOW)
+#define INT_NEGATE_OVERFLOW(a) \
+ INT_NEGATE_RANGE_OVERFLOW (a, _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a))
+#define INT_MULTIPLY_OVERFLOW(a, b) \
+ _GL_BINARY_OP_OVERFLOW (a, b, _GL_MULTIPLY_OVERFLOW)
+#define INT_DIVIDE_OVERFLOW(a, b) \
+ _GL_BINARY_OP_OVERFLOW (a, b, _GL_DIVIDE_OVERFLOW)
+#define INT_REMAINDER_OVERFLOW(a, b) \
+ _GL_BINARY_OP_OVERFLOW (a, b, _GL_REMAINDER_OVERFLOW)
+#define INT_LEFT_SHIFT_OVERFLOW(a, b) \
+ INT_LEFT_SHIFT_RANGE_OVERFLOW (a, b, \
+ _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a))
+
+/* Return 1 if the expression A <op> B would overflow,
+ where OP_RESULT_OVERFLOW (A, B, MIN, MAX) does the actual test,
+ assuming MIN and MAX are the minimum and maximum for the result type.
+ Arguments should be free of side effects. */
+#define _GL_BINARY_OP_OVERFLOW(a, b, op_result_overflow) \
+ op_result_overflow (a, b, \
+ _GL_INT_MINIMUM (0 * (b) + (a)), \
+ _GL_INT_MAXIMUM (0 * (b) + (a)))
+
+#endif /* _GL_INTPROPS_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/libopts.c b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/libopts.c
new file mode 100644
index 0000000..f5bbb3e
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/libopts.c
@@ -0,0 +1,50 @@
+#include <machine/rtems-bsd-user-space.h>
+
+#define AUTOOPTS_INTERNAL 1
+#include "autoopts/project.h"
+#define LOCAL static
+#include "ao-strs.h"
+static char const ao_ver_string[] =
+ "41:0:16\n";
+#include "autoopts/options.h"
+#include "autoopts/usage-txt.h"
+#include "genshell.h"
+#include "option-xat-attribute.h"
+#include "option-value-type.h"
+#include "ao-strs.h"
+#include "ag-char-map.h"
+#include "autoopts.h"
+#include "proto.h"
+#include "parse-duration.c"
+#include "ao-strs.c"
+#include "option-value-type.c"
+#include "option-xat-attribute.c"
+#include "autoopts.c"
+#include "alias.c"
+#include "boolean.c"
+#include "check.c"
+#include "configfile.c"
+#include "cook.c"
+#include "enum.c"
+#include "env.c"
+#include "file.c"
+#include "find.c"
+#include "genshell.c"
+#include "load.c"
+#include "makeshell.c"
+#include "nested.c"
+#include "numeric.c"
+#include "pgusage.c"
+#include "putshell.c"
+#include "reset.c"
+#include "restore.c"
+#include "save.c"
+#include "sort.c"
+#include "stack.c"
+#include "streqvcmp.c"
+#include "text_mmap.c"
+#include "time.c"
+#include "tokenize.c"
+#include "usage.c"
+#include "version.c"
+#include "init.c"
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/load.c b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/load.c
new file mode 100644
index 0000000..ccda5b4
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/load.c
@@ -0,0 +1,588 @@
+
+/**
+ * \file load.c
+ *
+ * This file contains the routines that deal with processing text strings
+ * for options, either from a NUL-terminated string passed in or from an
+ * rc/ini file.
+ *
+ * @addtogroup autoopts
+ * @{
+ */
+/*
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
+ *
+ * AutoOpts is available under any one of two licenses. The license
+ * in use must be one of these two and the choice is under the control
+ * of the user of the license.
+ *
+ * The GNU Lesser General Public License, version 3 or later
+ * See the files "COPYING.lgplv3" and "COPYING.gplv3"
+ *
+ * The Modified Berkeley Software Distribution License
+ * See the file "COPYING.mbsd"
+ *
+ * These files have the following sha256 sums:
+ *
+ * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
+ * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
+ * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
+ */
+
+/* = = = START-STATIC-FORWARD = = = */
+static bool
+get_realpath(char * buf, size_t b_sz);
+
+static bool
+add_prog_path(char * buf, int b_sz, char const * fname, char const * prg_path);
+
+static bool
+add_env_val(char * buf, int buf_sz, char const * name);
+
+static char *
+assemble_arg_val(char * txt, tOptionLoadMode mode);
+
+static char *
+trim_quotes(char * arg);
+
+static bool
+direction_ok(opt_state_mask_t f, int dir);
+/* = = = END-STATIC-FORWARD = = = */
+
+static bool
+get_realpath(char * buf, size_t b_sz)
+{
+#if defined(HAVE_CANONICALIZE_FILE_NAME)
+ {
+ size_t name_len;
+
+ char * pz = canonicalize_file_name(buf);
+ if (pz == NULL)
+ return false;
+
+ name_len = strlen(pz);
+ if (name_len >= (size_t)b_sz) {
+ free(pz);
+ return false;
+ }
+
+ memcpy(buf, pz, name_len + 1);
+ free(pz);
+ }
+
+#elif defined(HAVE_REALPATH)
+ {
+ size_t name_len;
+ char z[PATH_MAX+1];
+
+ if (realpath(buf, z) == NULL)
+ return false;
+
+ name_len = strlen(z);
+ if (name_len >= b_sz)
+ return false;
+
+ memcpy(buf, z, name_len + 1);
+ }
+#endif
+ return true;
+}
+
+/*=export_func optionMakePath
+ * private:
+ *
+ * what: translate and construct a path
+ * arg: + char * + p_buf + The result buffer +
+ * arg: + int + b_sz + The size of this buffer +
+ * arg: + char const * + fname + The input name +
+ * arg: + char const * + prg_path + The full path of the current program +
+ *
+ * ret-type: bool
+ * ret-desc: true if the name was handled, otherwise false.
+ * If the name does not start with ``$'', then it is handled
+ * simply by copying the input name to the output buffer and
+ * resolving the name with either
+ * @code{canonicalize_file_name(3GLIBC)} or @code{realpath(3C)}.
+ *
+ * doc:
+ *
+ * This routine will copy the @code{pzName} input name into the
+ * @code{pzBuf} output buffer, not exceeding @code{bufSize} bytes. If the
+ * first character of the input name is a @code{'$'} character, then there
+ * is special handling:
+ * @*
+ * @code{$$} is replaced with the directory name of the @code{pzProgPath},
+ * searching @code{$PATH} if necessary.
+ * @*
+ * @code{$@} is replaced with the AutoGen package data installation directory
+ * (aka @code{pkgdatadir}).
+ * @*
+ * @code{$NAME} is replaced by the contents of the @code{NAME} environment
+ * variable. If not found, the search fails.
+ *
+ * Please note: both @code{$$} and @code{$NAME} must be at the start of the
+ * @code{pzName} string and must either be the entire string or be followed
+ * by the @code{'/'} (backslash on windows) character.
+ *
+ * err: @code{false} is returned if:
+ * @*
+ * @bullet{} The input name exceeds @code{bufSize} bytes.
+ * @*
+ * @bullet{} @code{$$}, @code{$@@} or @code{$NAME} is not the full string
+ * and the next character is not '/'.
+ * @*
+ * @bullet{} libopts was built without PKGDATADIR defined and @code{$@@}
+ * was specified.
+ * @*
+ * @bullet{} @code{NAME} is not a known environment variable
+ * @*
+ * @bullet{} @code{canonicalize_file_name} or @code{realpath} return
+ * errors (cannot resolve the resulting path).
+=*/
+bool
+optionMakePath(char * p_buf, int b_sz, char const * fname, char const * prg_path)
+{
+ {
+ size_t len = strlen(fname);
+
+ if (((size_t)b_sz <= len) || (len == 0))
+ return false;
+ }
+
+ /*
+ * IF not an environment variable, just copy the data
+ */
+ if (*fname != '$') {
+ char const * src = fname;
+ char * dst = p_buf;
+ int ct = b_sz;
+
+ for (;;) {
+ if ( (*(dst++) = *(src++)) == NUL)
+ break;
+ if (--ct <= 0)
+ return false;
+ }
+ }
+
+ /*
+ * IF the name starts with "$$", then it must be "$$" or
+ * it must start with "$$/". In either event, replace the "$$"
+ * with the path to the executable and append a "/" character.
+ */
+ else switch (fname[1]) {
+ case NUL:
+ return false;
+
+ case '$':
+ if (! add_prog_path(p_buf, b_sz, fname, prg_path))
+ return false;
+ break;
+
+ case '@':
+ if (program_pkgdatadir[0] == NUL)
+ return false;
+
+ if (snprintf(p_buf, (size_t)b_sz, "%s%s",
+ program_pkgdatadir, fname + 2) >= b_sz)
+ return false;
+ break;
+
+ default:
+ if (! add_env_val(p_buf, b_sz, fname))
+ return false;
+ }
+
+ return get_realpath(p_buf, b_sz);
+}
+
+/**
+ * convert a leading "$$" into a path to the executable.
+ */
+static bool
+add_prog_path(char * buf, int b_sz, char const * fname, char const * prg_path)
+{
+ char const * path;
+ char const * pz;
+ int skip = 2;
+
+ switch (fname[2]) {
+ case DIRCH:
+ skip = 3;
+ case NUL:
+ break;
+ default:
+ return false;
+ }
+
+ /*
+ * See if the path is included in the program name.
+ * If it is, we're done. Otherwise, we have to hunt
+ * for the program using "pathfind".
+ */
+ if (strchr(prg_path, DIRCH) != NULL)
+ path = prg_path;
+ else {
+ path = pathfind(getenv("PATH"), prg_path, "rx");
+
+ if (path == NULL)
+ return false;
+ }
+
+ pz = strrchr(path, DIRCH);
+
+ /*
+ * IF we cannot find a directory name separator,
+ * THEN we do not have a path name to our executable file.
+ */
+ if (pz == NULL)
+ return false;
+
+ fname += skip;
+
+ /*
+ * Concatenate the file name to the end of the executable path.
+ * The result may be either a file or a directory.
+ */
+ if ((unsigned)(pz - path) + 1 + strlen(fname) >= (unsigned)b_sz)
+ return false;
+
+ memcpy(buf, path, (size_t)((pz - path)+1));
+ strcpy(buf + (pz - path) + 1, fname);
+
+ /*
+ * If the "path" path was gotten from "pathfind()", then it was
+ * allocated and we need to deallocate it.
+ */
+ if (path != prg_path)
+ AGFREE(path);
+ return true;
+}
+
+/**
+ * Add an environment variable value.
+ */
+static bool
+add_env_val(char * buf, int buf_sz, char const * name)
+{
+ char * dir_part = buf;
+
+ for (;;) {
+ int ch = (int)*++name;
+ if (! IS_VALUE_NAME_CHAR(ch))
+ break;
+ *(dir_part++) = (char)ch;
+ }
+
+ if (dir_part == buf)
+ return false;
+
+ *dir_part = NUL;
+
+ dir_part = getenv(buf);
+
+ /*
+ * Environment value not found -- skip the home list entry
+ */
+ if (dir_part == NULL)
+ return false;
+
+ if (strlen(dir_part) + 1 + strlen(name) >= (unsigned)buf_sz)
+ return false;
+
+ sprintf(buf, "%s%s", dir_part, name);
+ return true;
+}
+
+/**
+ * Trim leading and trailing white space.
+ * If we are cooking the text and the text is quoted, then "cook"
+ * the string. To cook, the string must be quoted.
+ *
+ * @param[in,out] txt the input and output string
+ * @param[in] mode the handling mode (cooking method)
+ */
+LOCAL void
+munge_str(char * txt, tOptionLoadMode mode)
+{
+ char * pzE;
+
+ if (mode == OPTION_LOAD_KEEP)
+ return;
+
+ if (IS_WHITESPACE_CHAR(*txt)) {
+ char * src = SPN_WHITESPACE_CHARS(txt+1);
+ size_t l = strlen(src) + 1;
+ memmove(txt, src, l);
+ pzE = txt + l - 1;
+
+ } else
+ pzE = txt + strlen(txt);
+
+ pzE = SPN_WHITESPACE_BACK(txt, pzE);
+ *pzE = NUL;
+
+ if (mode == OPTION_LOAD_UNCOOKED)
+ return;
+
+ switch (*txt) {
+ default: return;
+ case '"':
+ case '\'': break;
+ }
+
+ switch (pzE[-1]) {
+ default: return;
+ case '"':
+ case '\'': break;
+ }
+
+ (void)ao_string_cook(txt, NULL);
+}
+
+static char *
+assemble_arg_val(char * txt, tOptionLoadMode mode)
+{
+ char * end = strpbrk(txt, ARG_BREAK_STR);
+ int space_break;
+
+ /*
+ * Not having an argument to a configurable name is okay.
+ */
+ if (end == NULL)
+ return txt + strlen(txt);
+
+ /*
+ * If we are keeping all whitespace, then the modevalue starts with the
+ * character that follows the end of the configurable name, regardless
+ * of which character caused it.
+ */
+ if (mode == OPTION_LOAD_KEEP) {
+ *(end++) = NUL;
+ return end;
+ }
+
+ /*
+ * If the name ended on a white space character, remember that
+ * because we'll have to skip over an immediately following ':' or '='
+ * (and the white space following *that*).
+ */
+ space_break = IS_WHITESPACE_CHAR(*end);
+ *(end++) = NUL;
+
+ end = SPN_WHITESPACE_CHARS(end);
+ if (space_break && ((*end == ':') || (*end == '=')))
+ end = SPN_WHITESPACE_CHARS(end+1);
+
+ return end;
+}
+
+static char *
+trim_quotes(char * arg)
+{
+ switch (*arg) {
+ case '"':
+ case '\'':
+ ao_string_cook(arg, NULL);
+ }
+ return arg;
+}
+
+/**
+ * See if the option is to be processed in the current scan direction
+ * (-1 or +1).
+ */
+static bool
+direction_ok(opt_state_mask_t f, int dir)
+{
+ if (dir == 0)
+ return true;
+
+ switch (f & (OPTST_IMM|OPTST_DISABLE_IMM)) {
+ case 0:
+ /*
+ * The selected option has no immediate action.
+ * THEREFORE, if the direction is PRESETTING
+ * THEN we skip this option.
+ */
+ if (PRESETTING(dir))
+ return false;
+ break;
+
+ case OPTST_IMM:
+ if (PRESETTING(dir)) {
+ /*
+ * We are in the presetting direction with an option we handle
+ * immediately for enablement, but normally for disablement.
+ * Therefore, skip if disabled.
+ */
+ if ((f & OPTST_DISABLED) == 0)
+ return false;
+ } else {
+ /*
+ * We are in the processing direction with an option we handle
+ * immediately for enablement, but normally for disablement.
+ * Therefore, skip if NOT disabled.
+ */
+ if ((f & OPTST_DISABLED) != 0)
+ return false;
+ }
+ break;
+
+ case OPTST_DISABLE_IMM:
+ if (PRESETTING(dir)) {
+ /*
+ * We are in the presetting direction with an option we handle
+ * immediately for disablement, but normally for disablement.
+ * Therefore, skip if NOT disabled.
+ */
+ if ((f & OPTST_DISABLED) != 0)
+ return false;
+ } else {
+ /*
+ * We are in the processing direction with an option we handle
+ * immediately for disablement, but normally for disablement.
+ * Therefore, skip if disabled.
+ */
+ if ((f & OPTST_DISABLED) == 0)
+ return false;
+ }
+ break;
+
+ case OPTST_IMM|OPTST_DISABLE_IMM:
+ /*
+ * The selected option is always for immediate action.
+ * THEREFORE, if the direction is PROCESSING
+ * THEN we skip this option.
+ */
+ if (PROCESSING(dir))
+ return false;
+ break;
+ }
+ return true;
+}
+
+/**
+ * Load an option from a block of text. The text must start with the
+ * configurable/option name and be followed by its associated value.
+ * That value may be processed in any of several ways. See "tOptionLoadMode"
+ * in autoopts.h.
+ *
+ * @param[in,out] opts program options descriptor
+ * @param[in,out] opt_state option processing state
+ * @param[in,out] line source line with long option name in it
+ * @param[in] direction current processing direction (preset or not)
+ * @param[in] load_mode option loading mode (OPTION_LOAD_*)
+ */
+LOCAL void
+load_opt_line(tOptions * opts, tOptState * opt_state, char * line,
+ tDirection direction, tOptionLoadMode load_mode )
+{
+ /*
+ * When parsing a stored line, we only look at the characters after
+ * a hyphen. Long names must always be at least two characters and
+ * short options are always exactly one character long.
+ */
+ line = SPN_LOAD_LINE_SKIP_CHARS(line);
+
+ {
+ char * arg = assemble_arg_val(line, load_mode);
+
+ if (IS_OPTION_NAME_CHAR(line[1])) {
+
+ if (! SUCCESSFUL(opt_find_long(opts, line, opt_state)))
+ return;
+
+ } else if (! SUCCESSFUL(opt_find_short(opts, *line, opt_state)))
+ return;
+
+ if ((! CALLED(direction)) && (opt_state->flags & OPTST_NO_INIT))
+ return;
+
+ opt_state->pzOptArg = trim_quotes(arg);
+ }
+
+ if (! direction_ok(opt_state->flags, direction))
+ return;
+
+ /*
+ * Fix up the args.
+ */
+ if (OPTST_GET_ARGTYPE(opt_state->pOD->fOptState) == OPARG_TYPE_NONE) {
+ if (*opt_state->pzOptArg != NUL)
+ return;
+ opt_state->pzOptArg = NULL;
+
+ } else if (opt_state->pOD->fOptState & OPTST_ARG_OPTIONAL) {
+ if (*opt_state->pzOptArg == NUL)
+ opt_state->pzOptArg = NULL;
+ else {
+ AGDUPSTR(opt_state->pzOptArg, opt_state->pzOptArg, "opt arg");
+ opt_state->flags |= OPTST_ALLOC_ARG;
+ }
+
+ } else {
+ if (*opt_state->pzOptArg == NUL)
+ opt_state->pzOptArg = zNil;
+ else {
+ AGDUPSTR(opt_state->pzOptArg, opt_state->pzOptArg, "opt arg");
+ opt_state->flags |= OPTST_ALLOC_ARG;
+ }
+ }
+
+ {
+ tOptionLoadMode sv = option_load_mode;
+ option_load_mode = load_mode;
+ handle_opt(opts, opt_state);
+ option_load_mode = sv;
+ }
+}
+
+/*=export_func optionLoadLine
+ *
+ * what: process a string for an option name and value
+ *
+ * arg: tOptions *, opts, program options descriptor
+ * arg: char const *, line, NUL-terminated text
+ *
+ * doc:
+ *
+ * This is a client program callable routine for setting options from, for
+ * example, the contents of a file that they read in. Only one option may
+ * appear in the text. It will be treated as a normal (non-preset) option.
+ *
+ * When passed a pointer to the option struct and a string, it will find
+ * the option named by the first token on the string and set the option
+ * argument to the remainder of the string. The caller must NUL terminate
+ * the string. The caller need not skip over any introductory hyphens.
+ * Any embedded new lines will be included in the option
+ * argument. If the input looks like one or more quoted strings, then the
+ * input will be "cooked". The "cooking" is identical to the string
+ * formation used in AutoGen definition files (@pxref{basic expression}),
+ * except that you may not use backquotes.
+ *
+ * err: Invalid options are silently ignored. Invalid option arguments
+ * will cause a warning to print, but the function should return.
+=*/
+void
+optionLoadLine(tOptions * opts, char const * line)
+{
+ tOptState st = OPTSTATE_INITIALIZER(SET);
+ char * pz;
+ proc_state_mask_t sv_flags = opts->fOptSet;
+ opts->fOptSet &= ~OPTPROC_ERRSTOP;
+ AGDUPSTR(pz, line, "opt line");
+ load_opt_line(opts, &st, pz, DIRECTION_CALLED, OPTION_LOAD_COOKED);
+ AGFREE(pz);
+ opts->fOptSet = sv_flags;
+}
+/** @}
+ *
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of autoopts/load.c */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/makeshell.c b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/makeshell.c
new file mode 100644
index 0000000..fbe8e17
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/makeshell.c
@@ -0,0 +1,956 @@
+
+/**
+ * \file makeshell.c
+ *
+ * This module will interpret the options set in the tOptions
+ * structure and create a Bourne shell script capable of parsing them.
+ *
+ * @addtogroup autoopts
+ * @{
+ */
+/*
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
+ *
+ * AutoOpts is available under any one of two licenses. The license
+ * in use must be one of these two and the choice is under the control
+ * of the user of the license.
+ *
+ * The GNU Lesser General Public License, version 3 or later
+ * See the files "COPYING.lgplv3" and "COPYING.gplv3"
+ *
+ * The Modified Berkeley Software Distribution License
+ * See the file "COPYING.mbsd"
+ *
+ * These files have the following sha256 sums:
+ *
+ * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
+ * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
+ * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
+ */
+
+ static inline unsigned char to_uchar (char ch) { return ch; }
+
+#define UPPER(_c) (toupper(to_uchar(_c)))
+#define LOWER(_c) (tolower(to_uchar(_c)))
+
+/* = = = START-STATIC-FORWARD = = = */
+static void
+emit_var_text(char const * prog, char const * var, int fdin);
+
+static void
+text_to_var(tOptions * opts, teTextTo which, tOptDesc * od);
+
+static void
+emit_usage(tOptions * opts);
+
+static void
+emit_wrapup(tOptions * opts);
+
+static void
+emit_setup(tOptions * opts);
+
+static void
+emit_action(tOptions * opts, tOptDesc * od);
+
+static void
+emit_inaction(tOptions * opts, tOptDesc * od);
+
+static void
+emit_flag(tOptions * opts);
+
+static void
+emit_match_expr(char const * name, tOptDesc * cod, tOptions * opts);
+
+static void
+emit_long(tOptions * opts);
+
+static char *
+load_old_output(char const * fname, char const * pname);
+
+static void
+open_out(char const * fname, char const * pname);
+/* = = = END-STATIC-FORWARD = = = */
+
+LOCAL noreturn void
+option_exits(int exit_code)
+{
+ if (print_exit)
+ printf("\nexit %d\n", exit_code);
+ exit(exit_code);
+}
+
+LOCAL noreturn void
+ao_bug(char const * msg)
+{
+ fprintf(stderr, zao_bug_msg, msg);
+ option_exits(EX_SOFTWARE);
+}
+
+LOCAL void
+fserr_warn(char const * prog, char const * op, char const * fname)
+{
+ fprintf(stderr, zfserr_fmt, prog, errno, strerror(errno),
+ op, fname);
+}
+
+LOCAL noreturn void
+fserr_exit(char const * prog, char const * op, char const * fname)
+{
+ fserr_warn(prog, op, fname);
+ option_exits(EXIT_FAILURE);
+}
+
+/*=export_func optionParseShell
+ * private:
+ *
+ * what: Decipher a boolean value
+ * arg: + tOptions * + pOpts + program options descriptor +
+ *
+ * doc:
+ * Emit a shell script that will parse the command line options.
+=*/
+void
+optionParseShell(tOptions * opts)
+{
+ /*
+ * Check for our SHELL option now.
+ * IF the output file contains the "#!" magic marker,
+ * it will override anything we do here.
+ */
+ if (HAVE_GENSHELL_OPT(SHELL))
+ shell_prog = GENSHELL_OPT_ARG(SHELL);
+
+ else if (! ENABLED_GENSHELL_OPT(SHELL))
+ shell_prog = NULL;
+
+ else if ((shell_prog = getenv("SHELL")),
+ shell_prog == NULL)
+
+ shell_prog = POSIX_SHELL;
+
+ /*
+ * Check for a specified output file
+ */
+ if (HAVE_GENSHELL_OPT(SCRIPT))
+ open_out(GENSHELL_OPT_ARG(SCRIPT), opts->pzProgName);
+
+ emit_usage(opts);
+ emit_setup(opts);
+
+ /*
+ * There are four modes of option processing.
+ */
+ switch (opts->fOptSet & (OPTPROC_LONGOPT|OPTPROC_SHORTOPT)) {
+ case OPTPROC_LONGOPT:
+ fputs(LOOP_STR, stdout);
+
+ fputs(LONG_OPT_MARK, stdout);
+ fputs(INIT_LOPT_STR, stdout);
+ emit_long(opts);
+ printf(LOPT_ARG_FMT, opts->pzPROGNAME);
+ fputs(END_OPT_SEL_STR, stdout);
+
+ fputs(NOT_FOUND_STR, stdout);
+ break;
+
+ case 0:
+ fputs(ONLY_OPTS_LOOP, stdout);
+ fputs(INIT_LOPT_STR, stdout);
+ emit_long(opts);
+ printf(LOPT_ARG_FMT, opts->pzPROGNAME);
+ break;
+
+ case OPTPROC_SHORTOPT:
+ fputs(LOOP_STR, stdout);
+
+ fputs(FLAG_OPT_MARK, stdout);
+ fputs(INIT_OPT_STR, stdout);
+ emit_flag(opts);
+ printf(OPT_ARG_FMT, opts->pzPROGNAME);
+ fputs(END_OPT_SEL_STR, stdout);
+
+ fputs(NOT_FOUND_STR, stdout);
+ break;
+
+ case OPTPROC_LONGOPT|OPTPROC_SHORTOPT:
+ fputs(LOOP_STR, stdout);
+
+ fputs(LONG_OPT_MARK, stdout);
+ fputs(INIT_LOPT_STR, stdout);
+ emit_long(opts);
+ printf(LOPT_ARG_FMT, opts->pzPROGNAME);
+ fputs(END_OPT_SEL_STR, stdout);
+
+ fputs(FLAG_OPT_MARK, stdout);
+ fputs(INIT_OPT_STR, stdout);
+ emit_flag(opts);
+ printf(OPT_ARG_FMT, opts->pzPROGNAME);
+ fputs(END_OPT_SEL_STR, stdout);
+
+ fputs(NOT_FOUND_STR, stdout);
+ break;
+ }
+
+ emit_wrapup(opts);
+ if ((script_trailer != NULL) && (*script_trailer != NUL))
+ fputs(script_trailer, stdout);
+ else if (ENABLED_GENSHELL_OPT(SHELL))
+ printf(SHOW_PROG_ENV, opts->pzPROGNAME);
+
+#ifdef HAVE_FCHMOD
+ fchmod(STDOUT_FILENO, 0755);
+#endif
+ fclose(stdout);
+
+ if (ferror(stdout))
+ fserr_exit(opts->pzProgName, zwriting, zstdout_name);
+
+ AGFREE(script_text);
+ script_leader = NULL;
+ script_trailer = NULL;
+ script_text = NULL;
+}
+
+#ifdef HAVE_WORKING_FORK
+/**
+ * Print the value of "var" to a file descriptor.
+ * The "fdin" is the read end of a pipe to a forked process that
+ * is writing usage text to it. We read that text in and re-emit
+ * to standard out, formatting it so that it is assigned to a
+ * shell variable.
+ *
+ * @param[in] prog The capitalized, c-variable-formatted program name
+ * @param[in] var a similarly formatted type name
+ * (LONGUSAGE, USAGE or VERSION)
+ * @param[in] fdin the input end of a pipe
+ */
+static void
+emit_var_text(char const * prog, char const * var, int fdin)
+{
+ FILE * fp = fdopen(fdin, "r" FOPEN_BINARY_FLAG);
+ int nlct = 0; /* defer newlines and skip trailing ones */
+
+ printf(SET_TEXT_FMT, prog, var);
+ if (fp == NULL)
+ goto skip_text;
+
+ for (;;) {
+ int ch = fgetc(fp);
+ switch (ch) {
+
+ case NL:
+ nlct++;
+ break;
+
+ case '\'':
+ while (nlct > 0) {
+ fputc(NL, stdout);
+ nlct--;
+ }
+ fputs(apostrophe, stdout);
+ break;
+
+ case EOF:
+ goto done;
+
+ default:
+ while (nlct > 0) {
+ fputc(NL, stdout);
+ nlct--;
+ }
+ fputc(ch, stdout);
+ break;
+ }
+ } done:;
+
+ fclose(fp);
+
+ skip_text:
+
+ fputs(END_SET_TEXT, stdout);
+}
+#endif
+
+/**
+ * The purpose of this function is to assign "long usage", short usage
+ * and version information to a shell variable. Rather than wind our
+ * way through all the logic necessary to emit the text directly, we
+ * fork(), have our child process emit the text the normal way and
+ * capture the output in the parent process.
+ *
+ * @param[in] opts the program options
+ * @param[in] which what to print: long usage, usage or version
+ * @param[in] od for TT_VERSION, it is the version option
+ */
+static void
+text_to_var(tOptions * opts, teTextTo which, tOptDesc * od)
+{
+# define _TT_(n) static char const z ## n [] = #n;
+ TEXTTO_TABLE
+# undef _TT_
+# define _TT_(n) z ## n ,
+ static char const * ttnames[] = { TEXTTO_TABLE };
+# undef _TT_
+
+#if ! defined(HAVE_WORKING_FORK)
+ printf(SET_NO_TEXT_FMT, opts->pzPROGNAME, ttnames[which]);
+#else
+ int fdpair[2];
+
+ fflush(stdout);
+ fflush(stderr);
+
+ if (pipe(fdpair) != 0)
+ fserr_exit(opts->pzProgName, "pipe", zinter_proc_pipe);
+
+ switch (fork()) {
+ case -1:
+ fserr_exit(opts->pzProgName, "fork", opts->pzProgName);
+ /* NOTREACHED */
+
+ case 0:
+ /*
+ * Send both stderr and stdout to the pipe. No matter which
+ * descriptor is used, we capture the output on the read end.
+ */
+ dup2(fdpair[1], STDERR_FILENO);
+ dup2(fdpair[1], STDOUT_FILENO);
+ close(fdpair[0]);
+
+ switch (which) {
+ case TT_LONGUSAGE:
+ (*(opts->pUsageProc))(opts, EXIT_SUCCESS);
+ /* NOTREACHED */
+
+ case TT_USAGE:
+ (*(opts->pUsageProc))(opts, EXIT_FAILURE);
+ /* NOTREACHED */
+
+ case TT_VERSION:
+ if (od->fOptState & OPTST_ALLOC_ARG) {
+ AGFREE(od->optArg.argString);
+ od->fOptState &= ~OPTST_ALLOC_ARG;
+ }
+ od->optArg.argString = "c";
+ optionPrintVersion(opts, od);
+ /* NOTREACHED */
+
+ default:
+ option_exits(EXIT_FAILURE);
+ /* NOTREACHED */
+ }
+ /* NOTREACHED */
+
+ default:
+ close(fdpair[1]);
+ }
+
+ emit_var_text(opts->pzPROGNAME, ttnames[which], fdpair[0]);
+#endif
+}
+
+/**
+ * capture usage text in shell variables.
+ *
+ */
+static void
+emit_usage(tOptions * opts)
+{
+ char tm_nm_buf[AO_NAME_SIZE];
+
+ /*
+ * First, switch stdout to the output file name.
+ * Then, change the program name to the one defined
+ * by the definitions (rather than the current
+ * executable name). Down case the upper cased name.
+ */
+ if (script_leader != NULL)
+ fputs(script_leader, stdout);
+
+ {
+ char const * out_nm;
+
+ {
+ time_t c_tim = time(NULL);
+ struct tm * ptm = localtime(&c_tim);
+ strftime(tm_nm_buf, AO_NAME_SIZE, TIME_FMT, ptm );
+ }
+
+ if (HAVE_GENSHELL_OPT(SCRIPT))
+ out_nm = GENSHELL_OPT_ARG(SCRIPT);
+ else out_nm = STDOUT;
+
+ if ((script_leader == NULL) && (shell_prog != NULL))
+ printf(SHELL_MAGIC, shell_prog);
+
+ printf(PREAMBLE_FMT, START_MARK, out_nm, tm_nm_buf);
+ }
+
+ printf(END_PRE_FMT, opts->pzPROGNAME);
+
+ /*
+ * Get a copy of the original program name in lower case and
+ * fill in an approximation of the program name from it.
+ */
+ {
+ char * pzPN = tm_nm_buf;
+ char const * pz = opts->pzPROGNAME;
+ char ** pp;
+
+ /* Copy the program name into the time/name buffer */
+ for (;;) {
+ if ((*pzPN++ = (char)tolower((unsigned char)*pz++)) == NUL)
+ break;
+ }
+
+ pp = VOIDP(&(opts->pzProgPath));
+ *pp = tm_nm_buf;
+ pp = VOIDP(&(opts->pzProgName));
+ *pp = tm_nm_buf;
+ }
+
+ text_to_var(opts, TT_LONGUSAGE, NULL);
+ text_to_var(opts, TT_USAGE, NULL);
+
+ {
+ tOptDesc * pOptDesc = opts->pOptDesc;
+ int optionCt = opts->optCt;
+
+ for (;;) {
+ if (pOptDesc->pOptProc == optionPrintVersion) {
+ text_to_var(opts, TT_VERSION, pOptDesc);
+ break;
+ }
+
+ if (--optionCt <= 0)
+ break;
+ pOptDesc++;
+ }
+ }
+}
+
+static void
+emit_wrapup(tOptions * opts)
+{
+ tOptDesc * od = opts->pOptDesc;
+ int opt_ct = opts->presetOptCt;
+ char const * fmt;
+
+ printf(FINISH_LOOP, opts->pzPROGNAME);
+ for (;opt_ct > 0; od++, --opt_ct) {
+ /*
+ * Options that are either usage documentation or are compiled out
+ * are not to be processed.
+ */
+ if (SKIP_OPT(od) || (od->pz_NAME == NULL))
+ continue;
+
+ /*
+ * do not presence check if there is no minimum/must-set
+ */
+ if ((od->optMinCt == 0) && ((od->fOptState & OPTST_MUST_SET) == 0))
+ continue;
+
+ if (od->optMaxCt > 1)
+ fmt = CHK_MIN_COUNT;
+ else fmt = CHK_ONE_REQUIRED;
+
+ {
+ int min = (od->optMinCt == 0) ? 1 : od->optMinCt;
+ printf(fmt, opts->pzPROGNAME, od->pz_NAME, min);
+ }
+ }
+ fputs(END_MARK, stdout);
+}
+
+static void
+emit_setup(tOptions * opts)
+{
+ tOptDesc * od = opts->pOptDesc;
+ int opt_ct = opts->presetOptCt;
+ char const * fmt;
+ char const * def_val;
+
+ for (;opt_ct > 0; od++, --opt_ct) {
+ char int_val_buf[32];
+
+ /*
+ * Options that are either usage documentation or are compiled out
+ * are not to be processed.
+ */
+ if (SKIP_OPT(od) || (od->pz_NAME == NULL))
+ continue;
+
+ if (od->optMaxCt > 1)
+ fmt = MULTI_DEF_FMT;
+ else fmt = SGL_DEF_FMT;
+
+ /*
+ * IF this is an enumeration/bitmask option, then convert the value
+ * to a string before printing the default value.
+ */
+ switch (OPTST_GET_ARGTYPE(od->fOptState)) {
+ case OPARG_TYPE_ENUMERATION:
+ (*(od->pOptProc))(OPTPROC_EMIT_SHELL, od );
+ def_val = od->optArg.argString;
+ break;
+
+ /*
+ * Numeric and membership bit options are just printed as a number.
+ */
+ case OPARG_TYPE_NUMERIC:
+ snprintf(int_val_buf, sizeof(int_val_buf), "%d",
+ (int)od->optArg.argInt);
+ def_val = int_val_buf;
+ break;
+
+ case OPARG_TYPE_MEMBERSHIP:
+ snprintf(int_val_buf, sizeof(int_val_buf), "%lu",
+ (unsigned long)od->optArg.argIntptr);
+ def_val = int_val_buf;
+ break;
+
+ case OPARG_TYPE_BOOLEAN:
+ def_val = (od->optArg.argBool) ? TRUE_STR : FALSE_STR;
+ break;
+
+ default:
+ if (od->optArg.argString == NULL) {
+ if (fmt == SGL_DEF_FMT)
+ fmt = SGL_NO_DEF_FMT;
+ def_val = NULL;
+ }
+ else
+ def_val = od->optArg.argString;
+ }
+
+ printf(fmt, opts->pzPROGNAME, od->pz_NAME, def_val);
+ }
+}
+
+static void
+emit_action(tOptions * opts, tOptDesc * od)
+{
+ if (od->pOptProc == optionPrintVersion)
+ printf(ECHO_N_EXIT, opts->pzPROGNAME, VER_STR);
+
+ else if (od->pOptProc == optionPagedUsage)
+ printf(PAGE_USAGE_TEXT, opts->pzPROGNAME);
+
+ else if (od->pOptProc == optionLoadOpt) {
+ printf(LVL3_CMD, NO_LOAD_WARN);
+ printf(LVL3_CMD, YES_NEED_OPT_ARG);
+
+ } else if (od->pz_NAME == NULL) {
+
+ if (od->pOptProc == NULL) {
+ printf(LVL3_CMD, NO_SAVE_OPTS);
+ printf(LVL3_CMD, OK_NEED_OPT_ARG);
+ } else
+ printf(ECHO_N_EXIT, opts->pzPROGNAME, LONG_USE_STR);
+
+ } else {
+ if (od->optMaxCt == 1)
+ printf(SGL_ARG_FMT, opts->pzPROGNAME, od->pz_NAME);
+ else {
+ if ((unsigned)od->optMaxCt < NOLIMIT)
+ printf(CHK_MAX_COUNT, opts->pzPROGNAME,
+ od->pz_NAME, od->optMaxCt);
+
+ printf(MULTI_ARG_FMT, opts->pzPROGNAME, od->pz_NAME);
+ }
+
+ /*
+ * Fix up the args.
+ */
+ if (OPTST_GET_ARGTYPE(od->fOptState) == OPARG_TYPE_NONE) {
+ printf(SET_MULTI_ARG, opts->pzPROGNAME, od->pz_NAME);
+ printf(LVL3_CMD, NO_ARG_NEEDED);
+
+ } else if (od->fOptState & OPTST_ARG_OPTIONAL) {
+ printf(SET_MULTI_ARG, opts->pzPROGNAME, od->pz_NAME);
+ printf(LVL3_CMD, OK_NEED_OPT_ARG);
+
+ } else {
+ printf(LVL3_CMD, YES_NEED_OPT_ARG);
+ }
+ }
+ fputs(zOptionEndSelect, stdout);
+}
+
+static void
+emit_inaction(tOptions * opts, tOptDesc * od)
+{
+ if (od->pOptProc == optionLoadOpt) {
+ printf(LVL3_CMD, NO_SUPPRESS_LOAD);
+
+ } else if (od->optMaxCt == 1)
+ printf(NO_SGL_ARG_FMT, opts->pzPROGNAME,
+ od->pz_NAME, od->pz_DisablePfx);
+ else
+ printf(NO_MULTI_ARG_FMT, opts->pzPROGNAME,
+ od->pz_NAME, od->pz_DisablePfx);
+
+ printf(LVL3_CMD, NO_ARG_NEEDED);
+ fputs(zOptionEndSelect, stdout);
+}
+
+/**
+ * recognize flag options. These go at the end.
+ * At the end, emit code to handle options we don't recognize.
+ *
+ * @param[in] opts the program options
+ */
+static void
+emit_flag(tOptions * opts)
+{
+ tOptDesc * od = opts->pOptDesc;
+ int opt_ct = opts->optCt;
+
+ fputs(zOptionCase, stdout);
+
+ for (;opt_ct > 0; od++, --opt_ct) {
+
+ if (SKIP_OPT(od) || ! IS_GRAPHIC_CHAR(od->optValue))
+ continue;
+
+ printf(zOptionFlag, od->optValue);
+ emit_action(opts, od);
+ }
+ printf(UNK_OPT_FMT, FLAG_STR, opts->pzPROGNAME);
+}
+
+/**
+ * Emit the match text for a long option. The passed in \a name may be
+ * either the enablement name or the disablement name.
+ *
+ * @param[in] name The current name to check.
+ * @param[in] cod current option descriptor
+ * @param[in] opts the program options
+ */
+static void
+emit_match_expr(char const * name, tOptDesc * cod, tOptions * opts)
+{
+ char name_bf[32];
+ unsigned int min_match_ct = 2;
+ unsigned int max_match_ct = strlen(name) - 1;
+
+ if (max_match_ct >= sizeof(name_bf) - 1)
+ goto leave;
+
+ {
+ tOptDesc * od = opts->pOptDesc;
+ int ct = opts->optCt;
+
+ for (; ct-- > 0; od++) {
+ unsigned int match_ct = 0;
+
+ /*
+ * Omit the current option, Doc opts and compiled out opts.
+ */
+ if ((od == cod) || SKIP_OPT(od))
+ continue;
+
+ /*
+ * Check each character of the name case insensitively.
+ * They must not be the same. They cannot be, because it would
+ * not compile correctly if they were.
+ */
+ while (UPPER(od->pz_Name[match_ct]) == UPPER(name[match_ct]))
+ match_ct++;
+
+ if (match_ct > min_match_ct)
+ min_match_ct = match_ct;
+
+ /*
+ * Check the disablement name, too.
+ */
+ if (od->pz_DisableName == NULL)
+ continue;
+
+ match_ct = 0;
+ while ( toupper((unsigned char)od->pz_DisableName[match_ct])
+ == toupper((unsigned char)name[match_ct]))
+ match_ct++;
+ if (match_ct > min_match_ct)
+ min_match_ct = match_ct;
+ }
+ }
+
+ /*
+ * Don't bother emitting partial matches if there is only one possible
+ * partial match.
+ */
+ if (min_match_ct < max_match_ct) {
+ char * pz = name_bf + min_match_ct;
+ int nm_ix = min_match_ct;
+
+ memcpy(name_bf, name, min_match_ct);
+
+ for (;;) {
+ *pz = NUL;
+ printf(zOptionPartName, name_bf);
+ *pz++ = name[nm_ix++];
+ if (name[nm_ix] == NUL) {
+ *pz = NUL;
+ break;
+ }
+ }
+ }
+
+leave:
+ printf(zOptionFullName, name);
+}
+
+/**
+ * Emit GNU-standard long option handling code.
+ *
+ * @param[in] opts the program options
+ */
+static void
+emit_long(tOptions * opts)
+{
+ tOptDesc * od = opts->pOptDesc;
+ int ct = opts->optCt;
+
+ fputs(zOptionCase, stdout);
+
+ /*
+ * do each option, ...
+ */
+ do {
+ /*
+ * Documentation & compiled-out options
+ */
+ if (SKIP_OPT(od))
+ continue;
+
+ emit_match_expr(od->pz_Name, od, opts);
+ emit_action(opts, od);
+
+ /*
+ * Now, do the same thing for the disablement version of the option.
+ */
+ if (od->pz_DisableName != NULL) {
+ emit_match_expr(od->pz_DisableName, od, opts);
+ emit_inaction(opts, od);
+ }
+ } while (od++, --ct > 0);
+
+ printf(UNK_OPT_FMT, OPTION_STR, opts->pzPROGNAME);
+}
+
+/**
+ * Load the previous shell script output file. We need to preserve any
+ * hand-edited additions outside of the START_MARK and END_MARKs.
+ *
+ * @param[in] fname the output file name
+ */
+static char *
+load_old_output(char const * fname, char const * pname)
+{
+ /*
+ * IF we cannot stat the file,
+ * THEN assume we are creating a new file.
+ * Skip the loading of the old data.
+ */
+ FILE * fp = fopen(fname, "r" FOPEN_BINARY_FLAG);
+ struct stat stbf;
+ char * text;
+ char * scan;
+
+ if (fp == NULL)
+ return NULL;
+
+ /*
+ * If we opened it, we should be able to stat it and it needs
+ * to be a regular file
+ */
+ if ((fstat(fileno(fp), &stbf) != 0) || (! S_ISREG(stbf.st_mode)))
+ fserr_exit(pname, "fstat", fname);
+
+ scan = text = AGALOC(stbf.st_size + 1, "f data");
+
+ /*
+ * Read in all the data as fast as our OS will let us.
+ */
+ for (;;) {
+ size_t inct = fread(VOIDP(scan), 1, (size_t)stbf.st_size, fp);
+ if (inct == 0)
+ break;
+
+ stbf.st_size -= (ssize_t)inct;
+
+ if (stbf.st_size == 0)
+ break;
+
+ scan += inct;
+ }
+
+ *scan = NUL;
+ fclose(fp);
+
+ return text;
+}
+
+/**
+ * Open the specified output file. If it already exists, load its
+ * contents and save the non-generated (hand edited) portions.
+ * If a "start mark" is found, everything before it is preserved leader.
+ * If not, the entire thing is a trailer. Assuming the start is found,
+ * then everything after the end marker is the trailer. If the end
+ * mark is not found, the file is actually corrupt, but we take the
+ * remainder to be the trailer.
+ *
+ * @param[in] fname the output file name
+ */
+static void
+open_out(char const * fname, char const * pname)
+{
+
+ do {
+ char * txt = script_text = load_old_output(fname, pname);
+ char * scn;
+
+ if (txt == NULL)
+ break;
+
+ scn = strstr(txt, START_MARK);
+ if (scn == NULL) {
+ script_trailer = txt;
+ break;
+ }
+
+ *(scn++) = NUL;
+ scn = strstr(scn, END_MARK);
+ if (scn == NULL) {
+ /*
+ * The file is corrupt. Set the trailer to be everything
+ * after the start mark. The user will need to fix it up.
+ */
+ script_trailer = txt + strlen(txt) + START_MARK_LEN + 1;
+ break;
+ }
+
+ /*
+ * Check to see if the data contains our marker.
+ * If it does, then we will skip over it
+ */
+ script_trailer = scn + END_MARK_LEN;
+ script_leader = txt;
+ } while (false);
+
+ if (freopen(fname, "w" FOPEN_BINARY_FLAG, stdout) != stdout)
+ fserr_exit(pname, "freopen", fname);
+}
+
+/*=export_func genshelloptUsage
+ * private:
+ * what: The usage function for the genshellopt generated program
+ *
+ * arg: + tOptions * + opts + program options descriptor +
+ * arg: + int + exit_cd + usage text type to produce +
+ *
+ * doc:
+ * This function is used to create the usage strings for the option
+ * processing shell script code. Two child processes are spawned
+ * each emitting the usage text in either the short (error exit)
+ * style or the long style. The generated program will capture this
+ * and create shell script variables containing the two types of text.
+=*/
+void
+genshelloptUsage(tOptions * opts, int exit_cd)
+{
+#if ! defined(HAVE_WORKING_FORK)
+ optionUsage(opts, exit_cd);
+#else
+ /*
+ * IF not EXIT_SUCCESS,
+ * THEN emit the short form of usage.
+ */
+ if (exit_cd != EXIT_SUCCESS)
+ optionUsage(opts, exit_cd);
+ fflush(stderr);
+ fflush(stdout);
+ if (ferror(stdout) || ferror(stderr))
+ option_exits(EXIT_FAILURE);
+
+ option_usage_fp = stdout;
+
+ /*
+ * First, print our usage
+ */
+ switch (fork()) {
+ case -1:
+ optionUsage(opts, EXIT_FAILURE);
+ /* NOTREACHED */
+
+ case 0:
+ pagerState = PAGER_STATE_CHILD;
+ optionUsage(opts, EXIT_SUCCESS);
+ /* NOTREACHED */
+ _exit(EXIT_FAILURE);
+
+ default:
+ {
+ int sts;
+ wait(&sts);
+ }
+ }
+
+ /*
+ * Generate the pzProgName, since optionProcess() normally
+ * gets it from the command line
+ */
+ {
+ char * pz;
+ char ** pp = VOIDP(&(optionParseShellOptions->pzProgName));
+ AGDUPSTR(pz, optionParseShellOptions->pzPROGNAME, "prog name");
+ *pp = pz;
+ while (*pz != NUL) {
+ *pz = (char)LOWER(*pz);
+ pz++;
+ }
+ }
+
+ /*
+ * Separate the makeshell usage from the client usage
+ */
+ fprintf(option_usage_fp, zGenshell, optionParseShellOptions->pzProgName);
+ fflush(option_usage_fp);
+
+ /*
+ * Now, print the client usage.
+ */
+ switch (fork()) {
+ case 0:
+ pagerState = PAGER_STATE_CHILD;
+ /*FALLTHROUGH*/
+ case -1:
+ optionUsage(optionParseShellOptions, EXIT_FAILURE);
+
+ default:
+ {
+ int sts;
+ wait(&sts);
+ }
+ }
+
+ fflush(stdout);
+ if (ferror(stdout))
+ fserr_exit(opts->pzProgName, zwriting, zstdout_name);
+
+ option_exits(EXIT_SUCCESS);
+#endif
+}
+
+/** @}
+ *
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of autoopts/makeshell.c */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/nested.c b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/nested.c
new file mode 100644
index 0000000..aaf089f
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/nested.c
@@ -0,0 +1,938 @@
+
+/**
+ * \file nested.c
+ *
+ * Handle options with arguments that contain nested values.
+ *
+ * @addtogroup autoopts
+ * @{
+ */
+/*
+ * Automated Options Nested Values module.
+ *
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
+ *
+ * AutoOpts is available under any one of two licenses. The license
+ * in use must be one of these two and the choice is under the control
+ * of the user of the license.
+ *
+ * The GNU Lesser General Public License, version 3 or later
+ * See the files "COPYING.lgplv3" and "COPYING.gplv3"
+ *
+ * The Modified Berkeley Software Distribution License
+ * See the file "COPYING.mbsd"
+ *
+ * These files have the following sha256 sums:
+ *
+ * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
+ * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
+ * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
+ */
+
+typedef struct {
+ int xml_ch;
+ int xml_len;
+ char xml_txt[8];
+} xml_xlate_t;
+
+static xml_xlate_t const xml_xlate[] = {
+ { '&', 4, "amp;" },
+ { '<', 3, "lt;" },
+ { '>', 3, "gt;" },
+ { '"', 5, "quot;" },
+ { '\'',5, "apos;" }
+};
+
+#ifndef ENOMSG
+#define ENOMSG ENOENT
+#endif
+
+/* = = = START-STATIC-FORWARD = = = */
+static void
+remove_continuation(char * src);
+
+static char const *
+scan_q_str(char const * pzTxt);
+
+static tOptionValue *
+add_string(void ** pp, char const * name, size_t nm_len,
+ char const * val, size_t d_len);
+
+static tOptionValue *
+add_bool(void ** pp, char const * name, size_t nm_len,
+ char const * val, size_t d_len);
+
+static tOptionValue *
+add_number(void ** pp, char const * name, size_t nm_len,
+ char const * val, size_t d_len);
+
+static tOptionValue *
+add_nested(void ** pp, char const * name, size_t nm_len,
+ char * val, size_t d_len);
+
+static char const *
+scan_name(char const * name, tOptionValue * res);
+
+static char const *
+unnamed_xml(char const * txt);
+
+static char const *
+scan_xml_name(char const * name, size_t * nm_len, tOptionValue * val);
+
+static char const *
+find_end_xml(char const * src, size_t nm_len, char const * val, size_t * len);
+
+static char const *
+scan_xml(char const * xml_name, tOptionValue * res_val);
+
+static void
+sort_list(tArgList * arg_list);
+/* = = = END-STATIC-FORWARD = = = */
+
+/**
+ * Backslashes are used for line continuations. We keep the newline
+ * characters, but trim out the backslash:
+ */
+static void
+remove_continuation(char * src)
+{
+ char * pzD;
+
+ do {
+ while (*src == NL) src++;
+ pzD = strchr(src, NL);
+ if (pzD == NULL)
+ return;
+
+ /*
+ * pzD has skipped at least one non-newline character and now
+ * points to a newline character. It now becomes the source and
+ * pzD goes to the previous character.
+ */
+ src = pzD--;
+ if (*pzD != '\\')
+ pzD++;
+ } while (pzD == src);
+
+ /*
+ * Start shifting text.
+ */
+ for (;;) {
+ char ch = ((*pzD++) = *(src++));
+ switch (ch) {
+ case NUL: return;
+ case '\\':
+ if (*src == NL)
+ --pzD; /* rewrite on next iteration */
+ }
+ }
+}
+
+/**
+ * Find the end of a quoted string, skipping escaped quote characters.
+ */
+static char const *
+scan_q_str(char const * pzTxt)
+{
+ char q = *(pzTxt++); /* remember the type of quote */
+
+ for (;;) {
+ char ch = *(pzTxt++);
+ if (ch == NUL)
+ return pzTxt-1;
+
+ if (ch == q)
+ return pzTxt;
+
+ if (ch == '\\') {
+ ch = *(pzTxt++);
+ /*
+ * IF the next character is NUL, drop the backslash, too.
+ */
+ if (ch == NUL)
+ return pzTxt - 2;
+
+ /*
+ * IF the quote character or the escape character were escaped,
+ * then skip both, as long as the string does not end.
+ */
+ if ((ch == q) || (ch == '\\')) {
+ if (*(pzTxt++) == NUL)
+ return pzTxt-1;
+ }
+ }
+ }
+}
+
+
+/**
+ * Associate a name with either a string or no value.
+ *
+ * @param[in,out] pp argument list to add to
+ * @param[in] name the name of the "suboption"
+ * @param[in] nm_len the length of the name
+ * @param[in] val the string value for the suboption
+ * @param[in] d_len the length of the value
+ *
+ * @returns the new value structure
+ */
+static tOptionValue *
+add_string(void ** pp, char const * name, size_t nm_len,
+ char const * val, size_t d_len)
+{
+ tOptionValue * pNV;
+ size_t sz = nm_len + d_len + sizeof(*pNV);
+
+ pNV = AGALOC(sz, "option name/str value pair");
+
+ if (val == NULL) {
+ pNV->valType = OPARG_TYPE_NONE;
+ pNV->pzName = pNV->v.strVal;
+
+ } else {
+ pNV->valType = OPARG_TYPE_STRING;
+ if (d_len > 0) {
+ char const * src = val;
+ char * pzDst = pNV->v.strVal;
+ int ct = (int)d_len;
+ do {
+ int ch = *(src++) & 0xFF;
+ if (ch == NUL) goto data_copy_done;
+ if (ch == '&')
+ ch = get_special_char(&src, &ct);
+ *(pzDst++) = (char)ch;
+ } while (--ct > 0);
+ data_copy_done:
+ *pzDst = NUL;
+
+ } else {
+ pNV->v.strVal[0] = NUL;
+ }
+
+ pNV->pzName = pNV->v.strVal + d_len + 1;
+ }
+
+ memcpy(pNV->pzName, name, nm_len);
+ pNV->pzName[ nm_len ] = NUL;
+ addArgListEntry(pp, pNV);
+ return pNV;
+}
+
+/**
+ * Associate a name with a boolean value
+ *
+ * @param[in,out] pp argument list to add to
+ * @param[in] name the name of the "suboption"
+ * @param[in] nm_len the length of the name
+ * @param[in] val the boolean value for the suboption
+ * @param[in] d_len the length of the value
+ *
+ * @returns the new value structure
+ */
+static tOptionValue *
+add_bool(void ** pp, char const * name, size_t nm_len,
+ char const * val, size_t d_len)
+{
+ size_t sz = nm_len + sizeof(tOptionValue) + 1;
+ tOptionValue * new_val = AGALOC(sz, "bool val");
+
+ /*
+ * Scan over whitespace is constrained by "d_len"
+ */
+ while (IS_WHITESPACE_CHAR(*val) && (d_len > 0)) {
+ d_len--; val++;
+ }
+
+ if (d_len == 0)
+ new_val->v.boolVal = 0;
+
+ else if (IS_DEC_DIGIT_CHAR(*val))
+ new_val->v.boolVal = (unsigned)atoi(val);
+
+ else new_val->v.boolVal = ! IS_FALSE_TYPE_CHAR(*val);
+
+ new_val->valType = OPARG_TYPE_BOOLEAN;
+ new_val->pzName = (char *)(new_val + 1);
+ memcpy(new_val->pzName, name, nm_len);
+ new_val->pzName[ nm_len ] = NUL;
+ addArgListEntry(pp, new_val);
+ return new_val;
+}
+
+/**
+ * Associate a name with strtol() value, defaulting to zero.
+ *
+ * @param[in,out] pp argument list to add to
+ * @param[in] name the name of the "suboption"
+ * @param[in] nm_len the length of the name
+ * @param[in] val the numeric value for the suboption
+ * @param[in] d_len the length of the value
+ *
+ * @returns the new value structure
+ */
+static tOptionValue *
+add_number(void ** pp, char const * name, size_t nm_len,
+ char const * val, size_t d_len)
+{
+ size_t sz = nm_len + sizeof(tOptionValue) + 1;
+ tOptionValue * new_val = AGALOC(sz, "int val");
+
+ /*
+ * Scan over whitespace is constrained by "d_len"
+ */
+ while (IS_WHITESPACE_CHAR(*val) && (d_len > 0)) {
+ d_len--; val++;
+ }
+ if (d_len == 0)
+ new_val->v.longVal = 0;
+ else
+ new_val->v.longVal = strtol(val, 0, 0);
+
+ new_val->valType = OPARG_TYPE_NUMERIC;
+ new_val->pzName = (char *)(new_val + 1);
+ memcpy(new_val->pzName, name, nm_len);
+ new_val->pzName[ nm_len ] = NUL;
+ addArgListEntry(pp, new_val);
+ return new_val;
+}
+
+/**
+ * Associate a name with a nested/hierarchical value.
+ *
+ * @param[in,out] pp argument list to add to
+ * @param[in] name the name of the "suboption"
+ * @param[in] nm_len the length of the name
+ * @param[in] val the nested values for the suboption
+ * @param[in] d_len the length of the value
+ *
+ * @returns the new value structure
+ */
+static tOptionValue *
+add_nested(void ** pp, char const * name, size_t nm_len,
+ char * val, size_t d_len)
+{
+ tOptionValue * new_val;
+
+ if (d_len == 0) {
+ size_t sz = nm_len + sizeof(*new_val) + 1;
+ new_val = AGALOC(sz, "empty nest");
+ new_val->v.nestVal = NULL;
+ new_val->valType = OPARG_TYPE_HIERARCHY;
+ new_val->pzName = (char *)(new_val + 1);
+ memcpy(new_val->pzName, name, nm_len);
+ new_val->pzName[ nm_len ] = NUL;
+
+ } else {
+ new_val = optionLoadNested(val, name, nm_len);
+ }
+
+ if (new_val != NULL)
+ addArgListEntry(pp, new_val);
+
+ return new_val;
+}
+
+/**
+ * We have an entry that starts with a name. Find the end of it, cook it
+ * (if called for) and create the name/value association.
+ */
+static char const *
+scan_name(char const * name, tOptionValue * res)
+{
+ tOptionValue * new_val;
+ char const * pzScan = name+1; /* we know first char is a name char */
+ char const * pzVal;
+ size_t nm_len = 1;
+ size_t d_len = 0;
+
+ /*
+ * Scan over characters that name a value. These names may not end
+ * with a colon, but they may contain colons.
+ */
+ pzScan = SPN_VALUE_NAME_CHARS(name + 1);
+ if (pzScan[-1] == ':')
+ pzScan--;
+ nm_len = (size_t)(pzScan - name);
+
+ pzScan = SPN_HORIZ_WHITE_CHARS(pzScan);
+
+ re_switch:
+
+ switch (*pzScan) {
+ case '=':
+ case ':':
+ pzScan = SPN_HORIZ_WHITE_CHARS(pzScan + 1);
+ if ((*pzScan == '=') || (*pzScan == ':'))
+ goto default_char;
+ goto re_switch;
+
+ case NL:
+ case ',':
+ pzScan++;
+ /* FALLTHROUGH */
+
+ case NUL:
+ add_string(&(res->v.nestVal), name, nm_len, NULL, (size_t)0);
+ break;
+
+ case '"':
+ case '\'':
+ pzVal = pzScan;
+ pzScan = scan_q_str(pzScan);
+ d_len = (size_t)(pzScan - pzVal);
+ new_val = add_string(&(res->v.nestVal), name, nm_len, pzVal,
+ d_len);
+ if ((new_val != NULL) && (option_load_mode == OPTION_LOAD_COOKED))
+ ao_string_cook(new_val->v.strVal, NULL);
+ break;
+
+ default:
+ default_char:
+ /*
+ * We have found some strange text value. It ends with a newline
+ * or a comma.
+ */
+ pzVal = pzScan;
+ for (;;) {
+ char ch = *(pzScan++);
+ switch (ch) {
+ case NUL:
+ pzScan--;
+ d_len = (size_t)(pzScan - pzVal);
+ goto string_done;
+ /* FALLTHROUGH */
+
+ case NL:
+ if ( (pzScan > pzVal + 2)
+ && (pzScan[-2] == '\\')
+ && (pzScan[ 0] != NUL))
+ continue;
+ /* FALLTHROUGH */
+
+ case ',':
+ d_len = (size_t)(pzScan - pzVal) - 1;
+ string_done:
+ new_val = add_string(&(res->v.nestVal), name, nm_len,
+ pzVal, d_len);
+ if (new_val != NULL)
+ remove_continuation(new_val->v.strVal);
+ goto leave_scan_name;
+ }
+ }
+ break;
+ } leave_scan_name:;
+
+ return pzScan;
+}
+
+/**
+ * Some xml element that does not start with a name.
+ * The next character must be either '!' (introducing a comment),
+ * or '?' (introducing an XML meta-marker of some sort).
+ * We ignore these and indicate an error (NULL result) otherwise.
+ *
+ * @param[in] txt the text within an xml bracket
+ * @returns the address of the character after the closing marker, or NULL.
+ */
+static char const *
+unnamed_xml(char const * txt)
+{
+ switch (*txt) {
+ default:
+ txt = NULL;
+ break;
+
+ case '!':
+ txt = strstr(txt, "-->");
+ if (txt != NULL)
+ txt += 3;
+ break;
+
+ case '?':
+ txt = strchr(txt, '>');
+ if (txt != NULL)
+ txt++;
+ break;
+ }
+ return txt;
+}
+
+/**
+ * Scan off the xml element name, and the rest of the header, too.
+ * Set the value type to NONE if it ends with "/>".
+ *
+ * @param[in] name the first name character (alphabetic)
+ * @param[out] nm_len the length of the name
+ * @param[out] val set valType field to STRING or NONE.
+ *
+ * @returns the scan resumption point, or NULL on error
+ */
+static char const *
+scan_xml_name(char const * name, size_t * nm_len, tOptionValue * val)
+{
+ char const * scan = SPN_VALUE_NAME_CHARS(name + 1);
+ *nm_len = (size_t)(scan - name);
+ if (*nm_len > 64)
+ return NULL;
+ val->valType = OPARG_TYPE_STRING;
+
+ if (IS_WHITESPACE_CHAR(*scan)) {
+ /*
+ * There are attributes following the name. Parse 'em.
+ */
+ scan = SPN_WHITESPACE_CHARS(scan);
+ scan = parse_attrs(NULL, scan, &option_load_mode, val);
+ if (scan == NULL)
+ return NULL; /* oops */
+ }
+
+ if (! IS_END_XML_TOKEN_CHAR(*scan))
+ return NULL; /* oops */
+
+ if (*scan == '/') {
+ /*
+ * Single element XML entries get inserted as an empty string.
+ */
+ if (*++scan != '>')
+ return NULL;
+ val->valType = OPARG_TYPE_NONE;
+ }
+ return scan+1;
+}
+
+/**
+ * We've found a closing '>' without a preceding '/', thus we must search
+ * the text for '<name/>' where "name" is the name of the XML element.
+ *
+ * @param[in] name the start of the name in the element header
+ * @param[in] nm_len the length of that name
+ * @param[out] len the length of the value (string between header and
+ * the trailer/tail.
+ * @returns the character after the trailer, or NULL if not found.
+ */
+static char const *
+find_end_xml(char const * src, size_t nm_len, char const * val, size_t * len)
+{
+ char z[72] = "</";
+ char * dst = z + 2;
+
+ do {
+ *(dst++) = *(src++);
+ } while (--nm_len > 0); /* nm_len is known to be 64 or less */
+ *(dst++) = '>';
+ *dst = NUL;
+
+ {
+ char const * res = strstr(val, z);
+
+ if (res != NULL) {
+ char const * end = (option_load_mode != OPTION_LOAD_KEEP)
+ ? SPN_WHITESPACE_BACK(val, res)
+ : res;
+ *len = (size_t)(end - val); /* includes trailing white space */
+ res = SPN_WHITESPACE_CHARS(res + (dst - z));
+ }
+ return res;
+ }
+}
+
+/**
+ * We've found a '<' character. We ignore this if it is a comment or a
+ * directive. If it is something else, then whatever it is we are looking
+ * at is bogus. Returning NULL stops processing.
+ *
+ * @param[in] xml_name the name of an xml bracket (usually)
+ * @param[in,out] res_val the option data derived from the XML element
+ *
+ * @returns the place to resume scanning input
+ */
+static char const *
+scan_xml(char const * xml_name, tOptionValue * res_val)
+{
+ size_t nm_len, v_len;
+ char const * scan;
+ char const * val_str;
+ tOptionValue valu;
+ tOptionLoadMode save_mode = option_load_mode;
+
+ if (! IS_VAR_FIRST_CHAR(*++xml_name))
+ return unnamed_xml(xml_name);
+
+ /*
+ * "scan_xml_name()" may change "option_load_mode".
+ */
+ val_str = scan_xml_name(xml_name, &nm_len, &valu);
+ if (val_str == NULL)
+ goto bail_scan_xml;
+
+ if (valu.valType == OPARG_TYPE_NONE)
+ scan = val_str;
+ else {
+ if (option_load_mode != OPTION_LOAD_KEEP)
+ val_str = SPN_WHITESPACE_CHARS(val_str);
+ scan = find_end_xml(xml_name, nm_len, val_str, &v_len);
+ if (scan == NULL)
+ goto bail_scan_xml;
+ }
+
+ /*
+ * "scan" now points to where the scan is to resume after returning.
+ * It either points after "/>" at the end of the XML element header,
+ * or it points after the "</name>" tail based on the name in the header.
+ */
+
+ switch (valu.valType) {
+ case OPARG_TYPE_NONE:
+ add_string(&(res_val->v.nestVal), xml_name, nm_len, NULL, 0);
+ break;
+
+ case OPARG_TYPE_STRING:
+ {
+ tOptionValue * new_val = add_string(
+ &(res_val->v.nestVal), xml_name, nm_len, val_str, v_len);
+
+ if (option_load_mode != OPTION_LOAD_KEEP)
+ munge_str(new_val->v.strVal, option_load_mode);
+
+ break;
+ }
+
+ case OPARG_TYPE_BOOLEAN:
+ add_bool(&(res_val->v.nestVal), xml_name, nm_len, val_str, v_len);
+ break;
+
+ case OPARG_TYPE_NUMERIC:
+ add_number(&(res_val->v.nestVal), xml_name, nm_len, val_str, v_len);
+ break;
+
+ case OPARG_TYPE_HIERARCHY:
+ {
+ char * pz = AGALOC(v_len+1, "h scan");
+ memcpy(pz, val_str, v_len);
+ pz[v_len] = NUL;
+ add_nested(&(res_val->v.nestVal), xml_name, nm_len, pz, v_len);
+ AGFREE(pz);
+ break;
+ }
+
+ case OPARG_TYPE_ENUMERATION:
+ case OPARG_TYPE_MEMBERSHIP:
+ default:
+ break;
+ }
+
+ option_load_mode = save_mode;
+ return scan;
+
+bail_scan_xml:
+ option_load_mode = save_mode;
+ return NULL;
+}
+
+
+/**
+ * Deallocate a list of option arguments. This must have been gotten from
+ * a hierarchical option argument, not a stacked list of strings. It is
+ * an internal call, so it is not validated. The caller is responsible for
+ * knowing what they are doing.
+ */
+LOCAL void
+unload_arg_list(tArgList * arg_list)
+{
+ int ct = arg_list->useCt;
+ char const ** pnew_val = arg_list->apzArgs;
+
+ while (ct-- > 0) {
+ tOptionValue * new_val = (tOptionValue *)VOIDP(*(pnew_val++));
+ if (new_val->valType == OPARG_TYPE_HIERARCHY)
+ unload_arg_list(new_val->v.nestVal);
+ AGFREE(new_val);
+ }
+
+ AGFREE(arg_list);
+}
+
+/*=export_func optionUnloadNested
+ *
+ * what: Deallocate the memory for a nested value
+ * arg: + tOptionValue const * + pOptVal + the hierarchical value +
+ *
+ * doc:
+ * A nested value needs to be deallocated. The pointer passed in should
+ * have been gotten from a call to @code{configFileLoad()} (See
+ * @pxref{libopts-configFileLoad}).
+=*/
+void
+optionUnloadNested(tOptionValue const * opt_val)
+{
+ if (opt_val == NULL) return;
+ if (opt_val->valType != OPARG_TYPE_HIERARCHY) {
+ errno = EINVAL;
+ return;
+ }
+
+ unload_arg_list(opt_val->v.nestVal);
+
+ AGFREE(opt_val);
+}
+
+/**
+ * This is a _stable_ sort. The entries are sorted alphabetically,
+ * but within entries of the same name the ordering is unchanged.
+ * Typically, we also hope the input is sorted.
+ */
+static void
+sort_list(tArgList * arg_list)
+{
+ int ix;
+ int lm = arg_list->useCt;
+
+ /*
+ * This loop iterates "useCt" - 1 times.
+ */
+ for (ix = 0; ++ix < lm;) {
+ int iy = ix-1;
+ tOptionValue * new_v = C(tOptionValue *, arg_list->apzArgs[ix]);
+ tOptionValue * old_v = C(tOptionValue *, arg_list->apzArgs[iy]);
+
+ /*
+ * For as long as the new entry precedes the "old" entry,
+ * move the old pointer. Stop before trying to extract the
+ * "-1" entry.
+ */
+ while (strcmp(old_v->pzName, new_v->pzName) > 0) {
+ arg_list->apzArgs[iy+1] = VOIDP(old_v);
+ old_v = (tOptionValue *)VOIDP(arg_list->apzArgs[--iy]);
+ if (iy < 0)
+ break;
+ }
+
+ /*
+ * Always store the pointer. Sometimes it is redundant,
+ * but the redundancy is cheaper than a test and branch sequence.
+ */
+ arg_list->apzArgs[iy+1] = VOIDP(new_v);
+ }
+}
+
+/*=
+ * private:
+ *
+ * what: parse a hierarchical option argument
+ * arg: + char const * + pzTxt + the text to scan +
+ * arg: + char const * + pzName + the name for the text +
+ * arg: + size_t + nm_len + the length of "name" +
+ *
+ * ret_type: tOptionValue *
+ * ret_desc: An allocated, compound value structure
+ *
+ * doc:
+ * A block of text represents a series of values. It may be an
+ * entire configuration file, or it may be an argument to an
+ * option that takes a hierarchical value.
+ *
+ * If NULL is returned, errno will be set:
+ * @itemize @bullet
+ * @item
+ * @code{EINVAL} the input text was NULL.
+ * @item
+ * @code{ENOMEM} the storage structures could not be allocated
+ * @item
+ * @code{ENOMSG} no configuration values were found
+ * @end itemize
+=*/
+LOCAL tOptionValue *
+optionLoadNested(char const * text, char const * name, size_t nm_len)
+{
+ tOptionValue * res_val;
+
+ /*
+ * Make sure we have some data and we have space to put what we find.
+ */
+ if (text == NULL) {
+ errno = EINVAL;
+ return NULL;
+ }
+ text = SPN_WHITESPACE_CHARS(text);
+ if (*text == NUL) {
+ errno = ENOMSG;
+ return NULL;
+ }
+ res_val = AGALOC(sizeof(*res_val) + nm_len + 1, "nest args");
+ res_val->valType = OPARG_TYPE_HIERARCHY;
+ res_val->pzName = (char *)(res_val + 1);
+ memcpy(res_val->pzName, name, nm_len);
+ res_val->pzName[nm_len] = NUL;
+
+ {
+ tArgList * arg_list = AGALOC(sizeof(*arg_list), "nest arg l");
+
+ res_val->v.nestVal = arg_list;
+ arg_list->useCt = 0;
+ arg_list->allocCt = MIN_ARG_ALLOC_CT;
+ }
+
+ /*
+ * Scan until we hit a NUL.
+ */
+ do {
+ text = SPN_WHITESPACE_CHARS(text);
+ if (IS_VAR_FIRST_CHAR(*text))
+ text = scan_name(text, res_val);
+
+ else switch (*text) {
+ case NUL: goto scan_done;
+ case '<': text = scan_xml(text, res_val);
+ if (text == NULL) goto woops;
+ if (*text == ',') text++; break;
+ case '#': text = strchr(text, NL); break;
+ default: goto woops;
+ }
+ } while (text != NULL); scan_done:;
+
+ {
+ tArgList * al = res_val->v.nestVal;
+ if (al->useCt == 0) {
+ errno = ENOMSG;
+ goto woops;
+ }
+ if (al->useCt > 1)
+ sort_list(al);
+ }
+
+ return res_val;
+
+ woops:
+ AGFREE(res_val->v.nestVal);
+ AGFREE(res_val);
+ return NULL;
+}
+
+/*=export_func optionNestedVal
+ * private:
+ *
+ * what: parse a hierarchical option argument
+ * arg: + tOptions * + opts + program options descriptor +
+ * arg: + tOptDesc * + od + the descriptor for this arg +
+ *
+ * doc:
+ * Nested value was found on the command line
+=*/
+void
+optionNestedVal(tOptions * opts, tOptDesc * od)
+{
+ if (opts < OPTPROC_EMIT_LIMIT)
+ return;
+
+ if (od->fOptState & OPTST_RESET) {
+ tArgList * arg_list = od->optCookie;
+ int ct;
+ char const ** av;
+
+ if (arg_list == NULL)
+ return;
+ ct = arg_list->useCt;
+ av = arg_list->apzArgs;
+
+ while (--ct >= 0) {
+ void * p = VOIDP(*(av++));
+ optionUnloadNested((tOptionValue const *)p);
+ }
+
+ AGFREE(od->optCookie);
+
+ } else {
+ tOptionValue * opt_val = optionLoadNested(
+ od->optArg.argString, od->pz_Name, strlen(od->pz_Name));
+
+ if (opt_val != NULL)
+ addArgListEntry(&(od->optCookie), VOIDP(opt_val));
+ }
+}
+
+/**
+ * get_special_char
+ */
+LOCAL int
+get_special_char(char const ** ppz, int * ct)
+{
+ char const * pz = *ppz;
+ char * rz;
+
+ if (*ct < 3)
+ return '&';
+
+ if (*pz == '#') {
+ int base = 10;
+ int retch;
+
+ pz++;
+ if (*pz == 'x') {
+ base = 16;
+ pz++;
+ }
+ retch = (int)strtoul(pz, &rz, base);
+ pz = rz;
+ if (*pz != ';')
+ return '&';
+ base = (int)(++pz - *ppz);
+ if (base > *ct)
+ return '&';
+
+ *ct -= base;
+ *ppz = pz;
+ return retch;
+ }
+
+ {
+ int ctr = sizeof(xml_xlate) / sizeof(xml_xlate[0]);
+ xml_xlate_t const * xlatp = xml_xlate;
+
+ for (;;) {
+ if ( (*ct >= xlatp->xml_len)
+ && (strncmp(pz, xlatp->xml_txt, (size_t)xlatp->xml_len) == 0)) {
+ *ppz += xlatp->xml_len;
+ *ct -= xlatp->xml_len;
+ return xlatp->xml_ch;
+ }
+
+ if (--ctr <= 0)
+ break;
+ xlatp++;
+ }
+ }
+ return '&';
+}
+
+/**
+ * emit_special_char
+ */
+LOCAL void
+emit_special_char(FILE * fp, int ch)
+{
+ int ctr = sizeof(xml_xlate) / sizeof(xml_xlate[0]);
+ xml_xlate_t const * xlatp = xml_xlate;
+
+ putc('&', fp);
+ for (;;) {
+ if (ch == xlatp->xml_ch) {
+ fputs(xlatp->xml_txt, fp);
+ return;
+ }
+ if (--ctr <= 0)
+ break;
+ xlatp++;
+ }
+ fprintf(fp, XML_HEX_BYTE_FMT, (ch & 0xFF));
+}
+
+/** @}
+ *
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of autoopts/nested.c */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/numeric.c b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/numeric.c
new file mode 100644
index 0000000..ab8f3d1
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/numeric.c
@@ -0,0 +1,179 @@
+
+/**
+ * \file numeric.c
+ *
+ * Handle options with numeric (integer) arguments.
+ *
+ * @addtogroup autoopts
+ * @{
+ */
+/*
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
+ *
+ * AutoOpts is available under any one of two licenses. The license
+ * in use must be one of these two and the choice is under the control
+ * of the user of the license.
+ *
+ * The GNU Lesser General Public License, version 3 or later
+ * See the files "COPYING.lgplv3" and "COPYING.gplv3"
+ *
+ * The Modified Berkeley Software Distribution License
+ * See the file "COPYING.mbsd"
+ *
+ * These files have the following sha256 sums:
+ *
+ * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
+ * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
+ * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
+ */
+
+/*=export_func optionShowRange
+ * private:
+ *
+ * what: Show info about range constraints
+ * arg: + tOptions * + pOpts + program options descriptor +
+ * arg: + tOptDesc * + pOptDesc + the descriptor for this arg +
+ * arg: + void * + rng_table + the value range tables +
+ * arg: + int + rng_count + the number of entries +
+ *
+ * doc:
+ * Show information about a numeric option with range constraints.
+=*/
+void
+optionShowRange(tOptions * pOpts, tOptDesc * pOD, void * rng_table, int rng_ct)
+{
+ const struct {long const rmin, rmax;} * rng = rng_table;
+
+ char const * pz_indent = zTabHyp + tab_skip_ct;
+
+ /*
+ * The range is shown only for full usage requests and an error
+ * in this particular option.
+ */
+ if (pOpts != OPTPROC_EMIT_USAGE) {
+ if (pOpts <= OPTPROC_EMIT_LIMIT)
+ return;
+ pz_indent = ONE_TAB_STR;
+
+ fprintf(option_usage_fp, zRangeErr, pOpts->pzProgName,
+ pOD->pz_Name, pOD->optArg.argInt);
+ pz_indent = "";
+ }
+
+ if (pOD->fOptState & OPTST_SCALED_NUM)
+ fprintf(option_usage_fp, zRangeScaled, pz_indent);
+
+ fprintf(option_usage_fp, (rng_ct > 1) ? zRangeLie : zRangeOnly, pz_indent);
+ pz_indent = (pOpts != OPTPROC_EMIT_USAGE)
+ ? ONE_TAB_STR
+ : (zTabSpace + tab_skip_ct);
+
+ for (;;) {
+ if (rng->rmax == LONG_MIN)
+ fprintf(option_usage_fp, zRangeExact, pz_indent, rng->rmin);
+ else if (rng->rmin == LONG_MIN)
+ fprintf(option_usage_fp, zRangeUpto, pz_indent, rng->rmax);
+ else if (rng->rmax == LONG_MAX)
+ fprintf(option_usage_fp, zRangeAbove, pz_indent, rng->rmin);
+ else
+ fprintf(option_usage_fp, zRange, pz_indent, rng->rmin,
+ rng->rmax);
+
+ if (--rng_ct <= 0) {
+ fputc(NL, option_usage_fp);
+ break;
+ }
+ fputs(zRangeOr, option_usage_fp);
+ rng++;
+ }
+
+ if (pOpts > OPTPROC_EMIT_LIMIT)
+ pOpts->pUsageProc(pOpts, EXIT_FAILURE);
+}
+
+/*=export_func optionNumericVal
+ * private:
+ *
+ * what: process an option with a numeric value.
+ * arg: + tOptions * + opts + program options descriptor +
+ * arg: + tOptDesc * + od + the descriptor for this arg +
+ *
+ * doc:
+ * Decipher a numeric value.
+=*/
+void
+optionNumericVal(tOptions * opts, tOptDesc * od)
+{
+ char * pz;
+ long val;
+
+ /*
+ * Guard against all the different ways this procedure might get invoked
+ * when there is no string argument provided.
+ */
+ if (INQUERY_CALL(opts, od) || (od->optArg.argString == NULL))
+ return;
+
+ /*
+ * Numeric options may have a range associated with it.
+ * If it does, the usage procedure requests that it be
+ * emitted by passing a NULL od pointer. Also bail out
+ * if there is no option argument or if we are being reset.
+ */
+ if ( (od == NULL)
+ || (od->optArg.argString == NULL)
+ || ((od->fOptState & OPTST_RESET) != 0))
+ return;
+
+ errno = 0;
+ val = strtol(od->optArg.argString, &pz, 0);
+ if ((pz == od->optArg.argString) || (errno != 0))
+ goto bad_number;
+
+ if ((od->fOptState & OPTST_SCALED_NUM) != 0)
+ switch (*(pz++)) {
+ case NUL: pz--; break;
+ case 't': val *= 1000;
+ case 'g': val *= 1000;
+ case 'm': val *= 1000;
+ case 'k': val *= 1000; break;
+
+ case 'T': val *= 1024;
+ case 'G': val *= 1024;
+ case 'M': val *= 1024;
+ case 'K': val *= 1024; break;
+
+ default: goto bad_number;
+ }
+
+ if (*pz != NUL)
+ goto bad_number;
+
+ if (od->fOptState & OPTST_ALLOC_ARG) {
+ AGFREE(od->optArg.argString);
+ od->fOptState &= ~OPTST_ALLOC_ARG;
+ }
+
+ od->optArg.argInt = val;
+ return;
+
+ bad_number:
+
+ fprintf( stderr, zNotNumber, opts->pzProgName, od->optArg.argString );
+ if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0)
+ (*(opts->pUsageProc))(opts, EXIT_FAILURE);
+
+ errno = EINVAL;
+ od->optArg.argInt = ~0;
+}
+
+/** @}
+ *
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of autoopts/numeric.c */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/option-value-type.c b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/option-value-type.c
new file mode 100644
index 0000000..5f67640
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/option-value-type.c
@@ -0,0 +1,156 @@
+/* -*- buffer-read-only: t -*- vi: set ro:
+ *
+ * DO NOT EDIT THIS FILE (stdin.c)
+ *
+ * It has been AutoGen-ed
+ * From the definitions stdin
+ * and the template file str2enum
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name ``Bruce Korb'' nor the name of any other
+ * contributor may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * str2enum IS PROVIDED BY Bruce Korb ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Bruce Korb OR ANY OTHER CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "option-value-type.h"
+/* ANSI-C code produced by gperf version 3.0.4 */
+/* Command-line: gperf option-value-type.gp */
+/* Computed positions: -k'1' */
+
+
+
+# if 0 /* gperf build options: */
+// %struct-type
+// %language=ANSI-C
+// %includes
+// %global-table
+// %omit-struct-type
+// %readonly-tables
+// %compare-strncmp
+//
+// %define slot-name vtp_name
+// %define hash-function-name option_value_type_hash
+// %define lookup-function-name find_option_value_type_name
+// %define word-array-name option_value_type_table
+// %define initializer-suffix ,VTP_COUNT_CMD
+//
+# endif
+
+#include "option-value-type.h"
+typedef struct {
+ char const * vtp_name;
+ option_value_type_enum_t vtp_id;
+} option_value_type_map_t;
+#include <string.h>
+
+/* maximum key range = 15, duplicates = 0 */
+
+static unsigned int
+option_value_type_hash (register const char *str, register unsigned int len)
+{
+ static const unsigned char asso_values[] =
+ {
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 0, 18,
+ 18, 18, 18, 18, 0, 10, 18, 5, 18, 18,
+ 5, 18, 18, 18, 18, 0, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18
+ };
+ return len + asso_values[(unsigned char)str[0]];
+}
+
+static const option_value_type_map_t option_value_type_table[] =
+ {
+ {"",VTP_COUNT_CMD}, {"",VTP_COUNT_CMD},
+ {"",VTP_COUNT_CMD},
+ {"set", VTP_CMD_SET},
+ {"bool", VTP_CMD_BOOL},
+ {"",VTP_COUNT_CMD},
+ {"string", VTP_CMD_STRING},
+ {"boolean", VTP_CMD_BOOLEAN},
+ {"",VTP_COUNT_CMD},
+ {"hierarchy", VTP_CMD_HIERARCHY},
+ {"",VTP_COUNT_CMD},
+ {"nested", VTP_CMD_NESTED},
+ {"keyword", VTP_CMD_KEYWORD},
+ {"",VTP_COUNT_CMD},
+ {"set-membership", VTP_CMD_SET_MEMBERSHIP},
+ {"",VTP_COUNT_CMD}, {"",VTP_COUNT_CMD},
+ {"integer", VTP_CMD_INTEGER}
+ };
+
+static inline const option_value_type_map_t *
+find_option_value_type_name (register const char *str, register unsigned int len)
+{
+ if (len <= 14 && len >= 3)
+ {
+ register int key = (int)option_value_type_hash (str, len);
+
+ if (key <= 17 && key >= 0)
+ {
+ register const char *s = option_value_type_table[key].vtp_name;
+
+ if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0')
+ return &option_value_type_table[key];
+ }
+ }
+ return 0;
+}
+
+/**
+ * Convert a command (keyword) to a option_value_type_enum_t enumeration value.
+ *
+ * @param[in] str a string that should start with a known key word.
+ * @param[in] len the provided length of the keyword at \a str.
+ * @returns the enumeration value.
+ * If not found, that value is VTP_INVALID_CMD.
+ */
+option_value_type_enum_t
+find_option_value_type_cmd(char const * str, size_t len)
+{
+ option_value_type_map_t const * map;
+
+ map = find_option_value_type_name(str, (unsigned int)len);
+ return (map == NULL) ? VTP_INVALID_CMD : map->vtp_id;
+}
+
+/* end of option-value-type.c */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/option-value-type.h b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/option-value-type.h
new file mode 100644
index 0000000..cf6dcaa
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/option-value-type.h
@@ -0,0 +1,60 @@
+/* -*- buffer-read-only: t -*- vi: set ro:
+ *
+ * DO NOT EDIT THIS FILE (stdin.h)
+ *
+ * It has been AutoGen-ed
+ * From the definitions stdin
+ * and the template file str2enum
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name ``Bruce Korb'' nor the name of any other
+ * contributor may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * str2enum IS PROVIDED BY Bruce Korb ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Bruce Korb OR ANY OTHER CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Command/Keyword Dispatcher
+ */
+#ifndef STR2ENUM_OPTION_VALUE_TYPE_H_GUARD
+#define STR2ENUM_OPTION_VALUE_TYPE_H_GUARD 1
+#include <sys/types.h>
+#ifndef MISSING_INTTYPES_H
+# include <inttypes.h>
+#endif
+
+typedef enum {
+ VTP_INVALID_CMD = 0,
+ VTP_CMD_STRING = 1,
+ VTP_CMD_INTEGER = 2,
+ VTP_CMD_BOOL = 3,
+ VTP_CMD_BOOLEAN = 4,
+ VTP_CMD_KEYWORD = 5,
+ VTP_CMD_SET = 6,
+ VTP_CMD_SET_MEMBERSHIP = 7,
+ VTP_CMD_NESTED = 8,
+ VTP_CMD_HIERARCHY = 9,
+ VTP_COUNT_CMD
+} option_value_type_enum_t;
+
+extern option_value_type_enum_t
+find_option_value_type_cmd(char const * str, size_t len);
+
+#endif /* STR2ENUM_OPTION_VALUE_TYPE_H_GUARD */
+/* end of option-value-type.h */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/option-xat-attribute.c b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/option-xat-attribute.c
new file mode 100644
index 0000000..be86041
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/option-xat-attribute.c
@@ -0,0 +1,148 @@
+/* -*- buffer-read-only: t -*- vi: set ro:
+ *
+ * DO NOT EDIT THIS FILE (stdin.c)
+ *
+ * It has been AutoGen-ed
+ * From the definitions stdin
+ * and the template file str2enum
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name ``Bruce Korb'' nor the name of any other
+ * contributor may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * str2enum IS PROVIDED BY Bruce Korb ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Bruce Korb OR ANY OTHER CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "option-xat-attribute.h"
+/* ANSI-C code produced by gperf version 3.0.4 */
+/* Command-line: gperf option-xat-attribute.gp */
+/* Computed positions: -k'1' */
+
+
+
+# if 0 /* gperf build options: */
+// %struct-type
+// %language=ANSI-C
+// %includes
+// %global-table
+// %omit-struct-type
+// %readonly-tables
+// %compare-strncmp
+//
+// %define slot-name xat_name
+// %define hash-function-name option_xat_attribute_hash
+// %define lookup-function-name find_option_xat_attribute_name
+// %define word-array-name option_xat_attribute_table
+// %define initializer-suffix ,XAT_COUNT_CMD
+//
+# endif
+
+#include "option-xat-attribute.h"
+typedef struct {
+ char const * xat_name;
+ option_xat_attribute_enum_t xat_id;
+} option_xat_attribute_map_t;
+#include <string.h>
+
+/* maximum key range = 6, duplicates = 0 */
+
+static unsigned int
+option_xat_attribute_hash (register const char *str, register unsigned int len)
+{
+ static const unsigned char asso_values[] =
+ {
+ 10,10,10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,10, 0,
+ 10,10,10,10,10,10,10, 5,10, 0,
+ 10,10,10,10,10,10, 0, 0,10, 0,
+ 10,10,10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10
+ };
+ return len + asso_values[(unsigned char)str[0]];
+}
+
+static const option_xat_attribute_map_t option_xat_attribute_table[] =
+ {
+ {"",XAT_COUNT_CMD}, {"",XAT_COUNT_CMD},
+ {"",XAT_COUNT_CMD}, {"",XAT_COUNT_CMD},
+ {"type", XAT_CMD_TYPE},
+ {"words", XAT_CMD_WORDS},
+ {"cooked", XAT_CMD_COOKED},
+ {"members", XAT_CMD_MEMBERS},
+ {"uncooked", XAT_CMD_UNCOOKED},
+ {"keep", XAT_CMD_KEEP}
+ };
+
+static inline const option_xat_attribute_map_t *
+find_option_xat_attribute_name (register const char *str, register unsigned int len)
+{
+ if (len <= 8 && len >= 4)
+ {
+ register int key = (int)option_xat_attribute_hash (str, len);
+
+ if (key <= 9 && key >= 0)
+ {
+ register const char *s = option_xat_attribute_table[key].xat_name;
+
+ if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0')
+ return &option_xat_attribute_table[key];
+ }
+ }
+ return 0;
+}
+
+/**
+ * Convert a command (keyword) to a option_xat_attribute_enum_t enumeration value.
+ *
+ * @param[in] str a string that should start with a known key word.
+ * @param[in] len the provided length of the keyword at \a str.
+ * @returns the enumeration value.
+ * If not found, that value is XAT_INVALID_CMD.
+ */
+option_xat_attribute_enum_t
+find_option_xat_attribute_cmd(char const * str, size_t len)
+{
+ option_xat_attribute_map_t const * map;
+
+ map = find_option_xat_attribute_name(str, (unsigned int)len);
+ return (map == NULL) ? XAT_INVALID_CMD : map->xat_id;
+}
+
+/* end of option-xat-attribute.c */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/option-xat-attribute.h b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/option-xat-attribute.h
new file mode 100644
index 0000000..dde1617
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/option-xat-attribute.h
@@ -0,0 +1,57 @@
+/* -*- buffer-read-only: t -*- vi: set ro:
+ *
+ * DO NOT EDIT THIS FILE (stdin.h)
+ *
+ * It has been AutoGen-ed
+ * From the definitions stdin
+ * and the template file str2enum
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name ``Bruce Korb'' nor the name of any other
+ * contributor may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * str2enum IS PROVIDED BY Bruce Korb ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Bruce Korb OR ANY OTHER CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Command/Keyword Dispatcher
+ */
+#ifndef STR2ENUM_OPTION_XAT_ATTRIBUTE_H_GUARD
+#define STR2ENUM_OPTION_XAT_ATTRIBUTE_H_GUARD 1
+#include <sys/types.h>
+#ifndef MISSING_INTTYPES_H
+# include <inttypes.h>
+#endif
+
+typedef enum {
+ XAT_INVALID_CMD = 0,
+ XAT_CMD_TYPE = 1,
+ XAT_CMD_WORDS = 2,
+ XAT_CMD_MEMBERS = 3,
+ XAT_CMD_COOKED = 4,
+ XAT_CMD_UNCOOKED = 5,
+ XAT_CMD_KEEP = 6,
+ XAT_COUNT_CMD
+} option_xat_attribute_enum_t;
+
+extern option_xat_attribute_enum_t
+find_option_xat_attribute_cmd(char const * str, size_t len);
+
+#endif /* STR2ENUM_OPTION_XAT_ATTRIBUTE_H_GUARD */
+/* end of option-xat-attribute.h */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/parse-duration.c b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/parse-duration.c
new file mode 100644
index 0000000..11e3d82
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/parse-duration.c
@@ -0,0 +1,610 @@
+/* Parse a time duration and return a seconds count
+ Copyright (C) 2008-2015 Free Software Foundation, Inc.
+ Written by Bruce Korb <bkorb@gnu.org>, 2008.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+/* Specification. */
+#include "parse-duration.h"
+
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "intprops.h"
+
+#ifndef NUL
+#define NUL '\0'
+#endif
+
+#define cch_t char const
+
+typedef enum {
+ NOTHING_IS_DONE,
+ YEAR_IS_DONE,
+ MONTH_IS_DONE,
+ WEEK_IS_DONE,
+ DAY_IS_DONE,
+ HOUR_IS_DONE,
+ MINUTE_IS_DONE,
+ SECOND_IS_DONE
+} whats_done_t;
+
+#define SEC_PER_MIN 60
+#define SEC_PER_HR (SEC_PER_MIN * 60)
+#define SEC_PER_DAY (SEC_PER_HR * 24)
+#define SEC_PER_WEEK (SEC_PER_DAY * 7)
+#define SEC_PER_MONTH (SEC_PER_DAY * 30)
+#define SEC_PER_YEAR (SEC_PER_DAY * 365)
+
+#undef MAX_DURATION
+#define MAX_DURATION TYPE_MAXIMUM(time_t)
+
+/* Wrapper around strtoul that does not require a cast. */
+static unsigned long
+str_const_to_ul (cch_t * str, cch_t ** ppz, int base)
+{
+ char * pz;
+ int rv = strtoul (str, &pz, base);
+ *ppz = pz;
+ return rv;
+}
+
+/* Wrapper around strtol that does not require a cast. */
+static long
+str_const_to_l (cch_t * str, cch_t ** ppz, int base)
+{
+ char * pz;
+ int rv = strtol (str, &pz, base);
+ *ppz = pz;
+ return rv;
+}
+
+/* Returns BASE + VAL * SCALE, interpreting BASE = BAD_TIME
+ with errno set as an error situation, and returning BAD_TIME
+ with errno set in an error situation. */
+static time_t
+scale_n_add (time_t base, time_t val, int scale)
+{
+ if (base == BAD_TIME)
+ {
+ if (errno == 0)
+ errno = EINVAL;
+ return BAD_TIME;
+ }
+
+ if (val > MAX_DURATION / scale)
+ {
+ errno = ERANGE;
+ return BAD_TIME;
+ }
+
+ val *= scale;
+ if (base > MAX_DURATION - val)
+ {
+ errno = ERANGE;
+ return BAD_TIME;
+ }
+
+ return base + val;
+}
+
+/* After a number HH has been parsed, parse subsequent :MM or :MM:SS. */
+static time_t
+parse_hr_min_sec (time_t start, cch_t * pz)
+{
+ int lpct = 0;
+
+ errno = 0;
+
+ /* For as long as our scanner pointer points to a colon *AND*
+ we've not looped before, then keep looping. (two iterations max) */
+ while ((*pz == ':') && (lpct++ <= 1))
+ {
+ unsigned long v = str_const_to_ul (pz+1, &pz, 10);
+
+ if (errno != 0)
+ return BAD_TIME;
+
+ start = scale_n_add (v, start, 60);
+
+ if (errno != 0)
+ return BAD_TIME;
+ }
+
+ /* allow for trailing spaces */
+ while (isspace ((unsigned char)*pz))
+ pz++;
+ if (*pz != NUL)
+ {
+ errno = EINVAL;
+ return BAD_TIME;
+ }
+
+ return start;
+}
+
+/* Parses a value and returns BASE + value * SCALE, interpreting
+ BASE = BAD_TIME with errno set as an error situation, and returning
+ BAD_TIME with errno set in an error situation. */
+static time_t
+parse_scaled_value (time_t base, cch_t ** ppz, cch_t * endp, int scale)
+{
+ cch_t * pz = *ppz;
+ time_t val;
+
+ if (base == BAD_TIME)
+ return base;
+
+ errno = 0;
+ val = str_const_to_ul (pz, &pz, 10);
+ if (errno != 0)
+ return BAD_TIME;
+ while (isspace ((unsigned char)*pz))
+ pz++;
+ if (pz != endp)
+ {
+ errno = EINVAL;
+ return BAD_TIME;
+ }
+
+ *ppz = pz;
+ return scale_n_add (base, val, scale);
+}
+
+/* Parses the syntax YEAR-MONTH-DAY.
+ PS points into the string, after "YEAR", before "-MONTH-DAY". */
+static time_t
+parse_year_month_day (cch_t * pz, cch_t * ps)
+{
+ time_t res = 0;
+
+ res = parse_scaled_value (0, &pz, ps, SEC_PER_YEAR);
+
+ pz++; /* over the first '-' */
+ ps = strchr (pz, '-');
+ if (ps == NULL)
+ {
+ errno = EINVAL;
+ return BAD_TIME;
+ }
+ res = parse_scaled_value (res, &pz, ps, SEC_PER_MONTH);
+
+ pz++; /* over the second '-' */
+ ps = pz + strlen (pz);
+ return parse_scaled_value (res, &pz, ps, SEC_PER_DAY);
+}
+
+/* Parses the syntax YYYYMMDD. */
+static time_t
+parse_yearmonthday (cch_t * in_pz)
+{
+ time_t res = 0;
+ char buf[8];
+ cch_t * pz;
+
+ if (strlen (in_pz) != 8)
+ {
+ errno = EINVAL;
+ return BAD_TIME;
+ }
+
+ memcpy (buf, in_pz, 4);
+ buf[4] = NUL;
+ pz = buf;
+ res = parse_scaled_value (0, &pz, buf + 4, SEC_PER_YEAR);
+
+ memcpy (buf, in_pz + 4, 2);
+ buf[2] = NUL;
+ pz = buf;
+ res = parse_scaled_value (res, &pz, buf + 2, SEC_PER_MONTH);
+
+ memcpy (buf, in_pz + 6, 2);
+ buf[2] = NUL;
+ pz = buf;
+ return parse_scaled_value (res, &pz, buf + 2, SEC_PER_DAY);
+}
+
+/* Parses the syntax yy Y mm M ww W dd D. */
+static time_t
+parse_YMWD (cch_t * pz)
+{
+ time_t res = 0;
+ cch_t * ps = strchr (pz, 'Y');
+ if (ps != NULL)
+ {
+ res = parse_scaled_value (0, &pz, ps, SEC_PER_YEAR);
+ pz++;
+ }
+
+ ps = strchr (pz, 'M');
+ if (ps != NULL)
+ {
+ res = parse_scaled_value (res, &pz, ps, SEC_PER_MONTH);
+ pz++;
+ }
+
+ ps = strchr (pz, 'W');
+ if (ps != NULL)
+ {
+ res = parse_scaled_value (res, &pz, ps, SEC_PER_WEEK);
+ pz++;
+ }
+
+ ps = strchr (pz, 'D');
+ if (ps != NULL)
+ {
+ res = parse_scaled_value (res, &pz, ps, SEC_PER_DAY);
+ pz++;
+ }
+
+ while (isspace ((unsigned char)*pz))
+ pz++;
+ if (*pz != NUL)
+ {
+ errno = EINVAL;
+ return BAD_TIME;
+ }
+
+ return res;
+}
+
+/* Parses the syntax HH:MM:SS.
+ PS points into the string, after "HH", before ":MM:SS". */
+static time_t
+parse_hour_minute_second (cch_t * pz, cch_t * ps)
+{
+ time_t res = 0;
+
+ res = parse_scaled_value (0, &pz, ps, SEC_PER_HR);
+
+ pz++;
+ ps = strchr (pz, ':');
+ if (ps == NULL)
+ {
+ errno = EINVAL;
+ return BAD_TIME;
+ }
+
+ res = parse_scaled_value (res, &pz, ps, SEC_PER_MIN);
+
+ pz++;
+ ps = pz + strlen (pz);
+ return parse_scaled_value (res, &pz, ps, 1);
+}
+
+/* Parses the syntax HHMMSS. */
+static time_t
+parse_hourminutesecond (cch_t * in_pz)
+{
+ time_t res = 0;
+ char buf[4];
+ cch_t * pz;
+
+ if (strlen (in_pz) != 6)
+ {
+ errno = EINVAL;
+ return BAD_TIME;
+ }
+
+ memcpy (buf, in_pz, 2);
+ buf[2] = NUL;
+ pz = buf;
+ res = parse_scaled_value (0, &pz, buf + 2, SEC_PER_HR);
+
+ memcpy (buf, in_pz + 2, 2);
+ buf[2] = NUL;
+ pz = buf;
+ res = parse_scaled_value (res, &pz, buf + 2, SEC_PER_MIN);
+
+ memcpy (buf, in_pz + 4, 2);
+ buf[2] = NUL;
+ pz = buf;
+ return parse_scaled_value (res, &pz, buf + 2, 1);
+}
+
+/* Parses the syntax hh H mm M ss S. */
+static time_t
+parse_HMS (cch_t * pz)
+{
+ time_t res = 0;
+ cch_t * ps = strchr (pz, 'H');
+ if (ps != NULL)
+ {
+ res = parse_scaled_value (0, &pz, ps, SEC_PER_HR);
+ pz++;
+ }
+
+ ps = strchr (pz, 'M');
+ if (ps != NULL)
+ {
+ res = parse_scaled_value (res, &pz, ps, SEC_PER_MIN);
+ pz++;
+ }
+
+ ps = strchr (pz, 'S');
+ if (ps != NULL)
+ {
+ res = parse_scaled_value (res, &pz, ps, 1);
+ pz++;
+ }
+
+ while (isspace ((unsigned char)*pz))
+ pz++;
+ if (*pz != NUL)
+ {
+ errno = EINVAL;
+ return BAD_TIME;
+ }
+
+ return res;
+}
+
+/* Parses a time (hours, minutes, seconds) specification in either syntax. */
+static time_t
+parse_time (cch_t * pz)
+{
+ cch_t * ps;
+ time_t res = 0;
+
+ /*
+ * Scan for a hyphen
+ */
+ ps = strchr (pz, ':');
+ if (ps != NULL)
+ {
+ res = parse_hour_minute_second (pz, ps);
+ }
+
+ /*
+ * Try for a 'H', 'M' or 'S' suffix
+ */
+ else if (ps = strpbrk (pz, "HMS"),
+ ps == NULL)
+ {
+ /* Its a YYYYMMDD format: */
+ res = parse_hourminutesecond (pz);
+ }
+
+ else
+ res = parse_HMS (pz);
+
+ return res;
+}
+
+/* Returns a substring of the given string, with spaces at the beginning and at
+ the end destructively removed, per SNOBOL. */
+static char *
+trim (char * pz)
+{
+ /* trim leading white space */
+ while (isspace ((unsigned char)*pz))
+ pz++;
+
+ /* trim trailing white space */
+ {
+ char * pe = pz + strlen (pz);
+ while ((pe > pz) && isspace ((unsigned char)pe[-1]))
+ pe--;
+ *pe = NUL;
+ }
+
+ return pz;
+}
+
+/*
+ * Parse the year/months/days of a time period
+ */
+static time_t
+parse_period (cch_t * in_pz)
+{
+ char * pT;
+ char * ps;
+ char * pz = strdup (in_pz);
+ void * fptr = pz;
+ time_t res = 0;
+
+ if (pz == NULL)
+ {
+ errno = ENOMEM;
+ return BAD_TIME;
+ }
+
+ pT = strchr (pz, 'T');
+ if (pT != NULL)
+ {
+ *(pT++) = NUL;
+ pz = trim (pz);
+ pT = trim (pT);
+ }
+
+ /*
+ * Scan for a hyphen
+ */
+ ps = strchr (pz, '-');
+ if (ps != NULL)
+ {
+ res = parse_year_month_day (pz, ps);
+ }
+
+ /*
+ * Try for a 'Y', 'M' or 'D' suffix
+ */
+ else if (ps = strpbrk (pz, "YMWD"),
+ ps == NULL)
+ {
+ /* Its a YYYYMMDD format: */
+ res = parse_yearmonthday (pz);
+ }
+
+ else
+ res = parse_YMWD (pz);
+
+ if ((errno == 0) && (pT != NULL))
+ {
+ time_t val = parse_time (pT);
+ res = scale_n_add (res, val, 1);
+ }
+
+ free (fptr);
+ return res;
+}
+
+static time_t
+parse_non_iso8601 (cch_t * pz)
+{
+ whats_done_t whatd_we_do = NOTHING_IS_DONE;
+
+ time_t res = 0;
+
+ do {
+ time_t val;
+
+ errno = 0;
+ val = str_const_to_l (pz, &pz, 10);
+ if (errno != 0)
+ goto bad_time;
+
+ /* IF we find a colon, then we're going to have a seconds value.
+ We will not loop here any more. We cannot already have parsed
+ a minute value and if we've parsed an hour value, then the result
+ value has to be less than an hour. */
+ if (*pz == ':')
+ {
+ if (whatd_we_do >= MINUTE_IS_DONE)
+ break;
+
+ val = parse_hr_min_sec (val, pz);
+
+ if ((whatd_we_do == HOUR_IS_DONE) && (val >= SEC_PER_HR))
+ break;
+
+ return scale_n_add (res, val, 1);
+ }
+
+ {
+ unsigned int mult;
+
+ /* Skip over white space following the number we just parsed. */
+ while (isspace ((unsigned char)*pz))
+ pz++;
+
+ switch (*pz)
+ {
+ default: goto bad_time;
+ case NUL:
+ return scale_n_add (res, val, 1);
+
+ case 'y': case 'Y':
+ if (whatd_we_do >= YEAR_IS_DONE)
+ goto bad_time;
+ mult = SEC_PER_YEAR;
+ whatd_we_do = YEAR_IS_DONE;
+ break;
+
+ case 'M':
+ if (whatd_we_do >= MONTH_IS_DONE)
+ goto bad_time;
+ mult = SEC_PER_MONTH;
+ whatd_we_do = MONTH_IS_DONE;
+ break;
+
+ case 'W':
+ if (whatd_we_do >= WEEK_IS_DONE)
+ goto bad_time;
+ mult = SEC_PER_WEEK;
+ whatd_we_do = WEEK_IS_DONE;
+ break;
+
+ case 'd': case 'D':
+ if (whatd_we_do >= DAY_IS_DONE)
+ goto bad_time;
+ mult = SEC_PER_DAY;
+ whatd_we_do = DAY_IS_DONE;
+ break;
+
+ case 'h':
+ if (whatd_we_do >= HOUR_IS_DONE)
+ goto bad_time;
+ mult = SEC_PER_HR;
+ whatd_we_do = HOUR_IS_DONE;
+ break;
+
+ case 'm':
+ if (whatd_we_do >= MINUTE_IS_DONE)
+ goto bad_time;
+ mult = SEC_PER_MIN;
+ whatd_we_do = MINUTE_IS_DONE;
+ break;
+
+ case 's':
+ mult = 1;
+ whatd_we_do = SECOND_IS_DONE;
+ break;
+ }
+
+ res = scale_n_add (res, val, mult);
+
+ pz++;
+ while (isspace ((unsigned char)*pz))
+ pz++;
+ if (*pz == NUL)
+ return res;
+
+ if (! isdigit ((unsigned char)*pz))
+ break;
+ }
+
+ } while (whatd_we_do < SECOND_IS_DONE);
+
+ bad_time:
+ errno = EINVAL;
+ return BAD_TIME;
+}
+
+time_t
+parse_duration (char const * pz)
+{
+ while (isspace ((unsigned char)*pz))
+ pz++;
+
+ switch (*pz)
+ {
+ case 'P':
+ return parse_period (pz + 1);
+
+ case 'T':
+ return parse_time (pz + 1);
+
+ default:
+ if (isdigit ((unsigned char)*pz))
+ return parse_non_iso8601 (pz);
+
+ errno = EINVAL;
+ return BAD_TIME;
+ }
+}
+
+/*
+ * Local Variables:
+ * mode: C
+ * c-file-style: "gnu"
+ * indent-tabs-mode: nil
+ * End:
+ * end of parse-duration.c */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/parse-duration.h b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/parse-duration.h
new file mode 100644
index 0000000..33ddc33
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/parse-duration.h
@@ -0,0 +1,90 @@
+/* Parse a time duration and return a seconds count
+ Copyright (C) 2008-2015 Free Software Foundation, Inc.
+ Written by Bruce Korb <bkorb@gnu.org>, 2008.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/*
+
+ Readers and users of this function are referred to the ISO-8601
+ specification, with particular attention to "Durations".
+
+ At the time of writing, this worked:
+
+ http://en.wikipedia.org/wiki/ISO_8601#Durations
+
+ The string must start with a 'P', 'T' or a digit.
+
+ ==== if it is a digit
+
+ the string may contain: NNN Y NNN M NNN W NNN d NNN h NNN m NNN s
+ This represents NNN years, NNN months, NNN weeks, NNN days, NNN hours,
+ NNN minutes and NNN seconds.
+ The embedded white space is optional.
+ These terms must appear in this order.
+ Case is significant: 'M' is months and 'm' is minutes.
+ The final "s" is optional.
+ All of the terms ("NNN" plus designator) are optional.
+ Minutes and seconds may optionally be represented as NNN:NNN.
+ Also, hours, minute and seconds may be represented as NNN:NNN:NNN.
+ There is no limitation on the value of any of the terms, except
+ that the final result must fit in a time_t value.
+
+ ==== if it is a 'P' or 'T', please see ISO-8601 for a rigorous definition.
+
+ The 'P' term may be followed by any of three formats:
+ yyyymmdd
+ yy-mm-dd
+ yy Y mm M ww W dd D
+
+ or it may be empty and followed by a 'T'. The "yyyymmdd" must be eight
+ digits long.
+
+ NOTE! Months are always 30 days and years are always 365 days long.
+ 5 years is always 1825 days, not 1826 or 1827 depending on leap year
+ considerations. 3 months is always 90 days. There is no consideration
+ for how many days are in the current, next or previous months.
+
+ For the final format:
+ * Embedded white space is allowed, but it is optional.
+ * All of the terms are optional. Any or all-but-one may be omitted.
+ * The meanings are yy years, mm months, ww weeks and dd days.
+ * The terms must appear in this order.
+
+ ==== The 'T' term may be followed by any of these formats:
+
+ hhmmss
+ hh:mm:ss
+ hh H mm M ss S
+
+ For the final format:
+ * Embedded white space is allowed, but it is optional.
+ * All of the terms are optional. Any or all-but-one may be omitted.
+ * The terms must appear in this order.
+
+ */
+#ifndef GNULIB_PARSE_DURATION_H
+#define GNULIB_PARSE_DURATION_H
+
+#include <time.h>
+
+/* Return value when a valid duration cannot be parsed. */
+#define BAD_TIME ((time_t)~0)
+
+/* Parses the given string. If it has the syntax of a valid duration,
+ this duration is returned. Otherwise, the return value is BAD_TIME,
+ and errno is set to either EINVAL (bad syntax) or ERANGE (out of range). */
+extern time_t parse_duration (char const * in_pz);
+
+#endif /* GNULIB_PARSE_DURATION_H */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/pgusage.c b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/pgusage.c
new file mode 100644
index 0000000..3d229c1
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/pgusage.c
@@ -0,0 +1,187 @@
+
+/**
+ * \file pgusage.c
+ *
+ * Automated Options Paged Usage module.
+ *
+ * @addtogroup autoopts
+ * @{
+ */
+/*
+ * This routine will run run-on options through a pager so the
+ * user may examine, print or edit them at their leisure.
+ *
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
+ *
+ * AutoOpts is available under any one of two licenses. The license
+ * in use must be one of these two and the choice is under the control
+ * of the user of the license.
+ *
+ * The GNU Lesser General Public License, version 3 or later
+ * See the files "COPYING.lgplv3" and "COPYING.gplv3"
+ *
+ * The Modified Berkeley Software Distribution License
+ * See the file "COPYING.mbsd"
+ *
+ * These files have the following sha256 sums:
+ *
+ * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
+ * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
+ * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
+ */
+
+#if defined(HAVE_WORKING_FORK)
+static inline FILE *
+open_tmp_usage(char ** buf)
+{
+ char * bf;
+ size_t bfsz;
+
+ {
+ unsigned int my_pid = (unsigned int)getpid();
+ char const * tmpdir = getenv(TMPDIR);
+ if (tmpdir == NULL)
+ tmpdir = tmp_dir;
+ bfsz = TMP_FILE_FMT_LEN + strlen(tmpdir) + 10;
+ bf = AGALOC(bfsz, "tmp fil");
+ snprintf(bf, bfsz, TMP_FILE_FMT, tmpdir, my_pid);
+ }
+
+ {
+ static mode_t const cmask = S_IRWXO | S_IRWXG;
+ mode_t svmsk = umask(cmask);
+ int fd = mkstemp(bf);
+ (void)umask(svmsk);
+
+ if (fd < 0) {
+ AGFREE(bf);
+ return NULL;
+ }
+ *buf = bf;
+ return fdopen(fd, "w");
+ }
+}
+
+static inline char *
+mk_pager_cmd(char const * fname)
+{
+ /*
+ * Page the file and remove it when done. For shell script processing,
+ * we must redirect the output to the current stderr, otherwise stdout.
+ */
+ fclose(option_usage_fp);
+ option_usage_fp = NULL;
+
+ {
+ char const * pager = (char const *)getenv(PAGER_NAME);
+ size_t bfsz;
+ char * res;
+
+ /*
+ * Use the "more(1)" program if "PAGER" has not been defined
+ */
+ if (pager == NULL)
+ pager = MORE_STR;
+
+ bfsz = 2 * strlen(fname) + strlen(pager) + PAGE_USAGE_FMT_LEN;
+ res = AGALOC(bfsz, "more cmd");
+ snprintf(res, bfsz, PAGE_USAGE_FMT, pager, fname);
+ AGFREE(fname);
+ return res;
+ }
+}
+#endif
+
+/*=export_func optionPagedUsage
+ * private:
+ *
+ * what: emit help text and pass through a pager program.
+ * arg: + tOptions * + opts + program options descriptor +
+ * arg: + tOptDesc * + od + the descriptor for this arg +
+ *
+ * doc:
+ * Run the usage output through a pager.
+ * This is very handy if it is very long.
+ * This is disabled on platforms without a working fork() function.
+=*/
+void
+optionPagedUsage(tOptions * opts, tOptDesc * od)
+{
+#if ! defined(HAVE_WORKING_FORK)
+ if ((od->fOptState & OPTST_RESET) != 0)
+ return;
+
+ (*opts->pUsageProc)(opts, EXIT_SUCCESS);
+#else
+ static bool sv_print_exit = false;
+ static char * fil_name = NULL;
+
+ /*
+ * IF we are being called after the usage proc is done
+ * (and thus has called "exit(2)")
+ * THEN invoke the pager to page through the usage file we created.
+ */
+ switch (pagerState) {
+ case PAGER_STATE_INITIAL:
+ {
+ if ((od->fOptState & OPTST_RESET) != 0)
+ return;
+ option_usage_fp = open_tmp_usage(&fil_name);
+ if (option_usage_fp == NULL)
+ (*opts->pUsageProc)(opts, EXIT_SUCCESS);
+
+ pagerState = PAGER_STATE_READY;
+ sv_print_exit = print_exit;
+
+ /*
+ * Set up so this routine gets called during the exit logic
+ */
+ atexit((void(*)(void))optionPagedUsage);
+
+ /*
+ * The usage procedure will now put the usage information into
+ * the temporary file we created above. Keep any shell commands
+ * out of the result.
+ */
+ print_exit = false;
+ (*opts->pUsageProc)(opts, EXIT_SUCCESS);
+
+ /* NOTREACHED */
+ _exit(EXIT_FAILURE);
+ }
+
+ case PAGER_STATE_READY:
+ fil_name = mk_pager_cmd(fil_name);
+
+ if (sv_print_exit) {
+ fputs("\nexit 0\n", stdout);
+ fclose(stdout);
+ dup2(STDERR_FILENO, STDOUT_FILENO);
+
+ } else {
+ fclose(stderr);
+ dup2(STDOUT_FILENO, STDERR_FILENO);
+ }
+
+ ignore_val( system( fil_name));
+ AGFREE(fil_name);
+
+ case PAGER_STATE_CHILD:
+ /*
+ * This is a child process used in creating shell script usage.
+ */
+ break;
+ }
+#endif
+}
+
+/** @}
+ *
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of autoopts/pgusage.c */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/proto.h b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/proto.h
new file mode 100644
index 0000000..a78b794
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/proto.h
@@ -0,0 +1,146 @@
+/* -*- buffer-read-only: t -*- vi: set ro:
+ *
+ * Prototypes for autoopts
+ * Generated Sat Apr 25 09:53:18 PDT 2015
+ */
+#ifndef AUTOOPTS_PROTO_H_GUARD
+#define AUTOOPTS_PROTO_H_GUARD 1
+
+/*
+ * Extracted from alias.c
+ */
+static tSuccess
+too_many_occurrences(tOptions * opts, tOptDesc * od);
+
+/*
+ * Extracted from autoopts.c
+ */
+static void *
+ao_malloc(size_t sz);
+
+static void *
+ao_realloc(void *p, size_t sz);
+
+static char *
+ao_strdup(char const *str);
+
+static tSuccess
+handle_opt(tOptions * opts, tOptState * o_st);
+
+static tSuccess
+next_opt(tOptions * opts, tOptState * o_st);
+
+static tSuccess
+regular_opts(tOptions * opts);
+
+/*
+ * Extracted from check.c
+ */
+static bool
+is_consistent(tOptions * pOpts);
+
+/*
+ * Extracted from configfile.c
+ */
+static void
+intern_file_load(tOptions * opts);
+
+static char const *
+parse_attrs(tOptions * opts, char const * txt, tOptionLoadMode * pMode,
+ tOptionValue * pType);
+
+/*
+ * Extracted from env.c
+ */
+static void
+doPrognameEnv(tOptions * pOpts, teEnvPresetType type);
+
+static void
+env_presets(tOptions * pOpts, teEnvPresetType type);
+
+/*
+ * Extracted from find.c
+ */
+static tSuccess
+opt_find_long(tOptions * opts, char const * opt_name, tOptState * state);
+
+static tSuccess
+opt_find_short(tOptions * pOpts, uint_t optValue, tOptState * pOptState);
+
+static tSuccess
+get_opt_arg(tOptions * opts, tOptState * o_st);
+
+static tSuccess
+find_opt(tOptions * opts, tOptState * o_st);
+
+/*
+ * Extracted from init.c
+ */
+static tSuccess
+validate_struct(tOptions * opts, char const * pname);
+
+static tSuccess
+immediate_opts(tOptions * opts);
+
+static bool
+ao_initialize(tOptions * opts, int a_ct, char ** a_v);
+
+/*
+ * Extracted from load.c
+ */
+static void
+munge_str(char * txt, tOptionLoadMode mode);
+
+static void
+load_opt_line(tOptions * opts, tOptState * opt_state, char * line,
+ tDirection direction, tOptionLoadMode load_mode );
+
+/*
+ * Extracted from makeshell.c
+ */
+static noreturn void
+option_exits(int exit_code);
+
+static noreturn void
+ao_bug(char const * msg);
+
+static void
+fserr_warn(char const * prog, char const * op, char const * fname);
+
+static noreturn void
+fserr_exit(char const * prog, char const * op, char const * fname);
+
+/*
+ * Extracted from nested.c
+ */
+static void
+unload_arg_list(tArgList * arg_list);
+
+static tOptionValue *
+optionLoadNested(char const * text, char const * name, size_t nm_len);
+
+static int
+get_special_char(char const ** ppz, int * ct);
+
+static void
+emit_special_char(FILE * fp, int ch);
+
+/*
+ * Extracted from sort.c
+ */
+static void
+optionSort(tOptions * opts);
+
+/*
+ * Extracted from stack.c
+ */
+static void
+addArgListEntry(void ** ppAL, void * entry);
+
+/*
+ * Extracted from usage.c
+ */
+static void
+set_usage_flags(tOptions * opts, char const * flg_txt);
+
+#endif /* AUTOOPTS_PROTO_H_GUARD */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/putshell.c b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/putshell.c
new file mode 100644
index 0000000..9bfa984
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/putshell.c
@@ -0,0 +1,511 @@
+
+/**
+ * \file putshell.c
+ *
+ * This module will interpret the options set in the tOptions
+ * structure and print them to standard out in a fashion that
+ * will allow them to be interpreted by the Bourne or Korn shells.
+ *
+ * @addtogroup autoopts
+ * @{
+ */
+/*
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
+ *
+ * AutoOpts is available under any one of two licenses. The license
+ * in use must be one of these two and the choice is under the control
+ * of the user of the license.
+ *
+ * The GNU Lesser General Public License, version 3 or later
+ * See the files "COPYING.lgplv3" and "COPYING.gplv3"
+ *
+ * The Modified Berkeley Software Distribution License
+ * See the file "COPYING.mbsd"
+ *
+ * These files have the following sha256 sums:
+ *
+ * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
+ * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
+ * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
+ */
+
+/* = = = START-STATIC-FORWARD = = = */
+static size_t
+string_size(char const * scan, size_t nl_len);
+
+static char const *
+print_quoted_apostrophes(char const * str);
+
+static void
+print_quot_str(char const * str);
+
+static void
+print_enumeration(tOptions * pOpts, tOptDesc * pOD);
+
+static void
+print_membership(tOptions * pOpts, tOptDesc * pOD);
+
+static void
+print_stacked_arg(tOptions * pOpts, tOptDesc * pOD);
+
+static void
+print_reordering(tOptions * opts);
+/* = = = END-STATIC-FORWARD = = = */
+
+/**
+ * Count the number of bytes required to represent a string as a
+ * compilable string.
+ *
+ * @param[in] scan the text to be rewritten as a C program text string.
+ * @param[in] nl_len the number of bytes used for each embedded newline.
+ *
+ * @returns the count, including the terminating NUL byte.
+ */
+static size_t
+string_size(char const * scan, size_t nl_len)
+{
+ /*
+ * Start by counting the start and end quotes, plus the NUL.
+ */
+ size_t res_ln = 3;
+
+ for (;;) {
+ char ch = *(scan++);
+ if ((ch >= ' ') && (ch <= '~')) {
+
+ /*
+ * a backslash allowance for double quotes and baskslashes
+ */
+ res_ln += ((ch == '"') || (ch == '\\')) ? 2 : 1;
+ }
+
+ /*
+ * When not a normal character, then count the characters
+ * required to represent whatever it is.
+ */
+ else switch (ch) {
+ case NUL:
+ return res_ln;
+
+ case NL:
+ res_ln += nl_len;
+ break;
+
+ case HT:
+ case BEL:
+ case BS:
+ case FF:
+ case CR:
+ case VT:
+ res_ln += 2;
+ break;
+
+ default:
+ res_ln += 4; /* text len for \xNN */
+ }
+ }
+}
+
+/*=export_func optionQuoteString
+ * private:
+ *
+ * what: Print a string as quoted text suitable for a C compiler.
+ * arg: + char const * + text + a block of text to quote +
+ * arg: + char const * + nl + line splice text +
+ *
+ * ret_type: char const *
+ * ret_desc: the allocated input string as a quoted string
+ *
+ * doc:
+ * This is for internal use by autogen and autoopts.
+ * It takes an input string and produces text the C compiler can process
+ * to produce an exact copy of the original string.
+ * The caller must deallocate the result. Standard C strings and
+ * K&R strings are distinguished by the "nl" string.
+=*/
+char const *
+optionQuoteString(char const * text, char const * nl)
+{
+ size_t nl_len = strlen(nl);
+ char * out;
+ char * res = out = AGALOC(string_size(text, nl_len), "quot str");
+ *(out++) = '"';
+
+ for (;;) {
+ unsigned char ch = (unsigned char)*text;
+ if ((ch >= ' ') && (ch <= '~')) {
+ if ((ch == '"') || (ch == '\\'))
+ /*
+ * We must escape these characters in the output string
+ */
+ *(out++) = '\\';
+ *(out++) = (char)ch;
+
+ } else switch (ch) {
+# define add_esc_ch(_ch) { *(out++) = '\\'; *(out++) = (_ch); }
+ case BEL: add_esc_ch('a'); break;
+ case BS: add_esc_ch('b'); break;
+ case HT: add_esc_ch('t'); break;
+ case VT: add_esc_ch('v'); break;
+ case FF: add_esc_ch('f'); break;
+ case CR: add_esc_ch('r'); break;
+
+ case LF:
+ /*
+ * Place contiguous new-lines on a single line.
+ * The current character is a NL, check the next one.
+ */
+ while (*++text == NL)
+ add_esc_ch('n');
+
+ /*
+ * Insert a splice before starting next line
+ */
+ if (*text != NUL) {
+ memcpy(out, nl, nl_len);
+ out += nl_len;
+
+ continue; /* text is already at the next character */
+ }
+
+ add_esc_ch('n');
+ /* FALLTHROUGH */
+
+ case NUL:
+ /*
+ * End of string. Terminate the quoted output. If necessary,
+ * deallocate the text string. Return the scan resumption point.
+ */
+ *(out++) = '"';
+ *out = NUL;
+ return res;
+
+ default:
+ /*
+ * sprintf is safe here, because we already computed
+ * the amount of space we will be using.
+ */
+ sprintf(out, MK_STR_OCT_FMT, ch);
+ out += 4;
+ }
+
+ text++;
+# undef add_esc_ch
+ }
+}
+
+/**
+ * Print out escaped apostorophes.
+ *
+ * @param[in] str the apostrophies to print
+ */
+static char const *
+print_quoted_apostrophes(char const * str)
+{
+ while (*str == APOSTROPHE) {
+ fputs(QUOT_APOS, stdout);
+ str++;
+ }
+ return str;
+}
+
+/**
+ * Print a single quote (apostrophe quoted) string.
+ * Other than somersaults for apostrophes, nothing else needs quoting.
+ *
+ * @param[in] str the string to print
+ */
+static void
+print_quot_str(char const * str)
+{
+ /*
+ * Handle empty strings to make the rest of the logic simpler.
+ */
+ if ((str == NULL) || (*str == NUL)) {
+ fputs(EMPTY_ARG, stdout);
+ return;
+ }
+
+ /*
+ * Emit any single quotes/apostrophes at the start of the string and
+ * bail if that is all we need to do.
+ */
+ str = print_quoted_apostrophes(str);
+ if (*str == NUL)
+ return;
+
+ /*
+ * Start the single quote string
+ */
+ fputc(APOSTROPHE, stdout);
+ for (;;) {
+ char const * pz = strchr(str, APOSTROPHE);
+ if (pz == NULL)
+ break;
+
+ /*
+ * Emit the string up to the single quote (apostrophe) we just found.
+ */
+ (void)fwrite(str, (size_t)(pz - str), (size_t)1, stdout);
+
+ /*
+ * Close the current string, emit the apostrophes and re-open the
+ * string (IFF there is more text to print).
+ */
+ fputc(APOSTROPHE, stdout);
+ str = print_quoted_apostrophes(pz);
+ if (*str == NUL)
+ return;
+
+ fputc(APOSTROPHE, stdout);
+ }
+
+ /*
+ * If we broke out of the loop, we must still emit the remaining text
+ * and then close the single quote string.
+ */
+ fputs(str, stdout);
+ fputc(APOSTROPHE, stdout);
+}
+
+static void
+print_enumeration(tOptions * pOpts, tOptDesc * pOD)
+{
+ uintptr_t e_val = pOD->optArg.argEnum;
+ printf(OPT_VAL_FMT, pOpts->pzPROGNAME, pOD->pz_NAME);
+
+ /*
+ * Convert value to string, print that and restore numeric value.
+ */
+ (*(pOD->pOptProc))(OPTPROC_RETURN_VALNAME, pOD);
+ printf(QUOT_ARG_FMT, pOD->optArg.argString);
+ if (pOD->fOptState & OPTST_ALLOC_ARG)
+ AGFREE(pOD->optArg.argString);
+ pOD->optArg.argEnum = e_val;
+
+ printf(OPT_END_FMT, pOpts->pzPROGNAME, pOD->pz_NAME);
+}
+
+static void
+print_membership(tOptions * pOpts, tOptDesc * pOD)
+{
+ char const * svstr = pOD->optArg.argString;
+ char const * pz;
+ uintptr_t val = 1;
+ printf(zOptNumFmt, pOpts->pzPROGNAME, pOD->pz_NAME,
+ (int)(uintptr_t)(pOD->optCookie));
+ pOD->optCookie = VOIDP(~0UL);
+ (*(pOD->pOptProc))(OPTPROC_RETURN_VALNAME, pOD);
+
+ pz = pOD->optArg.argString;
+ while (*pz != NUL) {
+ printf("readonly %s_", pOD->pz_NAME);
+ pz = SPN_PLUS_N_SPACE_CHARS(pz);
+
+ for (;;) {
+ int ch = *(pz++);
+ if (IS_LOWER_CASE_CHAR(ch)) fputc(toupper(ch), stdout);
+ else if (IS_UPPER_CASE_CHAR(ch)) fputc(ch, stdout);
+ else if (IS_PLUS_N_SPACE_CHAR(ch)) goto name_done;
+ else if (ch == NUL) { pz--; goto name_done; }
+ else fputc('_', stdout);
+ } name_done:;
+ printf(SHOW_VAL_FMT, (unsigned long)val);
+ val <<= 1;
+ }
+
+ AGFREE(pOD->optArg.argString);
+ pOD->optArg.argString = svstr;
+}
+
+static void
+print_stacked_arg(tOptions * pOpts, tOptDesc * pOD)
+{
+ tArgList * pAL = (tArgList *)pOD->optCookie;
+ char const ** ppz = pAL->apzArgs;
+ int ct = pAL->useCt;
+
+ printf(zOptCookieCt, pOpts->pzPROGNAME, pOD->pz_NAME, ct);
+
+ while (--ct >= 0) {
+ printf(ARG_BY_NUM_FMT, pOpts->pzPROGNAME, pOD->pz_NAME,
+ pAL->useCt - ct);
+ print_quot_str(*(ppz++));
+ printf(EXPORT_ARG_FMT, pOpts->pzPROGNAME, pOD->pz_NAME,
+ pAL->useCt - ct);
+ }
+}
+
+/**
+ * emit the arguments as readily parsed text.
+ * The program options are set by emitting the shell "set" command.
+ *
+ * @param[in] opts the program options structure
+ */
+static void
+print_reordering(tOptions * opts)
+{
+ unsigned int ix;
+
+ fputs(set_dash, stdout);
+
+ for (ix = opts->curOptIdx;
+ ix < opts->origArgCt;
+ ix++) {
+ fputc(' ', stdout);
+ print_quot_str(opts->origArgVect[ ix ]);
+ }
+ fputs(init_optct, stdout);
+}
+
+/*=export_func optionPutShell
+ * what: write a portable shell script to parse options
+ * private:
+ * arg: tOptions *, pOpts, the program options descriptor
+ * doc: This routine will emit portable shell script text for parsing
+ * the options described in the option definitions.
+=*/
+void
+optionPutShell(tOptions * pOpts)
+{
+ int optIx = 0;
+
+ printf(zOptCtFmt, pOpts->curOptIdx-1);
+
+ do {
+ tOptDesc * pOD = pOpts->pOptDesc + optIx;
+
+ if ((pOD->fOptState & OPTST_NO_OUTPUT_MASK) != 0)
+ continue;
+
+ /*
+ * Equivalence classes are hard to deal with. Where the
+ * option data wind up kind of squishes around. For the purposes
+ * of emitting shell state, they are not recommended, but we'll
+ * do something. I guess we'll emit the equivalenced-to option
+ * at the point in time when the base option is found.
+ */
+ if (pOD->optEquivIndex != NO_EQUIVALENT)
+ continue; /* equivalence to a different option */
+
+ /*
+ * Equivalenced to a different option. Process the current option
+ * as the equivalenced-to option. Keep the persistent state bits,
+ * but copy over the set-state bits.
+ */
+ if (pOD->optActualIndex != optIx) {
+ tOptDesc * p = pOpts->pOptDesc + pOD->optActualIndex;
+ p->optArg = pOD->optArg;
+ p->fOptState &= OPTST_PERSISTENT_MASK;
+ p->fOptState |= pOD->fOptState & ~OPTST_PERSISTENT_MASK;
+ printf(zEquivMode, pOpts->pzPROGNAME, pOD->pz_NAME, p->pz_NAME);
+ pOD = p;
+ }
+
+ /*
+ * If the argument type is a set membership bitmask, then we always
+ * emit the thing. We do this because it will always have some sort
+ * of bitmask value and we need to emit the bit values.
+ */
+ if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_MEMBERSHIP) {
+ print_membership(pOpts, pOD);
+ continue;
+ }
+
+ /*
+ * IF the option was either specified or it wakes up enabled,
+ * then we will emit information. Otherwise, skip it.
+ * The idea is that if someone defines an option to initialize
+ * enabled, we should tell our shell script that it is enabled.
+ */
+ if (UNUSED_OPT(pOD) && DISABLED_OPT(pOD))
+ continue;
+
+ /*
+ * Handle stacked arguments
+ */
+ if ( (pOD->fOptState & OPTST_STACKED)
+ && (pOD->optCookie != NULL) ) {
+ print_stacked_arg(pOpts, pOD);
+ continue;
+ }
+
+ /*
+ * If the argument has been disabled,
+ * Then set its value to the disablement string
+ */
+ if ((pOD->fOptState & OPTST_DISABLED) != 0) {
+ printf(zOptDisabl, pOpts->pzPROGNAME, pOD->pz_NAME,
+ (pOD->pz_DisablePfx != NULL)
+ ? pOD->pz_DisablePfx : "false");
+ continue;
+ }
+
+ /*
+ * If the argument type is numeric, the last arg pointer
+ * is really the VALUE of the string that was pointed to.
+ */
+ if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_NUMERIC) {
+ printf(zOptNumFmt, pOpts->pzPROGNAME, pOD->pz_NAME,
+ (int)pOD->optArg.argInt);
+ continue;
+ }
+
+ /*
+ * If the argument type is an enumeration, then it is much
+ * like a text value, except we call the callback function
+ * to emit the value corresponding to the "optArg" number.
+ */
+ if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_ENUMERATION) {
+ print_enumeration(pOpts, pOD);
+ continue;
+ }
+
+ /*
+ * If the argument type is numeric, the last arg pointer
+ * is really the VALUE of the string that was pointed to.
+ */
+ if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_BOOLEAN) {
+ printf(zFullOptFmt, pOpts->pzPROGNAME, pOD->pz_NAME,
+ (pOD->optArg.argBool == 0) ? "false" : "true");
+ continue;
+ }
+
+ /*
+ * IF the option has an empty value,
+ * THEN we set the argument to the occurrence count.
+ */
+ if ( (pOD->optArg.argString == NULL)
+ || (pOD->optArg.argString[0] == NUL) ) {
+
+ printf(zOptNumFmt, pOpts->pzPROGNAME, pOD->pz_NAME,
+ pOD->optOccCt);
+ continue;
+ }
+
+ /*
+ * This option has a text value
+ */
+ printf(OPT_VAL_FMT, pOpts->pzPROGNAME, pOD->pz_NAME);
+ print_quot_str(pOD->optArg.argString);
+ printf(OPT_END_FMT, pOpts->pzPROGNAME, pOD->pz_NAME);
+
+ } while (++optIx < pOpts->presetOptCt );
+
+ if ( ((pOpts->fOptSet & OPTPROC_REORDER) != 0)
+ && (pOpts->curOptIdx < pOpts->origArgCt))
+ print_reordering(pOpts);
+
+ fflush(stdout);
+}
+
+/** @}
+ *
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of autoopts/putshell.c */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/reset.c b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/reset.c
new file mode 100644
index 0000000..97ecb52
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/reset.c
@@ -0,0 +1,141 @@
+
+/**
+ * \file reset.c
+ *
+ * Reset the option state to the compiled state.
+ *
+ * @addtogroup autoopts
+ * @{
+ */
+/*
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
+ *
+ * AutoOpts is available under any one of two licenses. The license
+ * in use must be one of these two and the choice is under the control
+ * of the user of the license.
+ *
+ * The GNU Lesser General Public License, version 3 or later
+ * See the files "COPYING.lgplv3" and "COPYING.gplv3"
+ *
+ * The Modified Berkeley Software Distribution License
+ * See the file "COPYING.mbsd"
+ *
+ * These files have the following sha256 sums:
+ *
+ * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
+ * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
+ * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
+ */
+
+static void
+optionReset(tOptions * pOpts, tOptDesc * pOD)
+{
+ pOD->fOptState &= OPTST_PERSISTENT_MASK;
+ pOD->fOptState |= OPTST_RESET;
+ if (pOD->pOptProc != NULL)
+ pOD->pOptProc(pOpts, pOD);
+ pOD->optArg.argString =
+ pOpts->originalOptArgArray[ pOD->optIndex ].argString;
+ pOD->optCookie = pOpts->originalOptArgCookie[ pOD->optIndex ];
+ pOD->fOptState &= OPTST_PERSISTENT_MASK;
+}
+
+
+static void
+optionResetEverything(tOptions * pOpts)
+{
+ tOptDesc * pOD = pOpts->pOptDesc;
+ int ct = pOpts->presetOptCt;
+
+ for (;;) {
+ optionReset(pOpts, pOD);
+
+ if (--ct <= 0)
+ break;
+ pOD++;
+ }
+}
+
+
+/*=export_func optionResetOpt
+ * private:
+ *
+ * what: Reset the value of an option
+ * arg: + tOptions * + pOpts + program options descriptor +
+ * arg: + tOptDesc * + pOptDesc + the descriptor for this arg +
+ *
+ * doc:
+ * This code will cause another option to be reset to its initial state.
+ * For example, --reset=foo will cause the --foo option to be reset.
+=*/
+void
+optionResetOpt(tOptions * pOpts, tOptDesc * pOD)
+{
+ static bool reset_active = false;
+
+ tOptState opt_state = OPTSTATE_INITIALIZER(DEFINED);
+ char const * pzArg = pOD->optArg.argString;
+ tSuccess succ;
+
+ if (pOpts <= OPTPROC_EMIT_LIMIT)
+ return;
+
+ if (reset_active)
+ return;
+
+ if ( (! HAS_originalOptArgArray(pOpts))
+ || (pOpts->originalOptArgCookie == NULL))
+ ao_bug(zno_reset);
+
+ if ((pzArg == NULL) || (*pzArg == NUL)) {
+ fprintf(stderr, zreset_arg, pOpts->pzProgName, pOD->pz_Name);
+ pOpts->pUsageProc(pOpts, EXIT_FAILURE);
+ /* NOTREACHED */
+ assert(0 == 1);
+ }
+
+ reset_active = true;
+
+ if (pzArg[1] == NUL) {
+ if (*pzArg == '*') {
+ optionResetEverything(pOpts);
+ reset_active = false;
+ return;
+ }
+
+ succ = opt_find_short(pOpts, (uint8_t)*pzArg, &opt_state);
+ if (! SUCCESSFUL(succ)) {
+ fprintf(stderr, zIllOptChr, pOpts->pzProgPath, *pzArg);
+ pOpts->pUsageProc(pOpts, EXIT_FAILURE);
+ /* NOTREACHED */
+ assert(0 == 1);
+ }
+ } else {
+ succ = opt_find_long(pOpts, pzArg, &opt_state);
+ if (! SUCCESSFUL(succ)) {
+ fprintf(stderr, zIllOptStr, pOpts->pzProgPath, pzArg);
+ pOpts->pUsageProc(pOpts, EXIT_FAILURE);
+ /* NOTREACHED */
+ assert(0 == 1);
+ }
+ }
+
+ /*
+ * We've found the indicated option. Turn off all non-persistent
+ * flags because we're forcing the option back to its initialized state.
+ * Call any callout procedure to handle whatever it needs to.
+ * Finally, clear the reset flag, too.
+ */
+ optionReset(pOpts, opt_state.pOD);
+ reset_active = false;
+}
+/** @}
+ *
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of autoopts/reset.c */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/restore.c b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/restore.c
new file mode 100644
index 0000000..02ef14a
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/restore.c
@@ -0,0 +1,223 @@
+
+/*
+ * \file restore.c
+ *
+ * This module's routines will save the current option state to memory
+ * and restore it. If saved prior to the initial optionProcess call,
+ * then the initial state will be restored.
+ *
+ * @addtogroup autoopts
+ * @{
+ */
+/*
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
+ *
+ * AutoOpts is available under any one of two licenses. The license
+ * in use must be one of these two and the choice is under the control
+ * of the user of the license.
+ *
+ * The GNU Lesser General Public License, version 3 or later
+ * See the files "COPYING.lgplv3" and "COPYING.gplv3"
+ *
+ * The Modified Berkeley Software Distribution License
+ * See the file "COPYING.mbsd"
+ *
+ * These files have the following sha256 sums:
+ *
+ * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
+ * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
+ * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
+ */
+
+/*
+ * optionFixupSavedOpts Really, it just wipes out option state for
+ * options that are troublesome to copy. viz., stacked strings and
+ * hierarcicaly valued option args. We do duplicate string args that
+ * have been marked as allocated though.
+ */
+static void
+fixupSavedOptionArgs(tOptions * pOpts)
+{
+ tOptions * p = pOpts->pSavedState;
+ tOptDesc * pOD = pOpts->pOptDesc;
+ int ct = pOpts->optCt;
+
+ /*
+ * Make sure that allocated stuff is only referenced in the
+ * archived copy of the data.
+ */
+ for (; ct-- > 0; pOD++) {
+ switch (OPTST_GET_ARGTYPE(pOD->fOptState)) {
+ case OPARG_TYPE_STRING:
+ if (pOD->fOptState & OPTST_STACKED) {
+ tOptDesc * q = p->pOptDesc + (pOD - pOpts->pOptDesc);
+ q->optCookie = NULL;
+ }
+ if (pOD->fOptState & OPTST_ALLOC_ARG) {
+ tOptDesc * q = p->pOptDesc + (pOD - pOpts->pOptDesc);
+ AGDUPSTR(q->optArg.argString, pOD->optArg.argString, "arg");
+ }
+ break;
+
+ case OPARG_TYPE_HIERARCHY:
+ {
+ tOptDesc * q = p->pOptDesc + (pOD - pOpts->pOptDesc);
+ q->optCookie = NULL;
+ }
+ }
+ }
+}
+
+/*=export_func optionSaveState
+ *
+ * what: saves the option state to memory
+ * arg: tOptions *, pOpts, program options descriptor
+ *
+ * doc:
+ *
+ * This routine will allocate enough memory to save the current option
+ * processing state. If this routine has been called before, that memory
+ * will be reused. You may only save one copy of the option state. This
+ * routine may be called before optionProcess(3AO). If you do call it
+ * before the first call to optionProcess, then you may also change the
+ * contents of argc/argv after you call optionRestore(3AO)
+ *
+ * In fact, more strongly put: it is safest to only use this function
+ * before having processed any options. In particular, the saving and
+ * restoring of stacked string arguments and hierarchical values is
+ * disabled. The values are not saved.
+ *
+ * err: If it fails to allocate the memory,
+ * it will print a message to stderr and exit.
+ * Otherwise, it will always succeed.
+=*/
+void
+optionSaveState(tOptions * pOpts)
+{
+ tOptions * p = (tOptions *)pOpts->pSavedState;
+
+ if (p == NULL) {
+ size_t sz = sizeof(*pOpts)
+ + ((size_t)pOpts->optCt * sizeof(tOptDesc));
+ p = AGALOC(sz, "saved option state");
+
+ pOpts->pSavedState = p;
+ }
+
+ memcpy(p, pOpts, sizeof(*p));
+ memcpy(p + 1, pOpts->pOptDesc, (size_t)p->optCt * sizeof(tOptDesc));
+
+ fixupSavedOptionArgs(pOpts);
+}
+
+
+/*=export_func optionRestore
+ *
+ * what: restore option state from memory copy
+ * arg: tOptions *, pOpts, program options descriptor
+ *
+ * doc: Copy back the option state from saved memory.
+ * The allocated memory is left intact, so this routine can be
+ * called repeatedly without having to call optionSaveState again.
+ * If you are restoring a state that was saved before the first call
+ * to optionProcess(3AO), then you may change the contents of the
+ * argc/argv parameters to optionProcess.
+ *
+ * err: If you have not called @code{optionSaveState} before, a diagnostic is
+ * printed to @code{stderr} and exit is called.
+=*/
+void
+optionRestore(tOptions * pOpts)
+{
+ tOptions * p = (tOptions *)pOpts->pSavedState;
+
+ if (p == NULL) {
+ char const * pzName = pOpts->pzProgName;
+ if (pzName == NULL) {
+ pzName = pOpts->pzPROGNAME;
+ if (pzName == NULL)
+ pzName = zNil;
+ }
+ fprintf(stderr, zNoState, pzName);
+ option_exits(EXIT_FAILURE);
+ }
+
+ pOpts->pSavedState = NULL;
+ optionFree(pOpts);
+
+ memcpy(pOpts, p, sizeof(*p));
+ memcpy(pOpts->pOptDesc, p+1, (size_t)p->optCt * sizeof(tOptDesc));
+ pOpts->pSavedState = p;
+
+ fixupSavedOptionArgs(pOpts);
+}
+
+/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
+
+/*=export_func optionFree
+ *
+ * what: free allocated option processing memory
+ * arg: tOptions *, pOpts, program options descriptor
+ *
+ * doc: AutoOpts sometimes allocates memory and puts pointers to it in the
+ * option state structures. This routine deallocates all such memory.
+ *
+ * err: As long as memory has not been corrupted,
+ * this routine is always successful.
+=*/
+void
+optionFree(tOptions * pOpts)
+{
+ free_saved_state:
+ {
+ tOptDesc * p = pOpts->pOptDesc;
+ int ct = pOpts->optCt;
+ do {
+ if (p->fOptState & OPTST_ALLOC_ARG) {
+ AGFREE(p->optArg.argString);
+ p->optArg.argString = NULL;
+ p->fOptState &= ~OPTST_ALLOC_ARG;
+ }
+
+ switch (OPTST_GET_ARGTYPE(p->fOptState)) {
+ case OPARG_TYPE_STRING:
+#ifdef WITH_LIBREGEX
+ if ( (p->fOptState & OPTST_STACKED)
+ && (p->optCookie != NULL)) {
+ p->optArg.argString = ".*";
+ optionUnstackArg(pOpts, p);
+ }
+#else
+ /* leak memory */;
+#endif
+ break;
+
+ case OPARG_TYPE_HIERARCHY:
+ if (p->optCookie != NULL)
+ unload_arg_list(p->optCookie);
+ break;
+ }
+
+ p->optCookie = NULL;
+ } while (p++, --ct > 0);
+ }
+ if (pOpts->pSavedState != NULL) {
+ tOptions * p = (tOptions *)pOpts->pSavedState;
+ memcpy(pOpts, p, sizeof(*p));
+ memcpy(pOpts->pOptDesc, p+1, (size_t)p->optCt * sizeof(tOptDesc));
+ AGFREE(pOpts->pSavedState);
+ pOpts->pSavedState = NULL;
+ goto free_saved_state;
+ }
+}
+
+/** @}
+ *
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of autoopts/restore.c */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/save.c b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/save.c
new file mode 100644
index 0000000..cdab05f
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/save.c
@@ -0,0 +1,809 @@
+
+/*
+ * \file save.c
+ *
+ * This module's routines will take the currently set options and
+ * store them into an ".rc" file for re-interpretation the next
+ * time the invoking program is run.
+ *
+ * @addtogroup autoopts
+ * @{
+ */
+/*
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
+ *
+ * AutoOpts is available under any one of two licenses. The license
+ * in use must be one of these two and the choice is under the control
+ * of the user of the license.
+ *
+ * The GNU Lesser General Public License, version 3 or later
+ * See the files "COPYING.lgplv3" and "COPYING.gplv3"
+ *
+ * The Modified Berkeley Software Distribution License
+ * See the file "COPYING.mbsd"
+ *
+ * These files have the following sha256 sums:
+ *
+ * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
+ * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
+ * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
+ */
+
+/* = = = START-STATIC-FORWARD = = = */
+static char const *
+find_dir_name(tOptions * opts, int * p_free);
+
+static char const *
+find_file_name(tOptions * opts, int * p_free_name);
+
+static void
+prt_entry(FILE * fp, tOptDesc * od, char const * l_arg);
+
+static void
+prt_value(FILE * fp, int depth, tOptDesc * pOD, tOptionValue const * ovp);
+
+static void
+prt_string(FILE * fp, char const * name, char const * pz);
+
+static void
+prt_val_list(FILE * fp, char const * name, tArgList * al);
+
+static void
+prt_nested(FILE * fp, tOptDesc * p);
+
+static FILE *
+open_sv_file(tOptions * opts);
+
+static void
+prt_no_arg_opt(FILE * fp, tOptDesc * p, tOptDesc * pOD);
+
+static void
+prt_str_arg(FILE * fp, tOptDesc * pOD);
+
+static void
+prt_enum_arg(FILE * fp, tOptDesc * od);
+
+static void
+prt_set_arg(FILE * fp, tOptDesc * od);
+
+static void
+prt_file_arg(FILE * fp, tOptDesc * od, tOptions * opts);
+/* = = = END-STATIC-FORWARD = = = */
+
+/**
+ */
+static char const *
+find_dir_name(tOptions * opts, int * p_free)
+{
+ char const * pzDir;
+
+ if ( (opts->specOptIdx.save_opts == NO_EQUIVALENT)
+ || (opts->specOptIdx.save_opts == 0))
+ return NULL;
+
+ pzDir = opts->pOptDesc[ opts->specOptIdx.save_opts ].optArg.argString;
+ if ((pzDir != NULL) && (*pzDir != NUL))
+ return pzDir;
+
+ /*
+ * This function only works if there is a directory where
+ * we can stash the RC (INI) file.
+ */
+ {
+ char const * const * papz = opts->papzHomeList;
+ if (papz == NULL)
+ return NULL;
+
+ while (papz[1] != NULL) papz++;
+ pzDir = *papz;
+ }
+
+ /*
+ * IF it does not require deciphering an env value, then just copy it
+ */
+ if (*pzDir != '$')
+ return pzDir;
+
+ {
+ char const * pzEndDir = strchr(++pzDir, DIRCH);
+ char * pzFileName;
+ char * pzEnv;
+
+ if (pzEndDir != NULL) {
+ char z[ AO_NAME_SIZE ];
+ if ((pzEndDir - pzDir) > AO_NAME_LIMIT )
+ return NULL;
+ memcpy(z, pzDir, (size_t)(pzEndDir - pzDir));
+ z[pzEndDir - pzDir] = NUL;
+ pzEnv = getenv(z);
+ } else {
+
+ /*
+ * Make sure we can get the env value (after stripping off
+ * any trailing directory or file names)
+ */
+ pzEnv = getenv(pzDir);
+ }
+
+ if (pzEnv == NULL) {
+ fprintf(stderr, zsave_warn, opts->pzProgName);
+ fprintf(stderr, zNotDef, pzDir);
+ return NULL;
+ }
+
+ if (pzEndDir == NULL)
+ return pzEnv;
+
+ {
+ size_t sz = strlen(pzEnv) + strlen(pzEndDir) + 2;
+ pzFileName = (char *)AGALOC(sz, "dir name");
+ }
+
+ if (pzFileName == NULL)
+ return NULL;
+
+ *p_free = 1;
+ /*
+ * Glue together the full name into the allocated memory.
+ * FIXME: We lose track of this memory.
+ */
+ sprintf(pzFileName, "%s/%s", pzEnv, pzEndDir);
+ return pzFileName;
+ }
+}
+
+/**
+ */
+static char const *
+find_file_name(tOptions * opts, int * p_free_name)
+{
+ struct stat stBuf;
+ int free_dir_name = 0;
+
+ char const * pzDir = find_dir_name(opts, &free_dir_name);
+ if (pzDir == NULL)
+ return NULL;
+
+ /*
+ * See if we can find the specified directory. We use a once-only loop
+ * structure so we can bail out early.
+ */
+ if (stat(pzDir, &stBuf) != 0) do {
+ char z[AG_PATH_MAX];
+ char * dirchp;
+
+ /*
+ * IF we could not, check to see if we got a full
+ * path to a file name that has not been created yet.
+ */
+ if (errno != ENOENT) {
+ bogus_name:
+ fprintf(stderr, zsave_warn, opts->pzProgName);
+ fprintf(stderr, zNoStat, errno, strerror(errno), pzDir);
+ if (free_dir_name)
+ AGFREE(pzDir);
+ return NULL;
+ }
+
+ /*
+ * Strip off the last component, stat the remaining string and
+ * that string must name a directory
+ */
+ dirchp = strrchr(pzDir, DIRCH);
+ if (dirchp == NULL) {
+ stBuf.st_mode = S_IFREG;
+ break; /* found directory -- viz., "." */
+ }
+
+ if ((size_t)(dirchp - pzDir) >= sizeof(z))
+ goto bogus_name;
+
+ memcpy(z, pzDir, (size_t)(dirchp - pzDir));
+ z[dirchp - pzDir] = NUL;
+
+ if ((stat(z, &stBuf) != 0) || ! S_ISDIR(stBuf.st_mode))
+ goto bogus_name;
+ stBuf.st_mode = S_IFREG; /* file within this directory */
+ } while (false);
+
+ /*
+ * IF what we found was a directory,
+ * THEN tack on the config file name
+ */
+ if (S_ISDIR(stBuf.st_mode)) {
+ size_t sz = strlen(pzDir) + strlen(opts->pzRcName) + 2;
+
+ {
+ char * pzPath = (char *)AGALOC(sz, "file name");
+#ifdef HAVE_SNPRINTF
+ snprintf(pzPath, sz, "%s/%s", pzDir, opts->pzRcName);
+#else
+ sprintf(pzPath, "%s/%s", pzDir, opts->pzRcName);
+#endif
+ if (free_dir_name)
+ AGFREE(pzDir);
+ pzDir = pzPath;
+ free_dir_name = 1;
+ }
+
+ /*
+ * IF we cannot stat the object for any reason other than
+ * it does not exist, then we bail out
+ */
+ if (stat(pzDir, &stBuf) != 0) {
+ if (errno != ENOENT) {
+ fprintf(stderr, zsave_warn, opts->pzProgName);
+ fprintf(stderr, zNoStat, errno, strerror(errno),
+ pzDir);
+ AGFREE(pzDir);
+ return NULL;
+ }
+
+ /*
+ * It does not exist yet, but it will be a regular file
+ */
+ stBuf.st_mode = S_IFREG;
+ }
+ }
+
+ /*
+ * Make sure that whatever we ultimately found, that it either is
+ * or will soon be a file.
+ */
+ if (! S_ISREG(stBuf.st_mode)) {
+ fprintf(stderr, zsave_warn, opts->pzProgName, pzDir);
+ if (free_dir_name)
+ AGFREE(pzDir);
+ return NULL;
+ }
+
+ /*
+ * Get rid of the old file
+ */
+ unlink(pzDir);
+ *p_free_name = free_dir_name;
+ return pzDir;
+}
+
+/**
+ * print one option entry to the save file.
+ *
+ * @param[in] fp the file pointer for the save file
+ * @param[in] od the option descriptor to print
+ * @param[in] l_arg the last argument for the option
+ */
+static void
+prt_entry(FILE * fp, tOptDesc * od, char const * l_arg)
+{
+ int space_ct;
+
+ /*
+ * There is an argument. Pad the name so values line up.
+ * Not disabled *OR* this got equivalenced to another opt,
+ * then use current option name.
+ * Otherwise, there must be a disablement name.
+ */
+ {
+ char const * pz =
+ (! DISABLED_OPT(od) || (od->optEquivIndex != NO_EQUIVALENT))
+ ? od->pz_Name
+ : od->pz_DisableName;
+ space_ct = 17 - strlen(pz);
+ fputs(pz, fp);
+ }
+
+ if ( (l_arg == NULL)
+ && (OPTST_GET_ARGTYPE(od->fOptState) != OPARG_TYPE_NUMERIC))
+ goto end_entry;
+
+ fputs(" = ", fp);
+ while (space_ct-- > 0) fputc(' ', fp);
+
+ /*
+ * IF the option is numeric only,
+ * THEN the char pointer is really the number
+ */
+ if (OPTST_GET_ARGTYPE(od->fOptState) == OPARG_TYPE_NUMERIC)
+ fprintf(fp, "%d", (int)(intptr_t)l_arg);
+
+ else {
+ for (;;) {
+ char const * eol = strchr(l_arg, NL);
+
+ /*
+ * IF this is the last line
+ * THEN bail and print it
+ */
+ if (eol == NULL)
+ break;
+
+ /*
+ * Print the continuation and the text from the current line
+ */
+ (void)fwrite(l_arg, (size_t)(eol - l_arg), (size_t)1, fp);
+ l_arg = eol+1; /* advance the Last Arg pointer */
+ fputs("\\\n", fp);
+ }
+
+ /*
+ * Terminate the entry
+ */
+ fputs(l_arg, fp);
+ }
+
+end_entry:
+ fputc(NL, fp);
+}
+
+/**
+ */
+static void
+prt_value(FILE * fp, int depth, tOptDesc * pOD, tOptionValue const * ovp)
+{
+ while (--depth >= 0)
+ putc(' ', fp), putc(' ', fp);
+
+ switch (ovp->valType) {
+ default:
+ case OPARG_TYPE_NONE:
+ fprintf(fp, NULL_ATR_FMT, ovp->pzName);
+ break;
+
+ case OPARG_TYPE_STRING:
+ prt_string(fp, ovp->pzName, ovp->v.strVal);
+ break;
+
+ case OPARG_TYPE_ENUMERATION:
+ case OPARG_TYPE_MEMBERSHIP:
+ if (pOD != NULL) {
+ uint32_t opt_state = pOD->fOptState;
+ uintptr_t val = pOD->optArg.argEnum;
+ char const * typ = (ovp->valType == OPARG_TYPE_ENUMERATION)
+ ? "keyword" : "set-membership";
+
+ fprintf(fp, TYPE_ATR_FMT, ovp->pzName, typ);
+
+ /*
+ * This is a magic incantation that will convert the
+ * bit flag values back into a string suitable for printing.
+ */
+ (*(pOD->pOptProc))(OPTPROC_RETURN_VALNAME, pOD );
+ if (pOD->optArg.argString != NULL) {
+ fputs(pOD->optArg.argString, fp);
+
+ if (ovp->valType != OPARG_TYPE_ENUMERATION) {
+ /*
+ * set membership strings get allocated
+ */
+ AGFREE(pOD->optArg.argString);
+ }
+ }
+
+ pOD->optArg.argEnum = val;
+ pOD->fOptState = opt_state;
+ fprintf(fp, END_XML_FMT, ovp->pzName);
+ break;
+ }
+ /* FALLTHROUGH */
+
+ case OPARG_TYPE_NUMERIC:
+ fprintf(fp, NUMB_ATR_FMT, ovp->pzName, ovp->v.longVal);
+ break;
+
+ case OPARG_TYPE_BOOLEAN:
+ fprintf(fp, BOOL_ATR_FMT, ovp->pzName,
+ ovp->v.boolVal ? "true" : "false");
+ break;
+
+ case OPARG_TYPE_HIERARCHY:
+ prt_val_list(fp, ovp->pzName, ovp->v.nestVal);
+ break;
+ }
+}
+
+/**
+ */
+static void
+prt_string(FILE * fp, char const * name, char const * pz)
+{
+ fprintf(fp, OPEN_XML_FMT, name);
+ for (;;) {
+ int ch = ((int)*(pz++)) & 0xFF;
+
+ switch (ch) {
+ case NUL: goto string_done;
+
+ case '&':
+ case '<':
+ case '>':
+#if __GNUC__ >= 4
+ case 1 ... (' ' - 1):
+ case ('~' + 1) ... 0xFF:
+#endif
+ emit_special_char(fp, ch);
+ break;
+
+ default:
+#if __GNUC__ < 4
+ if ( ((ch >= 1) && (ch <= (' ' - 1)))
+ || ((ch >= ('~' + 1)) && (ch <= 0xFF)) ) {
+ emit_special_char(fp, ch);
+ break;
+ }
+#endif
+ putc(ch, fp);
+ }
+ } string_done:;
+ fprintf(fp, END_XML_FMT, name);
+}
+
+/**
+ */
+static void
+prt_val_list(FILE * fp, char const * name, tArgList * al)
+{
+ static int depth = 1;
+
+ int sp_ct;
+ int opt_ct;
+ void ** opt_list;
+
+ if (al == NULL)
+ return;
+ opt_ct = al->useCt;
+ opt_list = VOIDP(al->apzArgs);
+
+ if (opt_ct <= 0) {
+ fprintf(fp, OPEN_CLOSE_FMT, name);
+ return;
+ }
+
+ fprintf(fp, NESTED_OPT_FMT, name);
+
+ depth++;
+ while (--opt_ct >= 0) {
+ tOptionValue const * ovp = *(opt_list++);
+
+ prt_value(fp, depth, NULL, ovp);
+ }
+ depth--;
+
+ for (sp_ct = depth; --sp_ct >= 0;)
+ putc(' ', fp), putc(' ', fp);
+ fprintf(fp, "</%s>\n", name);
+}
+
+/**
+ */
+static void
+prt_nested(FILE * fp, tOptDesc * p)
+{
+ int opt_ct;
+ tArgList * al = p->optCookie;
+ void ** opt_list;
+
+ if (al == NULL)
+ return;
+
+ opt_ct = al->useCt;
+ opt_list = VOIDP(al->apzArgs);
+
+ if (opt_ct <= 0)
+ return;
+
+ do {
+ tOptionValue const * base = *(opt_list++);
+ tOptionValue const * ovp = optionGetValue(base, NULL);
+
+ if (ovp == NULL)
+ continue;
+
+ fprintf(fp, NESTED_OPT_FMT, p->pz_Name);
+
+ do {
+ prt_value(fp, 1, p, ovp);
+
+ } while (ovp = optionNextValue(base, ovp),
+ ovp != NULL);
+
+ fprintf(fp, "</%s>\n", p->pz_Name);
+ } while (--opt_ct > 0);
+}
+
+/**
+ * open the file for saving option state.
+ *
+ * @param[in] opts the program options structure
+ * @returns the open file pointer. It may be NULL.
+ */
+static FILE *
+open_sv_file(tOptions * opts)
+{
+ FILE * fp;
+
+ {
+ int free_name = 0;
+ char const * pzFName = find_file_name(opts, &free_name);
+ if (pzFName == NULL)
+ return NULL;
+
+ fp = fopen(pzFName, "w" FOPEN_BINARY_FLAG);
+ if (fp == NULL) {
+ fprintf(stderr, zsave_warn, opts->pzProgName);
+ fprintf(stderr, zNoCreat, errno, strerror(errno), pzFName);
+ if (free_name)
+ AGFREE(pzFName);
+ return fp;
+ }
+
+ if (free_name)
+ AGFREE(pzFName);
+ }
+
+ fputs("# ", fp);
+ {
+ char const * e = strchr(opts->pzUsageTitle, NL);
+ if (e++ != NULL)
+ fwrite(opts->pzUsageTitle, 1, e - opts->pzUsageTitle, fp);
+ }
+
+ {
+ time_t cur_time = time(NULL);
+ char * time_str = ctime(&cur_time);
+
+ fprintf(fp, zPresetFile, time_str);
+#ifdef HAVE_ALLOCATED_CTIME
+ /*
+ * The return values for ctime(), localtime(), and gmtime()
+ * normally point to static data that is overwritten by each call.
+ * The test to detect allocated ctime, so we leak the memory.
+ */
+ AGFREE(time_str);
+#endif
+ }
+
+ return fp;
+}
+
+/**
+ */
+static void
+prt_no_arg_opt(FILE * fp, tOptDesc * p, tOptDesc * pOD)
+{
+ /*
+ * The aliased to argument indicates whether or not the option
+ * is "disabled". However, the original option has the name
+ * string, so we get that there, not with "p".
+ */
+ char const * pznm =
+ (DISABLED_OPT(p)) ? pOD->pz_DisableName : pOD->pz_Name;
+ /*
+ * If the option was disabled and the disablement name is NULL,
+ * then the disablement was caused by aliasing.
+ * Use the name as the string to emit.
+ */
+ if (pznm == NULL)
+ pznm = pOD->pz_Name;
+
+ fprintf(fp, "%s\n", pznm);
+}
+
+/**
+ */
+static void
+prt_str_arg(FILE * fp, tOptDesc * pOD)
+{
+ if (pOD->fOptState & OPTST_STACKED) {
+ tArgList * pAL = (tArgList *)pOD->optCookie;
+ int uct = pAL->useCt;
+ char const ** ppz = pAL->apzArgs;
+
+ /*
+ * un-disable multiple copies of disabled options.
+ */
+ if (uct > 1)
+ pOD->fOptState &= ~OPTST_DISABLED;
+
+ while (uct-- > 0)
+ prt_entry(fp, pOD, *(ppz++));
+ } else {
+ prt_entry(fp, pOD, pOD->optArg.argString);
+ }
+}
+
+/**
+ * print the string value of an enumeration.
+ *
+ * @param[in] fp the file pointer to write to
+ * @param[in] od the option descriptor with the enumerated value
+ */
+static void
+prt_enum_arg(FILE * fp, tOptDesc * od)
+{
+ uintptr_t val = od->optArg.argEnum;
+
+ /*
+ * This is a magic incantation that will convert the
+ * bit flag values back into a string suitable for printing.
+ */
+ (*(od->pOptProc))(OPTPROC_RETURN_VALNAME, od);
+ prt_entry(fp, od, VOIDP(od->optArg.argString));
+
+ od->optArg.argEnum = val;
+}
+
+/**
+ * Print the bits set in a bit mask option.
+ * We call the option handling function with a magic value for
+ * the options pointer and it allocates and fills in the string.
+ * We print that with a call to prt_entry().
+ *
+ * @param[in] fp the file pointer to write to
+ * @param[in] od the option descriptor with a bit mask value type
+ */
+static void
+prt_set_arg(FILE * fp, tOptDesc * od)
+{
+ char * list = optionMemberList(od);
+ size_t len = strlen(list);
+ char * buf = (char *)AGALOC(len + 3, "dir name");
+ *buf= '=';
+ memcpy(buf+1, list, len + 1);
+ prt_entry(fp, od, buf);
+ AGFREE(buf);
+ AGFREE(list);
+}
+
+/**
+ * figure out what the option file name argument is.
+ * If one can be found, call prt_entry() to emit it.
+ *
+ * @param[in] fp the file pointer to write to.
+ * @param[in] od the option descriptor with a bit mask value type
+ * @param[in] opts the program options descriptor
+ */
+static void
+prt_file_arg(FILE * fp, tOptDesc * od, tOptions * opts)
+{
+ /*
+ * If the cookie is not NULL, then it has the file name, period.
+ * Otherwise, if we have a non-NULL string argument, then....
+ */
+ if (od->optCookie != NULL)
+ prt_entry(fp, od, od->optCookie);
+
+ else if (HAS_originalOptArgArray(opts)) {
+ char const * orig =
+ opts->originalOptArgArray[od->optIndex].argString;
+
+ if (od->optArg.argString == orig)
+ return;
+
+ prt_entry(fp, od, od->optArg.argString);
+ }
+}
+
+/*=export_func optionSaveFile
+ *
+ * what: saves the option state to a file
+ *
+ * arg: tOptions *, opts, program options descriptor
+ *
+ * doc:
+ *
+ * This routine will save the state of option processing to a file. The name
+ * of that file can be specified with the argument to the @code{--save-opts}
+ * option, or by appending the @code{rcfile} attribute to the last
+ * @code{homerc} attribute. If no @code{rcfile} attribute was specified, it
+ * will default to @code{.@i{programname}rc}. If you wish to specify another
+ * file, you should invoke the @code{SET_OPT_SAVE_OPTS(@i{filename})} macro.
+ *
+ * The recommend usage is as follows:
+ * @example
+ * optionProcess(&progOptions, argc, argv);
+ * if (i_want_a_non_standard_place_for_this)
+ * SET_OPT_SAVE_OPTS("myfilename");
+ * optionSaveFile(&progOptions);
+ * @end example
+ *
+ * err:
+ *
+ * If no @code{homerc} file was specified, this routine will silently return
+ * and do nothing. If the output file cannot be created or updated, a message
+ * will be printed to @code{stderr} and the routine will return.
+=*/
+void
+optionSaveFile(tOptions * opts)
+{
+ tOptDesc * od;
+ int ct;
+ FILE * fp = open_sv_file(opts);
+
+ if (fp == NULL)
+ return;
+
+ /*
+ * FOR each of the defined options, ...
+ */
+ ct = opts->presetOptCt;
+ od = opts->pOptDesc;
+ do {
+ tOptDesc * p;
+
+ /*
+ * IF the option has not been defined
+ * OR it does not take an initialization value
+ * OR it is equivalenced to another option
+ * THEN continue (ignore it)
+ *
+ * Equivalenced options get picked up when the equivalenced-to
+ * option is processed.
+ */
+ if (UNUSED_OPT(od))
+ continue;
+
+ if ((od->fOptState & OPTST_DO_NOT_SAVE_MASK) != 0)
+ continue;
+
+ if ( (od->optEquivIndex != NO_EQUIVALENT)
+ && (od->optEquivIndex != od->optIndex))
+ continue;
+
+ /*
+ * The option argument data are found at the equivalenced-to option,
+ * but the actual option argument type comes from the original
+ * option descriptor. Be careful!
+ */
+ p = ((od->fOptState & OPTST_EQUIVALENCE) != 0)
+ ? (opts->pOptDesc + od->optActualIndex) : od;
+
+ switch (OPTST_GET_ARGTYPE(od->fOptState)) {
+ case OPARG_TYPE_NONE:
+ prt_no_arg_opt(fp, p, od);
+ break;
+
+ case OPARG_TYPE_NUMERIC:
+ prt_entry(fp, p, VOIDP(p->optArg.argInt));
+ break;
+
+ case OPARG_TYPE_STRING:
+ prt_str_arg(fp, p);
+ break;
+
+ case OPARG_TYPE_ENUMERATION:
+ prt_enum_arg(fp, p);
+ break;
+
+ case OPARG_TYPE_MEMBERSHIP:
+ prt_set_arg(fp, p);
+ break;
+
+ case OPARG_TYPE_BOOLEAN:
+ prt_entry(fp, p, p->optArg.argBool ? "true" : "false");
+ break;
+
+ case OPARG_TYPE_HIERARCHY:
+ prt_nested(fp, p);
+ break;
+
+ case OPARG_TYPE_FILE:
+ prt_file_arg(fp, p, opts);
+ break;
+
+ default:
+ break; /* cannot handle - skip it */
+ }
+ } while (od++, (--ct > 0));
+
+ fclose(fp);
+}
+/** @}
+ *
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of autoopts/save.c */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/sort.c b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/sort.c
new file mode 100644
index 0000000..da00334
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/sort.c
@@ -0,0 +1,340 @@
+
+/*
+ * \file sort.c
+ *
+ * This module implements argument sorting.
+ *
+ * @addtogroup autoopts
+ * @{
+ */
+/*
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
+ *
+ * AutoOpts is available under any one of two licenses. The license
+ * in use must be one of these two and the choice is under the control
+ * of the user of the license.
+ *
+ * The GNU Lesser General Public License, version 3 or later
+ * See the files "COPYING.lgplv3" and "COPYING.gplv3"
+ *
+ * The Modified Berkeley Software Distribution License
+ * See the file "COPYING.mbsd"
+ *
+ * These files have the following sha256 sums:
+ *
+ * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
+ * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
+ * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
+ */
+
+/* = = = START-STATIC-FORWARD = = = */
+static tSuccess
+must_arg(tOptions * opts, char * arg_txt, tOptState * pOS,
+ char ** opt_txt, uint32_t * opt_idx);
+
+static tSuccess
+maybe_arg(tOptions * opts, char * arg_txt, tOptState * pOS,
+ char ** opt_txt, uint32_t * opt_idx);
+
+static tSuccess
+short_opt_ck(tOptions * opts, char * arg_txt, tOptState * pOS,
+ char ** opt_txt, uint32_t * opt_idx);
+/* = = = END-STATIC-FORWARD = = = */
+
+/*
+ * "must_arg" and "maybe_arg" are really similar. The biggest
+ * difference is that "may" will consume the next argument only if it
+ * does not start with a hyphen and "must" will consume it, hyphen or not.
+ */
+static tSuccess
+must_arg(tOptions * opts, char * arg_txt, tOptState * pOS,
+ char ** opt_txt, uint32_t * opt_idx)
+{
+ /*
+ * An option argument is required. Long options can either have
+ * a separate command line argument, or an argument attached by
+ * the '=' character. Figure out which.
+ */
+ switch (pOS->optType) {
+ case TOPT_SHORT:
+ /*
+ * See if an arg string follows the flag character. If not,
+ * the next arg must be the option argument.
+ */
+ if (*arg_txt != NUL)
+ return SUCCESS;
+ break;
+
+ case TOPT_LONG:
+ /*
+ * See if an arg string has already been assigned (glued on
+ * with an `=' character). If not, the next is the opt arg.
+ */
+ if (pOS->pzOptArg != NULL)
+ return SUCCESS;
+ break;
+
+ default:
+ return FAILURE;
+ }
+ if (opts->curOptIdx >= opts->origArgCt)
+ return FAILURE;
+
+ opt_txt[ (*opt_idx)++ ] = opts->origArgVect[ (opts->curOptIdx)++ ];
+ return SUCCESS;
+}
+
+static tSuccess
+maybe_arg(tOptions * opts, char * arg_txt, tOptState * pOS,
+ char ** opt_txt, uint32_t * opt_idx)
+{
+ /*
+ * An option argument is optional.
+ */
+ switch (pOS->optType) {
+ case TOPT_SHORT:
+ /*
+ * IF nothing is glued on after the current flag character,
+ * THEN see if there is another argument. If so and if it
+ * does *NOT* start with a hyphen, then it is the option arg.
+ */
+ if (*arg_txt != NUL)
+ return SUCCESS;
+ break;
+
+ case TOPT_LONG:
+ /*
+ * Look for an argument if we don't already have one (glued on
+ * with a `=' character)
+ */
+ if (pOS->pzOptArg != NULL)
+ return SUCCESS;
+ break;
+
+ default:
+ return FAILURE;
+ }
+ if (opts->curOptIdx >= opts->origArgCt)
+ return PROBLEM;
+
+ arg_txt = opts->origArgVect[ opts->curOptIdx ];
+ if (*arg_txt != '-')
+ opt_txt[ (*opt_idx)++ ] = opts->origArgVect[ (opts->curOptIdx)++ ];
+ return SUCCESS;
+}
+
+/*
+ * Process a string of short options glued together. If the last one
+ * does or may take an argument, the do the argument processing and leave.
+ */
+static tSuccess
+short_opt_ck(tOptions * opts, char * arg_txt, tOptState * pOS,
+ char ** opt_txt, uint32_t * opt_idx)
+{
+ while (*arg_txt != NUL) {
+ if (FAILED(opt_find_short(opts, (uint8_t)*arg_txt, pOS)))
+ return FAILURE;
+
+ /*
+ * See if we can have an arg.
+ */
+ if (OPTST_GET_ARGTYPE(pOS->pOD->fOptState) == OPARG_TYPE_NONE) {
+ arg_txt++;
+
+ } else if (pOS->pOD->fOptState & OPTST_ARG_OPTIONAL) {
+ /*
+ * Take an argument if it is not attached and it does not
+ * start with a hyphen.
+ */
+ if (arg_txt[1] != NUL)
+ return SUCCESS;
+
+ arg_txt = opts->origArgVect[ opts->curOptIdx ];
+ if (*arg_txt != '-')
+ opt_txt[ (*opt_idx)++ ] =
+ opts->origArgVect[ (opts->curOptIdx)++ ];
+ return SUCCESS;
+
+ } else {
+ /*
+ * IF we need another argument, be sure it is there and
+ * take it.
+ */
+ if (arg_txt[1] == NUL) {
+ if (opts->curOptIdx >= opts->origArgCt)
+ return FAILURE;
+ opt_txt[ (*opt_idx)++ ] =
+ opts->origArgVect[ (opts->curOptIdx)++ ];
+ }
+ return SUCCESS;
+ }
+ }
+ return SUCCESS;
+}
+
+/*
+ * If the program wants sorted options (separated operands and options),
+ * then this routine will to the trick.
+ */
+LOCAL void
+optionSort(tOptions * opts)
+{
+ char ** opt_txt;
+ char ** ppzOpds;
+ uint32_t optsIdx = 0;
+ uint32_t opdsIdx = 0;
+
+ tOptState os = OPTSTATE_INITIALIZER(DEFINED);
+
+ /*
+ * Disable for POSIX conformance, or if there are no operands.
+ */
+ if ( (getenv("POSIXLY_CORRECT") != NULL)
+ || NAMED_OPTS(opts))
+ return;
+
+ /*
+ * Make sure we can allocate two full-sized arg vectors.
+ */
+ opt_txt = malloc(opts->origArgCt * sizeof(char *));
+ if (opt_txt == NULL)
+ goto exit_no_mem;
+
+ ppzOpds = malloc(opts->origArgCt * sizeof(char *));
+ if (ppzOpds == NULL) {
+ free(opt_txt);
+ goto exit_no_mem;
+ }
+
+ opts->curOptIdx = 1;
+ opts->pzCurOpt = NULL;
+
+ /*
+ * Now, process all the options from our current position onward.
+ * (This allows interspersed options and arguments for the few
+ * non-standard programs that require it.)
+ */
+ for (;;) {
+ char * arg_txt;
+ tSuccess res;
+
+ /*
+ * If we're out of arguments, we're done. Join the option and
+ * operand lists into the original argument vector.
+ */
+ if (opts->curOptIdx >= opts->origArgCt) {
+ errno = 0;
+ goto joinLists;
+ }
+
+ arg_txt = opts->origArgVect[ opts->curOptIdx ];
+ if (*arg_txt != '-') {
+ ppzOpds[ opdsIdx++ ] = opts->origArgVect[ (opts->curOptIdx)++ ];
+ continue;
+ }
+
+ switch (arg_txt[1]) {
+ case NUL:
+ /*
+ * A single hyphen is an operand.
+ */
+ ppzOpds[ opdsIdx++ ] = opts->origArgVect[ (opts->curOptIdx)++ ];
+ continue;
+
+ case '-':
+ /*
+ * Two consecutive hypens. Put them on the options list and then
+ * _always_ force the remainder of the arguments to be operands.
+ */
+ if (arg_txt[2] == NUL) {
+ opt_txt[ optsIdx++ ] =
+ opts->origArgVect[ (opts->curOptIdx)++ ];
+ goto restOperands;
+ }
+ res = opt_find_long(opts, arg_txt+2, &os);
+ break;
+
+ default:
+ /*
+ * If short options are not allowed, then do long
+ * option processing. Otherwise the character must be a
+ * short (i.e. single character) option.
+ */
+ if ((opts->fOptSet & OPTPROC_SHORTOPT) == 0) {
+ res = opt_find_long(opts, arg_txt+1, &os);
+ } else {
+ res = opt_find_short(opts, (uint8_t)arg_txt[1], &os);
+ }
+ break;
+ }
+ if (FAILED(res)) {
+ errno = EINVAL;
+ goto freeTemps;
+ }
+
+ /*
+ * We've found an option. Add the argument to the option list.
+ * Next, we have to see if we need to pull another argument to be
+ * used as the option argument.
+ */
+ opt_txt[ optsIdx++ ] = opts->origArgVect[ (opts->curOptIdx)++ ];
+
+ if (OPTST_GET_ARGTYPE(os.pOD->fOptState) == OPARG_TYPE_NONE) {
+ /*
+ * No option argument. If we have a short option here,
+ * then scan for short options until we get to the end
+ * of the argument string.
+ */
+ if ( (os.optType == TOPT_SHORT)
+ && FAILED(short_opt_ck(opts, arg_txt+2, &os, opt_txt,
+ &optsIdx)) ) {
+ errno = EINVAL;
+ goto freeTemps;
+ }
+
+ } else if (os.pOD->fOptState & OPTST_ARG_OPTIONAL) {
+ switch (maybe_arg(opts, arg_txt+2, &os, opt_txt, &optsIdx)) {
+ case FAILURE: errno = EIO; goto freeTemps;
+ case PROBLEM: errno = 0; goto joinLists;
+ }
+
+ } else {
+ switch (must_arg(opts, arg_txt+2, &os, opt_txt, &optsIdx)) {
+ case PROBLEM:
+ case FAILURE: errno = EIO; goto freeTemps;
+ }
+ }
+ } /* for (;;) */
+
+ restOperands:
+ while (opts->curOptIdx < opts->origArgCt)
+ ppzOpds[ opdsIdx++ ] = opts->origArgVect[ (opts->curOptIdx)++ ];
+
+ joinLists:
+ if (optsIdx > 0)
+ memcpy(opts->origArgVect + 1, opt_txt,
+ (size_t)optsIdx * sizeof(char *));
+ if (opdsIdx > 0)
+ memcpy(opts->origArgVect + 1 + optsIdx, ppzOpds,
+ (size_t)opdsIdx * sizeof(char *));
+
+ freeTemps:
+ free(opt_txt);
+ free(ppzOpds);
+ return;
+
+ exit_no_mem:
+ errno = ENOMEM;
+ return;
+}
+
+/** @}
+ *
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of autoopts/sort.c */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/stack.c b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/stack.c
new file mode 100644
index 0000000..affe6b6
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/stack.c
@@ -0,0 +1,267 @@
+
+/**
+ * \file stack.c
+ *
+ * This is a special option processing routine that will save the
+ * argument to an option in a FIFO queue.
+ *
+ * @addtogroup autoopts
+ * @{
+ */
+/*
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
+ *
+ * AutoOpts is available under any one of two licenses. The license
+ * in use must be one of these two and the choice is under the control
+ * of the user of the license.
+ *
+ * The GNU Lesser General Public License, version 3 or later
+ * See the files "COPYING.lgplv3" and "COPYING.gplv3"
+ *
+ * The Modified Berkeley Software Distribution License
+ * See the file "COPYING.mbsd"
+ *
+ * These files have the following sha256 sums:
+ *
+ * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
+ * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
+ * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
+ */
+
+#ifdef WITH_LIBREGEX
+# include REGEX_HEADER
+#endif
+
+/*=export_func optionUnstackArg
+ * private:
+ *
+ * what: Remove option args from a stack
+ * arg: + tOptions * + opts + program options descriptor +
+ * arg: + tOptDesc * + od + the descriptor for this arg +
+ *
+ * doc:
+ * Invoked for options that are equivalenced to stacked options.
+=*/
+void
+optionUnstackArg(tOptions * opts, tOptDesc * od)
+{
+ tArgList * arg_list;
+
+ if (INQUERY_CALL(opts, od))
+ return;
+
+ arg_list = (tArgList *)od->optCookie;
+
+ /*
+ * IF we don't have any stacked options,
+ * THEN indicate that we don't have any of these options
+ */
+ if (arg_list == NULL) {
+ od->fOptState &= OPTST_PERSISTENT_MASK;
+ if ((od->fOptState & OPTST_INITENABLED) == 0)
+ od->fOptState |= OPTST_DISABLED;
+ return;
+ }
+
+#ifdef WITH_LIBREGEX
+ {
+ regex_t re;
+ int i, ct, dIdx;
+
+ if (regcomp(&re, od->optArg.argString, REG_NOSUB) != 0)
+ return;
+
+ /*
+ * search the list for the entry(s) to remove. Entries that
+ * are removed are *not* copied into the result. The source
+ * index is incremented every time. The destination only when
+ * we are keeping a define.
+ */
+ for (i = 0, dIdx = 0, ct = arg_list->useCt; --ct >= 0; i++) {
+ char const * pzSrc = arg_list->apzArgs[ i ];
+ char * pzEq = strchr(pzSrc, '=');
+ int res;
+
+
+ if (pzEq != NULL)
+ *pzEq = NUL;
+
+ res = regexec(&re, pzSrc, (size_t)0, NULL, 0);
+ switch (res) {
+ case 0:
+ /*
+ * Remove this entry by reducing the in-use count
+ * and *not* putting the string pointer back into
+ * the list.
+ */
+ AGFREE(pzSrc);
+ arg_list->useCt--;
+ break;
+
+ default:
+ case REG_NOMATCH:
+ if (pzEq != NULL)
+ *pzEq = '=';
+
+ /*
+ * IF we have dropped an entry
+ * THEN we have to move the current one.
+ */
+ if (dIdx != i)
+ arg_list->apzArgs[ dIdx ] = pzSrc;
+ dIdx++;
+ }
+ }
+
+ regfree(&re);
+ }
+#else /* not WITH_LIBREGEX */
+ {
+ int i, ct, dIdx;
+
+ /*
+ * search the list for the entry(s) to remove. Entries that
+ * are removed are *not* copied into the result. The source
+ * index is incremented every time. The destination only when
+ * we are keeping a define.
+ */
+ for (i = 0, dIdx = 0, ct = arg_list->useCt; --ct >= 0; i++) {
+ const char * pzSrc = arg_list->apzArgs[ i ];
+ char * pzEq = strchr(pzSrc, '=');
+
+ if (pzEq != NULL)
+ *pzEq = NUL;
+
+ if (strcmp(pzSrc, od->optArg.argString) == 0) {
+ /*
+ * Remove this entry by reducing the in-use count
+ * and *not* putting the string pointer back into
+ * the list.
+ */
+ AGFREE(pzSrc);
+ arg_list->useCt--;
+ } else {
+ if (pzEq != NULL)
+ *pzEq = '=';
+
+ /*
+ * IF we have dropped an entry
+ * THEN we have to move the current one.
+ */
+ if (dIdx != i)
+ arg_list->apzArgs[ dIdx ] = pzSrc;
+ dIdx++;
+ }
+ }
+ }
+#endif /* WITH_LIBREGEX */
+ /*
+ * IF we have unstacked everything,
+ * THEN indicate that we don't have any of these options
+ */
+ if (arg_list->useCt == 0) {
+ od->fOptState &= OPTST_PERSISTENT_MASK;
+ if ((od->fOptState & OPTST_INITENABLED) == 0)
+ od->fOptState |= OPTST_DISABLED;
+ AGFREE(arg_list);
+ od->optCookie = NULL;
+ }
+}
+
+
+/*
+ * Put an entry into an argument list. The first argument points to
+ * a pointer to the argument list structure. It gets passed around
+ * as an opaque address.
+ */
+LOCAL void
+addArgListEntry(void ** ppAL, void * entry)
+{
+ tArgList * pAL = *(void **)ppAL;
+
+ /*
+ * IF we have never allocated one of these,
+ * THEN allocate one now
+ */
+ if (pAL == NULL) {
+ pAL = (tArgList *)AGALOC(sizeof(*pAL), "new option arg stack");
+ if (pAL == NULL)
+ return;
+ pAL->useCt = 0;
+ pAL->allocCt = MIN_ARG_ALLOC_CT;
+ *ppAL = VOIDP(pAL);
+ }
+
+ /*
+ * ELSE if we are out of room
+ * THEN make it bigger
+ */
+ else if (pAL->useCt >= pAL->allocCt) {
+ size_t sz = sizeof(*pAL);
+ pAL->allocCt += INCR_ARG_ALLOC_CT;
+
+ /*
+ * The base structure contains space for MIN_ARG_ALLOC_CT
+ * pointers. We subtract it off to find our augment size.
+ */
+ sz += sizeof(char *) * ((size_t)pAL->allocCt - MIN_ARG_ALLOC_CT);
+ pAL = (tArgList *)AGREALOC(VOIDP(pAL), sz, "expanded opt arg stack");
+ if (pAL == NULL)
+ return;
+ *ppAL = VOIDP(pAL);
+ }
+
+ /*
+ * Insert the new argument into the list
+ */
+ pAL->apzArgs[ (pAL->useCt)++ ] = entry;
+}
+
+
+/*=export_func optionStackArg
+ * private:
+ *
+ * what: put option args on a stack
+ * arg: + tOptions * + opts + program options descriptor +
+ * arg: + tOptDesc * + od + the descriptor for this arg +
+ *
+ * doc:
+ * Keep an entry-ordered list of option arguments.
+=*/
+void
+optionStackArg(tOptions * opts, tOptDesc * od)
+{
+ char * pz;
+
+ if (INQUERY_CALL(opts, od))
+ return;
+
+ if ((od->fOptState & OPTST_RESET) != 0) {
+ tArgList * arg_list = od->optCookie;
+ int ix;
+ if (arg_list == NULL)
+ return;
+
+ ix = arg_list->useCt;
+ while (--ix >= 0)
+ AGFREE(arg_list->apzArgs[ix]);
+ AGFREE(arg_list);
+
+ } else {
+ if (od->optArg.argString == NULL)
+ return;
+
+ AGDUPSTR(pz, od->optArg.argString, "stack arg");
+ addArgListEntry(&(od->optCookie), VOIDP(pz));
+ }
+}
+/** @}
+ *
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of autoopts/stack.c */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/streqvcmp.c b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/streqvcmp.c
new file mode 100644
index 0000000..e87a232
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/streqvcmp.c
@@ -0,0 +1,284 @@
+
+/**
+ * \file streqvcmp.c
+ *
+ * String Equivalence Comparison
+ *
+ * These routines allow any character to be mapped to any other
+ * character before comparison. In processing long option names,
+ * the characters "-", "_" and "^" all need to be equivalent
+ * (because they are treated so by different development environments).
+ *
+ * @addtogroup autoopts
+ * @{
+ */
+/*
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
+ *
+ * AutoOpts is available under any one of two licenses. The license
+ * in use must be one of these two and the choice is under the control
+ * of the user of the license.
+ *
+ * The GNU Lesser General Public License, version 3 or later
+ * See the files "COPYING.lgplv3" and "COPYING.gplv3"
+ *
+ * The Modified Berkeley Software Distribution License
+ * See the file "COPYING.mbsd"
+ *
+ * These files have the following sha256 sums:
+ *
+ * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
+ * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
+ * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
+ *
+ * This array is designed for mapping upper and lower case letter
+ * together for a case independent comparison. The mappings are
+ * based upon ascii character sequences.
+ */
+static unsigned char charmap[] = {
+ NUL, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, '\a',
+ '\b', '\t', NL, '\v', '\f', '\r', 0x0E, 0x0F,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
+
+ ' ', '!', '"', '#', '$', '%', '&', '\'',
+ '(', ')', '*', '+', ',', '-', '.', '/',
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', ':', ';', '<', '=', '>', '?',
+
+ '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
+ 'x', 'y', 'z', '[', '\\', ']', '^', '_',
+ '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
+ 'x', 'y', 'z', '{', '|', '}', '~', 0x7f,
+
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+ 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
+ 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
+ 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
+ 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
+ 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
+
+ 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
+ 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
+ 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
+ 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
+ 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
+ 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
+ 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
+ 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
+};
+
+
+/*=export_func strneqvcmp
+ *
+ * what: compare two strings with an equivalence mapping
+ *
+ * arg: + char const * + str1 + first string +
+ * arg: + char const * + str2 + second string +
+ * arg: + int + ct + compare length +
+ *
+ * ret_type: int
+ * ret_desc: the difference between two differing characters
+ *
+ * doc:
+ *
+ * Using a character mapping, two strings are compared for "equivalence".
+ * Each input character is mapped to a comparison character and the
+ * mapped-to characters are compared for the two NUL terminated input strings.
+ * The comparison is limited to @code{ct} bytes.
+ * This function name is mapped to option_strneqvcmp so as to not conflict
+ * with the POSIX name space.
+ *
+ * err: none checked. Caller responsible for seg faults.
+=*/
+int
+strneqvcmp(char const * s1, char const * s2, int ct)
+{
+ for (; ct > 0; --ct) {
+ unsigned char u1 = (unsigned char) *s1++;
+ unsigned char u2 = (unsigned char) *s2++;
+ int dif;
+ if (u1 == u2) {
+ if (u1 == NUL)
+ return 0;
+ continue;
+ }
+
+ dif = charmap[ u1 ] - charmap[ u2 ];
+
+ if (dif != 0)
+ return dif;
+
+ if (u1 == NUL)
+ return 0;
+ }
+
+ return 0;
+}
+
+
+/*=export_func streqvcmp
+ *
+ * what: compare two strings with an equivalence mapping
+ *
+ * arg: + char const * + str1 + first string +
+ * arg: + char const * + str2 + second string +
+ *
+ * ret_type: int
+ * ret_desc: the difference between two differing characters
+ *
+ * doc:
+ *
+ * Using a character mapping, two strings are compared for "equivalence".
+ * Each input character is mapped to a comparison character and the
+ * mapped-to characters are compared for the two NUL terminated input strings.
+ * This function name is mapped to option_streqvcmp so as to not conflict
+ * with the POSIX name space.
+ *
+ * err: none checked. Caller responsible for seg faults.
+=*/
+int
+streqvcmp(char const * s1, char const * s2)
+{
+ for (;;) {
+ unsigned char u1 = (unsigned char) *s1++;
+ unsigned char u2 = (unsigned char) *s2++;
+ int dif;
+ if (u1 == u2) {
+ if (u1 == NUL)
+ return 0;
+ continue;
+ }
+
+ dif = charmap[ u1 ] - charmap[ u2 ];
+
+ if (dif != 0)
+ return dif;
+
+ if (u1 == NUL)
+ return 0;
+ }
+}
+
+
+/*=export_func streqvmap
+ *
+ * what: Set the character mappings for the streqv functions
+ *
+ * arg: + char + from + Input character +
+ * arg: + char + to + Mapped-to character +
+ * arg: + int + ct + compare length +
+ *
+ * doc:
+ *
+ * Set the character mapping. If the count (@code{ct}) is set to zero, then
+ * the map is cleared by setting all entries in the map to their index
+ * value. Otherwise, the "@code{From}" character is mapped to the "@code{To}"
+ * character. If @code{ct} is greater than 1, then @code{From} and @code{To}
+ * are incremented and the process repeated until @code{ct} entries have been
+ * set. For example,
+ * @example
+ * streqvmap('a', 'A', 26);
+ * @end example
+ * @noindent
+ * will alter the mapping so that all English lower case letters
+ * will map to upper case.
+ *
+ * This function name is mapped to option_streqvmap so as to not conflict
+ * with the POSIX name space.
+ *
+ * err: none.
+=*/
+void
+streqvmap(char from, char to, int ct)
+{
+ if (ct == 0) {
+ ct = sizeof(charmap) - 1;
+ do {
+ charmap[ct] = (unsigned char)ct;
+ } while (--ct >= 0);
+ }
+
+ else {
+ unsigned int i_to = (int)to & 0xFF;
+ unsigned int i_from = (int)from & 0xFF;
+
+ do {
+ charmap[i_from] = (unsigned char)i_to;
+ i_from++;
+ i_to++;
+ if ((i_from >= sizeof(charmap)) || (i_to >= sizeof(charmap)))
+ break;
+ } while (--ct > 0);
+ }
+}
+
+
+/*=export_func strequate
+ *
+ * what: map a list of characters to the same value
+ *
+ * arg: + char const * + ch_list + characters to equivalence +
+ *
+ * doc:
+ *
+ * Each character in the input string get mapped to the first character
+ * in the string.
+ * This function name is mapped to option_strequate so as to not conflict
+ * with the POSIX name space.
+ *
+ * err: none.
+=*/
+void
+strequate(char const * s)
+{
+ if ((s != NULL) && (*s != NUL)) {
+ unsigned char equiv = (unsigned char)*s;
+ while (*s != NUL)
+ charmap[(unsigned char)*(s++)] = equiv;
+ }
+}
+
+
+/*=export_func strtransform
+ *
+ * what: convert a string into its mapped-to value
+ *
+ * arg: + char * + dest + output string +
+ * arg: + char const * + src + input string +
+ *
+ * doc:
+ *
+ * Each character in the input string is mapped and the mapped-to
+ * character is put into the output.
+ * This function name is mapped to option_strtransform so as to not conflict
+ * with the POSIX name space.
+ *
+ * The source and destination may be the same.
+ *
+ * err: none.
+=*/
+void
+strtransform(char * d, char const * s)
+{
+ do {
+ *(d++) = (char)charmap[(unsigned char)*s];
+ } while (*(s++) != NUL);
+}
+
+/** @}
+ *
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of autoopts/streqvcmp.c */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/text_mmap.c b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/text_mmap.c
new file mode 100644
index 0000000..07c0bf1
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/text_mmap.c
@@ -0,0 +1,379 @@
+/**
+ * @file text_mmap.c
+ *
+ * Map a text file, ensuring the text always has an ending NUL byte.
+ *
+ * @addtogroup autoopts
+ * @{
+ */
+/*
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
+ *
+ * AutoOpts is available under any one of two licenses. The license
+ * in use must be one of these two and the choice is under the control
+ * of the user of the license.
+ *
+ * The GNU Lesser General Public License, version 3 or later
+ * See the files "COPYING.lgplv3" and "COPYING.gplv3"
+ *
+ * The Modified Berkeley Software Distribution License
+ * See the file "COPYING.mbsd"
+ *
+ * These files have the following sha256 sums:
+ *
+ * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
+ * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
+ * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
+ */
+#if defined(HAVE_MMAP)
+# ifndef MAP_ANONYMOUS
+# ifdef MAP_ANON
+# define MAP_ANONYMOUS MAP_ANON
+# endif
+# endif
+
+# if ! defined(MAP_ANONYMOUS) && ! defined(HAVE_DEV_ZERO)
+ /*
+ * We must have either /dev/zero or anonymous mapping for
+ * this to work.
+ */
+# undef HAVE_MMAP
+
+# else
+# ifdef _SC_PAGESIZE
+# define GETPAGESIZE() sysconf(_SC_PAGESIZE)
+# else
+# define GETPAGESIZE() getpagesize()
+# endif
+# endif
+#endif
+
+/*
+ * Some weird systems require that a specifically invalid FD number
+ * get passed in as an argument value. Which value is that? Well,
+ * as everybody knows, if open(2) fails, it returns -1, so that must
+ * be the value. :)
+ */
+#define AO_INVALID_FD -1
+
+#define FILE_WRITABLE(_prt,_flg) \
+ ( (_prt & PROT_WRITE) \
+ && ((_flg & (MAP_SHARED|MAP_PRIVATE)) == MAP_SHARED))
+#define MAP_FAILED_PTR (VOIDP(MAP_FAILED))
+
+/**
+ * Load the contents of a text file. There are two separate implementations,
+ * depending up on whether mmap(3) is available.
+ *
+ * If not available, malloc the file length plus one byte. Read it in
+ * and NUL terminate.
+ *
+ * If available, first check to see if the text file size is a multiple of a
+ * page size. If it is, map the file size plus an extra page from either
+ * anonymous memory or from /dev/zero. Then map the file text on top of the
+ * first pages of the anonymous/zero pages. Otherwise, just map the file
+ * because there will be NUL bytes provided at the end.
+ *
+ * @param mapinfo a structure holding everything we need to know
+ * about the mapping.
+ *
+ * @param pzFile name of the file, for error reporting.
+ */
+static void
+load_text_file(tmap_info_t * mapinfo, char const * pzFile)
+{
+#if ! defined(HAVE_MMAP)
+ mapinfo->txt_data = AGALOC(mapinfo->txt_size+1, "file text");
+ if (mapinfo->txt_data == NULL) {
+ mapinfo->txt_errno = ENOMEM;
+ return;
+ }
+
+ {
+ size_t sz = mapinfo->txt_size;
+ char * pz = mapinfo->txt_data;
+
+ while (sz > 0) {
+ ssize_t rdct = read(mapinfo->txt_fd, pz, sz);
+ if (rdct <= 0) {
+ mapinfo->txt_errno = errno;
+ fserr_warn("libopts", "read", pzFile);
+ free(mapinfo->txt_data);
+ return;
+ }
+
+ pz += rdct;
+ sz -= rdct;
+ }
+
+ *pz = NUL;
+ }
+
+ mapinfo->txt_errno = 0;
+
+#else /* HAVE mmap */
+ size_t const pgsz = (size_t)GETPAGESIZE();
+ void * map_addr = NULL;
+
+ (void)pzFile;
+
+ mapinfo->txt_full_size = (mapinfo->txt_size + pgsz) & ~(pgsz - 1);
+ if (mapinfo->txt_full_size == (mapinfo->txt_size + pgsz)) {
+ /*
+ * The text is a multiple of a page boundary. We must map an
+ * extra page so the text ends with a NUL.
+ */
+#if defined(MAP_ANONYMOUS)
+ map_addr = mmap(NULL, mapinfo->txt_full_size, PROT_READ|PROT_WRITE,
+ MAP_ANONYMOUS|MAP_PRIVATE, AO_INVALID_FD, 0);
+#else
+ mapinfo->txt_zero_fd = open("/dev/zero", O_RDONLY);
+
+ if (mapinfo->txt_zero_fd == AO_INVALID_FD) {
+ mapinfo->txt_errno = errno;
+ return;
+ }
+ map_addr = mmap(NULL, mapinfo->txt_full_size, PROT_READ|PROT_WRITE,
+ MAP_PRIVATE, mapinfo->txt_zero_fd, 0);
+#endif
+ if (map_addr == MAP_FAILED_PTR) {
+ mapinfo->txt_errno = errno;
+ return;
+ }
+ mapinfo->txt_flags |= MAP_FIXED;
+ }
+
+ mapinfo->txt_data =
+ mmap(map_addr, mapinfo->txt_size, mapinfo->txt_prot,
+ mapinfo->txt_flags, mapinfo->txt_fd, 0);
+
+ if (mapinfo->txt_data == MAP_FAILED_PTR)
+ mapinfo->txt_errno = errno;
+#endif /* HAVE_MMAP */
+}
+
+/**
+ * Make sure all the parameters are correct: we have a file name that
+ * is a text file that we can read.
+ *
+ * @param fname the text file to map
+ * @param prot the memory protections requested (read/write/etc.)
+ * @param flags mmap flags
+ * @param mapinfo a structure holding everything we need to know
+ * about the mapping.
+ */
+static void
+validate_mmap(char const * fname, int prot, int flags, tmap_info_t * mapinfo)
+{
+ memset(mapinfo, 0, sizeof(*mapinfo));
+#if defined(HAVE_MMAP) && ! defined(MAP_ANONYMOUS)
+ mapinfo->txt_zero_fd = AO_INVALID_FD;
+#endif
+ mapinfo->txt_fd = AO_INVALID_FD;
+ mapinfo->txt_prot = prot;
+ mapinfo->txt_flags = flags;
+
+ /*
+ * Map mmap flags and protections into open flags and do the open.
+ */
+ {
+ /*
+ * See if we will be updating the file. If we can alter the memory
+ * and if we share the data and we are *not* copy-on-writing the data,
+ * then our updates will show in the file, so we must open with
+ * write access.
+ */
+ int o_flag = FILE_WRITABLE(prot, flags) ? O_RDWR : O_RDONLY;
+
+ /*
+ * If you're not sharing the file and you are writing to it,
+ * then don't let anyone else have access to the file.
+ */
+ if (((flags & MAP_SHARED) == 0) && (prot & PROT_WRITE))
+ o_flag |= O_EXCL;
+
+ mapinfo->txt_fd = open(fname, o_flag);
+ if (mapinfo->txt_fd < 0) {
+ mapinfo->txt_errno = errno;
+ mapinfo->txt_fd = AO_INVALID_FD;
+ return;
+ }
+ }
+
+ /*
+ * Make sure we can stat the regular file. Save the file size.
+ */
+ {
+ struct stat sb;
+ if (fstat(mapinfo->txt_fd, &sb) != 0) {
+ mapinfo->txt_errno = errno;
+ close(mapinfo->txt_fd);
+ return;
+ }
+
+ if (! S_ISREG(sb.st_mode)) {
+ mapinfo->txt_errno = errno = EINVAL;
+ close(mapinfo->txt_fd);
+ return;
+ }
+
+ mapinfo->txt_size = (size_t)sb.st_size;
+ }
+
+ if (mapinfo->txt_fd == AO_INVALID_FD)
+ mapinfo->txt_errno = errno;
+}
+
+/**
+ * Close any files opened by the mapping.
+ *
+ * @param mi a structure holding everything we need to know about the map.
+ */
+static void
+close_mmap_files(tmap_info_t * mi)
+{
+ if (mi->txt_fd == AO_INVALID_FD)
+ return;
+
+ close(mi->txt_fd);
+ mi->txt_fd = AO_INVALID_FD;
+
+#if defined(HAVE_MMAP) && ! defined(MAP_ANONYMOUS)
+ if (mi->txt_zero_fd == AO_INVALID_FD)
+ return;
+
+ close(mi->txt_zero_fd);
+ mi->txt_zero_fd = AO_INVALID_FD;
+#endif
+}
+
+/*=export_func text_mmap
+ * private:
+ *
+ * what: map a text file with terminating NUL
+ *
+ * arg: char const *, pzFile, name of the file to map
+ * arg: int, prot, mmap protections (see mmap(2))
+ * arg: int, flags, mmap flags (see mmap(2))
+ * arg: tmap_info_t *, mapinfo, returned info about the mapping
+ *
+ * ret-type: void *
+ * ret-desc: The mmaped data address
+ *
+ * doc:
+ *
+ * This routine will mmap a file into memory ensuring that there is at least
+ * one @file{NUL} character following the file data. It will return the
+ * address where the file contents have been mapped into memory. If there is a
+ * problem, then it will return @code{MAP_FAILED} and set @code{errno}
+ * appropriately.
+ *
+ * The named file does not exist, @code{stat(2)} will set @code{errno} as it
+ * will. If the file is not a regular file, @code{errno} will be
+ * @code{EINVAL}. At that point, @code{open(2)} is attempted with the access
+ * bits set appropriately for the requested @code{mmap(2)} protections and flag
+ * bits. On failure, @code{errno} will be set according to the documentation
+ * for @code{open(2)}. If @code{mmap(2)} fails, @code{errno} will be set as
+ * that routine sets it. If @code{text_mmap} works to this point, a valid
+ * address will be returned, but there may still be ``issues''.
+ *
+ * If the file size is not an even multiple of the system page size, then
+ * @code{text_map} will return at this point and @code{errno} will be zero.
+ * Otherwise, an anonymous map is attempted. If not available, then an attempt
+ * is made to @code{mmap(2)} @file{/dev/zero}. If any of these fail, the
+ * address of the file's data is returned, bug @code{no} @file{NUL} characters
+ * are mapped after the end of the data.
+ *
+ * see: mmap(2), open(2), stat(2)
+ *
+ * err: Any error code issued by mmap(2), open(2), stat(2) is possible.
+ * Additionally, if the specified file is not a regular file, then
+ * errno will be set to @code{EINVAL}.
+ *
+ * example:
+ * #include <mylib.h>
+ * tmap_info_t mi;
+ * int no_nul;
+ * void * data = text_mmap("file", PROT_WRITE, MAP_PRIVATE, &mi);
+ * if (data == MAP_FAILED) return;
+ * no_nul = (mi.txt_size == mi.txt_full_size);
+ * << use the data >>
+ * text_munmap(&mi);
+=*/
+void *
+text_mmap(char const * pzFile, int prot, int flags, tmap_info_t * mi)
+{
+ validate_mmap(pzFile, prot, flags, mi);
+ if (mi->txt_errno != 0)
+ return MAP_FAILED_PTR;
+
+ load_text_file(mi, pzFile);
+
+ if (mi->txt_errno == 0)
+ return mi->txt_data;
+
+ close_mmap_files(mi);
+
+ errno = mi->txt_errno;
+ mi->txt_data = MAP_FAILED_PTR;
+ return mi->txt_data;
+}
+
+
+/*=export_func text_munmap
+ * private:
+ *
+ * what: unmap the data mapped in by text_mmap
+ *
+ * arg: tmap_info_t *, mapinfo, info about the mapping
+ *
+ * ret-type: int
+ * ret-desc: -1 or 0. @code{errno} will have the error code.
+ *
+ * doc:
+ *
+ * This routine will unmap the data mapped in with @code{text_mmap} and close
+ * the associated file descriptors opened by that function.
+ *
+ * see: munmap(2), close(2)
+ *
+ * err: Any error code issued by munmap(2) or close(2) is possible.
+=*/
+int
+text_munmap(tmap_info_t * mi)
+{
+ errno = 0;
+
+#ifdef HAVE_MMAP
+ (void)munmap(mi->txt_data, mi->txt_full_size);
+
+#else /* don't HAVE_MMAP */
+ /*
+ * IF the memory is writable *AND* it is not private (copy-on-write)
+ * *AND* the memory is "sharable" (seen by other processes)
+ * THEN rewrite the data. Emulate mmap visibility.
+ */
+ if ( FILE_WRITABLE(mi->txt_prot, mi->txt_flags)
+ && (lseek(mi->txt_fd, 0, SEEK_SET) >= 0) ) {
+ write(mi->txt_fd, mi->txt_data, mi->txt_size);
+ }
+
+ free(mi->txt_data);
+#endif /* HAVE_MMAP */
+
+ mi->txt_errno = errno;
+ close_mmap_files(mi);
+
+ return mi->txt_errno;
+}
+
+/** @}
+ *
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of autoopts/text_mmap.c */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/time.c b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/time.c
new file mode 100644
index 0000000..62e0754
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/time.c
@@ -0,0 +1,143 @@
+
+/**
+ * \file time.c
+ *
+ * @addtogroup autoopts
+ * @{
+ */
+/*
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
+ *
+ * AutoOpts is available under any one of two licenses. The license
+ * in use must be one of these two and the choice is under the control
+ * of the user of the license.
+ *
+ * The GNU Lesser General Public License, version 3 or later
+ * See the files "COPYING.lgplv3" and "COPYING.gplv3"
+ *
+ * The Modified Berkeley Software Distribution License
+ * See the file "COPYING.mbsd"
+ *
+ * These files have the following sha256 sums:
+ *
+ * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
+ * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
+ * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
+ */
+
+/*=export_func optionTimeVal
+ * private:
+ *
+ * what: process an option with a time duration.
+ * arg: + tOptions * + opts + program options descriptor +
+ * arg: + tOptDesc * + od + the descriptor for this arg +
+ *
+ * doc:
+ * Decipher a time duration value.
+=*/
+void
+optionTimeVal(tOptions * opts, tOptDesc * od)
+{
+ time_t val;
+
+ if (INQUERY_CALL(opts, od))
+ return;
+
+ val = parse_duration(od->optArg.argString);
+ if (val == BAD_TIME) {
+ fprintf(stderr, zNotDuration, opts->pzProgName, od->optArg.argString);
+ if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0)
+ (*(opts->pUsageProc))(opts, EXIT_FAILURE);
+ }
+
+ if (od->fOptState & OPTST_ALLOC_ARG) {
+ AGFREE(od->optArg.argString);
+ od->fOptState &= ~OPTST_ALLOC_ARG;
+ }
+
+ od->optArg.argInt = (long)val;
+}
+
+/*=export_func optionTimeDate
+ * private:
+ *
+ * what: process an option with a time and date.
+ * arg: + tOptions * + opts + program options descriptor +
+ * arg: + tOptDesc * + od + the descriptor for this arg +
+ *
+ * doc:
+ * Decipher a time and date value.
+=*/
+void
+optionTimeDate(tOptions * opts, tOptDesc * od)
+{
+#if defined(HAVE_GETDATE_R) && defined(HAVE_PUTENV)
+ if (INQUERY_CALL(opts, od))
+ return;
+
+ if ((! HAS_pzPkgDataDir(opts)) || (opts->pzPkgDataDir == NULL))
+ goto default_action;
+
+ /*
+ * Export the DATEMSK environment variable. getdate_r() uses it to
+ * find the file with the strptime formats. If we cannot find the file
+ * we need ($PKGDATADIR/datemsk), then fall back to just a time duration.
+ */
+ {
+ static char * envptr = NULL;
+
+ if (envptr == NULL) {
+ static char const fmt[] = "DATEMSK=%s/datemsk";
+ envptr = AGALOC(sizeof(fmt) + strlen(opts->pzPkgDataDir), fmt);
+ sprintf(envptr, fmt, opts->pzPkgDataDir);
+
+ putenv(envptr);
+ }
+
+ if (access(envptr+8, R_OK) != 0)
+ goto default_action;
+ }
+
+ /*
+ * Convert the date to a time since the epoch and stash it in a long int.
+ */
+ {
+ struct tm stm;
+ time_t tm;
+
+ if (getdate_r(od->optArg.argString, &stm) != 0) {
+ fprintf(stderr, zNotDate, opts->pzProgName,
+ od->optArg.argString);
+ if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0)
+ (*(opts->pUsageProc))(opts, EXIT_FAILURE);
+ return;
+ }
+
+ tm = mktime(&stm);
+
+ if (od->fOptState & OPTST_ALLOC_ARG) {
+ AGFREE(od->optArg.argString);
+ od->fOptState &= ~OPTST_ALLOC_ARG;
+ }
+
+ od->optArg.argInt = tm;
+ }
+ return;
+
+ default_action:
+
+#endif
+ optionTimeVal(opts, od);
+ if (od->optArg.argInt != BAD_TIME)
+ od->optArg.argInt += (long)time(NULL);
+}
+/** @}
+ *
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of autoopts/time.c */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/tokenize.c b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/tokenize.c
new file mode 100644
index 0000000..25550ea
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/tokenize.c
@@ -0,0 +1,339 @@
+/** \file tokenize.c
+ *
+ * Tokenize a string, accommodating quoted strings.
+ *
+ * @addtogroup autoopts
+ * @{
+ */
+/*
+ * This file defines the string_tokenize interface
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
+ *
+ * AutoOpts is available under any one of two licenses. The license
+ * in use must be one of these two and the choice is under the control
+ * of the user of the license.
+ *
+ * The GNU Lesser General Public License, version 3 or later
+ * See the files "COPYING.lgplv3" and "COPYING.gplv3"
+ *
+ * The Modified Berkeley Software Distribution License
+ * See the file "COPYING.mbsd"
+ *
+ * These files have the following sha256 sums:
+ *
+ * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
+ * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
+ * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+
+#define cc_t const unsigned char
+#define ch_t unsigned char
+
+/* = = = START-STATIC-FORWARD = = = */
+static void
+copy_cooked(ch_t ** ppDest, char const ** ppSrc);
+
+static void
+copy_raw(ch_t ** ppDest, char const ** ppSrc);
+
+static token_list_t *
+alloc_token_list(char const * str);
+/* = = = END-STATIC-FORWARD = = = */
+
+static void
+copy_cooked(ch_t ** ppDest, char const ** ppSrc)
+{
+ ch_t * pDest = (ch_t *)*ppDest;
+ const ch_t * pSrc = (const ch_t *)(*ppSrc + 1);
+
+ for (;;) {
+ ch_t ch = *(pSrc++);
+ switch (ch) {
+ case NUL: *ppSrc = NULL; return;
+ case '"': goto done;
+ case '\\':
+ pSrc += ao_string_cook_escape_char((const char *)pSrc, (char *)&ch, 0x7F);
+ if (ch == 0x7F)
+ break;
+ /* FALLTHROUGH */
+
+ default:
+ *(pDest++) = ch;
+ }
+ }
+
+ done:
+ *ppDest = (ch_t *)pDest; /* next spot for storing character */
+ *ppSrc = (char const *)pSrc; /* char following closing quote */
+}
+
+
+static void
+copy_raw(ch_t ** ppDest, char const ** ppSrc)
+{
+ ch_t * pDest = *ppDest;
+ cc_t * pSrc = (cc_t *) (*ppSrc + 1);
+
+ for (;;) {
+ ch_t ch = *(pSrc++);
+ switch (ch) {
+ case NUL: *ppSrc = NULL; return;
+ case '\'': goto done;
+ case '\\':
+ /*
+ * *Four* escapes are handled: newline removal, escape char
+ * quoting and apostrophe quoting
+ */
+ switch (*pSrc) {
+ case NUL: *ppSrc = NULL; return;
+ case '\r':
+ if (*(++pSrc) == NL)
+ ++pSrc;
+ continue;
+
+ case NL:
+ ++pSrc;
+ continue;
+
+ case '\'':
+ ch = '\'';
+ /* FALLTHROUGH */
+
+ case '\\':
+ ++pSrc;
+ break;
+ }
+ /* FALLTHROUGH */
+
+ default:
+ *(pDest++) = ch;
+ }
+ }
+
+ done:
+ *ppDest = pDest; /* next spot for storing character */
+ *ppSrc = (char const *) pSrc; /* char following closing quote */
+}
+
+static token_list_t *
+alloc_token_list(char const * str)
+{
+ token_list_t * res;
+
+ int max_token_ct = 2; /* allow for trailing NULL pointer & NUL on string */
+
+ if (str == NULL) goto enoent_res;
+
+ /*
+ * Trim leading white space. Use "ENOENT" and a NULL return to indicate
+ * an empty string was passed.
+ */
+ str = SPN_WHITESPACE_CHARS(str);
+ if (*str == NUL) goto enoent_res;
+
+ /*
+ * Take an approximate count of tokens. If no quoted strings are used,
+ * it will be accurate. If quoted strings are used, it will be a little
+ * high and we'll squander the space for a few extra pointers.
+ */
+ {
+ char const * pz = str;
+
+ do {
+ max_token_ct++;
+ pz = BRK_WHITESPACE_CHARS(pz+1);
+ pz = SPN_WHITESPACE_CHARS(pz);
+ } while (*pz != NUL);
+
+ res = malloc(sizeof(*res) + (size_t)(pz - str)
+ + ((size_t)max_token_ct * sizeof(ch_t *)));
+ }
+
+ if (res == NULL)
+ errno = ENOMEM;
+ else res->tkn_list[0] = (ch_t *)(res->tkn_list + (max_token_ct - 1));
+
+ return res;
+
+ enoent_res:
+
+ errno = ENOENT;
+ return NULL;
+}
+
+/*=export_func ao_string_tokenize
+ *
+ * what: tokenize an input string
+ *
+ * arg: + char const * + string + string to be tokenized +
+ *
+ * ret_type: token_list_t *
+ * ret_desc: pointer to a structure that lists each token
+ *
+ * doc:
+ *
+ * This function will convert one input string into a list of strings.
+ * The list of strings is derived by separating the input based on
+ * white space separation. However, if the input contains either single
+ * or double quote characters, then the text after that character up to
+ * a matching quote will become the string in the list.
+ *
+ * The returned pointer should be deallocated with @code{free(3C)} when
+ * are done using the data. The data are placed in a single block of
+ * allocated memory. Do not deallocate individual token/strings.
+ *
+ * The structure pointed to will contain at least these two fields:
+ * @table @samp
+ * @item tkn_ct
+ * The number of tokens found in the input string.
+ * @item tok_list
+ * An array of @code{tkn_ct + 1} pointers to substring tokens, with
+ * the last pointer set to NULL.
+ * @end table
+ *
+ * There are two types of quoted strings: single quoted (@code{'}) and
+ * double quoted (@code{"}). Singly quoted strings are fairly raw in that
+ * escape characters (@code{\\}) are simply another character, except when
+ * preceding the following characters:
+ * @example
+ * @code{\\} double backslashes reduce to one
+ * @code{'} incorporates the single quote into the string
+ * @code{\n} suppresses both the backslash and newline character
+ * @end example
+ *
+ * Double quote strings are formed according to the rules of string
+ * constants in ANSI-C programs.
+ *
+ * example:
+ * @example
+ * #include <stdlib.h>
+ * int ix;
+ * token_list_t * ptl = ao_string_tokenize(some_string)
+ * for (ix = 0; ix < ptl->tkn_ct; ix++)
+ * do_something_with_tkn(ptl->tkn_list[ix]);
+ * free(ptl);
+ * @end example
+ * Note that everything is freed with the one call to @code{free(3C)}.
+ *
+ * err:
+ * NULL is returned and @code{errno} will be set to indicate the problem:
+ * @itemize @bullet
+ * @item
+ * @code{EINVAL} - There was an unterminated quoted string.
+ * @item
+ * @code{ENOENT} - The input string was empty.
+ * @item
+ * @code{ENOMEM} - There is not enough memory.
+ * @end itemize
+=*/
+token_list_t *
+ao_string_tokenize(char const * str)
+{
+ token_list_t * res = alloc_token_list(str);
+ ch_t * pzDest;
+
+ /*
+ * Now copy each token into the output buffer.
+ */
+ if (res == NULL)
+ return res;
+
+ pzDest = (ch_t *)(res->tkn_list[0]);
+ res->tkn_ct = 0;
+
+ do {
+ res->tkn_list[ res->tkn_ct++ ] = pzDest;
+ for (;;) {
+ int ch = (ch_t)*str;
+ if (IS_WHITESPACE_CHAR(ch)) {
+ found_white_space:
+ str = SPN_WHITESPACE_CHARS(str+1);
+ break;
+ }
+
+ switch (ch) {
+ case '"':
+ copy_cooked(&pzDest, &str);
+ if (str == NULL) {
+ free(res);
+ errno = EINVAL;
+ return NULL;
+ }
+ if (IS_WHITESPACE_CHAR(*str))
+ goto found_white_space;
+ break;
+
+ case '\'':
+ copy_raw(&pzDest, &str);
+ if (str == NULL) {
+ free(res);
+ errno = EINVAL;
+ return NULL;
+ }
+ if (IS_WHITESPACE_CHAR(*str))
+ goto found_white_space;
+ break;
+
+ case NUL:
+ goto copy_done;
+
+ default:
+ str++;
+ *(pzDest++) = (unsigned char)ch;
+ }
+ } copy_done:;
+
+ /*
+ * NUL terminate the last token and see if we have any more tokens.
+ */
+ *(pzDest++) = NUL;
+ } while (*str != NUL);
+
+ res->tkn_list[ res->tkn_ct ] = NULL;
+
+ return res;
+}
+
+#ifdef TEST
+#include <stdio.h>
+#include <string.h>
+
+int
+main(int argc, char ** argv)
+{
+ if (argc == 1) {
+ printf("USAGE: %s arg [ ... ]\n", *argv);
+ return 1;
+ }
+ while (--argc > 0) {
+ char * arg = *(++argv);
+ token_list_t * p = ao_string_tokenize(arg);
+ if (p == NULL) {
+ printf("Parsing string ``%s'' failed:\n\terrno %d (%s)\n",
+ arg, errno, strerror(errno));
+ } else {
+ int ix = 0;
+ printf("Parsed string ``%s''\ninto %d tokens:\n", arg, p->tkn_ct);
+ do {
+ printf(" %3d: ``%s''\n", ix+1, p->tkn_list[ix]);
+ } while (++ix < p->tkn_ct);
+ free(p);
+ }
+ }
+ return 0;
+}
+#endif
+
+/** @}
+ *
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of autoopts/tokenize.c */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/usage.c b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/usage.c
new file mode 100644
index 0000000..c652da7
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/usage.c
@@ -0,0 +1,1336 @@
+
+/*
+ * \file usage.c
+ *
+ * This module implements the default usage procedure for
+ * Automated Options. It may be overridden, of course.
+ *
+ * @addtogroup autoopts
+ * @{
+ */
+/*
+ * Sort options:
+ --start=END-[S]TATIC-FORWARD --patt='^/\*($|[^:])' \
+ --out=xx.c key='^[a-zA-Z0-9_]+\(' --trail='^/\*:' \
+ --spac=2 --input=usage.c
+ */
+
+/*
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
+ *
+ * AutoOpts is available under any one of two licenses. The license
+ * in use must be one of these two and the choice is under the control
+ * of the user of the license.
+ *
+ * The GNU Lesser General Public License, version 3 or later
+ * See the files "COPYING.lgplv3" and "COPYING.gplv3"
+ *
+ * The Modified Berkeley Software Distribution License
+ * See the file "COPYING.mbsd"
+ *
+ * These files have the following sha256 sums:
+ *
+ * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
+ * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
+ * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
+ */
+
+/* = = = START-STATIC-FORWARD = = = */
+static unsigned int
+parse_usage_flags(ao_flag_names_t const * fnt, char const * txt);
+
+static inline bool
+do_gnu_usage(tOptions * pOpts);
+
+static inline bool
+skip_misuse_usage(tOptions * pOpts);
+
+static void
+print_offer_usage(tOptions * opts);
+
+static void
+print_usage_details(tOptions * opts, int exit_code);
+
+static void
+print_one_paragraph(char const * text, bool plain, FILE * fp);
+
+static void
+prt_conflicts(tOptions * opts, tOptDesc * od);
+
+static void
+prt_one_vendor(tOptions * opts, tOptDesc * od,
+ arg_types_t * argtp, char const * usefmt);
+
+static void
+prt_vendor_opts(tOptions * opts, char const * title);
+
+static void
+prt_extd_usage(tOptions * opts, tOptDesc * od, char const * title);
+
+static void
+prt_ini_list(char const * const * papz, char const * ini_file,
+ char const * path_nm);
+
+static void
+prt_preamble(tOptions * opts, tOptDesc * od, arg_types_t * at);
+
+static void
+prt_one_usage(tOptions * opts, tOptDesc * od, arg_types_t * at);
+
+static void
+prt_opt_usage(tOptions * opts, int ex_code, char const * title);
+
+static void
+prt_prog_detail(tOptions * opts);
+
+static int
+setGnuOptFmts(tOptions * opts, char const ** ptxt);
+
+static int
+setStdOptFmts(tOptions * opts, char const ** ptxt);
+/* = = = END-STATIC-FORWARD = = = */
+
+/**
+ * Parse the option usage flags string. Any parsing problems yield
+ * a zero (no flags set) result. This function is internal to
+ * set_usage_flags().
+ *
+ * @param[in] fnt Flag Name Table - maps a name to a mask
+ * @param[in] txt the text to process. If NULL, then
+ * getenv("AUTOOPTS_USAGE") is used.
+ * @returns a bit mask indicating which \a fnt entries were found.
+ */
+static unsigned int
+parse_usage_flags(ao_flag_names_t const * fnt, char const * txt)
+{
+ unsigned int res = 0;
+
+ /*
+ * The text may be passed in. If not, use the environment variable.
+ */
+ if (txt == NULL) {
+ txt = getenv("AUTOOPTS_USAGE");
+ if (txt == NULL)
+ return 0;
+ }
+
+ txt = SPN_WHITESPACE_CHARS(txt);
+ if (*txt == NUL)
+ return 0;
+
+ /*
+ * search the string for table entries. We must understand everything
+ * we see in the string, or we give up on it.
+ */
+ for (;;) {
+ int ix = 0;
+
+ for (;;) {
+ if (strneqvcmp(txt, fnt[ix].fnm_name, (int)fnt[ix].fnm_len) == 0)
+ break;
+ if (++ix >= AOUF_COUNT)
+ return 0;
+ }
+
+ /*
+ * Make sure we have a full match. Look for whitespace,
+ * a comma, or a NUL byte.
+ */
+ if (! IS_END_LIST_ENTRY_CHAR(txt[fnt[ix].fnm_len]))
+ return 0;
+
+ res |= 1U << ix;
+ txt = SPN_WHITESPACE_CHARS(txt + fnt[ix].fnm_len);
+
+ switch (*txt) {
+ case NUL:
+ return res;
+
+ case ',':
+ txt = SPN_WHITESPACE_CHARS(txt + 1);
+ /* Something must follow the comma */
+
+ default:
+ continue;
+ }
+ }
+}
+
+/**
+ * Set option usage flags. Any parsing problems yield no changes to options.
+ * Three different bits may be fiddled: \a OPTPROC_GNUUSAGE, \a OPTPROC_MISUSE
+ * and \a OPTPROC_COMPUTE.
+ *
+ * @param[in] flg_txt text to parse. If NULL, then the AUTOOPTS_USAGE
+ * environment variable is parsed.
+ * @param[in,out] opts the program option descriptor
+ */
+LOCAL void
+set_usage_flags(tOptions * opts, char const * flg_txt)
+{
+# define _aof_(_n, _f) { sizeof(#_n)-1, _f, #_n },
+ static ao_flag_names_t const fn_table[AOUF_COUNT] = {
+ AOFLAG_TABLE
+ };
+# undef _aof_
+
+ /*
+ * the flag word holds a bit for each selected table entry.
+ */
+ unsigned int flg = parse_usage_flags(fn_table, flg_txt);
+ if (flg == 0) return;
+
+ /*
+ * Ensure we do not have conflicting selections
+ */
+ {
+ static unsigned int const form_mask =
+ AOUF_gnu | AOUF_autoopts;
+ static unsigned int const misuse_mask =
+ AOUF_no_misuse_usage | AOUF_misuse_usage;
+ if ( ((flg & form_mask) == form_mask)
+ || ((flg & misuse_mask) == misuse_mask) )
+ return;
+ }
+
+ /*
+ * Now fiddle the fOptSet bits, based on settings.
+ * The OPTPROC_LONGOPT bit is immutable, thus if it is set,
+ * then fnm points to a mask off mask.
+ */
+ {
+ ao_flag_names_t const * fnm = fn_table;
+ for (;;) {
+ if ((flg & 1) != 0) {
+ if ((fnm->fnm_mask & OPTPROC_LONGOPT) != 0)
+ opts->fOptSet &= fnm->fnm_mask;
+ else opts->fOptSet |= fnm->fnm_mask;
+ }
+ flg >>= 1;
+ if (flg == 0)
+ break;
+ fnm++;
+ }
+ }
+}
+
+/*
+ * Figure out if we should try to format usage text sort-of like
+ * the way many GNU programs do.
+ */
+static inline bool
+do_gnu_usage(tOptions * pOpts)
+{
+ return (pOpts->fOptSet & OPTPROC_GNUUSAGE) ? true : false;
+}
+
+/*
+ * Figure out if we should try to format usage text sort-of like
+ * the way many GNU programs do.
+ */
+static inline bool
+skip_misuse_usage(tOptions * pOpts)
+{
+ return (pOpts->fOptSet & OPTPROC_MISUSE) ? true : false;
+}
+
+
+/*=export_func optionOnlyUsage
+ *
+ * what: Print usage text for just the options
+ * arg: + tOptions * + pOpts + program options descriptor +
+ * arg: + int + ex_code + exit code for calling exit(3) +
+ *
+ * doc:
+ * This routine will print only the usage for each option.
+ * This function may be used when the emitted usage must incorporate
+ * information not available to AutoOpts.
+=*/
+void
+optionOnlyUsage(tOptions * pOpts, int ex_code)
+{
+ char const * pOptTitle = NULL;
+
+ set_usage_flags(pOpts, NULL);
+ if ((ex_code != EXIT_SUCCESS) &&
+ skip_misuse_usage(pOpts))
+ return;
+
+ /*
+ * Determine which header and which option formatting strings to use
+ */
+ if (do_gnu_usage(pOpts))
+ (void)setGnuOptFmts(pOpts, &pOptTitle);
+ else
+ (void)setStdOptFmts(pOpts, &pOptTitle);
+
+ prt_opt_usage(pOpts, ex_code, pOptTitle);
+
+ fflush(option_usage_fp);
+ if (ferror(option_usage_fp) != 0)
+ fserr_exit(pOpts->pzProgName, zwriting, (option_usage_fp == stderr)
+ ? zstderr_name : zstdout_name);
+}
+
+/**
+ * Print a message suggesting how to get help.
+ *
+ * @param[in] opts the program options
+ */
+static void
+print_offer_usage(tOptions * opts)
+{
+ char help[24];
+
+ if (HAS_opt_usage_t(opts)) {
+ int ix = opts->presetOptCt;
+ tOptDesc * od = opts->pOptDesc + ix;
+ while (od->optUsage != AOUSE_HELP) {
+ if (++ix >= opts->optCt)
+ ao_bug(zmissing_help_msg);
+ od++;
+ }
+ switch (opts->fOptSet & (OPTPROC_LONGOPT | OPTPROC_SHORTOPT)) {
+ case OPTPROC_SHORTOPT:
+ help[0] = '-';
+ help[1] = od->optValue;
+ help[2] = NUL;
+ break;
+
+ case OPTPROC_LONGOPT:
+ case (OPTPROC_LONGOPT | OPTPROC_SHORTOPT):
+ help[0] = help[1] = '-';
+ strncpy(help + 2, od->pz_Name, 20);
+ break;
+
+ case 0:
+ strncpy(help, od->pz_Name, 20);
+ break;
+ }
+
+ } else {
+ switch (opts->fOptSet & (OPTPROC_LONGOPT | OPTPROC_SHORTOPT)) {
+ case OPTPROC_SHORTOPT:
+ strcpy(help, "-h");
+ break;
+
+ case OPTPROC_LONGOPT:
+ case (OPTPROC_LONGOPT | OPTPROC_SHORTOPT):
+ strcpy(help, "--help");
+ break;
+
+ case 0:
+ strcpy(help, "help");
+ break;
+ }
+ }
+
+ fprintf(option_usage_fp, zoffer_usage_fmt, opts->pzProgName, help);
+}
+
+/**
+ * Print information about each option.
+ *
+ * @param[in] opts the program options
+ * @param[in] exit_code whether or not there was a usage error reported.
+ * used to select full usage versus abbreviated.
+ */
+static void
+print_usage_details(tOptions * opts, int exit_code)
+{
+ {
+ char const * pOptTitle = NULL;
+ int flen;
+
+ /*
+ * Determine which header and which option formatting strings to use
+ */
+ if (do_gnu_usage(opts)) {
+ flen = setGnuOptFmts(opts, &pOptTitle);
+ sprintf(line_fmt_buf, zFmtFmt, flen);
+ fputc(NL, option_usage_fp);
+ }
+ else {
+ flen = setStdOptFmts(opts, &pOptTitle);
+ sprintf(line_fmt_buf, zFmtFmt, flen);
+
+ /*
+ * When we exit with EXIT_SUCCESS and the first option is a doc
+ * option, we do *NOT* want to emit the column headers.
+ * Otherwise, we do.
+ */
+ if ( (exit_code != EXIT_SUCCESS)
+ || ((opts->pOptDesc->fOptState & OPTST_DOCUMENT) == 0) )
+
+ fputs(pOptTitle, option_usage_fp);
+ }
+
+ flen = 4 - ((flen + 15) / 8);
+ if (flen > 0)
+ tab_skip_ct = flen;
+ prt_opt_usage(opts, exit_code, pOptTitle);
+ }
+
+ /*
+ * Describe the mechanics of denoting the options
+ */
+ switch (opts->fOptSet & OPTPROC_L_N_S) {
+ case OPTPROC_L_N_S: fputs(zFlagOkay, option_usage_fp); break;
+ case OPTPROC_SHORTOPT: break;
+ case OPTPROC_LONGOPT: fputs(zNoFlags, option_usage_fp); break;
+ case 0: fputs(zOptsOnly, option_usage_fp); break;
+ }
+
+ if ((opts->fOptSet & OPTPROC_NUM_OPT) != 0)
+ fputs(zNumberOpt, option_usage_fp);
+
+ if ((opts->fOptSet & OPTPROC_REORDER) != 0)
+ fputs(zReorder, option_usage_fp);
+
+ if (opts->pzExplain != NULL)
+ fputs(opts->pzExplain, option_usage_fp);
+
+ /*
+ * IF the user is asking for help (thus exiting with SUCCESS),
+ * THEN see what additional information we can provide.
+ */
+ if (exit_code == EXIT_SUCCESS)
+ prt_prog_detail(opts);
+
+ /*
+ * Give bug notification preference to the packager information
+ */
+ if (HAS_pzPkgDataDir(opts) && (opts->pzPackager != NULL))
+ fputs(opts->pzPackager, option_usage_fp);
+
+ else if (opts->pzBugAddr != NULL)
+ fprintf(option_usage_fp, zPlsSendBugs, opts->pzBugAddr);
+
+ fflush(option_usage_fp);
+
+ if (ferror(option_usage_fp) != 0)
+ fserr_exit(opts->pzProgName, zwriting, (option_usage_fp == stderr)
+ ? zstderr_name : zstdout_name);
+}
+
+static void
+print_one_paragraph(char const * text, bool plain, FILE * fp)
+{
+ if (plain) {
+#ifdef ENABLE_NLS
+#ifdef HAVE_LIBINTL_H
+#ifdef DEBUG_ENABLED
+#undef gettext
+#endif
+ char * buf = dgettext("libopts", text);
+ if (buf == text)
+ text = gettext(text);
+#endif /* HAVE_LIBINTL_H */
+#endif /* ENABLE_NLS */
+ fputs(text, fp);
+ }
+
+ else {
+ char const * t = optionQuoteString(text, LINE_SPLICE);
+ fprintf(fp, PUTS_FMT, t);
+ AGFREE(t);
+ }
+}
+
+/*=export_func optionPrintParagraphs
+ * private:
+ *
+ * what: Print a paragraph of usage text
+ * arg: + char const * + text + a block of text that has bee i18n-ed +
+ * arg: + bool + plain + false -> wrap text in fputs() +
+ * arg: + FILE * + fp + the stream file pointer for output +
+ *
+ * doc:
+ * This procedure is called in two contexts: when a full or short usage text
+ * has been provided for display, and when autogen is assembling a list of
+ * translatable texts in the optmain.tlib template. In the former case, \a
+ * plain is set to \a true, otherwise \a false.
+ *
+ * Anything less than 256 characters in size is printed as a single unit.
+ * Otherwise, paragraphs are detected. A paragraph break is defined as just
+ * before a non-empty line preceded by two newlines or a line that starts
+ * with at least one space character but fewer than 8 space characters.
+ * Lines indented with tabs or more than 7 spaces are considered continuation
+ * lines.
+ *
+ * If 'plain' is true, we are emitting text for a user to see. So, if it is
+ * true and NLS is not enabled, then just write the whole thing at once.
+=*/
+void
+optionPrintParagraphs(char const * text, bool plain, FILE * fp)
+{
+ size_t len = strlen(text);
+ char * buf;
+#ifndef ENABLE_NLS
+ if (plain || (len < 256))
+#else
+ if (len < 256)
+#endif
+ {
+ print_one_paragraph(text, plain, fp);
+ return;
+ }
+
+ AGDUPSTR(buf, text, "ppara");
+ text = buf;
+
+ for (;;) {
+ char * scan;
+
+ if (len < 256) {
+ done:
+ print_one_paragraph(buf, plain, fp);
+ break;
+ }
+ scan = buf;
+
+ try_longer:
+ scan = strchr(scan, NL);
+ if (scan == NULL)
+ goto done;
+
+ if ((scan - buf) < 40) {
+ scan++;
+ goto try_longer;
+ }
+
+ scan++;
+ if ((! isspace((int)*scan)) || (*scan == HT))
+ /*
+ * line starts with tab or non-whitespace --> continuation
+ */
+ goto try_longer;
+
+ if (*scan == NL) {
+ /*
+ * Double newline -> paragraph break
+ * Include all newlines in current paragraph.
+ */
+ while (*++scan == NL) /*continue*/;
+
+ } else {
+ char * p = scan;
+ int sp_ct = 0;
+
+ while (*p == ' ') {
+ if (++sp_ct >= 8) {
+ /*
+ * Too many spaces --> continuation line
+ */
+ scan = p;
+ goto try_longer;
+ }
+ p++;
+ }
+ }
+
+ /*
+ * "scan" points to the first character of a paragraph or the
+ * terminating NUL byte.
+ */
+ {
+ char svch = *scan;
+ *scan = NUL;
+ print_one_paragraph(buf, plain, fp);
+ len -= scan - buf;
+ if (len <= 0)
+ break;
+ *scan = svch;
+ buf = scan;
+ }
+ }
+ AGFREE(text);
+}
+
+/*=export_func optionUsage
+ * private:
+ *
+ * what: Print usage text
+ * arg: + tOptions * + opts + program options descriptor +
+ * arg: + int + exitCode + exit code for calling exit(3) +
+ *
+ * doc:
+ * This routine will print usage in both GNU-standard and AutoOpts-expanded
+ * formats. The descriptor specifies the default, but AUTOOPTS_USAGE will
+ * over-ride this, providing the value of it is set to either "gnu" or
+ * "autoopts". This routine will @strong{not} return.
+ *
+ * If "exitCode" is "AO_EXIT_REQ_USAGE" (normally 64), then output will to
+ * to stdout and the actual exit code will be "EXIT_SUCCESS".
+=*/
+void
+optionUsage(tOptions * opts, int usage_exit_code)
+{
+ int exit_code = (usage_exit_code == AO_EXIT_REQ_USAGE)
+ ? EXIT_SUCCESS : usage_exit_code;
+
+ displayEnum = false;
+ set_usage_flags(opts, NULL);
+
+ /*
+ * Paged usage will preset option_usage_fp to an output file.
+ * If it hasn't already been set, then set it to standard output
+ * on successful exit (help was requested), otherwise error out.
+ *
+ * Test the version before obtaining pzFullUsage or pzShortUsage.
+ * These fields do not exist before revision 30.
+ */
+ {
+ char const * pz;
+
+ if (exit_code == EXIT_SUCCESS) {
+ pz = (opts->structVersion >= 30 * 4096)
+ ? opts->pzFullUsage : NULL;
+
+ if (option_usage_fp == NULL)
+ option_usage_fp = print_exit ? stderr : stdout;
+
+ } else {
+ pz = (opts->structVersion >= 30 * 4096)
+ ? opts->pzShortUsage : NULL;
+
+ if (option_usage_fp == NULL)
+ option_usage_fp = stderr;
+ }
+
+ if (((opts->fOptSet & OPTPROC_COMPUTE) == 0) && (pz != NULL)) {
+ if ((opts->fOptSet & OPTPROC_TRANSLATE) != 0)
+ optionPrintParagraphs(pz, true, option_usage_fp);
+ else
+ fputs(pz, option_usage_fp);
+ goto flush_and_exit;
+ }
+ }
+
+ fprintf(option_usage_fp, opts->pzUsageTitle, opts->pzProgName);
+
+ if ((exit_code == EXIT_SUCCESS) ||
+ (! skip_misuse_usage(opts)))
+
+ print_usage_details(opts, usage_exit_code);
+ else
+ print_offer_usage(opts);
+
+ flush_and_exit:
+ fflush(option_usage_fp);
+ if (ferror(option_usage_fp) != 0)
+ fserr_exit(opts->pzProgName, zwriting, (option_usage_fp == stdout)
+ ? zstdout_name : zstderr_name);
+
+ option_exits(exit_code);
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * PER OPTION TYPE USAGE INFORMATION
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/**
+ * print option conflicts.
+ *
+ * @param opts the program option descriptor
+ * @param od the option descriptor
+ */
+static void
+prt_conflicts(tOptions * opts, tOptDesc * od)
+{
+ const int * opt_no;
+ fputs(zTabHyp + tab_skip_ct, option_usage_fp);
+
+ /*
+ * REQUIRED:
+ */
+ if (od->pOptMust != NULL) {
+ opt_no = od->pOptMust;
+
+ if (opt_no[1] == NO_EQUIVALENT) {
+ fprintf(option_usage_fp, zReqOne,
+ opts->pOptDesc[*opt_no].pz_Name);
+ } else {
+ fputs(zReqThese, option_usage_fp);
+ for (;;) {
+ fprintf(option_usage_fp, zTabout + tab_skip_ct,
+ opts->pOptDesc[*opt_no].pz_Name);
+ if (*++opt_no == NO_EQUIVALENT)
+ break;
+ }
+ }
+
+ if (od->pOptCant != NULL)
+ fputs(zTabHypAnd + tab_skip_ct, option_usage_fp);
+ }
+
+ /*
+ * CONFLICTS:
+ */
+ if (od->pOptCant == NULL)
+ return;
+
+ opt_no = od->pOptCant;
+
+ if (opt_no[1] == NO_EQUIVALENT) {
+ fprintf(option_usage_fp, zProhibOne,
+ opts->pOptDesc[*opt_no].pz_Name);
+ return;
+ }
+
+ fputs(zProhib, option_usage_fp);
+ for (;;) {
+ fprintf(option_usage_fp, zTabout + tab_skip_ct,
+ opts->pOptDesc[*opt_no].pz_Name);
+ if (*++opt_no == NO_EQUIVALENT)
+ break;
+ }
+}
+
+/**
+ * Print the usage information for a single vendor option.
+ *
+ * @param[in] opts the program option descriptor
+ * @param[in] od the option descriptor
+ * @param[in] argtp names of the option argument types
+ * @param[in] usefmt format for primary usage line
+ */
+static void
+prt_one_vendor(tOptions * opts, tOptDesc * od,
+ arg_types_t * argtp, char const * usefmt)
+{
+ prt_preamble(opts, od, argtp);
+
+ {
+ char z[ 80 ];
+ char const * pzArgType;
+
+ /*
+ * Determine the argument type string first on its usage, then,
+ * when the option argument is required, base the type string on the
+ * argument type.
+ */
+ if (od->fOptState & OPTST_ARG_OPTIONAL) {
+ pzArgType = argtp->pzOpt;
+
+ } else switch (OPTST_GET_ARGTYPE(od->fOptState)) {
+ case OPARG_TYPE_NONE: pzArgType = argtp->pzNo; break;
+ case OPARG_TYPE_ENUMERATION: pzArgType = argtp->pzKey; break;
+ case OPARG_TYPE_FILE: pzArgType = argtp->pzFile; break;
+ case OPARG_TYPE_MEMBERSHIP: pzArgType = argtp->pzKeyL; break;
+ case OPARG_TYPE_BOOLEAN: pzArgType = argtp->pzBool; break;
+ case OPARG_TYPE_NUMERIC: pzArgType = argtp->pzNum; break;
+ case OPARG_TYPE_HIERARCHY: pzArgType = argtp->pzNest; break;
+ case OPARG_TYPE_STRING: pzArgType = argtp->pzStr; break;
+ case OPARG_TYPE_TIME: pzArgType = argtp->pzTime; break;
+ default: goto bogus_desc;
+ }
+
+ pzArgType = SPN_WHITESPACE_CHARS(pzArgType);
+ if (*pzArgType == NUL)
+ snprintf(z, sizeof(z), "%s", od->pz_Name);
+ else
+ snprintf(z, sizeof(z), "%s=%s", od->pz_Name, pzArgType);
+ fprintf(option_usage_fp, usefmt, z, od->pzText);
+
+ switch (OPTST_GET_ARGTYPE(od->fOptState)) {
+ case OPARG_TYPE_ENUMERATION:
+ case OPARG_TYPE_MEMBERSHIP:
+ displayEnum = (od->pOptProc != NULL) ? true : displayEnum;
+ }
+ }
+
+ return;
+
+ bogus_desc:
+ fprintf(stderr, zbad_od, opts->pzProgName, od->pz_Name);
+ ao_bug(zbad_arg_type_msg);
+}
+
+/**
+ * Print the long options processed with "-W". These options will be the
+ * ones that do *not* have flag characters.
+ *
+ * @param opts the program option descriptor
+ * @param title the title for the options
+ */
+static void
+prt_vendor_opts(tOptions * opts, char const * title)
+{
+ static unsigned int const not_vended_mask =
+ OPTST_NO_USAGE_MASK | OPTST_DOCUMENT;
+
+ static char const vfmtfmt[] = "%%-%us %%s\n";
+ char vfmt[sizeof(vfmtfmt)];
+
+ /*
+ * Only handle client specified options. The "vendor option" follows
+ * "presetOptCt", so we won't loop/recurse indefinitely.
+ */
+ int ct = opts->presetOptCt;
+ tOptDesc * od = opts->pOptDesc;
+ fprintf(option_usage_fp, zTabout + tab_skip_ct, zVendOptsAre);
+
+ {
+ size_t nmlen = 0;
+ do {
+ size_t l;
+ if ( ((od->fOptState & not_vended_mask) != 0)
+ || IS_GRAPHIC_CHAR(od->optValue))
+ continue;
+
+ l = strlen(od->pz_Name);
+ if (l > nmlen) nmlen = l;
+ } while (od++, (--ct > 0));
+
+ snprintf(vfmt, sizeof(vfmt), vfmtfmt, (unsigned int)nmlen + 4);
+ }
+
+ if (tab_skip_ct > 0)
+ tab_skip_ct--;
+
+ ct = opts->presetOptCt;
+ od = opts->pOptDesc;
+
+ do {
+ if ( ((od->fOptState & not_vended_mask) != 0)
+ || IS_GRAPHIC_CHAR(od->optValue))
+ continue;
+
+ prt_one_vendor(opts, od, &argTypes, vfmt);
+ prt_extd_usage(opts, od, title);
+
+ } while (od++, (--ct > 0));
+
+ /* no need to restore "tab_skip_ct" - options are done now */
+}
+
+/**
+ * Print extended usage. Usage/help was requested.
+ *
+ * @param opts the program option descriptor
+ * @param od the option descriptor
+ * @param title the title for the options
+ */
+static void
+prt_extd_usage(tOptions * opts, tOptDesc * od, char const * title)
+{
+ if ( ((opts->fOptSet & OPTPROC_VENDOR_OPT) != 0)
+ && (od->optActualValue == VENDOR_OPTION_VALUE)) {
+ prt_vendor_opts(opts, title);
+ return;
+ }
+
+ /*
+ * IF there are option conflicts or dependencies,
+ * THEN print them here.
+ */
+ if ((od->pOptMust != NULL) || (od->pOptCant != NULL))
+ prt_conflicts(opts, od);
+
+ /*
+ * IF there is a disablement string
+ * THEN print the disablement info
+ */
+ if (od->pz_DisableName != NULL )
+ fprintf(option_usage_fp, zDis + tab_skip_ct, od->pz_DisableName);
+
+ /*
+ * Check for argument types that have callbacks with magical properties
+ */
+ switch (OPTST_GET_ARGTYPE(od->fOptState)) {
+ case OPARG_TYPE_NUMERIC:
+ /*
+ * IF the numeric option has a special callback,
+ * THEN call it, requesting the range or other special info
+ */
+ if ( (od->pOptProc != NULL)
+ && (od->pOptProc != optionNumericVal) ) {
+ (*(od->pOptProc))(OPTPROC_EMIT_USAGE, od);
+ }
+ break;
+
+ case OPARG_TYPE_FILE:
+ (*(od->pOptProc))(OPTPROC_EMIT_USAGE, od);
+ break;
+ }
+
+ /*
+ * IF the option defaults to being enabled,
+ * THEN print that out
+ */
+ if (od->fOptState & OPTST_INITENABLED)
+ fputs(zEnab + tab_skip_ct, option_usage_fp);
+
+ /*
+ * IF the option is in an equivalence class
+ * AND not the designated lead
+ * THEN print equivalence and leave it at that.
+ */
+ if ( (od->optEquivIndex != NO_EQUIVALENT)
+ && (od->optEquivIndex != od->optActualIndex ) ) {
+ fprintf(option_usage_fp, zalt_opt + tab_skip_ct,
+ opts->pOptDesc[ od->optEquivIndex ].pz_Name);
+ return;
+ }
+
+ /*
+ * IF this particular option can NOT be preset
+ * AND some form of presetting IS allowed,
+ * AND it is not an auto-managed option (e.g. --help, et al.)
+ * THEN advise that this option may not be preset.
+ */
+ if ( ((od->fOptState & OPTST_NO_INIT) != 0)
+ && ( (opts->papzHomeList != NULL)
+ || (opts->pzPROGNAME != NULL)
+ )
+ && (od->optIndex < opts->presetOptCt)
+ )
+
+ fputs(zNoPreset + tab_skip_ct, option_usage_fp);
+
+ /*
+ * Print the appearance requirements.
+ */
+ if (OPTST_GET_ARGTYPE(od->fOptState) == OPARG_TYPE_MEMBERSHIP)
+ fputs(zMembers + tab_skip_ct, option_usage_fp);
+
+ else switch (od->optMinCt) {
+ case 1:
+ case 0:
+ switch (od->optMaxCt) {
+ case 0: fputs(zPreset + tab_skip_ct, option_usage_fp); break;
+ case NOLIMIT: fputs(zNoLim + tab_skip_ct, option_usage_fp); break;
+ case 1: break;
+ /*
+ * IF the max is more than one but limited, print "UP TO" message
+ */
+ default:
+ fprintf(option_usage_fp, zUpTo + tab_skip_ct, od->optMaxCt); break;
+ }
+ break;
+
+ default:
+ /*
+ * More than one is required. Print the range.
+ */
+ fprintf(option_usage_fp, zMust + tab_skip_ct,
+ od->optMinCt, od->optMaxCt);
+ }
+
+ if ( NAMED_OPTS(opts)
+ && (opts->specOptIdx.default_opt == od->optIndex))
+ fputs(zDefaultOpt + tab_skip_ct, option_usage_fp);
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/**
+ * Figure out where all the initialization files might live. This requires
+ * translating some environment variables and testing to see if a name is a
+ * directory or a file. It's squishy, but important to tell users how to
+ * find these files.
+ *
+ * @param[in] papz search path
+ * @param[out] ini_file an output buffer of AG_PATH_MAX+1 bytes
+ * @param[in] path_nm the name of the file we're hunting for
+ */
+static void
+prt_ini_list(char const * const * papz, char const * ini_file,
+ char const * path_nm)
+{
+ char pth_buf[AG_PATH_MAX+1];
+
+ fputs(zPresetIntro, option_usage_fp);
+
+ for (;;) {
+ char const * path = *(papz++);
+ char const * nm_buf = pth_buf;
+
+ if (path == NULL)
+ break;
+
+ /*
+ * Ignore any invalid paths
+ */
+ if (! optionMakePath(pth_buf, (int)sizeof(pth_buf), path, path_nm))
+ nm_buf = path;
+
+ /*
+ * Expand paths that are relative to the executable or installation
+ * directories. Leave alone paths that use environment variables.
+ */
+ else if ((*path == '$')
+ && ((path[1] == '$') || (path[1] == '@')))
+ path = nm_buf;
+
+ /*
+ * Print the name of the "homerc" file. If the "rcfile" name is
+ * not empty, we may or may not print that, too...
+ */
+ fprintf(option_usage_fp, zPathFmt, path);
+ if (*ini_file != NUL) {
+ struct stat sb;
+
+ /*
+ * IF the "homerc" file is a directory,
+ * then append the "rcfile" name.
+ */
+ if ((stat(nm_buf, &sb) == 0) && S_ISDIR(sb.st_mode)) {
+ fputc(DIRCH, option_usage_fp);
+ fputs(ini_file, option_usage_fp);
+ }
+ }
+
+ fputc(NL, option_usage_fp);
+ }
+}
+
+/**
+ * Print the usage line preamble text
+ *
+ * @param opts the program option descriptor
+ * @param od the option descriptor
+ * @param at names of the option argument types
+ */
+static void
+prt_preamble(tOptions * opts, tOptDesc * od, arg_types_t * at)
+{
+ /*
+ * Flag prefix: IF no flags at all, then omit it. If not printable
+ * (not allowed for this option), then blank, else print it.
+ * Follow it with a comma if we are doing GNU usage and long
+ * opts are to be printed too.
+ */
+ if ((opts->fOptSet & OPTPROC_SHORTOPT) == 0)
+ fputs(at->pzSpc, option_usage_fp);
+
+ else if (! IS_GRAPHIC_CHAR(od->optValue)) {
+ if ( (opts->fOptSet & (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT))
+ == (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT))
+ fputc(' ', option_usage_fp);
+ fputs(at->pzNoF, option_usage_fp);
+
+ } else {
+ fprintf(option_usage_fp, " -%c", od->optValue);
+ if ( (opts->fOptSet & (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT))
+ == (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT))
+ fputs(", ", option_usage_fp);
+ }
+}
+
+/**
+ * Print the usage information for a single option.
+ *
+ * @param opts the program option descriptor
+ * @param od the option descriptor
+ * @param at names of the option argument types
+ */
+static void
+prt_one_usage(tOptions * opts, tOptDesc * od, arg_types_t * at)
+{
+ prt_preamble(opts, od, at);
+
+ {
+ char z[80];
+ char const * atyp;
+
+ /*
+ * Determine the argument type string first on its usage, then,
+ * when the option argument is required, base the type string on the
+ * argument type.
+ */
+ if (od->fOptState & OPTST_ARG_OPTIONAL) {
+ atyp = at->pzOpt;
+
+ } else switch (OPTST_GET_ARGTYPE(od->fOptState)) {
+ case OPARG_TYPE_NONE: atyp = at->pzNo; break;
+ case OPARG_TYPE_ENUMERATION: atyp = at->pzKey; break;
+ case OPARG_TYPE_FILE: atyp = at->pzFile; break;
+ case OPARG_TYPE_MEMBERSHIP: atyp = at->pzKeyL; break;
+ case OPARG_TYPE_BOOLEAN: atyp = at->pzBool; break;
+ case OPARG_TYPE_NUMERIC: atyp = at->pzNum; break;
+ case OPARG_TYPE_HIERARCHY: atyp = at->pzNest; break;
+ case OPARG_TYPE_STRING: atyp = at->pzStr; break;
+ case OPARG_TYPE_TIME: atyp = at->pzTime; break;
+ default: goto bogus_desc;
+ }
+
+#ifdef _WIN32
+ if (at->pzOptFmt == zGnuOptFmt)
+ snprintf(z, sizeof(z), "--%s%s", od->pz_Name, atyp);
+ else if (at->pzOptFmt == zGnuOptFmt + 2)
+ snprintf(z, sizeof(z), "%s%s", od->pz_Name, atyp);
+ else
+#endif
+ snprintf(z, sizeof(z), at->pzOptFmt, atyp, od->pz_Name,
+ (od->optMinCt != 0) ? at->pzReq : at->pzOpt);
+
+ fprintf(option_usage_fp, line_fmt_buf, z, od->pzText);
+
+ switch (OPTST_GET_ARGTYPE(od->fOptState)) {
+ case OPARG_TYPE_ENUMERATION:
+ case OPARG_TYPE_MEMBERSHIP:
+ displayEnum = (od->pOptProc != NULL) ? true : displayEnum;
+ }
+ }
+
+ return;
+
+ bogus_desc:
+ fprintf(stderr, zbad_od, opts->pzProgName, od->pz_Name);
+ option_exits(EX_SOFTWARE);
+}
+
+/**
+ * Print out the usage information for just the options.
+ */
+static void
+prt_opt_usage(tOptions * opts, int ex_code, char const * title)
+{
+ int ct = opts->optCt;
+ int optNo = 0;
+ tOptDesc * od = opts->pOptDesc;
+ int docCt = 0;
+
+ do {
+ /*
+ * no usage --> disallowed on command line (OPTST_NO_COMMAND), or
+ * deprecated -- strongly discouraged (OPTST_DEPRECATED), or
+ * compiled out of current object code (OPTST_OMITTED)
+ */
+ if ((od->fOptState & OPTST_NO_USAGE_MASK) != 0) {
+
+ /*
+ * IF this is a compiled-out option
+ * *AND* usage was requested with "omitted-usage"
+ * *AND* this is NOT abbreviated usage
+ * THEN display this option.
+ */
+ if ( (od->fOptState == (OPTST_OMITTED | OPTST_NO_INIT))
+ && (od->pz_Name != NULL)
+ && (ex_code == EXIT_SUCCESS)) {
+
+ char const * why_pz =
+ (od->pzText == NULL) ? zDisabledWhy : od->pzText;
+ prt_preamble(opts, od, &argTypes);
+ fprintf(option_usage_fp, zDisabledOpt, od->pz_Name, why_pz);
+ }
+
+ continue;
+ }
+
+ if ((od->fOptState & OPTST_DOCUMENT) != 0) {
+ if (ex_code == EXIT_SUCCESS) {
+ fprintf(option_usage_fp, argTypes.pzBrk, od->pzText,
+ title);
+ docCt++;
+ }
+
+ continue;
+ }
+
+ /* Skip name only options when we have a vendor option */
+ if ( ((opts->fOptSet & OPTPROC_VENDOR_OPT) != 0)
+ && (! IS_GRAPHIC_CHAR(od->optValue)))
+ continue;
+
+ /*
+ * IF this is the first auto-opt maintained option
+ * *AND* we are doing a full help
+ * *AND* there are documentation options
+ * *AND* the last one was not a doc option,
+ * THEN document that the remaining options are not user opts
+ */
+ if ((docCt > 0) && (ex_code == EXIT_SUCCESS)) {
+ if (opts->presetOptCt == optNo) {
+ if ((od[-1].fOptState & OPTST_DOCUMENT) == 0)
+ fprintf(option_usage_fp, argTypes.pzBrk, zAuto, title);
+
+ } else if ((ct == 1) &&
+ (opts->fOptSet & OPTPROC_VENDOR_OPT))
+ fprintf(option_usage_fp, argTypes.pzBrk, zVendIntro, title);
+ }
+
+ prt_one_usage(opts, od, &argTypes);
+
+ /*
+ * IF we were invoked because of the --help option,
+ * THEN print all the extra info
+ */
+ if (ex_code == EXIT_SUCCESS)
+ prt_extd_usage(opts, od, title);
+
+ } while (od++, optNo++, (--ct > 0));
+
+ fputc(NL, option_usage_fp);
+}
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/**
+ * Print program details.
+ * @param[in] opts the program option descriptor
+ */
+static void
+prt_prog_detail(tOptions * opts)
+{
+ bool need_intro = (opts->papzHomeList == NULL);
+
+ /*
+ * Display all the places we look for config files, if we have
+ * a list of directories to search.
+ */
+ if (! need_intro)
+ prt_ini_list(opts->papzHomeList, opts->pzRcName, opts->pzProgPath);
+
+ /*
+ * Let the user know about environment variable settings
+ */
+ if ((opts->fOptSet & OPTPROC_ENVIRON) != 0) {
+ if (need_intro)
+ fputs(zPresetIntro, option_usage_fp);
+
+ fprintf(option_usage_fp, zExamineFmt, opts->pzPROGNAME);
+ }
+
+ /*
+ * IF we found an enumeration,
+ * THEN hunt for it again. Call the handler proc with a NULL
+ * option struct pointer. That tells it to display the keywords.
+ */
+ if (displayEnum) {
+ int ct = opts->optCt;
+ int optNo = 0;
+ tOptDesc * od = opts->pOptDesc;
+
+ fputc(NL, option_usage_fp);
+ fflush(option_usage_fp);
+ do {
+ switch (OPTST_GET_ARGTYPE(od->fOptState)) {
+ case OPARG_TYPE_ENUMERATION:
+ case OPARG_TYPE_MEMBERSHIP:
+ (*(od->pOptProc))(OPTPROC_EMIT_USAGE, od);
+ }
+ } while (od++, optNo++, (--ct > 0));
+ }
+
+ /*
+ * If there is a detail string, now is the time for that.
+ */
+ if (opts->pzDetail != NULL)
+ fputs(opts->pzDetail, option_usage_fp);
+}
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * OPTION LINE FORMATTING SETUP
+ *
+ * The "OptFmt" formats receive three arguments:
+ * 1. the type of the option's argument
+ * 2. the long name of the option
+ * 3. "YES" or "no ", depending on whether or not the option must appear
+ * on the command line.
+ * These formats are used immediately after the option flag (if used) has
+ * been printed.
+ *
+ * Set up the formatting for GNU-style output
+ */
+static int
+setGnuOptFmts(tOptions * opts, char const ** ptxt)
+{
+ static char const zOneSpace[] = " ";
+ int flen = 22;
+ *ptxt = zNoRq_ShrtTtl;
+
+ argTypes.pzStr = zGnuStrArg;
+ argTypes.pzReq = zOneSpace;
+ argTypes.pzNum = zGnuNumArg;
+ argTypes.pzKey = zGnuKeyArg;
+ argTypes.pzKeyL = zGnuKeyLArg;
+ argTypes.pzTime = zGnuTimeArg;
+ argTypes.pzFile = zGnuFileArg;
+ argTypes.pzBool = zGnuBoolArg;
+ argTypes.pzNest = zGnuNestArg;
+ argTypes.pzOpt = zGnuOptArg;
+ argTypes.pzNo = zOneSpace;
+ argTypes.pzBrk = zGnuBreak;
+ argTypes.pzNoF = zSixSpaces;
+ argTypes.pzSpc = zThreeSpaces;
+
+ switch (opts->fOptSet & OPTPROC_L_N_S) {
+ case OPTPROC_L_N_S: argTypes.pzOptFmt = zGnuOptFmt; break;
+ case OPTPROC_LONGOPT: argTypes.pzOptFmt = zGnuOptFmt; break;
+ case 0: argTypes.pzOptFmt = zGnuOptFmt + 2; break;
+ case OPTPROC_SHORTOPT:
+ argTypes.pzOptFmt = zShrtGnuOptFmt;
+ zGnuStrArg[0] = zGnuNumArg[0] = zGnuKeyArg[0] = zGnuBoolArg[0] = ' ';
+ argTypes.pzOpt = " [arg]";
+ flen = 8;
+ break;
+ }
+
+ return flen;
+}
+
+
+/*
+ * Standard (AutoOpts normal) option line formatting
+ */
+static int
+setStdOptFmts(tOptions * opts, char const ** ptxt)
+{
+ int flen = 0;
+
+ argTypes.pzStr = zStdStrArg;
+ argTypes.pzReq = zStdReqArg;
+ argTypes.pzNum = zStdNumArg;
+ argTypes.pzKey = zStdKeyArg;
+ argTypes.pzKeyL = zStdKeyLArg;
+ argTypes.pzTime = zStdTimeArg;
+ argTypes.pzFile = zStdFileArg;
+ argTypes.pzBool = zStdBoolArg;
+ argTypes.pzNest = zStdNestArg;
+ argTypes.pzOpt = zStdOptArg;
+ argTypes.pzNo = zStdNoArg;
+ argTypes.pzBrk = zStdBreak;
+ argTypes.pzNoF = zFiveSpaces;
+ argTypes.pzSpc = zTwoSpaces;
+
+ switch (opts->fOptSet & (OPTPROC_NO_REQ_OPT | OPTPROC_SHORTOPT)) {
+ case (OPTPROC_NO_REQ_OPT | OPTPROC_SHORTOPT):
+ *ptxt = zNoRq_ShrtTtl;
+ argTypes.pzOptFmt = zNrmOptFmt;
+ flen = 19;
+ break;
+
+ case OPTPROC_NO_REQ_OPT:
+ *ptxt = zNoRq_NoShrtTtl;
+ argTypes.pzOptFmt = zNrmOptFmt;
+ flen = 19;
+ break;
+
+ case OPTPROC_SHORTOPT:
+ *ptxt = zReq_ShrtTtl;
+ argTypes.pzOptFmt = zReqOptFmt;
+ flen = 24;
+ break;
+
+ case 0:
+ *ptxt = zReq_NoShrtTtl;
+ argTypes.pzOptFmt = zReqOptFmt;
+ flen = 24;
+ }
+
+ return flen;
+}
+
+/** @}
+ *
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of autoopts/usage.c */
diff --git a/sebhbsd/freebsd/contrib/ntp/sntp/libopts/version.c b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/version.c
new file mode 100644
index 0000000..8a8de75
--- /dev/null
+++ b/sebhbsd/freebsd/contrib/ntp/sntp/libopts/version.c
@@ -0,0 +1,237 @@
+
+/** \file version.c
+ *
+ * This module implements the default usage procedure for
+ * Automated Options. It may be overridden, of course.
+ *
+ * @addtogroup autoopts
+ * @{
+ */
+/*
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
+ *
+ * AutoOpts is available under any one of two licenses. The license
+ * in use must be one of these two and the choice is under the control
+ * of the user of the license.
+ *
+ * The GNU Lesser General Public License, version 3 or later
+ * See the files "COPYING.lgplv3" and "COPYING.gplv3"
+ *
+ * The Modified Berkeley Software Distribution License
+ * See the file "COPYING.mbsd"
+ *
+ * These files have the following sha256 sums:
+ *
+ * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
+ * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
+ * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
+ */
+
+/*=export_func optionVersion
+ *
+ * what: return the compiled AutoOpts version number
+ * ret_type: char const *
+ * ret_desc: the version string in constant memory
+ * doc:
+ * Returns the full version string compiled into the library.
+ * The returned string cannot be modified.
+=*/
+char const *
+optionVersion(void)
+{
+ static char const ver[] = OPTIONS_DOTTED_VERSION;
+ return ver;
+}
+
+static void
+emit_first_line(
+ FILE * fp, char const * alt1, char const * alt2, char const * alt3)
+{
+ char const * p = (alt1 != NULL) ? alt1 : ((alt2 != NULL) ? alt2 : alt3);
+ char const * e;
+ if (p == NULL)
+ return;
+ e = strchr(p, NL);
+ if (e == NULL)
+ fputs(p, fp);
+ else
+ fwrite(p, 1, (e - p), fp);
+ fputc(NL, fp);
+}
+
+/**
+ * Select among various ways to emit version information.
+ *
+ * @param[in] o the option descriptor
+ * @param[in] fp the output stream
+ */
+static void
+emit_simple_ver(tOptions * o, FILE * fp)
+{
+ emit_first_line(fp, o->pzFullVersion, o->pzCopyright, o->pzUsageTitle);
+}
+
+/**
+ * print the version with a copyright notice.
+ *
+ * @param[in] o the option descriptor
+ * @param[in] fp the output stream
+ */
+static void
+emit_copy_full(tOptions * o, FILE * fp)
+{
+ if (o->pzCopyright != NULL)
+ fputs(o->pzCopyright, fp);
+
+ else if (o->pzFullVersion != NULL)
+ fputs(o->pzFullVersion, fp);
+
+ else
+ emit_first_line(fp, o->pzUsageTitle, NULL, NULL);
+
+ if (HAS_pzPkgDataDir(o) && (o->pzPackager != NULL)) {
+ fputc(NL, fp);
+ fputs(o->pzPackager, fp);
+
+ } else if (o->pzBugAddr != NULL) {
+ fputc(NL, fp);
+ fprintf(fp, zPlsSendBugs, o->pzBugAddr);
+ }
+}
+
+/**
+ * print the version and any copyright notice.
+ * The version with a full copyright and additional notes.
+ *
+ * @param[in] opts the option descriptor
+ * @param[in] fp the output stream
+ */
+static void
+emit_copy_note(tOptions * opts, FILE * fp)
+{
+ if (opts->pzCopyright != NULL)
+ fputs(opts->pzCopyright, fp);
+
+ if (opts->pzCopyNotice != NULL)
+ fputs(opts->pzCopyNotice, fp);
+
+ fputc(NL, fp);
+ fprintf(fp, zao_ver_fmt, optionVersion());
+
+ if (HAS_pzPkgDataDir(opts) && (opts->pzPackager != NULL)) {
+ fputc(NL, fp);
+ fputs(opts->pzPackager, fp);
+
+ } else if (opts->pzBugAddr != NULL) {
+ fputc(NL, fp);
+ fprintf(fp, zPlsSendBugs, opts->pzBugAddr);
+ }
+}
+
+/**
+ * Handle the version printing. We must see how much information
+ * is being requested and select the correct printing routine.
+ */
+static void
+print_ver(tOptions * opts, tOptDesc * od, FILE * fp, bool call_exit)
+{
+ char ch;
+
+ if (opts <= OPTPROC_EMIT_LIMIT)
+ return;
+
+ /*
+ * IF we have an argument for this option, use it
+ * Otherwise, default to version only or copyright note,
+ * depending on whether the layout is GNU standard form or not.
+ */
+ if ( (od->fOptState & OPTST_ARG_OPTIONAL)
+ && (od->optArg.argString != NULL)
+ && (od->optArg.argString[0] != NUL))
+
+ ch = od->optArg.argString[0];
+
+ else {
+ set_usage_flags(opts, NULL);
+ ch = (opts->fOptSet & OPTPROC_GNUUSAGE) ? 'c' : 'v';
+ }
+
+ switch (ch) {
+ case NUL: /* arg provided, but empty */
+ case 'v': case 'V': emit_simple_ver(opts, fp); break;
+ case 'c': case 'C': emit_copy_full( opts, fp); break;
+ case 'n': case 'N': emit_copy_note( opts, fp); break;
+
+ default:
+ fprintf(stderr, zBadVerArg, ch);
+ option_exits(EXIT_FAILURE);
+ }
+
+ fflush(fp);
+ if (ferror(fp))
+ fserr_exit(opts->pzProgName, zwriting,
+ (fp == stdout) ? zstdout_name : zstderr_name);
+
+ if (call_exit)
+ option_exits(EXIT_SUCCESS);
+}
+
+/*=export_func optionPrintVersion
+ *
+ * what: Print the program version
+ * arg: + tOptions * + opts + program options descriptor +
+ * arg: + tOptDesc * + od + the descriptor for this arg +
+ *
+ * doc:
+ * This routine will print the version to stdout.
+=*/
+void
+optionPrintVersion(tOptions * opts, tOptDesc * od)
+{
+ print_ver(opts, od, print_exit ? stderr : stdout, true);
+}
+
+/*=export_func optionPrintVersionAndReturn
+ *
+ * what: Print the program version
+ * arg: + tOptions * + opts + program options descriptor +
+ * arg: + tOptDesc * + od + the descriptor for this arg +
+ *
+ * doc:
+ * This routine will print the version to stdout and return
+ * instead of exiting. Please see the source for the
+ * @code{print_ver} funtion for details on selecting how
+ * verbose to be after this function returns.
+=*/
+void
+optionPrintVersionAndReturn(tOptions * opts, tOptDesc * od)
+{
+ print_ver(opts, od, print_exit ? stderr : stdout, false);
+}
+
+/*=export_func optionVersionStderr
+ * private:
+ *
+ * what: Print the program version to stderr
+ * arg: + tOptions * + opts + program options descriptor +
+ * arg: + tOptDesc * + od + the descriptor for this arg +
+ *
+ * doc:
+ * This routine will print the version to stderr.
+=*/
+void
+optionVersionStderr(tOptions * opts, tOptDesc * od)
+{
+ print_ver(opts, od, stderr, true);
+}
+
+/** @}
+ *
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of autoopts/version.c */
diff --git a/sebhbsd/rtemsbsd/include/machine/rtems-bsd-program.h b/sebhbsd/rtemsbsd/include/machine/rtems-bsd-program.h
new file mode 100644
index 0000000..3062c1a
--- /dev/null
+++ b/sebhbsd/rtemsbsd/include/machine/rtems-bsd-program.h
@@ -0,0 +1,212 @@
+/**
+ * @file
+ *
+ * @ingroup rtems_bsd_machine
+ *
+ * @brief TODO.
+ */
+
+/*
+ * Copyright (c) 2013, 2019 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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.
+ */
+
+#ifndef _RTEMS_BSD_MACHINE_RTEMS_BSD_PROGRAM_H_
+#define _RTEMS_BSD_MACHINE_RTEMS_BSD_PROGRAM_H_
+
+#include <sys/cdefs.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+__BEGIN_DECLS
+
+int
+rtems_bsd_program_call(const char *name, int (*prog)(void *), void *context);
+
+int
+rtems_bsd_program_call_main(const char *name, int (*main)(int, char **),
+ int argc, char **argv);
+
+int
+rtems_bsd_program_call_main_with_data_restore(const char *name,
+ int (*main)(int, char **), int argc, char **argv,
+ void *data_buf, const size_t data_size);
+
+void *
+rtems_bsd_program_add_destructor(void (*destructor)(void *), void *arg);
+
+void
+rtems_bsd_program_remove_destructor(void *cookie, bool call);
+
+void
+rtems_bsd_program_exit(int exit_code) __dead2;
+
+void
+rtems_bsd_program_error(const char *, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
+
+const char *
+rtems_bsd_program_get_name(void);
+
+void *
+rtems_bsd_program_get_context(void) __pure2;
+
+void
+rtems_bsd_program_lock(void);
+
+void
+rtems_bsd_program_unlock(void);
+
+int
+rtems_bsd_program_open(const char *path, int oflag, ...);
+
+int
+rtems_bsd_program_socket(int domain, int type, int protocol);
+
+int
+rtems_bsd_program_close(int fd);
+
+FILE *
+rtems_bsd_program_fopen(const char *restrict filename,
+ const char *restrict mode);
+
+int
+rtems_bsd_program_fclose(FILE *file);
+
+void *
+rtems_bsd_program_malloc(size_t size);
+
+void *
+rtems_bsd_program_calloc(size_t nelem, size_t elsize);
+
+void *
+rtems_bsd_program_realloc(void *ptr, size_t size);
+
+void *
+rtems_bsd_program_reallocf(void *ptr, size_t size);
+
+char *
+rtems_bsd_program_strdup(const char *s);
+
+char *
+rtems_bsd_program_strndup(const char *s, size_t size);
+
+int
+rtems_bsd_program_vasprintf(char **strp, const char *fmt, va_list ap);
+
+int
+rtems_bsd_program_asprintf(char **strp, const char *fmt, ...);
+
+void
+rtems_bsd_program_free(void *ptr);
+
+#ifndef RTEMS_BSD_PROGRAM_NO_ABORT_WRAP
+ #define abort() rtems_bsd_program_exit(1)
+#endif
+
+#ifndef RTEMS_BSD_PROGRAM_NO_EXIT_WRAP
+ #define exit(code) rtems_bsd_program_exit(code)
+#endif
+
+#ifndef RTEMS_BSD_PROGRAM_NO_ERROR_WRAP
+ #define error(fmt, ...) rtems_bsd_program_error(fmt, ## __VA_ARGS__)
+#endif
+
+#ifndef RTEMS_BSD_PROGRAM_NO_GETPROGNAME_WRAP
+ #define getprogname() rtems_bsd_program_get_name()
+#endif
+
+#ifndef RTEMS_BSD_PROGRAM_NO_PRINTF_WRAP
+ #define printf(...) fprintf(stdout, __VA_ARGS__)
+#endif
+
+#ifndef RTEMS_BSD_PROGRAM_NO_OPEN_WRAP
+ #define open(path, oflag, ...) \
+ rtems_bsd_program_open(path, oflag, ## __VA_ARGS__)
+#endif
+
+#ifndef RTEMS_BSD_PROGRAM_NO_SOCKET_WRAP
+ #define socket(domain, type, protocol) \
+ rtems_bsd_program_socket(domain, type, protocol)
+#endif
+
+#ifndef RTEMS_BSD_PROGRAM_NO_CLOSE_WRAP
+ #define close(fildes) rtems_bsd_program_close(fildes)
+#endif
+
+#ifndef RTEMS_BSD_PROGRAM_NO_FOPEN_WRAP
+ #define fopen(filename, mode) rtems_bsd_program_fopen(filename, mode)
+#endif
+
+#ifndef RTEMS_BSD_PROGRAM_NO_FCLOSE_WRAP
+ #define fclose(file) rtems_bsd_program_fclose(file)
+#endif
+
+#ifndef RTEMS_BSD_PROGRAM_NO_MALLOC_WRAP
+ #define malloc(size) rtems_bsd_program_malloc(size)
+#endif
+
+#ifndef RTEMS_BSD_PROGRAM_NO_CALLOC_WRAP
+ #define calloc(nelem, elsize) rtems_bsd_program_calloc(nelem, elsize)
+#endif
+
+#ifndef RTEMS_BSD_PROGRAM_NO_REALLOC_WRAP
+ #define realloc(ptr, size) rtems_bsd_program_realloc(ptr, size)
+#endif
+
+#ifndef RTEMS_BSD_PROGRAM_NO_REALLOC_WRAP
+ #define reallocf(ptr, size) rtems_bsd_program_reallocf(ptr, size)
+#endif
+
+#ifndef RTEMS_BSD_PROGRAM_NO_STRDUP_WRAP
+ #define strdup(s) rtems_bsd_program_strdup(s)
+#endif
+
+#ifndef RTEMS_BSD_PROGRAM_NO_STRNDUP_WRAP
+ #define strndup(s, size) rtems_bsd_program_strndup(s, size)
+#endif
+
+#ifndef RTEMS_BSD_PROGRAM_NO_VASPRINTF_WRAP
+ #define vasprintf(strp, fmt, ap) \
+ rtems_bsd_program_vasprintf(strp, fmt, ap)
+#endif
+
+#ifndef RTEMS_BSD_PROGRAM_NO_ASPRINTF_WRAP
+ #define asprintf(strp, fmt, ...) \
+ rtems_bsd_program_asprintf(strp, fmt, ## __VA_ARGS__)
+#endif
+
+#ifndef RTEMS_BSD_PROGRAM_NO_FREE_WRAP
+ #define free(ptr) rtems_bsd_program_free(ptr)
+#endif
+
+__END_DECLS
+
+#endif /* _RTEMS_BSD_MACHINE_RTEMS_BSD_PROGRAM_H_ */
diff --git a/sebhbsd/rtemsbsd/include/rtems/ntpd.h b/sebhbsd/rtemsbsd/include/rtems/ntpd.h
new file mode 100644
index 0000000..00af1ea
--- /dev/null
+++ b/sebhbsd/rtemsbsd/include/rtems/ntpd.h
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup rtems_bsd
+ *
+ * @brief This header file defines the NTP daemon interfaces.
+ */
+
+/*
+ * Copyright (C) 2022 embedded brains GmbH (http://www.embedded-brains.de)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTEMS_NTPD_H
+#define _RTEMS_NTPD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Runs the NTP daemon (nptd).
+ *
+ * It is recommended to use the ``-g`` option. The NTP daemon will start
+ * worker theads which inherit scheduler attributes from the runner thread.
+ *
+ * @param argc is the argument count.
+ *
+ * @param argv is the vector of arguments.
+ *
+ * @return This function should never return. If it returns, then there is a
+ * serious error.
+ */
+int rtems_ntpd_run(int argc, char **argv);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTEMS_NTPD_H */
diff --git a/sebhbsd/rtemsbsd/rtems/program-internal.h b/sebhbsd/rtemsbsd/rtems/program-internal.h
new file mode 100644
index 0000000..2104c06
--- /dev/null
+++ b/sebhbsd/rtemsbsd/rtems/program-internal.h
@@ -0,0 +1,84 @@
+/**
+ * @file
+ *
+ * @ingroup rtems_bsd_rtems
+ *
+ * @brief TODO.
+ */
+
+/*
+ * Copyright (c) 2013, 2016 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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>
+#include <sys/types.h>
+#include <sys/queue.h>
+
+#include <setjmp.h>
+
+__BEGIN_DECLS
+
+struct program_fd_item {
+ int fd;
+ LIST_ENTRY(program_fd_item) entries;
+};
+
+struct program_file_item {
+ FILE *file;
+ LIST_ENTRY(program_file_item) entries;
+};
+
+struct program_allocmem_item {
+ void *ptr;
+ LIST_ENTRY(program_allocmem_item) entries;
+};
+
+struct program_destructor {
+ void (*destructor)(void *);
+ void *arg;
+ LIST_ENTRY(program_destructor) link;
+};
+
+struct rtems_bsd_program_control {
+ void *context;
+ int exit_code;
+ const char *name;
+ jmp_buf return_context;
+ LIST_HEAD(, program_fd_item) open_fd;
+ LIST_HEAD(, program_file_item) open_file;
+ LIST_HEAD(, program_allocmem_item) allocated_mem;
+ LIST_HEAD(, program_destructor) destructors;
+};
+
+struct rtems_bsd_program_control *rtems_bsd_program_get_control_or_null(void);
+
+int rtems_bsd_program_set_control(struct rtems_bsd_program_control *);
+
+__END_DECLS
diff --git a/sebhbsd/rtemsbsd/rtems/rtems-program-socket.c b/sebhbsd/rtemsbsd/rtems/rtems-program-socket.c
new file mode 100644
index 0000000..4a8d9fc
--- /dev/null
+++ b/sebhbsd/rtemsbsd/rtems/rtems-program-socket.c
@@ -0,0 +1,79 @@
+/**
+ * @file
+ *
+ * @ingroup rtems_bsd_rtems
+ *
+ * @brief TODO.
+ */
+
+/*
+ * Copyright (c) 2013, 2016 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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/socket.h>
+
+#include <errno.h>
+#include <stdlib.h>
+
+#define RTEMS_BSD_PROGRAM_NO_SOCKET_WRAP
+#define RTEMS_BSD_PROGRAM_NO_CALLOC_WRAP
+#define RTEMS_BSD_PROGRAM_NO_FREE_WRAP
+#include <machine/rtems-bsd-program.h>
+
+#include "program-internal.h"
+
+int
+rtems_bsd_program_socket(int domain, int type, int protocol)
+{
+ struct rtems_bsd_program_control *prog_ctrl;
+ struct program_fd_item *item;
+ int fd;
+
+ prog_ctrl = rtems_bsd_program_get_control_or_null();
+ if (prog_ctrl == NULL) {
+ errno = ENOMEM;
+ return (-1);
+ }
+
+ item = calloc(1, sizeof(*item));
+ if (item == NULL) {
+ return (-1);
+ }
+
+ fd = socket(domain, type, protocol);
+ if (fd >= 0) {
+ item->fd = fd;
+ LIST_INSERT_HEAD(&prog_ctrl->open_fd, item, entries);
+ } else {
+ free(item);
+ }
+
+ return (fd);
+}
diff --git a/sebhbsd/rtemsbsd/rtems/rtems-program.c b/sebhbsd/rtemsbsd/rtems/rtems-program.c
new file mode 100644
index 0000000..4d2ce6e
--- /dev/null
+++ b/sebhbsd/rtemsbsd/rtems/rtems-program.c
@@ -0,0 +1,680 @@
+/**
+ * @file
+ *
+ * @ingroup rtems_bsd_rtems
+ *
+ * @brief TODO.
+ */
+
+/*
+ * Copyright (c) 2013, 2016 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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/types.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#define RTEMS_BSD_PROGRAM_NO_OPEN_WRAP
+#define RTEMS_BSD_PROGRAM_NO_CLOSE_WRAP
+#define RTEMS_BSD_PROGRAM_NO_FOPEN_WRAP
+#define RTEMS_BSD_PROGRAM_NO_FCLOSE_WRAP
+#define RTEMS_BSD_PROGRAM_NO_MALLOC_WRAP
+#define RTEMS_BSD_PROGRAM_NO_CALLOC_WRAP
+#define RTEMS_BSD_PROGRAM_NO_REALLOC_WRAP
+#define RTEMS_BSD_PROGRAM_NO_STRDUP_WRAP
+#define RTEMS_BSD_PROGRAM_NO_VASPRINTF_WRAP
+#define RTEMS_BSD_PROGRAM_NO_ASPRINTF_WRAP
+#define RTEMS_BSD_PROGRAM_NO_FREE_WRAP
+#include <machine/rtems-bsd-program.h>
+
+#include "program-internal.h"
+
+static int
+fd_remove(struct rtems_bsd_program_control *prog_ctrl, int fd)
+{
+ struct program_fd_item *current;
+ int rv = -1;
+
+ for (current = prog_ctrl->open_fd.lh_first;
+ current != NULL;
+ current = current->entries.le_next) {
+ if (current->fd == fd) {
+ LIST_REMOVE(current, entries);
+ free(current);
+ rv = 0;
+ break;
+ }
+ }
+
+ return rv;
+}
+
+static int
+fd_close_remove(struct rtems_bsd_program_control *prog_ctrl, int fd)
+{
+ int rv = -1;
+
+ rv = fd_remove(prog_ctrl, fd);
+ if (rv == 0) {
+ rv = close(fd);
+ }
+
+ return rv;
+}
+
+static void
+fd_close_all(struct rtems_bsd_program_control *prog_ctrl)
+{
+ while(prog_ctrl->open_fd.lh_first != NULL) {
+ struct program_fd_item *current;
+ int fd;
+ int rv;
+
+ current = prog_ctrl->open_fd.lh_first;
+ fd = current->fd;
+
+ rv = fd_close_remove(prog_ctrl, fd);
+ if (rv != 0) {
+ syslog(LOG_ERR,
+ "BSD Program: Could not close file %d or could not remove it from list of open files",
+ fd);
+ }
+ }
+}
+
+static int
+file_remove(struct rtems_bsd_program_control *prog_ctrl, FILE *file)
+{
+ struct program_file_item *current;
+ int rv = EOF;
+
+ for (current = prog_ctrl->open_file.lh_first;
+ current != NULL;
+ current = current->entries.le_next) {
+ if (current->file == file) {
+ LIST_REMOVE(current, entries);
+ free(current);
+ rv = 0;
+ break;
+ }
+ }
+
+ return rv;
+}
+
+static int
+file_close_remove(struct rtems_bsd_program_control *prog_ctrl, FILE *file)
+{
+ int rv = EOF;
+
+ rv = file_remove(prog_ctrl, file);
+ if (rv == 0) {
+ rv = fclose(file);
+ }
+
+ return rv;
+}
+
+static void
+file_close_all(struct rtems_bsd_program_control *prog_ctrl)
+{
+ while(prog_ctrl->open_file.lh_first != NULL) {
+ struct program_file_item *current;
+ FILE *file;
+ int rv;
+
+ current = prog_ctrl->open_file.lh_first;
+ file = current->file;
+
+ rv = file_close_remove(prog_ctrl, file);
+ if (rv != 0) {
+ syslog(LOG_ERR,
+ "BSD Program: Could not close stream %p or could not remove it from list of open streams",
+ file);
+ }
+ }
+}
+
+static int
+allocmem_remove(struct rtems_bsd_program_control *prog_ctrl, void *ptr)
+{
+ struct program_allocmem_item *current;
+ int rv = -1;
+
+ for (current = prog_ctrl->allocated_mem.lh_first;
+ current != NULL;
+ current = current->entries.le_next) {
+ if (current->ptr == ptr) {
+ LIST_REMOVE(current, entries);
+ rv = 0;
+ break;
+ }
+ }
+
+ return rv;
+}
+
+static int
+allocmem_free_remove(struct rtems_bsd_program_control *prog_ctrl, void *ptr)
+{
+ int rv = -1;
+
+ rv = allocmem_remove(prog_ctrl, ptr);
+ if (rv == 0) {
+ free(ptr);
+ }
+
+ return rv;
+}
+
+static void
+allocmem_free_all(struct rtems_bsd_program_control *prog_ctrl)
+{
+ while(prog_ctrl->allocated_mem.lh_first != NULL) {
+ struct program_allocmem_item *current;
+ void *ptr;
+ int rv;
+
+ current = prog_ctrl->allocated_mem.lh_first;
+ ptr = current->ptr;
+
+ rv = allocmem_free_remove(prog_ctrl, ptr);
+ if (rv != 0) {
+ /* This should never happen. It would mean that someone
+ * changed the allocmem list while we are removing the
+ * element. */
+ syslog(LOG_ERR,
+ "BSD Program: Could not remove %p from list of allocated memory",
+ ptr);
+ }
+ }
+}
+
+static void
+call_destructors(struct rtems_bsd_program_control *prog_ctrl)
+{
+ struct program_destructor *node;
+ struct program_destructor *tmp;
+
+ LIST_FOREACH_SAFE(node, &prog_ctrl->destructors, link, tmp) {
+ (*node->destructor)(node->arg);
+ free(node);
+ }
+}
+
+int
+rtems_bsd_program_call(const char *name, int (*prog)(void *), void *context)
+{
+ struct rtems_bsd_program_control *prog_ctrl;
+ int error;
+ int exit_code;
+
+ prog_ctrl = calloc(1, sizeof(*prog_ctrl));
+ if (prog_ctrl == NULL) {
+ errno = ENOMEM;
+ return (EXIT_FAILURE);
+ }
+
+ error = rtems_bsd_program_set_control(prog_ctrl);
+ if (error != 0) {
+ free(prog_ctrl);
+ errno = error;
+ return (EXIT_FAILURE);
+ }
+
+ prog_ctrl->context = context;
+ prog_ctrl->name = name;
+ prog_ctrl->exit_code = EXIT_FAILURE;
+
+ LIST_INIT(&prog_ctrl->open_fd);
+ LIST_INIT(&prog_ctrl->open_file);
+ LIST_INIT(&prog_ctrl->allocated_mem);
+ LIST_INIT(&prog_ctrl->destructors);
+
+ if (setjmp(prog_ctrl->return_context) == 0) {
+ exit_code = (*prog)(context);
+ } else {
+ exit_code = prog_ctrl->exit_code;
+ }
+
+ rtems_bsd_program_set_control(NULL);
+ fd_close_all(prog_ctrl);
+ file_close_all(prog_ctrl);
+ allocmem_free_all(prog_ctrl);
+ call_destructors(prog_ctrl);
+ free(prog_ctrl);
+ return (exit_code);
+}
+
+void *
+rtems_bsd_program_add_destructor(void (*destructor)(void *), void *arg)
+{
+ struct rtems_bsd_program_control *prog_ctrl;
+ struct program_destructor *node;
+
+ prog_ctrl = rtems_bsd_program_get_control_or_null();
+ if (prog_ctrl == NULL) {
+ return (NULL);
+ }
+
+ node = malloc(sizeof(*node));
+ if (node == NULL) {
+ return (NULL);
+ }
+
+ node->destructor = destructor;
+ node->arg = arg;
+ LIST_INSERT_HEAD(&prog_ctrl->destructors, node, link);
+ return (node);
+}
+
+void
+rtems_bsd_program_remove_destructor(void *cookie, bool call)
+{
+ struct program_destructor *node;
+
+ node = cookie;
+ LIST_REMOVE(node, link);
+
+ if (call) {
+ (*node->destructor)(node->arg);
+ }
+
+ free(node);
+}
+
+void
+rtems_bsd_program_exit(int exit_code)
+{
+ struct rtems_bsd_program_control *prog_ctrl =
+ rtems_bsd_program_get_control_or_null();
+
+ if (prog_ctrl != NULL) {
+ prog_ctrl->exit_code = exit_code;
+ longjmp(prog_ctrl->return_context, 1);
+ }
+
+ assert(0);
+}
+
+void
+rtems_bsd_program_error(const char *fmt, ...)
+{
+ va_list list;
+ va_start(list, fmt);
+ vfprintf(stderr, fmt, list);
+ fprintf(stderr, "\n");
+ va_end(list);
+ rtems_bsd_program_exit(1);
+}
+
+const char *
+rtems_bsd_program_get_name(void)
+{
+ struct rtems_bsd_program_control *prog_ctrl =
+ rtems_bsd_program_get_control_or_null();
+ const char *name = "?";
+
+ if (prog_ctrl != NULL) {
+ name = prog_ctrl->name;
+ }
+
+ return name;
+}
+
+void *
+rtems_bsd_program_get_context(void)
+{
+ struct rtems_bsd_program_control *prog_ctrl =
+ rtems_bsd_program_get_control_or_null();
+ void *context = NULL;
+
+ if (prog_ctrl != NULL) {
+ context = prog_ctrl->context;
+ }
+
+ return context;
+}
+
+struct main_context {
+ int argc;
+ char **argv;
+ int (*main)(int, char **);
+};
+
+static int
+call_main(void *ctx)
+{
+ const struct main_context *mc = ctx;
+
+ return (*mc->main)(mc->argc, mc->argv);
+}
+
+int
+rtems_bsd_program_call_main(const char *name, int (*main)(int, char **),
+ int argc, char **argv)
+{
+ struct main_context mc = {
+ .argc = argc,
+ .argv = argv,
+ .main = main
+ };
+ int exit_code;
+
+ if (argv[argc] == NULL) {
+ exit_code = rtems_bsd_program_call(name, call_main, &mc);
+ } else {
+ errno = EFAULT;
+ exit_code = EXIT_FAILURE;
+ }
+
+ return exit_code;
+}
+
+int
+rtems_bsd_program_call_main_with_data_restore(const char *name,
+ int (*main)(int, char **), int argc, char **argv,
+ void *data_buf, const size_t data_size)
+{
+ int exit_code = EXIT_FAILURE;
+ void *savebuf;
+
+ savebuf = malloc(data_size);
+ if (savebuf == NULL) {
+ errno = ENOMEM;
+ exit_code = EXIT_FAILURE;
+ } else {
+ memcpy(savebuf, data_buf, data_size);
+ exit_code = rtems_bsd_program_call_main(name, main, argc,
+ argv);
+ memcpy(data_buf, savebuf, data_size);
+ free(savebuf);
+ }
+
+ return exit_code;
+}
+
+int
+rtems_bsd_program_open(const char *path, int oflag, ...)
+{
+ struct rtems_bsd_program_control *prog_ctrl =
+ rtems_bsd_program_get_control_or_null();
+ va_list list;
+ mode_t mode = 0;
+ int fd = -1;
+
+ if (prog_ctrl != NULL) {
+ struct program_fd_item *item =
+ malloc(sizeof(*item));
+
+ if (item != NULL) {
+ va_start(list, oflag);
+ mode = va_arg(list, mode_t);
+
+ fd = open(path, oflag, mode);
+
+ va_end(list);
+
+ if (fd != -1) {
+ item->fd = fd;
+ LIST_INSERT_HEAD(&(prog_ctrl->open_fd),
+ item, entries);
+ } else {
+ free(item);
+ }
+ } else {
+ errno = ENOMEM;
+ }
+ }
+
+ return fd;
+}
+
+int
+rtems_bsd_program_close(int fd)
+{
+ struct rtems_bsd_program_control *prog_ctrl =
+ rtems_bsd_program_get_control_or_null();
+ int rv = -1;
+
+ if (prog_ctrl != NULL) {
+ rv = fd_close_remove(prog_ctrl, fd);
+ }
+
+ return rv;
+}
+
+FILE *
+rtems_bsd_program_fopen(const char *restrict filename,
+ const char *restrict mode)
+{
+ FILE *file = NULL;
+ struct rtems_bsd_program_control *prog_ctrl =
+ rtems_bsd_program_get_control_or_null();
+
+ if (prog_ctrl != NULL) {
+ struct program_file_item *item = malloc(sizeof(*item));
+
+ if (item != NULL) {
+ file = fopen(filename, mode);
+
+ if (file != NULL) {
+ item->file = file;
+ LIST_INSERT_HEAD(
+ &(prog_ctrl->open_file), item,
+ entries);
+ } else {
+ free(item);
+ }
+ } else {
+ errno = ENOMEM;
+ }
+ }
+
+ return file;
+}
+
+int
+rtems_bsd_program_fclose(FILE *file)
+{
+ struct rtems_bsd_program_control *prog_ctrl =
+ rtems_bsd_program_get_control_or_null();
+ int rv = EOF;
+
+ if (prog_ctrl != NULL) {
+ rv = file_close_remove(prog_ctrl, file);
+ }
+
+ return rv;
+}
+
+static void *
+rtems_bsd_program_alloc(size_t size, void *org_ptr)
+{
+ struct rtems_bsd_program_control *prog_ctrl =
+ rtems_bsd_program_get_control_or_null();
+ void *ptr = NULL;
+ size_t size_with_list;
+ size_t size_alligned;
+ size_t alignment = sizeof(void*);
+
+ if (prog_ctrl != NULL) {
+ /* align the end to the next word address */
+ size_alligned = size;
+ if ((size_alligned & (alignment - 1)) != 0) {
+ size_alligned = (size_alligned | (alignment - 1)) + 1;
+ }
+ size_with_list = size_alligned +
+ sizeof(struct program_allocmem_item);
+
+ if (org_ptr != NULL) {
+ /* It's a reallocation. So first remove the old pointer
+ * from the list */
+ allocmem_remove(prog_ctrl, org_ptr);
+ }
+
+ ptr = realloc(org_ptr, size_with_list);
+
+ if (ptr != NULL) {
+ struct program_allocmem_item *item;
+ item = ptr + size_alligned;
+ item->ptr = ptr;
+ LIST_INSERT_HEAD(&(prog_ctrl->allocated_mem),
+ item, entries);
+ }
+ }
+
+ return ptr;
+}
+
+void *
+rtems_bsd_program_malloc(size_t size)
+{
+ return rtems_bsd_program_alloc(size, NULL);
+}
+
+void *
+rtems_bsd_program_calloc(size_t nelem, size_t elsize)
+{
+ void *ptr;
+ size_t size = elsize * nelem;
+
+ ptr = rtems_bsd_program_alloc(size, NULL);
+ if (ptr != NULL) {
+ memset(ptr, 0, size);
+ }
+
+ return ptr;
+}
+
+void *
+rtems_bsd_program_realloc(void *ptr, size_t size)
+{
+ return rtems_bsd_program_alloc(size, ptr);
+}
+
+void *
+rtems_bsd_program_reallocf(void *ptr, size_t size)
+{
+ void *ret = rtems_bsd_program_alloc(size, ptr);
+ if (ret == NULL) {
+ free(ptr);
+ }
+ return ret;
+}
+
+char *
+rtems_bsd_program_strdup(const char *s)
+{
+ size_t size;
+ void *s2;
+
+ size = strlen(s) + 1;
+ s2 = rtems_bsd_program_alloc(size, NULL);
+ if (s2 == NULL) {
+ return (NULL);
+ }
+
+ return (memcpy(s2, s, size));
+}
+
+char *
+rtems_bsd_program_strndup(const char *s, size_t size)
+{
+ void *s2;
+
+ size = strnlen(s, size) + 1;
+ s2 = rtems_bsd_program_alloc(size, NULL);
+ if (s2 == NULL) {
+ return (NULL);
+ }
+
+ return (memcpy(s2, s, size));
+}
+
+int
+rtems_bsd_program_vasprintf(char **strp, const char *fmt, va_list ap)
+{
+ va_list aq;
+ int size;
+ int rv = -1;
+
+ va_copy(aq, ap);
+ size = vsnprintf(NULL, 0, fmt, aq);
+ va_end(aq);
+
+ size += 1; /* Add space for terminating null byte */
+ *strp = rtems_bsd_program_alloc(size, NULL);
+
+ if (*strp != NULL) {
+ rv = vsnprintf(*strp, size, fmt, ap);
+ }
+
+ return rv;
+}
+
+int
+rtems_bsd_program_asprintf(char **strp, const char *fmt, ...)
+{
+ va_list ap;
+ int rv;
+
+ va_start(ap, fmt);
+
+ rv = rtems_bsd_program_vasprintf(strp, fmt, ap);
+
+ va_end(ap);
+
+ return rv;
+}
+
+void
+rtems_bsd_program_free(void *ptr)
+{
+ if (ptr != NULL) {
+ struct rtems_bsd_program_control *prog_ctrl =
+ rtems_bsd_program_get_control_or_null();
+
+ if (prog_ctrl != NULL) {
+ int rv = allocmem_free_remove(prog_ctrl, ptr);
+ assert(rv == 0);
+ } else {
+ /* Outside of program context. Just free it. */
+ free(ptr);
+ }
+ }
+}