Beispiel #1
0
int main(int argc, char *argv[])
{
    init_signal();

    g_shm_bsb = fifo_creat_shm(DEF_SHMMAP_KEY, 10, 1024);
    if(NULL == g_shm_bsb){
        printf("fifo_creat_shm failed \n");
        return -1;
    }
#if 1
    if(start_writer() < 0){
         printf("start_writer failed!\n");
         return -1;
    }
#else
    if(start_reader() < 0){
         printf("start_reader failed!\n");
         return -1;
    }
#endif
    while(!g_flag_shm_exit){
        sleep(100);
    }

    return 0;
}
Beispiel #2
0
void InitThread(int argc, char* argv[])
{
  if (argc < 3) {
    for(int i = 0; i < totalThreads; i++) {
      glThreads[i] = new GLThread();
    }
    for(int i = 0; i < 500; i ++) {
      apprxThreads[i] = new GLThread();
    }

  } else {
    Trajectory_Reader start_reader(argv[1]);
    start_reader.read_threads_from_file();
    Trajectory_Reader end_reader(argv[2]);
    end_reader.read_threads_from_file();

    glThreads[0] = new GLThread(new Thread(start_reader.get_all_threads()[0]));
    glThreads[1] = new GLThread(new Thread(start_reader.get_all_threads()[0]));
    glThreads[2] = new GLThread(new Thread(start_reader.get_all_threads()[0]));

    glThreads[3] = new GLThread(new Thread(end_reader.get_all_threads()[0]));

    glThreads[4] = new GLThread(new Thread(start_reader.get_all_threads()[0]));
    glThreads[5] = new GLThread(new Thread(start_reader.get_all_threads()[0]));
    glThreads[6] = new GLThread(new Thread(start_reader.get_all_threads()[0]));
    glThreads[7] = new GLThread(new Thread(start_reader.get_all_threads()[0]));

  }
  for(int i = 0; i < totalThreads; i++) {
    glThreads[i]->minimize_energy();
  }
}
Beispiel #3
0
int main(int argc, char *argv[]){
    struct timeval st , et;

    gettimeofday(&st , NULL);    
    start_reader();
    gettimeofday(&et , NULL);

    printf("Tempo total de execução do programa: %lu seconds\n",(et.tv_sec - st.tv_sec));

    return 0;
}
Beispiel #4
0
void run_read(CQ qp, RPQ rside, RPQ wside)
{
	/* more data in queue? run more reader threads */
	if (qsize(qp) > 0)
	{
		/* run more readers */
		start_reader(rside);
	}

	/* some space freed? run some writer threads */
	if (!rpqempty(wside) && !qfull(qp))
		Run(rpqtop(wside));
}
Beispiel #5
0
static int ti_restart(struct tip_cygwin *priv)
{
	/* kill handle to if */
	if (priv->tc_h)
		CloseHandle(priv->tc_h);

	/* stop reader */
	if (stop_reader(priv))
		return -1;

	/* reopen dev */
	if (ti_do_open_cygwin(priv))
		return -1;

	return start_reader(priv);
}
Beispiel #6
0
void t_monitor (const char *cmd, DDS_DomainParticipant part)
{
	Topic	*tp;
	char	spec [192];

	skip_blanks (&cmd);
	skip_string (&cmd, spec);
	if (spec [0]) {
		lock_take (topic_lock);
		LIST_FOREACH (topics, tp)
			if (!tp->active &&
			    tp->writers &&
			    !nmatch (spec, tp->topic_name, NM_CASEFOLD))
				start_reader (part, tp);
		lock_release (topic_lock);
	}
}
Beispiel #7
0
static struct tif *ti_open_cygwin(char *iface)
{
	struct tif *ti;
	struct tip_cygwin *priv;

	/* setup ti struct */
	ti = ti_alloc(sizeof(*priv));
	if (!ti)
		return NULL;
	priv = ti_priv(ti);

	ti->ti_name	= ti_name_cygwin;
	ti->ti_set_mtu	= ti_set_mtu_cygwin;
	ti->ti_close	= ti_close_cygwin;
	ti->ti_fd	= ti_fd_cygwin;
	ti->ti_read	= ti_read_cygwin;
	ti->ti_write	= ti_write_cygwin;
	ti->ti_set_mac	= ti_set_mac_cygwin;
	ti->ti_set_ip	= ti_set_ip_cygwin;

	/* setup iface */
	if (iface)
		snprintf(priv->tc_guid, sizeof(priv->tc_guid), "%s", iface);
	if (ti_do_open_cygwin(priv) == -1)
		goto err;

	/* setup reader */
	if (pipe(priv->tc_pipe) == -1)
		goto err;

	if (pthread_mutex_init(&priv->tc_mtx, NULL))
		goto err;

	/* launch reader */
	if (start_reader(priv))
		goto err;

	return ti;
err:
	ti_do_free(ti);
	return NULL;
}
/**
 * @brief connect to a cSploitd UNIX socket
 * @param jsocket_path path to the UNIX socket
 * @returns true on success, false on error.
 */
jboolean connect_unix(JNIEnv *env, jclass clazz _U_, jstring jsocket_path) {
  const char *socket_path;
  jboolean ret;
  struct sockaddr_un addr;
  
  if(connected)
    disconnect_unix(env, clazz);
  
  sockfd=-1;
  ret = JNI_FALSE;
  
  socket_path = (*env)->GetStringUTFChars(env, jsocket_path, NULL);
  
  if(!socket_path) goto jni_error;
  
  sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
  
  if(sockfd<0) {
    LOGE("%s: socket: %s", __func__, strerror(errno));
    goto cleanup; // nothing to close
  }
  
  memset(&addr, 0, sizeof(struct sockaddr_un));
  addr.sun_family = AF_UNIX;
  strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path)-1);
  
  if(connect(sockfd, (struct sockaddr *) &addr, sizeof(addr))) {
    LOGE("%s: connect: %s", __func__, strerror(errno));
    goto error;
  }
  
  if(start_reader()) {
    LOGE("%s: cannot start reader", __func__);
    goto error;
  }
  
  if(start_notifier()) {
    LOGE("%s: cannot start notifier", __func__);
    goto error;
  }
  
  connected = 1;
  
  on_connect();
  
  ret = JNI_TRUE;
  
  goto cleanup;
  
  jni_error:
  
  if((*env)->ExceptionCheck(env)) {
    (*env)->ExceptionDescribe(env);
    (*env)->ExceptionClear(env);
  }
  
  error:
  
  stop_notifier();
  
  shutdown(sockfd, SHUT_WR);
  
  stop_reader();
  
  close(sockfd);
  sockfd = -1;
  
  cleanup:
  
  if(socket_path)
    (*env)->ReleaseStringUTFChars(env, jsocket_path, socket_path);
  
  return ret;
}
Beispiel #9
0
/* Call GPG to decrypt a block of data.


 */
static gpg_error_t
_gpg_decrypt (ctrl_t ctrl,
              const char *gpg_program,
              strlist_t gpg_arguments,
              const void *ciph, size_t ciphlen,
              estream_t cipher_stream,
              membuf_t *reader_mb,
              estream_t plain_stream)
{
  gpg_error_t err;
  assuan_context_t ctx = NULL;
  int outbound_fds[2] = { -1, -1 };
  int inbound_fds[2]  = { -1, -1 };
  npth_t writer_thread = (npth_t)0;
  npth_t reader_thread = (npth_t)0;
  gpg_error_t writer_err, reader_err;
  int ret;

  /* Make sure that either the stream interface xor the buffer
     interface is used.  */
  assert ((ciph == NULL) != (cipher_stream == NULL));
  assert ((reader_mb == NULL) != (plain_stream == NULL));

  /* Create two pipes.  */
  err = gnupg_create_outbound_pipe (outbound_fds, NULL, 0);
  if (!err)
    err = gnupg_create_inbound_pipe (inbound_fds, NULL, 0);
  if (err)
    {
      log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
      goto leave;
    }

  /* Start GPG and send the INPUT and OUTPUT commands.  */
  err = start_gpg (ctrl, gpg_program, gpg_arguments,
                   outbound_fds[0], inbound_fds[1], &ctx);
  if (err)
    goto leave;
  close (outbound_fds[0]); outbound_fds[0] = -1;
  close (inbound_fds[1]); inbound_fds[1] = -1;

  /* Start a writer thread to feed the INPUT command of the server.  */
  err = start_writer (outbound_fds[1], ciph, ciphlen, cipher_stream,
                      &writer_thread, &writer_err);
  if (err)
    return err;
  outbound_fds[1] = -1;  /* The thread owns the FD now.  */

  /* Start a reader thread to eat from the OUTPUT command of the
     server.  */
  err = start_reader (inbound_fds[0], reader_mb, plain_stream,
                      &reader_thread, &reader_err);
  if (err)
    return err;
  outbound_fds[0] = -1;  /* The thread owns the FD now.  */

  /* Run the decryption.  */
  err = assuan_transact (ctx, "DECRYPT", NULL, NULL, NULL, NULL, NULL, NULL);
  if (err)
    {
      log_error ("the engine's DECRYPT command failed: %s <%s>\n",
                 gpg_strerror (err), gpg_strsource (err));
      goto leave;
    }

  /* Wait for reader and return the data.  */
  ret = npth_join (reader_thread, NULL);
  if (ret)
    {
      err = my_error_from_errno (ret);
      log_error ("waiting for reader thread failed: %s\n", gpg_strerror (err));
      goto leave;
    }
  memset (&reader_thread, '\0', sizeof (reader_thread));
  if (reader_err)
    {
      err = reader_err;
      log_error ("read error in reader thread: %s\n", gpg_strerror (err));
      goto leave;
    }

  /* Wait for the writer to catch a writer error.  */
  ret = npth_join (writer_thread, NULL);
  if (ret)
    {
      err = my_error_from_errno (ret);
      log_error ("waiting for writer thread failed: %s\n", gpg_strerror (err));
      goto leave;
    }
  memset (&writer_thread, '\0', sizeof (writer_thread));
  if (writer_err)
    {
      err = writer_err;
      log_error ("write error in writer thread: %s\n", gpg_strerror (err));
      goto leave;
    }

 leave:
  if (reader_thread)
    npth_detach (reader_thread);
  if (writer_thread)
    npth_detach (writer_thread);
  if (outbound_fds[0] != -1)
    close (outbound_fds[0]);
  if (outbound_fds[1] != -1)
    close (outbound_fds[1]);
  if (inbound_fds[0] != -1)
    close (inbound_fds[0]);
  if (inbound_fds[1] != -1)
    close (inbound_fds[1]);
  release_gpg (ctx);
  return err;
}
Beispiel #10
0
/* Call GPG to encrypt a block of data.


 */
static gpg_error_t
_gpg_encrypt (ctrl_t ctrl,
              const char *gpg_program,
              strlist_t gpg_arguments,
              const void *plain, size_t plainlen,
              estream_t plain_stream,
              strlist_t keys,
              membuf_t *reader_mb,
              estream_t cipher_stream)
{
  gpg_error_t err;
  assuan_context_t ctx = NULL;
  int outbound_fds[2] = { -1, -1 };
  int inbound_fds[2]  = { -1, -1 };
  npth_t writer_thread = (npth_t)0;
  npth_t reader_thread = (npth_t)0;
  gpg_error_t writer_err, reader_err;
  char line[ASSUAN_LINELENGTH];
  strlist_t sl;
  int ret;

  /* Make sure that either the stream interface xor the buffer
     interface is used.  */
  assert ((plain == NULL) != (plain_stream == NULL));
  assert ((reader_mb == NULL) != (cipher_stream == NULL));

  /* Create two pipes.  */
  err = gnupg_create_outbound_pipe (outbound_fds, NULL, 0);
  if (!err)
    err = gnupg_create_inbound_pipe (inbound_fds, NULL, 0);
  if (err)
    {
      log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
      goto leave;
    }

  /* Start GPG and send the INPUT and OUTPUT commands.  */
  err = start_gpg (ctrl, gpg_program, gpg_arguments,
                   outbound_fds[0], inbound_fds[1], &ctx);
  if (err)
    goto leave;
  close (outbound_fds[0]); outbound_fds[0] = -1;
  close (inbound_fds[1]); inbound_fds[1] = -1;

  /* Start a writer thread to feed the INPUT command of the server.  */
  err = start_writer (outbound_fds[1], plain, plainlen, plain_stream,
                      &writer_thread, &writer_err);
  if (err)
    return err;
  outbound_fds[1] = -1;  /* The thread owns the FD now.  */

  /* Start a reader thread to eat from the OUTPUT command of the
     server.  */
  err = start_reader (inbound_fds[0], reader_mb, cipher_stream,
                      &reader_thread, &reader_err);
  if (err)
    return err;
  outbound_fds[0] = -1;  /* The thread owns the FD now.  */

  /* Run the encryption.  */
  for (sl = keys; sl; sl = sl->next)
    {
      snprintf (line, sizeof line, "RECIPIENT -- %s", sl->d);
      err = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
      if (err)
        {
          log_error ("the engine's RECIPIENT command failed: %s <%s>\n",
                 gpg_strerror (err), gpg_strsource (err));
          goto leave;
        }
    }

  err = assuan_transact (ctx, "ENCRYPT", NULL, NULL, NULL, NULL, NULL, NULL);
  if (err)
    {
      log_error ("the engine's ENCRYPT command failed: %s <%s>\n",
                 gpg_strerror (err), gpg_strsource (err));
      goto leave;
    }

  /* Wait for reader and return the data.  */
  ret = npth_join (reader_thread, NULL);
  if (ret)
    {
      err = my_error_from_errno (ret);
      log_error ("waiting for reader thread failed: %s\n", gpg_strerror (err));
      goto leave;
    }
  /* FIXME: Not really valid, as npth_t is an opaque type.  */
  memset (&reader_thread, '\0', sizeof (reader_thread));
  if (reader_err)
    {
      err = reader_err;
      log_error ("read error in reader thread: %s\n", gpg_strerror (err));
      goto leave;
    }

  /* Wait for the writer to catch  a writer error.  */
  ret = npth_join (writer_thread, NULL);
  if (ret)
    {
      err = my_error_from_errno (ret);
      log_error ("waiting for writer thread failed: %s\n", gpg_strerror (err));
      goto leave;
    }
  memset (&writer_thread, '\0', sizeof (writer_thread));
  if (writer_err)
    {
      err = writer_err;
      log_error ("write error in writer thread: %s\n", gpg_strerror (err));
      goto leave;
    }

 leave:
  /* FIXME: Not valid, as npth_t is an opaque type.  */
  if (reader_thread)
    npth_detach (reader_thread);
  if (writer_thread)
    npth_detach (writer_thread);
  if (outbound_fds[0] != -1)
    close (outbound_fds[0]);
  if (outbound_fds[1] != -1)
    close (outbound_fds[1]);
  if (inbound_fds[0] != -1)
    close (inbound_fds[0]);
  if (inbound_fds[1] != -1)
    close (inbound_fds[1]);
  release_gpg (ctx);
  return err;
}
Beispiel #11
0
/* Call GPG to decrypt a block of data.


 */
gpg_error_t
gpg_decrypt_blob (ctrl_t ctrl, const void *ciph, size_t ciphlen,
                  void **r_plain, size_t *r_plainlen)
{
  gpg_error_t err;
  assuan_context_t ctx = NULL;
  int outbound_fds[2] = { -1, -1 };
  int inbound_fds[2]  = { -1, -1 };
  npth_t writer_thread = (npth_t)0;
  npth_t reader_thread = (npth_t)0;
  gpg_error_t writer_err, reader_err;
  membuf_t reader_mb;
  int ret;

  *r_plain = NULL;
  *r_plainlen = 0;

  /* Init the memory buffer to receive the encrypted stuff.  */
  init_membuf_secure (&reader_mb, 1024);

  /* Create two pipes.  */
  err = gnupg_create_outbound_pipe (outbound_fds);
  if (!err)
    err = gnupg_create_inbound_pipe (inbound_fds);
  if (err)
    {
      log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
      goto leave;
    }

  /* Start GPG and send the INPUT and OUTPUT commands.  */
  err = start_gpg (ctrl, outbound_fds[0], inbound_fds[1], &ctx);
  if (err)
    goto leave;
  close (outbound_fds[0]); outbound_fds[0] = -1;
  close (inbound_fds[1]); inbound_fds[1] = -1;

  /* Start a writer thread to feed the INPUT command of the server.  */
  err = start_writer (outbound_fds[1], ciph, ciphlen,
                      &writer_thread, &writer_err);
  if (err)
    return err;
  outbound_fds[1] = -1;  /* The thread owns the FD now.  */

  /* Start a reader thread to eat from the OUTPUT command of the
     server.  */
  err = start_reader (inbound_fds[0], &reader_mb,
                      &reader_thread, &reader_err);
  if (err)
    return err;
  outbound_fds[0] = -1;  /* The thread owns the FD now.  */

  /* Run the decryption.  */
  err = assuan_transact (ctx, "DECRYPT", NULL, NULL, NULL, NULL, NULL, NULL);
  if (err)
    {
      log_error ("the engine's DECRYPT command failed: %s <%s>\n",
                 gpg_strerror (err), gpg_strsource (err));
      goto leave;
    }

  /* Wait for reader and return the data.  */
  ret = npth_join (reader_thread, NULL);
  if (ret)
    {
      err = gpg_error_from_errno (ret);
      log_error ("waiting for reader thread failed: %s\n", gpg_strerror (err));
      goto leave;
    }
  memset (&reader_thread, '\0', sizeof (reader_thread));
  if (reader_err)
    {
      err = reader_err;
      log_error ("read error in reader thread: %s\n", gpg_strerror (err));
      goto leave;
    }

  /* Wait for the writer to catch a writer error.  */
  ret = npth_join (writer_thread, NULL);
  if (ret)
    {
      err = gpg_error_from_errno (ret);
      log_error ("waiting for writer thread failed: %s\n", gpg_strerror (err));
      goto leave;
    }
  memset (&writer_thread, '\0', sizeof (writer_thread));
  if (writer_err)
    {
      err = writer_err;
      log_error ("write error in writer thread: %s\n", gpg_strerror (err));
      goto leave;
    }

  /* Return the data.  */
  *r_plain = get_membuf (&reader_mb, r_plainlen);
  if (!*r_plain)
    {
      err = gpg_error_from_syserror ();
      log_error ("error while storing the data in the reader thread: %s\n",
                 gpg_strerror (err));
      goto leave;
    }

 leave:
  if (reader_thread)
    npth_detach (reader_thread);
  if (writer_thread)
    npth_detach (writer_thread);
  if (outbound_fds[0] != -1)
    close (outbound_fds[0]);
  if (outbound_fds[1] != -1)
    close (outbound_fds[1]);
  if (inbound_fds[0] != -1)
    close (inbound_fds[0]);
  if (inbound_fds[1] != -1)
    close (inbound_fds[1]);
  release_gpg (ctx);
  xfree (get_membuf (&reader_mb, NULL));
  return err;
}
Beispiel #12
0
/* Call GPG to encrypt a block of data.


 */
gpg_error_t
gpg_encrypt_blob (ctrl_t ctrl, const void *plain, size_t plainlen,
                  strlist_t keys, void **r_ciph, size_t *r_ciphlen)
{
  gpg_error_t err;
  assuan_context_t ctx = NULL;
  int outbound_fds[2] = { -1, -1 };
  int inbound_fds[2]  = { -1, -1 };
  npth_t writer_thread = (npth_t)0;
  npth_t reader_thread = (npth_t)0;
  gpg_error_t writer_err, reader_err;
  membuf_t reader_mb;
  char line[ASSUAN_LINELENGTH];
  strlist_t sl;
  int ret;

  *r_ciph = NULL;
  *r_ciphlen = 0;

  /* Init the memory buffer to receive the encrypted stuff.  */
  init_membuf (&reader_mb, 4096);

  /* Create two pipes.  */
  err = gnupg_create_outbound_pipe (outbound_fds);
  if (!err)
    err = gnupg_create_inbound_pipe (inbound_fds);
  if (err)
    {
      log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
      goto leave;
    }

  /* Start GPG and send the INPUT and OUTPUT commands.  */
  err = start_gpg (ctrl, outbound_fds[0], inbound_fds[1], &ctx);
  if (err)
    goto leave;
  close (outbound_fds[0]); outbound_fds[0] = -1;
  close (inbound_fds[1]); inbound_fds[1] = -1;

  /* Start a writer thread to feed the INPUT command of the server.  */
  err = start_writer (outbound_fds[1], plain, plainlen,
                      &writer_thread, &writer_err);
  if (err)
    return err;
  outbound_fds[1] = -1;  /* The thread owns the FD now.  */

  /* Start a reader thread to eat from the OUTPUT command of the
     server.  */
  err = start_reader (inbound_fds[0], &reader_mb,
                      &reader_thread, &reader_err);
  if (err)
    return err;
  outbound_fds[0] = -1;  /* The thread owns the FD now.  */

  /* Run the encryption.  */
  for (sl = keys; sl; sl = sl->next)
    {
      snprintf (line, sizeof line, "RECIPIENT -- %s", sl->d);
      err = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
      if (err)
        {
          log_error ("the engine's RECIPIENT command failed: %s <%s>\n",
                 gpg_strerror (err), gpg_strsource (err));
          goto leave;
        }
    }

  err = assuan_transact (ctx, "ENCRYPT", NULL, NULL, NULL, NULL, NULL, NULL);
  if (err)
    {
      log_error ("the engine's ENCRYPT command failed: %s <%s>\n",
                 gpg_strerror (err), gpg_strsource (err));
      goto leave;
    }

  /* Wait for reader and return the data.  */
  ret = npth_join (reader_thread, NULL);
  if (ret)
    {
      err = gpg_error_from_errno (ret);
      log_error ("waiting for reader thread failed: %s\n", gpg_strerror (err));
      goto leave;
    }
  /* FIXME: Not really valid, as npth_t is an opaque type.  */
  memset (&reader_thread, '\0', sizeof (reader_thread));
  if (reader_err)
    {
      err = reader_err;
      log_error ("read error in reader thread: %s\n", gpg_strerror (err));
      goto leave;
    }

  /* Wait for the writer to catch  a writer error.  */
  ret = npth_join (writer_thread, NULL);
  if (ret)
    {
      err = gpg_error_from_errno (ret);
      log_error ("waiting for writer thread failed: %s\n", gpg_strerror (err));
      goto leave;
    }
  memset (&writer_thread, '\0', sizeof (writer_thread));
  if (writer_err)
    {
      err = writer_err;
      log_error ("write error in writer thread: %s\n", gpg_strerror (err));
      goto leave;
    }

  /* Return the data.  */
  *r_ciph = get_membuf (&reader_mb, r_ciphlen);
  if (!*r_ciph)
    {
      err = gpg_error_from_syserror ();
      log_error ("error while storing the data in the reader thread: %s\n",
                 gpg_strerror (err));
      goto leave;
    }

 leave:
  /* FIXME: Not valid, as npth_t is an opaque type.  */
  if (reader_thread)
    npth_detach (reader_thread);
  if (writer_thread)
    npth_detach (writer_thread);
  if (outbound_fds[0] != -1)
    close (outbound_fds[0]);
  if (outbound_fds[1] != -1)
    close (outbound_fds[1]);
  if (inbound_fds[0] != -1)
    close (inbound_fds[0]);
  if (inbound_fds[1] != -1)
    close (inbound_fds[1]);
  release_gpg (ctx);
  xfree (get_membuf (&reader_mb, NULL));
  return err;
}
Beispiel #13
0
Endpoint *ep_create (DDS_DomainParticipant           part,
		     DDS_BuiltinTopicKey_t           *key,
		     const char                      *topic_name,
		     const char                      *type_name,
		     DDS_PublicationBuiltinTopicData *data,
		     int                             writer)
{
	Topic		*tp;
	Endpoint	*ep;

	printf ("* New %s (%s/%s)\r\n", (writer) ? "writer" : "reader", 
						topic_name, type_name);
	ep = ep_lookup (key);
	if (ep) {
		if (writer) {
			ep->data = *data;
			tp = ep->topic;
			ep->data.topic_name = tp->topic_name;
			ep->data.type_name = tp->type_name;
		}
		return (ep);
	}
	ep = malloc (sizeof (Endpoint));
	if (!ep) {
		fprintf (stderr, "Not enough memory to create endpoint!\r\n");
		return (NULL);
	}
	ep->topic = tp = t_lookup (topic_name);
	if (!tp) {
		ep->link = NULL;
		tp = malloc (sizeof (Topic));
		if (!tp) {
			fprintf (stderr, "Not enough memory to create topic!\r\n");
			free (ep);
			return (NULL);
		}
		if (writer) {
			tp->writers = ep;
			tp->readers = NULL;
		}
		else {
			tp->readers = ep;
			tp->writers = NULL;
		}
		tp->topic_name = strdup (topic_name);
		tp->type_name = strdup (type_name);
		tp->active = 0;
		tp->topic = NULL;
		tp->dtype = NULL;
		tp->sub = NULL;
		tp->ts = NULL;
		tp->ndata = tp->ndispose = tp->nnowriter = 0;
		ep->topic = tp;
		LIST_ADD_TAIL (topics, *tp);
	}
	else if (writer) {
		ep->link = tp->writers;
		tp->writers = ep;
	}
	else {
		ep->link = tp->readers;
		tp->readers = ep;
	}
	ep->writer = writer;
	ep->key = *key;
	if (ep->writer) {
		ep->data = *data;
		ep->data.topic_name = tp->topic_name;
		ep->data.type_name = tp->type_name;
	}
	LIST_ADD_TAIL (endpoints, *ep);

	/* Endpoint successfully added -- check if we need a reader. */
	if (writer &&
	    !ep->link &&
	    auto_filter [0] &&
	    !nmatch (auto_filter, tp->topic_name, NM_CASEFOLD))
		start_reader (part, tp);
	return (ep);
}