[Gpa-commits] r956 - in trunk: . src
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Fri Feb 27 11:06:30 CET 2009
Author: werner
Date: 2009-02-27 11:06:24 +0100 (Fri, 27 Feb 2009)
New Revision: 956
Modified:
trunk/NEWS
trunk/src/ChangeLog
trunk/src/cardman.c
trunk/src/filewatch.c
Log:
Use a ticker to reload the card.
Modified: trunk/NEWS
===================================================================
--- trunk/NEWS 2009-02-26 18:57:16 UTC (rev 955)
+++ trunk/NEWS 2009-02-27 10:06:24 UTC (rev 956)
@@ -1,5 +1,7 @@
-Noteworthy changes in version 0.8.1
+Noteworthy changes in version 0.9.0
------------------------------------------------
+
+ * Add a basic smartcard manager and the option --card.
Noteworthy changes in version 0.8.0 (2008-09-04)
Modified: trunk/src/ChangeLog
===================================================================
--- trunk/src/ChangeLog 2009-02-26 18:57:16 UTC (rev 955)
+++ trunk/src/ChangeLog 2009-02-27 10:06:24 UTC (rev 956)
@@ -1,3 +1,13 @@
+2009-02-27 Werner Koch <wk at g10code.com>
+
+ * filewatch.c: Remove debug output.
+
+ * cardman.c (struct _GpaCardManager): Add TICKER_TIMEOUT_ID and
+ EVENTCOUNTER.
+ (geteventcounter_status_cb, ticker_cb, start_ticker): New.
+ (gpa_card_manager_finalize): Remove the ticker.
+ (card_reload): Start the ticker and update the evntcounter.
+
2009-02-26 Werner Koch <wk at g10code.com>
* cm-object.c (gpa_cm_object_class_init): Register "update-status"
Modified: trunk/src/cardman.c
===================================================================
--- trunk/src/cardman.c 2009-02-26 18:57:16 UTC (rev 955)
+++ trunk/src/cardman.c 2009-02-27 10:06:24 UTC (rev 956)
@@ -81,6 +81,15 @@
gpgme_ctx_t gpgagent; /* Gpgme context for the assuan
connection with the gpg-agent. */
+
+ guint ticker_timeout_id; /* Source Id of the timeout ticker or 0. */
+
+
+ struct {
+ int card_any; /* Any card event counter seen. */
+ unsigned int card; /* Last seen card event counter. */
+ } eventcounter;
+
};
/* There is only one instance of the card manager class. Use a global
@@ -89,6 +98,7 @@
/* Local prototypes */
+static void start_ticker (GpaCardManager *cardman);
static void update_card_widget (GpaCardManager *cardman);
static void gpa_card_manager_finalize (GObject *object);
@@ -228,7 +238,17 @@
cardman->cardtypename = "Unknown";
}
+ else if ( !strcmp (status, "EVENTCOUNTER") )
+ {
+ unsigned int count;
+ if (sscanf (args, "%*u %*u %u ", &count) == 1)
+ {
+ cardman->eventcounter.card_any = 1;
+ cardman->eventcounter.card = count;
+ }
+ }
+
return 0;
}
@@ -242,6 +262,9 @@
if (!cardman->gpgagent)
return; /* No support for GPGME_PROTOCOL_ASSUAN. */
+
+ /* Start the ticker if not yet done. */
+ start_ticker (cardman);
if (!cardman->in_card_reload)
{
@@ -276,6 +299,14 @@
if (!err)
{
+ /* Get the event counter to avoid a duplicate reload due to
+ the ticker. */
+ gpgme_op_assuan_transact (cardman->gpgagent,
+ "GETEVENTCOUNTER",
+ NULL, NULL,
+ NULL, NULL,
+ scd_status_cb, cardman);
+
/* Now we need to get the APPTYPE of the card so that the
correct GpaCM* object can can act on the data. */
command = "SCD GETATTR APPTYPE";
@@ -296,6 +327,7 @@
statusbar_update (cardman, _("Error accessing card"));
}
}
+
update_card_widget (cardman);
update_title (cardman);
@@ -334,6 +366,79 @@
}
+static gpg_error_t
+geteventcounter_status_cb (void *opaque, const char *status, const char *args)
+{
+ GpaCardManager *cardman = opaque;
+
+ if ( !strcmp (status, "EVENTCOUNTER") )
+ {
+ unsigned int count;
+
+ /* We don't check while we are already reloading a card. The
+ last action of the card reload code will also update the
+ event counter. */
+ if (!cardman->in_card_reload
+ && sscanf (args, "%*u %*u %u ", &count) == 1)
+ {
+ if (cardman->eventcounter.card_any
+ && cardman->eventcounter.card != count)
+ {
+ /* Actually we should not do a reload based only on the
+ eventcounter but check the actual card status first.
+ However simply triggering a reload is not different
+ from the user hitting the reload button. */
+ g_object_ref (cardman);
+ g_idle_add (card_reload_idle_cb, cardman);
+ }
+ cardman->eventcounter.card_any = 1;
+ cardman->eventcounter.card = count;
+ }
+ }
+
+ return 0;
+}
+
+/* This fucntion is called by the timerout ticker started by
+ start_ticker. It is used to poll scdaemon to detect a card status
+ change. */
+static gboolean
+ticker_cb (gpointer user_data)
+{
+ GpaCardManager *cardman = user_data;
+
+ if (!cardman || !cardman->ticker_timeout_id || !cardman->gpgagent)
+ return TRUE; /* Keep on ticking. */
+
+ /* Note that we are single threaded and thus there is no need to
+ lock the assuan context. */
+
+ gpgme_op_assuan_transact (cardman->gpgagent,
+ "GETEVENTCOUNTER",
+ NULL, NULL,
+ NULL, NULL,
+ geteventcounter_status_cb, cardman);
+
+ return TRUE; /* Keep on ticking. */
+}
+
+
+/* If no ticker is active start one. */
+static void
+start_ticker (GpaCardManager *cardman)
+{
+ if (!cardman->ticker_timeout_id)
+ {
+#if GTK_CHECK_VERSION (2, 14, 0)
+ cardman->ticker_timeout_id = g_timeout_add_seconds (1,
+ ticker_cb, cardman);
+#else
+ cardman->ticker_timeout_id = g_timeout_add (1000, ticker_cb, cardman);
+#endif
+ }
+}
+
+
/* Signal handler for the completed signal of the key generation. */
static void
card_genkey_completed (GpaCardManager *cardman, gpg_error_t err)
@@ -398,11 +503,6 @@
if (cardman && strchr (reason, 'w') )
{
-/* reader_status_t reader_status; */
-
-/* reader_status = reader_status_from_file (filename); */
-/* if (reader_status == READER_STATUS_PRESENT) */
-/* statusbar_update (cardman, _("Reloading card data...")); */
card_reload (cardman);
}
}
@@ -655,6 +755,9 @@
G_CALLBACK (card_manager_closed), cardman);
+ /* We use the file watcher to speed up card change detection. If it
+ does not work (i.e. on non Linux based systems) the ticker takes
+ care of it. */
fname = g_build_filename (gnupg_homedir, "reader_0.status", NULL);
cardman->watch = gpa_add_filewatch (fname, "w", watcher_cb, cardman);
xfree (fname);
@@ -684,6 +787,12 @@
gpgme_release (cardman->gpgagent);
cardman->gpgagent = NULL;
+
+ if (cardman->ticker_timeout_id)
+ {
+ g_source_remove (cardman->ticker_timeout_id);
+ cardman->ticker_timeout_id = 0;
+ }
/* FIXME: Remove the watch object and all other resources. */
Modified: trunk/src/filewatch.c
===================================================================
--- trunk/src/filewatch.c 2009-02-26 18:57:16 UTC (rev 955)
+++ trunk/src/filewatch.c 2009-02-27 10:06:24 UTC (rev 956)
@@ -81,7 +81,7 @@
status, err->message);
g_error_free (err);
}
- g_debug ("new file watch event, nread=%u", (unsigned int)nread);
+/* g_debug ("new file watch event, nread=%u", (unsigned int)nread); */
if (status == G_IO_STATUS_NORMAL)
{
@@ -116,9 +116,9 @@
MAKEREASON ('x', IN_IGNORED);
#undef MAKEREASON
reason[reasonidx] = 0;
- g_debug ("event: wd=%d mask=%#x (%s) cookie=%#x len=%u name=`%.*s'",
- ev->wd, ev->mask, reason, ev->cookie, ev->len,
- (int)ev->len, ev->name);
+/* g_debug ("event: wd=%d mask=%#x (%s) cookie=%#x len=%u name=`%.*s'", */
+/* ev->wd, ev->mask, reason, ev->cookie, ev->len, */
+/* (int)ev->len, ev->name); */
walking_watch_list_p++;
for (watch=watch_list; watch; watch = watch->next)
More information about the Gpa-commits
mailing list