]> git.sesse.net Git - betaftpd/blobdiff - dcache.c
Fixed a security problem where the custom snprintf() would always be used. Thanks...
[betaftpd] / dcache.c
index bd0fcd70b229e1166c5392c92f909de23be15601..9ed8a27857c138276efe4e0b86d54c913bf0b478 100644 (file)
--- a/dcache.c
+++ b/dcache.c
@@ -2,7 +2,7 @@
     Copyright (C) 2000 Steinar H. Gunderson
 
     This program is is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License, version 2 if the
+    it under the terms of the GNU General Public License, version 2 of the
     License as published by the Free Software Foundation.
 
     This program is distributed in the hope that it will be useful,
 #include <config.h>
 #endif
 
-#if HAVE_TIME_H
-#include <time.h>
-#endif
-
-#if HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-
-#if HAVE_PWD_H
-#include <pwd.h>
-#endif
-
-#if HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-
-#if HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-
 #if HAVE_SYS_STAT_H
 #include <sys/stat.h>
 #endif
 
-#if HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-
 #if HAVE_STDLIB_H
 #include <stdlib.h>
 #endif
@@ -59,9 +35,8 @@
 #include <strings.h>
 #endif
 
-#include <ftpd.h>
-
 #if WANT_DCACHE
+#include <ftpd.h>
 #include <dcache.h>
 
 extern struct dcache *first_dcache;
@@ -88,6 +63,25 @@ struct dcache *alloc_new_dcache()
        return d;
 }
 
+/*
+ * destroy_dcache():
+ *             Destroy a directory listing cache entry, remove it from the
+ *             linked list, and clean up after it.
+ *
+ *             If you free a cache entry that is in use (use_count > 0),
+ *             BetaFTPD will most likely crash (later). The thing you're supposed
+ *             to do when you're done with a dcache entry, is to decrement
+ *             its use_count, and let the timeout functions do the destroying
+ *             when it's time to do so.
+ */
+void destroy_dcache(struct dcache * const d)
+{
+       if (d == NULL) return;
+
+       if (d->dir_data != NULL) free(d->dir_data);
+       remove_from_linked_list((struct list_element *)d);
+}
+
 /*
  * time_out_dcache():
  *             Time out expired directory listing cache entries.
@@ -133,4 +127,32 @@ void populate_dcache(struct ftran * const f, const char * const cwd,
                d->lo = *lo;
        }
 }
+
+/*
+ * find_dcache():
+ *             Check if there is an existing dcache object matching our
+ *             criteria.
+ */
+struct dcache *find_dcache(const char * const cwd, const char * const pattern,
+                           const struct list_options * const lo)
+{
+       struct dcache *d = NULL, *next = first_dcache->next_dcache;
+       struct stat buf;
+
+       if (stat(cwd, &buf) > -1) {
+               /* run through the linked list */
+               while (next != NULL) {
+                       d = next;
+                       next = d->next_dcache;
+
+                       if (buf.st_mtime <= d->generated &&
+                           strcmp(d->dir_name, cwd) == 0 &&
+                           strcmp(d->pattern, pattern) == 0 &&
+                           memcmp(&(d->lo), lo, sizeof(struct list_options)) == 0) {
+                               return d;
+                       }
+               }
+       }
+       return NULL;
+}
 #endif /* WANT_DCACHE */