154359Sroberto/* 254359Sroberto * pretty printing of status information 354359Sroberto */ 454359Sroberto#ifdef HAVE_CONFIG_H 554359Sroberto#include <config.h> 654359Sroberto#endif 754359Sroberto#include <stdio.h> 854359Sroberto#include "ntp_stdlib.h" 954359Sroberto#include "ntp_fp.h" 1054359Sroberto#include "ntp.h" 1154359Sroberto#include "lib_strbuf.h" 1254359Sroberto#include "ntp_refclock.h" 1354359Sroberto#include "ntp_control.h" 1454359Sroberto#include "ntp_string.h" 15290001Sglebius#ifdef KERNEL_PLL 16290001Sglebius# include "ntp_syscall.h" 17290001Sglebius#endif 1854359Sroberto 19290001Sglebius 2054359Sroberto/* 2154359Sroberto * Structure for turning various constants into a readable string. 2254359Sroberto */ 2354359Srobertostruct codestring { 2454359Sroberto int code; 25290001Sglebius const char * const string; 2654359Sroberto}; 2754359Sroberto 2854359Sroberto/* 29290001Sglebius * Leap status (leap) 3054359Sroberto */ 31290001Sglebiusstatic const struct codestring leap_codes[] = { 3254359Sroberto { LEAP_NOWARNING, "leap_none" }, 3354359Sroberto { LEAP_ADDSECOND, "leap_add_sec" }, 3454359Sroberto { LEAP_DELSECOND, "leap_del_sec" }, 35290001Sglebius { LEAP_NOTINSYNC, "leap_alarm" }, 36290001Sglebius { -1, "leap" } 3754359Sroberto}; 3854359Sroberto 3954359Sroberto/* 40290001Sglebius * Clock source status (sync) 4154359Sroberto */ 42290001Sglebiusstatic const struct codestring sync_codes[] = { 4354359Sroberto { CTL_SST_TS_UNSPEC, "sync_unspec" }, 44290001Sglebius { CTL_SST_TS_ATOM, "sync_pps" }, 45290001Sglebius { CTL_SST_TS_LF, "sync_lf_radio" }, 46290001Sglebius { CTL_SST_TS_HF, "sync_hf_radio" }, 47290001Sglebius { CTL_SST_TS_UHF, "sync_uhf_radio" }, 48290001Sglebius { CTL_SST_TS_LOCAL, "sync_local" }, 4954359Sroberto { CTL_SST_TS_NTP, "sync_ntp" }, 50290001Sglebius { CTL_SST_TS_UDPTIME, "sync_other" }, 5154359Sroberto { CTL_SST_TS_WRSTWTCH, "sync_wristwatch" }, 5254359Sroberto { CTL_SST_TS_TELEPHONE, "sync_telephone" }, 5354359Sroberto { -1, "sync" } 5454359Sroberto}; 5554359Sroberto 5654359Sroberto/* 57290001Sglebius * Peer selection status (sel) 5854359Sroberto */ 59290001Sglebiusstatic const struct codestring select_codes[] = { 60290001Sglebius { CTL_PST_SEL_REJECT, "sel_reject" }, 6154359Sroberto { CTL_PST_SEL_SANE, "sel_falsetick" }, 6254359Sroberto { CTL_PST_SEL_CORRECT, "sel_excess" }, 63290001Sglebius { CTL_PST_SEL_SELCAND, "sel_outlier" }, 64290001Sglebius { CTL_PST_SEL_SYNCCAND, "sel_candidate" }, 65290001Sglebius { CTL_PST_SEL_EXCESS, "sel_backup" }, 6654359Sroberto { CTL_PST_SEL_SYSPEER, "sel_sys.peer" }, 6754359Sroberto { CTL_PST_SEL_PPS, "sel_pps.peer" }, 6854359Sroberto { -1, "sel" } 6954359Sroberto}; 7054359Sroberto 7154359Sroberto/* 72290001Sglebius * Clock status (clk) 7354359Sroberto */ 74290001Sglebiusstatic const struct codestring clock_codes[] = { 75290001Sglebius { CTL_CLK_OKAY, "clk_unspec" }, 76290001Sglebius { CTL_CLK_NOREPLY, "clk_no_reply" }, 77290001Sglebius { CTL_CLK_BADFORMAT, "clk_bad_format" }, 7854359Sroberto { CTL_CLK_FAULT, "clk_fault" }, 79290001Sglebius { CTL_CLK_PROPAGATION, "clk_bad_signal" }, 80290001Sglebius { CTL_CLK_BADDATE, "clk_bad_date" }, 81290001Sglebius { CTL_CLK_BADTIME, "clk_bad_time" }, 8254359Sroberto { -1, "clk" } 8354359Sroberto}; 8454359Sroberto 8554359Sroberto 86290001Sglebius#ifdef FLASH_CODES_UNUSED 8754359Sroberto/* 88290001Sglebius * Flash bits -- see ntpq.c tstflags & tstflagnames 8954359Sroberto */ 90290001Sglebiusstatic const struct codestring flash_codes[] = { 91290001Sglebius { TEST1, "pkt_dup" }, 92290001Sglebius { TEST2, "pkt_bogus" }, 93290001Sglebius { TEST3, "pkt_unsync" }, 94290001Sglebius { TEST4, "pkt_denied" }, 95290001Sglebius { TEST5, "pkt_auth" }, 96290001Sglebius { TEST6, "pkt_stratum" }, 97290001Sglebius { TEST7, "pkt_header" }, 98290001Sglebius { TEST8, "pkt_autokey" }, 99290001Sglebius { TEST9, "pkt_crypto" }, 100290001Sglebius { TEST10, "peer_stratum" }, 101290001Sglebius { TEST11, "peer_dist" }, 102290001Sglebius { TEST12, "peer_loop" }, 103290001Sglebius { TEST13, "peer_unreach" }, 104290001Sglebius { -1, "flash" } 10554359Sroberto}; 106290001Sglebius#endif 10754359Sroberto 108290001Sglebius 10954359Sroberto/* 110290001Sglebius * System events (sys) 11154359Sroberto */ 112290001Sglebiusstatic const struct codestring sys_codes[] = { 113290001Sglebius { EVNT_UNSPEC, "unspecified" }, 114290001Sglebius { EVNT_NSET, "freq_not_set" }, 115290001Sglebius { EVNT_FSET, "freq_set" }, 116290001Sglebius { EVNT_SPIK, "spike_detect" }, 117290001Sglebius { EVNT_FREQ, "freq_mode" }, 118290001Sglebius { EVNT_SYNC, "clock_sync" }, 119290001Sglebius { EVNT_SYSRESTART, "restart" }, 120290001Sglebius { EVNT_SYSFAULT, "panic_stop" }, 121290001Sglebius { EVNT_NOPEER, "no_sys_peer" }, 122290001Sglebius { EVNT_ARMED, "leap_armed" }, 123290001Sglebius { EVNT_DISARMED, "leap_disarmed" }, 124290001Sglebius { EVNT_LEAP, "leap_event" }, 125290001Sglebius { EVNT_CLOCKRESET, "clock_step" }, 126290001Sglebius { EVNT_KERN, "kern" }, 127290001Sglebius { EVNT_TAI, "TAI" }, 128290001Sglebius { EVNT_LEAPVAL, "stale_leapsecond_values" }, 129290001Sglebius { -1, "" } 13054359Sroberto}; 13154359Sroberto 132132451Sroberto/* 133290001Sglebius * Peer events (peer) 134132451Sroberto */ 135290001Sglebiusstatic const struct codestring peer_codes[] = { 136290001Sglebius { PEVNT_MOBIL & ~PEER_EVENT, "mobilize" }, 137290001Sglebius { PEVNT_DEMOBIL & ~PEER_EVENT, "demobilize" }, 138290001Sglebius { PEVNT_UNREACH & ~PEER_EVENT, "unreachable" }, 139290001Sglebius { PEVNT_REACH & ~PEER_EVENT, "reachable" }, 140290001Sglebius { PEVNT_RESTART & ~PEER_EVENT, "restart" }, 141290001Sglebius { PEVNT_REPLY & ~PEER_EVENT, "no_reply" }, 142290001Sglebius { PEVNT_RATE & ~PEER_EVENT, "rate_exceeded" }, 143290001Sglebius { PEVNT_DENY & ~PEER_EVENT, "access_denied" }, 144290001Sglebius { PEVNT_ARMED & ~PEER_EVENT, "leap_armed" }, 145290001Sglebius { PEVNT_NEWPEER & ~PEER_EVENT, "sys_peer" }, 146290001Sglebius { PEVNT_CLOCK & ~PEER_EVENT, "clock_event" }, 147290001Sglebius { PEVNT_AUTH & ~PEER_EVENT, "bad_auth" }, 148290001Sglebius { PEVNT_POPCORN & ~PEER_EVENT, "popcorn" }, 149290001Sglebius { PEVNT_XLEAVE & ~PEER_EVENT, "interleave_mode" }, 150290001Sglebius { PEVNT_XERR & ~PEER_EVENT, "interleave_error" }, 151290001Sglebius { -1, "" } 152290001Sglebius}; 153290001Sglebius 154290001Sglebius/* 155290001Sglebius * Peer status bits 156290001Sglebius */ 157290001Sglebiusstatic const struct codestring peer_st_bits[] = { 158290001Sglebius { CTL_PST_CONFIG, "conf" }, 159290001Sglebius { CTL_PST_AUTHENABLE, "authenb" }, 160290001Sglebius { CTL_PST_AUTHENTIC, "auth" }, 161290001Sglebius { CTL_PST_REACH, "reach" }, 162290001Sglebius { CTL_PST_BCAST, "bcast" }, 163290001Sglebius /* not used with getcode(), no terminating entry needed */ 164290001Sglebius}; 165290001Sglebius 166290001Sglebius/* 167290001Sglebius * Restriction match bits 168290001Sglebius */ 169290001Sglebiusstatic const struct codestring res_match_bits[] = { 170290001Sglebius { RESM_NTPONLY, "ntpport" }, 171290001Sglebius { RESM_INTERFACE, "interface" }, 172290001Sglebius { RESM_SOURCE, "source" }, 173290001Sglebius /* not used with getcode(), no terminating entry needed */ 174290001Sglebius}; 175290001Sglebius 176290001Sglebius/* 177290001Sglebius * Restriction access bits 178290001Sglebius */ 179290001Sglebiusstatic const struct codestring res_access_bits[] = { 180290001Sglebius { RES_IGNORE, "ignore" }, 181290001Sglebius { RES_DONTSERVE, "noserve" }, 182290001Sglebius { RES_DONTTRUST, "notrust" }, 183290001Sglebius { RES_NOQUERY, "noquery" }, 184290001Sglebius { RES_NOMODIFY, "nomodify" }, 185290001Sglebius { RES_NOPEER, "nopeer" }, 186290001Sglebius { RES_NOTRAP, "notrap" }, 187290001Sglebius { RES_LPTRAP, "lptrap" }, 188290001Sglebius { RES_LIMITED, "limited" }, 189290001Sglebius { RES_VERSION, "version" }, 190290001Sglebius { RES_KOD, "kod" }, 191290001Sglebius { RES_FLAKE, "flake" }, 192290001Sglebius /* not used with getcode(), no terminating entry needed */ 193290001Sglebius}; 194290001Sglebius 195290001Sglebius#ifdef AUTOKEY 196290001Sglebius/* 197290001Sglebius * Crypto events (cryp) 198290001Sglebius */ 199290001Sglebiusstatic const struct codestring crypto_codes[] = { 200132451Sroberto { XEVNT_OK & ~CRPT_EVENT, "success" }, 201132451Sroberto { XEVNT_LEN & ~CRPT_EVENT, "bad_field_format_or_length" }, 202132451Sroberto { XEVNT_TSP & ~CRPT_EVENT, "bad_timestamp" }, 203132451Sroberto { XEVNT_FSP & ~CRPT_EVENT, "bad_filestamp" }, 204182007Sroberto { XEVNT_PUB & ~CRPT_EVENT, "bad_or_missing_public_key" }, 205132451Sroberto { XEVNT_MD & ~CRPT_EVENT, "unsupported_digest_type" }, 206132451Sroberto { XEVNT_KEY & ~CRPT_EVENT, "unsupported_identity_type" }, 207132451Sroberto { XEVNT_SGL & ~CRPT_EVENT, "bad_signature_length" }, 208132451Sroberto { XEVNT_SIG & ~CRPT_EVENT, "signature_not_verified" }, 209182007Sroberto { XEVNT_VFY & ~CRPT_EVENT, "certificate_not_verified" }, 210290001Sglebius { XEVNT_PER & ~CRPT_EVENT, "host_certificate_expired" }, 211132451Sroberto { XEVNT_CKY & ~CRPT_EVENT, "bad_or_missing_cookie" }, 212290001Sglebius { XEVNT_DAT & ~CRPT_EVENT, "bad_or_missing_leapseconds" }, 213132451Sroberto { XEVNT_CRT & ~CRPT_EVENT, "bad_or_missing_certificate" }, 214290001Sglebius { XEVNT_ID & ~CRPT_EVENT, "bad_or_missing_group key" }, 215182007Sroberto { XEVNT_ERR & ~CRPT_EVENT, "protocol_error" }, 216290001Sglebius { -1, "" } 217132451Sroberto}; 218290001Sglebius#endif /* AUTOKEY */ 219132451Sroberto 220290001Sglebius#ifdef KERNEL_PLL 221290001Sglebius/* 222290001Sglebius * kernel discipline status bits 223290001Sglebius */ 224290001Sglebiusstatic const struct codestring k_st_bits[] = { 225290001Sglebius# ifdef STA_PLL 226290001Sglebius { STA_PLL, "pll" }, 227290001Sglebius# endif 228290001Sglebius# ifdef STA_PPSFREQ 229290001Sglebius { STA_PPSFREQ, "ppsfreq" }, 230290001Sglebius# endif 231290001Sglebius# ifdef STA_PPSTIME 232290001Sglebius { STA_PPSTIME, "ppstime" }, 233290001Sglebius# endif 234290001Sglebius# ifdef STA_FLL 235290001Sglebius { STA_FLL, "fll" }, 236290001Sglebius# endif 237290001Sglebius# ifdef STA_INS 238290001Sglebius { STA_INS, "ins" }, 239290001Sglebius# endif 240290001Sglebius# ifdef STA_DEL 241290001Sglebius { STA_DEL, "del" }, 242290001Sglebius# endif 243290001Sglebius# ifdef STA_UNSYNC 244290001Sglebius { STA_UNSYNC, "unsync" }, 245290001Sglebius# endif 246290001Sglebius# ifdef STA_FREQHOLD 247290001Sglebius { STA_FREQHOLD, "freqhold" }, 248290001Sglebius# endif 249290001Sglebius# ifdef STA_PPSSIGNAL 250290001Sglebius { STA_PPSSIGNAL, "ppssignal" }, 251290001Sglebius# endif 252290001Sglebius# ifdef STA_PPSJITTER 253290001Sglebius { STA_PPSJITTER, "ppsjitter" }, 254290001Sglebius# endif 255290001Sglebius# ifdef STA_PPSWANDER 256290001Sglebius { STA_PPSWANDER, "ppswander" }, 257290001Sglebius# endif 258290001Sglebius# ifdef STA_PPSERROR 259290001Sglebius { STA_PPSERROR, "ppserror" }, 260290001Sglebius# endif 261290001Sglebius# ifdef STA_CLOCKERR 262290001Sglebius { STA_CLOCKERR, "clockerr" }, 263290001Sglebius# endif 264290001Sglebius# ifdef STA_NANO 265290001Sglebius { STA_NANO, "nano" }, 266290001Sglebius# endif 267290001Sglebius# ifdef STA_MODE 268290001Sglebius { STA_MODE, "mode=fll" }, 269290001Sglebius# endif 270290001Sglebius# ifdef STA_CLK 271290001Sglebius { STA_CLK, "src=B" }, 272290001Sglebius# endif 273290001Sglebius /* not used with getcode(), no terminating entry needed */ 274290001Sglebius}; 275290001Sglebius#endif /* KERNEL_PLL */ 276290001Sglebius 27754359Sroberto/* Forwards */ 278290001Sglebiusstatic const char * getcode(int, const struct codestring *); 279290001Sglebiusstatic const char * getevents(int); 280290001Sglebiusstatic const char * peer_st_flags(u_char pst); 28154359Sroberto 28254359Sroberto/* 28354359Sroberto * getcode - return string corresponding to code 28454359Sroberto */ 28554359Srobertostatic const char * 28654359Srobertogetcode( 287290001Sglebius int code, 288290001Sglebius const struct codestring * codetab 28954359Sroberto ) 29054359Sroberto{ 291290001Sglebius char * buf; 29254359Sroberto 29354359Sroberto while (codetab->code != -1) { 29454359Sroberto if (codetab->code == code) 295290001Sglebius return codetab->string; 29654359Sroberto codetab++; 29754359Sroberto } 298290001Sglebius 299290001Sglebius LIB_GETBUF(buf); 300290001Sglebius snprintf(buf, LIB_BUFLENGTH, "%s_%d", codetab->string, code); 301290001Sglebius 30254359Sroberto return buf; 30354359Sroberto} 30454359Sroberto 30554359Sroberto/* 30654359Sroberto * getevents - return a descriptive string for the event count 30754359Sroberto */ 30854359Srobertostatic const char * 30954359Srobertogetevents( 31054359Sroberto int cnt 31154359Sroberto ) 31254359Sroberto{ 313290001Sglebius char * buf; 31454359Sroberto 31554359Sroberto if (cnt == 0) 316290001Sglebius return "no events"; 317290001Sglebius 318290001Sglebius LIB_GETBUF(buf); 319290001Sglebius snprintf(buf, LIB_BUFLENGTH, "%d event%s", cnt, 320290001Sglebius (1 == cnt) 321290001Sglebius ? "" 322290001Sglebius : "s"); 323290001Sglebius 32454359Sroberto return buf; 32554359Sroberto} 32654359Sroberto 327290001Sglebius 32854359Sroberto/* 329290001Sglebius * decode_bitflags() 330290001Sglebius * 331290001Sglebius * returns a human-readable string with a keyword from tab for each bit 332290001Sglebius * set in bits, separating multiple entries with text of sep2. 333290001Sglebius */ 334290001Sglebiusstatic const char * 335290001Sglebiusdecode_bitflags( 336290001Sglebius int bits, 337290001Sglebius const char * sep2, 338290001Sglebius const struct codestring * tab, 339290001Sglebius size_t tab_ct 340290001Sglebius ) 341290001Sglebius{ 342290001Sglebius const char * sep; 343290001Sglebius char * buf; 344290001Sglebius char * pch; 345290001Sglebius char * lim; 346290001Sglebius size_t b; 347290001Sglebius int rc; 348290001Sglebius int saved_errno; /* for use in DPRINTF with %m */ 349290001Sglebius 350290001Sglebius saved_errno = errno; 351290001Sglebius LIB_GETBUF(buf); 352290001Sglebius pch = buf; 353290001Sglebius lim = buf + LIB_BUFLENGTH; 354290001Sglebius sep = ""; 355290001Sglebius 356290001Sglebius for (b = 0; b < tab_ct; b++) { 357290001Sglebius if (tab[b].code & bits) { 358290001Sglebius rc = snprintf(pch, (lim - pch), "%s%s", sep, 359290001Sglebius tab[b].string); 360290001Sglebius if (rc < 0) 361290001Sglebius goto toosmall; 362290001Sglebius pch += (u_int)rc; 363290001Sglebius if (pch >= lim) 364290001Sglebius goto toosmall; 365290001Sglebius sep = sep2; 366290001Sglebius } 367290001Sglebius } 368290001Sglebius 369290001Sglebius return buf; 370290001Sglebius 371290001Sglebius toosmall: 372290001Sglebius snprintf(buf, LIB_BUFLENGTH, 373290001Sglebius "decode_bitflags(%s) can't decode 0x%x in %d bytes", 374290001Sglebius (tab == peer_st_bits) 375290001Sglebius ? "peer_st" 376290001Sglebius : 377290001Sglebius#ifdef KERNEL_PLL 378290001Sglebius (tab == k_st_bits) 379290001Sglebius ? "kern_st" 380290001Sglebius : 381290001Sglebius#endif 382290001Sglebius "", 383290001Sglebius bits, (int)LIB_BUFLENGTH); 384290001Sglebius errno = saved_errno; 385290001Sglebius 386290001Sglebius return buf; 387290001Sglebius} 388290001Sglebius 389290001Sglebius 390290001Sglebiusstatic const char * 391290001Sglebiuspeer_st_flags( 392290001Sglebius u_char pst 393290001Sglebius ) 394290001Sglebius{ 395290001Sglebius return decode_bitflags(pst, ", ", peer_st_bits, 396290001Sglebius COUNTOF(peer_st_bits)); 397290001Sglebius} 398290001Sglebius 399290001Sglebius 400290001Sglebiusconst char * 401290001Sglebiusres_match_flags( 402290001Sglebius u_short mf 403290001Sglebius ) 404290001Sglebius{ 405290001Sglebius return decode_bitflags(mf, " ", res_match_bits, 406290001Sglebius COUNTOF(res_match_bits)); 407290001Sglebius} 408290001Sglebius 409290001Sglebius 410290001Sglebiusconst char * 411290001Sglebiusres_access_flags( 412290001Sglebius u_short af 413290001Sglebius ) 414290001Sglebius{ 415290001Sglebius return decode_bitflags(af, " ", res_access_bits, 416290001Sglebius COUNTOF(res_access_bits)); 417290001Sglebius} 418290001Sglebius 419290001Sglebius 420290001Sglebius#ifdef KERNEL_PLL 421290001Sglebiusconst char * 422290001Sglebiusk_st_flags( 423290001Sglebius u_int32 st 424290001Sglebius ) 425290001Sglebius{ 426290001Sglebius return decode_bitflags(st, " ", k_st_bits, COUNTOF(k_st_bits)); 427290001Sglebius} 428290001Sglebius#endif /* KERNEL_PLL */ 429290001Sglebius 430290001Sglebius 431290001Sglebius/* 43254359Sroberto * statustoa - return a descriptive string for a peer status 43354359Sroberto */ 43454359Srobertochar * 43554359Srobertostatustoa( 43654359Sroberto int type, 43754359Sroberto int st 43854359Sroberto ) 43954359Sroberto{ 440290001Sglebius char * cb; 441290001Sglebius char * cc; 442290001Sglebius u_char pst; 44354359Sroberto 44454359Sroberto LIB_GETBUF(cb); 44554359Sroberto 44654359Sroberto switch (type) { 447290001Sglebius 448290001Sglebius case TYPE_SYS: 449290001Sglebius snprintf(cb, LIB_BUFLENGTH, "%s, %s, %s, %s", 450290001Sglebius getcode(CTL_SYS_LI(st), leap_codes), 451290001Sglebius getcode(CTL_SYS_SOURCE(st), sync_codes), 452290001Sglebius getevents(CTL_SYS_NEVNT(st)), 453290001Sglebius getcode(CTL_SYS_EVENT(st), sys_codes)); 45454359Sroberto break; 45554359Sroberto 456290001Sglebius case TYPE_PEER: 457290001Sglebius pst = (u_char)CTL_PEER_STATVAL(st); 458290001Sglebius snprintf(cb, LIB_BUFLENGTH, "%s, %s, %s", 459290001Sglebius peer_st_flags(pst), 460290001Sglebius getcode(pst & 0x7, select_codes), 461290001Sglebius getevents(CTL_PEER_NEVNT(st))); 46254359Sroberto if (CTL_PEER_EVENT(st) != EVNT_UNSPEC) { 463290001Sglebius cc = cb + strlen(cb); 464290001Sglebius snprintf(cc, LIB_BUFLENGTH - (cc - cb), ", %s", 465290001Sglebius getcode(CTL_PEER_EVENT(st), 466290001Sglebius peer_codes)); 46754359Sroberto } 46854359Sroberto break; 46954359Sroberto 470290001Sglebius case TYPE_CLOCK: 471290001Sglebius snprintf(cb, LIB_BUFLENGTH, "%s, %s", 472290001Sglebius getevents(CTL_SYS_NEVNT(st)), 473290001Sglebius getcode((st) & 0xf, clock_codes)); 47454359Sroberto break; 47554359Sroberto } 476290001Sglebius 47754359Sroberto return cb; 47854359Sroberto} 47954359Sroberto 48054359Srobertoconst char * 48154359Srobertoeventstr( 48254359Sroberto int num 48354359Sroberto ) 48454359Sroberto{ 485132451Sroberto if (num & PEER_EVENT) 486132451Sroberto return (getcode(num & ~PEER_EVENT, peer_codes)); 487290001Sglebius#ifdef AUTOKEY 488132451Sroberto else if (num & CRPT_EVENT) 489132451Sroberto return (getcode(num & ~CRPT_EVENT, crypto_codes)); 490290001Sglebius#endif /* AUTOKEY */ 491132451Sroberto else 492132451Sroberto return (getcode(num, sys_codes)); 49354359Sroberto} 49454359Sroberto 49554359Srobertoconst char * 49654359Srobertoceventstr( 49754359Sroberto int num 49854359Sroberto ) 49954359Sroberto{ 50054359Sroberto return getcode(num, clock_codes); 50154359Sroberto} 502