OSDN Git Service

ext4_utils: Yet another MMC discard pain in the ass
[android-x86/system-extras.git] / su / utils.c
1 /*
2 ** Copyright 2012, The CyanogenMod Project
3 **
4 ** Licensed under the Apache License, Version 2.0 (the "License");
5 ** you may not use this file except in compliance with the License.
6 ** You may obtain a copy of the License at
7 **
8 **     http://www.apache.org/licenses/LICENSE-2.0
9 **
10 ** Unless required by applicable law or agreed to in writing, software
11 ** distributed under the License is distributed on an "AS IS" BASIS,
12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 ** See the License for the specific language governing permissions and
14 ** limitations under the License.
15 */
16
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <unistd.h>
20 #include <limits.h>
21 #include <fcntl.h>
22 #include <errno.h>
23 #include <ctype.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include "utils.h"
29
30 /* reads a file, making sure it is terminated with \n \0 */
31 char* read_file(const char *fn)
32 {
33     struct stat st;
34     char *data = NULL;
35
36     int fd = open(fn, O_RDONLY);
37     if (fd < 0) return data;
38
39     if (fstat(fd, &st)) goto oops;
40
41     data = malloc(st.st_size + 2);
42     if (!data) goto oops;
43
44     if (read(fd, data, st.st_size) != st.st_size) goto oops;
45     close(fd);
46     data[st.st_size] = '\n';
47     data[st.st_size + 1] = 0;
48     return data;
49
50 oops:
51     close(fd);
52     if (data) free(data);
53     return NULL;
54 }
55
56 int get_property(const char *data, char *found, const char *searchkey, const char *not_found)
57 {
58     char *key, *value, *eol, *sol, *tmp;
59     if (data == NULL) goto defval;
60     int matched = 0;
61     char *dup = strdup(data);
62
63     sol = dup;
64     while((eol = strchr(sol, '\n'))) {
65         key = sol;
66         *eol++ = 0;
67         sol = eol;
68
69         value = strchr(key, '=');
70         if(value == 0) continue;
71         *value++ = 0;
72
73         while(isspace(*key)) key++;
74         if(*key == '#') continue;
75         tmp = value - 2;
76         while((tmp > key) && isspace(*tmp)) *tmp-- = 0;
77
78         while(isspace(*value)) value++;
79         tmp = eol - 2;
80         while((tmp > value) && isspace(*tmp)) *tmp-- = 0;
81
82         if (strncmp(searchkey, key, strlen(searchkey)) == 0) {
83             matched = 1;
84             break;
85         }
86     }
87     free(dup);
88     int len;
89     if (matched) {
90         len = strlen(value);
91         if (len >= PROPERTY_VALUE_MAX)
92             return -1;
93         memcpy(found, value, len + 1);
94     } else goto defval;
95     return len;
96
97 defval:
98     len = strlen(not_found);
99     memcpy(found, not_found, len + 1);
100     return len;
101 }
102
103 /*
104  * Fast version of get_property which purpose is to check
105  * whether the property with given prefix exists.
106  *
107  * Assume nobody is stupid enough to put a propery with prefix ro.cm.version
108  * in his build.prop on a non-CM ROM and comment it out.
109  */
110 int check_property(const char *data, const char *prefix)
111 {
112     if (!data)
113         return 0;
114     return strstr(data, prefix) != NULL;
115 }