aboutsummaryrefslogtreecommitdiffstats
path: root/scd/statusfd.c
diff options
context:
space:
mode:
authorMoritz Schulte <[email protected]>2007-08-16 12:44:17 +0000
committerMoritz Schulte <[email protected]>2007-08-16 12:44:17 +0000
commit62039d815eef5a699cb7d78a36a0a5e9eb5910c8 (patch)
tree925563c8c20b48aabd3825d26bc387d9e4631c84 /scd/statusfd.c
parentCreating new branch for moritz' hacks (diff)
downloadgnupg-GNUPG-TRUNK-MO-HACKS.tar.gz
gnupg-GNUPG-TRUNK-MO-HACKS.zip
Implemented the STATUSFD mechanism.GNUPG-TRUNK-MO-HACKS
2007-08-16 Moritz Schulte <[email protected]> * command.c: Include "statusfd.h". (cmd_statusfd): New function. (register_commands): New entry for STATUSFD command. (update_reader_status_file): Call statusfd_event_card_inserted and statusfd_event_card_removed on events. (scd_command_handler): Pass flags=3 to assuan_init_socket_server_ext (enabling fd passing). * statusfd.c, statusfd.h: New files. * Makefile.am (scdaemon_SOURCES): Added statusfd.c, statusfd.h. * NOTES-STATUSFD: New file.
Diffstat (limited to '')
-rw-r--r--scd/statusfd.c139
1 files changed, 139 insertions, 0 deletions
diff --git a/scd/statusfd.c b/scd/statusfd.c
new file mode 100644
index 000000000..1fa7375a7
--- /dev/null
+++ b/scd/statusfd.c
@@ -0,0 +1,139 @@
+/* statusfd.c - SCdaemon status fd handling
+ * Copyright (C) 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* AUTHOR: Moritz Schulte <[email protected]>. */
+
+#include <config.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pth.h>
+
+#include "scdaemon.h"
+#include "statusfd.h"
+
+struct statusfd_s
+{
+ FILE *stream;
+ struct statusfd_s *next, **prevp;
+};
+
+typedef struct statusfd_s *statusfd_t;
+
+static statusfd_t statusfd_list;
+
+
+
+static int
+statusfd_add (FILE *stream)
+{
+ statusfd_t statusfd_obj;
+ int rc;
+
+ statusfd_obj = xtrymalloc (sizeof (*statusfd_obj));
+
+ if (statusfd_obj)
+ {
+ statusfd_obj->stream = stream;
+ statusfd_obj->next = statusfd_list;
+ statusfd_obj->prevp = &statusfd_list;
+ if (statusfd_list)
+ statusfd_list->prevp = &statusfd_obj->next;
+ statusfd_list = statusfd_obj;
+ rc = 0;
+ }
+ else
+ rc = gpg_error_from_syserror ();
+
+ return rc;
+}
+
+static void
+statusfd_remove (statusfd_t statusfd)
+{
+ *statusfd->prevp = statusfd->next;
+ if (statusfd->next)
+ statusfd->next->prevp = statusfd->prevp;
+
+ xfree (statusfd);
+}
+
+static void
+statusfd_broadcast (const char *fmt, ...)
+{
+ statusfd_t statusfd = statusfd_list;
+ statusfd_t statusfd_next;
+ int ret;
+ va_list ap;
+
+ va_start (ap, fmt);
+
+ while (statusfd)
+ {
+ ret = vfprintf (statusfd->stream, fmt, ap);
+ if (ret >= 0)
+ ret = fflush (statusfd->stream);
+
+ if (ret < 0)
+ {
+ /* Error on this statusfd stream, remove it. */
+ /* FIXME: only remove on certain errros? -moritz */
+
+ statusfd_next = statusfd->next;
+ statusfd_remove (statusfd);
+ statusfd = statusfd_next;
+ continue;
+ }
+
+ statusfd = statusfd->next;
+ }
+
+ va_end (ap);
+}
+
+int
+statusfd_register (int fd)
+{
+ FILE *stream;
+ int rc;
+
+ stream = fdopen (fd, "a");
+ if (! stream)
+ rc = gpg_error_from_syserror ();
+ else
+ rc = statusfd_add (stream);
+
+ if (rc && stream)
+ fclose (stream);
+
+ return rc;
+}
+
+void
+statusfd_event_card_inserted (int slot)
+{
+ statusfd_broadcast ("CARD INSERTED\n");
+}
+
+void
+statusfd_event_card_removed (int slot)
+{
+ statusfd_broadcast ("CARD REMOVED\n");
+}