blob: 0f44b7478b33a88274264a6161e18e60106e8e85 [file] [log] [blame]
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -08001/*
2 * Copyright (C) 2007 The Android Open Source 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 <stdlib.h>
18#include <stdio.h>
19#include <string.h>
20#undef NDEBUG
21#include <assert.h>
22#include "commands.h"
23
24#include "register.h"
25
26#define UNUSED(p) ((void)(p))
27
28#define CHECK_BOOL() \
29 do { \
30 assert(argv == NULL); \
31 if (argv != NULL) return -1; \
32 assert(argc == true || argc == false); \
33 if (argc != true && argc != false) return -1; \
34 } while (false)
35
36#define CHECK_WORDS() \
37 do { \
38 assert(argc >= 0); \
39 if (argc < 0) return -1; \
40 assert(argc == 0 || argv != NULL); \
41 if (argc != 0 && argv == NULL) return -1; \
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080042 } while (false)
43
44#define CHECK_FN() \
45 do { \
46 CHECK_WORDS(); \
Doug Zongkerf28c9162009-06-02 15:30:11 -070047 assert(result != NULL); \
48 if (result == NULL) return -1; \
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080049 } while (false)
50
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080051
52/*
53 * Command definitions
54 */
55
56/* assert <boolexpr>
57 */
58static int
Doug Zongkerf28c9162009-06-02 15:30:11 -070059cmd_assert(const char *name, void *cookie, int argc, const char *argv[])
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080060{
61 UNUSED(name);
62 UNUSED(cookie);
63 CHECK_BOOL();
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080064
65 /* If our argument is false, return non-zero (failure)
66 * If our argument is true, return zero (success)
67 */
68 if (argc) {
69 return 0;
70 } else {
71 return 1;
72 }
73}
74
75/* format <root>
76 */
77static int
Doug Zongkerf28c9162009-06-02 15:30:11 -070078cmd_format(const char *name, void *cookie, int argc, const char *argv[])
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080079{
80 UNUSED(name);
81 UNUSED(cookie);
82 CHECK_WORDS();
83//xxx
84 return -1;
85}
86
87/* copy_dir <srcdir> <dstdir>
88 */
89static int
Doug Zongkerf28c9162009-06-02 15:30:11 -070090cmd_copy_dir(const char *name, void *cookie, int argc, const char *argv[])
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080091{
92 UNUSED(name);
93 UNUSED(cookie);
94 CHECK_WORDS();
95//xxx
96 return -1;
97}
98
99/* mark <resource> dirty|clean
100 */
101static int
Doug Zongkerf28c9162009-06-02 15:30:11 -0700102cmd_mark(const char *name, void *cookie, int argc, const char *argv[])
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800103{
104 UNUSED(name);
105 UNUSED(cookie);
106 CHECK_WORDS();
107//xxx when marking, save the top-level hash at the mark point
108// so we can retry on failure. Otherwise the hashes won't match,
109// or someone could intentionally dirty the FS to force a downgrade
110//xxx
111 return -1;
112}
113
114/* done
115 */
116static int
Doug Zongkerf28c9162009-06-02 15:30:11 -0700117cmd_done(const char *name, void *cookie, int argc, const char *argv[])
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800118{
119 UNUSED(name);
120 UNUSED(cookie);
121 CHECK_WORDS();
122//xxx
123 return -1;
124}
125
126int
127registerUpdateCommands()
128{
129 int ret;
130
131 ret = registerCommand("assert", CMD_ARGS_BOOLEAN, cmd_assert, NULL);
132 if (ret < 0) return ret;
133
134 ret = registerCommand("copy_dir", CMD_ARGS_WORDS, cmd_copy_dir, NULL);
135 if (ret < 0) return ret;
136
137 ret = registerCommand("format", CMD_ARGS_WORDS, cmd_format, NULL);
138 if (ret < 0) return ret;
139
140 ret = registerCommand("mark", CMD_ARGS_WORDS, cmd_mark, NULL);
141 if (ret < 0) return ret;
142
143 ret = registerCommand("done", CMD_ARGS_WORDS, cmd_done, NULL);
144 if (ret < 0) return ret;
145
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800146 return 0;
147}
148
149
150/*
151 * Function definitions
152 */
153
154/* update_forced()
155 *
156 * Returns "true" if some system setting has determined that
157 * the update should happen no matter what.
158 */
159static int
160fn_update_forced(const char *name, void *cookie, int argc, const char *argv[],
Doug Zongkerf28c9162009-06-02 15:30:11 -0700161 char **result, size_t *resultLen)
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800162{
163 UNUSED(name);
164 UNUSED(cookie);
165 CHECK_FN();
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800166
167 if (argc != 0) {
168 fprintf(stderr, "%s: wrong number of arguments (%d)\n",
169 name, argc);
170 return 1;
171 }
172
173 //xxx check some global or property
174 bool force = true;
175 if (force) {
176 *result = strdup("true");
177 } else {
178 *result = strdup("");
179 }
180 if (resultLen != NULL) {
181 *resultLen = strlen(*result);
182 }
183
184 return 0;
185}
186
187/* get_mark(<resource>)
188 *
189 * Returns the current mark associated with the provided resource.
190 */
191static int
192fn_get_mark(const char *name, void *cookie, int argc, const char *argv[],
Doug Zongkerf28c9162009-06-02 15:30:11 -0700193 char **result, size_t *resultLen)
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800194{
195 UNUSED(name);
196 UNUSED(cookie);
197 CHECK_FN();
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800198
199 if (argc != 1) {
200 fprintf(stderr, "%s: wrong number of arguments (%d)\n",
201 name, argc);
202 return 1;
203 }
204
205 //xxx look up the value
206 *result = strdup("");
207 if (resultLen != NULL) {
208 *resultLen = strlen(*result);
209 }
210
211 return 0;
212}
213
214/* hash_dir(<path-to-directory>)
215 */
216static int
217fn_hash_dir(const char *name, void *cookie, int argc, const char *argv[],
Doug Zongkerf28c9162009-06-02 15:30:11 -0700218 char **result, size_t *resultLen)
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800219{
220 int ret = -1;
221
222 UNUSED(name);
223 UNUSED(cookie);
224 CHECK_FN();
225
226 const char *dir;
227 if (argc != 1) {
228 fprintf(stderr, "%s: wrong number of arguments (%d)\n",
229 name, argc);
230 return 1;
231 } else {
232 dir = argv[0];
233 }
234
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800235//xxx build and return the string
Doug Zongkerf28c9162009-06-02 15:30:11 -0700236 *result = strdup("hashvalue");
237 if (resultLen != NULL) {
238 *resultLen = strlen(*result);
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800239 }
Doug Zongkerf28c9162009-06-02 15:30:11 -0700240 ret = 0;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800241
242 return ret;
243}
244
245/* matches(<str>, <str1> [, <strN>...])
246 * If <str> matches (strcmp) any of <str1>...<strN>, returns <str>,
247 * otherwise returns "".
248 *
249 * E.g., assert matches(hash_dir("/path"), "hash1", "hash2")
250 */
251static int
252fn_matches(const char *name, void *cookie, int argc, const char *argv[],
Doug Zongkerf28c9162009-06-02 15:30:11 -0700253 char **result, size_t *resultLen)
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800254{
255 UNUSED(name);
256 UNUSED(cookie);
257 CHECK_FN();
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800258
259 if (argc < 2) {
260 fprintf(stderr, "%s: not enough arguments (%d < 2)\n",
261 name, argc);
262 return 1;
263 }
264
265 int i;
266 for (i = 1; i < argc; i++) {
267 if (strcmp(argv[0], argv[i]) == 0) {
268 *result = strdup(argv[0]);
269 if (resultLen != NULL) {
270 *resultLen = strlen(*result);
271 }
272 return 0;
273 }
274 }
275
276 *result = strdup("");
277 if (resultLen != NULL) {
278 *resultLen = 1;
279 }
280 return 0;
281}
282
283/* concat(<str>, <str1> [, <strN>...])
284 * Returns the concatenation of all strings.
285 */
286static int
287fn_concat(const char *name, void *cookie, int argc, const char *argv[],
Doug Zongkerf28c9162009-06-02 15:30:11 -0700288 char **result, size_t *resultLen)
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800289{
290 UNUSED(name);
291 UNUSED(cookie);
292 CHECK_FN();
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800293
294 size_t totalLen = 0;
295 int i;
296 for (i = 0; i < argc; i++) {
297 totalLen += strlen(argv[i]);
298 }
299
300 char *s = (char *)malloc(totalLen + 1);
301 if (s == NULL) {
302 return -1;
303 }
304 s[totalLen] = '\0';
305 for (i = 0; i < argc; i++) {
306 //TODO: keep track of the end to avoid walking the string each time
307 strcat(s, argv[i]);
308 }
309 *result = s;
310 if (resultLen != NULL) {
311 *resultLen = strlen(s);
312 }
313
314 return 0;
315}
316
317int
318registerUpdateFunctions()
319{
320 int ret;
321
322 ret = registerFunction("update_forced", fn_update_forced, NULL);
323 if (ret < 0) return ret;
324
325 ret = registerFunction("get_mark", fn_get_mark, NULL);
326 if (ret < 0) return ret;
327
328 ret = registerFunction("hash_dir", fn_hash_dir, NULL);
329 if (ret < 0) return ret;
330
331 ret = registerFunction("matches", fn_matches, NULL);
332 if (ret < 0) return ret;
333
334 ret = registerFunction("concat", fn_concat, NULL);
335 if (ret < 0) return ret;
336
337 return 0;
338}