[Gpa-commits] r923 - in trunk: . src

scm-commit@wald.intevation.org scm-commit at wald.intevation.org
Tue Dec 16 21:11:39 CET 2008


Author: werner
Date: 2008-12-16 21:11:36 +0100 (Tue, 16 Dec 2008)
New Revision: 923

Added:
   trunk/src/filewatch.c
Modified:
   trunk/ChangeLog
   trunk/configure.ac
   trunk/src/ChangeLog
   trunk/src/Makefile.am
   trunk/src/cardman.c
   trunk/src/gpa.c
   trunk/src/gpa.h
   trunk/src/gpacardreloadop.c
   trunk/src/gpacontext.c
Log:
Add a filewatcher facility to allow detection of card changes.
(not complete)


Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2008-12-16 11:14:15 UTC (rev 922)
+++ trunk/ChangeLog	2008-12-16 20:11:36 UTC (rev 923)
@@ -1,3 +1,8 @@
+2008-12-16  Werner Koch  <wk at g10code.com>
+
+	* configure.ac: Remove unused test for getopt_long.
+	(AC_CHECK_FUNCS): Check for inotify_init.
+
 2008-12-10  Marcus Brinkmann  <marcus at g10code.de>
 
 	* configure.ac: Require gtk 2.10.0.

Modified: trunk/configure.ac
===================================================================
--- trunk/configure.ac	2008-12-16 11:14:15 UTC (rev 922)
+++ trunk/configure.ac	2008-12-16 20:11:36 UTC (rev 923)
@@ -95,8 +95,7 @@
 dnl Check for libraries
 AC_CHECK_LIB(m, sin)
 CHECK_ZLIB
-AC_CHECK_FUNCS(strsep)
-AC_CHECK_FUNCS(stpcpy)
+AC_CHECK_FUNCS([strsep stpcpy])
 
 development_version=no
 # Allow users to append something to the version string (other than -cvs)
@@ -185,12 +184,6 @@
 AM_GNU_GETTEXT([external],[need-ngettext])
 
 
-AC_CHECK_FUNC(getopt_long,
-    AC_MSG_RESULT(using libc's getopt_long),
-    AC_CHECK_LIB(iberty, getopt_long,[LIBS="$LIBS -liberty"],
-	AC_CHECK_LIB(gnugetopt, getopt_long,[LIBS="$LIBS -lgnugetopt"],
-	    AC_MSG_ERROR(Cannot find a getopt_long function))))
-
 dnl Where is the GTK+ toolkit
 AM_PATH_GTK_2_0(2.10.0,, AC_MSG_ERROR(Cannot find GTK+ 2.0))
 
@@ -228,16 +221,32 @@
 # We need this for GPGME
 AC_SYS_LARGEFILE
 
-dnl
-dnl Checks for typedefs and structures
-dnl
 
+#
+# Checks for typedefs and structures
+#
+
 GNUPG_CHECK_TYPEDEF(byte, HAVE_BYTE_TYPEDEF)
 GNUPG_CHECK_TYPEDEF(ushort, HAVE_USHORT_TYPEDEF)
 GNUPG_CHECK_TYPEDEF(ulong, HAVE_ULONG_TYPEDEF)
 GNUPG_CHECK_TYPEDEF(u16, HAVE_U16_TYPEDEF)
 GNUPG_CHECK_TYPEDEF(u32, HAVE_U32_TYPEDEF)
 
+#
+# Check for library fucntions
+#
+
+# See whether libc supports the Linux inotify interface
+case "${host}" in
+    *-*-linux*)
+        AC_CHECK_FUNCS([inotify_init])
+        ;;
+esac
+
+
+#
+# Set extra compiler flags
+# 
 if test "$GCC" = yes; then
     if test "$USE_MAINTAINER_MODE" = "yes"; then
         # FIXME:

Modified: trunk/src/ChangeLog
===================================================================
--- trunk/src/ChangeLog	2008-12-16 11:14:15 UTC (rev 922)
+++ trunk/src/ChangeLog	2008-12-16 20:11:36 UTC (rev 923)
@@ -1,6 +1,21 @@
 2008-12-16  Werner Koch  <wk at g10code.com>
 
+	* cardman.c (_GpaCardManager): Add fields CARD_WIDGET and HAVE_CARD.
+	(gpa_card_manager_constructor): Use it here.
+	(update_title, update_info_visibility): New.
+	(gpa_card_manager_constructor): Use them.
+	(watcher_cb): New.
+
+	* gpacardreloadop.c (process_line): Rewrite to handle empty fields.
+
+	* gpacontext.c (gpa_context_start, gpa_context_done): Remove
+	debug output.
+
+	* filewatch.c: New.
+	* gpa.c (main): Intialize the file watcher.
+
 	* cardman.c (card_reload_cb): Pretty print serial, version and URL.
+
 	* utils.c (decode_c_string, hextobyte): New.  Based on code taken
 	GPGME (conversion.c).
 

Modified: trunk/src/Makefile.am
===================================================================
--- trunk/src/Makefile.am	2008-12-16 11:14:15 UTC (rev 922)
+++ trunk/src/Makefile.am	2008-12-16 20:11:36 UTC (rev 923)
@@ -119,6 +119,7 @@
 	      gpabackupop.h gpabackupop.c \
 	      gpakeyselector.h gpakeyselector.c \
 	      server.c \
+	      filewatch.c \
 	      options.c \
 	      confdialog.h confdialog.c \
 	      gpa-marshal.c gpa-marshal.h \

Modified: trunk/src/cardman.c
===================================================================
--- trunk/src/cardman.c	2008-12-16 11:14:15 UTC (rev 922)
+++ trunk/src/cardman.c	2008-12-16 20:11:36 UTC (rev 923)
@@ -53,6 +53,11 @@
   GtkWindow parent;
 
   GtkWidget *window;
+
+  GtkUIManager *ui_manager;
+
+  GtkWidget *card_widget;     /* The container of all the info widgets.  */
+
   GtkWidget *entrySerialno;
   GtkWidget *entryVersion;
   GtkWidget *entryManufacturer;
@@ -68,6 +73,10 @@
   GtkWidget *comboSex;
   GList *selection_sensitive_actions; /* ? */
 #endif
+
+  int have_card;             /* True, if a supported card is in the reader.  */
+  gpa_filewatch_id_t watch;  /* For watching the reader status file.  */
+  int in_watcher_cb;         /* Sentinel for watcher_cb().  */
 };
 
 struct _GpaCardManagerClass 
@@ -90,9 +99,13 @@
 #endif
 
 /* Local prototypes */
-static GObject *gpa_card_manager_constructor (GType type,
-					      guint n_construct_properties,
-					      GObjectConstructParam *construct_properties);
+static void watcher_cb (void *opaque, 
+                        const char *filename, const char *reason);
+static void update_title (GpaCardManager *cardman);
+static void update_info_visibility (GpaCardManager *cardman);
+static GObject *gpa_card_manager_constructor
+                (GType type, guint n_construct_properties,
+                 GObjectConstructParam *construct_properties);
 
 
 
@@ -102,6 +115,8 @@
 static void
 gpa_card_manager_finalize (GObject *object)
 {  
+  /* FIXME: Remove the watch object and all other resources.  */
+
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
@@ -109,6 +124,11 @@
 static void
 gpa_card_manager_init (GpaCardManager *cardman)
 {
+  char *fname;
+
+  fname = g_build_filename (gnupg_homedir, "reader_0.status", NULL);
+  cardman->watch = gpa_add_filewatch (fname, "c", watcher_cb, cardman);
+  xfree (fname);
 }
 
 static void
@@ -151,7 +171,21 @@
 }
 
 
+static void
+watcher_cb (void *opaque, const char *filename, const char *reason)
+{
+  GpaCardManager *cardman = opaque;
 
+  if (cardman && !cardman->in_watcher_cb && strchr (reason, 'c') )
+    {
+      cardman->in_watcher_cb++;
+      gtk_action_activate (gtk_ui_manager_get_action 
+                           (cardman->ui_manager, "/MainMenu/Card/CardReload"));
+      cardman->in_watcher_cb--;
+    }
+}
+
+
 static void
 register_reload_operation (GpaCardManager *cardman, GpaCardReloadOperation *op)
 {
@@ -164,13 +198,23 @@
    called for each data item during a reload operation and updates the
    according widgets. */
 static void
-card_reload_cb (void *opaque, const char *identifier, int idx, const void *value)
+card_reload_cb (void *opaque,
+                const char *identifier, int idx, const void *value)
 {
   GpaCardManager *cardman = opaque;
   const char *string = value;
 
-  if (strcmp (identifier, "serial") == 0 && idx == 0)
+  if (!strcmp (identifier, "AID"))
     {
+      if (idx == 0)
+        {
+          cardman->have_card = !!*string;
+          update_info_visibility (cardman);
+          update_title (cardman);
+        }
+    }
+  else if (strcmp (identifier, "serial") == 0 && idx == 0)
+    {
       while (*string == '0' && string[1])
         string++;
       gtk_entry_set_text (GTK_ENTRY (cardman->entrySerialno), string);
@@ -226,7 +270,8 @@
   GpaCardManager *cardman = param;
   GpaCardReloadOperation *op;
 
-  op = gpa_card_reload_operation_new (cardman->window, card_reload_cb, cardman);
+  op = gpa_card_reload_operation_new (cardman->window, 
+                                      card_reload_cb, cardman);
   register_reload_operation (cardman, GPA_CARD_RELOAD_OPERATION (op));
 }
 
@@ -326,7 +371,6 @@
   GtkAccelGroup *accel_group;
   GtkActionGroup *action_group;
   GtkAction *action;
-  GtkUIManager *ui_manager;
   GError *error;
 
   action_group = gtk_action_group_new ("MenuActions");
@@ -341,11 +385,11 @@
   gtk_action_group_add_actions
     (action_group, gpa_preferences_menu_action_entries,
      G_N_ELEMENTS (gpa_preferences_menu_action_entries), cardman);
-  ui_manager = gtk_ui_manager_new ();
-  gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
-  accel_group = gtk_ui_manager_get_accel_group (ui_manager);
+  cardman->ui_manager = gtk_ui_manager_new ();
+  gtk_ui_manager_insert_action_group (cardman->ui_manager, action_group, 0);
+  accel_group = gtk_ui_manager_get_accel_group (cardman->ui_manager);
   gtk_window_add_accel_group (GTK_WINDOW (cardman), accel_group);
-  if (! gtk_ui_manager_add_ui_from_string (ui_manager, ui_description,
+  if (! gtk_ui_manager_add_ui_from_string (cardman->ui_manager, ui_description,
 					   -1, &error))
     {
       g_message ("building cardman menus failed: %s", error->message);
@@ -359,8 +403,8 @@
   action = gtk_action_group_get_action (action_group, "WindowsFileManager");
   g_object_set (action, "short_label", _("Files"), NULL);
 
-  *menubar = gtk_ui_manager_get_widget (ui_manager, "/MainMenu");
-  *toolbar = gtk_ui_manager_get_widget (ui_manager, "/ToolBar");
+  *menubar = gtk_ui_manager_get_widget (cardman->ui_manager, "/MainMenu");
+  *toolbar = gtk_ui_manager_get_widget (cardman->ui_manager, "/ToolBar");
   gpa_toolbar_set_homogeneous (GTK_TOOLBAR (*toolbar), FALSE);
 }
 
@@ -373,6 +417,34 @@
   instance = NULL;
 }
 
+
+static void
+update_title (GpaCardManager *cardman)
+{
+  const char *title = _("GNU Privacy Assistant - Card Manager");
+
+  if (cardman->have_card)
+    gtk_window_set_title (GTK_WINDOW (cardman), title);
+  else
+    {
+      char *tmp;
+      
+      tmp = g_strdup_printf ("%s (%s)", title, _("no card"));
+      gtk_window_set_title (GTK_WINDOW (cardman), tmp);
+      xfree (tmp);
+    }
+}
+
+static void
+update_info_visibility (GpaCardManager *cardman)
+{
+  if (cardman->have_card)
+    gtk_widget_show_all (cardman->card_widget);
+  else
+    gtk_widget_hide_all (cardman->card_widget);
+}
+
+
 /* This function constructs the container holding the card "form". It
    updates CARDMAN with new references to the entry widgets, etc.  */
 static GtkWidget *
@@ -467,7 +539,6 @@
   GtkWidget *icon;
   gchar *markup;
   GtkWidget *menubar;
-  GtkWidget *card_widget;
   GtkWidget *toolbar;
 
   /* Invoke parent's constructor.  */
@@ -476,6 +547,8 @@
 				      construct_properties);
   cardman = GPA_CARD_MANAGER (object);
 
+  cardman->have_card = 1;
+
   cardman->entryLogin = NULL;
 
   cardman->entrySerialno = NULL;
@@ -490,9 +563,9 @@
   cardman->entryKeyEnc = NULL;
   cardman->entryKeyAuth = NULL;
 
+
   /* Initialize.  */
-  gtk_window_set_title (GTK_WINDOW (cardman),
-			_("GNU Privacy Assistant - Card Manager"));
+  update_title (cardman);
   gtk_window_set_default_size (GTK_WINDOW (cardman), 640, 480);
   /* Realize the window so that we can create pixmaps without warnings.  */
   gtk_widget_realize (GTK_WIDGET (cardman));
@@ -521,14 +594,16 @@
   gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 10);
   gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
 
-  card_widget = construct_card_widget (cardman);
-  gtk_box_pack_start (GTK_BOX (vbox), card_widget, TRUE, TRUE, 0);
+  cardman->card_widget = construct_card_widget (cardman);
+  gtk_box_pack_start (GTK_BOX (vbox), cardman->card_widget, TRUE, TRUE, 0);
 
   gtk_container_add (GTK_CONTAINER (cardman), vbox);
 
   g_signal_connect (object, "destroy",
                     G_CALLBACK (card_manager_closed), object);
 
+  gtk_widget_show_all (cardman->card_widget);
+  gtk_widget_hide_all (cardman->card_widget);
   return object;
 }
 
@@ -538,6 +613,8 @@
   GpaCardManager *cardman;
 
   cardman = g_object_new (GPA_CARD_MANAGER_TYPE, NULL);  
+  gtk_action_activate (gtk_ui_manager_get_action 
+                       (cardman->ui_manager, "/MainMenu/Card/CardReload"));
 
 #if 0
   /* ? */

Added: trunk/src/filewatch.c
===================================================================
--- trunk/src/filewatch.c	2008-12-16 11:14:15 UTC (rev 922)
+++ trunk/src/filewatch.c	2008-12-16 20:11:36 UTC (rev 923)
@@ -0,0 +1,271 @@
+/* filewatch.c -  The file watch facility
+   Copyright (C) 2008 g10 Code GmbH
+
+   This file is part of GPA
+
+   GPA 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.
+
+   GPA 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/>.  */
+
+/* 
+   Note that we do not want to use the GIO library because this would
+   require DBus; which we try to avoid.  The reason we need this file
+   watcher facility at all is to get notified on card reader changes
+   by scdaemon.  It might be useful for other things too, though.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#ifdef HAVE_INOTIFY_INIT
+# include <sys/inotify.h>
+#endif /*HAVE_INOTIFY_INIT*/
+
+#include <glib.h>
+
+#include "gpa.h"
+
+/* The object used to identify a file watch within GPA.  */
+struct gpa_filewatch_id_s
+{
+  gpa_filewatch_id_t next;
+  int wd;
+  gpa_filewatch_cb_t callback;
+  void *callback_data;
+  char fname[1];
+};
+
+
+/* The file descriptor used for the inotify queue.  */
+static int queue_fd = -1;
+
+/* We need to keep a list of active file watches.  */
+static gpa_filewatch_id_t watch_list;
+
+/* We set this flag to true while walking thewatch_list.  */
+static int walking_watch_list_p;
+
+
+/* This function is called by the main event loop if the file watcher
+   fd is readable.  This is currently only used under Linux if the
+   inotify interface is available. */
+#ifdef HAVE_INOTIFY_INIT
+static gboolean 
+filewatch_cb (GIOChannel *channel, 
+              GIOCondition condition, void *data)
+{
+  gsize nread;
+  GIOStatus status;
+  GError *err = NULL;
+  char buffer[512];
+
+  status = g_io_channel_read_chars (channel, buffer, sizeof buffer,
+                                    &nread, &err);
+  if (err)
+    {
+      g_debug ("error reading inotify queue: status=%d, err=%s",
+               status, err->message);
+      g_error_free (err);
+    }
+  g_debug ("new file watch event, nread=%u", (unsigned int)nread);
+  
+  if (status == G_IO_STATUS_NORMAL)
+    {
+      struct inotify_event *ev;
+      char *p = buffer;
+      gpa_filewatch_id_t watch;
+      char reason[20];
+      int  reasonidx;
+      
+      while (nread >= sizeof *ev) 
+        {
+          ev = (void *)p;
+          g_debug ("event: wd=%d mask=%#x cookie=%#x len=%u name=`%.*s'",
+                   ev->wd, ev->mask, ev->cookie, ev->len, 
+                   (int)ev->len, ev->name);
+#define MAKEREASON(a,b) do { if ((ev->mask & (b))                   \
+                                  && reasonidx < sizeof reason) \
+                                reason[reasonidx++] = (a);      \
+                           } while (0)
+          reasonidx = 0;
+          MAKEREASON ('a', IN_ACCESS);
+          MAKEREASON ('c', IN_MODIFY);
+          MAKEREASON ('e', IN_ATTRIB);
+          MAKEREASON ('w', IN_CLOSE_WRITE);
+          MAKEREASON ('0', IN_CLOSE_NOWRITE);
+          MAKEREASON ('r', IN_OPEN);
+          MAKEREASON ('m', IN_MOVED_FROM);
+          MAKEREASON ('y', IN_MOVED_TO);
+          MAKEREASON ('n', IN_CREATE);
+          MAKEREASON ('d', IN_DELETE);
+          MAKEREASON ('D', IN_DELETE_SELF);
+          MAKEREASON ('M', IN_MOVE_SELF);
+          MAKEREASON ('u', IN_UNMOUNT);
+          MAKEREASON ('o', IN_Q_OVERFLOW);
+          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);
+
+          walking_watch_list_p++;
+          for (watch=watch_list; watch; watch = watch->next)
+            {
+              if (ev->wd == watch->wd && watch->callback)
+                watch->callback (watch->callback_data, watch->fname, reason);
+            }
+          walking_watch_list_p--;
+
+          nread -= sizeof *ev;
+          nread -= (nread > ev->len)?  ev->len : nread;
+          p += sizeof *ev + ev->len;
+        }
+      
+    }
+
+  return TRUE; /* Keep the file watcher fd in the event loop.  */
+}
+#endif /*HAVE_INOTIFY_INIT*/
+
+
+
+/* Initialize the file watcher.  */
+void
+gpa_init_filewatch (void)
+{
+#ifdef HAVE_INOTIFY_INIT
+  GIOChannel *channel;
+  unsigned int source_id;
+
+  if (queue_fd != -1)
+    {
+      g_debug ("gpa_init_filewatch called twice\n");
+      return;
+    }
+
+  queue_fd = inotify_init ();
+  if (queue_fd == -1)
+    {
+      g_debug ("this machine does not support the inotify interface"
+               " - some features won't work\n");
+      return;
+    }
+
+  channel = g_io_channel_unix_new (queue_fd);
+  if (!channel)
+    {
+      g_debug ("error creating a new i/o channel\n");
+      close (queue_fd);
+      queue_fd = -1;
+      return;
+    }
+  g_io_channel_set_encoding (channel, NULL, NULL);
+  g_io_channel_set_buffered (channel, FALSE);
+
+  source_id = g_io_add_watch (channel, G_IO_IN, filewatch_cb, NULL);
+  if (!source_id)
+    {
+      g_debug ("error creating watch for I/O channel\n");
+      g_io_channel_shutdown (channel, 0, NULL);
+      close (queue_fd);
+      queue_fd = -1;
+      return;
+    }
+#endif /*HAVE_INOTIFY_INIT*/
+}
+
+/* Add a new filewatch for file FILENAME using MASKSTRING.  MASKSTRING
+   is a string of letters, describing what events are to be watched
+   watched:
+
+        "a"  File was accessed
+	"c"  File was modified
+	"e"  Metadata changed
+	"w"  Writtable file was closed
+	"0"  Unwrittable file closed
+	"r"  File was opened
+	"m"  File was moved from X
+	"y"  File was moved to Y
+	"n"  Subfile was created
+	"d"  Subfile was deleted
+	"D"  Self was deleted
+	"M"  Self was moved
+	"u"  Backing fs was unmounted 
+	"o"  Event queued overflowed
+	"x"  File is no longer watched
+
+   CALLBACK is the callback function to be called for all matching
+   events.  
+
+   The function returns NULL on error or an object used for other
+   operations.
+*/
+gpa_filewatch_id_t
+gpa_add_filewatch (const char *filename, const char *maskstring,
+                   gpa_filewatch_cb_t callback, void *callback_data)
+{
+#ifdef HAVE_INOTIFY_INIT
+  unsigned int mask = 0;
+  int wd;
+  gpa_filewatch_id_t handle;
+
+  for (mask=0; *maskstring; maskstring++)
+    switch (*maskstring)
+      {
+      case 'a': mask |= IN_ACCESS; break;
+      case 'c': mask |= IN_MODIFY; break;
+      case 'e': mask |= IN_ATTRIB; break;
+      case 'w': mask |= IN_CLOSE_WRITE; break;
+      case '0': mask |= IN_CLOSE_NOWRITE; break;
+      case 'r': mask |= IN_OPEN; break;
+      case 'm': mask |= IN_MOVED_FROM; break;
+      case 'y': mask |= IN_MOVED_TO; break;
+      case 'n': mask |= IN_CREATE; break;
+      case 'd': mask |= IN_DELETE; break;
+      case 'D': mask |= IN_DELETE_SELF; break;
+      case 'M': mask |= IN_MOVE_SELF; break;
+      case 'u': mask |= IN_UNMOUNT; break;
+      case 'o': mask |= IN_Q_OVERFLOW; break;
+      case 'x': mask |= IN_IGNORED; break;
+      default:
+        g_debug ("invalid filewatch mask character '%c'\n", *maskstring);
+        return NULL;
+      }
+
+  wd = inotify_add_watch (queue_fd, filename, mask);
+  if (wd == -1)
+    {
+      g_debug ("adding watch for `%s' failed: %s", filename, strerror (errno));
+      return NULL;
+    }
+
+  handle = xcalloc (1, sizeof *handle + strlen (filename));
+  strcpy (handle->fname, filename);
+  handle->wd = wd;
+  handle->callback = callback;
+  handle->callback_data = callback_data;
+  
+  handle->next = watch_list;
+  watch_list = handle;
+
+  return handle;
+
+#else /*!HAVE_INOTIFY_INIT*/
+  return NULL;
+#endif /*!HAVE_INOTIFY_INIT*/  
+}

Modified: trunk/src/gpa.c
===================================================================
--- trunk/src/gpa.c	2008-12-16 11:14:15 UTC (rev 922)
+++ trunk/src/gpa.c	2008-12-16 20:11:36 UTC (rev 923)
@@ -430,6 +430,10 @@
 					 keyservers->data);
     }
 
+  /* Initialize the file watch facility.  */
+  gpa_init_filewatch ();
+
+  /* Startup whatever has been requested by the user.  */
   if (args.start_only_server)
     {
       /* Fire up the server.  Note that the server allows to start the

Modified: trunk/src/gpa.h
===================================================================
--- trunk/src/gpa.h	2008-12-16 11:14:15 UTC (rev 922)
+++ trunk/src/gpa.h	2008-12-16 20:11:36 UTC (rev 923)
@@ -106,6 +106,17 @@
 void gpa_start_server (void);
 void gpa_stop_server (void);
 
+
+typedef struct gpa_filewatch_id_s *gpa_filewatch_id_t;
+typedef void (*gpa_filewatch_cb_t) 
+     (void *user_data, const char *filename, const char *reason);
+void gpa_init_filewatch (void);
+gpa_filewatch_id_t gpa_add_filewatch (const char *filename,
+                                      const char *maskstring,
+                                      gpa_filewatch_cb_t cb,
+                                      void *cb_data);
+
+
 /*-- utils.c --*/
 /* We are so used to these function thus provide them.  */
 void *xmalloc (size_t n);

Modified: trunk/src/gpacardreloadop.c
===================================================================
--- trunk/src/gpacardreloadop.c	2008-12-16 11:14:15 UTC (rev 922)
+++ trunk/src/gpacardreloadop.c	2008-12-16 20:11:36 UTC (rev 923)
@@ -261,31 +261,25 @@
 static void
 process_line (char *line, gpa_card_reload_cb_t cb, void *opaque)
 {
-  char *save_ptr = NULL;
-  char *identifier;
+  char *field[5];
+  int fields = 0;
   int idx;
 
-  idx = 0;
-  identifier = strtok_r (line, ":", &save_ptr);
-  if (!identifier)
-    /* FIXME: maybe an assert here? -mo */
-    return;
+  /* Note that !line indicates EOF but we have no use for it here.  */
 
-  while (1)
+  while (line && fields < DIM (field))
     {
-      char *token;
-
-      token = strtok_r (NULL, ":", &save_ptr);
-      if (token)
-	{
-	  (*cb) (opaque, identifier, idx, token);
-	  idx++;
-	}
-      else
-	break;
+      field[fields++] = line;
+      line = strchr (line, ':');
+      if (line)
+	*line++ = 0;
     }
+
+  for (idx=1; idx < fields; idx++)
+    (*cb) (opaque, field[0], idx-1, field[idx]);
 }
 
+
 /* Processes the GPGME output contained in OUT, calling the callback
    CB with it's opaque argument OPAQUE for each data item. */
 static void

Modified: trunk/src/gpacontext.c
===================================================================
--- trunk/src/gpacontext.c	2008-12-16 11:14:15 UTC (rev 922)
+++ trunk/src/gpacontext.c	2008-12-16 20:11:36 UTC (rev 923)
@@ -434,18 +434,18 @@
 static void
 gpa_context_start (GpaContext *context)
 {
-  g_debug ("gpgme event START enter");
+/*   g_debug ("gpgme event START enter"); */
   context->busy = TRUE;
   /* We have START, register all queued callbacks */
   register_all_callbacks (context);
-  g_debug ("gpgme event START leave");
+/*   g_debug ("gpgme event START leave"); */
 }
 
 static void
 gpa_context_done (GpaContext *context, gpg_error_t err)
 {
   context->busy = FALSE;
-  g_debug ("gpgme event DONE ready");
+/*   g_debug ("gpgme event DONE ready"); */
 }
 
 static void



More information about the Gpa-commits mailing list