Cleanup of command_startup().
[pwmd.git] / src / status.c
blob58a4c7ba5559b2f261466c76d0598bb48cc212f7
1 /* vim:tw=78:ts=8:sw=4:set ft=c: */
2 /*
3 Copyright (C) 2006-2010 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 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
23 #include <glib.h>
24 #include "common.h"
25 #include "mutex.h"
26 #include "misc.h"
27 #include "status.h"
28 #include "pwmd_error.h"
30 static void *write_status_cb(void *arg)
32 struct assuan_cmd_s *data = arg;
33 gpg_error_t *rc;
34 gint old;
36 pth_cancel_state(PTH_CANCEL_ENABLE|PTH_CANCEL_ASYNCHRONOUS, &old);
37 rc = g_malloc(sizeof(gpg_error_t));
38 *rc = assuan_write_status(data->ctx, data->line, data->line2);
39 pth_cancel_state(old, NULL);
40 pth_exit(rc);
41 return NULL;
44 gpg_error_t send_status(assuan_context_t ctx, status_msg_t which,
45 const gchar *fmt, ...)
47 const gchar *line = NULL;
48 gchar buf[ASSUAN_LINELENGTH+1];
49 gchar *status = NULL;
50 va_list ap;
51 gpg_error_t rc;
52 struct assuan_cmd_s data;
54 if (fmt) {
55 va_start(ap, fmt);
56 g_vsnprintf(buf, sizeof(buf), fmt, ap);
57 va_end(ap);
58 line = buf;
61 switch (which) {
62 case STATUS_XFER:
63 status = "XFER";
64 break;
65 case STATUS_CACHE:
66 CACHE_LOCK(ctx);
67 line = print_fmt(buf, sizeof(buf), "%i", cache_file_count());
68 CACHE_UNLOCK;
69 status = "CACHE";
70 break;
71 case STATUS_CLIENTS:
72 MUTEX_LOCK(&cn_mutex);
73 line = print_fmt(buf, sizeof(buf), "%i", g_slist_length(cn_thread_list));
74 MUTEX_UNLOCK(&cn_mutex);
75 status = "CLIENTS";
76 break;
77 case STATUS_CONFIG:
78 status = "CONFIG";
79 break;
80 case STATUS_KEEPALIVE:
81 status = "KEEPALIVE";
82 break;
83 case STATUS_LOCKED:
84 status = "LOCKED";
85 line = N_("Waiting for lock");
86 break;
87 case STATUS_ENCRYPT:
88 status = "ENCRYPT";
89 break;
90 case STATUS_DECRYPT:
91 status = "DECRYPT";
92 break;
93 case STATUS_DECOMPRESS:
94 status = "DECOMPRESS";
95 break;
96 case STATUS_COMPRESS:
97 status = "COMPRESS";
98 break;
101 if (!ctx) {
102 log_write("%s %s", status, line);
103 return 0;
106 data.ctx = ctx;
107 data.line = status;
108 data.line2 = line;
109 rc = do_assuan_command(ctx, write_status_cb, &data);
110 return rc;
113 void *client_msg_thread(void *arg)
115 struct client_thread_s *thd = arg;
116 pth_attr_t attr = pth_attr_of(pth_self());
118 pth_attr_set(attr, PTH_ATTR_NAME, __FUNCTION__);
119 pth_attr_destroy(attr);
121 for (;;) {
122 pth_event_t ev = pth_event(PTH_EVENT_MSG, thd->mp);
124 pth_cleanup_push(cleanup_ev_cb, ev);
125 pth_wait(ev);
126 MUTEX_LOCK(&thd->mp_mutex);
128 do {
129 pth_message_t *msg = pth_msgport_get(thd->mp);
130 status_msg_t *s = msg->m_data;
131 gpg_error_t rc;
133 MUTEX_UNLOCK(&thd->mp_mutex);
134 g_free(msg);
135 pth_cleanup_push(g_free, s);
136 rc = send_status(thd->cl->ctx, *s, NULL);
137 pth_cleanup_pop(1);
139 if (rc) {
140 log_write("%s(%i): %s", __FILE__, __LINE__, pwmd_strerror(rc));
141 pth_cancel(thd->tid);
142 break;
145 MUTEX_LOCK(&thd->mp_mutex);
146 } while (pth_msgport_pending(thd->mp));
148 MUTEX_UNLOCK(&thd->mp_mutex);
149 pth_cleanup_pop(1);
152 return NULL;
155 void send_status_all(status_msg_t which)
157 guint i, t;
159 MUTEX_LOCK(&cn_mutex);
160 pth_cleanup_push(cleanup_mutex_cb, &cn_mutex);
162 for (t = g_slist_length(cn_thread_list), i = 0; i < t; i++) {
163 struct client_thread_s *cn = g_slist_nth_data(cn_thread_list, i);
164 pth_message_t *msg;
165 status_msg_t *m;
167 msg = g_malloc0(sizeof(pth_message_t));
169 if (!msg) {
170 log_write("%s(%i): %s", __FILE__, __LINE__, pwmd_strerror(GPG_ERR_ENOMEM));
171 pth_cancel(cn->tid);
172 continue;
175 m = g_malloc(sizeof(status_msg_t));
177 if (!m) {
178 g_free(msg);
179 log_write("%s(%i): %s", __FILE__, __LINE__, pwmd_strerror(GPG_ERR_ENOMEM));
180 pth_cancel(cn->tid);
181 continue;
184 *m = which;
185 msg->m_data = m;
187 if (cn->mp) {
188 MUTEX_LOCK(&cn->mp_mutex);
189 pth_msgport_put(cn->mp, msg);
190 MUTEX_UNLOCK(&cn->mp_mutex);
194 pth_cleanup_pop(1);