From c24a8e688a6312764254beac2b2520bb0c5e998d Mon Sep 17 00:00:00 2001 From: The Android Open Source Project Date: Tue, 3 Mar 2009 19:28:42 -0800 Subject: auto import from //depot/cupcake/@135843 --- tools/ota/add-property-tag.c | 141 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 tools/ota/add-property-tag.c (limited to 'tools/ota/add-property-tag.c') diff --git a/tools/ota/add-property-tag.c b/tools/ota/add-property-tag.c new file mode 100644 index 000000000..5277edd9c --- /dev/null +++ b/tools/ota/add-property-tag.c @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +/* + * Append a tag to a property value in a .prop file if it isn't already there. + * Normally used to modify build properties to record incremental updates. + */ + +// Return nonzero if the tag should be added to this line. +int should_tag(const char *line, const char *propname) { + const char *prop = strstr(line, propname); + if (prop == NULL) return 0; + + // Make sure this is actually the property name (not an accidental hit) + const char *ptr; + for (ptr = line; ptr < prop && isspace(*ptr); ++ptr) ; + if (ptr != prop) return 0; // Must be at the beginning of the line + + for (ptr += strlen(propname); *ptr != '\0' && isspace(*ptr); ++ptr) ; + return (*ptr == '='); // Must be followed by a '=' +} + +// Remove existing tags from the line, return the following number (if any) +int remove_tag(char *line, const char *tag) { + char *pos = strstr(line, tag); + if (pos == NULL) return 0; + + char *end; + int num = strtoul(pos + strlen(tag), &end, 10); + strcpy(pos, end); + return num; +} + +// Write line to output with the tag added, adding a number (if >0) +void write_tagged(FILE *out, const char *line, const char *tag, int number) { + const char *end = line + strlen(line); + while (end > line && isspace(end[-1])) --end; + if (number > 0) { + fprintf(out, "%.*s%s%d%s", end - line, line, tag, number, end); + } else { + fprintf(out, "%.*s%s%s", end - line, line, tag, end); + } +} + +int main(int argc, char **argv) { + const char *filename = "/system/build.prop"; + const char *propname = "ro.build.fingerprint"; + const char *tag = NULL; + int do_remove = 0, do_number = 0; + + int opt; + while ((opt = getopt(argc, argv, "f:p:rn")) != -1) { + switch (opt) { + case 'f': filename = optarg; break; + case 'p': propname = optarg; break; + case 'r': do_remove = 1; break; + case 'n': do_number = 1; break; + case '?': return 2; + } + } + + if (argc != optind + 1) { + fprintf(stderr, + "usage: add-property-tag [flags] tag-to-add\n" + "flags: -f /dir/file.prop (default /system/build.prop)\n" + " -p prop.name (default ro.build.fingerprint)\n" + " -r (if set, remove the tag rather than adding it)\n" + " -n (if set, add and increment a number after the tag)\n"); + return 2; + } + + tag = argv[optind]; + FILE *input = fopen(filename, "r"); + if (input == NULL) { + fprintf(stderr, "can't read %s: %s\n", filename, strerror(errno)); + return 1; + } + + char tmpname[PATH_MAX]; + snprintf(tmpname, sizeof(tmpname), "%s.tmp", filename); + FILE *output = fopen(tmpname, "w"); + if (output == NULL) { + fprintf(stderr, "can't write %s: %s\n", tmpname, strerror(errno)); + return 1; + } + + int found = 0; + char line[4096]; + while (fgets(line, sizeof(line), input)) { + if (!should_tag(line, propname)) { + fputs(line, output); // Pass through unmodified + } else { + found = 1; + int number = remove_tag(line, tag); + if (do_remove) { + fputs(line, output); // Remove the tag but don't re-add it + } else { + write_tagged(output, line, tag, number + do_number); + } + } + } + + fclose(input); + fclose(output); + + if (!found) { + fprintf(stderr, "property %s not found in %s\n", propname, filename); + remove(tmpname); + return 1; + } + + if (rename(tmpname, filename)) { + fprintf(stderr, "can't rename %s to %s: %s\n", + tmpname, filename, strerror(errno)); + remove(tmpname); + return 1; + } + + return 0; +} -- cgit v1.2.3