A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 231 lines 6.4 kB view raw
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}