A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita
audio
rust
zig
deno
mpris
rockbox
mpd
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 Linus Nielsen Feltzing
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "plugin.h"
22#include "configfile.h"
23
24static void get_cfg_filename(char* buf, int buf_len, const char* filename)
25{
26 if (rb->strncmp(filename, ROCKBOX_DIR, sizeof(ROCKBOX_DIR) - 1) == 0)
27 {
28 /* allow the rockbox directory */
29 rb->snprintf(buf, buf_len, "/%s", filename);
30 return;
31 }
32
33#ifdef APPLICATION
34 rb->snprintf(buf, buf_len, PLUGIN_DATA_DIR "/%s", filename);
35#else
36 char *s;
37 rb->strcpy(buf, rb->plugin_get_current_filename());
38 s = rb->strrchr(buf, '/');
39 if (!s) /* should never happen */
40 {
41 rb->snprintf(buf, buf_len, PLUGIN_DATA_DIR "/%s", filename);
42 }
43 else
44 {
45 s++;
46 *s = '\0';
47 rb->strcat(s, filename);
48 }
49#endif
50}
51
52int configfile_save(const char *filename, const struct configdata *cfg,
53 int num_items, int version)
54{
55 int fd;
56 int i;
57 char buf[MAX_PATH];
58
59 get_cfg_filename(buf, MAX_PATH, filename);
60 fd = rb->creat(buf, 0666);
61
62 if(fd < 0)
63 return fd*10 - 1;
64
65 /* pre-allocate 10 bytes for INT */
66 rb->fdprintf(fd, "file version: %10d\n", version);
67
68 for(i = 0;i < num_items;i++) {
69 switch(cfg[i].type) {
70 case TYPE_INT:
71 /* pre-allocate 10 bytes for INT */
72 rb->fdprintf(fd, "%s: %10d\n",
73 cfg[i].name,
74 *cfg[i].int_p);
75 break;
76
77 case TYPE_BOOL:
78 rb->fdprintf(fd, "%s: %10d\n",
79 cfg[i].name,
80 (int)*cfg[i].bool_p);
81 break;
82
83 case TYPE_ENUM:
84 rb->fdprintf(fd, "%s: %s\n",
85 cfg[i].name,
86 cfg[i].values[*cfg[i].int_p]);
87 break;
88
89 case TYPE_STRING:
90 rb->fdprintf(fd, "%s: %s\n",
91 cfg[i].name,
92 cfg[i].string);
93 break;
94
95 }
96 }
97
98 rb->close(fd);
99 return 0;
100}
101
102int configfile_load(const char *filename, const struct configdata *cfg,
103 int num_items, int min_version)
104{
105 int fd;
106 int i, j;
107 char *name;
108 char *val;
109 char buf[MAX_PATH];
110 int file_version = -1;
111 int tmp;
112
113 get_cfg_filename(buf, MAX_PATH, filename);
114 fd = rb->open(buf, O_RDONLY);
115 if(fd < 0)
116 return fd*10 - 1;
117
118 while(rb->read_line(fd, buf, MAX_PATH) > 0) {
119 rb->settings_parseline(buf, &name, &val);
120
121 /* Bail out if the file version is too old */
122 if(!rb->strcmp("file version", name)) {
123 file_version = rb->atoi(val);
124 if(file_version < min_version) {
125 rb->close(fd);
126 return -1;
127 }
128 }
129
130 for(i = 0;i < num_items;i++) {
131 if(!rb->strcmp(cfg[i].name, name)) {
132 switch(cfg[i].type) {
133 case TYPE_INT:
134 tmp = rb->atoi(val);
135 /* Only set it if it's within range */
136 if(tmp >= cfg[i].min && tmp <= cfg[i].max)
137 *cfg[i].int_p = tmp;
138 break;
139
140 case TYPE_BOOL:
141 tmp = rb->atoi(val);
142 *cfg[i].bool_p = (bool)tmp;
143 break;
144
145 case TYPE_ENUM:
146 for(j = 0;j < cfg[i].max;j++) {
147 if(!rb->strcmp(cfg[i].values[j], val)) {
148 *cfg[i].int_p = j;
149 }
150 }
151 break;
152
153 case TYPE_STRING:
154 rb->strlcpy(cfg[i].string, val, cfg[i].max);
155 break;
156 }
157 }
158 }
159 }
160
161 rb->close(fd);
162 return 0;
163}
164
165int configfile_get_value(const char* filename, const char* name)
166{
167 int fd;
168 char *pname;
169 char *pval;
170 char buf[MAX_PATH];
171
172 get_cfg_filename(buf, MAX_PATH, filename);
173 fd = rb->open(buf, O_RDONLY);
174 if(fd < 0)
175 return -1;
176
177 while(rb->read_line(fd, buf, MAX_PATH) > 0)
178 {
179 rb->settings_parseline(buf, &pname, &pval);
180 if(!rb->strcmp(name, pname))
181 {
182 rb->close(fd);
183 return rb->atoi(pval);
184 }
185 }
186
187 rb->close(fd);
188 return -1;
189}
190
191int configfile_update_entry(const char* filename, const char* name, int val)
192{
193 int fd;
194 char *pname;
195 char *pval;
196 char path[MAX_PATH];
197 char buf[256];
198 int found = 0;
199 int line_len = 0;
200 int pos = 0;
201
202 /* open the current config file */
203 get_cfg_filename(path, MAX_PATH, filename);
204 fd = rb->open(path, O_RDWR);
205 if(fd < 0)
206 return -1;
207
208 /* read in the current stored settings */
209 while((line_len = rb->read_line(fd, buf, 256)) > 0)
210 {
211 rb->settings_parseline(buf, &pname, &pval);
212 if(!rb->strcmp(name, pname))
213 {
214 found = 1;
215 rb->lseek(fd, pos, SEEK_SET);
216 /* pre-allocate 10 bytes for INT */
217 rb->fdprintf(fd, "%s: %10d\n", pname, val);
218 break;
219 }
220 pos += line_len;
221 }
222
223 /* if (name/val) is a new entry just append to file */
224 if (found == 0)
225 /* pre-allocate 10 bytes for INT */
226 rb->fdprintf(fd, "%s: %10d\n", name, val);
227
228 rb->close(fd);
229
230 return found;
231}