diff options
author | Aidan MacDonald <amachronic@protonmail.com> | 2022-11-30 12:48:09 +0000 |
---|---|---|
committer | Aidan MacDonald <amachronic@protonmail.com> | 2022-12-05 14:18:06 -0500 |
commit | a89f279fd4dfb0ecbb61d39b3e11122ebb99d94c (patch) | |
tree | 931b3c45ef367f6b21d4eca1454f6a760de226ac | |
parent | 961e73b3a1e076478e794bb79ce96b71dc81027f (diff) | |
download | rockbox-a89f279fd4dfb0ecbb61d39b3e11122ebb99d94c.tar.gz rockbox-a89f279fd4dfb0ecbb61d39b3e11122ebb99d94c.zip |
settings: Clean up NVRAM code
Code style fixes, tighten error checking, replace a static buffer
with a stack allocated one.
Change-Id: I48392fa187057cc4a07847d45147f0db9f43f509
-rw-r--r-- | apps/settings.c | 133 |
1 files changed, 70 insertions, 63 deletions
diff --git a/apps/settings.c b/apps/settings.c index 256c71267c..38f083f595 100644 --- a/apps/settings.c +++ b/apps/settings.c | |||
@@ -123,97 +123,103 @@ long lasttime = 0; | |||
123 | 123 | ||
124 | /** NVRAM stuff, if the target doesnt have NVRAM it is saved in ROCKBOX_DIR /nvram.bin **/ | 124 | /** NVRAM stuff, if the target doesnt have NVRAM it is saved in ROCKBOX_DIR /nvram.bin **/ |
125 | /* NVRAM is set out as | 125 | /* NVRAM is set out as |
126 | [0] 'R' | 126 | * |
127 | [1] 'b' | 127 | * [0] 'R' |
128 | [2] version | 128 | * [1] 'b' |
129 | [3] stored variable count | 129 | * [2] version |
130 | [4-7] crc32 checksum | 130 | * [3] stored variable count |
131 | [8-NVRAM_BLOCK_SIZE] data | 131 | * [4-7] crc32 checksum in host endian order |
132 | */ | 132 | * [8+] data |
133 | static char nvram_buffer[NVRAM_BLOCK_SIZE]; | 133 | */ |
134 | 134 | ||
135 | static bool read_nvram_data(char* buf, int max_len) | 135 | static unsigned int nvram_crc(char *buf, int max_len) |
136 | { | ||
137 | return crc_32(&buf[NVRAM_DATA_START], max_len - NVRAM_DATA_START - 1, 0xffffffff); | ||
138 | } | ||
139 | |||
140 | static void read_nvram_data(void) | ||
136 | { | 141 | { |
137 | rename_temp_file(NVRAM_FILE_TEMP, NVRAM_FILE, NVRAM_FILE".old"); | 142 | rename_temp_file(NVRAM_FILE_TEMP, NVRAM_FILE, NVRAM_FILE".old"); |
138 | unsigned crc32 = 0xffffffff; | 143 | |
139 | int var_count = 0, i = 0, buf_pos = 0; | ||
140 | int fd = open(NVRAM_FILE, O_RDONLY); | 144 | int fd = open(NVRAM_FILE, O_RDONLY); |
141 | int bytes; | ||
142 | if (fd < 0) | 145 | if (fd < 0) |
143 | return false; | 146 | return; |
144 | memset(buf,0,max_len); | 147 | |
145 | bytes = read(fd,buf,max_len); | 148 | char buf[NVRAM_BLOCK_SIZE]; |
149 | memset(buf, 0, sizeof(buf)); | ||
150 | |||
151 | ssize_t bytes = read(fd, buf, sizeof(buf)); | ||
146 | close(fd); | 152 | close(fd); |
153 | |||
147 | if (bytes < 8) /* min is 8 bytes,magic, ver, vars, crc32 */ | 154 | if (bytes < 8) /* min is 8 bytes,magic, ver, vars, crc32 */ |
148 | return false; | 155 | return; |
156 | |||
149 | /* check magic, version */ | 157 | /* check magic, version */ |
150 | if ((buf[0] != 'R') || (buf[1] != 'b') | 158 | if (buf[0] != 'R' || buf[1] != 'b' || buf[2] != NVRAM_CONFIG_VERSION) |
151 | || (buf[2] != NVRAM_CONFIG_VERSION)) | 159 | return; |
152 | return false; | 160 | |
153 | /* check crc32 */ | 161 | /* check crc32 */ |
154 | crc32 = crc_32(&buf[NVRAM_DATA_START], | 162 | unsigned int crc32 = nvram_crc(buf, sizeof(buf)); |
155 | max_len-NVRAM_DATA_START-1,0xffffffff); | 163 | if (crc32 != load_h32(&buf[4])) |
156 | if (memcmp(&crc32,&buf[4],4)) | 164 | return; |
157 | return false; | 165 | |
158 | /* all good, so read in the settings */ | 166 | /* all good, so read in the settings */ |
159 | var_count = buf[3]; | 167 | int var_count = buf[3]; |
160 | buf_pos = NVRAM_DATA_START; | 168 | size_t buf_pos = NVRAM_DATA_START; |
161 | for(i=0; i<nb_settings; i++) | 169 | for(int i = 0; i < nb_settings; i++) |
162 | { | 170 | { |
163 | int nvram_bytes = (settings[i].flags&F_NVRAM_BYTES_MASK) | 171 | const struct settings_list *setting = &settings[i]; |
164 | >>F_NVRAM_MASK_SHIFT; | 172 | int nvram_bytes = (setting->flags & F_NVRAM_BYTES_MASK) >> F_NVRAM_MASK_SHIFT; |
165 | if (nvram_bytes) | 173 | if (nvram_bytes) |
166 | { | 174 | { |
167 | if ((var_count>0) && (buf_pos<max_len)) | 175 | if (var_count > 0 && buf_pos < (size_t)bytes) |
168 | { | 176 | { |
169 | memcpy(settings[i].setting,&buf[buf_pos],nvram_bytes); | 177 | memcpy(setting->setting, &buf[buf_pos], nvram_bytes); |
170 | buf_pos += nvram_bytes; | 178 | buf_pos += nvram_bytes; |
171 | var_count--; | 179 | var_count--; |
172 | } | 180 | } |
173 | else /* should only happen when new items are added to the end */ | 181 | else /* should only happen when new items are added to the end */ |
174 | { | 182 | { |
175 | memcpy(settings[i].setting, &settings[i].default_val, nvram_bytes); | 183 | memcpy(setting->setting, &setting->default_val, nvram_bytes); |
176 | } | 184 | } |
177 | } | 185 | } |
178 | } | 186 | } |
179 | return true; | ||
180 | } | 187 | } |
181 | static bool write_nvram_data(char* buf, int max_len) | 188 | |
189 | static void write_nvram_data(void) | ||
182 | { | 190 | { |
183 | unsigned crc32 = 0xffffffff; | 191 | char buf[NVRAM_BLOCK_SIZE]; |
184 | int i = 0, buf_pos = 0; | 192 | memset(buf, 0, sizeof(buf)); |
185 | char var_count = 0; | 193 | |
186 | int fd; | ||
187 | memset(buf,0,max_len); | ||
188 | /* magic, version */ | 194 | /* magic, version */ |
189 | buf[0] = 'R'; buf[1] = 'b'; | 195 | buf[0] = 'R'; |
196 | buf[1] = 'b'; | ||
190 | buf[2] = NVRAM_CONFIG_VERSION; | 197 | buf[2] = NVRAM_CONFIG_VERSION; |
191 | buf_pos = NVRAM_DATA_START; | 198 | |
192 | for(i=0; (i<nb_settings) && (buf_pos<max_len); i++) | 199 | size_t buf_pos = NVRAM_DATA_START; |
200 | int var_count = 0; | ||
201 | for(int i = 0; i < nb_settings && buf_pos < sizeof(buf); i++) | ||
193 | { | 202 | { |
194 | int nvram_bytes = (settings[i].flags&F_NVRAM_BYTES_MASK) | 203 | const struct settings_list *setting = &settings[i]; |
195 | >>F_NVRAM_MASK_SHIFT; | 204 | int nvram_bytes = (setting->flags & F_NVRAM_BYTES_MASK) >> F_NVRAM_MASK_SHIFT; |
196 | if (nvram_bytes) | 205 | if (nvram_bytes) |
197 | { | 206 | { |
198 | memcpy(&buf[buf_pos],settings[i].setting,nvram_bytes); | 207 | memcpy(&buf[buf_pos], setting->setting, nvram_bytes); |
199 | buf_pos += nvram_bytes; | 208 | buf_pos += nvram_bytes; |
200 | var_count++; | 209 | var_count++; |
201 | } | 210 | } |
202 | } | 211 | } |
212 | |||
203 | /* count and crc32 */ | 213 | /* count and crc32 */ |
204 | buf[3] = var_count; | 214 | buf[3] = var_count; |
205 | crc32 = crc_32(&buf[NVRAM_DATA_START], | 215 | store_h32(&buf[4], nvram_crc(buf, sizeof(buf))); |
206 | max_len-NVRAM_DATA_START-1,0xffffffff); | 216 | |
207 | memcpy(&buf[4],&crc32,4); | 217 | int fd = open(NVRAM_FILE_TEMP,O_CREAT|O_TRUNC|O_WRONLY, 0666); |
208 | fd = open(NVRAM_FILE_TEMP,O_CREAT|O_TRUNC|O_WRONLY, 0666); | 218 | if (fd < 0) |
209 | if (fd >= 0) | 219 | return; |
210 | { | 220 | |
211 | int len = write(fd,buf,max_len); | 221 | write(fd, buf, sizeof(buf)); |
212 | close(fd); | 222 | close(fd); |
213 | if (len < 8) | ||
214 | return false; | ||
215 | } | ||
216 | return true; | ||
217 | } | 223 | } |
218 | 224 | ||
219 | /** Reading from a config file **/ | 225 | /** Reading from a config file **/ |
@@ -222,9 +228,9 @@ static bool write_nvram_data(char* buf, int max_len) | |||
222 | */ | 228 | */ |
223 | void settings_load(int which) | 229 | void settings_load(int which) |
224 | { | 230 | { |
225 | if (which&SETTINGS_RTC) | 231 | if (which & SETTINGS_RTC) |
226 | read_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE); | 232 | read_nvram_data(); |
227 | if (which&SETTINGS_HD) | 233 | if (which & SETTINGS_HD) |
228 | { | 234 | { |
229 | rename_temp_file(CONFIGFILE_TEMP, CONFIGFILE, CONFIGFILE".old"); | 235 | rename_temp_file(CONFIGFILE_TEMP, CONFIGFILE, CONFIGFILE".old"); |
230 | settings_load_config(CONFIGFILE, false); | 236 | settings_load_config(CONFIGFILE, false); |
@@ -604,16 +610,17 @@ static bool settings_write_config(const char* filename, int options) | |||
604 | 610 | ||
605 | static void flush_global_status_callback(void) | 611 | static void flush_global_status_callback(void) |
606 | { | 612 | { |
607 | write_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE); | 613 | write_nvram_data(); |
608 | } | 614 | } |
609 | 615 | ||
610 | static void flush_config_block_callback(void) | 616 | static void flush_config_block_callback(void) |
611 | { | 617 | { |
612 | write_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE); | 618 | write_nvram_data(); |
613 | settings_write_config(CONFIGFILE_TEMP, SETTINGS_SAVE_CHANGED); | 619 | settings_write_config(CONFIGFILE_TEMP, SETTINGS_SAVE_CHANGED); |
614 | } | 620 | } |
615 | 621 | ||
616 | void reset_runtime(void) { | 622 | void reset_runtime(void) |
623 | { | ||
617 | lasttime = current_tick; | 624 | lasttime = current_tick; |
618 | global_status.runtime = 0; | 625 | global_status.runtime = 0; |
619 | } | 626 | } |