/*
* $Log$
+ * Revision 1.14 2008/02/28 16:57:51 james
+ * *** empty log message ***
+ *
+ * Revision 1.13 2008/02/28 16:37:16 james
+ * *** empty log message ***
+ *
+ * Revision 1.12 2008/02/28 12:12:24 james
+ * *** empty log message ***
+ *
+ * Revision 1.11 2008/02/23 11:48:51 james
+ * *** empty log message ***
+ *
+ * Revision 1.10 2008/02/22 17:06:59 james
+ * *** empty log message ***
+ *
+ * Revision 1.9 2008/02/20 18:49:11 staffcvs
+ * *** empty log message ***
+ *
+ * Revision 1.8 2008/02/20 18:31:44 james
+ * *** empty log message ***
+ *
+ * Revision 1.7 2008/02/15 23:52:12 james
+ * *** empty log message ***
+ *
+ * Revision 1.6 2008/02/15 03:32:07 james
+ * *** empty log message ***
+ *
+ * Revision 1.5 2008/02/14 10:34:47 james
+ * *** empty log message ***
+ *
+ * Revision 1.4 2008/02/14 10:34:30 james
+ * *** empty log message ***
+ *
+ * Revision 1.3 2008/02/14 02:46:44 james
+ * *** empty log message ***
+ *
+ * Revision 1.2 2008/02/14 00:57:58 james
+ * *** empty log message ***
+ *
* Revision 1.1 2008/02/13 18:05:06 james
* *** empty log message ***
*
*/
#include <sympathy.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <malloc.h>
#include "clients.h"
+void
+client_msg (IPC_Msg * m, Context * c)
+{
+ switch (m->hdr.type)
+ {
+
+ case IPC_MSG_TYPE_NOOP:
+ break;
+ case IPC_MSG_TYPE_DEBUG:
+ fprintf (stderr, "%p [%d] %s\n", m, m->hdr.size, m->debug.msg);
+ break;
+ case IPC_MSG_TYPE_KEY:
+ vt102_send (c, m->key.key);
+ break;
+ case IPC_MSG_TYPE_SETBAUD:
+ tty_set_baud (c->t, m->setbaud.baud);
+ tty_parse_reset (c);
+
+ log_f (c->l, "<baud changed to %d>", m->setbaud.baud);
+ break;
+ case IPC_MSG_TYPE_SENDBREAK:
+ tty_send_break (c->t);
+ break;
+ case IPC_MSG_TYPE_SETFLOW:
+ tty_set_flow (c->t, m->setflow.flow);
+ break;
+ case IPC_MSG_TYPE_SETANSI:
+ vt102_set_ansi (c->v, m->setansi.ansi);
+ break;
+ case IPC_MSG_TYPE_HANGUP:
+ tty_hangup (c->t);
+ break;
+ case IPC_MSG_TYPE_SETSIZE:
+ vt102_resize (c, m->setsize.winsize);
+ break;
+ case IPC_MSG_TYPE_RESET:
+ vt102_reset (c);
+ break;
+ default:
+ fprintf (stderr, "Unhandeled message type %d\n", m->hdr.type);
+ }
+}
-void clients_output (Clients *c, void *_buf, int len)
+void
+client_free (Client * c)
{
+ if (c->s)
+ socket_free (c->s);
+ free (c);
+#if 0
+ fprintf (stderr, "Client at %p freed\n", c);
+#endif
}
-Clients *clients_new(void)
+Client *
+clients_new_client (Clients * cs, Socket * s, Context * ctx)
{
+ Client *c;
+ c = (Client *) malloc (sizeof (Client));
+ c->dead = 0;
+ c->s = s;
+ c->next = cs->head;
-return NULL;
+ cs->head = c;
+ cs->n++;
+
+#if 0
+ fprintf (stderr, "Client at %p created\n", c);
+#endif
+
+
+ if (ipc_msg_send_debug (s, "new_client"))
+ c->dead++;
+
+ return c;
}
-void clients_pre_select (Clients *c, fd_set *rfds, fd_set *wfds)
+void
+clients_reap (Clients * cs)
{
+ Client **p, *c;
+
+ for (p = &cs->head; *p;)
+ {
+ Client *c = *p;
+ if (c->dead)
+ {
+ *p = c->next;
+ client_free (c);
+ cs->n--;
+ }
+ else
+ {
+ p = &(c->next);
+ }
+ }
}
-void clients_post_select(Clients *c,Context *ctx, fd_set *rfds, fd_set *wfds)
+Clients *
+clients_new (void)
{
+ Clients *ret = (Clients *) malloc (sizeof (Clients));
+ ret->n = 0;
+ ret->head = NULL;
+
+ return ret;
+}
+
+void
+clients_pre_select (Clients * cs, fd_set * rfds, fd_set * wfds)
+{
+ Client *c;
+ for (c = cs->head; c; c = c->next)
+ {
+ socket_pre_select (c->s, rfds, wfds);
+ }
}
-Client * clients_new_client(Clients *c,Socket *s,Context *ctx)
+void
+clients_post_select (Clients * cs, Context * ctx, fd_set * rfds,
+ fd_set * wfds)
{
+ Client *c;
+ int deaded = 0;
-ipc_msg_send_debug(s,"fishsoup");
-socket_free(s);
+ for (c = cs->head; c; c = c->next)
+ {
+ if (socket_post_select (c->s, rfds, wfds))
+ {
+ c->dead++;
+ deaded++;
+ }
-return NULL;
+ if (c->s->msg)
+ {
+ client_msg (c->s->msg, ctx);
+ socket_consume_msg (c->s);
+ }
+
+ }
+
+ if (deaded)
+ clients_reap (cs);
+}
+
+
+void
+clients_shutdown (Clients * cs)
+{
+ Client *c;
+
+ for (c = cs->head; c; c = c->next)
+ {
+ c->dead++;
+ }
+
+
+ clients_reap (cs);
+}
+
+
+
+
+
+
+int
+send_status (Clients * cs, char *msg)
+{
+ char mbuf[IPC_MAX_BUF + sizeof (IPC_Msg_status)];
+ IPC_Msg_status *m = (IPC_Msg_status *) mbuf;
+ int len;
+
+ Client *c;
+
+ if (!msg)
+ return;
+ len = strlen (msg) + 1;
+
+ if (!len)
+ return;
+ if (len > IPC_MAX_BUF)
+ len = IPC_MAX_BUF;
+
+ m->size = len + sizeof (IPC_Msg_status);
+ m->type = IPC_MSG_TYPE_STATUS;
+ strncpy (m->status, msg, IPC_MAX_BUF);
+ m->status[IPC_MAX_BUF - 1] = 0;
+
+ for (c = cs->head; c; c = c->next)
+ {
+ if (!c->dead)
+ if (ipc_msg_send (c->s, (IPC_Msg *) m))
+ c->dead++;
+ }
+
+ return len;
}
-void clients_shutdown(Clients *c)
+
+int
+send_output (Clients * cs, void *buf, int len)
{
+ char mbuf[IPC_MAX_BUF + sizeof (IPC_Msg_term)];
+ IPC_Msg_term *m = (IPC_Msg_term *) mbuf;
+ Client *c;
+ if (!len)
+ return;
+ if (len > IPC_MAX_BUF)
+ len = IPC_MAX_BUF;
+
+ m->size = len + sizeof (IPC_Msg_term);
+ m->type = IPC_MSG_TYPE_TERM;
+ m->len = len;
+ memcpy (m->term, buf, len);
+
+ for (c = cs->head; c; c = c->next)
+ {
+ if (!c->dead)
+ if (ipc_msg_send (c->s, (IPC_Msg *) m))
+ c->dead++;
+ }
+
+
+ return len;
+}
+
+void
+send_history (History * h, Client * c)
+{
+ int rptr = h->wptr;
+
+ HISTORY_INC (h, rptr);
+
+ HISTORY_INC (h, rptr);
+ while (rptr != h->wptr)
+ {
+ History_ent *l = &h->lines[rptr];
+ if (l->valid)
+ {
+
+ if (ipc_msg_send_history (c->s, l))
+ c->dead++;
+
+ }
+ HISTORY_INC (h, rptr);
+ }
+}
+
+void
+send_vt102 (VT102 * v, Client * c)
+{
+ if (ipc_msg_send_vt102 (c->s, v))
+ c->dead++;
}