static
Clause conflicts(Clause a, Clause b)
{
  if (!unit_clause(a) || !unit_clause(b))
    return NULL;
  else if (a->literals->sign == b->literals->sign)
    return NULL;
  else {
    Clause empty = NULL;
    Term a_atom = a->literals->atom;
    Term b_atom = b->literals->atom;
    Context ca = get_context();
    Context cb = get_context();
    Trail tr = NULL;
    if (unify(a_atom, ca, b_atom, cb, &tr)) {
      Ilist j = NULL;
      undo_subst(tr);
      empty = get_clause();

      j = ilist_append(j, a->id);
      j = ilist_append(j, 1);
      j = ilist_append(j, b->id);
      j = ilist_append(j, 1);
      empty->justification = resolve_just(j, BINARY_RES_JUST);
      upward_clause_links(empty);
      assign_clause_id(empty);
    }
    free_context(ca);
    free_context(cb);
    return empty;
  }
}  /* conflicts */
Beispiel #2
0
int main(int argc, char *argv[])
{
	int restart = 0;
	int os_handler_installed = 0;
	int rc = 0;
	ddns_t *ctx = NULL;

	do {
		rc = init_context(&ctx);
		if (rc != 0)
			break;

		if (!os_handler_installed) {
			rc = os_install_signal_handler(ctx);
			if (rc != 0) {
				logit(LOG_WARNING,
				      "Failed installing OS signal handler: %s", errorcode_get_name(rc));
				break;
			}
			os_handler_installed = 1;
		}

		rc = dyn_dns_main(ctx, argc, argv);
		if (rc == RC_RESTART) {
			restart = 1;

			/* do some cleanup if restart requested */
			rc = free_context(ctx);
			if (rc != 0)
				logit(LOG_WARNING,
				      "Failed cleaning up before restart: %s, ignoring...",
				      errorcode_get_name(rc));
		} else {
			/* Error, or OK.  In either case exit outer loop. */
			restart = 0;
		}
	}
	while (restart);

	if (rc != 0)
		logit(LOG_WARNING, "Failed %sstarting daemon: %s", restart ? "re" : "", errorcode_get_name(rc));

	/* Cleanup */
	free_context(ctx);
	os_close_dbg_output();

	return (int)rc;
}
static void on_sequence_complete(GIO_ASYNCSEQ_HANDLE async_seq_handle, gpointer previous_result)
{
    READ_CONTEXT* context = (READ_CONTEXT*)GIO_Async_Seq_GetContext(async_seq_handle);
    GBytes* data = (GBytes*)previous_result;
    const unsigned char* buffer;
    size_t size;

    if (data != NULL)
    {
        buffer = g_bytes_get_data(data, &size);
    }
    else
    {
        buffer = NULL;
        size = 0;
    }

    /*Codes_SRS_BLEIO_GATT_13_032: [ BLEIO_gatt_read_char_by_uuid shall invoke on_bleio_gatt_attrib_read_complete when the read operation completes. ]*/
    /*Codes_SRS_BLEIO_GATT_13_033: [ BLEIO_gatt_read_char_by_uuid shall pass the value of the callback_context parameter to on_bleio_gatt_attrib_read_complete as the context parameter when it is invoked. ]*/
    /*Codes_SRS_BLEIO_GATT_13_034: [BLEIO_gatt_read_char_by_uuid, when successful, shall supply the data that has been read to the on_bleio_gatt_attrib_read_complete callback along with the value BLEIO_GATT_OK for the result parameter.]*/
    context->on_read_complete(
        (BLEIO_GATT_HANDLE)context->handle_data,
        context->callback_context,
        BLEIO_GATT_OK,
        buffer,
        size
    );

    g_bytes_unref(data);
    free_context(context);
}
Beispiel #4
0
OPENVPN_EXPORT void
openvpn_plugin_close_v1(openvpn_plugin_handle_t handle)
{
    struct down_root_context *context = (struct down_root_context *) handle;

    if (DEBUG(context->verb))
    {
        fprintf(stderr, "DOWN-ROOT: close\n");
    }

    if (context->foreground_fd >= 0)
    {
        /* tell background process to exit */
        if (send_control(context->foreground_fd, COMMAND_EXIT) == -1)
        {
            warn("DOWN-ROOT: Error signalling background process to exit");
        }

        /* wait for background process to exit */
        if (context->background_pid > 0)
        {
            waitpid(context->background_pid, NULL, 0);
        }

        close(context->foreground_fd);
        context->foreground_fd = -1;
    }

    free_context(context);
}
Beispiel #5
0
static ErlDrvData
exmpp_xml_start(ErlDrvPort port, char *command)
{
	struct exmpp_xml_data *edd;

	/* Set binary mode. */
	set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);

	/* Allocate driver data structure. */
	edd = driver_alloc(sizeof(*edd));
	if (edd == NULL)
		return (ERL_DRV_ERROR_GENERAL);

	/* Initialize generic context. */
	if (init_context(&edd->ctx) != 0) {
		driver_free(edd);
		return (ERL_DRV_ERROR_GENERAL);
	}
	edd->ctx.make_attributes = exmpp_xml_cb_make_attributes;

	/* Initialize driver instance's context. */
	edd->parser = NULL;

	/* Initialize the declared_nss list. */
	edd->declared_nss = driver_alloc(sizeof(*(edd->declared_nss)));
	if (edd->declared_nss == NULL) {
		free_context(&edd->ctx);
		driver_free(edd);
		return (ERL_DRV_ERROR_GENERAL);
	}
	ei_x_new(edd->declared_nss);

	return ((ErlDrvData)edd);
}
Beispiel #6
0
void touch(const char* path, const char* host, const char* username, const char* pass)
{
  xafp_client_handle ctx = get_context(host, username, pass);
  
  xafp_create_file(ctx, path);
  free_context(ctx);  
}
Beispiel #7
0
static void process_write_frontend(struct conn_context *ctx)
{
	int front_fd;
	char *buf;
	int data_len;
	int cpu_id;
	int ret;

	cpu_id = ctx->cpu_id;
	front_fd = ctx->fd;
	buf = ctx->buf;
	data_len = ctx->data_len;

	if (ctx->flags & PROXY_BACKEND_EVENT) {
		printf("Write to front end socket while back end socket enabled\n");
		goto free_back;
	}

	ret = write(front_fd, buf, data_len);
	if (ret < 0) {
		perror("Can't write front-end socket");
		goto free_back;
	}

	print_d("Write %d to front end socket %d\n", data_len, front_fd);

	wdata[cpu_id].trancnt++;

free_back:

	process_close(ctx);
	free_context(ctx);

	return;
}
Beispiel #8
0
Datei: eval.c Projekt: S010/misc
struct expr    *
lambda(struct expr * e, struct context * context)
{
	int             i;
	const struct list *lp, *la;
	struct expr    *pe, *pr;
	struct context *ctx;

	/* assume e is a valid func call expr */

	ctx = new_context();
	ctx->is_root_level = 0;
	ctx->next = (struct context *) context;
	dbgprintf("created new context\n");
	for (i = 0, lp = e->v.list->v->v.list->next->v->v.list, la = e->v.list->next; lp && la; ++i, lp = lp->next, la = la->next) {
		dbgprintf("evaluating arguments, iter %d\n", i);
		pe = add_to_context(ctx, strdup(lp->v->v.atom->v), eval(la->v, context));
		full_free_expr(pe);
	}
	dbgprintf("eval'ing e expr\n");
	pr = eval(e->v.list->v->v.list->next->next->v, ctx);
	free_expr(e);
	free_context(ctx);
	return pr;
}
Beispiel #9
0
struct mg_context *mg_start(mg_callback_t user_callback, void *user_data, int port) {
  struct mg_context *ctx;

  // Allocate context and initialize reasonable general case defaults.
  // TODO(lsm): do proper error handling here.
  ctx = (struct mg_context *) calloc(1, sizeof(*ctx));
  ctx->user_callback = user_callback;
  ctx->user_data = user_data;

  if (!set_ports_option(ctx, port)) {
    free_context(ctx);
    return NULL;
  }
  // Ignore SIGPIPE signal, so if browser cancels the request, it
  // won't kill the whole process.
  (void) signal(SIGPIPE, SIG_IGN);
  (void) pthread_mutex_init(&ctx->mutex, NULL);
  (void) pthread_cond_init(&ctx->cond, NULL);
  (void) pthread_cond_init(&ctx->sq_empty, NULL);
  (void) pthread_cond_init(&ctx->sq_full, NULL);

  // Start master (listening) thread
  start_thread(ctx, (mg_thread_func_t) master_thread, ctx);

  // Start worker threads
  for (int i = 0; i < NUM_THREADS; i++) {
    if (start_thread(ctx, (mg_thread_func_t) worker_thread, ctx) != 0) {
      cry(fc(ctx), "Cannot start worker thread: %d", ERRNO);
    } else {
      ctx->num_threads++;
    }
  }

  return ctx;
}
Beispiel #10
0
    static int finish (bool abort)
    {
        context & ctx = get_context();
        double elapsed = ctx.elapsed_time();

        std::cout.precision(6);
        std::cout << "-----------------------------------" << std::endl
                    << "Results: total=" << ctx.total()
                    << ", run="          << ctx.processed()
                    << ", ok="           << ctx.passed()
                    << ", failed="       << ctx.failed() << std::endl;

        if (ctx.total() != ctx.processed())
            std::cerr << "WARN: Incomplete tests" << std::endl;

        std::cout << "Elapsed time: " << elapsed << " seconds" << std::endl;
        std::cout << "Total result: "
                    << (ctx.failed() > 0
                        ? "FAILURE"
                        : (ctx.processed() == ctx.total()
                                ? "SUCCESS"
                                : "INCOMPLETE"))
                    << std::endl;

        int r = ctx.result();
        free_context();

        if (abort)
            ::exit(r);

        return r;

    }
static void on_sequence_complete(GIO_ASYNCSEQ_HANDLE async_seq_handle, gpointer previous_result)
{
    CONNECT_CONTEXT* context = (CONNECT_CONTEXT*)GIO_Async_Seq_GetContext(async_seq_handle);
    context->handle_data->state = BLEIO_GATT_STATE_CONNECTED;

    // fetch list of objects on the object manager
    GList* objects_list = g_dbus_object_manager_get_objects(
        (GDBusObjectManager*)context->handle_data->object_manager
    );
    if (objects_list == NULL)
    {
        on_sequence_error(async_seq_handle, NULL);
    }
    else
    {
        // iterate through each object and add each characteristic
        // that is a child of the device object path to the map
        g_list_foreach(objects_list, process_object, context);
        g_list_free(objects_list);

        /*Codes_SRS_BLEIO_GATT_13_011: [ When the connect operation to the device has been completed, the callback function pointed at by on_bleio_gatt_connect_complete shall be invoked. ]*/
        /*Codes_SRS_BLEIO_GATT_13_012: [ When on_bleio_gatt_connect_complete is invoked the value passed in callback_context to BLEIO_gatt_connect shall be passed along to on_bleio_gatt_connect_complete. ]*/
        /*Codes_SRS_BLEIO_GATT_13_013: [ The connect_result parameter of the on_bleio_gatt_connect_complete callback shall indicate the status of the connect operation. ]*/
        // invoke the user's callback
        context->on_connect_complete(
            (BLEIO_GATT_HANDLE)context->handle_data,
            context->callback_context,
            BLEIO_GATT_CONNECT_OK
        );

        free_context(context);
    }
}
Beispiel #12
0
static void process_write_backend(struct conn_context *ctx)
{
	int ep_fd, end_fd;
	int events = ctx->events;
	char *buf;
	int data_len;
	int ret;

	ep_fd = ctx->ep_fd;
	end_fd = ctx->end_fd;
	buf = ctx->buf;
	data_len = ctx->data_len;

	print_d("Process write event[%02x] on back-end socket %d\n", events, end_fd);

	if (events & (EPOLLHUP | EPOLLERR)) {
		printf("process_write_backend() with events HUP or ERR 0x%x\n", events);
		goto free_back;
	}

	struct epoll_event evt;

	if (!(ctx->flags & PROXY_BACKEND_EVENT))
	{
		printf("Write to back-end socket while back end socket not enabled\n");
		goto free_back;
	}

	ret = write(end_fd, buf, data_len);
	if (ret < 0) {
		perror("process_write() can't write back end socket");
		goto free_back;
	}

	print_d("Write %d to back-end socket %d\n", ret, end_fd);

	ctx->handler = process_read_backend;
	ctx->flags |= PROXY_BACKEND_EVENT;

	evt.events = EPOLLIN | EPOLLHUP | EPOLLERR;
	evt.data.ptr = ctx;

	ret = epoll_ctl(ep_fd, EPOLL_CTL_MOD, end_fd, &evt);
	if (ret < 0) {
		perror("Unable to add client socket read event to epoll");
		goto free_back;
	}

	goto back;

free_back:

	process_close(ctx);
	free_context(ctx);

back:

	return;
}
static
Clause cd(Clause maj, Clause min)
{
  if (!unit_clause(maj) || !unit_clause(min))
    return NULL;
  else if (!maj->literals->sign || !min->literals->sign)
    return NULL;
  else {
    Term a = ARG(maj->literals->atom,0);
    Term b = ARG(min->literals->atom,0);
    if (ARITY(a) != 2)
      return NULL;
    else {
      Clause resolvent = NULL;
      Term a0 = ARG(a,0);
      Term a1 = ARG(a,1);
      Context ca = get_context();
      Context cb = get_context();
      Trail tr = NULL;
      if (unify(a0, ca, b, cb, &tr)) {
	Term r = apply(a1, ca);
	Term r_atom = build_unary_term(SYMNUM(maj->literals->atom), r);
	Literal r_literal = get_literal();
	Ilist j = NULL;
	r_literal->sign = TRUE;
	r_literal->atom = r_atom;
	resolvent = get_clause();
	append_literal(resolvent, r_literal);
	
	j = ilist_append(j, maj->id);
	j = ilist_append(j, 1);
	j = ilist_append(j, min->id);
	j = ilist_append(j, 1);

	resolvent->justification = resolve_just(j, BINARY_RES_JUST);
	upward_clause_links(resolvent);
	renumber_variables(resolvent, MAX_VARS);

	undo_subst(tr);
      }
      free_context(ca);
      free_context(cb);
      return resolvent;
    }
  }
}  /* cd */
Beispiel #14
0
static switch_status_t shout_file_close(switch_file_handle_t *handle)
{
	shout_context_t *context = handle->private_info;

	free_context(context);

	return SWITCH_STATUS_SUCCESS;
}
Beispiel #15
0
int pcmrec_read_params(void) {
	struct audiotest_thread_context *context;
	struct itimerspec ts;
	char *token;
	int ret_val = 0;

	if ((context = get_free_context()) == NULL) {
		ret_val = -1;
	} else {
		context->config.sample_rate = 8000;
		context->config.file_name = "/data/rec.wav";
		context->config.rec_mode = 1;
		context->type = AUDIOTEST_TEST_MOD_PCM_ENC;
		g_terminate_early = 0;
		struct audio_pvt_data *audio_data;
		audio_data = (struct audio_pvt_data *) malloc(sizeof(struct audio_pvt_data));
		if(!audio_data) {
			printf("error allocating audio instance structure \n");
			free_context(context);
			ret_val = -1;
		} else {
			audio_data->g_rec_buf_size = 4096;
			token = strtok(NULL, " ");
			while (token != NULL) {
				printf("%s \n", token);
				if (!memcmp(token,"-rate=", (sizeof("-rate=") - 1))) {
					context->config.sample_rate =
					atoi(&token[sizeof("-rate=") - 1]);
				} else if (!memcmp(token,"-rec_mode=", (sizeof("-rec_mode=") - 1))) {
					context->config.rec_mode =
					atoi(&token[sizeof("-rec_mode=") - 1]);
				} else if (!memcmp(token,"-recbufsize=", (sizeof("-recbufsize=") - 1))) {
					audio_data->g_rec_buf_size = atoi(&token[sizeof("-recbufsize=") - 1]);
				} else if (!memcmp(token,"-id=", (sizeof("-id=") - 1))) {
					context->cxt_id = atoi(&token[sizeof("-id=") - 1]);
				} else if (!memcmp(token,"-timeout=", (sizeof("-timeout=") - 1))) {
					audio_data->g_rec_timeout = atoi(&token[sizeof("-timeout=") - 1]);
					memset(&ts, 0, sizeof(struct itimerspec));
					printf("setting rec timeout to %d secs\n", audio_data->g_rec_timeout);
					ts.it_value.tv_sec = audio_data->g_rec_timeout;
					signal(SIGALRM, audiotest_alarm_handler);
					setitimer(ITIMER_REAL, &ts, NULL);
				} else {
					context->config.file_name = token;
				}
				token = strtok(NULL, " ");
			}
			context->config.private_data = (struct audio_pvt_data *) audio_data;
			printf("%s : sample_rate=%d rec_mode=%d\n",
				__FUNCTION__, context->config.sample_rate,
				context->config.rec_mode);
			pthread_create( &context->thread, NULL, recpcm_thread, (void*) context);
		}
	}

	return ret_val;
}
Beispiel #16
0
void rm(const char* path, const char* host, const char* username, const char* pass)
{
  xafp_client_handle ctx = get_context(host, username, pass);
  
  xafp_remove(ctx, path);
  
  // Clean-up the session
  free_context(ctx);  
}
Beispiel #17
0
void mv(const char* path, const char* newPath, const char* host, const char* username, const char* pass, uint32_t offset=0)
{
  xafp_client_handle ctx = get_context(host, username, pass);
  
  xafp_rename_file(ctx, path, newPath);
  
  // Clean-up the session
  free_context(ctx);  
}
/* PUBLIC */
void  zap_clash(Clash p)
{
  while (p != NULL) {
    Clash q = p;
    p = p->next;
    if (q->clashable && !q->clashed)
      free_context(q->sat_subst);
    free_clash(q);
  }
}  /* zap_clash */
Beispiel #19
0
void mg_stop(struct mg_context *ctx) {
  ctx->stop_flag = 1;

  // Wait until mg_fini() stops
  while (ctx->stop_flag != 2) {
    // TODO(steineldar): Avoid busy waiting.
    (void) sleep(0);
  }
  free_context(ctx);
}
Beispiel #20
0
void free_module(struct module* module) {
  if (module) {
    if (module->context) {
      mod_free_context* free_context = dlsym(module->handle, "freeContext");
      free_context(module->context);
    }
    dlclose(module->handle);
    free(module);
  }
};
Beispiel #21
0
void* recpcm_thread(void* arg) {
	struct audiotest_thread_context *context =
		(struct audiotest_thread_context*) arg;
	int ret_val;

	ret_val = wav_rec(&context->config);
	free_context(context);
	pthread_exit((void*) ret_val);

    return NULL;
}
Beispiel #22
0
bool exists(const char* path, const char* host, const char* username, const char* pass)
{
  xafp_client_handle ctx = get_context(host, username, pass);
  
  bool res = !xafp_stat(ctx, path);
  
  // Clean-up the session
  free_context(ctx);  
  
  return res;
}
Beispiel #23
0
void* playmp3_thread(void* arg) {
	struct audiotest_thread_context *context =
		(struct audiotest_thread_context*) arg;
	int ret_val;

	ret_val = mp3_play(&context->config);
	free_context(context);
	pthread_exit((void*) ret_val);

    return NULL;
}
Beispiel #24
0
void
free_settings(settings_t *settings)
{
	bool autofree = settings->autofree;

	if (settings->ctx)
		free_context(settings->ctx);
	memset(settings, 0, sizeof(settings_t));
	if (autofree)
		free(settings);
}
Beispiel #25
0
static void process_write(struct conn_context *client_ctx)
{
	int ep_fd, fd;
	int events = client_ctx->events;
	int cpu_id = client_ctx->cpu_id;
	int ret;
	struct epoll_event evt;

	ep_fd = client_ctx->ep_fd;
	fd = client_ctx->fd;

	print_d("Process write event[%02x]\n", events);

	if (events & (EPOLLHUP | EPOLLERR)) {
		printf("process_write() with events HUP or ERR\n");
		goto free_back;
	}

	ret = write(fd, http_response, http_response_len);
	if (ret < 0) {
		wdata[cpu_id].write_cnt++;
		perror("process_write() can't write client socket");
		goto free_back;
	}

	print_d("Write %d to socket %d\n", ret, fd);

	wdata[cpu_id].trancnt++;

	if (!enable_keepalive)
		goto free_back;

	client_ctx->handler = process_read;

	evt.events = EPOLLIN | EPOLLHUP | EPOLLERR;
	evt.data.ptr = client_ctx;

	ret = epoll_ctl(ep_fd, EPOLL_CTL_MOD, fd, &evt);
	if (ret < 0) {
		perror("Unable to add client socket read event to epoll");
		goto free_back;
	}

	goto back;

free_back:

	process_close(client_ctx);
	free_context(client_ctx);
back:

	return;
}
Beispiel #26
0
void cat(const char* path, void* pBuf, int len, const char* host, const char* username, const char* pass, uint32_t offset=0)
{
  xafp_client_handle ctx = get_context(host, username, pass);
  
  xafp_file_handle file = xafp_open_file(ctx, path, xafp_open_flag_read | xafp_open_flag_write);
  if (file)
  {
    xafp_write_file(ctx, file, offset, pBuf, len);
    xafp_close_file(ctx, file);
  }
  
  // Clean-up the session
  free_context(ctx);  
}
Beispiel #27
0
int mp3play_read_params(void) {
	struct audiotest_thread_context *context;
	struct itimerspec ts;
	char *token;
	int ret_val = 0;

	printf("This option is not supported currently\n");
	return -1;

	if ((context = get_free_context()) == NULL) {
		ret_val = -1;
	} else {
		context->config.file_name = "/data/test.mp3";
		g_terminate_early = 0;
		struct audio_pvt_data *audio_data;
		audio_data = (struct audio_pvt_data *) malloc(sizeof(struct audio_pvt_data));
		if(!audio_data) {
			printf("error allocating audio instance structure \n");
			free_context(context);
			ret_val = -1;
		} else {
			token = strtok(NULL, " ");
			while (token != NULL) {
				if (!memcmp(token,"-id=", (sizeof("-id=")-1))) {
					context->cxt_id = atoi(&token[sizeof("-id=") - 1]);
				} else if (!memcmp(token,"-volume=", (sizeof("-volume=") - 1))) {
					audio_data->g_test_volume = atoi(&token[sizeof("-volume=") - 1]);
				} else if (!memcmp(token,"-timeout=", (sizeof("-timeout=") - 1))) {
					audio_data->g_rec_timeout = atoi(&token[sizeof("-timeout=") - 1]);
					memset(&ts, 0, sizeof(struct itimerspec));
					printf("setting rec timeout to %d secs\n", audio_data->g_rec_timeout);
					ts.it_value.tv_sec = audio_data->g_rec_timeout;
					signal(SIGALRM, audiotest_alarm_handler);
					setitimer(ITIMER_REAL, &ts, NULL);
				} else {
					context->config.file_name = token;
				}
				token = strtok(NULL, " ");
			}
			context->type = AUDIOTEST_TEST_MOD_MP3_DEC;
			context->config.private_data = (struct audio_pvt_data *) audio_data;
			pthread_create( &context->thread, NULL,
					playmp3_thread, (void*) context);
		}
	}

	return ret_val;

}
Beispiel #28
0
/* MUST be called with cs_error held */
static void
release_context(kherr_context * c)
{
    if (IS_KHERR_CTX(c)) {
        c->refcount--;

        {
            kherr_event * e;

            e = QBOTTOM(c);
            if (IS_KHERR_EVENT(e) && !(e->flags & KHERR_RF_COMMIT)) {
                commit_event(c, e);
            }
        }

        if (c->refcount == 0) {
            kherr_context * p;

            if (CTX_USES_OWN_PROGRESS(c)) {
                set_and_notify_progress_change(c, 256, 256);
            }

            p = TPARENT(c);

#ifdef DEBUG
	    kherr_debug_printf(L"Posting KHERR_CTX_END for %p\n", (void *) c);
#endif
            notify_ctx_event(KHERR_CTX_END, c, NULL, NULL, 0);

            if (IS_KHERR_CTX(p)) {
                kherr_event * e;

                e = fold_context(c);
                TDELCHILD(p, c);
                
		if (e) {
                    add_event(p, e);
		    notify_ctx_event(KHERR_CTX_FOLDCHILD, p, NULL, e, 0);
		}

                release_context(p);
            } else {
                LDELETE(&ctx_root_list, c);
            }
            free_context(c);
        }
    }
}
Beispiel #29
0
OPENVPN_EXPORT openvpn_plugin_handle_t
openvpn_plugin_open_v1 (unsigned int *type_mask, const char *argv[], const char *envp[])
{
  struct down_root_context *context;

  /*
   * Allocate our context
   */
  context = (struct down_root_context *) calloc (1, sizeof (struct down_root_context));
  if (!context)
    goto error;
  context->foreground_fd = -1;

  /*
   * Intercept the --up and --down callbacks
   */
  *type_mask = OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_UP) | OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_DOWN);

  /*
   * Make sure we have two string arguments: the first is the .so name,
   * the second is the script command.
   */
  if (string_array_len (argv) < 2)
    {
      fprintf (stderr, "DOWN-ROOT: need down script command\n");
      goto error;
    }

  /*
   * Save our argument in context
   */
  context->command = build_command_line (&argv[1]);

  /*
   * Get verbosity level from environment
   */
  {
    const char *verb_string = get_env ("verb", envp);
    if (verb_string)
      context->verb = atoi (verb_string);
  }

  return (openvpn_plugin_handle_t) context;

 error:
  free_context (context);
  return NULL;
}
static void
exmpp_xml_stop(ErlDrvData drv_data)
{
	struct exmpp_xml_data *edd;

	edd = (struct exmpp_xml_data *)drv_data;

	/* Destroy the parser. */
	destroy_parser(edd);

	/* Free generic context. */
	free_context(&edd->ctx);

	/* Free driver data structure. */
	driver_free(edd);
}