aboutsummaryrefslogtreecommitdiffstats
path: root/dedupe
diff options
context:
space:
mode:
authorKoushik Dutta <koushd@gmail.com>2011-07-11 13:25:04 -0700
committerKoushik Dutta <koushd@gmail.com>2011-07-11 13:25:04 -0700
commit4f1c5e37f4a0e7a758b29a87eb9d831bcdab390a (patch)
tree932a84d0d15ca963fe9179c926b81c3924801fc9 /dedupe
parent67700e791a064b936d7a221868bc55a61e2727cd (diff)
downloadbootable_recovery-4f1c5e37f4a0e7a758b29a87eb9d831bcdab390a.zip
bootable_recovery-4f1c5e37f4a0e7a758b29a87eb9d831bcdab390a.tar.gz
bootable_recovery-4f1c5e37f4a0e7a758b29a87eb9d831bcdab390a.tar.bz2
working restore
Change-Id: Id152f5f28b3836bae5884fcf2bec67b599e991c7
Diffstat (limited to 'dedupe')
-rw-r--r--dedupe/Android.mkbin242 -> 4096 bytes
-rw-r--r--dedupe/dedupe.c143
2 files changed, 117 insertions, 26 deletions
diff --git a/dedupe/Android.mk b/dedupe/Android.mk
index d61e0cb..8266c82 100644
--- a/dedupe/Android.mk
+++ b/dedupe/Android.mk
Binary files differ
diff --git a/dedupe/dedupe.c b/dedupe/dedupe.c
index 7a80f0a..94be9ba 100644
--- a/dedupe/dedupe.c
+++ b/dedupe/dedupe.c
@@ -10,13 +10,13 @@
#include <fcntl.h>
#include <limits.h>
-typedef struct DEDUPE_STORE_CTX {
+typedef struct DEDUPE_STORE_CONTEXT {
char blob_dir[PATH_MAX];
FILE *output_manifest;
};
static void usage(char** argv) {
- fprintf(stderr, "usage: %s c input_file|input_directory blob_dir output_manifest\n", argv[0]);
+ fprintf(stderr, "usage: %s c input_directory blob_dir output_manifest\n", argv[0]);
fprintf(stderr, "usage: %s x input_manifest blob_dir output_directory\n", argv[0]);
}
@@ -81,13 +81,13 @@ static int do_md5sum_file(const char* filename, unsigned char *rptr) {
return 0;
}
-static int store_st(struct DEDUPE_STORE_CTX *context, struct stat st, const char* s);
+static int store_st(struct DEDUPE_STORE_CONTEXT *context, struct stat st, const char* s);
-void print_stat(struct DEDUPE_STORE_CTX *context, char type, struct stat st, const char *f) {
+void print_stat(struct DEDUPE_STORE_CONTEXT *context, char type, struct stat st, const char *f) {
fprintf(context->output_manifest, "%c\t%o\t%d\t%d\t%s\t", type, st.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID), st.st_uid, st.st_gid, f);
}
-static int store_file(struct DEDUPE_STORE_CTX *context, struct stat st, const char* f) {
+static int store_file(struct DEDUPE_STORE_CONTEXT *context, struct stat st, const char* f) {
printf("%s\n", f);
unsigned char sumdata[SHA_DIGEST_LENGTH];
int ret;
@@ -100,12 +100,7 @@ static int store_file(struct DEDUPE_STORE_CTX *context, struct stat st, const ch
for (j = 0; j < MD5_DIGEST_LENGTH; j++)
sprintf(&psum[(j*2)], "%02x", (int)sumdata[j]);
psum[(MD5_DIGEST_LENGTH * 2)] = '\0';
-
-
- //char cmd[PATH_MAX];
- //sprintf(cmd, "cat %s > '/%s/%s'", f, context->blob_dir, psum);
- //system(cmd);
-
+
char out_blob[PATH_MAX];
sprintf(out_blob, "%s/%s", context->blob_dir, psum);
if (ret = copy_file(out_blob, f)) {
@@ -113,13 +108,11 @@ static int store_file(struct DEDUPE_STORE_CTX *context, struct stat st, const ch
return ret;
}
- //sprintf("cat %s > $OUTPUT_DIR")
-
- fprintf(context->output_manifest, "%s\n", psum);
+ fprintf(context->output_manifest, "%s\t\n", psum);
return 0;
}
-static int store_dir(struct DEDUPE_STORE_CTX *context, struct stat st, const char* d) {
+static int store_dir(struct DEDUPE_STORE_CONTEXT *context, struct stat st, const char* d) {
printf("%s\n", d);
DIR *dp = opendir(d);
if (d == NULL) {
@@ -149,7 +142,7 @@ static int store_dir(struct DEDUPE_STORE_CTX *context, struct stat st, const cha
return 0;
}
-static int store_link(struct DEDUPE_STORE_CTX *context, struct stat st, const char* l) {
+static int store_link(struct DEDUPE_STORE_CONTEXT *context, struct stat st, const char* l) {
printf("%s\n", l);
char link[PATH_MAX];
int ret = readlink(l, link, PATH_MAX);
@@ -157,11 +150,11 @@ static int store_link(struct DEDUPE_STORE_CTX *context, struct stat st, const ch
fprintf(stderr, "Error reading symlink\n");
return errno;
}
- fprintf(context->output_manifest, "%s\n", link);
+ fprintf(context->output_manifest, "%s\t\n", link);
return 0;
}
-static int store_st(struct DEDUPE_STORE_CTX *context, struct stat st, const char* s) {
+static int store_st(struct DEDUPE_STORE_CONTEXT *context, struct stat st, const char* s) {
if (S_ISREG(st.st_mode)) {
print_stat(context, 'f', st, s);
return store_file(context, st, s);
@@ -173,14 +166,15 @@ static int store_st(struct DEDUPE_STORE_CTX *context, struct stat st, const char
}
else if (S_ISLNK(st.st_mode)) {
print_stat(context, 'l', st, s);
- store_link(context, st, s);
+ return store_link(context, st, s);
}
else {
- return fprintf(stderr, "Skipping special: %s\n", s);
+ fprintf(stderr, "Skipping special: %s\n", s);
+ return 0;
}
}
-void get_full_path(char *rel_path, char *out_path) {
+void get_full_path(char *out_path, char *rel_path) {
char tmp[PATH_MAX];
getcwd(tmp, PATH_MAX);
chdir(rel_path);
@@ -188,6 +182,35 @@ void get_full_path(char *rel_path, char *out_path) {
chdir(tmp);
}
+static char* tokenize(char *out, const char* line, const char sep) {
+ while (*line != sep) {
+ if (*line == NULL) {
+ return NULL;
+ }
+
+ *out = *line;
+ out++;
+ line++;
+ }
+
+ *out = NULL;
+ // resume at the next char
+ return line + 1;
+}
+
+static int dec_to_oct(int dec) {
+ int ret = 0;
+ int mult = 1;
+ while (dec != 0) {
+ int rem = dec % 10;
+ ret += (rem * mult);
+ dec /= 10;
+ mult *= 8;
+ }
+
+ return ret;
+}
+
int main(int argc, char** argv) {
if (argc != 5) {
usage(argv);
@@ -208,23 +231,91 @@ int main(int argc, char** argv) {
}
char blob_dir[PATH_MAX];
- struct DEDUPE_STORE_CTX context;
+ struct DEDUPE_STORE_CONTEXT context;
context.output_manifest = fopen(argv[4], "wb");
if (context.output_manifest == NULL) {
fprintf(stderr, "Unable to open output file %s\n", argv[4]);
return 1;
}
- get_full_path(argv[3], context.blob_dir);
+ get_full_path(context.blob_dir, argv[3]);
chdir(argv[2]);
return store_dir(&context, st, ".");
}
else if (strcmp(argv[1], "x") == 0) {
+ FILE *input_manifest = fopen(argv[2], "rb");
+ if (input_manifest == NULL) {
+ fprintf(stderr, "Unable to open input manifest %s\n", argv[2]);
+ return 1;
+ }
+
+ char blob_dir[PATH_MAX];
+ char *output_dir = argv[4];
+ get_full_path(blob_dir, argv[3]);
+
+ printf("%s\n" , output_dir);
+ chdir(output_dir);
+
+ char line[PATH_MAX];
+ while (fgets(line, PATH_MAX, input_manifest)) {
+ //printf("%s", line);
+
+ char type[4];
+ char mode[8];
+ char uid[32];
+ char gid[32];
+ char filename[PATH_MAX];
+
+ char *token = line;
+ token = tokenize(type, token, '\t');
+ token = tokenize(mode, token, '\t');
+ token = tokenize(uid, token, '\t');
+ token = tokenize(gid, token, '\t');
+ token = tokenize(filename, token, '\t');
+
+ int mode_oct = dec_to_oct(atoi(mode));
+ int ret;
+ printf("%s\t%s\t%s\t%s\t%s\t", type, mode, uid, gid, filename);
+ if (strcmp(type, "f") == 0) {
+ char md5[41];
+ token = tokenize(md5, token, '\t');
+ printf("%s\n", md5);
+
+ char blob_file[PATH_MAX];
+ sprintf(blob_file, "%s/%s", blob_dir, md5);
+ if (ret = copy_file(filename, blob_file)) {
+ fprintf(stderr, "Unable to copy file %s\n", filename);
+ return ret;
+ }
+
+ chmod(filename, mode_oct);
+ chown(filename, uid, gid);
+ }
+ else if (strcmp(type, "l") == 0) {
+ char link[41];
+ token = tokenize(link, token, '\t');
+ printf("%s\n", link);
+
+ symlink(link, filename);
+
+ chmod(filename, mode_oct);
+ lchown(filename, uid, gid);
+ }
+ else if (strcmp(type, "d") == 0) {
+ printf("\n");
+
+ mkdir(filename, mode_oct);
+
+ chmod(filename, mode_oct);
+ chown(filename, uid, gid);
+ }
+ }
+
+ fclose(input_manifest);
+ return 0;
}
else {
usage(argv);
return 1;
}
-
- return 0;
-} \ No newline at end of file
+}