Portability fixes. Mostly for Android.
[pwmd.git] / src / status.c
blob47e7ac1d48b3137d368907947b2343f1616b4915
1 /*
2 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012
3 Ben Kibbey <bjk@luxsci.net>
5 This file is part of pwmd.
7 Pwmd is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 2 of the License, or
10 (at your option) any later version.
12 Pwmd is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Pwmd. If not, see <http://www.gnu.org/licenses/>.
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
24 #include <pthread.h>
25 #include <stdarg.h>
27 #include "pwmd-error.h"
28 #include "common.h"
29 #include "mutex.h"
30 #include "util-misc.h"
31 #include "util-string.h"
32 #include "status.h"
33 #include "cache.h"
34 #include "mem.h"
36 gpg_error_t send_status(assuan_context_t ctx, status_msg_t which,
37 const char *fmt, ...)
39 const char *line = NULL;
40 char buf[ASSUAN_LINELENGTH+1];
41 const char *status = NULL;
42 va_list ap;
43 char *p;
45 if (fmt) {
46 va_start(ap, fmt);
47 vsnprintf(buf, sizeof(buf), fmt, ap);
48 va_end(ap);
49 line = buf;
52 switch (which) {
53 case STATUS_GENKEY:
54 status = "GENKEY";
55 break;
56 case STATUS_XFER:
57 status = "XFER";
58 break;
59 case STATUS_CACHE:
60 snprintf(buf, sizeof(buf), "%u", cache_file_count());
61 line = buf;
62 status = "CACHE";
63 break;
64 case STATUS_CLIENTS:
65 MUTEX_LOCK(&cn_mutex);
66 snprintf(buf, sizeof(buf), "%i", slist_length(cn_thread_list));
67 line = buf;
68 MUTEX_UNLOCK(&cn_mutex);
69 status = "CLIENTS";
70 break;
71 case STATUS_LOCKED:
72 status = "LOCKED";
73 line = _("Waiting for lock");
74 break;
75 case STATUS_ENCRYPT:
76 status = "ENCRYPT";
77 break;
78 case STATUS_DECRYPT:
79 status = "DECRYPT";
80 break;
81 case STATUS_NEWFILE:
82 status = "NEWFILE";
83 break;
84 case STATUS_AGENT:
85 p = strchr(line, ' ');
87 if (!p) {
88 status = line;
89 line = NULL;
91 else {
92 *p = 0;
93 status = line;
94 line = line+strlen(status)+1;
96 break;
99 if (!ctx) {
100 log_write("%s %s", status, line ? line : "");
101 return 0;
104 return assuan_write_status(ctx, status, line);
107 void send_status_all(status_msg_t s, const char *fmt, ...)
109 MUTEX_LOCK(&cn_mutex);
110 int i = 0;
111 int t = slist_length(cn_thread_list);
113 for (; i < t; i++) {
114 struct client_thread_s *thd = slist_nth_data(cn_thread_list, i);
115 struct status_msg_s *msg, *p;
116 char c = 0xff;
117 int match = 0;
119 MUTEX_LOCK(&thd->status_mutex);
121 for (p = thd->msg_queue; p; p = p->next) {
122 if (p->s == s) {
123 match = 1;
124 break;
128 if (match) {
129 MUTEX_UNLOCK(&thd->status_mutex);
130 continue;
133 msg = xcalloc(1, sizeof(struct status_msg_s));
134 msg->s = s;
135 if (fmt) {
136 va_list ap;
138 va_start(ap, fmt);
139 str_vasprintf(&msg->line, fmt, ap);
140 va_end(ap);
143 for (p = thd->msg_queue; p && p->next; p = p->next);
144 if (!p)
145 thd->msg_queue = msg;
146 else
147 p->next = msg;
149 write(thd->status_msg_pipe[1], &c, 1);
150 MUTEX_UNLOCK(&thd->status_mutex);
153 MUTEX_UNLOCK(&cn_mutex);