예제 #1
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);
}
예제 #2
0
파일: shfs_ref.c 프로젝트: neonatura/share
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);
}
예제 #3
0
파일: shfs_ref.c 프로젝트: neonatura/share
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);
}
예제 #4
0
파일: shfs_rev.c 프로젝트: neonatura/share
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);
}
예제 #5
0
void shmap_load(shmap_t *ht, shbuf_t *buff)
{
  shmap_value_t *hdr;
  unsigned char *map_data;
  unsigned char *data;
  shsize_t b_len;
  shsize_t b_of;


  b_of = 0;
  b_len = shbuf_size(buff);
  map_data = shbuf_data(buff);

  while (b_of < b_len) {
    hdr = (shmap_value_t *)(map_data + b_of);
    b_of += sizeof(shmap_value_t);
    if (b_of > b_len) break;

    if (hdr->magic != SHMEM32_MAGIC) {
      sherr(SHERR_IO, "shmap_load: error reading map record.");
      continue;
    }

    data = NULL;
    if (hdr->sz) {
      data = (map_data + b_of);
      b_of += hdr->sz;
    }
    if (!data) {
      continue;
}
    shmap_set_ent(ht, &hdr->name, hdr->pf | SHMAP_ALLOC, data, hdr->sz);  
  }

}
예제 #6
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);
}
예제 #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
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);
}
예제 #9
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);
}
예제 #10
0
static int _test_shproc_req(int fd, shbuf_t *buff)
{
  int val;

  if (!fd) {
    if (shbuf_size(buff) != sizeof(val)) {
      return (-1);
    }
    val = *((int *)shbuf_data(buff));
  } else {
    if (shbuf_size(buff) != 0) {
      return (-1);
    }
    lseek(fd, 0L, SEEK_SET);
    read(fd, &val, sizeof(int));
    close(fd);
  }

  _test_shproc_value[val] = -1;

  shbuf_clear(buff);
  shbuf_cat(buff, &val, sizeof(int));

  return (0);
}
예제 #11
0
파일: shfs_rev.c 프로젝트: neonatura/share
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);
}
예제 #12
0
static int _test_shproc_resp(int err_code, shbuf_t *buff)
{
  if (err_code == 0) {
    int val = *((int *)shbuf_data(buff));
    _test_shproc_value[val] = val+1;
  }
  return (0);
}
예제 #13
0
int sexe_exec_popen(shbuf_t *buff, shjson_t *arg, sexe_t **mod_p)
{
  lua_State *L = luaL_newstate();
  sexe_mod_t *mod;
  int narg = 1;
  int status;
  int err;

  if (!mod_p)
    return (SHERR_INVAL);

  *mod_p = NULL;

  if (shbuf_size(buff) < sizeof(sexe_mod_t))
    return (SHERR_INVAL);

  mod = (sexe_mod_t *)shbuf_data(buff);
  if (0 != memcmp(mod->sig, SEXE_SIGNATURE, sizeof(mod->sig)))
    return (SHERR_ILSEQ);

  /* open standard libraries */
  luaL_checkversion(L);
  lua_gc(L, LUA_GCSTOP, 0);  /* stop collector during initialization */
  luaL_openlibs(L);  /* open libraries */
  lua_gc(L, LUA_GCRESTART, 0);

  //if (!args[has_E] && handle_luainit(L) != LUA_OK)
  err = _api_handle_luainit(L);
  if (err) {
    lua_close(L);
    return (err);
  }

  install_sexe_userdata(L, mod->name); /* sexe api lib */
  install_sexe_functions(L); /* sexe api lib */

  if (!arg)
    arg = shjson_init(NULL);

  lua_pushstring(L, "arg");
  sexe_exec_pset(L, "arg", arg);

  status = sexe_loadmem(L, mod->name, buff);
  lua_insert(L, -(narg+1));

  if (status != LUA_OK) {
    lua_pop(L, narg);
    status = _api_report(L, status);
    lua_close(L);

    return (status);
  }

  *mod_p = L;

  return (LUA_OK);
}
예제 #14
0
파일: shsys_log.c 프로젝트: neonatura/share
void shlog_write(shbuf_t *buff, int level, int err_code, char *log_str)
{
  static char log_path[PATH_MAX+1];
  char line[640];
  char *beg_line;
  size_t mem_size;

  if (!buff)
    return;

  if (!*log_path) {
		char *label;
    shpeer_t peer;

    memcpy(&peer, ashpeer(), sizeof(peer));
		label = (!*peer.label ? PACKAGE_NAME : peer.label);
		sprintf(log_path, "%s%s.log", shlog_path(label), label); 
  }
  if (*log_path && !_shlog_file) {
    _shlog_file = fopen(log_path, "ab");
  }

  beg_line = shbuf_data(buff) + shbuf_size(buff);

  sprintf(line, "%s", shstrtime(shtime(), "[%x %T] "));
  shbuf_catstr(buff, line);

  if (level == SHLOG_ERROR) {
    shbuf_catstr(buff, "error");
  } else if (level == SHLOG_WARNING) {
    shbuf_catstr(buff, "warning");
  } else {
    shbuf_catstr(buff, "info");
  }

  if (err_code) {
    memset(line, 0, sizeof(line));
    snprintf(line, sizeof(line) - 1,
        ": %s [code %d]", strerror(-(err_code)), (err_code));
    shbuf_catstr(buff, line);
  }

  if (log_str) {
    shbuf_catstr(buff, ": ");
    shbuf_catstr(buff, log_str);
  }

  mem_size = shlog_mem_size();
  if (mem_size > 100000) {
    sprintf(line, " (mem:%dm)", (mem_size / 1000)); 
    shbuf_catstr(buff, line);
  }

  shbuf_catstr(buff, "\n");

}
예제 #15
0
파일: shsys_log.c 프로젝트: neonatura/share
int shlog(int level, int err_code, char *log_str)
{
  static time_t last_day;
  static time_t last_flush;
  static shbuf_t *buff;
  time_t day;
  time_t now;
  int err;

	if (level < _log_level)
		return (0);

  now = time(NULL);
  day = now / 86400; 
  if (day != last_day) {
    // shlog_zcompr();  /* compress .YY.WW bin log file, removing prev zip */
    shlog_free();
  }
  last_day = day;

  if (!buff)
    buff = shbuf_init();

	{
		shbuf_lock(buff);

		shbuf_clear(buff);
		shlog_write(buff, level, err_code, log_str);
		if (shbuf_data(buff) && _shlog_file) {
			fprintf(_shlog_file, "%s", shbuf_data(buff));
			if (last_flush < (now - MAX_FLUSH_SPAN)) {
				fflush(_shlog_file);
				last_flush = now;
			}
		}

		shbuf_unlock(buff);
	}

  return (0);
}
예제 #16
0
파일: file_cat.c 프로젝트: neonatura/share
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);
}
예제 #17
0
static int shproc_write(shproc_t *proc, shproc_req_t *req)
{
  int w_len;
  int err;
  int of;

  req->data_len = shbuf_size(proc->proc_buff);
  req->crc = shcrc(shbuf_data(proc->proc_buff), shbuf_size(proc->proc_buff));
  err = write(proc->proc_fd, req, sizeof(shproc_req_t));
  if (err == -1) 
    return (errno2sherr());
  if (err == 0)
    return (SHERR_AGAIN);

  of = 0;
  while (of < shbuf_size(proc->proc_buff)) {
    /*
     * On i386 the buffer is 4096 and 65k otherwise. 
     * Parent is granted 100ms to 'poll' when size exceeds buffer limit.
     */
    err = shproc_write_wait(proc, 100);
    if (err)
      return (err);

    w_len = write(proc->proc_fd, 
        shbuf_data(proc->proc_buff) + of, 
        shbuf_size(proc->proc_buff) - of);
    if (w_len == -1)
      return (errno2sherr());
    if (w_len == 0)
      return (SHERR_AGAIN);

    of += w_len;
  }

  return (0);
}
예제 #18
0
파일: shfs_mem.c 프로젝트: neonatura/share
int shfs_mem_write(char *path, shbuf_t *buff)
{
  FILE *fl;
  char hier[NAME_MAX + 1];
  char dir[NAME_MAX + 1];
  char *n_tok;
  char *tok;
  ssize_t b_of;
  ssize_t b_len;
  ssize_t len;
  int err;

  if (*path != '/') {
    /* recursive dir generation for relative paths. */
    memset(hier, 0, sizeof(hier));
    strncpy(hier, path, sizeof(hier) - 1); 
    tok = strtok(hier, "/");
    while (tok) {
      n_tok = strtok(NULL, "/");
      if (!n_tok)
        break;

      strcat(dir, tok);
      strcat(dir, "/");
      mkdir(dir, 0777);
      tok = n_tok;
    }
  }

  fl = fopen(path, "wb");
  if (!fl)
    return (-1);

  b_of = 0;
  while (b_of < shbuf_size(buff)) {
    len = MIN(65536, (shbuf_size(buff) - b_of));
    b_len = fwrite(shbuf_data(buff) + b_of, sizeof(char), len, fl);
    if (b_len < 0)
      return (errno2sherr());

    b_of += b_len;
  }

  err = fclose(fl);
  if (err)
    return (err);

  return (0);
}
예제 #19
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);
}
예제 #20
0
static int _xd3_read_primary_input(_xd3_file *file, uint8_t  *buf, size_t  size, size_t  *nread)
{
  size_t max_len;

  if (!file->buff)
    return (SHERR_IO);

  max_len = MIN(size, shbuf_size(file->buff));
  if (max_len) {
    memcpy(buf, shbuf_data(file->buff), max_len);
    shbuf_trim(file->buff, max_len);
  }

  if (nread)
    *nread = max_len;
  file->nread += max_len;

  return (0);
}
예제 #21
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);
}
예제 #22
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);
}
예제 #23
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);
}
예제 #24
0
파일: shfs_attr.c 프로젝트: neonatura/share
/**
 * 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);
}
예제 #25
0
int sharelog_list(shpeer_t *peer, time_t stime, time_t etime)
{
  shbuf_t *buff;
  fd_set read_fd;
  shjson_t *json;
  char tbuf[256];
  char *data;
  time_t now;
  char *str;
  int err;
  int fd;

  fd = shconnect_host("127.0.0.1", PROCESS_PORT, SHNET_ASYNC);
  if (fd < 0)
    return (fd);

  json = shjson_init(NULL);
  shjson_num_add(json, "id", 1);
  shjson_str_add(json, "method", "log.list");
  shjson_str_add(json, "key", (char *)shkey_print(shpeer_kpub(peer)));
  shjson_null_add(json, "params");

  str = shjson_print(json);
  shjson_free(&json);

  err = shnet_write(fd, str, strlen(str));
  free(str);
  if (err < 0) {
    shclose(fd);
    return (err);
  }

  err = shnet_write(fd, "\n", 1);
  if (err < 0) {
    shclose(fd);
    return (err);
  }

  while (1) {
    FD_ZERO(&read_fd);
    FD_SET(fd, &read_fd);
    err = shnet_verify(&read_fd, NULL, NULL);
    if (err < 0) {
      continue;
    }

    buff = shnet_read_buf(fd);
    if (!buff)
      break;

    data = shbuf_data(buff);
    if (!strchr(data, '\n'))
      continue;

    json = shjson_init(data);
    if (json) {
      char *text = shjson_astr(json, "result", NULL);
      if (text) {
        printf("%s", text);
      }
      shjson_free(&json);
    }

    break;
  }

  shclose(fd);

  return (0);
}
예제 #26
0
ssize_t shnet_read(int fd, const void *buf, size_t count)
{
  unsigned int usk = (unsigned int)fd;
  struct timeval to;
  size_t max_r_len;
  ssize_t r_len;
  size_t len;
  fd_set read_set;
  fd_set exc_set;
  char tbuf[8];
  int err;

  if (_sk_table[usk].fd == 0)
    return (SHERR_BADF);

  if (count == 0) {
    buf = NULL;
    count = 65536;
  }
  count = MIN(MAX_READ_BUFFER_SIZE, count);

  if (!_sk_table[usk].recv_buff)
    _sk_table[usk].recv_buff = shbuf_init();

  if (!(_sk_table[usk].flags & SHNET_ASYNC)) {
    FD_ZERO(&read_set);
    FD_SET(fd, &read_set);
    FD_ZERO(&exc_set);
    FD_SET(fd, &exc_set);

    /* block for data */
    err = select(fd+1, &read_set, NULL, &exc_set, NULL);
    if (err == -1) 
      return (errno2sherr());
  } 

  /* data available for read. */
  memset(_read_buff, 0, sizeof(_read_buff));
  r_len = read(fd, _read_buff, count);
  if (r_len == 0) {
#if 0
    if (shbuf_size(_sk_table[usk].recv_buff) == 0)
#endif
      return (SHERR_CONNRESET);
  } else if (r_len < 1) {
    return (errno2sherr());
  } else {
    /* append to internal buffer */
    shbuf_cat(_sk_table[usk].recv_buff, _read_buff, r_len);
  }

  if (buf) {
    /* extract head */
    r_len = MIN(count, shbuf_size(_sk_table[usk].recv_buff));
    if (r_len != 0) {
      memcpy((char *)buf, (char *)shbuf_data(_sk_table[usk].recv_buff), r_len);
      shbuf_trim(_sk_table[usk].recv_buff, r_len);
    }
  }

  return (r_len);
}
예제 #27
0
파일: shfs_rev.c 프로젝트: neonatura/share
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);
}
예제 #28
0
int sharelog_tail(shpeer_t *peer)
{
  shbuf_t *buff;
  fd_set read_fd;
  shjson_t *json;
  char tbuf[256];
  time_t stime, etime;
  time_t now;
  char *str;
  int err;
  int fd;

  fd = shconnect_host("127.0.0.1", PROCESS_PORT, SHNET_ASYNC);
  if (fd < 0)
    return (fd);

  json = shjson_init(NULL);
  shjson_num_add(json, "id", 1);
  shjson_str_add(json, "method", "log.subscribe");
  shjson_str_add(json, "key", (char *)shkey_print(shpeer_kpub(peer)));
  shjson_null_add(json, "params");

  str = shjson_print(json);
  shjson_free(&json);

  err = shnet_write(fd, str, strlen(str));
  free(str);
  if (err < 0) {
    shclose(fd);
    return (err);
  }

  err = shnet_write(fd, "\n", 1);
  if (err < 0) {
    shclose(fd);
    return (err);
  }

  while (proc_mode == RUN_TAIL) {
    FD_ZERO(&read_fd);
    FD_SET(fd, &read_fd);
    err = shnet_verify(&read_fd, NULL, NULL);
    if (err < 0) {
      continue;
    }

    buff = shnet_read_buf(fd);
    if (!buff || shbuf_size(buff) == 0)
      continue;

    json = shjson_init(shbuf_data(buff));
    if (json) {
      char *text = shjson_astr(json, "result", NULL);
      if (text) {
        now = time(NULL);
        strftime(tbuf, sizeof(tbuf) - 1, "%D %T", localtime(&now));
        printf("[%s] %s", tbuf, text);
      }
    }

    shbuf_clear(buff);
  }

  shclose(fd);

  return (0);
}