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) {
* config_remotely() - implements ntpd side of ntpq :config
*/
void
-config_remotely(void)
+config_remotely(
+ sockaddr_u * remote_addr
+ )
{
input_from_file = 0;
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"));
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
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));
}
int res;
FILE *config_fd;
char config_cmd[MAXLINE];
+ size_t config_len;
if (debug > 2) {
printf("In Config\n");
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);