Ejemplo n.º 1
0
Archivo: zxcot.c Proyecto: gitpan/zxid
/* Called by:  zxcot_main */
static int zxid_addmd(zxid_conf* cf, char* mdurl, int dry_run, const char* dcot)
{
  int got;
  fdtype fd;
  char* p;
  zxid_entity* ent;
  struct zx_str* ss;
  
  if (mdurl) {
    ent = zxid_get_meta(cf, mdurl);
  } else {
    read_all_fd(fdstdin, buf, sizeof(buf)-1, &got);
    buf[got] = 0;
    p = buf;
    ent = zxid_parse_meta(cf, &p, buf+got);
  }
  
  if (!ent) {
    ERR("***** Parsing metadata failed %d", 0);
    return 1;
  }

  for (; ent; ent = ent->n) {
    ss = zx_easy_enc_elem_opt(cf, &ent->ed->gg);
    if (!ss)
      return 2;
  
    if (dry_run) {
      write_all_fd(fdstdout, ss->s, ss->len);
      zx_str_free(cf->ctx, ss);
      if (verbose>1)
	printf("\n\nDry run ent(%s) to %s%s\n", ent->eid, dcot, ent->sha1_name);
      continue;
    }
    if (verbose)
      printf("Writing ent(%s) to %s%s\n", ent->eid, dcot, ent->sha1_name);
  
    fd = open_fd_from_path(O_CREAT | O_WRONLY | O_TRUNC, 0666, "zxcot -a", 1,
			   "%s%s", dcot, ent->sha1_name);
    if (fd == BADFD) {
      perror("open metadata for writing metadata to cache");
      ERR("Failed to open file for writing: sha1_name(%s) to metadata cache", ent->sha1_name);
      zx_str_free(cf->ctx, ss);
      return 1;
    }
    
    write_all_fd(fd, ss->s, ss->len);
    zx_str_free(cf->ctx, ss);
    close_file(fd, (const char*)__FUNCTION__);
  }
  return 0;
}
Ejemplo n.º 2
0
/* Called by: */
size_t zxid_curl_write_data(void *buffer, size_t size, size_t nmemb, void *userp)
{
  int len = size * nmemb;
#if 1
  struct zxid_curl_ctx* rc = (struct zxid_curl_ctx*)userp;
  int old_len, new_len, in_buf = rc->p - rc->buf;
  if (rc->p + len > rc->lim) {
    old_len = rc->lim-rc->buf;
    new_len = MIN(MAX(old_len + old_len, in_buf + len), ZXID_MAX_CURL_BUF);
    if (new_len == ZXID_MAX_CURL_BUF) {
      ERR("Too large HTTP response. Response length at least %d. Maximum allowed length (ZXID_MAX_CURL_BUF): %d", in_buf + len, ZXID_MAX_CURL_BUF);
      return -1;  /* Signal error */
    }
    D("Reallocating curl buffer from %d to %d in_buf=%d len=%d", old_len, new_len, in_buf, len);
    REALLOCN(rc->buf, new_len+1);
    rc->p = rc->buf + in_buf;
    rc->lim = rc->buf + new_len;
  }
  memcpy(rc->p, buffer, len);
  rc->p += len;
  if (errmac_debug & CURL_INOUT) {
    INFO("RECV(%.*s) %d chars", len, (char*)buffer, len);
    D_XML_BLOB(0, "RECV", len, (char*)buffer);
  }
#else
  int fd = (int)userp;
  write_all_fd(fd, buffer, len);
#endif
  return len;
}
Ejemplo n.º 3
0
void fable_release_read_buf_shmem_pipe(void* handle, struct fable_buf* fbuf) {

  struct shmem_pipe_handle_conn *sp = (struct shmem_pipe_handle_conn*)handle;
  struct shmem_pipe_buf* buf = (struct shmem_pipe_buf*)fbuf;

  assert(buf->base.nbufs == 1 && buf->base.bufs == &buf->iov);

  struct extent *inc = (struct extent*)(sp->incoming + sp->incoming_bytes_consumed);
  assert(((char*)sp->ring) + inc->base == fbuf->bufs[0].iov_base);
  
  struct extent tosend;
  // Was the extent fully consumed by this read?
  if(fbuf->bufs[0].iov_len == inc->size) {

    tosend = *inc;

    // Dismiss this incoming extent
    sp->incoming_bytes_consumed += sizeof(struct extent);

    if(sp->incoming_bytes_consumed - sp->incoming_bytes < sizeof(struct extent)) {
      memmove(sp->incoming, sp->incoming + sp->incoming_bytes_consumed, sp->incoming_bytes - sp->incoming_bytes_consumed);
      sp->incoming_bytes -= sp->incoming_bytes_consumed;
      sp->incoming_bytes_consumed = 0;
    }

  }
  // Otherwise, divide the extent in two; queue one and keep the other.
  else {
    
    tosend.base = inc->base;
    tosend.size = fbuf->bufs[0].iov_len;
    inc->base += fbuf->bufs[0].iov_len;
    inc->size -= fbuf->bufs[0].iov_len;

  }

  // Queue it for transmission back to the writer
  struct extent *out;
  out = &sp->outgoing_extents[sp->nr_outgoing_extents-1];
  /* Try to reuse previous outgoing extent */
  if (sp->nr_outgoing_extents != 0 && out->base + out->size == tosend.base) {
    out->size += tosend.size;
  } else {
    sp->outgoing_extents[sp->nr_outgoing_extents] = tosend; // Struct copy
    sp->nr_outgoing_extents++;
  }
  sp->outgoing_extent_bytes += tosend.size;

  // Send the queued extents, if the queue is big enough

  // TODO: blocking operations regardless of nonblocking status.
  if (sp->outgoing_extent_bytes > ring_size / 8) {
    write_all_fd(sp->base.fd, (char*)sp->outgoing_extents, sp->nr_outgoing_extents * sizeof(struct extent), 1 /* Allow writing to closed socket */);
    sp->nr_outgoing_extents = 0;
    sp->outgoing_extent_bytes = 0;
  }

  free(fbuf);

}
Ejemplo n.º 4
0
int fable_release_write_buf_shmem_pipe(void* handle, struct fable_buf* fbuf)
{
  struct shmem_pipe_handle_conn *sp = (struct shmem_pipe_handle_conn*)handle;
  struct shmem_pipe_buf *buf = (struct shmem_pipe_buf*)fbuf;
  struct extent ext;

  assert(fbuf->nbufs == 1 && fbuf->bufs == &buf->iov);

  unsigned long offset = ((char*)fbuf->bufs[0].iov_base) - ((char*)sp->ring);
  ext.base = offset;
  ext.size = fbuf->bufs[0].iov_len;

  // TODO: Blocking ops in nonblocking context
  write_all_fd(sp->base.fd, (char*)&ext, sizeof(ext), 1 /* Allow writing to closed socket */);

  assert(sp->nr_alloc_nodes <= 3);

  return 1;
}
Ejemplo n.º 5
0
Archivo: zxcot.c Proyecto: gitpan/zxid
/* Called by:  zxcot_main */
static int zxid_reg_svc(zxid_conf* cf, int bs_reg, int dry_run, const char* ddimd, const char* duid)
{
  char sha1_name[28];
  char path[ZXID_MAX_BUF];
  int got;
  fdtype fd;
  struct zx_root_s* r;
  zxid_epr* epr;
  struct zx_str* ss;
  struct zx_str* tt;
  
  read_all_fd(fdstdin, buf, sizeof(buf)-1, &got);  /* Read EPR */
  buf[got] = 0;
  
  r = zx_dec_zx_root(cf->ctx, got, buf, "cot reg_svc");
  if (!r || !r->EndpointReference) {
    ERR("Failed to parse <EndpointReference> buf(%.*s)", got, buf);
    return 1;
  }
  epr = r->EndpointReference;
  if (!ZX_SIMPLE_ELEM_CHK(epr->Address)) {
    ERR("<EndpointReference> MUST have <Address> element buf(%.*s)", got, buf);
    return 1;
  }
  if (!epr->Metadata) {
    ERR("<EndpointReference> MUST have <Metadata> element buf(%.*s)", got, buf);
    return 1;
  }
  if (!ZX_SIMPLE_ELEM_CHK(epr->Metadata->ProviderID)) {
    ERR("<EndpointReference> MUST have <Metadata> with <ProviderID> element buf(%.*s)", got, buf);
    return 1;
  }
  if (!epr->Metadata->ServiceType) {
    ERR("<EndpointReference> MUST have <ServiceType> element buf(%.*s)", got, buf);
    return 1;
  }

  /* *** possibly add something here and double check the required fields are available. */

  ss = zx_easy_enc_elem_opt(cf, &epr->gg);
  if (!ss)
    return 2;
  
#if 0
  // *** wrong
  tt = ZX_GET_CONTENT(epr->Metadata->ProviderID);
#else
  tt = ZX_GET_CONTENT(epr->Metadata->ServiceType);
#endif
  got = MIN(tt->len, sizeof(path)-1);
  memcpy(path, tt?tt->s:"", got);
  path[got] = 0;
  zxid_fold_svc(path, got);

  sha1_safe_base64(sha1_name, ss->len, ss->s);
  sha1_name[27] = 0;

  if (verbose)
    fprintf(stderr, "Registering metadata in %s%s,%s\n", ddimd, path, sha1_name);
  
  if (dry_run) {
    if (verbose)
      fprintf(stderr, "Register EPR dry run. Would have written to path(%s%s,%s). "
	      "You may also want to\n"
	      "  touch %s.all/.bs/%s,%s\n\n", ddimd, path, sha1_name, uiddir, path, sha1_name);
    fflush(stdin);
    write_all_fd(fdstdout, ss->s, ss->len);
    zx_str_free(cf->ctx, ss);
    return 0;
  }
  
  D("Register EPR path(%s%s,%s) in discovery metadata.", ddimd, path, sha1_name);
  fd = open_fd_from_path(O_CREAT | O_WRONLY | O_TRUNC, 0666, "zxcot -b", 1,
			 "%s%s,%s", ddimd, path, sha1_name);
  if (fd == BADFD) {
    perror("open epr for registering");
    ERR("Failed to open file for writing: sha1_name(%s,%s) to service registration", path, sha1_name);
    zx_str_free(cf->ctx, ss);
    return 1;
  }
  
  write_all_fd(fd, ss->s, ss->len);
  zx_str_free(cf->ctx, ss);
  close_file(fd, (const char*)__FUNCTION__);

  if (bs_reg) {
    if (verbose)
      fprintf(stderr, "Activating bootstrap %s.all/.bs/%s,%s", duid, path, sha1_name);

    if (!dryrun) {
      fd = open_fd_from_path(O_CREAT | O_WRONLY | O_TRUNC, 0666, "zxcot -bs", 1,
			     "%s.all/.bs/%s,%s", duid, path, sha1_name);
      if (fd == BADFD) {
	perror("open epr for bootstrap activation");
	ERR("Failed to open file for writing: sha1_name(%s,%s) to bootstrap activation", path, sha1_name);
	return 1;
      }
    
      write_all_fd(fd, "", 0);
      close_file(fd, (const char*)__FUNCTION__);
    }
  } else {
    D("You may also want to activate bootstrap by\n  touch %s.all/.bs/%s,%s", duid, path, sha1_name);
  }
  return 0;
}
Ejemplo n.º 6
0
void* fable_connect_shmem_pipe(const char* name, int direction) {

  // As the connection initiator, it's our responsibility to supply shared memory.

  char random_name[22];
  int ring_pages = pow(2, ring_order);
  
  int shm_fd = -1;
  errno = EEXIST;
  for(int i = 0; i < 100 && shm_fd == -1 && errno == EEXIST; ++i) {
    strcpy(random_name, "/fable_segment_XXXXXX");
    if(!mktemp(random_name))
      break;
    shm_fd = shm_open(random_name, O_RDWR|O_CREAT|O_EXCL, 0600);
  }

  if(shm_fd == -1)
    return 0;

  shm_unlink(random_name);
  if (ftruncate(shm_fd, PAGE_SIZE * ring_pages) < 0) {
    close(shm_fd);
    return 0;
  }

  void* ring_addr = mmap(NULL, PAGE_SIZE * ring_pages, PROT_READ|PROT_WRITE, MAP_SHARED, shm_fd, 0);
 
  void* unix_handle = fable_connect_unixdomain(name, FABLE_DIRECTION_DUPLEX);
  if(!unix_handle)
    return 0;

  int unix_fd = *((int*)unix_handle);
  free(unix_handle);

  // OK, send our partner the FD and the appropriate size to mmap.
  int send_ret = unix_send_fd(unix_fd, shm_fd);
  close(shm_fd);
  
  if(send_ret <= 0) {
    munmap(ring_addr, PAGE_SIZE * ring_pages);
    close(unix_fd);
    return 0;
  }

  write_all_fd(unix_fd, (const char*)&ring_pages, sizeof(int));

  struct shmem_pipe_handle_conn* conn_handle = (struct shmem_pipe_handle_conn*)malloc(sizeof(struct shmem_pipe_handle_conn));
  memset(conn_handle, 0, sizeof(struct shmem_pipe_handle_conn));

  conn_handle->base.fd = unix_fd;
  conn_handle->base.type = SHMEMPIPE_HANDLE_CONN;
  conn_handle->ring = ring_addr;
  conn_handle->ring_pages = ring_pages;
  conn_handle->direction = direction;

  if(direction == FABLE_DIRECTION_SEND)
    shmem_pipe_init_send(conn_handle);
  // Otherwise memset-0 is enough

  return conn_handle;

}