Infrastructure for the new design.
authormdw <mdw>
Mon, 26 Jul 1999 23:33:01 +0000 (23:33 +0000)
committermdw <mdw>
Mon, 26 Jul 1999 23:33:01 +0000 (23:33 +0000)
endpt.c [new file with mode: 0644]
endpt.h [new file with mode: 0644]
reffd.c [new file with mode: 0644]
reffd.h [new file with mode: 0644]
source.c [new file with mode: 0644]
source.h [new file with mode: 0644]
target.h [new file with mode: 0644]

diff --git a/endpt.c b/endpt.c
new file mode 100644 (file)
index 0000000..348dd44
--- /dev/null
+++ b/endpt.c
@@ -0,0 +1,374 @@
+/* -*-c-*-
+ *
+ * $Id: endpt.c,v 1.1 1999/07/26 23:33:01 mdw Exp $
+ *
+ * Generic endpoint abstraction
+ *
+ * (c) 1999 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------* 
+ *
+ * This file is part of the `fw' port forwarder.
+ *
+ * `fw' is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * `fw' is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with `fw'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*----- Revision history --------------------------------------------------* 
+ *
+ * $Log: endpt.c,v $
+ * Revision 1.1  1999/07/26 23:33:01  mdw
+ * Infrastructure for the new design.
+ *
+ */
+
+/*----- Header files ------------------------------------------------------*/
+
+#include "config.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "chan.h"
+#include "endpt.h"
+
+/*----- Data structures ---------------------------------------------------*/
+
+/* --- Pairs of channels --- *
+ *
+ * Channels are always allocated and freed in pairs.  It makes sense to keep
+ * the pair together.  (It also wastes less memory.)
+ */
+
+typedef struct chanpair {
+  struct chanpair *next;
+  chan ab, ba;
+} chanpair;
+
+/* --- The `private data structure' --- *
+ *
+ * This is called a @tango@ because it takes two (endpoints).
+ */
+
+typedef struct tango {
+  struct tango *next, *prev;           /* A big list of all tangos */
+  endpt *a, *b;                                /* The two endpoints */
+  unsigned s;                          /* State of the connection */
+  chanpair *c;                         /* The pair of channels */
+} tango;
+
+#define EPS_AB 1u
+#define EPS_BA 2u
+
+/*----- Static variables --------------------------------------------------*/
+
+static chanpair *chans = 0;            /* List of spare channel pairs */
+static tango *tangos = 0;              /* List of tangos */
+
+/*----- Main code ---------------------------------------------------------*/
+
+/* --- @doneab@, @doneba@ --- *
+ *
+ * Arguments:  @void *p@ = pointer to a tango block
+ *
+ * Returns:    ---
+ *
+ * Use:                Handles completion of a channel.
+ */
+
+static void doneab(void *p)
+{
+  tango *t = p;
+  t->s &= ~EPS_AB;
+  t->b->ops->wclose(t->b);
+  if (!t->s)
+    endpt_kill(t->a);
+}
+
+static void doneba(void *p)
+{
+  tango *t = p;
+  t->s &= ~EPS_BA;
+  t->a->ops->wclose(t->a);
+  if (!t->s)
+    endpt_kill(t->a);
+}
+
+/* --- @endpt_kill@ --- *
+ *
+ * Arguments:  @endpt *a@ = an endpoint
+ *
+ * Returns:    ---
+ *
+ * Use:                Kills an endpoint.  If the endpoint is joined to another, the
+ *             other endpoint is also killed, as is the connection between
+ *             them (and that's the tricky bit).
+ */
+
+void endpt_kill(endpt *a)
+{
+  tango *t;
+  endpt *b;
+
+  /* --- If the endpont is unconnected, just close it --- */
+
+  if (!a->t) {
+    a->ops->close(a);
+    return;
+  }
+  t = a->t;
+  a = t->a;
+  b = t->b;
+
+  /* --- See whether to close channels --- *
+   *
+   * I'll only have opened channels if both things are files.  Also, the
+   * channel from @b@ to @a@ will only be open if @b@ is not pending.
+   */
+
+  if (a->f & b->f & EPF_FILE) {
+    if (t->s & EPS_AB)
+      chan_close(&t->c->ab);
+    if (!(b->f & EPF_PENDING) && (t->s & EPS_BA))
+      chan_close(&t->c->ba);
+    t->c->next = chans;
+    chans = t->c;
+  }
+
+  /* --- Now just throw the endpoints and tango block away --- */
+
+  a->ops->close(a);
+  b->ops->close(b);
+  if (t->next)
+    t->next->prev = t->prev;
+  if (t->prev)
+    t->prev->next = t->next;
+  else
+    tangos = t->next;
+  DESTROY(t);
+}
+
+/* --- @endpt_killall@ --- *
+ *
+ * Arguments:  ---
+ *
+ * Returns:    ---
+ *
+ * Use:                Destroys all current endpoint connections.  Used when
+ *             shutting down.
+ */
+
+void endpt_killall(void)
+{
+  tango *t = tangos;
+  while (t) {
+    tango *tt = t;
+    t = t->next;
+    endpt_kill(tt->a);
+  }
+  tangos = 0;
+}
+
+/* --- @endpt_join@ --- *
+ *
+ * Arguments:  @endpt *a@ = pointer to first endpoint
+ *             @endpt *b@ = pointer to second endpoint
+ *
+ * Returns:    ---
+ *
+ * Use:                Joins two endpoints together.  It's OK to join endpoints
+ *             which are already joined; in fact, the the right thing to do
+ *             when your endpoint decides that it's not pending any more is
+ *             to join it to its partner again.
+ */
+
+void endpt_join(endpt *a, endpt *b)
+{
+  tango *t = a->t;
+
+  /* --- If there is no tango yet, create one --- */
+
+  if (!t) {
+    t = CREATE(tango);
+    t->next = tangos;
+    t->prev = 0;
+    t->a = b->other = a;
+    t->b = a->other = b;
+    a->t = b->t = t;
+    t->s = EPS_AB | EPS_BA;
+    t->c = 0;
+    if (tangos)
+      tangos->prev = t;
+    tangos = t;
+  }
+
+  /* --- If both endpoints are unfinished, leave them for a while --- */
+
+  if (a->f & b->f & EPF_PENDING)
+    return;
+
+  /* --- At least one endpoint is ready --- *
+   *
+   * If both endpoints are files then I can speculatively create the
+   * channels, which will let data start flowing a bit.  Otherwise, I'll just
+   * have to wait some more.
+   */
+
+  if ((a->f | b->f) & EPF_PENDING) {
+
+    /* --- Only be interested if both things are files --- */
+
+    if (!t->c && (a->f & b->f & EPF_FILE)) {
+
+      /* --- Allocate a pair of channels --- */
+
+      if (!chans)
+       t->c = xmalloc(sizeof(*t->c));
+      else {
+       t->c = chans;
+       chans = chans->next;
+      }
+
+      /* --- Make @a@ the endpoint which is ready --- */
+
+      if (a->f & EPF_PENDING) {
+       t->b = a; t->a = b;
+       a = t->a; b = t->b;
+      }
+
+      /* --- Open one channel to read from @a@ --- */
+
+      chan_open(&t->c->ab, a->in->fd, -1, doneab, t);
+    }
+    return;
+  }
+
+  /* --- Both endpoints are now ready --- *
+   *
+   * There are four cases to consider here.
+   */
+
+  /* --- Case 1 --- *
+   *
+   * Neither endpoint is a file.  I need to make a pair of pipes and tell
+   * both endpoints to attach to them.  I can then close the pipes and
+   * discard the tango.
+   */
+
+  if (!((a->f | b->f) & EPF_FILE)) {
+    int pab[2], pba[2];
+    reffd *rab, *wab, *rba, *wba;
+
+    /* --- Create the pipes --- */
+
+    if (pipe(pab)) goto tidy_nofile_0;
+    if (pipe(pba)) goto tidy_nofile_1;
+
+    /* --- Attach reference counters --- */
+
+    rab = reffd_init(pab[0]); wab = reffd_init(pab[1]);
+    rba = reffd_init(pba[0]); wba = reffd_init(pba[1]);
+    a->ops->attach(a, rba, wab);
+    b->ops->attach(b, rab, wba);
+    REFFD_DEC(rab); REFFD_DEC(wab);
+    REFFD_DEC(rba); REFFD_DEC(wba);
+    goto tidy_nofile_0;
+
+    /* --- Tidy up after a mess --- */
+
+  tidy_nofile_1:
+    close(pab[0]); close(pab[1]);
+  tidy_nofile_0:
+    a->ops->close(a);
+    b->ops->close(b);
+    if (t->next)
+      t->next->prev = t->prev;
+    if (t->prev)
+      t->prev->next = t->next;
+    else
+      tangos = t->next;
+    DESTROY(t);
+    return;
+  }
+
+  /* --- Case 2 --- *
+   *
+   * One endpoint is a file, the other isn't.  I just attach the other
+   * endpoint to the file and stand well back.
+   */
+
+  if ((a->f ^ b->f) & EPF_FILE) {
+
+    /* --- Let @a@ be the endpoint with the file --- */
+
+    if (b->f & EPF_FILE) {
+      endpt *e;
+      e = a; a = b; b = e;
+    }
+
+    /* --- Attach the non-file endpoint to the file and run away --- */
+
+    b->ops->attach(b, a->in, a->out);
+    a->ops->close(a);
+    b->ops->close(b);
+    if (t->next)
+      t->next->prev = t->prev;
+    if (t->prev)
+      t->prev->next = t->next;
+    else
+      tangos = t->next;
+    DESTROY(t);
+    return;
+  }
+
+  /* --- Case 3 --- *
+   *
+   * Both endpoints are files and I have a partially created channel pair.  I
+   * need to create the other channel and add a destination to the first one.
+   * In this case, @t->b@ is the endpoint which has just finished setting
+   * itself up.
+   */
+
+  if (t->c) {
+    a = t->a; b = t->b;
+    chan_open(&t->c->ba, b->in->fd, a->out->fd, doneba, t);
+    chan_dest(&t->c->ab, b->out->fd);
+    return;
+  }
+
+  /* --- Case 4 --- *
+   *
+   * Both endpoints are files and I don't have a partially created channel
+   * pair.  I need to allocate a channel pair and create both channels.
+   */
+
+  if (!chans)
+    t->c = xmalloc(sizeof(*t->c));
+  else {
+    t->c = chans;
+    chans = chans->next;
+  }
+  chan_open(&t->c->ab, a->in->fd, b->out->fd, doneab, t);
+  chan_open(&t->c->ba, b->in->fd, a->out->fd, doneba, t);
+  return;
+}  
+
+/*----- That's all, folks -------------------------------------------------*/
diff --git a/endpt.h b/endpt.h
new file mode 100644 (file)
index 0000000..fb44aa9
--- /dev/null
+++ b/endpt.h
@@ -0,0 +1,155 @@
+/* -*-c-*-
+ *
+ * $Id: endpt.h,v 1.1 1999/07/26 23:33:01 mdw Exp $
+ *
+ * Generic endpoint abstraction
+ *
+ * (c) 1999 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------* 
+ *
+ * This file is part of the `fw' port forwarder.
+ *
+ * `fw' is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * `fw' is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with `fw'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*----- Revision history --------------------------------------------------* 
+ *
+ * $Log: endpt.h,v $
+ * Revision 1.1  1999/07/26 23:33:01  mdw
+ * Infrastructure for the new design.
+ *
+ */
+
+#ifndef ENDPT_H
+#define ENDPT_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/*----- Header files ------------------------------------------------------*/
+
+#ifndef REFFD_H
+#  include "reffd.h"
+#endif
+
+/*----- Data structures ---------------------------------------------------*/
+
+/* --- Basic endpoint structure --- */
+
+typedef struct endpt {
+  struct endpt_ops *ops;               /* Pointer to operations table */
+  struct endpt *other;                 /* Pointer to sibling endpoint */
+  unsigned f;                          /* Various flags */
+  struct tango *t;                     /* Private data structure */
+  reffd *in, *out;                     /* File descriptors */
+} endpt;
+
+/* --- Endpoint flags --- */
+
+#define EPF_PENDING 1u                 /* Endpoint creation in progress */
+#define EPF_FILE 2u                    /* Endpoint smells like a file */
+
+/* --- Endpoint operations table --- */
+
+typedef struct endpt_ops {
+
+  /* --- @attach@ --- *
+   *
+   * Arguments:        @endpt *e@ = pointer to endpoint to be attached
+   *           @reffd *in, *out@ = input and output file descriptors
+   *
+   * Returns:  ---
+   *
+   * Use:      Instructs a non-file endpoint to attach itself to a pair of
+   *           files.
+   */
+
+  void (*attach)(endpt */*e*/, reffd */*in*/, reffd */*out*/);
+
+  /* --- @wclose@ --- *
+   *
+   * Arguments:        @endpt *e@ = endpoint to be partially closed
+   *
+   * Returns:  ---
+   *
+   * Use:      Announces that the endpoint will not be written to any more.
+   */
+
+  void (*wclose)(endpt */*e*/);
+
+  /* --- @close@ --- *
+   *
+   * Arguments:        @endpt *e@ = endpoint to be closed
+   *
+   * Returns:  ---
+   *
+   * Use:      Completely closes an endpoint.  The endpoint's data may be
+   *           freed, although some endpoints may wish to delay freeing for
+   *           some reason.
+   */
+
+  void (*close)(endpt */*e*/);
+
+} endpt_ops;
+
+/*----- Functions provided ------------------------------------------------*/
+
+/* --- @endpt_kill@ --- *
+ *
+ * Arguments:  @endpt *a@ = an endpoint
+ *
+ * Returns:    ---
+ *
+ * Use:                Kills an endpoint.  If the endpoint is joined to another, the
+ *             other endpoint is also killed, as is the connection between
+ *             them (and that's the tricky bit).
+ */
+
+extern void endpt_kill(endpt */*a*/);
+
+/* --- @endpt_killall@ --- *
+ *
+ * Arguments:  ---
+ *
+ * Returns:    ---
+ *
+ * Use:                Destroys all current endpoint connections.  Used when
+ *             shutting down.
+ */
+
+extern void endpt_killall(void);
+
+/* --- @endpt_join@ --- *
+ *
+ * Arguments:  @endpt *a@ = pointer to first endpoint
+ *             @endpt *b@ = pointer to second endpoint
+ *
+ * Returns:    ---
+ *
+ * Use:                Joins two endpoints together.
+ */
+
+extern void endpt_join(endpt */*a*/, endpt */*b*/);
+
+/*----- That's all, folks -------------------------------------------------*/
+
+#ifdef __cplusplus
+  }
+#endif
+
+#endif
diff --git a/reffd.c b/reffd.c
new file mode 100644 (file)
index 0000000..823b102
--- /dev/null
+++ b/reffd.c
@@ -0,0 +1,111 @@
+/* -*-c-*-
+ *
+ * $Id: reffd.c,v 1.1 1999/07/26 23:33:01 mdw Exp $
+ *
+ * Reference counted file descriptors
+ *
+ * (c) 1999 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------* 
+ *
+ * This file is part of the `fw' port forwarder.
+ *
+ * `fw' is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * `fw' is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with `fw'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*----- Revision history --------------------------------------------------* 
+ *
+ * $Log: reffd.c,v $
+ * Revision 1.1  1999/07/26 23:33:01  mdw
+ * Infrastructure for the new design.
+ *
+ */
+
+/*----- Header files ------------------------------------------------------*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <mLib/sub.h>
+
+#include "reffd.h"
+
+/*----- Main code ---------------------------------------------------------*/
+
+/* --- @reffd_init@ --- *
+ *
+ * Arguments:  @int fd@ = file descriptor
+ *
+ * Returns:    Reference-counted file descriptor object.
+ *
+ * Use:                Creates a refcounted file descriptor.
+ */
+
+reffd *reffd_init(int fd)
+{
+  reffd *r = CREATE(reffd);
+  r->fd = fd;
+  r->ref = 1;
+  r->proc = 0;
+  r->p = 0;
+  return (r);
+}
+
+/* --- @reffd_handler@ --- *
+ *
+ * Arguments:  @reffd *r@ = pointer to reference counted filehandle
+ *             @void (*proc)(void *p)@ = procedure to call
+ *             @void *p@
+ *
+ * Returns:    ---
+ *
+ * Use:                Sets the reference counted file descriptor to call @proc@
+ *             when it is no longer required.
+ */
+
+void reffd_handler(reffd *r, void (*proc)(void *p), void *p)
+{
+  r->proc = proc;
+  r->p = p;
+}
+
+/* --- @reffd_inc@ --- *
+ *
+ * Arguments:  @reffd *r@ = pointer to reference counted filehandle
+ *
+ * Returns:    ---
+ *
+ * Use:                Increments the reference count for a file descriptor.
+ */
+
+void reffd_inc(reffd *r) { REFFD_INC(r); }
+
+/* --- @reffd_dec@ --- *
+ *
+ * Arguments:  @reffd *r@ = pointer to reference counted filehandle
+ *
+ * Returns:    ---
+ *
+ * Use:                Decrements the reference count for a file descriptor.
+ */
+
+void reffd_dec(reffd *r) { REFFD_DEC(r); }
+
+/*----- That's all, folks -------------------------------------------------*/
diff --git a/reffd.h b/reffd.h
new file mode 100644 (file)
index 0000000..cdefa85
--- /dev/null
+++ b/reffd.h
@@ -0,0 +1,128 @@
+/* -*-c-*-
+ *
+ * $Id: reffd.h,v 1.1 1999/07/26 23:33:01 mdw Exp $
+ *
+ * Reference counted file descriptors
+ *
+ * (c) 1999 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------* 
+ *
+ * This file is part of the `fw' port forwarder.
+ *
+ * `fw' is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * `fw' is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with `fw'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*----- Revision history --------------------------------------------------* 
+ *
+ * $Log: reffd.h,v $
+ * Revision 1.1  1999/07/26 23:33:01  mdw
+ * Infrastructure for the new design.
+ *
+ */
+
+#ifndef REFFD_H
+#define REFFD_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/*----- Header files ------------------------------------------------------*/
+
+#include <unistd.h>
+
+#include <mLib/sub.h>
+
+/*----- Data structures ---------------------------------------------------*/
+
+typedef struct reffd {
+  int fd;
+  unsigned ref;
+  void (*proc)(void */*p*/);
+  void *p;
+} reffd;
+
+/*----- Functions provided ------------------------------------------------*/
+
+/* --- @reffd_init@ --- *
+ *
+ * Arguments:  @int fd@ = file descriptor
+ *
+ * Returns:    Reference-counted file descriptor object.
+ *
+ * Use:                Creates a refcounted file descriptor.
+ */
+
+extern reffd *reffd_init(int /*fd*/);
+
+/* --- @reffd_handler@ --- *
+ *
+ * Arguments:  @reffd *r@ = pointer to reference counted filehandle
+ *             @void (*proc)(void *p)@ = procedure to call
+ *             @void *p@
+ *
+ * Returns:    ---
+ *
+ * Use:                Sets the reference counted file descriptor to call @proc@
+ *             when it is no longer required.
+ */
+
+extern void reffd_handler(reffd */*r*/, void (*/*proc*/)(void */*p*/),
+                         void */*p*/);
+
+/* --- @reffd_inc@ --- *
+ *
+ * Arguments:  @reffd *r@ = pointer to reference counted filehandle
+ *
+ * Returns:    ---
+ *
+ * Use:                Increments the reference count for a file descriptor.
+ */
+
+#define REFFD_INC(r) do { (r)->ref++; } while (0)
+
+extern void reffd_inc(reffd */*r*/);
+
+/* --- @reffd_dec@ --- *
+ *
+ * Arguments:  @reffd *r@ = pointer to reference counted filehandle
+ *
+ * Returns:    ---
+ *
+ * Use:                Decrements the reference count for a file descriptor.
+ */
+
+#define REFFD_DEC(r) do {                                              \
+  reffd *_r = (r);                                                     \
+  _r->ref--;                                                           \
+  if (_r->ref == 0) {                                                  \
+    close(_r->fd);                                                     \
+    if (_r->proc)                                                      \
+      _r->proc(_r->p);                                                 \
+    DESTROY(_r);                                                       \
+  }                                                                    \
+} while (0)
+
+extern void reffd_dec(reffd */*r*/);
+
+/*----- That's all, folks -------------------------------------------------*/
+
+#ifdef __cplusplus
+  }
+#endif
+
+#endif
diff --git a/source.c b/source.c
new file mode 100644 (file)
index 0000000..5973547
--- /dev/null
+++ b/source.c
@@ -0,0 +1,110 @@
+/* -*-c-*-
+ *
+ * $Id: source.c,v 1.1 1999/07/26 23:33:01 mdw Exp $
+ *
+ * Standard routines for forwarding sources
+ *
+ * (c) 1999 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------* 
+ *
+ * This file is part of the `fw' port forwarder.
+ *
+ * `fw' is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * `fw' is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with `fw'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*----- Revision history --------------------------------------------------* 
+ *
+ * $Log: source.c,v $
+ * Revision 1.1  1999/07/26 23:33:01  mdw
+ * Infrastructure for the new design.
+ *
+ */
+
+/*----- Header files ------------------------------------------------------*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "source.h"
+
+/*----- Static variables --------------------------------------------------*/
+
+static source *sources = 0;
+
+/*----- Main code ---------------------------------------------------------*/
+
+/* --- @source_add@ --- *
+ *
+ * Arguments:  @source *s@ = pointer to a source
+ *
+ * Returns:    ---
+ *
+ * Use:                Adds a source to the master list.  Only do this for passive
+ *             sources (e.g., listening sockets), not active sources (e.g.,
+ *             executable programs).
+ */
+
+void source_add(source *s)
+{
+  s->next = sources;
+  s->prev = 0;
+  if (sources)
+    sources->prev = s;
+  sources = s;
+}
+
+/* --- @source_remove@ --- *
+ *
+ * Arguments:  @source *s@ = pointer to a source
+ *
+ * Returns:    ---
+ *
+ * Use:                Removes a source from the master list.
+ */
+
+void source_remove(source *s)
+{
+  if (s->next)
+    s->next->prev = s->prev;
+  if (s->prev)
+    s->prev->next = s->next;
+  else
+    sources = s->next;
+}
+
+/* --- @source_killall@ --- *
+ *
+ * Arguments:  ---
+ *
+ * Returns:    ---
+ *
+ * Use:                Frees all sources.
+ */
+
+void source_killall(void)
+{
+  source *s = sources;
+  while (s) {
+    source *ss = s;
+    s = s->next;
+    ss->ops->destroy(ss);
+  }
+  sources = 0;
+}
+
+/*----- That's all, folks -------------------------------------------------*/
diff --git a/source.h b/source.h
new file mode 100644 (file)
index 0000000..9a066f0
--- /dev/null
+++ b/source.h
@@ -0,0 +1,166 @@
+/* -*-c-*-
+ *
+ * $Id: source.h,v 1.1 1999/07/26 23:33:01 mdw Exp $
+ *
+ * Description of forwarding sources
+ *
+ * (c) 1999 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------* 
+ *
+ * This file is part of the `fw' port forwarder.
+ *
+ * `fw' is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * `fw' is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with `fw'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*----- Revision history --------------------------------------------------* 
+ *
+ * $Log: source.h,v $
+ * Revision 1.1  1999/07/26 23:33:01  mdw
+ * Infrastructure for the new design.
+ *
+ */
+
+#ifndef SOURCE_H
+#define SOURCE_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/*----- Header files ------------------------------------------------------*/
+
+#include <stdio.h>
+
+#ifndef SCAN_H
+#  include "scan.h"
+#endif
+
+#ifndef TARGET_H
+#  include "target.h"
+#endif
+
+/*----- Data structures ---------------------------------------------------*/
+
+/* --- A basic source object --- */
+
+typedef struct source {
+  struct source *next, *prev;
+  struct source_ops *ops;
+  char *desc;
+} source;
+
+/* --- Forwarding source operations --- */
+
+typedef struct source_ops {
+  const char *name;                    /* Name of this source */
+
+  /* --- @option@ --- *
+   *
+   * Arguments:        @scanner *sc@ = scanner to read from
+   *           @source *s@ = pointer to source object, or zero if global
+   *
+   * Returns:  Nonzero to claim the option.
+   *
+   * Use:      Handles an option string from the configuration file.
+   */
+
+  int (*option)(source */*s*/, scanner */*sc*/);
+
+  /* --- @read@ --- *
+   *
+   * Arguments:        @scanner *sc@ = pointer to scanner to read from
+   *
+   * Returns:  Pointer to a source object to claim, null to reject.
+   *
+   * Use:      Parses a source description from the configuration file.
+   *           Only the socket source is allowed to omit the prefix on a
+   *           source specification.
+   */
+
+  source *(*read)(scanner */*sc*/);
+
+  /* --- @attach@ --- *
+   *
+   * Arguments:        @source *s@ = pointer to source
+   *           @scanner *sc@ = scanner (for error reporting)
+   *           @target *t@ = pointer to target to attach
+   *
+   * Returns:  ---
+   *
+   * Use:      Attaches a target to a source.
+   */
+
+  void (*attach)(source */*s*/, scanner */*sc*/, target */*t*/);
+
+  /* --- @destroy@ --- *
+   *
+   * Arguments:        @source *s@ = pointer to source
+   *
+   * Returns:  ---
+   *
+   * Use:      Destroys a source.  Used when closing the system down, for
+   *           example as a result of a signal.
+   */
+
+  void (*destroy)(source */*s*/);
+
+} source_ops;
+
+/*----- Functions provided ------------------------------------------------*/
+
+/* --- @source_add@ --- *
+ *
+ * Arguments:  @source *s@ = pointer to a source
+ *
+ * Returns:    ---
+ *
+ * Use:                Adds a source to the master list.  Only do this for passive
+ *             sources (e.g., listening sockets), not active sources (e.g.,
+ *             executable programs).
+ */
+
+extern void source_add(source */*s*/);
+
+/* --- @source_remove@ --- *
+ *
+ * Arguments:  @source *s@ = pointer to a source
+ *
+ * Returns:    ---
+ *
+ * Use:                Removes a source from the master list.
+ */
+
+extern void source_remove(source */*s*/);
+
+/* --- @source_killall@ --- *
+ *
+ * Arguments:  ---
+ *
+ * Returns:    ---
+ *
+ * Use:                Frees all sources.
+ */
+
+extern void source_killall(void);
+
+/*----- That's all, folks -------------------------------------------------*/
+
+#ifdef __cplusplus
+  }
+#endif
+
+#endif
diff --git a/target.h b/target.h
new file mode 100644 (file)
index 0000000..5077c39
--- /dev/null
+++ b/target.h
@@ -0,0 +1,126 @@
+/* -*-c-*-
+ *
+ * $Id: target.h,v 1.1 1999/07/26 23:33:01 mdw Exp $
+ *
+ * Description of forwarding targets
+ *
+ * (c) 1999 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------* 
+ *
+ * This file is part of the `fw' port forwarder.
+ *
+ * `fw' is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * `fw' is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with `fw'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*----- Revision history --------------------------------------------------* 
+ *
+ * $Log: target.h,v $
+ * Revision 1.1  1999/07/26 23:33:01  mdw
+ * Infrastructure for the new design.
+ *
+ */
+
+#ifndef TARGET_H
+#define TARGET_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/*----- Header files ------------------------------------------------------*/
+
+#include <stdio.h>
+
+#ifndef ENDPT_H
+#  include "endpt.h"
+#endif
+
+#ifndef SCAN_H
+#  include "scan.h"
+#endif
+
+/*----- Data structures ---------------------------------------------------*/
+
+/* --- A basic target object --- */
+
+typedef struct target {
+  struct target_ops *ops;
+  char *desc;
+} target;
+
+/* --- Forwarding target operations --- */
+
+typedef struct target_ops {
+  const char *name;                    /* Name of this target */
+
+  /* --- @option@ --- *
+   *
+   * Arguments:        @scanner *sc@ = scanner to read from
+   *           @target *t@ = pointer to target object, or zero if global
+   *
+   * Returns:  Nonzero to claim the option.
+   *
+   * Use:      Handles an option string from the configuration file.
+   */
+
+  int (*option)(target */*t*/, scanner */*sc*/);
+
+  /* --- @read@ --- *
+   *
+   * Arguments:        @scanner *sc@ = pointer to scanner to read from
+   *
+   * Returns:  Pointer to a target object to claim, null to reject.
+   *
+   * Use:      Parses a target description from the configuration file.
+   *           Only the socket target is allowed to omit the prefix on a
+   *           target specification.
+   */
+
+  target *(*read)(scanner */*sc*/);
+
+  /* --- @create@ --- *
+   *
+   * Arguments:        @target *t@ = pointer to target
+   *           @const char *desc@ = description of connection
+   *
+   * Returns:  Pointer to a created endpoint.
+   *
+   * Use:      Generates a target endpoint for communication.
+   */
+
+  endpt *(*create)(target */*t*/, const char */*desc*/);
+
+  /* --- @destroy@ --- *
+   *
+   * Arguments:        @target *t@ = pointer to target
+   *
+   * Returns:  ---
+   *
+   * Use:      Destroys a target.
+   */
+
+  void (*destroy)(target */*t*/);
+
+} target_ops;
+
+/*----- That's all, folks -------------------------------------------------*/
+
+#ifdef __cplusplus
+  }
+#endif
+
+#endif