1 /* 2 * Copyright (c) 2013, Google Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google, Inc. nor the names of its contributors 15 * may be used to endorse or promote products derived from this 16 * software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 22 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 25 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 28 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 #include <fcntl.h> 33 #include <string.h> 34 #include <unistd.h> 35 #include <sys/types.h> 36 37 #include "protocol.h" 38 #include "utils.h" 39 40 #include "debug.h" 41 42 // TODO: change config path 43 #define CONFIG_PATH "/data/fastboot.cfg" 44 45 static int config_parse_line(char *line) 46 { 47 char *c; 48 char *key; 49 char *value; 50 51 c = strchr(line, '#'); 52 if (c) 53 *c = '\0'; 54 55 if (strspn(line, " \t") == strlen(line)) 56 return 0; 57 58 c = strchr(line, '='); 59 if (c == NULL) 60 return -1; 61 62 key = line; 63 *c = '\0'; 64 value = c + 1; 65 66 key = strip(key); 67 value = strip(value); 68 69 key = strdup(key); 70 value = strdup(value); 71 72 fastboot_publish(key, value); 73 74 return 0; 75 } 76 77 static void config_parse(char *buffer) 78 { 79 char *saveptr; 80 char *str = buffer; 81 char *line = buffer; 82 int c; 83 int ret; 84 85 for (c = 1; line != NULL; c++) { 86 line = strtok_r(str, "\r\n", &saveptr); 87 if (line != NULL) { 88 D(VERBOSE, "'%s'", line); 89 ret = config_parse_line(line); 90 if (ret < 0) { 91 D(WARN, "error parsing " CONFIG_PATH " line %d", c); 92 } 93 } 94 str = NULL; 95 } 96 } 97 98 void config_init() 99 { 100 int fd; 101 off_t len; 102 ssize_t ret; 103 size_t count = 0; 104 char *buffer; 105 106 fd = open(CONFIG_PATH, O_RDONLY); 107 if (fd < 0) { 108 D(ERR, "failed to open " CONFIG_PATH); 109 return; 110 } 111 112 len = lseek(fd, 0, SEEK_END); 113 if (len < 0) { 114 D(ERR, "failed to seek to end of " CONFIG_PATH); 115 return; 116 } 117 118 lseek(fd, 0, SEEK_SET); 119 120 buffer = malloc(len + 1); 121 if (buffer == NULL) { 122 D(ERR, "failed to allocate %ld bytes", len); 123 return; 124 } 125 126 while (count < (size_t)len) { 127 ret = read(fd, buffer + count, len - count); 128 if (ret < 0 && errno != EINTR) { 129 D(ERR, "failed to read " CONFIG_PATH ": %d %s", errno, strerror(errno)); 130 return; 131 } 132 if (ret == 0) { 133 D(ERR, "early EOF reading " CONFIG_PATH); 134 return; 135 } 136 137 count += ret; 138 } 139 140 buffer[len] = '\0'; 141 142 config_parse(buffer); 143 144 free(buffer); 145 } 146