|  | @@ -1046,28 +1046,32 @@ int setting_cmp ( struct setting *a, struct setting *b ) {
 | 
		
	
		
			
			| 1046 | 1046 |   */
 | 
		
	
		
			
			| 1047 | 1047 |  int fetchf_setting ( struct settings *settings, struct setting *setting,
 | 
		
	
		
			
			| 1048 | 1048 |  		     char *buf, size_t len ) {
 | 
		
	
		
			
			|  | 1049 | +	void *raw;
 | 
		
	
		
			
			| 1049 | 1050 |  	int raw_len;
 | 
		
	
		
			
			| 1050 |  | -	int check_len;
 | 
		
	
		
			
			| 1051 |  | -	int rc;
 | 
		
	
		
			
			|  | 1051 | +	int ret;
 | 
		
	
		
			
			| 1052 | 1052 |  
 | 
		
	
		
			
			| 1053 | 1053 |  	/* Fetch raw value */
 | 
		
	
		
			
			| 1054 |  | -	raw_len = fetch_setting_len ( settings, setting );
 | 
		
	
		
			
			|  | 1054 | +	raw_len = fetch_setting_copy ( settings, setting, &raw );
 | 
		
	
		
			
			| 1055 | 1055 |  	if ( raw_len < 0 ) {
 | 
		
	
		
			
			| 1056 |  | -		rc = raw_len;
 | 
		
	
		
			
			| 1057 |  | -		return rc;
 | 
		
	
		
			
			| 1058 |  | -	} else {
 | 
		
	
		
			
			| 1059 |  | -		uint8_t raw[raw_len];
 | 
		
	
		
			
			| 1060 |  | -
 | 
		
	
		
			
			| 1061 |  | -		/* Fetch raw value */
 | 
		
	
		
			
			| 1062 |  | -		check_len = fetch_setting ( settings, setting, raw,
 | 
		
	
		
			
			| 1063 |  | -					    sizeof ( raw ) );
 | 
		
	
		
			
			| 1064 |  | -		if ( check_len < 0 )
 | 
		
	
		
			
			| 1065 |  | -			return check_len;
 | 
		
	
		
			
			| 1066 |  | -		assert ( check_len == raw_len );
 | 
		
	
		
			
			|  | 1056 | +		ret = raw_len;
 | 
		
	
		
			
			|  | 1057 | +		goto err_fetch_copy;
 | 
		
	
		
			
			|  | 1058 | +	}
 | 
		
	
		
			
			| 1067 | 1059 |  
 | 
		
	
		
			
			| 1068 |  | -		/* Format value */
 | 
		
	
		
			
			| 1069 |  | -		return setting->type->format ( raw, sizeof ( raw ), buf, len );
 | 
		
	
		
			
			|  | 1060 | +	/* Return error if setting does not exist */
 | 
		
	
		
			
			|  | 1061 | +	if ( ! raw ) {
 | 
		
	
		
			
			|  | 1062 | +		ret = -ENOENT;
 | 
		
	
		
			
			|  | 1063 | +		goto err_exists;
 | 
		
	
		
			
			| 1070 | 1064 |  	}
 | 
		
	
		
			
			|  | 1065 | +
 | 
		
	
		
			
			|  | 1066 | +	/* Format setting */
 | 
		
	
		
			
			|  | 1067 | +	if ( ( ret = setting->type->format ( raw, raw_len, buf, len ) ) < 0 )
 | 
		
	
		
			
			|  | 1068 | +		goto err_format;
 | 
		
	
		
			
			|  | 1069 | +
 | 
		
	
		
			
			|  | 1070 | + err_format:
 | 
		
	
		
			
			|  | 1071 | +	free ( raw );
 | 
		
	
		
			
			|  | 1072 | + err_exists:
 | 
		
	
		
			
			|  | 1073 | + err_fetch_copy:
 | 
		
	
		
			
			|  | 1074 | +	return ret;
 | 
		
	
		
			
			| 1071 | 1075 |  }
 | 
		
	
		
			
			| 1072 | 1076 |  
 | 
		
	
		
			
			| 1073 | 1077 |  /**
 | 
		
	
	
		
			
			|  | @@ -1080,6 +1084,7 @@ int fetchf_setting ( struct settings *settings, struct setting *setting,
 | 
		
	
		
			
			| 1080 | 1084 |   */
 | 
		
	
		
			
			| 1081 | 1085 |  int storef_setting ( struct settings *settings, struct setting *setting,
 | 
		
	
		
			
			| 1082 | 1086 |  		     const char *value ) {
 | 
		
	
		
			
			|  | 1087 | +	void *raw;
 | 
		
	
		
			
			| 1083 | 1088 |  	int raw_len;
 | 
		
	
		
			
			| 1084 | 1089 |  	int check_len;
 | 
		
	
		
			
			| 1085 | 1090 |  	int rc;
 | 
		
	
	
		
			
			|  | @@ -1088,21 +1093,33 @@ int storef_setting ( struct settings *settings, struct setting *setting,
 | 
		
	
		
			
			| 1088 | 1093 |  	if ( ( ! value ) || ( ! value[0] ) )
 | 
		
	
		
			
			| 1089 | 1094 |  		return delete_setting ( settings, setting );
 | 
		
	
		
			
			| 1090 | 1095 |  
 | 
		
	
		
			
			| 1091 |  | -	/* Parse formatted value */
 | 
		
	
		
			
			|  | 1096 | +	/* Get raw value length */
 | 
		
	
		
			
			| 1092 | 1097 |  	raw_len = setting->type->parse ( value, NULL, 0 );
 | 
		
	
		
			
			| 1093 | 1098 |  	if ( raw_len < 0 ) {
 | 
		
	
		
			
			| 1094 | 1099 |  		rc = raw_len;
 | 
		
	
		
			
			| 1095 |  | -		return rc;
 | 
		
	
		
			
			| 1096 |  | -	} else {
 | 
		
	
		
			
			| 1097 |  | -		uint8_t raw[raw_len];
 | 
		
	
		
			
			| 1098 |  | -
 | 
		
	
		
			
			| 1099 |  | -		/* Parse formatted value */
 | 
		
	
		
			
			| 1100 |  | -		check_len = setting->type->parse ( value, raw, sizeof ( raw ) );
 | 
		
	
		
			
			| 1101 |  | -		assert ( check_len == raw_len );
 | 
		
	
		
			
			|  | 1100 | +		goto err_parse_len;
 | 
		
	
		
			
			|  | 1101 | +	}
 | 
		
	
		
			
			| 1102 | 1102 |  
 | 
		
	
		
			
			| 1103 |  | -		/* Store raw value */
 | 
		
	
		
			
			| 1104 |  | -		return store_setting ( settings, setting, raw, sizeof ( raw ) );
 | 
		
	
		
			
			|  | 1103 | +	/* Allocate buffer for raw value */
 | 
		
	
		
			
			|  | 1104 | +	raw = malloc ( raw_len );
 | 
		
	
		
			
			|  | 1105 | +	if ( ! raw ) {
 | 
		
	
		
			
			|  | 1106 | +		rc = -ENOMEM;
 | 
		
	
		
			
			|  | 1107 | +		goto err_alloc_raw;
 | 
		
	
		
			
			| 1105 | 1108 |  	}
 | 
		
	
		
			
			|  | 1109 | +
 | 
		
	
		
			
			|  | 1110 | +	/* Parse formatted value */
 | 
		
	
		
			
			|  | 1111 | +	check_len = setting->type->parse ( value, raw, raw_len );
 | 
		
	
		
			
			|  | 1112 | +	assert ( check_len == raw_len );
 | 
		
	
		
			
			|  | 1113 | +
 | 
		
	
		
			
			|  | 1114 | +	/* Store raw value */
 | 
		
	
		
			
			|  | 1115 | +	if ( ( rc = store_setting ( settings, setting, raw, raw_len ) ) != 0 )
 | 
		
	
		
			
			|  | 1116 | +		goto err_store;
 | 
		
	
		
			
			|  | 1117 | +
 | 
		
	
		
			
			|  | 1118 | + err_store:
 | 
		
	
		
			
			|  | 1119 | +	free ( raw );
 | 
		
	
		
			
			|  | 1120 | + err_alloc_raw:
 | 
		
	
		
			
			|  | 1121 | + err_parse_len:
 | 
		
	
		
			
			|  | 1122 | +	return rc;
 | 
		
	
		
			
			| 1106 | 1123 |  }
 | 
		
	
		
			
			| 1107 | 1124 |  
 | 
		
	
		
			
			| 1108 | 1125 |  /******************************************************************************
 |