/* * clients.c: * * Copyright (c) 2008 James McKenzie , * All rights reserved. * */ static char rcsid[] = "$Id$"; /* * $Log$ * Revision 1.26 2012/06/22 10:22:24 james * *** empty log message *** * * Revision 1.25 2008/05/09 12:35:57 james * *** empty log message *** * * Revision 1.24 2008/03/11 17:56:04 james * *** empty log message *** * * Revision 1.23 2008/03/11 17:47:24 james * *** empty log message *** * * Revision 1.22 2008/03/07 14:16:44 james * *** empty log message *** * * Revision 1.21 2008/03/07 14:13:40 james * *** empty log message *** * * Revision 1.20 2008/03/07 13:56:39 james * *** empty log message *** * * Revision 1.19 2008/03/07 13:16:02 james * *** empty log message *** * * Revision 1.18 2008/03/03 18:16:16 james * *** empty log message *** * * Revision 1.17 2008/03/03 18:15:19 james * *** empty log message *** * * Revision 1.16 2008/03/03 06:04:42 james * *** empty log message *** * * Revision 1.15 2008/03/02 10:27:24 james * *** empty log message *** * * 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 #include #include #include #include #include #include "clients.h" static inline char * stop_wno_unused_on_rcsid (void) { return rcsid; } void client_initialize (Client * c, Context * ctx) { send_history (ctx->h, c); send_vt102 (ctx->v, c); c->initialized = 1; } void client_execute_message (Client * client, IPC_Msg * m, Context * c) { switch (m->hdr.type) { case IPC_MSG_TYPE_NOOP: break; case IPC_MSG_TYPE_DEBUG: log_f (c->l, "", 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, "", m->setbaud.baud); break; case IPC_MSG_TYPE_SENDBREAK: log_f (c->l, ""); tty_send_break (c->t); break; case IPC_MSG_TYPE_SETFLOW: log_f (c->l, "", m->setflow.flow ? "on" : "off"); 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: log_f (c->l, ""); 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; case IPC_MSG_TYPE_INITIALIZE: client_initialize (client, c); break; case IPC_MSG_TYPE_KILLME: client->dead++; break; default: log_f (c->l, "", m->hdr.type); } } 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 } Client * clients_new_client (Clients * cs, Socket * s, Context * ctx) { Client *c; c = (Client *) xmalloc (sizeof (Client)); c->initialized = 0; c->dead = 0; c->s = s; c->next = cs->head; cs->head = c; cs->n++; #if 0 fprintf (stderr, "Client at %p created\n", c); #endif log_f (ctx->l, "", c, cs->n); if (ipc_msg_send_debug (s, "new_client")) c->dead++; return c; } void clients_reap (Clients * cs, Context * ctx) { Client **p; for (p = &cs->head; *p;) { Client *c = *p; if (c->dead) { *p = c->next; client_free (c); cs->n--; log_f (ctx->l, "", c, cs->n); } else { p = &(c->next); } } } Clients * clients_new (void) { Clients *ret = (Clients *) xmalloc (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); } } void clients_post_select (Clients * cs, Context * ctx, fd_set * rfds, fd_set * wfds) { Client *c; int deaded = 0; for (c = cs->head; c; c = c->next) { if (socket_post_select (c->s, rfds, wfds)) { c->dead++; deaded++; } if (c->s->msg) { client_execute_message (c, c->s->msg, ctx); socket_consume_msg (c->s); if (c->dead) deaded++; } } if (deaded) clients_reap (cs, ctx); } void clients_shutdown (Clients * cs, Context * ctx) { Client *c; for (c = cs->head; c; c = c->next) { c->dead++; } clients_reap (cs, ctx); } 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 -1; len = strlen (msg) + 1; if (!len) return -1; 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 && c->initialized) if (ipc_msg_send (c->s, (IPC_Msg *) m)) c->dead++; } return len; } 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 -1; 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 && c->initialized) 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++; }