The big Assuan error code removal.
[gnupg.git] / agent / cache.c
index b6ab550..2f46839 100644 (file)
@@ -15,7 +15,8 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
  */
 
 #include <config.h>
@@ -39,9 +40,10 @@ struct cache_item_s {
   ITEM next;
   time_t created;
   time_t accessed;
-  int  ttl;  /* max. lifetime given in seonds */
+  int ttl;  /* max. lifetime given in seconds, -1 one means infinite */
   int lockcount;
   struct secret_data_s *pw;
+  cache_mode_t cache_mode;
   char key[1];
 };
 
@@ -78,6 +80,7 @@ new_data (const void *data, size_t length)
 }
 
 
+
 /* check whether there are items to expire */
 static void
 housekeeping (void)
@@ -85,10 +88,11 @@ housekeeping (void)
   ITEM r, rprev;
   time_t current = gnupg_get_time ();
 
-  /* first expire the actual data */
+  /* First expire the actual data */
   for (r=thecache; r; r = r->next)
     {
-      if (!r->lockcount && r->pw && r->accessed + r->ttl < current)
+      if (!r->lockcount && r->pw
+         && r->ttl >= 0 && r->accessed + r->ttl < current)
         {
           if (DBG_CACHE)
             log_debug ("  expired `%s' (%ds after last access)\n",
@@ -99,25 +103,33 @@ housekeeping (void)
         }
     }
 
-  /* second, make sure that we also remove them based on the created stamp so
-     that the user has to enter it from time to time.  We do this every hour */
+  /* Second, make sure that we also remove them based on the created stamp so
+     that the user has to enter it from time to time. */
   for (r=thecache; r; r = r->next)
     {
-      if (!r->lockcount && r->pw && r->created + 60*60 < current)
+      unsigned long maxttl;
+      
+      switch (r->cache_mode)
+        {
+        case CACHE_MODE_SSH: maxttl = opt.max_cache_ttl_ssh; break;
+        default: maxttl = opt.max_cache_ttl; break;
+        }
+      if (!r->lockcount && r->pw && r->created + maxttl < current)
         {
           if (DBG_CACHE)
-            log_debug ("  expired `%s' (1h after creation)\n", r->key);
+            log_debug ("  expired `%s' (%lus after creation)\n",
+                       r->key, opt.max_cache_ttl);
           release_data (r->pw);
           r->pw = NULL;
           r->accessed = current;
         }
     }
 
-  /* third, make sure that we don't have too many items in the list.
+  /* Third, make sure that we don't have too many items in the list.
      Expire old and unused entries after 30 minutes */
   for (rprev=NULL, r=thecache; r; )
     {
-      if (!r->pw && r->accessed + 60*30 < current)
+      if (!r->pw && r->ttl >= 0 && r->accessed + 60*30 < current)
         {
           if (r->lockcount)
             {
@@ -183,19 +195,29 @@ agent_flush_cache (void)
 /* Store DATA of length DATALEN in the cache under KEY and mark it
    with a maximum lifetime of TTL seconds.  If there is already data
    under this key, it will be replaced.  Using a DATA of NULL deletes
-   the entry */
+   the entry.  A TTL of 0 is replaced by the default TTL and a TTL of
+   -1 set infinite timeout. CACHE_MODE is stored with the cache entry
+   and used t select different timeouts. */
 int
-agent_put_cache (const char *key, const char *data, int ttl)
+agent_put_cache (const char *key, cache_mode_t cache_mode,
+                 const char *data, int ttl)
 {
   ITEM r;
 
   if (DBG_CACHE)
-    log_debug ("agent_put_cache `%s'\n", key);
+    log_debug ("agent_put_cache `%s' requested ttl=%d mode=%d\n",
+               key, ttl, cache_mode);
   housekeeping ();
 
-  if (ttl < 1)
-    ttl = opt.def_cache_ttl;
   if (!ttl)
+    {
+      switch(cache_mode)
+        {
+        case CACHE_MODE_SSH: ttl = opt.def_cache_ttl_ssh; break;
+        default: ttl = opt.def_cache_ttl; break;
+        }
+    }
+  if (!ttl || cache_mode == CACHE_MODE_IGNORE)
     return 0;
 
   for (r=thecache; r; r = r->next)
@@ -214,6 +236,7 @@ agent_put_cache (const char *key, const char *data, int ttl)
         {
           r->created = r->accessed = gnupg_get_time (); 
           r->ttl = ttl;
+          r->cache_mode = cache_mode;
           r->pw = new_data (data, strlen (data)+1);
           if (!r->pw)
             log_error ("out of core while allocating new cache item\n");
@@ -229,6 +252,7 @@ agent_put_cache (const char *key, const char *data, int ttl)
           strcpy (r->key, key);
           r->created = r->accessed = gnupg_get_time (); 
           r->ttl = ttl;
+          r->cache_mode = cache_mode;
           r->pw = new_data (data, strlen (data)+1);
           if (!r->pw)
             {
@@ -246,12 +270,16 @@ agent_put_cache (const char *key, const char *data, int ttl)
 }
 
 
-/* Try to find an item in the cache */
+/* Try to find an item in the cache.  Note that we currently don't
+   make use of CACHE_MODE.  */
 const char *
-agent_get_cache (const char *key, void **cache_id)
+agent_get_cache (const char *key, cache_mode_t cache_mode, void **cache_id)
 {
   ITEM r;
 
+  if (cache_mode == CACHE_MODE_IGNORE)
+    return NULL;
+
   if (DBG_CACHE)
     log_debug ("agent_get_cache `%s'...\n", key);
   housekeeping ();