From: Dave Hart Date: Tue, 18 Aug 2009 05:05:46 +0000 (+0000) Subject: [Bug 1285] Log ntpq :config/config-from-file events. X-Git-Tag: NTP_4_2_5P205~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=96d09f709a045fb41a6ae26f6c9fdc23d1e68393;p=thirdparty%2Fntp.git [Bug 1285] Log ntpq :config/config-from-file events. bk: 4a8a36aabB-9EhRBgv574wNFKWhZng --- diff --git a/ChangeLog b/ChangeLog index bb6590966..7fdf77a84 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ +* [Bug 1285] Log ntpq :config/config-from-file events. * [Bug 1286] dumpcfg omits statsdir, mangles filegen. (4.2.5p204) 2009/08/17 Released by Harlan Stenn * [Bug 1284] infinite loop in ntpd dumping more than one trustedkey diff --git a/include/ntp_config.h b/include/ntp_config.h index ca41b95af..25f93631a 100644 --- a/include/ntp_config.h +++ b/include/ntp_config.h @@ -203,7 +203,7 @@ script_info *create_sim_script_info(double duration, queue *script_queue); server_info *create_sim_server(struct address_node *addr, double server_offset, queue *script); extern struct REMOTE_CONFIG_INFO remote_config; -void config_remotely(void); +void config_remotely(sockaddr_u *); int dump_config_tree(struct config_tree *ptree, FILE *df); int dump_all_config_trees(FILE *df); diff --git a/ntpd/ntp_config.c b/ntpd/ntp_config.c index aa7a66438..b02bddc7e 100644 --- a/ntpd/ntp_config.c +++ b/ntpd/ntp_config.c @@ -508,9 +508,21 @@ dump_config_tree( void *flags = NULL; void *opts = NULL; char refid[5]; + char timestamp[80]; printf("dump_config_tree(%p)\n", ptree); + 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 I didn't find documentation I'll just output its name and the cor. value */ list_ptr = queue_head(ptree->vars); if (list_ptr != NULL) { @@ -3725,7 +3737,9 @@ config_ntpdsim( * config_remotely() - implements ntpd side of ntpq :config */ void -config_remotely(void) +config_remotely( + sockaddr_u * remote_addr + ) { input_from_file = 0; @@ -3735,6 +3749,8 @@ config_remotely(void) delete_keyword_scanner(key_scanner); key_scanner = NULL; cfgt.source.attr = CONF_SOURCE_NTPQ; + cfgt.timestamp = time(NULL); + cfgt.source.value.s = estrdup(stoa(remote_addr)); DPRINTF(1, ("Finished Parsing!!\n")); diff --git a/ntpd/ntp_control.c b/ntpd/ntp_control.c index 6169d8dc7..7479997d2 100644 --- a/ntpd/ntp_control.c +++ b/ntpd/ntp_control.c @@ -2387,13 +2387,16 @@ write_variables( ctl_flushpkt(0); } -/* SK: - * configure: remotely configure an NTP daemon +/* + * configure() processes ntpq :config/config-from-file, allowing + * generic runtime reconfiguration. */ -static void configure(struct recvbuf *rbufp,int restrict_mask) +static void configure( + struct recvbuf *rbufp, + int restrict_mask + ) { - int data_count; - int retval; + int data_count, retval, replace_nl; /* I haven't yet implemented changes to an existing association. * Hence check if the association id is 0 @@ -2402,44 +2405,63 @@ static void configure(struct recvbuf *rbufp,int restrict_mask) ctl_error(CERR_BADVALUE); return; } - + /* Initialize the remote config buffer */ data_count = reqend - reqpt; memcpy(remote_config.buffer, reqpt, data_count); - remote_config.buffer[data_count++] = '\n'; + if (data_count > 0 + && '\n' != remote_config.buffer[data_count - 1]) + 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; -#ifdef DEBUG - if (debug > 0) - printf("Got Remote Configuration Command: %s\n\n", remote_config.buffer); -#endif + /* do not include terminating newline in log */ + if (data_count > 0 + && '\n' == remote_config.buffer[data_count - 1]) { + remote_config.buffer[data_count - 1] = '\0'; + replace_nl = 1; + } else + replace_nl = 0; - config_remotely(); + DPRINTF(1, ("Got Remote Configuration Command: %s\n", + remote_config.buffer)); + msyslog(LOG_NOTICE, "%s config: %s", + stoa(&rbufp->recv_srcadr), + remote_config.buffer); - /* Check if errors were reported. If not, output 'Config Succeeded' - * Else output the error message + if (replace_nl) + remote_config.buffer[data_count - 1] = '\n'; + + 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. */ - printf("No_Errors %d\n", remote_config.no_errors); - if (remote_config.no_errors == 0) { - retval = snprintf(remote_config.err_msg, MAXLINE, "Config Succeeded"); - if (retval > 0) - remote_config.err_pos += retval; - } + if (0 == remote_config.no_errors) + retval = snprintf(remote_config.err_msg, + sizeof(remote_config.err_msg), + "Config Succeeded"); + else + retval = snprintf(remote_config.err_msg, + sizeof(remote_config.err_msg), + "%d error, failure", + remote_config.no_errors); + if (retval > 0) + remote_config.err_pos += retval; + ctl_putdata(remote_config.err_msg, remote_config.err_pos, 0); - -#if 0 - datapt = remote_config.err_msg; - dataend = remote_config.err_msg + remote_config.err_pos; - datalinelen = remote_config.err_pos; - datanotbinflag = 1; - - printf("Reply: %s\n\nReply_len: %d\n\n", datapt, datalinelen); -#endif - 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)); } diff --git a/ntpq/ntpq-subs.c b/ntpq/ntpq-subs.c index 8dd74d592..b39843f99 100644 --- a/ntpq/ntpq-subs.c +++ b/ntpq/ntpq-subs.c @@ -1869,6 +1869,7 @@ config_from_file ( int res; FILE *config_fd; char config_cmd[MAXLINE]; + size_t config_len; if (debug > 2) { printf("In Config\n"); @@ -1883,13 +1884,21 @@ config_from_file ( int i = 0; printf("Sending configuration file, one line at a time.\n"); while (fgets(config_cmd, MAXLINE, config_fd) != NULL) { + config_len = strlen(config_cmd); + /* ensure even the last line has newline, if possible */ + if (config_len > 0 && config_len + 2 < sizeof(config_cmd) + && '\n' != config_cmd[config_len - 1]) + config_cmd[config_len++] = '\n'; ++i; res = doquery(CTL_OP_CONFIGURE, 0, 1, strlen(config_cmd), config_cmd, &rstatus, &rsize, &rdata); - printf("Line No: %d ", i); + if (rsize > 0 && '\n' == rdata[rsize - 1]) + rsize--; + if (rsize > 0 && '\r' == rdata[rsize - 1]) + rsize--; rdata[rsize] = '\0'; - printf(rdata); + printf("Line No: %d %s: %s", i, rdata, config_cmd); } printf("Done sending file\n"); fclose(config_fd);