summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAidan MacDonald <amachronic@protonmail.com>2022-11-30 12:48:09 +0000
committerAidan MacDonald <amachronic@protonmail.com>2022-12-05 14:18:06 -0500
commita89f279fd4dfb0ecbb61d39b3e11122ebb99d94c (patch)
tree931b3c45ef367f6b21d4eca1454f6a760de226ac
parent961e73b3a1e076478e794bb79ce96b71dc81027f (diff)
downloadrockbox-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.c133
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
133static char nvram_buffer[NVRAM_BLOCK_SIZE]; 133 */
134 134
135static bool read_nvram_data(char* buf, int max_len) 135static 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
140static 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}
181static bool write_nvram_data(char* buf, int max_len) 188
189static 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 */
223void settings_load(int which) 229void 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
605static void flush_global_status_callback(void) 611static 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
610static void flush_config_block_callback(void) 616static 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
616void reset_runtime(void) { 622void reset_runtime(void)
623{
617 lasttime = current_tick; 624 lasttime = current_tick;
618 global_status.runtime = 0; 625 global_status.runtime = 0;
619} 626}