1c0b746e5SOllivier Robert /* 2c0b746e5SOllivier Robert * pretty printing of status information 3c0b746e5SOllivier Robert */ 4c0b746e5SOllivier Robert #ifdef HAVE_CONFIG_H 5c0b746e5SOllivier Robert #include <config.h> 6c0b746e5SOllivier Robert #endif 7c0b746e5SOllivier Robert #include <stdio.h> 8c0b746e5SOllivier Robert #include "ntp_stdlib.h" 9c0b746e5SOllivier Robert #include "ntp_fp.h" 10c0b746e5SOllivier Robert #include "ntp.h" 11c0b746e5SOllivier Robert #include "lib_strbuf.h" 12c0b746e5SOllivier Robert #include "ntp_refclock.h" 13c0b746e5SOllivier Robert #include "ntp_control.h" 14c0b746e5SOllivier Robert #include "ntp_string.h" 152b15cb3dSCy Schubert #ifdef KERNEL_PLL 162b15cb3dSCy Schubert # include "ntp_syscall.h" 172b15cb3dSCy Schubert #endif 182b15cb3dSCy Schubert 19c0b746e5SOllivier Robert 20c0b746e5SOllivier Robert /* 21c0b746e5SOllivier Robert * Structure for turning various constants into a readable string. 22c0b746e5SOllivier Robert */ 23c0b746e5SOllivier Robert struct codestring { 24c0b746e5SOllivier Robert int code; 252b15cb3dSCy Schubert const char * const string; 26c0b746e5SOllivier Robert }; 27c0b746e5SOllivier Robert 28c0b746e5SOllivier Robert /* 292b15cb3dSCy Schubert * Leap status (leap) 30c0b746e5SOllivier Robert */ 312b15cb3dSCy Schubert static const struct codestring leap_codes[] = { 32c0b746e5SOllivier Robert { LEAP_NOWARNING, "leap_none" }, 33c0b746e5SOllivier Robert { LEAP_ADDSECOND, "leap_add_sec" }, 34c0b746e5SOllivier Robert { LEAP_DELSECOND, "leap_del_sec" }, 352b15cb3dSCy Schubert { LEAP_NOTINSYNC, "leap_alarm" }, 36c0b746e5SOllivier Robert { -1, "leap" } 37c0b746e5SOllivier Robert }; 38c0b746e5SOllivier Robert 39c0b746e5SOllivier Robert /* 402b15cb3dSCy Schubert * Clock source status (sync) 41c0b746e5SOllivier Robert */ 422b15cb3dSCy Schubert static const struct codestring sync_codes[] = { 43c0b746e5SOllivier Robert { CTL_SST_TS_UNSPEC, "sync_unspec" }, 442b15cb3dSCy Schubert { CTL_SST_TS_ATOM, "sync_pps" }, 452b15cb3dSCy Schubert { CTL_SST_TS_LF, "sync_lf_radio" }, 462b15cb3dSCy Schubert { CTL_SST_TS_HF, "sync_hf_radio" }, 472b15cb3dSCy Schubert { CTL_SST_TS_UHF, "sync_uhf_radio" }, 482b15cb3dSCy Schubert { CTL_SST_TS_LOCAL, "sync_local" }, 49c0b746e5SOllivier Robert { CTL_SST_TS_NTP, "sync_ntp" }, 502b15cb3dSCy Schubert { CTL_SST_TS_UDPTIME, "sync_other" }, 51c0b746e5SOllivier Robert { CTL_SST_TS_WRSTWTCH, "sync_wristwatch" }, 52c0b746e5SOllivier Robert { CTL_SST_TS_TELEPHONE, "sync_telephone" }, 53c0b746e5SOllivier Robert { -1, "sync" } 54c0b746e5SOllivier Robert }; 55c0b746e5SOllivier Robert 56c0b746e5SOllivier Robert /* 572b15cb3dSCy Schubert * Peer selection status (sel) 58c0b746e5SOllivier Robert */ 592b15cb3dSCy Schubert static const struct codestring select_codes[] = { 602b15cb3dSCy Schubert { CTL_PST_SEL_REJECT, "sel_reject" }, 61c0b746e5SOllivier Robert { CTL_PST_SEL_SANE, "sel_falsetick" }, 62c0b746e5SOllivier Robert { CTL_PST_SEL_CORRECT, "sel_excess" }, 639034852cSGleb Smirnoff { CTL_PST_SEL_SELCAND, "sel_outlier" }, 642b15cb3dSCy Schubert { CTL_PST_SEL_SYNCCAND, "sel_candidate" }, 652b15cb3dSCy Schubert { CTL_PST_SEL_EXCESS, "sel_backup" }, 66c0b746e5SOllivier Robert { CTL_PST_SEL_SYSPEER, "sel_sys.peer" }, 67c0b746e5SOllivier Robert { CTL_PST_SEL_PPS, "sel_pps.peer" }, 68c0b746e5SOllivier Robert { -1, "sel" } 69c0b746e5SOllivier Robert }; 70c0b746e5SOllivier Robert 71c0b746e5SOllivier Robert /* 722b15cb3dSCy Schubert * Clock status (clk) 73c0b746e5SOllivier Robert */ 742b15cb3dSCy Schubert static const struct codestring clock_codes[] = { 752b15cb3dSCy Schubert { CTL_CLK_OKAY, "clk_unspec" }, 762b15cb3dSCy Schubert { CTL_CLK_NOREPLY, "clk_no_reply" }, 772b15cb3dSCy Schubert { CTL_CLK_BADFORMAT, "clk_bad_format" }, 78c0b746e5SOllivier Robert { CTL_CLK_FAULT, "clk_fault" }, 792b15cb3dSCy Schubert { CTL_CLK_PROPAGATION, "clk_bad_signal" }, 802b15cb3dSCy Schubert { CTL_CLK_BADDATE, "clk_bad_date" }, 812b15cb3dSCy Schubert { CTL_CLK_BADTIME, "clk_bad_time" }, 82c0b746e5SOllivier Robert { -1, "clk" } 83c0b746e5SOllivier Robert }; 84c0b746e5SOllivier Robert 85c0b746e5SOllivier Robert 862b15cb3dSCy Schubert #ifdef FLASH_CODES_UNUSED 87c0b746e5SOllivier Robert /* 882b15cb3dSCy Schubert * Flash bits -- see ntpq.c tstflags & tstflagnames 89c0b746e5SOllivier Robert */ 902b15cb3dSCy Schubert static const struct codestring flash_codes[] = { 912b15cb3dSCy Schubert { TEST1, "pkt_dup" }, 922b15cb3dSCy Schubert { TEST2, "pkt_bogus" }, 932b15cb3dSCy Schubert { TEST3, "pkt_unsync" }, 942b15cb3dSCy Schubert { TEST4, "pkt_denied" }, 952b15cb3dSCy Schubert { TEST5, "pkt_auth" }, 962b15cb3dSCy Schubert { TEST6, "pkt_stratum" }, 972b15cb3dSCy Schubert { TEST7, "pkt_header" }, 982b15cb3dSCy Schubert { TEST8, "pkt_autokey" }, 992b15cb3dSCy Schubert { TEST9, "pkt_crypto" }, 1002b15cb3dSCy Schubert { TEST10, "peer_stratum" }, 1012b15cb3dSCy Schubert { TEST11, "peer_dist" }, 1022b15cb3dSCy Schubert { TEST12, "peer_loop" }, 1032b15cb3dSCy Schubert { TEST13, "peer_unreach" }, 1042b15cb3dSCy Schubert { -1, "flash" } 105c0b746e5SOllivier Robert }; 106c0b746e5SOllivier Robert #endif 1072b15cb3dSCy Schubert 1082b15cb3dSCy Schubert 1092b15cb3dSCy Schubert /* 1102b15cb3dSCy Schubert * System events (sys) 1112b15cb3dSCy Schubert */ 1122b15cb3dSCy Schubert static const struct codestring sys_codes[] = { 1132b15cb3dSCy Schubert { EVNT_UNSPEC, "unspecified" }, 1142b15cb3dSCy Schubert { EVNT_NSET, "freq_not_set" }, 1152b15cb3dSCy Schubert { EVNT_FSET, "freq_set" }, 1162b15cb3dSCy Schubert { EVNT_SPIK, "spike_detect" }, 1172b15cb3dSCy Schubert { EVNT_FREQ, "freq_mode" }, 1182b15cb3dSCy Schubert { EVNT_SYNC, "clock_sync" }, 1192b15cb3dSCy Schubert { EVNT_SYSRESTART, "restart" }, 1202b15cb3dSCy Schubert { EVNT_SYSFAULT, "panic_stop" }, 1212b15cb3dSCy Schubert { EVNT_NOPEER, "no_sys_peer" }, 1222b15cb3dSCy Schubert { EVNT_ARMED, "leap_armed" }, 1232b15cb3dSCy Schubert { EVNT_DISARMED, "leap_disarmed" }, 1242b15cb3dSCy Schubert { EVNT_LEAP, "leap_event" }, 1252b15cb3dSCy Schubert { EVNT_CLOCKRESET, "clock_step" }, 1262b15cb3dSCy Schubert { EVNT_KERN, "kern" }, 1272b15cb3dSCy Schubert { EVNT_TAI, "TAI" }, 1282b15cb3dSCy Schubert { EVNT_LEAPVAL, "stale_leapsecond_values" }, 1292b15cb3dSCy Schubert { -1, "" } 130c0b746e5SOllivier Robert }; 131c0b746e5SOllivier Robert 1329c2daa00SOllivier Robert /* 1332b15cb3dSCy Schubert * Peer events (peer) 1349c2daa00SOllivier Robert */ 1352b15cb3dSCy Schubert static const struct codestring peer_codes[] = { 1362b15cb3dSCy Schubert { PEVNT_MOBIL & ~PEER_EVENT, "mobilize" }, 1372b15cb3dSCy Schubert { PEVNT_DEMOBIL & ~PEER_EVENT, "demobilize" }, 1382b15cb3dSCy Schubert { PEVNT_UNREACH & ~PEER_EVENT, "unreachable" }, 1392b15cb3dSCy Schubert { PEVNT_REACH & ~PEER_EVENT, "reachable" }, 1402b15cb3dSCy Schubert { PEVNT_RESTART & ~PEER_EVENT, "restart" }, 1412b15cb3dSCy Schubert { PEVNT_REPLY & ~PEER_EVENT, "no_reply" }, 1422b15cb3dSCy Schubert { PEVNT_RATE & ~PEER_EVENT, "rate_exceeded" }, 1432b15cb3dSCy Schubert { PEVNT_DENY & ~PEER_EVENT, "access_denied" }, 1442b15cb3dSCy Schubert { PEVNT_ARMED & ~PEER_EVENT, "leap_armed" }, 1452b15cb3dSCy Schubert { PEVNT_NEWPEER & ~PEER_EVENT, "sys_peer" }, 1462b15cb3dSCy Schubert { PEVNT_CLOCK & ~PEER_EVENT, "clock_event" }, 1472b15cb3dSCy Schubert { PEVNT_AUTH & ~PEER_EVENT, "bad_auth" }, 1482b15cb3dSCy Schubert { PEVNT_POPCORN & ~PEER_EVENT, "popcorn" }, 1492b15cb3dSCy Schubert { PEVNT_XLEAVE & ~PEER_EVENT, "interleave_mode" }, 1502b15cb3dSCy Schubert { PEVNT_XERR & ~PEER_EVENT, "interleave_error" }, 1512b15cb3dSCy Schubert { -1, "" } 1522b15cb3dSCy Schubert }; 1532b15cb3dSCy Schubert 1542b15cb3dSCy Schubert /* 1552b15cb3dSCy Schubert * Peer status bits 1562b15cb3dSCy Schubert */ 1572b15cb3dSCy Schubert static const struct codestring peer_st_bits[] = { 1582b15cb3dSCy Schubert { CTL_PST_CONFIG, "conf" }, 1592b15cb3dSCy Schubert { CTL_PST_AUTHENABLE, "authenb" }, 1602b15cb3dSCy Schubert { CTL_PST_AUTHENTIC, "auth" }, 1612b15cb3dSCy Schubert { CTL_PST_REACH, "reach" }, 1622b15cb3dSCy Schubert { CTL_PST_BCAST, "bcast" }, 1632b15cb3dSCy Schubert /* not used with getcode(), no terminating entry needed */ 1642b15cb3dSCy Schubert }; 1652b15cb3dSCy Schubert 1662b15cb3dSCy Schubert /* 1672b15cb3dSCy Schubert * Restriction match bits 1682b15cb3dSCy Schubert */ 1692b15cb3dSCy Schubert static const struct codestring res_match_bits[] = { 1702b15cb3dSCy Schubert { RESM_NTPONLY, "ntpport" }, 1712b15cb3dSCy Schubert { RESM_INTERFACE, "interface" }, 1722b15cb3dSCy Schubert { RESM_SOURCE, "source" }, 1732b15cb3dSCy Schubert /* not used with getcode(), no terminating entry needed */ 1742b15cb3dSCy Schubert }; 1752b15cb3dSCy Schubert 1762b15cb3dSCy Schubert /* 1772b15cb3dSCy Schubert * Restriction access bits 1782b15cb3dSCy Schubert */ 1792b15cb3dSCy Schubert static const struct codestring res_access_bits[] = { 1802b15cb3dSCy Schubert { RES_IGNORE, "ignore" }, 1812b15cb3dSCy Schubert { RES_DONTSERVE, "noserve" }, 1822b15cb3dSCy Schubert { RES_DONTTRUST, "notrust" }, 1832b15cb3dSCy Schubert { RES_NOQUERY, "noquery" }, 1842b15cb3dSCy Schubert { RES_NOMODIFY, "nomodify" }, 1852b15cb3dSCy Schubert { RES_NOPEER, "nopeer" }, 1862b15cb3dSCy Schubert { RES_NOTRAP, "notrap" }, 1872b15cb3dSCy Schubert { RES_LPTRAP, "lptrap" }, 1882b15cb3dSCy Schubert { RES_LIMITED, "limited" }, 1892b15cb3dSCy Schubert { RES_VERSION, "version" }, 1902b15cb3dSCy Schubert { RES_KOD, "kod" }, 1912b15cb3dSCy Schubert { RES_FLAKE, "flake" }, 1922b15cb3dSCy Schubert /* not used with getcode(), no terminating entry needed */ 1932b15cb3dSCy Schubert }; 1942b15cb3dSCy Schubert 1952b15cb3dSCy Schubert #ifdef AUTOKEY 1962b15cb3dSCy Schubert /* 1972b15cb3dSCy Schubert * Crypto events (cryp) 1982b15cb3dSCy Schubert */ 1992b15cb3dSCy Schubert static const struct codestring crypto_codes[] = { 2009c2daa00SOllivier Robert { XEVNT_OK & ~CRPT_EVENT, "success" }, 2019c2daa00SOllivier Robert { XEVNT_LEN & ~CRPT_EVENT, "bad_field_format_or_length" }, 2029c2daa00SOllivier Robert { XEVNT_TSP & ~CRPT_EVENT, "bad_timestamp" }, 2039c2daa00SOllivier Robert { XEVNT_FSP & ~CRPT_EVENT, "bad_filestamp" }, 204ea906c41SOllivier Robert { XEVNT_PUB & ~CRPT_EVENT, "bad_or_missing_public_key" }, 2059c2daa00SOllivier Robert { XEVNT_MD & ~CRPT_EVENT, "unsupported_digest_type" }, 2069c2daa00SOllivier Robert { XEVNT_KEY & ~CRPT_EVENT, "unsupported_identity_type" }, 2079c2daa00SOllivier Robert { XEVNT_SGL & ~CRPT_EVENT, "bad_signature_length" }, 2089c2daa00SOllivier Robert { XEVNT_SIG & ~CRPT_EVENT, "signature_not_verified" }, 209ea906c41SOllivier Robert { XEVNT_VFY & ~CRPT_EVENT, "certificate_not_verified" }, 2102b15cb3dSCy Schubert { XEVNT_PER & ~CRPT_EVENT, "host_certificate_expired" }, 2119c2daa00SOllivier Robert { XEVNT_CKY & ~CRPT_EVENT, "bad_or_missing_cookie" }, 2122b15cb3dSCy Schubert { XEVNT_DAT & ~CRPT_EVENT, "bad_or_missing_leapseconds" }, 2139c2daa00SOllivier Robert { XEVNT_CRT & ~CRPT_EVENT, "bad_or_missing_certificate" }, 2142b15cb3dSCy Schubert { XEVNT_ID & ~CRPT_EVENT, "bad_or_missing_group key" }, 215ea906c41SOllivier Robert { XEVNT_ERR & ~CRPT_EVENT, "protocol_error" }, 2162b15cb3dSCy Schubert { -1, "" } 2179c2daa00SOllivier Robert }; 2182b15cb3dSCy Schubert #endif /* AUTOKEY */ 2192b15cb3dSCy Schubert 2202b15cb3dSCy Schubert #ifdef KERNEL_PLL 2212b15cb3dSCy Schubert /* 2222b15cb3dSCy Schubert * kernel discipline status bits 2232b15cb3dSCy Schubert */ 2242b15cb3dSCy Schubert static const struct codestring k_st_bits[] = { 2252b15cb3dSCy Schubert # ifdef STA_PLL 2262b15cb3dSCy Schubert { STA_PLL, "pll" }, 2272b15cb3dSCy Schubert # endif 2282b15cb3dSCy Schubert # ifdef STA_PPSFREQ 2292b15cb3dSCy Schubert { STA_PPSFREQ, "ppsfreq" }, 2302b15cb3dSCy Schubert # endif 2312b15cb3dSCy Schubert # ifdef STA_PPSTIME 2322b15cb3dSCy Schubert { STA_PPSTIME, "ppstime" }, 2332b15cb3dSCy Schubert # endif 2342b15cb3dSCy Schubert # ifdef STA_FLL 2352b15cb3dSCy Schubert { STA_FLL, "fll" }, 2362b15cb3dSCy Schubert # endif 2372b15cb3dSCy Schubert # ifdef STA_INS 2382b15cb3dSCy Schubert { STA_INS, "ins" }, 2392b15cb3dSCy Schubert # endif 2402b15cb3dSCy Schubert # ifdef STA_DEL 2412b15cb3dSCy Schubert { STA_DEL, "del" }, 2422b15cb3dSCy Schubert # endif 2432b15cb3dSCy Schubert # ifdef STA_UNSYNC 2442b15cb3dSCy Schubert { STA_UNSYNC, "unsync" }, 2452b15cb3dSCy Schubert # endif 2462b15cb3dSCy Schubert # ifdef STA_FREQHOLD 2472b15cb3dSCy Schubert { STA_FREQHOLD, "freqhold" }, 2482b15cb3dSCy Schubert # endif 2492b15cb3dSCy Schubert # ifdef STA_PPSSIGNAL 2502b15cb3dSCy Schubert { STA_PPSSIGNAL, "ppssignal" }, 2512b15cb3dSCy Schubert # endif 2522b15cb3dSCy Schubert # ifdef STA_PPSJITTER 2532b15cb3dSCy Schubert { STA_PPSJITTER, "ppsjitter" }, 2542b15cb3dSCy Schubert # endif 2552b15cb3dSCy Schubert # ifdef STA_PPSWANDER 2562b15cb3dSCy Schubert { STA_PPSWANDER, "ppswander" }, 2572b15cb3dSCy Schubert # endif 2582b15cb3dSCy Schubert # ifdef STA_PPSERROR 2592b15cb3dSCy Schubert { STA_PPSERROR, "ppserror" }, 2602b15cb3dSCy Schubert # endif 2612b15cb3dSCy Schubert # ifdef STA_CLOCKERR 2622b15cb3dSCy Schubert { STA_CLOCKERR, "clockerr" }, 2632b15cb3dSCy Schubert # endif 2642b15cb3dSCy Schubert # ifdef STA_NANO 2652b15cb3dSCy Schubert { STA_NANO, "nano" }, 2662b15cb3dSCy Schubert # endif 2672b15cb3dSCy Schubert # ifdef STA_MODE 2682b15cb3dSCy Schubert { STA_MODE, "mode=fll" }, 2692b15cb3dSCy Schubert # endif 2702b15cb3dSCy Schubert # ifdef STA_CLK 2712b15cb3dSCy Schubert { STA_CLK, "src=B" }, 2722b15cb3dSCy Schubert # endif 2732b15cb3dSCy Schubert /* not used with getcode(), no terminating entry needed */ 2742b15cb3dSCy Schubert }; 2752b15cb3dSCy Schubert #endif /* KERNEL_PLL */ 2769c2daa00SOllivier Robert 277c0b746e5SOllivier Robert /* Forwards */ 2782b15cb3dSCy Schubert static const char * getcode(int, const struct codestring *); 2792b15cb3dSCy Schubert static const char * getevents(int); 2802b15cb3dSCy Schubert static const char * peer_st_flags(u_char pst); 281c0b746e5SOllivier Robert 282c0b746e5SOllivier Robert /* 283c0b746e5SOllivier Robert * getcode - return string corresponding to code 284c0b746e5SOllivier Robert */ 285c0b746e5SOllivier Robert static const char * 286c0b746e5SOllivier Robert getcode( 287c0b746e5SOllivier Robert int code, 2882b15cb3dSCy Schubert const struct codestring * codetab 289c0b746e5SOllivier Robert ) 290c0b746e5SOllivier Robert { 2912b15cb3dSCy Schubert char * buf; 292c0b746e5SOllivier Robert 293c0b746e5SOllivier Robert while (codetab->code != -1) { 294c0b746e5SOllivier Robert if (codetab->code == code) 295c0b746e5SOllivier Robert return codetab->string; 296c0b746e5SOllivier Robert codetab++; 297c0b746e5SOllivier Robert } 2982b15cb3dSCy Schubert 2992b15cb3dSCy Schubert LIB_GETBUF(buf); 3002b15cb3dSCy Schubert snprintf(buf, LIB_BUFLENGTH, "%s_%d", codetab->string, code); 3012b15cb3dSCy Schubert 302c0b746e5SOllivier Robert return buf; 303c0b746e5SOllivier Robert } 304c0b746e5SOllivier Robert 305c0b746e5SOllivier Robert /* 306c0b746e5SOllivier Robert * getevents - return a descriptive string for the event count 307c0b746e5SOllivier Robert */ 308c0b746e5SOllivier Robert static const char * 309c0b746e5SOllivier Robert getevents( 310c0b746e5SOllivier Robert int cnt 311c0b746e5SOllivier Robert ) 312c0b746e5SOllivier Robert { 3132b15cb3dSCy Schubert char * buf; 314c0b746e5SOllivier Robert 315c0b746e5SOllivier Robert if (cnt == 0) 316c0b746e5SOllivier Robert return "no events"; 3172b15cb3dSCy Schubert 3182b15cb3dSCy Schubert LIB_GETBUF(buf); 3192b15cb3dSCy Schubert snprintf(buf, LIB_BUFLENGTH, "%d event%s", cnt, 3202b15cb3dSCy Schubert (1 == cnt) 3212b15cb3dSCy Schubert ? "" 3222b15cb3dSCy Schubert : "s"); 3232b15cb3dSCy Schubert 324c0b746e5SOllivier Robert return buf; 325c0b746e5SOllivier Robert } 326c0b746e5SOllivier Robert 3272b15cb3dSCy Schubert 3282b15cb3dSCy Schubert /* 3292b15cb3dSCy Schubert * decode_bitflags() 3302b15cb3dSCy Schubert * 3312b15cb3dSCy Schubert * returns a human-readable string with a keyword from tab for each bit 3322b15cb3dSCy Schubert * set in bits, separating multiple entries with text of sep2. 3332b15cb3dSCy Schubert */ 3342b15cb3dSCy Schubert static const char * 3352b15cb3dSCy Schubert decode_bitflags( 3362b15cb3dSCy Schubert int bits, 3372b15cb3dSCy Schubert const char * sep2, 3382b15cb3dSCy Schubert const struct codestring * tab, 3392b15cb3dSCy Schubert size_t tab_ct 3402b15cb3dSCy Schubert ) 3412b15cb3dSCy Schubert { 3422b15cb3dSCy Schubert const char * sep; 3432b15cb3dSCy Schubert char * buf; 3442b15cb3dSCy Schubert char * pch; 3452b15cb3dSCy Schubert char * lim; 3462b15cb3dSCy Schubert size_t b; 3472b15cb3dSCy Schubert int rc; 3482b15cb3dSCy Schubert int saved_errno; /* for use in DPRINTF with %m */ 3492b15cb3dSCy Schubert 3502b15cb3dSCy Schubert saved_errno = errno; 3512b15cb3dSCy Schubert LIB_GETBUF(buf); 3522b15cb3dSCy Schubert pch = buf; 3532b15cb3dSCy Schubert lim = buf + LIB_BUFLENGTH; 3542b15cb3dSCy Schubert sep = ""; 3552b15cb3dSCy Schubert 3562b15cb3dSCy Schubert for (b = 0; b < tab_ct; b++) { 3572b15cb3dSCy Schubert if (tab[b].code & bits) { 358*f0574f5cSXin LI size_t avail = lim - pch; 359*f0574f5cSXin LI rc = snprintf(pch, avail, "%s%s", sep, 3602b15cb3dSCy Schubert tab[b].string); 361*f0574f5cSXin LI if ((size_t)rc >= avail) 3622b15cb3dSCy Schubert goto toosmall; 363*f0574f5cSXin LI pch += rc; 3642b15cb3dSCy Schubert sep = sep2; 3652b15cb3dSCy Schubert } 3662b15cb3dSCy Schubert } 3672b15cb3dSCy Schubert 3682b15cb3dSCy Schubert return buf; 3692b15cb3dSCy Schubert 3702b15cb3dSCy Schubert toosmall: 3712b15cb3dSCy Schubert snprintf(buf, LIB_BUFLENGTH, 3722b15cb3dSCy Schubert "decode_bitflags(%s) can't decode 0x%x in %d bytes", 3732b15cb3dSCy Schubert (tab == peer_st_bits) 3742b15cb3dSCy Schubert ? "peer_st" 3752b15cb3dSCy Schubert : 3762b15cb3dSCy Schubert #ifdef KERNEL_PLL 3772b15cb3dSCy Schubert (tab == k_st_bits) 3782b15cb3dSCy Schubert ? "kern_st" 3792b15cb3dSCy Schubert : 3802b15cb3dSCy Schubert #endif 3812b15cb3dSCy Schubert "", 3822b15cb3dSCy Schubert bits, (int)LIB_BUFLENGTH); 3832b15cb3dSCy Schubert errno = saved_errno; 3842b15cb3dSCy Schubert 3852b15cb3dSCy Schubert return buf; 3862b15cb3dSCy Schubert } 3872b15cb3dSCy Schubert 3882b15cb3dSCy Schubert 3892b15cb3dSCy Schubert static const char * 3902b15cb3dSCy Schubert peer_st_flags( 3912b15cb3dSCy Schubert u_char pst 3922b15cb3dSCy Schubert ) 3932b15cb3dSCy Schubert { 3942b15cb3dSCy Schubert return decode_bitflags(pst, ", ", peer_st_bits, 3952b15cb3dSCy Schubert COUNTOF(peer_st_bits)); 3962b15cb3dSCy Schubert } 3972b15cb3dSCy Schubert 3982b15cb3dSCy Schubert 3992b15cb3dSCy Schubert const char * 4002b15cb3dSCy Schubert res_match_flags( 4012b15cb3dSCy Schubert u_short mf 4022b15cb3dSCy Schubert ) 4032b15cb3dSCy Schubert { 4042b15cb3dSCy Schubert return decode_bitflags(mf, " ", res_match_bits, 4052b15cb3dSCy Schubert COUNTOF(res_match_bits)); 4062b15cb3dSCy Schubert } 4072b15cb3dSCy Schubert 4082b15cb3dSCy Schubert 4092b15cb3dSCy Schubert const char * 4102b15cb3dSCy Schubert res_access_flags( 4112b15cb3dSCy Schubert u_short af 4122b15cb3dSCy Schubert ) 4132b15cb3dSCy Schubert { 4142b15cb3dSCy Schubert return decode_bitflags(af, " ", res_access_bits, 4152b15cb3dSCy Schubert COUNTOF(res_access_bits)); 4162b15cb3dSCy Schubert } 4172b15cb3dSCy Schubert 4182b15cb3dSCy Schubert 4192b15cb3dSCy Schubert #ifdef KERNEL_PLL 4202b15cb3dSCy Schubert const char * 4212b15cb3dSCy Schubert k_st_flags( 4222b15cb3dSCy Schubert u_int32 st 4232b15cb3dSCy Schubert ) 4242b15cb3dSCy Schubert { 4252b15cb3dSCy Schubert return decode_bitflags(st, " ", k_st_bits, COUNTOF(k_st_bits)); 4262b15cb3dSCy Schubert } 4272b15cb3dSCy Schubert #endif /* KERNEL_PLL */ 4282b15cb3dSCy Schubert 4292b15cb3dSCy Schubert 430c0b746e5SOllivier Robert /* 431c0b746e5SOllivier Robert * statustoa - return a descriptive string for a peer status 432c0b746e5SOllivier Robert */ 433c0b746e5SOllivier Robert char * 434c0b746e5SOllivier Robert statustoa( 435c0b746e5SOllivier Robert int type, 436c0b746e5SOllivier Robert int st 437c0b746e5SOllivier Robert ) 438c0b746e5SOllivier Robert { 439c0b746e5SOllivier Robert char * cb; 4402b15cb3dSCy Schubert char * cc; 441c0b746e5SOllivier Robert u_char pst; 442c0b746e5SOllivier Robert 443c0b746e5SOllivier Robert LIB_GETBUF(cb); 444c0b746e5SOllivier Robert 445c0b746e5SOllivier Robert switch (type) { 4462b15cb3dSCy Schubert 447c0b746e5SOllivier Robert case TYPE_SYS: 4482b15cb3dSCy Schubert snprintf(cb, LIB_BUFLENGTH, "%s, %s, %s, %s", 4492b15cb3dSCy Schubert getcode(CTL_SYS_LI(st), leap_codes), 4502b15cb3dSCy Schubert getcode(CTL_SYS_SOURCE(st), sync_codes), 4512b15cb3dSCy Schubert getevents(CTL_SYS_NEVNT(st)), 4522b15cb3dSCy Schubert getcode(CTL_SYS_EVENT(st), sys_codes)); 453c0b746e5SOllivier Robert break; 454c0b746e5SOllivier Robert 455c0b746e5SOllivier Robert case TYPE_PEER: 456c0b746e5SOllivier Robert pst = (u_char)CTL_PEER_STATVAL(st); 4572b15cb3dSCy Schubert snprintf(cb, LIB_BUFLENGTH, "%s, %s, %s", 4582b15cb3dSCy Schubert peer_st_flags(pst), 4592b15cb3dSCy Schubert getcode(pst & 0x7, select_codes), 4602b15cb3dSCy Schubert getevents(CTL_PEER_NEVNT(st))); 461c0b746e5SOllivier Robert if (CTL_PEER_EVENT(st) != EVNT_UNSPEC) { 4622b15cb3dSCy Schubert cc = cb + strlen(cb); 4632b15cb3dSCy Schubert snprintf(cc, LIB_BUFLENGTH - (cc - cb), ", %s", 4642b15cb3dSCy Schubert getcode(CTL_PEER_EVENT(st), 465c0b746e5SOllivier Robert peer_codes)); 466c0b746e5SOllivier Robert } 467c0b746e5SOllivier Robert break; 468c0b746e5SOllivier Robert 469c0b746e5SOllivier Robert case TYPE_CLOCK: 4702b15cb3dSCy Schubert snprintf(cb, LIB_BUFLENGTH, "%s, %s", 4712b15cb3dSCy Schubert getevents(CTL_SYS_NEVNT(st)), 4722b15cb3dSCy Schubert getcode((st) & 0xf, clock_codes)); 473c0b746e5SOllivier Robert break; 474c0b746e5SOllivier Robert } 4752b15cb3dSCy Schubert 476c0b746e5SOllivier Robert return cb; 477c0b746e5SOllivier Robert } 478c0b746e5SOllivier Robert 479c0b746e5SOllivier Robert const char * 480c0b746e5SOllivier Robert eventstr( 481c0b746e5SOllivier Robert int num 482c0b746e5SOllivier Robert ) 483c0b746e5SOllivier Robert { 4849c2daa00SOllivier Robert if (num & PEER_EVENT) 4859c2daa00SOllivier Robert return (getcode(num & ~PEER_EVENT, peer_codes)); 4862b15cb3dSCy Schubert #ifdef AUTOKEY 4879c2daa00SOllivier Robert else if (num & CRPT_EVENT) 4889c2daa00SOllivier Robert return (getcode(num & ~CRPT_EVENT, crypto_codes)); 4892b15cb3dSCy Schubert #endif /* AUTOKEY */ 4909c2daa00SOllivier Robert else 4919c2daa00SOllivier Robert return (getcode(num, sys_codes)); 492c0b746e5SOllivier Robert } 493c0b746e5SOllivier Robert 494c0b746e5SOllivier Robert const char * 495c0b746e5SOllivier Robert ceventstr( 496c0b746e5SOllivier Robert int num 497c0b746e5SOllivier Robert ) 498c0b746e5SOllivier Robert { 499c0b746e5SOllivier Robert return getcode(num, clock_codes); 500c0b746e5SOllivier Robert } 501