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 39 #include "debug.h" 40 41 // TODO: change config path 42 #define CONFIG_PATH "/data/fastboot.cfg" 43 44 static char *strip(char *str) 45 { 46 int n; 47 48 n = strspn(str, " \t"); 49 str += n; 50 51 for (n = strlen(str) - 1; n >= 0; n--) { 52 if (str[n] == ' ' || str[n] == '\t') 53 str[n] = '\0'; 54 else 55 break; 56 } 57 58 return str; 59 } 60 61 static int config_parse_line(char *line) 62 { 63 char *c; 64 char *key; 65 char *value; 66 67 c = strchr(line, '#'); 68 if (c) 69 *c = '\0'; 70 71 if (strspn(line, " \t") == strlen(line)) 72 return 0; 73 74 c = strchr(line, '='); 75 if (c == NULL) 76 return -1; 77 78 key = line; 79 *c = '\0'; 80 value = c + 1; 81 82 key = strip(key); 83 value = strip(value); 84 85 key = strdup(key); 86 value = strdup(value); 87 88 fastboot_publish(key, value); 89 90 return 0; 91 } 92 93 static void config_parse(char *buffer) 94 { 95 char *saveptr; 96 char *str = buffer; 97 char *line = buffer; 98 int c; 99 int ret; 100 101 for (c = 1; line != NULL; c++) { 102 line = strtok_r(str, "\r\n", &saveptr); 103 if (line != NULL) { 104 D(VERBOSE, "'%s'", line); 105 ret = config_parse_line(line); 106 if (ret < 0) { 107 D(WARN, "error parsing " CONFIG_PATH " line %d", c); 108 } 109 } 110 str = NULL; 111 } 112 } 113 114 void config_init() 115 { 116 int fd; 117 off_t len; 118 ssize_t ret; 119 size_t count = 0; 120 char *buffer; 121 122 fd = open(CONFIG_PATH, O_RDONLY); 123 if (fd < 0) { 124 D(ERR, "failed to open " CONFIG_PATH); 125 return; 126 } 127 128 len = lseek(fd, 0, SEEK_END); 129 if (len < 0) { 130 D(ERR, "failed to seek to end of " CONFIG_PATH); 131 return; 132 } 133 134 lseek(fd, 0, SEEK_SET); 135 136 buffer = malloc(len + 1); 137 if (buffer == NULL) { 138 D(ERR, "failed to allocate %ld bytes", len); 139 return; 140 } 141 142 while (count < (size_t)len) { 143 ret = read(fd, buffer + count, len - count); 144 if (ret < 0 && errno != EINTR) { 145 D(ERR, "failed to read " CONFIG_PATH ": %d %s", errno, strerror(errno)); 146 return; 147 } 148 if (ret == 0) { 149 D(ERR, "early EOF reading " CONFIG_PATH); 150 return; 151 } 152 153 count += ret; 154 } 155 156 buffer[len] = '\0'; 157 158 config_parse(buffer); 159 160 free(buffer); 161 } 162