diff options
Diffstat (limited to 'examples/VFS')
-rw-r--r-- | examples/VFS/.cvsignore | 4 | ||||
-rw-r--r-- | examples/VFS/Makefile | 35 | ||||
-rw-r--r-- | examples/VFS/Makefile.in | 31 | ||||
-rw-r--r-- | examples/VFS/README | 11 | ||||
-rw-r--r-- | examples/VFS/block/Makefile | 37 | ||||
-rw-r--r-- | examples/VFS/block/block.c | 14 | ||||
-rwxr-xr-x | examples/VFS/configure | 1161 | ||||
-rw-r--r-- | examples/VFS/configure.in | 92 | ||||
-rw-r--r-- | examples/VFS/recycle.c | 287 | ||||
-rw-r--r-- | examples/VFS/recycle/README | 83 | ||||
-rw-r--r-- | examples/VFS/recycle/cleanup_recycle.pl | 25 | ||||
-rw-r--r-- | examples/VFS/recycle/recycle.c | 556 | ||||
-rw-r--r-- | examples/VFS/recycle/recycle.conf | 17 |
13 files changed, 1985 insertions, 368 deletions
diff --git a/examples/VFS/.cvsignore b/examples/VFS/.cvsignore index 0b0923a496a..e3ebfe8e3d5 100644 --- a/examples/VFS/.cvsignore +++ b/examples/VFS/.cvsignore @@ -1,2 +1,6 @@ .libs *.so +Makefile +config.status +config.log +config.cache diff --git a/examples/VFS/Makefile b/examples/VFS/Makefile deleted file mode 100644 index eaa1ffbb54e..00000000000 --- a/examples/VFS/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -# -# Makefile for samba-vfs examples -# -# - -# Variables - -CC = gcc -LIBTOOL = libtool - -SAMBA_SRC = ../../source -SAMBA_INCL = ../../source/include -UBIQX_SRC = ../../source/ubiqx -SMBWR_SRC = ../../source/smbwrapper -CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -Wall -g -VFS_OBJS = audit.so skel.so recycle.so - -# Default target - -default: $(VFS_OBJS) - -# Pattern rules - -%.so: %.lo - $(LIBTOOL) $(CC) -shared -o $@ $< $(LDFLAGS) - -%.lo: %.c - $(LIBTOOL) $(CC) $(CPPFLAGS) $(CFLAGS) -c $< - -# Misc targets - -clean: - rm -rf .libs - rm -f core *~ *% *.bak \ - $(VFS_OBJS) $(VFS_OBJS:.so=.o) $(VFS_OBJS:.so=.lo) diff --git a/examples/VFS/Makefile.in b/examples/VFS/Makefile.in new file mode 100644 index 00000000000..a39ab511dd1 --- /dev/null +++ b/examples/VFS/Makefile.in @@ -0,0 +1,31 @@ +########################################################################## +# Makefile.in for Samba VFS modules +########################################################################### + +CC=@CC@ +LIBTOOL=@LIBTOOL@ +CFLAGS=@CFLAGS@ +LDFLAGS=@LDFLAGS@ + +VFS_OBJS=audit.so skel.so block/block.so recycle/recycle.so + +SHELL=/bin/sh + +default: $(VFS_OBJS) + +# Pattern rules + +%.so: %.lo + @echo Linking $< + @$(LIBTOOL) --mode=link $(CC) -o $@ $< $(LDFLAGS) + +%.lo: %.c + @echo Compiling $< + @$(LIBTOOL) --mode=compile $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@ + +# Misc targets + +clean: + rm -rf .libs */.libs + rm -f core *~ *% *.bak *.o */*.o *.lo $(VFS_OBJS) + diff --git a/examples/VFS/README b/examples/VFS/README index d3053a48f3b..475c4ec43fe 100644 --- a/examples/VFS/README +++ b/examples/VFS/README @@ -17,14 +17,9 @@ construction. The following VFS modules are given: connect/disconnect, directory opens/create/remove, file open/close/rename/unlink/chmod. - recycle - Add a recycle bin facility to a samba share - Copy this to somewhere like /usr/local/samba/lib/recycle.so - and then add these options on a per-share basis to enable the - recycle bin : - - vfs object = /usr/local/samba/lib/recycle.so - vfs options= recycle=.recycle + recycle/ + Add a recycle bin facility to a samba share. + see recycle/README for details block/ diff --git a/examples/VFS/block/Makefile b/examples/VFS/block/Makefile deleted file mode 100644 index 4887915fb4f..00000000000 --- a/examples/VFS/block/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -# -# Makefile for samba-vfs examples -# -# - -# Variables - -CC = gcc -LIBTOOL = libtool - -SAMBA_SRC = ../../../source -SAMBA_INCL = ${SAMBA_SRC}/include -UBIQX_SRC = ${SAMBA_SRC}/ubiqx -SMBWR_SRC = ${SAMBA_SRC}/smbwrapper -CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -Wall -g - - -VFS_OBJS = block.so - -# Default target - -default: $(VFS_OBJS) - -# Pattern rules - -%.so: %.lo - $(LIBTOOL) $(CC) -shared -o $@ $< $(LDFLAGS) - -%.lo: %.c - $(LIBTOOL) $(CC) $(CPPFLAGS) $(CFLAGS) -c $< - -# Misc targets - -clean: - rm -rf .libs - rm -f core *~ *% *.bak \ - $(VFS_OBJS) $(VFS_OBJS:.so=.o) $(VFS_OBJS:.so=.lo) diff --git a/examples/VFS/block/block.c b/examples/VFS/block/block.c index 8c0fa61d506..a8b17a35dd4 100644 --- a/examples/VFS/block/block.c +++ b/examples/VFS/block/block.c @@ -47,6 +47,7 @@ + DIR *block_opendir(struct connection_struct *conn, const char *fname); int block_connect(struct connection_struct *conn, const char *service, const char *user); void block_disconnect(struct connection_struct *conn); @@ -461,7 +462,18 @@ BOOL search(struct stat *stat_buf) BOOL dir_search(char *link, const char *dir) { - char buf[PATH_MAX +1], *ext_path; + char *ext_path; + +#ifdef PATH_MAX + char buf[PATH_MAX +1]; +#else +#ifdef MAXPATHLEN + char buf[MAXPATHLEN +1]; +#else + char buf[BUFSIZ]; +#endif +#endif + int len = 0; struct block_dir *tmp_pblock = pblock_dir; diff --git a/examples/VFS/configure b/examples/VFS/configure new file mode 100755 index 00000000000..e70d69f02d7 --- /dev/null +++ b/examples/VFS/configure @@ -0,0 +1,1161 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: +ac_help="$ac_help + --with-included-popt use bundled popt library, not from system" + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file= + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + +uname=`uname` + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:533: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:563: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:614: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:646: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 657 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:662: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:688: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:693: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <<EOF +#ifdef __GNUC__ + yes; +#endif +EOF +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:702: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:721: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + + +# Extract the first word of "libtool", so it can be a program name with args. +set dummy libtool; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:756: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_LIBTOOL'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$LIBTOOL" in + /*) + ac_cv_path_LIBTOOL="$LIBTOOL" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_LIBTOOL="$LIBTOOL" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_LIBTOOL="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + ;; +esac +fi +LIBTOOL="$ac_cv_path_LIBTOOL" +if test -n "$LIBTOOL"; then + echo "$ac_t""$LIBTOOL" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test "$LIBTOOL" = ""; then + echo + echo 'FATAL ERROR: libtool does not seem to be installed.' + echo $pkg_name cannot be built without a working libtool installation. + exit 1 +fi + +# +# Config CFLAGS settings +# +CFLAGS="-Wall" + +case "$uname" in + AIX) + if test "${GCC}" = "yes"; then + CFLAGS="$CFLAGS -I/usr/include -D_LINUX_SOURCE_COMPAT" + else + CFLAGS="-D_LINUX_SOURCE_COMPAT" + fi + ;; + SunOS) + if test "${GCC}" = "yes"; then + CFLAGS="$CFLAGS" + else + CFLAGS="" + fi + ;; +# Linux) +# CFLAGS="-Wall" +# ;; +esac + +# +# Config LDLAGS settings +# +LDFLAGS="-shared" + +case "$uname" in + AIX) + LDFLAGS="-Wl,-G,-bexpall,-bnoentry" + ;; + SunOS) + LDFLAGS="-G" + ;; +# Linux) +# echo "Linux found" +# LDFLAGS="-shared" +# ;; +esac + +################################################# +# Check to see if we should use the included popt + +# Check whether --with-included-popt or --without-included-popt was given. +if test "${with_included_popt+set}" = set; then + withval="$with_included_popt" + + case "$withval" in + yes) + INCLUDED_POPT=yes + ;; + no) + INCLUDED_POPT=no + ;; + esac +fi + +if test x"$INCLUDED_POPT" != x"yes"; then + echo $ac_n "checking for poptGetContext in -lpopt""... $ac_c" 1>&6 +echo "configure:857: checking for poptGetContext in -lpopt" >&5 +ac_lib_var=`echo popt'_'poptGetContext | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lpopt $LIBS" +cat > conftest.$ac_ext <<EOF +#line 865 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char poptGetContext(); + +int main() { +poptGetContext() +; return 0; } +EOF +if { (eval echo configure:876: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + INCLUDED_POPT=no +else + echo "$ac_t""no" 1>&6 +INCLUDED_POPT=yes +fi + +fi + +echo $ac_n "checking whether to use included popt""... $ac_c" 1>&6 +echo "configure:900: checking whether to use included popt" >&5 +if test x"$INCLUDED_POPT" = x"yes"; then + echo "$ac_t""$srcdir/popt" 1>&6 + CFLAGS="$CFLAGS -I../../source/popt" +else + echo "$ac_t""no" 1>&6 +fi + +CFLAGS="$CFLAGS -I../../source -I../../source/include -I../../source/ubiqx -I../../source/smbwrapper" + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +cat > conftest.defs <<\EOF +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g +s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g +s%\[%\\&%g +s%\]%\\&%g +s%\$%$$%g +EOF +DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` +rm -f conftest.defs + + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS <<EOF +#! /bin/sh +# Generated automatically by configure. +# Run this file to recreate the current configuration. +# This directory was configured as follows, +# on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir + +trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS <<EOF + +# Protect against being on the right side of a sed subst in config.status. +sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g; + s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@CC@%$CC%g +s%@LIBTOOL@%$LIBTOOL%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <<EOF + +CONFIG_FILES=\${CONFIG_FILES-"Makefile"} +EOF +cat >> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +EOF +cat >> $CONFIG_STATUS <<EOF + +EOF +cat >> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + diff --git a/examples/VFS/configure.in b/examples/VFS/configure.in new file mode 100644 index 00000000000..2afa2e1a044 --- /dev/null +++ b/examples/VFS/configure.in @@ -0,0 +1,92 @@ +dnl Samba VFS Modules + +AC_INIT + +uname=`uname` + +dnl Check programs needed +AC_PROG_CC + +dnl ensure libtool is installed +AC_PATH_PROG(LIBTOOL, libtool,,) +if test "$LIBTOOL" = ""; then + echo + echo 'FATAL ERROR: libtool does not seem to be installed.' + echo $pkg_name cannot be built without a working libtool installation. + exit 1 +fi + +# +# Config CFLAGS settings +# +CFLAGS="-Wall" + +case "$uname" in + AIX) + if test "${GCC}" = "yes"; then + CFLAGS="$CFLAGS -I/usr/include -D_LINUX_SOURCE_COMPAT" + else + CFLAGS="-D_LINUX_SOURCE_COMPAT" + fi + ;; + SunOS) + if test "${GCC}" = "yes"; then + CFLAGS="$CFLAGS" + else + CFLAGS="" + fi + ;; +# Linux) +# CFLAGS="-Wall" +# ;; +esac + +# +# Config LDLAGS settings +# +LDFLAGS="-shared" + +case "$uname" in + AIX) + LDFLAGS="-Wl,-G,-bexpall,-bnoentry" + ;; + SunOS) + LDFLAGS="-G" + ;; +# Linux) +# echo "Linux found" +# LDFLAGS="-shared" +# ;; +esac + +################################################# +# Check to see if we should use the included popt + +AC_ARG_WITH(included-popt, +[ --with-included-popt use bundled popt library, not from system], +[ + case "$withval" in + yes) + INCLUDED_POPT=yes + ;; + no) + INCLUDED_POPT=no + ;; + esac ], +) +if test x"$INCLUDED_POPT" != x"yes"; then + AC_CHECK_LIB(popt, poptGetContext, + INCLUDED_POPT=no, INCLUDED_POPT=yes) +fi + +AC_MSG_CHECKING(whether to use included popt) +if test x"$INCLUDED_POPT" = x"yes"; then + AC_MSG_RESULT($srcdir/popt) + CFLAGS="$CFLAGS -I../../source/popt" +else + AC_MSG_RESULT(no) +fi + +CFLAGS="$CFLAGS -I../../source -I../../source/include -I../../source/ubiqx -I../../source/smbwrapper" + +AC_OUTPUT([Makefile]) diff --git a/examples/VFS/recycle.c b/examples/VFS/recycle.c deleted file mode 100644 index 74d3657895a..00000000000 --- a/examples/VFS/recycle.c +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Auditing VFS module for samba. Log selected file operations to syslog - * facility. - * - * Copyright (C) 2001, Brandon Stone, Amherst College, <bbstone@amherst.edu>. - * Copyright (C) 2002, Jeremy Allison - modified to make a VFS module. - * - * This program 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 2 of the License, or - * (at your option) any later version. - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "config.h" -#include <stdio.h> -#include <sys/stat.h> -#ifdef HAVE_UTIME_H -#include <utime.h> -#endif -#ifdef HAVE_DIRENT_H -#include <dirent.h> -#endif -#include <syslog.h> -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif -#include <errno.h> -#include <string.h> -#include <includes.h> -#include <vfs.h> - -/* VFS operations */ - -extern struct vfs_ops default_vfs_ops; /* For passthrough operation */ - -static int recycle_unlink(connection_struct *, const char *); -static int recycle_connect(struct connection_struct *conn, const char *service, const char *user); -static void recycle_disconnect(struct connection_struct *conn); - -struct vfs_ops recycle_ops = { - - /* Disk operations */ - - recycle_connect, /* connect */ - recycle_disconnect, /* disconnect */ - NULL, /* disk free */ - - /* Directory operations */ - - NULL, /* opendir */ - NULL, /* readdir */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* closedir */ - - /* File operations */ - - NULL, /* open */ - NULL, /* close */ - NULL, /* read */ - NULL, /* write */ - NULL, /* lseek */ - NULL, /* rename */ - NULL, /* fsync */ - NULL, /* stat */ - NULL, /* fstat */ - NULL, /* lstat */ - recycle_unlink, - NULL, /* chmod */ - NULL, /* fchmod */ - NULL, /* chown */ - NULL, /* fchown */ - NULL, /* chdir */ - NULL, /* getwd */ - NULL, /* utime */ - NULL, /* ftruncate */ - NULL, /* lock */ - NULL, /* symlink */ - NULL, /* readlink */ - NULL, /* link */ - NULL, /* mknod */ - NULL, /* realpath */ - NULL, /* fget_nt_acl */ - NULL, /* get_nt_acl */ - NULL, /* fset_nt_acl */ - NULL, /* set_nt_acl */ - - NULL, /* chmod_acl */ - NULL, /* fchmod_acl */ - - NULL, /* sys_acl_get_entry */ - NULL, /* sys_acl_get_tag_type */ - NULL, /* sys_acl_get_permset */ - NULL, /* sys_acl_get_qualifier */ - NULL, /* sys_acl_get_file */ - NULL, /* sys_acl_get_fd */ - NULL, /* sys_acl_clear_perms */ - NULL, /* sys_acl_add_perm */ - NULL, /* sys_acl_to_text */ - NULL, /* sys_acl_init */ - NULL, /* sys_acl_create_entry */ - NULL, /* sys_acl_set_tag_type */ - NULL, /* sys_acl_set_qualifier */ - NULL, /* sys_acl_set_permset */ - NULL, /* sys_acl_valid */ - NULL, /* sys_acl_set_file */ - NULL, /* sys_acl_set_fd */ - NULL, /* sys_acl_delete_def_file */ - NULL, /* sys_acl_get_perm */ - NULL, /* sys_acl_free_text */ - NULL, /* sys_acl_free_acl */ - NULL /* sys_acl_free_qualifier */ -}; - -/* VFS initialisation function. Return initialised vfs_ops structure - back to SAMBA. */ - -struct vfs_ops *vfs_init(int *vfs_version, struct vfs_ops *def_vfs_ops) -{ - struct vfs_ops tmp_ops; - - *vfs_version = SMB_VFS_INTERFACE_VERSION; - memcpy(&tmp_ops, def_vfs_ops, sizeof(struct vfs_ops)); - tmp_ops.unlink = recycle_unlink; - tmp_ops.connect = recycle_connect; - tmp_ops.disconnect = recycle_disconnect; - memcpy(&recycle_ops, &tmp_ops, sizeof(struct vfs_ops)); - return &recycle_ops; -} - -static int recycle_connect(struct connection_struct *conn, const char *service, const char *user) -{ - pstring opts_str; - fstring recycle_bin; - char *p; - - DEBUG(3,("recycle_connect: called for service %s as user %s\n", service, user)); - - pstrcpy(opts_str, (const char *)lp_vfs_options(SNUM(conn))); - if (!*opts_str) { - DEBUG(3,("recycle_connect: No options listed (%s).\n", lp_vfs_options(SNUM(conn)) )); - return 0; /* No options. */ - } - - p = opts_str; - if (next_token(&p,recycle_bin,"=",sizeof(recycle_bin))) { - if (!strequal("recycle", recycle_bin)) { - DEBUG(3,("recycle_connect: option %s is not recycle\n", recycle_bin )); - return -1; - } - } - - if (!next_token(&p,recycle_bin," \n",sizeof(recycle_bin))) { - DEBUG(3,("recycle_connect: no option after recycle=\n")); - return -1; - } - - DEBUG(10,("recycle_connect: recycle name is %s\n", recycle_bin )); - - conn->vfs_private = (void *)strdup(recycle_bin); - return 0; -} - -static void recycle_disconnect(struct connection_struct *conn) -{ - SAFE_FREE(conn->vfs_private); -} - -static BOOL recycle_XXX_exist(connection_struct *conn, const char *dname, BOOL isdir) -{ - SMB_STRUCT_STAT st; - - if (default_vfs_ops.stat(conn,dname,&st) != 0) - return(False); - - if (isdir) - return S_ISDIR(st.st_mode) ? True : False; - else - return S_ISREG(st.st_mode) ? True : False; -} - -static BOOL recycle_directory_exist(connection_struct *conn, const char *dname) -{ - return recycle_XXX_exist(conn, dname, True); -} - -static BOOL recycle_file_exist(connection_struct *conn, const char *fname) -{ - return recycle_XXX_exist(conn, fname, False); -} - -static SMB_OFF_T recycle_get_file_size(connection_struct *conn, const char *fname) -{ - SMB_STRUCT_STAT st; - - if (default_vfs_ops.stat(conn,fname,&st) != 0) - return (SMB_OFF_T)-1; - - return(st.st_size); -} - -/******************************************************************** - Check if file should be recycled -*********************************************************************/ - -static int recycle_unlink(connection_struct *conn, const char *inname) -{ - fstring recycle_bin; - pstring fname; - char *base, *ext; - pstring bin; - int i=1, len, addlen; - int dir_mask=0770; - SMB_BIG_UINT dfree,dsize,bsize; - - *recycle_bin = '\0'; - pstrcpy(fname, inname); - - if (conn->vfs_private) - fstrcpy(recycle_bin, (const char *)conn->vfs_private); - - if(!*recycle_bin) { - DEBUG(3, ("recycle bin: share parameter not set, purging %s...\n", fname)); - return default_vfs_ops.unlink(conn,fname); - } - - if(recycle_get_file_size(conn, fname) == 0) { - DEBUG(3, ("recycle bin: file %s is empty, purging...\n", fname)); - return default_vfs_ops.unlink(conn,fname); - } - - base = strrchr(fname, '/') + 1; - if(base == (char*)1) - ext = strrchr(fname, '.'); - else - ext = strrchr(base, '.'); - - pstrcpy(bin, recycle_bin); - pstrcat(bin, "/"); - pstrcat(bin, base); - - if(strcmp(fname,bin) == 0) { - DEBUG(3, ("recycle bin: file %s exists, purging...\n", fname)); - return default_vfs_ops.unlink(conn,fname); - } - - len = strlen(bin); - addlen = sizeof(pstring)-len-1; - while(recycle_file_exist(conn,bin)) { - slprintf(bin+len, addlen, " (Copy #%d)", i++); - pstrcat(bin, ext); - } - - DEBUG(3, ("recycle bin: moving source=%s to dest=%s\n", fname, bin)); - default_vfs_ops.disk_free(conn,".",True,&bsize,&dfree,&dsize); - if((unsigned int)dfree > 0) { - int ret; - if(!recycle_directory_exist(conn,recycle_bin)) { - DEBUG(3, ("recycle bin: directory %s nonexistant, creating...\n", recycle_bin)); - if (default_vfs_ops.mkdir(conn,recycle_bin,dir_mask) == -1) { - DEBUG(3, ("recycle bin: unable to create directory %s. Error was %s\n", - recycle_bin, strerror(errno) )); - } - } - DEBUG(3, ("recycle bin: move %s -> %s\n", fname, bin)); - - ret = default_vfs_ops.rename(conn, fname, bin); - if (ret == -1) { - DEBUG(3, ("recycle bin: move error %d (%s)\n", errno, strerror(errno) )); - DEBUG(3, ("recycle bin: move failed, purging...\n")); - return default_vfs_ops.unlink(conn,fname); - } - return ret; - } else { - DEBUG(3, ("recycle bin: move failed, purging...\n")); - return default_vfs_ops.unlink(conn,fname); - } -} diff --git a/examples/VFS/recycle/README b/examples/VFS/recycle/README new file mode 100644 index 00000000000..2b85a65925e --- /dev/null +++ b/examples/VFS/recycle/README @@ -0,0 +1,83 @@ +The recycle VFS module implements a recycle bin for Samba. +Deleted files will be moved to a special directory and +not be deleted unless specified in the configuration file. +It is up to the administrator/user to clean up the files +in the recycle bin. + +Installation: + +1. Build VFS module using the GNU autoconf script and Makefile + in the parent directory (cd .. && ./configure && make) +2. Install module by copying to /usr/lib/samba/vfs (or any other place you like) +3. Install/modify recycle.conf. See below for the description +4. Modify smb.conf to use the recycle module + Add the lines "vfs object = /usr/lib/samba/recycle.so" + and "vfs options = /etc/samba/recycle.conf". +5. Start Samba + + +Options for recycle.conf: +name + name of the recycle bin at root level of the share + allows smb.conf substutitions like %U. + Example: + name = .recycle/%U + +mode + KEEP_DIRECTORIES : retain directory hierarchy of deleted file, + VERSIONS : create several versions of a file in recycle bin if + the file already exists in the recycle bin + e.g. mytext.doc + Copy #1 of mytext.doc + Copy #2 of mytext.doc + + TOUCH : touch access date when moving files to the recycle bin. + This is useful for automatic cleanup scripts. + Attn: This doesn't work if you have no write permissions + to the file being deleted. Deletion works if you + have write permissions to the parent directory. + Example: + mode = KEEP_DIRECTORIES|VERSIONS|TOUCH + +maxsize + maximum size of files to be moved to recycle bin. Setting this zo + zero (default) moves files of any size to the recycle bin. + Example: + maxsize = 0 + +exclude + exclude files from moving to recycle bin. Delete them immediately + Useful for temporary files. You can use the wildcards * and ? + Example: + exclude = *.tmp|*.temp|*.obj|~$*|*.$$$ + +excludedir + exclude directories from the recycle bin, useful for temporary + directories. + Example + excludedir = /tmp|/temp|/trash + +noversions + don't create versions of files in the recycle bin. Only usefull if + mode = VERSIONS is set. + Examples: + noversions = *.doc|*.xls|*.ppt + +Example smb.conf: + +[homes] + comment = Home-directory + path = /home/%u + read only = No + create mask = 0750 + vfs object = /usr/lib/samba/recycle.so + vfs options = /etc/samba/recycle.conf + +Example recycle.conf: + +name = .recycle/%U +mode = KEEP_DIRECTORIES|NOVERSIONS|TOUCH +maxsize = 0 +exclude = *.tmp|*.temp|*.o|*.obj|~$* +excludedir = /tmp|/temp|/cache +noversions = *.doc|*.xls|*.ppt diff --git a/examples/VFS/recycle/cleanup_recycle.pl b/examples/VFS/recycle/cleanup_recycle.pl new file mode 100644 index 00000000000..f614cf78708 --- /dev/null +++ b/examples/VFS/recycle/cleanup_recycle.pl @@ -0,0 +1,25 @@ +# !/usr/bin/perl -w +# +# this script looks for all files with an access date older than +# $maxage days and deletes them. +# Empty directories will be deleted afterwards +# + +$dirpath = "/data/.recycle"; +$maxage = 2; + +# delete all old files +@a=`find $dirpath -atime +$maxage`; +foreach (@a) + { + print "deleting file: $_"; + $r = `rm -f $_ 2> /dev/zero`; + } + +# delete all empty directories +@a=`find $dirpath -type d | sort -r`; +foreach (@a) + { + print "deleting directory: $_"; + $r = `rmdir $_ 2> /dev/zero`; + } diff --git a/examples/VFS/recycle/recycle.c b/examples/VFS/recycle/recycle.c new file mode 100644 index 00000000000..3d2d5d79697 --- /dev/null +++ b/examples/VFS/recycle/recycle.c @@ -0,0 +1,556 @@ +/* + * Recycle bin VFS module for Samba. + * + * Copyright (C) 2001, Brandon Stone, Amherst College, <bbstone@amherst.edu>. + * Copyright (C) 2002, Jeremy Allison - modified to make a VFS module. + * Copyright (C) 2002, Juergen Hasch - added some options. + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "config.h" +#include <stdio.h> +#include <sys/stat.h> +#ifdef HAVE_UTIME_H +#include <utime.h> +#endif +#ifdef HAVE_DIRENT_H +#include <dirent.h> +#endif +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif +#include <errno.h> +#include <string.h> +#include <includes.h> +#include <vfs.h> + +const char delimiter = '|'; /* delimiter for options */ + +/* One per connection */ + +typedef struct recycle_bin_struct +{ + TALLOC_CTX *ctx; + char *recycle_bin; /* name of the recycle bin directory */ + BOOL keep_directories; /* keep directory structure of deleted file in recycle bin */ + BOOL versions; /* create versions of deleted files with identical name */ + BOOL touch; /* touch access date of deleted file */ + char *exclude; /* which files to exclude */ + char *exclude_dir; /* which directories to exclude */ + char *noversions; /* which files to exclude from versioning */ + SMB_OFF_T max_size; /* maximum file size to be saved */ +} recycle_bin_struct; + +/* Global Variables */ +static recycle_bin_struct *current; + +/* VFS operations */ + +extern struct vfs_ops default_vfs_ops; /* For passthrough operation */ + +static int recycle_unlink(connection_struct *, const char *); +static int recycle_connect(struct connection_struct *conn, const char *service, const char *user); +static void recycle_disconnect(struct connection_struct *conn); + +BOOL checkparam(char *haystack,char *needle); + +struct vfs_ops recycle_ops = { + + /* Disk operations */ + + recycle_connect, /* connect */ + recycle_disconnect, /* disconnect */ + NULL, /* disk free */ + + /* Directory operations */ + + NULL, /* opendir */ + NULL, /* readdir */ + NULL, /* mkdir */ + NULL, /* rmdir */ + NULL, /* closedir */ + + /* File operations */ + + NULL, /* open */ + NULL, /* close */ + NULL, /* read */ + NULL, /* write */ + NULL, /* lseek */ + NULL, /* rename */ + NULL, /* fsync */ + NULL, /* stat */ + NULL, /* fstat */ + NULL, /* lstat */ + recycle_unlink, + NULL, /* chmod */ + NULL, /* fchmod */ + NULL, /* chown */ + NULL, /* fchown */ + NULL, /* chdir */ + NULL, /* getwd */ + NULL, /* utime */ + NULL, /* ftruncate */ + NULL, /* lock */ + NULL, /* symlink */ + NULL, /* readlink */ + NULL, /* link */ + NULL, /* mknod */ + NULL, /* realpath */ + NULL, /* fget_nt_acl */ + NULL, /* get_nt_acl */ + NULL, /* fset_nt_acl */ + NULL, /* set_nt_acl */ + + NULL, /* chmod_acl */ + NULL, /* fchmod_acl */ + + NULL, /* sys_acl_get_entry */ + NULL, /* sys_acl_get_tag_type */ + NULL, /* sys_acl_get_permset */ + NULL, /* sys_acl_get_qualifier */ + NULL, /* sys_acl_get_file */ + NULL, /* sys_acl_get_fd */ + NULL, /* sys_acl_clear_perms */ + NULL, /* sys_acl_add_perm */ + NULL, /* sys_acl_to_text */ + NULL, /* sys_acl_init */ + NULL, /* sys_acl_create_entry */ + NULL, /* sys_acl_set_tag_type */ + NULL, /* sys_acl_set_qualifier */ + NULL, /* sys_acl_set_permset */ + NULL, /* sys_acl_valid */ + NULL, /* sys_acl_set_file */ + NULL, /* sys_acl_set_fd */ + NULL, /* sys_acl_delete_def_file */ + NULL, /* sys_acl_get_perm */ + NULL, /* sys_acl_free_text */ + NULL, /* sys_acl_free_acl */ + NULL /* sys_acl_free_qualifier */ +}; + +/** + * Parse recycle bin configuration parameters + * + * @retval False if out of memory + **/ +static BOOL do_parameter(char *pszParmName, char *pszParmValue) +{ + if (StrCaseCmp("name",pszParmName)==0) { + current->recycle_bin = (char *)talloc(current->ctx,sizeof(pstring)); + if (current->recycle_bin == NULL) + return False; + current->recycle_bin = safe_strcpy(current->recycle_bin,pszParmValue,sizeof(pstring)); + standard_sub_basic(current->recycle_bin); + trim_string(current->recycle_bin,"/","/"); + DEBUG(10, ("name=%s\n", current->recycle_bin)); + } else if (StrCaseCmp("mode",pszParmName)==0) { + if (checkparam(pszParmValue,"KEEP_DIRECTORIES") == True) + current->keep_directories = True; + if (checkparam(pszParmValue,"VERSIONS") == True) + current->versions = True; + if (checkparam(pszParmValue,"TOUCH") == True) + current->touch = True; + DEBUG(10, ("mode=%s\n", pszParmValue)); + } else if (StrCaseCmp("maxsize",pszParmName)==0) { + current->max_size = strtoul(pszParmValue,NULL,10); + DEBUG(10, ("max_size=%ld\n", (long int)current->max_size)); + } else if (StrCaseCmp("exclude",pszParmName)==0) { + current->exclude = talloc_strdup(current->ctx, pszParmValue); + if (current->exclude == NULL) + return False; + DEBUG(10, ("exclude=%s\n", current->exclude)); + } else if (StrCaseCmp("excludedir",pszParmName)==0) { + current->exclude_dir = talloc_strdup(current->ctx, pszParmValue); + if (current->exclude_dir == NULL) + return False; + DEBUG(10, ("exclude_dir=%s\n", current->exclude_dir)); + } else if (StrCaseCmp("noversions",pszParmName)==0) { + current->noversions = talloc_strdup(current->ctx, pszParmValue); + if (current->noversions == NULL) + return False; + DEBUG(10, ("noversions=%s\n", current->noversions)); + } + return True; +} + +/** + * We don't care for sections in configuration file + * + **/ +static BOOL do_section(char *pszSectionName) +{ + return True; +} + +/** + * VFS initialisation function. + * + * @retval initialised vfs_ops structure + **/ +struct vfs_ops *vfs_init(int *vfs_version, struct vfs_ops *def_vfs_ops) +{ + struct vfs_ops tmp_ops; + DEBUG(3, ("Initializing VFS module recycle\n")); + + *vfs_version = SMB_VFS_INTERFACE_VERSION; + memcpy(&tmp_ops, def_vfs_ops, sizeof(struct vfs_ops)); + tmp_ops.unlink = recycle_unlink; + tmp_ops.connect = recycle_connect; + tmp_ops.disconnect = recycle_disconnect; + memcpy(&recycle_ops, &tmp_ops, sizeof(struct vfs_ops)); + return &recycle_ops; +} + +static int recycle_connect(struct connection_struct *conn, const char *service, const char *user) +{ + const char *p; + pstring conf_file; + int rc; + TALLOC_CTX *ctx=NULL; + + DEBUG(3,("Called for service %s (%d) as user %s\n", service, SNUM(conn), user)); + + if (!(ctx = talloc_init_named("recycle bin"))) { + DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n")); + return 0; + } + + /* read configuration file */ + *conf_file='\0'; + p = (const char *)lp_vfs_options(SNUM(conn)); + if (p != NULL && strlen(p) > 0) { + pstrcpy(conf_file,p); + DEBUG(10,("Using configuration file %s\n",conf_file)); + } + + current = talloc(ctx,sizeof(recycle_bin_struct)); + if ( current == NULL) { + DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n")); + return -1; + } + current->ctx = ctx; + /* Set defaults */ + current->recycle_bin = talloc_strdup(ctx,".recycle"); + current->keep_directories = False; + current->versions = False; + current->touch = False; + current->exclude = ""; + current->exclude_dir = ""; + current->noversions = ""; + current->max_size = 0; + if (strlen(conf_file) > 0) { + rc=pm_process( conf_file, do_section, do_parameter); + DEBUG(10, ("pm_process returned %d\n", rc)); + } + conn->vfs_private= (void *)current; + return 0; +} + +static void recycle_disconnect(struct connection_struct *conn) +{ + DEBUG(3, ("Disconnecting VFS module recycle_bin\n")); + talloc_destroy(((recycle_bin_struct*)conn->vfs_private)->ctx); + default_vfs_ops.disconnect(conn); +} + +static BOOL recycle_XXX_exist(connection_struct *conn, const char *dname, BOOL isdir) +{ + SMB_STRUCT_STAT st; + + if (default_vfs_ops.stat(conn,dname,&st) != 0) + return(False); + + if (isdir) + return S_ISDIR(st.st_mode) ? True : False; + else + return S_ISREG(st.st_mode) ? True : False; +} + +static BOOL recycle_directory_exist(connection_struct *conn, const char *dname) +{ + return recycle_XXX_exist(conn, dname, True); +} + +static BOOL recycle_file_exist(connection_struct *conn, const char *fname) +{ + return recycle_XXX_exist(conn, fname, False); +} + +/** + * Return file size + * @param conn connection + * @param fname file name + * @return size in bytes + **/ +static SMB_OFF_T recycle_get_file_size(connection_struct *conn, const char *fname) +{ + SMB_STRUCT_STAT st; + if (default_vfs_ops.stat(conn,fname,&st) != 0) { + DEBUG(0,("stat for %s returned %s\n",fname,strerror(errno))); + return (SMB_OFF_T)0; + } + return(st.st_size); +} + +/** + * Create directory tree + * @param conn connection + * @param dname Directory tree to be created + * @return Returns True for success + **/ +static BOOL recycle_create_dir(connection_struct *conn, const char *dname) +{ + char *c,*y; + int i; + + mode_t mode; + pstring tempstr; + pstring newdir; + + *newdir='\0'; + mode=S_IREAD|S_IWRITE|S_IEXEC; + pstrcpy(tempstr,dname); + y=tempstr; + /* Create directory tree if neccessary */ + while((c=strsep(&y,"/"))) { + pstrcat(newdir,c); + if (recycle_directory_exist(conn,newdir)) + DEBUG(3, ("dir %s already exists\n",newdir)); + else { + DEBUG(3, ("creating new dir %s\n",newdir)); + i=default_vfs_ops.mkdir(conn,newdir,mode); + if (i) { + DEBUG(3,("mkdir failed for %s with error %s\n",newdir,strerror(errno))); + return False; + } + } + pstrcat(newdir,"/"); + } + return True; +} + +/** + * Check if needle is contained exactly in haystack + * @param haystack list of parameters separated by delimimiter character + * @param needle string to be matched exactly to haystack + * @return True if found + **/ +BOOL checkparam(char *haystack,char *needle) +{ + char *p,*c; + pstring str; + int i,len; + + if (haystack==NULL || strlen(haystack)==0 || needle == NULL || strlen(needle)== 0) + return False; + + pstrcpy(str,haystack); + len=strlen(str)+1; + p=c=str; + + for (i=0; i < len; i++, p++) { + if (*p == delimiter || *p == '\0') { + *p='\0'; + if(strncmp(c,needle,c-p) == 0) + return True; + c=p+1; + } + } + return False; +} + +/** + * Check if needle is contained in haystack, * and ? patterns are resolved + * @param haystack list of parameters separated by delimimiter character + * @param needle string to be matched exectly to haystack including pattern matching + * @return True if found + **/ +BOOL matchparam(char *haystack,char *needle) +{ + char *p,*c; + pstring str; + int i,len; + + if (haystack==NULL || strlen(haystack)==0 || needle == NULL || strlen(needle)== 0) + return False; + + pstrcpy(str,haystack); + len=strlen(str)+1; + p=c=str; + + for (i=0; i < len; i++, p++) { + if (*p == delimiter || *p == '\0') { + *p='\0'; + if (!unix_wild_match(c,needle)) + return True; + c=p+1; + } + } + return False; +} + +/** + * Touch access date + **/ +void recycle_touch(connection_struct *conn, const char *fname) +{ + SMB_STRUCT_STAT st; + struct utimbuf tb; + time_t current; + + if (default_vfs_ops.stat(conn,fname,&st) != 0) { + DEBUG(0,("stat for %s returned %s\n",fname,strerror(errno))); + return; + } + current = time(¤t); + tb.actime = current; + tb.modtime = st.st_mtime; + + if (default_vfs_ops.utime(conn, fname, &tb) == -1 ) + DEBUG(0, ("Touching %s failed, reason = %s\n",fname,strerror(errno))); + } + +/** + * Check if file should be recycled + **/ +static int recycle_unlink(connection_struct *conn, const char *inname) +{ + pstring fname,fpath, bin; + char *base, *ext; + int i=1, len, addlen; + SMB_BIG_UINT dfree,dsize,bsize; + SMB_OFF_T fsize,space_avail; + BOOL exist; + int rc; + + pstrcpy(fname,inname); + if (conn->vfs_private) + current = (recycle_bin_struct *)conn->vfs_private; + else { + DEBUG(0,("Recycle bin not initialized!\n")); + return default_vfs_ops.unlink(conn,fname); + } + + if(!current->recycle_bin || !*(current->recycle_bin)) { + DEBUG(3, ("Recycle path not set, purging %s...\n", fname)); + return default_vfs_ops.unlink(conn,fname); + } + + /* we don't recycle the recycle bin... */ + if (strstr(fname,current->recycle_bin)==fname) { + DEBUG(3, ("File is within recycling bin\n")); + return default_vfs_ops.unlink(conn,fname); + } + + fsize = recycle_get_file_size(conn,fname); + if(fsize == 0) { + DEBUG(3, ("File %s is empty, purging...\n", fname)); + return default_vfs_ops.unlink(conn,fname); + } + + if(current->max_size > 0 && fsize > current->max_size) { + DEBUG(3, ("File %s exceeds maximum recycle size, purging... \n", fname)); + return default_vfs_ops.unlink(conn,fname); + } + + space_avail = default_vfs_ops.disk_free(conn,".",True,&bsize,&dfree,&dsize)*1024L; + DEBUG(10,("space_avail = %Lu, fsize = %Lu\n",space_avail,fsize)); + if(space_avail < fsize) { + DEBUG(3, ("Not enough diskspace, purging file %s\n",fname)); + return default_vfs_ops.unlink(conn,fname); + } + + /* extract filename and path */ + pstrcpy(fpath,"/"); + pstrcat(fpath, fname); + base = strrchr(fpath, '/'); + if (base == NULL) { + ext = strrchr(fname, '.'); + base = (char *)fname; + pstrcpy(fpath,"/"); + } + else { + ext = strrchr(base, '.'); + *(base++) = '\0'; + } + + DEBUG(10, ("fname:%s\n", fname)); /* original filename with path */ + DEBUG(10, ("fpath:%s\n", fpath)); /* original path */ + DEBUG(10, ("base:%s\n", base)); /* filename without path */ + DEBUG(10, ("ext:%s\n", ext)); /* filename extension */ + + if (matchparam(current->exclude,base)) { + DEBUG(3, ("file %s is excluded \n",base)); + return default_vfs_ops.unlink(conn,fname); + } + + if (checkparam(current->exclude_dir,fpath)) { + DEBUG(3, ("directory %s is excluded \n",fpath)); + return default_vfs_ops.unlink(conn,fname); + } + + pstrcpy(bin, current->recycle_bin); + + /* see if we need to recreate the original directory structure in the recycle bin */ + if (current->keep_directories == True) + pstrcat(bin, fpath); + + exist=recycle_directory_exist(conn,bin); + if (exist) + DEBUG(10, ("Directory already exists\n")); + else { + DEBUG(10, ("Creating directory %s\n",bin)); + rc=recycle_create_dir(conn,bin); + if (rc == False) + { + DEBUG(3, ("Could not create directory, purging %s...\n", fname)); + return default_vfs_ops.unlink(conn,fname); + } + } + + pstrcat(bin, "/"); + pstrcat(bin,base); + DEBUG(10, ("bin:%s\n", bin)); /* new filename with path */ + + /* check if we should delete file from recycle bin */ + if (recycle_file_exist(conn,bin)) { + if (current->versions == False || matchparam(current->noversions,base) == True) { + DEBUG(3, ("Removing old file %s from recycle bin\n",bin)); + default_vfs_ops.unlink(conn,bin); + } + } + + /* rename file we move to recycle bin */ + len = strlen(bin); + addlen = sizeof(pstring)-len-1; + while(recycle_file_exist(conn,bin)) { + slprintf(bin+len, addlen, " (Copy #%d)", i++); + pstrcat(bin, ext); + } + + DEBUG(10, ("Moving source=%s to dest=%s\n", fname, bin)); + rc = default_vfs_ops.rename(conn, fname, bin); + if (rc == -1) { + DEBUG(3, ("Move error %d (%s), purging file %s (%s)\n", errno, strerror(errno),fname,bin)); + return default_vfs_ops.unlink(conn,fname); + } + + /* touch access date of moved file */ + if (current->touch == True ) + recycle_touch(conn,bin); + return rc; +} diff --git a/examples/VFS/recycle/recycle.conf b/examples/VFS/recycle/recycle.conf new file mode 100644 index 00000000000..00cc7982124 --- /dev/null +++ b/examples/VFS/recycle/recycle.conf @@ -0,0 +1,17 @@ +# name of the recycle bin at root level of share +name = .recycle +# mode : +# KEEP_DIRECTORIES = retain directory hierarchy of deleted file, +# i.e. recreate all directories in recycle bin +# VERSIONS = create copies in case of identical file names in recycle bin +# TOUCH = touch access date of files moved into the recycle bin +mode = KEEP_DIRECTORIES|VERSIONS|TOUCH +# maximum file size to be moved to the recycle bin (0 means any size) +maxsize = 0 +# exclude file names with the following extensions: +exclude = *.tmp|*.temp|*.o|*.obj|~$* +# exclude directories: +excludedir = /tmp|/temp|/cache +# Add file extensions of files where no versioning is wanted (i.e. copy # 1...) +# only valid when mode=VERSIONS is set +noversions = *.doc|*.xls|*.ppt |