chiark / gitweb /
b5bafcdabd42e146565beb74f61074b2245edc73
[sympathy.git] / apps / clients.c
1 /*
2  * clients.c:
3  *
4  * Copyright (c) 2008 James McKenzie <james@fishsoup.dhs.org>,
5  * All rights reserved.
6  *
7  */
8
9 static char rcsid[] = "$Id$";
10
11 /*
12  * $Log$
13  * Revision 1.3  2008/02/14 02:46:44  james
14  * *** empty log message ***
15  *
16  * Revision 1.2  2008/02/14 00:57:58  james
17  * *** empty log message ***
18  *
19  * Revision 1.1  2008/02/13 18:05:06  james
20  * *** empty log message ***
21  *
22  */
23
24 #include <sympathy.h>
25 #include "clients.h"
26
27 static void
28 client_msg (IPC_Msg * m, Context * c)
29 {
30   switch (m->hdr.type)
31     {
32
33     case IPC_MSG_TYPE_NOOP:
34       break;
35     case IPC_MSG_TYPE_DEBUG:
36       fprintf (stderr, "%p [%d] %s\n", m, m->hdr.size, m->debug.msg);
37       break;
38     case IPC_MSG_TYPE_KEY:
39       vt102_send (c, m->key.key);
40       break;
41     default:
42       fprintf (stderr, "Unhandeled message type %d\n", m->hdr.type);
43     }
44 }
45
46 void
47 client_free (Client * c)
48 {
49   if (c->s)
50     socket_free (c->s);
51
52   free (c);
53   fprintf (stderr, "Client at %p freed\n", c);
54 }
55
56 Client *
57 clients_new_client (Clients * cs, Socket * s, Context * ctx)
58 {
59   Client *c;
60
61   c = (Client *) malloc (sizeof (Client));
62
63   c->dead = 0;
64   c->s = s;
65   c->next = cs->head;
66
67   cs->head = c;
68   cs->n++;
69
70   fprintf (stderr, "Client at %p created\n", c);
71
72
73   if (ipc_msg_send_debug (s, "new_client"))
74     c->dead++;
75
76   return c;
77 }
78
79 void
80 clients_reap (Clients * cs)
81 {
82   Client **p, *c;
83
84
85   for (p = &cs->head; *p;)
86     {
87       Client *c = *p;
88
89       if (c->dead)
90         {
91           *p = c->next;
92           client_free (c);
93           cs->n--;
94         }
95       else
96         {
97           p = &(c->next);
98         }
99     }
100 }
101
102 Clients *
103 clients_new (void)
104 {
105   Clients *ret = (Clients *) malloc (sizeof (Clients));
106
107   ret->n = 0;
108   ret->head = NULL;
109
110   return ret;
111 }
112
113 void
114 clients_pre_select (Clients * cs, fd_set * rfds, fd_set * wfds)
115 {
116   Client *c;
117
118   for (c = cs->head; c; c = c->next)
119     {
120       socket_pre_select (c->s, rfds, wfds);
121     }
122 }
123
124 void
125 clients_post_select (Clients * cs, Context * ctx, fd_set * rfds,
126                      fd_set * wfds)
127 {
128   Client *c;
129   int deaded = 0;
130
131   for (c = cs->head; c; c = c->next)
132     {
133       if (socket_post_select (c->s, rfds, wfds))
134         {
135           c->dead++;
136           deaded++;
137         }
138
139       if (c->s->msg)
140         {
141           client_msg (c->s->msg, ctx);
142           socket_consume_msg (c->s);
143         }
144
145     }
146
147   if (deaded)
148     clients_reap (cs);
149 }
150
151 int
152 clients_output (Clients * cs, void *buf, int len)
153 {
154   char mbuf[IPC_MAX_BUF + sizeof (IPC_Msg_term)];
155   IPC_Msg_term *m = (IPC_Msg_term *) mbuf;
156
157   Client *c;
158
159   if (!len)
160     return;
161   if (len > IPC_MAX_BUF)
162     len = IPC_MAX_BUF;
163
164   m->size = len + sizeof (IPC_Msg_term);
165   m->type = IPC_MSG_TYPE_TERM;
166   m->len = len;
167   memcpy (m->term, buf, len);
168
169   for (c = cs->head; c; c = c->next)
170     {
171       if (!c->dead)
172         if (ipc_msg_send (c->s, (IPC_Msg *) m))
173           c->dead++;
174     }
175
176
177   return len;
178 }
179
180 void
181 clients_shutdown (Clients * cs)
182 {
183   Client *c;
184
185   for (c = cs->head; c; c = c->next)
186     {
187       c->dead++;
188     }
189
190
191   clients_reap (cs);
192 }