diff options
| -rw-r--r-- | include/osmocom/vty/misc.h | 3 | ||||
| -rw-r--r-- | src/vty/command.c | 176 | 
2 files changed, 133 insertions, 46 deletions
| diff --git a/include/osmocom/vty/misc.h b/include/osmocom/vty/misc.h index 707f82fa..89234733 100644 --- a/include/osmocom/vty/misc.h +++ b/include/osmocom/vty/misc.h @@ -7,4 +7,7 @@  void vty_out_rate_ctr_group(struct vty *vty, const char *prefix,                              struct rate_ctr_group *ctrg); +int osmo_vty_write_config_file(const char *filename); +int osmo_vty_save_config_file(void); +  #endif diff --git a/src/vty/command.c b/src/vty/command.c index ab1eacaa..fda2e17f 100644 --- a/src/vty/command.c +++ b/src/vty/command.c @@ -2268,31 +2268,19 @@ gDEFUN(config_list, config_list_cmd, "list", "Print command list\n")  	return CMD_SUCCESS;  } -/* Write current configuration into file. */ -DEFUN(config_write_file, -      config_write_file_cmd, -      "write file", -      "Write running configuration to memory, network, or terminal\n" -      "Write to configuration file\n") +static int write_config_file(const char *config_file, char **outpath)  {  	unsigned int i;  	int fd;  	struct cmd_node *node; -	char *config_file;  	char *config_file_tmp = NULL;  	char *config_file_sav = NULL;  	struct vty *file_vty; +	struct stat st; -	/* Check and see if we are operating under vtysh configuration */ -	if (host.config == NULL) { -		vty_out(vty, "Can't save to configuration file, using vtysh.%s", -			VTY_NEWLINE); -		return CMD_WARNING; -	} - -	/* Get filename. */ -	config_file = host.config; +	*outpath = NULL; +	/* Check and see if we are operating under vtysh configuration */  	config_file_sav =  	    _talloc_zero(tall_vty_cmd_ctx,  			 strlen(config_file) + strlen(CONF_BACKUP_EXT) + 1, @@ -2307,11 +2295,10 @@ DEFUN(config_write_file,  	/* Open file to configuration write. */  	fd = mkstemp(config_file_tmp);  	if (fd < 0) { -		vty_out(vty, "Can't open configuration file %s.%s", -			config_file_tmp, VTY_NEWLINE); +		*outpath = talloc_strdup(tall_vty_cmd_ctx, config_file_tmp);  		talloc_free(config_file_tmp);  		talloc_free(config_file_sav); -		return CMD_WARNING; +		return -1;  	}  	/* Make vty for configuration file. */ @@ -2334,38 +2321,37 @@ DEFUN(config_write_file,  	if (unlink(config_file_sav) != 0)  		if (errno != ENOENT) { -			vty_out(vty, -				"Can't unlink backup configuration file %s.%s", -				config_file_sav, VTY_NEWLINE); +			*outpath = talloc_strdup(tall_vty_cmd_ctx, config_file_sav);  			talloc_free(config_file_sav);  			talloc_free(config_file_tmp);  			unlink(config_file_tmp); -			return CMD_WARNING; +			return -2; +		} + +	/* Only link the .sav file if the original file exists */ +	if (stat(config_file, &st) == 0) { +		if (link(config_file, config_file_sav) != 0) { +			*outpath = talloc_strdup(tall_vty_cmd_ctx, config_file_sav); +			talloc_free(config_file_sav); +			talloc_free(config_file_tmp); +			unlink(config_file_tmp); +			return -3; +		} +		sync(); +		if (unlink(config_file) != 0) { +			*outpath = talloc_strdup(tall_vty_cmd_ctx, config_file); +			talloc_free(config_file_sav); +			talloc_free(config_file_tmp); +			unlink(config_file_tmp); +			return -4;  		} -	if (link(config_file, config_file_sav) != 0) { -		vty_out(vty, "Can't backup old configuration file %s.%s", -			config_file_sav, VTY_NEWLINE); -		talloc_free(config_file_sav); -		talloc_free(config_file_tmp); -		unlink(config_file_tmp); -		return CMD_WARNING; -	} -	sync(); -	if (unlink(config_file) != 0) { -		vty_out(vty, "Can't unlink configuration file %s.%s", -			config_file, VTY_NEWLINE); -		talloc_free(config_file_sav); -		talloc_free(config_file_tmp); -		unlink(config_file_tmp); -		return CMD_WARNING;  	}  	if (link(config_file_tmp, config_file) != 0) { -		vty_out(vty, "Can't save configuration file %s.%s", config_file, -			VTY_NEWLINE); +		*outpath = talloc_strdup(tall_vty_cmd_ctx, config_file);  		talloc_free(config_file_sav);  		talloc_free(config_file_tmp);  		unlink(config_file_tmp); -		return CMD_WARNING; +		return -5;  	}  	unlink(config_file_tmp);  	sync(); @@ -2374,13 +2360,70 @@ DEFUN(config_write_file,  	talloc_free(config_file_tmp);  	if (chmod(config_file, 0666 & ~CONFIGFILE_MASK) != 0) { -		vty_out(vty, "Can't chmod configuration file %s: %s (%d).%s", -			config_file, strerror(errno), errno, VTY_NEWLINE); +		*outpath = talloc_strdup(tall_vty_cmd_ctx, config_file); +		return -6; +	} + +	return 0; +} + + +/* Write current configuration into file. */ +DEFUN(config_write_file, +      config_write_file_cmd, +      "write file", +      "Write running configuration to memory, network, or terminal\n" +      "Write to configuration file\n") +{ +	char *failed_file; +	int rc; + +	if (host.config == NULL) { +		vty_out(vty, "Can't save to configuration file, using vtysh.%s", +			VTY_NEWLINE);  		return CMD_WARNING;  	} -	vty_out(vty, "Configuration saved to %s%s", config_file, VTY_NEWLINE); -	return CMD_SUCCESS; +	rc = write_config_file(host.config, &failed_file); +	switch (rc) { +	case -1: +		vty_out(vty, "Can't open configuration file %s.%s", +			failed_file, VTY_NEWLINE); +		rc = CMD_WARNING; +		break; +	case -2: +		vty_out(vty, "Can't unlink backup configuration file %s.%s", +			failed_file, VTY_NEWLINE); +		rc = CMD_WARNING; +		break; +	case -3: +		vty_out(vty, "Can't backup old configuration file %s.%s", +			failed_file, VTY_NEWLINE); +		rc = CMD_WARNING; +		break; +	case -4: +		vty_out(vty, "Can't unlink configuration file %s.%s", +			failed_file, VTY_NEWLINE); +		rc = CMD_WARNING; +		break; +	case -5: +		vty_out(vty, "Can't save configuration file %s.%s", failed_file, +			VTY_NEWLINE); +		rc = CMD_WARNING; +		break; +	case -6: +		vty_out(vty, "Can't chmod configuration file %s: %s (%d).%s", +			failed_file, strerror(errno), errno, VTY_NEWLINE); +		rc = CMD_WARNING; +		break; +	default: +		vty_out(vty, "Configuration saved to %s%s", host.config, VTY_NEWLINE); +		rc = CMD_SUCCESS; +		break; +	} + +	talloc_free(failed_file); +	return rc;  }  ALIAS(config_write_file, @@ -3160,6 +3203,47 @@ void install_default(enum node_type node)  	install_element(node, &show_running_config_cmd);  } +/** + * \brief Write the current running config to a given file + * \param[in] vty the vty of the code + * \param[in] filename where to store the file + * \return 0 in case of success. + * + * If the filename already exists create a filename.sav + * version with the current code. + * + */ +int osmo_vty_write_config_file(const char *filename) +{ +	char *failed_file; +	int rc; + +	rc = write_config_file(filename, &failed_file); +	talloc_free(failed_file); +	return rc; +} + +/** + * \brief Save the current state to the config file + * \return 0 in case of success. + * + * If the filename already exists create a filename.sav + * version with the current code. + * + */ +int osmo_vty_save_config_file(void) +{ +	char *failed_file; +	int rc; + +	if (host.config == NULL) +		return -7; + +	rc = write_config_file(host.config, &failed_file); +	talloc_free(failed_file); +	return rc; +} +  /* Initialize command interface. Install basic nodes and commands. */  void cmd_init(int terminal)  { | 
