int
csm_add_service(csm_service_list *services, csm_service *s, csm_ctx *ctx)
{
  // validate service fields against schema
  CHECK(csm_validate_fields(ctx, s), "Service doesn't validate");
  
  // attach service to service list
  s->parent = services;
//   co_obj_t *service_obj = co_service_create(s);
//   CHECK_MEM(service_obj);
  co_service_t *service_obj = container_of(s, co_service_t, service);
  CHECK(co_list_append(services->services, (co_obj_t *)service_obj),
	"Failed to add service to service list");
  
  co_obj_t *fields = s->fields;
  // detach s->fields from s before adding s->fields to services->service_fields
  hattach(fields, NULL);
  
  // add service fields to service list
  CHECK(co_list_append(services->service_fields, fields),
        "Failed to add service fields to service list");
  
  CHECK(csm_update_service(services, s, ctx, 0),
        "Failed to finalize service");
  
  return 1;
error:
  csm_remove_service(services, s);
//   csm_service_destroy(s);
  return 0;
}
Exemple #2
0
int
co_request_append_uint(co_obj_t *request, const unsigned int i)
{
  CHECK_MEM(request);
  CHECK(IS_LIST(request), "Not a valid request.");
  CHECK(i < UINT64_MAX, "Integer out of bounds.");
  if(i > UINT32_MAX) return co_list_append(request, co_uint64_create(i, 0));
  if(i > UINT16_MAX) return co_list_append(request, co_uint32_create(i, 0));
  if(i > UINT8_MAX) return co_list_append(request, co_uint16_create(i, 0));
  return co_list_append(request, co_uint8_create(i, 0));
error:
  return 0;
}
Exemple #3
0
int
co_request_append_int(co_obj_t *request, const int i)
{
  CHECK_MEM(request);
  CHECK(IS_LIST(request), "Not a valid request.");
  CHECK(i < INT64_MAX && i > INT64_MIN, "Integer out of bounds.");
  if(i > INT32_MAX || i < INT32_MIN) return co_list_append(request, co_int64_create(i, 0));
  if(i > INT16_MAX || i < INT16_MIN) return co_list_append(request, co_int32_create(i, 0));
  if(i > INT8_MAX || i < INT8_MIN) return co_list_append(request, co_int16_create(i, 0));
  return co_list_append(request, co_int8_create(i, 0));
error:
  return 0;
}
Exemple #4
0
int
co_request_append_bin(co_obj_t *request, const char *s, const size_t slen)
{
  CHECK_MEM(request);
  CHECK_MEM(s);
  CHECK(IS_LIST(request), "Not a valid request.");
  CHECK(slen < UINT32_MAX, "Binary is too large.");
  if(slen > UINT16_MAX) return co_list_append(request, co_bin32_create(s, slen, 0));
  if(slen > UINT8_MAX) return co_list_append(request, co_bin16_create(s, slen, 0));
  return co_list_append(request, co_bin8_create(s, slen, 0));
  error:
  return 0;
}
Exemple #5
0
int
co_request_append(co_obj_t *request, co_obj_t *object)
{
  CHECK_MEM(request);
  CHECK_MEM(object);
  CHECK(IS_LIST(request), "Not a valid request.");
  return co_list_append(request, object);
error:
  return 0;
}
Exemple #6
0
co_obj_t *
co_connect(const char *uri, const size_t ulen)
{
  CHECK_MEM(_sockets);
  CHECK(uri != NULL && ulen > 0, "Invalid URI.");
  co_obj_t *socket = NEW(co_socket, unix_socket);
  hattach(socket, _pool);
  CHECK((((co_socket_t*)socket)->connect(socket, uri)), "Failed to connect to commotiond at %s\n", uri);
  co_list_append(_sockets, socket);
  return socket;
error:
  co_obj_free(socket);
  return NULL;
}
/** 
 * update handlers must be idempotent and side effect free, as
 * handlers are called in the order they were registered with
 * service list
 */
int
csm_services_register_commit_hook(csm_service_list *services, co_cb_t handler)
{
  co_cbptr_t *callback = h_calloc(1, sizeof(co_cbptr_t));
  CHECK_MEM(callback);
  callback->_header._type = _ext8;
  callback->_header._ref = 0;
  callback->_header._flags = 0;
  callback->_exttype = _cbptr;
  callback->_len = sizeof(co_cb_t *);
  callback->cb = handler;
  CHECK(co_list_append(services->update_handlers, (co_obj_t *)callback),
	"Failed to register commit hook");
  return 1;
error:
  return 0;
}
int
csm_update_service(csm_service_list *services, csm_service *s, csm_ctx *ctx, int validate)
{
  if (validate)
    CHECK(csm_validate_fields(ctx, s), "Service doesn't validate");
//   assert(s->lifetime);
  long lifetime = s->lifetime;
  
  // check if service is attached to service_list
  CHECK(co_list_contains(services->services, (co_obj_t*)container_of(s, co_service_t, service)),
	"Cannot update service not in service list");
  
  // detach s->fields from s and attach to services->service_fields
  if (!co_list_contains(services->service_fields, s->fields)) {
    co_obj_t *fields = s->fields;
    hattach(fields, NULL);
    CHECK(co_list_append(services->service_fields, fields),
	  "Failed to add service fields to service list");
  }
  
  /* Create or verify signature */
  if (s->signature)
    CHECK(csm_verify_signature(s),"Invalid signature");
  else
    CHECK(csm_create_signature(s),"Failed to create signature");
  
  /* Set expiration timer on the service */
#ifdef USE_UCI
  long def_lifetime = default_lifetime();
  if (lifetime == 0 || (def_lifetime < lifetime && def_lifetime > 0))
    lifetime = def_lifetime;
#endif
  if (lifetime > 0) {
    struct timeval tv;
    avahi_elapse_time(&tv, 1000*lifetime, 0);
    time_t current_time = time(NULL);
    // create expiration event for service
    s->timeout = avahi_simple_poll_get(simple_poll)->timeout_new(avahi_simple_poll_get(simple_poll),
								       &tv,
								       _csm_expire_service,
								       s);
    /* Convert lifetime period into timestamp */
    if (current_time != ((time_t)-1)) {
      struct tm *timestr = localtime(&current_time);
      timestr->tm_sec += lifetime;
      current_time = mktime(timestr);
      char *c_time_string = ctime(&current_time);
      if (c_time_string) {
	c_time_string[strlen(c_time_string)-1] = '\0'; /* ctime adds \n to end of time string; remove it */
	s->expiration = h_strdup(c_time_string);
	CHECK_MEM(s->expiration);
	service_attach(s->expiration, s);
      }
    }
  }
  
  // finalize service by running update handlers
  csm_services_commit(services);
  
  return 1;
error:
  return 0;
}