Version 2.2.
[pwmd.git] / src / status.c
blob67e53aba64ac817b8eacd470084c61029a0fd088
1 /* vim:tw=78:ts=8:sw=4:set ft=c: */
2 /*
3 Copyright (C) 2006-2009 Ben Kibbey <bjk@luxsci.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02110-1301 USA
19 #include <glib.h>
20 #include "common.h"
21 #include "lock.h"
22 #include "misc.h"
23 #include "status.h"
24 #include "pwmd_error.h"
26 static void *write_status_cb(void *arg)
28 struct assuan_cmd_s *data = arg;
29 gpg_error_t rc;
30 gint old;
32 pth_cancel_state(PTH_CANCEL_ENABLE|PTH_CANCEL_ASYNCHRONOUS, &old);
33 rc = assuan_write_status(data->ctx, data->line, data->line2);
34 pth_cancel_state(old, NULL);
35 pth_exit((void *)rc);
36 return NULL;
39 gpg_error_t send_status(assuan_context_t ctx, status_msg_t which,
40 const gchar *fmt, ...)
42 const gchar *line = NULL;
43 gchar buf[ASSUAN_LINELENGTH+1];
44 gchar *status = NULL;
45 va_list ap;
46 gpg_error_t rc;
47 struct assuan_cmd_s data;
49 if (fmt) {
50 va_start(ap, fmt);
51 g_vsnprintf(buf, sizeof(buf), fmt, ap);
52 va_end(ap);
53 line = buf;
56 switch (which) {
57 case STATUS_XFER:
58 status = "XFER";
59 break;
60 case STATUS_CACHE:
61 CACHE_LOCK(ctx);
62 line = print_fmt(buf, sizeof(buf), "%i", cache_file_count());
63 CACHE_UNLOCK;
64 status = "CACHE";
65 break;
66 case STATUS_CLIENTS:
67 MUTEX_LOCK(&cn_mutex);
68 line = print_fmt(buf, sizeof(buf), "%i", g_slist_length(cn_thread_list));
69 MUTEX_UNLOCK(&cn_mutex);
70 status = "CLIENTS";
71 break;
72 case STATUS_CONFIG:
73 status = "CONFIG";
74 break;
75 case STATUS_KEEPALIVE:
76 status = "KEEPALIVE";
77 break;
78 case STATUS_LOCKED:
79 status = "LOCKED";
80 line = N_("Waiting for lock");
81 break;
82 case STATUS_ENCRYPT:
83 status = "ENCRYPT";
84 break;
85 case STATUS_DECRYPT:
86 status = "DECRYPT";
87 break;
88 case STATUS_DECOMPRESS:
89 status = "DECOMPRESS";
90 break;
91 case STATUS_COMPRESS:
92 status = "COMPRESS";
93 break;
96 if (!ctx) {
97 log_write("%s %s", status, line);
98 return 0;
101 data.ctx = ctx;
102 data.line = status;
103 data.line2 = line;
104 rc = do_assuan_command(ctx, write_status_cb, &data);
105 return rc;
108 void *client_msg_thread(void *arg)
110 struct client_thread_s *thd = arg;
111 pth_attr_t attr = pth_attr_of(pth_self());
113 pth_attr_set(attr, PTH_ATTR_NAME, __FUNCTION__);
114 pth_attr_destroy(attr);
116 for (;;) {
117 pth_event_t ev = pth_event(PTH_EVENT_MSG, thd->mp);
119 pth_cleanup_push(cleanup_ev_cb, ev);
120 pth_wait(ev);
121 MUTEX_LOCK(&thd->mp_mutex);
123 do {
124 pth_message_t *msg = pth_msgport_get(thd->mp);
125 status_msg_t *s = msg->m_data;
126 gpg_error_t rc;
128 MUTEX_UNLOCK(&thd->mp_mutex);
129 g_free(msg);
130 pth_cleanup_push(g_free, s);
131 rc = send_status(thd->cl->ctx, *s, NULL);
132 pth_cleanup_pop(1);
134 if (rc) {
135 log_write("%s(%i): %s", __FILE__, __LINE__, pwmd_strerror(rc));
136 pth_cancel(thd->tid);
137 break;
140 MUTEX_LOCK(&thd->mp_mutex);
141 } while (pth_msgport_pending(thd->mp));
143 MUTEX_UNLOCK(&thd->mp_mutex);
144 pth_cleanup_pop(1);
147 return NULL;
150 void send_status_all(status_msg_t which)
152 guint i, t;
154 MUTEX_LOCK(&cn_mutex);
155 pth_cleanup_push(cleanup_mutex_cb, &cn_mutex);
157 for (t = g_slist_length(cn_thread_list), i = 0; i < t; i++) {
158 struct client_thread_s *cn = g_slist_nth_data(cn_thread_list, i);
159 pth_message_t *msg;
160 status_msg_t *m;
162 msg = g_malloc0(sizeof(pth_message_t));
164 if (!msg) {
165 log_write("%s(%i): %s", __FILE__, __LINE__, strerror(ENOMEM));
166 pth_cancel(cn->tid);
167 continue;
170 m = g_malloc(sizeof(status_msg_t));
172 if (!m) {
173 g_free(msg);
174 log_write("%s(%i): %s", __FILE__, __LINE__, strerror(ENOMEM));
175 pth_cancel(cn->tid);
176 continue;
179 *m = which;
180 msg->m_data = m;
182 if (cn->mp) {
183 MUTEX_LOCK(&cn->mp_mutex);
184 pth_msgport_put(cn->mp, msg);
185 MUTEX_UNLOCK(&cn->mp_mutex);
189 pth_cleanup_pop(1);