Пример #1
0
const shseed_t *shpam_shadow_pass(shfs_ino_t *file, uint64_t uid)
{
  static shseed_t ret_seed;
  shbuf_t *buff;
  shseed_t *seeds;
  int total;
  int idx;
  int err;

  memset(&ret_seed, 0, sizeof(ret_seed));

  buff = shbuf_init();
  err = shfs_read(file, buff);
  if (err) {
    shbuf_free(&buff);
    return (NULL);
  }

  seeds = (shseed_t *)shbuf_data(buff);
  total = shbuf_size(buff) / sizeof(shseed_t);
  for (idx = 0; idx < total; idx++) {
    if (seeds[idx].seed_uid == uid) {
      memcpy(&ret_seed, &seeds[idx], sizeof(shseed_t));
      break;
    }
  }
  shbuf_free(&buff);

  if (idx != total) {
    return (&ret_seed);
  }

  return (NULL);
}
Пример #2
0
int shfs_file_pipe(shfs_ino_t *file, int fd)
{
  shbuf_t *buff;
  ssize_t b_of;
  int b_len;
  int err;

  if (file == NULL)
    return (SHERR_NOENT);

  buff = shbuf_init();
  err = shfs_read(file, buff);
  if (err) {
    shbuf_free(&buff);
    return (err);
  }

  for (b_of = 0; b_of < buff->data_of; b_of++) {
    b_len = write(fd, buff->data + b_of, buff->data_of - b_of);
    if (b_len < 0) {
      shbuf_free(&buff);
      return (-errno);
    }

    b_of += b_len;
  }

  shbuf_free(&buff);
  return (0);
}
Пример #3
0
int shfs_read_mem(char *path, char **data_p, size_t *data_len_p)
{
  shbuf_t *buff;
  size_t data_len;
  int err;

  buff = shbuf_init();
  err = shfs_mem_read(path, buff);
  if (err) {
    shbuf_free(&buff);
    return (err);
  }

  data_len = shbuf_size(buff);
  if (data_len_p) {
    *data_len_p = data_len;
  }
  if (data_p) {
    *data_p = shbuf_unmap(buff);
  } else {
    shbuf_free(&buff);
  }

  return (0);
}
Пример #4
0
int shpam_shadow_pass_remove(shfs_ino_t *file, uint64_t rem_uid)
{
  shbuf_t *rbuff;
  shbuf_t *buff;
  shseed_t *seeds;
  int total;
  int idx;
  int err;

  rbuff = shbuf_init();
  shfs_read(file, rbuff);

  buff = shbuf_init();
  seeds = (shseed_t *)shbuf_data(rbuff);
  total = shbuf_size(rbuff) / sizeof(shseed_t);
  for (idx = 0; idx < total; idx++) {
    if (seeds[idx].seed_uid == rem_uid)
      continue;

    shbuf_cat(buff, &seeds[idx], sizeof(shseed_t));
  }
  shbuf_free(&rbuff);

  err = shfs_write(file, buff);
  shbuf_free(&buff);
  if (err)
    return (err);
  
  return (0);
}
Пример #5
0
int shfs_rev_diff(shfs_ino_t *file, shkey_t *rev_key, shbuf_t *buff)
{
  shbuf_t *work_buff;
  shbuf_t *head_buff;
  shfs_ino_t *new_rev;
  shfs_ino_t *delta;
  shfs_ino_t *rev;
  shfs_t *fs;
  int err;

  if (!file || shfs_type(file) != SHINODE_FILE)
    return (SHERR_INVAL);

  if (!buff)
    return (SHERR_INVAL);

  if (!rev_key) {
    /* obtain current committed revision. */
    rev = shfs_rev_base(file);
  } else {
    rev = shfs_rev_get(file, rev_key);
  }
  if (!rev)
    return (SHERR_NOENT);

 /* obtain work-data for BASE branch revision. */
  head_buff = shbuf_init();
  err = shfs_rev_ref_read(file, "tag", "BASE", head_buff);
  if (err) {
    shbuf_free(&head_buff);
    return (err);
  }

  work_buff = shbuf_init();
  err = shfs_read(file, work_buff);
  if (err) {
    shbuf_free(&head_buff);
    shbuf_free(&work_buff);
    return (err);
  }

  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 to report */
    err = 0;
  } else {
    /* print textual difference to <buff> */
    err = shdiff(buff, shbuf_data(work_buff), shbuf_data(head_buff));
  }
  shbuf_free(&work_buff);
  shbuf_free(&head_buff);

  return (err);
}
Пример #6
0
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);
}
Пример #7
0
int shpam_shadow_pass_append(shfs_ino_t *file, shseed_t *seed)
{
  shbuf_t *buff;
  shseed_t *seeds;
  int total;
  int idx;
  int err;

  buff = shbuf_init();
  shfs_read(file, buff);

  seeds = (shseed_t *)shbuf_data(buff);
  total = shbuf_size(buff) / sizeof(shseed_t);
  for (idx = 0; idx < total; idx++) {
    if (seeds[idx].seed_uid == seed->seed_uid) {
      memcpy(&seeds[idx], seed, sizeof(shseed_t));
      break;
    }
  }
  if (idx == total) {
    shbuf_cat(buff, seed, sizeof(shseed_t));
  }

  err = shfs_write(file, buff);
  shbuf_free(&buff);
  if (err)
    return (err);
  
  return (0);
}
Пример #8
0
void sched_tx_payload(shkey_t *dest_key, void *data, size_t data_len, void *payload, size_t payload_len)
{
  tx_t *tx = (tx_t *)data;
  tx_t sig_tx;
  tx_net_t net;
  shsig_t sig;
  shsig_t new_sig;
  shbuf_t *buff;
  shpeer_t *self_peer;

  if (!data)
    return;
  if (data_len < sizeof(tx_t))
    return;

  prep_net_tx(tx, &net, dest_key, data_len + payload_len); 

  buff = shbuf_init();
  shbuf_cat(buff, &net, sizeof(tx_net_t));
  shbuf_cat(buff, data, data_len);
  if (payload && payload_len)
    shbuf_cat(buff, payload, payload_len);
tx_wrap(NULL, shbuf_data(buff) + sizeof(tx_net_t));
  broadcast_raw(shbuf_data(buff), shbuf_size(buff));
  shbuf_free(&buff);

fprintf(stderr, "DEBUG: SEND: sched_tx_payload: [OP %d] hash(%s) peer(%s) stamp(%llu) nonce(%d) method(%d) OP(%d)\n", (int)tx->tx_op, tx->hash, shkey_print(&tx->tx_peer), (unsigned long long)tx->tx_stamp, (int)tx->nonce, TXHASH_SCRYPT, (int)tx->tx_op);
}
Пример #9
0
int shproc_stop(shproc_t *proc)
{
  int err;

  if (child_proc)
    return (SHERR_INVAL);

  if (proc->proc_pid == 0)
    return (SHERR_INVAL);

  if (proc->proc_state == SHPROC_NONE)
    return (0); /* all done */

  err = kill(proc->proc_pid, SIGQUIT);  
  if (err)
    return (err);

  shproc_state_set(proc, SHPROC_NONE);

  shbuf_free(&proc->proc_buff);

  close(proc->proc_fd);
  close(proc->dgram_fd);

  proc->proc_fd =  proc->proc_pid = 0;
  proc->dgram_fd = 0;

  return (0);
}
Пример #10
0
int install_sexe_userdata(sexe_t *S, char *tag)
{
  SHFL *fl;
  shjson_t *udata;
  shfs_t *fs;
  shbuf_t *buff;
  shkey_t *k;
  char path[PATH_MAX+1];
  int is_new;

  k = shkey_str(tag);
  sprintf(path, "/sys/data/sexe/%s", shkey_hex(k)); 
  memcpy(&S->pname, k, sizeof(S->pname));
  shkey_free(&k);

  buff = shbuf_init();
  fs = shfs_init(NULL);
  fl = shfs_file_find(fs, path);
  is_new = shfs_read(fl, buff);

  udata = shjson_init(shbuf_size(buff) ? (char *)shbuf_data(buff) : NULL);
  shbuf_free(&buff);

  if (is_new)
    shjson_num_add(udata, "birth", shtimef(shtime()));

  sexe_table_set(S, udata);
  lua_setglobal(S, "userdata");
  shjson_free(&udata);

  shfs_free(&fs);

  return (0);
}
Пример #11
0
int shfs_file_notify(shfs_ino_t *file)
{
  shfs_t *tree = file->tree;
  shbuf_t *buff;
  uint32_t mode; 
  int qid;
  int err;

  if (!file || !tree)
    return (0); /* done */

  qid = _shfs_file_qid();
  if (qid == -1)
    return (SHERR_IO);

  buff = shbuf_init();
  mode = TX_FILE;
  shbuf_cat(buff, &mode, sizeof(mode));
  shbuf_cat(buff, &tree->peer, sizeof(shpeer_t));
  shbuf_catstr(buff, shfs_inode_path(file));
  err = shmsg_write(qid, buff, NULL);
  shbuf_free(&buff);
  if (err)
    return (err);

  return (0);
}
Пример #12
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);
}
Пример #13
0
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);
}
Пример #14
0
int shfs_rev_revert(shfs_ino_t *file)
{
  shbuf_t *buff;
  int err;

  buff = shbuf_init();
  err = shfs_rev_ref_read(file, "tag", "BASE", buff);
  if (err) {
    shbuf_free(&buff);
    return (err);
  }

  err = shfs_write(file, buff);
  shbuf_free(&buff);
  if (err)
    return (err);

  return (0);
}
Пример #15
0
int shfs_file_read(shfs_ino_t *file, unsigned char *data, size_t data_len)
{
  shbuf_t *buff;
  ssize_t r_len;
  int err;

  buff = shbuf_init();
  err = shfs_read(file, buff);
  if (err) {
    shbuf_free(&buff);
    return (err);
  } 

  r_len = MIN(shbuf_size(buff), data_len);
  if (shbuf_size(buff) != 0)
    memcpy(data, shbuf_data(buff), r_len);
  shbuf_free(&buff);

  return ((int)r_len);
}
Пример #16
0
int shpam_pshadow_load(shfs_ino_t *file, uint64_t uid, shseed_t *ret_seed)
{
  shbuf_t *buff;
  shseed_t *seeds;
  int total;
  int idx;
  int err;

  if (ret_seed)
    memset(ret_seed, 0, sizeof(shseed_t));

  buff = shbuf_init();
  err = shfs_read(file, buff);
  if (err) {
    shbuf_free(&buff);
    return (err);
  }

  seeds = (shseed_t *)shbuf_data(buff);
  total = shbuf_size(buff) / sizeof(shseed_t);
  if (!total) {
    shbuf_free(&buff);
    return (SHERR_NOENT); /* done */
  }

  for (idx = 0; idx < total; idx++) {
    if (seeds[idx].seed_uid == uid)
      break;
  }

  if (idx == total) {
    shbuf_free(&buff);
    return (SHERR_NOENT);
  }

  if (ret_seed)
    memcpy(ret_seed, &seeds[idx], sizeof(shseed_t));

  shbuf_free(&buff);
  return (0);
}
Пример #17
0
static void shproc_worker_signal(int sig_num)
{
  shbuf_free(&child_proc->proc_buff);
  close(child_proc->proc_fd);
  child_proc = NULL;

  /* user-supplied signal handler for spawned worker process */
  if (_shproc_signal_handler)
    (*_shproc_signal_handler)(sig_num);

  exit(0);
}
Пример #18
0
int shproc_child_poll(shproc_t *proc)
{
  struct shproc_req_t req;
  struct timeval to;
  shbuf_t *sp_buf;
  fd_set in_set;
  int r_len;
  int err;
  int fd;

  err = shproc_read(proc);
  if (err == 1)
    return (0); /* nothing to do */
  if (err)
    return (err);

  memset(&req, 0, sizeof(req));
  /* spawned worker - data receieved as request */
  sp_buf = shbuf_clone(proc->proc_buff);

  memset(&req, 0, sizeof(req));
  req.state = SHPROC_RUN;
  shbuf_clear(proc->proc_buff);
  err = shproc_write(proc, &req);

  fd = 0;
  if (proc->user_fd) {
    fd = shproc_read_fd(proc);
  }

  err = 0;
  if (proc->proc_req) {
    err = (*proc->proc_req)(fd, sp_buf);
    /* user-result data */
    shbuf_append(sp_buf, proc->proc_buff);
  }
  if (fd != 0)
    close(fd);
  shbuf_free(&sp_buf);

  memset(&req, 0, sizeof(req));
  req.state = SHPROC_IDLE;
  req.error = err;
  err = shproc_write(proc, &req);

  proc->proc_idx++;
  shproc_state_set(proc, SHPROC_IDLE);
  shbuf_clear(proc->proc_buff);

  return (0);
}
Пример #19
0
/**
 * Load supplementary credential data from a file.
 */
int shfs_cred_load(shfs_ino_t *file, shkey_t *key, unsigned char *data, size_t max_len)
{
  shfs_ino_t *cred;
  shbuf_t *buff;
  char key_buf[MAX_SHARE_HASH_LENGTH];
  int err;

  if (!(file->blk.hdr.attr & SHATTR_CRED))
    return (SHERR_NOENT);

  memset(key_buf, 0, sizeof(key_buf));
  sprintf(key_buf, "%s", shkey_hex(key));
  cred = shfs_inode(file, key_buf, SHINODE_ACCESS);
  if (!cred)
    return (SHERR_IO);

  if (cred->blk.hdr.format != SHINODE_ACCESS)
    return (SHERR_NOENT);

  buff = shbuf_init();
  err = shfs_aux_read(cred, buff);
  if (err) {
    shbuf_free(&buff);
    return (err);
  }
  if (shbuf_size(buff) == 0) {
    shbuf_free(&buff);
    return (SHERR_IO);
  }

  /* copy buffer */
  memcpy(data, shbuf_data(buff), MIN(shbuf_size(buff), max_len));
  shbuf_free(&buff);

  return (0);
}
Пример #20
0
int update_sexe_userdata(sexe_t *S)
{
  SHFL *fl;
  shjson_t *udata;
  shfs_t *fs;
  shbuf_t *buff;
  shkey_t *k;
  char path[PATH_MAX+1];
  char *str;
  int err;

  k = &S->pname;
  if (shkey_cmp(k, ashkey_blank())) {
fprintf(stderr, "DEBUG: update_sexe_userdata: no app key\n");
    return (0); /* blank */
  }
  sprintf(path, "/sys/data/sexe/%s", shkey_hex(k)); 

  lua_getglobal(S, "userdata");
  udata = sexe_table_get(S);
  if (!udata) {
fprintf(stderr, "DEBUG: update_sexe_userdata: no global 'userdata' variable.\n");
    return (SHERR_INVAL);
  }

  str = shjson_print(udata);
  if (!str) {
fprintf(stderr, "DEBUG: update_sexe_userdata: error encoding JSON.\n");
    return (SHERR_INVAL);
}
  shjson_free(&udata);

  buff = shbuf_init();
  shbuf_catstr(buff, str);
  free(str);


  fs = shfs_init(NULL);
  fl = shfs_file_find(fs, path);
  err = shfs_write(fl, buff);
  shbuf_free(&buff);
  shfs_free(&fs);

  return (err);
}
Пример #21
0
void *pstore_read(int tx_op, char *name)
{
    SHFL *fl;
    shbuf_t *buff;
    char path[PATH_MAX+1];
    char prefix[256];
    unsigned char *data;
    size_t data_len;
    int err;

    pstore_init();

    memset(prefix, 0, sizeof(prefix));
    switch (tx_op) {
    case TX_ACCOUNT:
        strcpy(prefix, "account");
        break;
    case TX_IDENT:
        strcpy(prefix, "id");
        break;
    case TX_SESSION:
        strcpy(prefix, "session");
        break;
    case TX_APP:
        strcpy(prefix, "app");
        break;
    case TX_LEDGER:
        strcpy(prefix, "ledger");
        break;
    default:
        strcpy(prefix, "default");
        break;
    }

    buff = shbuf_init();
    sprintf(path, "/sys/net/tx/%s/%s", prefix, name);
    fl = shfs_file_find(_pstore_fs, path);
    err = shfs_read(fl, buff);
    if (err) {
        shbuf_free(&buff);
        return (NULL);
    }

    return (shbuf_unmap(buff));
}
Пример #22
0
int pstore_write(int tx_op, char *name, unsigned char *data, size_t data_len)
{
    SHFL *fl;
    char prefix[256];
    char path[PATH_MAX+1];
    shbuf_t *buff;
    int err;

    pstore_init();

    memset(prefix, 0, sizeof(prefix));
    switch (tx_op) {
    case TX_ACCOUNT:
        strcpy(prefix, "account");
        break;
    case TX_IDENT:
        strcpy(prefix, "id");
        break;
    case TX_SESSION:
        strcpy(prefix, "session");
        break;
    case TX_APP:
        strcpy(prefix, "app");
        break;
    case TX_LEDGER:
        strcpy(prefix, "ledger");
        break;
    default:
        strcpy(prefix, "default");
        break;
    }

    sprintf(path, "/sys/net/tx/%s/%s", prefix, name);
    fl = shfs_file_find(_pstore_fs, path);
    buff = shbuf_init();
    shbuf_cat(buff, data, data_len);
    err = shfs_write(fl, buff);
    shbuf_free(&buff);
    if (err)
        return (err);

    return (0);
}
Пример #23
0
/**
 * @param file The inode refeferencing another inode.
 * @param ref_file The inode being referenced.
 */
int shfs_ref_set(shfs_ino_t *file, shfs_ino_t *ref_file)
{
    shfs_ino_t *parent;
    shbuf_t *buff;
    int err;
    int i;

    if (!file || !file->tree)
        return (SHERR_INVAL);

    if (shfs_type(file) != shfs_type(ref_file)) {
        if (shfs_type(ref_file) != SHINODE_DIRECTORY)
            return (SHERR_ISDIR);
        return (SHERR_NOTDIR);
    }

    buff = shbuf_init();
    shbuf_cat(buff, &file->tree->peer, sizeof(shpeer_t));

    parent = ref_file;
    for (i = 0; i < SHFS_MAX_REFERENCE_HIERARCHY; i++) {
        if (parent) {
            shbuf_cat(buff, &parent->blk.hdr.name, sizeof(shkey_t));
            parent = shfs_inode_parent(parent);
        }
    }

    err = _shfs_ref_raw_write(file, buff);
    shbuf_free(&buff);
    if (err)
        return (err);

    err = shfs_inode_write_entity(file);
    if (err)
        return (err);

    return (0);
}
Пример #24
0
int shpam_pshadow_store(shfs_ino_t *file, shseed_t *seed)
{
  shbuf_t *buff;
  shseed_t *seeds;
  int total;
  int idx;
  int err;

#if 0
  /* ensure record exists. */
  err = shpam_pshadow_load(file, seed->seed_uid, NULL);
  if (err)
    return (err);
#endif

  buff = shbuf_init();
  shfs_read(file, buff);

  seeds = (shseed_t *)shbuf_data(buff);
  total = shbuf_size(buff) / sizeof(shseed_t);
  for (idx = 0; idx < total; idx++) {
    if (seeds[idx].seed_uid == seed->seed_uid) {
      memcpy(&seeds[idx], seed, sizeof(shseed_t));
      break;
    }
  }
  if (idx == total) {
    shbuf_cat(buff, seed, sizeof(shseed_t));
  }

  err = shfs_write(file, buff);
  shbuf_free(&buff);
  if (err)
    return (err);

  return (0);
}
Пример #25
0
int confirm_tx_key(txop_t *op, tx_t *tx)
{
  shkey_t *c_key = &tx->tx_key;
  shkey_t *key;
  shbuf_t *buff;
  tx_t *k_tx;
  size_t len;
  int confirm;

  if (!op || !tx)
    return (SHERR_INVAL);

  if (op->op_size == 0)
    return (0);

  /* allocate working copy */
  len = MAX(sizeof(tx_t), op->op_keylen ? op->op_keylen : op->op_size);
  buff = shbuf_init();
  shbuf_cat(buff, (char *)tx, len);

  /* blank out tx key */
  k_tx = (tx_t *)shbuf_data(buff);
  memset(&k_tx->tx_key, '\000', sizeof(k_tx->tx_key));

  /* verify generated tx key matches. */
  key = shkey_bin(shbuf_data(buff), shbuf_size(buff));
  confirm = shkey_cmp(c_key, key);
  shkey_free(&key);
  shbuf_free(&buff);

  if (!confirm) {
    return (SHERR_INVAL);
  }

  return (0);
}
Пример #26
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);
}
Пример #27
0
/**
 * Generates the working-copy for a particular revision.
 */
int shfs_rev_read(shfs_ino_t *i_rev, shbuf_t *buff)
{
  shfs_ino_t *repo;
  shfs_ino_t *file;
  shfs_ino_t *rev;
  shbuf_t *delta_buff;
  shbuf_t *head_buff;
  shbuf_t *out_buff;
  int err;

  if (shfs_type(i_rev) != SHINODE_REVISION) {
    return (SHERR_INVAL);
  }

  repo = shfs_inode_parent(i_rev);
  if (!repo || shfs_type(repo) != SHINODE_REPOSITORY)
    return (SHERR_IO);

  file = shfs_inode_parent(repo);
  if (!file || shfs_type(file) != SHINODE_FILE)
    return (SHERR_IO);

  head_buff = shbuf_init();
  err = shfs_rev_ref_read(file, "tag", "BASE", head_buff);
  if (err)
    return (err);

  err = SHERR_NOENT; /* ret'd when no matching revision found */
  out_buff = shbuf_init();
  delta_buff = shbuf_init();

  /* search BASE chain for revision -- applying each revision's patch. */
  rev = shfs_rev_tag_resolve(file, "BASE");
  while (rev) {
    if (shkey_cmp(shfs_token(rev), shfs_token(i_rev))) {
      /* found revision in branch chain. */
      shbuf_append(head_buff, buff);
      err = 0;
      break;
    }

    shbuf_clear(delta_buff);
    err = shfs_rev_delta_read(rev, delta_buff);
    if (err)
      break;

/* DEBUG: TODO: merge together deltas to reduce performance over-head */
    shbuf_clear(out_buff);
    err = shpatch(head_buff, delta_buff, out_buff); 
    if (err)
      break;

    shbuf_clear(head_buff);
    shbuf_append(out_buff, head_buff);

    rev = shfs_rev_prev(rev);
  }

  shbuf_free(&head_buff);
  shbuf_free(&out_buff);
  shbuf_free(&delta_buff);
  return (err);
}
Пример #28
0
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);
}