示例#1
0
文件: store.c 项目: pmyadlowsky/mash
FILE *store_open_file(const char *file, const char *mode) {
	char path[PATH_MAX];
	FILE *stream;
	sprintf(path, "%s/%s", store_dir(), file);
	stream = fopen(path, mode);
	return stream;
	}
示例#2
0
文件: store.c 项目: pmyadlowsky/mash
static sqlite3 *sql_handle(void) {
	char path[PATH_MAX];
	int rc;
	if (_sql_handle != NULL) return _sql_handle;
	sprintf(path, "%s/sql.db", store_dir());
	rc = sqlite3_open(path, &_sql_handle);
	if (rc) {
		logmsg("can't open database '%s': %s\n", path,
			sqlite3_errmsg(_sql_handle));
		sqlite3_close(_sql_handle);
		_sql_handle = NULL;
		}
	return _sql_handle;
	}
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);
    }
    else if (S_ISDIR(st.st_mode)) {
        print_stat(context, 'd', st, s);
        fprintf(context->output_manifest, "\n");
        return store_dir(context, st, s);
    }
    else if (S_ISLNK(st.st_mode)) {
        print_stat(context, 'l', st, s);
        return store_link(context, st, s);
    }
    else {
        fprintf(stderr, "Skipping special: %s\n", s);
        return 0;
    }
}
示例#4
0
文件: store.c 项目: pmyadlowsky/mash
int store_delete_file(const char *file) {
	char path[PATH_MAX];
	sprintf(path, "%s/%s", store_dir(), file);
	return unlink(path);
	}
int dedupe_main(int argc, char** argv) {
    if (argc < 3) {
        usage(argv);
        return 1;
    }

    if (strcmp(argv[1], "c") == 0) {
        if (argc < 5) {
            usage(argv);
            return 1;
        }

        struct stat st;
        int ret;
        if (0 != (ret = lstat(argv[2], &st))) {
            fprintf(stderr, "Error opening input_file/input_directory.\n");
            return ret;
        }

        if (!S_ISDIR(st.st_mode)) {
            fprintf(stderr, "%s must be a directory.\n", argv[2]);
            return 1;
        }

        struct DEDUPE_STORE_CONTEXT context;
        context.output_manifest = fopen(argv[4], "wb");
        fprintf(context.output_manifest, "dedupe\t%d\n", DEDUPE_VERSION);
        if (context.output_manifest == NULL) {
            fprintf(stderr, "Unable to open output file %s\n", argv[4]);
            return 1;
        }
        mkdir(argv[3], S_IRWXU | S_IRWXG | S_IRWXO);
        realpath(argv[3], context.blob_dir);
        chdir(argv[2]);
        context.excludes = argv + 5;
        context.exclude_count = argc - 5;

        return store_dir(&context, st, ".");
    }
    else if (strcmp(argv[1], "x") == 0) {
        if (argc != 5) {
            usage(argv);
            return 1;
        }

        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];
        realpath(argv[3], blob_dir);

        printf("%s\n" , output_dir);
        mkdir(output_dir, S_IRWXU | S_IRWXG | S_IRWXO);
        if (chdir(output_dir)) {
            fprintf(stderr, "Unable to open output directory %s\n", output_dir);
            return 1;
        }

        char line[PATH_MAX];
        fgets(line, PATH_MAX, input_manifest);
        int version = 1;
        if (sscanf(line, "dedupe\t%d", &version) != 1) {
            fseek(input_manifest, 0, SEEK_SET);
        }
        if (version > DEDUPE_VERSION) {
            fprintf(stderr, "Attempting to restore newer dedupe file: %s\n", argv[2]);
            return 1;
        }
        while (fgets(line, PATH_MAX, input_manifest)) {
            //printf("%s", line);

            char type[4];
            char mode[8];
            char uid[32];
            char gid[32];
            char at[32];
            char mt[32];
            char ct[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');
            if (version >= 2) {
                token = tokenize(at, token, '\t');
                token = tokenize(mt, token, '\t');
                token = tokenize(ct, token, '\t');
            }
            token = tokenize(filename, token, '\t');

            int mode_oct = dec_to_oct(atoi(mode));
            int uid_int = atoi(uid);
            int gid_int = atoi(gid);
            int ret;
            //printf("%s\t%s\t%s\t%s\t%s\t", type, mode, uid, gid, filename);
            printf("%s\n", filename);
            if (strcmp(type, "f") == 0) {
                char sha256[128];
                token = tokenize(sha256, token, '\t');
                char sizeStr[32];
                token = tokenize(sizeStr, token, '\t');
                int size = atoi(sizeStr);
                // printf("%s\t%d\n", sha256, size);

                char blob_file[PATH_MAX];
                sprintf(blob_file, "%s/%s", blob_dir, sha256);
                if (ret = copy_file(blob_file, filename)) {
                    fprintf(stderr, "Unable to copy file %s\n", filename);
                    fclose(input_manifest);
                    return ret;
                }

                chown(filename, uid_int, gid_int);
                chmod(filename, mode_oct);
            }
            else if (strcmp(type, "l") == 0) {
                char link[41];
                token = tokenize(link, token, '\t');
                // printf("%s\n", link);

                symlink(link, filename);

                // Android has no lchmod, and chmod follows symlinks
                //chmod(filename, mode_oct);
                lchown(filename, uid_int, gid_int);
            }
            else if (strcmp(type, "d") == 0) {
                // printf("\n");

                mkdir(filename, mode_oct);

                chown(filename, uid_int, gid_int);
                chmod(filename, mode_oct);
            }
            else {
                fprintf(stderr, "Unknown type %s\n", type);
                fclose(input_manifest);
                return 1;
            }
            if (version >= 2) {
                struct timeval times[2];
                times[0].tv_sec = atol(at);
                times[1].tv_sec = atol(mt);
                utimes(filename, times);
            }
        }

        fclose(input_manifest);
        return 0;
    }
    else if (strcmp(argv[1], "gc") == 0) {
        if (argc < 3) {
            usage(argv);
            return 1;
        }
        
        char blob_dir[PATH_MAX];
        realpath(argv[2], blob_dir);
        if (check_file(blob_dir)) {
            fprintf(stderr, "Unable to open blobs dir: %s\n", blob_dir);
            return 1;
        }

        char gc_dir[PATH_MAX];
        sprintf(gc_dir, "%s/%s", blob_dir, ".gc");
        mkdir(gc_dir, S_IRWXU | S_IRWXG | S_IRWXO);
        if (check_file(gc_dir)) {
            fprintf(stderr, "Unable to open gc dir: %s\n", gc_dir);
            return 1;
        }

        char blob[PATH_MAX];
        int i;
        int failure = 0;
        for (i = 3; i < argc; i++) {
            FILE *input_manifest = fopen(argv[i], "rb");
            if (input_manifest == NULL) {
                fprintf(stderr, "Unable to open input manifest %s\n", argv[i]);
                return 1;
            }

            char line[PATH_MAX];
            fgets(line, PATH_MAX, input_manifest);
            int version = 1;
            if (sscanf(line, "dedupe\t%d", &version) != 1) {
                fseek(input_manifest, 0, SEEK_SET);
            }
            if (version > DEDUPE_VERSION) {
                fprintf(stderr, "Attempting to gc newer dedupe file: %s\n", argv[2]);
                failure = 1;
                fclose(input_manifest);
                break;
            }
            while (fgets(line, PATH_MAX, input_manifest)) {
                char type[4];
                char mode[8];
                char uid[32];
                char gid[32];
                char at[32];
                char mt[32];
                char ct[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');
                if (version >= 2) {
                    token = tokenize(at, token, '\t');
                    token = tokenize(mt, token, '\t');
                    token = tokenize(ct, token, '\t');
                }
                token = tokenize(filename, token, '\t');

                int mode_oct = dec_to_oct(atoi(mode));
                int uid_int = atoi(uid);
                int gid_int = atoi(gid);
                int ret;
                // printf("%s\n", filename);
                if (strcmp(type, "f") == 0) {
                    char key[128];
                    token = tokenize(key, token, '\t');
                    char sizeStr[32];
                    token = tokenize(sizeStr, token, '\t');
                    int size = atoi(sizeStr);
                    
                    sprintf(blob, "%s/%s", blob_dir, key);
                    char dst[PATH_MAX];
                    sprintf(dst, "%s/%s", gc_dir, key);
                    struct stat file_info;
                    if (stat(blob, &file_info) == 0) {
                        // keys can have a single parent directory. make sure it exists
                        mkdir(dirname(dst), S_IRWXU | S_IRWXG | S_IRWXO);
                        rename(blob, dst);
                    }
                }
            }
            fclose(input_manifest);
        }

        // rm -rf
        if (!failure)
            recursive_delete_skip_gc(blob_dir);

        // move .gc over
        char dst[PATH_MAX];
        DIR *dp = opendir(gc_dir);
        if (dp == NULL) {
            fprintf(stderr, "Error opening directory: %s\n", gc_dir);
            return 1;
        }
        struct dirent *ep;
        while (ep = readdir(dp)) {
            if (strcmp(ep->d_name, ".") == 0)
                continue;
            if (strcmp(ep->d_name, "..") == 0)
                continue;
            struct stat cst;
            int ret;
            sprintf(blob, "%s/%s", gc_dir, ep->d_name);
            sprintf(dst, "%s/%s", blob_dir, ep->d_name);
            if ((ret = lstat(blob, &cst))) {
                fprintf(stderr, "Error opening: %s\n", ep->d_name);
                continue;
            }

            if (rename(blob, dst)) {
                fprintf(stderr, "Error moving: %s\n", ep->d_name);
            }
        }
        closedir(dp);

        return failure;
    }
    else {
        usage(argv);
        return 1;
    }
}