Preparing a new release. Updated gettext
[gnupg.git] / agent / gpg-agent.c
index f7e701b..4e3f0b5 100644 (file)
@@ -77,8 +77,9 @@ enum cmd_and_opt_values
   oLCctype,
   oLCmessages,
   oScdaemonProgram,
-  oDefCacheTTL,
   oDisablePth,
+  oDefCacheTTL,
+  oMaxCacheTTL,
 
   oIgnoreCacheForSigning,
   oAllowMarkTrusted,
@@ -127,6 +128,7 @@ static ARGPARSE_OPTS opts[] = {
 
   { oDefCacheTTL, "default-cache-ttl", 4,
                                N_("|N|expire cached PINs after N seconds")},
+  { oMaxCacheTTL, "max-cache-ttl", 4, "@" },
   { oIgnoreCacheForSigning, "ignore-cache-for-signing", 0,
                                N_("do not use the PIN cache when signing")},
   { oAllowMarkTrusted, "allow-mark-trusted", 0,
@@ -135,7 +137,8 @@ static ARGPARSE_OPTS opts[] = {
 };
 
 
-#define DEFAULT_CACHE_TTL (10*60) /* 10 minutes */
+#define DEFAULT_CACHE_TTL (10*60)  /* 10 minutes */
+#define MAX_CACHE_TTL     (120*60) /* 2 hours */
 
 static volatile int caught_fatal_sig = 0;
 
@@ -175,6 +178,7 @@ static void handle_connections (int listen_fd);
 GCRY_THREAD_OPTION_PTH_IMPL;
 
 #endif /*USE_GNU_PTH*/
+static void check_for_running_agent (void);
 
 
 
@@ -342,6 +346,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
       opt.pinentry_program = NULL;
       opt.scdaemon_program = NULL;
       opt.def_cache_ttl = DEFAULT_CACHE_TTL;
+      opt.max_cache_ttl = MAX_CACHE_TTL;
       opt.ignore_cache_for_signing = 0;
       opt.allow_mark_trusted = 0;
       return 1;
@@ -357,8 +362,9 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
     case oDebugLevel: debug_level = pargs->r.ret_str; break;
 
     case oLogFile:
-      if (!current_logfile || !pargs->r.ret_str
-          || strcmp (current_logfile, pargs->r.ret_str))
+      if (reread 
+          && (!current_logfile || !pargs->r.ret_str
+              || strcmp (current_logfile, pargs->r.ret_str)))
         {
           log_set_file (pargs->r.ret_str);
           xfree (current_logfile);
@@ -372,6 +378,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
     case oScdaemonProgram: opt.scdaemon_program = pargs->r.ret_str; break;
 
     case oDefCacheTTL: opt.def_cache_ttl = pargs->r.ret_ulong; break;
+    case oMaxCacheTTL: opt.max_cache_ttl = pargs->r.ret_ulong; break;
       
     case oIgnoreCacheForSigning: opt.ignore_cache_for_signing = 1; break;
 
@@ -594,7 +601,9 @@ main (int argc, char **argv )
       fprintf (stderr, "%s\n", strusage(15) );
     }
 #ifdef IS_DEVELOPMENT_VERSION
-  log_info ("NOTE: this is a development version!\n");
+  /* We don't want to print it here because gpg-agent is useful of its
+     own and quite matured.  */
+  /*log_info ("NOTE: this is a development version!\n");*/
 #endif
 
   set_debug ();
@@ -664,9 +673,15 @@ main (int argc, char **argv )
       agent_exit (0);
     }
 
+  /* If this has been called without any options, we merely check
+     whether an agent is already running.  We do this here so that we
+     don't clobber a logfile but print it directly to stderr. */
   if (!pipe_server && !is_daemon)
-    log_info (_("please use the option `--daemon'"
-                " to run the program in the background\n"));
+    {
+      log_set_prefix (NULL, JNLIB_LOG_WITH_PREFIX); 
+      check_for_running_agent ();
+      agent_exit (0);
+    }
   
 #ifdef ENABLE_NLS
   /* gpg-agent usually does not output any messages because it runs in
@@ -700,9 +715,9 @@ main (int argc, char **argv )
       start_command_handler (-1, -1);
     }
   else if (!is_daemon)
-    ;
+    ; /* NOTREACHED */
   else
-    { /* regular server mode */
+    { /* Regular server mode */
       int fd;
       pid_t pid;
       int len;
@@ -1215,3 +1230,56 @@ handle_connections (int listen_fd)
   log_info ("%s %s stopped\n", strusage(11), strusage(13));
 }
 #endif /*USE_GNU_PTH*/
+
+
+/* Figure out whether an agent is available and running. Prints an
+   error if not.  */
+static void
+check_for_running_agent ()
+{
+  int rc;
+  char *infostr, *p;
+  assuan_context_t ctx;
+  int prot, pid;
+
+  infostr = getenv ("GPG_AGENT_INFO");
+  if (!infostr || !*infostr)
+    {
+      log_error (_("no gpg-agent running in this session\n"));
+      return;
+    }
+
+  infostr = xstrdup (infostr);
+  if ( !(p = strchr (infostr, ':')) || p == infostr)
+    {
+      log_error (_("malformed GPG_AGENT_INFO environment variable\n"));
+      xfree (infostr);
+      return;
+    }
+
+  *p++ = 0;
+  pid = atoi (p);
+  while (*p && *p != ':')
+    p++;
+  prot = *p? atoi (p+1) : 0;
+  if (prot != 1)
+    {
+      log_error (_("gpg-agent protocol version %d is not supported\n"),
+                 prot);
+      xfree (infostr);
+      return;
+    }
+
+  rc = assuan_socket_connect (&ctx, infostr, pid);
+  xfree (infostr);
+  if (rc)
+    {
+      log_error ("can't connect to the agent: %s\n", assuan_strerror (rc));
+      return;
+    }
+
+  if (!opt.quiet)
+    log_info ("gpg-agent running and available\n");
+
+  assuan_disconnect (ctx);
+}