示例#1
0
shfs_ino_t *shfs_rev_get(shfs_ino_t *repo, shkey_t *rev_key)
{
  shfs_ino_t *rev;

  if (shfs_type(repo) == SHINODE_FILE)
    repo = shfs_inode(repo, NULL, SHINODE_REPOSITORY);
  if (shfs_type(repo) != SHINODE_REPOSITORY)
    return (NULL);

  if (shkey_cmp(rev_key, ashkey_blank()))
    return (NULL);

  return (shfs_inode(repo, (char *)shkey_hex(rev_key), SHINODE_REVISION));
}
示例#2
0
int shfs_rev_ref_write(shfs_ino_t *file, char *group, char *name, shbuf_t *buff)
{
  shfs_ino_t *ref;
  shfs_ino_t *aux;
  char buf[SHFS_PATH_MAX];
  int err;

  memset(buf, 0, sizeof(buf));
  snprintf(buf, sizeof(buf) - 1, "%s/%s", group, name);
  ref = shfs_inode(file, buf, SHINODE_OBJECT);
  err = shfs_bin_write(ref, buff);
  if (err)
    return (err);
#if 0
  err = shfs_aux_write(aux, buff);
  if (err)
    return (err);
#endif

  err = shfs_inode_write_entity(ref);
  if (err) {
    sherr(err, "shfs_rev_ref_write [shfs_inode_write_entity]");
    return (err);
  }

#if 0
  /* copy aux stats to file inode. */
  file->blk.hdr.mtime = ref->blk.hdr.mtime;
  file->blk.hdr.size = ref->blk.hdr.size;
  file->blk.hdr.crc = ref->blk.hdr.crc;
  file->blk.hdr.format = SHINODE_OBJECT;
#endif

  return (0);
}
示例#3
0
shfs_ino_t *shfs_rev_ref_resolve(shfs_ino_t *file, char *group, char *name)
{
  shfs_ino_t *branch;
  shfs_ino_t *repo;
  shfs_ino_t *ref;
  shkey_t *key;
  char buf[SHFS_PATH_MAX];
  int obj_type;
  int err;

  if (!file)
    return (NULL);

  memset(buf, 0, sizeof(buf));
  snprintf(buf, sizeof(buf)-1, "%s/%s", group, name);
  err = shfs_obj_get(file, buf, &key);
  if (err)
    return (NULL);

  repo = shfs_inode(file, NULL, SHINODE_REPOSITORY);
  branch = shfs_rev_get(repo, key);
  shkey_free(&key);

  return (branch);
}
示例#4
0
int _shfs_ref_raw_write(shfs_ino_t *file, shbuf_t *buff)
{
    shfs_ino_t *inode;
    int err;

    if (!file)
        return (SHERR_INVAL);

    inode = shfs_inode(file, NULL, SHINODE_REFERENCE);
    if (!inode)
        return (SHERR_IO);

    if (shbuf_size(buff) > SHFS_BLOCK_DATA_SIZE) {
        return (SHERR_TOOMANYREFS);
    }

    memset((char *)inode->blk.raw, 0, SHFS_BLOCK_DATA_SIZE);
    memcpy((char *)inode->blk.raw, shbuf_data(buff), shbuf_size(buff));
    inode->blk.hdr.size = shbuf_size(buff);
    inode->blk.hdr.crc = shcrc(shbuf_data(buff), shbuf_size(buff));
    err = shfs_inode_write_entity(inode);
    if (err)
        return (err);

    /* copy aux stats to file inode. */
    file->blk.hdr.mtime = inode->blk.hdr.mtime;
    file->blk.hdr.size = inode->blk.hdr.size;
    file->blk.hdr.crc = inode->blk.hdr.crc;
    file->blk.hdr.format = SHINODE_REFERENCE;
    file->blk.hdr.attr |= SHATTR_LINK;

    return (0);
}
示例#5
0
/**
 * Store supplementary credential data in a file.
 */
int shfs_cred_store(shfs_ino_t *file, shkey_t *key, unsigned char *data, size_t data_len)
{
  shfs_ino_t *cred;
  shbuf_t *buff;
  char key_buf[MAX_SHARE_HASH_LENGTH];
  int err;

  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);

  cred->blk.hdr.format = SHINODE_ACCESS;
  buff = shbuf_map(data, data_len);
  err = shfs_aux_write(cred, buff);
  free(buff);
  if (err)
    return (err);

  file->blk.hdr.attr |= SHATTR_CRED;
  file->blk.hdr.crc = shcrc(data, data_len);
  file->blk.hdr.size = data_len;
  err = shfs_inode_write_entity(file);
  if (err)
    return (err);

  return (0);
}
示例#6
0
int shfs_rev_cat(shfs_ino_t *file, shkey_t *rev_key, shbuf_t *buff, shfs_ino_t **rev_p)
{
  shfs_ino_t *repo;
  shfs_ino_t *rev;
  int err;

  /* obtain repository for inode. */
  repo = shfs_inode(file, NULL, SHINODE_REPOSITORY);
  if (!repo)
    return (SHERR_IO);

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

  err = shfs_rev_read(rev, buff);
  if (err)
    return (err);

  if (rev_p)
    *rev_p = rev;

  return (0);
}
示例#7
0
int shfs_rev_clear(shfs_ino_t *file)
{
  shfs_ino_t *repo;

  /* obtain repository for inode. */
  repo = shfs_inode(file, NULL, SHINODE_REPOSITORY);

  /* clear contents of repository. */
  return (shfs_inode_clear(repo));
}
示例#8
0
shfs_ino_t *shfs_file_find(shfs_t *tree, char *path)
{
  shfs_ino_t *dir;
  shfs_ino_t *file;
  char fpath[PATH_MAX+1];
  char curpath[PATH_MAX+1];
  char *filename;
  char *dirname;
  char *ptr;

  file = NULL;

  if (!path || !*path)
    return (NULL);

  if (strlen(path) >= SHFS_PATH_MAX)
    return (NULL);//SHERR_NAMETOOLONG);

  memset(fpath, 0, sizeof(fpath));
  if (*path == '/') {
    strncpy(fpath, path + 1, PATH_MAX);
  } else {
    strncpy(fpath, path, PATH_MAX);
  }
  
  if (!*fpath || fpath[strlen(fpath)-1] == '/') {
    dir = shfs_dir_find(tree, fpath);
    return (dir);
  }

  dirname = NULL;
  filename = NULL;

  ptr = strrchr(fpath, '/');
  if (!ptr) {
    dirname = "";
    filename = fpath;
  } else {
    *ptr++ = '\000';
    dirname = fpath;
    filename = ptr;
  }

  dir = shfs_dir_find(tree, dirname);
  if (!dir)
    return (NULL);

  file = shfs_inode(dir, filename, SHINODE_FILE);

  return (file);
}
示例#9
0
int shfs_rev_ref_read(shfs_ino_t *file, char *group, char *name, shbuf_t *buff)
{
  shfs_ino_t *ref;
  shfs_ino_t *aux;
  char buf[SHFS_PATH_MAX];
  int err;

  memset(buf, 0, sizeof(buf));
  snprintf(buf, sizeof(buf) - 1, "%s/%s", group, name);
  ref = shfs_inode(file, buf, SHINODE_OBJECT);
  err = shfs_bin_read(ref, buff);
  if (err)
    return (err);

#if 0
  aux = shfs_inode(ref, NULL, SHINODE_BINARY);
  err = shfs_aux_read(aux, buff);
  if (err)
    return (err);
#endif

  return (0);
}
示例#10
0
int shfs_rev_delta_write(shfs_ino_t *rev, shbuf_t *buff)
{
  shfs_ino_t *aux;
  int err;

  aux = shfs_inode(rev, NULL, SHINODE_DELTA);
  if (!aux)
    return (SHERR_IO);

  err = shfs_aux_write(aux, buff);
  if (err)
    return (err);

  return (0);
}
示例#11
0
shkey_t *shfs_index_key(shfs_idx_t *idx, uint64_t crc, shfs_dirent_t *ent_p)
{
  shkey_t *key;
  int h_num = (crc % 256);
  
  if (!idx->hash[h_num]) {
    key = shkey_bin(&crc, sizeof(uint64_t));
    idx->hash_ino[h_num] = shfs_inode(idx->file, shkey_hex(key), SHINODE_INDEX);
    shkey_free(&key);
    return (NULL);
  }
  for (i = 0; i < idx->hash_max[h_num]; i++) {
    if ((idx->key[h_num] + i) == crc) {
      return (idx->hash[h_num] + i); 
    }
  }

  return (NULL);
}
示例#12
0
int shfs_cred_remove(shfs_ino_t *file, shkey_t *key)
{
  shfs_ino_t *cred;
  char key_buf[MAX_SHARE_HASH_LENGTH];
  int err;

  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 (shfs_format(cred) != SHINODE_ACCESS)
    return (0); /* done */

  err = shfs_inode_clear(cred);
  if (err)
    return (err);

  return (0);
}
示例#13
0
int shfs_ext_set(shfs_ino_t *file, const char *path)
{
  struct stat st;
  shfs_ino_t *ext;
  char fs_path[SHFS_PATH_MAX];
  int err;

  if (file == NULL || !path || !*path)
    return (SHERR_INVAL);

  err = stat(path, &st);
  if (err) {
    return (errno2sherr());
}

  ext = shfs_inode(file, NULL, SHINODE_EXTERNAL);
  if (!ext)
    return (SHERR_IO);

  memset(fs_path, 0, sizeof(fs_path));
  strncpy(fs_path, path, sizeof(fs_path) - 1);

  /* save local hard-drive path as inode data. */
  memset(ext->blk.raw, 0, SHFS_PATH_MAX);
  strcpy((char *)ext->blk.raw, fs_path);
  ext->blk.hdr.size = SHFS_PATH_MAX;
  ext->blk.hdr.crc = shcrc(fs_path, SHFS_PATH_MAX);
  err = shfs_inode_write_entity(ext);
  if (err)
    return (err);

  /* copy ext stats to file inode. */
  file->blk.hdr.mtime = ext->blk.hdr.mtime;
  file->blk.hdr.size = ext->blk.hdr.size;
  file->blk.hdr.crc = ext->blk.hdr.crc;
  file->blk.hdr.format = SHINODE_EXTERNAL;
  file->blk.hdr.attr |= SHATTR_LINK_EXT;

  return (0);
}
示例#14
0
int _shfs_ref_raw_read(shfs_ino_t *file, shbuf_t *buff)
{
    shfs_ino_t *inode;
    int err;

    if (!file)
        return (SHERR_INVAL);

    if (shfs_format(file) != SHINODE_REFERENCE)
        return (SHERR_INVAL);

    inode = shfs_inode(file, NULL, SHINODE_REFERENCE);
    if (!inode)
        return (SHERR_IO);

    if (inode->blk.hdr.size < (sizeof(shpeer_t) + sizeof(shkey_t)) ||
            inode->blk.hdr.size > SHFS_BLOCK_DATA_SIZE)
        return (SHERR_IO);

    shbuf_cat(buff, (char *)inode->blk.raw, inode->blk.hdr.size);
    return (0);
}
示例#15
0
int shfs_truncate(shfs_ino_t *file, shsize_t len)
{
  shfs_ino_t *bin;
  shfs_ino_t *aux;
  int err;

  if (!file)
    return (0);

  if (!IS_INODE_CONTAINER(shfs_type(file)))
    return (SHERR_INVAL); /* see shfs_inode_truncate() */

  switch (shfs_format(file)) {
    case SHINODE_NULL:
      return (SHERR_NOENT); /* no data content */

    case SHINODE_BINARY:
      bin = shfs_inode(file, NULL, SHINODE_BINARY);
      err = shfs_inode_truncate(bin, len);
      if (err)
        return (err);

      /* update file inode attributes */
      file->blk.hdr.mtime = bin->blk.hdr.mtime;
      file->blk.hdr.size = bin->blk.hdr.size;
      file->blk.hdr.crc = bin->blk.hdr.crc;
      err = shfs_inode_write_entity(file);
      if (err)
        return (err);

      break;

    default:
      return (SHERR_OPNOTSUPP);
  }

  return (0);
}
示例#16
0
int shfs_rev_checkout(shfs_ino_t *file, shkey_t *key, shfs_ino_t **rev_p)
{
  shfs_ino_t *repo;
  shfs_ino_t *rev;
  int err;

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

  repo = shfs_inode(file, NULL, SHINODE_REPOSITORY);
  rev = shfs_rev_get(repo, key);
  if (!rev)
    return (SHERR_NOENT);

  err = shfs_rev_base_set(file, rev);
  if (err)
    return (err);

  if (rev_p)
    *rev_p = rev;

  return (0);
}
示例#17
0
int shfs_ext_write(shfs_ino_t *file, shbuf_t *buff)
{
  shfs_ino_t *ext;
  char *path;
  int err;

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

  if (shfs_format(file) != SHINODE_EXTERNAL)
    return (SHERR_INVAL);

  ext = shfs_inode(file, NULL, SHINODE_EXTERNAL);
  if (!ext)
    return (SHERR_IO);

  path = (char *)ext->blk.raw;
  err = shfs_mem_write(path, buff);
  if (err)
    return (err);

  return (0);
}
示例#18
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);
}
示例#19
0
int shfs_file_remove(shfs_ino_t *file)
{
  shfs_ino_t *child;
  shbuf_t *buff;
  shfs_dirent_t *ents;
  size_t ent_max;
  int fmt;
  int err;
  int i;

  if (IS_INODE_CONTAINER(shfs_type(file))) {
    ents = NULL;
    ent_max = shfs_list(file, NULL, &ents);
    if (ent_max < 0) {
      return (ent_max);
    }

    if (ents) {
      for (i = 0; i < ent_max; i++) {
        if (IS_INODE_CONTAINER(ents[i].d_type)) {
          child = shfs_inode(file, ents[i].d_name, ents[i].d_type);
          err = shfs_file_remove(child);
          if (err)
            return (err);
        } else {
          child = shfs_inode(file, NULL, ents[i].d_type);
          shfs_inode_clear(child);
        }
      }
      free(ents);
    } else {
      /* version repository */
      if (shfs_attr(file) & SHATTR_VER) {
        child = shfs_inode(file, NULL, SHINODE_REPOSITORY);
        err = shfs_file_remove(child);
        if (err)
          return (err);
      }

      /* specific format */
      fmt = shfs_format(file);
      if (fmt == SHINODE_NULL && shfs_type(file) == SHINODE_BINARY) {
        fmt = SHINODE_AUX;
      }
      if (fmt != SHINODE_NULL) {
        child = shfs_inode(file, NULL, fmt);
        if (!IS_INODE_CONTAINER(shfs_type(child))) {
          err = shfs_inode_clear(child);
        } else {
          err = shfs_file_remove(child);
        }
        if (err)
          return (err);
      }
    }
  }

  if (shfs_type(file) != SHINODE_DIRECTORY) {
#if 0
/* DEBUG: perform inode_clear on 'fpos' index */
  /* clear previous format */
err = shfs_format_set(file, SHINODE_NULL);
        if (err)
          return (err);
#endif
  

    /* reset stats on file inode. */
    file->blk.hdr.mtime = 0;
    file->blk.hdr.size = 0;
    //  file->blk.hdr.type = SHINODE_NULL;
    file->blk.hdr.format = SHINODE_NULL;
    file->blk.hdr.attr = SHINODE_NULL;
    file->blk.hdr.crc = 0;
    err = shfs_inode_write_entity(file);
    if (err) {
      return (err);
    }

  }

  return (0);
}
示例#20
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);
}
示例#21
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);
}