int share_file_copy(char **args, int arg_cnt, int pflags) { struct stat st; shfs_t *dest_fs; shfs_t **src_fs; shfs_ino_t *dest_file; shfs_ino_t **src_file; shbuf_t *buff; char fpath[PATH_MAX+1]; unsigned char *data; size_t data_len; size_t of; int src_cnt; int w_len; int err; int i; if (arg_cnt < 1) return (SHERR_INVAL); src_file = NULL; src_fs = NULL; arg_cnt--; src_cnt = 0; if (!arg_cnt) { /* create faux substitute. */ /*DEBUG: */return (SHERR_INVAL); } else { dest_file = sharetool_file(args[arg_cnt], &dest_fs); src_file = (shfs_ino_t **)calloc(arg_cnt + 1, sizeof(shfs_ino_t *)); src_fs = (shfs_t **)calloc(arg_cnt + 1, sizeof(shfs_t *)); for (i = 1; i < arg_cnt; i++) { src_file[src_cnt] = sharetool_file(args[i], &src_fs[src_cnt]); err = shfs_fstat(src_file[src_cnt], &st); src_cnt++; if (err) goto done; } } for (i = 0; i < src_cnt; i++) { shfs_t *s_fs = src_fs[i]; err = shfs_file_copy(src_file[i], dest_file); shfs_free(&s_fs); if (err) goto done; } err = 0; done: if (src_file) free(src_file); if (src_fs) free(src_fs); return (err); }
static int _shfs_lock_verify(shfs_ino_t *inode, int flags) { shstat st; int err; err = shfs_fstat(inode, &st); if (err) return (err); return (_shfs_lock_verify_hier(inode)); }
int share_file_cat(char *path, int pflags) { shstat st; shfs_t *tree; shfs_ino_t *file; shbuf_t *buff; char fpath[PATH_MAX+1]; unsigned char *data; size_t data_len; size_t of; int w_len; int err; tree = shfs_uri_init(path, 0, &file); if (!tree) return (SHERR_NOENT); err = shfs_fstat(file, &st); if (err) { shfs_free(&tree); return (err); } buff = shbuf_init(); err = shfs_read(file, buff); if (err) { shbuf_free(&buff); shfs_free(&tree); return (err); } of = 0; while (of < shbuf_size(buff)) { data_len = MIN((shbuf_size(buff) - of), 65536); data = shbuf_data(buff) + of; w_len = fwrite(data, sizeof(char), data_len, sharetool_fout); if (w_len < 0) { shbuf_free(&buff); shfs_free(&tree); return (-errno); } of += w_len; } shbuf_free(&buff); shfs_free(&tree); return (0); }
int shfs_unlock(shfs_ino_t *inode) { shstat st; int err; err = shfs_fstat(inode, &st); if (err) return (err); if (shfs_type(inode) == SHINODE_FILE_LOCK) return (SHERR_OPNOTSUPP); return (shfs_attr_unset(inode, SHATTR_FLOCK)); }
int shfs_lock_of(shfs_ino_t *inode, int flags, size_t of, size_t len) { shstat st; int err; err = shfs_fstat(inode, &st); if (err) return (err); if (shfs_type(inode) == SHINODE_FILE_LOCK) return (SHERR_OPNOTSUPP); return (shfs_attr_set(inode, SHATTR_FLOCK)); }
int shfs_rev_delta(shfs_ino_t *file, shbuf_t *diff_buff) { shstat st; shbuf_t *work_buff; shbuf_t *head_buff; shbuf_t *ref_buff; shfs_t *fs; shkey_t *key; int err; if (shfs_type(file) != SHINODE_FILE) return (SHERR_INVAL); err = shfs_fstat(file, &st); if (err) return (err); work_buff = shbuf_init(); err = shfs_read(file, work_buff); if (err) { shbuf_free(&work_buff); return (err); } /* obtain BASE branch snapshot */ head_buff = shbuf_init(); err = shfs_rev_ref_read(file, "tag", "BASE", head_buff); if (err) goto done; if (shbuf_size(work_buff) == shbuf_size(head_buff) && 0 == memcmp(shbuf_data(work_buff), shbuf_data(head_buff), shbuf_size(work_buff))) { /* no difference */ err = SHERR_AGAIN; goto done; } err = shdelta(work_buff, head_buff, diff_buff); done: shbuf_free(&work_buff); shbuf_free(&head_buff); shbuf_free(&work_buff); return (err); }
int shfs_rev_commit(shfs_ino_t *file, shfs_ino_t **rev_p) { shstat st; shbuf_t *diff_buff; shbuf_t *work_buff; shbuf_t *head_buff; shfs_ino_t *base; shfs_ino_t *repo; /* SHINODE_REPOSITORY */ shfs_ino_t *new_rev; /* SHINODE_REVISION */ shfs_ino_t *delta; /* SHINODE_DELTA */ shkey_t *rev_key; shfs_t *fs; int err; if (rev_p) *rev_p = NULL; head_buff = work_buff = diff_buff = NULL; err = shfs_fstat(file, &st); if (err) return (err); work_buff = shbuf_init(); err = shfs_read(file, work_buff); if (err) goto done; base = shfs_rev_base(file); if (base) { /* obtain delta of current file data content against BASE revision's data content. */ head_buff = shbuf_init(); err = shfs_rev_ref_read(file, "tag", "BASE", head_buff); if (err) goto done; if (shbuf_size(work_buff) == shbuf_size(head_buff) && 0 == memcmp(shbuf_data(work_buff), shbuf_data(head_buff), shbuf_size(work_buff))) { /* no difference */ err = SHERR_AGAIN; goto done; } diff_buff = shbuf_init(); err = shdelta(work_buff, head_buff, diff_buff); shbuf_free(&head_buff); if (err) return (err); rev_key = shfs_token(base); } else { /* initial revision */ rev_key = ashkey_uniq(); } repo = shfs_inode(file, NULL, SHINODE_REPOSITORY); if (!repo) { err = SHERR_IO; goto done; } /* create a new revision using previous revision's inode name */ new_rev = shfs_inode(repo, (char *)shkey_hex(rev_key), SHINODE_REVISION); if (!new_rev) { err = SHERR_IO; goto done; } /* define revision's meta information. */ shfs_meta_set(new_rev, SHMETA_USER_NAME, (char *)get_libshare_account_name()); /* save delta to new revision */ err = shfs_rev_delta_write(new_rev, diff_buff); shbuf_free(&diff_buff); if (err) goto done; /* save new revision as BASE branch head */ err = shfs_rev_base_set(file, new_rev); if (err) goto done; /* save work-data to BASE tag. */ err = shfs_rev_ref_write(file, "tag", "BASE", work_buff); shbuf_free(&work_buff); if (err) goto done; if (base) { /* tag previous revision's key token onto revision inode. */ shfs_rev_tag(new_rev, "PREV", base); } if (rev_p) *rev_p = new_rev; done: shbuf_free(&work_buff); shbuf_free(&diff_buff); shbuf_free(&head_buff); return (err); }
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); }