int share_file_copy_cb(SHFL *src_file, SHFL *dest_file) { shpeer_t *src_peer = shfs_inode_peer(src_file); int err; if (0 == strcmp(src_peer->label, "file")) { char path[PATH_MAX+1]; /* set link to local-disk path. */ sprintf(path, "%s", shfs_inode_path(src_file)); err = shfs_ext_set(src_file, path); if (err) return (err); } /* perform file copy */ err = shfs_file_copy(src_file, dest_file); if (err) { fprintf(sharetool_fout, "%s: error copying \"%s\" to \"%s\": %s [sherr %d].\n", process_path, shfs_filename(src_file), shfs_filename(dest_file), sherrstr(err), err); return (err); } if (!(run_flags & PFLAG_QUIET) && (run_flags & PFLAG_VERBOSE)) { fprintf(sharetool_fout, "%s: %s \"%s\" copied to %s \"%s\".\n", process_path, shfs_type_str(shfs_type(src_file)), shfs_filename(src_file), shfs_type_str(shfs_type(dest_file)), shfs_filename(dest_file)); } return (0); }
/** reference a revision by name */ int shfs_rev_ref(shfs_ino_t *file, char *group, char *name, shfs_ino_t *rev) { shfs_ino_t *branch; shfs_ino_t *ref; shkey_t *ref_key; char buf[SHFS_PATH_MAX]; int err; if (!rev) { return (SHERR_INVAL); } if (shfs_type(rev) != SHINODE_REVISION) return (SHERR_INVAL); ref_key = shkey_hexgen(shfs_filename(rev)); if (!ref_key) return (SHERR_IO); if (shkey_cmp(ref_key, ashkey_blank())) { /* not a revision (filename has no hex key) */ shkey_free(&ref_key); return (SHERR_INVAL); } memset(buf, 0, sizeof(buf)); snprintf(buf, sizeof(buf)-1, "%s/%s", group, name); err = shfs_obj_set(file, buf, ref_key); shkey_free(&ref_key); if (err) return (err); return (0); }
int shfs_ref_get(shfs_ino_t *file, shfs_t **ref_fs_p, shfs_ino_t **ref_p) { shfs_ino_t *ref; shfs_ino_t *parent; shpeer_t *peer; shfs_t *fs; shkey_t *hier; shbuf_t *buff; char path[SHFS_PATH_MAX]; int hier_cnt; int err; int i; *ref_p = NULL; *ref_fs_p = NULL; if (!file || !file->tree) return (SHERR_INVAL); buff = shbuf_init(); err = _shfs_ref_raw_read(file, buff); if (err) return (err); peer = (shpeer_t *)shbuf_data(buff); hier = (shkey_t *)(shbuf_data(buff) + sizeof(shpeer_t)); fs = shfs_init(peer); if (!fs) return (SHERR_IO); memset(path, 0, sizeof(path)); strcpy(path, "/"); ref = fs->fsbase_ino; for (i = SHFS_MAX_REFERENCE_HIERARCHY - 1; i >= 0; i--) { if (shkey_cmp(&hier[i], ashkey_blank())) continue; if (shkey_cmp(&hier[i], shfs_token(file->tree->fsbase_ino))) continue; ref = shfs_inode_load(ref, &hier[i]); if (!ref) { shfs_free(&fs); return (SHERR_NOENT); } if (shfs_type(ref) == SHINODE_DIRECTORY) strncat(path, "/", SHFS_PATH_MAX - strlen(path) - 1); strncat(path, shfs_filename(ref), SHFS_PATH_MAX - strlen(path) - 1); } shbuf_free(&buff); *ref_p = ref; *ref_fs_p = fs; return (0); }
int share_file_copy_recursive(SHFL *dest_file, char *fname) { shfs_dirent_t *ents; shfs_t *fs; SHFL **files; SHFL *dir; struct stat st; char spec_prefix[SHFS_PATH_MAX]; char spec_dir[SHFS_PATH_MAX]; char spec_fname[SHFS_PATH_MAX]; char path[SHFS_PATH_MAX]; char work_path[SHFS_PATH_MAX]; char buf[4096]; char *list_fname; char *ptr; int ent_nr; int err; int i; memset(spec_prefix, 0, sizeof(spec_prefix)); ptr = strstr(fname, ":/"); if (ptr) { ptr += 2; strncpy(spec_prefix, fname, MIN(sizeof(spec_prefix)-1, (ptr-fname))); fname += strlen(spec_prefix); } if (!strchr(fname, '/') || 0 == strncmp(fname, "./", 2)) { if (0 == strncmp(fname, "./", 2)) fname += 2; strcpy(spec_prefix, "file:/"); getcwd(buf, sizeof(buf)-1); strcat(buf, "/"); strcat(buf, fname); ptr = strrchr(buf, '/'); strncpy(spec_dir, buf + 1, strlen(buf) - strlen(ptr)); sprintf(spec_fname, "%s%s", spec_dir, ptr+1); list_fname = basename(spec_fname); } else { memset(spec_fname, 0, sizeof(spec_fname)); strncpy(spec_fname, fname, sizeof(spec_fname)-1); list_fname = basename(spec_fname); memset(spec_dir, 0, sizeof(spec_dir)); strncpy(spec_dir, fname, MIN(strlen(fname) - strlen(list_fname), sizeof(spec_dir)-1)); } sprintf(path, "%s%s", spec_prefix, spec_dir); fprintf(stderr, "DEBUG: file_recursive: shfs_uri_init(%s)\n", path); fs = shfs_uri_init(path, 0, &dir); if (!*list_fname) { /* directory reference. */ ent_nr = 1; files = (SHFL **)calloc(ent_nr+1, sizeof(SHFL *)); if (!files) return (SHERR_NOMEM); files[0] = dir; } else { /* search files in directory */ err = 0; ent_nr = shfs_list(dir, list_fname, &ents); if (ent_nr <= 0) return (ent_nr); err = SHERR_NOENT; files = (SHFL **)calloc(ent_nr+1, sizeof(SHFL *)); if (!files) return (SHERR_NOMEM); for (i = 0; i < ent_nr; i++) { ptr = strstr(spec_dir, ":/"); if (ptr) { sprintf(path, "%s%s", ptr+2, ents[i].d_name); } else { sprintf(path, "%s%s", spec_dir, ents[i].d_name); } err = shfs_stat(fs, path, &st); if (err) break; files[i] = shfs_file_find(fs, path); } shfs_list_free(&ents); if (err) { free(files); return (err); } } #if 0 /* handle recursive hierarchy */ if ((run_flags & PFLAG_RECURSIVE)) { for (i = 0; i < ent_nr; i++) { if (shfs_type(files[i]) != SHINODE_DIRECTORY) continue; /* .. */ } } #endif for (i = 0; i < ent_nr; i++) { /* perform file copy */ err = shfs_file_copy(files[i], dest_file); if (err) { fprintf(sharetool_fout, "%s: error copying \"%s\" to \"%s\": %s [sherr %d].\n", process_path, shfs_filename(files[i]), shfs_filename(dest_file), sherrstr(err), err); return (err); } if (!(run_flags & PFLAG_QUIET) && (run_flags & PFLAG_VERBOSE)) { fprintf(sharetool_fout, "%s: %s \"%s\" copied to %s \"%s\".\n", process_path, shfs_type_str(shfs_type(files[i])), shfs_filename(files[i]), shfs_type_str(shfs_type(dest_file)), shfs_filename(dest_file)); } } free(files); shfs_free(&fs); return (0); }
int shfs_file_copy(shfs_ino_t *src_file, shfs_ino_t *dest_file) { shfs_t *ref_fs; shfs_ino_t *ref; shstat st; shbuf_t *buff; int err; if (!src_file || !dest_file) return (SHERR_INVAL); /* ensure there is something to copy */ err = shfs_fstat(src_file, &st); if (err) { fprintf(stderr, "DEBUG: shfs_file_copy: %d = shfs_fstat(src_file)\n", err); return (err); } if (shfs_type(dest_file) == SHINODE_DIRECTORY) { #if 0 /* extract tar archive */ if (shfs_format(dest_file) == SHINODE_BINARY && 0 == strcmp(shfs_meta_get(dest_file, "content.mime"), "application/x-tar")) { buff = shbuf_init(); err = shfs_read(src_file, buff); if (err) { shbuf_free(&buff); return (err); } err = shfs_unarch(buff, dest_file); shbuf_free(&buff); return (0); } #endif if (!(shfs_attr(src_file) & SHATTR_ARCH)) { if (IS_INODE_CONTAINER(shfs_type(src_file))) { dest_file = shfs_inode(dest_file, shfs_filename(src_file), shfs_type(src_file)); } else { dest_file = shfs_inode(dest_file, NULL, shfs_type(src_file)); } } } ref = NULL; ref_fs = NULL; if (shfs_format(dest_file) == SHINODE_REFERENCE) { /* apply operation to end-point inode. */ err = shfs_ref_get(dest_file, &ref_fs, &ref); if (err) { fprintf(stderr, "DEBUG: shfs_file_copy: %d = shfs_ref_get(dest_file)\n", err); return (err); } dest_file = ref; } if (shfs_format(dest_file) != SHINODE_EXTERNAL) { /* direct copy data content without conversion when applicable. */ switch (shfs_format(src_file)) { #if 0 case SHINODE_COMPRESS: err = shfs_zlib_copy(src_file, dest_file); if (err) return (err); return (0); #endif } } /* default case */ buff = shbuf_init(); err = shfs_read(src_file, buff); if (err) { fprintf(stderr, "DEBUG: shfs_file_copy: %d = shfs_read()\n", err); goto done; } err = shfs_write(dest_file, buff); shbuf_free(&buff); if (err) { fprintf(stderr, "DEBUG: shfs_file_copy: %d = shfs_write()\n", err); goto done; } /* success */ err = 0; done: shbuf_free(&buff); if (ref_fs) shfs_free(&ref_fs); return (err); }