Changed how "GETCONFIG ITERATIONS" works. If there is a file specified,
[pwmd.git] / src / status.c
blob9e169e8425d0e874f57c3554087b9eb0d0f0b6e8
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;
31 rc = assuan_write_status(data->ctx, data->line, data->line2);
32 pth_exit((void *)rc);
33 return NULL;
36 gpg_error_t send_status(assuan_context_t ctx, status_msg_t which,
37 const gchar *fmt, ...)
39 const gchar *line = NULL;
40 gchar buf[ASSUAN_LINELENGTH+1];
41 gchar *status = NULL;
42 va_list ap;
43 gpg_error_t rc;
44 struct assuan_cmd_s data;
46 if (fmt) {
47 va_start(ap, fmt);
48 g_vsnprintf(buf, sizeof(buf), fmt, ap);
49 va_end(ap);
50 line = buf;
53 switch (which) {
54 case STATUS_XFER:
55 status = "XFER";
56 break;
57 case STATUS_CACHE:
58 CACHE_LOCK(client->ctx);
59 line = print_fmt(buf, sizeof(buf), "%i", cache_file_count());
60 CACHE_UNLOCK;
61 status = "CACHE";
62 break;
63 case STATUS_CLIENTS:
64 MUTEX_LOCK(&cn_mutex);
65 line = print_fmt(buf, sizeof(buf), "%i", g_slist_length(cn_thread_list));
66 MUTEX_UNLOCK(&cn_mutex);
67 status = "CLIENTS";
68 break;
69 case STATUS_CONFIG:
70 status = "CONFIG";
71 break;
72 case STATUS_KEEPALIVE:
73 status = "KEEPALIVE";
74 break;
75 case STATUS_LOCKED:
76 status = "LOCKED";
77 line = N_("Waiting for lock");
78 break;
79 case STATUS_ENCRYPT:
80 status = "ENCRYPT";
81 break;
82 case STATUS_DECRYPT:
83 status = "DECRYPT";
84 break;
85 case STATUS_DECOMPRESS:
86 status = "DECOMPRESS";
87 break;
88 case STATUS_COMPRESS:
89 status = "COMPRESS";
90 break;
93 if (!ctx) {
94 log_write("%s %s", status, line);
95 return 0;
98 data.ctx = ctx;
99 data.line = status;
100 data.line2 = line;
101 rc = do_assuan_command(ctx, write_status_cb, &data);
102 return rc;
105 void *client_msg_thread(void *arg)
107 struct client_thread_s *thd = arg;
108 pth_mutex_t m;
109 pth_attr_t attr = pth_attr_of(pth_self());
111 pth_attr_set(attr, PTH_ATTR_NAME, __FUNCTION__);
112 pth_attr_destroy(attr);
113 pth_mutex_init(&m);
114 pth_cond_init(&thd->msg_cond);
115 pth_mutex_acquire(&m, FALSE, NULL);
117 for (;;) {
118 pth_cond_await(&thd->msg_cond, &m, NULL);
119 pth_cancel_point();
121 for (;;) {
122 status_msg_t *msg;
123 gpg_error_t rc;
125 MUTEX_LOCK(&thd->msg_list_mutex);
126 msg = g_slist_nth_data(thd->msg_list, 0);
128 if (msg)
129 thd->msg_list = g_slist_remove(thd->msg_list, msg);
131 MUTEX_UNLOCK(&thd->msg_list_mutex);
133 if (!msg)
134 break;
136 rc = send_status(thd->cl->ctx, *msg, NULL);
137 g_free(msg);
138 pth_cancel_point();
140 if (rc) {
141 log_write("%s(%i): %s", __FILE__, __LINE__, pwmd_strerror(rc));
142 pth_cancel(thd->tid);
143 break;
148 return NULL;
151 static gboolean msg_list_dup(GSList *list, status_msg_t which)
153 guint i, t;
155 for (t = g_slist_length(list), i = 0; i < t; i++) {
156 status_msg_t *m = g_slist_nth_data(list, i);
158 if (*m == which)
159 return TRUE;
162 return FALSE;
165 void send_status_all(status_msg_t which)
167 guint i, t;
169 MUTEX_LOCK(&cn_mutex);
171 for (t = g_slist_length(cn_thread_list), i = 0; i < t; i++) {
172 struct client_thread_s *cn = g_slist_nth_data(cn_thread_list, i);
173 status_msg_t *m;
175 if (msg_list_dup(cn->msg_list, which))
176 continue;
178 m = g_malloc(sizeof(status_msg_t));
180 if (!m) {
181 log_write("%s(%i): %s", __FILE__, __LINE__, strerror(ENOMEM));
182 continue;
185 *m = which;
186 MUTEX_LOCK(&cn->msg_list_mutex);
187 cn->msg_list = g_slist_append(cn->msg_list, m);
188 MUTEX_UNLOCK(&cn->msg_list_mutex);
189 pth_cond_notify(&cn->msg_cond, FALSE);
192 MUTEX_UNLOCK(&cn_mutex);