CFLAGS = @CFLAGS@
REAL_CFLAGS = $(CFLAGS) @DEFS@ -I@srcdir@ -I. -DVERSION=\"$(VERSION)\"
LIBS = @LIBS@
-OBJS = disp.o ftpd.o cmds.o nonroot.o ascii.o
-ASSMS = disp.s ftpd.s cmds.s nonroot.s ascii.s
-CPPS = disp.i ftpd.i cmds.i nonroot.i ascii.i
+OBJS = disp.o ftpd.o cmds.o nonroot.o ascii.o dcache.o
+ASSMS = disp.s ftpd.s cmds.s nonroot.s ascii.s dcache.s
+CPPS = disp.i ftpd.i cmds.i nonroot.i ascii.i dcache.i
# Since we use VPATH, override .c.o rule
.c.o: $*.c config.h
$(CC) $(REAL_CFLAGS) -S @srcdir@/$*.c
# deps
-cmds.o: @srcdir@/cmds.c @srcdir@/ftpd.h @srcdir@/cmds.h @srcdir@/nonroot.h config.h
-ftpd.o: @srcdir@/ftpd.c @srcdir@/ftpd.h @srcdir@/cmds.h config.h
+cmds.o: @srcdir@/cmds.c @srcdir@/ftpd.h @srcdir@/cmds.h @srcdir@/nonroot.h @srcdir@/dcache.h config.h
+ftpd.o: @srcdir@/ftpd.c @srcdir@/ftpd.h @srcdir@/cmds.h @srcdir@/dcache.h config.h
disp.o: @srcdir@/disp.c @srcdir@/ftpd.h config.h
nonroot.o: @srcdir@/nonroot.c @srcdir@/nonroot.h config.h
-ascii.o: @srcdir@/ascii.c config.h
+ascii.o: @srcdir@/ascii.c @srcdir@/ascii.h config.h
+dcache.o: @srcdir@/dcache.c @srcdir@/dcache.h config.h
betaftpd: $(OBJS)
$(CC) $(REAL_CFLAGS) $(LIBS) -o betaftpd $(OBJS)
-cvs2cl.pl -U users
cp ChangeLog README Makefile.in acconfig.h cmds.c cmds.h betaftpd-$(VERSION)
cp config.h.in configure configure.in disp.c ftpd.c betaftpd-$(VERSION)
- cp nonroot.c ascii.c ascii.h nonroot.h ftpd.h strip-exec betaftpd.lsm betaftpd-$(VERSION)
+ cp nonroot.c ascii.c ascii.h nonroot.h ftpd.h betaftpd-$(VERSION)
+ cp dcache.c dcache.h strip-exec betaftpd.lsm betaftpd-$(VERSION)
cp doc/CREDITS doc/CHANGES doc/CHANGES-0.0.8 doc/COPYING betaftpd-$(VERSION)/doc
cp doc/KNOWN-BUGS doc/RFC-COMPLIANCE doc/README.nonroot betaftpd-$(VERSION)/doc
cp doc/README.rights doc/README.platforms betaftpd-$(VERSION)/doc
#include <cmds.h>
#include <nonroot.h>
+#if WANT_DCACHE
+#include <dcache.h>
+#endif
+
#define lstat stat
extern struct conn *first_conn;
#endif
#if WANT_DCACHE
- /* populate the directory listing cache */
- {
- struct stat buf;
- struct dcache *d = alloc_new_dcache();
- if (d != NULL && stat(cwd, &buf) > -1) {
- d->use_count++;
- f->dir_cache = d;
- d->dir_data = f->file_data;
- d->dir_size = f->size;
- d->generated = buf.st_mtime;
-
- strcpy(d->dir_name, cwd);
- strncpy(d->pattern, ptr, 255);
- d->pattern[255] = 0;
- d->lo = *lo;
- }
- }
+ populate_dcache(f, cwd, ptr, lo);
#endif
#if HAVE_MMAP
/* Define if you have the <grp.h> header file. */
#undef HAVE_GRP_H
+/* Define if you have the <linux/socket.h> header file. */
+#undef HAVE_LINUX_SOCKET_H
+
+/* Define if you have the <linux/tcp.h> header file. */
+#undef HAVE_LINUX_TCP_H
+
/* Define if you have the <netdb.h> header file. */
#undef HAVE_NETDB_H
fi
if test "$result" = "no"; then
- ac_safe=`echo "linux/socket.h" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for linux/socket.h""... $ac_c" 1>&6
-echo "configure:2315: checking for linux/socket.h" >&5
+ for ac_hdr in linux/socket.h linux/tcp.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:2317: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2320 "configure"
+#line 2322 "configure"
#include "confdefs.h"
-#include <linux/socket.h>
+#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2325: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2327: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
fi
if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
echo "$ac_t""yes" 1>&6
- :
-else
- echo "$ac_t""no" 1>&6
-fi
-
- ac_safe=`echo "linux/tcp.h" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for linux/tcp.h""... $ac_c" 1>&6
-echo "configure:2348: checking for linux/tcp.h" >&5
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2353 "configure"
-#include "confdefs.h"
-#include <linux/tcp.h>
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2358: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=yes"
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- :
+
else
echo "$ac_t""no" 1>&6
fi
+done
fi
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:2385: checking for $ac_hdr" >&5
+echo "configure:2359: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2390 "configure"
+#line 2364 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2395: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2369: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
echo $ac_n "checking for poll()""... $ac_c" 1>&6
-echo "configure:2423: checking for poll()" >&5
+echo "configure:2397: checking for poll()" >&5
cat > conftest.$ac_ext <<EOF
-#line 2425 "configure"
+#line 2399 "configure"
#include "confdefs.h"
#if HAVE_SYS_POLL_H
; return 0; }
EOF
-if { (eval echo configure:2442: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2416: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
enableval=yes
else
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:2465: checking for $ac_hdr" >&5
+echo "configure:2439: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2470 "configure"
+#line 2444 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2475: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2449: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
if test "$result" = "yes"; then
echo $ac_n "checking for Linux sendfile()""... $ac_c" 1>&6
-echo "configure:2505: checking for Linux sendfile()" >&5
+echo "configure:2479: checking for Linux sendfile()" >&5
cat > conftest.$ac_ext <<EOF
-#line 2507 "configure"
+#line 2481 "configure"
#include "confdefs.h"
#if HAVE_SYS_SOCKET_H
; return 0; }
EOF
-if { (eval echo configure:2548: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2522: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
enableval=yes
else
if test "$enableval" = "yes"; then
echo $ac_n "checking that sendfile() really is implemented""... $ac_c" 1>&6
-echo "configure:2562: checking that sendfile() really is implemented" >&5
+echo "configure:2536: checking that sendfile() really is implemented" >&5
if test "$cross_compiling" = yes; then
enableval="cross-compiling, not checked"
else
cat > conftest.$ac_ext <<EOF
-#line 2568 "configure"
+#line 2542 "configure"
#include "confdefs.h"
#if HAVE_SYS_SOCKET_H
return 1;
}
EOF
-if { (eval echo configure:2612: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2586: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
enableval=no
else
has_sendfile=disabled
fi
echo $ac_n "checking final status of Linux sendfile() support""... $ac_c" 1>&6
-echo "configure:2645: checking final status of Linux sendfile() support" >&5
+echo "configure:2619: checking final status of Linux sendfile() support" >&5
echo "$ac_t""$has_sendfile" 1>&6
fi
fi
ac_safe=`echo "sys/uio.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for sys/uio.h""... $ac_c" 1>&6
-echo "configure:2652: checking for sys/uio.h" >&5
+echo "configure:2626: checking for sys/uio.h" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2657 "configure"
+#line 2631 "configure"
#include "confdefs.h"
#include <sys/uio.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2662: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2636: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
if test "$result" = "yes"; then
echo $ac_n "checking for BSD sendfile()""... $ac_c" 1>&6
-echo "configure:2686: checking for BSD sendfile()" >&5
+echo "configure:2660: checking for BSD sendfile()" >&5
cat > conftest.$ac_ext <<EOF
-#line 2688 "configure"
+#line 2662 "configure"
#include "confdefs.h"
#if HAVE_SYS_LIMITS_H
; return 0; }
EOF
-if { (eval echo configure:2729: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2703: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
enableval=yes
else
fi
if test "$result" = "no"; then
- AC_CHECK_HEADER(linux/socket.h)
- AC_CHECK_HEADER(linux/tcp.h)
+ AC_CHECK_HEADERS(linux/socket.h linux/tcp.h)
fi
AC_CHECK_HEADERS(sys/poll.h)
--- /dev/null
+/* dcache.c: BetaFTPD directory listing cache
+ 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
+ License as published by the Free Software Foundation.
+
+ This program 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#if HAVE_CONFIG_H
+#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
+
+#if HAVE_STRING_H
+#include <string.h>
+#endif
+
+#if HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
+#include <ftpd.h>
+
+#if WANT_DCACHE
+#include <dcache.h>
+
+extern struct dcache *first_dcache;
+
+/*
+ * alloc_new_dcache():
+ * Allocates a new directory cache entry (type `struct dcache'),
+ * and adds it to the linked list.
+ */
+struct dcache *alloc_new_dcache()
+{
+ struct dcache *d = (struct dcache *)(malloc(sizeof(struct dcache)));
+
+ if (d == NULL) return d;
+
+ d->use_count = 0;
+ d->last_used = 0;
+ strcpy(d->dir_name, "");
+ d->dir_data = NULL;
+
+ add_to_linked_list((struct list_element *)first_dcache,
+ (struct list_element *)d);
+
+ return d;
+}
+
+/*
+ * time_out_dcache():
+ * Time out expired directory listing cache entries.
+ * Uses much of the same code as time_out_sockets().
+ */
+void time_out_dcache()
+{
+ struct dcache *d = NULL, *next = first_dcache->next_dcache;
+ time_t now = time(NULL);
+
+ /* run through the linked list */
+ while (next != NULL) {
+ d = next;
+ next = d->next_dcache;
+
+ if (d->use_count == 0 && (now - d->last_used > 900)) {
+ destroy_dcache(d);
+ }
+ }
+}
+
+/*
+ * populate_dcache():
+ * Add a new entry in the dcache, using information from
+ * the given file transfer object, and the current directory
+ * (cwd).
+ */
+void populate_dcache(struct ftran * const f, const char * const cwd,
+ const char * const pattern, const struct list_options * const lo)
+{
+ struct stat buf;
+ struct dcache *d = alloc_new_dcache();
+ if (d != NULL && stat(cwd, &buf) > -1) {
+ d->use_count++;
+ f->dir_cache = d;
+ d->dir_data = f->file_data;
+ d->dir_size = f->size;
+ d->generated = buf.st_mtime;
+
+ strcpy(d->dir_name, cwd);
+ strncpy(d->pattern, pattern, 255);
+ d->pattern[255] = 0;
+ d->lo = *lo;
+ }
+}
+#endif /* WANT_DCACHE */
--- /dev/null
+/* dcache.h: BetaFTPD directory cache prototypes
+ 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
+ License as published by the Free Software Foundation.
+
+ This program 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/* doubly linked list of cached directory listings */
+struct dcache {
+ struct dcache *prev_dcache;
+ struct dcache *next_dcache;
+
+ int use_count;
+ time_t last_used;
+ time_t generated;
+
+ char dir_name[256];
+ char pattern[256];
+ struct list_options lo;
+
+ char *dir_data;
+ int dir_size;
+};
+
+struct dcache *alloc_new_dcache();
+void time_out_dcache();
+void populate_dcache(struct ftran * const f, const char * const cwd,
+ const char * const pattern, const struct list_options * const lo);
#include <ascii.h>
#endif
+#if WANT_DCACHE
+#include <dcache.h>
+#endif
+
#ifndef MAP_FAILED
#define MAP_FAILED -1
#endif
return f;
}
-#if WANT_DCACHE
-/*
- * alloc_new_dcache():
- * Allocates a new directory cache entry (type `struct dcache'),
- * and adds it to the linked list.
- */
-struct dcache *alloc_new_dcache()
-{
- struct dcache *d = (struct dcache *)(malloc(sizeof(struct dcache)));
-
- if (d == NULL) return d;
-
- d->use_count = 0;
- d->last_used = 0;
- strcpy(d->dir_name, "");
- d->dir_data = NULL;
-
- add_to_linked_list((struct list_element *)first_dcache,
- (struct list_element *)d);
-
- return d;
-}
-#endif
-
/*
* destroy_conn():
* Destroy a control connection, remove it from the linked
}
}
-#if WANT_DCACHE
-/*
- * time_out_dcache():
- * Time out expired directory listing cache entries.
- * Uses much of the same code as time_out_sockets().
- */
-void time_out_dcache()
-{
- struct dcache *d = NULL, *next = first_dcache->next_dcache;
- time_t now = time(NULL);
-
- /* run through the linked list */
- while (next != NULL) {
- d = next;
- next = d->next_dcache;
-
- if (d->use_count == 0 && (now - d->last_used > 900)) {
- destroy_dcache(d);
- }
- }
-}
-#endif
-
/*
* remove_bytes():
* Remove some bytes from the incoming buffer. This gives
time_t last_transfer;
};
-#if WANT_DCACHE
-/* doubly linked list of cached directory listings */
-struct dcache {
- struct dcache *prev_dcache;
- struct dcache *next_dcache;
-
- int use_count;
- time_t last_used;
- time_t generated;
-
- char dir_name[256];
- char pattern[256];
- struct list_options lo;
-
- char *dir_data;
- int dir_size;
-};
-#endif
-
/* doubly linked list of file transfers */
struct ftran {
struct ftran *prev_ftran;