static void unhash_tree(storage_t storage, const char *path, const struct element *elem) { char *download_path; FILE *descr; char buf[4096]; if (options['v']) printf("%s\n", path); if (mkdir(path, 0700) == -1 && errno != EEXIST) err(EXIT_FAILURE, "unable to restore: %s", path); download_path = path_concat("objects", elem->hash); if ((descr = storage_retrieve_file(storage, download_path)) == NULL) errx(EXIT_FAILURE, "unable to retrieve: %s", path); free(download_path); while (fgets(buf, 4096, descr) != NULL) unhash_dispatch(storage, path, buf); if (ferror(descr)) errx(EXIT_FAILURE, "unable to restore: %s", path); fclose(descr); if (chmod(path, elem->perm) == -1) warn("unable to set mode for %s", path); if (lchown(path, elem->uid, elem->gid) == -1) warn("unable to set uid/gid for %s", path); }
static void purge_file(storage_t storage, strset_t objects, char *hash) { char *download_path; FILE *descr; char buf[4096]; char *blob_hash; download_path = path_concat("objects", hash); if ((descr = storage_retrieve_file(storage, download_path)) == NULL) logger(LOG_ERROR, "unable to retrieve: %s", hash); free(download_path); while ((blob_hash = fgets(buf, 4096, descr)) != NULL) { size_t size; size = strlen(blob_hash); if (blob_hash[size - 1] != '\n') logger(LOG_ERROR, "invalid object: %s", hash); blob_hash[size - 1] = '\0'; strset_del(objects, blob_hash); } if (ferror(descr)) logger(LOG_ERROR, "unable to purge: %s", hash); fclose(descr); }
int cmd_restore(int argc, char *argv[]) { storage_t storage; FILE *backup; char *backup_name; char *download_path; char buf[4096]; if (!(argc == 3 || (argc == 2 && options['i']))) { int help_argc = 2; char *help_argv[] = { "help_err", "restore", NULL }; return cmd_help(help_argc, help_argv); } if ((storage = storage_new(argv[1], 0)) == NULL) errx(EXIT_FAILURE, "unable to open storage: %s", argv[1]); if (argc == 3) { backup_name = estrdup(argv[2]); } else { printf("Available backups:\n"); if (cmd_list(argc, argv) == EXIT_FAILURE) return EXIT_FAILURE; backup_name = readline("Enter the backup name to restore: "); /* Cleanly exit if the user did not enter any backup to restore. */ if (backup_name == NULL || strlen(backup_name) == 0) return EXIT_SUCCESS; } download_path = path_concat("backups", backup_name); free(backup_name); if ((backup = storage_retrieve_file(storage, download_path)) == NULL) errx(EXIT_FAILURE, "unable to retrieve the backup description file"); free(download_path); while (fgets(buf, 4096, backup) != NULL) unhash_dispatch(storage, "", buf); if (ferror(backup)) errx(EXIT_FAILURE, "unable to restore the backup"); fclose(backup); storage_delete(storage); return EXIT_SUCCESS; }
static void unhash_file(storage_t storage, const char *path, const struct element *elem) { FILE *res; char *download_path; FILE *descr; char buf[4096]; char *blob_hash; struct buffer *blob; if (options['v']) printf("%s\n", path); if ((res = fopen(path, "wb")) == NULL) err(EXIT_FAILURE, "unable to restore: %s", path); download_path = path_concat("objects", elem->hash); if ((descr = storage_retrieve_file(storage, download_path)) == NULL) errx(EXIT_FAILURE, "unable to retrieve: %s", path); free(download_path); while ((blob_hash = fgets(buf, 4096, descr)) != NULL) { size_t size, full_size; size = strlen(blob_hash); if (blob_hash[size - 1] != '\n') errx(EXIT_FAILURE, "invalid description file: %s", path); blob_hash[size - 1] = '\0'; blob = unhash_blob(storage, path, blob_hash); full_size = 0; while ((size = fwrite(blob->data + full_size, 1, blob->used - full_size, res)) > 0) full_size += size; buffer_delete(blob); } if (ferror(descr)) errx(EXIT_FAILURE, "unable to restore: %s", path); fclose(res); fclose(descr); }
static void purge_tree(storage_t storage, strset_t objects, char *hash) { char *download_path; FILE *descr; char buf[4096]; download_path = path_concat("objects", hash); if ((descr = storage_retrieve_file(storage, download_path)) == NULL) logger(LOG_ERROR, "unable to retrieve: %s", hash); free(download_path); while (fgets(buf, 4096, descr) != NULL) purge_dispatch(storage, objects, buf); if (ferror(descr)) logger(LOG_ERROR, "unable to purge: %s", hash); fclose(descr); }
static void mark_backup(const char *str, void *data) { struct mark_backup_args *args = data; char *download_path; FILE *backup; char buf[4096]; download_path = path_concat("backups", str); if ((backup = storage_retrieve_file(args->storage, download_path)) == NULL) logger(LOG_ERROR, "%s: unable to retrieve the description file", str); free(download_path); while (fgets(buf, 4096, backup) != NULL) purge_dispatch(args->storage, args->objects, buf); if (ferror(backup)) logger(LOG_ERROR, "unable to restore the backup"); fclose(backup); }