From 231f549eb0dbeaf92b684f0de8a3b5d3a9ff63d9 Mon Sep 17 00:00:00 2001 From: Sam Hartman Date: Sun, 24 Oct 2004 03:34:41 +0000 Subject: [PATCH] Import OpenAFS 1.3.73 --- acinclude.m4 | 4 + aclocal.m4 | 25 +- configure | 391 +- configure-libafs | 391 +- configure-libafs.in | 2 +- configure.in | 2 +- src/WINNT/afsd/afsd_flushvol.c | 672 +- src/WINNT/afsd/afsd_init.c | 667 +- src/WINNT/afsd/afsd_service.c | 361 +- src/WINNT/afsd/afskfw.c | 80 +- src/WINNT/afsd/afsshare.c | 2 +- src/WINNT/afsd/cm_buf.c | 1932 ++--- src/WINNT/afsd/cm_buf.h | 2 +- src/WINNT/afsd/cm_callback.c | 428 +- src/WINNT/afsd/cm_conn.c | 109 +- src/WINNT/afsd/cm_conn.h | 5 +- src/WINNT/afsd/cm_dcache.c | 1117 +-- src/WINNT/afsd/cm_diskcache95.h | 2 +- src/WINNT/afsd/cm_freelance.c | 667 +- src/WINNT/afsd/cm_freelance.h | 4 +- src/WINNT/afsd/cm_ioctl.c | 2688 +++---- src/WINNT/afsd/cm_ioctl.h | 6 +- src/WINNT/afsd/cm_scache.h | 2 +- src/WINNT/afsd/cm_server.c | 491 +- src/WINNT/afsd/cm_server.h | 4 +- src/WINNT/afsd/cm_user.h | 2 +- src/WINNT/afsd/cm_utils.c | 79 +- src/WINNT/afsd/cm_vnodeops.c | 4140 +++++------ src/WINNT/afsd/cm_vnodeops.h | 12 +- src/WINNT/afsd/cm_volume.h | 2 +- src/WINNT/afsd/ctokens.c | 3 +- src/WINNT/afsd/fs.c | 103 +- src/WINNT/afsd/lanahelper.cpp | 29 + src/WINNT/afsd/lanahelper.h | 2 + src/WINNT/afsd/smb.c | 9355 +++++++++++++------------ src/WINNT/afsd/smb.h | 20 +- src/WINNT/afsd/smb3.c | 6313 +++++++++-------- src/WINNT/afsd/smb3.h | 13 +- src/WINNT/aklog/aklog.c | 1404 ++-- src/WINNT/client_config/drivemap.cpp | 55 +- src/WINNT/client_config/isadmin.cpp | 85 +- src/WINNT/client_creds/ipaddrchg.c | 25 +- src/WINNT/client_osi/osisleep.h | 2 +- src/WINNT/client_osi/osistatl.h | 6 +- src/WINNT/install/NSIS/AdminGroup.cpp | 4 +- src/WINNT/install/NSIS/NTMakefile | 17 +- src/WINNT/install/NSIS/OpenAFS.nsi | 84 + src/WINNT/install/wix/NTMakefile | 2 +- src/afs/LINUX/osi_groups.c | 6 +- src/afs/LINUX/osi_module.c | 17 +- src/afs/LINUX/osi_prototypes.h | 3 - src/afs/LINUX/osi_vnodeops.c | 19 +- src/afs/SOLARIS/osi_vnodeops.c | 4 +- src/afs/VNOPS/afs_vnop_create.c | 10 +- src/afs/VNOPS/afs_vnop_dirops.c | 12 +- src/afs/VNOPS/afs_vnop_link.c | 6 +- src/afs/VNOPS/afs_vnop_lookup.c | 16 +- src/afs/VNOPS/afs_vnop_readdir.c | 28 +- src/afs/VNOPS/afs_vnop_remove.c | 8 +- src/afs/VNOPS/afs_vnop_rename.c | 24 +- src/afs/VNOPS/afs_vnop_symlink.c | 6 +- src/afs/afs.h | 4 +- src/afs/afs_buffer.c | 23 +- src/afs/afs_dcache.c | 8 +- src/afs/afs_osi.h | 6 +- src/afs/afs_osi_pag.c | 89 +- src/afs/afs_pioctl.c | 20 +- src/afs/afs_prototypes.h | 6 +- src/afs/afs_segments.c | 10 +- src/afs/afs_stats.h | 2 +- src/afs/afs_vcache.c | 17 +- src/auth/Makefile.in | 2 +- src/bozo/bos.c | 4 +- src/bucoord/commands.c | 12 +- src/bucoord/dump_sched.c | 5 +- src/bucoord/restore.c | 4 +- src/butc/lwps.c | 12 +- src/butc/recoverDb.c | 17 +- src/butc/tcmain.c | 6 +- src/butm/test_ftm.c | 6 +- src/cf/linux-test3.m4 | 17 + src/cf/osconf.m4 | 4 +- src/config/NTMakefile.i386_nt40 | 2 +- src/config/afs_sysnames.h | 2 + src/config/afsconfig.h.in | 3 + src/config/param.amd64_linux26.h | 147 + src/des/Makefile.in | 4 +- src/des/cbc_encrypt.c | 4 +- src/des/des.c | 31 +- src/des/des_prototypes.h | 6 +- src/des/pcbc_encrypt.c | 4 +- src/kauth/Makefile.in | 4 +- src/libafs/MakefileProto.LINUX.in | 24 +- src/libafsauthent/Makefile.in | 4 + src/libafsauthent/NTMakefile | 1 + src/libafsrpc/Makefile.in | 10 +- src/libafsrpc/afsrpc.def | 3 +- src/libafsrpc/mapfile | 117 - src/ptserver/pts.c | 4 +- src/ptserver/ptuser.c | 8 +- src/rx/LINUX/rx_knet.c | 9 +- src/rx/rx.c | 32 +- src/rx/rx.h | 13 +- src/rx/rx_getaddr.c | 48 +- src/rx/rx_globals.h | 1 + src/rx/rx_packet.c | 9 +- src/rx/rx_prototypes.h | 1 + src/rx/rx_rdwr.c | 4 +- src/rx/rx_user.c | 29 +- src/rx/rxdebug.c | 6 +- src/rxkad/Makefile.in | 25 +- src/rxkad/domestic/fcrypt.c | 22 +- src/rxkad/rxkad.p.h | 5 - src/rxkad/rxkad_prototypes.h | 4 +- src/scout/Makefile.in | 2 +- src/shlibafsauthent/Makefile.in | 4 + src/shlibafsrpc/Makefile.in | 6 +- src/shlibafsrpc/NTMakefile | 349 - src/shlibafsrpc/afsrpc.def | 200 - src/shlibafsrpc/afsrpc.rc | 18 - src/sys/pioctl_nt.c | 138 +- src/ubik/Makefile.in | 3 +- src/ubik/NTMakefile | 1 + src/ubik/beacon.c | 5 +- src/ubik/ubik.p.h | 11 + src/ubik/udebug.c | 4 +- src/ubik/uinit.c | 206 + src/util/Makefile.in | 8 +- src/util/ktime.c | 5 +- src/util/netutils.c | 11 +- src/util/serverLog.c | 5 +- src/util/snprintf.c | 10 +- src/venus/fs.c | 163 +- src/viced/callback.c | 11 +- src/viced/host.c | 3 +- src/viced/viced.c | 11 +- src/vlserver/vlclient.c | 99 +- src/vol/listinodes.c | 28 +- src/vol/namei_ops.c | 29 +- src/vol/namei_ops.h | 8 +- src/vol/ntops.c | 27 +- src/vol/ntops.h | 8 +- src/vol/nuke.c | 21 +- src/vol/vol-salvage.c | 6 +- src/volser/volmain.c | 24 +- src/volser/volprocs.c | 42 +- src/volser/voltrans.c | 28 +- src/volser/vsutils.c | 128 +- 148 files changed, 17635 insertions(+), 16817 deletions(-) create mode 100644 src/config/param.amd64_linux26.h delete mode 100644 src/libafsrpc/mapfile delete mode 100644 src/shlibafsrpc/NTMakefile delete mode 100644 src/shlibafsrpc/afsrpc.def delete mode 100644 src/shlibafsrpc/afsrpc.rc create mode 100644 src/ubik/uinit.c diff --git a/acinclude.m4 b/acinclude.m4 index 14f70611a..7876de6ff 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -185,6 +185,7 @@ case $system in LINUX_INODE_SETATTR_RETURN_TYPE LINUX_KERNEL_LINUX_SYSCALL_H LINUX_KERNEL_SELINUX + LINUX_KERNEL_SOCK_CREATE LINUX_NEED_RHCONFIG LINUX_RECALC_SIGPENDING_ARG_TYPE LINUX_SCHED_STRUCT_TASK_STRUCT_HAS_PARENT @@ -296,6 +297,9 @@ case $system in if test "x$ac_cv_linux_kernel_is_selinux" = "xyes" ; then AC_DEFINE(LINUX_KERNEL_IS_SELINUX, 1, [define if your linux kernel uses SELinux features]) fi + if test "x$ac_cv_linux_kernel_sock_create_v" = "xyes" ; then + AC_DEFINE(LINUX_KERNEL_SOCK_CREATE_V, 1, [define if your linux kernel uses 5 arguments for sock_create]) + fi if test "x$ac_linux_syscall" = "xyes" ; then AC_DEFINE(HAVE_KERNEL_LINUX_SYSCALL_H, 1, [define if your linux kernel has linux/syscall.h]) fi diff --git a/aclocal.m4 b/aclocal.m4 index c9c30b1d0..51b8f5bda 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -197,6 +197,7 @@ case $system in LINUX_INODE_SETATTR_RETURN_TYPE LINUX_KERNEL_LINUX_SYSCALL_H LINUX_KERNEL_SELINUX + LINUX_KERNEL_SOCK_CREATE LINUX_NEED_RHCONFIG LINUX_RECALC_SIGPENDING_ARG_TYPE LINUX_SCHED_STRUCT_TASK_STRUCT_HAS_PARENT @@ -308,6 +309,9 @@ case $system in if test "x$ac_cv_linux_kernel_is_selinux" = "xyes" ; then AC_DEFINE(LINUX_KERNEL_IS_SELINUX, 1, [define if your linux kernel uses SELinux features]) fi + if test "x$ac_cv_linux_kernel_sock_create_v" = "xyes" ; then + AC_DEFINE(LINUX_KERNEL_SOCK_CREATE_V, 1, [define if your linux kernel uses 5 arguments for sock_create]) + fi if test "x$ac_linux_syscall" = "xyes" ; then AC_DEFINE(HAVE_KERNEL_LINUX_SYSCALL_H, 1, [define if your linux kernel has linux/syscall.h]) fi @@ -1803,6 +1807,23 @@ AC_TRY_COMPILE( AC_MSG_RESULT($ac_cv_linux_kernel_is_selinux) CPPFLAGS="$save_CPPFLAGS"]) +AC_DEFUN([LINUX_KERNEL_SOCK_CREATE],[ +AC_MSG_CHECKING(for 5th argument in sock_create found in some SELinux kernels) +save_CPPFLAGS="$CPPFLAGS" +CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -D__KERNEL__ $CPPFLAGS" +AC_CACHE_VAL(ac_cv_linux_kernel_sock_create_v, +[ +AC_TRY_COMPILE( + [#include ], + [ + sock_create(0,0,0,0,0) + ], + ac_cv_linux_kernel_sock_create_v=yes, + ac_cv_linux_kernel_sock_create_v=no)]) +AC_MSG_RESULT($ac_cv_linux_kernel_sock_create_v) +CPPFLAGS="$save_CPPFLAGS"]) + + AC_DEFUN([SOLARIS_UFSVFS_HAS_DQRWLOCK], [ AC_MSG_CHECKING(for vfs_dqrwlock in struct ufsvfs) AC_CACHE_VAL(ac_cv_solaris_ufsvfs_has_dqrwlock, @@ -2111,12 +2132,14 @@ case $AFS_SYSNAME in SHLIB_LINKER="${MT_CC} -shared" ;; - amd64_linux24) + amd64_linux*) + CCOBJ="${CC} -fPIC" KERN_OPTMZ=-O2 LEX="flex -l" MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}' MT_LIBS="-lpthread" PAM_CFLAGS="-g -O2 -Dlinux -DLINUX_PAM -fPIC" + SHLIB_CFLAGS="-fPIC" SHLIB_LDFLAGS="-shared -Xlinker -x" TXLIBS="-lncurses" XCFLAGS="-g -O2 -D_LARGEFILE64_SOURCE" diff --git a/configure b/configure index 025aa11c7..aa155348a 100644 --- a/configure +++ b/configure @@ -754,7 +754,7 @@ fi PACKAGE=openafs -VERSION=1.3.71 +VERSION=1.3.73 if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; } @@ -2869,13 +2869,46 @@ fi echo "$ac_t""$ac_cv_linux_kernel_is_selinux" 1>&6 CPPFLAGS="$save_CPPFLAGS" +echo $ac_n "checking for 5th argument in sock_create found in some SELinux kernels""... $ac_c" 1>&6 +echo "configure:2874: checking for 5th argument in sock_create found in some SELinux kernels" >&5 +save_CPPFLAGS="$CPPFLAGS" +CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -D__KERNEL__ $CPPFLAGS" +if eval "test \"`echo '$''{'ac_cv_linux_kernel_sock_create_v'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + +cat > conftest.$ac_ext < +int main() { + + sock_create(0,0,0,0,0) + +; return 0; } +EOF +if { (eval echo configure:2891: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_linux_kernel_sock_create_v=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_linux_kernel_sock_create_v=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_linux_kernel_sock_create_v" 1>&6 +CPPFLAGS="$save_CPPFLAGS" + RHCONFIG_SP="" RHCONFIG_MP="" if test "x$enable_redhat_buildsys" = "xyes"; then echo "configure: warning: Configured to build from a Red Hat SPEC file" 1>&2 else echo $ac_n "checking for redhat kernel configuration""... $ac_c" 1>&6 -echo "configure:2879: checking for redhat kernel configuration" >&5 +echo "configure:2912: checking for redhat kernel configuration" >&5 if test -f "${LINUX_KERNEL_PATH}/include/linux/rhconfig.h"; then ac_linux_rhconfig=yes RHCONFIG_SP="-D__BOOT_KERNEL_UP=1 -D__BOOT_KERNEL_SMP=0" @@ -2894,7 +2927,7 @@ fi echo $ac_n "checking for recalc_sigpending arg type""... $ac_c" 1>&6 -echo "configure:2898: checking for recalc_sigpending arg type" >&5 +echo "configure:2931: checking for recalc_sigpending arg type" >&5 save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -I${LINUX_KERNEL_PATH}/include/asm/mach-${SUBARCH} -D__KERNEL__ $CPPFLAGS" if eval "test \"`echo '$''{'ac_cv_linux_func_recalc_sigpending_takes_void'+set}'`\" = set"; then @@ -2902,14 +2935,14 @@ if eval "test \"`echo '$''{'ac_cv_linux_func_recalc_sigpending_takes_void'+set}' else cat > conftest.$ac_ext < int main() { recalc_sigpending(); ; return 0; } EOF -if { (eval echo configure:2913: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2946: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_linux_func_recalc_sigpending_takes_void=yes else @@ -2925,7 +2958,7 @@ echo "$ac_t""$ac_cv_linux_func_recalc_sigpending_takes_void" 1>&6 CPPFLAGS="$save_CPPFLAGS" echo $ac_n "checking for parent in struct task_struct""... $ac_c" 1>&6 -echo "configure:2929: checking for parent in struct task_struct" >&5 +echo "configure:2962: checking for parent in struct task_struct" >&5 save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -I${LINUX_KERNEL_PATH}/include/asm/mach-${SUBARCH} -D__KERNEL__ $CPPFLAGS" if eval "test \"`echo '$''{'ac_cv_linux_sched_struct_task_struct_has_parent'+set}'`\" = set"; then @@ -2933,7 +2966,7 @@ if eval "test \"`echo '$''{'ac_cv_linux_sched_struct_task_struct_has_parent'+set else cat > conftest.$ac_ext < int main() { @@ -2941,7 +2974,7 @@ struct task_struct _tsk; printf("%d\n", _tsk.parent); ; return 0; } EOF -if { (eval echo configure:2945: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2978: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_linux_sched_struct_task_struct_has_parent=yes else @@ -2957,7 +2990,7 @@ echo "$ac_t""$ac_cv_linux_sched_struct_task_struct_has_parent" 1>&6 CPPFLAGS="$save_CPPFLAGS" echo $ac_n "checking for real_parent in struct task_struct""... $ac_c" 1>&6 -echo "configure:2961: checking for real_parent in struct task_struct" >&5 +echo "configure:2994: checking for real_parent in struct task_struct" >&5 save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -I${LINUX_KERNEL_PATH}/include/asm/mach-${SUBARCH} -D__KERNEL__ $CPPFLAGS" if eval "test \"`echo '$''{'ac_cv_linux_sched_struct_task_struct_has_real_parent'+set}'`\" = set"; then @@ -2965,7 +2998,7 @@ if eval "test \"`echo '$''{'ac_cv_linux_sched_struct_task_struct_has_real_parent else cat > conftest.$ac_ext < int main() { @@ -2973,7 +3006,7 @@ struct task_struct _tsk; printf("%d\n", _tsk.real_parent); ; return 0; } EOF -if { (eval echo configure:2977: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3010: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_linux_sched_struct_task_struct_has_real_parent=yes else @@ -2989,7 +3022,7 @@ echo "$ac_t""$ac_cv_linux_sched_struct_task_struct_has_real_parent" 1>&6 CPPFLAGS="$save_CPPFLAGS" echo $ac_n "checking for sig in struct task_struct""... $ac_c" 1>&6 -echo "configure:2993: checking for sig in struct task_struct" >&5 +echo "configure:3026: checking for sig in struct task_struct" >&5 save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -I${LINUX_KERNEL_PATH}/include/asm/mach-${SUBARCH} -D__KERNEL__ $CPPFLAGS" if eval "test \"`echo '$''{'ac_cv_linux_sched_struct_task_struct_has_sig'+set}'`\" = set"; then @@ -2997,7 +3030,7 @@ if eval "test \"`echo '$''{'ac_cv_linux_sched_struct_task_struct_has_sig'+set}'` else cat > conftest.$ac_ext < int main() { @@ -3005,7 +3038,7 @@ struct task_struct _tsk; printf("%d\n", _tsk.sig); ; return 0; } EOF -if { (eval echo configure:3009: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3042: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_linux_sched_struct_task_struct_has_sig=yes else @@ -3021,7 +3054,7 @@ echo "$ac_t""$ac_cv_linux_sched_struct_task_struct_has_sig" 1>&6 CPPFLAGS="$save_CPPFLAGS" echo $ac_n "checking for sighand in struct task_struct""... $ac_c" 1>&6 -echo "configure:3025: checking for sighand in struct task_struct" >&5 +echo "configure:3058: checking for sighand in struct task_struct" >&5 save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -I${LINUX_KERNEL_PATH}/include/asm/mach-${SUBARCH} -D__KERNEL__ $CPPFLAGS" if eval "test \"`echo '$''{'ac_cv_linux_sched_struct_task_struct_has_sighand'+set}'`\" = set"; then @@ -3029,7 +3062,7 @@ if eval "test \"`echo '$''{'ac_cv_linux_sched_struct_task_struct_has_sighand'+se else cat > conftest.$ac_ext < int main() { @@ -3037,7 +3070,7 @@ struct task_struct _tsk; printf("%d\n", _tsk.sighand); ; return 0; } EOF -if { (eval echo configure:3041: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3074: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_linux_sched_struct_task_struct_has_sighand=yes else @@ -3053,7 +3086,7 @@ echo "$ac_t""$ac_cv_linux_sched_struct_task_struct_has_sighand" 1>&6 CPPFLAGS="$save_CPPFLAGS" echo $ac_n "checking for sigmask_lock in struct task_struct""... $ac_c" 1>&6 -echo "configure:3057: checking for sigmask_lock in struct task_struct" >&5 +echo "configure:3090: checking for sigmask_lock in struct task_struct" >&5 save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -I${LINUX_KERNEL_PATH}/include/asm/mach-${SUBARCH} -D__KERNEL__ $CPPFLAGS" if eval "test \"`echo '$''{'ac_cv_linux_sched_struct_task_struct_has_sigmask_lock'+set}'`\" = set"; then @@ -3061,7 +3094,7 @@ if eval "test \"`echo '$''{'ac_cv_linux_sched_struct_task_struct_has_sigmask_loc else cat > conftest.$ac_ext < int main() { @@ -3069,7 +3102,7 @@ struct task_struct _tsk; printf("%d\n", _tsk.sigmask_lock); ; return 0; } EOF -if { (eval echo configure:3073: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3106: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_linux_sched_struct_task_struct_has_sigmask_lock=yes else @@ -3090,13 +3123,13 @@ else save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -D__KERNEL__ $RHCONFIG_SP $CPPFLAGS" echo $ac_n "checking if kernel uses MODVERSIONS""... $ac_c" 1>&6 -echo "configure:3094: checking if kernel uses MODVERSIONS" >&5 +echo "configure:3127: checking if kernel uses MODVERSIONS" >&5 if eval "test \"`echo '$''{'ac_cv_linux_config_modversions'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -3108,7 +3141,7 @@ lose; ; return 0; } EOF -if { (eval echo configure:3112: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3145: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_linux_config_modversions=yes else @@ -3122,7 +3155,7 @@ fi echo "$ac_t""$ac_cv_linux_config_modversions" 1>&6 echo $ac_n "checking which kernel modules to build""... $ac_c" 1>&6 -echo "configure:3126: checking which kernel modules to build" >&5 +echo "configure:3159: checking which kernel modules to build" >&5 if test "x$ac_linux_rhconfig" = "xyes" -o "x$ac_cv_linux_config_modversions" = "xno"; then MPS="MP SP" else @@ -3131,7 +3164,7 @@ echo "configure:3126: checking which kernel modules to build" >&5 else cat > conftest.$ac_ext < @@ -3142,7 +3175,7 @@ lose; ; return 0; } EOF -if { (eval echo configure:3146: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3179: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_linux_config_smp=yes else @@ -3174,7 +3207,7 @@ fi else echo $ac_n "checking for exported init_mm""... $ac_c" 1>&6 -echo "configure:3178: checking for exported init_mm" >&5 +echo "configure:3211: checking for exported init_mm" >&5 save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -I${LINUX_KERNEL_PATH}/include/asm/mach-${SUBARCH} -D__KERNEL__ $CPPFLAGS" if eval "test \"`echo '$''{'ac_cv_linux_exports_init_mm'+set}'`\" = set"; then @@ -3182,7 +3215,7 @@ if eval "test \"`echo '$''{'ac_cv_linux_exports_init_mm'+set}'`\" = set"; then else cat > conftest.$ac_ext < int main() { @@ -3191,7 +3224,7 @@ int main() { #endif ; return 0; } EOF -if { (eval echo configure:3195: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3228: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_linux_exports_init_mm=yes else @@ -3207,7 +3240,7 @@ echo "$ac_t""$ac_cv_linux_exports_init_mm" 1>&6 CPPFLAGS="$save_CPPFLAGS" echo $ac_n "checking for exported kallsyms_address_to_symbol""... $ac_c" 1>&6 -echo "configure:3211: checking for exported kallsyms_address_to_symbol" >&5 +echo "configure:3244: checking for exported kallsyms_address_to_symbol" >&5 save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -I${LINUX_KERNEL_PATH}/include/asm/mach-${SUBARCH} -D__KERNEL__ $CPPFLAGS" if eval "test \"`echo '$''{'ac_cv_linux_exports_kallsyms_address'+set}'`\" = set"; then @@ -3215,7 +3248,7 @@ if eval "test \"`echo '$''{'ac_cv_linux_exports_kallsyms_address'+set}'`\" = set else cat > conftest.$ac_ext < int main() { @@ -3224,7 +3257,7 @@ int main() { #endif ; return 0; } EOF -if { (eval echo configure:3228: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3261: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_linux_exports_kallsyms_address=yes else @@ -3240,7 +3273,7 @@ echo "$ac_t""$ac_cv_linux_exports_kallsyms_address" 1>&6 CPPFLAGS="$save_CPPFLAGS" echo $ac_n "checking for exported kallsyms_symbol_to_address""... $ac_c" 1>&6 -echo "configure:3244: checking for exported kallsyms_symbol_to_address" >&5 +echo "configure:3277: checking for exported kallsyms_symbol_to_address" >&5 save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -I${LINUX_KERNEL_PATH}/include/asm/mach-${SUBARCH} -D__KERNEL__ $CPPFLAGS" if eval "test \"`echo '$''{'ac_cv_linux_exports_kallsyms_symbol'+set}'`\" = set"; then @@ -3248,7 +3281,7 @@ if eval "test \"`echo '$''{'ac_cv_linux_exports_kallsyms_symbol'+set}'`\" = set" else cat > conftest.$ac_ext < int main() { @@ -3257,7 +3290,7 @@ int main() { #endif ; return 0; } EOF -if { (eval echo configure:3261: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3294: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_linux_exports_kallsyms_symbol=yes else @@ -3273,7 +3306,7 @@ echo "$ac_t""$ac_cv_linux_exports_kallsyms_symbol" 1>&6 CPPFLAGS="$save_CPPFLAGS" echo $ac_n "checking for exported sys_call_table""... $ac_c" 1>&6 -echo "configure:3277: checking for exported sys_call_table" >&5 +echo "configure:3310: checking for exported sys_call_table" >&5 save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -I${LINUX_KERNEL_PATH}/include/asm/mach-${SUBARCH} -D__KERNEL__ $CPPFLAGS" if eval "test \"`echo '$''{'ac_cv_linux_exports_sys_call_table'+set}'`\" = set"; then @@ -3281,7 +3314,7 @@ if eval "test \"`echo '$''{'ac_cv_linux_exports_sys_call_table'+set}'`\" = set"; else cat > conftest.$ac_ext < int main() { @@ -3290,7 +3323,7 @@ int main() { #endif ; return 0; } EOF -if { (eval echo configure:3294: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3327: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_linux_exports_sys_call_table=yes else @@ -3306,7 +3339,7 @@ echo "$ac_t""$ac_cv_linux_exports_sys_call_table" 1>&6 CPPFLAGS="$save_CPPFLAGS" echo $ac_n "checking for exported ia32_sys_call_table""... $ac_c" 1>&6 -echo "configure:3310: checking for exported ia32_sys_call_table" >&5 +echo "configure:3343: checking for exported ia32_sys_call_table" >&5 save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -I${LINUX_KERNEL_PATH}/include/asm/mach-${SUBARCH} -D__KERNEL__ $CPPFLAGS" if eval "test \"`echo '$''{'ac_cv_linux_exports_ia32_sys_call_table'+set}'`\" = set"; then @@ -3314,7 +3347,7 @@ if eval "test \"`echo '$''{'ac_cv_linux_exports_ia32_sys_call_table'+set}'`\" = else cat > conftest.$ac_ext < int main() { @@ -3323,7 +3356,7 @@ int main() { #endif ; return 0; } EOF -if { (eval echo configure:3327: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3360: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_linux_exports_ia32_sys_call_table=yes else @@ -3339,7 +3372,7 @@ echo "$ac_t""$ac_cv_linux_exports_ia32_sys_call_table" 1>&6 CPPFLAGS="$save_CPPFLAGS" echo $ac_n "checking for exported sys_chdir""... $ac_c" 1>&6 -echo "configure:3343: checking for exported sys_chdir" >&5 +echo "configure:3376: checking for exported sys_chdir" >&5 save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -I${LINUX_KERNEL_PATH}/include/asm/mach-${SUBARCH} -D__KERNEL__ $CPPFLAGS" if eval "test \"`echo '$''{'ac_cv_linux_exports_sys_chdir'+set}'`\" = set"; then @@ -3347,7 +3380,7 @@ if eval "test \"`echo '$''{'ac_cv_linux_exports_sys_chdir'+set}'`\" = set"; then else cat > conftest.$ac_ext < int main() { @@ -3356,7 +3389,7 @@ int main() { #endif ; return 0; } EOF -if { (eval echo configure:3360: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3393: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_linux_exports_sys_chdir=yes else @@ -3372,7 +3405,7 @@ echo "$ac_t""$ac_cv_linux_exports_sys_chdir" 1>&6 CPPFLAGS="$save_CPPFLAGS" echo $ac_n "checking for exported sys_close""... $ac_c" 1>&6 -echo "configure:3376: checking for exported sys_close" >&5 +echo "configure:3409: checking for exported sys_close" >&5 save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -I${LINUX_KERNEL_PATH}/include/asm/mach-${SUBARCH} -D__KERNEL__ $CPPFLAGS" if eval "test \"`echo '$''{'ac_cv_linux_exports_sys_close'+set}'`\" = set"; then @@ -3380,7 +3413,7 @@ if eval "test \"`echo '$''{'ac_cv_linux_exports_sys_close'+set}'`\" = set"; then else cat > conftest.$ac_ext < int main() { @@ -3389,7 +3422,7 @@ int main() { #endif ; return 0; } EOF -if { (eval echo configure:3393: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3426: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_linux_exports_sys_close=yes else @@ -3405,7 +3438,7 @@ echo "$ac_t""$ac_cv_linux_exports_sys_close" 1>&6 CPPFLAGS="$save_CPPFLAGS" echo $ac_n "checking for exported sys_wait4""... $ac_c" 1>&6 -echo "configure:3409: checking for exported sys_wait4" >&5 +echo "configure:3442: checking for exported sys_wait4" >&5 save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -I${LINUX_KERNEL_PATH}/include/asm/mach-${SUBARCH} -D__KERNEL__ $CPPFLAGS" if eval "test \"`echo '$''{'ac_cv_linux_exports_sys_wait4'+set}'`\" = set"; then @@ -3413,7 +3446,7 @@ if eval "test \"`echo '$''{'ac_cv_linux_exports_sys_wait4'+set}'`\" = set"; then else cat > conftest.$ac_ext < int main() { @@ -3422,7 +3455,7 @@ int main() { #endif ; return 0; } EOF -if { (eval echo configure:3426: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3459: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_linux_exports_sys_wait4=yes else @@ -3593,6 +3626,12 @@ EOF if test "x$ac_cv_linux_kernel_is_selinux" = "xyes" ; then cat >> confdefs.h <<\EOF #define LINUX_KERNEL_IS_SELINUX 1 +EOF + + fi + if test "x$ac_cv_linux_kernel_sock_create_v" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define LINUX_KERNEL_SOCK_CREATE_V 1 EOF fi @@ -3640,13 +3679,13 @@ EOF echo "$ac_t""sun4" 1>&6 echo $ac_n "checking for vfs_dqrwlock in struct ufsvfs""... $ac_c" 1>&6 -echo "configure:3644: checking for vfs_dqrwlock in struct ufsvfs" >&5 +echo "configure:3683: checking for vfs_dqrwlock in struct ufsvfs" >&5 if eval "test \"`echo '$''{'ac_cv_solaris_ufsvfs_has_dqrwlock'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -3655,7 +3694,7 @@ struct ufsvfs _ufsvfs; (void) _ufsvfs.vfs_dqrwlock; ; return 0; } EOF -if { (eval echo configure:3659: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3698: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_solaris_ufsvfs_has_dqrwlock=yes else @@ -3677,13 +3716,13 @@ fi echo $ac_n "checking for p_corefile in struct proc""... $ac_c" 1>&6 -echo "configure:3681: checking for p_corefile in struct proc" >&5 +echo "configure:3720: checking for p_corefile in struct proc" >&5 if eval "test \"`echo '$''{'ac_cv_solaris_proc_has_p_corefile'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -3692,7 +3731,7 @@ struct proc _proc; (void) _proc.p_corefile; ; return 0; } EOF -if { (eval echo configure:3696: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3735: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_solaris_proc_has_p_corefile=yes else @@ -3714,13 +3753,13 @@ fi echo $ac_n "checking for fs_rolled in struct proc""... $ac_c" 1>&6 -echo "configure:3718: checking for fs_rolled in struct proc" >&5 +echo "configure:3757: checking for fs_rolled in struct proc" >&5 if eval "test \"`echo '$''{'ac_cv_solaris_fs_has_fs_rolled'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { @@ -3728,7 +3767,7 @@ struct fs _fs; (void) _fs.fs_rolled; ; return 0; } EOF -if { (eval echo configure:3732: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3771: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_solaris_fs_has_fs_rolled=yes else @@ -3809,7 +3848,7 @@ if test "x$with_afs_sysname" != "x"; then AFS_SYSNAME="$with_afs_sysname" else echo $ac_n "checking your AFS sysname""... $ac_c" 1>&6 -echo "configure:3813: checking your AFS sysname" >&5 +echo "configure:3852: checking your AFS sysname" >&5 case $host in i?86-*-openbsd3.1) AFS_SYSNAME="i386_obsd31" @@ -4074,7 +4113,7 @@ echo "configure:3813: checking your AFS sysname" >&5 save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-I${LINUX_KERNEL_PATH}/include $CPPFLAGS" cat > conftest.$ac_ext < int main() { @@ -4083,7 +4122,7 @@ int main() { #endif ; return 0; } EOF -if { (eval echo configure:4087: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4126: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_linux_is_uml=yes else @@ -4113,14 +4152,14 @@ EOF ;; *) echo $ac_n "checking for definition of struct buf""... $ac_c" 1>&6 -echo "configure:4117: checking for definition of struct buf" >&5 +echo "configure:4156: checking for definition of struct buf" >&5 if eval "test \"`echo '$''{'ac_cv_have_struct_buf'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_have_struct_buf=no cat > conftest.$ac_ext < int main() { @@ -4128,7 +4167,7 @@ struct buf x; printf("%d\n", sizeof(x)); ; return 0; } EOF -if { (eval echo configure:4132: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4171: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_have_struct_buf=yes else @@ -4156,9 +4195,9 @@ if eval "test \"`echo '$''{'ac_cv_sockaddr_len'+set}'`\" = set"; then else echo $ac_n "checking if struct sockaddr has sa_len field""... $ac_c" 1>&6 -echo "configure:4160: checking if struct sockaddr has sa_len field" >&5 +echo "configure:4199: checking if struct sockaddr has sa_len field" >&5 cat > conftest.$ac_ext < #include @@ -4167,7 +4206,7 @@ struct sockaddr *a; a->sa_len=0; ; return 0; } EOF -if { (eval echo configure:4171: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4210: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_sockaddr_len=yes else @@ -4192,12 +4231,12 @@ else for ac_func in socket do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:4196: checking for $ac_func" >&5 +echo "configure:4235: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4263: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -4249,7 +4288,7 @@ done for lib in socket inet; do if test "$HAVE_SOCKET" != 1; then echo $ac_n "checking for socket in -l${lib}""... $ac_c" 1>&6 -echo "configure:4253: checking for socket in -l${lib}" >&5 +echo "configure:4292: checking for socket in -l${lib}" >&5 ac_lib_var=`echo ${lib}'_'socket | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4257,7 +4296,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l${lib} $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4311: \"$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 @@ -4298,12 +4337,12 @@ fi for ac_func in connect do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:4302: checking for $ac_func" >&5 +echo "configure:4341: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4369: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -4355,7 +4394,7 @@ done for lib in nsl; do if test "$HAVE_CONNECT" != 1; then echo $ac_n "checking for connect in -l${lib}""... $ac_c" 1>&6 -echo "configure:4359: checking for connect in -l${lib}" >&5 +echo "configure:4398: checking for connect in -l${lib}" >&5 ac_lib_var=`echo ${lib}'_'connect | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4363,7 +4402,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l${lib} $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4417: \"$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 @@ -4404,12 +4443,12 @@ fi for ac_func in gethostbyname do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:4408: checking for $ac_func" >&5 +echo "configure:4447: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4475: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -4460,7 +4499,7 @@ done for lib in dns nsl resolv; do if test "$HAVE_GETHOSTBYNAME" != 1; then echo $ac_n "checking for gethostbyname in -l${lib}""... $ac_c" 1>&6 -echo "configure:4464: checking for gethostbyname in -l${lib}" >&5 +echo "configure:4503: checking for gethostbyname in -l${lib}" >&5 ac_lib_var=`echo ${lib}'_'gethostbyname | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4468,7 +4507,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l${lib} $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4522: \"$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 @@ -4507,9 +4546,9 @@ fi fi echo $ac_n "checking for the useability of arpa/nameser_compat.h""... $ac_c" 1>&6 -echo "configure:4511: checking for the useability of arpa/nameser_compat.h" >&5 +echo "configure:4550: checking for the useability of arpa/nameser_compat.h" >&5 cat > conftest.$ac_ext < @@ -4526,7 +4565,7 @@ int main() { static int i; i = 0; ; return 0; } EOF -if { (eval echo configure:4530: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4569: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF @@ -4544,11 +4583,11 @@ rm -f conftest* openafs_save_libs="$LIBS" echo $ac_n "checking for res_search""... $ac_c" 1>&6 -echo "configure:4548: checking for res_search" >&5 +echo "configure:4587: checking for res_search" >&5 ac_cv_func_res_search=no cat > conftest.$ac_ext < @@ -4572,7 +4611,7 @@ return 0; ; return 0; } EOF -if { (eval echo configure:4576: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4615: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_func_res_search=yes else @@ -4589,7 +4628,7 @@ rm -f conftest* ac_cv_func_res_search=no cat > conftest.$ac_ext < @@ -4613,7 +4652,7 @@ return 0; ; return 0; } EOF -if { (eval echo configure:4617: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4656: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_func_res_search=yes else @@ -4647,7 +4686,7 @@ fi PTHREAD_LIBS=error echo $ac_n "checking for pthread_attr_init in -lpthread""... $ac_c" 1>&6 -echo "configure:4651: checking for pthread_attr_init in -lpthread" >&5 +echo "configure:4690: checking for pthread_attr_init in -lpthread" >&5 ac_lib_var=`echo pthread'_'pthread_attr_init | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4655,7 +4694,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpthread $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4709: \"$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 @@ -4688,7 +4727,7 @@ fi if test "x$PTHREAD_LIBS" = xerror; then echo $ac_n "checking for pthread_attr_init in -lpthreads""... $ac_c" 1>&6 -echo "configure:4692: checking for pthread_attr_init in -lpthreads" >&5 +echo "configure:4731: checking for pthread_attr_init in -lpthreads" >&5 ac_lib_var=`echo pthreads'_'pthread_attr_init | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4696,7 +4735,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpthreads $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4750: \"$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 @@ -4730,7 +4769,7 @@ fi fi if test "x$PTHREAD_LIBS" = xerror; then echo $ac_n "checking for pthread_attr_init in -lc_r""... $ac_c" 1>&6 -echo "configure:4734: checking for pthread_attr_init in -lc_r" >&5 +echo "configure:4773: checking for pthread_attr_init in -lc_r" >&5 ac_lib_var=`echo c_r'_'pthread_attr_init | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4738,7 +4777,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lc_r $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4792: \"$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 @@ -4772,12 +4811,12 @@ fi fi if test "x$PTHREAD_LIBS" = xerror; then echo $ac_n "checking for pthread_attr_init""... $ac_c" 1>&6 -echo "configure:4776: checking for pthread_attr_init" >&5 +echo "configure:4815: checking for pthread_attr_init" >&5 if eval "test \"`echo '$''{'ac_cv_func_pthread_attr_init'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4843: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_pthread_attr_init=yes" else @@ -4920,7 +4959,7 @@ EOF fi echo $ac_n "checking for tivoli tsm butc support""... $ac_c" 1>&6 -echo "configure:4924: checking for tivoli tsm butc support" >&5 +echo "configure:4963: checking for tivoli tsm butc support" >&5 XBSA_CFLAGS="" if test "$enable_tivoli_tsm" = "yes"; then XBSADIR1=/usr/tivoli/tsm/client/api/bin/xopen @@ -4941,12 +4980,12 @@ fi echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 -echo "configure:4945: checking for ANSI C header files" >&5 +echo "configure:4984: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -4954,7 +4993,7 @@ else #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4958: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4997: \"$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* @@ -4971,7 +5010,7 @@ rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -4989,7 +5028,7 @@ fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -5010,7 +5049,7 @@ if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') @@ -5021,7 +5060,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF -if { (eval echo configure:5025: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:5064: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else @@ -5045,12 +5084,12 @@ EOF fi echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6 -echo "configure:5049: checking for sys/wait.h that is POSIX.1 compatible" >&5 +echo "configure:5088: checking for sys/wait.h that is POSIX.1 compatible" >&5 if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -5066,7 +5105,7 @@ wait (&s); s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; ; return 0; } EOF -if { (eval echo configure:5070: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5109: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_header_sys_wait_h=yes else @@ -5091,12 +5130,12 @@ for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6 -echo "configure:5095: checking for $ac_hdr that defines DIR" >&5 +echo "configure:5134: checking for $ac_hdr that defines DIR" >&5 if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include <$ac_hdr> @@ -5104,7 +5143,7 @@ int main() { DIR *dirp = 0; ; return 0; } EOF -if { (eval echo configure:5108: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5147: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* eval "ac_cv_header_dirent_$ac_safe=yes" else @@ -5129,7 +5168,7 @@ done # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. if test $ac_header_dirent = dirent.h; then echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6 -echo "configure:5133: checking for opendir in -ldir" >&5 +echo "configure:5172: checking for opendir in -ldir" >&5 ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5137,7 +5176,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldir $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5191: \"$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 @@ -5170,7 +5209,7 @@ fi else echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6 -echo "configure:5174: checking for opendir in -lx" >&5 +echo "configure:5213: checking for opendir in -lx" >&5 ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5178,7 +5217,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lx $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5232: \"$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 @@ -5215,17 +5254,17 @@ for ac_hdr in stdlib.h string.h unistd.h fcntl.h sys/time.h sys/file.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:5219: checking for $ac_hdr" >&5 +echo "configure:5258: 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 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5229: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:5268: \"$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* @@ -5255,17 +5294,17 @@ for ac_hdr in netinet/in.h netdb.h sys/fcntl.h sys/mnttab.h sys/mntent.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:5259: checking for $ac_hdr" >&5 +echo "configure:5298: 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 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5269: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:5308: \"$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* @@ -5295,17 +5334,17 @@ for ac_hdr in mntent.h sys/vfs.h sys/param.h sys/fs_types.h sys/fstyp.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:5299: checking for $ac_hdr" >&5 +echo "configure:5338: 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 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5309: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:5348: \"$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* @@ -5335,17 +5374,17 @@ for ac_hdr in sys/mount.h strings.h termios.h signal.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:5339: checking for $ac_hdr" >&5 +echo "configure:5378: 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 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5349: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:5388: \"$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* @@ -5375,17 +5414,17 @@ for ac_hdr in windows.h malloc.h winsock2.h direct.h io.h sys/user.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:5379: checking for $ac_hdr" >&5 +echo "configure:5418: 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 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5389: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:5428: \"$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* @@ -5415,17 +5454,17 @@ for ac_hdr in security/pam_modules.h siad.h usersec.h ucontext.h regex.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:5419: checking for $ac_hdr" >&5 +echo "configure:5458: 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 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5429: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:5468: \"$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* @@ -5469,12 +5508,12 @@ fi for ac_func in utimes random srandom getdtablesize snprintf strlcat strlcpy re_comp re_exec do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5473: checking for $ac_func" >&5 +echo "configure:5512: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5540: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5524,12 +5563,12 @@ done for ac_func in setprogname getprogname sigaction mkstemp vsnprintf strerror do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5528: checking for $ac_func" >&5 +echo "configure:5567: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5595: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5580,12 +5619,12 @@ done for ac_func in regcomp regexec regerror do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5584: checking for $ac_func" >&5 +echo "configure:5623: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5651: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5633,7 +5672,7 @@ fi done echo $ac_n "checking for POSIX regex library""... $ac_c" 1>&6 -echo "configure:5637: checking for POSIX regex library" >&5 +echo "configure:5676: checking for POSIX regex library" >&5 if test "$ac_cv_header_regex_h" = "yes" && \ test "$ac_cv_func_regcomp" = "yes" && \ test "$ac_cv_func_regexec" = "yes" && \ @@ -5648,12 +5687,12 @@ else fi echo $ac_n "checking for ssize_t""... $ac_c" 1>&6 -echo "configure:5652: checking for ssize_t" >&5 +echo "configure:5691: checking for ssize_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_ssize_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -5681,7 +5720,7 @@ EOF fi echo $ac_n "checking size of long""... $ac_c" 1>&6 -echo "configure:5685: checking size of long" >&5 +echo "configure:5724: checking size of long" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5689,7 +5728,7 @@ else { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext < main() @@ -5700,7 +5739,7 @@ main() exit(0); } EOF -if { (eval echo configure:5704: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:5743: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_long=`cat conftestval` else @@ -5723,12 +5762,12 @@ EOF for ac_func in timegm do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5727: checking for $ac_func" >&5 +echo "configure:5766: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5794: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5855,7 +5894,7 @@ LWP_OPTMZ=-O # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:5859: checking for $ac_word" >&5 +echo "configure:5898: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5887,7 +5926,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:5891: checking for $ac_word" >&5 +echo "configure:5930: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5922,7 +5961,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:5926: checking for $ac_word" >&5 +echo "configure:5965: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5957,7 +5996,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:5961: checking for $ac_word" >&5 +echo "configure:6000: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_MV'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5992,7 +6031,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:5996: checking for $ac_word" >&5 +echo "configure:6035: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RM'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -6027,7 +6066,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:6031: checking for $ac_word" >&5 +echo "configure:6070: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LD'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -6062,7 +6101,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:6066: checking for $ac_word" >&5 +echo "configure:6105: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -6097,7 +6136,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:6101: checking for $ac_word" >&5 +echo "configure:6140: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -6132,7 +6171,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:6136: checking for $ac_word" >&5 +echo "configure:6175: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LORDER'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -6361,12 +6400,14 @@ case $AFS_SYSNAME in SHLIB_LINKER="${MT_CC} -shared" ;; - amd64_linux24) + amd64_linux*) + CCOBJ="${CC} -fPIC" KERN_OPTMZ=-O2 LEX="flex -l" MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}' MT_LIBS="-lpthread" PAM_CFLAGS="-g -O2 -Dlinux -DLINUX_PAM -fPIC" + SHLIB_CFLAGS="-fPIC" SHLIB_LDFLAGS="-shared -Xlinker -x" TXLIBS="-lncurses" XCFLAGS="-g -O2 -D_LARGEFILE64_SOURCE" @@ -6962,7 +7003,7 @@ case $AFS_SYSNAME in sgi_6*) echo $ac_n "checking for mem* in sys/systm.h""... $ac_c" 1>&6 -echo "configure:6966: checking for mem* in sys/systm.h" >&5 +echo "configure:7007: checking for mem* in sys/systm.h" >&5 save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS -D_KERNEL -D__STRING_H__" if eval "test \"`echo '$''{'ac_cv_irix_sys_systm_h_has_mem_funcs'+set}'`\" = set"; then @@ -6970,7 +7011,7 @@ if eval "test \"`echo '$''{'ac_cv_irix_sys_systm_h_has_mem_funcs'+set}'`\" = set else cat > conftest.$ac_ext < #include @@ -6980,7 +7021,7 @@ extern void *memcpy(char *, const void *, size_t); ; return 0; } EOF -if { (eval echo configure:6984: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:7025: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_irix_sys_systm_h_has_mem_funcs=no else diff --git a/configure-libafs b/configure-libafs index 037b5800c..2fd5e6afe 100644 --- a/configure-libafs +++ b/configure-libafs @@ -754,7 +754,7 @@ fi PACKAGE=openafs-libafs -VERSION=1.3.71 +VERSION=1.3.73 if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; } @@ -2869,13 +2869,46 @@ fi echo "$ac_t""$ac_cv_linux_kernel_is_selinux" 1>&6 CPPFLAGS="$save_CPPFLAGS" +echo $ac_n "checking for 5th argument in sock_create found in some SELinux kernels""... $ac_c" 1>&6 +echo "configure:2874: checking for 5th argument in sock_create found in some SELinux kernels" >&5 +save_CPPFLAGS="$CPPFLAGS" +CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -D__KERNEL__ $CPPFLAGS" +if eval "test \"`echo '$''{'ac_cv_linux_kernel_sock_create_v'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + +cat > conftest.$ac_ext < +int main() { + + sock_create(0,0,0,0,0) + +; return 0; } +EOF +if { (eval echo configure:2891: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_linux_kernel_sock_create_v=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_linux_kernel_sock_create_v=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_linux_kernel_sock_create_v" 1>&6 +CPPFLAGS="$save_CPPFLAGS" + RHCONFIG_SP="" RHCONFIG_MP="" if test "x$enable_redhat_buildsys" = "xyes"; then echo "configure: warning: Configured to build from a Red Hat SPEC file" 1>&2 else echo $ac_n "checking for redhat kernel configuration""... $ac_c" 1>&6 -echo "configure:2879: checking for redhat kernel configuration" >&5 +echo "configure:2912: checking for redhat kernel configuration" >&5 if test -f "${LINUX_KERNEL_PATH}/include/linux/rhconfig.h"; then ac_linux_rhconfig=yes RHCONFIG_SP="-D__BOOT_KERNEL_UP=1 -D__BOOT_KERNEL_SMP=0" @@ -2894,7 +2927,7 @@ fi echo $ac_n "checking for recalc_sigpending arg type""... $ac_c" 1>&6 -echo "configure:2898: checking for recalc_sigpending arg type" >&5 +echo "configure:2931: checking for recalc_sigpending arg type" >&5 save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -I${LINUX_KERNEL_PATH}/include/asm/mach-${SUBARCH} -D__KERNEL__ $CPPFLAGS" if eval "test \"`echo '$''{'ac_cv_linux_func_recalc_sigpending_takes_void'+set}'`\" = set"; then @@ -2902,14 +2935,14 @@ if eval "test \"`echo '$''{'ac_cv_linux_func_recalc_sigpending_takes_void'+set}' else cat > conftest.$ac_ext < int main() { recalc_sigpending(); ; return 0; } EOF -if { (eval echo configure:2913: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2946: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_linux_func_recalc_sigpending_takes_void=yes else @@ -2925,7 +2958,7 @@ echo "$ac_t""$ac_cv_linux_func_recalc_sigpending_takes_void" 1>&6 CPPFLAGS="$save_CPPFLAGS" echo $ac_n "checking for parent in struct task_struct""... $ac_c" 1>&6 -echo "configure:2929: checking for parent in struct task_struct" >&5 +echo "configure:2962: checking for parent in struct task_struct" >&5 save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -I${LINUX_KERNEL_PATH}/include/asm/mach-${SUBARCH} -D__KERNEL__ $CPPFLAGS" if eval "test \"`echo '$''{'ac_cv_linux_sched_struct_task_struct_has_parent'+set}'`\" = set"; then @@ -2933,7 +2966,7 @@ if eval "test \"`echo '$''{'ac_cv_linux_sched_struct_task_struct_has_parent'+set else cat > conftest.$ac_ext < int main() { @@ -2941,7 +2974,7 @@ struct task_struct _tsk; printf("%d\n", _tsk.parent); ; return 0; } EOF -if { (eval echo configure:2945: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2978: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_linux_sched_struct_task_struct_has_parent=yes else @@ -2957,7 +2990,7 @@ echo "$ac_t""$ac_cv_linux_sched_struct_task_struct_has_parent" 1>&6 CPPFLAGS="$save_CPPFLAGS" echo $ac_n "checking for real_parent in struct task_struct""... $ac_c" 1>&6 -echo "configure:2961: checking for real_parent in struct task_struct" >&5 +echo "configure:2994: checking for real_parent in struct task_struct" >&5 save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -I${LINUX_KERNEL_PATH}/include/asm/mach-${SUBARCH} -D__KERNEL__ $CPPFLAGS" if eval "test \"`echo '$''{'ac_cv_linux_sched_struct_task_struct_has_real_parent'+set}'`\" = set"; then @@ -2965,7 +2998,7 @@ if eval "test \"`echo '$''{'ac_cv_linux_sched_struct_task_struct_has_real_parent else cat > conftest.$ac_ext < int main() { @@ -2973,7 +3006,7 @@ struct task_struct _tsk; printf("%d\n", _tsk.real_parent); ; return 0; } EOF -if { (eval echo configure:2977: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3010: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_linux_sched_struct_task_struct_has_real_parent=yes else @@ -2989,7 +3022,7 @@ echo "$ac_t""$ac_cv_linux_sched_struct_task_struct_has_real_parent" 1>&6 CPPFLAGS="$save_CPPFLAGS" echo $ac_n "checking for sig in struct task_struct""... $ac_c" 1>&6 -echo "configure:2993: checking for sig in struct task_struct" >&5 +echo "configure:3026: checking for sig in struct task_struct" >&5 save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -I${LINUX_KERNEL_PATH}/include/asm/mach-${SUBARCH} -D__KERNEL__ $CPPFLAGS" if eval "test \"`echo '$''{'ac_cv_linux_sched_struct_task_struct_has_sig'+set}'`\" = set"; then @@ -2997,7 +3030,7 @@ if eval "test \"`echo '$''{'ac_cv_linux_sched_struct_task_struct_has_sig'+set}'` else cat > conftest.$ac_ext < int main() { @@ -3005,7 +3038,7 @@ struct task_struct _tsk; printf("%d\n", _tsk.sig); ; return 0; } EOF -if { (eval echo configure:3009: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3042: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_linux_sched_struct_task_struct_has_sig=yes else @@ -3021,7 +3054,7 @@ echo "$ac_t""$ac_cv_linux_sched_struct_task_struct_has_sig" 1>&6 CPPFLAGS="$save_CPPFLAGS" echo $ac_n "checking for sighand in struct task_struct""... $ac_c" 1>&6 -echo "configure:3025: checking for sighand in struct task_struct" >&5 +echo "configure:3058: checking for sighand in struct task_struct" >&5 save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -I${LINUX_KERNEL_PATH}/include/asm/mach-${SUBARCH} -D__KERNEL__ $CPPFLAGS" if eval "test \"`echo '$''{'ac_cv_linux_sched_struct_task_struct_has_sighand'+set}'`\" = set"; then @@ -3029,7 +3062,7 @@ if eval "test \"`echo '$''{'ac_cv_linux_sched_struct_task_struct_has_sighand'+se else cat > conftest.$ac_ext < int main() { @@ -3037,7 +3070,7 @@ struct task_struct _tsk; printf("%d\n", _tsk.sighand); ; return 0; } EOF -if { (eval echo configure:3041: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3074: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_linux_sched_struct_task_struct_has_sighand=yes else @@ -3053,7 +3086,7 @@ echo "$ac_t""$ac_cv_linux_sched_struct_task_struct_has_sighand" 1>&6 CPPFLAGS="$save_CPPFLAGS" echo $ac_n "checking for sigmask_lock in struct task_struct""... $ac_c" 1>&6 -echo "configure:3057: checking for sigmask_lock in struct task_struct" >&5 +echo "configure:3090: checking for sigmask_lock in struct task_struct" >&5 save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -I${LINUX_KERNEL_PATH}/include/asm/mach-${SUBARCH} -D__KERNEL__ $CPPFLAGS" if eval "test \"`echo '$''{'ac_cv_linux_sched_struct_task_struct_has_sigmask_lock'+set}'`\" = set"; then @@ -3061,7 +3094,7 @@ if eval "test \"`echo '$''{'ac_cv_linux_sched_struct_task_struct_has_sigmask_loc else cat > conftest.$ac_ext < int main() { @@ -3069,7 +3102,7 @@ struct task_struct _tsk; printf("%d\n", _tsk.sigmask_lock); ; return 0; } EOF -if { (eval echo configure:3073: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3106: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_linux_sched_struct_task_struct_has_sigmask_lock=yes else @@ -3090,13 +3123,13 @@ else save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -D__KERNEL__ $RHCONFIG_SP $CPPFLAGS" echo $ac_n "checking if kernel uses MODVERSIONS""... $ac_c" 1>&6 -echo "configure:3094: checking if kernel uses MODVERSIONS" >&5 +echo "configure:3127: checking if kernel uses MODVERSIONS" >&5 if eval "test \"`echo '$''{'ac_cv_linux_config_modversions'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -3108,7 +3141,7 @@ lose; ; return 0; } EOF -if { (eval echo configure:3112: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3145: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_linux_config_modversions=yes else @@ -3122,7 +3155,7 @@ fi echo "$ac_t""$ac_cv_linux_config_modversions" 1>&6 echo $ac_n "checking which kernel modules to build""... $ac_c" 1>&6 -echo "configure:3126: checking which kernel modules to build" >&5 +echo "configure:3159: checking which kernel modules to build" >&5 if test "x$ac_linux_rhconfig" = "xyes" -o "x$ac_cv_linux_config_modversions" = "xno"; then MPS="MP SP" else @@ -3131,7 +3164,7 @@ echo "configure:3126: checking which kernel modules to build" >&5 else cat > conftest.$ac_ext < @@ -3142,7 +3175,7 @@ lose; ; return 0; } EOF -if { (eval echo configure:3146: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3179: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_linux_config_smp=yes else @@ -3174,7 +3207,7 @@ fi else echo $ac_n "checking for exported init_mm""... $ac_c" 1>&6 -echo "configure:3178: checking for exported init_mm" >&5 +echo "configure:3211: checking for exported init_mm" >&5 save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -I${LINUX_KERNEL_PATH}/include/asm/mach-${SUBARCH} -D__KERNEL__ $CPPFLAGS" if eval "test \"`echo '$''{'ac_cv_linux_exports_init_mm'+set}'`\" = set"; then @@ -3182,7 +3215,7 @@ if eval "test \"`echo '$''{'ac_cv_linux_exports_init_mm'+set}'`\" = set"; then else cat > conftest.$ac_ext < int main() { @@ -3191,7 +3224,7 @@ int main() { #endif ; return 0; } EOF -if { (eval echo configure:3195: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3228: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_linux_exports_init_mm=yes else @@ -3207,7 +3240,7 @@ echo "$ac_t""$ac_cv_linux_exports_init_mm" 1>&6 CPPFLAGS="$save_CPPFLAGS" echo $ac_n "checking for exported kallsyms_address_to_symbol""... $ac_c" 1>&6 -echo "configure:3211: checking for exported kallsyms_address_to_symbol" >&5 +echo "configure:3244: checking for exported kallsyms_address_to_symbol" >&5 save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -I${LINUX_KERNEL_PATH}/include/asm/mach-${SUBARCH} -D__KERNEL__ $CPPFLAGS" if eval "test \"`echo '$''{'ac_cv_linux_exports_kallsyms_address'+set}'`\" = set"; then @@ -3215,7 +3248,7 @@ if eval "test \"`echo '$''{'ac_cv_linux_exports_kallsyms_address'+set}'`\" = set else cat > conftest.$ac_ext < int main() { @@ -3224,7 +3257,7 @@ int main() { #endif ; return 0; } EOF -if { (eval echo configure:3228: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3261: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_linux_exports_kallsyms_address=yes else @@ -3240,7 +3273,7 @@ echo "$ac_t""$ac_cv_linux_exports_kallsyms_address" 1>&6 CPPFLAGS="$save_CPPFLAGS" echo $ac_n "checking for exported kallsyms_symbol_to_address""... $ac_c" 1>&6 -echo "configure:3244: checking for exported kallsyms_symbol_to_address" >&5 +echo "configure:3277: checking for exported kallsyms_symbol_to_address" >&5 save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -I${LINUX_KERNEL_PATH}/include/asm/mach-${SUBARCH} -D__KERNEL__ $CPPFLAGS" if eval "test \"`echo '$''{'ac_cv_linux_exports_kallsyms_symbol'+set}'`\" = set"; then @@ -3248,7 +3281,7 @@ if eval "test \"`echo '$''{'ac_cv_linux_exports_kallsyms_symbol'+set}'`\" = set" else cat > conftest.$ac_ext < int main() { @@ -3257,7 +3290,7 @@ int main() { #endif ; return 0; } EOF -if { (eval echo configure:3261: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3294: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_linux_exports_kallsyms_symbol=yes else @@ -3273,7 +3306,7 @@ echo "$ac_t""$ac_cv_linux_exports_kallsyms_symbol" 1>&6 CPPFLAGS="$save_CPPFLAGS" echo $ac_n "checking for exported sys_call_table""... $ac_c" 1>&6 -echo "configure:3277: checking for exported sys_call_table" >&5 +echo "configure:3310: checking for exported sys_call_table" >&5 save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -I${LINUX_KERNEL_PATH}/include/asm/mach-${SUBARCH} -D__KERNEL__ $CPPFLAGS" if eval "test \"`echo '$''{'ac_cv_linux_exports_sys_call_table'+set}'`\" = set"; then @@ -3281,7 +3314,7 @@ if eval "test \"`echo '$''{'ac_cv_linux_exports_sys_call_table'+set}'`\" = set"; else cat > conftest.$ac_ext < int main() { @@ -3290,7 +3323,7 @@ int main() { #endif ; return 0; } EOF -if { (eval echo configure:3294: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3327: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_linux_exports_sys_call_table=yes else @@ -3306,7 +3339,7 @@ echo "$ac_t""$ac_cv_linux_exports_sys_call_table" 1>&6 CPPFLAGS="$save_CPPFLAGS" echo $ac_n "checking for exported ia32_sys_call_table""... $ac_c" 1>&6 -echo "configure:3310: checking for exported ia32_sys_call_table" >&5 +echo "configure:3343: checking for exported ia32_sys_call_table" >&5 save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -I${LINUX_KERNEL_PATH}/include/asm/mach-${SUBARCH} -D__KERNEL__ $CPPFLAGS" if eval "test \"`echo '$''{'ac_cv_linux_exports_ia32_sys_call_table'+set}'`\" = set"; then @@ -3314,7 +3347,7 @@ if eval "test \"`echo '$''{'ac_cv_linux_exports_ia32_sys_call_table'+set}'`\" = else cat > conftest.$ac_ext < int main() { @@ -3323,7 +3356,7 @@ int main() { #endif ; return 0; } EOF -if { (eval echo configure:3327: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3360: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_linux_exports_ia32_sys_call_table=yes else @@ -3339,7 +3372,7 @@ echo "$ac_t""$ac_cv_linux_exports_ia32_sys_call_table" 1>&6 CPPFLAGS="$save_CPPFLAGS" echo $ac_n "checking for exported sys_chdir""... $ac_c" 1>&6 -echo "configure:3343: checking for exported sys_chdir" >&5 +echo "configure:3376: checking for exported sys_chdir" >&5 save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -I${LINUX_KERNEL_PATH}/include/asm/mach-${SUBARCH} -D__KERNEL__ $CPPFLAGS" if eval "test \"`echo '$''{'ac_cv_linux_exports_sys_chdir'+set}'`\" = set"; then @@ -3347,7 +3380,7 @@ if eval "test \"`echo '$''{'ac_cv_linux_exports_sys_chdir'+set}'`\" = set"; then else cat > conftest.$ac_ext < int main() { @@ -3356,7 +3389,7 @@ int main() { #endif ; return 0; } EOF -if { (eval echo configure:3360: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3393: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_linux_exports_sys_chdir=yes else @@ -3372,7 +3405,7 @@ echo "$ac_t""$ac_cv_linux_exports_sys_chdir" 1>&6 CPPFLAGS="$save_CPPFLAGS" echo $ac_n "checking for exported sys_close""... $ac_c" 1>&6 -echo "configure:3376: checking for exported sys_close" >&5 +echo "configure:3409: checking for exported sys_close" >&5 save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -I${LINUX_KERNEL_PATH}/include/asm/mach-${SUBARCH} -D__KERNEL__ $CPPFLAGS" if eval "test \"`echo '$''{'ac_cv_linux_exports_sys_close'+set}'`\" = set"; then @@ -3380,7 +3413,7 @@ if eval "test \"`echo '$''{'ac_cv_linux_exports_sys_close'+set}'`\" = set"; then else cat > conftest.$ac_ext < int main() { @@ -3389,7 +3422,7 @@ int main() { #endif ; return 0; } EOF -if { (eval echo configure:3393: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3426: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_linux_exports_sys_close=yes else @@ -3405,7 +3438,7 @@ echo "$ac_t""$ac_cv_linux_exports_sys_close" 1>&6 CPPFLAGS="$save_CPPFLAGS" echo $ac_n "checking for exported sys_wait4""... $ac_c" 1>&6 -echo "configure:3409: checking for exported sys_wait4" >&5 +echo "configure:3442: checking for exported sys_wait4" >&5 save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -I${LINUX_KERNEL_PATH}/include/asm/mach-${SUBARCH} -D__KERNEL__ $CPPFLAGS" if eval "test \"`echo '$''{'ac_cv_linux_exports_sys_wait4'+set}'`\" = set"; then @@ -3413,7 +3446,7 @@ if eval "test \"`echo '$''{'ac_cv_linux_exports_sys_wait4'+set}'`\" = set"; then else cat > conftest.$ac_ext < int main() { @@ -3422,7 +3455,7 @@ int main() { #endif ; return 0; } EOF -if { (eval echo configure:3426: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3459: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_linux_exports_sys_wait4=yes else @@ -3593,6 +3626,12 @@ EOF if test "x$ac_cv_linux_kernel_is_selinux" = "xyes" ; then cat >> confdefs.h <<\EOF #define LINUX_KERNEL_IS_SELINUX 1 +EOF + + fi + if test "x$ac_cv_linux_kernel_sock_create_v" = "xyes" ; then + cat >> confdefs.h <<\EOF +#define LINUX_KERNEL_SOCK_CREATE_V 1 EOF fi @@ -3640,13 +3679,13 @@ EOF echo "$ac_t""sun4" 1>&6 echo $ac_n "checking for vfs_dqrwlock in struct ufsvfs""... $ac_c" 1>&6 -echo "configure:3644: checking for vfs_dqrwlock in struct ufsvfs" >&5 +echo "configure:3683: checking for vfs_dqrwlock in struct ufsvfs" >&5 if eval "test \"`echo '$''{'ac_cv_solaris_ufsvfs_has_dqrwlock'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -3655,7 +3694,7 @@ struct ufsvfs _ufsvfs; (void) _ufsvfs.vfs_dqrwlock; ; return 0; } EOF -if { (eval echo configure:3659: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3698: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_solaris_ufsvfs_has_dqrwlock=yes else @@ -3677,13 +3716,13 @@ fi echo $ac_n "checking for p_corefile in struct proc""... $ac_c" 1>&6 -echo "configure:3681: checking for p_corefile in struct proc" >&5 +echo "configure:3720: checking for p_corefile in struct proc" >&5 if eval "test \"`echo '$''{'ac_cv_solaris_proc_has_p_corefile'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -3692,7 +3731,7 @@ struct proc _proc; (void) _proc.p_corefile; ; return 0; } EOF -if { (eval echo configure:3696: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3735: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_solaris_proc_has_p_corefile=yes else @@ -3714,13 +3753,13 @@ fi echo $ac_n "checking for fs_rolled in struct proc""... $ac_c" 1>&6 -echo "configure:3718: checking for fs_rolled in struct proc" >&5 +echo "configure:3757: checking for fs_rolled in struct proc" >&5 if eval "test \"`echo '$''{'ac_cv_solaris_fs_has_fs_rolled'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { @@ -3728,7 +3767,7 @@ struct fs _fs; (void) _fs.fs_rolled; ; return 0; } EOF -if { (eval echo configure:3732: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3771: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_solaris_fs_has_fs_rolled=yes else @@ -3809,7 +3848,7 @@ if test "x$with_afs_sysname" != "x"; then AFS_SYSNAME="$with_afs_sysname" else echo $ac_n "checking your AFS sysname""... $ac_c" 1>&6 -echo "configure:3813: checking your AFS sysname" >&5 +echo "configure:3852: checking your AFS sysname" >&5 case $host in i?86-*-openbsd3.1) AFS_SYSNAME="i386_obsd31" @@ -4074,7 +4113,7 @@ echo "configure:3813: checking your AFS sysname" >&5 save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-I${LINUX_KERNEL_PATH}/include $CPPFLAGS" cat > conftest.$ac_ext < int main() { @@ -4083,7 +4122,7 @@ int main() { #endif ; return 0; } EOF -if { (eval echo configure:4087: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4126: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_linux_is_uml=yes else @@ -4113,14 +4152,14 @@ EOF ;; *) echo $ac_n "checking for definition of struct buf""... $ac_c" 1>&6 -echo "configure:4117: checking for definition of struct buf" >&5 +echo "configure:4156: checking for definition of struct buf" >&5 if eval "test \"`echo '$''{'ac_cv_have_struct_buf'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_have_struct_buf=no cat > conftest.$ac_ext < int main() { @@ -4128,7 +4167,7 @@ struct buf x; printf("%d\n", sizeof(x)); ; return 0; } EOF -if { (eval echo configure:4132: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4171: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_have_struct_buf=yes else @@ -4156,9 +4195,9 @@ if eval "test \"`echo '$''{'ac_cv_sockaddr_len'+set}'`\" = set"; then else echo $ac_n "checking if struct sockaddr has sa_len field""... $ac_c" 1>&6 -echo "configure:4160: checking if struct sockaddr has sa_len field" >&5 +echo "configure:4199: checking if struct sockaddr has sa_len field" >&5 cat > conftest.$ac_ext < #include @@ -4167,7 +4206,7 @@ struct sockaddr *a; a->sa_len=0; ; return 0; } EOF -if { (eval echo configure:4171: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4210: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_sockaddr_len=yes else @@ -4192,12 +4231,12 @@ else for ac_func in socket do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:4196: checking for $ac_func" >&5 +echo "configure:4235: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4263: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -4249,7 +4288,7 @@ done for lib in socket inet; do if test "$HAVE_SOCKET" != 1; then echo $ac_n "checking for socket in -l${lib}""... $ac_c" 1>&6 -echo "configure:4253: checking for socket in -l${lib}" >&5 +echo "configure:4292: checking for socket in -l${lib}" >&5 ac_lib_var=`echo ${lib}'_'socket | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4257,7 +4296,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l${lib} $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4311: \"$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 @@ -4298,12 +4337,12 @@ fi for ac_func in connect do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:4302: checking for $ac_func" >&5 +echo "configure:4341: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4369: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -4355,7 +4394,7 @@ done for lib in nsl; do if test "$HAVE_CONNECT" != 1; then echo $ac_n "checking for connect in -l${lib}""... $ac_c" 1>&6 -echo "configure:4359: checking for connect in -l${lib}" >&5 +echo "configure:4398: checking for connect in -l${lib}" >&5 ac_lib_var=`echo ${lib}'_'connect | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4363,7 +4402,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l${lib} $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4417: \"$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 @@ -4404,12 +4443,12 @@ fi for ac_func in gethostbyname do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:4408: checking for $ac_func" >&5 +echo "configure:4447: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4475: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -4460,7 +4499,7 @@ done for lib in dns nsl resolv; do if test "$HAVE_GETHOSTBYNAME" != 1; then echo $ac_n "checking for gethostbyname in -l${lib}""... $ac_c" 1>&6 -echo "configure:4464: checking for gethostbyname in -l${lib}" >&5 +echo "configure:4503: checking for gethostbyname in -l${lib}" >&5 ac_lib_var=`echo ${lib}'_'gethostbyname | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4468,7 +4507,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l${lib} $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4522: \"$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 @@ -4507,9 +4546,9 @@ fi fi echo $ac_n "checking for the useability of arpa/nameser_compat.h""... $ac_c" 1>&6 -echo "configure:4511: checking for the useability of arpa/nameser_compat.h" >&5 +echo "configure:4550: checking for the useability of arpa/nameser_compat.h" >&5 cat > conftest.$ac_ext < @@ -4526,7 +4565,7 @@ int main() { static int i; i = 0; ; return 0; } EOF -if { (eval echo configure:4530: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4569: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF @@ -4544,11 +4583,11 @@ rm -f conftest* openafs_save_libs="$LIBS" echo $ac_n "checking for res_search""... $ac_c" 1>&6 -echo "configure:4548: checking for res_search" >&5 +echo "configure:4587: checking for res_search" >&5 ac_cv_func_res_search=no cat > conftest.$ac_ext < @@ -4572,7 +4611,7 @@ return 0; ; return 0; } EOF -if { (eval echo configure:4576: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4615: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_func_res_search=yes else @@ -4589,7 +4628,7 @@ rm -f conftest* ac_cv_func_res_search=no cat > conftest.$ac_ext < @@ -4613,7 +4652,7 @@ return 0; ; return 0; } EOF -if { (eval echo configure:4617: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4656: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_func_res_search=yes else @@ -4647,7 +4686,7 @@ fi PTHREAD_LIBS=error echo $ac_n "checking for pthread_attr_init in -lpthread""... $ac_c" 1>&6 -echo "configure:4651: checking for pthread_attr_init in -lpthread" >&5 +echo "configure:4690: checking for pthread_attr_init in -lpthread" >&5 ac_lib_var=`echo pthread'_'pthread_attr_init | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4655,7 +4694,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpthread $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4709: \"$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 @@ -4688,7 +4727,7 @@ fi if test "x$PTHREAD_LIBS" = xerror; then echo $ac_n "checking for pthread_attr_init in -lpthreads""... $ac_c" 1>&6 -echo "configure:4692: checking for pthread_attr_init in -lpthreads" >&5 +echo "configure:4731: checking for pthread_attr_init in -lpthreads" >&5 ac_lib_var=`echo pthreads'_'pthread_attr_init | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4696,7 +4735,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpthreads $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4750: \"$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 @@ -4730,7 +4769,7 @@ fi fi if test "x$PTHREAD_LIBS" = xerror; then echo $ac_n "checking for pthread_attr_init in -lc_r""... $ac_c" 1>&6 -echo "configure:4734: checking for pthread_attr_init in -lc_r" >&5 +echo "configure:4773: checking for pthread_attr_init in -lc_r" >&5 ac_lib_var=`echo c_r'_'pthread_attr_init | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4738,7 +4777,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lc_r $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4792: \"$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 @@ -4772,12 +4811,12 @@ fi fi if test "x$PTHREAD_LIBS" = xerror; then echo $ac_n "checking for pthread_attr_init""... $ac_c" 1>&6 -echo "configure:4776: checking for pthread_attr_init" >&5 +echo "configure:4815: checking for pthread_attr_init" >&5 if eval "test \"`echo '$''{'ac_cv_func_pthread_attr_init'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4843: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_pthread_attr_init=yes" else @@ -4920,7 +4959,7 @@ EOF fi echo $ac_n "checking for tivoli tsm butc support""... $ac_c" 1>&6 -echo "configure:4924: checking for tivoli tsm butc support" >&5 +echo "configure:4963: checking for tivoli tsm butc support" >&5 XBSA_CFLAGS="" if test "$enable_tivoli_tsm" = "yes"; then XBSADIR1=/usr/tivoli/tsm/client/api/bin/xopen @@ -4941,12 +4980,12 @@ fi echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 -echo "configure:4945: checking for ANSI C header files" >&5 +echo "configure:4984: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -4954,7 +4993,7 @@ else #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4958: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4997: \"$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* @@ -4971,7 +5010,7 @@ rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -4989,7 +5028,7 @@ fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -5010,7 +5049,7 @@ if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') @@ -5021,7 +5060,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF -if { (eval echo configure:5025: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:5064: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else @@ -5045,12 +5084,12 @@ EOF fi echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6 -echo "configure:5049: checking for sys/wait.h that is POSIX.1 compatible" >&5 +echo "configure:5088: checking for sys/wait.h that is POSIX.1 compatible" >&5 if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -5066,7 +5105,7 @@ wait (&s); s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; ; return 0; } EOF -if { (eval echo configure:5070: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5109: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_header_sys_wait_h=yes else @@ -5091,12 +5130,12 @@ for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6 -echo "configure:5095: checking for $ac_hdr that defines DIR" >&5 +echo "configure:5134: checking for $ac_hdr that defines DIR" >&5 if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include <$ac_hdr> @@ -5104,7 +5143,7 @@ int main() { DIR *dirp = 0; ; return 0; } EOF -if { (eval echo configure:5108: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5147: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* eval "ac_cv_header_dirent_$ac_safe=yes" else @@ -5129,7 +5168,7 @@ done # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. if test $ac_header_dirent = dirent.h; then echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6 -echo "configure:5133: checking for opendir in -ldir" >&5 +echo "configure:5172: checking for opendir in -ldir" >&5 ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5137,7 +5176,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldir $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5191: \"$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 @@ -5170,7 +5209,7 @@ fi else echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6 -echo "configure:5174: checking for opendir in -lx" >&5 +echo "configure:5213: checking for opendir in -lx" >&5 ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5178,7 +5217,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lx $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5232: \"$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 @@ -5215,17 +5254,17 @@ for ac_hdr in stdlib.h string.h unistd.h fcntl.h sys/time.h sys/file.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:5219: checking for $ac_hdr" >&5 +echo "configure:5258: 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 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5229: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:5268: \"$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* @@ -5255,17 +5294,17 @@ for ac_hdr in netinet/in.h netdb.h sys/fcntl.h sys/mnttab.h sys/mntent.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:5259: checking for $ac_hdr" >&5 +echo "configure:5298: 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 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5269: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:5308: \"$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* @@ -5295,17 +5334,17 @@ for ac_hdr in mntent.h sys/vfs.h sys/param.h sys/fs_types.h sys/fstyp.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:5299: checking for $ac_hdr" >&5 +echo "configure:5338: 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 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5309: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:5348: \"$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* @@ -5335,17 +5374,17 @@ for ac_hdr in sys/mount.h strings.h termios.h signal.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:5339: checking for $ac_hdr" >&5 +echo "configure:5378: 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 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5349: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:5388: \"$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* @@ -5375,17 +5414,17 @@ for ac_hdr in windows.h malloc.h winsock2.h direct.h io.h sys/user.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:5379: checking for $ac_hdr" >&5 +echo "configure:5418: 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 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5389: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:5428: \"$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* @@ -5415,17 +5454,17 @@ for ac_hdr in security/pam_modules.h siad.h usersec.h ucontext.h regex.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:5419: checking for $ac_hdr" >&5 +echo "configure:5458: 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 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5429: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:5468: \"$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* @@ -5469,12 +5508,12 @@ fi for ac_func in utimes random srandom getdtablesize snprintf strlcat strlcpy re_comp re_exec do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5473: checking for $ac_func" >&5 +echo "configure:5512: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5540: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5524,12 +5563,12 @@ done for ac_func in setprogname getprogname sigaction mkstemp vsnprintf strerror do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5528: checking for $ac_func" >&5 +echo "configure:5567: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5595: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5580,12 +5619,12 @@ done for ac_func in regcomp regexec regerror do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5584: checking for $ac_func" >&5 +echo "configure:5623: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5651: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5633,7 +5672,7 @@ fi done echo $ac_n "checking for POSIX regex library""... $ac_c" 1>&6 -echo "configure:5637: checking for POSIX regex library" >&5 +echo "configure:5676: checking for POSIX regex library" >&5 if test "$ac_cv_header_regex_h" = "yes" && \ test "$ac_cv_func_regcomp" = "yes" && \ test "$ac_cv_func_regexec" = "yes" && \ @@ -5648,12 +5687,12 @@ else fi echo $ac_n "checking for ssize_t""... $ac_c" 1>&6 -echo "configure:5652: checking for ssize_t" >&5 +echo "configure:5691: checking for ssize_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_ssize_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -5681,7 +5720,7 @@ EOF fi echo $ac_n "checking size of long""... $ac_c" 1>&6 -echo "configure:5685: checking size of long" >&5 +echo "configure:5724: checking size of long" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5689,7 +5728,7 @@ else { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext < main() @@ -5700,7 +5739,7 @@ main() exit(0); } EOF -if { (eval echo configure:5704: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:5743: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_long=`cat conftestval` else @@ -5723,12 +5762,12 @@ EOF for ac_func in timegm do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5727: checking for $ac_func" >&5 +echo "configure:5766: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5794: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5855,7 +5894,7 @@ LWP_OPTMZ=-O # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:5859: checking for $ac_word" >&5 +echo "configure:5898: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5887,7 +5926,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:5891: checking for $ac_word" >&5 +echo "configure:5930: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5922,7 +5961,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:5926: checking for $ac_word" >&5 +echo "configure:5965: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5957,7 +5996,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:5961: checking for $ac_word" >&5 +echo "configure:6000: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_MV'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5992,7 +6031,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:5996: checking for $ac_word" >&5 +echo "configure:6035: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RM'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -6027,7 +6066,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:6031: checking for $ac_word" >&5 +echo "configure:6070: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LD'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -6062,7 +6101,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:6066: checking for $ac_word" >&5 +echo "configure:6105: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -6097,7 +6136,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:6101: checking for $ac_word" >&5 +echo "configure:6140: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -6132,7 +6171,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:6136: checking for $ac_word" >&5 +echo "configure:6175: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LORDER'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -6361,12 +6400,14 @@ case $AFS_SYSNAME in SHLIB_LINKER="${MT_CC} -shared" ;; - amd64_linux24) + amd64_linux*) + CCOBJ="${CC} -fPIC" KERN_OPTMZ=-O2 LEX="flex -l" MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}' MT_LIBS="-lpthread" PAM_CFLAGS="-g -O2 -Dlinux -DLINUX_PAM -fPIC" + SHLIB_CFLAGS="-fPIC" SHLIB_LDFLAGS="-shared -Xlinker -x" TXLIBS="-lncurses" XCFLAGS="-g -O2 -D_LARGEFILE64_SOURCE" @@ -6962,7 +7003,7 @@ case $AFS_SYSNAME in sgi_6*) echo $ac_n "checking for mem* in sys/systm.h""... $ac_c" 1>&6 -echo "configure:6966: checking for mem* in sys/systm.h" >&5 +echo "configure:7007: checking for mem* in sys/systm.h" >&5 save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS -D_KERNEL -D__STRING_H__" if eval "test \"`echo '$''{'ac_cv_irix_sys_systm_h_has_mem_funcs'+set}'`\" = set"; then @@ -6970,7 +7011,7 @@ if eval "test \"`echo '$''{'ac_cv_irix_sys_systm_h_has_mem_funcs'+set}'`\" = set else cat > conftest.$ac_ext < #include @@ -6980,7 +7021,7 @@ extern void *memcpy(char *, const void *, size_t); ; return 0; } EOF -if { (eval echo configure:6984: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:7025: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_irix_sys_systm_h_has_mem_funcs=no else diff --git a/configure-libafs.in b/configure-libafs.in index 93fe6746c..eaf1f0a5b 100644 --- a/configure-libafs.in +++ b/configure-libafs.in @@ -1,5 +1,5 @@ AC_INIT(src/libafs/Makefile.common.in) -AM_INIT_AUTOMAKE(openafs-libafs,1.3.71) +AM_INIT_AUTOMAKE(openafs-libafs,1.3.73) AC_CONFIG_HEADER(src/config/afsconfig.h) define(OPENAFS_CONFIGURE_LIBAFS) diff --git a/configure.in b/configure.in index 7395939a7..298ae1841 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ AC_INIT(src/config/stds.h) -AM_INIT_AUTOMAKE(openafs,1.3.71) +AM_INIT_AUTOMAKE(openafs,1.3.73) AC_CONFIG_HEADER(src/config/afsconfig.h) AC_PROG_CC diff --git a/src/WINNT/afsd/afsd_flushvol.c b/src/WINNT/afsd/afsd_flushvol.c index 32ab70025..5d90c7fba 100644 --- a/src/WINNT/afsd/afsd_flushvol.c +++ b/src/WINNT/afsd/afsd_flushvol.c @@ -27,6 +27,9 @@ #include "afsd_flushvol.h" #include "afsd_eventlog.h" +#include "lanahelper.h" + +extern void afsi_log(char *pattern, ...); static FLUSHVOLTHREADINFO gThreadInfo = {0}; static HANDLE gThreadHandle = NULL; @@ -45,145 +48,150 @@ static HANDLE gThreadHandle = NULL; afs_int32 afsd_ServicePerformFlushVolumeCmd(char *data) { - register afs_int32 code; - struct ViceIoctl blob; + register afs_int32 code; + struct ViceIoctl blob; - memset(&blob, '\0', sizeof(blob)); - code = pioctl(data, VIOC_FLUSHVOLUME, &blob, 0); + afsi_log("Flushing Volume \"%s\"",data); + memset(&blob, '\0', sizeof(blob)); + code = pioctl(data, VIOC_FLUSHVOLUME, &blob, 0); - return code; + return code; } BOOL afsd_ServicePerformFlushVolumes() -{ - CONST CHAR COLON = ':'; - CONST CHAR SLASH = '\\'; - CONST DWORD NETRESBUFSIZE = 16384; - CHAR bufMessage[1024]; - UINT i; - DWORD dwServerSize; - DWORD dwRet; - DWORD dwCount; - DWORD dwNetResBufSize; - DWORD dwTotalVols = 0; - DWORD dwVolBegin, dwVolEnd; - DWORD dwFlushBegin, dwFlushEnd; - HANDLE hEnum; - LPNETRESOURCE lpNetResBuf, lpnr; - PCHAR pszShareName, pc; - afs_int32 afsRet = 0; - - // Determine the root share name (\\AFS\ALL or \\-AFS\ALL), - // and the length of the server name prefix. - pszShareName = smb_GetSharename(); - if (pszShareName == NULL) - { - LogEvent(EVENTLOG_ERROR_TYPE, MSG_FLUSH_NO_SHARE_NAME, NULL); - return FALSE; - } - pc = strrchr(pszShareName, SLASH); - if ((pc == NULL) || ((dwServerSize = pc - pszShareName) < 3)) - { - LogEvent(EVENTLOG_ERROR_TYPE, MSG_FLUSH_BAD_SHARE_NAME, - pszShareName, NULL); - free(pszShareName); - return FALSE; - } - - // Allocate a buffer to hold network resources returned by - // WNetEnumResource(). - lpNetResBuf = malloc(NETRESBUFSIZE); - if (lpNetResBuf == NULL) - { - // Out of memory, give up now. - LogEvent(EVENTLOG_ERROR_TYPE, MSG_FLUSH_NO_MEMORY, NULL); - free(pszShareName); - return FALSE; - } - - // Initialize the flush timer. Note that GetTickCount() returns - // the number of milliseconds since the system started, in a DWORD, - // so that the value wraps around every 49.7 days. We do not bother - // to handle the case where the flush elapsed time is greater than - // that. - dwFlushBegin = GetTickCount(); +{ + CONST CHAR COLON = ':'; + CONST CHAR SLASH = '\\'; + CONST DWORD NETRESBUFSIZE = 16384; + CHAR bufMessage[1024]; + UINT i; + DWORD dwServerSize; + DWORD dwRet; + DWORD dwCount; + DWORD dwNetResBufSize; + DWORD dwTotalVols = 0; + DWORD dwVolBegin, dwVolEnd; + DWORD dwFlushBegin, dwFlushEnd; + HANDLE hEnum; + LPNETRESOURCE lpNetResBuf, lpnr; + PCHAR pszShareName, pc; + afs_int32 afsRet = 0; + + if ( lana_OnlyLoopback() ) { + // Nothing to do if we only have a loopback interface + return TRUE; + } + + // Determine the root share name (\\AFS\ALL or \\-AFS\ALL), + // and the length of the server name prefix. + pszShareName = smb_GetSharename(); + if (pszShareName == NULL) + { + LogEvent(EVENTLOG_ERROR_TYPE, MSG_FLUSH_NO_SHARE_NAME, NULL); + return FALSE; + } + pc = strrchr(pszShareName, SLASH); + if ((pc == NULL) || ((dwServerSize = pc - pszShareName) < 3)) + { + LogEvent(EVENTLOG_ERROR_TYPE, MSG_FLUSH_BAD_SHARE_NAME, + pszShareName, NULL); + free(pszShareName); + return FALSE; + } + + // Allocate a buffer to hold network resources returned by + // WNetEnumResource(). + lpNetResBuf = malloc(NETRESBUFSIZE); + if (lpNetResBuf == NULL) + { + // Out of memory, give up now. + LogEvent(EVENTLOG_ERROR_TYPE, MSG_FLUSH_NO_MEMORY, NULL); + free(pszShareName); + return FALSE; + } + + // Initialize the flush timer. Note that GetTickCount() returns + // the number of milliseconds since the system started, in a DWORD, + // so that the value wraps around every 49.7 days. We do not bother + // to handle the case where the flush elapsed time is greater than + // that. + dwFlushBegin = GetTickCount(); + + dwRet = WNetOpenEnum(RESOURCE_CONNECTED, RESOURCETYPE_ANY, 0, NULL, + &hEnum); + if (dwRet != NO_ERROR) + { + LogEventMessage(EVENTLOG_ERROR_TYPE, MSG_FLUSH_OPEN_ENUM_ERROR, + dwRet); + free(pszShareName); + return FALSE; + } + + // Loop to enumerate network resources, and flush those associated + // with AFS volumes. + while (1) + { + dwCount = -1; + memset(lpNetResBuf, 0, NETRESBUFSIZE); + dwNetResBufSize = NETRESBUFSIZE; + dwRet = WNetEnumResource(hEnum, &dwCount, + lpNetResBuf, &dwNetResBufSize); + if (dwRet != NO_ERROR) + break; + // Iterate over the returned network resources. + for (i = 0, lpnr = lpNetResBuf; i < dwCount; i++, lpnr++) + { + // Ensure resource has a remote name, and is connected. + if ((lpnr->lpRemoteName == NULL) || + (lpnr->dwScope != RESOURCE_CONNECTED)) + continue; + if ((_strnicmp(lpnr->lpRemoteName, pszShareName, + dwServerSize) == 0) && + (lpnr->lpRemoteName[dwServerSize] == SLASH)) + { + // got one! + // but we don't want to flush '\\[...]afs\all' + if (_stricmp(lpnr->lpRemoteName, pszShareName) == 0) + continue; + ++dwTotalVols; + + dwVolBegin = GetTickCount(); + afsRet = afsd_ServicePerformFlushVolumeCmd(lpnr->lpRemoteName); + dwVolEnd = GetTickCount(); + if (afsRet == 0) + { + LogTimingEvent(MSG_TIME_FLUSH_PER_VOLUME, + lpnr->lpRemoteName, + dwVolEnd - dwVolBegin); + } + else + { + LogEvent(EVENTLOG_WARNING_TYPE, + MSG_FLUSH_FAILED, + lpnr->lpRemoteName, NULL); + } + } + } + } + WNetCloseEnum(hEnum); + free(lpNetResBuf); + free(pszShareName); + if (dwRet != ERROR_NO_MORE_ITEMS) + { + LogEventMessage(EVENTLOG_ERROR_TYPE, MSG_FLUSH_ENUM_ERROR, + dwRet); + return FALSE; + } + + dwFlushEnd = GetTickCount(); - dwRet = WNetOpenEnum(RESOURCE_CONNECTED, RESOURCETYPE_ANY, 0, NULL, - &hEnum); - if (dwRet != NO_ERROR) - { - LogEventMessage(EVENTLOG_ERROR_TYPE, MSG_FLUSH_OPEN_ENUM_ERROR, - dwRet); - free(pszShareName); - return FALSE; - } - - // Loop to enumerate network resources, and flush those associated - // with AFS volumes. - while (1) - { - dwCount = -1; - memset(lpNetResBuf, 0, NETRESBUFSIZE); - dwNetResBufSize = NETRESBUFSIZE; - dwRet = WNetEnumResource(hEnum, &dwCount, - lpNetResBuf, &dwNetResBufSize); - if (dwRet != NO_ERROR) - break; - // Iterate over the returned network resources. - for (i = 0, lpnr = lpNetResBuf; i < dwCount; i++, lpnr++) - { - // Ensure resource has a remote name, and is connected. - if ((lpnr->lpRemoteName == NULL) || - (lpnr->dwScope != RESOURCE_CONNECTED)) - continue; - if ((_strnicmp(lpnr->lpRemoteName, pszShareName, - dwServerSize) == 0) && - (lpnr->lpRemoteName[dwServerSize] == SLASH)) - { - // got one! - // but we don't want to flush '\\[...]afs\all' - if (_stricmp(lpnr->lpRemoteName, - pszShareName) == 0) - continue; - ++dwTotalVols; - - dwVolBegin = GetTickCount(); - afsRet = afsd_ServicePerformFlushVolumeCmd(lpnr->lpRemoteName); - dwVolEnd = GetTickCount(); - if (afsRet == 0) - { - LogTimingEvent(MSG_TIME_FLUSH_PER_VOLUME, - lpnr->lpRemoteName, - dwVolEnd - dwVolBegin); - } - else - { - LogEvent(EVENTLOG_WARNING_TYPE, - MSG_FLUSH_FAILED, - lpnr->lpRemoteName, NULL); - } - } - } - } - WNetCloseEnum(hEnum); - free(lpNetResBuf); - free(pszShareName); - if (dwRet != ERROR_NO_MORE_ITEMS) - { - LogEventMessage(EVENTLOG_ERROR_TYPE, MSG_FLUSH_ENUM_ERROR, - dwRet); - return FALSE; - } - - dwFlushEnd = GetTickCount(); - - // display total volume count in Event Logger - sprintf(bufMessage, "%d", dwTotalVols); - LogTimingEvent(MSG_TIME_FLUSH_TOTAL, bufMessage, - dwFlushEnd - dwFlushBegin); + // display total volume count in Event Logger + sprintf(bufMessage, "%d", dwTotalVols); + LogTimingEvent(MSG_TIME_FLUSH_TOTAL, bufMessage, + dwFlushEnd - dwFlushBegin); - return TRUE; + return TRUE; } // Report a timing event to the system event log. @@ -193,11 +201,11 @@ afsd_ServicePerformFlushVolumes() static VOID LogTimingEvent(DWORD dwEventID, LPTSTR lpString1, DWORD dwTime) { - CHAR szTime[16]; + CHAR szTime[16]; - sprintf(szTime, "%lu", dwTime); - LogEvent(EVENTLOG_INFORMATION_TYPE, dwEventID, lpString1, szTime, - NULL); + sprintf(szTime, "%lu", dwTime); + LogEvent(EVENTLOG_INFORMATION_TYPE, dwEventID, lpString1, szTime, + NULL); } @@ -223,91 +231,91 @@ LogTimingEvent(DWORD dwEventID, LPTSTR lpString1, DWORD dwTime) // HANDLE GetUserToken(DWORD access) { - HANDLE hTok = NULL; - DWORD pid = 0, tid = 0; - - // Try it the easy way first - look for a window owned by the shell on - // our current desktop. If we find one, use that to get the process id. - HWND shell = FindWindowEx(NULL, NULL, "Progman", NULL); - if (shell != NULL) - { - tid = GetWindowThreadProcessId(shell, &pid); - } - - // We are possibly running on a private window station and desktop: we must - // switch to the default (which we suppose is where we will find the - // running shell). - else - { - HWINSTA saveWinSta = GetProcessWindowStation(); - HDESK saveDesk = GetThreadDesktop(GetCurrentThreadId()); - HWINSTA winSta = NULL; - HDESK desk = NULL; - BOOL changeFlag = FALSE; - BOOL dummy = saveWinSta != NULL && - saveDesk != NULL && - (winSta = OpenWindowStation("WinSta0", FALSE, - MAXIMUM_ALLOWED)) != NULL && - (changeFlag = SetProcessWindowStation(winSta)) != 0 && - (desk = OpenDesktop("Default", 0, FALSE, - MAXIMUM_ALLOWED)) != NULL && - SetThreadDesktop(desk) != 0; - - // Now find the window and process on this desktop - shell = FindWindowEx(NULL, NULL, "Progman", NULL); - if (shell != NULL) - { - tid = GetWindowThreadProcessId(shell, &pid); - } - - // Restore our own window station and desktop - if (changeFlag) - { - SetProcessWindowStation(saveWinSta); - SetThreadDesktop(saveDesk); - } - - // Close temporary objects - if (winSta != NULL) - CloseWindowStation(winSta); - if (desk != NULL) - CloseDesktop(desk); - } - - // - // If we have a process id, use that to get the process handle and - // from there the process' access token. - // - if (pid != 0) - { - HANDLE hProc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid); - if (hProc != NULL) - { - OpenProcessToken(hProc, access, &hTok) || (hTok = NULL); - CloseHandle(hProc); - } - } - - // Return token if we got one - return hTok; -} + HANDLE hTok = NULL; + DWORD pid = 0, tid = 0; + + // Try it the easy way first - look for a window owned by the shell on + // our current desktop. If we find one, use that to get the process id. + HWND shell = FindWindowEx(NULL, NULL, "Progman", NULL); + if (shell != NULL) + { + tid = GetWindowThreadProcessId(shell, &pid); + } + + // We are possibly running on a private window station and desktop: we must + // switch to the default (which we suppose is where we will find the + // running shell). + else + { + HWINSTA saveWinSta = GetProcessWindowStation(); + HDESK saveDesk = GetThreadDesktop(GetCurrentThreadId()); + HWINSTA winSta = NULL; + HDESK desk = NULL; + BOOL changeFlag = FALSE; + BOOL dummy = saveWinSta != NULL && + saveDesk != NULL && + (winSta = OpenWindowStation("WinSta0", FALSE, + MAXIMUM_ALLOWED)) != NULL && + (changeFlag = SetProcessWindowStation(winSta)) != 0 && + (desk = OpenDesktop("Default", 0, FALSE, + MAXIMUM_ALLOWED)) != NULL && + SetThreadDesktop(desk) != 0; + + // Now find the window and process on this desktop + shell = FindWindowEx(NULL, NULL, "Progman", NULL); + if (shell != NULL) + { + tid = GetWindowThreadProcessId(shell, &pid); + } + + // Restore our own window station and desktop + if (changeFlag) + { + SetProcessWindowStation(saveWinSta); + SetThreadDesktop(saveDesk); + } + + // Close temporary objects + if (winSta != NULL) + CloseWindowStation(winSta); + if (desk != NULL) + CloseDesktop(desk); + } + + // + // If we have a process id, use that to get the process handle and + // from there the process' access token. + // + if (pid != 0) + { + HANDLE hProc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid); + if (hProc != NULL) + { + OpenProcessToken(hProc, access, &hTok) || (hTok = NULL); + CloseHandle(hProc); + } + } + + // Return token if we got one + return hTok; +} // impersonate logged-on user as client BOOL ImpersonateClient() { - DWORD dwDesiredAccess = TOKEN_ALL_ACCESS; - HANDLE hUserToken = GetUserToken(dwDesiredAccess); + DWORD dwDesiredAccess = TOKEN_ALL_ACCESS; + HANDLE hUserToken = GetUserToken(dwDesiredAccess); - if (hUserToken == NULL) - return FALSE; - if (ImpersonateLoggedOnUser(hUserToken) == 0) - { - LogEvent(EVENTLOG_ERROR_TYPE, MSG_FLUSH_IMPERSONATE_ERROR, - NULL); - return FALSE; - } - return TRUE; + if (hUserToken == NULL) + return FALSE; + if (ImpersonateLoggedOnUser(hUserToken) == 0) + { + LogEvent(EVENTLOG_ERROR_TYPE, MSG_FLUSH_IMPERSONATE_ERROR, + NULL); + return FALSE; + } + return TRUE; } ///////////////////////////////////////////////////////////////////// @@ -317,67 +325,67 @@ ImpersonateClient() DWORD WINAPI afsd_ServiceFlushVolumesThreadProc(LPVOID lpParam) { - FLUSHVOLTHREADINFO ThreadInfo; - PFLUSHVOLTHREADINFO pThreadInfo = (PFLUSHVOLTHREADINFO) lpParam; - HANDLE arHandles[2] = {0}; - DWORD dwWaitState = 0; - - // thread running - get handles - ThreadInfo.hEventPowerEvent = pThreadInfo->hEventPowerEvent; - ThreadInfo.hEventResumeMain = pThreadInfo->hEventResumeMain; - ThreadInfo.hEventTerminate = pThreadInfo->hEventTerminate; - - // setup to wait - arHandles[0] = ThreadInfo.hEventTerminate; - arHandles[1] = ThreadInfo.hEventPowerEvent; - - // do stuff .. - while (1) - { - // wait for an event to happen - dwWaitState = WaitForMultipleObjectsEx(2, arHandles, FALSE, INFINITE, FALSE); - - switch (dwWaitState) - { - case WAIT_OBJECT_0: - // termination signaled - RevertToSelf(); + FLUSHVOLTHREADINFO ThreadInfo; + PFLUSHVOLTHREADINFO pThreadInfo = (PFLUSHVOLTHREADINFO) lpParam; + HANDLE arHandles[2] = {0}; + DWORD dwWaitState = 0; + + // thread running - get handles + ThreadInfo.hEventPowerEvent = pThreadInfo->hEventPowerEvent; + ThreadInfo.hEventResumeMain = pThreadInfo->hEventResumeMain; + ThreadInfo.hEventTerminate = pThreadInfo->hEventTerminate; + + // setup to wait + arHandles[0] = ThreadInfo.hEventTerminate; + arHandles[1] = ThreadInfo.hEventPowerEvent; + + // do stuff .. + while (1) + { + // wait for an event to happen + dwWaitState = WaitForMultipleObjectsEx(2, arHandles, FALSE, INFINITE, FALSE); + + switch (dwWaitState) + { + case WAIT_OBJECT_0: + // termination signaled + RevertToSelf(); CheckAndCloseHandle(ThreadInfo.hEventPowerEvent); CheckAndCloseHandle(ThreadInfo.hEventResumeMain); CheckAndCloseHandle(ThreadInfo.hEventTerminate); - ExitThread(0); - break; - - case WAIT_OBJECT_0+1: - // Power event - // - flush 'em! - if (ImpersonateClient()) - { - afsd_ServicePerformFlushVolumes(); - } - // acknowledge event - ResetEvent(ThreadInfo.hEventPowerEvent); - break; - - case WAIT_ABANDONED_0: - case WAIT_ABANDONED_0+1: - case WAIT_IO_COMPLETION: - case WAIT_TIMEOUT: - // sno* - LogEvent(EVENTLOG_WARNING_TYPE, - MSG_FLUSH_UNEXPECTED_EVENT, NULL); - break; - - } // end switch - - // signal back to waiting mainline - SetEvent(ThreadInfo.hEventResumeMain); - - } // end while - - // I suppose we never get here - ExitThread(0); -} + ExitThread(0); + break; + + case WAIT_OBJECT_0+1: + // Power event + // - flush 'em! + if (ImpersonateClient()) + { + afsd_ServicePerformFlushVolumes(); + } + // acknowledge event + ResetEvent(ThreadInfo.hEventPowerEvent); + break; + + case WAIT_ABANDONED_0: + case WAIT_ABANDONED_0+1: + case WAIT_IO_COMPLETION: + case WAIT_TIMEOUT: + // sno* + LogEvent(EVENTLOG_WARNING_TYPE, + MSG_FLUSH_UNEXPECTED_EVENT, NULL); + break; + + } // end switch + + // signal back to waiting mainline + SetEvent(ThreadInfo.hEventResumeMain); + + } // end while + + // I suppose we never get here + ExitThread(0); +} ///////////////////////////////////////////////////////////////////// // @@ -387,11 +395,11 @@ afsd_ServiceFlushVolumesThreadProc(LPVOID lpParam) VOID CheckAndCloseHandle(HANDLE thisHandle) { - if (thisHandle != NULL) - { - CloseHandle(thisHandle); - thisHandle = NULL; - } + if (thisHandle != NULL) + { + CloseHandle(thisHandle); + thisHandle = NULL; + } } // @@ -400,62 +408,62 @@ CheckAndCloseHandle(HANDLE thisHandle) BOOL PowerNotificationThreadCreate() { - BOOL bSuccess = FALSE; - DWORD dwThreadId = 0; + BOOL bSuccess = FALSE; + DWORD dwThreadId = 0; char eventName[MAX_PATH]; - do - { - // create power event notification event - // bManualReset=TRUE, bInitialState=FALSE - gThreadInfo.hEventPowerEvent = CreateEvent(NULL, TRUE, FALSE, + do + { + // create power event notification event + // bManualReset=TRUE, bInitialState=FALSE + gThreadInfo.hEventPowerEvent = CreateEvent(NULL, TRUE, FALSE, TEXT("afsd_flushvol_EventPowerEvent")); if ( GetLastError() == ERROR_ALREADY_EXISTS ) afsi_log("Event Object Already Exists: %s", eventName); - if (gThreadInfo.hEventPowerEvent == NULL) - break; + if (gThreadInfo.hEventPowerEvent == NULL) + break; - // create mainline resume event - // bManualReset=FALSE, bInitialState=FALSE - gThreadInfo.hEventResumeMain = CreateEvent(NULL, FALSE, FALSE, + // create mainline resume event + // bManualReset=FALSE, bInitialState=FALSE + gThreadInfo.hEventResumeMain = CreateEvent(NULL, FALSE, FALSE, TEXT("afsd_flushvol_EventResumeMain")); if ( GetLastError() == ERROR_ALREADY_EXISTS ) afsi_log("Event Object Already Exists: %s", eventName); - if (gThreadInfo.hEventResumeMain == NULL) - break; + if (gThreadInfo.hEventResumeMain == NULL) + break; - // create thread terminate event - // bManualReset=FALSE, bInitialState=FALSE - gThreadInfo.hEventTerminate = CreateEvent(NULL, FALSE, FALSE, + // create thread terminate event + // bManualReset=FALSE, bInitialState=FALSE + gThreadInfo.hEventTerminate = CreateEvent(NULL, FALSE, FALSE, TEXT("afsd_flushvol_EventTerminate")); if ( GetLastError() == ERROR_ALREADY_EXISTS ) afsi_log("Event Object Already Exists: %s", eventName); - if (gThreadInfo.hEventTerminate == NULL) - break; - - // good so far - create thread - gThreadHandle = CreateThread(NULL, 0, - afsd_ServiceFlushVolumesThreadProc, - (LPVOID) &gThreadInfo, - 0, &dwThreadId); + if (gThreadInfo.hEventTerminate == NULL) + break; + + // good so far - create thread + gThreadHandle = CreateThread(NULL, 0, + afsd_ServiceFlushVolumesThreadProc, + (LPVOID) &gThreadInfo, + 0, &dwThreadId); - if (!gThreadHandle) - break; + if (!gThreadHandle) + break; - bSuccess = TRUE; + bSuccess = TRUE; - } while (0); + } while (0); - if (!bSuccess) - { - CheckAndCloseHandle(gThreadInfo.hEventPowerEvent); - CheckAndCloseHandle(gThreadInfo.hEventResumeMain); - CheckAndCloseHandle(gThreadInfo.hEventTerminate); - CheckAndCloseHandle(gThreadHandle); - } + if (!bSuccess) + { + CheckAndCloseHandle(gThreadInfo.hEventPowerEvent); + CheckAndCloseHandle(gThreadInfo.hEventResumeMain); + CheckAndCloseHandle(gThreadInfo.hEventTerminate); + CheckAndCloseHandle(gThreadHandle); + } - return bSuccess; + return bSuccess; } // @@ -464,21 +472,21 @@ PowerNotificationThreadCreate() BOOL PowerNotificationThreadNotify() { - DWORD dwRet = 0; - BOOL bRet = FALSE; + DWORD dwRet = 0; + BOOL bRet = FALSE; - // Notify thread of power event, and wait for the HardDead timeout period - dwRet = SignalObjectAndWait( - gThreadInfo.hEventPowerEvent, // object to signal - gThreadInfo.hEventResumeMain, // object to watch - HardDeadtimeout*1000, // timeout (ms) - FALSE // alertable - ); + // Notify thread of power event, and wait for the HardDead timeout period + dwRet = SignalObjectAndWait( + gThreadInfo.hEventPowerEvent, // object to signal + gThreadInfo.hEventResumeMain, // object to watch + HardDeadtimeout*1000, // timeout (ms) + FALSE // alertable + ); - if (dwRet == WAIT_OBJECT_0) - bRet = TRUE; + if (dwRet == WAIT_OBJECT_0) + bRet = TRUE; - return bRet; + return bRet; } // @@ -487,12 +495,12 @@ PowerNotificationThreadNotify() VOID PowerNotificationThreadExit() { - // ExitThread - if (gThreadHandle) - { - SetEvent(gThreadInfo.hEventTerminate); + // ExitThread + if (gThreadHandle) + { + SetEvent(gThreadInfo.hEventTerminate); WaitForSingleObject(gThreadHandle, INFINITE); - CloseHandle(gThreadHandle); - } + CloseHandle(gThreadHandle); + } } diff --git a/src/WINNT/afsd/afsd_init.c b/src/WINNT/afsd/afsd_init.c index faf11da1c..a11118b94 100644 --- a/src/WINNT/afsd/afsd_init.c +++ b/src/WINNT/afsd/afsd_init.c @@ -81,7 +81,7 @@ BOOL reportSessionStartups = FALSE; cm_initparams_v1 cm_initParams; char *cm_sysName = 0; -int cm_sysNameCount = 0; +unsigned int cm_sysNameCount = 0; char *cm_sysNameList[MAXNUMSYSNAMES]; DWORD TraceOption = 0; @@ -358,72 +358,72 @@ configureBackConnectionHostNames(void) int afsd_InitCM(char **reasonP) { - osi_uid_t debugID; - long cacheBlocks; - long cacheSize; - long logChunkSize; - long stats; - long traceBufSize; + osi_uid_t debugID; + long cacheBlocks; + long cacheSize; + long logChunkSize; + long stats; + long traceBufSize; long maxcpus; - long ltt, ltto; + long ltt, ltto; long rx_mtu, rx_nojumbo; long virtualCache; - char rootCellName[256]; - struct rx_service *serverp; - static struct rx_securityClass *nullServerSecurityClassp; - struct hostent *thp; - char *msgBuf; - char buf[200]; - HKEY parmKey; - DWORD dummyLen; + char rootCellName[256]; + struct rx_service *serverp; + static struct rx_securityClass *nullServerSecurityClassp; + struct hostent *thp; + char *msgBuf; + char buf[1024]; + HKEY parmKey; + DWORD dummyLen; DWORD regType; - long code; - /*int freelanceEnabled;*/ - WSADATA WSAjunk; + long code; + /*int freelanceEnabled;*/ + WSADATA WSAjunk; lana_number_t lanaNum; int i; - WSAStartup(0x0101, &WSAjunk); + WSAStartup(0x0101, &WSAjunk); afsd_initUpperCaseTable(); - /* setup osidebug server at RPC slot 1000 */ - osi_LongToUID(1000, &debugID); - code = osi_InitDebug(&debugID); - afsi_log("osi_InitDebug code %d", code); + /* setup osidebug server at RPC slot 1000 */ + osi_LongToUID(1000, &debugID); + code = osi_InitDebug(&debugID); + afsi_log("osi_InitDebug code %d", code); // osi_LockTypeSetDefault("stat"); /* comment this out for speed * - if (code != 0) { - *reasonP = "unknown error"; - return -1; - } + if (code != 0) { + *reasonP = "unknown error"; + return -1; + } - /* who are we ? */ - gethostname(cm_HostName, sizeof(cm_HostName)); - afsi_log("gethostname %s", cm_HostName); - thp = gethostbyname(cm_HostName); - memcpy(&cm_HostAddr, thp->h_addr_list[0], 4); - - /* seed random number generator */ - srand(ntohl(cm_HostAddr)); - - /* Look up configuration parameters in Registry */ - code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSConfigKeyName, - 0, KEY_QUERY_VALUE, &parmKey); - if (code != ERROR_SUCCESS) { - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM - | FORMAT_MESSAGE_ALLOCATE_BUFFER, - NULL, code, 0, (LPTSTR)&msgBuf, 0, NULL); - StringCbPrintfA(buf, sizeof(buf), - "Failure in configuration while opening Registry: %s", - msgBuf); - osi_panic(buf, __FILE__, __LINE__); - } + /* who are we ? */ + gethostname(cm_HostName, sizeof(cm_HostName)); + afsi_log("gethostname %s", cm_HostName); + thp = gethostbyname(cm_HostName); + memcpy(&cm_HostAddr, thp->h_addr_list[0], 4); + + /* seed random number generator */ + srand(ntohl(cm_HostAddr)); + + /* Look up configuration parameters in Registry */ + code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSConfigKeyName, + 0, KEY_QUERY_VALUE, &parmKey); + if (code != ERROR_SUCCESS) { + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, code, 0, (LPTSTR)&msgBuf, 0, NULL); + StringCbPrintfA(buf, sizeof(buf), + "Failure in configuration while opening Registry: %s", + msgBuf); + osi_panic(buf, __FILE__, __LINE__); + } dummyLen = sizeof(maxcpus); - code = RegQueryValueEx(parmKey, "MaxCPUs", NULL, NULL, - (BYTE *) &maxcpus, &dummyLen); - if (code == ERROR_SUCCESS) { + code = RegQueryValueEx(parmKey, "MaxCPUs", NULL, NULL, + (BYTE *) &maxcpus, &dummyLen); + if (code == ERROR_SUCCESS) { HANDLE hProcess; DWORD_PTR processAffinityMask, systemAffinityMask; @@ -456,141 +456,141 @@ int afsd_InitCM(char **reasonP) } } - dummyLen = sizeof(TraceOption); - code = RegQueryValueEx(parmKey, "TraceOption", NULL, NULL, - (BYTE *) &TraceOption, &dummyLen); + dummyLen = sizeof(TraceOption); + code = RegQueryValueEx(parmKey, "TraceOption", NULL, NULL, + (BYTE *) &TraceOption, &dummyLen); afsi_log("Event Log Tracing = %lX", TraceOption); - dummyLen = sizeof(traceBufSize); - code = RegQueryValueEx(parmKey, "TraceBufferSize", NULL, NULL, - (BYTE *) &traceBufSize, &dummyLen); - if (code == ERROR_SUCCESS) - afsi_log("Trace Buffer size %d", traceBufSize); - else { - traceBufSize = CM_CONFIGDEFAULT_TRACEBUFSIZE; - afsi_log("Default trace buffer size %d", traceBufSize); - } + dummyLen = sizeof(traceBufSize); + code = RegQueryValueEx(parmKey, "TraceBufferSize", NULL, NULL, + (BYTE *) &traceBufSize, &dummyLen); + if (code == ERROR_SUCCESS) + afsi_log("Trace Buffer size %d", traceBufSize); + else { + traceBufSize = CM_CONFIGDEFAULT_TRACEBUFSIZE; + afsi_log("Default trace buffer size %d", traceBufSize); + } - /* setup and enable debug log */ - afsd_logp = osi_LogCreate("afsd", traceBufSize); - afsi_log("osi_LogCreate log addr %x", (int)afsd_logp); + /* setup and enable debug log */ + afsd_logp = osi_LogCreate("afsd", traceBufSize); + afsi_log("osi_LogCreate log addr %x", (int)afsd_logp); osi_LogEnable(afsd_logp); - logReady = 1; + logReady = 1; osi_Log0(afsd_logp, "Log init"); - dummyLen = sizeof(cacheSize); - code = RegQueryValueEx(parmKey, "CacheSize", NULL, NULL, - (BYTE *) &cacheSize, &dummyLen); - if (code == ERROR_SUCCESS) - afsi_log("Cache size %d", cacheSize); - else { - cacheSize = CM_CONFIGDEFAULT_CACHESIZE; - afsi_log("Default cache size %d", cacheSize); - } + dummyLen = sizeof(cacheSize); + code = RegQueryValueEx(parmKey, "CacheSize", NULL, NULL, + (BYTE *) &cacheSize, &dummyLen); + if (code == ERROR_SUCCESS) + afsi_log("Cache size %d", cacheSize); + else { + cacheSize = CM_CONFIGDEFAULT_CACHESIZE; + afsi_log("Default cache size %d", cacheSize); + } - dummyLen = sizeof(logChunkSize); - code = RegQueryValueEx(parmKey, "ChunkSize", NULL, NULL, - (BYTE *) &logChunkSize, &dummyLen); - if (code == ERROR_SUCCESS) { - if (logChunkSize < 12 || logChunkSize > 30) { - afsi_log("Invalid chunk size %d, using default", - logChunkSize); - logChunkSize = CM_CONFIGDEFAULT_CHUNKSIZE; - } - afsi_log("Chunk size %d", logChunkSize); - } else { - logChunkSize = CM_CONFIGDEFAULT_CHUNKSIZE; - afsi_log("Default chunk size %d", logChunkSize); - } - cm_logChunkSize = logChunkSize; - cm_chunkSize = 1 << logChunkSize; - - dummyLen = sizeof(numBkgD); - code = RegQueryValueEx(parmKey, "Daemons", NULL, NULL, - (BYTE *) &numBkgD, &dummyLen); - if (code == ERROR_SUCCESS) - afsi_log("%d background daemons", numBkgD); - else { - numBkgD = CM_CONFIGDEFAULT_DAEMONS; - afsi_log("Defaulting to %d background daemons", numBkgD); - } + dummyLen = sizeof(logChunkSize); + code = RegQueryValueEx(parmKey, "ChunkSize", NULL, NULL, + (BYTE *) &logChunkSize, &dummyLen); + if (code == ERROR_SUCCESS) { + if (logChunkSize < 12 || logChunkSize > 30) { + afsi_log("Invalid chunk size %d, using default", + logChunkSize); + logChunkSize = CM_CONFIGDEFAULT_CHUNKSIZE; + } + afsi_log("Chunk size %d", logChunkSize); + } else { + logChunkSize = CM_CONFIGDEFAULT_CHUNKSIZE; + afsi_log("Default chunk size %d", logChunkSize); + } + cm_logChunkSize = logChunkSize; + cm_chunkSize = 1 << logChunkSize; + + dummyLen = sizeof(numBkgD); + code = RegQueryValueEx(parmKey, "Daemons", NULL, NULL, + (BYTE *) &numBkgD, &dummyLen); + if (code == ERROR_SUCCESS) + afsi_log("%d background daemons", numBkgD); + else { + numBkgD = CM_CONFIGDEFAULT_DAEMONS; + afsi_log("Defaulting to %d background daemons", numBkgD); + } - dummyLen = sizeof(numSvThreads); - code = RegQueryValueEx(parmKey, "ServerThreads", NULL, NULL, - (BYTE *) &numSvThreads, &dummyLen); - if (code == ERROR_SUCCESS) - afsi_log("%d server threads", numSvThreads); - else { - numSvThreads = CM_CONFIGDEFAULT_SVTHREADS; - afsi_log("Defaulting to %d server threads", numSvThreads); - } + dummyLen = sizeof(numSvThreads); + code = RegQueryValueEx(parmKey, "ServerThreads", NULL, NULL, + (BYTE *) &numSvThreads, &dummyLen); + if (code == ERROR_SUCCESS) + afsi_log("%d server threads", numSvThreads); + else { + numSvThreads = CM_CONFIGDEFAULT_SVTHREADS; + afsi_log("Defaulting to %d server threads", numSvThreads); + } - dummyLen = sizeof(stats); - code = RegQueryValueEx(parmKey, "Stats", NULL, NULL, - (BYTE *) &stats, &dummyLen); - if (code == ERROR_SUCCESS) - afsi_log("Status cache size %d", stats); - else { - stats = CM_CONFIGDEFAULT_STATS; - afsi_log("Default status cache size %d", stats); - } + dummyLen = sizeof(stats); + code = RegQueryValueEx(parmKey, "Stats", NULL, NULL, + (BYTE *) &stats, &dummyLen); + if (code == ERROR_SUCCESS) + afsi_log("Status cache size %d", stats); + else { + stats = CM_CONFIGDEFAULT_STATS; + afsi_log("Default status cache size %d", stats); + } - dummyLen = sizeof(ltt); - code = RegQueryValueEx(parmKey, "LogoffTokenTransfer", NULL, NULL, - (BYTE *) <t, &dummyLen); - if (code == ERROR_SUCCESS) - afsi_log("Logoff token transfer %s", (ltt ? "on" : "off")); - else { - ltt = 1; - afsi_log("Logoff token transfer on by default"); - } + dummyLen = sizeof(ltt); + code = RegQueryValueEx(parmKey, "LogoffTokenTransfer", NULL, NULL, + (BYTE *) <t, &dummyLen); + if (code == ERROR_SUCCESS) + afsi_log("Logoff token transfer %s", (ltt ? "on" : "off")); + else { + ltt = 1; + afsi_log("Logoff token transfer on by default"); + } smb_LogoffTokenTransfer = ltt; afsi_log("Logoff token transfer is currently ignored"); - if (ltt) { - dummyLen = sizeof(ltto); - code = RegQueryValueEx(parmKey, "LogoffTokenTransferTimeout", - NULL, NULL, (BYTE *) <to, &dummyLen); - if (code == ERROR_SUCCESS) + if (ltt) { + dummyLen = sizeof(ltto); + code = RegQueryValueEx(parmKey, "LogoffTokenTransferTimeout", + NULL, NULL, (BYTE *) <to, &dummyLen); + if (code == ERROR_SUCCESS) afsi_log("Logoff token tranfer timeout %d seconds", ltto); - else { - ltto = 10; - afsi_log("Default logoff token transfer timeout 10 seconds"); - } - } else { + else { + ltto = 10; + afsi_log("Default logoff token transfer timeout 10 seconds"); + } + } else { ltto = 0; - } + } smb_LogoffTransferTimeout = ltto; afsi_log("Default logoff token is currently ignored"); - dummyLen = sizeof(cm_rootVolumeName); - code = RegQueryValueEx(parmKey, "RootVolume", NULL, NULL, - cm_rootVolumeName, &dummyLen); - if (code == ERROR_SUCCESS) - afsi_log("Root volume %s", cm_rootVolumeName); - else { - StringCbCopyA(cm_rootVolumeName, sizeof(cm_rootVolumeName), "root.afs"); - afsi_log("Default root volume name root.afs"); - } + dummyLen = sizeof(cm_rootVolumeName); + code = RegQueryValueEx(parmKey, "RootVolume", NULL, NULL, + cm_rootVolumeName, &dummyLen); + if (code == ERROR_SUCCESS) + afsi_log("Root volume %s", cm_rootVolumeName); + else { + StringCbCopyA(cm_rootVolumeName, sizeof(cm_rootVolumeName), "root.afs"); + afsi_log("Default root volume name root.afs"); + } - cm_mountRootLen = sizeof(cm_mountRoot); - code = RegQueryValueEx(parmKey, "MountRoot", NULL, NULL, - cm_mountRoot, &cm_mountRootLen); - if (code == ERROR_SUCCESS) { - afsi_log("Mount root %s", cm_mountRoot); - cm_mountRootLen = strlen(cm_mountRoot); - } else { - StringCbCopyA(cm_mountRoot, sizeof(cm_mountRoot), "/afs"); - cm_mountRootLen = 4; - /* Don't log */ - } + cm_mountRootLen = sizeof(cm_mountRoot); + code = RegQueryValueEx(parmKey, "MountRoot", NULL, NULL, + cm_mountRoot, &cm_mountRootLen); + if (code == ERROR_SUCCESS) { + afsi_log("Mount root %s", cm_mountRoot); + cm_mountRootLen = strlen(cm_mountRoot); + } else { + StringCbCopyA(cm_mountRoot, sizeof(cm_mountRoot), "/afs"); + cm_mountRootLen = 4; + /* Don't log */ + } - dummyLen = sizeof(buf); - code = RegQueryValueEx(parmKey, "CachePath", NULL, ®Type, - buf, &dummyLen); + dummyLen = sizeof(buf); + code = RegQueryValueEx(parmKey, "CachePath", NULL, ®Type, + buf, &dummyLen); if (code == ERROR_SUCCESS && buf[0]) { - if(regType == REG_EXPAND_SZ) { + if (regType == REG_EXPAND_SZ) { dummyLen = ExpandEnvironmentStrings(buf, cm_CachePath, sizeof(cm_CachePath)); if(dummyLen > sizeof(cm_CachePath)) { afsi_log("Cache path [%s] longer than %d after expanding env strings", buf, sizeof(cm_CachePath)); @@ -599,17 +599,17 @@ int afsd_InitCM(char **reasonP) } else { StringCbCopyA(cm_CachePath, sizeof(cm_CachePath), buf); } - afsi_log("Cache path %s", cm_CachePath); + afsi_log("Cache path %s", cm_CachePath); } else { - GetWindowsDirectory(cm_CachePath, sizeof(cm_CachePath)); - cm_CachePath[2] = 0; /* get drive letter only */ - StringCbCatA(cm_CachePath, sizeof(cm_CachePath), "\\AFSCache"); - afsi_log("Default cache path %s", cm_CachePath); - } + GetWindowsDirectory(cm_CachePath, sizeof(cm_CachePath)); + cm_CachePath[2] = 0; /* get drive letter only */ + StringCbCatA(cm_CachePath, sizeof(cm_CachePath), "\\AFSCache"); + afsi_log("Default cache path %s", cm_CachePath); + } dummyLen = sizeof(virtualCache); code = RegQueryValueEx(parmKey, "NonPersistentCaching", NULL, NULL, - &virtualCache, &dummyLen); + &virtualCache, &dummyLen); if (code == ERROR_SUCCESS && virtualCache) { buf_cacheType = CM_BUF_CACHETYPE_VIRTUAL; } else { @@ -617,27 +617,27 @@ int afsd_InitCM(char **reasonP) } afsi_log("Cache type is %s", ((buf_cacheType == CM_BUF_CACHETYPE_FILE)?"FILE":"VIRTUAL")); - dummyLen = sizeof(traceOnPanic); - code = RegQueryValueEx(parmKey, "TrapOnPanic", NULL, NULL, - (BYTE *) &traceOnPanic, &dummyLen); - if (code == ERROR_SUCCESS) - afsi_log("Set to %s on panic", - traceOnPanic ? "trap" : "not trap"); - else { - traceOnPanic = 0; - /* Don't log */ - } + dummyLen = sizeof(traceOnPanic); + code = RegQueryValueEx(parmKey, "TrapOnPanic", NULL, NULL, + (BYTE *) &traceOnPanic, &dummyLen); + if (code == ERROR_SUCCESS) + afsi_log("Set to %s on panic", + traceOnPanic ? "trap" : "not trap"); + else { + traceOnPanic = 0; + /* Don't log */ + } - dummyLen = sizeof(reportSessionStartups); - code = RegQueryValueEx(parmKey, "ReportSessionStartups", NULL, NULL, - (BYTE *) &reportSessionStartups, &dummyLen); - if (code == ERROR_SUCCESS) - afsi_log("Session startups %s be recorded in the Event Log", - reportSessionStartups ? "will" : "will not"); - else { - reportSessionStartups = 0; - /* Don't log */ - } + dummyLen = sizeof(reportSessionStartups); + code = RegQueryValueEx(parmKey, "ReportSessionStartups", NULL, NULL, + (BYTE *) &reportSessionStartups, &dummyLen); + if (code == ERROR_SUCCESS) + afsi_log("Session startups %s be recorded in the Event Log", + reportSessionStartups ? "will" : "will not"); + else { + reportSessionStartups = 0; + /* Don't log */ + } for ( i=0; i < MAXNUMSYSNAMES; i++ ) { cm_sysNameList[i] = osi_Alloc(MAXSYSNAME); @@ -645,53 +645,75 @@ int afsd_InitCM(char **reasonP) } cm_sysName = cm_sysNameList[0]; - dummyLen = MAXSYSNAME; - code = RegQueryValueEx(parmKey, "SysName", NULL, NULL, cm_sysName, &dummyLen); - if (code == ERROR_SUCCESS) - afsi_log("Sys name %s", cm_sysName); - else { - StringCbCopyA(cm_sysName, MAXSYSNAME, "i386_nt40"); - afsi_log("Default sys name %s", cm_sysName); - } - cm_sysNameCount = 1; - - dummyLen = sizeof(cryptall); - code = RegQueryValueEx(parmKey, "SecurityLevel", NULL, NULL, - (BYTE *) &cryptall, &dummyLen); - if (code == ERROR_SUCCESS) - afsi_log("SecurityLevel is %s", cryptall?"crypt":"clear"); - else { - cryptall = rxkad_clear; - afsi_log("Default SecurityLevel is clear"); - } + dummyLen = sizeof(buf); + code = RegQueryValueEx(parmKey, "SysName", NULL, NULL, buf, &dummyLen); + if (code == ERROR_SUCCESS && buf[0]) { + char * p, *q; + afsi_log("Sys name %s", buf); + + for (p = q = buf; p < cm_sysName + dummyLen; p++) + { + if (*p == '\0' || isspace(*p)) { + memcpy(cm_sysNameList[cm_sysNameCount],q,p-q); + cm_sysNameList[cm_sysNameCount][p-q] = '\0'; + cm_sysNameCount++; + + do { + if (*p == '\0') + goto done_sysname; + + p++; + } while (*p == '\0' || isspace(*p)); + q = p; + p--; + } + } + done_sysname: + StringCbCopyA(cm_sysName, MAXSYSNAME, cm_sysNameList[0]); + } else { + cm_sysNameCount = 1; + StringCbCopyA(cm_sysName, MAXSYSNAME, "i386_nt40"); + StringCbCopyA(cm_sysNameList[0], MAXSYSNAME, "i386_nt40"); + afsi_log("Default sys name %s", cm_sysName); + } + + dummyLen = sizeof(cryptall); + code = RegQueryValueEx(parmKey, "SecurityLevel", NULL, NULL, + (BYTE *) &cryptall, &dummyLen); + if (code == ERROR_SUCCESS) { + afsi_log("SecurityLevel is %s", cryptall?"crypt":"clear"); + } else { + cryptall = 0; + afsi_log("Default SecurityLevel is clear"); + } #ifdef AFS_AFSDB_ENV - dummyLen = sizeof(cm_dnsEnabled); - code = RegQueryValueEx(parmKey, "UseDNS", NULL, NULL, - (BYTE *) &cm_dnsEnabled, &dummyLen); - if (code == ERROR_SUCCESS) { - afsi_log("DNS %s be used to find AFS cell servers", - cm_dnsEnabled ? "will" : "will not"); - } - else { - cm_dnsEnabled = 1; /* default on */ - afsi_log("Default to use DNS to find AFS cell servers"); - } + dummyLen = sizeof(cm_dnsEnabled); + code = RegQueryValueEx(parmKey, "UseDNS", NULL, NULL, + (BYTE *) &cm_dnsEnabled, &dummyLen); + if (code == ERROR_SUCCESS) { + afsi_log("DNS %s be used to find AFS cell servers", + cm_dnsEnabled ? "will" : "will not"); + } + else { + cm_dnsEnabled = 1; /* default on */ + afsi_log("Default to use DNS to find AFS cell servers"); + } #else /* AFS_AFSDB_ENV */ - afsi_log("AFS not built with DNS support to find AFS cell servers"); + afsi_log("AFS not built with DNS support to find AFS cell servers"); #endif /* AFS_AFSDB_ENV */ #ifdef AFS_FREELANCE_CLIENT - dummyLen = sizeof(cm_freelanceEnabled); - code = RegQueryValueEx(parmKey, "FreelanceClient", NULL, NULL, - (BYTE *) &cm_freelanceEnabled, &dummyLen); - if (code == ERROR_SUCCESS) { - afsi_log("Freelance client feature %s activated", - cm_freelanceEnabled ? "is" : "is not"); - } - else { - cm_freelanceEnabled = 0; /* default off */ - } + dummyLen = sizeof(cm_freelanceEnabled); + code = RegQueryValueEx(parmKey, "FreelanceClient", NULL, NULL, + (BYTE *) &cm_freelanceEnabled, &dummyLen); + if (code == ERROR_SUCCESS) { + afsi_log("Freelance client feature %s activated", + cm_freelanceEnabled ? "is" : "is not"); + } + else { + cm_freelanceEnabled = 0; /* default off */ + } #endif /* AFS_FREELANCE_CLIENT */ #ifdef COMMENT @@ -738,15 +760,15 @@ int afsd_InitCM(char **reasonP) } afsi_log("Maximum number of VCs per server is %d", smb_maxVCPerServer); - dummyLen = sizeof(smb_authType); - code = RegQueryValueEx(parmKey, "SMBAuthType", NULL, NULL, - (BYTE *) &smb_authType, &dummyLen); + dummyLen = sizeof(smb_authType); + code = RegQueryValueEx(parmKey, "SMBAuthType", NULL, NULL, + (BYTE *) &smb_authType, &dummyLen); - if (code != ERROR_SUCCESS || - (smb_authType != SMB_AUTH_EXTENDED && smb_authType != SMB_AUTH_NTLM && smb_authType != SMB_AUTH_NONE)) { - smb_authType = SMB_AUTH_EXTENDED; /* default is to use extended authentication */ - } - afsi_log("SMB authentication type is %s", ((smb_authType == SMB_AUTH_NONE)?"NONE":((smb_authType == SMB_AUTH_EXTENDED)?"EXTENDED":"NTLM"))); + if (code != ERROR_SUCCESS || + (smb_authType != SMB_AUTH_EXTENDED && smb_authType != SMB_AUTH_NTLM && smb_authType != SMB_AUTH_NONE)) { + smb_authType = SMB_AUTH_EXTENDED; /* default is to use extended authentication */ + } + afsi_log("SMB authentication type is %s", ((smb_authType == SMB_AUTH_NONE)?"NONE":((smb_authType == SMB_AUTH_EXTENDED)?"EXTENDED":"NTLM"))); dummyLen = sizeof(rx_nojumbo); code = RegQueryValueEx(parmKey, "RxNoJumbo", NULL, NULL, @@ -754,7 +776,7 @@ int afsd_InitCM(char **reasonP) if (code != ERROR_SUCCESS) { rx_nojumbo = 0; } - if(rx_nojumbo) + if (rx_nojumbo) afsi_log("RX Jumbograms are disabled"); dummyLen = sizeof(rx_mtu); @@ -763,7 +785,7 @@ int afsd_InitCM(char **reasonP) if (code != ERROR_SUCCESS || !rx_mtu) { rx_mtu = -1; } - if(rx_mtu != -1) + if (rx_mtu != -1) afsi_log("RX maximum MTU is %d", rx_mtu); dummyLen = sizeof(ConnDeadtimeout); @@ -776,18 +798,18 @@ int afsd_InitCM(char **reasonP) (BYTE *) &HardDeadtimeout, &dummyLen); afsi_log("HardDeadTimeout is %d", HardDeadtimeout); - RegCloseKey (parmKey); + RegCloseKey (parmKey); /* Call lanahelper to get Netbios name, lan adapter number and gateway flag */ if(SUCCEEDED(code = lana_GetUncServerNameEx(cm_NetbiosName, &lanaNum, &isGateway, LANA_NETBIOS_NAME_FULL))) { LANadapter = (lanaNum == LANA_INVALID)? -1: lanaNum; - if(LANadapter != -1) + if (LANadapter != -1) afsi_log("LAN adapter number %d", LANadapter); else afsi_log("LAN adapter number not determined"); - if(isGateway) + if (isGateway) afsi_log("Set for gateway service"); afsi_log("Using >%s< as SMB server name", cm_NetbiosName); @@ -797,38 +819,38 @@ int afsd_InitCM(char **reasonP) osi_panic(buf, __FILE__, __LINE__); } - /* setup early variables */ - /* These both used to be configurable. */ - smb_UseV3 = 1; + /* setup early variables */ + /* These both used to be configurable. */ + smb_UseV3 = 1; buf_bufferSize = CM_CONFIGDEFAULT_BLOCKSIZE; - /* turn from 1024 byte units into memory blocks */ + /* turn from 1024 byte units into memory blocks */ cacheBlocks = (cacheSize * 1024) / buf_bufferSize; - /* get network related info */ - cm_noIPAddr = CM_MAXINTERFACE_ADDR; - code = syscfg_GetIFInfo(&cm_noIPAddr, - cm_IPAddr, cm_SubnetMask, - cm_NetMtu, cm_NetFlags); - - if ( (cm_noIPAddr <= 0) || (code <= 0 ) ) - afsi_log("syscfg_GetIFInfo error code %d", code); - else - afsi_log("First Network address %x SubnetMask %x", - cm_IPAddr[0], cm_SubnetMask[0]); - - /* - * Save client configuration for GetCacheConfig requests - */ - cm_initParams.nChunkFiles = 0; - cm_initParams.nStatCaches = stats; - cm_initParams.nDataCaches = 0; - cm_initParams.nVolumeCaches = 0; - cm_initParams.firstChunkSize = cm_chunkSize; - cm_initParams.otherChunkSize = cm_chunkSize; - cm_initParams.cacheSize = cacheSize; - cm_initParams.setTime = 0; - cm_initParams.memCache = 0; + /* get network related info */ + cm_noIPAddr = CM_MAXINTERFACE_ADDR; + code = syscfg_GetIFInfo(&cm_noIPAddr, + cm_IPAddr, cm_SubnetMask, + cm_NetMtu, cm_NetFlags); + + if ( (cm_noIPAddr <= 0) || (code <= 0 ) ) + afsi_log("syscfg_GetIFInfo error code %d", code); + else + afsi_log("First Network address %x SubnetMask %x", + cm_IPAddr[0], cm_SubnetMask[0]); + + /* + * Save client configuration for GetCacheConfig requests + */ + cm_initParams.nChunkFiles = 0; + cm_initParams.nStatCaches = stats; + cm_initParams.nDataCaches = 0; + cm_initParams.nVolumeCaches = 0; + cm_initParams.firstChunkSize = cm_chunkSize; + cm_initParams.otherChunkSize = cm_chunkSize; + cm_initParams.cacheSize = cacheSize; + cm_initParams.setTime = 0; + cm_initParams.memCache = 0; /* Set RX parameters before initializing RX */ if ( rx_nojumbo ) { @@ -847,48 +869,48 @@ int afsd_InitCM(char **reasonP) /* Ensure the AFS Netbios Name is registered to allow loopback access */ configureBackConnectionHostNames(); - /* initialize RX, and tell it to listen to port 7001, which is used for + /* initialize RX, and tell it to listen to port 7001, which is used for * callback RPC messages. */ - code = rx_Init(htons(7001)); - afsi_log("rx_Init code %x", code); - if (code != 0) { - *reasonP = "afsd: failed to init rx client on port 7001"; - return -1; - } + code = rx_Init(htons(7001)); + afsi_log("rx_Init code %x", code); + if (code != 0) { + *reasonP = "afsd: failed to init rx client on port 7001"; + return -1; + } - /* Initialize the RPC server for session keys */ - RpcInit(); + /* Initialize the RPC server for session keys */ + RpcInit(); - /* create an unauthenticated service #1 for callbacks */ - nullServerSecurityClassp = rxnull_NewServerSecurityObject(); + /* create an unauthenticated service #1 for callbacks */ + nullServerSecurityClassp = rxnull_NewServerSecurityObject(); serverp = rx_NewService(0, 1, "AFS", &nullServerSecurityClassp, 1, - RXAFSCB_ExecuteRequest); - afsi_log("rx_NewService addr %x", (int)serverp); - if (serverp == NULL) { - *reasonP = "unknown error"; - return -1; - } + RXAFSCB_ExecuteRequest); + afsi_log("rx_NewService addr %x", (int)serverp); + if (serverp == NULL) { + *reasonP = "unknown error"; + return -1; + } - nullServerSecurityClassp = rxnull_NewServerSecurityObject(); + nullServerSecurityClassp = rxnull_NewServerSecurityObject(); serverp = rx_NewService(0, RX_STATS_SERVICE_ID, "rpcstats", - &nullServerSecurityClassp, 1, RXSTATS_ExecuteRequest); - afsi_log("rx_NewService addr %x", (int)serverp); - if (serverp == NULL) { - *reasonP = "unknown error"; - return -1; - } + &nullServerSecurityClassp, 1, RXSTATS_ExecuteRequest); + afsi_log("rx_NewService addr %x", (int)serverp); + if (serverp == NULL) { + *reasonP = "unknown error"; + return -1; + } /* start server threads, *not* donating this one to the pool */ rx_StartServer(0); - afsi_log("rx_StartServer"); + afsi_log("rx_StartServer"); - /* init user daemon, and other packages */ - cm_InitUser(); + /* init user daemon, and other packages */ + cm_InitUser(); - cm_InitACLCache(2*stats); + cm_InitACLCache(2*stats); - cm_InitConn(); + cm_InitConn(); cm_InitCell(); @@ -905,28 +927,28 @@ int afsd_InitCM(char **reasonP) cm_InitSCache(stats); code = cm_InitDCache(0, cacheBlocks); - afsi_log("cm_InitDCache code %x", code); - if (code != 0) { - *reasonP = "error initializing cache"; - return -1; - } + afsi_log("cm_InitDCache code %x", code); + if (code != 0) { + *reasonP = "error initializing cache"; + return -1; + } #ifdef AFS_AFSDB_ENV #if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500) - if (cm_InitDNS(cm_dnsEnabled) == -1) - cm_dnsEnabled = 0; /* init failed, so deactivate */ - afsi_log("cm_InitDNS %d", cm_dnsEnabled); + if (cm_InitDNS(cm_dnsEnabled) == -1) + cm_dnsEnabled = 0; /* init failed, so deactivate */ + afsi_log("cm_InitDNS %d", cm_dnsEnabled); #endif #endif - code = cm_GetRootCellName(rootCellName); - afsi_log("cm_GetRootCellName code %d, cm_freelanceEnabled= %d, rcn= %s", - code, cm_freelanceEnabled, (code ? "" : rootCellName)); - if (code != 0 && !cm_freelanceEnabled) + code = cm_GetRootCellName(rootCellName); + afsi_log("cm_GetRootCellName code %d, cm_freelanceEnabled= %d, rcn= %s", + code, cm_freelanceEnabled, (code ? "" : rootCellName)); + if (code != 0 && !cm_freelanceEnabled) { - *reasonP = "can't find root cell name in afsd.ini"; - return -1; - } + *reasonP = "can't find root cell name in afsd.ini"; + return -1; + } else if (cm_freelanceEnabled) cm_rootCellp = NULL; @@ -939,14 +961,13 @@ int afsd_InitCM(char **reasonP) *reasonP = "can't find root cell in afsdcell.ini"; return -1; } - } - + } #ifdef AFS_FREELANCE_CLIENT - if (cm_freelanceEnabled) - cm_InitFreelance(); + if (cm_freelanceEnabled) + cm_InitFreelance(); #endif - return 0; + return 0; } int afsd_InitDaemons(char **reasonP) diff --git a/src/WINNT/afsd/afsd_service.c b/src/WINNT/afsd/afsd_service.c index 0517edec7..43fcb783f 100644 --- a/src/WINNT/afsd/afsd_service.c +++ b/src/WINNT/afsd/afsd_service.c @@ -32,7 +32,8 @@ // The following is defined if you want to receive Power notifications, // including Hibernation, and also subsequent flushing of AFS volumes // -#define REGISTER_POWER_NOTIFICATIONS +#define REGISTER_POWER_NOTIFICATIONS 1 +#define FLUSH_VOLUME 1 // // Check */ @@ -54,31 +55,33 @@ jmp_buf notifier_jmp; extern int traceOnPanic; extern HANDLE afsi_file; +int powerEventsRegistered = 0; + /* * Notifier function for use by osi_panic */ static void afsd_notifier(char *msgp, char *filep, long line) { - char tbuffer[512]; - char *ptbuf[1]; - HANDLE h; + char tbuffer[512]; + char *ptbuf[1]; + HANDLE h; - if (filep) - sprintf(tbuffer, "Error at file %s, line %d: %s", - filep, line, msgp); - else - sprintf(tbuffer, "Error at unknown location: %s", msgp); + if (filep) + sprintf(tbuffer, "Error at file %s, line %d: %s", + filep, line, msgp); + else + sprintf(tbuffer, "Error at unknown location: %s", msgp); - h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME); - ptbuf[0] = tbuffer; - ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, line, NULL, 1, 0, ptbuf, NULL); - DeregisterEventSource(h); + h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME); + ptbuf[0] = tbuffer; + ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, line, NULL, 1, 0, ptbuf, NULL); + DeregisterEventSource(h); - GlobalStatus = line; + GlobalStatus = line; - osi_LogEnable(afsd_logp); + osi_LogEnable(afsd_logp); - afsd_ForceTrace(TRUE); + afsd_ForceTrace(TRUE); afsi_log("--- begin dump ---"); cm_DumpSCache(afsi_file, "a"); @@ -91,14 +94,14 @@ static void afsd_notifier(char *msgp, char *filep, long line) DebugBreak(); - SetEvent(WaitToTerminate); + SetEvent(WaitToTerminate); #ifdef JUMP - if (GetCurrentThreadId() == MainThreadId) - longjmp(notifier_jmp, 1); - else + if (GetCurrentThreadId() == MainThreadId) + longjmp(notifier_jmp, 1); + else #endif /* JUMP */ - ExitThread(1); + ExitThread(1); } /* @@ -106,7 +109,7 @@ static void afsd_notifier(char *msgp, char *filep, long line) */ static int _stdcall DummyMessageBox(HWND h, LPCTSTR l1, LPCTSTR l2, UINT ui) { - return 0; + return 0; } static SERVICE_STATUS ServiceStatus; @@ -130,7 +133,6 @@ afsd_ServiceFlushVolume(DWORD dwlpEventData) { dwRet = NO_ERROR; } - else { /* flush was unsuccessful, or timeout - deny shutdown */ @@ -151,53 +153,53 @@ afsd_ServiceFlushVolume(DWORD dwlpEventData) VOID WINAPI afsd_ServiceControlHandler(DWORD ctrlCode) { - HKEY parmKey; - DWORD dummyLen, doTrace; - long code; - - switch (ctrlCode) { - case SERVICE_CONTROL_STOP: - /* Shutdown RPC */ - RpcMgmtStopServerListening(NULL); - - /* Force trace if requested */ - code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, - AFSConfigKeyName, - 0, KEY_QUERY_VALUE, &parmKey); - if (code != ERROR_SUCCESS) - goto doneTrace; - - dummyLen = sizeof(doTrace); - code = RegQueryValueEx(parmKey, "TraceOnShutdown", - NULL, NULL, - (BYTE *) &doTrace, &dummyLen); - RegCloseKey (parmKey); - if (code != ERROR_SUCCESS) - doTrace = 0; - if (doTrace) - afsd_ForceTrace(FALSE); - -doneTrace: - ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING; - ServiceStatus.dwWin32ExitCode = NO_ERROR; - ServiceStatus.dwCheckPoint = 1; - ServiceStatus.dwWaitHint = 10000; - ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; - SetServiceStatus(StatusHandle, &ServiceStatus); - SetEvent(WaitToTerminate); - break; - case SERVICE_CONTROL_INTERROGATE: - ServiceStatus.dwCurrentState = SERVICE_RUNNING; - ServiceStatus.dwWin32ExitCode = NO_ERROR; - ServiceStatus.dwCheckPoint = 0; - ServiceStatus.dwWaitHint = 0; - ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; - SetServiceStatus(StatusHandle, &ServiceStatus); - break; - /* XXX handle system shutdown */ - /* XXX handle pause & continue */ - } -} + HKEY parmKey; + DWORD dummyLen, doTrace; + long code; + + switch (ctrlCode) { + case SERVICE_CONTROL_STOP: + /* Shutdown RPC */ + RpcMgmtStopServerListening(NULL); + + /* Force trace if requested */ + code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, + AFSConfigKeyName, + 0, KEY_QUERY_VALUE, &parmKey); + if (code != ERROR_SUCCESS) + goto doneTrace; + + dummyLen = sizeof(doTrace); + code = RegQueryValueEx(parmKey, "TraceOnShutdown", + NULL, NULL, + (BYTE *) &doTrace, &dummyLen); + RegCloseKey (parmKey); + if (code != ERROR_SUCCESS) + doTrace = 0; + if (doTrace) + afsd_ForceTrace(FALSE); + + doneTrace: + ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING; + ServiceStatus.dwWin32ExitCode = NO_ERROR; + ServiceStatus.dwCheckPoint = 1; + ServiceStatus.dwWaitHint = 10000; + ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; + SetServiceStatus(StatusHandle, &ServiceStatus); + SetEvent(WaitToTerminate); + break; + case SERVICE_CONTROL_INTERROGATE: + ServiceStatus.dwCurrentState = SERVICE_RUNNING; + ServiceStatus.dwWin32ExitCode = NO_ERROR; + ServiceStatus.dwCheckPoint = 0; + ServiceStatus.dwWaitHint = 0; + ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; + SetServiceStatus(StatusHandle, &ServiceStatus); + break; + /* XXX handle system shutdown */ + /* XXX handle pause & continue */ + } +} /* @@ -212,12 +214,12 @@ afsd_ServiceControlHandlerEx( LPVOID lpContext ) { - HKEY parmKey; - DWORD dummyLen, doTrace; - long code; + HKEY parmKey; + DWORD dummyLen, doTrace; + long code; DWORD dwRet = ERROR_CALL_NOT_IMPLEMENTED; - switch (ctrlCode) + switch (ctrlCode) { case SERVICE_CONTROL_STOP: /* Shutdown RPC */ @@ -261,45 +263,47 @@ afsd_ServiceControlHandlerEx( dwRet = NO_ERROR; break; - /* XXX handle system shutdown */ - /* XXX handle pause & continue */ - case SERVICE_CONTROL_POWEREVENT: - { - /* + /* XXX handle system shutdown */ + /* XXX handle pause & continue */ + case SERVICE_CONTROL_POWEREVENT: + { + /* ** dwEventType of this notification == WPARAM of WM_POWERBROADCAST - ** Return NO_ERROR == return TRUE for that message, i.e. accept request - ** Return any error code to deny request, - ** i.e. as if returning BROADCAST_QUERY_DENY - */ - switch((int) dwEventType) - { - case PBT_APMQUERYSUSPEND: - case PBT_APMQUERYSTANDBY: - -#ifdef REGISTER_POWER_NOTIFICATIONS - /* handle event */ - dwRet = afsd_ServiceFlushVolume((DWORD) lpEventData); + ** Return NO_ERROR == return TRUE for that message, i.e. accept request + ** Return any error code to deny request, + ** i.e. as if returning BROADCAST_QUERY_DENY + */ + if (powerEventsRegistered) { + switch((int) dwEventType) + { + case PBT_APMQUERYSUSPEND: + case PBT_APMQUERYSTANDBY: + +#ifdef FLUSH_VOLUME + /* handle event */ + dwRet = afsd_ServiceFlushVolume((DWORD) lpEventData); #else - dwRet = NO_ERROR; + dwRet = NO_ERROR; #endif - break; + break; - /* allow remaining case PBT_WhatEver */ - case PBT_APMSUSPEND: - case PBT_APMSTANDBY: - case PBT_APMRESUMECRITICAL: - case PBT_APMRESUMESUSPEND: - case PBT_APMRESUMESTANDBY: - case PBT_APMBATTERYLOW: - case PBT_APMPOWERSTATUSCHANGE: - case PBT_APMOEMEVENT: - case PBT_APMRESUMEAUTOMATIC: - default: - dwRet = NO_ERROR; + /* allow remaining case PBT_WhatEver */ + case PBT_APMSUSPEND: + case PBT_APMSTANDBY: + case PBT_APMRESUMECRITICAL: + case PBT_APMRESUMESUSPEND: + case PBT_APMRESUMESTANDBY: + case PBT_APMBATTERYLOW: + case PBT_APMPOWERSTATUSCHANGE: + case PBT_APMOEMEVENT: + case PBT_APMRESUMEAUTOMATIC: + default: + dwRet = NO_ERROR; + } } } } /* end switch(ctrlCode) */ - return dwRet; + return dwRet; } /* There is similar code in client_config\drivemap.cpp GlobalMountDrive() @@ -308,7 +312,7 @@ afsd_ServiceControlHandlerEx( */ /* DEE Could check first if we are run as SYSTEM */ #define MAX_RETRIES 30 -static void MountGlobalDrives() +static void MountGlobalDrives(void) { char szAfsPath[_MAX_PATH]; char szDriveToMapTo[5]; @@ -323,8 +327,8 @@ static void MountGlobalDrives() sprintf(szKeyName, "%s\\GlobalAutoMapper", AFSConfigKeyName); - dwResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_QUERY_VALUE, &hKey); - if (dwResult != ERROR_SUCCESS) + dwResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_QUERY_VALUE, &hKey); + if (dwResult != ERROR_SUCCESS) return; while (dwRetry < MAX_RETRIES) { @@ -385,8 +389,8 @@ static void DismountGlobalDrives() sprintf(szKeyName, "%s\\GlobalAutoMapper", AFSConfigKeyName); - dwResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_QUERY_VALUE, &hKey); - if (dwResult != ERROR_SUCCESS) + dwResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_QUERY_VALUE, &hKey); + if (dwResult != ERROR_SUCCESS) return; while (1) { @@ -428,10 +432,10 @@ RegisterServiceCtrlHandlerFunc pRegisterServiceCtrlHandler = NULL; void afsd_Main(DWORD argc, LPTSTR *argv) { - long code; - char *reason; + long code; + char *reason; #ifdef JUMP - int jmpret; + int jmpret; #endif /* JUMP */ HANDLE hInitHookDll; HANDLE hAdvApi32; @@ -443,13 +447,13 @@ void afsd_Main(DWORD argc, LPTSTR *argv) #endif osi_InitPanic(afsd_notifier); - osi_InitTraceOption(); + osi_InitTraceOption(); - GlobalStatus = 0; + GlobalStatus = 0; - afsi_start(); + afsi_start(); - WaitToTerminate = CreateEvent(NULL, TRUE, FALSE, TEXT("afsd_service_WaitToTerminate")); + WaitToTerminate = CreateEvent(NULL, TRUE, FALSE, TEXT("afsd_service_WaitToTerminate")); if ( GetLastError() == ERROR_ALREADY_EXISTS ) afsi_log("Event Object Already Exists: %s", TEXT("afsd_service_WaitToTerminate")); @@ -472,15 +476,15 @@ void afsd_Main(DWORD argc, LPTSTR *argv) StatusHandle = RegisterServiceCtrlHandler(AFS_DAEMON_SERVICE_NAME, afsd_ServiceControlHandler); } - ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; - ServiceStatus.dwServiceSpecificExitCode = 0; - ServiceStatus.dwCurrentState = SERVICE_START_PENDING; - ServiceStatus.dwWin32ExitCode = NO_ERROR; - ServiceStatus.dwCheckPoint = 1; - ServiceStatus.dwWaitHint = 30000; + ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; + ServiceStatus.dwServiceSpecificExitCode = 0; + ServiceStatus.dwCurrentState = SERVICE_START_PENDING; + ServiceStatus.dwWin32ExitCode = NO_ERROR; + ServiceStatus.dwCheckPoint = 1; + ServiceStatus.dwWaitHint = 30000; /* accept Power Events */ - ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_POWEREVENT; - SetServiceStatus(StatusHandle, &ServiceStatus); + ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_POWEREVENT; + SetServiceStatus(StatusHandle, &ServiceStatus); #endif { @@ -492,8 +496,30 @@ void afsd_Main(DWORD argc, LPTSTR *argv) } #ifdef REGISTER_POWER_NOTIFICATIONS - /* create thread used to flush cache */ - PowerNotificationThreadCreate(); + { + HKEY hkParm; + DWORD code; + DWORD dummyLen; + int bpower = TRUE; + + /* see if we should handle power notifications */ + code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSConfigKeyName, 0, KEY_QUERY_VALUE, &hkParm); + if (code == ERROR_SUCCESS) { + dummyLen = sizeof(bpower); + code = RegQueryValueEx(hkParm, "FlushOnHibernate", NULL, NULL, + (BYTE *) &bpower, &dummyLen); + + if(code != ERROR_SUCCESS) + bpower = TRUE; + + RegCloseKey(hkParm); + } + /* create thread used to flush cache */ + if (bpower) { + PowerNotificationThreadCreate(); + powerEventsRegistered = 1; + } + } #endif /* allow an exit to be called prior to any initialization */ @@ -538,15 +564,15 @@ void afsd_Main(DWORD argc, LPTSTR *argv) #ifdef JUMP MainThreadId = GetCurrentThreadId(); - jmpret = setjmp(notifier_jmp); + jmpret = setjmp(notifier_jmp); - if (jmpret == 0) + if (jmpret == 0) #endif /* JUMP */ { - code = afsd_InitCM(&reason); - if (code != 0) { + code = afsd_InitCM(&reason); + if (code != 0) { afsi_log("afsd_InitCM failed: %s (code = %d)", reason, code); - osi_panic(reason, __FILE__, __LINE__); + osi_panic(reason, __FILE__, __LINE__); } #ifndef NOTSERVICE @@ -554,8 +580,8 @@ void afsd_Main(DWORD argc, LPTSTR *argv) ServiceStatus.dwWaitHint -= 5000; SetServiceStatus(StatusHandle, &ServiceStatus); #endif - code = afsd_InitDaemons(&reason); - if (code != 0) { + code = afsd_InitDaemons(&reason); + if (code != 0) { afsi_log("afsd_InitDaemons failed: %s (code = %d)", reason, code); osi_panic(reason, __FILE__, __LINE__); } @@ -565,42 +591,42 @@ void afsd_Main(DWORD argc, LPTSTR *argv) ServiceStatus.dwWaitHint -= 5000; SetServiceStatus(StatusHandle, &ServiceStatus); #endif - code = afsd_InitSMB(&reason, MessageBox); - if (code != 0) { + code = afsd_InitSMB(&reason, MessageBox); + if (code != 0) { afsi_log("afsd_InitSMB failed: %s (code = %d)", reason, code); - osi_panic(reason, __FILE__, __LINE__); + osi_panic(reason, __FILE__, __LINE__); } MountGlobalDrives(); #ifndef NOTSERVICE - ServiceStatus.dwCurrentState = SERVICE_RUNNING; - ServiceStatus.dwWin32ExitCode = NO_ERROR; - ServiceStatus.dwCheckPoint = 0; - ServiceStatus.dwWaitHint = 0; + ServiceStatus.dwCurrentState = SERVICE_RUNNING; + ServiceStatus.dwWin32ExitCode = NO_ERROR; + ServiceStatus.dwCheckPoint = 0; + ServiceStatus.dwWaitHint = 0; /* accept Power events */ - ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_POWEREVENT; - SetServiceStatus(StatusHandle, &ServiceStatus); -#endif + ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_POWEREVENT; + SetServiceStatus(StatusHandle, &ServiceStatus); +#endif { HANDLE h; char *ptbuf[1]; - h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME); - ptbuf[0] = "AFS running"; - ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, ptbuf, NULL); - DeregisterEventSource(h); + h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME); + ptbuf[0] = "AFS running"; + ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, ptbuf, NULL); + DeregisterEventSource(h); } - } + } - WaitForSingleObject(WaitToTerminate, INFINITE); + WaitForSingleObject(WaitToTerminate, INFINITE); { - HANDLE h; char *ptbuf[1]; + HANDLE h; char *ptbuf[1]; h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME); ptbuf[0] = "AFS quitting"; ReportEvent(h, GlobalStatus ? EVENTLOG_ERROR_TYPE : EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, ptbuf, NULL); - DeregisterEventSource(h); + DeregisterEventSource(h); } DismountGlobalDrives(); @@ -608,20 +634,21 @@ void afsd_Main(DWORD argc, LPTSTR *argv) rx_Finalize(); #ifdef REGISTER_POWER_NOTIFICATIONS - /* terminate thread used to flush cache */ - PowerNotificationThreadExit(); + /* terminate thread used to flush cache */ + if (powerEventsRegistered) + PowerNotificationThreadExit(); #endif /* Remove the ExceptionFilter */ SetUnhandledExceptionFilter(NULL); ServiceStatus.dwCurrentState = SERVICE_STOPPED; - ServiceStatus.dwWin32ExitCode = GlobalStatus ? ERROR_EXCEPTION_IN_SERVICE : NO_ERROR; - ServiceStatus.dwCheckPoint = 0; - ServiceStatus.dwWaitHint = 0; - ServiceStatus.dwControlsAccepted = 0; - SetServiceStatus(StatusHandle, &ServiceStatus); -} + ServiceStatus.dwWin32ExitCode = GlobalStatus ? ERROR_EXCEPTION_IN_SERVICE : NO_ERROR; + ServiceStatus.dwCheckPoint = 0; + ServiceStatus.dwWaitHint = 0; + ServiceStatus.dwControlsAccepted = 0; + SetServiceStatus(StatusHandle, &ServiceStatus); +} DWORD __stdcall afsdMain_thread(void* notUsed) { @@ -633,15 +660,15 @@ DWORD __stdcall afsdMain_thread(void* notUsed) int main(void) { - static SERVICE_TABLE_ENTRY dispatchTable[] = { - {AFS_DAEMON_SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION) afsd_Main}, - {NULL, NULL} - }; + static SERVICE_TABLE_ENTRY dispatchTable[] = { + {AFS_DAEMON_SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION) afsd_Main}, + {NULL, NULL} + }; - if (!StartServiceCtrlDispatcher(dispatchTable)) + if (!StartServiceCtrlDispatcher(dispatchTable)) { LONG status = GetLastError(); - if (status == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) + if (status == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) { DWORD tid; hAFSDMainThread = CreateThread(NULL, 0, afsdMain_thread, 0, 0, &tid); diff --git a/src/WINNT/afsd/afskfw.c b/src/WINNT/afsd/afskfw.c index 763dc19b1..743374a28 100644 --- a/src/WINNT/afsd/afskfw.c +++ b/src/WINNT/afsd/afskfw.c @@ -444,28 +444,65 @@ KFW_cleanup(void) static char OpenAFSConfigKeyName[] = "SOFTWARE\\OpenAFS\\Client"; +int +KFW_use_krb524(void) +{ + HKEY parmKey; + DWORD code, len; + DWORD use524 = 0; + + code = RegOpenKeyEx(HKEY_CURRENT_USER, OpenAFSConfigKeyName, + 0, KEY_QUERY_VALUE, &parmKey); + if (code == ERROR_SUCCESS) { + len = sizeof(use524); + code = RegQueryValueEx(parmKey, "Use524", NULL, NULL, + (BYTE *) &use524, &len); + if (code != ERROR_SUCCESS) { + RegCloseKey(parmKey); + + code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, OpenAFSConfigKeyName, + 0, KEY_QUERY_VALUE, &parmKey); + if (code == ERROR_SUCCESS) { + len = sizeof(use524); + code = RegQueryValueEx(parmKey, "Use524", NULL, NULL, + (BYTE *) &use524, &len); + if (code != ERROR_SUCCESS) + use524 = 0; + } + } + RegCloseKey (parmKey); + } + return use524; +} + int KFW_is_available(void) { HKEY parmKey; - DWORD code, len; + DWORD code, len; DWORD enableKFW = 1; code = RegOpenKeyEx(HKEY_CURRENT_USER, OpenAFSConfigKeyName, 0, KEY_QUERY_VALUE, &parmKey); - if (code != ERROR_SUCCESS) - code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, OpenAFSConfigKeyName, - 0, KEY_QUERY_VALUE, &parmKey); - if (code == ERROR_SUCCESS) { + if (code == ERROR_SUCCESS) { len = sizeof(enableKFW); code = RegQueryValueEx(parmKey, "EnableKFW", NULL, NULL, (BYTE *) &enableKFW, &len); if (code != ERROR_SUCCESS) { - enableKFW = 1; + RegCloseKey(parmKey); + + code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, OpenAFSConfigKeyName, + 0, KEY_QUERY_VALUE, &parmKey); + if (code == ERROR_SUCCESS) { + len = sizeof(enableKFW); + code = RegQueryValueEx(parmKey, "EnableKFW", NULL, NULL, + (BYTE *) &enableKFW, &len); + if (code != ERROR_SUCCESS) + enableKFW = 1; + } } RegCloseKey (parmKey); - } - + } if ( !enableKFW ) return FALSE; @@ -890,11 +927,11 @@ KFW_import_windows_lsa(void) princ_realm = krb5_princ_realm(ctx, princ); for ( i=0; ilength; i++ ) { - realm[i] = princ_realm->data[i]; + realm[i] = princ_realm->data[i]; cell[i] = tolower(princ_realm->data[i]); } - cell[i] = '\0'; - realm[i] = '\0'; + cell[i] = '\0'; + realm[i] = '\0'; code = KFW_AFS_klog(ctx, cc, "afs", cell, realm, pLeash_get_default_lifetime(),NULL); if ( IsDebuggerPresent() ) { @@ -2546,10 +2583,10 @@ KFW_AFS_klog( memset(ServiceName, '\0', sizeof(ServiceName)); memset(realm_of_user, '\0', sizeof(realm_of_user)); memset(realm_of_cell, '\0', sizeof(realm_of_cell)); - if (cell && cell[0]) - strcpy(Dmycell, cell); - else - memset(Dmycell, '\0', sizeof(Dmycell)); + if (cell && cell[0]) + strcpy(Dmycell, cell); + else + memset(Dmycell, '\0', sizeof(Dmycell)); // NULL or empty cell returns information on local cell if (rc = KFW_AFS_get_cellconfig(Dmycell, &ak_cellconfig, local_cell)) @@ -2575,13 +2612,21 @@ KFW_AFS_klog( memset((char *)&increds, 0, sizeof(increds)); code = pkrb5_cc_get_principal(ctx, cc, &client_principal); - if (code) { + if (code) { if ( code == KRB5_CC_NOTFOUND && IsDebuggerPresent() ) { OutputDebugString("Principal Not Found for ccache\n"); } goto skip_krb5_init; } + + if ( strchr(krb5_princ_component(ctx,client_principal,0),'.') != NULL ) + { + OutputDebugString("Illegal Principal name contains dot in first component\n"); + rc = KRB5KRB_ERR_GENERIC; + goto cleanup; + } + i = krb5_princ_realm(ctx, client_principal)->length; if (i > REALM_SZ-1) i = REALM_SZ-1; @@ -2761,7 +2806,8 @@ KFW_AFS_klog( * No need to perform a krb524 translation which is * commented out in the code below */ - if (k5creds->ticket.length > MAXKTCTICKETLEN) + if (KFW_use_krb524() || + k5creds->ticket.length > MAXKTCTICKETLEN) goto try_krb524d; memset(&aserver, '\0', sizeof(aserver)); diff --git a/src/WINNT/afsd/afsshare.c b/src/WINNT/afsd/afsshare.c index eb0f83a52..6ef60a0e3 100644 --- a/src/WINNT/afsd/afsshare.c +++ b/src/WINNT/afsd/afsshare.c @@ -65,7 +65,7 @@ main(int argc, char **argv) { else mountstring = argv[2]; - if (RegSetValueEx(hkSubmounts, argv[1], 0, REG_SZ, mountstring, strlen(mountstring)+1)) { + if (RegSetValueEx(hkSubmounts, argv[1], 0, REG_EXPAND_SZ, mountstring, strlen(mountstring)+1)) { fprintf(stderr,"Submount Set failure for [%s]: %lX", argv[1], GetLastError()); RegCloseKey(hkSubmounts); diff --git a/src/WINNT/afsd/cm_buf.c b/src/WINNT/afsd/cm_buf.c index e0ee133fd..9fef57dfe 100644 --- a/src/WINNT/afsd/cm_buf.c +++ b/src/WINNT/afsd/cm_buf.c @@ -110,58 +110,58 @@ extern int cm_diskCacheEnabled; /* hold a reference to an already held buffer */ void buf_Hold(cm_buf_t *bp) { - lock_ObtainWrite(&buf_globalLock); - bp->refCount++; - lock_ReleaseWrite(&buf_globalLock); + lock_ObtainWrite(&buf_globalLock); + bp->refCount++; + lock_ReleaseWrite(&buf_globalLock); } /* incremental sync daemon. Writes 1/10th of all the buffers every 5000 ms */ void buf_IncrSyncer(long parm) { - cm_buf_t *bp; /* buffer we're hacking on; held */ - long i; /* counter */ - long nAtOnce; /* how many to do at once */ - cm_req_t req; - - lock_ObtainWrite(&buf_globalLock); - bp = buf_allp; - bp->refCount++; - lock_ReleaseWrite(&buf_globalLock); - nAtOnce = buf_nbuffers / 10; - while (1) { + cm_buf_t *bp; /* buffer we're hacking on; held */ + long i; /* counter */ + long nAtOnce; /* how many to do at once */ + cm_req_t req; + + lock_ObtainWrite(&buf_globalLock); + bp = buf_allp; + bp->refCount++; + lock_ReleaseWrite(&buf_globalLock); + nAtOnce = buf_nbuffers / 10; + while (1) { #ifndef DJGPP - i = SleepEx(5000, 1); - if (i != 0) continue; + i = SleepEx(5000, 1); + if (i != 0) continue; #else - thrd_Sleep(5000); + thrd_Sleep(5000); #endif /* DJGPP */ - /* now go through our percentage of the buffers */ - for(i=0; iallp; - if (!bp) bp = buf_allp; - bp->refCount++; - lock_ReleaseWrite(&buf_globalLock); - } /* for loop over a bunch of buffers */ - } /* whole daemon's while loop */ + /* now go through our percentage of the buffers */ + for(i=0; iallp; + if (!bp) bp = buf_allp; + bp->refCount++; + lock_ReleaseWrite(&buf_globalLock); + } /* for loop over a bunch of buffers */ + } /* whole daemon's while loop */ } #ifndef DJGPP @@ -172,58 +172,58 @@ void buf_IncrSyncer(long parm) */ PSECURITY_ATTRIBUTES CreateCacheFileSA() { - PSECURITY_ATTRIBUTES psa; - PSECURITY_DESCRIPTOR psd; - SID_IDENTIFIER_AUTHORITY authority = SECURITY_NT_AUTHORITY; - PSID AdminSID; - DWORD AdminSIDlength; - PACL AdminOnlyACL; - DWORD ACLlength; - - /* Get Administrator SID */ - AllocateAndInitializeSid(&authority, 2, - SECURITY_BUILTIN_DOMAIN_RID, - DOMAIN_ALIAS_RID_ADMINS, - 0, 0, 0, 0, 0, 0, - &AdminSID); - - /* Create Administrator-only ACL */ - AdminSIDlength = GetLengthSid(AdminSID); - ACLlength = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) - + AdminSIDlength - sizeof(DWORD); - AdminOnlyACL = GlobalAlloc(GMEM_FIXED, ACLlength); - InitializeAcl(AdminOnlyACL, ACLlength, ACL_REVISION); - AddAccessAllowedAce(AdminOnlyACL, ACL_REVISION, - STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL, - AdminSID); - - /* Create security descriptor */ - psd = GlobalAlloc(GMEM_FIXED, sizeof(SECURITY_DESCRIPTOR)); - InitializeSecurityDescriptor(psd, SECURITY_DESCRIPTOR_REVISION); - SetSecurityDescriptorDacl(psd, TRUE, AdminOnlyACL, FALSE); - - /* Create security attributes structure */ - psa = GlobalAlloc(GMEM_FIXED, sizeof(SECURITY_ATTRIBUTES)); - psa->nLength = sizeof(SECURITY_ATTRIBUTES); - psa->lpSecurityDescriptor = psd; - psa->bInheritHandle = TRUE; - - return psa; -} + PSECURITY_ATTRIBUTES psa; + PSECURITY_DESCRIPTOR psd; + SID_IDENTIFIER_AUTHORITY authority = SECURITY_NT_AUTHORITY; + PSID AdminSID; + DWORD AdminSIDlength; + PACL AdminOnlyACL; + DWORD ACLlength; + + /* Get Administrator SID */ + AllocateAndInitializeSid(&authority, 2, + SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, + 0, 0, 0, 0, 0, 0, + &AdminSID); + + /* Create Administrator-only ACL */ + AdminSIDlength = GetLengthSid(AdminSID); + ACLlength = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + + AdminSIDlength - sizeof(DWORD); + AdminOnlyACL = GlobalAlloc(GMEM_FIXED, ACLlength); + InitializeAcl(AdminOnlyACL, ACLlength, ACL_REVISION); + AddAccessAllowedAce(AdminOnlyACL, ACL_REVISION, + STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL, + AdminSID); + + /* Create security descriptor */ + psd = GlobalAlloc(GMEM_FIXED, sizeof(SECURITY_DESCRIPTOR)); + InitializeSecurityDescriptor(psd, SECURITY_DESCRIPTOR_REVISION); + SetSecurityDescriptorDacl(psd, TRUE, AdminOnlyACL, FALSE); + + /* Create security attributes structure */ + psa = GlobalAlloc(GMEM_FIXED, sizeof(SECURITY_ATTRIBUTES)); + psa->nLength = sizeof(SECURITY_ATTRIBUTES); + psa->lpSecurityDescriptor = psd; + psa->bInheritHandle = TRUE; + + return psa; +} #endif /* !DJGPP */ #ifndef DJGPP /* Free a security attribute structure created by CreateCacheFileSA() */ VOID FreeCacheFileSA(PSECURITY_ATTRIBUTES psa) { - BOOL b1, b2; - PACL pAcl; - - GetSecurityDescriptorDacl(psa->lpSecurityDescriptor, &b1, &pAcl, &b2); - GlobalFree(pAcl); - GlobalFree(psa->lpSecurityDescriptor); - GlobalFree(psa); -} + BOOL b1, b2; + PACL pAcl; + + GetSecurityDescriptorDacl(psa->lpSecurityDescriptor, &b1, &pAcl, &b2); + GlobalFree(pAcl); + GlobalFree(psa->lpSecurityDescriptor); + GlobalFree(psa); +} #endif /* !DJGPP */ /* initialize the buffer package; called with no locks @@ -231,167 +231,170 @@ VOID FreeCacheFileSA(PSECURITY_ATTRIBUTES psa) */ long buf_Init(cm_buf_ops_t *opsp) { - static osi_once_t once; - cm_buf_t *bp; - long sectorSize; - thread_t phandle; + static osi_once_t once; + cm_buf_t *bp; + long sectorSize; + thread_t phandle; #ifndef DJGPP - HANDLE hf, hm; - PSECURITY_ATTRIBUTES psa; + HANDLE hf, hm; + PSECURITY_ATTRIBUTES psa; #endif /* !DJGPP */ - long i; - unsigned long pid; - char *data; - long cs; + long i; + unsigned long pid; + char *data; + long cs; #ifndef DJGPP - /* Get system info; all we really want is the allocation granularity */ - GetSystemInfo(&sysInfo); + /* Get system info; all we really want is the allocation granularity */ + GetSystemInfo(&sysInfo); #endif /* !DJGPP */ - /* Have to be able to reserve a whole chunk */ - if (((buf_nbuffers - 3) * buf_bufferSize) < cm_chunkSize) - return CM_ERROR_TOOFEWBUFS; + /* Have to be able to reserve a whole chunk */ + if (((buf_nbuffers - 3) * buf_bufferSize) < cm_chunkSize) + return CM_ERROR_TOOFEWBUFS; - /* recall for callouts */ - cm_buf_opsp = opsp; + /* recall for callouts */ + cm_buf_opsp = opsp; - if (osi_Once(&once)) { - /* initialize global locks */ - lock_InitializeRWLock(&buf_globalLock, "Global buffer lock"); + if (osi_Once(&once)) { + /* initialize global locks */ + lock_InitializeRWLock(&buf_globalLock, "Global buffer lock"); #ifndef DJGPP - /* - * Cache file mapping constrained by - * system allocation granularity; - * round up, assuming granularity is a power of two - */ - cs = buf_nbuffers * buf_bufferSize; - cs = (cs + (sysInfo.dwAllocationGranularity - 1)) - & ~(sysInfo.dwAllocationGranularity - 1); - if (cs != buf_nbuffers * buf_bufferSize) { - buf_nbuffers = cs / buf_bufferSize; - afsi_log("Cache size rounded up to %d buffers", - buf_nbuffers); - } + /* + * Cache file mapping constrained by + * system allocation granularity; + * round up, assuming granularity is a power of two + */ + cs = buf_nbuffers * buf_bufferSize; + cs = (cs + (sysInfo.dwAllocationGranularity - 1)) + & ~(sysInfo.dwAllocationGranularity - 1); + if (cs != buf_nbuffers * buf_bufferSize) { + buf_nbuffers = cs / buf_bufferSize; + afsi_log("Cache size rounded up to %d buffers", + buf_nbuffers); + } #endif /* !DJGPP */ - /* remember this for those who want to reset it */ - buf_nOrigBuffers = buf_nbuffers; + /* remember this for those who want to reset it */ + buf_nOrigBuffers = buf_nbuffers; - /* lower hash size to a prime number */ - buf_hashSize = osi_PrimeLessThan(buf_hashSize); + /* lower hash size to a prime number */ + buf_hashSize = osi_PrimeLessThan(buf_hashSize); - /* create hash table */ - buf_hashTablepp = malloc(buf_hashSize * sizeof(cm_buf_t *)); - memset((void *)buf_hashTablepp, 0, - buf_hashSize * sizeof(cm_buf_t *)); + /* create hash table */ + buf_hashTablepp = malloc(buf_hashSize * sizeof(cm_buf_t *)); + memset((void *)buf_hashTablepp, 0, + buf_hashSize * sizeof(cm_buf_t *)); - /* another hash table */ - buf_fileHashTablepp = malloc(buf_hashSize * sizeof(cm_buf_t *)); - memset((void *)buf_fileHashTablepp, 0, - buf_hashSize * sizeof(cm_buf_t *)); + /* another hash table */ + buf_fileHashTablepp = malloc(buf_hashSize * sizeof(cm_buf_t *)); + memset((void *)buf_fileHashTablepp, 0, + buf_hashSize * sizeof(cm_buf_t *)); - /* min value for which this works */ - sectorSize = 1; + /* min value for which this works */ + sectorSize = 1; #ifndef DJGPP - if(buf_cacheType == CM_BUF_CACHETYPE_FILE) { - /* Reserve buffer space by mapping cache file */ - psa = CreateCacheFileSA(); - hf = CreateFile(cm_CachePath, - GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, - psa, - OPEN_ALWAYS, - FILE_ATTRIBUTE_NORMAL, - NULL); - if (hf == INVALID_HANDLE_VALUE) { - afsi_log("create file error %d", GetLastError()); - return CM_ERROR_INVAL; - } - FreeCacheFileSA(psa); + if (buf_cacheType == CM_BUF_CACHETYPE_FILE) { + /* Reserve buffer space by mapping cache file */ + psa = CreateCacheFileSA(); + hf = CreateFile(cm_CachePath, + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + psa, + OPEN_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (hf == INVALID_HANDLE_VALUE) { + afsi_log("Error creating cache file \"%s\" error %d", + cm_CachePath, GetLastError()); + return CM_ERROR_INVAL; + } + FreeCacheFileSA(psa); } else { /* buf_cacheType == CM_BUF_CACHETYPE_VIRTUAL */ hf = INVALID_HANDLE_VALUE; } - CacheHandle = hf; - hm = CreateFileMapping(hf, - NULL, - PAGE_READWRITE, - 0, buf_nbuffers * buf_bufferSize, - NULL); - if (hm == NULL) { - if (GetLastError() == ERROR_DISK_FULL) { - afsi_log("Error creating cache file mapping: disk full"); - return CM_ERROR_TOOMANYBUFS; - } - return CM_ERROR_INVAL; - } - data = MapViewOfFile(hm, - FILE_MAP_ALL_ACCESS, - 0, 0, - buf_nbuffers * buf_bufferSize); - if (data == NULL) { - if(hf != INVALID_HANDLE_VALUE) CloseHandle(hf); - CloseHandle(hm); - return CM_ERROR_INVAL; - } - CloseHandle(hm); -#else - /* djgpp doesn't support memory mapped files */ - data = malloc(buf_nbuffers * buf_bufferSize); + CacheHandle = hf; + hm = CreateFileMapping(hf, + NULL, + PAGE_READWRITE, + 0, buf_nbuffers * buf_bufferSize, + NULL); + if (hm == NULL) { + if (GetLastError() == ERROR_DISK_FULL) { + afsi_log("Error creating cache file \"%s\" mapping: disk full", + cm_CachePath); + return CM_ERROR_TOOMANYBUFS; + } + return CM_ERROR_INVAL; + } + data = MapViewOfFile(hm, + FILE_MAP_ALL_ACCESS, + 0, 0, + buf_nbuffers * buf_bufferSize); + if (data == NULL) { + if (hf != INVALID_HANDLE_VALUE) + CloseHandle(hf); + CloseHandle(hm); + return CM_ERROR_INVAL; + } + CloseHandle(hm); +#else + /* djgpp doesn't support memory mapped files */ + data = malloc(buf_nbuffers * buf_bufferSize); #endif /* !DJGPP */ - /* create buffer headers and put in free list */ - bp = malloc(buf_nbuffers * sizeof(cm_buf_t)); - buf_allp = NULL; - for(i=0; iallp = buf_allp; - buf_allp = bp; - - osi_QAdd((osi_queue_t **)&buf_freeListp, &bp->q); - bp->flags |= CM_BUF_INLRU; - lock_InitializeMutex(&bp->mx, "Buffer mutex"); + /* thread on list of all buffers */ + bp->allp = buf_allp; + buf_allp = bp; - /* grab appropriate number of bytes from aligned zone */ - bp->datap = data; + osi_QAdd((osi_queue_t **)&buf_freeListp, &bp->q); + bp->flags |= CM_BUF_INLRU; + lock_InitializeMutex(&bp->mx, "Buffer mutex"); - /* setup last buffer pointer */ - if (i == 0) - buf_freeListEndp = bp; + /* grab appropriate number of bytes from aligned zone */ + bp->datap = data; - /* next */ - bp++; - data += buf_bufferSize; - } - - /* none reserved at first */ - buf_reservedBufs = 0; - - /* just for safety's sake */ - buf_maxReservedBufs = buf_nbuffers - 3; - - /* init the buffer trace log */ - buf_logp = osi_LogCreate("buffer", 10); + /* setup last buffer pointer */ + if (i == 0) + buf_freeListEndp = bp; - osi_EndOnce(&once); - - /* and create the incr-syncer */ - phandle = thrd_Create(0, 0, - (ThreadFunc) buf_IncrSyncer, 0, 0, &pid, - "buf_IncrSyncer"); + /* next */ + bp++; + data += buf_bufferSize; + } + + /* none reserved at first */ + buf_reservedBufs = 0; + + /* just for safety's sake */ + buf_maxReservedBufs = buf_nbuffers - 3; + + /* init the buffer trace log */ + buf_logp = osi_LogCreate("buffer", 10); - osi_assertx(phandle != NULL, "buf: can't create incremental sync proc"); + osi_EndOnce(&once); + + /* and create the incr-syncer */ + phandle = thrd_Create(0, 0, + (ThreadFunc) buf_IncrSyncer, 0, 0, &pid, + "buf_IncrSyncer"); + + osi_assertx(phandle != NULL, "buf: can't create incremental sync proc"); #ifndef DJGPP - CloseHandle(phandle); + CloseHandle(phandle); #endif /* !DJGPP */ - } + } - return 0; + return 0; } /* add nbuffers to the buffer pool, if possible. @@ -399,12 +402,12 @@ long buf_Init(cm_buf_ops_t *opsp) */ long buf_AddBuffers(long nbuffers) { - cm_buf_t *bp; - int i; - char *data; + cm_buf_t *bp; + int i; + char *data; #ifndef DJGPP - HANDLE hm; - long cs; + HANDLE hm; + long cs; afsi_log("%d buffers being added to the existing cache of size %d", nbuffers, buf_nbuffers); @@ -418,73 +421,73 @@ long buf_AddBuffers(long nbuffers) return CM_ERROR_INVAL; } - /* - * Cache file mapping constrained by - * system allocation granularity; - * round up, assuming granularity is a power of two; - * assume existing cache size is already rounded - */ - cs = nbuffers * buf_bufferSize; - cs = (cs + (sysInfo.dwAllocationGranularity - 1)) - & ~(sysInfo.dwAllocationGranularity - 1); - if (cs != nbuffers * buf_bufferSize) { - nbuffers = cs / buf_bufferSize; - } - - /* Reserve additional buffer space by remapping cache file */ - hm = CreateFileMapping(CacheHandle, - NULL, - PAGE_READWRITE, - 0, (buf_nbuffers + nbuffers) * buf_bufferSize, - NULL); - if (hm == NULL) { - if (GetLastError() == ERROR_DISK_FULL) - return CM_ERROR_TOOMANYBUFS; - else - return CM_ERROR_INVAL; - } - data = MapViewOfFile(hm, - FILE_MAP_ALL_ACCESS, - 0, buf_nbuffers * buf_bufferSize, - nbuffers * buf_bufferSize); - if (data == NULL) { - CloseHandle(hm); - return CM_ERROR_INVAL; - } - CloseHandle(hm); + /* + * Cache file mapping constrained by + * system allocation granularity; + * round up, assuming granularity is a power of two; + * assume existing cache size is already rounded + */ + cs = nbuffers * buf_bufferSize; + cs = (cs + (sysInfo.dwAllocationGranularity - 1)) + & ~(sysInfo.dwAllocationGranularity - 1); + if (cs != nbuffers * buf_bufferSize) { + nbuffers = cs / buf_bufferSize; + } + + /* Reserve additional buffer space by remapping cache file */ + hm = CreateFileMapping(CacheHandle, + NULL, + PAGE_READWRITE, + 0, (buf_nbuffers + nbuffers) * buf_bufferSize, + NULL); + if (hm == NULL) { + if (GetLastError() == ERROR_DISK_FULL) + return CM_ERROR_TOOMANYBUFS; + else + return CM_ERROR_INVAL; + } + data = MapViewOfFile(hm, + FILE_MAP_ALL_ACCESS, + 0, buf_nbuffers * buf_bufferSize, + nbuffers * buf_bufferSize); + if (data == NULL) { + CloseHandle(hm); + return CM_ERROR_INVAL; + } + CloseHandle(hm); #else - data = malloc(buf_nbuffers * buf_bufferSize); + data = malloc(buf_nbuffers * buf_bufferSize); #endif /* DJGPP */ - /* Create buffer headers and put in free list */ - bp = malloc(nbuffers * sizeof(*bp)); + /* Create buffer headers and put in free list */ + bp = malloc(nbuffers * sizeof(*bp)); - for(i=0; imx, "cm_buf_t"); + lock_InitializeMutex(&bp->mx, "cm_buf_t"); - /* grab appropriate number of bytes from aligned zone */ - bp->datap = data; + /* grab appropriate number of bytes from aligned zone */ + bp->datap = data; - bp->flags |= CM_BUF_INLRU; - - lock_ObtainWrite(&buf_globalLock); - /* note that buf_allp chain is covered by buf_globalLock now */ - bp->allp = buf_allp; - buf_allp = bp; - osi_QAdd((osi_queue_t **) &buf_freeListp, &bp->q); - if (!buf_freeListEndp) buf_freeListEndp = bp; - buf_nbuffers++; - lock_ReleaseWrite(&buf_globalLock); + bp->flags |= CM_BUF_INLRU; + + lock_ObtainWrite(&buf_globalLock); + /* note that buf_allp chain is covered by buf_globalLock now */ + bp->allp = buf_allp; + buf_allp = bp; + osi_QAdd((osi_queue_t **) &buf_freeListp, &bp->q); + if (!buf_freeListEndp) buf_freeListEndp = bp; + buf_nbuffers++; + lock_ReleaseWrite(&buf_globalLock); - bp++; - data += buf_bufferSize; + bp++; + data += buf_bufferSize; - } /* for loop over all buffers */ + } /* for loop over all buffers */ - return 0; -} + return 0; +} /* interface to set the number of buffers to an exact figure. * Called with no locks held. @@ -495,8 +498,8 @@ long buf_SetNBuffers(long nbuffers) return CM_ERROR_INVAL; if (nbuffers == buf_nbuffers) return 0; - else if (nbuffers > buf_nbuffers) - return buf_AddBuffers(nbuffers - buf_nbuffers); + else if (nbuffers > buf_nbuffers) + return buf_AddBuffers(nbuffers - buf_nbuffers); else return CM_ERROR_INVAL; } @@ -504,9 +507,9 @@ long buf_SetNBuffers(long nbuffers) /* release a buffer. Buffer must be referenced, but unlocked. */ void buf_Release(cm_buf_t *bp) { - lock_ObtainWrite(&buf_globalLock); - buf_LockedRelease(bp); - lock_ReleaseWrite(&buf_globalLock); + lock_ObtainWrite(&buf_globalLock); + buf_LockedRelease(bp); + lock_ReleaseWrite(&buf_globalLock); } /* wait for reading or writing to clear; called with write-locked @@ -514,10 +517,10 @@ void buf_Release(cm_buf_t *bp) */ void buf_WaitIO(cm_buf_t *bp) { - while (1) { - /* if no IO is happening, we're done */ - if (!(bp->flags & (CM_BUF_READING | CM_BUF_WRITING))) - break; + while (1) { + /* if no IO is happening, we're done */ + if (!(bp->flags & (CM_BUF_READING | CM_BUF_WRITING))) + break; /* otherwise I/O is happening, but some other thread is waiting for * the I/O already. Wait for that guy to figure out what happened, @@ -536,7 +539,7 @@ void buf_WaitIO(cm_buf_t *bp) * the I/O to complete. Do so. */ if (bp->flags & CM_BUF_WAITING) { - bp->flags &= ~CM_BUF_WAITING; + bp->flags &= ~CM_BUF_WAITING; osi_Wakeup((long) bp); } osi_Log1(buf_logp, "WaitIO finished wait for bp 0x%x", (long) bp); @@ -545,40 +548,40 @@ void buf_WaitIO(cm_buf_t *bp) /* code to drop reference count while holding buf_globalLock */ void buf_LockedRelease(cm_buf_t *bp) { - /* ensure that we're in the LRU queue if our ref count is 0 */ - osi_assert(bp->refCount > 0); - if (--bp->refCount == 0) { - if (!(bp->flags & CM_BUF_INLRU)) { - osi_QAdd((osi_queue_t **) &buf_freeListp, &bp->q); - - /* watch for transition from empty to one element */ - if (!buf_freeListEndp) - buf_freeListEndp = buf_freeListp; - bp->flags |= CM_BUF_INLRU; - } + /* ensure that we're in the LRU queue if our ref count is 0 */ + osi_assert(bp->refCount > 0); + if (--bp->refCount == 0) { + if (!(bp->flags & CM_BUF_INLRU)) { + osi_QAdd((osi_queue_t **) &buf_freeListp, &bp->q); + + /* watch for transition from empty to one element */ + if (!buf_freeListEndp) + buf_freeListEndp = buf_freeListp; + bp->flags |= CM_BUF_INLRU; } -} + } +} /* find a buffer, if any, for a particular file ID and offset. Assumes * that buf_globalLock is write locked when called. */ cm_buf_t *buf_LockedFind(struct cm_scache *scp, osi_hyper_t *offsetp) { - long i; - cm_buf_t *bp; - - i = BUF_HASH(&scp->fid, offsetp); - for(bp = buf_hashTablepp[i]; bp; bp=bp->hashp) { - if (cm_FidCmp(&scp->fid, &bp->fid) == 0 - && offsetp->LowPart == bp->offset.LowPart - && offsetp->HighPart == bp->offset.HighPart) { - bp->refCount++; - break; - } + long i; + cm_buf_t *bp; + + i = BUF_HASH(&scp->fid, offsetp); + for(bp = buf_hashTablepp[i]; bp; bp=bp->hashp) { + if (cm_FidCmp(&scp->fid, &bp->fid) == 0 + && offsetp->LowPart == bp->offset.LowPart + && offsetp->HighPart == bp->offset.HighPart) { + bp->refCount++; + break; } + } - /* return whatever we found, if anything */ - return bp; + /* return whatever we found, if anything */ + return bp; } /* find a buffer with offset *offsetp for vnode *scp. Called @@ -586,14 +589,14 @@ cm_buf_t *buf_LockedFind(struct cm_scache *scp, osi_hyper_t *offsetp) */ cm_buf_t *buf_Find(struct cm_scache *scp, osi_hyper_t *offsetp) { - cm_buf_t *bp; + cm_buf_t *bp; - lock_ObtainWrite(&buf_globalLock); - bp = buf_LockedFind(scp, offsetp); - lock_ReleaseWrite(&buf_globalLock); + lock_ObtainWrite(&buf_globalLock); + bp = buf_LockedFind(scp, offsetp); + lock_ReleaseWrite(&buf_globalLock); - return bp; -} + return bp; +} /* start cleaning I/O on this buffer. Buffer must be write locked, and is returned * write-locked. @@ -604,37 +607,38 @@ cm_buf_t *buf_Find(struct cm_scache *scp, osi_hyper_t *offsetp) */ void buf_LockedCleanAsync(cm_buf_t *bp, cm_req_t *reqp) { - long code; + long code; - code = 0; - while ((bp->flags & (CM_BUF_WRITING | CM_BUF_DIRTY)) == CM_BUF_DIRTY) { - lock_ReleaseMutex(&bp->mx); + code = 0; + while ((bp->flags & (CM_BUF_WRITING | CM_BUF_DIRTY)) == CM_BUF_DIRTY) { + lock_ReleaseMutex(&bp->mx); - code = (*cm_buf_opsp->Writep)(&bp->fid, &bp->offset, - buf_bufferSize, 0, bp->userp, - reqp); + code = (*cm_buf_opsp->Writep)(&bp->fid, &bp->offset, + buf_bufferSize, 0, bp->userp, + reqp); - lock_ObtainMutex(&bp->mx); - if (code) break; + lock_ObtainMutex(&bp->mx); + if (code) + break; #ifdef DISKCACHE95 - /* Disk cache support */ - /* write buffer to disk cache (synchronous for now) */ - diskcache_Update(bp->dcp, bp->datap, buf_bufferSize, bp->dataVersion); + /* Disk cache support */ + /* write buffer to disk cache (synchronous for now) */ + diskcache_Update(bp->dcp, bp->datap, buf_bufferSize, bp->dataVersion); #endif /* DISKCACHE95 */ - }; + }; - /* do logging after call to GetLastError, or else */ - osi_Log2(buf_logp, "buf_CleanAsync starts I/O on 0x%x, done=%d", bp, code); + /* do logging after call to GetLastError, or else */ + osi_Log2(buf_logp, "buf_CleanAsync starts I/O on 0x%x, done=%d", bp, code); - /* if someone was waiting for the I/O that just completed or failed, - * wake them up. - */ - if (bp->flags & CM_BUF_WAITING) { - /* turn off flags and wakeup users */ - bp->flags &= ~CM_BUF_WAITING; - osi_Wakeup((long) bp); - } + /* if someone was waiting for the I/O that just completed or failed, + * wake them up. + */ + if (bp->flags & CM_BUF_WAITING) { + /* turn off flags and wakeup users */ + bp->flags &= ~CM_BUF_WAITING; + osi_Wakeup((long) bp); + } } /* Called with a zero-ref count buffer and with the buf_globalLock write locked. @@ -643,63 +647,63 @@ void buf_LockedCleanAsync(cm_buf_t *bp, cm_req_t *reqp) */ void buf_Recycle(cm_buf_t *bp) { - int i; - cm_buf_t **lbpp; - cm_buf_t *tbp; - cm_buf_t *prevBp, *nextBp; - - /* if we get here, we know that the buffer still has a 0 ref count, - * and that it is clean and has no currently pending I/O. This is - * the dude to return. - * Remember that as long as the ref count is 0, we know that we won't - * have any lock conflicts, so we can grab the buffer lock out of - * order in the locking hierarchy. - */ + int i; + cm_buf_t **lbpp; + cm_buf_t *tbp; + cm_buf_t *prevBp, *nextBp; + + /* if we get here, we know that the buffer still has a 0 ref count, + * and that it is clean and has no currently pending I/O. This is + * the dude to return. + * Remember that as long as the ref count is 0, we know that we won't + * have any lock conflicts, so we can grab the buffer lock out of + * order in the locking hierarchy. + */ osi_Log2( buf_logp, "buf_Recycle recycles 0x%x, off 0x%x", - bp, bp->offset.LowPart); + bp, bp->offset.LowPart); - osi_assert(bp->refCount == 0); - osi_assert(!(bp->flags & (CM_BUF_READING | CM_BUF_WRITING | CM_BUF_DIRTY))); - lock_AssertWrite(&buf_globalLock); + osi_assert(bp->refCount == 0); + osi_assert(!(bp->flags & (CM_BUF_READING | CM_BUF_WRITING | CM_BUF_DIRTY))); + lock_AssertWrite(&buf_globalLock); - if (bp->flags & CM_BUF_INHASH) { - /* Remove from hash */ + if (bp->flags & CM_BUF_INHASH) { + /* Remove from hash */ - i = BUF_HASH(&bp->fid, &bp->offset); - lbpp = &(buf_hashTablepp[i]); - for(tbp = *lbpp; tbp; lbpp = &tbp->hashp, tbp = *lbpp) { - if (tbp == bp) break; - } + i = BUF_HASH(&bp->fid, &bp->offset); + lbpp = &(buf_hashTablepp[i]); + for(tbp = *lbpp; tbp; lbpp = &tbp->hashp, tbp = *lbpp) { + if (tbp == bp) break; + } - /* we better find it */ - osi_assertx(tbp != NULL, "buf_GetNewLocked: hash table screwup"); + /* we better find it */ + osi_assertx(tbp != NULL, "buf_GetNewLocked: hash table screwup"); - *lbpp = bp->hashp; /* hash out */ + *lbpp = bp->hashp; /* hash out */ - /* Remove from file hash */ + /* Remove from file hash */ - i = BUF_FILEHASH(&bp->fid); - prevBp = bp->fileHashBackp; - nextBp = bp->fileHashp; - if (prevBp) - prevBp->fileHashp = nextBp; - else - buf_fileHashTablepp[i] = nextBp; - if (nextBp) - nextBp->fileHashBackp = prevBp; + i = BUF_FILEHASH(&bp->fid); + prevBp = bp->fileHashBackp; + nextBp = bp->fileHashp; + if (prevBp) + prevBp->fileHashp = nextBp; + else + buf_fileHashTablepp[i] = nextBp; + if (nextBp) + nextBp->fileHashBackp = prevBp; - bp->flags &= ~CM_BUF_INHASH; - } - - /* bump the soft reference counter now, to invalidate softRefs; no - * wakeup is required since people don't sleep waiting for this - * counter to change. - */ - bp->idCounter++; + bp->flags &= ~CM_BUF_INHASH; + } - /* make the fid unrecognizable */ - memset(&bp->fid, 0, sizeof(bp->fid)); -} + /* bump the soft reference counter now, to invalidate softRefs; no + * wakeup is required since people don't sleep waiting for this + * counter to change. + */ + bp->idCounter++; + + /* make the fid unrecognizable */ + memset(&bp->fid, 0, sizeof(bp->fid)); +} /* recycle a buffer, removing it from the free list, hashing in its new identity * and returning it write-locked so that no one can use it. Called without @@ -714,153 +718,154 @@ void buf_Recycle(cm_buf_t *bp) */ long buf_GetNewLocked(struct cm_scache *scp, osi_hyper_t *offsetp, cm_buf_t **bufpp) { - cm_buf_t *bp; /* buffer we're dealing with */ - cm_buf_t *nextBp; /* next buffer in file hash chain */ - long i; /* temp */ - cm_req_t req; - - cm_InitReq(&req); /* just in case */ - - while(1) { -retry: - lock_ObtainWrite(&buf_globalLock); - /* check to see if we lost the race */ - if (scp) { - if (bp = buf_LockedFind(scp, offsetp)) { - bp->refCount--; - lock_ReleaseWrite(&buf_globalLock); - return CM_BUF_EXISTS; - } - } - - /* for debugging, assert free list isn't empty, although we - * really should try waiting for a running tranasction to finish - * instead of this; or better, we should have a transaction - * throttler prevent us from entering this situation. - */ - osi_assertx(buf_freeListEndp != NULL, "buf_GetNewLocked: no free buffers"); + cm_buf_t *bp; /* buffer we're dealing with */ + cm_buf_t *nextBp; /* next buffer in file hash chain */ + long i; /* temp */ + cm_req_t req; - /* look at all buffers in free list, some of which may temp. - * have high refcounts and which then should be skipped, - * starting cleaning I/O for those which are dirty. If we find - * a clean buffer, we rehash it, lock it and return it. - */ - for(bp = buf_freeListEndp; bp; bp=(cm_buf_t *) osi_QPrev(&bp->q)) { - /* check to see if it really has zero ref count. This - * code can bump refcounts, at least, so it may not be - * zero. - */ - if (bp->refCount > 0) continue; - - /* we don't have to lock buffer itself, since the ref - * count is 0 and we know it will stay zero as long as - * we hold the global lock. - */ - - /* don't recycle someone in our own chunk */ - if (!cm_FidCmp(&bp->fid, &scp->fid) - && (bp->offset.LowPart & (-cm_chunkSize)) - == (offsetp->LowPart & (-cm_chunkSize))) - continue; - - /* if this page is being filled (!) or cleaned, see if - * the I/O has completed. If not, skip it, otherwise - * do the final processing for the I/O. - */ - if (bp->flags & (CM_BUF_READING | CM_BUF_WRITING)) { - /* probably shouldn't do this much work while - * holding the big lock? Watch for contention - * here. - */ - continue; - } - - if (bp->flags & CM_BUF_DIRTY) { - /* if the buffer is dirty, start cleaning it and - * move on to the next buffer. We do this with - * just the lock required to minimize contention - * on the big lock. - */ - bp->refCount++; - lock_ReleaseWrite(&buf_globalLock); - - /* grab required lock and clean; this only - * starts the I/O. By the time we're back, - * it'll still be marked dirty, but it will also - * have the WRITING flag set, so we won't get - * back here. - */ - buf_CleanAsync(bp, &req); - - /* now put it back and go around again */ - buf_Release(bp); - goto retry; - } - - /* if we get here, we know that the buffer still has a 0 - * ref count, and that it is clean and has no currently - * pending I/O. This is the dude to return. - * Remember that as long as the ref count is 0, we know - * that we won't have any lock conflicts, so we can grab - * the buffer lock out of order in the locking hierarchy. - */ - buf_Recycle(bp); - - /* clean up junk flags */ - bp->flags &= ~(CM_BUF_EOF | CM_BUF_ERROR); - bp->dataVersion = -1; /* unknown so far */ - - /* now hash in as our new buffer, and give it the - * appropriate label, if requested. - */ - if (scp) { - bp->flags |= CM_BUF_INHASH; - bp->fid = scp->fid; - bp->offset = *offsetp; - i = BUF_HASH(&scp->fid, offsetp); - bp->hashp = buf_hashTablepp[i]; - buf_hashTablepp[i] = bp; - i = BUF_FILEHASH(&scp->fid); - nextBp = buf_fileHashTablepp[i]; - bp->fileHashp = nextBp; - bp->fileHashBackp = NULL; - if (nextBp) - nextBp->fileHashBackp = bp; - buf_fileHashTablepp[i] = bp; - } + cm_InitReq(&req); /* just in case */ + + while(1) { + retry: + lock_ObtainWrite(&buf_globalLock); + /* check to see if we lost the race */ + if (scp) { + if (bp = buf_LockedFind(scp, offsetp)) { + bp->refCount--; + lock_ReleaseWrite(&buf_globalLock); + return CM_BUF_EXISTS; + } + } + + /* for debugging, assert free list isn't empty, although we + * really should try waiting for a running tranasction to finish + * instead of this; or better, we should have a transaction + * throttler prevent us from entering this situation. + */ + osi_assertx(buf_freeListEndp != NULL, "buf_GetNewLocked: no free buffers"); + + /* look at all buffers in free list, some of which may temp. + * have high refcounts and which then should be skipped, + * starting cleaning I/O for those which are dirty. If we find + * a clean buffer, we rehash it, lock it and return it. + */ + for(bp = buf_freeListEndp; bp; bp=(cm_buf_t *) osi_QPrev(&bp->q)) { + /* check to see if it really has zero ref count. This + * code can bump refcounts, at least, so it may not be + * zero. + */ + if (bp->refCount > 0) + continue; - /* prepare to return it. Start by giving it a good - * refcount */ - bp->refCount = 1; + /* we don't have to lock buffer itself, since the ref + * count is 0 and we know it will stay zero as long as + * we hold the global lock. + */ + + /* don't recycle someone in our own chunk */ + if (!cm_FidCmp(&bp->fid, &scp->fid) + && (bp->offset.LowPart & (-cm_chunkSize)) + == (offsetp->LowPart & (-cm_chunkSize))) + continue; + + /* if this page is being filled (!) or cleaned, see if + * the I/O has completed. If not, skip it, otherwise + * do the final processing for the I/O. + */ + if (bp->flags & (CM_BUF_READING | CM_BUF_WRITING)) { + /* probably shouldn't do this much work while + * holding the big lock? Watch for contention + * here. + */ + continue; + } - /* and since it has a non-zero ref count, we should move - * it from the lru queue. It better be still there, - * since we've held the global (big) lock since we found - * it there. - */ - osi_assertx(bp->flags & CM_BUF_INLRU, - "buf_GetNewLocked: LRU screwup"); - if (buf_freeListEndp == bp) { - /* we're the last guy in this queue, so maintain it */ - buf_freeListEndp = (cm_buf_t *) osi_QPrev(&bp->q); - } - osi_QRemove((osi_queue_t **) &buf_freeListp, &bp->q); - bp->flags &= ~CM_BUF_INLRU; + if (bp->flags & CM_BUF_DIRTY) { + /* if the buffer is dirty, start cleaning it and + * move on to the next buffer. We do this with + * just the lock required to minimize contention + * on the big lock. + */ + bp->refCount++; + lock_ReleaseWrite(&buf_globalLock); + + /* grab required lock and clean; this only + * starts the I/O. By the time we're back, + * it'll still be marked dirty, but it will also + * have the WRITING flag set, so we won't get + * back here. + */ + buf_CleanAsync(bp, &req); + + /* now put it back and go around again */ + buf_Release(bp); + goto retry; + } + + /* if we get here, we know that the buffer still has a 0 + * ref count, and that it is clean and has no currently + * pending I/O. This is the dude to return. + * Remember that as long as the ref count is 0, we know + * that we won't have any lock conflicts, so we can grab + * the buffer lock out of order in the locking hierarchy. + */ + buf_Recycle(bp); + + /* clean up junk flags */ + bp->flags &= ~(CM_BUF_EOF | CM_BUF_ERROR); + bp->dataVersion = -1; /* unknown so far */ + + /* now hash in as our new buffer, and give it the + * appropriate label, if requested. + */ + if (scp) { + bp->flags |= CM_BUF_INHASH; + bp->fid = scp->fid; + bp->offset = *offsetp; + i = BUF_HASH(&scp->fid, offsetp); + bp->hashp = buf_hashTablepp[i]; + buf_hashTablepp[i] = bp; + i = BUF_FILEHASH(&scp->fid); + nextBp = buf_fileHashTablepp[i]; + bp->fileHashp = nextBp; + bp->fileHashBackp = NULL; + if (nextBp) + nextBp->fileHashBackp = bp; + buf_fileHashTablepp[i] = bp; + } + + /* prepare to return it. Start by giving it a good + * refcount */ + bp->refCount = 1; - /* finally, grab the mutex so that people don't use it - * before the caller fills it with data. Again, no one - * should have been able to get to this dude to lock it. - */ - osi_assertx(lock_TryMutex(&bp->mx), - "buf_GetNewLocked: TryMutex failed"); - - lock_ReleaseWrite(&buf_globalLock); - *bufpp = bp; - return 0; - } /* for all buffers in lru queue */ - lock_ReleaseWrite(&buf_globalLock); - } /* while loop over everything */ - /* not reached */ + /* and since it has a non-zero ref count, we should move + * it from the lru queue. It better be still there, + * since we've held the global (big) lock since we found + * it there. + */ + osi_assertx(bp->flags & CM_BUF_INLRU, + "buf_GetNewLocked: LRU screwup"); + if (buf_freeListEndp == bp) { + /* we're the last guy in this queue, so maintain it */ + buf_freeListEndp = (cm_buf_t *) osi_QPrev(&bp->q); + } + osi_QRemove((osi_queue_t **) &buf_freeListp, &bp->q); + bp->flags &= ~CM_BUF_INLRU; + + /* finally, grab the mutex so that people don't use it + * before the caller fills it with data. Again, no one + * should have been able to get to this dude to lock it. + */ + osi_assertx(lock_TryMutex(&bp->mx), + "buf_GetNewLocked: TryMutex failed"); + + lock_ReleaseWrite(&buf_globalLock); + *bufpp = bp; + return 0; + } /* for all buffers in lru queue */ + lock_ReleaseWrite(&buf_globalLock); + } /* while loop over everything */ + /* not reached */ } /* the proc */ /* get a page, returning it held but unlocked. Doesn't fill in the page @@ -868,185 +873,189 @@ retry: */ long buf_GetNew(struct cm_scache *scp, osi_hyper_t *offsetp, cm_buf_t **bufpp) { - cm_buf_t *bp; - long code; - osi_hyper_t pageOffset; - int created; - - created = 0; - pageOffset.HighPart = offsetp->HighPart; - pageOffset.LowPart = offsetp->LowPart & ~(buf_bufferSize-1); - while (1) { - lock_ObtainWrite(&buf_globalLock); - bp = buf_LockedFind(scp, &pageOffset); - lock_ReleaseWrite(&buf_globalLock); - if (bp) { - /* lock it and break out */ - lock_ObtainMutex(&bp->mx); - break; - } - - /* otherwise, we have to create a page */ - code = buf_GetNewLocked(scp, &pageOffset, &bp); + cm_buf_t *bp; + long code; + osi_hyper_t pageOffset; + int created; + + created = 0; + pageOffset.HighPart = offsetp->HighPart; + pageOffset.LowPart = offsetp->LowPart & ~(buf_bufferSize-1); + while (1) { + lock_ObtainWrite(&buf_globalLock); + bp = buf_LockedFind(scp, &pageOffset); + lock_ReleaseWrite(&buf_globalLock); + if (bp) { + /* lock it and break out */ + lock_ObtainMutex(&bp->mx); + break; + } - /* check if the buffer was created in a race condition branch. - * If so, go around so we can hold a reference to it. - */ - if (code == CM_BUF_EXISTS) continue; - - /* something else went wrong */ - if (code != 0) return code; - - /* otherwise, we have a locked buffer that we just created */ - created = 1; - break; - } /* big while loop */ - - /* wait for reads */ - if (bp->flags & CM_BUF_READING) - buf_WaitIO(bp); + /* otherwise, we have to create a page */ + code = buf_GetNewLocked(scp, &pageOffset, &bp); - /* once it has been read once, we can unlock it and return it, still - * with its refcount held. + /* check if the buffer was created in a race condition branch. + * If so, go around so we can hold a reference to it. */ - lock_ReleaseMutex(&bp->mx); - *bufpp = bp; - osi_Log3(buf_logp, "buf_GetNew returning bp 0x%x for file 0x%x, offset 0x%x", - bp, (long) scp, offsetp->LowPart); - return 0; + if (code == CM_BUF_EXISTS) + continue; + + /* something else went wrong */ + if (code != 0) + return code; + + /* otherwise, we have a locked buffer that we just created */ + created = 1; + break; + } /* big while loop */ + + /* wait for reads */ + if (bp->flags & CM_BUF_READING) + buf_WaitIO(bp); + + /* once it has been read once, we can unlock it and return it, still + * with its refcount held. + */ + lock_ReleaseMutex(&bp->mx); + *bufpp = bp; + osi_Log3(buf_logp, "buf_GetNew returning bp 0x%x for file 0x%x, offset 0x%x", + bp, (long) scp, offsetp->LowPart); + return 0; } /* get a page, returning it held but unlocked. Make sure it is complete */ long buf_Get(struct cm_scache *scp, osi_hyper_t *offsetp, cm_buf_t **bufpp) { - cm_buf_t *bp; - long code; - osi_hyper_t pageOffset; - unsigned long tcount; - int created; + cm_buf_t *bp; + long code; + osi_hyper_t pageOffset; + unsigned long tcount; + int created; #ifdef DISKCACHE95 - cm_diskcache_t *dcp; + cm_diskcache_t *dcp; #endif /* DISKCACHE95 */ - created = 0; - pageOffset.HighPart = offsetp->HighPart; - pageOffset.LowPart = offsetp->LowPart & ~(buf_bufferSize-1); - while (1) { - lock_ObtainWrite(&buf_globalLock); - bp = buf_LockedFind(scp, &pageOffset); - lock_ReleaseWrite(&buf_globalLock); - if (bp) { - /* lock it and break out */ - lock_ObtainMutex(&bp->mx); - break; + created = 0; + pageOffset.HighPart = offsetp->HighPart; + pageOffset.LowPart = offsetp->LowPart & ~(buf_bufferSize-1); + while (1) { + lock_ObtainWrite(&buf_globalLock); + bp = buf_LockedFind(scp, &pageOffset); + lock_ReleaseWrite(&buf_globalLock); + if (bp) { + /* lock it and break out */ + lock_ObtainMutex(&bp->mx); + break; #ifdef DISKCACHE95 - /* touch disk chunk to update LRU info */ - diskcache_Touch(bp->dcp); + /* touch disk chunk to update LRU info */ + diskcache_Touch(bp->dcp); #endif /* DISKCACHE95 */ - } - - /* otherwise, we have to create a page */ - code = buf_GetNewLocked(scp, &pageOffset, &bp); + } - /* check if the buffer was created in a race condition branch. - * If so, go around so we can hold a reference to it. - */ - if (code == CM_BUF_EXISTS) continue; - - /* something else went wrong */ - if (code != 0) return code; - - /* otherwise, we have a locked buffer that we just created */ - created = 1; - break; - } /* big while loop */ - - /* if we get here, we have a locked buffer that may have just been - * created, in which case it needs to be filled with data. + /* otherwise, we have to create a page */ + code = buf_GetNewLocked(scp, &pageOffset, &bp); + + /* check if the buffer was created in a race condition branch. + * If so, go around so we can hold a reference to it. */ - if (created) { - /* load the page; freshly created pages should be idle */ - osi_assert(!(bp->flags & (CM_BUF_READING | CM_BUF_WRITING))); + if (code == CM_BUF_EXISTS) + continue; + + /* something else went wrong */ + if (code != 0) + return code; + + /* otherwise, we have a locked buffer that we just created */ + created = 1; + break; + } /* big while loop */ + + /* if we get here, we have a locked buffer that may have just been + * created, in which case it needs to be filled with data. + */ + if (created) { + /* load the page; freshly created pages should be idle */ + osi_assert(!(bp->flags & (CM_BUF_READING | CM_BUF_WRITING))); - /* setup offset, event */ + /* setup offset, event */ #ifndef DJGPP /* doesn't seem to be used */ - bp->over.Offset = bp->offset.LowPart; - bp->over.OffsetHigh = bp->offset.HighPart; + bp->over.Offset = bp->offset.LowPart; + bp->over.OffsetHigh = bp->offset.HighPart; #endif /* !DJGPP */ - /* start the I/O; may drop lock */ - bp->flags |= CM_BUF_READING; - code = (*cm_buf_opsp->Readp)(bp, buf_bufferSize, &tcount, NULL); + /* start the I/O; may drop lock */ + bp->flags |= CM_BUF_READING; + code = (*cm_buf_opsp->Readp)(bp, buf_bufferSize, &tcount, NULL); #ifdef DISKCACHE95 - code = diskcache_Get(&bp->fid, &bp->offset, bp->datap, buf_bufferSize, &bp->dataVersion, &tcount, &dcp); - bp->dcp = dcp; /* pointer to disk cache struct. */ + code = diskcache_Get(&bp->fid, &bp->offset, bp->datap, buf_bufferSize, &bp->dataVersion, &tcount, &dcp); + bp->dcp = dcp; /* pointer to disk cache struct. */ #endif /* DISKCACHE95 */ - if (code != 0) { - /* failure or queued */ + if (code != 0) { + /* failure or queued */ #ifndef DJGPP /* cm_bufRead always returns 0 */ - if (code != ERROR_IO_PENDING) { + if (code != ERROR_IO_PENDING) { #endif - bp->error = code; - bp->flags |= CM_BUF_ERROR; - bp->flags &= ~CM_BUF_READING; - if (bp->flags & CM_BUF_WAITING) { - bp->flags &= ~CM_BUF_WAITING; - osi_Wakeup((long) bp); - } - lock_ReleaseMutex(&bp->mx); - buf_Release(bp); - return code; + bp->error = code; + bp->flags |= CM_BUF_ERROR; + bp->flags &= ~CM_BUF_READING; + if (bp->flags & CM_BUF_WAITING) { + bp->flags &= ~CM_BUF_WAITING; + osi_Wakeup((long) bp); + } + lock_ReleaseMutex(&bp->mx); + buf_Release(bp); + return code; #ifndef DJGPP - } + } #endif - } else { - /* otherwise, I/O completed instantly and we're done, except - * for padding the xfr out with 0s and checking for EOF - */ - if (tcount < (unsigned long) buf_bufferSize) { - memset(bp->datap+tcount, 0, buf_bufferSize - tcount); - if (tcount == 0) - bp->flags |= CM_BUF_EOF; - } - bp->flags &= ~CM_BUF_READING; - if (bp->flags & CM_BUF_WAITING) { - bp->flags &= ~CM_BUF_WAITING; - osi_Wakeup((long) bp); - } - } - - } /* if created */ - - /* wait for reads, either that which we started above, or that someone - * else started. We don't care if we return a buffer being cleaned. - */ - if (bp->flags & CM_BUF_READING) - buf_WaitIO(bp); + } else { + /* otherwise, I/O completed instantly and we're done, except + * for padding the xfr out with 0s and checking for EOF + */ + if (tcount < (unsigned long) buf_bufferSize) { + memset(bp->datap+tcount, 0, buf_bufferSize - tcount); + if (tcount == 0) + bp->flags |= CM_BUF_EOF; + } + bp->flags &= ~CM_BUF_READING; + if (bp->flags & CM_BUF_WAITING) { + bp->flags &= ~CM_BUF_WAITING; + osi_Wakeup((long) bp); + } + } - /* once it has been read once, we can unlock it and return it, still - * with its refcount held. - */ - lock_ReleaseMutex(&bp->mx); - *bufpp = bp; + } /* if created */ - /* now remove from queue; will be put in at the head (farthest from - * being recycled) when we're done in buf_Release. - */ - lock_ObtainWrite(&buf_globalLock); - if (bp->flags & CM_BUF_INLRU) { - if (buf_freeListEndp == bp) - buf_freeListEndp = (cm_buf_t *) osi_QPrev(&bp->q); - osi_QRemove((osi_queue_t **) &buf_freeListp, &bp->q); - bp->flags &= ~CM_BUF_INLRU; - } - lock_ReleaseWrite(&buf_globalLock); + /* wait for reads, either that which we started above, or that someone + * else started. We don't care if we return a buffer being cleaned. + */ + if (bp->flags & CM_BUF_READING) + buf_WaitIO(bp); - osi_Log3(buf_logp, "buf_Get returning bp 0x%x for file 0x%x, offset 0x%x", - bp, (long) scp, offsetp->LowPart); - return 0; + /* once it has been read once, we can unlock it and return it, still + * with its refcount held. + */ + lock_ReleaseMutex(&bp->mx); + *bufpp = bp; + + /* now remove from queue; will be put in at the head (farthest from + * being recycled) when we're done in buf_Release. + */ + lock_ObtainWrite(&buf_globalLock); + if (bp->flags & CM_BUF_INLRU) { + if (buf_freeListEndp == bp) + buf_freeListEndp = (cm_buf_t *) osi_QPrev(&bp->q); + osi_QRemove((osi_queue_t **) &buf_freeListp, &bp->q); + bp->flags &= ~CM_BUF_INLRU; + } + lock_ReleaseWrite(&buf_globalLock); + + osi_Log3(buf_logp, "buf_Get returning bp 0x%x for file 0x%x, offset 0x%x", + bp, (long) scp, offsetp->LowPart); + return 0; } /* count # of elements in the free list; @@ -1056,40 +1065,40 @@ long buf_Get(struct cm_scache *scp, osi_hyper_t *offsetp, cm_buf_t **bufpp) */ long buf_CountFreeList(void) { - long count; - cm_buf_t *bufp; - - count = 0; - lock_ObtainRead(&buf_globalLock); - for(bufp = buf_freeListp; bufp; bufp = (cm_buf_t *) osi_QNext(&bufp->q)) { - /* if the buffer doesn't have an identity, or if the buffer - * has been invalidate (by having its DV stomped upon), then - * count it as free, since it isn't really being utilized. - */ - if (!(bufp->flags & CM_BUF_INHASH) || bufp->dataVersion <= 0) - count++; - } - lock_ReleaseRead(&buf_globalLock); - return count; + long count; + cm_buf_t *bufp; + + count = 0; + lock_ObtainRead(&buf_globalLock); + for(bufp = buf_freeListp; bufp; bufp = (cm_buf_t *) osi_QNext(&bufp->q)) { + /* if the buffer doesn't have an identity, or if the buffer + * has been invalidate (by having its DV stomped upon), then + * count it as free, since it isn't really being utilized. + */ + if (!(bufp->flags & CM_BUF_INHASH) || bufp->dataVersion <= 0) + count++; + } + lock_ReleaseRead(&buf_globalLock); + return count; } /* clean a buffer synchronously */ void buf_CleanAsync(cm_buf_t *bp, cm_req_t *reqp) { - lock_ObtainMutex(&bp->mx); - buf_LockedCleanAsync(bp, reqp); - lock_ReleaseMutex(&bp->mx); -} + lock_ObtainMutex(&bp->mx); + buf_LockedCleanAsync(bp, reqp); + lock_ReleaseMutex(&bp->mx); +} /* wait for a buffer's cleaning to finish */ void buf_CleanWait(cm_buf_t *bp) { - lock_ObtainMutex(&bp->mx); - if (bp->flags & CM_BUF_WRITING) { - buf_WaitIO(bp); - } - lock_ReleaseMutex(&bp->mx); -} + lock_ObtainMutex(&bp->mx); + if (bp->flags & CM_BUF_WRITING) { + buf_WaitIO(bp); + } + lock_ReleaseMutex(&bp->mx); +} /* set the dirty flag on a buffer, and set associated write-ahead log, * if there is one. Allow one to be added to a buffer, but not changed. @@ -1098,15 +1107,15 @@ void buf_CleanWait(cm_buf_t *bp) */ void buf_SetDirty(cm_buf_t *bp) { - osi_assert(bp->refCount > 0); + osi_assert(bp->refCount > 0); - osi_Log1(buf_logp, "buf_SetDirty 0x%x", bp); + osi_Log1(buf_logp, "buf_SetDirty 0x%x", bp); - /* set dirty bit */ - bp->flags |= CM_BUF_DIRTY; + /* set dirty bit */ + bp->flags |= CM_BUF_DIRTY; - /* and turn off EOF flag, since it has associated data now */ - bp->flags &= ~CM_BUF_EOF; + /* and turn off EOF flag, since it has associated data now */ + bp->flags &= ~CM_BUF_EOF; } /* clean all buffers, reset log pointers and invalidate all buffers. @@ -1131,84 +1140,84 @@ void buf_SetDirty(cm_buf_t *bp) */ long buf_CleanAndReset(void) { - long i; - cm_buf_t *bp; - cm_req_t req; - - lock_ObtainWrite(&buf_globalLock); - for(i=0; ihashp) { - bp->refCount++; - lock_ReleaseWrite(&buf_globalLock); - - /* now no locks are held; clean buffer and go on */ - cm_InitReq(&req); - buf_CleanAsync(bp, &req); - buf_CleanWait(bp); - - /* relock and release buffer */ - lock_ObtainWrite(&buf_globalLock); - buf_LockedRelease(bp); - } /* over one bucket */ - } /* for loop over all hash buckets */ - - /* release locks */ - lock_ReleaseWrite(&buf_globalLock); + long i; + cm_buf_t *bp; + cm_req_t req; - /* and we're done */ - return 0; -} + lock_ObtainWrite(&buf_globalLock); + for(i=0; ihashp) { + bp->refCount++; + lock_ReleaseWrite(&buf_globalLock); + + /* now no locks are held; clean buffer and go on */ + cm_InitReq(&req); + buf_CleanAsync(bp, &req); + buf_CleanWait(bp); + + /* relock and release buffer */ + lock_ObtainWrite(&buf_globalLock); + buf_LockedRelease(bp); + } /* over one bucket */ + } /* for loop over all hash buckets */ + + /* release locks */ + lock_ReleaseWrite(&buf_globalLock); + + /* and we're done */ + return 0; +} /* called without global lock being held, reserves buffers for callers * that need more than one held (not locked) at once. */ void buf_ReserveBuffers(long nbuffers) { - lock_ObtainWrite(&buf_globalLock); - while (1) { - if (buf_reservedBufs + nbuffers > buf_maxReservedBufs) { - buf_reserveWaiting = 1; - osi_Log1(buf_logp, "buf_ReserveBuffers waiting for %d bufs", nbuffers); - osi_SleepW((long) &buf_reservedBufs, &buf_globalLock); - lock_ObtainWrite(&buf_globalLock); - } - else { - buf_reservedBufs += nbuffers; - break; - } + lock_ObtainWrite(&buf_globalLock); + while (1) { + if (buf_reservedBufs + nbuffers > buf_maxReservedBufs) { + buf_reserveWaiting = 1; + osi_Log1(buf_logp, "buf_ReserveBuffers waiting for %d bufs", nbuffers); + osi_SleepW((long) &buf_reservedBufs, &buf_globalLock); + lock_ObtainWrite(&buf_globalLock); + } + else { + buf_reservedBufs += nbuffers; + break; } - lock_ReleaseWrite(&buf_globalLock); + } + lock_ReleaseWrite(&buf_globalLock); } int buf_TryReserveBuffers(long nbuffers) { - int code; - - lock_ObtainWrite(&buf_globalLock); - if (buf_reservedBufs + nbuffers > buf_maxReservedBufs) { - code = 0; - } - else { - buf_reservedBufs += nbuffers; - code = 1; - } - lock_ReleaseWrite(&buf_globalLock); - return code; -} + int code; + + lock_ObtainWrite(&buf_globalLock); + if (buf_reservedBufs + nbuffers > buf_maxReservedBufs) { + code = 0; + } + else { + buf_reservedBufs += nbuffers; + code = 1; + } + lock_ReleaseWrite(&buf_globalLock); + return code; +} /* called without global lock held, releases reservation held by * buf_ReserveBuffers. */ void buf_UnreserveBuffers(long nbuffers) { - lock_ObtainWrite(&buf_globalLock); - buf_reservedBufs -= nbuffers; - if (buf_reserveWaiting) { - buf_reserveWaiting = 0; - osi_Wakeup((long) &buf_reservedBufs); - } - lock_ReleaseWrite(&buf_globalLock); -} + lock_ObtainWrite(&buf_globalLock); + buf_reservedBufs -= nbuffers; + if (buf_reserveWaiting) { + buf_reserveWaiting = 0; + osi_Wakeup((long) &buf_reservedBufs); + } + lock_ReleaseWrite(&buf_globalLock); +} /* truncate the buffers past sizep, zeroing out the page, if we don't * end on a page boundary. @@ -1216,219 +1225,222 @@ void buf_UnreserveBuffers(long nbuffers) * Requires cm_bufCreateLock to be write locked. */ long buf_Truncate(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp, - osi_hyper_t *sizep) + osi_hyper_t *sizep) { - cm_buf_t *bufp; - cm_buf_t *nbufp; /* next buffer, if didRelease */ - osi_hyper_t bufEnd; - long code; - long bufferPos; - int didRelease; - long i; - - /* assert that cm_bufCreateLock is held in write mode */ - lock_AssertWrite(&scp->bufCreateLock); - - i = BUF_FILEHASH(&scp->fid); - - lock_ObtainWrite(&buf_globalLock); - bufp = buf_fileHashTablepp[i]; - if (bufp == NULL) { - lock_ReleaseWrite(&buf_globalLock); - return 0; - } - - bufp->refCount++; - lock_ReleaseWrite(&buf_globalLock); - for(; bufp; bufp = nbufp) { - didRelease = 0; - lock_ObtainMutex(&bufp->mx); - - bufEnd.HighPart = 0; - bufEnd.LowPart = buf_bufferSize; - bufEnd = LargeIntegerAdd(bufEnd, bufp->offset); - - if (cm_FidCmp(&bufp->fid, &scp->fid) == 0 && - LargeIntegerLessThan(*sizep, bufEnd)) { - buf_WaitIO(bufp); - } - lock_ObtainMutex(&scp->mx); + cm_buf_t *bufp; + cm_buf_t *nbufp; /* next buffer, if didRelease */ + osi_hyper_t bufEnd; + long code; + long bufferPos; + int didRelease; + long i; + + /* assert that cm_bufCreateLock is held in write mode */ + lock_AssertWrite(&scp->bufCreateLock); + + i = BUF_FILEHASH(&scp->fid); + + lock_ObtainWrite(&buf_globalLock); + bufp = buf_fileHashTablepp[i]; + if (bufp == NULL) { + lock_ReleaseWrite(&buf_globalLock); + return 0; + } + + bufp->refCount++; + lock_ReleaseWrite(&buf_globalLock); + for(; bufp; bufp = nbufp) { + didRelease = 0; + lock_ObtainMutex(&bufp->mx); + + bufEnd.HighPart = 0; + bufEnd.LowPart = buf_bufferSize; + bufEnd = LargeIntegerAdd(bufEnd, bufp->offset); + + if (cm_FidCmp(&bufp->fid, &scp->fid) == 0 && + LargeIntegerLessThan(*sizep, bufEnd)) { + buf_WaitIO(bufp); + } + lock_ObtainMutex(&scp->mx); - /* make sure we have a callback (so we have the right value for - * the length), and wait for it to be safe to do a truncate. - */ - code = cm_SyncOp(scp, bufp, userp, reqp, 0, - CM_SCACHESYNC_NEEDCALLBACK - | CM_SCACHESYNC_GETSTATUS - | CM_SCACHESYNC_SETSIZE - | CM_SCACHESYNC_BUFLOCKED); - /* if we succeeded in our locking, and this applies to the right - * file, and the truncate request overlaps the buffer either - * totally or partially, then do something. + /* make sure we have a callback (so we have the right value for + * the length), and wait for it to be safe to do a truncate. + */ + code = cm_SyncOp(scp, bufp, userp, reqp, 0, + CM_SCACHESYNC_NEEDCALLBACK + | CM_SCACHESYNC_GETSTATUS + | CM_SCACHESYNC_SETSIZE + | CM_SCACHESYNC_BUFLOCKED); + /* if we succeeded in our locking, and this applies to the right + * file, and the truncate request overlaps the buffer either + * totally or partially, then do something. + */ + if (code == 0 && cm_FidCmp(&bufp->fid, &scp->fid) == 0 + && LargeIntegerLessThan(*sizep, bufEnd)) { + + lock_ObtainWrite(&buf_globalLock); + + /* destroy the buffer, turning off its dirty bit, if + * we're truncating the whole buffer. Otherwise, set + * the dirty bit, and clear out the tail of the buffer + * if we just overlap some. + */ + if (LargeIntegerLessThanOrEqualTo(*sizep, bufp->offset)) { + /* truncating the entire page */ + bufp->flags &= ~CM_BUF_DIRTY; + bufp->dataVersion = -1; /* known bad */ + bufp->dirtyCounter++; + } + else { + /* don't set dirty, since dirty implies + * currently up-to-date. Don't need to do this, + * since we'll update the length anyway. + * + * Zero out remainder of the page, in case we + * seek and write past EOF, and make this data + * visible again. */ - if (code == 0 && cm_FidCmp(&bufp->fid, &scp->fid) == 0 - && LargeIntegerLessThan(*sizep, bufEnd)) { - - lock_ObtainWrite(&buf_globalLock); - - /* destroy the buffer, turning off its dirty bit, if - * we're truncating the whole buffer. Otherwise, set - * the dirty bit, and clear out the tail of the buffer - * if we just overlap some. - */ - if (LargeIntegerLessThanOrEqualTo(*sizep, bufp->offset)) { - /* truncating the entire page */ - bufp->flags &= ~CM_BUF_DIRTY; - bufp->dataVersion = -1; /* known bad */ - bufp->dirtyCounter++; - } - else { - /* don't set dirty, since dirty implies - * currently up-to-date. Don't need to do this, - * since we'll update the length anyway. - * - * Zero out remainder of the page, in case we - * seek and write past EOF, and make this data - * visible again. - */ - bufferPos = sizep->LowPart & (buf_bufferSize - 1); - osi_assert(bufferPos != 0); - memset(bufp->datap + bufferPos, 0, - buf_bufferSize - bufferPos); - } - - lock_ReleaseWrite(&buf_globalLock); - } + bufferPos = sizep->LowPart & (buf_bufferSize - 1); + osi_assert(bufferPos != 0); + memset(bufp->datap + bufferPos, 0, + buf_bufferSize - bufferPos); + } + + lock_ReleaseWrite(&buf_globalLock); + } - lock_ReleaseMutex(&scp->mx); - lock_ReleaseMutex(&bufp->mx); - if (!didRelease) { - lock_ObtainWrite(&buf_globalLock); - nbufp = bufp->fileHashp; - if (nbufp) nbufp->refCount++; - buf_LockedRelease(bufp); - lock_ReleaseWrite(&buf_globalLock); - } - - /* bail out early if we fail */ - if (code) { - /* at this point, nbufp is held; bufp has already been - * released. - */ - if (nbufp) buf_Release(nbufp); - return code; - } - } - - /* success */ - return 0; + lock_ReleaseMutex(&scp->mx); + lock_ReleaseMutex(&bufp->mx); + if (!didRelease) { + lock_ObtainWrite(&buf_globalLock); + nbufp = bufp->fileHashp; + if (nbufp) nbufp->refCount++; + buf_LockedRelease(bufp); + lock_ReleaseWrite(&buf_globalLock); + } + + /* bail out early if we fail */ + if (code) { + /* at this point, nbufp is held; bufp has already been + * released. + */ + if (nbufp) + buf_Release(nbufp); + return code; + } + } + + /* success */ + return 0; } long buf_FlushCleanPages(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp) { - long code; - cm_buf_t *bp; /* buffer we're hacking on */ - cm_buf_t *nbp; - int didRelease; - long i; - - i = BUF_FILEHASH(&scp->fid); - - code = 0; - lock_ObtainWrite(&buf_globalLock); - bp = buf_fileHashTablepp[i]; - if (bp) bp->refCount++; - lock_ReleaseWrite(&buf_globalLock); - for(; bp; bp = nbp) { - didRelease = 0; /* haven't released this buffer yet */ - - /* clean buffer synchronously */ - if (cm_FidCmp(&bp->fid, &scp->fid) == 0) { - lock_ObtainMutex(&bp->mx); - - /* start cleaning the buffer, and wait for it to finish */ - buf_LockedCleanAsync(bp, reqp); - buf_WaitIO(bp); - lock_ReleaseMutex(&bp->mx); - - code = (*cm_buf_opsp->Stabilizep)(scp, userp, reqp); - if (code) goto skip; - - lock_ObtainWrite(&buf_globalLock); - /* actually, we only know that buffer is clean if ref - * count is 1, since we don't have buffer itself locked. - */ - if (!(bp->flags & CM_BUF_DIRTY)) { - if (bp->refCount == 1) { /* bp is held above */ - buf_LockedRelease(bp); - nbp = bp->fileHashp; - if (nbp) nbp->refCount++; - didRelease = 1; - buf_Recycle(bp); - } - } - lock_ReleaseWrite(&buf_globalLock); - - (*cm_buf_opsp->Unstabilizep)(scp, userp); - } - -skip: - if (!didRelease) { - lock_ObtainWrite(&buf_globalLock); - if (nbp = bp->fileHashp) nbp->refCount++; - buf_LockedRelease(bp); - lock_ReleaseWrite(&buf_globalLock); - } - } /* for loop over a bunch of buffers */ - - /* done */ - return code; -} + long code; + cm_buf_t *bp; /* buffer we're hacking on */ + cm_buf_t *nbp; + int didRelease; + long i; + + i = BUF_FILEHASH(&scp->fid); + + code = 0; + lock_ObtainWrite(&buf_globalLock); + bp = buf_fileHashTablepp[i]; + if (bp) bp->refCount++; + lock_ReleaseWrite(&buf_globalLock); + for(; bp; bp = nbp) { + didRelease = 0; /* haven't released this buffer yet */ + + /* clean buffer synchronously */ + if (cm_FidCmp(&bp->fid, &scp->fid) == 0) { + lock_ObtainMutex(&bp->mx); + + /* start cleaning the buffer, and wait for it to finish */ + buf_LockedCleanAsync(bp, reqp); + buf_WaitIO(bp); + lock_ReleaseMutex(&bp->mx); + + code = (*cm_buf_opsp->Stabilizep)(scp, userp, reqp); + if (code) goto skip; + + lock_ObtainWrite(&buf_globalLock); + /* actually, we only know that buffer is clean if ref + * count is 1, since we don't have buffer itself locked. + */ + if (!(bp->flags & CM_BUF_DIRTY)) { + if (bp->refCount == 1) { /* bp is held above */ + buf_LockedRelease(bp); + nbp = bp->fileHashp; + if (nbp) nbp->refCount++; + didRelease = 1; + buf_Recycle(bp); + } + } + lock_ReleaseWrite(&buf_globalLock); + + (*cm_buf_opsp->Unstabilizep)(scp, userp); + } + + skip: + if (!didRelease) { + lock_ObtainWrite(&buf_globalLock); + if (nbp = bp->fileHashp) nbp->refCount++; + buf_LockedRelease(bp); + lock_ReleaseWrite(&buf_globalLock); + } + } /* for loop over a bunch of buffers */ + + /* done */ + return code; +} long buf_CleanVnode(struct cm_scache *scp, cm_user_t *userp, cm_req_t *reqp) { - long code; - cm_buf_t *bp; /* buffer we're hacking on */ + long code; + cm_buf_t *bp; /* buffer we're hacking on */ cm_buf_t *nbp; /* next one */ - long i; + long i; - i = BUF_FILEHASH(&scp->fid); + i = BUF_FILEHASH(&scp->fid); - code = 0; - lock_ObtainWrite(&buf_globalLock); + code = 0; + lock_ObtainWrite(&buf_globalLock); bp = buf_fileHashTablepp[i]; if (bp) bp->refCount++; lock_ReleaseWrite(&buf_globalLock); - for(; bp; bp = nbp) { - /* clean buffer synchronously */ - if (cm_FidCmp(&bp->fid, &scp->fid) == 0) { - if (userp) { + for(; bp; bp = nbp) { + /* clean buffer synchronously */ + if (cm_FidCmp(&bp->fid, &scp->fid) == 0) { + if (userp) { cm_HoldUser(userp); - lock_ObtainMutex(&bp->mx); - if (bp->userp) + lock_ObtainMutex(&bp->mx); + if (bp->userp) cm_ReleaseUser(bp->userp); bp->userp = userp; - lock_ReleaseMutex(&bp->mx); - } - buf_CleanAsync(bp, reqp); + lock_ReleaseMutex(&bp->mx); + } + buf_CleanAsync(bp, reqp); buf_CleanWait(bp); lock_ObtainMutex(&bp->mx); - if (bp->flags & CM_BUF_ERROR) { - if (code == 0 || code == -1) code = bp->error; - if (code == 0) code = -1; + if (bp->flags & CM_BUF_ERROR) { + if (code == 0 || code == -1) + code = bp->error; + if (code == 0) + code = -1; } lock_ReleaseMutex(&bp->mx); - } + } - lock_ObtainWrite(&buf_globalLock); - buf_LockedRelease(bp); + lock_ObtainWrite(&buf_globalLock); + buf_LockedRelease(bp); nbp = bp->fileHashp; if (nbp) nbp->refCount++; - lock_ReleaseWrite(&buf_globalLock); - } /* for loop over a bunch of buffers */ - + lock_ReleaseWrite(&buf_globalLock); + } /* for loop over a bunch of buffers */ + /* done */ - return code; + return code; } /* dump the contents of the buf_hashTablepp. */ @@ -1439,8 +1451,8 @@ int cm_DumpBufHashTable(FILE *outputFile, char *cookie) char output[1024]; int i; - if (buf_hashTablepp == NULL) - return -1; + if (buf_hashTablepp == NULL) + return -1; lock_ObtainRead(&buf_globalLock); diff --git a/src/WINNT/afsd/cm_buf.h b/src/WINNT/afsd/cm_buf.h index 8826e1d74..4ca977ad4 100644 --- a/src/WINNT/afsd/cm_buf.h +++ b/src/WINNT/afsd/cm_buf.h @@ -72,7 +72,7 @@ typedef struct cm_buf { */ struct cm_buf *allp; /* next in all list */ osi_mutex_t mx; /* mutex protecting structure except refcount */ - int refCount; /* reference count (buf_globalLock) */ + unsigned long refCount; /* reference count (buf_globalLock) */ long idCounter; /* counter for softrefs; bumped at each recycle */ long dirtyCounter; /* bumped at each dirty->clean transition */ #ifdef notdef diff --git a/src/WINNT/afsd/cm_callback.c b/src/WINNT/afsd/cm_callback.c index 950a2dbe7..14dac4286 100644 --- a/src/WINNT/afsd/cm_callback.c +++ b/src/WINNT/afsd/cm_callback.c @@ -70,22 +70,22 @@ cm_racingRevokes_t *cm_racingRevokesp; */ void cm_RecordRacingRevoke(cm_fid_t *fidp, long cancelFlags) { - cm_racingRevokes_t *rp; + cm_racingRevokes_t *rp; - lock_ObtainWrite(&cm_callbackLock); + lock_ObtainWrite(&cm_callbackLock); osi_Log3(afsd_logp, "RecordRacingRevoke Volume %d Flags %lX activeCalls %d", fidp->volume, cancelFlags, cm_activeCallbackGrantingCalls); - if (cm_activeCallbackGrantingCalls > 0) { - rp = malloc(sizeof(*rp)); - memset(rp, 0, sizeof(*rp)); - osi_QAdd((osi_queue_t **) &cm_racingRevokesp, &rp->q); - rp->flags |= (cancelFlags & CM_RACINGFLAG_ALL); - if (fidp) rp->fid = *fidp; - rp->callbackCount = ++cm_callbackCount; - } - lock_ReleaseWrite(&cm_callbackLock); + if (cm_activeCallbackGrantingCalls > 0) { + rp = malloc(sizeof(*rp)); + memset(rp, 0, sizeof(*rp)); + osi_QAdd((osi_queue_t **) &cm_racingRevokesp, &rp->q); + rp->flags |= (cancelFlags & CM_RACINGFLAG_ALL); + if (fidp) rp->fid = *fidp; + rp->callbackCount = ++cm_callbackCount; + } + lock_ReleaseWrite(&cm_callbackLock); } /* @@ -128,50 +128,50 @@ void cm_CallbackNotifyChange(cm_scache_t *scp) */ void cm_RevokeCallback(struct rx_call *callp, AFSFid *fidp) { - cm_fid_t tfid; - cm_scache_t *scp; - long hash; + cm_fid_t tfid; + cm_scache_t *scp; + long hash; - /* don't bother setting cell, since we won't be checking it (to aid - * in working with multi-homed servers: we don't know the cell if we - * don't recognize the IP address). - */ - tfid.cell = 0; - tfid.volume = fidp->Volume; - tfid.vnode = fidp->Vnode; - tfid.unique = fidp->Unique; - hash = CM_SCACHE_HASH(&tfid); + /* don't bother setting cell, since we won't be checking it (to aid + * in working with multi-homed servers: we don't know the cell if we + * don't recognize the IP address). + */ + tfid.cell = 0; + tfid.volume = fidp->Volume; + tfid.vnode = fidp->Vnode; + tfid.unique = fidp->Unique; + hash = CM_SCACHE_HASH(&tfid); osi_Log3(afsd_logp, "RevokeCallback vol %d vn %d un %d", - fidp->Volume, fidp->Vnode, fidp->Unique); + fidp->Volume, fidp->Vnode, fidp->Unique); - /* do this first, so that if we're executing a callback granting call - * at this moment, we kill it before it can be merged in. Otherwise, - * it could complete while we're doing the scan below, and get missed - * by both the scan and by this code. - */ - cm_RecordRacingRevoke(&tfid, 0); + /* do this first, so that if we're executing a callback granting call + * at this moment, we kill it before it can be merged in. Otherwise, + * it could complete while we're doing the scan below, and get missed + * by both the scan and by this code. + */ + cm_RecordRacingRevoke(&tfid, 0); - lock_ObtainWrite(&cm_scacheLock); - /* do all in the hash bucket, since we don't know how many we'll find with - * varying cells. - */ - for(scp = cm_hashTablep[hash]; scp; scp=scp->nextp) { - if (scp->fid.volume == tfid.volume && - scp->fid.vnode == tfid.vnode && - scp->fid.unique == tfid.unique) { - scp->refCount++; - lock_ReleaseWrite(&cm_scacheLock); + lock_ObtainWrite(&cm_scacheLock); + /* do all in the hash bucket, since we don't know how many we'll find with + * varying cells. + */ + for (scp = cm_hashTablep[hash]; scp; scp=scp->nextp) { + if (scp->fid.volume == tfid.volume && + scp->fid.vnode == tfid.vnode && + scp->fid.unique == tfid.unique) { + scp->refCount++; + lock_ReleaseWrite(&cm_scacheLock); osi_Log1(afsd_logp, "Discarding SCache scp %x", scp); - lock_ObtainMutex(&scp->mx); - cm_DiscardSCache(scp); - lock_ReleaseMutex(&scp->mx); - cm_CallbackNotifyChange(scp); - lock_ObtainWrite(&cm_scacheLock); - scp->refCount--; - } + lock_ObtainMutex(&scp->mx); + cm_DiscardSCache(scp); + lock_ReleaseMutex(&scp->mx); + cm_CallbackNotifyChange(scp); + lock_ObtainWrite(&cm_scacheLock); + scp->refCount--; } - lock_ReleaseWrite(&cm_scacheLock); + } + lock_ReleaseWrite(&cm_scacheLock); } /* called to revoke a volume callback, which is typically issued when a volume @@ -181,40 +181,40 @@ void cm_RevokeCallback(struct rx_call *callp, AFSFid *fidp) */ void cm_RevokeVolumeCallback(struct rx_call *callp, AFSFid *fidp) { - long hash; - cm_scache_t *scp; - cm_fid_t tfid; + long hash; + cm_scache_t *scp; + cm_fid_t tfid; osi_Log1(afsd_logp, "RevokeVolumeCallback %d", fidp->Volume); - /* do this first, so that if we're executing a callback granting call - * at this moment, we kill it before it can be merged in. Otherwise, - * it could complete while we're doing the scan below, and get missed - * by both the scan and by this code. - */ - tfid.cell = tfid.vnode = tfid.unique = 0; - tfid.volume = fidp->Volume; - cm_RecordRacingRevoke(&tfid, CM_RACINGFLAG_CANCELVOL); - - - lock_ObtainWrite(&cm_scacheLock); - for(hash = 0; hash < cm_hashTableSize; hash++) { - for(scp=cm_hashTablep[hash]; scp; scp=scp->nextp) { - if (scp->fid.volume == fidp->Volume) { - scp->refCount++; - lock_ReleaseWrite(&cm_scacheLock); - lock_ObtainMutex(&scp->mx); + /* do this first, so that if we're executing a callback granting call + * at this moment, we kill it before it can be merged in. Otherwise, + * it could complete while we're doing the scan below, and get missed + * by both the scan and by this code. + */ + tfid.cell = tfid.vnode = tfid.unique = 0; + tfid.volume = fidp->Volume; + cm_RecordRacingRevoke(&tfid, CM_RACINGFLAG_CANCELVOL); + + + lock_ObtainWrite(&cm_scacheLock); + for (hash = 0; hash < cm_hashTableSize; hash++) { + for(scp=cm_hashTablep[hash]; scp; scp=scp->nextp) { + if (scp->fid.volume == fidp->Volume) { + scp->refCount++; + lock_ReleaseWrite(&cm_scacheLock); + lock_ObtainMutex(&scp->mx); osi_Log1(afsd_logp, "Discarding SCache scp %x", scp); - cm_DiscardSCache(scp); - lock_ReleaseMutex(&scp->mx); - cm_CallbackNotifyChange(scp); - lock_ObtainWrite(&cm_scacheLock); - scp->refCount--; - } - } /* search one hash bucket */ - } /* search all hash buckets */ - - lock_ReleaseWrite(&cm_scacheLock); + cm_DiscardSCache(scp); + lock_ReleaseMutex(&scp->mx); + cm_CallbackNotifyChange(scp); + lock_ObtainWrite(&cm_scacheLock); + scp->refCount--; + } + } /* search one hash bucket */ + } /* search all hash buckets */ + + lock_ReleaseWrite(&cm_scacheLock); } /* handle incoming RPC callback breaking message. @@ -222,23 +222,23 @@ void cm_RevokeVolumeCallback(struct rx_call *callp, AFSFid *fidp) */ SRXAFSCB_CallBack(struct rx_call *callp, AFSCBFids *fidsArrayp, AFSCBs *cbsArrayp) { - int i; - AFSFid *tfidp; + int i; + AFSFid *tfidp; osi_Log0(afsd_logp, "SRXAFSCB_CallBack"); - for(i=0; i < (long) fidsArrayp->AFSCBFids_len; i++) { - tfidp = &fidsArrayp->AFSCBFids_val[i]; + for (i=0; i < (long) fidsArrayp->AFSCBFids_len; i++) { + tfidp = &fidsArrayp->AFSCBFids_val[i]; if (tfidp->Volume == 0) continue; /* means don't do anything */ - else if (tfidp->Vnode == 0) - cm_RevokeVolumeCallback(callp, tfidp); + else if (tfidp->Vnode == 0) + cm_RevokeVolumeCallback(callp, tfidp); else cm_RevokeCallback(callp, tfidp); - } + } - return 0; + return 0; } /* called with no locks by RPC system when a server indicates that it has never @@ -288,32 +288,33 @@ SRXAFSCB_InitCallBackState(struct rx_call *callp) * are "rare," hopefully this won't be a problem. */ lock_ObtainWrite(&cm_scacheLock); - for(hash = 0; hash < cm_hashTableSize; hash++) { - for(scp=cm_hashTablep[hash]; scp; scp=scp->nextp) { - scp->refCount++; - lock_ReleaseWrite(&cm_scacheLock); - lock_ObtainMutex(&scp->mx); - discarded = 0; - if (scp->cbServerp != NULL) { - /* we have a callback, now decide if we should clear it */ - if (scp->cbServerp == tsp || tsp == NULL) { + for (hash = 0; hash < cm_hashTableSize; hash++) { + for (scp=cm_hashTablep[hash]; scp; scp=scp->nextp) { + scp->refCount++; + lock_ReleaseWrite(&cm_scacheLock); + lock_ObtainMutex(&scp->mx); + discarded = 0; + if (scp->cbServerp != NULL) { + /* we have a callback, now decide if we should clear it */ + if (scp->cbServerp == tsp || tsp == NULL) { osi_Log1(afsd_logp, "Discarding SCache scp %x", scp); - cm_DiscardSCache(scp); - discarded = 1; - } - } - lock_ReleaseMutex(&scp->mx); - if (discarded) - cm_CallbackNotifyChange(scp); - lock_ObtainWrite(&cm_scacheLock); - scp->refCount--; - } /* search one hash bucket */ - } /* search all hash buckets */ + cm_DiscardSCache(scp); + discarded = 1; + } + } + lock_ReleaseMutex(&scp->mx); + if (discarded) + cm_CallbackNotifyChange(scp); + lock_ObtainWrite(&cm_scacheLock); + scp->refCount--; + } /* search one hash bucket */ + } /* search all hash buckets */ lock_ReleaseWrite(&cm_scacheLock); /* we're done with the server structure */ - if (tsp) cm_PutServer(tsp); + if (tsp) + cm_PutServer(tsp); } return 0; @@ -323,7 +324,7 @@ SRXAFSCB_InitCallBackState(struct rx_call *callp) SRXAFSCB_Probe(struct rx_call *callp) { osi_Log0(afsd_logp, "SRXAFSCB_Probe - not implemented"); - return 0; + return 0; } /* debug interface: not implemented */ @@ -337,67 +338,67 @@ SRXAFSCB_GetCE64(struct rx_call *callp, long index, AFSDBCacheEntry *cep) /* debug interface: not implemented */ SRXAFSCB_GetLock(struct rx_call *callp, long index, AFSDBLock *lockp) { - /* XXXX */ + /* XXXX */ osi_Log0(afsd_logp, "SRXAFSCB_GetLock - not implemented"); - return RXGEN_OPCODE; + return RXGEN_OPCODE; } /* debug interface: not implemented */ SRXAFSCB_GetCE(struct rx_call *callp, long index, AFSDBCacheEntry *cep) { - /* XXXX */ + /* XXXX */ osi_Log0(afsd_logp, "SRXAFSCB_GetCE - not implemented"); - return RXGEN_OPCODE; + return RXGEN_OPCODE; } /* debug interface: not implemented */ SRXAFSCB_XStatsVersion(struct rx_call *callp, long *vp) { - /* XXXX */ + /* XXXX */ osi_Log0(afsd_logp, "SRXAFSCB_XStatsVersion - not implemented"); - *vp = -1; - return RXGEN_OPCODE; + *vp = -1; + return RXGEN_OPCODE; } /* debug interface: not implemented */ SRXAFSCB_GetXStats(struct rx_call *callp, long cvn, long coln, long *srvp, long *timep, AFSCB_CollData *datap) { - /* XXXX */ + /* XXXX */ osi_Log0(afsd_logp, "SRXAFSCB_GetXStats - not implemented"); - return RXGEN_OPCODE; + return RXGEN_OPCODE; } /* debug interface: not implemented */ SRXAFSCB_InitCallBackState2(struct rx_call *callp, struct interfaceAddr* addr) { - /* XXXX */ + /* XXXX */ osi_Log0(afsd_logp, "SRXAFSCB_InitCallBackState2 - not implemented"); - return RXGEN_OPCODE; + return RXGEN_OPCODE; } /* debug interface: not implemented */ SRXAFSCB_WhoAreYou(struct rx_call *callp, struct interfaceAddr* addr) { - /* XXXX */ + /* XXXX */ osi_Log0(afsd_logp, "SRXAFSCB_WhoAreYou - not implemented"); - return RXGEN_OPCODE; + return RXGEN_OPCODE; } /* debug interface: not implemented */ SRXAFSCB_InitCallBackState3(struct rx_call *callp, afsUUID* serverUuid) { - /* XXXX */ + /* XXXX */ osi_Log0(afsd_logp, "SRXAFSCB_InitCallBackState3 - not implemented"); - return RXGEN_OPCODE; + return RXGEN_OPCODE; } /* debug interface: not implemented */ SRXAFSCB_ProbeUuid(struct rx_call *callp, afsUUID* clientUuid) { - /* XXXX */ + /* XXXX */ osi_Log0(afsd_logp, "SRXAFSCB_ProbeUuid - not implemented"); - return RXGEN_OPCODE; + return RXGEN_OPCODE; } /*------------------------------------------------------------------------ @@ -608,8 +609,8 @@ cacheConfig *config; /* called by afsd without any locks to initialize this module */ void cm_InitCallback(void) { - lock_InitializeRWLock(&cm_callbackLock, "cm_callbackLock"); - cm_activeCallbackGrantingCalls = 0; + lock_InitializeRWLock(&cm_callbackLock, "cm_callbackLock"); + cm_activeCallbackGrantingCalls = 0; } /* called with locked scp; tells us whether we've got a callback. @@ -633,7 +634,7 @@ int cm_HaveCallback(cm_scache_t *scp) // to be called because cm_GetCallback has some initialization work to do. // If cm_fakeDirCallback is 2, then it means that the fake directory is in // good shape and we simply return true, provided no change is detected. - int fdc, fgc; + int fdc, fgc; if (cm_freelanceEnabled && scp->fid.cell==AFS_FAKE_ROOT_CELL_ID && scp->fid.volume==AFS_FAKE_ROOT_VOL_ID) { @@ -691,12 +692,12 @@ int cm_HaveCallback(cm_scache_t *scp) */ void cm_StartCallbackGrantingCall(cm_scache_t *scp, cm_callbackRequest_t *cbrp) { - lock_ObtainWrite(&cm_callbackLock); - cbrp->callbackCount = cm_callbackCount; - cm_activeCallbackGrantingCalls++; - cbrp->startTime = osi_Time(); - cbrp->serverp = NULL; - lock_ReleaseWrite(&cm_callbackLock); + lock_ObtainWrite(&cm_callbackLock); + cbrp->callbackCount = cm_callbackCount; + cm_activeCallbackGrantingCalls++; + cbrp->startTime = osi_Time(); + cbrp->serverp = NULL; + lock_ReleaseWrite(&cm_callbackLock); } /* Called at the end of a callback-granting call, to remove the callback @@ -706,83 +707,83 @@ void cm_StartCallbackGrantingCall(cm_scache_t *scp, cm_callbackRequest_t *cbrp) * this locking hierarchy. */ void cm_EndCallbackGrantingCall(cm_scache_t *scp, cm_callbackRequest_t *cbrp, - AFSCallBack *cbp, long flags) + AFSCallBack *cbp, long flags) { - cm_racingRevokes_t *revp; /* where we are */ - cm_racingRevokes_t *nrevp; /* where we'll be next */ - int freeFlag; + cm_racingRevokes_t *revp; /* where we are */ + cm_racingRevokes_t *nrevp; /* where we'll be next */ + int freeFlag; cm_server_t * serverp = 0; - lock_ObtainWrite(&cm_callbackLock); - if (flags & CM_CALLBACK_MAINTAINCOUNT) { - osi_assert(cm_activeCallbackGrantingCalls > 0); - } - else { - osi_assert(cm_activeCallbackGrantingCalls-- > 0); - } + lock_ObtainWrite(&cm_callbackLock); + if (flags & CM_CALLBACK_MAINTAINCOUNT) { + osi_assert(cm_activeCallbackGrantingCalls > 0); + } + else { + osi_assert(cm_activeCallbackGrantingCalls-- > 0); + } if (cm_activeCallbackGrantingCalls == 0) freeFlag = 1; else freeFlag = 0; - /* record the callback; we'll clear it below if we really lose it */ + /* record the callback; we'll clear it below if we really lose it */ if (cbrp) { if (scp) { if (scp->cbServerp != cbrp->serverp) { serverp = scp->cbServerp; } - scp->cbServerp = cbrp->serverp; - scp->cbExpires = cbrp->startTime + cbp->ExpirationTime; + scp->cbServerp = cbrp->serverp; + scp->cbExpires = cbrp->startTime + cbp->ExpirationTime; } else { serverp = cbrp->serverp; } cbrp->serverp = NULL; - } + } - /* a callback was actually revoked during our granting call, so - * run down the list of revoked fids, looking for ours. - * If activeCallbackGrantingCalls is zero, free the elements, too. - * - * May need to go through entire list just to do the freeing. - */ - for(revp = cm_racingRevokesp; revp; revp = nrevp) { - nrevp = (cm_racingRevokes_t *) osi_QNext(&revp->q); - /* if this callback came in later than when we started the - * callback-granting call, and if this fid is the right fid, - * then clear the callback. - */ + /* a callback was actually revoked during our granting call, so + * run down the list of revoked fids, looking for ours. + * If activeCallbackGrantingCalls is zero, free the elements, too. + * + * May need to go through entire list just to do the freeing. + */ + for (revp = cm_racingRevokesp; revp; revp = nrevp) { + nrevp = (cm_racingRevokes_t *) osi_QNext(&revp->q); + /* if this callback came in later than when we started the + * callback-granting call, and if this fid is the right fid, + * then clear the callback. + */ if (scp && cbrp && cbrp->callbackCount != cm_callbackCount - && revp->callbackCount > cbrp->callbackCount + && revp->callbackCount > cbrp->callbackCount && (( scp->fid.volume == revp->fid.volume && - scp->fid.vnode == revp->fid.vnode && - scp->fid.unique == revp->fid.unique) - || - ((revp->flags & CM_RACINGFLAG_CANCELVOL) && - scp->fid.volume == revp->fid.volume) - || - (revp->flags & CM_RACINGFLAG_CANCELALL))) { - /* this one matches */ - osi_Log4(afsd_logp, - "Racing revoke scp %x old cbc %d rev cbc %d cur cbc %d", - scp, - cbrp->callbackCount, revp->callbackCount, - cm_callbackCount); - cm_DiscardSCache(scp); - /* - * Since we don't have a callback to preserve, it's - * OK to drop the lock and re-obtain it. - */ - lock_ReleaseMutex(&scp->mx); - cm_CallbackNotifyChange(scp); - lock_ObtainMutex(&scp->mx); - } - if (freeFlag) free(revp); + scp->fid.vnode == revp->fid.vnode && + scp->fid.unique == revp->fid.unique) + || + ((revp->flags & CM_RACINGFLAG_CANCELVOL) && + scp->fid.volume == revp->fid.volume) + || + (revp->flags & CM_RACINGFLAG_CANCELALL))) { + /* this one matches */ + osi_Log4(afsd_logp, + "Racing revoke scp %x old cbc %d rev cbc %d cur cbc %d", + scp, + cbrp->callbackCount, revp->callbackCount, + cm_callbackCount); + cm_DiscardSCache(scp); + /* + * Since we don't have a callback to preserve, it's + * OK to drop the lock and re-obtain it. + */ + lock_ReleaseMutex(&scp->mx); + cm_CallbackNotifyChange(scp); + lock_ObtainMutex(&scp->mx); } + if (freeFlag) free(revp); + } - /* if we freed the list, zap the pointer to it */ - if (freeFlag) cm_racingRevokesp = NULL; + /* if we freed the list, zap the pointer to it */ + if (freeFlag) cm_racingRevokesp = NULL; - lock_ReleaseWrite(&cm_callbackLock); + lock_ReleaseWrite(&cm_callbackLock); if ( serverp ) { lock_ObtainWrite(&cm_serverLock); @@ -795,9 +796,9 @@ void cm_EndCallbackGrantingCall(cm_scache_t *scp, cm_callbackRequest_t *cbrp, * called with locked scp; returns with same. */ long cm_GetCallback(cm_scache_t *scp, struct cm_user *userp, - struct cm_req *reqp, long flags) + struct cm_req *reqp, long flags) { - long code; + long code; cm_conn_t *connp; AFSFetchStatus afsStatus; AFSVolSync volSync; @@ -807,14 +808,15 @@ long cm_GetCallback(cm_scache_t *scp, struct cm_user *userp, int mustCall; long sflags; cm_fid_t sfid; + struct rx_connection * callp; osi_Log2(afsd_logp, "GetCallback scp %x flags %lX", scp, flags); #ifdef AFS_FREELANCE_CLIENT - // The case where a callback is needed on /afs is handled - // specially. We need to fetch the status by calling - // cm_MergeStatus and mark that cm_fakeDirCallback is 2 - if (cm_freelanceEnabled) { + // The case where a callback is needed on /afs is handled + // specially. We need to fetch the status by calling + // cm_MergeStatus and mark that cm_fakeDirCallback is 2 + if (cm_freelanceEnabled) { if (scp->fid.cell==AFS_FAKE_ROOT_CELL_ID && scp->fid.volume==AFS_FAKE_ROOT_VOL_ID && scp->fid.unique==0x1 && @@ -849,41 +851,43 @@ long cm_GetCallback(cm_scache_t *scp, struct cm_user *userp, } #endif /* AFS_FREELANCE_CLIENT */ - mustCall = (flags & 1); - cm_AFSFidFromFid(&tfid, &scp->fid); - while (1) { - if (!mustCall && cm_HaveCallback(scp)) return 0; + mustCall = (flags & 1); + cm_AFSFidFromFid(&tfid, &scp->fid); + while (1) { + if (!mustCall && cm_HaveCallback(scp)) return 0; /* turn off mustCall, since it has now forced us past the check above */ mustCall = 0; /* otherwise, we have to make an RPC to get the status */ - sflags = CM_SCACHESYNC_FETCHSTATUS | CM_SCACHESYNC_GETCALLBACK; + sflags = CM_SCACHESYNC_FETCHSTATUS | CM_SCACHESYNC_GETCALLBACK; cm_SyncOp(scp, NULL, NULL, NULL, 0, sflags); cm_StartCallbackGrantingCall(scp, &cbr); sfid = scp->fid; - lock_ReleaseMutex(&scp->mx); + lock_ReleaseMutex(&scp->mx); - /* now make the RPC */ - osi_Log1(afsd_logp, "CALL FetchStatus vp %x", (long) scp); + /* now make the RPC */ + osi_Log1(afsd_logp, "CALL FetchStatus vp %x", (long) scp); do { - code = cm_Conn(&sfid, userp, reqp, &connp); + code = cm_Conn(&sfid, userp, reqp, &connp); if (code) continue; - - code = RXAFS_FetchStatus(connp->callp, &tfid, + + callp = cm_GetRxConn(connp); + code = RXAFS_FetchStatus(callp, &tfid, &afsStatus, &callback, &volSync); + rx_PutConnection(callp); - } while (cm_Analyze(connp, userp, reqp, &sfid, &volSync, NULL, + } while (cm_Analyze(connp, userp, reqp, &sfid, &volSync, NULL, &cbr, code)); code = cm_MapRPCError(code, reqp); - osi_Log0(afsd_logp, "CALL FetchStatus DONE"); + osi_Log0(afsd_logp, "CALL FetchStatus DONE"); - lock_ObtainMutex(&scp->mx); + lock_ObtainMutex(&scp->mx); cm_SyncOpDone(scp, NULL, sflags); - if (code == 0) { + if (code == 0) { cm_EndCallbackGrantingCall(scp, &cbr, &callback, 0); cm_MergeStatus(scp, &afsStatus, &volSync, userp, 0); - } + } else cm_EndCallbackGrantingCall(NULL, &cbr, NULL, 0); @@ -903,8 +907,8 @@ void cm_CheckCBExpiration(void) now = osi_Time(); lock_ObtainWrite(&cm_scacheLock); - for(i=0; inextp) { + for (i=0; inextp) { scp->refCount++; lock_ReleaseWrite(&cm_scacheLock); if (scp->cbExpires > 0 && (scp->cbServerp == NULL || now > scp->cbExpires)) { diff --git a/src/WINNT/afsd/cm_conn.c b/src/WINNT/afsd/cm_conn.c index a7ee8c386..32e748ad1 100644 --- a/src/WINNT/afsd/cm_conn.c +++ b/src/WINNT/afsd/cm_conn.c @@ -463,29 +463,29 @@ long cm_ConnByMServers(cm_serverRef_t *serversp, cm_user_t *usersp, /* called with a held server to GC all bad connections hanging off of the server */ void cm_GCConnections(cm_server_t *serverp) { - cm_conn_t *tcp; + cm_conn_t *tcp; cm_conn_t **lcpp; cm_user_t *userp; - lock_ObtainWrite(&cm_connLock); - lcpp = &serverp->connsp; - for(tcp = *lcpp; tcp; tcp = *lcpp) { - userp = tcp->userp; - if (userp && tcp->refCount == 0 && (userp->vcRefs == 0)) { - /* do the deletion of this guy */ + lock_ObtainWrite(&cm_connLock); + lcpp = &serverp->connsp; + for (tcp = *lcpp; tcp; tcp = *lcpp) { + userp = tcp->userp; + if (userp && tcp->refCount == 0 && (userp->vcRefs == 0)) { + /* do the deletion of this guy */ cm_PutServer(tcp->serverp); cm_ReleaseUser(userp); *lcpp = tcp->nextp; - rx_DestroyConnection(tcp->callp); + rx_DestroyConnection(tcp->callp); lock_FinalizeMutex(&tcp->mx); free(tcp); } else { - /* just advance to the next */ + /* just advance to the next */ lcpp = &tcp->nextp; } } - lock_ReleaseWrite(&cm_connLock); + lock_ReleaseWrite(&cm_connLock); } static void cm_NewRXConnection(cm_conn_t *tcp, cm_ucell_t *ucellp, @@ -495,25 +495,24 @@ static void cm_NewRXConnection(cm_conn_t *tcp, cm_ucell_t *ucellp, int serviceID; int secIndex; struct rx_securityClass *secObjp; - afs_int32 level; + afs_int32 level; - if (serverp->type == CM_SERVER_VLDB) { - port = htons(7003); + if (serverp->type == CM_SERVER_VLDB) { + port = htons(7003); serviceID = 52; } else { - osi_assert(serverp->type == CM_SERVER_FILE); + osi_assert(serverp->type == CM_SERVER_FILE); port = htons(7000); serviceID = 1; } - if (ucellp->flags & CM_UCELLFLAG_RXKAD) { - secIndex = 2; - if (cryptall) { - level = rxkad_crypt; - tcp->cryptlevel = rxkad_crypt; - } else { - level = rxkad_clear; - } + if (ucellp->flags & CM_UCELLFLAG_RXKAD) { + secIndex = 2; + if (cryptall) { + level = tcp->cryptlevel = rxkad_crypt; + } else { + level = tcp->cryptlevel = rxkad_clear; + } secObjp = rxkad_NewClientSecurityObject(level, &ucellp->sessionKey, ucellp->kvno, ucellp->ticketLen, ucellp->ticketp); @@ -523,61 +522,65 @@ static void cm_NewRXConnection(cm_conn_t *tcp, cm_ucell_t *ucellp, secIndex = 0; secObjp = rxnull_NewClientSecurityObject(); } - osi_assert(secObjp != NULL); + osi_assert(secObjp != NULL); tcp->callp = rx_NewConnection(serverp->addr.sin_addr.s_addr, port, serviceID, secObjp, secIndex); - rx_SetConnDeadTime(tcp->callp, ConnDeadtimeout); - rx_SetConnHardDeadTime(tcp->callp, HardDeadtimeout); - tcp->ucgen = ucellp->gen; + rx_SetConnDeadTime(tcp->callp, ConnDeadtimeout); + rx_SetConnHardDeadTime(tcp->callp, HardDeadtimeout); + tcp->ucgen = ucellp->gen; if (secObjp) rxs_Release(secObjp); /* Decrement the initial refCount */ } long cm_ConnByServer(cm_server_t *serverp, cm_user_t *userp, cm_conn_t **connpp) { - cm_conn_t *tcp; + cm_conn_t *tcp; cm_ucell_t *ucellp; - lock_ObtainMutex(&userp->mx); - lock_ObtainWrite(&cm_connLock); - for(tcp = serverp->connsp; tcp; tcp=tcp->nextp) { + lock_ObtainMutex(&userp->mx); + lock_ObtainWrite(&cm_connLock); + for (tcp = serverp->connsp; tcp; tcp=tcp->nextp) { if (tcp->userp == userp) break; } - /* find ucell structure */ + /* find ucell structure */ ucellp = cm_GetUCell(userp, serverp->cellp); - if (!tcp) { + if (!tcp) { cm_GetServer(serverp); - tcp = malloc(sizeof(*tcp)); + tcp = malloc(sizeof(*tcp)); memset(tcp, 0, sizeof(*tcp)); tcp->nextp = serverp->connsp; serverp->connsp = tcp; cm_HoldUser(userp); tcp->userp = userp; lock_InitializeMutex(&tcp->mx, "cm_conn_t mutex"); + lock_ObtainMutex(&tcp->mx); tcp->serverp = serverp; - tcp->cryptlevel = rxkad_clear; - cm_NewRXConnection(tcp, ucellp, serverp); - tcp->refCount = 1; - } - else { - if ((tcp->ucgen < ucellp->gen) || (tcp->cryptlevel != cryptall)) - { - rx_DestroyConnection(tcp->callp); - cm_NewRXConnection(tcp, ucellp, serverp); - } + tcp->cryptlevel = rxkad_clear; + cm_NewRXConnection(tcp, ucellp, serverp); + tcp->refCount = 1; + lock_ReleaseMutex(&tcp->mx); + } else { + if ((tcp->ucgen < ucellp->gen) || + (tcp->cryptlevel != (cryptall ? rxkad_crypt : rxkad_clear))) + { + lock_ObtainMutex(&tcp->mx); + rx_DestroyConnection(tcp->callp); + cm_NewRXConnection(tcp, ucellp, serverp); + lock_ReleaseMutex(&tcp->mx); + } tcp->refCount++; - } - lock_ReleaseWrite(&cm_connLock); + } + lock_ReleaseWrite(&cm_connLock); lock_ReleaseMutex(&userp->mx); - /* return this pointer to our caller */ + /* return this pointer to our caller */ osi_Log1(afsd_logp, "cm_ConnByServer returning conn 0x%x", (long) tcp); - *connpp = tcp; + *connpp = tcp; return 0; } @@ -599,3 +602,15 @@ long cm_Conn(struct cm_fid *fidp, struct cm_user *userp, cm_req_t *reqp, cm_FreeServerList(serverspp); return code; } + +extern struct rx_connection * +cm_GetRxConn(cm_conn_t *connp) +{ + struct rx_connection * rxconn; + lock_ObtainMutex(&connp->mx); + rxconn = connp->callp; + rx_GetConnection(rxconn); + lock_ReleaseMutex(&connp->mx); + return rxconn; +} + diff --git a/src/WINNT/afsd/cm_conn.h b/src/WINNT/afsd/cm_conn.h index 6f2f2e385..0e9e0234f 100644 --- a/src/WINNT/afsd/cm_conn.h +++ b/src/WINNT/afsd/cm_conn.h @@ -23,7 +23,7 @@ typedef struct cm_conn { struct rx_connection *callp; /* locked by mx */ struct cm_user *userp; /* locked by mx; a held reference */ osi_mutex_t mx; /* mutex for some of these fields */ - int refCount; /* locked by cm_connLock */ + unsigned long refCount; /* locked by cm_connLock */ int ucgen; /* ucellp's generation number */ long flags; /* locked by mx */ int cryptlevel; /* encrytion status */ @@ -83,6 +83,7 @@ typedef struct cm_req { cache managers treat it as "server is down"*/ #include "cm_server.h" +#include "rx.h" extern void cm_InitConn(void); @@ -106,4 +107,6 @@ extern void cm_PutConn(cm_conn_t *connp); extern void cm_GCConnections(cm_server_t *serverp); +extern struct rx_connection * cm_GetRxConn(cm_conn_t *connp); + #endif /* __CM_CONN_H_ENV__ */ diff --git a/src/WINNT/afsd/cm_dcache.c b/src/WINNT/afsd/cm_dcache.c index 56400e829..550fa2278 100644 --- a/src/WINNT/afsd/cm_dcache.c +++ b/src/WINNT/afsd/cm_dcache.c @@ -37,16 +37,16 @@ extern osi_mutex_t cm_Freelance_Lock; * or when holding or releasing a vnode pointer. */ long cm_BufWrite(void *vfidp, osi_hyper_t *offsetp, long length, long flags, - cm_user_t *userp, cm_req_t *reqp) + cm_user_t *userp, cm_req_t *reqp) { - /* store the data back from this buffer; the buffer is locked and held, - * but the vnode involved isn't locked, yet. It is held by its - * reference from the buffer, which won't change until the buffer is - * released by our caller. Thus, we don't have to worry about holding - * bufp->scp. - */ - long code; - cm_fid_t *fidp = vfidp; + /* store the data back from this buffer; the buffer is locked and held, + * but the vnode involved isn't locked, yet. It is held by its + * reference from the buffer, which won't change until the buffer is + * released by our caller. Thus, we don't have to worry about holding + * bufp->scp. + */ + long code; + cm_fid_t *fidp = vfidp; cm_scache_t *scp; long nbytes; long temp; @@ -70,35 +70,35 @@ long cm_BufWrite(void *vfidp, osi_hyper_t *offsetp, long length, long flags, * drops lots of locks, and may indeed return a properly initialized * buffer, although more likely it will just return a new, empty, buffer. */ - scp = cm_FindSCache(fidp); - if (scp == NULL) - return CM_ERROR_NOSUCHFILE; /* shouldn't happen */ + scp = cm_FindSCache(fidp); + if (scp == NULL) + return CM_ERROR_NOSUCHFILE; /* shouldn't happen */ - cm_AFSFidFromFid(&tfid, fidp); + cm_AFSFidFromFid(&tfid, fidp); - lock_ObtainMutex(&scp->mx); + lock_ObtainMutex(&scp->mx); code = cm_SetupStoreBIOD(scp, offsetp, length, &biod, userp, reqp); if (code) { - osi_Log1(afsd_logp, "cm_SetupStoreBIOD code %x", code); - lock_ReleaseMutex(&scp->mx); - cm_ReleaseSCache(scp); + osi_Log1(afsd_logp, "cm_SetupStoreBIOD code %x", code); + lock_ReleaseMutex(&scp->mx); + cm_ReleaseSCache(scp); return code; } - if (biod.length == 0) { - osi_Log0(afsd_logp, "cm_SetupStoreBIOD length 0"); - lock_ReleaseMutex(&scp->mx); - cm_ReleaseBIOD(&biod, 1); /* should be a NOOP */ - cm_ReleaseSCache(scp); + if (biod.length == 0) { + osi_Log0(afsd_logp, "cm_SetupStoreBIOD length 0"); + lock_ReleaseMutex(&scp->mx); + cm_ReleaseBIOD(&biod, 1); /* should be a NOOP */ + cm_ReleaseSCache(scp); return 0; - } + } - /* Serialize StoreData RPC's; for rationale see cm_scache.c */ - (void) cm_SyncOp(scp, NULL, userp, reqp, 0, CM_SCACHESYNC_STOREDATA_EXCL); + /* Serialize StoreData RPC's; for rationale see cm_scache.c */ + (void) cm_SyncOp(scp, NULL, userp, reqp, 0, CM_SCACHESYNC_STOREDATA_EXCL); - /* prepare the output status for the store */ - scp->mask |= CM_SCACHEMASK_CLIENTMODTIME; + /* prepare the output status for the store */ + scp->mask |= CM_SCACHEMASK_CLIENTMODTIME; cm_StatusFromAttr(&inStatus, scp, NULL); truncPos = scp->length.LowPart; if ((scp->mask & CM_SCACHEMASK_TRUNCPOS) @@ -106,46 +106,48 @@ long cm_BufWrite(void *vfidp, osi_hyper_t *offsetp, long length, long flags, truncPos = scp->truncPos.LowPart; scp->mask &= ~CM_SCACHEMASK_TRUNCPOS; - /* compute how many bytes to write from this buffer */ + /* compute how many bytes to write from this buffer */ thyper = LargeIntegerSubtract(scp->length, biod.offset); if (LargeIntegerLessThanZero(thyper)) { - /* entire buffer is past EOF */ - nbytes = 0; + /* entire buffer is past EOF */ + nbytes = 0; } else { - /* otherwise write out part of buffer before EOF, but not + /* otherwise write out part of buffer before EOF, but not * more than bufferSize bytes. */ - nbytes = thyper.LowPart; + nbytes = thyper.LowPart; if (nbytes > biod.length) nbytes = biod.length; } - lock_ReleaseMutex(&scp->mx); + lock_ReleaseMutex(&scp->mx); /* now we're ready to do the store operation */ do { - code = cm_Conn(&scp->fid, userp, reqp, &connp); + code = cm_Conn(&scp->fid, userp, reqp, &connp); if (code) continue; - callp = rx_NewCall(connp->callp); + lock_ObtainMutex(&connp->mx); + callp = rx_NewCall(connp->callp); + lock_ReleaseMutex(&connp->mx); - osi_Log3(afsd_logp, "CALL StoreData vp %x, off 0x%x, size 0x%x", + osi_Log3(afsd_logp, "CALL StoreData vp %x, off 0x%x, size 0x%x", (long) scp, biod.offset.LowPart, nbytes); code = StartRXAFS_StoreData(callp, &tfid, &inStatus, biod.offset.LowPart, nbytes, truncPos); - if (code == 0) { + if (code == 0) { /* write the data from the the list of buffers */ qdp = NULL; - while(nbytes > 0) { - if (qdp == NULL) - qdp = biod.bufListEndp; - else - qdp = (osi_queueData_t *) osi_QPrev(&qdp->q); - osi_assert(qdp != NULL); + while(nbytes > 0) { + if (qdp == NULL) + qdp = biod.bufListEndp; + else + qdp = (osi_queueData_t *) osi_QPrev(&qdp->q); + osi_assert(qdp != NULL); bufp = osi_GetQData(qdp); bufferp = bufp->datap; wbytes = nbytes; @@ -157,63 +159,63 @@ long cm_BufWrite(void *vfidp, osi_hyper_t *offsetp, long length, long flags, if (temp != wbytes) { osi_Log2(afsd_logp, "rx_Write failed %d != %d",temp,wbytes); code = -1; - break; - } else { + break; + } else { osi_Log1(afsd_logp, "rx_Write succeeded %d",temp); - } + } nbytes -= wbytes; } /* while more bytes to write */ - } /* if RPC started successfully */ + } /* if RPC started successfully */ else { osi_Log1(afsd_logp, "StartRXAFS_StoreData failed (%lX)",code); } - if (code == 0) { - code = EndRXAFS_StoreData(callp, &outStatus, &volSync); + if (code == 0) { + code = EndRXAFS_StoreData(callp, &outStatus, &volSync); if (code) osi_Log1(afsd_logp, "EndRXAFS_StoreData failed (%lX)",code); } code = rx_EndCall(callp, code); osi_Log0(afsd_logp, "CALL StoreData DONE"); - } while (cm_Analyze(connp, userp, reqp, &scp->fid, &volSync, NULL, NULL, code)); + } while (cm_Analyze(connp, userp, reqp, &scp->fid, &volSync, NULL, NULL, code)); code = cm_MapRPCError(code, reqp); /* now, clean up our state */ lock_ObtainMutex(&scp->mx); - cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_STOREDATA_EXCL); + cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_STOREDATA_EXCL); - if (code == 0) { - /* now, here's something a little tricky: in AFS 3, a dirty - * length can't be directly stored, instead, a dirty chunk is - * stored that sets the file's size (by writing and by using - * the truncate-first option in the store call). - * + if (code == 0) { + /* now, here's something a little tricky: in AFS 3, a dirty + * length can't be directly stored, instead, a dirty chunk is + * stored that sets the file's size (by writing and by using + * the truncate-first option in the store call). + * * At this point, we've just finished a store, and so the trunc - * pos field is clean. If the file's size at the server is at - * least as big as we think it should be, then we turn off the - * length dirty bit, since all the other dirty buffers must - * precede this one in the file. + * pos field is clean. If the file's size at the server is at + * least as big as we think it should be, then we turn off the + * length dirty bit, since all the other dirty buffers must + * precede this one in the file. * * The file's desired size shouldn't be smaller than what's - * stored at the server now, since we just did the trunc pos - * store. + * stored at the server now, since we just did the trunc pos + * store. * * We have to turn off the length dirty bit as soon as we can, - * so that we see updates made by other machines. + * so that we see updates made by other machines. */ - if (outStatus.Length >= scp->length.LowPart) + if (outStatus.Length >= scp->length.LowPart) scp->mask &= ~CM_SCACHEMASK_LENGTH; - cm_MergeStatus(scp, &outStatus, &volSync, userp, 0); - } else { - if (code == CM_ERROR_SPACE) - scp->flags |= CM_SCACHEFLAG_OUTOFSPACE; - else if (code == CM_ERROR_QUOTA) - scp->flags |= CM_SCACHEFLAG_OVERQUOTA; - } + cm_MergeStatus(scp, &outStatus, &volSync, userp, 0); + } else { + if (code == CM_ERROR_SPACE) + scp->flags |= CM_SCACHEFLAG_OUTOFSPACE; + else if (code == CM_ERROR_QUOTA) + scp->flags |= CM_SCACHEFLAG_OVERQUOTA; + } lock_ReleaseMutex(&scp->mx); cm_ReleaseBIOD(&biod, 1); - cm_ReleaseSCache(scp); + cm_ReleaseSCache(scp); return code; } @@ -229,71 +231,74 @@ long cm_StoreMini(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp) AFSStoreStatus inStatus; AFSVolSync volSync; AFSFid tfid; - long code; - long truncPos; - cm_conn_t *connp; + long code; + long truncPos; + cm_conn_t *connp; struct rx_call *callp; - /* Serialize StoreData RPC's; for rationale see cm_scache.c */ - (void) cm_SyncOp(scp, NULL, userp, reqp, 0, + /* Serialize StoreData RPC's; for rationale see cm_scache.c */ + (void) cm_SyncOp(scp, NULL, userp, reqp, 0, CM_SCACHESYNC_STOREDATA_EXCL); - /* prepare the output status for the store */ - inStatus.Mask = AFS_SETMODTIME; - inStatus.ClientModTime = scp->clientModTime; - scp->mask &= ~CM_SCACHEMASK_CLIENTMODTIME; + /* prepare the output status for the store */ + inStatus.Mask = AFS_SETMODTIME; + inStatus.ClientModTime = scp->clientModTime; + scp->mask &= ~CM_SCACHEMASK_CLIENTMODTIME; - /* calculate truncation position */ + /* calculate truncation position */ truncPos = scp->length.LowPart; if ((scp->mask & CM_SCACHEMASK_TRUNCPOS) && scp->truncPos.LowPart < (unsigned long) truncPos) truncPos = scp->truncPos.LowPart; - scp->mask &= ~CM_SCACHEMASK_TRUNCPOS; - - lock_ReleaseMutex(&scp->mx); + scp->mask &= ~CM_SCACHEMASK_TRUNCPOS; + + lock_ReleaseMutex(&scp->mx); - cm_AFSFidFromFid(&tfid, &scp->fid); + cm_AFSFidFromFid(&tfid, &scp->fid); /* now we're ready to do the store operation */ do { - code = cm_Conn(&scp->fid, userp, reqp, &connp); + code = cm_Conn(&scp->fid, userp, reqp, &connp); if (code) continue; - callp = rx_NewCall(connp->callp); + lock_ObtainMutex(&connp->mx); + callp = rx_NewCall(connp->callp); + lock_ReleaseMutex(&connp->mx); code = StartRXAFS_StoreData(callp, &tfid, &inStatus, 0, 0, truncPos); - if (code == 0) - code = EndRXAFS_StoreData(callp, &outStatus, &volSync); + if (code == 0) + code = EndRXAFS_StoreData(callp, &outStatus, &volSync); code = rx_EndCall(callp, code); - } while (cm_Analyze(connp, userp, reqp, &scp->fid, &volSync, NULL, NULL, code)); + + } while (cm_Analyze(connp, userp, reqp, &scp->fid, &volSync, NULL, NULL, code)); code = cm_MapRPCError(code, reqp); /* now, clean up our state */ lock_ObtainMutex(&scp->mx); - cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_STOREDATA_EXCL); + cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_STOREDATA_EXCL); - if (code == 0) { - /* - * For explanation of handling of CM_SCACHEMASK_LENGTH, - * see cm_BufWrite(). - */ - if (outStatus.Length >= scp->length.LowPart) + if (code == 0) { + /* + * For explanation of handling of CM_SCACHEMASK_LENGTH, + * see cm_BufWrite(). + */ + if (outStatus.Length >= scp->length.LowPart) scp->mask &= ~CM_SCACHEMASK_LENGTH; - cm_MergeStatus(scp, &outStatus, &volSync, userp, 0); - } + cm_MergeStatus(scp, &outStatus, &volSync, userp, 0); + } - return code; + return code; } long cm_BufRead(cm_buf_t *bufp, long nbytes, long *bytesReadp, cm_user_t *userp) { - *bytesReadp = buf_bufferSize; + *bytesReadp = buf_bufferSize; - /* now return a code that means that I/O is done */ + /* now return a code that means that I/O is done */ return 0; } @@ -302,18 +307,18 @@ long cm_BufRead(cm_buf_t *bufp, long nbytes, long *bytesReadp, cm_user_t *userp) */ long cm_BufStabilize(void *parmp, cm_user_t *userp, cm_req_t *reqp) { - cm_scache_t *scp; + cm_scache_t *scp; long code; scp = parmp; - lock_ObtainMutex(&scp->mx); + lock_ObtainMutex(&scp->mx); code = cm_SyncOp(scp, NULL, userp, reqp, 0, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_SETSIZE); - if (code) { - lock_ReleaseMutex(&scp->mx); + if (code) { + lock_ReleaseMutex(&scp->mx); return code; - } + } return 0; } @@ -321,18 +326,18 @@ long cm_BufStabilize(void *parmp, cm_user_t *userp, cm_req_t *reqp) /* undoes the work that cm_BufStabilize does: releases lock so things can change again */ long cm_BufUnstabilize(void *parmp, cm_user_t *userp) { - cm_scache_t *scp; + cm_scache_t *scp; scp = parmp; lock_ReleaseMutex(&scp->mx); - /* always succeeds */ + /* always succeeds */ return 0; } cm_buf_ops_t cm_bufOps = { - cm_BufWrite, + cm_BufWrite, cm_BufRead, cm_BufStabilize, cm_BufUnstabilize @@ -340,10 +345,10 @@ cm_buf_ops_t cm_bufOps = { int cm_InitDCache(long chunkSize, long nbuffers) { - lock_InitializeMutex(&cm_bufGetMutex, "buf_Get mutex"); - if (nbuffers) + lock_InitializeMutex(&cm_bufGetMutex, "buf_Get mutex"); + if (nbuffers) buf_nbuffers = nbuffers; - return buf_Init(&cm_bufOps); + return buf_Init(&cm_bufOps); } /* check to see if we have an up-to-date buffer. The buffer must have @@ -357,44 +362,44 @@ int cm_InitDCache(long chunkSize, long nbuffers) */ int cm_HaveBuffer(cm_scache_t *scp, cm_buf_t *bufp, int isBufLocked) { - int code; - if (!cm_HaveCallback(scp)) - return 0; - if ((bufp->cmFlags - & (CM_BUF_CMFETCHING | CM_BUF_CMFULLYFETCHED)) - == (CM_BUF_CMFETCHING | CM_BUF_CMFULLYFETCHED)) - return 1; - if (bufp->dataVersion == scp->dataVersion) - return 1; - if (!isBufLocked) { - code = lock_TryMutex(&bufp->mx); + int code; + if (!cm_HaveCallback(scp)) + return 0; + if ((bufp->cmFlags + & (CM_BUF_CMFETCHING | CM_BUF_CMFULLYFETCHED)) + == (CM_BUF_CMFETCHING | CM_BUF_CMFULLYFETCHED)) + return 1; + if (bufp->dataVersion == scp->dataVersion) + return 1; + if (!isBufLocked) { + code = lock_TryMutex(&bufp->mx); if (code == 0) { - /* don't have the lock, and can't lock it, then + /* don't have the lock, and can't lock it, then * return failure. */ return 0; } } - /* remember dirty flag for later */ - code = bufp->flags & CM_BUF_DIRTY; + /* remember dirty flag for later */ + code = bufp->flags & CM_BUF_DIRTY; - /* release lock if we obtained it here */ - if (!isBufLocked) + /* release lock if we obtained it here */ + if (!isBufLocked) lock_ReleaseMutex(&bufp->mx); - /* if buffer was dirty, buffer is acceptable for use */ - if (code) - return 1; - else - return 0; + /* if buffer was dirty, buffer is acceptable for use */ + if (code) + return 1; + else + return 0; } /* used when deciding whether to do a prefetch or not */ long cm_CheckFetchRange(cm_scache_t *scp, osi_hyper_t *startBasep, long length, - cm_user_t *up, cm_req_t *reqp, osi_hyper_t *realBasep) + cm_user_t *up, cm_req_t *reqp, osi_hyper_t *realBasep) { - osi_hyper_t toffset; + osi_hyper_t toffset; osi_hyper_t tbase; long code; cm_buf_t *bp; @@ -403,37 +408,37 @@ long cm_CheckFetchRange(cm_scache_t *scp, osi_hyper_t *startBasep, long length, /* now scan all buffers in the range, looking for any that look like * they need work. */ - tbase = *startBasep; - stop = 0; - lock_ObtainMutex(&scp->mx); + tbase = *startBasep; + stop = 0; + lock_ObtainMutex(&scp->mx); while(length > 0) { - /* get callback so we can do a meaningful dataVersion comparison */ + /* get callback so we can do a meaningful dataVersion comparison */ code = cm_SyncOp(scp, NULL, up, reqp, 0, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); - if (code) { - scp->flags &= ~CM_SCACHEFLAG_PREFETCHING; - lock_ReleaseMutex(&scp->mx); + if (code) { + scp->flags &= ~CM_SCACHEFLAG_PREFETCHING; + lock_ReleaseMutex(&scp->mx); return code; } if (LargeIntegerGreaterThanOrEqualTo(tbase, scp->length)) { - /* we're past the end of file */ + /* we're past the end of file */ break; } - bp = buf_Find(scp, &tbase); - /* We cheat slightly by not locking the bp mutex. */ + bp = buf_Find(scp, &tbase); + /* We cheat slightly by not locking the bp mutex. */ if (bp) { if ((bp->cmFlags - & (CM_BUF_CMFETCHING | CM_BUF_CMSTORING)) == 0 + & (CM_BUF_CMFETCHING | CM_BUF_CMSTORING)) == 0 && bp->dataVersion != scp->dataVersion) stop = 1; buf_Release(bp); - } + } else stop = 1; - /* if this buffer is essentially guaranteed to require a fetch, + /* if this buffer is essentially guaranteed to require a fetch, * break out here and return this position. */ if (stop) @@ -449,13 +454,13 @@ long cm_CheckFetchRange(cm_scache_t *scp, osi_hyper_t *startBasep, long length, * particular buffer in the range that definitely needs to be fetched. */ if (stop == 0) { - /* return non-zero code since realBasep won't be valid */ - scp->flags &= ~CM_SCACHEFLAG_PREFETCHING; - code = -1; - } + /* return non-zero code since realBasep won't be valid */ + scp->flags &= ~CM_SCACHEFLAG_PREFETCHING; + code = -1; + } else { - /* successfully found a page that will need fetching */ - *realBasep = tbase; + /* successfully found a page that will need fetching */ + *realBasep = tbase; code = 0; } lock_ReleaseMutex(&scp->mx); @@ -463,79 +468,79 @@ long cm_CheckFetchRange(cm_scache_t *scp, osi_hyper_t *startBasep, long length, } void cm_BkgStore(cm_scache_t *scp, long p1, long p2, long p3, long p4, - cm_user_t *userp) + cm_user_t *userp) { - osi_hyper_t toffset; + osi_hyper_t toffset; long length; - cm_req_t req; + cm_req_t req; - cm_InitReq(&req); - req.flags |= CM_REQ_NORETRY; + cm_InitReq(&req); + req.flags |= CM_REQ_NORETRY; toffset.LowPart = p1; toffset.HighPart = p2; length = p3; - osi_Log2(afsd_logp, "Starting BKG store vp 0x%x, base 0x%x", scp, p1); + osi_Log2(afsd_logp, "Starting BKG store vp 0x%x, base 0x%x", scp, p1); - cm_BufWrite(&scp->fid, &toffset, length, /* flags */ 0, userp, &req); + cm_BufWrite(&scp->fid, &toffset, length, /* flags */ 0, userp, &req); - lock_ObtainMutex(&scp->mx); - cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_ASYNCSTORE); + lock_ObtainMutex(&scp->mx); + cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_ASYNCSTORE); lock_ReleaseMutex(&scp->mx); } void cm_ClearPrefetchFlag(long code, cm_scache_t *scp, osi_hyper_t *base) { - osi_hyper_t thyper; - - if (code == 0) { - thyper.LowPart = cm_chunkSize; - thyper.HighPart = 0; - thyper = LargeIntegerAdd(*base, thyper); - thyper.LowPart &= (-cm_chunkSize); - if (LargeIntegerGreaterThan(*base, scp->prefetch.base)) + osi_hyper_t thyper; + + if (code == 0) { + thyper.LowPart = cm_chunkSize; + thyper.HighPart = 0; + thyper = LargeIntegerAdd(*base, thyper); + thyper.LowPart &= (-cm_chunkSize); + if (LargeIntegerGreaterThan(*base, scp->prefetch.base)) scp->prefetch.base = *base; - if (LargeIntegerGreaterThan(thyper, scp->prefetch.end)) + if (LargeIntegerGreaterThan(thyper, scp->prefetch.end)) scp->prefetch.end = thyper; - } - scp->flags &= ~CM_SCACHEFLAG_PREFETCHING; + } + scp->flags &= ~CM_SCACHEFLAG_PREFETCHING; } /* do the prefetch */ void cm_BkgPrefetch(cm_scache_t *scp, long p1, long p2, long p3, long p4, - cm_user_t *userp) + cm_user_t *userp) { - long length; + long length; osi_hyper_t base; long code; cm_buf_t *bp; - int cpff = 0; /* cleared prefetch flag */ - cm_req_t req; + int cpff = 0; /* cleared prefetch flag */ + cm_req_t req; - cm_InitReq(&req); - req.flags |= CM_REQ_NORETRY; + cm_InitReq(&req); + req.flags |= CM_REQ_NORETRY; - base.LowPart = p1; + base.LowPart = p1; base.HighPart = p2; length = p3; - osi_Log2(afsd_logp, "Starting BKG prefetch vp 0x%x, base 0x%x", scp, p1); + osi_Log2(afsd_logp, "Starting BKG prefetch vp 0x%x, base 0x%x", scp, p1); code = buf_Get(scp, &base, &bp); - lock_ObtainMutex(&scp->mx); + lock_ObtainMutex(&scp->mx); if (code || (bp->cmFlags & CM_BUF_CMFETCHING)) { - scp->flags &= ~CM_SCACHEFLAG_PREFETCHING; - lock_ReleaseMutex(&scp->mx); - return; - } + scp->flags &= ~CM_SCACHEFLAG_PREFETCHING; + lock_ReleaseMutex(&scp->mx); + return; + } code = cm_GetBuffer(scp, bp, &cpff, userp, &req); - if (!cpff) + if (!cpff) cm_ClearPrefetchFlag(code, scp, &base); - lock_ReleaseMutex(&scp->mx); + lock_ReleaseMutex(&scp->mx); buf_Release(bp); return; } @@ -544,36 +549,36 @@ void cm_BkgPrefetch(cm_scache_t *scp, long p1, long p2, long p3, long p4, * do a prefetch. */ void cm_ConsiderPrefetch(cm_scache_t *scp, osi_hyper_t *offsetp, - cm_user_t *userp, cm_req_t *reqp) + cm_user_t *userp, cm_req_t *reqp) { - long code; + long code; osi_hyper_t realBase; osi_hyper_t readBase; readBase = *offsetp; - /* round up to chunk boundary */ - readBase.LowPart += (cm_chunkSize-1); - readBase.LowPart &= (-cm_chunkSize); + /* round up to chunk boundary */ + readBase.LowPart += (cm_chunkSize-1); + readBase.LowPart &= (-cm_chunkSize); - lock_ObtainMutex(&scp->mx); - if ((scp->flags & CM_SCACHEFLAG_PREFETCHING) + lock_ObtainMutex(&scp->mx); + if ((scp->flags & CM_SCACHEFLAG_PREFETCHING) || LargeIntegerLessThanOrEqualTo(readBase, scp->prefetch.base)) { - lock_ReleaseMutex(&scp->mx); + lock_ReleaseMutex(&scp->mx); return; - } - scp->flags |= CM_SCACHEFLAG_PREFETCHING; + } + scp->flags |= CM_SCACHEFLAG_PREFETCHING; - /* start the scan at the latter of the end of this read or + /* start the scan at the latter of the end of this read or * the end of the last fetched region. */ - if (LargeIntegerGreaterThan(scp->prefetch.end, readBase)) + if (LargeIntegerGreaterThan(scp->prefetch.end, readBase)) readBase = scp->prefetch.end; lock_ReleaseMutex(&scp->mx); code = cm_CheckFetchRange(scp, &readBase, cm_chunkSize, userp, reqp, - &realBase); - if (code) + &realBase); + if (code) return; /* can't find something to prefetch */ osi_Log2(afsd_logp, "BKG Prefetch request vp 0x%x, base 0x%x", @@ -595,7 +600,7 @@ void cm_ConsiderPrefetch(cm_scache_t *scp, osi_hyper_t *offsetp, * is being written out. */ long cm_SetupStoreBIOD(cm_scache_t *scp, osi_hyper_t *inOffsetp, long inSize, - cm_bulkIO_t *biop, cm_user_t *userp, cm_req_t *reqp) + cm_bulkIO_t *biop, cm_user_t *userp, cm_req_t *reqp) { cm_buf_t *bufp; osi_queueData_t *qdp; @@ -608,75 +613,75 @@ long cm_SetupStoreBIOD(cm_scache_t *scp, osi_hyper_t *inOffsetp, long inSize, long code; long flags; /* flags to cm_SyncOp */ - /* clear things out */ - biop->scp = scp; /* don't hold */ + /* clear things out */ + biop->scp = scp; /* don't hold */ biop->offset = *inOffsetp; biop->length = 0; biop->bufListp = NULL; biop->bufListEndp = NULL; - biop->reserved = 0; + biop->reserved = 0; - /* reserve a chunk's worth of buffers */ - lock_ReleaseMutex(&scp->mx); - buf_ReserveBuffers(cm_chunkSize / buf_bufferSize); - lock_ObtainMutex(&scp->mx); + /* reserve a chunk's worth of buffers */ + lock_ReleaseMutex(&scp->mx); + buf_ReserveBuffers(cm_chunkSize / buf_bufferSize); + lock_ObtainMutex(&scp->mx); bufp = NULL; - for(temp = 0; temp < inSize; temp += buf_bufferSize, bufp = NULL) { - thyper.HighPart = 0; - thyper.LowPart = temp; + for (temp = 0; temp < inSize; temp += buf_bufferSize, bufp = NULL) { + thyper.HighPart = 0; + thyper.LowPart = temp; tbase = LargeIntegerAdd(*inOffsetp, thyper); bufp = buf_Find(scp, &tbase); if (bufp) { - /* get buffer mutex and scp mutex safely */ - lock_ReleaseMutex(&scp->mx); - lock_ObtainMutex(&bufp->mx); - lock_ObtainMutex(&scp->mx); - - flags = CM_SCACHESYNC_NEEDCALLBACK - | CM_SCACHESYNC_GETSTATUS - | CM_SCACHESYNC_STOREDATA - | CM_SCACHESYNC_BUFLOCKED; - code = cm_SyncOp(scp, bufp, userp, reqp, 0, flags); + /* get buffer mutex and scp mutex safely */ + lock_ReleaseMutex(&scp->mx); + lock_ObtainMutex(&bufp->mx); + lock_ObtainMutex(&scp->mx); + + flags = CM_SCACHESYNC_NEEDCALLBACK + | CM_SCACHESYNC_GETSTATUS + | CM_SCACHESYNC_STOREDATA + | CM_SCACHESYNC_BUFLOCKED; + code = cm_SyncOp(scp, bufp, userp, reqp, 0, flags); if (code) { - lock_ReleaseMutex(&bufp->mx); + lock_ReleaseMutex(&bufp->mx); buf_Release(bufp); - buf_UnreserveBuffers(cm_chunkSize / buf_bufferSize); + buf_UnreserveBuffers(cm_chunkSize / buf_bufferSize); return code; - } + } - /* if the buffer is dirty, we're done */ + /* if the buffer is dirty, we're done */ if (bufp->flags & CM_BUF_DIRTY) { osi_assertx(!(bufp->flags & CM_BUF_WRITING), "WRITING w/o CMSTORING in SetupStoreBIOD"); - bufp->flags |= CM_BUF_WRITING; - break; + bufp->flags |= CM_BUF_WRITING; + break; } - /* this buffer is clean, so there's no reason to process it */ - cm_SyncOpDone(scp, bufp, flags); - lock_ReleaseMutex(&bufp->mx); - buf_Release(bufp); - } + /* this buffer is clean, so there's no reason to process it */ + cm_SyncOpDone(scp, bufp, flags); + lock_ReleaseMutex(&bufp->mx); + buf_Release(bufp); + } } - biop->reserved = 1; + biop->reserved = 1; /* if we get here, if bufp is null, we didn't find any dirty buffers - * that weren't already being stored back, so we just quit now. + * that weren't already being stored back, so we just quit now. */ - if (!bufp) { - return 0; - } + if (!bufp) { + return 0; + } - /* don't need buffer mutex any more */ - lock_ReleaseMutex(&bufp->mx); + /* don't need buffer mutex any more */ + lock_ReleaseMutex(&bufp->mx); - /* put this element in the list */ + /* put this element in the list */ qdp = osi_QDAlloc(); osi_SetQData(qdp, bufp); - /* don't have to hold bufp, since held by buf_Find above */ + /* don't have to hold bufp, since held by buf_Find above */ osi_QAddH((osi_queue_t **) &biop->bufListp, (osi_queue_t **) &biop->bufListEndp, &qdp->q); @@ -684,66 +689,66 @@ long cm_SetupStoreBIOD(cm_scache_t *scp, osi_hyper_t *inOffsetp, long inSize, firstModOffset = bufp->offset; biop->offset = firstModOffset; - /* compute the window surrounding *inOffsetp of size cm_chunkSize */ - scanStart = *inOffsetp; + /* compute the window surrounding *inOffsetp of size cm_chunkSize */ + scanStart = *inOffsetp; scanStart.LowPart &= (-cm_chunkSize); - thyper.LowPart = cm_chunkSize; + thyper.LowPart = cm_chunkSize; thyper.HighPart = 0; - scanEnd = LargeIntegerAdd(scanStart, thyper); + scanEnd = LargeIntegerAdd(scanStart, thyper); - flags = CM_SCACHESYNC_NEEDCALLBACK - | CM_SCACHESYNC_GETSTATUS + flags = CM_SCACHESYNC_NEEDCALLBACK + | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_STOREDATA | CM_SCACHESYNC_BUFLOCKED | CM_SCACHESYNC_NOWAIT; - /* start by looking backwards until scanStart */ - thyper.HighPart = 0; /* hyper version of buf_bufferSize */ + /* start by looking backwards until scanStart */ + thyper.HighPart = 0; /* hyper version of buf_bufferSize */ thyper.LowPart = buf_bufferSize; - tbase = LargeIntegerSubtract(firstModOffset, thyper); + tbase = LargeIntegerSubtract(firstModOffset, thyper); while(LargeIntegerGreaterThanOrEqualTo(tbase, scanStart)) { /* see if we can find the buffer */ - bufp = buf_Find(scp, &tbase); + bufp = buf_Find(scp, &tbase); if (!bufp) break; - /* try to lock it, and quit if we can't (simplifies locking) */ + /* try to lock it, and quit if we can't (simplifies locking) */ code = lock_TryMutex(&bufp->mx); if (code == 0) { - buf_Release(bufp); + buf_Release(bufp); break; } code = cm_SyncOp(scp, bufp, userp, reqp, 0, flags); if (code) { - lock_ReleaseMutex(&bufp->mx); - buf_Release(bufp); + lock_ReleaseMutex(&bufp->mx); + buf_Release(bufp); break; } - if (!(bufp->flags & CM_BUF_DIRTY)) { - /* buffer is clean, so we shouldn't add it */ - cm_SyncOpDone(scp, bufp, flags); - lock_ReleaseMutex(&bufp->mx); - buf_Release(bufp); + if (!(bufp->flags & CM_BUF_DIRTY)) { + /* buffer is clean, so we shouldn't add it */ + cm_SyncOpDone(scp, bufp, flags); + lock_ReleaseMutex(&bufp->mx); + buf_Release(bufp); break; } - /* don't need buffer mutex any more */ - lock_ReleaseMutex(&bufp->mx); + /* don't need buffer mutex any more */ + lock_ReleaseMutex(&bufp->mx); /* we have a dirty buffer ready for storing. Add it to the tail * of the list, since it immediately precedes all of the disk * addresses we've already collected. */ - qdp = osi_QDAlloc(); + qdp = osi_QDAlloc(); osi_SetQData(qdp, bufp); /* no buf_hold necessary, since we have it held from buf_Find */ osi_QAddT((osi_queue_t **) &biop->bufListp, (osi_queue_t **) &biop->bufListEndp, &qdp->q); - /* update biod info describing the transfer */ + /* update biod info describing the transfer */ biop->offset = LargeIntegerSubtract(biop->offset, thyper); biop->length += buf_bufferSize; @@ -751,53 +756,53 @@ long cm_SetupStoreBIOD(cm_scache_t *scp, osi_hyper_t *inOffsetp, long inSize, tbase = LargeIntegerSubtract(tbase, thyper); } /* while loop looking for pages preceding the one we found */ - /* now, find later dirty, contiguous pages, and add them to the list */ - thyper.HighPart = 0; /* hyper version of buf_bufferSize */ + /* now, find later dirty, contiguous pages, and add them to the list */ + thyper.HighPart = 0; /* hyper version of buf_bufferSize */ thyper.LowPart = buf_bufferSize; - tbase = LargeIntegerAdd(firstModOffset, thyper); + tbase = LargeIntegerAdd(firstModOffset, thyper); while(LargeIntegerLessThan(tbase, scanEnd)) { - /* see if we can find the buffer */ - bufp = buf_Find(scp, &tbase); + /* see if we can find the buffer */ + bufp = buf_Find(scp, &tbase); if (!bufp) break; - /* try to lock it, and quit if we can't (simplifies locking) */ + /* try to lock it, and quit if we can't (simplifies locking) */ code = lock_TryMutex(&bufp->mx); if (code == 0) { - buf_Release(bufp); + buf_Release(bufp); break; } code = cm_SyncOp(scp, bufp, userp, reqp, 0, flags); if (code) { - lock_ReleaseMutex(&bufp->mx); - buf_Release(bufp); + lock_ReleaseMutex(&bufp->mx); + buf_Release(bufp); break; } - if (!(bufp->flags & CM_BUF_DIRTY)) { - /* buffer is clean, so we shouldn't add it */ - cm_SyncOpDone(scp, bufp, flags); - lock_ReleaseMutex(&bufp->mx); - buf_Release(bufp); + if (!(bufp->flags & CM_BUF_DIRTY)) { + /* buffer is clean, so we shouldn't add it */ + cm_SyncOpDone(scp, bufp, flags); + lock_ReleaseMutex(&bufp->mx); + buf_Release(bufp); break; } - /* don't need buffer mutex any more */ - lock_ReleaseMutex(&bufp->mx); + /* don't need buffer mutex any more */ + lock_ReleaseMutex(&bufp->mx); /* we have a dirty buffer ready for storing. Add it to the head * of the list, since it immediately follows all of the disk * addresses we've already collected. */ - qdp = osi_QDAlloc(); + qdp = osi_QDAlloc(); osi_SetQData(qdp, bufp); /* no buf_hold necessary, since we have it held from buf_Find */ osi_QAddH((osi_queue_t **) &biop->bufListp, (osi_queue_t **) &biop->bufListEndp, &qdp->q); - /* update biod info describing the transfer */ + /* update biod info describing the transfer */ biop->length += buf_bufferSize; /* update loop pointer */ @@ -816,7 +821,7 @@ long cm_SetupStoreBIOD(cm_scache_t *scp, osi_hyper_t *inOffsetp, long inSize, long cm_SetupFetchBIOD(cm_scache_t *scp, osi_hyper_t *offsetp, cm_bulkIO_t *biop, cm_user_t *up, cm_req_t *reqp) { - long code; + long code; cm_buf_t *tbp; osi_hyper_t toffset; /* a long long temp variable */ osi_hyper_t pageBase; /* base offset we're looking at */ @@ -828,86 +833,86 @@ long cm_SetupFetchBIOD(cm_scache_t *scp, osi_hyper_t *offsetp, osi_hyper_t fileSize; /* the # of bytes in the file */ osi_queueData_t *heldBufListp; /* we hold all buffers in this list */ osi_queueData_t *heldBufListEndp; /* first one */ - int reserving; + int reserving; biop->scp = scp; biop->offset = *offsetp; - /* null out the list of buffers */ + /* null out the list of buffers */ biop->bufListp = biop->bufListEndp = NULL; - biop->reserved = 0; + biop->reserved = 0; - /* first lookup the file's length, so we know when to stop */ + /* first lookup the file's length, so we know when to stop */ code = cm_SyncOp(scp, NULL, up, reqp, 0, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); if (code) return code; - /* copy out size, since it may change */ + /* copy out size, since it may change */ fileSize = scp->serverLength; lock_ReleaseMutex(&scp->mx); - pageBase = *offsetp; + pageBase = *offsetp; collected = pageBase.LowPart & (cm_chunkSize - 1); heldBufListp = NULL; heldBufListEndp = NULL; - /* - * Obtaining buffers can cause dirty buffers to be recycled, which - * can cause a storeback, so cannot be done while we have buffers - * reserved. - * - * To get around this, we get buffers twice. Before reserving buffers, - * we obtain and release each one individually. After reserving - * buffers, we try to obtain them again, but only by lookup, not by - * recycling. If a buffer has gone away while we were waiting for - * the others, we just use whatever buffers we already have. - * - * On entry to this function, we are already holding a buffer, so we - * can't wait for reservation. So we call buf_TryReserveBuffers() - * instead. Not only that, we can't really even call buf_Get(), for - * the same reason. We can't avoid that, though. To avoid deadlock - * we allow only one thread to be executing the buf_Get()-buf_Release() - * sequence at a time. - */ - - /* first hold all buffers, since we can't hold any locks in buf_Get */ + /* + * Obtaining buffers can cause dirty buffers to be recycled, which + * can cause a storeback, so cannot be done while we have buffers + * reserved. + * + * To get around this, we get buffers twice. Before reserving buffers, + * we obtain and release each one individually. After reserving + * buffers, we try to obtain them again, but only by lookup, not by + * recycling. If a buffer has gone away while we were waiting for + * the others, we just use whatever buffers we already have. + * + * On entry to this function, we are already holding a buffer, so we + * can't wait for reservation. So we call buf_TryReserveBuffers() + * instead. Not only that, we can't really even call buf_Get(), for + * the same reason. We can't avoid that, though. To avoid deadlock + * we allow only one thread to be executing the buf_Get()-buf_Release() + * sequence at a time. + */ + + /* first hold all buffers, since we can't hold any locks in buf_Get */ while (1) { - /* stop at chunk boundary */ - if (collected >= cm_chunkSize) break; + /* stop at chunk boundary */ + if (collected >= cm_chunkSize) break; /* see if the next page would be past EOF */ if (LargeIntegerGreaterThanOrEqualTo(pageBase, fileSize)) break; - lock_ObtainMutex(&cm_bufGetMutex); + lock_ObtainMutex(&cm_bufGetMutex); - code = buf_Get(scp, &pageBase, &tbp); + code = buf_Get(scp, &pageBase, &tbp); if (code) { - lock_ReleaseMutex(&cm_bufGetMutex); - lock_ObtainMutex(&scp->mx); - return code; - } + lock_ReleaseMutex(&cm_bufGetMutex); + lock_ObtainMutex(&scp->mx); + return code; + } - buf_Release(tbp); + buf_Release(tbp); - lock_ReleaseMutex(&cm_bufGetMutex); + lock_ReleaseMutex(&cm_bufGetMutex); toffset.HighPart = 0; toffset.LowPart = buf_bufferSize; pageBase = LargeIntegerAdd(toffset, pageBase); - collected += buf_bufferSize; + collected += buf_bufferSize; } /* reserve a chunk's worth of buffers if possible */ - reserving = buf_TryReserveBuffers(cm_chunkSize / buf_bufferSize); + reserving = buf_TryReserveBuffers(cm_chunkSize / buf_bufferSize); - pageBase = *offsetp; + pageBase = *offsetp; collected = pageBase.LowPart & (cm_chunkSize - 1); - /* now hold all buffers, if they are still there */ + /* now hold all buffers, if they are still there */ while (1) { - /* stop at chunk boundary */ - if (collected >= cm_chunkSize) + /* stop at chunk boundary */ + if (collected >= cm_chunkSize) break; /* see if the next page would be past EOF */ @@ -915,17 +920,17 @@ long cm_SetupFetchBIOD(cm_scache_t *scp, osi_hyper_t *offsetp, break; tbp = buf_Find(scp, &pageBase); - if (!tbp) + if (!tbp) break; /* add the buffer to the list */ - qdp = osi_QDAlloc(); + qdp = osi_QDAlloc(); osi_SetQData(qdp, tbp); osi_QAdd((osi_queue_t **)&heldBufListp, &qdp->q); if (!heldBufListEndp) heldBufListEndp = qdp; - /* leave tbp held (from buf_Get) */ + /* leave tbp held (from buf_Get) */ - if (!reserving) + if (!reserving) break; collected += buf_bufferSize; @@ -935,67 +940,67 @@ long cm_SetupFetchBIOD(cm_scache_t *scp, osi_hyper_t *offsetp, } /* look at each buffer, adding it into the list if it looks idle and - * filled with old data. One special case: wait for idle if it is the - * first buffer since we really need that one for our caller to make - * any progress. + * filled with old data. One special case: wait for idle if it is the + * first buffer since we really need that one for our caller to make + * any progress. */ isFirst = 1; collected = 0; /* now count how many we'll really use */ - for(tqdp = heldBufListEndp; + for (tqdp = heldBufListEndp; tqdp; - tqdp = (osi_queueData_t *) osi_QPrev(&tqdp->q)) { - /* get a ptr to the held buffer */ - tbp = osi_GetQData(tqdp); + tqdp = (osi_queueData_t *) osi_QPrev(&tqdp->q)) { + /* get a ptr to the held buffer */ + tbp = osi_GetQData(tqdp); pageBase = tbp->offset; - /* now lock the buffer lock */ - lock_ObtainMutex(&tbp->mx); - lock_ObtainMutex(&scp->mx); + /* now lock the buffer lock */ + lock_ObtainMutex(&tbp->mx); + lock_ObtainMutex(&scp->mx); - /* don't bother fetching over data that is already current */ - if (tbp->dataVersion == scp->dataVersion) { - /* we don't need this buffer, since it is current */ - lock_ReleaseMutex(&scp->mx); + /* don't bother fetching over data that is already current */ + if (tbp->dataVersion == scp->dataVersion) { + /* we don't need this buffer, since it is current */ + lock_ReleaseMutex(&scp->mx); lock_ReleaseMutex(&tbp->mx); break; } - flags = CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_FETCHDATA - | CM_SCACHESYNC_BUFLOCKED; - if (!isFirst) + flags = CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_FETCHDATA + | CM_SCACHESYNC_BUFLOCKED; + if (!isFirst) flags |= CM_SCACHESYNC_NOWAIT; - /* wait for the buffer to serialize, if required. Doesn't - * release the scp or buffer lock(s) if NOWAIT is specified. + /* wait for the buffer to serialize, if required. Doesn't + * release the scp or buffer lock(s) if NOWAIT is specified. */ - code = cm_SyncOp(scp, tbp, up, reqp, 0, flags); + code = cm_SyncOp(scp, tbp, up, reqp, 0, flags); if (code) { - lock_ReleaseMutex(&scp->mx); - lock_ReleaseMutex(&tbp->mx); + lock_ReleaseMutex(&scp->mx); + lock_ReleaseMutex(&tbp->mx); break; - } + } - /* don't fetch over dirty buffers */ + /* don't fetch over dirty buffers */ if (tbp->flags & CM_BUF_DIRTY) { - cm_SyncOpDone(scp, tbp, flags); - lock_ReleaseMutex(&scp->mx); + cm_SyncOpDone(scp, tbp, flags); + lock_ReleaseMutex(&scp->mx); lock_ReleaseMutex(&tbp->mx); break; - } + } - /* Release locks */ - lock_ReleaseMutex(&scp->mx); - lock_ReleaseMutex(&tbp->mx); + /* Release locks */ + lock_ReleaseMutex(&scp->mx); + lock_ReleaseMutex(&tbp->mx); /* add the buffer to the list */ - qdp = osi_QDAlloc(); + qdp = osi_QDAlloc(); osi_SetQData(qdp, tbp); osi_QAdd((osi_queue_t **)&biop->bufListp, &qdp->q); if (!biop->bufListEndp) biop->bufListEndp = qdp; - buf_Hold(tbp); + buf_Hold(tbp); - /* from now on, a failure just stops our collection process, but + /* from now on, a failure just stops our collection process, but * we still do the I/O to whatever we've already managed to collect. */ isFirst = 0; @@ -1003,33 +1008,33 @@ long cm_SetupFetchBIOD(cm_scache_t *scp, osi_hyper_t *offsetp, } /* now, we've held in biop->bufListp all the buffer's we're really - * interested in. We also have holds left from heldBufListp, and we - * now release those holds on the buffers. + * interested in. We also have holds left from heldBufListp, and we + * now release those holds on the buffers. */ - for(qdp = heldBufListp; qdp; qdp = tqdp) { - tqdp = (osi_queueData_t *) osi_QNext(&qdp->q); - tbp = osi_GetQData(qdp); + for (qdp = heldBufListp; qdp; qdp = tqdp) { + tqdp = (osi_queueData_t *) osi_QNext(&qdp->q); + tbp = osi_GetQData(qdp); osi_QDFree(qdp); buf_Release(tbp); } - /* Caller expects this */ - lock_ObtainMutex(&scp->mx); + /* Caller expects this */ + lock_ObtainMutex(&scp->mx); - /* if we got a failure setting up the first buffer, then we don't have + /* if we got a failure setting up the first buffer, then we don't have * any side effects yet, and we also have failed an operation that the * caller requires to make any progress. Give up now. */ if (code && isFirst) { - buf_UnreserveBuffers(cm_chunkSize / buf_bufferSize); - return code; - } + buf_UnreserveBuffers(cm_chunkSize / buf_bufferSize); + return code; + } /* otherwise, we're still OK, and should just return the I/O setup we've * got. */ - biop->length = collected; - biop->reserved = reserving; + biop->length = collected; + biop->reserved = reserving; return 0; } @@ -1038,41 +1043,41 @@ long cm_SetupFetchBIOD(cm_scache_t *scp, osi_hyper_t *offsetp, */ void cm_ReleaseBIOD(cm_bulkIO_t *biop, int isStore) { - cm_scache_t *scp; + cm_scache_t *scp; cm_buf_t *bufp; osi_queueData_t *qdp; osi_queueData_t *nqdp; int flags; - /* Give back reserved buffers */ - if (biop->reserved) - buf_UnreserveBuffers(cm_chunkSize / buf_bufferSize); + /* Give back reserved buffers */ + if (biop->reserved) + buf_UnreserveBuffers(cm_chunkSize / buf_bufferSize); - flags = CM_SCACHESYNC_NEEDCALLBACK; + flags = CM_SCACHESYNC_NEEDCALLBACK; if (isStore) flags |= CM_SCACHESYNC_STOREDATA; - else - flags |= CM_SCACHESYNC_FETCHDATA; + else + flags |= CM_SCACHESYNC_FETCHDATA; - scp = biop->scp; + scp = biop->scp; for(qdp = biop->bufListp; qdp; qdp = nqdp) { - /* lookup next guy first, since we're going to free this one */ - nqdp = (osi_queueData_t *) osi_QNext(&qdp->q); + /* lookup next guy first, since we're going to free this one */ + nqdp = (osi_queueData_t *) osi_QNext(&qdp->q); - /* extract buffer and free queue data */ + /* extract buffer and free queue data */ bufp = osi_GetQData(qdp); osi_QDFree(qdp); /* now, mark I/O as done, unlock the buffer and release it */ - lock_ObtainMutex(&bufp->mx); - lock_ObtainMutex(&scp->mx); + lock_ObtainMutex(&bufp->mx); + lock_ObtainMutex(&scp->mx); cm_SyncOpDone(scp, bufp, flags); - lock_ReleaseMutex(&scp->mx); + lock_ReleaseMutex(&scp->mx); - /* turn off writing and wakeup users */ + /* turn off writing and wakeup users */ if (isStore) { if (bufp->flags & CM_BUF_WAITING) { - osi_Wakeup((long) bufp); + osi_Wakeup((long) bufp); } bufp->flags &= ~(CM_BUF_WAITING | CM_BUF_WRITING | CM_BUF_DIRTY); } @@ -1090,9 +1095,9 @@ void cm_ReleaseBIOD(cm_bulkIO_t *biop, int isStore) * The scp is locked on return. */ long cm_GetBuffer(cm_scache_t *scp, cm_buf_t *bufp, int *cpffp, cm_user_t *up, - cm_req_t *reqp) + cm_req_t *reqp) { - long code; + long code; long nbytes; /* bytes in transfer */ long rbytes; /* bytes in rx_Read call */ long temp; @@ -1106,8 +1111,8 @@ long cm_GetBuffer(cm_scache_t *scp, cm_buf_t *bufp, int *cpffp, cm_user_t *up, struct rx_call *callp; cm_bulkIO_t biod; /* bulk IO descriptor */ cm_conn_t *connp; - int getroot; - long t1, t2; + int getroot; + long t1, t2; /* now, the buffer may or may not be filled with good data (buf_GetNew * drops lots of locks, and may indeed return a properly initialized @@ -1116,45 +1121,45 @@ long cm_GetBuffer(cm_scache_t *scp, cm_buf_t *bufp, int *cpffp, cm_user_t *up, #ifdef AFS_FREELANCE_CLIENT - // yj: if they're trying to get the /afs directory, we need to - // handle it differently, since it's local rather than on any - // server + // yj: if they're trying to get the /afs directory, we need to + // handle it differently, since it's local rather than on any + // server - getroot = (scp==cm_rootSCachep); - if (getroot) - osi_Log1(afsd_logp,"GetBuffer returns cm_rootSCachep=%x",cm_rootSCachep); + getroot = (scp==cm_rootSCachep); + if (getroot) + osi_Log1(afsd_logp,"GetBuffer returns cm_rootSCachep=%x",cm_rootSCachep); #endif - cm_AFSFidFromFid(&tfid, &scp->fid); + cm_AFSFidFromFid(&tfid, &scp->fid); - code = cm_SetupFetchBIOD(scp, &bufp->offset, &biod, up, reqp); - if (code) { - /* couldn't even get the first page setup properly */ - osi_Log1(afsd_logp, "SetupFetchBIOD failure code %d", code); + code = cm_SetupFetchBIOD(scp, &bufp->offset, &biod, up, reqp); + if (code) { + /* couldn't even get the first page setup properly */ + osi_Log1(afsd_logp, "SetupFetchBIOD failure code %d", code); return code; - } + } /* once we get here, we have the callback in place, we know that no one - * is fetching the data now. Check one last time that we still have - * the wrong data, and then fetch it if we're still wrong. - * + * is fetching the data now. Check one last time that we still have + * the wrong data, and then fetch it if we're still wrong. + * * We can lose a race condition and end up with biod.length zero, in - * which case we just retry. + * which case we just retry. */ if (bufp->dataVersion == scp->dataVersion || biod.length == 0) { - osi_Log3(afsd_logp, "Bad DVs %d, %d or length 0x%x", + osi_Log3(afsd_logp, "Bad DVs %d, %d or length 0x%x", bufp->dataVersion, scp->dataVersion, biod.length); - if ((bufp->dataVersion == -1 - || bufp->dataVersion < scp->dataVersion) + if ((bufp->dataVersion == -1 + || bufp->dataVersion < scp->dataVersion) && LargeIntegerGreaterThanOrEqualTo(bufp->offset, scp->serverLength)) { - if (bufp->dataVersion == -1) - memset(bufp->datap, 0, buf_bufferSize); - bufp->dataVersion = scp->dataVersion; - } - lock_ReleaseMutex(&scp->mx); - cm_ReleaseBIOD(&biod, 0); - lock_ObtainMutex(&scp->mx); + if (bufp->dataVersion == -1) + memset(bufp->datap, 0, buf_bufferSize); + bufp->dataVersion = scp->dataVersion; + } + lock_ReleaseMutex(&scp->mx); + cm_ReleaseBIOD(&biod, 0); + lock_ObtainMutex(&scp->mx); return 0; } @@ -1167,200 +1172,202 @@ long cm_GetBuffer(cm_scache_t *scp, cm_buf_t *bufp, int *cpffp, cm_user_t *up, #ifdef AFS_FREELANCE_CLIENT - // yj code - // if getroot then we don't need to make any calls - // just return fake data + // yj code + // if getroot then we don't need to make any calls + // just return fake data - if (cm_freelanceEnabled && getroot) { - // setup the fake status - afsStatus.InterfaceVersion = 0x1; - afsStatus.FileType = 0x2; - afsStatus.LinkCount = scp->linkCount; - afsStatus.Length = cm_fakeDirSize; - afsStatus.DataVersion = cm_fakeDirVersion; - afsStatus.Author = 0x1; - afsStatus.Owner = 0x0; - afsStatus.CallerAccess = 0x9; - afsStatus.AnonymousAccess = 0x9; - afsStatus.UnixModeBits = 0x1ff; - afsStatus.ParentVnode = 0x1; - afsStatus.ParentUnique = 0x1; - afsStatus.ResidencyMask = 0; - afsStatus.ClientModTime = FakeFreelanceModTime; - afsStatus.ServerModTime = FakeFreelanceModTime; - afsStatus.Group = 0; - afsStatus.SyncCounter = 0; - afsStatus.dataVersionHigh = 0; + if (cm_freelanceEnabled && getroot) { + // setup the fake status + afsStatus.InterfaceVersion = 0x1; + afsStatus.FileType = 0x2; + afsStatus.LinkCount = scp->linkCount; + afsStatus.Length = cm_fakeDirSize; + afsStatus.DataVersion = cm_fakeDirVersion; + afsStatus.Author = 0x1; + afsStatus.Owner = 0x0; + afsStatus.CallerAccess = 0x9; + afsStatus.AnonymousAccess = 0x9; + afsStatus.UnixModeBits = 0x1ff; + afsStatus.ParentVnode = 0x1; + afsStatus.ParentUnique = 0x1; + afsStatus.ResidencyMask = 0; + afsStatus.ClientModTime = FakeFreelanceModTime; + afsStatus.ServerModTime = FakeFreelanceModTime; + afsStatus.Group = 0; + afsStatus.SyncCounter = 0; + afsStatus.dataVersionHigh = 0; - // once we're done setting up the status info, - // we just fill the buffer pages with fakedata - // from cm_FakeRootDir. Extra pages are set to - // 0. + // once we're done setting up the status info, + // we just fill the buffer pages with fakedata + // from cm_FakeRootDir. Extra pages are set to + // 0. - lock_ObtainMutex(&cm_Freelance_Lock); - t1 = bufp->offset.LowPart; - qdp = biod.bufListEndp; - while (qdp) { - tbufp = osi_GetQData(qdp); - bufferp=tbufp->datap; - memset(bufferp, 0, buf_bufferSize); - t2 = cm_fakeDirSize - t1; - if (t2>buf_bufferSize) t2=buf_bufferSize; - if (t2 > 0) { - memcpy(bufferp, cm_FakeRootDir+t1, t2); - } else { - t2 = 0; - } - t1+=t2; - qdp = (osi_queueData_t *) osi_QPrev(&qdp->q); - - } - lock_ReleaseMutex(&cm_Freelance_Lock); + lock_ObtainMutex(&cm_Freelance_Lock); + t1 = bufp->offset.LowPart; + qdp = biod.bufListEndp; + while (qdp) { + tbufp = osi_GetQData(qdp); + bufferp=tbufp->datap; + memset(bufferp, 0, buf_bufferSize); + t2 = cm_fakeDirSize - t1; + if (t2>buf_bufferSize) t2=buf_bufferSize; + if (t2 > 0) { + memcpy(bufferp, cm_FakeRootDir+t1, t2); + } else { + t2 = 0; + } + t1+=t2; + qdp = (osi_queueData_t *) osi_QPrev(&qdp->q); + + } + lock_ReleaseMutex(&cm_Freelance_Lock); - // once we're done, we skip over the part of the - // code that does the ACTUAL fetching of data for - // real files + // once we're done, we skip over the part of the + // code that does the ACTUAL fetching of data for + // real files - goto fetchingcompleted; - } + goto fetchingcompleted; + } #endif /* AFS_FREELANCE_CLIENT */ /* now make the call */ do { - code = cm_Conn(&scp->fid, up, reqp, &connp); + code = cm_Conn(&scp->fid, up, reqp, &connp); if (code) continue; - callp = rx_NewCall(connp->callp); + lock_ObtainMutex(&connp->mx); + callp = rx_NewCall(connp->callp); + lock_ReleaseMutex(&connp->mx); - osi_Log3(afsd_logp, "CALL FetchData vp %x, off 0x%x, size 0x%x", - (long) scp, biod.offset.LowPart, biod.length); + osi_Log3(afsd_logp, "CALL FetchData vp %x, off 0x%x, size 0x%x", + (long) scp, biod.offset.LowPart, biod.length); code = StartRXAFS_FetchData(callp, &tfid, biod.offset.LowPart, biod.length); - /* now copy the data out of the pipe and put it in the buffer */ - temp = rx_Read(callp, (char *)&nbytes, 4); - if (temp == 4) { - nbytes = ntohl(nbytes); + /* now copy the data out of the pipe and put it in the buffer */ + temp = rx_Read(callp, (char *)&nbytes, 4); + if (temp == 4) { + nbytes = ntohl(nbytes); if (nbytes > biod.length) code = (callp->error < 0) ? callp->error : -1; } else code = (callp->error < 0) ? callp->error : -1; - if (code == 0) { + if (code == 0) { qdp = biod.bufListEndp; if (qdp) { - tbufp = osi_GetQData(qdp); + tbufp = osi_GetQData(qdp); bufferp = tbufp->datap; } else bufferp = NULL; - /* fill nbytes of data from the pipe into the pages. - * When we stop, qdp will point at the last page we're - * dealing with, and bufferp will tell us where we - * stopped. We'll need this info below when we clear - * the remainder of the last page out (and potentially + /* fill nbytes of data from the pipe into the pages. + * When we stop, qdp will point at the last page we're + * dealing with, and bufferp will tell us where we + * stopped. We'll need this info below when we clear + * the remainder of the last page out (and potentially * clear later pages out, if we fetch past EOF). */ - while(nbytes > 0) { - /* assert that there are still more buffers; - * our check above for nbytes being less than - * biod.length should ensure this. + while (nbytes > 0) { + /* assert that there are still more buffers; + * our check above for nbytes being less than + * biod.length should ensure this. */ - osi_assert(bufferp != NULL); + osi_assert(bufferp != NULL); - /* read rbytes of data */ + /* read rbytes of data */ rbytes = (nbytes > buf_bufferSize? buf_bufferSize : nbytes); temp = rx_Read(callp, bufferp, rbytes); if (temp < rbytes) { code = (callp->error < 0) ? callp->error : -1; break; - } - - /* allow read-while-fetching. - * if this is the last buffer, clear the - * PREFETCHING flag, so the reader waiting for - * this buffer will start a prefetch. - */ - tbufp->cmFlags |= CM_BUF_CMFULLYFETCHED; - lock_ObtainMutex(&scp->mx); - if (scp->flags & CM_SCACHEFLAG_WAITING) { - scp->flags &= ~CM_SCACHEFLAG_WAITING; - osi_Wakeup((long) &scp->flags); - } - if (cpffp && !*cpffp && !osi_QPrev(&qdp->q)) { - *cpffp = 1; - cm_ClearPrefetchFlag(0, scp, &biod.offset); - } - lock_ReleaseMutex(&scp->mx); - - /* and adjust counters */ + } + + /* allow read-while-fetching. + * if this is the last buffer, clear the + * PREFETCHING flag, so the reader waiting for + * this buffer will start a prefetch. + */ + tbufp->cmFlags |= CM_BUF_CMFULLYFETCHED; + lock_ObtainMutex(&scp->mx); + if (scp->flags & CM_SCACHEFLAG_WAITING) { + scp->flags &= ~CM_SCACHEFLAG_WAITING; + osi_Wakeup((long) &scp->flags); + } + if (cpffp && !*cpffp && !osi_QPrev(&qdp->q)) { + *cpffp = 1; + cm_ClearPrefetchFlag(0, scp, &biod.offset); + } + lock_ReleaseMutex(&scp->mx); + + /* and adjust counters */ nbytes -= temp; - + /* and move to the next buffer */ - if (nbytes != 0) { + if (nbytes != 0) { qdp = (osi_queueData_t *) osi_QPrev(&qdp->q); if (qdp) { - tbufp = osi_GetQData(qdp); + tbufp = osi_GetQData(qdp); bufferp = tbufp->datap; } else bufferp = NULL; - } else + } else bufferp += temp; } /* zero out remainder of last pages, in case we are - * fetching past EOF. We were fetching an integral # - * of pages, but stopped, potentially in the middle of - * a page. Zero the remainder of that page, and then - * all of the rest of the pages. + * fetching past EOF. We were fetching an integral # + * of pages, but stopped, potentially in the middle of + * a page. Zero the remainder of that page, and then + * all of the rest of the pages. */ - /* bytes fetched */ + /* bytes fetched */ rbytes = bufferp - tbufp->datap; - /* bytes left to zero */ + /* bytes left to zero */ rbytes = buf_bufferSize - rbytes; while(qdp) { if (rbytes != 0) - memset(bufferp, 0, rbytes); + memset(bufferp, 0, rbytes); qdp = (osi_queueData_t *) osi_QPrev(&qdp->q); - if (qdp == NULL) + if (qdp == NULL) break; - tbufp = osi_GetQData(qdp); + tbufp = osi_GetQData(qdp); bufferp = tbufp->datap; - /* bytes to clear in this page */ - rbytes = buf_bufferSize; - } - } + /* bytes to clear in this page */ + rbytes = buf_bufferSize; + } + } - if (code == 0) - code = EndRXAFS_FetchData(callp, &afsStatus, &callback, &volSync); - else - osi_Log0(afsd_logp, "CALL EndRXAFS_FetchData skipped due to error"); + if (code == 0) + code = EndRXAFS_FetchData(callp, &afsStatus, &callback, &volSync); + else + osi_Log0(afsd_logp, "CALL EndRXAFS_FetchData skipped due to error"); code = rx_EndCall(callp, code); if (code == RXKADUNKNOWNKEY) osi_Log0(afsd_logp, "CALL EndCall returns RXKADUNKNOWNKEY"); osi_Log0(afsd_logp, "CALL FetchData DONE"); - } while (cm_Analyze(connp, up, reqp, &scp->fid, &volSync, NULL, NULL, code)); + } while (cm_Analyze(connp, up, reqp, &scp->fid, &volSync, NULL, NULL, code)); fetchingcompleted: code = cm_MapRPCError(code, reqp); lock_ObtainMutex(&scp->mx); - /* we know that no one else has changed the buffer, since we still have - * the fetching flag on the buffers, and we have the scp locked again. - * Copy in the version # into the buffer if we got code 0 back from the - * read. + /* we know that no one else has changed the buffer, since we still have + * the fetching flag on the buffers, and we have the scp locked again. + * Copy in the version # into the buffer if we got code 0 back from the + * read. */ - if (code == 0) { - for(qdp = biod.bufListp; - qdp; - qdp = (osi_queueData_t *) osi_QNext(&qdp->q)) { - tbufp = osi_GetQData(qdp); + if (code == 0) { + for(qdp = biod.bufListp; + qdp; + qdp = (osi_queueData_t *) osi_QNext(&qdp->q)) { + tbufp = osi_GetQData(qdp); tbufp->dataVersion = afsStatus.DataVersion; #ifdef DISKCACHE95 @@ -1371,12 +1378,12 @@ long cm_GetBuffer(cm_scache_t *scp, cm_buf_t *bufp, int *cpffp, cm_user_t *up, } } - /* release scatter/gather I/O structure (buffers, locks) */ - lock_ReleaseMutex(&scp->mx); - cm_ReleaseBIOD(&biod, 0); - lock_ObtainMutex(&scp->mx); + /* release scatter/gather I/O structure (buffers, locks) */ + lock_ReleaseMutex(&scp->mx); + cm_ReleaseBIOD(&biod, 0); + lock_ObtainMutex(&scp->mx); if (code == 0) cm_MergeStatus(scp, &afsStatus, &volSync, up, 0); - return code; + return code; } diff --git a/src/WINNT/afsd/cm_diskcache95.h b/src/WINNT/afsd/cm_diskcache95.h index f8721e0f0..fa8c78367 100644 --- a/src/WINNT/afsd/cm_diskcache95.h +++ b/src/WINNT/afsd/cm_diskcache95.h @@ -51,7 +51,7 @@ typedef struct cm_diskcache { int openfd; /* open file descriptor */ struct cm_diskcache *hash_next; struct cm_diskcache *hash_prev; - int refCount; + unsigned long refCount; osi_mutex_t mx; } cm_diskcache_t; diff --git a/src/WINNT/afsd/cm_freelance.c b/src/WINNT/afsd/cm_freelance.c index f0caaf3db..2933c0f50 100644 --- a/src/WINNT/afsd/cm_freelance.c +++ b/src/WINNT/afsd/cm_freelance.c @@ -30,7 +30,7 @@ cm_localMountPoint_t* cm_localMountPoints; osi_mutex_t cm_Freelance_Lock; int cm_localMountPointChangeFlag = 0; int cm_freelanceEnabled = 0; -afs_uint32 FakeFreelanceModTime = 0x3b49f6e2; +time_t FakeFreelanceModTime = 0x3b49f6e2; void cm_InitFakeRootDir(); @@ -81,23 +81,23 @@ void cm_InitFreelance() { int lpid; #endif - lock_InitializeMutex(&cm_Freelance_Lock, "Freelance Lock"); + lock_InitializeMutex(&cm_Freelance_Lock, "Freelance Lock"); - // yj: first we make a call to cm_initLocalMountPoints - // to read all the local mount points from an ini file - cm_InitLocalMountPoints(); + // yj: first we make a call to cm_initLocalMountPoints + // to read all the local mount points from an ini file + cm_InitLocalMountPoints(); - // then we make a call to InitFakeRootDir to create - // a fake root directory based on the local mount points - cm_InitFakeRootDir(); - // --- end of yj code + // then we make a call to InitFakeRootDir to create + // a fake root directory based on the local mount points + cm_InitFakeRootDir(); + // --- end of yj code #if !defined(DJGPP) /* Start the registry monitor */ phandle = thrd_Create(NULL, 65536, (ThreadFunc) cm_FreelanceChangeNotifier, NULL, 0, &lpid, "cm_FreelanceChangeNotifier"); - osi_assert(phandle != NULL); - thrd_CloseHandle(phandle); + osi_assert(phandle != NULL); + thrd_CloseHandle(phandle); #endif } @@ -105,186 +105,186 @@ void cm_InitFreelance() { /* to be called while holding freelance lock unless during init. */ void cm_InitFakeRootDir() { - int i, t1, t2; - char* currentPos; - int noChunks; - - // allocate space for the fake info - cm_dirHeader_t fakeDirHeader; - cm_dirEntry_t fakeEntry; - cm_pageHeader_t fakePageHeader; - - // i'm going to calculate how much space is needed for - // this fake root directory. we have these rules: - // 1. there are cm_noLocalMountPoints number of entries - // 2. each page is CM_DIR_PAGESIZE in size - // 3. the first 13 chunks of the first page are used for - // some header stuff - // 4. the first chunk of all subsequent pages are used - // for page header stuff - // 5. a max of CM_DIR_EPP entries are allowed per page - // 6. each entry takes 1 or more chunks, depending on - // the size of the mount point string, as determined - // by cm_NameEntries - // 7. each chunk is CM_DIR_CHUNKSIZE bytes - - int CPP = CM_DIR_PAGESIZE / CM_DIR_CHUNKSIZE; - int curChunk = 13; // chunks 0 - 12 are used for header stuff - // of the first page in the directory - int curPage = 0; - int curDirEntry = 0; - int curDirEntryInPage = 0; - int sizeOfCurEntry; - int dirSize; - - /* Reserve 2 directory chunks for "." and ".." */ - curChunk += 2; - - while (curDirEntry!=cm_noLocalMountPoints) { - sizeOfCurEntry = cm_NameEntries((cm_localMountPoints+curDirEntry)->namep, 0); - if ((curChunk + sizeOfCurEntry >= CPP) || - (curDirEntryInPage + 1 >= CM_DIR_EPP)) { - curPage++; - curDirEntryInPage = 0; - curChunk = 1; - } - curChunk += sizeOfCurEntry; - curDirEntry++; - curDirEntryInPage++; - } - - dirSize = (curPage+1) * CM_DIR_PAGESIZE; - cm_FakeRootDir = malloc(dirSize); - cm_fakeDirSize = dirSize; - - // yj: when we get here, we've figured out how much memory we need and - // allocated the appropriate space for it. we now prceed to fill - // it up with entries. - curPage = 0; - curDirEntry = 0; - curDirEntryInPage = 0; - curChunk = 0; - - // fields in the directory entry that are unused. - fakeEntry.flag = 1; - fakeEntry.length = 0; - fakeEntry.next = 0; - fakeEntry.fid.unique = htonl(1); - - // the first page is special, it uses fakeDirHeader instead of fakePageHeader - // we fill up the page with dirEntries that belong there and we make changes - // to the fakeDirHeader.header.freeBitmap along the way. Then when we're done - // filling up the dirEntries in this page, we copy the fakeDirHeader into - // the top of the page. - - // init the freeBitmap array - for (i=0; i<8; i++) - fakeDirHeader.header.freeBitmap[i]=0; - - fakeDirHeader.header.freeBitmap[0] = 0xff; - fakeDirHeader.header.freeBitmap[1] = 0x7f; - + int i, t1, t2; + char* currentPos; + int noChunks; + + // allocate space for the fake info + cm_dirHeader_t fakeDirHeader; + cm_dirEntry_t fakeEntry; + cm_pageHeader_t fakePageHeader; + + // i'm going to calculate how much space is needed for + // this fake root directory. we have these rules: + // 1. there are cm_noLocalMountPoints number of entries + // 2. each page is CM_DIR_PAGESIZE in size + // 3. the first 13 chunks of the first page are used for + // some header stuff + // 4. the first chunk of all subsequent pages are used + // for page header stuff + // 5. a max of CM_DIR_EPP entries are allowed per page + // 6. each entry takes 1 or more chunks, depending on + // the size of the mount point string, as determined + // by cm_NameEntries + // 7. each chunk is CM_DIR_CHUNKSIZE bytes + + int CPP = CM_DIR_PAGESIZE / CM_DIR_CHUNKSIZE; + int curChunk = 13; // chunks 0 - 12 are used for header stuff + // of the first page in the directory + int curPage = 0; + int curDirEntry = 0; + int curDirEntryInPage = 0; + int sizeOfCurEntry; + int dirSize; + + /* Reserve 2 directory chunks for "." and ".." */ + curChunk += 2; + + while (curDirEntry!=cm_noLocalMountPoints) { + sizeOfCurEntry = cm_NameEntries((cm_localMountPoints+curDirEntry)->namep, 0); + if ((curChunk + sizeOfCurEntry >= CPP) || + (curDirEntryInPage + 1 >= CM_DIR_EPP)) { + curPage++; + curDirEntryInPage = 0; + curChunk = 1; + } + curChunk += sizeOfCurEntry; + curDirEntry++; + curDirEntryInPage++; + } - // we start counting at 13 because the 0th to 12th chunks are used for header - curChunk = 13; - - // stick the first 2 entries "." and ".." in - fakeEntry.fid.unique = htonl(1); - fakeEntry.fid.vnode = htonl(1); - strcpy(fakeEntry.name, "."); - currentPos = cm_FakeRootDir + curPage * CM_DIR_PAGESIZE + curChunk * CM_DIR_CHUNKSIZE; - memcpy(currentPos, &fakeEntry, CM_DIR_CHUNKSIZE); - curChunk++; curDirEntryInPage++; - strcpy(fakeEntry.name, ".."); - currentPos = cm_FakeRootDir + curPage * CM_DIR_PAGESIZE + curChunk * CM_DIR_CHUNKSIZE; - memcpy(currentPos, &fakeEntry, CM_DIR_CHUNKSIZE); - curChunk++; curDirEntryInPage++; - - // keep putting stuff into page 0 if - // 1. we're not done with all entries - // 2. we have less than CM_DIR_EPP entries in page 0 - // 3. we're not out of chunks in page 0 - - while( (curDirEntry!=cm_noLocalMountPoints) && - (curDirEntryInPage < CM_DIR_EPP) && - (curChunk + cm_NameEntries((cm_localMountPoints+curDirEntry)->namep, 0) <= CPP)) - { - - noChunks = cm_NameEntries((cm_localMountPoints+curDirEntry)->namep, 0); - fakeEntry.fid.vnode = htonl(curDirEntry + 2); - currentPos = cm_FakeRootDir + curPage * CM_DIR_PAGESIZE + curChunk * CM_DIR_CHUNKSIZE; - - memcpy(currentPos, &fakeEntry, CM_DIR_CHUNKSIZE); - strcpy(currentPos + 12, (cm_localMountPoints+curDirEntry)->namep); - curDirEntry++; - curDirEntryInPage++; - for (i=0; inamep, 0) <= CPP)) - { - // add an entry to this page - - noChunks = cm_NameEntries((cm_localMountPoints+curDirEntry)->namep, 0); - fakeEntry.fid.vnode=htonl(curDirEntry+2); - currentPos = cm_FakeRootDir + curPage * CM_DIR_PAGESIZE + curChunk * CM_DIR_CHUNKSIZE; - memcpy(currentPos, &fakeEntry, CM_DIR_CHUNKSIZE); - strcpy(currentPos + 12, (cm_localMountPoints+curDirEntry)->namep); - curDirEntry++; - curDirEntryInPage++; - for (i=0; inamep, 0) <= CPP)) + { + + noChunks = cm_NameEntries((cm_localMountPoints+curDirEntry)->namep, 0); + fakeEntry.fid.vnode = htonl(curDirEntry + 2); + currentPos = cm_FakeRootDir + curPage * CM_DIR_PAGESIZE + curChunk * CM_DIR_CHUNKSIZE; + + memcpy(currentPos, &fakeEntry, CM_DIR_CHUNKSIZE); + strcpy(currentPos + 12, (cm_localMountPoints+curDirEntry)->namep); + curDirEntry++; + curDirEntryInPage++; + for (i=0; inamep, 0) <= CPP)) + { + // add an entry to this page + + noChunks = cm_NameEntries((cm_localMountPoints+curDirEntry)->namep, 0); + fakeEntry.fid.vnode=htonl(curDirEntry+2); + currentPos = cm_FakeRootDir + curPage * CM_DIR_PAGESIZE + curChunk * CM_DIR_CHUNKSIZE; + memcpy(currentPos, &fakeEntry, CM_DIR_CHUNKSIZE); + strcpy(currentPos + 12, (cm_localMountPoints+curDirEntry)->namep); + curDirEntry++; + curDirEntryInPage++; + for (i=0; icell = AFS_FAKE_ROOT_CELL_ID; /* root cell */ - fidp->volume = AFS_FAKE_ROOT_VOL_ID; /* root.afs ? */ - fidp->vnode = 0x1; - fidp->unique = 0x1; - return 0; + fidp->cell = AFS_FAKE_ROOT_CELL_ID; /* root cell */ + fidp->volume = AFS_FAKE_ROOT_VOL_ID; /* root.afs ? */ + fidp->vnode = 0x1; + fidp->unique = 0x1; + return 0; } /* called directly from ioctl */ @@ -307,83 +307,80 @@ int cm_clearLocalMountPointChange() { } int cm_reInitLocalMountPoints() { - cm_fid_t aFid; - int i, hash; - cm_scache_t *scp, **lscpp, *tscp; - - osi_Log0(afsd_logp,"----- freelance reinitialization starts ----- "); - - // first we invalidate all the SCPs that were created - // for the local mount points - - osi_Log0(afsd_logp,"Invalidating local mount point scp... "); - - aFid.cell = AFS_FAKE_ROOT_CELL_ID; - aFid.volume=AFS_FAKE_ROOT_VOL_ID; - aFid.unique=0x1; - aFid.vnode=0x2; - - lock_ObtainWrite(&cm_scacheLock); - lock_ObtainMutex(&cm_Freelance_Lock); /* always scache then freelance lock */ - for (i=0; inextp) { - if (scp->fid.volume == aFid.volume && - scp->fid.vnode == aFid.vnode && - scp->fid.unique == aFid.unique - ) { - - // mark the scp to be reused - lock_ReleaseWrite(&cm_scacheLock); - lock_ObtainMutex(&scp->mx); - cm_DiscardSCache(scp); - lock_ReleaseMutex(&scp->mx); - cm_CallbackNotifyChange(scp); - lock_ObtainWrite(&cm_scacheLock); - scp->refCount--; - - // take the scp out of the hash - lscpp = &cm_hashTablep[hash]; - for (tscp=*lscpp; tscp; lscpp = &tscp->nextp, tscp = *lscpp) { - if (tscp == scp) break; - } - *lscpp = scp->nextp; - scp->flags &= ~CM_SCACHEFLAG_INHASH; - - - } - } - aFid.vnode = aFid.vnode + 1; - } - lock_ReleaseWrite(&cm_scacheLock); - osi_Log0(afsd_logp,"\tall old scp cleared!"); - - // we must free the memory that was allocated in the prev - // cm_InitLocalMountPoints call - osi_Log0(afsd_logp,"Removing old localmountpoints... "); - free(cm_localMountPoints); - osi_Log0(afsd_logp,"\tall old localmountpoints cleared!"); - - // now re-init the localmountpoints - osi_Log0(afsd_logp,"Creating new localmountpoints... "); - cm_InitLocalMountPoints(); - osi_Log0(afsd_logp,"\tcreated new set of localmountpoints!"); + cm_fid_t aFid; + int i, hash; + cm_scache_t *scp, **lscpp, *tscp; - - // now we have to free the memory allocated in cm_initfakerootdir - osi_Log0(afsd_logp,"Removing old fakedir... "); - free(cm_FakeRootDir); - osi_Log0(afsd_logp,"\t\told fakedir removed!"); - - // then we re-create that dir - osi_Log0(afsd_logp,"Creating new fakedir... "); - cm_InitFakeRootDir(); - osi_Log0(afsd_logp,"\t\tcreated new fakedir!"); + osi_Log0(afsd_logp,"----- freelance reinitialization starts ----- "); + + // first we invalidate all the SCPs that were created + // for the local mount points + + osi_Log0(afsd_logp,"Invalidating local mount point scp... "); + + aFid.cell = AFS_FAKE_ROOT_CELL_ID; + aFid.volume=AFS_FAKE_ROOT_VOL_ID; + aFid.unique=0x1; + aFid.vnode=0x2; + + lock_ObtainWrite(&cm_scacheLock); + lock_ObtainMutex(&cm_Freelance_Lock); /* always scache then freelance lock */ + for (i=0; inextp) { + if (scp->fid.volume == aFid.volume && + scp->fid.vnode == aFid.vnode && + scp->fid.unique == aFid.unique + ) { + + // mark the scp to be reused + lock_ReleaseWrite(&cm_scacheLock); + lock_ObtainMutex(&scp->mx); + cm_DiscardSCache(scp); + lock_ReleaseMutex(&scp->mx); + cm_CallbackNotifyChange(scp); + lock_ObtainWrite(&cm_scacheLock); + scp->refCount--; + + // take the scp out of the hash + lscpp = &cm_hashTablep[hash]; + for (tscp=*lscpp; tscp; lscpp = &tscp->nextp, tscp = *lscpp) { + if (tscp == scp) break; + } + *lscpp = scp->nextp; + scp->flags &= ~CM_SCACHEFLAG_INHASH; + } + } + aFid.vnode = aFid.vnode + 1; + } + lock_ReleaseWrite(&cm_scacheLock); + osi_Log0(afsd_logp,"\tall old scp cleared!"); + + // we must free the memory that was allocated in the prev + // cm_InitLocalMountPoints call + osi_Log0(afsd_logp,"Removing old localmountpoints... "); + free(cm_localMountPoints); + osi_Log0(afsd_logp,"\tall old localmountpoints cleared!"); + + // now re-init the localmountpoints + osi_Log0(afsd_logp,"Creating new localmountpoints... "); + cm_InitLocalMountPoints(); + osi_Log0(afsd_logp,"\tcreated new set of localmountpoints!"); + + // now we have to free the memory allocated in cm_initfakerootdir + osi_Log0(afsd_logp,"Removing old fakedir... "); + free(cm_FakeRootDir); + osi_Log0(afsd_logp,"\t\told fakedir removed!"); + + // then we re-create that dir + osi_Log0(afsd_logp,"Creating new fakedir... "); + cm_InitFakeRootDir(); + osi_Log0(afsd_logp,"\t\tcreated new fakedir!"); - lock_ReleaseMutex(&cm_Freelance_Lock); + lock_ReleaseMutex(&cm_Freelance_Lock); - osi_Log0(afsd_logp,"----- freelance reinit complete -----"); - return 0; + osi_Log0(afsd_logp,"----- freelance reinit complete -----"); + return 0; } @@ -392,12 +389,12 @@ int cm_reInitLocalMountPoints() { // process for the freelance client. /* to be called while holding freelance lock unless during init. */ long cm_InitLocalMountPoints() { - FILE *fp; + FILE *fp; int i; - char line[512]; - char* t; - cm_localMountPoint_t* aLocalMountPoint; - char hdir[120]; + char line[512]; + char*t, *t2; + cm_localMountPoint_t* aLocalMountPoint; + char hdir[120]; long code; char rootCellName[256]; #if !defined(DJGPP) @@ -465,6 +462,11 @@ long cm_InitLocalMountPoints() { RegEnumValue( hkFreelance, dwIndex, szValueName, &dwValueSize, NULL, &dwType, line, &dwSize); + /* find the trailing dot; null terminate after it */ + t2 = strrchr(line, '.'); + if (t2) + *(t2+1) = '\0'; + // line is not empty, so let's parse it t = strchr(line, '#'); if (!t) @@ -477,12 +479,13 @@ long cm_InitLocalMountPoints() { continue; } aLocalMountPoint->namep=malloc(t-line+1); - memcpy(aLocalMountPoint->namep, line, t-line); - *(aLocalMountPoint->namep + (t-line)) = 0; + strncpy(aLocalMountPoint->namep, line, t-line); + aLocalMountPoint->namep[t-line] = '\0'; - aLocalMountPoint->mountPointStringp=malloc(strlen(line) - (t-line) + 1); - memcpy(aLocalMountPoint->mountPointStringp, t, strlen(line)-(t-line)-2); - *(aLocalMountPoint->mountPointStringp + (strlen(line)-(t-line)-2)) = 0; + /* copy the mount point string without the trailing dot */ + aLocalMountPoint->mountPointStringp=malloc(strlen(t)); + strncpy(aLocalMountPoint->mountPointStringp, t, strlen(t)-1); + aLocalMountPoint->mountPointStringp[strlen(t)-1] = '\0'; osi_Log2(afsd_logp,"found mount point: name %s, string %s", osi_LogSaveString(afsd_logp,aLocalMountPoint->namep), @@ -499,13 +502,13 @@ long cm_InitLocalMountPoints() { /* What follows is the old code to read freelance mount points * out of a text file modified to copy the data into the registry */ - cm_GetConfigDir(hdir); - strcat(hdir, AFS_FREELANCE_INI); - // open the ini file for reading - fp = fopen(hdir, "r"); + cm_GetConfigDir(hdir); + strcat(hdir, AFS_FREELANCE_INI); + // open the ini file for reading + fp = fopen(hdir, "r"); - // if we fail to open the file, create an empty one - if (!fp) { + // if we fail to open the file, create an empty one + if (!fp) { fp = fopen(hdir, "w"); code = cm_GetRootCellName(rootCellName); if (code == 0) { @@ -519,10 +522,10 @@ long cm_InitLocalMountPoints() { fclose(fp); return 0; /* success */ } - } + } - // we successfully opened the file - osi_Log0(afsd_logp,"opened afs_freelance.ini"); + // we successfully opened the file + osi_Log0(afsd_logp,"opened afs_freelance.ini"); #if !defined(DJGPP) RegCreateKeyEx( HKEY_LOCAL_MACHINE, @@ -537,41 +540,41 @@ long cm_InitLocalMountPoints() { dwIndex = 0; #endif - // now we read the first line to see how many entries - // there are - fgets(line, sizeof(line), fp); - - // if the line is empty at any point when we're reading - // we're screwed. report error and return. - if (*line==0) { - afsi_log("error occurred while reading afs_freelance.ini"); - fprintf(stderr, "error occurred while reading afs_freelance.ini"); - return -1; - } - - // get the number of entries there are from the first line - // that we read - cm_noLocalMountPoints = atoi(line); - - // create space to store the local mount points - cm_localMountPoints = malloc(sizeof(cm_localMountPoint_t) * cm_noLocalMountPoints); - aLocalMountPoint = cm_localMountPoints; - - // now we read n lines and parse them into local mount points - // where n is the number of local mount points there are, as - // determined above. - // Each line in the ini file represents 1 local mount point and - // is in the format xxx#yyy:zzz, where xxx is the directory - // entry name, yyy is the cell name and zzz is the volume name. - // #yyy:zzz together make up the mount point. - for (i=0; inamep=malloc(t-line+1); - memcpy(aLocalMountPoint->namep, line, t-line); - *(aLocalMountPoint->namep + (t-line)) = 0; - + // make sure that there is a '#' or '%' separator in the line + if (!t) { + afsi_log("error occurred while parsing entry in %s: no # or %% separator in line %d", AFS_FREELANCE_INI, i); + fprintf(stderr, "error occurred while parsing entry in afs_freelance.ini: no # or %% separator in line %d", i); + return -1; + } + aLocalMountPoint->namep=malloc(t-line+1); + memcpy(aLocalMountPoint->namep, line, t-line); + *(aLocalMountPoint->namep + (t-line)) = 0; + aLocalMountPoint->mountPointStringp=malloc(strlen(line) - (t-line) + 1); - memcpy(aLocalMountPoint->mountPointStringp, t, strlen(line)-(t-line)-2); - *(aLocalMountPoint->mountPointStringp + (strlen(line)-(t-line)-2)) = 0; - + memcpy(aLocalMountPoint->mountPointStringp, t, strlen(line)-(t-line)-2); + *(aLocalMountPoint->mountPointStringp + (strlen(line)-(t-line)-2)) = 0; + osi_Log2(afsd_logp,"found mount point: name %s, string %s", aLocalMountPoint->namep, aLocalMountPoint->mountPointStringp); aLocalMountPoint++; - } - fclose(fp); + } + fclose(fp); #if !defined(DJGPP) if ( hkFreelance ) { RegCloseKey(hkFreelance); DeleteFile(hdir); } #endif - return 0; + return 0; } int cm_getNoLocalMountPoints() { - return cm_noLocalMountPoints; + return cm_noLocalMountPoints; } cm_localMountPoint_t* cm_getLocalMountPoint(int vnode) { - return 0; + return 0; } long cm_FreelanceAddMount(char *filename, char *cellname, char *volume, int rw, cm_fid_t *fidp) diff --git a/src/WINNT/afsd/cm_freelance.h b/src/WINNT/afsd/cm_freelance.h index b7d90e3e7..3d02b9e09 100644 --- a/src/WINNT/afsd/cm_freelance.h +++ b/src/WINNT/afsd/cm_freelance.h @@ -17,11 +17,11 @@ extern void cm_InitFreelance(); extern long cm_FreelanceRemoveMount(char *toremove); extern long cm_FreelanceAddMount(char *filename, char *cellname, char *volume, int rw, cm_fid_t *fidp); extern int cm_clearLocalMountPointChange(); - +extern int cm_FakeRootFid(cm_fid_t *fidp); #define AFS_FREELANCE_INI "afs_freelance.ini" #define AFS_FAKE_ROOT_CELL_ID 0xFFFFFFFF #define AFS_FAKE_ROOT_VOL_ID 0xFFFFFFFF -extern afs_uint32 FakeFreelanceModTime; +extern time_t FakeFreelanceModTime; #endif // _CM_FREELANCE_H diff --git a/src/WINNT/afsd/cm_ioctl.c b/src/WINNT/afsd/cm_ioctl.c index 169861875..13bd7a48f 100644 --- a/src/WINNT/afsd/cm_ioctl.c +++ b/src/WINNT/afsd/cm_ioctl.c @@ -39,6 +39,7 @@ #endif #include "cm_rpc.h" +#include #ifdef _DEBUG #include @@ -53,27 +54,29 @@ osi_mutex_t cm_Afsdsbmt_Lock; extern afs_int32 cryptall; extern char cm_NetbiosName[]; +extern void afsi_log(char *pattern, ...); + void cm_InitIoctl(void) { - lock_InitializeMutex(&cm_Afsdsbmt_Lock, "AFSDSBMT.INI Access Lock"); + lock_InitializeMutex(&cm_Afsdsbmt_Lock, "AFSDSBMT.INI Access Lock"); } long cm_FlushFile(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp) { - long code; + long code; - lock_ObtainWrite(&scp->bufCreateLock); - code = buf_FlushCleanPages(scp, userp, reqp); + lock_ObtainWrite(&scp->bufCreateLock); + code = buf_FlushCleanPages(scp, userp, reqp); - lock_ObtainMutex(&scp->mx); - scp->cbServerp = NULL; - scp->cbExpires = 0; - lock_ReleaseMutex(&scp->mx); + lock_ObtainMutex(&scp->mx); + scp->cbServerp = NULL; + scp->cbExpires = 0; + lock_ReleaseMutex(&scp->mx); - lock_ReleaseWrite(&scp->bufCreateLock); - cm_dnlcPurgedp(scp); + lock_ReleaseWrite(&scp->bufCreateLock); + cm_dnlcPurgedp(scp); - return code; + return code; } /* @@ -82,23 +85,23 @@ long cm_FlushFile(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp) */ void cm_ResetACLCache(cm_user_t *userp) { - cm_scache_t *scp; - int hash; - - lock_ObtainWrite(&cm_scacheLock); - for (hash=0; hash < cm_hashTableSize; hash++) { - for (scp=cm_hashTablep[hash]; scp; scp=scp->nextp) { - scp->refCount++; - lock_ReleaseWrite(&cm_scacheLock); - lock_ObtainMutex(&scp->mx); - cm_InvalidateACLUser(scp, userp); - lock_ReleaseMutex(&scp->mx); - lock_ObtainWrite(&cm_scacheLock); - scp->refCount--; - } - } - lock_ReleaseWrite(&cm_scacheLock); -} + cm_scache_t *scp; + int hash; + + lock_ObtainWrite(&cm_scacheLock); + for (hash=0; hash < cm_hashTableSize; hash++) { + for (scp=cm_hashTablep[hash]; scp; scp=scp->nextp) { + scp->refCount++; + lock_ReleaseWrite(&cm_scacheLock); + lock_ObtainMutex(&scp->mx); + cm_InvalidateACLUser(scp, userp); + lock_ReleaseMutex(&scp->mx); + lock_ObtainWrite(&cm_scacheLock); + scp->refCount--; + } + } + lock_ReleaseWrite(&cm_scacheLock); +} /* * TranslateExtendedChars - This is a fix for TR 54482. @@ -136,8 +139,8 @@ void TranslateExtendedChars(char *str) long cm_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp, cm_scache_t **scpp) { - long code; - cm_scache_t *substRootp; + long code; + cm_scache_t *substRootp; char * relativePath = ioctlp->inDatap; /* This is usually the file name, but for StatMountPoint it is the path. */ @@ -147,7 +150,7 @@ long cm_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp, * \\netbios-name\submount\path\. * \\netbios-name\submount\path\file */ - TranslateExtendedChars(relativePath); + TranslateExtendedChars(relativePath); if (relativePath[0] == relativePath[1] && relativePath[1] == '\\' && @@ -180,67 +183,73 @@ long cm_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, userp, sharePath, reqp, &substRootp); free(sharePath); - if (code) return code; + if (code) + return code; - code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, - userp, NULL, reqp, scpp); - if (code) return code; + code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, + userp, NULL, reqp, scpp); + if (code) + return code; } else { /* otherwise, treat the name as a cellname mounted off the afs root. - * This requires that we reconstruct the shareName string with - * leading and trailing slashes. - */ + * This requires that we reconstruct the shareName string with + * leading and trailing slashes. + */ p = relativePath + 2 + strlen(cm_NetbiosName) + 1; - if ( !_strnicmp("all", p, 3) ) - p += 4; - - shareName[0] = '/'; - for (i = 1; *p && *p != '\\'; i++,p++ ) { - shareName[i] = *p; - } - p++; /* skip past trailing slash */ - shareName[i++] = '/'; /* add trailing slash */ - shareName[i] = 0; /* terminate string */ - - - code = cm_NameI(cm_rootSCachep, ioctlp->prefix->data, + if ( !_strnicmp("all", p, 3) ) + p += 4; + + shareName[0] = '/'; + for (i = 1; *p && *p != '\\'; i++,p++ ) { + shareName[i] = *p; + } + p++; /* skip past trailing slash */ + shareName[i++] = '/'; /* add trailing slash */ + shareName[i] = 0; /* terminate string */ + + + code = cm_NameI(cm_rootSCachep, ioctlp->prefix->data, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, userp, shareName, reqp, &substRootp); - if (code) return code; + if (code) + return code; - code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, - userp, NULL, reqp, scpp); - if (code) return code; + code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, + userp, NULL, reqp, scpp); + if (code) + return code; } } else { code = cm_NameI(cm_rootSCachep, ioctlp->prefix->data, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, userp, ioctlp->tidPathp, reqp, &substRootp); - if (code) return code; + if (code) + return code; code = cm_NameI(substRootp, relativePath, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, userp, NULL, reqp, scpp); - if (code) return code; + if (code) + return code; } - /* # of bytes of path */ + /* # of bytes of path */ code = strlen(ioctlp->inDatap) + 1; ioctlp->inDatap += code; /* This is usually nothing, but for StatMountPoint it is the file name. */ TranslateExtendedChars(ioctlp->inDatap); - /* and return success */ + /* and return success */ return 0; } void cm_SkipIoctlPath(smb_ioctl_t *ioctlp) { - long temp; + long temp; - temp = strlen(ioctlp->inDatap) + 1; - ioctlp->inDatap += temp; -} + temp = strlen(ioctlp->inDatap) + 1; + ioctlp->inDatap += temp; +} /* format the specified path to look like "/afs//usr", by @@ -252,33 +261,33 @@ void cm_SkipIoctlPath(smb_ioctl_t *ioctlp) */ void cm_NormalizeAfsPath (char *outpathp, char *inpathp) { - char *cp; + char *cp; char bslash_mountRoot[256]; strncpy(bslash_mountRoot, cm_mountRoot, sizeof(bslash_mountRoot) - 1); bslash_mountRoot[0] = '\\'; if (!strnicmp (inpathp, cm_mountRoot, strlen(cm_mountRoot))) - lstrcpy (outpathp, inpathp); - else if (!strnicmp (inpathp, bslash_mountRoot, strlen(bslash_mountRoot))) - lstrcpy (outpathp, inpathp); - else if ((inpathp[0] == '/') || (inpathp[0] == '\\')) - sprintf (outpathp, "%s%s", cm_mountRoot, inpathp); - else // inpathp looks like "/usr" - sprintf (outpathp, "%s/%s", cm_mountRoot, inpathp); - - for (cp = outpathp; *cp != 0; ++cp) { - if (*cp == '\\') - *cp = '/'; - } - - if (strlen(outpathp) && (outpathp[strlen(outpathp)-1] == '/')) { - outpathp[strlen(outpathp)-1] = 0; - } - - if (!strcmpi (outpathp, cm_mountRoot)) { + lstrcpy (outpathp, inpathp); + else if (!strnicmp (inpathp, bslash_mountRoot, strlen(bslash_mountRoot))) + lstrcpy (outpathp, inpathp); + else if ((inpathp[0] == '/') || (inpathp[0] == '\\')) + sprintf (outpathp, "%s%s", cm_mountRoot, inpathp); + else // inpathp looks like "/usr" + sprintf (outpathp, "%s/%s", cm_mountRoot, inpathp); + + for (cp = outpathp; *cp != 0; ++cp) { + if (*cp == '\\') + *cp = '/'; + } + + if (strlen(outpathp) && (outpathp[strlen(outpathp)-1] == '/')) { + outpathp[strlen(outpathp)-1] = 0; + } + + if (!strcmpi (outpathp, cm_mountRoot)) { strcpy (outpathp, cm_mountRoot); - } + } } /* parse the passed-in file name and do a namei on its parent. If we fail, @@ -287,28 +296,28 @@ void cm_NormalizeAfsPath (char *outpathp, char *inpathp) long cm_ParseIoctlParent(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp, cm_scache_t **scpp, char *leafp) { - long code; + long code; char tbuffer[1024]; char *tp, *jp; - cm_scache_t *substRootp; + cm_scache_t *substRootp; - strcpy(tbuffer, ioctlp->inDatap); + strcpy(tbuffer, ioctlp->inDatap); tp = strrchr(tbuffer, '\\'); - jp = strrchr(tbuffer, '/'); - if (!tp) - tp = jp; - else if (jp && (tp - tbuffer) < (jp - tbuffer)) - tp = jp; + jp = strrchr(tbuffer, '/'); + if (!tp) + tp = jp; + else if (jp && (tp - tbuffer) < (jp - tbuffer)) + tp = jp; if (!tp) { strcpy(tbuffer, "\\"); if (leafp) strcpy(leafp, ioctlp->inDatap); - } + } else { *tp = 0; if (leafp) strcpy(leafp, tp+1); - } + } if (tbuffer[0] == tbuffer[1] && tbuffer[1] == '\\' && @@ -343,722 +352,740 @@ long cm_ParseIoctlParent(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp, free(sharePath); if (code) return code; - code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, - userp, NULL, reqp, scpp); - if (code) return code; + code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, + userp, NULL, reqp, scpp); + if (code) return code; } else { /* otherwise, treat the name as a cellname mounted off the afs root. - * This requires that we reconstruct the shareName string with - * leading and trailing slashes. - */ + * This requires that we reconstruct the shareName string with + * leading and trailing slashes. + */ p = tbuffer + 2 + strlen(cm_NetbiosName) + 1; - if ( !_strnicmp("all", p, 3) ) - p += 4; - - shareName[0] = '/'; - for (i = 1; *p && *p != '\\'; i++,p++ ) { - shareName[i] = *p; - } - p++; /* skip past trailing slash */ - shareName[i++] = '/'; /* add trailing slash */ - shareName[i] = 0; /* terminate string */ - - code = cm_NameI(cm_rootSCachep, ioctlp->prefix->data, + if ( !_strnicmp("all", p, 3) ) + p += 4; + + shareName[0] = '/'; + for (i = 1; *p && *p != '\\'; i++,p++ ) { + shareName[i] = *p; + } + p++; /* skip past trailing slash */ + shareName[i++] = '/'; /* add trailing slash */ + shareName[i] = 0; /* terminate string */ + + code = cm_NameI(cm_rootSCachep, ioctlp->prefix->data, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, userp, shareName, reqp, &substRootp); if (code) return code; - code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, - userp, NULL, reqp, scpp); - if (code) return code; + code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, + userp, NULL, reqp, scpp); + if (code) return code; } } else { code = cm_NameI(cm_rootSCachep, ioctlp->prefix->data, - CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, - userp, ioctlp->tidPathp, reqp, &substRootp); + CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, + userp, ioctlp->tidPathp, reqp, &substRootp); if (code) return code; code = cm_NameI(substRootp, tbuffer, CM_FLAG_FOLLOW, - userp, NULL, reqp, scpp); + userp, NULL, reqp, scpp); if (code) return code; } - /* # of bytes of path */ - code = strlen(ioctlp->inDatap) + 1; - ioctlp->inDatap += code; + /* # of bytes of path */ + code = strlen(ioctlp->inDatap) + 1; + ioctlp->inDatap += code; - /* and return success */ - return 0; + /* and return success */ + return 0; } long cm_IoctlGetACL(smb_ioctl_t *ioctlp, cm_user_t *userp) { - cm_conn_t *connp; - cm_scache_t *scp; - AFSOpaque acl; - AFSFetchStatus fileStatus; - AFSVolSync volSync; - long code; - AFSFid fid; - int tlen; - cm_req_t req; + cm_conn_t *connp; + cm_scache_t *scp; + AFSOpaque acl; + AFSFetchStatus fileStatus; + AFSVolSync volSync; + long code; + AFSFid fid; + int tlen; + cm_req_t req; + struct rx_connection * callp; - cm_InitReq(&req); + cm_InitReq(&req); - code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp); - if (code) return code; - - /* now make the get acl call */ - fid.Volume = scp->fid.volume; - fid.Vnode = scp->fid.vnode; - fid.Unique = scp->fid.unique; - do { - acl.AFSOpaque_val = ioctlp->outDatap; - acl.AFSOpaque_len = 0; - code = cm_Conn(&scp->fid, userp, &req, &connp); - if (code) continue; - - code = RXAFS_FetchACL(connp->callp, &fid, &acl, &fileStatus, &volSync); - } while (cm_Analyze(connp, userp, &req, &scp->fid, &volSync, NULL, NULL, code)); - code = cm_MapRPCError(code, &req); - cm_ReleaseSCache(scp); - - if (code) return code; - - /* skip over return data */ - tlen = strlen(ioctlp->outDatap) + 1; - ioctlp->outDatap += tlen; + code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp); + if (code) return code; - /* and return success */ - return 0; + /* now make the get acl call */ + fid.Volume = scp->fid.volume; + fid.Vnode = scp->fid.vnode; + fid.Unique = scp->fid.unique; + do { + acl.AFSOpaque_val = ioctlp->outDatap; + acl.AFSOpaque_len = 0; + code = cm_Conn(&scp->fid, userp, &req, &connp); + if (code) continue; + + callp = cm_GetRxConn(connp); + code = RXAFS_FetchACL(callp, &fid, &acl, &fileStatus, &volSync); + rx_PutConnection(callp); + + } while (cm_Analyze(connp, userp, &req, &scp->fid, &volSync, NULL, NULL, code)); + code = cm_MapRPCError(code, &req); + cm_ReleaseSCache(scp); + + if (code) return code; + + /* skip over return data */ + tlen = strlen(ioctlp->outDatap) + 1; + ioctlp->outDatap += tlen; + + /* and return success */ + return 0; } long cm_IoctlGetFileCellName(struct smb_ioctl *ioctlp, struct cm_user *userp) { - long code; - cm_scache_t *scp; - cm_cell_t *cellp; - cm_req_t req; + long code; + cm_scache_t *scp; + cm_cell_t *cellp; + cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); - code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp); - if (code) return code; - - cellp = cm_FindCellByID(scp->fid.cell); - if (cellp) { - strcpy(ioctlp->outDatap, cellp->namep); - ioctlp->outDatap += strlen(ioctlp->outDatap) + 1; - code = 0; - } - else code = CM_ERROR_NOSUCHCELL; - - cm_ReleaseSCache(scp); - return code; + code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp); + if (code) return code; + + cellp = cm_FindCellByID(scp->fid.cell); + if (cellp) { + strcpy(ioctlp->outDatap, cellp->namep); + ioctlp->outDatap += strlen(ioctlp->outDatap) + 1; + code = 0; + } + else code = CM_ERROR_NOSUCHCELL; + + cm_ReleaseSCache(scp); + return code; } long cm_IoctlSetACL(struct smb_ioctl *ioctlp, struct cm_user *userp) { - cm_conn_t *connp; - cm_scache_t *scp; - AFSOpaque acl; - AFSFetchStatus fileStatus; - AFSVolSync volSync; - long code; - AFSFid fid; - cm_req_t req; + cm_conn_t *connp; + cm_scache_t *scp; + AFSOpaque acl; + AFSFetchStatus fileStatus; + AFSVolSync volSync; + long code; + AFSFid fid; + cm_req_t req; + struct rx_connection * callp; - cm_InitReq(&req); + cm_InitReq(&req); - code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp); - if (code) return code; + code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp); + if (code) return code; - /* now make the get acl call */ - fid.Volume = scp->fid.volume; - fid.Vnode = scp->fid.vnode; - fid.Unique = scp->fid.unique; - do { - acl.AFSOpaque_val = ioctlp->inDatap; - acl.AFSOpaque_len = strlen(ioctlp->inDatap)+1; - code = cm_Conn(&scp->fid, userp, &req, &connp); - if (code) continue; - - code = RXAFS_StoreACL(connp->callp, &fid, &acl, &fileStatus, &volSync); - } while (cm_Analyze(connp, userp, &req, &scp->fid, &volSync, NULL, NULL, code)); - code = cm_MapRPCError(code, &req); - - /* invalidate cache info, since we just trashed the ACL cache */ - lock_ObtainMutex(&scp->mx); - cm_DiscardSCache(scp); - lock_ReleaseMutex(&scp->mx); - - cm_ReleaseSCache(scp); - - return code; + /* now make the get acl call */ + fid.Volume = scp->fid.volume; + fid.Vnode = scp->fid.vnode; + fid.Unique = scp->fid.unique; + do { + acl.AFSOpaque_val = ioctlp->inDatap; + acl.AFSOpaque_len = strlen(ioctlp->inDatap)+1; + code = cm_Conn(&scp->fid, userp, &req, &connp); + if (code) continue; + + callp = cm_GetRxConn(connp); + code = RXAFS_StoreACL(callp, &fid, &acl, &fileStatus, &volSync); + rx_PutConnection(callp); + + } while (cm_Analyze(connp, userp, &req, &scp->fid, &volSync, NULL, NULL, code)); + code = cm_MapRPCError(code, &req); + + /* invalidate cache info, since we just trashed the ACL cache */ + lock_ObtainMutex(&scp->mx); + cm_DiscardSCache(scp); + lock_ReleaseMutex(&scp->mx); + + cm_ReleaseSCache(scp); + + return code; } long cm_IoctlFlushVolume(struct smb_ioctl *ioctlp, struct cm_user *userp) { - long code; - cm_scache_t *scp; - unsigned long volume; - int i; - cm_req_t req; + long code; + cm_scache_t *scp; + unsigned long volume; + int i; + cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); - code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp); - if (code) return code; + code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp); + if (code) return code; - volume = scp->fid.volume; - cm_ReleaseSCache(scp); - - lock_ObtainWrite(&cm_scacheLock); - for(i=0; inextp) { - if (scp->fid.volume == volume) { - scp->refCount++; - lock_ReleaseWrite(&cm_scacheLock); - - /* now flush the file */ - cm_FlushFile(scp, userp, &req); + volume = scp->fid.volume; + cm_ReleaseSCache(scp); - lock_ObtainWrite(&cm_scacheLock); - scp->refCount--; - } - } + lock_ObtainWrite(&cm_scacheLock); + for (i=0; inextp) { + if (scp->fid.volume == volume) { + scp->refCount++; + lock_ReleaseWrite(&cm_scacheLock); + + /* now flush the file */ + code = cm_FlushFile(scp, userp, &req); + if ( code ) + afsi_log("cm_FlushFile returns error: [%x]",code); + lock_ObtainWrite(&cm_scacheLock); + scp->refCount--; + } } - lock_ReleaseWrite(&cm_scacheLock); + } + lock_ReleaseWrite(&cm_scacheLock); - return code; + return code; } long cm_IoctlFlushFile(struct smb_ioctl *ioctlp, struct cm_user *userp) { - long code; - cm_scache_t *scp; - cm_req_t req; + long code; + cm_scache_t *scp; + cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); - code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp); - if (code) return code; + code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp); + if (code) return code; - cm_FlushFile(scp, userp, &req); - cm_ReleaseSCache(scp); + cm_FlushFile(scp, userp, &req); + cm_ReleaseSCache(scp); - return 0; + return 0; } long cm_IoctlSetVolumeStatus(struct smb_ioctl *ioctlp, struct cm_user *userp) { - cm_scache_t *scp; - char volName[32]; - char offLineMsg[256]; - char motd[256]; - cm_conn_t *tcp; - long code; - AFSFetchVolumeStatus volStat; - AFSStoreVolumeStatus storeStat; - cm_volume_t *tvp; - char *cp; - cm_cell_t *cellp; - cm_req_t req; - - cm_InitReq(&req); - - code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp); - if (code) return code; + cm_scache_t *scp; + char volName[32]; + char offLineMsg[256]; + char motd[256]; + cm_conn_t *tcp; + long code; + AFSFetchVolumeStatus volStat; + AFSStoreVolumeStatus storeStat; + cm_volume_t *tvp; + char *cp; + cm_cell_t *cellp; + cm_req_t req; + struct rx_connection * callp; - cellp = cm_FindCellByID(scp->fid.cell); - osi_assert(cellp); + cm_InitReq(&req); - if (scp->flags & CM_SCACHEFLAG_RO) { - cm_ReleaseSCache(scp); - return CM_ERROR_READONLY; - } + code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp); + if (code) return code; - code = cm_GetVolumeByID(cellp, scp->fid.volume, userp, &req, &tvp); - if (code) { - cm_ReleaseSCache(scp); - return code; - } - - /* Copy the junk out, using cp as a roving pointer. */ - cp = ioctlp->inDatap; - memcpy((char *)&volStat, cp, sizeof(AFSFetchVolumeStatus)); - cp += sizeof(AFSFetchVolumeStatus); - strcpy(volName, cp); - cp += strlen(volName)+1; - strcpy(offLineMsg, cp); - cp += strlen(offLineMsg)+1; - strcpy(motd, cp); - storeStat.Mask = 0; - if (volStat.MinQuota != -1) { - storeStat.MinQuota = volStat.MinQuota; - storeStat.Mask |= AFS_SETMINQUOTA; - } - if (volStat.MaxQuota != -1) { - storeStat.MaxQuota = volStat.MaxQuota; - storeStat.Mask |= AFS_SETMAXQUOTA; - } - - do { - code = cm_Conn(&scp->fid, userp, &req, &tcp); - if (code) continue; - - code = RXAFS_SetVolumeStatus(tcp->callp, scp->fid.volume, - &storeStat, volName, offLineMsg, motd); - } while (cm_Analyze(tcp, userp, &req, &scp->fid, NULL, NULL, NULL, code)); - code = cm_MapRPCError(code, &req); - - /* return on failure */ - cm_ReleaseSCache(scp); - if (code) { - return code; - } - - /* we are sending parms back to make compat. with prev system. should - * change interface later to not ask for current status, just set - * new status - */ - cp = ioctlp->outDatap; - memcpy(cp, (char *)&volStat, sizeof(VolumeStatus)); - cp += sizeof(VolumeStatus); - strcpy(cp, volName); - cp += strlen(volName)+1; - strcpy(cp, offLineMsg); - cp += strlen(offLineMsg)+1; - strcpy(cp, motd); - cp += strlen(motd)+1; - - /* now return updated return data pointer */ - ioctlp->outDatap = cp; - - return 0; -} + cellp = cm_FindCellByID(scp->fid.cell); + osi_assert(cellp); + + if (scp->flags & CM_SCACHEFLAG_RO) { + cm_ReleaseSCache(scp); + return CM_ERROR_READONLY; + } + + code = cm_GetVolumeByID(cellp, scp->fid.volume, userp, &req, &tvp); + if (code) { + cm_ReleaseSCache(scp); + return code; + } + + /* Copy the junk out, using cp as a roving pointer. */ + cp = ioctlp->inDatap; + memcpy((char *)&volStat, cp, sizeof(AFSFetchVolumeStatus)); + cp += sizeof(AFSFetchVolumeStatus); + strcpy(volName, cp); + cp += strlen(volName)+1; + strcpy(offLineMsg, cp); + cp += strlen(offLineMsg)+1; + strcpy(motd, cp); + storeStat.Mask = 0; + if (volStat.MinQuota != -1) { + storeStat.MinQuota = volStat.MinQuota; + storeStat.Mask |= AFS_SETMINQUOTA; + } + if (volStat.MaxQuota != -1) { + storeStat.MaxQuota = volStat.MaxQuota; + storeStat.Mask |= AFS_SETMAXQUOTA; + } + + do { + code = cm_Conn(&scp->fid, userp, &req, &tcp); + if (code) continue; + + callp = cm_GetRxConn(tcp); + code = RXAFS_SetVolumeStatus(callp, scp->fid.volume, + &storeStat, volName, offLineMsg, motd); + rx_PutConnection(callp); + + } while (cm_Analyze(tcp, userp, &req, &scp->fid, NULL, NULL, NULL, code)); + code = cm_MapRPCError(code, &req); + + /* return on failure */ + cm_ReleaseSCache(scp); + if (code) { + return code; + } + + /* we are sending parms back to make compat. with prev system. should + * change interface later to not ask for current status, just set + * new status + */ + cp = ioctlp->outDatap; + memcpy(cp, (char *)&volStat, sizeof(VolumeStatus)); + cp += sizeof(VolumeStatus); + strcpy(cp, volName); + cp += strlen(volName)+1; + strcpy(cp, offLineMsg); + cp += strlen(offLineMsg)+1; + strcpy(cp, motd); + cp += strlen(motd)+1; + + /* now return updated return data pointer */ + ioctlp->outDatap = cp; + + return 0; +} long cm_IoctlGetVolumeStatus(struct smb_ioctl *ioctlp, struct cm_user *userp) { - char volName[32]; - cm_scache_t *scp; - char offLineMsg[256]; - char motd[256]; - cm_conn_t *tcp; - register long code; - AFSFetchVolumeStatus volStat; - register char *cp; - char *Name; - char *OfflineMsg; - char *MOTD; - cm_req_t req; - - cm_InitReq(&req); - - code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp); - if (code) return code; + char volName[32]; + cm_scache_t *scp; + char offLineMsg[256]; + char motd[256]; + cm_conn_t *tcp; + register long code; + AFSFetchVolumeStatus volStat; + register char *cp; + char *Name; + char *OfflineMsg; + char *MOTD; + cm_req_t req; + struct rx_connection * callp; + + cm_InitReq(&req); + + code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp); + if (code) return code; - Name = volName; - OfflineMsg = offLineMsg; - MOTD = motd; - do { - code = cm_Conn(&scp->fid, userp, &req, &tcp); - if (code) continue; - - code = RXAFS_GetVolumeStatus(tcp->callp, scp->fid.volume, - &volStat, &Name, &OfflineMsg, &MOTD); - } while (cm_Analyze(tcp, userp, &req, &scp->fid, NULL, NULL, NULL, code)); - code = cm_MapRPCError(code, &req); - - cm_ReleaseSCache(scp); - if (code) return code; - - /* Copy all this junk into msg->im_data, keeping track of the lengths. */ - cp = ioctlp->outDatap; - memcpy(cp, (char *)&volStat, sizeof(AFSFetchVolumeStatus)); - cp += sizeof(AFSFetchVolumeStatus); - strcpy(cp, volName); - cp += strlen(volName)+1; - strcpy(cp, offLineMsg); - cp += strlen(offLineMsg)+1; - strcpy(cp, motd); - cp += strlen(motd)+1; - - /* return new size */ - ioctlp->outDatap = cp; - - return 0; + Name = volName; + OfflineMsg = offLineMsg; + MOTD = motd; + do { + code = cm_Conn(&scp->fid, userp, &req, &tcp); + if (code) continue; + + callp = cm_GetRxConn(tcp); + code = RXAFS_GetVolumeStatus(callp, scp->fid.volume, + &volStat, &Name, &OfflineMsg, &MOTD); + rx_PutConnection(callp); + + } while (cm_Analyze(tcp, userp, &req, &scp->fid, NULL, NULL, NULL, code)); + code = cm_MapRPCError(code, &req); + + cm_ReleaseSCache(scp); + if (code) return code; + + /* Copy all this junk into msg->im_data, keeping track of the lengths. */ + cp = ioctlp->outDatap; + memcpy(cp, (char *)&volStat, sizeof(AFSFetchVolumeStatus)); + cp += sizeof(AFSFetchVolumeStatus); + strcpy(cp, volName); + cp += strlen(volName)+1; + strcpy(cp, offLineMsg); + cp += strlen(offLineMsg)+1; + strcpy(cp, motd); + cp += strlen(motd)+1; + + /* return new size */ + ioctlp->outDatap = cp; + + return 0; } long cm_IoctlWhereIs(struct smb_ioctl *ioctlp, struct cm_user *userp) { - long code; + long code; cm_scache_t *scp; cm_cell_t *cellp; cm_volume_t *tvp; - cm_serverRef_t **tsrpp, *current; + cm_serverRef_t **tsrpp, *current; cm_server_t *tsp; unsigned long volume; char *cp; cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp); if (code) return code; - volume = scp->fid.volume; + volume = scp->fid.volume; - cellp = cm_FindCellByID(scp->fid.cell); + cellp = cm_FindCellByID(scp->fid.cell); osi_assert(cellp); cm_ReleaseSCache(scp); - code = cm_GetVolumeByID(cellp, volume, userp, &req, &tvp); + code = cm_GetVolumeByID(cellp, volume, userp, &req, &tvp); if (code) return code; cp = ioctlp->outDatap; - lock_ObtainMutex(&tvp->mx); - tsrpp = cm_GetVolServers(tvp, volume); - lock_ObtainRead(&cm_serverLock); - for (current = *tsrpp; current; current = current->next) { - tsp = current->server; - memcpy(cp, (char *)&tsp->addr.sin_addr.s_addr, sizeof(long)); - cp += sizeof(long); - } - lock_ReleaseRead(&cm_serverLock); + lock_ObtainMutex(&tvp->mx); + tsrpp = cm_GetVolServers(tvp, volume); + lock_ObtainRead(&cm_serverLock); + for (current = *tsrpp; current; current = current->next) { + tsp = current->server; + memcpy(cp, (char *)&tsp->addr.sin_addr.s_addr, sizeof(long)); + cp += sizeof(long); + } + lock_ReleaseRead(&cm_serverLock); cm_FreeServerList(tsrpp); lock_ReleaseMutex(&tvp->mx); - /* still room for terminating NULL, add it on */ - volume = 0; /* reuse vbl */ - memcpy(cp, (char *)&volume, sizeof(long)); - cp += sizeof(long); + /* still room for terminating NULL, add it on */ + volume = 0; /* reuse vbl */ + memcpy(cp, (char *)&volume, sizeof(long)); + cp += sizeof(long); - ioctlp->outDatap = cp; - cm_PutVolume(tvp); - return 0; -} + ioctlp->outDatap = cp; + cm_PutVolume(tvp); + return 0; +} long cm_IoctlStatMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp) { - long code; - cm_scache_t *dscp; - cm_scache_t *scp; - char *cp; - cm_req_t req; + long code; + cm_scache_t *dscp; + cm_scache_t *scp; + char *cp; + cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); - code = cm_ParseIoctlPath(ioctlp, userp, &req, &dscp); - if (code) return code; - - cp = ioctlp->inDatap; + code = cm_ParseIoctlPath(ioctlp, userp, &req, &dscp); + if (code) return code; - code = cm_Lookup(dscp, cp, CM_FLAG_NOMOUNTCHASE, userp, &req, &scp); - cm_ReleaseSCache(dscp); - if (code) return code; + cp = ioctlp->inDatap; + + code = cm_Lookup(dscp, cp, CM_FLAG_NOMOUNTCHASE, userp, &req, &scp); + cm_ReleaseSCache(dscp); + if (code) return code; - lock_ObtainMutex(&scp->mx); + lock_ObtainMutex(&scp->mx); - /* now check that this is a real mount point */ - if (scp->fileType != CM_SCACHETYPE_MOUNTPOINT) { - lock_ReleaseMutex(&scp->mx); - cm_ReleaseSCache(scp); - return CM_ERROR_INVAL; - } - - code = cm_ReadMountPoint(scp, userp, &req); - if (code == 0) { - cp = ioctlp->outDatap; - strcpy(cp, scp->mountPointStringp); - cp += strlen(cp) + 1; - ioctlp->outDatap = cp; - } - lock_ReleaseMutex(&scp->mx); + /* now check that this is a real mount point */ + if (scp->fileType != CM_SCACHETYPE_MOUNTPOINT) { + lock_ReleaseMutex(&scp->mx); cm_ReleaseSCache(scp); + return CM_ERROR_INVAL; + } - return code; -} + code = cm_ReadMountPoint(scp, userp, &req); + if (code == 0) { + cp = ioctlp->outDatap; + strcpy(cp, scp->mountPointStringp); + cp += strlen(cp) + 1; + ioctlp->outDatap = cp; + } + lock_ReleaseMutex(&scp->mx); + cm_ReleaseSCache(scp); + + return code; +} long cm_IoctlDeleteMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp) { - long code; - cm_scache_t *dscp; - cm_scache_t *scp; - char *cp; - cm_req_t req; + long code; + cm_scache_t *dscp; + cm_scache_t *scp; + char *cp; + cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); - code = cm_ParseIoctlPath(ioctlp, userp, &req, &dscp); - if (code) return code; - - cp = ioctlp->inDatap; + code = cm_ParseIoctlPath(ioctlp, userp, &req, &dscp); + if (code) return code; - code = cm_Lookup(dscp, cp, CM_FLAG_NOMOUNTCHASE, userp, &req, &scp); + cp = ioctlp->inDatap; + + code = cm_Lookup(dscp, cp, CM_FLAG_NOMOUNTCHASE, userp, &req, &scp); - /* if something went wrong, bail out now */ - if (code) { - goto done; - } + /* if something went wrong, bail out now */ + if (code) { + goto done; + } - lock_ObtainMutex(&scp->mx); - code = cm_SyncOp(scp, NULL, userp, &req, 0, - CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); - if (code) { - lock_ReleaseMutex(&scp->mx); - cm_ReleaseSCache(scp); - goto done; - } - - /* now check that this is a real mount point */ - if (scp->fileType != CM_SCACHETYPE_MOUNTPOINT) { - lock_ReleaseMutex(&scp->mx); - cm_ReleaseSCache(scp); - code = CM_ERROR_INVAL; - goto done; - } - - /* time to make the RPC, so drop the lock */ - lock_ReleaseMutex(&scp->mx); + lock_ObtainMutex(&scp->mx); + code = cm_SyncOp(scp, NULL, userp, &req, 0, + CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + if (code) { + lock_ReleaseMutex(&scp->mx); cm_ReleaseSCache(scp); - - /* easier to do it this way */ - code = cm_Unlink(dscp, cp, userp, &req); - if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) - smb_NotifyChange(FILE_ACTION_REMOVED, - FILE_NOTIFY_CHANGE_DIR_NAME, - dscp, cp, NULL, TRUE); - -done: - cm_ReleaseSCache(dscp); - return code; + goto done; + } + + /* now check that this is a real mount point */ + if (scp->fileType != CM_SCACHETYPE_MOUNTPOINT) { + lock_ReleaseMutex(&scp->mx); + cm_ReleaseSCache(scp); + code = CM_ERROR_INVAL; + goto done; + } + + /* time to make the RPC, so drop the lock */ + lock_ReleaseMutex(&scp->mx); + cm_ReleaseSCache(scp); + + /* easier to do it this way */ + code = cm_Unlink(dscp, cp, userp, &req); + if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) + smb_NotifyChange(FILE_ACTION_REMOVED, + FILE_NOTIFY_CHANGE_DIR_NAME, + dscp, cp, NULL, TRUE); + + done: + cm_ReleaseSCache(dscp); + return code; } long cm_IoctlCheckServers(struct smb_ioctl *ioctlp, struct cm_user *userp) { - cm_cell_t *cellp; - chservinfo_t csi; - char *tp; - char *cp; - long temp; - cm_server_t *tsp; - int haveCell; + cm_cell_t *cellp; + chservinfo_t csi; + char *tp; + char *cp; + long temp; + cm_server_t *tsp; + int haveCell; - cm_SkipIoctlPath(ioctlp); /* we don't care about the path */ - tp = ioctlp->inDatap; - haveCell = 0; - - memcpy(&temp, tp, sizeof(temp)); - if (temp == 0x12345678) { /* For afs3.3 version */ - memcpy(&csi, tp, sizeof(csi)); - if (csi.tinterval >= 0) { - cp = ioctlp->outDatap; - memcpy(cp, (char *)&cm_daemonCheckInterval, sizeof(long)); - ioctlp->outDatap += sizeof(long); - if (csi.tinterval > 0) { - if (!smb_SUser(userp)) - return CM_ERROR_NOACCESS; - cm_daemonCheckInterval = csi.tinterval; - } - return 0; - } - if (csi.tsize) - haveCell = 1; - temp = csi.tflags; - cp = csi.tbuffer; - } else { /* For pre afs3.3 versions */ - memcpy((char *)&temp, ioctlp->inDatap, sizeof(long)); - ioctlp->inDatap = cp = ioctlp->inDatap + sizeof(long); - if (cp - ioctlp->inAllocp < ioctlp->inCopied) /* still more data available */ - haveCell = 1; - } - - /* - * 1: fast check, don't contact servers. - * 2: local cell only. - */ - if (haveCell) { - /* have cell name, too */ - cellp = cm_GetCell(cp, 0); - if (!cellp) return CM_ERROR_NOSUCHCELL; - } - else cellp = (cm_cell_t *) 0; - if (!cellp && (temp & 2)) { - /* use local cell */ - cellp = cm_FindCellByID(1); - } - if (!(temp & 1)) { /* if not fast, call server checker routine */ - /* check down servers */ - cm_CheckServers(CM_FLAG_CHECKDOWNSERVERS | CM_FLAG_CHECKUPSERVERS, - cellp); - } - - /* now return the current down server list */ - cp = ioctlp->outDatap; - lock_ObtainRead(&cm_serverLock); - for(tsp = cm_allServersp; tsp; tsp=tsp->allNextp) { - if (cellp && tsp->cellp != cellp) continue; /* cell spec'd and wrong */ - if ((tsp->flags & CM_SERVERFLAG_DOWN) - && tsp->type == CM_SERVER_FILE) { - memcpy(cp, (char *)&tsp->addr.sin_addr.s_addr, sizeof(long)); - cp += sizeof(long); - } - } - lock_ReleaseRead(&cm_serverLock); - - ioctlp->outDatap = cp; - return 0; + cm_SkipIoctlPath(ioctlp); /* we don't care about the path */ + tp = ioctlp->inDatap; + haveCell = 0; + + memcpy(&temp, tp, sizeof(temp)); + if (temp == 0x12345678) { /* For afs3.3 version */ + memcpy(&csi, tp, sizeof(csi)); + if (csi.tinterval >= 0) { + cp = ioctlp->outDatap; + memcpy(cp, (char *)&cm_daemonCheckInterval, sizeof(long)); + ioctlp->outDatap += sizeof(long); + if (csi.tinterval > 0) { + if (!smb_SUser(userp)) + return CM_ERROR_NOACCESS; + cm_daemonCheckInterval = csi.tinterval; + } + return 0; + } + if (csi.tsize) + haveCell = 1; + temp = csi.tflags; + cp = csi.tbuffer; + } else { /* For pre afs3.3 versions */ + memcpy((char *)&temp, ioctlp->inDatap, sizeof(long)); + ioctlp->inDatap = cp = ioctlp->inDatap + sizeof(long); + if (cp - ioctlp->inAllocp < ioctlp->inCopied) /* still more data available */ + haveCell = 1; + } + + /* + * 1: fast check, don't contact servers. + * 2: local cell only. + */ + if (haveCell) { + /* have cell name, too */ + cellp = cm_GetCell(cp, 0); + if (!cellp) return CM_ERROR_NOSUCHCELL; + } + else cellp = (cm_cell_t *) 0; + if (!cellp && (temp & 2)) { + /* use local cell */ + cellp = cm_FindCellByID(1); + } + if (!(temp & 1)) { /* if not fast, call server checker routine */ + /* check down servers */ + cm_CheckServers(CM_FLAG_CHECKDOWNSERVERS | CM_FLAG_CHECKUPSERVERS, + cellp); + } + + /* now return the current down server list */ + cp = ioctlp->outDatap; + lock_ObtainRead(&cm_serverLock); + for (tsp = cm_allServersp; tsp; tsp=tsp->allNextp) { + if (cellp && tsp->cellp != cellp) continue; /* cell spec'd and wrong */ + if ((tsp->flags & CM_SERVERFLAG_DOWN) + && tsp->type == CM_SERVER_FILE) { + memcpy(cp, (char *)&tsp->addr.sin_addr.s_addr, sizeof(long)); + cp += sizeof(long); + } + } + lock_ReleaseRead(&cm_serverLock); + + ioctlp->outDatap = cp; + return 0; } long cm_IoctlGag(struct smb_ioctl *ioctlp, struct cm_user *userp) { - /* we don't print anything superfluous, so we don't support the gag call */ - return CM_ERROR_INVAL; + /* we don't print anything superfluous, so we don't support the gag call */ + return CM_ERROR_INVAL; } long cm_IoctlCheckVolumes(struct smb_ioctl *ioctlp, struct cm_user *userp) { - cm_CheckVolumes(); - return 0; -} + cm_CheckVolumes(); + return 0; +} long cm_IoctlSetCacheSize(struct smb_ioctl *ioctlp, struct cm_user *userp) { - long temp; - long code; - - cm_SkipIoctlPath(ioctlp); + long temp; + long code; - memcpy(&temp, ioctlp->inDatap, sizeof(temp)); - if (temp == 0) temp = buf_nOrigBuffers; - else { - /* temp is in 1K units, convert to # of buffers */ - temp = temp / (buf_bufferSize / 1024); - } + cm_SkipIoctlPath(ioctlp); + + memcpy(&temp, ioctlp->inDatap, sizeof(temp)); + if (temp == 0) + temp = buf_nOrigBuffers; + else { + /* temp is in 1K units, convert to # of buffers */ + temp = temp / (buf_bufferSize / 1024); + } - /* now adjust the cache size */ - code = buf_SetNBuffers(temp); + /* now adjust the cache size */ + code = buf_SetNBuffers(temp); - return code; + return code; } long cm_IoctlTraceControl(struct smb_ioctl *ioctlp, struct cm_user *userp) { - long inValue; + long inValue; - cm_SkipIoctlPath(ioctlp); + cm_SkipIoctlPath(ioctlp); - memcpy(&inValue, ioctlp->inDatap, sizeof(long)); + memcpy(&inValue, ioctlp->inDatap, sizeof(long)); - /* print trace */ - if (inValue & 8) { - afsd_ForceTrace(FALSE); - } + /* print trace */ + if (inValue & 8) { + afsd_ForceTrace(FALSE); + } - if (inValue & 2) { - /* set tracing value to low order bit */ - if ((inValue & 1) == 0) { - /* disable tracing */ - osi_LogDisable(afsd_logp); - } - else { - /* enable tracing */ - osi_LogEnable(afsd_logp); - } - } - - /* see if we're supposed to do a reset, too */ - if (inValue & 4) { - osi_LogReset(afsd_logp); - } - - /* and copy out tracing flag */ - inValue = afsd_logp->enabled; /* use as a temp vbl */ - memcpy(ioctlp->outDatap, &inValue, sizeof(long)); - ioctlp->outDatap += sizeof(long); - return 0; -} + if (inValue & 2) { + /* set tracing value to low order bit */ + if ((inValue & 1) == 0) { + /* disable tracing */ + osi_LogDisable(afsd_logp); + } + else { + /* enable tracing */ + osi_LogEnable(afsd_logp); + } + } + + /* see if we're supposed to do a reset, too */ + if (inValue & 4) { + osi_LogReset(afsd_logp); + } + + /* and copy out tracing flag */ + inValue = afsd_logp->enabled; /* use as a temp vbl */ + memcpy(ioctlp->outDatap, &inValue, sizeof(long)); + ioctlp->outDatap += sizeof(long); + return 0; +} long cm_IoctlGetCacheParms(struct smb_ioctl *ioctlp, struct cm_user *userp) { - cm_cacheParms_t parms; - - memset(&parms, 0, sizeof(parms)); + cm_cacheParms_t parms; - /* first we get, in 1K units, the cache size */ - parms.parms[0] = buf_nbuffers * (buf_bufferSize / 1024); - - /* and then the actual # of buffers in use (not in the free list, I guess, - * will be what we do). - */ - parms.parms[1] = (buf_nbuffers - buf_CountFreeList()) * (buf_bufferSize / 1024); - - memcpy(ioctlp->outDatap, &parms, sizeof(parms)); - ioctlp->outDatap += sizeof(parms); + memset(&parms, 0, sizeof(parms)); + + /* first we get, in 1K units, the cache size */ + parms.parms[0] = buf_nbuffers * (buf_bufferSize / 1024); - return 0; + /* and then the actual # of buffers in use (not in the free list, I guess, + * will be what we do). + */ + parms.parms[1] = (buf_nbuffers - buf_CountFreeList()) * (buf_bufferSize / 1024); + + memcpy(ioctlp->outDatap, &parms, sizeof(parms)); + ioctlp->outDatap += sizeof(parms); + + return 0; } long cm_IoctlGetCell(struct smb_ioctl *ioctlp, struct cm_user *userp) { - long whichCell; + long whichCell; long magic = 0; - cm_cell_t *tcellp; - cm_serverRef_t *serverRefp; + cm_cell_t *tcellp; + cm_serverRef_t *serverRefp; cm_server_t *serverp; - long i; + long i; char *cp; char *tp; char *basep; - cm_SkipIoctlPath(ioctlp); + cm_SkipIoctlPath(ioctlp); - tp = ioctlp->inDatap; + tp = ioctlp->inDatap; - memcpy((char *)&whichCell, tp, sizeof(long)); - tp += sizeof(long); - - /* see if more than one long passed in, ignoring the null pathname (the -1) */ - if (ioctlp->inCopied-1 > sizeof(long)) { - memcpy((char *)&magic, tp, sizeof(long)); - } + memcpy((char *)&whichCell, tp, sizeof(long)); + tp += sizeof(long); + + /* see if more than one long passed in, ignoring the null pathname (the -1) */ + if (ioctlp->inCopied-1 > sizeof(long)) { + memcpy((char *)&magic, tp, sizeof(long)); + } lock_ObtainRead(&cm_cellLock); - for(tcellp = cm_allCellsp; tcellp; tcellp = tcellp->nextp) { - if (whichCell == 0) break; - whichCell--; - } - lock_ReleaseRead(&cm_cellLock); - if (tcellp) { - int max = 8; - - cp = ioctlp->outDatap; - - if (magic == 0x12345678) { - memcpy(cp, (char *)&magic, sizeof(long)); - max = 13; - } - memset(cp, 0, max * sizeof(long)); + for (tcellp = cm_allCellsp; tcellp; tcellp = tcellp->nextp) { + if (whichCell == 0) break; + whichCell--; + } + lock_ReleaseRead(&cm_cellLock); + if (tcellp) { + int max = 8; + + cp = ioctlp->outDatap; + + if (magic == 0x12345678) { + memcpy(cp, (char *)&magic, sizeof(long)); + max = 13; + } + memset(cp, 0, max * sizeof(long)); basep = cp; - lock_ObtainRead(&cm_serverLock); /* for going down server list */ + lock_ObtainRead(&cm_serverLock); /* for going down server list */ /* jaltman - do the reference counts to serverRefp contents need to be increased? */ - serverRefp = tcellp->vlServersp; - for(i=0; iserver; - memcpy(cp, &serverp->addr.sin_addr.s_addr, sizeof(long)); - cp += sizeof(long); + serverRefp = tcellp->vlServersp; + for (i=0; iserver; + memcpy(cp, &serverp->addr.sin_addr.s_addr, sizeof(long)); + cp += sizeof(long); serverRefp = serverRefp->next; - } - lock_ReleaseRead(&cm_serverLock); - cp = basep + max * sizeof(afs_int32); - strcpy(cp, tcellp->namep); - cp += strlen(tcellp->namep)+1; - ioctlp->outDatap = cp; - } + } + lock_ReleaseRead(&cm_serverLock); + cp = basep + max * sizeof(afs_int32); + strcpy(cp, tcellp->namep); + cp += strlen(tcellp->namep)+1; + ioctlp->outDatap = cp; + } if (tcellp) return 0; @@ -1077,14 +1104,14 @@ long cm_IoctlNewCell(struct smb_ioctl *ioctlp, struct cm_user *userp) * are already loaded. * cell list will be cm_CellLock and cm_ServerLock will be held for write. - */ + */ cm_cell_t *cp; cm_SkipIoctlPath(ioctlp); lock_ObtainWrite(&cm_cellLock); - for(cp = cm_allCellsp; cp; cp=cp->nextp) + for (cp = cm_allCellsp; cp; cp=cp->nextp) { long code; /* delete all previous server lists - cm_FreeServerList will ask for write on cm_ServerLock*/ @@ -1092,7 +1119,7 @@ long cm_IoctlNewCell(struct smb_ioctl *ioctlp, struct cm_user *userp) cp->vlServersp = NULL; code = cm_SearchCellFile(cp->namep, cp->namep, cm_AddCellProc, cp); #ifdef AFS_AFSDB_ENV - if (code) { + if (code) { if (cm_dnsEnabled) { int ttl; code = cm_SearchCellByDNS(cp->namep, cp->namep, &ttl, cm_AddCellProc, cp); @@ -1122,27 +1149,27 @@ long cm_IoctlNewCell(struct smb_ioctl *ioctlp, struct cm_user *userp) long cm_IoctlGetWsCell(smb_ioctl_t *ioctlp, cm_user_t *userp) { - /* if we don't know our default cell, return failure */ - if (cm_rootCellp == NULL) { - return CM_ERROR_NOSUCHCELL; - } - - /* return the default cellname to the caller */ - strcpy(ioctlp->outDatap, cm_rootCellp->namep); - ioctlp->outDatap += strlen(ioctlp->outDatap) +1; - - /* done: success */ - return 0; + /* if we don't know our default cell, return failure */ + if (cm_rootCellp == NULL) { + return CM_ERROR_NOSUCHCELL; + } + + /* return the default cellname to the caller */ + strcpy(ioctlp->outDatap, cm_rootCellp->namep); + ioctlp->outDatap += strlen(ioctlp->outDatap) +1; + + /* done: success */ + return 0; } long cm_IoctlSysName(struct smb_ioctl *ioctlp, struct cm_user *userp) { - long setSysName, foundname = 0; + long setSysName, foundname = 0; char *cp, *cp2, inname[MAXSYSNAME], outname[MAXSYSNAME]; int t, count, num = 0; char **sysnamelist[MAXSYSNAME]; - cm_SkipIoctlPath(ioctlp); + cm_SkipIoctlPath(ioctlp); memcpy(&setSysName, ioctlp->inDatap, sizeof(long)); ioctlp->inDatap += sizeof(long); @@ -1180,7 +1207,8 @@ long cm_IoctlSysName(struct smb_ioctl *ioctlp, struct cm_user *userp) strcpy(outname, cm_sysName); foundname = cm_sysNameCount; *sysnamelist = cm_sysNameList; - } else { /* Local guy; only root can change sysname */ + } else { + /* Local guy; only root can change sysname */ /* clear @sys entries from the dnlc, once afs_lookup can * do lookups of @sys entries and thinks it can trust them */ /* privs ok, store the entry, ... */ @@ -1189,9 +1217,8 @@ long cm_IoctlSysName(struct smb_ioctl *ioctlp, struct cm_user *userp) cp = ioctlp->inDatap; for (count = 1; count < setSysName; ++count) { if (!cm_sysNameList[count]) - osi_panic - ("cm_IoctlSysName: no cm_sysNameList entry to write\n" - , __FILE__, __LINE__); + osi_panic("cm_IoctlSysName: no cm_sysNameList entry to write\n", + __FILE__, __LINE__); t = strlen(cp); memcpy(cm_sysNameList[count], cp, t + 1); /* include null */ cp += t + 1; @@ -1201,8 +1228,8 @@ long cm_IoctlSysName(struct smb_ioctl *ioctlp, struct cm_user *userp) } if (!setSysName) { - /* return the sysname to the caller */ - cp = ioctlp->outDatap; + /* return the sysname to the caller */ + cp = ioctlp->outDatap; memcpy(cp, (char *)&foundname, sizeof(afs_int32)); cp += sizeof(afs_int32); /* skip found flag */ if (foundname) { @@ -1210,12 +1237,12 @@ long cm_IoctlSysName(struct smb_ioctl *ioctlp, struct cm_user *userp) cp += strlen(outname) + 1; /* skip name and terminating null char */ for ( count=1; count < foundname ; ++count) { /* ... or list */ if ( !(*sysnamelist)[count] ) - osi_panic("cm_IoctlSysName: no cm_sysNameList entry to read\n" - , __FILE__, __LINE__); + osi_panic("cm_IoctlSysName: no cm_sysNameList entry to read\n", + __FILE__, __LINE__); t = strlen((*sysnamelist)[count]); if (t >= MAXSYSNAME) - osi_panic("cm_IoctlSysName: sysname entry garbled\n" - , __FILE__, __LINE__); + osi_panic("cm_IoctlSysName: sysname entry garbled\n", + __FILE__, __LINE__); strcpy(cp, (*sysnamelist)[count]); cp += t + 1; } @@ -1223,178 +1250,180 @@ long cm_IoctlSysName(struct smb_ioctl *ioctlp, struct cm_user *userp) ioctlp->outDatap = cp; } - /* done: success */ + /* done: success */ return 0; } long cm_IoctlGetCellStatus(struct smb_ioctl *ioctlp, struct cm_user *userp) { - long temp; - cm_cell_t *cellp; + long temp; + cm_cell_t *cellp; - cm_SkipIoctlPath(ioctlp); + cm_SkipIoctlPath(ioctlp); - cellp = cm_GetCell(ioctlp->inDatap, 0); - if (!cellp) return CM_ERROR_NOSUCHCELL; + cellp = cm_GetCell(ioctlp->inDatap, 0); + if (!cellp) + return CM_ERROR_NOSUCHCELL; - temp = 0; - lock_ObtainMutex(&cellp->mx); - if (cellp->flags & CM_CELLFLAG_SUID) - temp |= CM_SETCELLFLAG_SUID; - lock_ReleaseMutex(&cellp->mx); + temp = 0; + lock_ObtainMutex(&cellp->mx); + if (cellp->flags & CM_CELLFLAG_SUID) + temp |= CM_SETCELLFLAG_SUID; + lock_ReleaseMutex(&cellp->mx); - /* now copy out parm */ - memcpy(ioctlp->outDatap, &temp, sizeof(long)); - ioctlp->outDatap += sizeof(long); + /* now copy out parm */ + memcpy(ioctlp->outDatap, &temp, sizeof(long)); + ioctlp->outDatap += sizeof(long); - return 0; + return 0; } long cm_IoctlSetCellStatus(struct smb_ioctl *ioctlp, struct cm_user *userp) { - long temp; - cm_cell_t *cellp; + long temp; + cm_cell_t *cellp; - cm_SkipIoctlPath(ioctlp); + cm_SkipIoctlPath(ioctlp); - cellp = cm_GetCell(ioctlp->inDatap + 2*sizeof(long), 0); - if (!cellp) return CM_ERROR_NOSUCHCELL; + cellp = cm_GetCell(ioctlp->inDatap + 2*sizeof(long), 0); + if (!cellp) + return CM_ERROR_NOSUCHCELL; - memcpy((char *)&temp, ioctlp->inDatap, sizeof(long)); + memcpy((char *)&temp, ioctlp->inDatap, sizeof(long)); - lock_ObtainMutex(&cellp->mx); - if (temp & CM_SETCELLFLAG_SUID) - cellp->flags |= CM_CELLFLAG_SUID; - else - cellp->flags &= ~CM_CELLFLAG_SUID; - lock_ReleaseMutex(&cellp->mx); + lock_ObtainMutex(&cellp->mx); + if (temp & CM_SETCELLFLAG_SUID) + cellp->flags |= CM_CELLFLAG_SUID; + else + cellp->flags &= ~CM_CELLFLAG_SUID; + lock_ReleaseMutex(&cellp->mx); - return 0; + return 0; } long cm_IoctlSetSPrefs(struct smb_ioctl *ioctlp, struct cm_user *userp) { - cm_SSetPref_t *spin; /* input */ - cm_SPref_t *srvin; /* one input component */ - cm_server_t *tsp; - int i, vlonly, noServers, type; - struct sockaddr_in tmp; - unsigned short rank; - - cm_SkipIoctlPath(ioctlp); /* we don't care about the path */ - - spin = (cm_SSetPref_t *)ioctlp->inDatap; - noServers = spin->num_servers; - vlonly = spin->flags; - if ( vlonly ) - type = CM_SERVER_VLDB; - else + cm_SSetPref_t *spin; /* input */ + cm_SPref_t *srvin; /* one input component */ + cm_server_t *tsp; + int i, vlonly, noServers, type; + struct sockaddr_in tmp; + unsigned short rank; + + cm_SkipIoctlPath(ioctlp); /* we don't care about the path */ + + spin = (cm_SSetPref_t *)ioctlp->inDatap; + noServers = spin->num_servers; + vlonly = spin->flags; + if ( vlonly ) + type = CM_SERVER_VLDB; + else type = CM_SERVER_FILE; - for ( i=0; i < noServers; i++) - { - srvin = &(spin->servers[i]); - rank = srvin->rank + (rand() & 0x000f); - tmp.sin_addr = srvin->host; - tmp.sin_family = AF_INET; - - tsp = cm_FindServer(&tmp, type); - if ( tsp ) /* an existing server - ref count increased */ - { - tsp->ipRank = rank; /* no need to protect by mutex*/ - - if ( type == CM_SERVER_FILE) /* fileserver */ - { - /* find volumes which might have RO copy - /* on server and change the ordering of - ** their RO list */ - cm_ChangeRankVolume(tsp); - } - else - { - /* set preferences for an existing vlserver */ - cm_ChangeRankCellVLServer(tsp); - } + for ( i=0; i < noServers; i++) + { + srvin = &(spin->servers[i]); + rank = srvin->rank + (rand() & 0x000f); + tmp.sin_addr = srvin->host; + tmp.sin_family = AF_INET; + + tsp = cm_FindServer(&tmp, type); + if ( tsp ) /* an existing server - ref count increased */ + { + tsp->ipRank = rank; /* no need to protect by mutex*/ + + if ( type == CM_SERVER_FILE) /* fileserver */ + { + /* find volumes which might have RO copy + /* on server and change the ordering of + ** their RO list */ + cm_ChangeRankVolume(tsp); + } + else + { + /* set preferences for an existing vlserver */ + cm_ChangeRankCellVLServer(tsp); + } cm_PutServer(tsp); /* decrease refcount */ - } - else /* add a new server without a cell */ - { - tsp = cm_NewServer(&tmp, type, NULL); /* refcount = 1 */ - tsp->ipRank = rank; - } - } - return 0; + } + else /* add a new server without a cell */ + { + tsp = cm_NewServer(&tmp, type, NULL); /* refcount = 1 */ + tsp->ipRank = rank; + } + } + return 0; } long cm_IoctlGetSPrefs(struct smb_ioctl *ioctlp, struct cm_user *userp) { - cm_SPrefRequest_t *spin; /* input */ - cm_SPrefInfo_t *spout; /* output */ - cm_SPref_t *srvout; /* one output component */ - cm_server_t *tsp; - int i, vlonly, noServers; - - cm_SkipIoctlPath(ioctlp); /* we don't care about the path */ - - spin = (cm_SPrefRequest_t *)ioctlp->inDatap; - spout = (cm_SPrefInfo_t *) ioctlp->outDatap; - srvout = spout->servers; - noServers = spin->num_servers; - vlonly = spin->flags & CM_SPREF_VLONLY; - spout->num_servers = 0; - - lock_ObtainRead(&cm_serverLock); /* get server lock */ - - for(tsp=cm_allServersp, i=0; tsp && noServers; tsp=tsp->allNextp,i++){ - if (spin->offset > i) { - continue; /* catch up to where we left off */ - } - - if ( vlonly && (tsp->type == CM_SERVER_FILE) ) - continue; /* ignore fileserver for -vlserver option*/ - if ( !vlonly && (tsp->type == CM_SERVER_VLDB) ) - continue; /* ignore vlservers */ - - srvout->host = tsp->addr.sin_addr; - srvout->rank = tsp->ipRank; - srvout++; - spout->num_servers++; - noServers--; - } - lock_ReleaseRead(&cm_serverLock); /* release server lock */ - - if ( tsp ) /* we ran out of space in the output buffer */ - spout->next_offset = i; - else - spout->next_offset = 0; - ioctlp->outDatap += sizeof(cm_SPrefInfo_t) + - (spout->num_servers -1 ) * sizeof(cm_SPref_t) ; - return 0; + cm_SPrefRequest_t *spin; /* input */ + cm_SPrefInfo_t *spout; /* output */ + cm_SPref_t *srvout; /* one output component */ + cm_server_t *tsp; + int i, vlonly, noServers; + + cm_SkipIoctlPath(ioctlp); /* we don't care about the path */ + + spin = (cm_SPrefRequest_t *)ioctlp->inDatap; + spout = (cm_SPrefInfo_t *) ioctlp->outDatap; + srvout = spout->servers; + noServers = spin->num_servers; + vlonly = spin->flags & CM_SPREF_VLONLY; + spout->num_servers = 0; + + lock_ObtainRead(&cm_serverLock); /* get server lock */ + + for (tsp=cm_allServersp, i=0; tsp && noServers; tsp=tsp->allNextp,i++){ + if (spin->offset > i) { + continue; /* catch up to where we left off */ + } + + if ( vlonly && (tsp->type == CM_SERVER_FILE) ) + continue; /* ignore fileserver for -vlserver option*/ + if ( !vlonly && (tsp->type == CM_SERVER_VLDB) ) + continue; /* ignore vlservers */ + + srvout->host = tsp->addr.sin_addr; + srvout->rank = tsp->ipRank; + srvout++; + spout->num_servers++; + noServers--; + } + lock_ReleaseRead(&cm_serverLock); /* release server lock */ + + if ( tsp ) /* we ran out of space in the output buffer */ + spout->next_offset = i; + else + spout->next_offset = 0; + ioctlp->outDatap += sizeof(cm_SPrefInfo_t) + + (spout->num_servers -1 ) * sizeof(cm_SPref_t) ; + return 0; } long cm_IoctlStoreBehind(struct smb_ioctl *ioctlp, struct cm_user *userp) { - /* we ignore default asynchrony since we only have one way - * of doing this today. - */ - return 0; -} + /* we ignore default asynchrony since we only have one way + * of doing this today. + */ + return 0; +} long cm_IoctlCreateMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp) { - char leaf[256]; + char leaf[256]; long code; cm_scache_t *dscp; cm_attr_t tattr; char *cp; - cm_req_t req; + cm_req_t req; char mpInfo[256]; char fullCell[256]; - char volume[256]; - char cell[256]; - int ttl; + char volume[256]; + char cell[256]; + int ttl; - cm_InitReq(&req); + cm_InitReq(&req); code = cm_ParseIoctlParent(ioctlp, userp, &req, &dscp, leaf); if (code) return code; @@ -1408,49 +1437,49 @@ long cm_IoctlCreateMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp) * work on UNIX clients. */ - /* Extract the possibly partial cell name */ - strcpy(cell, ioctlp->inDatap + 1); /* Skip the mp type character */ + /* Extract the possibly partial cell name */ + strcpy(cell, ioctlp->inDatap + 1); /* Skip the mp type character */ if (cp = strchr(cell, ':')) { - /* Extract the volume name */ + /* Extract the volume name */ *cp = 0; - strcpy(volume, cp + 1); + strcpy(volume, cp + 1); /* Get the full name for this cell */ code = cm_SearchCellFile(cell, fullCell, 0, 0); #ifdef AFS_AFSDB_ENV - if (code && cm_dnsEnabled) + if (code && cm_dnsEnabled) code = cm_SearchCellByDNS(cell, fullCell, &ttl, 0, 0); #endif if (code) - return CM_ERROR_NOSUCHCELL; + return CM_ERROR_NOSUCHCELL; sprintf(mpInfo, "%c%s:%s", *ioctlp->inDatap, fullCell, volume); - } else { + } else { /* No cell name specified */ strcpy(mpInfo, ioctlp->inDatap); } #ifdef AFS_FREELANCE_CLIENT - if (cm_freelanceEnabled && dscp == cm_rootSCachep) { - /* we are adding the mount point to the root dir., so call - the freelance code to do the add. */ - osi_Log0(afsd_logp,"IoctlCreateMountPoint within Freelance root dir"); - code = cm_FreelanceAddMount(leaf, fullCell, volume, - *ioctlp->inDatap == '%', NULL); - return code; - } + if (cm_freelanceEnabled && dscp == cm_rootSCachep) { + /* we are adding the mount point to the root dir., so call + * the freelance code to do the add. */ + osi_Log0(afsd_logp,"IoctlCreateMountPoint within Freelance root dir"); + code = cm_FreelanceAddMount(leaf, fullCell, volume, + *ioctlp->inDatap == '%', NULL); + return code; + } #endif - /* create the symlink with mode 644. The lack of X bits tells + /* create the symlink with mode 644. The lack of X bits tells * us that it is a mount point. */ - tattr.mask = CM_ATTRMASK_UNIXMODEBITS | CM_ATTRMASK_CLIENTMODTIME; + tattr.mask = CM_ATTRMASK_UNIXMODEBITS | CM_ATTRMASK_CLIENTMODTIME; tattr.unixModeBits = 0644; - tattr.clientModTime = time(NULL); + tattr.clientModTime = time(NULL); code = cm_SymLink(dscp, leaf, mpInfo, 0, &tattr, userp, &req); - if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) - smb_NotifyChange(FILE_ACTION_ADDED, + if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) + smb_NotifyChange(FILE_ACTION_ADDED, FILE_NOTIFY_CHANGE_DIR_NAME, dscp, leaf, NULL, TRUE); @@ -1460,563 +1489,563 @@ long cm_IoctlCreateMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp) long cm_IoctlSymlink(struct smb_ioctl *ioctlp, struct cm_user *userp) { - char leaf[256]; - long code; - cm_scache_t *dscp; - cm_attr_t tattr; - char *cp; - cm_req_t req; + char leaf[256]; + long code; + cm_scache_t *dscp; + cm_attr_t tattr; + char *cp; + cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); - code = cm_ParseIoctlParent(ioctlp, userp, &req, &dscp, leaf); - if (code) return code; + code = cm_ParseIoctlParent(ioctlp, userp, &req, &dscp, leaf); + if (code) return code; - /* Translate chars for the link name */ - TranslateExtendedChars(leaf); + /* Translate chars for the link name */ + TranslateExtendedChars(leaf); - /* Translate chars for the linked to name */ - TranslateExtendedChars(ioctlp->inDatap); + /* Translate chars for the linked to name */ + TranslateExtendedChars(ioctlp->inDatap); - cp = ioctlp->inDatap; /* contents of link */ + cp = ioctlp->inDatap; /* contents of link */ - /* Create symlink with mode 0755. */ - tattr.mask = CM_ATTRMASK_UNIXMODEBITS; - tattr.unixModeBits = 0755; + /* Create symlink with mode 0755. */ + tattr.mask = CM_ATTRMASK_UNIXMODEBITS; + tattr.unixModeBits = 0755; - code = cm_SymLink(dscp, leaf, cp, 0, &tattr, userp, &req); - if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) - smb_NotifyChange(FILE_ACTION_ADDED, - FILE_NOTIFY_CHANGE_FILE_NAME - | FILE_NOTIFY_CHANGE_DIR_NAME, - dscp, leaf, NULL, TRUE); + code = cm_SymLink(dscp, leaf, cp, 0, &tattr, userp, &req); + if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) + smb_NotifyChange(FILE_ACTION_ADDED, + FILE_NOTIFY_CHANGE_FILE_NAME + | FILE_NOTIFY_CHANGE_DIR_NAME, + dscp, leaf, NULL, TRUE); - cm_ReleaseSCache(dscp); + cm_ReleaseSCache(dscp); - return code; + return code; } extern long cm_AssembleLink(cm_scache_t *linkScp, char *pathSuffixp, - cm_scache_t **newRootScpp, cm_space_t **newSpaceBufferp, - cm_user_t *userp, cm_req_t *reqp); + cm_scache_t **newRootScpp, cm_space_t **newSpaceBufferp, + cm_user_t *userp, cm_req_t *reqp); long cm_IoctlListlink(struct smb_ioctl *ioctlp, struct cm_user *userp) { - long code; - cm_scache_t *dscp; - cm_scache_t *scp; - char *cp; - cm_space_t *spacep; - cm_scache_t *newRootScp; - cm_req_t req; - - cm_InitReq(&req); - - code = cm_ParseIoctlPath(ioctlp, userp, &req, &dscp); - if (code) return code; - - cp = ioctlp->inDatap; - - code = cm_Lookup(dscp, cp, CM_FLAG_NOMOUNTCHASE, userp, &req, &scp); - cm_ReleaseSCache(dscp); - if (code) return code; - - /* Check that it's a real symlink */ - if (scp->fileType != CM_SCACHETYPE_SYMLINK){ - cm_ReleaseSCache(scp); - return CM_ERROR_INVAL; - } - - code = cm_AssembleLink(scp, "", &newRootScp, &spacep, userp, &req); - cm_ReleaseSCache(scp); - if (code == 0) { - cp = ioctlp->outDatap; - if (newRootScp != NULL) { + long code; + cm_scache_t *dscp; + cm_scache_t *scp; + char *cp; + cm_space_t *spacep; + cm_scache_t *newRootScp; + cm_req_t req; + + cm_InitReq(&req); + + code = cm_ParseIoctlPath(ioctlp, userp, &req, &dscp); + if (code) return code; + + cp = ioctlp->inDatap; + + code = cm_Lookup(dscp, cp, CM_FLAG_NOMOUNTCHASE, userp, &req, &scp); + cm_ReleaseSCache(dscp); + if (code) return code; + + /* Check that it's a real symlink */ + if (scp->fileType != CM_SCACHETYPE_SYMLINK){ + cm_ReleaseSCache(scp); + return CM_ERROR_INVAL; + } + + code = cm_AssembleLink(scp, "", &newRootScp, &spacep, userp, &req); + cm_ReleaseSCache(scp); + if (code == 0) { + cp = ioctlp->outDatap; + if (newRootScp != NULL) { strcpy(cp, cm_mountRoot); strcat(cp, "/"); - cp += strlen(cp); - } - strcpy(cp, spacep->data); - cp += strlen(cp) + 1; - ioctlp->outDatap = cp; - cm_FreeSpace(spacep); - if (newRootScp != NULL) - cm_ReleaseSCache(newRootScp); - } - - return code; + cp += strlen(cp); + } + strcpy(cp, spacep->data); + cp += strlen(cp) + 1; + ioctlp->outDatap = cp; + cm_FreeSpace(spacep); + if (newRootScp != NULL) + cm_ReleaseSCache(newRootScp); + } + + return code; } long cm_IoctlIslink(struct smb_ioctl *ioctlp, struct cm_user *userp) {/*CHECK FOR VALID SYMLINK*/ - long code; - cm_scache_t *dscp; - cm_scache_t *scp; - char *cp; - cm_req_t req; + long code; + cm_scache_t *dscp; + cm_scache_t *scp; + char *cp; + cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); - code = cm_ParseIoctlPath(ioctlp, userp, &req, &dscp); - if (code) return code; + code = cm_ParseIoctlPath(ioctlp, userp, &req, &dscp); + if (code) return code; - cp = ioctlp->inDatap; - osi_LogEvent("cm_IoctlListlink",NULL," name[%s]",cp); + cp = ioctlp->inDatap; + osi_LogEvent("cm_IoctlListlink",NULL," name[%s]",cp); - code = cm_Lookup(dscp, cp, CM_FLAG_NOMOUNTCHASE, userp, &req, &scp); - cm_ReleaseSCache(dscp); - if (code) return code; + code = cm_Lookup(dscp, cp, CM_FLAG_NOMOUNTCHASE, userp, &req, &scp); + cm_ReleaseSCache(dscp); + if (code) return code; - /* Check that it's a real symlink */ - if (scp->fileType != CM_SCACHETYPE_SYMLINK) - code = CM_ERROR_INVAL; - cm_ReleaseSCache(scp); - return code; + /* Check that it's a real symlink */ + if (scp->fileType != CM_SCACHETYPE_SYMLINK) + code = CM_ERROR_INVAL; + cm_ReleaseSCache(scp); + return code; } long cm_IoctlDeletelink(struct smb_ioctl *ioctlp, struct cm_user *userp) { - long code; - cm_scache_t *dscp; - cm_scache_t *scp; - char *cp; - cm_req_t req; + long code; + cm_scache_t *dscp; + cm_scache_t *scp; + char *cp; + cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); - code = cm_ParseIoctlPath(ioctlp, userp, &req, &dscp); - if (code) return code; + code = cm_ParseIoctlPath(ioctlp, userp, &req, &dscp); + if (code) return code; - cp = ioctlp->inDatap; + cp = ioctlp->inDatap; - code = cm_Lookup(dscp, cp, CM_FLAG_NOMOUNTCHASE, userp, &req, &scp); + code = cm_Lookup(dscp, cp, CM_FLAG_NOMOUNTCHASE, userp, &req, &scp); - /* if something went wrong, bail out now */ - if (code) { - goto done; - } + /* if something went wrong, bail out now */ + if (code) { + goto done; + } - lock_ObtainMutex(&scp->mx); - code = cm_SyncOp(scp, NULL, userp, &req, 0, - CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); - if (code) { - lock_ReleaseMutex(&scp->mx); - cm_ReleaseSCache(scp); - goto done; - } - - /* now check that this is a real symlink */ - if (scp->fileType != CM_SCACHETYPE_SYMLINK) { - lock_ReleaseMutex(&scp->mx); - cm_ReleaseSCache(scp); - code = CM_ERROR_INVAL; - goto done; - } + lock_ObtainMutex(&scp->mx); + code = cm_SyncOp(scp, NULL, userp, &req, 0, + CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + if (code) { + lock_ReleaseMutex(&scp->mx); + cm_ReleaseSCache(scp); + goto done; + } - /* time to make the RPC, so drop the lock */ - lock_ReleaseMutex(&scp->mx); + /* now check that this is a real symlink */ + if (scp->fileType != CM_SCACHETYPE_SYMLINK) { + lock_ReleaseMutex(&scp->mx); cm_ReleaseSCache(scp); + code = CM_ERROR_INVAL; + goto done; + } + + /* time to make the RPC, so drop the lock */ + lock_ReleaseMutex(&scp->mx); + cm_ReleaseSCache(scp); - /* easier to do it this way */ - code = cm_Unlink(dscp, cp, userp, &req); - if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) - smb_NotifyChange(FILE_ACTION_REMOVED, - FILE_NOTIFY_CHANGE_FILE_NAME - | FILE_NOTIFY_CHANGE_DIR_NAME, - dscp, cp, NULL, TRUE); - -done: - cm_ReleaseSCache(dscp); - return code; + /* easier to do it this way */ + code = cm_Unlink(dscp, cp, userp, &req); + if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) + smb_NotifyChange(FILE_ACTION_REMOVED, + FILE_NOTIFY_CHANGE_FILE_NAME + | FILE_NOTIFY_CHANGE_DIR_NAME, + dscp, cp, NULL, TRUE); + + done: + cm_ReleaseSCache(dscp); + return code; } long cm_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp) { - char *saveDataPtr; - char *tp; - int ticketLen; - char *ticket; - int ctSize; - struct ClearToken ct; - cm_cell_t *cellp; - cm_ucell_t *ucellp; - char *uname = NULL; - afs_uuid_t uuid; - int flags; - char sessionKey[8]; - char *smbname; - - saveDataPtr = ioctlp->inDatap; - - cm_SkipIoctlPath(ioctlp); - - tp = ioctlp->inDatap; - - /* ticket length */ - memcpy(&ticketLen, tp, sizeof(ticketLen)); - tp += sizeof(ticketLen); - if (ticketLen < MINKTCTICKETLEN || ticketLen > MAXKTCTICKETLEN) - return CM_ERROR_INVAL; - - /* remember ticket and skip over it for now */ - ticket = tp; - tp += ticketLen; - - /* clear token size */ - memcpy(&ctSize, tp, sizeof(ctSize)); - tp += sizeof(ctSize); - if (ctSize != sizeof(struct ClearToken)) - return CM_ERROR_INVAL; - - /* clear token */ - memcpy(&ct, tp, ctSize); - tp += ctSize; - if (ct.AuthHandle == -1) - ct.AuthHandle = 999; /* more rxvab compat stuff */ - - /* more stuff, if any */ - if (ioctlp->inCopied > tp - saveDataPtr) { - /* flags: logon flag */ - memcpy(&flags, tp, sizeof(int)); - tp += sizeof(int); - - /* cell name */ - cellp = cm_GetCell(tp, CM_FLAG_CREATE); - if (!cellp) return CM_ERROR_NOSUCHCELL; - tp += strlen(tp) + 1; - - /* user name */ - uname = tp; - tp += strlen(tp) + 1; + char *saveDataPtr; + char *tp; + int ticketLen; + char *ticket; + int ctSize; + struct ClearToken ct; + cm_cell_t *cellp; + cm_ucell_t *ucellp; + char *uname = NULL; + afs_uuid_t uuid; + int flags; + char sessionKey[8]; + char *smbname; + + saveDataPtr = ioctlp->inDatap; + + cm_SkipIoctlPath(ioctlp); + + tp = ioctlp->inDatap; + + /* ticket length */ + memcpy(&ticketLen, tp, sizeof(ticketLen)); + tp += sizeof(ticketLen); + if (ticketLen < MINKTCTICKETLEN || ticketLen > MAXKTCTICKETLEN) + return CM_ERROR_INVAL; + + /* remember ticket and skip over it for now */ + ticket = tp; + tp += ticketLen; + + /* clear token size */ + memcpy(&ctSize, tp, sizeof(ctSize)); + tp += sizeof(ctSize); + if (ctSize != sizeof(struct ClearToken)) + return CM_ERROR_INVAL; + + /* clear token */ + memcpy(&ct, tp, ctSize); + tp += ctSize; + if (ct.AuthHandle == -1) + ct.AuthHandle = 999; /* more rxvab compat stuff */ + + /* more stuff, if any */ + if (ioctlp->inCopied > tp - saveDataPtr) { + /* flags: logon flag */ + memcpy(&flags, tp, sizeof(int)); + tp += sizeof(int); + + /* cell name */ + cellp = cm_GetCell(tp, CM_FLAG_CREATE); + if (!cellp) return CM_ERROR_NOSUCHCELL; + tp += strlen(tp) + 1; + + /* user name */ + uname = tp; + tp += strlen(tp) + 1; if (flags & PIOCTL_LOGON) { - /* SMB user name with which to associate tokens */ - smbname = tp; - osi_Log2(smb_logp,"cm_IoctlSetToken for user [%s] smbname [%s]", - osi_LogSaveString(smb_logp,uname), osi_LogSaveString(smb_logp,smbname)); - fprintf(stderr, "SMB name = %s\n", smbname); - tp += strlen(tp) + 1; + /* SMB user name with which to associate tokens */ + smbname = tp; + osi_Log2(smb_logp,"cm_IoctlSetToken for user [%s] smbname [%s]", + osi_LogSaveString(smb_logp,uname), osi_LogSaveString(smb_logp,smbname)); + fprintf(stderr, "SMB name = %s\n", smbname); + tp += strlen(tp) + 1; } else { osi_Log1(smb_logp,"cm_IoctlSetToken for user [%s]", - osi_LogSaveString(smb_logp,uname)); + osi_LogSaveString(smb_logp,uname)); } #ifndef DJGPP /* for win95, session key is back in pioctl */ /* uuid */ - memcpy(&uuid, tp, sizeof(uuid)); - if (!cm_FindTokenEvent(uuid, sessionKey)) - return CM_ERROR_INVAL; + memcpy(&uuid, tp, sizeof(uuid)); + if (!cm_FindTokenEvent(uuid, sessionKey)) + return CM_ERROR_INVAL; #endif /* !DJGPP */ - } else { - cellp = cm_rootCellp; + } else { + cellp = cm_rootCellp; osi_Log0(smb_logp,"cm_IoctlSetToken - no name specified"); } - if (flags & PIOCTL_LOGON) { - userp = smb_FindCMUserByName(smbname, ioctlp->fidp->vcp->rname); - } - - /* store the token */ - lock_ObtainMutex(&userp->mx); - ucellp = cm_GetUCell(userp, cellp); + if (flags & PIOCTL_LOGON) { + userp = smb_FindCMUserByName(smbname, ioctlp->fidp->vcp->rname); + } + + /* store the token */ + lock_ObtainMutex(&userp->mx); + ucellp = cm_GetUCell(userp, cellp); osi_Log1(smb_logp,"cm_IoctlSetToken ucellp %lx", ucellp); - ucellp->ticketLen = ticketLen; - if (ucellp->ticketp) - free(ucellp->ticketp); /* Discard old token if any */ - ucellp->ticketp = malloc(ticketLen); - memcpy(ucellp->ticketp, ticket, ticketLen); + ucellp->ticketLen = ticketLen; + if (ucellp->ticketp) + free(ucellp->ticketp); /* Discard old token if any */ + ucellp->ticketp = malloc(ticketLen); + memcpy(ucellp->ticketp, ticket, ticketLen); #ifndef DJGPP - /* - * Get the session key from the RPC, rather than from the pioctl. - */ - /* - memcpy(&ucellp->sessionKey, ct.HandShakeKey, sizeof(ct.HandShakeKey)); - */ - memcpy(ucellp->sessionKey.data, sessionKey, sizeof(sessionKey)); + /* + * Get the session key from the RPC, rather than from the pioctl. + */ + /* + memcpy(&ucellp->sessionKey, ct.HandShakeKey, sizeof(ct.HandShakeKey)); + */ + memcpy(ucellp->sessionKey.data, sessionKey, sizeof(sessionKey)); #else - /* for win95, we are getting the session key from the pioctl */ - memcpy(&ucellp->sessionKey, ct.HandShakeKey, sizeof(ct.HandShakeKey)); + /* for win95, we are getting the session key from the pioctl */ + memcpy(&ucellp->sessionKey, ct.HandShakeKey, sizeof(ct.HandShakeKey)); #endif /* !DJGPP */ - ucellp->kvno = ct.AuthHandle; - ucellp->expirationTime = ct.EndTimestamp; - ucellp->gen++; - if (uname) strcpy(ucellp->userName, uname); - ucellp->flags |= CM_UCELLFLAG_RXKAD; - lock_ReleaseMutex(&userp->mx); - - if (flags & PIOCTL_LOGON) { - ioctlp->flags |= SMB_IOCTLFLAG_LOGON; - } + ucellp->kvno = ct.AuthHandle; + ucellp->expirationTime = ct.EndTimestamp; + ucellp->gen++; + if (uname) strcpy(ucellp->userName, uname); + ucellp->flags |= CM_UCELLFLAG_RXKAD; + lock_ReleaseMutex(&userp->mx); + + if (flags & PIOCTL_LOGON) { + ioctlp->flags |= SMB_IOCTLFLAG_LOGON; + } - cm_ResetACLCache(userp); + cm_ResetACLCache(userp); - return 0; + return 0; } long cm_IoctlGetTokenIter(struct smb_ioctl *ioctlp, struct cm_user *userp) { - char *tp, *cp; - int iterator; - int temp; - cm_ucell_t *ucellp; - struct ClearToken ct; - - cm_SkipIoctlPath(ioctlp); - - tp = ioctlp->inDatap; - cp = ioctlp->outDatap; - - /* iterator */ - memcpy(&iterator, tp, sizeof(iterator)); - tp += sizeof(iterator); - - lock_ObtainMutex(&userp->mx); - - /* look for token */ - for (;;iterator++) { - ucellp = cm_FindUCell(userp, iterator); - if (!ucellp) { - lock_ReleaseMutex(&userp->mx); - return CM_ERROR_NOMORETOKENS; - } - if (ucellp->flags & CM_UCELLFLAG_RXKAD) - break; - } - - /* new iterator */ - temp = ucellp->iterator + 1; - memcpy(cp, &temp, sizeof(temp)); - cp += sizeof(temp); - - /* ticket length */ - memcpy(cp, &ucellp->ticketLen, sizeof(ucellp->ticketLen)); - cp += sizeof(ucellp->ticketLen); - - /* ticket */ - memcpy(cp, ucellp->ticketp, ucellp->ticketLen); - cp += ucellp->ticketLen; - - /* clear token size */ - temp = sizeof(ct); - memcpy(cp, &temp, sizeof(temp)); - cp += sizeof(temp); - - /* clear token */ - ct.AuthHandle = ucellp->kvno; + char *tp, *cp; + int iterator; + int temp; + cm_ucell_t *ucellp; + struct ClearToken ct; + + cm_SkipIoctlPath(ioctlp); + + tp = ioctlp->inDatap; + cp = ioctlp->outDatap; + + /* iterator */ + memcpy(&iterator, tp, sizeof(iterator)); + tp += sizeof(iterator); + + lock_ObtainMutex(&userp->mx); + + /* look for token */ + for (;;iterator++) { + ucellp = cm_FindUCell(userp, iterator); + if (!ucellp) { + lock_ReleaseMutex(&userp->mx); + return CM_ERROR_NOMORETOKENS; + } + if (ucellp->flags & CM_UCELLFLAG_RXKAD) + break; + } + + /* new iterator */ + temp = ucellp->iterator + 1; + memcpy(cp, &temp, sizeof(temp)); + cp += sizeof(temp); + + /* ticket length */ + memcpy(cp, &ucellp->ticketLen, sizeof(ucellp->ticketLen)); + cp += sizeof(ucellp->ticketLen); + + /* ticket */ + memcpy(cp, ucellp->ticketp, ucellp->ticketLen); + cp += ucellp->ticketLen; + + /* clear token size */ + temp = sizeof(ct); + memcpy(cp, &temp, sizeof(temp)); + cp += sizeof(temp); + + /* clear token */ + ct.AuthHandle = ucellp->kvno; #ifndef DJGPP - /* - * Don't give out a real session key here - */ - /* - memcpy(ct.HandShakeKey, &ucellp->sessionKey, sizeof(ct.HandShakeKey)); - */ - memset(ct.HandShakeKey, 0, sizeof(ct.HandShakeKey)); + /* + * Don't give out a real session key here + */ + /* + memcpy(ct.HandShakeKey, &ucellp->sessionKey, sizeof(ct.HandShakeKey)); + */ + memset(ct.HandShakeKey, 0, sizeof(ct.HandShakeKey)); #else - memcpy(ct.HandShakeKey, &ucellp->sessionKey, sizeof(ct.HandShakeKey)); + memcpy(ct.HandShakeKey, &ucellp->sessionKey, sizeof(ct.HandShakeKey)); #endif /* !DJGPP */ - ct.ViceId = 37; /* XXX */ - ct.BeginTimestamp = 0; /* XXX */ - ct.EndTimestamp = ucellp->expirationTime; - memcpy(cp, &ct, sizeof(ct)); - cp += sizeof(ct); + ct.ViceId = 37; /* XXX */ + ct.BeginTimestamp = 0; /* XXX */ + ct.EndTimestamp = ucellp->expirationTime; + memcpy(cp, &ct, sizeof(ct)); + cp += sizeof(ct); - /* Primary flag (unused) */ - temp = 0; - memcpy(cp, &temp, sizeof(temp)); - cp += sizeof(temp); + /* Primary flag (unused) */ + temp = 0; + memcpy(cp, &temp, sizeof(temp)); + cp += sizeof(temp); - /* cell name */ - strcpy(cp, ucellp->cellp->namep); - cp += strlen(cp) + 1; + /* cell name */ + strcpy(cp, ucellp->cellp->namep); + cp += strlen(cp) + 1; - /* user name */ - strcpy(cp, ucellp->userName); - cp += strlen(cp) + 1; + /* user name */ + strcpy(cp, ucellp->userName); + cp += strlen(cp) + 1; - ioctlp->outDatap = cp; + ioctlp->outDatap = cp; - lock_ReleaseMutex(&userp->mx); + lock_ReleaseMutex(&userp->mx); - return 0; + return 0; } long cm_IoctlGetToken(struct smb_ioctl *ioctlp, struct cm_user *userp) { - char *cp; - int temp; - cm_cell_t *cellp; - cm_ucell_t *ucellp; - struct ClearToken ct; - char *tp; + char *cp; + int temp; + cm_cell_t *cellp; + cm_ucell_t *ucellp; + struct ClearToken ct; + char *tp; #ifndef DJGPP - afs_uuid_t uuid; + afs_uuid_t uuid; #endif /* !DJGPP */ - cm_SkipIoctlPath(ioctlp); + cm_SkipIoctlPath(ioctlp); - tp = ioctlp->inDatap; + tp = ioctlp->inDatap; - cp = ioctlp->outDatap; + cp = ioctlp->outDatap; - /* cell name is right here */ - cellp = cm_GetCell(tp, 0); - if (!cellp) return CM_ERROR_NOSUCHCELL; - tp += strlen(tp) + 1; + /* cell name is right here */ + cellp = cm_GetCell(tp, 0); + if (!cellp) return CM_ERROR_NOSUCHCELL; + tp += strlen(tp) + 1; #ifndef DJGPP - /* uuid */ - memcpy(&uuid, tp, sizeof(uuid)); + /* uuid */ + memcpy(&uuid, tp, sizeof(uuid)); #endif /* !DJGPP */ - lock_ObtainMutex(&userp->mx); + lock_ObtainMutex(&userp->mx); - ucellp = cm_GetUCell(userp, cellp); - if (!ucellp || !(ucellp->flags & CM_UCELLFLAG_RXKAD)) { - lock_ReleaseMutex(&userp->mx); - return CM_ERROR_NOMORETOKENS; - } + ucellp = cm_GetUCell(userp, cellp); + if (!ucellp || !(ucellp->flags & CM_UCELLFLAG_RXKAD)) { + lock_ReleaseMutex(&userp->mx); + return CM_ERROR_NOMORETOKENS; + } - /* ticket length */ - memcpy(cp, &ucellp->ticketLen, sizeof(ucellp->ticketLen)); - cp += sizeof(ucellp->ticketLen); + /* ticket length */ + memcpy(cp, &ucellp->ticketLen, sizeof(ucellp->ticketLen)); + cp += sizeof(ucellp->ticketLen); - /* ticket */ - memcpy(cp, ucellp->ticketp, ucellp->ticketLen); - cp += ucellp->ticketLen; + /* ticket */ + memcpy(cp, ucellp->ticketp, ucellp->ticketLen); + cp += ucellp->ticketLen; - /* clear token size */ - temp = sizeof(ct); - memcpy(cp, &temp, sizeof(temp)); - cp += sizeof(temp); + /* clear token size */ + temp = sizeof(ct); + memcpy(cp, &temp, sizeof(temp)); + cp += sizeof(temp); - /* clear token */ - ct.AuthHandle = ucellp->kvno; + /* clear token */ + ct.AuthHandle = ucellp->kvno; #ifndef DJGPP - /* - * Don't give out a real session key here - */ - /* - memcpy(ct.HandShakeKey, &ucellp->sessionKey, sizeof(ct.HandShakeKey)); - */ - memset(ct.HandShakeKey, 0, sizeof(ct.HandShakeKey)); + /* + * Don't give out a real session key here + */ + /* + memcpy(ct.HandShakeKey, &ucellp->sessionKey, sizeof(ct.HandShakeKey)); + */ + memset(ct.HandShakeKey, 0, sizeof(ct.HandShakeKey)); #else - memcpy(ct.HandShakeKey, &ucellp->sessionKey, sizeof(ct.HandShakeKey)); + memcpy(ct.HandShakeKey, &ucellp->sessionKey, sizeof(ct.HandShakeKey)); #endif /* !DJGPP */ - ct.ViceId = 37; /* XXX */ - ct.BeginTimestamp = 0; /* XXX */ - ct.EndTimestamp = ucellp->expirationTime; - memcpy(cp, &ct, sizeof(ct)); - cp += sizeof(ct); + ct.ViceId = 37; /* XXX */ + ct.BeginTimestamp = 0; /* XXX */ + ct.EndTimestamp = ucellp->expirationTime; + memcpy(cp, &ct, sizeof(ct)); + cp += sizeof(ct); - /* Primary flag (unused) */ - temp = 0; - memcpy(cp, &temp, sizeof(temp)); - cp += sizeof(temp); + /* Primary flag (unused) */ + temp = 0; + memcpy(cp, &temp, sizeof(temp)); + cp += sizeof(temp); - /* cell name */ - strcpy(cp, ucellp->cellp->namep); - cp += strlen(cp) + 1; + /* cell name */ + strcpy(cp, ucellp->cellp->namep); + cp += strlen(cp) + 1; - /* user name */ - strcpy(cp, ucellp->userName); - cp += strlen(cp) + 1; + /* user name */ + strcpy(cp, ucellp->userName); + cp += strlen(cp) + 1; - ioctlp->outDatap = cp; + ioctlp->outDatap = cp; - lock_ReleaseMutex(&userp->mx); + lock_ReleaseMutex(&userp->mx); #ifndef DJGPP - cm_RegisterNewTokenEvent(uuid, ucellp->sessionKey.data); + cm_RegisterNewTokenEvent(uuid, ucellp->sessionKey.data); #endif /* !DJGPP */ - return 0; + return 0; } long cm_IoctlDelToken(struct smb_ioctl *ioctlp, struct cm_user *userp) { - char *cp; - cm_cell_t *cellp; - cm_ucell_t *ucellp; + char *cp; + cm_cell_t *cellp; + cm_ucell_t *ucellp; - cm_SkipIoctlPath(ioctlp); + cm_SkipIoctlPath(ioctlp); - cp = ioctlp->outDatap; + cp = ioctlp->outDatap; - /* cell name is right here */ - cellp = cm_GetCell(ioctlp->inDatap, 0); - if (!cellp) return CM_ERROR_NOSUCHCELL; + /* cell name is right here */ + cellp = cm_GetCell(ioctlp->inDatap, 0); + if (!cellp) return CM_ERROR_NOSUCHCELL; - lock_ObtainMutex(&userp->mx); + lock_ObtainMutex(&userp->mx); - ucellp = cm_GetUCell(userp, cellp); - if (!ucellp) { - lock_ReleaseMutex(&userp->mx); - return CM_ERROR_NOMORETOKENS; - } + ucellp = cm_GetUCell(userp, cellp); + if (!ucellp) { + lock_ReleaseMutex(&userp->mx); + return CM_ERROR_NOMORETOKENS; + } osi_Log1(smb_logp,"cm_IoctlDelToken ucellp %lx", ucellp); - if (ucellp->ticketp) { - free(ucellp->ticketp); - ucellp->ticketp = NULL; - } - ucellp->flags &= ~CM_UCELLFLAG_RXKAD; - ucellp->gen++; + if (ucellp->ticketp) { + free(ucellp->ticketp); + ucellp->ticketp = NULL; + } + ucellp->flags &= ~CM_UCELLFLAG_RXKAD; + ucellp->gen++; - lock_ReleaseMutex(&userp->mx); + lock_ReleaseMutex(&userp->mx); - cm_ResetACLCache(userp); + cm_ResetACLCache(userp); - return 0; + return 0; } long cm_IoctlDelAllToken(struct smb_ioctl *ioctlp, struct cm_user *userp) { - cm_ucell_t *ucellp; + cm_ucell_t *ucellp; - lock_ObtainMutex(&userp->mx); + lock_ObtainMutex(&userp->mx); for (ucellp = userp->cellInfop; ucellp; ucellp = ucellp->nextp) { osi_Log1(smb_logp,"cm_IoctlDelAllToken ucellp %lx", ucellp); - ucellp->flags &= ~CM_UCELLFLAG_RXKAD; - ucellp->gen++; - } + ucellp->flags &= ~CM_UCELLFLAG_RXKAD; + ucellp->gen++; + } - lock_ReleaseMutex(&userp->mx); + lock_ReleaseMutex(&userp->mx); - cm_ResetACLCache(userp); + cm_ResetACLCache(userp); - return 0; + return 0; } long cm_IoctlMakeSubmount(smb_ioctl_t *ioctlp, cm_user_t *userp) { - char afspath[MAX_PATH]; - char *submountreqp; - int nextAutoSubmount; + char afspath[MAX_PATH]; + char *submountreqp; + int nextAutoSubmount; HKEY hkSubmounts; DWORD dwType, dwSize; DWORD status; DWORD dwIndex; DWORD dwSubmounts; - cm_SkipIoctlPath(ioctlp); + cm_SkipIoctlPath(ioctlp); - /* Serialize this one, to prevent simultaneous mods - * to afsdsbmt.ini - */ - lock_ObtainMutex(&cm_Afsdsbmt_Lock); + /* Serialize this one, to prevent simultaneous mods + * to afsdsbmt.ini + */ + lock_ObtainMutex(&cm_Afsdsbmt_Lock); - /* Parse the input parameters--first the required afs path, - * then the requested submount name (which may be ""). - */ - cm_NormalizeAfsPath (afspath, ioctlp->inDatap); - submountreqp = ioctlp->inDatap + (strlen(ioctlp->inDatap)+1); + /* Parse the input parameters--first the required afs path, + * then the requested submount name (which may be ""). + */ + cm_NormalizeAfsPath (afspath, ioctlp->inDatap); + submountreqp = ioctlp->inDatap + (strlen(ioctlp->inDatap)+1); - /* If the caller supplied a suggested submount name, see if - * that submount name is in use... if so, the submount's path - * has to match our path. - */ + /* If the caller supplied a suggested submount name, see if + * that submount name is in use... if so, the submount's path + * has to match our path. + */ RegCreateKeyEx( HKEY_LOCAL_MACHINE, "SOFTWARE\\OpenAFS\\Client\\Submounts", @@ -2029,22 +2058,22 @@ long cm_IoctlMakeSubmount(smb_ioctl_t *ioctlp, cm_user_t *userp) NULL ); if (submountreqp && *submountreqp) { - char submountPathNormalized[MAX_PATH]; - char submountPath[MAX_PATH]; + char submountPathNormalized[MAX_PATH]; + char submountPath[MAX_PATH]; dwSize = sizeof(submountPath); status = RegQueryValueEx( hkSubmounts, submountreqp, 0, - &dwType, submountPath, &dwSize); + &dwType, submountPath, &dwSize); - if (status != ERROR_SUCCESS) { + if (status != ERROR_SUCCESS) { - /* The suggested submount name isn't in use now-- - * so we can safely map the requested submount name - * to the supplied path. Remember not to write the - * leading "/afs" when writing out the submount. - */ + /* The suggested submount name isn't in use now-- + * so we can safely map the requested submount name + * to the supplied path. Remember not to write the + * leading "/afs" when writing out the submount. + */ RegSetValueEx( hkSubmounts, submountreqp, 0, - REG_SZ, + REG_EXPAND_SZ, (strlen(&afspath[strlen(cm_mountRoot)])) ? &afspath[strlen(cm_mountRoot)]:"/", (strlen(&afspath[strlen(cm_mountRoot)])) ? @@ -2055,123 +2084,130 @@ long cm_IoctlMakeSubmount(smb_ioctl_t *ioctlp, cm_user_t *userp) ioctlp->outDatap += strlen(ioctlp->outDatap) +1; lock_ReleaseMutex(&cm_Afsdsbmt_Lock); return 0; - } - - /* The suggested submount name is already in use--if the - * supplied path matches the submount's path, we can still - * use the suggested submount name. - */ - cm_NormalizeAfsPath (submountPathNormalized, submountPath); - if (!strcmp (submountPathNormalized, afspath)) { - strcpy(ioctlp->outDatap, submountreqp); - ioctlp->outDatap += strlen(ioctlp->outDatap) +1; + } + + /* The suggested submount name is already in use--if the + * supplied path matches the submount's path, we can still + * use the suggested submount name. + */ + cm_NormalizeAfsPath (submountPathNormalized, submountPath); + if (!strcmp (submountPathNormalized, afspath)) { + strcpy(ioctlp->outDatap, submountreqp); + ioctlp->outDatap += strlen(ioctlp->outDatap) +1; RegCloseKey( hkSubmounts ); - lock_ReleaseMutex(&cm_Afsdsbmt_Lock); + lock_ReleaseMutex(&cm_Afsdsbmt_Lock); return 0; - } - } + } + } RegQueryInfoKey( hkSubmounts, - NULL, /* lpClass */ - NULL, /* lpcClass */ - NULL, /* lpReserved */ - NULL, /* lpcSubKeys */ - NULL, /* lpcMaxSubKeyLen */ - NULL, /* lpcMaxClassLen */ - &dwSubmounts, /* lpcValues */ - NULL, /* lpcMaxValueNameLen */ - NULL, /* lpcMaxValueLen */ - NULL, /* lpcbSecurityDescriptor */ - NULL /* lpftLastWriteTime */ - ); - - - /* Having obtained a list of all available submounts, start - * searching that list for a path which matches the requested - * AFS path. We'll also keep track of the highest "auto15"/"auto47" - * submount, in case we need to add a new one later. - */ - - nextAutoSubmount = 1; + NULL, /* lpClass */ + NULL, /* lpcClass */ + NULL, /* lpReserved */ + NULL, /* lpcSubKeys */ + NULL, /* lpcMaxSubKeyLen */ + NULL, /* lpcMaxClassLen */ + &dwSubmounts, /* lpcValues */ + NULL, /* lpcMaxValueNameLen */ + NULL, /* lpcMaxValueLen */ + NULL, /* lpcbSecurityDescriptor */ + NULL /* lpftLastWriteTime */ + ); + + + /* Having obtained a list of all available submounts, start + * searching that list for a path which matches the requested + * AFS path. We'll also keep track of the highest "auto15"/"auto47" + * submount, in case we need to add a new one later. + */ + + nextAutoSubmount = 1; for ( dwIndex = 0; dwIndex < dwSubmounts; dwIndex ++ ) { - char submountPathNormalized[MAX_PATH]; - char submountPath[MAX_PATH] = ""; - DWORD submountPathLen = sizeof(submountPath); - char submountName[256]; + char submountPathNormalized[MAX_PATH]; + char submountPath[MAX_PATH] = ""; + DWORD submountPathLen = sizeof(submountPath); + char submountName[MAX_PATH]; DWORD submountNameLen = sizeof(submountName); + dwType = 0; RegEnumValue( hkSubmounts, dwIndex, submountName, &submountNameLen, NULL, - &dwType, submountPath, &submountPathLen); - - /* If this is an Auto### submount, remember its ### value */ - - if ((!strnicmp (submountName, "auto", 4)) && - (isdigit (submountName[strlen("auto")]))) { - int thisAutoSubmount; - thisAutoSubmount = atoi (&submountName[strlen("auto")]); - nextAutoSubmount = max (nextAutoSubmount, - thisAutoSubmount+1); - } - - if ((submountPathLen == 0) || - (submountPathLen == sizeof(submountPath) - 1)) { - continue; - } - - /* See if the path for this submount matches the path - * that our caller specified. If so, we can return - * this submount. - */ - cm_NormalizeAfsPath (submountPathNormalized, submountPath); - if (!strcmp (submountPathNormalized, afspath)) { - strcpy(ioctlp->outDatap, submountName); - ioctlp->outDatap += strlen(ioctlp->outDatap) +1; + &dwType, submountPath, &submountPathLen); + if (dwType == REG_EXPAND_SZ) { + char buf[MAX_PATH]; + StringCbCopyA(buf, MAX_PATH, submountPath); + submountPathLen = ExpandEnvironmentStrings(buf, submountPath, MAX_PATH); + if (submountPathLen > MAX_PATH) + continue; + } + + /* If this is an Auto### submount, remember its ### value */ + if ((!strnicmp (submountName, "auto", 4)) && + (isdigit (submountName[strlen("auto")]))) { + int thisAutoSubmount; + thisAutoSubmount = atoi (&submountName[strlen("auto")]); + nextAutoSubmount = max (nextAutoSubmount, + thisAutoSubmount+1); + } + + if ((submountPathLen == 0) || + (submountPathLen == sizeof(submountPath) - 1)) { + continue; + } + + /* See if the path for this submount matches the path + * that our caller specified. If so, we can return + * this submount. + */ + cm_NormalizeAfsPath (submountPathNormalized, submountPath); + if (!strcmp (submountPathNormalized, afspath)) { + strcpy(ioctlp->outDatap, submountName); + ioctlp->outDatap += strlen(ioctlp->outDatap) +1; RegCloseKey(hkSubmounts); - lock_ReleaseMutex(&cm_Afsdsbmt_Lock); + lock_ReleaseMutex(&cm_Afsdsbmt_Lock); return 0; - } - } + } + } - /* We've been through the entire list of existing submounts, and - * didn't find any which matched the specified path. So, we'll - * just have to add one. Remember not to write the leading "/afs" - * when writing out the submount. - */ + /* We've been through the entire list of existing submounts, and + * didn't find any which matched the specified path. So, we'll + * just have to add one. Remember not to write the leading "/afs" + * when writing out the submount. + */ - sprintf(ioctlp->outDatap, "auto%ld", nextAutoSubmount); + sprintf(ioctlp->outDatap, "auto%ld", nextAutoSubmount); RegSetValueEx( hkSubmounts, ioctlp->outDatap, 0, - REG_SZ, + REG_EXPAND_SZ, (strlen(&afspath[strlen(cm_mountRoot)])) ? &afspath[strlen(cm_mountRoot)]:"/", (strlen(&afspath[strlen(cm_mountRoot)])) ? strlen(&afspath[strlen(cm_mountRoot)])+1:2); - ioctlp->outDatap += strlen(ioctlp->outDatap) +1; + ioctlp->outDatap += strlen(ioctlp->outDatap) +1; RegCloseKey(hkSubmounts); - lock_ReleaseMutex(&cm_Afsdsbmt_Lock); - return 0; + lock_ReleaseMutex(&cm_Afsdsbmt_Lock); + return 0; } long cm_IoctlGetRxkcrypt(smb_ioctl_t *ioctlp, cm_user_t *userp) { - memcpy(ioctlp->outDatap, &cryptall, sizeof(cryptall)); - ioctlp->outDatap += sizeof(cryptall); + memcpy(ioctlp->outDatap, &cryptall, sizeof(cryptall)); + ioctlp->outDatap += sizeof(cryptall); - return 0; + return 0; } long cm_IoctlSetRxkcrypt(smb_ioctl_t *ioctlp, cm_user_t *userp) { - cm_SkipIoctlPath(ioctlp); + cm_SkipIoctlPath(ioctlp); - memcpy(&cryptall, ioctlp->inDatap, sizeof(cryptall)); + memcpy(&cryptall, ioctlp->inDatap, sizeof(cryptall)); - return 0; + return 0; } #ifdef DJGPP @@ -2191,7 +2227,7 @@ long cm_IoctlGetSMBName(smb_ioctl_t *ioctlp, cm_user_t *userp) if (uidp && uidp->unp) { memcpy(ioctlp->outDatap, uidp->unp->name, strlen(uidp->unp->name)); ioctlp->outDatap += strlen(uidp->unp->name); - } + } return 0; } diff --git a/src/WINNT/afsd/cm_ioctl.h b/src/WINNT/afsd/cm_ioctl.h index c9ba93249..bcf7545ba 100644 --- a/src/WINNT/afsd/cm_ioctl.h +++ b/src/WINNT/afsd/cm_ioctl.h @@ -43,9 +43,9 @@ typedef struct cm_SSetPref { #define MAXNUMSYSNAMES 16 /* max that current constants allow */ #define MAXSYSNAME 128 /* max sysname (i.e. @sys) size */ -extern char *cm_sysName; -extern int cm_sysNameCount; -extern char *cm_sysNameList[MAXNUMSYSNAMES]; +extern char * cm_sysName; +extern unsigned int cm_sysNameCount; +extern char * cm_sysNameList[MAXNUMSYSNAMES]; #ifndef __CM_IOCTL_INTERFACES_ONLY__ diff --git a/src/WINNT/afsd/cm_scache.h b/src/WINNT/afsd/cm_scache.h index aeeeeeeb4..18b345033 100644 --- a/src/WINNT/afsd/cm_scache.h +++ b/src/WINNT/afsd/cm_scache.h @@ -58,7 +58,7 @@ typedef struct cm_scache { * write-locked to prevent buffers from * being created during a truncate op, etc. */ - int refCount; /* reference count; cm_scacheLock */ + unsigned long refCount; /* reference count; cm_scacheLock */ osi_queueData_t *bufReadsp; /* queue of buffers being read */ osi_queueData_t *bufWritesp; /* queue of buffers being written */ diff --git a/src/WINNT/afsd/cm_server.c b/src/WINNT/afsd/cm_server.c index ebe9eb2b8..fa2eb8560 100644 --- a/src/WINNT/afsd/cm_server.c +++ b/src/WINNT/afsd/cm_server.c @@ -37,102 +37,105 @@ int cm_NetFlags[CM_MAXINTERFACE_ADDR]; /* network flags */ void cm_CheckServers(long flags, cm_cell_t *cellp) { - /* ping all file servers, up or down, with unauthenticated connection, - * to find out whether we have all our callbacks from the server still. - * Also, ping down VLDBs. - */ - cm_server_t *tsp; - long code; - long secs; - long usecs; - int doPing; - int serverType; - long now; - int wasDown; - cm_conn_t *connp; + /* ping all file servers, up or down, with unauthenticated connection, + * to find out whether we have all our callbacks from the server still. + * Also, ping down VLDBs. + */ + cm_server_t *tsp; + long code; + long secs; + long usecs; + int doPing; + int serverType; + long now; + int wasDown; + cm_conn_t *connp; + struct rx_connection * callp; - lock_ObtainWrite(&cm_serverLock); - for(tsp = cm_allServersp; tsp; tsp = tsp->allNextp) { + lock_ObtainWrite(&cm_serverLock); + for (tsp = cm_allServersp; tsp; tsp = tsp->allNextp) { cm_GetServerNoLock(tsp); - lock_ReleaseWrite(&cm_serverLock); + lock_ReleaseWrite(&cm_serverLock); - /* now process the server */ - lock_ObtainMutex(&tsp->mx); + /* now process the server */ + lock_ObtainMutex(&tsp->mx); - /* what time is it? */ - now = osi_Time(); + /* what time is it? */ + now = osi_Time(); - serverType = tsp->type; - doPing = 0; - wasDown = tsp->flags & CM_SERVERFLAG_DOWN; + serverType = tsp->type; + doPing = 0; + wasDown = tsp->flags & CM_SERVERFLAG_DOWN; - /* only do the ping if the cell matches the requested cell, or we're - * matching all cells (cellp == NULL), and if we've requested to ping - * this type of {up, down} servers. - */ - if ((cellp == NULL || cellp == tsp->cellp) && - ((wasDown && (flags & CM_FLAG_CHECKDOWNSERVERS)) || - (!wasDown && (flags & CM_FLAG_CHECKUPSERVERS)))) { - - doPing = 1; - } /* we're supposed to check this up/down server */ - lock_ReleaseMutex(&tsp->mx); - - /* at this point, we've adjusted the server state, so do the ping and - * adjust things. + /* only do the ping if the cell matches the requested cell, or we're + * matching all cells (cellp == NULL), and if we've requested to ping + * this type of {up, down} servers. + */ + if ((cellp == NULL || cellp == tsp->cellp) && + ((wasDown && (flags & CM_FLAG_CHECKDOWNSERVERS)) || + (!wasDown && (flags & CM_FLAG_CHECKUPSERVERS)))) { + + doPing = 1; + } /* we're supposed to check this up/down server */ + lock_ReleaseMutex(&tsp->mx); + + /* at this point, we've adjusted the server state, so do the ping and + * adjust things. + */ + if (doPing) { + code = cm_ConnByServer(tsp, cm_rootUserp, &connp); + if (code == 0) { + /* now call the appropriate ping call. Drop the timeout if + * the server is known to be down, so that we don't waste a + * lot of time retiming out down servers. */ - if (doPing) { - code = cm_ConnByServer(tsp, cm_rootUserp, &connp); - if (code == 0) { - /* now call the appropriate ping call. Drop the timeout if - * the server is known to be down, so that we don't waste a - * lot of time retiming out down servers. - */ - if (wasDown) - rx_SetConnDeadTime(connp->callp, 10); - if (serverType == CM_SERVER_VLDB) { - code = VL_ProbeServer(connp->callp); - } - else { - /* file server */ - code = RXAFS_GetTime(connp->callp, &secs, &usecs); - } - if (wasDown) - rx_SetConnDeadTime(connp->callp, ConnDeadtimeout); - cm_PutConn(connp); - } /* got an unauthenticated connection to this server */ - - lock_ObtainMutex(&tsp->mx); - if (code == 0) { - /* mark server as up */ - tsp->flags &= ~CM_SERVERFLAG_DOWN; - } - else { - /* mark server as down */ - tsp->flags |= CM_SERVERFLAG_DOWN; - } - lock_ReleaseMutex(&tsp->mx); + if (wasDown) + rx_SetConnDeadTime(connp->callp, 10); + if (serverType == CM_SERVER_VLDB) { + code = VL_ProbeServer(connp->callp); } - - /* also, run the GC function for connections on all of the - * server's connections. - */ - cm_GCConnections(tsp); + else { + /* file server */ + callp = cm_GetRxConn(connp); + code = RXAFS_GetTime(callp, &secs, &usecs); + rx_PutConnection(callp); + } + if (wasDown) + rx_SetConnDeadTime(connp->callp, ConnDeadtimeout); + cm_PutConn(connp); + } /* got an unauthenticated connection to this server */ + + lock_ObtainMutex(&tsp->mx); + if (code == 0) { + /* mark server as up */ + tsp->flags &= ~CM_SERVERFLAG_DOWN; + } + else { + /* mark server as down */ + tsp->flags |= CM_SERVERFLAG_DOWN; + } + lock_ReleaseMutex(&tsp->mx); + } + + /* also, run the GC function for connections on all of the + * server's connections. + */ + cm_GCConnections(tsp); - lock_ObtainWrite(&cm_serverLock); + lock_ObtainWrite(&cm_serverLock); cm_PutServerNoLock(tsp); - } - lock_ReleaseWrite(&cm_serverLock); -} + } + lock_ReleaseWrite(&cm_serverLock); +} void cm_InitServer(void) { - static osi_once_t once; + static osi_once_t once; - if (osi_Once(&once)) { - lock_InitializeRWLock(&cm_serverLock, "cm_serverLock"); - osi_EndOnce(&once); - } + if (osi_Once(&once)) { + lock_InitializeRWLock(&cm_serverLock, "cm_serverLock"); + osi_EndOnce(&once); + } } void cm_GetServer(cm_server_t *serverp) @@ -149,85 +152,85 @@ void cm_GetServerNoLock(cm_server_t *serverp) void cm_PutServer(cm_server_t *serverp) { - lock_ObtainWrite(&cm_serverLock); - osi_assert(serverp->refCount-- > 0); - lock_ReleaseWrite(&cm_serverLock); + lock_ObtainWrite(&cm_serverLock); + osi_assert(serverp->refCount-- > 0); + lock_ReleaseWrite(&cm_serverLock); } void cm_PutServerNoLock(cm_server_t *serverp) { - osi_assert(serverp->refCount-- > 0); + osi_assert(serverp->refCount-- > 0); } void cm_SetServerPrefs(cm_server_t * serverp) { - unsigned long serverAddr; /* in host byte order */ - unsigned long myAddr, myNet, mySubnet;/* in host byte order */ - unsigned long netMask; - int i; - - /* implement server prefs for fileservers only */ - if ( serverp->type == CM_SERVER_FILE ) - { - serverAddr = ntohl(serverp->addr.sin_addr.s_addr); - serverp->ipRank = CM_IPRANK_LOW; /* default setings */ - - for ( i=0; i < cm_noIPAddr; i++) - { - /* loop through all the client's IP address and compare - ** each of them against the server's IP address */ - - myAddr = cm_IPAddr[i]; - if ( IN_CLASSA(myAddr) ) - netMask = IN_CLASSA_NET; - else if ( IN_CLASSB(myAddr) ) - netMask = IN_CLASSB_NET; - else if ( IN_CLASSC(myAddr) ) - netMask = IN_CLASSC_NET; - else - netMask = 0; - - myNet = myAddr & netMask; - mySubnet = myAddr & cm_SubnetMask[i]; - - if ( (serverAddr & netMask) == myNet ) - { - if ( (serverAddr & cm_SubnetMask[i]) == mySubnet) - { - if ( serverAddr == myAddr ) - serverp->ipRank = min(serverp->ipRank, - CM_IPRANK_TOP);/* same machine */ - else serverp->ipRank = min(serverp->ipRank, - CM_IPRANK_HI); /* same subnet */ - } - else serverp->ipRank = min(serverp->ipRank,CM_IPRANK_MED); - /* same net */ - } - /* random between 0..15*/ - serverp->ipRank += min(serverp->ipRank, rand() % 0x000f); - } /* and of for loop */ - } + unsigned long serverAddr; /* in host byte order */ + unsigned long myAddr, myNet, mySubnet;/* in host byte order */ + unsigned long netMask; + int i; + + /* implement server prefs for fileservers only */ + if ( serverp->type == CM_SERVER_FILE ) + { + serverAddr = ntohl(serverp->addr.sin_addr.s_addr); + serverp->ipRank = CM_IPRANK_LOW; /* default setings */ + + for ( i=0; i < cm_noIPAddr; i++) + { + /* loop through all the client's IP address and compare + ** each of them against the server's IP address */ + + myAddr = cm_IPAddr[i]; + if ( IN_CLASSA(myAddr) ) + netMask = IN_CLASSA_NET; + else if ( IN_CLASSB(myAddr) ) + netMask = IN_CLASSB_NET; + else if ( IN_CLASSC(myAddr) ) + netMask = IN_CLASSC_NET; + else + netMask = 0; + + myNet = myAddr & netMask; + mySubnet = myAddr & cm_SubnetMask[i]; + + if ( (serverAddr & netMask) == myNet ) + { + if ( (serverAddr & cm_SubnetMask[i]) == mySubnet) + { + if ( serverAddr == myAddr ) + serverp->ipRank = min(serverp->ipRank, + CM_IPRANK_TOP);/* same machine */ + else serverp->ipRank = min(serverp->ipRank, + CM_IPRANK_HI); /* same subnet */ + } + else serverp->ipRank = min(serverp->ipRank,CM_IPRANK_MED); + /* same net */ + } + /* random between 0..15*/ + serverp->ipRank += min(serverp->ipRank, rand() % 0x000f); + } /* and of for loop */ + } else serverp->ipRank = 10000 + (rand() % 0x00ff); /* VL server */ } cm_server_t *cm_NewServer(struct sockaddr_in *socketp, int type, cm_cell_t *cellp) { - cm_server_t *tsp; + cm_server_t *tsp; - osi_assert(socketp->sin_family == AF_INET); + osi_assert(socketp->sin_family == AF_INET); - tsp = malloc(sizeof(*tsp)); + tsp = malloc(sizeof(*tsp)); memset(tsp, 0, sizeof(*tsp)); - tsp->type = type; + tsp->type = type; tsp->cellp = cellp; tsp->refCount = 1; - lock_InitializeMutex(&tsp->mx, "cm_server_t mutex"); - tsp->addr = *socketp; + lock_InitializeMutex(&tsp->mx, "cm_server_t mutex"); + tsp->addr = *socketp; - cm_SetServerPrefs(tsp); + cm_SetServerPrefs(tsp); lock_ObtainWrite(&cm_serverLock); /* get server lock */ - tsp->allNextp = cm_allServersp; + tsp->allNextp = cm_allServersp; cm_allServersp = tsp; lock_ReleaseWrite(&cm_serverLock); /* release server lock */ @@ -237,58 +240,58 @@ cm_server_t *cm_NewServer(struct sockaddr_in *socketp, int type, cm_cell_t *cell /* find a server based on its properties */ cm_server_t *cm_FindServer(struct sockaddr_in *addrp, int type) { - cm_server_t *tsp; + cm_server_t *tsp; - osi_assert(addrp->sin_family == AF_INET); + osi_assert(addrp->sin_family == AF_INET); - lock_ObtainWrite(&cm_serverLock); - for(tsp = cm_allServersp; tsp; tsp=tsp->allNextp) { - if (tsp->type == type && - tsp->addr.sin_addr.s_addr == addrp->sin_addr.s_addr) break; - } + lock_ObtainWrite(&cm_serverLock); + for (tsp = cm_allServersp; tsp; tsp=tsp->allNextp) { + if (tsp->type == type && + tsp->addr.sin_addr.s_addr == addrp->sin_addr.s_addr) break; + } - /* bump ref count if we found the server */ + /* bump ref count if we found the server */ if (tsp) cm_GetServerNoLock(tsp); - /* drop big table lock */ - lock_ReleaseWrite(&cm_serverLock); + /* drop big table lock */ + lock_ReleaseWrite(&cm_serverLock); - /* return what we found */ - return tsp; -} + /* return what we found */ + return tsp; +} cm_serverRef_t *cm_NewServerRef(cm_server_t *serverp) { - cm_serverRef_t *tsrp; + cm_serverRef_t *tsrp; cm_GetServer(serverp); - tsrp = malloc(sizeof(*tsrp)); - tsrp->server = serverp; - tsrp->status = not_busy; - tsrp->next = NULL; + tsrp = malloc(sizeof(*tsrp)); + tsrp->server = serverp; + tsrp->status = not_busy; + tsrp->next = NULL; tsrp->refCount = 1; - return tsrp; + return tsrp; } long cm_ChecksumServerList(cm_serverRef_t *serversp) { - long sum = 0; - int first = 1; - cm_serverRef_t *tsrp; + long sum = 0; + int first = 1; + cm_serverRef_t *tsrp; lock_ObtainWrite(&cm_serverLock); - for (tsrp = serversp; tsrp; tsrp=tsrp->next) { - if (first) - first = 0; - else - sum <<= 1; - sum ^= (long) tsrp->server; - } + for (tsrp = serversp; tsrp; tsrp=tsrp->next) { + if (first) + first = 0; + else + sum <<= 1; + sum ^= (long) tsrp->server; + } lock_ReleaseWrite(&cm_serverLock); - return sum; + return sum; } /* @@ -299,31 +302,31 @@ long cm_ChecksumServerList(cm_serverRef_t *serversp) */ void cm_InsertServerList(cm_serverRef_t** list, cm_serverRef_t* element) { - cm_serverRef_t *current=*list; - unsigned short ipRank = element->server->ipRank; + cm_serverRef_t *current=*list; + unsigned short ipRank = element->server->ipRank; lock_ObtainWrite(&cm_serverLock); element->refCount++; /* increase refCount */ /* insertion into empty list or at the beginning of the list */ - if ( !current || (current->server->ipRank > ipRank) ) - { - element->next = *list; - *list = element; + if ( !current || (current->server->ipRank > ipRank) ) + { + element->next = *list; + *list = element; lock_ReleaseWrite(&cm_serverLock); - return ; - } + return ; + } - while ( current->next ) /* find appropriate place to insert */ - { - if ( current->next->server->ipRank > ipRank ) - break; - else current = current->next; - } - element->next = current->next; - current->next = element; + while ( current->next ) /* find appropriate place to insert */ + { + if ( current->next->server->ipRank > ipRank ) + break; + else current = current->next; + } + element->next = current->next; + current->next = element; lock_ReleaseWrite(&cm_serverLock); -} +} /* ** Re-sort the server list with the modified rank ** returns 0 if element was changed successfully. @@ -331,39 +334,39 @@ void cm_InsertServerList(cm_serverRef_t** list, cm_serverRef_t* element) */ long cm_ChangeRankServer(cm_serverRef_t** list, cm_server_t* server) { - cm_serverRef_t **current=list; - cm_serverRef_t *element=0; + cm_serverRef_t **current=list; + cm_serverRef_t *element=0; - /* if there is max of one element in the list, nothing to sort */ - if ( (!*current) || !((*current)->next) ) - return 1; /* list unchanged: return success */ + /* if there is max of one element in the list, nothing to sort */ + if ( (!*current) || !((*current)->next) ) + return 1; /* list unchanged: return success */ lock_ObtainWrite(&cm_serverLock); - /* if the server is on the list, delete it from list */ - while ( *current ) - { - if ( (*current)->server == server) - { - element = (*current); - *current = (*current)->next; /* delete it */ - break; - } - current = & ( (*current)->next); - } + /* if the server is on the list, delete it from list */ + while ( *current ) + { + if ( (*current)->server == server) + { + element = (*current); + *current = (*current)->next; /* delete it */ + break; + } + current = & ( (*current)->next); + } lock_ReleaseWrite(&cm_serverLock); /* if this volume is not replicated on this server */ - if (!element) - return 1; /* server is not on list */ + if (!element) + return 1; /* server is not on list */ - /* re-insert deleted element into the list with modified rank*/ - cm_InsertServerList(list, element); + /* re-insert deleted element into the list with modified rank*/ + cm_InsertServerList(list, element); /* reduce refCount which was increased by cm_InsertServerList */ lock_ObtainWrite(&cm_serverLock); element->refCount--; lock_ReleaseWrite(&cm_serverLock); - return 0; + return 0; } /* ** If there are more than one server on the list and the first n servers on @@ -371,49 +374,49 @@ long cm_ChangeRankServer(cm_serverRef_t** list, cm_server_t* server) */ void cm_RandomizeServer(cm_serverRef_t** list) { - int count, picked; - cm_serverRef_t* tsrp = *list, *lastTsrp; - unsigned short lowestRank; + int count, picked; + cm_serverRef_t* tsrp = *list, *lastTsrp; + unsigned short lowestRank; - /* an empty list or a list with only one element */ - if ( !tsrp || ! tsrp->next ) - return ; + /* an empty list or a list with only one element */ + if ( !tsrp || ! tsrp->next ) + return ; lock_ObtainWrite(&cm_serverLock); - /* count the number of servers with the lowest rank */ - lowestRank = tsrp->server->ipRank; - for ( count=1, tsrp=tsrp->next; tsrp; tsrp=tsrp->next) - { - if ( tsrp->server->ipRank != lowestRank) - break; - else - count++; - } - - /* if there is only one server with the lowest rank, we are done */ - if ( count <= 1 ) { + /* count the number of servers with the lowest rank */ + lowestRank = tsrp->server->ipRank; + for ( count=1, tsrp=tsrp->next; tsrp; tsrp=tsrp->next) + { + if ( tsrp->server->ipRank != lowestRank) + break; + else + count++; + } + + /* if there is only one server with the lowest rank, we are done */ + if ( count <= 1 ) { lock_ReleaseWrite(&cm_serverLock); - return ; - } + return ; + } - picked = rand() % count; - if ( !picked ) { + picked = rand() % count; + if ( !picked ) { lock_ReleaseWrite(&cm_serverLock); - return ; - } + return ; + } - tsrp = *list; - while (--picked >= 0) - { - lastTsrp = tsrp; - tsrp = tsrp->next; - } - lastTsrp->next = tsrp->next; /* delete random element from list*/ - tsrp->next = *list; /* insert element at the beginning of list */ - *list = tsrp; + tsrp = *list; + while (--picked >= 0) + { + lastTsrp = tsrp; + tsrp = tsrp->next; + } + lastTsrp->next = tsrp->next; /* delete random element from list*/ + tsrp->next = *list; /* insert element at the beginning of list */ + *list = tsrp; lock_ReleaseWrite(&cm_serverLock); -} +} /* call cm_FreeServer while holding a write lock on cm_serverLock */ void cm_FreeServer(cm_server_t* serverp) @@ -447,7 +450,7 @@ void cm_FreeServerList(cm_serverRef_t** list) { cm_serverRef_t **current = list; cm_serverRef_t **nextp = 0; - cm_serverRef_t * next = 0; + cm_serverRef_t * next = 0; lock_ObtainWrite(&cm_serverLock); @@ -455,7 +458,7 @@ void cm_FreeServerList(cm_serverRef_t** list) { nextp = &(*current)->next; if (--((*current)->refCount) == 0) { - next = *nextp; + next = *nextp; cm_FreeServer((*current)->server); free(*current); *current = next; diff --git a/src/WINNT/afsd/cm_server.h b/src/WINNT/afsd/cm_server.h index fc766c316..0ea6e6787 100644 --- a/src/WINNT/afsd/cm_server.h +++ b/src/WINNT/afsd/cm_server.h @@ -27,7 +27,7 @@ typedef struct cm_server { struct cm_conn *connsp; /* locked by cm_connLock */ long flags; /* by mx */ struct cm_cell *cellp; /* cell containing this server */ - int refCount; /* locked by cm_serverLock */ + unsigned long refCount; /* locked by cm_serverLock */ osi_mutex_t mx; unsigned short ipRank; /* server priority */ } cm_server_t; @@ -38,7 +38,7 @@ typedef struct cm_serverRef { struct cm_serverRef *next; /* locked by cm_serverLock */ struct cm_server *server; /* locked by cm_serverLock */ enum repstate status; /* locked by cm_serverLock */ - int refCount; /* locked by cm_serverLock */ + unsigned long refCount; /* locked by cm_serverLock */ } cm_serverRef_t; /* types */ diff --git a/src/WINNT/afsd/cm_user.h b/src/WINNT/afsd/cm_user.h index 3a160d7b0..1e586498b 100644 --- a/src/WINNT/afsd/cm_user.h +++ b/src/WINNT/afsd/cm_user.h @@ -39,7 +39,7 @@ typedef struct cm_ucell { #define CM_UCELLFLAG_BADTIX 4 /* tickets are bad or expired */ typedef struct cm_user { - int refCount; /* ref count */ + unsigned long refCount; /* ref count */ cm_ucell_t *cellInfop; /* list of cell info */ osi_mutex_t mx; /* mutex */ int vcRefs; /* count of references from virtual circuits */ diff --git a/src/WINNT/afsd/cm_utils.c b/src/WINNT/afsd/cm_utils.c index f7e3284c0..edceef032 100644 --- a/src/WINNT/afsd/cm_utils.c +++ b/src/WINNT/afsd/cm_utils.c @@ -30,41 +30,52 @@ cm_space_t *cm_spaceListp; long cm_MapRPCError(long error, cm_req_t *reqp) { - if (error == 0) return 0; - - /* If we had to stop retrying, report our saved error code. */ - if (reqp && error == CM_ERROR_TIMEDOUT) { - if (reqp->accessError) - return reqp->accessError; - if (reqp->volumeError) - return reqp->volumeError; - if (reqp->rpcError) - return reqp->rpcError; - return error; - } - - if (error < 0) error = CM_ERROR_TIMEDOUT; - else if (error == 30) error = CM_ERROR_READONLY; - else if (error == 13) error = CM_ERROR_NOACCESS; - else if (error == 18) error = CM_ERROR_CROSSDEVLINK; - else if (error == 17) error = CM_ERROR_EXISTS; - else if (error == 20) error = CM_ERROR_NOTDIR; - else if (error == 2) error = CM_ERROR_NOSUCHFILE; - else if (error == 11 /* EAGAIN, most servers */ - || error == 35) /* EAGAIN, Digital UNIX */ - error = CM_ERROR_WOULDBLOCK; - else if (error == VDISKFULL - || error == 28) /* ENOSPC */ - error = CM_ERROR_SPACE; - else if (error == VOVERQUOTA - || error == 49 /* EDQUOT on Solaris */ - || error == 88 /* EDQUOT on AIX */ - || error == 69 /* EDQUOT on Digital UNIX and HPUX */ - || error == 122 /* EDQUOT on Linux */ - || error == 1133) /* EDQUOT on Irix */ - error = CM_ERROR_QUOTA; - else if (error == VNOVNODE) error = CM_ERROR_BADFD; + if (error == 0) + return 0; + + /* If we had to stop retrying, report our saved error code. */ + if (reqp && error == CM_ERROR_TIMEDOUT) { + if (reqp->accessError) + return reqp->accessError; + if (reqp->volumeError) + return reqp->volumeError; + if (reqp->rpcError) + return reqp->rpcError; return error; + } + + if (error < 0) + error = CM_ERROR_TIMEDOUT; + else if (error == 30) + error = CM_ERROR_READONLY; + else if (error == 13) + error = CM_ERROR_NOACCESS; + else if (error == 18) + error = CM_ERROR_CROSSDEVLINK; + else if (error == 17) + error = CM_ERROR_EXISTS; + else if (error == 20) + error = CM_ERROR_NOTDIR; + else if (error == 2) + error = CM_ERROR_NOSUCHFILE; + else if (error == 11 /* EAGAIN, most servers */ + || error == 35) /* EAGAIN, Digital UNIX */ + error = CM_ERROR_WOULDBLOCK; + else if (error == VDISKFULL + || error == 28) /* ENOSPC */ + error = CM_ERROR_SPACE; + else if (error == VOVERQUOTA + || error == 49 /* EDQUOT on Solaris */ + || error == 88 /* EDQUOT on AIX */ + || error == 69 /* EDQUOT on Digital UNIX and HPUX */ + || error == 122 /* EDQUOT on Linux */ + || error == 1133) /* EDQUOT on Irix */ + error = CM_ERROR_QUOTA; + else if (error == VNOVNODE) + error = CM_ERROR_BADFD; + else if (error == 21) + return CM_ERROR_ISDIR; + return error; } long cm_MapRPCErrorRmdir(long error, cm_req_t *reqp) diff --git a/src/WINNT/afsd/cm_vnodeops.c b/src/WINNT/afsd/cm_vnodeops.c index 22d75dd9f..5397dcbdd 100644 --- a/src/WINNT/afsd/cm_vnodeops.c +++ b/src/WINNT/afsd/cm_vnodeops.c @@ -80,23 +80,23 @@ unsigned char cm_foldUpper[256] = { */ int cm_stricmp(const char *str1, const char *str2) { - char c1, c2; - - while (1) { - if (*str1 == 0) - if (*str2 == 0) - return 0; - else - return -1; - if (*str2 == 0) - return 1; - c1 = (char) cm_foldUpper[(unsigned char)(*str1++)]; - c2 = (char) cm_foldUpper[(unsigned char)(*str2++)]; - if (c1 < c2) - return -1; - if (c1 > c2) - return 1; - } + char c1, c2; + + while (1) { + if (*str1 == 0) + if (*str2 == 0) + return 0; + else + return -1; + if (*str2 == 0) + return 1; + c1 = (char) cm_foldUpper[(unsigned char)(*str1++)]; + c2 = (char) cm_foldUpper[(unsigned char)(*str2++)]; + if (c1 < c2) + return -1; + if (c1 > c2) + return 1; + } } /* characters that are legal in an 8.3 name */ @@ -129,53 +129,53 @@ char cm_LegalChars[256] = { /* return true iff component is a valid 8.3 name */ int cm_Is8Dot3(char *namep) { - int sawDot = 0; - int sawUpper = 0, sawLower = 0; - unsigned char tc; - int charCount = 0; + int sawDot = 0; + int sawUpper = 0, sawLower = 0; + unsigned char tc; + int charCount = 0; - /* - * can't have a leading dot; - * special case for . and .. - */ - if (namep[0] == '.') { - if (namep[1] == 0) - return 1; - if (namep[1] == '.' && namep[2] == 0) - return 1; - return 0; - } - while (tc = *namep++) { - if (tc == '.') { - /* saw another dot */ - if (sawDot) return 0; /* second dot */ - sawDot = 1; - charCount = 0; - continue; - } - if (cm_LegalChars[tc] == 0) - return 0; - if (tc >= 'A' && tc <= 'Z') - sawUpper = 1; - else if (tc >= 'a' && tc <= 'z') - sawLower = 1; - charCount++; - if (!sawDot && charCount > 8) - /* more than 8 chars in name */ - return 0; - if (sawDot && charCount > 3) - /* more than 3 chars in extension */ - return 0; + /* + * can't have a leading dot; + * special case for . and .. + */ + if (namep[0] == '.') { + if (namep[1] == 0) + return 1; + if (namep[1] == '.' && namep[2] == 0) + return 1; + return 0; + } + while (tc = *namep++) { + if (tc == '.') { + /* saw another dot */ + if (sawDot) return 0; /* second dot */ + sawDot = 1; + charCount = 0; + continue; } -/* - * Used to check that all characters were the same case. - * This doesn't help 16-bit apps, and meanwhile it causes the - * MS-DOS Command Prompt to misbehave; see Sybase defect 10709. - * - if (sawUpper && sawLower) - return 0; - */ - return 1; + if (cm_LegalChars[tc] == 0) + return 0; + if (tc >= 'A' && tc <= 'Z') + sawUpper = 1; + else if (tc >= 'a' && tc <= 'z') + sawLower = 1; + charCount++; + if (!sawDot && charCount > 8) + /* more than 8 chars in name */ + return 0; + if (sawDot && charCount > 3) + /* more than 3 chars in extension */ + return 0; + } + /* + * Used to check that all characters were the same case. + * This doesn't help 16-bit apps, and meanwhile it causes the + * MS-DOS Command Prompt to misbehave; see Sybase defect 10709. + * + if (sawUpper && sawLower) + return 0; + */ + return 1; } /* @@ -191,133 +191,133 @@ int cm_8Dot3MapSize = sizeof(cm_8Dot3Mapping); void cm_Gen8Dot3Name(cm_dirEntry_t *dep, char *shortName, char **shortNameEndp) { - char number[12]; - int i, nsize = 0; - int vnode = ntohl(dep->fid.vnode); - char *lastDot; - int validExtension = 0; - char tc, *temp, *name; - - /* Unparse the file's vnode number to get a "uniquifier" */ - do { - number[nsize] = cm_8Dot3Mapping[vnode % cm_8Dot3MapSize]; - nsize++; - vnode /= cm_8Dot3MapSize; - } while (vnode); - - /* - * Look for valid extension. There has to be a dot, and - * at least one of the characters following has to be legal. - */ - lastDot = strrchr(dep->name, '.'); - if (lastDot) { - temp = lastDot; temp++; - while (tc = *temp++) - if (cm_LegalChars[tc]) - break; - if (tc) - validExtension = 1; - } - - /* Copy name characters */ - name = dep->name; - for (i = 0, name = dep->name; - i < (7 - nsize) && name != lastDot; ) { - tc = *name++; - - if (tc == 0) - break; - if (!cm_LegalChars[tc]) - continue; - i++; - *shortName++ = toupper(tc); - } - - /* tilde */ - *shortName++ = '~'; - - /* Copy uniquifier characters */ - memcpy(shortName, number, nsize); - shortName += nsize; - - if (validExtension) { - /* Copy extension characters */ - *shortName++ = *lastDot++; /* copy dot */ - for (i = 0, tc = *lastDot++; - i < 3 && tc; - tc = *lastDot++) { - if (cm_LegalChars[tc]) { - i++; - *shortName++ = toupper(tc); - } - } - } + char number[12]; + int i, nsize = 0; + int vnode = ntohl(dep->fid.vnode); + char *lastDot; + int validExtension = 0; + char tc, *temp, *name; + + /* Unparse the file's vnode number to get a "uniquifier" */ + do { + number[nsize] = cm_8Dot3Mapping[vnode % cm_8Dot3MapSize]; + nsize++; + vnode /= cm_8Dot3MapSize; + } while (vnode); + + /* + * Look for valid extension. There has to be a dot, and + * at least one of the characters following has to be legal. + */ + lastDot = strrchr(dep->name, '.'); + if (lastDot) { + temp = lastDot; temp++; + while (tc = *temp++) + if (cm_LegalChars[tc]) + break; + if (tc) + validExtension = 1; + } + + /* Copy name characters */ + name = dep->name; + for (i = 0, name = dep->name; + i < (7 - nsize) && name != lastDot; ) { + tc = *name++; + + if (tc == 0) + break; + if (!cm_LegalChars[tc]) + continue; + i++; + *shortName++ = toupper(tc); + } + + /* tilde */ + *shortName++ = '~'; + + /* Copy uniquifier characters */ + memcpy(shortName, number, nsize); + shortName += nsize; + + if (validExtension) { + /* Copy extension characters */ + *shortName++ = *lastDot++; /* copy dot */ + for (i = 0, tc = *lastDot++; + i < 3 && tc; + tc = *lastDot++) { + if (cm_LegalChars[tc]) { + i++; + *shortName++ = toupper(tc); + } + } + } - /* Trailing null */ - *shortName = 0; + /* Trailing null */ + *shortName = 0; - if (shortNameEndp) - *shortNameEndp = shortName; -} + if (shortNameEndp) + *shortNameEndp = shortName; +} /* return success if we can open this file in this mode */ long cm_CheckOpen(cm_scache_t *scp, int openMode, int trunc, cm_user_t *userp, - cm_req_t *reqp) + cm_req_t *reqp) { - long rights; - long code; + long rights; + long code; - rights = 0; - if (openMode != 1) rights |= PRSFS_READ; - if (openMode == 1 || openMode == 2 || trunc) rights |= PRSFS_WRITE; + rights = 0; + if (openMode != 1) rights |= PRSFS_READ; + if (openMode == 1 || openMode == 2 || trunc) rights |= PRSFS_WRITE; - lock_ObtainMutex(&scp->mx); + lock_ObtainMutex(&scp->mx); - code = cm_SyncOp(scp, NULL, userp, reqp, rights, - CM_SCACHESYNC_GETSTATUS - | CM_SCACHESYNC_NEEDCALLBACK); - lock_ReleaseMutex(&scp->mx); + code = cm_SyncOp(scp, NULL, userp, reqp, rights, + CM_SCACHESYNC_GETSTATUS + | CM_SCACHESYNC_NEEDCALLBACK); + lock_ReleaseMutex(&scp->mx); - return code; + return code; } /* return success if we can open this file in this mode */ long cm_CheckNTOpen(cm_scache_t *scp, unsigned int desiredAccess, - unsigned int createDisp, cm_user_t *userp, cm_req_t *reqp) + unsigned int createDisp, cm_user_t *userp, cm_req_t *reqp) { - long rights; - long code; + long rights; + long code; - /* Always allow delete; the RPC will tell us if it's OK */ - if (desiredAccess == DELETE) - return 0; + /* Always allow delete; the RPC will tell us if it's OK */ + if (desiredAccess == DELETE) + return 0; - rights = 0; + rights = 0; - if (desiredAccess & AFS_ACCESS_READ) - rights |= PRSFS_READ; + if (desiredAccess & AFS_ACCESS_READ) + rights |= PRSFS_READ; - if ((desiredAccess & AFS_ACCESS_WRITE) - || createDisp == 4) - rights |= PRSFS_WRITE; - - lock_ObtainMutex(&scp->mx); - - code = cm_SyncOp(scp, NULL, userp, reqp, rights, - CM_SCACHESYNC_GETSTATUS - | CM_SCACHESYNC_NEEDCALLBACK); - lock_ReleaseMutex(&scp->mx); - - /* - * If the open will fail because the volume is readonly, then we will - * return an access denied error instead. This is to help brain-dead - * apps run correctly on replicated volumes. - * See defect 10007 for more information. - */ - if (code == CM_ERROR_READONLY) - code = CM_ERROR_NOACCESS; + if ((desiredAccess & AFS_ACCESS_WRITE) + || createDisp == 4) + rights |= PRSFS_WRITE; + + lock_ObtainMutex(&scp->mx); - return code; + code = cm_SyncOp(scp, NULL, userp, reqp, rights, + CM_SCACHESYNC_GETSTATUS + | CM_SCACHESYNC_NEEDCALLBACK); + lock_ReleaseMutex(&scp->mx); + + /* + * If the open will fail because the volume is readonly, then we will + * return an access denied error instead. This is to help brain-dead + * apps run correctly on replicated volumes. + * See defect 10007 for more information. + */ + if (code == CM_ERROR_READONLY) + code = CM_ERROR_NOACCESS; + + return code; } /* @@ -336,92 +336,92 @@ long cm_CheckNTOpen(cm_scache_t *scp, unsigned int desiredAccess, long cm_CheckNTDelete(cm_scache_t *dscp, cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp) { - long code; - osi_hyper_t thyper; - cm_buf_t *bufferp; - cm_dirEntry_t *dep; - unsigned short *hashTable; - unsigned int i, idx; - int BeyondPage = 0, HaveDot = 0, HaveDotDot = 0; - - /* First check permissions */ - lock_ObtainMutex(&dscp->mx); - code = cm_SyncOp(dscp, NULL, userp, reqp, PRSFS_DELETE, - CM_SCACHESYNC_GETSTATUS - | CM_SCACHESYNC_NEEDCALLBACK); - lock_ReleaseMutex(&dscp->mx); - if (code) - return code; - - /* If deleting directory, must be empty */ - - if (scp->fileType != CM_SCACHETYPE_DIRECTORY) - return code; - - thyper.HighPart = 0; thyper.LowPart = 0; - lock_ObtainRead(&scp->bufCreateLock); - code = buf_Get(scp, &thyper, &bufferp); - lock_ReleaseRead(&scp->bufCreateLock); - if (code) - return code; - - lock_ObtainMutex(&bufferp->mx); - lock_ObtainMutex(&scp->mx); - while (1) { - code = cm_SyncOp(scp, bufferp, userp, reqp, 0, - CM_SCACHESYNC_NEEDCALLBACK - | CM_SCACHESYNC_READ - | CM_SCACHESYNC_BUFLOCKED); - if (code) - break; - - if (cm_HaveBuffer(scp, bufferp, 1)) - break; - - /* otherwise, load the buffer and try again */ - lock_ReleaseMutex(&bufferp->mx); - code = cm_GetBuffer(scp, bufferp, NULL, userp, reqp); - lock_ReleaseMutex(&scp->mx); - lock_ObtainMutex(&bufferp->mx); - lock_ObtainMutex(&scp->mx); - if (code) - break; - } - - /* We try to determine emptiness without looking beyond the first page, - * and without assuming "." and ".." are present and are on the first - * page (though these assumptions might, after all, be reasonable). - */ - hashTable = (unsigned short *)(bufferp->datap + (32 * 5)); - for (i=0; i<128; i++) { - idx = ntohs(hashTable[i]); - while (idx) { - if (idx >= 64) { - BeyondPage = 1; - break; - } - dep = (cm_dirEntry_t *)(bufferp->datap + (32 * idx)); - if (strcmp(dep->name, ".") == 0) - HaveDot = 1; - else if (strcmp(dep->name, "..") == 0) - HaveDotDot = 1; - else { - code = CM_ERROR_NOTEMPTY; - goto done; - } - idx = ntohs(dep->next); - } - } - if (BeyondPage && HaveDot && HaveDotDot) - code = CM_ERROR_NOTEMPTY; - else - code = 0; -done: - lock_ReleaseMutex(&bufferp->mx); - buf_Release(bufferp); - lock_ReleaseMutex(&scp->mx); - return code; -} + long code; + osi_hyper_t thyper; + cm_buf_t *bufferp; + cm_dirEntry_t *dep; + unsigned short *hashTable; + unsigned int i, idx; + int BeyondPage = 0, HaveDot = 0, HaveDotDot = 0; + + /* First check permissions */ + lock_ObtainMutex(&dscp->mx); + code = cm_SyncOp(dscp, NULL, userp, reqp, PRSFS_DELETE, + CM_SCACHESYNC_GETSTATUS + | CM_SCACHESYNC_NEEDCALLBACK); + lock_ReleaseMutex(&dscp->mx); + if (code) + return code; + + /* If deleting directory, must be empty */ + + if (scp->fileType != CM_SCACHETYPE_DIRECTORY) + return code; + + thyper.HighPart = 0; thyper.LowPart = 0; + lock_ObtainRead(&scp->bufCreateLock); + code = buf_Get(scp, &thyper, &bufferp); + lock_ReleaseRead(&scp->bufCreateLock); + if (code) + return code; + + lock_ObtainMutex(&bufferp->mx); + lock_ObtainMutex(&scp->mx); + while (1) { + code = cm_SyncOp(scp, bufferp, userp, reqp, 0, + CM_SCACHESYNC_NEEDCALLBACK + | CM_SCACHESYNC_READ + | CM_SCACHESYNC_BUFLOCKED); + if (code) + break; + + if (cm_HaveBuffer(scp, bufferp, 1)) + break; + + /* otherwise, load the buffer and try again */ + lock_ReleaseMutex(&bufferp->mx); + code = cm_GetBuffer(scp, bufferp, NULL, userp, reqp); + lock_ReleaseMutex(&scp->mx); + lock_ObtainMutex(&bufferp->mx); + lock_ObtainMutex(&scp->mx); + if (code) + break; + } + + /* We try to determine emptiness without looking beyond the first page, + * and without assuming "." and ".." are present and are on the first + * page (though these assumptions might, after all, be reasonable). + */ + hashTable = (unsigned short *)(bufferp->datap + (32 * 5)); + for (i=0; i<128; i++) { + idx = ntohs(hashTable[i]); + while (idx) { + if (idx >= 64) { + BeyondPage = 1; + break; + } + dep = (cm_dirEntry_t *)(bufferp->datap + (32 * idx)); + if (strcmp(dep->name, ".") == 0) + HaveDot = 1; + else if (strcmp(dep->name, "..") == 0) + HaveDotDot = 1; + else { + code = CM_ERROR_NOTEMPTY; + goto done; + } + idx = ntohs(dep->next); + } + } + if (BeyondPage && HaveDot && HaveDotDot) + code = CM_ERROR_NOTEMPTY; + else + code = 0; + done: + lock_ReleaseMutex(&bufferp->mx); + buf_Release(bufferp); + lock_ReleaseMutex(&scp->mx); + return code; +} /* * Iterate through all entries in a directory. @@ -429,8 +429,8 @@ done: * directory vnode is not. */ long cm_ApplyDir(cm_scache_t *scp, cm_DirFuncp_t funcp, void *parmp, - osi_hyper_t *startOffsetp, cm_user_t *userp, cm_req_t *reqp, - cm_scache_t **retscp) + osi_hyper_t *startOffsetp, cm_user_t *userp, cm_req_t *reqp, + cm_scache_t **retscp) { char *tp; long code; @@ -443,74 +443,74 @@ long cm_ApplyDir(cm_scache_t *scp, cm_DirFuncp_t funcp, void *parmp, osi_hyper_t thyper; long entryInDir; long entryInBuffer; - cm_pageHeader_t *pageHeaderp; + cm_pageHeader_t *pageHeaderp; int slotInPage; long nextEntryCookie; int numDirChunks; /* # of 32 byte dir chunks in this entry */ /* get the directory size */ - lock_ObtainMutex(&scp->mx); + lock_ObtainMutex(&scp->mx); code = cm_SyncOp(scp, NULL, userp, reqp, PRSFS_LOOKUP, - CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); - if (code) { - lock_ReleaseMutex(&scp->mx); + CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + if (code) { + lock_ReleaseMutex(&scp->mx); return code; } if (scp->fileType != CM_SCACHETYPE_DIRECTORY) { - lock_ReleaseMutex(&scp->mx); - return CM_ERROR_NOTDIR; - } + lock_ReleaseMutex(&scp->mx); + return CM_ERROR_NOTDIR; + } - if (retscp) /* if this is a lookup call */ - { - cm_lookupSearch_t* sp = parmp; + if (retscp) /* if this is a lookup call */ + { + cm_lookupSearch_t* sp = parmp; int casefold = sp->caseFold; sp->caseFold = 0; /* we have a strong preference for exact matches */ - if ( *retscp = cm_dnlcLookup(scp, sp)) /* dnlc hit */ - { + if ( *retscp = cm_dnlcLookup(scp, sp)) /* dnlc hit */ + { sp->caseFold = casefold; - lock_ReleaseMutex(&scp->mx); - return 0; - } + lock_ReleaseMutex(&scp->mx); + return 0; + } sp->caseFold = casefold; - } + } - /* - * XXX We only get the length once. It might change when we drop the - * lock. - */ + /* + * XXX We only get the length once. It might change when we drop the + * lock. + */ dirLength = scp->length; - lock_ReleaseMutex(&scp->mx); + lock_ReleaseMutex(&scp->mx); bufferp = NULL; bufferOffset.LowPart = bufferOffset.HighPart = 0; - if (startOffsetp) + if (startOffsetp) curOffset = *startOffsetp; - else { + else { curOffset.HighPart = 0; curOffset.LowPart = 0; - } + } while (1) { - /* make sure that curOffset.LowPart doesn't point to the first + /* make sure that curOffset.LowPart doesn't point to the first * 32 bytes in the 2nd through last dir page, and that it - * doesn't point at the first 13 32-byte chunks in the first - * dir page, since those are dir and page headers, and don't - * contain useful information. + * doesn't point at the first 13 32-byte chunks in the first + * dir page, since those are dir and page headers, and don't + * contain useful information. */ - temp = curOffset.LowPart & (2048-1); + temp = curOffset.LowPart & (2048-1); if (curOffset.HighPart == 0 && curOffset.LowPart < 2048) { /* we're in the first page */ if (temp < 13*32) temp = 13*32; - } - else { - /* we're in a later dir page */ - if (temp < 32) temp = 32; } + else { + /* we're in a later dir page */ + if (temp < 32) temp = 32; + } /* make sure the low order 5 bits are zero */ temp &= ~(32-1); @@ -521,487 +521,468 @@ long cm_ApplyDir(cm_scache_t *scp, cm_DirFuncp_t funcp, void *parmp, /* check if we've passed the dir's EOF */ if (LargeIntegerGreaterThanOrEqualTo(curOffset, dirLength)) - break; + break; /* see if we can use the bufferp we have now; compute in which * page the current offset would be, and check whether that's - * the offset of the buffer we have. If not, get the buffer. - */ + * the offset of the buffer we have. If not, get the buffer. + */ thyper.HighPart = curOffset.HighPart; thyper.LowPart = curOffset.LowPart & ~(buf_bufferSize-1); if (!bufferp || !LargeIntegerEqualTo(thyper, bufferOffset)) { - /* wrong buffer */ + /* wrong buffer */ if (bufferp) { - lock_ReleaseMutex(&bufferp->mx); + lock_ReleaseMutex(&bufferp->mx); buf_Release(bufferp); bufferp = NULL; - } + } - lock_ObtainRead(&scp->bufCreateLock); + lock_ObtainRead(&scp->bufCreateLock); code = buf_Get(scp, &thyper, &bufferp); - lock_ReleaseRead(&scp->bufCreateLock); + lock_ReleaseRead(&scp->bufCreateLock); - lock_ObtainMutex(&bufferp->mx); - if (code) break; + lock_ObtainMutex(&bufferp->mx); + if (code) + break; bufferOffset = thyper; /* now get the data in the cache */ while (1) { lock_ObtainMutex(&scp->mx); - code = cm_SyncOp(scp, bufferp, userp, reqp, - PRSFS_LOOKUP, - CM_SCACHESYNC_NEEDCALLBACK - | CM_SCACHESYNC_READ - | CM_SCACHESYNC_BUFLOCKED); - if (code) { - lock_ReleaseMutex(&scp->mx); - break; - } + code = cm_SyncOp(scp, bufferp, userp, reqp, + PRSFS_LOOKUP, + CM_SCACHESYNC_NEEDCALLBACK + | CM_SCACHESYNC_READ + | CM_SCACHESYNC_BUFLOCKED); + if (code) { + lock_ReleaseMutex(&scp->mx); + break; + } if (cm_HaveBuffer(scp, bufferp, 1)) { - lock_ReleaseMutex(&scp->mx); - break; - } - + lock_ReleaseMutex(&scp->mx); + break; + } + /* otherwise, load the buffer and try again */ lock_ReleaseMutex(&bufferp->mx); code = cm_GetBuffer(scp, bufferp, NULL, userp, reqp); lock_ReleaseMutex(&scp->mx); lock_ObtainMutex(&bufferp->mx); - if (code) break; + if (code) + break; } if (code) { - lock_ReleaseMutex(&bufferp->mx); - buf_Release(bufferp); + lock_ReleaseMutex(&bufferp->mx); + buf_Release(bufferp); bufferp = NULL; break; - } + } } /* if (wrong buffer) ... */ /* now we have the buffer containing the entry we're interested * in; copy it out if it represents a non-deleted entry. */ - entryInDir = curOffset.LowPart & (2048-1); + entryInDir = curOffset.LowPart & (2048-1); entryInBuffer = curOffset.LowPart & (buf_bufferSize - 1); - /* page header will help tell us which entries are free. Page - * header can change more often than once per buffer, since - * AFS 3 dir page size may be less than (but not more than) a - * buffer package buffer. + /* page header will help tell us which entries are free. Page + * header can change more often than once per buffer, since + * AFS 3 dir page size may be less than (but not more than) a + * buffer package buffer. */ - /* only look intra-buffer */ - temp = curOffset.LowPart & (buf_bufferSize - 1); + /* only look intra-buffer */ + temp = curOffset.LowPart & (buf_bufferSize - 1); temp &= ~(2048 - 1); /* turn off intra-page bits */ - pageHeaderp = (cm_pageHeader_t *) (bufferp->datap + temp); + pageHeaderp = (cm_pageHeader_t *) (bufferp->datap + temp); - /* now determine which entry we're looking at in the page. If - * it is free (there's a free bitmap at the start of the dir), - * we should skip these 32 bytes. + /* now determine which entry we're looking at in the page. If + * it is free (there's a free bitmap at the start of the dir), + * we should skip these 32 bytes. */ slotInPage = (entryInDir & 0x7e0) >> 5; if (!(pageHeaderp->freeBitmap[slotInPage>>3] & (1 << (slotInPage & 0x7)))) { - /* this entry is free */ + /* this entry is free */ numDirChunks = 1; /* only skip this guy */ goto nextEntry; } - tp = bufferp->datap + entryInBuffer; + tp = bufferp->datap + entryInBuffer; dep = (cm_dirEntry_t *) tp; /* now points to AFS3 dir entry */ /* while we're here, compute the next entry's location, too, - * since we'll need it when writing out the cookie into the - * dir listing stream. + * since we'll need it when writing out the cookie into the + * dir listing stream. */ - numDirChunks = cm_NameEntries(dep->name, NULL); + numDirChunks = cm_NameEntries(dep->name, NULL); /* compute the offset of the cookie representing the next entry */ nextEntryCookie = curOffset.LowPart - + (CM_DIR_CHUNKSIZE * numDirChunks); + + (CM_DIR_CHUNKSIZE * numDirChunks); if (dep->fid.vnode != 0) { - /* this is one of the entries to use: it is not deleted */ - code = (*funcp)(scp, dep, parmp, &curOffset); - if (code) break; - } /* if we're including this name */ + /* this is one of the entries to use: it is not deleted */ + code = (*funcp)(scp, dep, parmp, &curOffset); + if (code) + break; + } /* if we're including this name */ nextEntry: /* and adjust curOffset to be where the new cookie is */ - thyper.HighPart = 0; + thyper.HighPart = 0; thyper.LowPart = CM_DIR_CHUNKSIZE * numDirChunks; curOffset = LargeIntegerAdd(thyper, curOffset); } /* while copying data for dir listing */ - /* release the mutex */ + /* release the mutex */ if (bufferp) { - lock_ReleaseMutex(&bufferp->mx); + lock_ReleaseMutex(&bufferp->mx); buf_Release(bufferp); - } + } return code; } int cm_NoneUpper(char *s) { - char c; - while (c = *s++) - if (c >= 'A' && c <= 'Z') - return 0; - return 1; + char c; + while (c = *s++) + if (c >= 'A' && c <= 'Z') + return 0; + return 1; } int cm_NoneLower(char *s) { - char c; - while (c = *s++) - if (c >= 'a' && c <= 'z') - return 0; - return 1; + char c; + while (c = *s++) + if (c >= 'a' && c <= 'z') + return 0; + return 1; } long cm_LookupSearchProc(cm_scache_t *scp, cm_dirEntry_t *dep, void *rockp, - osi_hyper_t *offp) + osi_hyper_t *offp) { - cm_lookupSearch_t *sp; + cm_lookupSearch_t *sp; int match; - char shortName[13]; - char *matchName; - + char shortName[13]; + char *matchName; + sp = (cm_lookupSearch_t *) rockp; - matchName = dep->name; - if (sp->caseFold) + matchName = dep->name; + if (sp->caseFold) match = cm_stricmp(matchName, sp->searchNamep); - else - match = strcmp(matchName, sp->searchNamep); - - if (match != 0 - && sp->hasTilde - && !cm_Is8Dot3(dep->name)) { - matchName = shortName; - cm_Gen8Dot3Name(dep, shortName, NULL); - if (sp->caseFold) - match = cm_stricmp(matchName, sp->searchNamep); - else - match = strcmp(matchName, sp->searchNamep); - } - - if (match != 0) - return 0; - - sp->found = 1; - if(!sp->caseFold) sp->ExactFound = 1; - - if (!sp->caseFold || matchName == shortName) { - sp->fid.vnode = ntohl(dep->fid.vnode); - sp->fid.unique = ntohl(dep->fid.unique); + else + match = strcmp(matchName, sp->searchNamep); + + if (match != 0 + && sp->hasTilde + && !cm_Is8Dot3(dep->name)) { + matchName = shortName; + cm_Gen8Dot3Name(dep, shortName, NULL); + if (sp->caseFold) + match = cm_stricmp(matchName, sp->searchNamep); + else + match = strcmp(matchName, sp->searchNamep); + } + + if (match != 0) + return 0; + + sp->found = 1; + if(!sp->caseFold) + sp->ExactFound = 1; + + if (!sp->caseFold || matchName == shortName) { + sp->fid.vnode = ntohl(dep->fid.vnode); + sp->fid.unique = ntohl(dep->fid.unique); return CM_ERROR_STOPNOW; } - /* - * If we get here, we are doing a case-insensitive search, and we - * have found a match. Now we determine what kind of match it is: - * exact, lower-case, upper-case, or none of the above. This is done - * in order to choose among matches, if there are more than one. - */ + /* + * If we get here, we are doing a case-insensitive search, and we + * have found a match. Now we determine what kind of match it is: + * exact, lower-case, upper-case, or none of the above. This is done + * in order to choose among matches, if there are more than one. + */ - /* Exact matches are the best. */ - match = strcmp(matchName, sp->searchNamep); - if (match == 0) { + /* Exact matches are the best. */ + match = strcmp(matchName, sp->searchNamep); + if (match == 0) { sp->ExactFound = 1; - sp->fid.vnode = ntohl(dep->fid.vnode); - sp->fid.unique = ntohl(dep->fid.unique); + sp->fid.vnode = ntohl(dep->fid.vnode); + sp->fid.unique = ntohl(dep->fid.unique); return CM_ERROR_STOPNOW; } - /* Lower-case matches are next. */ - if (sp->LCfound) - return 0; - if (cm_NoneUpper(matchName)) { - sp->LCfound = 1; - goto inexact; - } - - /* Upper-case matches are next. */ - if (sp->UCfound) - return 0; - if (cm_NoneLower(matchName)) { - sp->UCfound = 1; - goto inexact; - } - - /* General matches are last. */ - if (sp->NCfound) - return 0; - sp->NCfound = 1; - -inexact: - sp->fid.vnode = ntohl(dep->fid.vnode); - sp->fid.unique = ntohl(dep->fid.unique); - return 0; -} + /* Lower-case matches are next. */ + if (sp->LCfound) + return 0; + if (cm_NoneUpper(matchName)) { + sp->LCfound = 1; + goto inexact; + } + + /* Upper-case matches are next. */ + if (sp->UCfound) + return 0; + if (cm_NoneLower(matchName)) { + sp->UCfound = 1; + goto inexact; + } + + /* General matches are last. */ + if (sp->NCfound) + return 0; + sp->NCfound = 1; + + inexact: + sp->fid.vnode = ntohl(dep->fid.vnode); + sp->fid.unique = ntohl(dep->fid.unique); + return 0; +} /* read the contents of a mount point into the appropriate string. * called with locked scp, and returns with locked scp. */ long cm_ReadMountPoint(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp) { - long code; - cm_buf_t *bufp; - osi_hyper_t thyper; - int tlen; + long code; + cm_buf_t *bufp; + osi_hyper_t thyper; + int tlen; - if (scp->mountPointStringp) return 0; + if (scp->mountPointStringp) + return 0; - /* otherwise, we have to read it in */ - lock_ReleaseMutex(&scp->mx); + /* otherwise, we have to read it in */ + lock_ReleaseMutex(&scp->mx); - lock_ObtainRead(&scp->bufCreateLock); - thyper.LowPart = thyper.HighPart = 0; - code = buf_Get(scp, &thyper, &bufp); - lock_ReleaseRead(&scp->bufCreateLock); + lock_ObtainRead(&scp->bufCreateLock); + thyper.LowPart = thyper.HighPart = 0; + code = buf_Get(scp, &thyper, &bufp); + lock_ReleaseRead(&scp->bufCreateLock); - lock_ObtainMutex(&scp->mx); + lock_ObtainMutex(&scp->mx); + if (code) { + return code; + } + while (1) { + code = cm_SyncOp(scp, bufp, userp, reqp, 0, + CM_SCACHESYNC_READ | CM_SCACHESYNC_NEEDCALLBACK); if (code) { - return code; + goto done; } - while (1) { - code = cm_SyncOp(scp, bufp, userp, reqp, 0, - CM_SCACHESYNC_READ | CM_SCACHESYNC_NEEDCALLBACK); - if (code) { - goto done; - } - - if (cm_HaveBuffer(scp, bufp, 0)) break; - - /* otherwise load buffer */ - code = cm_GetBuffer(scp, bufp, NULL, userp, reqp); - if (code) { - goto done; - } - } - /* locked, has callback, has valid data in buffer */ - if ((tlen = scp->length.LowPart) > 1000) return CM_ERROR_TOOBIG; - if (tlen <= 0) { - code = CM_ERROR_INVAL; - goto done; - } - - /* someone else did the work while we were out */ - if (scp->mountPointStringp) { - code = 0; - goto done; + + if (cm_HaveBuffer(scp, bufp, 0)) + break; + + /* otherwise load buffer */ + code = cm_GetBuffer(scp, bufp, NULL, userp, reqp); + if (code) { + goto done; } - - /* otherwise, copy out the link */ - scp->mountPointStringp = malloc(tlen); - memcpy(scp->mountPointStringp, bufp->datap, tlen); - - /* now make it null-terminated. Note that the original contents of a - * link that is a mount point is "#volname." where "." is there just to - * be turned into a null. That is, we can trash the last char of the - * link without damaging the vol name. This is a stupid convention, - * but that's the protocol. - */ - scp->mountPointStringp[tlen-1] = 0; + } + /* locked, has callback, has valid data in buffer */ + if ((tlen = scp->length.LowPart) > 1000) return CM_ERROR_TOOBIG; + if (tlen <= 0) { + code = CM_ERROR_INVAL; + goto done; + } + + /* someone else did the work while we were out */ + if (scp->mountPointStringp) { code = 0; + goto done; + } -done: - if (bufp) buf_Release(bufp); - return code; + /* otherwise, copy out the link */ + scp->mountPointStringp = malloc(tlen); + memcpy(scp->mountPointStringp, bufp->datap, tlen); + + /* now make it null-terminated. Note that the original contents of a + * link that is a mount point is "#volname." where "." is there just to + * be turned into a null. That is, we can trash the last char of the + * link without damaging the vol name. This is a stupid convention, + * but that's the protocol. + */ + scp->mountPointStringp[tlen-1] = 0; + code = 0; + + done: + if (bufp) + buf_Release(bufp); + return code; } /* called with a locked scp and chases the mount point, yielding outScpp. * scp remains locked, just for simplicity of describing the interface. */ long cm_FollowMountPoint(cm_scache_t *scp, cm_scache_t *dscp, cm_user_t *userp, - cm_req_t *reqp, cm_scache_t **outScpp) + cm_req_t *reqp, cm_scache_t **outScpp) { - char *cellNamep; - char *volNamep; - int tlen; - long code; - char *cp; - char *mpNamep; - cm_volume_t *volp; - cm_cell_t *cellp; - char mtType; - cm_fid_t tfid; - size_t vnLength; - int type; - - if (scp->mountRootFidp && scp->mountRootGen >= cm_mountRootGen) { - tfid = *scp->mountRootFidp; - lock_ReleaseMutex(&scp->mx); - code = cm_GetSCache(&tfid, outScpp, userp, reqp); - lock_ObtainMutex(&scp->mx); - return code; - } - - /* parse the volume name */ - mpNamep = scp->mountPointStringp; - osi_assert(mpNamep); - tlen = strlen(scp->mountPointStringp); - mtType = *scp->mountPointStringp; - cellNamep = malloc(tlen); - volNamep = malloc(tlen); - - cp = strrchr(mpNamep, ':'); - if (cp) { - /* cellular mount point */ - memset(cellNamep, 0, tlen); - strncpy(cellNamep, mpNamep+1, cp - mpNamep - 1); - strcpy(volNamep, cp+1); - /* now look up the cell */ - cellp = cm_GetCell(cellNamep, CM_FLAG_CREATE); - } - else { - /* normal mt pt */ - strcpy(volNamep, mpNamep+1); - - cellp = cm_FindCellByID(scp->fid.cell); - } - - if (!cellp) { - code = CM_ERROR_NOSUCHCELL; - goto done; - } - - vnLength = strlen(volNamep); - if (vnLength >= 8 && strcmp(volNamep + vnLength - 7, ".backup") == 0) - type = BACKVOL; - else if (vnLength >= 10 - && strcmp(volNamep + vnLength - 9, ".readonly") == 0) - type = ROVOL; - else - type = RWVOL; - - /* check for backups within backups */ - if (type == BACKVOL - && (scp->flags & (CM_SCACHEFLAG_RO | CM_SCACHEFLAG_PURERO)) - == CM_SCACHEFLAG_RO) { - code = CM_ERROR_NOSUCHVOLUME; - goto done; - } - - /* now we need to get the volume */ + char *cellNamep; + char *volNamep; + int tlen; + long code; + char *cp; + char *mpNamep; + cm_volume_t *volp; + cm_cell_t *cellp; + char mtType; + cm_fid_t tfid; + size_t vnLength; + int type; + + if (scp->mountRootFidp && scp->mountRootGen >= cm_mountRootGen) { + tfid = *scp->mountRootFidp; lock_ReleaseMutex(&scp->mx); - code = cm_GetVolumeByName(cellp, volNamep, userp, reqp, 0, &volp); + code = cm_GetSCache(&tfid, outScpp, userp, reqp); lock_ObtainMutex(&scp->mx); - - if (code == 0) { - /* save the parent of the volume root for this is the - * place where the volume is mounted and we must remember - * this in the volume structure rather than just in the - * scache entry lest the scache entry gets recycled - * (defect 11489) - */ - lock_ObtainMutex(&volp->mx); - if(volp->dotdotFidp == (cm_fid_t *) NULL) - volp->dotdotFidp = (cm_fid_t *) malloc(sizeof(cm_fid_t)); - *(volp->dotdotFidp) = dscp->fid; - lock_ReleaseMutex(&volp->mx); - - if (scp->mountRootFidp == 0) { - scp->mountRootFidp = malloc(sizeof(cm_fid_t)); - } - scp->mountRootFidp->cell = cellp->cellID; - /* if the mt pt is in a read-only volume (not just a - * backup), and if there is a read-only volume for the - * target, and if this is a type '#' mount point, use - * the read-only, otherwise use the one specified. - */ - if (mtType == '#' && (scp->flags & CM_SCACHEFLAG_PURERO) - && volp->roID != 0 && type == RWVOL) - type = ROVOL; - if (type == ROVOL) - scp->mountRootFidp->volume = volp->roID; - else if (type == BACKVOL) - scp->mountRootFidp->volume = volp->bkID; - else - scp->mountRootFidp->volume = volp->rwID; - - /* the rest of the fid is a magic number */ - scp->mountRootFidp->vnode = 1; - scp->mountRootFidp->unique = 1; - scp->mountRootGen = cm_mountRootGen; - - tfid = *scp->mountRootFidp; - lock_ReleaseMutex(&scp->mx); - code = cm_GetSCache(&tfid, outScpp, userp, reqp); - lock_ObtainMutex(&scp->mx); - } - -done: - free(cellNamep); - free(volNamep); return code; -} + } -int cm_ExpandSysName(char *inp, char *outp, long outSize) -{ - char *tp; - int prefixCount; + /* parse the volume name */ + mpNamep = scp->mountPointStringp; + osi_assert(mpNamep); + tlen = strlen(scp->mountPointStringp); + mtType = *scp->mountPointStringp; + cellNamep = malloc(tlen); + volNamep = malloc(tlen); + + cp = strrchr(mpNamep, ':'); + if (cp) { + /* cellular mount point */ + memset(cellNamep, 0, tlen); + strncpy(cellNamep, mpNamep+1, cp - mpNamep - 1); + strcpy(volNamep, cp+1); + /* now look up the cell */ + cellp = cm_GetCell(cellNamep, CM_FLAG_CREATE); + } + else { + /* normal mt pt */ + strcpy(volNamep, mpNamep+1); - tp = strrchr(inp, '@'); - if (tp == NULL) return 0; /* no @sys */ + cellp = cm_FindCellByID(scp->fid.cell); + } - if (strcmp(tp, "@sys") != 0) return 0; /* no @sys */ + if (!cellp) { + code = CM_ERROR_NOSUCHCELL; + goto done; + } - /* caller just wants to know if this is a valid @sys type of name */ - if (outp == NULL) return 1; + vnLength = strlen(volNamep); + if (vnLength >= 8 && strcmp(volNamep + vnLength - 7, ".backup") == 0) + type = BACKVOL; + else if (vnLength >= 10 + && strcmp(volNamep + vnLength - 9, ".readonly") == 0) + type = ROVOL; + else + type = RWVOL; + + /* check for backups within backups */ + if (type == BACKVOL + && (scp->flags & (CM_SCACHEFLAG_RO | CM_SCACHEFLAG_PURERO)) + == CM_SCACHEFLAG_RO) { + code = CM_ERROR_NOSUCHVOLUME; + goto done; + } - /* otherwise generate the properly expanded @sys name */ - prefixCount = tp - inp; + /* now we need to get the volume */ + lock_ReleaseMutex(&scp->mx); + code = cm_GetVolumeByName(cellp, volNamep, userp, reqp, 0, &volp); + lock_ObtainMutex(&scp->mx); + + if (code == 0) { + /* save the parent of the volume root for this is the + * place where the volume is mounted and we must remember + * this in the volume structure rather than just in the + * scache entry lest the scache entry gets recycled + * (defect 11489) + */ + lock_ObtainMutex(&volp->mx); + if(volp->dotdotFidp == (cm_fid_t *) NULL) + volp->dotdotFidp = (cm_fid_t *) malloc(sizeof(cm_fid_t)); + *(volp->dotdotFidp) = dscp->fid; + lock_ReleaseMutex(&volp->mx); + + if (scp->mountRootFidp == 0) { + scp->mountRootFidp = malloc(sizeof(cm_fid_t)); + } + scp->mountRootFidp->cell = cellp->cellID; + /* if the mt pt is in a read-only volume (not just a + * backup), and if there is a read-only volume for the + * target, and if this is a type '#' mount point, use + * the read-only, otherwise use the one specified. + */ + if (mtType == '#' && (scp->flags & CM_SCACHEFLAG_PURERO) + && volp->roID != 0 && type == RWVOL) + type = ROVOL; + if (type == ROVOL) + scp->mountRootFidp->volume = volp->roID; + else if (type == BACKVOL) + scp->mountRootFidp->volume = volp->bkID; + else + scp->mountRootFidp->volume = volp->rwID; + + /* the rest of the fid is a magic number */ + scp->mountRootFidp->vnode = 1; + scp->mountRootFidp->unique = 1; + scp->mountRootGen = cm_mountRootGen; + + tfid = *scp->mountRootFidp; + lock_ReleaseMutex(&scp->mx); + code = cm_GetSCache(&tfid, outScpp, userp, reqp); + lock_ObtainMutex(&scp->mx); + } - strncpy(outp, inp, prefixCount); /* copy out "a." from "a.@sys" */ - outp[prefixCount] = 0; /* null terminate the "a." */ - strcat(outp, cm_sysName); /* append i386_nt40 */ - return 1; -} + done: + free(cellNamep); + free(volNamep); + return code; +} -long cm_Lookup(cm_scache_t *dscp, char *namep, long flags, cm_user_t *userp, - cm_req_t *reqp, cm_scache_t **outpScpp) +long cm_LookupInternal(cm_scache_t *dscp, char *namep, long flags, cm_user_t *userp, + cm_req_t *reqp, cm_scache_t **outpScpp) { - long code; - int dnlcHit = 1; /* did we hit in the dnlc? yes, we did */ + long code; + int dnlcHit = 1; /* did we hit in the dnlc? yes, we did */ cm_scache_t *tscp = NULL; cm_scache_t *mountedScp; cm_lookupSearch_t rock; - char tname[256]; - int getroot; + int getroot; - if (dscp->fid.vnode == 1 && dscp->fid.unique == 1 + if (dscp->fid.vnode == 1 && dscp->fid.unique == 1 && strcmp(namep, "..") == 0) { - if (dscp->dotdotFidp == (cm_fid_t *)NULL + if (dscp->dotdotFidp == (cm_fid_t *)NULL || dscp->dotdotFidp->volume == 0) - return CM_ERROR_NOSUCHVOLUME; - rock.fid = *dscp->dotdotFidp; - goto haveFid; - } - - if (cm_ExpandSysName(namep, tname, sizeof(tname))) { - namep = tname; + return CM_ERROR_NOSUCHVOLUME; + rock.fid = *dscp->dotdotFidp; + goto haveFid; } - memset(&rock, 0, sizeof(rock)); + + memset(&rock, 0, sizeof(rock)); rock.fid.cell = dscp->fid.cell; rock.fid.volume = dscp->fid.volume; rock.searchNamep = namep; rock.caseFold = (flags & CM_FLAG_CASEFOLD); - rock.hasTilde = ((strchr(namep, '~') != NULL) ? 1 : 0); + rock.hasTilde = ((strchr(namep, '~') != NULL) ? 1 : 0); - /* If NOMOUNTCHASE, bypass DNLC by passing NULL scp pointer */ - code = cm_ApplyDir(dscp, cm_LookupSearchProc, &rock, NULL, userp, reqp, - (flags & CM_FLAG_NOMOUNTCHASE) ? NULL : &tscp); + /* If NOMOUNTCHASE, bypass DNLC by passing NULL scp pointer */ + code = cm_ApplyDir(dscp, cm_LookupSearchProc, &rock, NULL, userp, reqp, + (flags & CM_FLAG_NOMOUNTCHASE) ? NULL : &tscp); - /* code == 0 means we fell off the end of the dir, while stopnow means + /* code == 0 means we fell off the end of the dir, while stopnow means * that we stopped early, probably because we found the entry we're - * looking for. Any other non-zero code is an error. + * looking for. Any other non-zero code is an error. */ if (code && code != CM_ERROR_STOPNOW) return code; - getroot = (dscp==cm_rootSCachep) ; + getroot = (dscp==cm_rootSCachep) ; if (!rock.found) { if (!cm_freelanceEnabled || !getroot) { if (flags & CM_FLAG_CHECKPATH) @@ -1010,9 +991,9 @@ long cm_Lookup(cm_scache_t *dscp, char *namep, long flags, cm_user_t *userp, return CM_ERROR_NOSUCHFILE; } else { /* nonexistent dir on freelance root, so add it */ - osi_Log1(afsd_logp,"cm_Lookup adding mount for non-existent directory: %s", - osi_LogSaveString(afsd_logp,namep)); - code = cm_FreelanceAddMount(namep, namep, "root.cell.", namep[0] == '.', &rock.fid); + osi_Log1(afsd_logp,"cm_Lookup adding mount for non-existent directory: %s", + osi_LogSaveString(afsd_logp,namep)); + code = cm_FreelanceAddMount(namep, namep, "root.cell.", namep[0] == '.', &rock.fid); if (code < 0) { /* add mount point failed, so give up */ if (flags & CM_FLAG_CHECKPATH) return CM_ERROR_NOSUCHPATH; @@ -1021,109 +1002,175 @@ long cm_Lookup(cm_scache_t *dscp, char *namep, long flags, cm_user_t *userp, } tscp = NULL; /* to force call of cm_GetSCache */ } - } + } -haveFid: - if ( !tscp ) /* we did not find it in the dnlc */ - { - dnlcHit = 0; + haveFid: + if ( !tscp ) /* we did not find it in the dnlc */ + { + dnlcHit = 0; code = cm_GetSCache(&rock.fid, &tscp, userp, reqp); if (code) return code; - } + } /* tscp is now held */ - lock_ObtainMutex(&tscp->mx); - code = cm_SyncOp(tscp, NULL, userp, reqp, 0, + lock_ObtainMutex(&tscp->mx); + code = cm_SyncOp(tscp, NULL, userp, reqp, 0, CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK); if (code) { - lock_ReleaseMutex(&tscp->mx); - cm_ReleaseSCache(tscp); + lock_ReleaseMutex(&tscp->mx); + cm_ReleaseSCache(tscp); return code; - } + } /* tscp is now locked */ if (!(flags & CM_FLAG_NOMOUNTCHASE) - && tscp->fileType == CM_SCACHETYPE_MOUNTPOINT) { - /* mount points are funny: they have a volume name to mount + && tscp->fileType == CM_SCACHETYPE_MOUNTPOINT) { + /* mount points are funny: they have a volume name to mount * the root of. */ - code = cm_ReadMountPoint(tscp, userp, reqp); + code = cm_ReadMountPoint(tscp, userp, reqp); if (code == 0) - code = cm_FollowMountPoint(tscp, dscp, userp, reqp, + code = cm_FollowMountPoint(tscp, dscp, userp, reqp, &mountedScp); - lock_ReleaseMutex(&tscp->mx); - cm_ReleaseSCache(tscp); - if (code) { + lock_ReleaseMutex(&tscp->mx); + cm_ReleaseSCache(tscp); + if (code) { return code; } tscp = mountedScp; } - else { - lock_ReleaseMutex(&tscp->mx); - } + else { + lock_ReleaseMutex(&tscp->mx); + } - /* copy back pointer */ + /* copy back pointer */ *outpScpp = tscp; - /* insert scache in dnlc */ - if ( !dnlcHit && !(flags & CM_FLAG_NOMOUNTCHASE) && rock.ExactFound ) { - /* lock the directory entry to prevent racing callback revokes */ - lock_ObtainMutex(&dscp->mx); - if ( dscp->cbServerp && dscp->cbExpires ) + /* insert scache in dnlc */ + if ( !dnlcHit && !(flags & CM_FLAG_NOMOUNTCHASE) && rock.ExactFound ) { + /* lock the directory entry to prevent racing callback revokes */ + lock_ObtainMutex(&dscp->mx); + if ( dscp->cbServerp && dscp->cbExpires ) cm_dnlcEnter(dscp, namep, tscp); - lock_ReleaseMutex(&dscp->mx); - } + lock_ReleaseMutex(&dscp->mx); + } - /* and return */ + /* and return */ return 0; } +int cm_ExpandSysName(char *inp, char *outp, long outSize, unsigned int index) +{ + char *tp; + int prefixCount; + + tp = strrchr(inp, '@'); + if (tp == NULL) + return 0; /* no @sys */ + + if (strcmp(tp, "@sys") != 0) + return 0; /* no @sys */ + + /* caller just wants to know if this is a valid @sys type of name */ + if (outp == NULL) + return 1; + + if (index >= MAXNUMSYSNAMES) + return -1; + + /* otherwise generate the properly expanded @sys name */ + prefixCount = tp - inp; + + strncpy(outp, inp, prefixCount); /* copy out "a." from "a.@sys" */ + outp[prefixCount] = 0; /* null terminate the "a." */ + strcat(outp, cm_sysNameList[index]);/* append i386_nt40 */ + return 1; +} + +long cm_Lookup(cm_scache_t *dscp, char *namep, long flags, cm_user_t *userp, + cm_req_t *reqp, cm_scache_t **outpScpp) +{ + long code; + char tname[256]; + int sysNameIndex = 0; + cm_scache_t *scp = 0; + + for ( sysNameIndex = 0; sysNameIndex < MAXNUMSYSNAMES; sysNameIndex++) { + code = cm_ExpandSysName(namep, tname, sizeof(tname), sysNameIndex); + if (code > 0) { + code = cm_LookupInternal(dscp, tname, flags, userp, reqp, &scp); + if (code == 0) { + *outpScpp = scp; + return 0; + } + if (scp) { + cm_ReleaseSCache(scp); + scp = 0; + } + } else { + return cm_LookupInternal(dscp, namep, flags, userp, reqp, outpScpp); + } + } + + /* None of the possible sysName expansions could be found */ + if (flags & CM_FLAG_CHECKPATH) + return CM_ERROR_NOSUCHPATH; + else + return CM_ERROR_NOSUCHFILE; +} + long cm_Unlink(cm_scache_t *dscp, char *namep, cm_user_t *userp, cm_req_t *reqp) { - long code; - cm_conn_t *connp; - AFSFid afsFid; - int sflags; - AFSFetchStatus newDirStatus; - AFSVolSync volSync; + long code; + cm_conn_t *connp; + AFSFid afsFid; + int sflags; + AFSFetchStatus newDirStatus; + AFSVolSync volSync; + struct rx_connection * callp; #ifdef AFS_FREELANCE_CLIENT - if (cm_freelanceEnabled && dscp == cm_rootSCachep) { - /* deleting a mount point from the root dir. */ - code = cm_FreelanceRemoveMount(namep); - return code; - } -#endif + if (cm_freelanceEnabled && dscp == cm_rootSCachep) { + /* deleting a mount point from the root dir. */ + code = cm_FreelanceRemoveMount(namep); + return code; + } +#endif + + /* make sure we don't screw up the dir status during the merge */ + lock_ObtainMutex(&dscp->mx); + sflags = CM_SCACHESYNC_STOREDATA; + code = cm_SyncOp(dscp, NULL, userp, reqp, 0, sflags); + lock_ReleaseMutex(&dscp->mx); + if (code) + return code; - /* make sure we don't screw up the dir status during the merge */ - lock_ObtainMutex(&dscp->mx); - sflags = CM_SCACHESYNC_STOREDATA; - code = cm_SyncOp(dscp, NULL, userp, reqp, 0, sflags); - lock_ReleaseMutex(&dscp->mx); - if (code) return code; + /* make the RPC */ + afsFid.Volume = dscp->fid.volume; + afsFid.Vnode = dscp->fid.vnode; + afsFid.Unique = dscp->fid.unique; + do { + code = cm_Conn(&dscp->fid, userp, reqp, &connp); + if (code) + continue; - /* make the RPC */ - afsFid.Volume = dscp->fid.volume; - afsFid.Vnode = dscp->fid.vnode; - afsFid.Unique = dscp->fid.unique; - do { - code = cm_Conn(&dscp->fid, userp, reqp, &connp); - if (code) continue; - - code = RXAFS_RemoveFile(connp->callp, &afsFid, namep, - &newDirStatus, &volSync); - - } while (cm_Analyze(connp, userp, reqp, &dscp->fid, &volSync, NULL, NULL, code)); - code = cm_MapRPCError(code, reqp); + callp = cm_GetRxConn(connp); + code = RXAFS_RemoveFile(callp, &afsFid, namep, + &newDirStatus, &volSync); + rx_PutConnection(callp); - lock_ObtainMutex(&dscp->mx); - cm_dnlcRemove(dscp, namep); - cm_SyncOpDone(dscp, NULL, sflags); - if (code == 0) cm_MergeStatus(dscp, &newDirStatus, &volSync, userp, 0); - lock_ReleaseMutex(&dscp->mx); + } while (cm_Analyze(connp, userp, reqp, &dscp->fid, &volSync, NULL, NULL, code)); + code = cm_MapRPCError(code, reqp); - return code; + lock_ObtainMutex(&dscp->mx); + cm_dnlcRemove(dscp, namep); + cm_SyncOpDone(dscp, NULL, sflags); + if (code == 0) + cm_MergeStatus(dscp, &newDirStatus, &volSync, userp, 0); + lock_ReleaseMutex(&dscp->mx); + + return code; } /* called with a locked vnode, and fills in the link info. @@ -1131,295 +1178,307 @@ long cm_Unlink(cm_scache_t *dscp, char *namep, cm_user_t *userp, cm_req_t *reqp) */ long cm_HandleLink(cm_scache_t *linkScp, cm_user_t *userp, cm_req_t *reqp) { - long code; - cm_buf_t *bufp; - long temp; - osi_hyper_t thyper; - - lock_AssertMutex(&linkScp->mx); - if (!linkScp->mountPointStringp) { - /* read the link data */ - lock_ReleaseMutex(&linkScp->mx); - thyper.LowPart = thyper.HighPart = 0; - code = buf_Get(linkScp, &thyper, &bufp); - lock_ObtainMutex(&linkScp->mx); - if (code) return code; - while (1) { - code = cm_SyncOp(linkScp, bufp, userp, reqp, 0, - CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ); - if (code) { - buf_Release(bufp); - return code; - } - if (cm_HaveBuffer(linkScp, bufp, 0)) break; - - code = cm_GetBuffer(linkScp, bufp, NULL, userp, reqp); - if (code) { - buf_Release(bufp); - return code; - } - } /* while loop to get the data */ - - /* now if we still have no link read in, - * copy the data from the buffer */ - if ((temp = linkScp->length.LowPart) >= 1024) { - buf_Release(bufp); - return CM_ERROR_TOOBIG; - } - - /* otherwise, it fits; make sure it is still null (could have - * lost race with someone else referencing this link above), - * and if so, copy in the data. - */ - if (linkScp->mountPointStringp == NULL) { - linkScp->mountPointStringp = malloc(temp+1); - strncpy(linkScp->mountPointStringp, bufp->datap, temp); - linkScp->mountPointStringp[temp] = 0; /* null terminate */ - } + long code; + cm_buf_t *bufp; + long temp; + osi_hyper_t thyper; + + lock_AssertMutex(&linkScp->mx); + if (!linkScp->mountPointStringp) { + /* read the link data */ + lock_ReleaseMutex(&linkScp->mx); + thyper.LowPart = thyper.HighPart = 0; + code = buf_Get(linkScp, &thyper, &bufp); + lock_ObtainMutex(&linkScp->mx); + if (code) + return code; + while (1) { + code = cm_SyncOp(linkScp, bufp, userp, reqp, 0, + CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ); + if (code) { buf_Release(bufp); - } /* don't have sym link contents cached */ - - return 0; -} + return code; + } + if (cm_HaveBuffer(linkScp, bufp, 0)) + break; -/* called with a held vnode and a path suffix, with the held vnode being a + code = cm_GetBuffer(linkScp, bufp, NULL, userp, reqp); + if (code) { + buf_Release(bufp); + return code; + } + } /* while loop to get the data */ + + /* now if we still have no link read in, + * copy the data from the buffer */ + if ((temp = linkScp->length.LowPart) >= 1024) { + buf_Release(bufp); + return CM_ERROR_TOOBIG; + } + + /* otherwise, it fits; make sure it is still null (could have + * lost race with someone else referencing this link above), + * and if so, copy in the data. + */ + if (linkScp->mountPointStringp == NULL) { + linkScp->mountPointStringp = malloc(temp+1); + strncpy(linkScp->mountPointStringp, bufp->datap, temp); + linkScp->mountPointStringp[temp] = 0; /* null terminate */ + } + buf_Release(bufp); + } /* don't have sym link contents cached */ + + return 0; +} + +/* called with a held vnode and a path suffix, with the held vnode being a * symbolic link. Our goal is to generate a new path to interpret, and return * this new path in newSpaceBufferp. If the new vnode is relative to a dir * other than the directory containing the symbolic link, then the new root is * returned in *newRootScpp, otherwise a null is returned there. */ long cm_AssembleLink(cm_scache_t *linkScp, char *pathSuffixp, - cm_scache_t **newRootScpp, cm_space_t **newSpaceBufferp, - cm_user_t *userp, cm_req_t *reqp) + cm_scache_t **newRootScpp, cm_space_t **newSpaceBufferp, + cm_user_t *userp, cm_req_t *reqp) { - long code; - char *linkp; - cm_space_t *tsp; + long code; + char *linkp; + cm_space_t *tsp; - lock_ObtainMutex(&linkScp->mx); - code = cm_HandleLink(linkScp, userp, reqp); - if (code) goto done; + lock_ObtainMutex(&linkScp->mx); + code = cm_HandleLink(linkScp, userp, reqp); + if (code) + goto done; - /* if we may overflow the buffer, bail out; buffer is signficantly - * bigger than max path length, so we don't really have to worry about - * being a little conservative here. - */ - if (strlen(linkScp->mountPointStringp) + strlen(pathSuffixp) + 2 - >= CM_UTILS_SPACESIZE) - return CM_ERROR_TOOBIG; - - tsp = cm_GetSpace(); - linkp = linkScp->mountPointStringp; - if (strncmp(linkp, cm_mountRoot, cm_mountRootLen) == 0) { - if (strlen(linkp) > cm_mountRootLen) - strcpy(tsp->data, linkp+cm_mountRootLen+1); - else - tsp->data[0] = 0; - *newRootScpp = cm_rootSCachep; - cm_HoldSCache(cm_rootSCachep); - } else if (*linkp == '\\' || *linkp == '/') { - /* formerly, this was considered to be from the AFS root, - but this seems to create problems. instead, we will just - reject the link */ -#if 0 - strcpy(tsp->data, linkp+1); - *newRootScpp = cm_rootSCachep; - cm_HoldSCache(cm_rootSCachep); + /* if we may overflow the buffer, bail out; buffer is signficantly + * bigger than max path length, so we don't really have to worry about + * being a little conservative here. + */ + if (strlen(linkScp->mountPointStringp) + strlen(pathSuffixp) + 2 + >= CM_UTILS_SPACESIZE) + return CM_ERROR_TOOBIG; + + tsp = cm_GetSpace(); + linkp = linkScp->mountPointStringp; + if (strncmp(linkp, cm_mountRoot, cm_mountRootLen) == 0) { + if (strlen(linkp) > cm_mountRootLen) + strcpy(tsp->data, linkp+cm_mountRootLen+1); + else + tsp->data[0] = 0; + *newRootScpp = cm_rootSCachep; + cm_HoldSCache(cm_rootSCachep); + } else if (*linkp == '\\' || *linkp == '/') { + /* formerly, this was considered to be from the AFS root, + * but this seems to create problems. instead, we will just + * reject the link */ +#if 0 + strcpy(tsp->data, linkp+1); + *newRootScpp = cm_rootSCachep; + cm_HoldSCache(cm_rootSCachep); #else - code = CM_ERROR_NOSUCHPATH; - goto done; -#endif - } - else { - /* a relative link */ - strcpy(tsp->data, linkp); - *newRootScpp = NULL; - } - if (pathSuffixp[0] != 0) { /* if suffix string is non-null */ - strcat(tsp->data, "\\"); - strcat(tsp->data, pathSuffixp); - } - *newSpaceBufferp = tsp; - code = 0; - -done: - lock_ReleaseMutex(&linkScp->mx); - return code; + code = CM_ERROR_NOSUCHPATH; + goto done; +#endif + } + else { + /* a relative link */ + strcpy(tsp->data, linkp); + *newRootScpp = NULL; + } + if (pathSuffixp[0] != 0) { /* if suffix string is non-null */ + strcat(tsp->data, "\\"); + strcat(tsp->data, pathSuffixp); + } + *newSpaceBufferp = tsp; + code = 0; + + done: + lock_ReleaseMutex(&linkScp->mx); + return code; } long cm_NameI(cm_scache_t *rootSCachep, char *pathp, long flags, - cm_user_t *userp, char *tidPathp, cm_req_t *reqp, cm_scache_t **outScpp) + cm_user_t *userp, char *tidPathp, cm_req_t *reqp, cm_scache_t **outScpp) { - long code; - char *tp; /* ptr moving through input buffer */ - char tc; /* temp char */ - int haveComponent; /* has new component started? */ - char component[256]; /* this is the new component */ - char *cp; /* component name being assembled */ - cm_scache_t *tscp; /* current location in the hierarchy */ - cm_scache_t *nscp; /* next dude down */ - cm_scache_t *dirScp; /* last dir we searched */ - cm_scache_t *linkScp; /* new root for the symlink we just - * looked up */ - cm_space_t *psp; /* space for current path, if we've hit - * any symlinks */ - cm_space_t *tempsp; /* temp vbl */ - char *restp; /* rest of the pathname to interpret */ - int symlinkCount; /* count of # of symlinks traversed */ - int extraFlag; /* avoid chasing mt pts for dir cmd */ - int phase = 1; /* 1 = tidPathp, 2 = pathp */ - - tp = tidPathp; - if (tp == NULL) { - tp = pathp; - phase = 2; - } - if (tp == NULL) { - tp = ""; - } - haveComponent = 0; - psp = NULL; - tscp = rootSCachep; - cm_HoldSCache(tscp); - symlinkCount = 0; - while (1) { - tc = *tp++; - - /* map Unix slashes into DOS ones so we can interpret Unix - * symlinks properly - */ - if (tc == '/') tc = '\\'; + long code; + char *tp; /* ptr moving through input buffer */ + char tc; /* temp char */ + int haveComponent; /* has new component started? */ + char component[256]; /* this is the new component */ + char *cp; /* component name being assembled */ + cm_scache_t *tscp; /* current location in the hierarchy */ + cm_scache_t *nscp; /* next dude down */ + cm_scache_t *dirScp; /* last dir we searched */ + cm_scache_t *linkScp; /* new root for the symlink we just + * looked up */ + cm_space_t *psp; /* space for current path, if we've hit + * any symlinks */ + cm_space_t *tempsp; /* temp vbl */ + char *restp; /* rest of the pathname to interpret */ + int symlinkCount; /* count of # of symlinks traversed */ + int extraFlag; /* avoid chasing mt pts for dir cmd */ + int phase = 1; /* 1 = tidPathp, 2 = pathp */ + + tp = tidPathp; + if (tp == NULL) { + tp = pathp; + phase = 2; + } + if (tp == NULL) { + tp = ""; + } + haveComponent = 0; + psp = NULL; + tscp = rootSCachep; + cm_HoldSCache(tscp); + symlinkCount = 0; + while (1) { + tc = *tp++; + + /* map Unix slashes into DOS ones so we can interpret Unix + * symlinks properly + */ + if (tc == '/') + tc = '\\'; - if (!haveComponent) { - if (tc == '\\') continue; + if (!haveComponent) { + if (tc == '\\') + continue; else if (tc == 0) { - if (phase == 1) { - phase = 2; - tp = pathp; - continue; - } + if (phase == 1) { + phase = 2; + tp = pathp; + continue; + } code = 0; break; } else { - haveComponent = 1; + haveComponent = 1; cp = component; *cp++ = tc; } - } - else { - /* we have a component here */ - if (tc == 0 || tc == '\\') { - /* end of the component; we're at the last - * component if tc == 0. However, if the last - * is a symlink, we have more to do. - */ - *cp++ = 0; /* add null termination */ - extraFlag = 0; - if ((flags & CM_FLAG_DIRSEARCH) && tc == 0) - extraFlag = CM_FLAG_NOMOUNTCHASE; - code = cm_Lookup(tscp, component, - flags | extraFlag, - userp, reqp, &nscp); + } + else { + /* we have a component here */ + if (tc == 0 || tc == '\\') { + /* end of the component; we're at the last + * component if tc == 0. However, if the last + * is a symlink, we have more to do. + */ + *cp++ = 0; /* add null termination */ + extraFlag = 0; + if ((flags & CM_FLAG_DIRSEARCH) && tc == 0) + extraFlag = CM_FLAG_NOMOUNTCHASE; + code = cm_Lookup(tscp, component, + flags | extraFlag, + userp, reqp, &nscp); - if (code) { + if (code) { + cm_ReleaseSCache(tscp); + if (psp) + cm_FreeSpace(psp); + return code; + } + haveComponent = 0; /* component done */ + dirScp = tscp; /* for some symlinks */ + tscp = nscp; /* already held */ + if (tc == 0 && !(flags & CM_FLAG_FOLLOW) && phase == 2) { + code = 0; + cm_ReleaseSCache(dirScp); + break; + } + + /* now, if tscp is a symlink, we should follow + * it and assemble the path again. + */ + lock_ObtainMutex(&tscp->mx); + code = cm_SyncOp(tscp, NULL, userp, reqp, 0, + CM_SCACHESYNC_GETSTATUS + | CM_SCACHESYNC_NEEDCALLBACK); + if (code) { + lock_ReleaseMutex(&tscp->mx); + cm_ReleaseSCache(tscp); + cm_ReleaseSCache(dirScp); + break; + } + if (tscp->fileType == CM_SCACHETYPE_SYMLINK) { + /* this is a symlink; assemble a new buffer */ + lock_ReleaseMutex(&tscp->mx); + if (symlinkCount++ >= 16) { cm_ReleaseSCache(tscp); - if (psp) cm_FreeSpace(psp); - return code; - } - haveComponent = 0; /* component done */ - dirScp = tscp; /* for some symlinks */ - tscp = nscp; /* already held */ - if (tc == 0 && !(flags & CM_FLAG_FOLLOW) && phase == 2) { - code = 0; cm_ReleaseSCache(dirScp); - break; + if (psp) + cm_FreeSpace(psp); + return CM_ERROR_TOOBIG; } - - /* now, if tscp is a symlink, we should follow - * it and assemble the path again. - */ - lock_ObtainMutex(&tscp->mx); - code = cm_SyncOp(tscp, NULL, userp, reqp, 0, - CM_SCACHESYNC_GETSTATUS - | CM_SCACHESYNC_NEEDCALLBACK); + if (tc == 0) + restp = ""; + else + restp = tp; + code = cm_AssembleLink(tscp, restp, &linkScp, &tempsp, userp, reqp); if (code) { - lock_ReleaseMutex(&tscp->mx); + /* something went wrong */ cm_ReleaseSCache(tscp); cm_ReleaseSCache(dirScp); break; } - if (tscp->fileType == CM_SCACHETYPE_SYMLINK) { - /* this is a symlink; assemble a new buffer */ - lock_ReleaseMutex(&tscp->mx); - if (symlinkCount++ >= 16) { - cm_ReleaseSCache(tscp); - cm_ReleaseSCache(dirScp); - if (psp) cm_FreeSpace(psp); - return CM_ERROR_TOOBIG; - } - if (tc == 0) restp = ""; - else restp = tp; - code = cm_AssembleLink(tscp, restp, &linkScp, &tempsp, userp, reqp); - if (code) { - /* something went wrong */ - cm_ReleaseSCache(tscp); - cm_ReleaseSCache(dirScp); - break; - } - /* otherwise, tempsp has the new path, - * and linkScp is the new root from - * which to interpret that path. - * Continue with the namei processing, - * also doing the bookkeeping for the - * space allocation and tracking the - * vnode reference counts. - */ - if (psp) cm_FreeSpace(psp); - psp = tempsp; - tp = psp->data; - cm_ReleaseSCache(tscp); + /* otherwise, tempsp has the new path, + * and linkScp is the new root from + * which to interpret that path. + * Continue with the namei processing, + * also doing the bookkeeping for the + * space allocation and tracking the + * vnode reference counts. + */ + if (psp) + cm_FreeSpace(psp); + psp = tempsp; + tp = psp->data; + cm_ReleaseSCache(tscp); tscp = linkScp; /* already held - * by AssembleLink */ - /* now, if linkScp is null, that's - * AssembleLink's way of telling us that - * the sym link is relative to the dir - * containing the link. We have a ref - * to it in dirScp, and we hold it now - * and reuse it as the new spot in the - * dir hierarchy. - */ - if (tscp == NULL) { - cm_HoldSCache(dirScp); - tscp = dirScp; - } - } /* if we have a sym link */ - else { - /* not a symlink, we may be done */ - lock_ReleaseMutex(&tscp->mx); - if (tc == 0) { - if (phase == 1) { - phase = 2; - tp = pathp; - continue; - } - cm_ReleaseSCache(dirScp); - code = 0; - break; + * by AssembleLink + * now, if linkScp is null, that's + * AssembleLink's way of telling us that + * the sym link is relative to the dir + * containing the link. We have a ref + * to it in dirScp, and we hold it now + * and reuse it as the new spot in the + * dir hierarchy. + */ + if (tscp == NULL) { + cm_HoldSCache(dirScp); + tscp = dirScp; + } + } /* if we have a sym link */ + else { + /* not a symlink, we may be done */ + lock_ReleaseMutex(&tscp->mx); + if (tc == 0) { + if (phase == 1) { + phase = 2; + tp = pathp; + continue; } + cm_ReleaseSCache(dirScp); + code = 0; + break; } - cm_ReleaseSCache(dirScp); - } /* end of a component */ - else *cp++ = tc; - } /* we have a component */ - } /* big while loop over all components */ - - /* already held */ - if (psp) cm_FreeSpace(psp); - if (code == 0) *outScpp = tscp; - return code; + } + cm_ReleaseSCache(dirScp); + } /* end of a component */ + else *cp++ = tc; + } /* we have a component */ + } /* big while loop over all components */ + + /* already held */ + if (psp) + cm_FreeSpace(psp); + if (code == 0) + *outScpp = tscp; + return code; } /* called with a dir, and a vnode within the dir that happens to be a symlink. @@ -1438,35 +1497,36 @@ long cm_NameI(cm_scache_t *rootSCachep, char *pathp, long flags, * The input vnode should not be locked when this function is called. */ long cm_EvaluateSymLink(cm_scache_t *dscp, cm_scache_t *linkScp, - cm_scache_t **outScpp, cm_user_t *userp, cm_req_t *reqp) + cm_scache_t **outScpp, cm_user_t *userp, cm_req_t *reqp) { - long code; - cm_space_t *spacep; - cm_scache_t *newRootScp; + long code; + cm_space_t *spacep; + cm_scache_t *newRootScp; - osi_Log1(afsd_logp, "Evaluating symlink vp %x", linkScp); + osi_Log1(afsd_logp, "Evaluating symlink vp %x", linkScp); - code = cm_AssembleLink(linkScp, "", &newRootScp, &spacep, userp, reqp); - if (code) return code; - - /* now, if newRootScp is NULL, we're really being told that the symlink - * is relative to the current directory (dscp). - */ - if (newRootScp == NULL) { - newRootScp = dscp; - cm_HoldSCache(dscp); - } - - code = cm_NameI(newRootScp, spacep->data, - CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW | CM_FLAG_DIRSEARCH, - userp, NULL, reqp, outScpp); + code = cm_AssembleLink(linkScp, "", &newRootScp, &spacep, userp, reqp); + if (code) + return code; - /* this stuff is allocated no matter what happened on the namei call, - * so free it */ - cm_FreeSpace(spacep); - cm_ReleaseSCache(newRootScp); + /* now, if newRootScp is NULL, we're really being told that the symlink + * is relative to the current directory (dscp). + */ + if (newRootScp == NULL) { + newRootScp = dscp; + cm_HoldSCache(dscp); + } - return code; + code = cm_NameI(newRootScp, spacep->data, + CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW | CM_FLAG_DIRSEARCH, + userp, NULL, reqp, outScpp); + + /* this stuff is allocated no matter what happened on the namei call, + * so free it */ + cm_FreeSpace(spacep); + cm_ReleaseSCache(newRootScp); + + return code; } /* make this big enough so that one buffer of dir pages won't overflow. We'll @@ -1477,13 +1537,13 @@ long cm_EvaluateSymLink(cm_scache_t *dscp, cm_scache_t *linkScp, /* rock for bulk stat calls */ typedef struct cm_bulkStat { - osi_hyper_t bufOffset; /* only do it for things in this buffer page */ + osi_hyper_t bufOffset; /* only do it for things in this buffer page */ - /* info for the actual call */ - int counter; /* next free slot */ - AFSFid fids[CM_BULKMAX]; - AFSFetchStatus stats[CM_BULKMAX]; - AFSCallBack callbacks[CM_BULKMAX]; + /* info for the actual call */ + int counter; /* next free slot */ + AFSFid fids[CM_BULKMAX]; + AFSFetchStatus stats[CM_BULKMAX]; + AFSCallBack callbacks[CM_BULKMAX]; } cm_bulkStat_t; /* for a given entry, make sure that it isn't in the stat cache, and then @@ -1494,1133 +1554,1257 @@ typedef struct cm_bulkStat { * processing, to avoid deadlocks. */ long cm_TryBulkProc(cm_scache_t *scp, cm_dirEntry_t *dep, void *rockp, - osi_hyper_t *offp) + osi_hyper_t *offp) { - osi_hyper_t thyper; - cm_bulkStat_t *bsp; - int i; - cm_scache_t *tscp; - cm_fid_t tfid; + osi_hyper_t thyper; + cm_bulkStat_t *bsp; + int i; + cm_scache_t *tscp; + cm_fid_t tfid; - bsp = rockp; + bsp = rockp; - /* Don't overflow bsp. */ - if (bsp->counter >= CM_BULKMAX) - return CM_ERROR_STOPNOW; + /* Don't overflow bsp. */ + if (bsp->counter >= CM_BULKMAX) + return CM_ERROR_STOPNOW; - thyper.LowPart = buf_bufferSize; - thyper.HighPart = 0; - thyper = LargeIntegerAdd(thyper, bsp->bufOffset); - - /* thyper is now the first byte past the end of the record we're - * interested in, and bsp->bufOffset is the first byte of the record - * we're interested in. - * Skip data in the others. - * Skip '.' and '..' - */ - if (LargeIntegerLessThan(*offp, bsp->bufOffset)) - return 0; - if (LargeIntegerGreaterThanOrEqualTo(*offp, thyper)) - return CM_ERROR_STOPNOW; - if (strcmp(dep->name, ".") == 0 || strcmp(dep->name, "..") == 0) - return 0; - - tfid.cell = scp->fid.cell; - tfid.volume = scp->fid.volume; - tfid.vnode = ntohl(dep->fid.vnode); - tfid.unique = ntohl(dep->fid.unique); - tscp = cm_FindSCache(&tfid); - if (tscp) { - if (lock_TryMutex(&tscp->mx)) { - /* we have an entry that we can look at */ - if (cm_HaveCallback(tscp)) { - /* we have a callback on it. Don't bother - * fetching this stat entry, since we're happy - * with the info we have. - */ - lock_ReleaseMutex(&tscp->mx); - cm_ReleaseSCache(tscp); - return 0; - } - lock_ReleaseMutex(&tscp->mx); - } /* got lock */ + thyper.LowPart = buf_bufferSize; + thyper.HighPart = 0; + thyper = LargeIntegerAdd(thyper, bsp->bufOffset); + + /* thyper is now the first byte past the end of the record we're + * interested in, and bsp->bufOffset is the first byte of the record + * we're interested in. + * Skip data in the others. + * Skip '.' and '..' + */ + if (LargeIntegerLessThan(*offp, bsp->bufOffset)) + return 0; + if (LargeIntegerGreaterThanOrEqualTo(*offp, thyper)) + return CM_ERROR_STOPNOW; + if (strcmp(dep->name, ".") == 0 || strcmp(dep->name, "..") == 0) + return 0; + + tfid.cell = scp->fid.cell; + tfid.volume = scp->fid.volume; + tfid.vnode = ntohl(dep->fid.vnode); + tfid.unique = ntohl(dep->fid.unique); + tscp = cm_FindSCache(&tfid); + if (tscp) { + if (lock_TryMutex(&tscp->mx)) { + /* we have an entry that we can look at */ + if (cm_HaveCallback(tscp)) { + /* we have a callback on it. Don't bother + * fetching this stat entry, since we're happy + * with the info we have. + */ + lock_ReleaseMutex(&tscp->mx); cm_ReleaseSCache(tscp); - } /* found entry */ + return 0; + } + lock_ReleaseMutex(&tscp->mx); + } /* got lock */ + cm_ReleaseSCache(tscp); + } /* found entry */ #ifdef AFS_FREELANCE_CLIENT - // yj: if this is a mountpoint under root.afs then we don't want it - // to be bulkstat-ed, instead, we call getSCache directly and under - // getSCache, it is handled specially. - if ( cm_freelanceEnabled && + // yj: if this is a mountpoint under root.afs then we don't want it + // to be bulkstat-ed, instead, we call getSCache directly and under + // getSCache, it is handled specially. + if ( cm_freelanceEnabled && tfid.cell==AFS_FAKE_ROOT_CELL_ID && tfid.volume==AFS_FAKE_ROOT_VOL_ID && !(tfid.vnode==0x1 && tfid.unique==0x1) ) - { + { osi_Log0(afsd_logp, "cm_TryBulkProc Freelance calls cm_SCache on root.afs mountpoint"); - return cm_GetSCache(&tfid, &tscp, NULL, NULL); - } + return cm_GetSCache(&tfid, &tscp, NULL, NULL); + } #endif /* AFS_FREELANCE_CLIENT */ - i = bsp->counter++; - bsp->fids[i].Volume = scp->fid.volume; - bsp->fids[i].Vnode = tfid.vnode; - bsp->fids[i].Unique = tfid.unique; - return 0; -} + i = bsp->counter++; + bsp->fids[i].Volume = scp->fid.volume; + bsp->fids[i].Vnode = tfid.vnode; + bsp->fids[i].Unique = tfid.unique; + return 0; +} /* called with a locked scp and a pointer to a buffer. Make bulk stat * calls on all undeleted files in the page of the directory specified. */ void cm_TryBulkStat(cm_scache_t *dscp, osi_hyper_t *offsetp, cm_user_t *userp, - cm_req_t *reqp) + cm_req_t *reqp) { - long code; - cm_bulkStat_t bb; /* this is *BIG*, probably 12K or so; - * watch for stack problems */ - AFSCBFids fidStruct; - AFSBulkStats statStruct; - cm_conn_t *connp; - AFSCBs callbackStruct; - long filex; - AFSVolSync volSync; - cm_callbackRequest_t cbReq; - long filesThisCall; - long i; - long j; - cm_scache_t *scp; - cm_fid_t tfid; - - osi_Log1(afsd_logp, "cm_TryBulkStat dir 0x%x", (long) dscp); - - /* should be on a buffer boundary */ - osi_assert((offsetp->LowPart & (buf_bufferSize - 1)) == 0); - - bb.counter = 0; - bb.bufOffset = *offsetp; - - /* first, assemble the file IDs we need to stat */ - code = cm_ApplyDir(dscp, cm_TryBulkProc, (void *) &bb, offsetp, userp, - reqp, NULL); - - /* if we failed, bail out early */ - if (code && code != CM_ERROR_STOPNOW) return; - - /* otherwise, we may have one or more bulk stat's worth of stuff in bb; - * make the calls to create the entries. Handle AFSCBMAX files at a - * time. - */ - filex = 0; - while(filex < bb.counter) { - filesThisCall = bb.counter - filex; - if (filesThisCall > AFSCBMAX) filesThisCall = AFSCBMAX; - - fidStruct.AFSCBFids_len = filesThisCall; - fidStruct.AFSCBFids_val = &bb.fids[filex]; - statStruct.AFSBulkStats_len = filesThisCall; - statStruct.AFSBulkStats_val = &bb.stats[filex]; - callbackStruct.AFSCBs_len = filesThisCall; - callbackStruct.AFSCBs_val = &bb.callbacks[filex]; - cm_StartCallbackGrantingCall(NULL, &cbReq); - osi_Log1(afsd_logp, "CALL BulkStatus, %d entries", filesThisCall); - do { - code = cm_Conn(&dscp->fid, userp, reqp, &connp); - if (code) continue; - - code = RXAFS_BulkStatus(connp->callp, &fidStruct, - &statStruct, &callbackStruct, &volSync); + long code; + cm_bulkStat_t bb; /* this is *BIG*, probably 12K or so; + * watch for stack problems */ + AFSCBFids fidStruct; + AFSBulkStats statStruct; + cm_conn_t *connp; + AFSCBs callbackStruct; + long filex; + AFSVolSync volSync; + cm_callbackRequest_t cbReq; + long filesThisCall; + long i; + long j; + cm_scache_t *scp; + cm_fid_t tfid; + struct rx_connection * callp; + + osi_Log1(afsd_logp, "cm_TryBulkStat dir 0x%x", (long) dscp); + + /* should be on a buffer boundary */ + osi_assert((offsetp->LowPart & (buf_bufferSize - 1)) == 0); + + bb.counter = 0; + bb.bufOffset = *offsetp; + + /* first, assemble the file IDs we need to stat */ + code = cm_ApplyDir(dscp, cm_TryBulkProc, (void *) &bb, offsetp, userp, + reqp, NULL); + + /* if we failed, bail out early */ + if (code && code != CM_ERROR_STOPNOW) return; + + /* otherwise, we may have one or more bulk stat's worth of stuff in bb; + * make the calls to create the entries. Handle AFSCBMAX files at a + * time. + */ + filex = 0; + while(filex < bb.counter) { + filesThisCall = bb.counter - filex; + if (filesThisCall > AFSCBMAX) filesThisCall = AFSCBMAX; + + fidStruct.AFSCBFids_len = filesThisCall; + fidStruct.AFSCBFids_val = &bb.fids[filex]; + statStruct.AFSBulkStats_len = filesThisCall; + statStruct.AFSBulkStats_val = &bb.stats[filex]; + callbackStruct.AFSCBs_len = filesThisCall; + callbackStruct.AFSCBs_val = &bb.callbacks[filex]; + cm_StartCallbackGrantingCall(NULL, &cbReq); + osi_Log1(afsd_logp, "CALL BulkStatus, %d entries", filesThisCall); + do { + code = cm_Conn(&dscp->fid, userp, reqp, &connp); + if (code) + continue; - } while (cm_Analyze(connp, userp, reqp, &dscp->fid, - &volSync, NULL, &cbReq, code)); - code = cm_MapRPCError(code, reqp); + callp = cm_GetRxConn(connp); + code = RXAFS_BulkStatus(callp, &fidStruct, + &statStruct, &callbackStruct, &volSync); + rx_PutConnection(callp); - osi_Log0(afsd_logp, "CALL BulkStatus DONE"); - - /* may as well quit on an error, since we're not going to do - * much better on the next immediate call, either. - */ - if (code) break; - - /* otherwise, we should do the merges */ - for(i = 0; ifid.cell; - tfid.volume = bb.fids[j].Volume; - tfid.vnode = bb.fids[j].Vnode; - tfid.unique = bb.fids[j].Unique; - code = cm_GetSCache(&tfid, &scp, userp, reqp); - if (code != 0) continue; - - /* otherwise, if this entry has no callback info, - * merge in this. - */ - lock_ObtainMutex(&scp->mx); - /* now, we have to be extra paranoid on merging in this - * information, since we didn't use cm_SyncOp before - * starting the fetch to make sure that no bad races - * were occurring. Specifically, we need to make sure - * we don't obliterate any newer information in the - * vnode than have here. - * - * Right now, be pretty conservative: if there's a - * callback or a pending call, skip it. - */ - if (scp->cbServerp == NULL - && !(scp->flags & - (CM_SCACHEFLAG_FETCHING - | CM_SCACHEFLAG_STORING - | CM_SCACHEFLAG_SIZESTORING))) { - cm_EndCallbackGrantingCall(scp, &cbReq, - &bb.callbacks[j], - CM_CALLBACK_MAINTAINCOUNT); - cm_MergeStatus(scp, &bb.stats[j], &volSync, - userp, 0); - } - lock_ReleaseMutex(&scp->mx); - cm_ReleaseSCache(scp); - } /* all files in the response */ - /* now tell it to drop the count, - * after doing the vnode processing above */ + } while (cm_Analyze(connp, userp, reqp, &dscp->fid, + &volSync, NULL, &cbReq, code)); + code = cm_MapRPCError(code, reqp); + + osi_Log0(afsd_logp, "CALL BulkStatus DONE"); + + /* may as well quit on an error, since we're not going to do + * much better on the next immediate call, either. + */ + if (code) + break; + + /* otherwise, we should do the merges */ + for(i = 0; ifid.cell; + tfid.volume = bb.fids[j].Volume; + tfid.vnode = bb.fids[j].Vnode; + tfid.unique = bb.fids[j].Unique; + code = cm_GetSCache(&tfid, &scp, userp, reqp); + if (code != 0) + continue; + + /* otherwise, if this entry has no callback info, + * merge in this. + */ + lock_ObtainMutex(&scp->mx); + /* now, we have to be extra paranoid on merging in this + * information, since we didn't use cm_SyncOp before + * starting the fetch to make sure that no bad races + * were occurring. Specifically, we need to make sure + * we don't obliterate any newer information in the + * vnode than have here. + * + * Right now, be pretty conservative: if there's a + * callback or a pending call, skip it. + */ + if (scp->cbServerp == NULL + && !(scp->flags & + (CM_SCACHEFLAG_FETCHING + | CM_SCACHEFLAG_STORING + | CM_SCACHEFLAG_SIZESTORING))) { + cm_EndCallbackGrantingCall(scp, &cbReq, + &bb.callbacks[j], + CM_CALLBACK_MAINTAINCOUNT); + cm_MergeStatus(scp, &bb.stats[j], &volSync, + userp, 0); + } + lock_ReleaseMutex(&scp->mx); + cm_ReleaseSCache(scp); + } /* all files in the response */ + /* now tell it to drop the count, + * after doing the vnode processing above */ cm_EndCallbackGrantingCall(NULL, &cbReq, NULL, 0); - - filex += filesThisCall; - } /* while there are still more files to process */ - osi_Log0(afsd_logp, "END cm_TryBulkStat"); -} + + filex += filesThisCall; + } /* while there are still more files to process */ + osi_Log0(afsd_logp, "END cm_TryBulkStat"); +} void cm_StatusFromAttr(AFSStoreStatus *statusp, cm_scache_t *scp, cm_attr_t *attrp) { - long mask; - - /* initialize store back mask as inexpensive local variable */ - mask = 0; - memset(statusp, 0, sizeof(AFSStoreStatus)); - - /* copy out queued info from scache first, if scp passed in */ - if (scp) { - if (scp->mask & CM_SCACHEMASK_CLIENTMODTIME) { - statusp->ClientModTime = scp->clientModTime; - mask |= AFS_SETMODTIME; - scp->mask &= ~CM_SCACHEMASK_CLIENTMODTIME; - } - } - - if (attrp) { - /* now add in our locally generated request */ - if (attrp->mask & CM_ATTRMASK_CLIENTMODTIME) { - statusp->ClientModTime = attrp->clientModTime; - mask |= AFS_SETMODTIME; - } - if (attrp->mask & CM_ATTRMASK_UNIXMODEBITS) { - statusp->UnixModeBits = attrp->unixModeBits; - mask |= AFS_SETMODE; - } - if (attrp->mask & CM_ATTRMASK_OWNER) { - statusp->Owner = attrp->owner; - mask |= AFS_SETOWNER; - } - if (attrp->mask & CM_ATTRMASK_GROUP) { - statusp->Group = attrp->group; - mask |= AFS_SETGROUP; - } - } - statusp->Mask = mask; -} + long mask; + + /* initialize store back mask as inexpensive local variable */ + mask = 0; + memset(statusp, 0, sizeof(AFSStoreStatus)); + + /* copy out queued info from scache first, if scp passed in */ + if (scp) { + if (scp->mask & CM_SCACHEMASK_CLIENTMODTIME) { + statusp->ClientModTime = scp->clientModTime; + mask |= AFS_SETMODTIME; + scp->mask &= ~CM_SCACHEMASK_CLIENTMODTIME; + } + } + + if (attrp) { + /* now add in our locally generated request */ + if (attrp->mask & CM_ATTRMASK_CLIENTMODTIME) { + statusp->ClientModTime = attrp->clientModTime; + mask |= AFS_SETMODTIME; + } + if (attrp->mask & CM_ATTRMASK_UNIXMODEBITS) { + statusp->UnixModeBits = attrp->unixModeBits; + mask |= AFS_SETMODE; + } + if (attrp->mask & CM_ATTRMASK_OWNER) { + statusp->Owner = attrp->owner; + mask |= AFS_SETOWNER; + } + if (attrp->mask & CM_ATTRMASK_GROUP) { + statusp->Group = attrp->group; + mask |= AFS_SETGROUP; + } + } + statusp->Mask = mask; +} /* set the file size, and make sure that all relevant buffers have been * truncated. Ensure that any partially truncated buffers have been zeroed * to the end of the buffer. */ long cm_SetLength(cm_scache_t *scp, osi_hyper_t *sizep, cm_user_t *userp, - cm_req_t *reqp) + cm_req_t *reqp) { - long code; - int shrinking; + long code; + int shrinking; - /* start by locking out buffer creation */ - lock_ObtainWrite(&scp->bufCreateLock); + /* start by locking out buffer creation */ + lock_ObtainWrite(&scp->bufCreateLock); - /* verify that this is a file, not a dir or a symlink */ - lock_ObtainMutex(&scp->mx); - code = cm_SyncOp(scp, NULL, userp, reqp, 0, - CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); - if (code) goto done; + /* verify that this is a file, not a dir or a symlink */ + lock_ObtainMutex(&scp->mx); + code = cm_SyncOp(scp, NULL, userp, reqp, 0, + CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + if (code) + goto done; - if (scp->fileType != CM_SCACHETYPE_FILE) { - code = CM_ERROR_ISDIR; - goto done; - } + if (scp->fileType != CM_SCACHETYPE_FILE) { + code = CM_ERROR_ISDIR; + goto done; + } -startover: - if (LargeIntegerLessThan(*sizep, scp->length)) - shrinking = 1; - else - shrinking = 0; + startover: + if (LargeIntegerLessThan(*sizep, scp->length)) + shrinking = 1; + else + shrinking = 0; - lock_ReleaseMutex(&scp->mx); + lock_ReleaseMutex(&scp->mx); - /* can't hold scp->mx lock here, since we may wait for a storeback to - * finish if the buffer package is cleaning a buffer by storing it to - * the server. - */ - if (shrinking) - buf_Truncate(scp, userp, reqp, sizep); - - /* now ensure that file length is short enough, and update truncPos */ - lock_ObtainMutex(&scp->mx); - - /* make sure we have a callback (so we have the right value for the - * length), and wait for it to be safe to do a truncate. + /* can't hold scp->mx lock here, since we may wait for a storeback to + * finish if the buffer package is cleaning a buffer by storing it to + * the server. + */ + if (shrinking) + buf_Truncate(scp, userp, reqp, sizep); + + /* now ensure that file length is short enough, and update truncPos */ + lock_ObtainMutex(&scp->mx); + + /* make sure we have a callback (so we have the right value for the + * length), and wait for it to be safe to do a truncate. + */ + code = cm_SyncOp(scp, NULL, userp, reqp, PRSFS_WRITE, + CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS + | CM_SCACHESYNC_SETSTATUS | CM_SCACHESYNC_SETSIZE); + if (code) + goto done; + + if (LargeIntegerLessThan(*sizep, scp->length)) { + /* a real truncation. If truncPos is not set yet, or is bigger + * than where we're truncating the file, set truncPos to this + * new value. */ - code = cm_SyncOp(scp, NULL, userp, reqp, PRSFS_WRITE, - CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS - | CM_SCACHESYNC_SETSTATUS | CM_SCACHESYNC_SETSIZE); - if (code) goto done; - - if (LargeIntegerLessThan(*sizep, scp->length)) { - /* a real truncation. If truncPos is not set yet, or is bigger - * than where we're truncating the file, set truncPos to this - * new value. - */ - if (!shrinking) - goto startover; - if (!(scp->mask & CM_SCACHEMASK_TRUNCPOS) - || LargeIntegerLessThan(*sizep, scp->length)) { - /* set trunc pos */ - scp->truncPos = *sizep; - scp->mask |= CM_SCACHEMASK_TRUNCPOS; - } - /* in either case, the new file size has been changed */ - scp->length = *sizep; - scp->mask |= CM_SCACHEMASK_LENGTH; + if (!shrinking) + goto startover; + if (!(scp->mask & CM_SCACHEMASK_TRUNCPOS) + || LargeIntegerLessThan(*sizep, scp->length)) { + /* set trunc pos */ + scp->truncPos = *sizep; + scp->mask |= CM_SCACHEMASK_TRUNCPOS; } - else if (LargeIntegerGreaterThan(*sizep, scp->length)) { - /* really extending the file */ - scp->length = *sizep; - scp->mask |= CM_SCACHEMASK_LENGTH; - } + /* in either case, the new file size has been changed */ + scp->length = *sizep; + scp->mask |= CM_SCACHEMASK_LENGTH; + } + else if (LargeIntegerGreaterThan(*sizep, scp->length)) { + /* really extending the file */ + scp->length = *sizep; + scp->mask |= CM_SCACHEMASK_LENGTH; + } - /* done successfully */ - code = 0; + /* done successfully */ + code = 0; -done: - lock_ReleaseMutex(&scp->mx); - lock_ReleaseWrite(&scp->bufCreateLock); + done: + lock_ReleaseMutex(&scp->mx); + lock_ReleaseWrite(&scp->bufCreateLock); - return code; + return code; } /* set the file size or other attributes (but not both at once) */ long cm_SetAttr(cm_scache_t *scp, cm_attr_t *attrp, cm_user_t *userp, - cm_req_t *reqp) + cm_req_t *reqp) { - long code; - int flags; - AFSFetchStatus afsOutStatus; - AFSVolSync volSync; - cm_conn_t *connp; - AFSFid tfid; - AFSStoreStatus afsInStatus; + long code; + int flags; + AFSFetchStatus afsOutStatus; + AFSVolSync volSync; + cm_conn_t *connp; + AFSFid tfid; + AFSStoreStatus afsInStatus; + struct rx_connection * callp; - /* handle file length setting */ - if (attrp->mask & CM_ATTRMASK_LENGTH) - return cm_SetLength(scp, &attrp->length, userp, reqp); + /* handle file length setting */ + if (attrp->mask & CM_ATTRMASK_LENGTH) + return cm_SetLength(scp, &attrp->length, userp, reqp); - flags = CM_SCACHESYNC_STORESTATUS; + flags = CM_SCACHESYNC_STORESTATUS; - lock_ObtainMutex(&scp->mx); - /* otherwise, we have to make an RPC to get the status */ - code = cm_SyncOp(scp, NULL, userp, reqp, 0, CM_SCACHESYNC_STORESTATUS); + lock_ObtainMutex(&scp->mx); + /* otherwise, we have to make an RPC to get the status */ + code = cm_SyncOp(scp, NULL, userp, reqp, 0, CM_SCACHESYNC_STORESTATUS); - /* make the attr structure */ - cm_StatusFromAttr(&afsInStatus, scp, attrp); + /* make the attr structure */ + cm_StatusFromAttr(&afsInStatus, scp, attrp); - lock_ReleaseMutex(&scp->mx); - if (code) return code; - - /* now make the RPC */ - osi_Log1(afsd_logp, "CALL StoreStatus vp %x", (long) scp); - tfid.Volume = scp->fid.volume; - tfid.Vnode = scp->fid.vnode; - tfid.Unique = scp->fid.unique; - do { - code = cm_Conn(&scp->fid, userp, reqp, &connp); - if (code) continue; - - code = RXAFS_StoreStatus(connp->callp, &tfid, - &afsInStatus, &afsOutStatus, &volSync); + lock_ReleaseMutex(&scp->mx); + if (code) + return code; - } while (cm_Analyze(connp, userp, reqp, - &scp->fid, &volSync, NULL, NULL, code)); - code = cm_MapRPCError(code, reqp); + /* now make the RPC */ + osi_Log1(afsd_logp, "CALL StoreStatus vp %x", (long) scp); + tfid.Volume = scp->fid.volume; + tfid.Vnode = scp->fid.vnode; + tfid.Unique = scp->fid.unique; + do { + code = cm_Conn(&scp->fid, userp, reqp, &connp); + if (code) + continue; + + callp = cm_GetRxConn(connp); + code = RXAFS_StoreStatus(callp, &tfid, + &afsInStatus, &afsOutStatus, &volSync); + rx_PutConnection(callp); - osi_Log1(afsd_logp, "CALL StoreStatus DONE, code %d", code); + } while (cm_Analyze(connp, userp, reqp, + &scp->fid, &volSync, NULL, NULL, code)); + code = cm_MapRPCError(code, reqp); - lock_ObtainMutex(&scp->mx); - cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_STORESTATUS); - if (code == 0) - cm_MergeStatus(scp, &afsOutStatus, &volSync, userp, - CM_MERGEFLAG_FORCE); + osi_Log1(afsd_logp, "CALL StoreStatus DONE, code %d", code); + + lock_ObtainMutex(&scp->mx); + cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_STORESTATUS); + if (code == 0) + cm_MergeStatus(scp, &afsOutStatus, &volSync, userp, + CM_MERGEFLAG_FORCE); - /* if we're changing the mode bits, discard the ACL cache, - * since we changed the mode bits. - */ - if (afsInStatus.Mask & AFS_SETMODE) cm_FreeAllACLEnts(scp); - lock_ReleaseMutex(&scp->mx); - return code; -} + /* if we're changing the mode bits, discard the ACL cache, + * since we changed the mode bits. + */ + if (afsInStatus.Mask & AFS_SETMODE) cm_FreeAllACLEnts(scp); + lock_ReleaseMutex(&scp->mx); + return code; +} long cm_Create(cm_scache_t *dscp, char *namep, long flags, cm_attr_t *attrp, - cm_scache_t **scpp, cm_user_t *userp, cm_req_t *reqp) -{ - cm_conn_t *connp; - long code; - AFSFid dirAFSFid; - cm_callbackRequest_t cbReq; - AFSFid newAFSFid; - cm_fid_t newFid; - cm_scache_t *scp; - int didEnd; - AFSStoreStatus inStatus; - AFSFetchStatus updatedDirStatus; - AFSFetchStatus newFileStatus; - AFSCallBack newFileCallback; - AFSVolSync volSync; - - /* can't create names with @sys in them; must expand it manually first. - * return "invalid request" if they try. - */ - if (cm_ExpandSysName(namep, NULL, 0)) { - return CM_ERROR_ATSYS; - } + cm_scache_t **scpp, cm_user_t *userp, cm_req_t *reqp) +{ + cm_conn_t *connp; + long code; + AFSFid dirAFSFid; + cm_callbackRequest_t cbReq; + AFSFid newAFSFid; + cm_fid_t newFid; + cm_scache_t *scp; + int didEnd; + AFSStoreStatus inStatus; + AFSFetchStatus updatedDirStatus; + AFSFetchStatus newFileStatus; + AFSCallBack newFileCallback; + AFSVolSync volSync; + struct rx_connection * callp; + + /* can't create names with @sys in them; must expand it manually first. + * return "invalid request" if they try. + */ + if (cm_ExpandSysName(namep, NULL, 0, 0)) { + return CM_ERROR_ATSYS; + } - /* before starting the RPC, mark that we're changing the file data, so - * that someone who does a chmod will know to wait until our call - * completes. - */ - lock_ObtainMutex(&dscp->mx); - code = cm_SyncOp(dscp, NULL, userp, reqp, 0, CM_SCACHESYNC_STOREDATA); - if (code == 0) { - cm_StartCallbackGrantingCall(NULL, &cbReq); - } - lock_ReleaseMutex(&dscp->mx); - if (code) { - return code; - } - didEnd = 0; + /* before starting the RPC, mark that we're changing the file data, so + * that someone who does a chmod will know to wait until our call + * completes. + */ + lock_ObtainMutex(&dscp->mx); + code = cm_SyncOp(dscp, NULL, userp, reqp, 0, CM_SCACHESYNC_STOREDATA); + if (code == 0) { + cm_StartCallbackGrantingCall(NULL, &cbReq); + } + lock_ReleaseMutex(&dscp->mx); + if (code) { + return code; + } + didEnd = 0; - cm_StatusFromAttr(&inStatus, NULL, attrp); + cm_StatusFromAttr(&inStatus, NULL, attrp); - /* try the RPC now */ - do { - code = cm_Conn(&dscp->fid, userp, reqp, &connp); - if (code) continue; - - dirAFSFid.Volume = dscp->fid.volume; - dirAFSFid.Vnode = dscp->fid.vnode; - dirAFSFid.Unique = dscp->fid.unique; - code = RXAFS_CreateFile(connp->callp, &dirAFSFid, namep, - &inStatus, &newAFSFid, &newFileStatus, - &updatedDirStatus, &newFileCallback, - &volSync); - } while (cm_Analyze(connp, userp, reqp, - &dscp->fid, &volSync, NULL, &cbReq, code)); - code = cm_MapRPCError(code, reqp); + /* try the RPC now */ + do { + code = cm_Conn(&dscp->fid, userp, reqp, &connp); + if (code) + continue; + + dirAFSFid.Volume = dscp->fid.volume; + dirAFSFid.Vnode = dscp->fid.vnode; + dirAFSFid.Unique = dscp->fid.unique; + + callp = cm_GetRxConn(connp); + code = RXAFS_CreateFile(connp->callp, &dirAFSFid, namep, + &inStatus, &newAFSFid, &newFileStatus, + &updatedDirStatus, &newFileCallback, + &volSync); + rx_PutConnection(callp); + + } while (cm_Analyze(connp, userp, reqp, + &dscp->fid, &volSync, NULL, &cbReq, code)); + code = cm_MapRPCError(code, reqp); - lock_ObtainMutex(&dscp->mx); - cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA); - if (code == 0) { - cm_MergeStatus(dscp, &updatedDirStatus, &volSync, userp, 0); - } - lock_ReleaseMutex(&dscp->mx); + lock_ObtainMutex(&dscp->mx); + cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA); + if (code == 0) { + cm_MergeStatus(dscp, &updatedDirStatus, &volSync, userp, 0); + } + lock_ReleaseMutex(&dscp->mx); - /* now try to create the file's entry, too, but be careful to - * make sure that we don't merge in old info. Since we weren't locking - * out any requests during the file's creation, we may have pretty old - * info. - */ - if (code == 0) { - newFid.cell = dscp->fid.cell; - newFid.volume = dscp->fid.volume; - newFid.vnode = newAFSFid.Vnode; - newFid.unique = newAFSFid.Unique; - code = cm_GetSCache(&newFid, &scp, userp, reqp); - if (code == 0) { - lock_ObtainMutex(&scp->mx); - if (!cm_HaveCallback(scp)) { - cm_MergeStatus(scp, &newFileStatus, &volSync, - userp, 0); - cm_EndCallbackGrantingCall(scp, &cbReq, - &newFileCallback, 0); - didEnd = 1; - } - lock_ReleaseMutex(&scp->mx); - *scpp = scp; - } + /* now try to create the file's entry, too, but be careful to + * make sure that we don't merge in old info. Since we weren't locking + * out any requests during the file's creation, we may have pretty old + * info. + */ + if (code == 0) { + newFid.cell = dscp->fid.cell; + newFid.volume = dscp->fid.volume; + newFid.vnode = newAFSFid.Vnode; + newFid.unique = newAFSFid.Unique; + code = cm_GetSCache(&newFid, &scp, userp, reqp); + if (code == 0) { + lock_ObtainMutex(&scp->mx); + if (!cm_HaveCallback(scp)) { + cm_MergeStatus(scp, &newFileStatus, &volSync, + userp, 0); + cm_EndCallbackGrantingCall(scp, &cbReq, + &newFileCallback, 0); + didEnd = 1; + } + lock_ReleaseMutex(&scp->mx); + *scpp = scp; } - - /* make sure we end things properly */ - if (!didEnd) - cm_EndCallbackGrantingCall(NULL, &cbReq, NULL, 0); + } - return code; -} + /* make sure we end things properly */ + if (!didEnd) + cm_EndCallbackGrantingCall(NULL, &cbReq, NULL, 0); + + return code; +} long cm_FSync(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp) { - long code; - - lock_ObtainWrite(&scp->bufCreateLock); - code = buf_CleanVnode(scp, userp, reqp); - lock_ReleaseWrite(&scp->bufCreateLock); - if (code == 0) { - lock_ObtainMutex(&scp->mx); - scp->flags &= ~(CM_SCACHEFLAG_OVERQUOTA - | CM_SCACHEFLAG_OUTOFSPACE); - if (scp->mask & (CM_SCACHEMASK_TRUNCPOS - | CM_SCACHEMASK_CLIENTMODTIME - | CM_SCACHEMASK_LENGTH)) - code = cm_StoreMini(scp, userp, reqp); - lock_ReleaseMutex(&scp->mx); - } - return code; + long code; + + lock_ObtainWrite(&scp->bufCreateLock); + code = buf_CleanVnode(scp, userp, reqp); + lock_ReleaseWrite(&scp->bufCreateLock); + if (code == 0) { + lock_ObtainMutex(&scp->mx); + scp->flags &= ~(CM_SCACHEFLAG_OVERQUOTA + | CM_SCACHEFLAG_OUTOFSPACE); + if (scp->mask & (CM_SCACHEMASK_TRUNCPOS + | CM_SCACHEMASK_CLIENTMODTIME + | CM_SCACHEMASK_LENGTH)) + code = cm_StoreMini(scp, userp, reqp); + lock_ReleaseMutex(&scp->mx); + } + return code; } long cm_MakeDir(cm_scache_t *dscp, char *namep, long flags, cm_attr_t *attrp, - cm_user_t *userp, cm_req_t *reqp) + cm_user_t *userp, cm_req_t *reqp) { - cm_conn_t *connp; - long code; - AFSFid dirAFSFid; - cm_callbackRequest_t cbReq; - AFSFid newAFSFid; - cm_fid_t newFid; - cm_scache_t *scp; - int didEnd; - AFSStoreStatus inStatus; - AFSFetchStatus updatedDirStatus; - AFSFetchStatus newDirStatus; - AFSCallBack newDirCallback; - AFSVolSync volSync; - - /* can't create names with @sys in them; must expand it manually first. - * return "invalid request" if they try. - */ - if (cm_ExpandSysName(namep, NULL, 0)) { - return CM_ERROR_ATSYS; - } + cm_conn_t *connp; + long code; + AFSFid dirAFSFid; + cm_callbackRequest_t cbReq; + AFSFid newAFSFid; + cm_fid_t newFid; + cm_scache_t *scp; + int didEnd; + AFSStoreStatus inStatus; + AFSFetchStatus updatedDirStatus; + AFSFetchStatus newDirStatus; + AFSCallBack newDirCallback; + AFSVolSync volSync; + struct rx_connection * callp; + + /* can't create names with @sys in them; must expand it manually first. + * return "invalid request" if they try. + */ + if (cm_ExpandSysName(namep, NULL, 0, 0)) { + return CM_ERROR_ATSYS; + } - /* before starting the RPC, mark that we're changing the directory - * data, so that someone who does a chmod on the dir will wait until - * our call completes. - */ - lock_ObtainMutex(&dscp->mx); - code = cm_SyncOp(dscp, NULL, userp, reqp, 0, CM_SCACHESYNC_STOREDATA); - if (code == 0) { - cm_StartCallbackGrantingCall(NULL, &cbReq); - } - lock_ReleaseMutex(&dscp->mx); - if (code) { - return code; - } - didEnd = 0; + /* before starting the RPC, mark that we're changing the directory + * data, so that someone who does a chmod on the dir will wait until + * our call completes. + */ + lock_ObtainMutex(&dscp->mx); + code = cm_SyncOp(dscp, NULL, userp, reqp, 0, CM_SCACHESYNC_STOREDATA); + if (code == 0) { + cm_StartCallbackGrantingCall(NULL, &cbReq); + } + lock_ReleaseMutex(&dscp->mx); + if (code) { + return code; + } + didEnd = 0; - cm_StatusFromAttr(&inStatus, NULL, attrp); + cm_StatusFromAttr(&inStatus, NULL, attrp); - /* try the RPC now */ - do { - code = cm_Conn(&dscp->fid, userp, reqp, &connp); - if (code) continue; - - dirAFSFid.Volume = dscp->fid.volume; - dirAFSFid.Vnode = dscp->fid.vnode; - dirAFSFid.Unique = dscp->fid.unique; - code = RXAFS_MakeDir(connp->callp, &dirAFSFid, namep, - &inStatus, &newAFSFid, &newDirStatus, - &updatedDirStatus, &newDirCallback, - &volSync); - } while (cm_Analyze(connp, userp, reqp, - &dscp->fid, &volSync, NULL, &cbReq, code)); - code = cm_MapRPCError(code, reqp); + /* try the RPC now */ + do { + code = cm_Conn(&dscp->fid, userp, reqp, &connp); + if (code) + continue; + + dirAFSFid.Volume = dscp->fid.volume; + dirAFSFid.Vnode = dscp->fid.vnode; + dirAFSFid.Unique = dscp->fid.unique; + + callp = cm_GetRxConn(connp); + code = RXAFS_MakeDir(connp->callp, &dirAFSFid, namep, + &inStatus, &newAFSFid, &newDirStatus, + &updatedDirStatus, &newDirCallback, + &volSync); + rx_PutConnection(callp); + + } while (cm_Analyze(connp, userp, reqp, + &dscp->fid, &volSync, NULL, &cbReq, code)); + code = cm_MapRPCError(code, reqp); - lock_ObtainMutex(&dscp->mx); - cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA); - if (code == 0) { - cm_MergeStatus(dscp, &updatedDirStatus, &volSync, userp, 0); - } - lock_ReleaseMutex(&dscp->mx); + lock_ObtainMutex(&dscp->mx); + cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA); + if (code == 0) { + cm_MergeStatus(dscp, &updatedDirStatus, &volSync, userp, 0); + } + lock_ReleaseMutex(&dscp->mx); - /* now try to create the new dir's entry, too, but be careful to - * make sure that we don't merge in old info. Since we weren't locking - * out any requests during the file's creation, we may have pretty old - * info. - */ - if (code == 0) { - newFid.cell = dscp->fid.cell; - newFid.volume = dscp->fid.volume; - newFid.vnode = newAFSFid.Vnode; - newFid.unique = newAFSFid.Unique; - code = cm_GetSCache(&newFid, &scp, userp, reqp); - if (code == 0) { - lock_ObtainMutex(&scp->mx); - if (!cm_HaveCallback(scp)) { - cm_MergeStatus(scp, &newDirStatus, &volSync, - userp, 0); - cm_EndCallbackGrantingCall(scp, &cbReq, - &newDirCallback, 0); - didEnd = 1; - } - lock_ReleaseMutex(&scp->mx); - cm_ReleaseSCache(scp); - } + /* now try to create the new dir's entry, too, but be careful to + * make sure that we don't merge in old info. Since we weren't locking + * out any requests during the file's creation, we may have pretty old + * info. + */ + if (code == 0) { + newFid.cell = dscp->fid.cell; + newFid.volume = dscp->fid.volume; + newFid.vnode = newAFSFid.Vnode; + newFid.unique = newAFSFid.Unique; + code = cm_GetSCache(&newFid, &scp, userp, reqp); + if (code == 0) { + lock_ObtainMutex(&scp->mx); + if (!cm_HaveCallback(scp)) { + cm_MergeStatus(scp, &newDirStatus, &volSync, + userp, 0); + cm_EndCallbackGrantingCall(scp, &cbReq, + &newDirCallback, 0); + didEnd = 1; + } + lock_ReleaseMutex(&scp->mx); + cm_ReleaseSCache(scp); } - - /* make sure we end things properly */ - if (!didEnd) - cm_EndCallbackGrantingCall(NULL, &cbReq, NULL, 0); - - /* and return error code */ + } + + /* make sure we end things properly */ + if (!didEnd) + cm_EndCallbackGrantingCall(NULL, &cbReq, NULL, 0); + + /* and return error code */ + return code; +} + +long cm_Link(cm_scache_t *dscp, char *namep, cm_scache_t *sscp, long flags, + cm_user_t *userp, cm_req_t *reqp) +{ + cm_conn_t *connp; + long code = 0; + AFSFid dirAFSFid; + AFSFid existingAFSFid; + AFSFetchStatus updatedDirStatus; + AFSFetchStatus newLinkStatus; + AFSVolSync volSync; + struct rx_connection * callp; + + if (dscp->fid.cell != sscp->fid.cell || + dscp->fid.volume != sscp->fid.volume) { + return CM_ERROR_CROSSDEVLINK; + } + + lock_ObtainMutex(&dscp->mx); + code = cm_SyncOp(dscp, NULL, userp, reqp, 0, CM_SCACHESYNC_STOREDATA); + lock_ReleaseMutex(&dscp->mx); + + if (code) return code; + + do { + code = cm_Conn(&dscp->fid, userp, reqp, &connp); + if (code) continue; + + dirAFSFid.Volume = dscp->fid.volume; + dirAFSFid.Vnode = dscp->fid.vnode; + dirAFSFid.Unique = dscp->fid.unique; + + existingAFSFid.Volume = sscp->fid.volume; + existingAFSFid.Vnode = sscp->fid.vnode; + existingAFSFid.Unique = sscp->fid.unique; + + callp = cm_GetRxConn(connp); + code = RXAFS_Link(callp, &dirAFSFid, namep, &existingAFSFid, + &newLinkStatus, &updatedDirStatus, &volSync); + rx_PutConnection(callp); + osi_Log1(smb_logp," RXAFS_Link returns %d", code); + + } while (cm_Analyze(connp, userp, reqp, + &dscp->fid, &volSync, NULL, NULL, code)); + + code = cm_MapRPCError(code, reqp); + + lock_ObtainMutex(&dscp->mx); + cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA); + if (code == 0) { + cm_MergeStatus(dscp, &updatedDirStatus, &volSync, userp, 0); + } + lock_ReleaseMutex(&dscp->mx); + + return code; } long cm_SymLink(cm_scache_t *dscp, char *namep, char *contentsp, long flags, - cm_attr_t *attrp, cm_user_t *userp, cm_req_t *reqp) + cm_attr_t *attrp, cm_user_t *userp, cm_req_t *reqp) { - cm_conn_t *connp; - long code; - AFSFid dirAFSFid; - AFSFid newAFSFid; - cm_fid_t newFid; - cm_scache_t *scp; - AFSStoreStatus inStatus; - AFSFetchStatus updatedDirStatus; - AFSFetchStatus newLinkStatus; - AFSVolSync volSync; - - /* before starting the RPC, mark that we're changing the directory data, - * so that someone who does a chmod on the dir will wait until our - * call completes. - */ - lock_ObtainMutex(&dscp->mx); - code = cm_SyncOp(dscp, NULL, userp, reqp, 0, CM_SCACHESYNC_STOREDATA); - lock_ReleaseMutex(&dscp->mx); - if (code) { - return code; - } + cm_conn_t *connp; + long code; + AFSFid dirAFSFid; + AFSFid newAFSFid; + cm_fid_t newFid; + cm_scache_t *scp; + AFSStoreStatus inStatus; + AFSFetchStatus updatedDirStatus; + AFSFetchStatus newLinkStatus; + AFSVolSync volSync; + struct rx_connection * callp; + + /* before starting the RPC, mark that we're changing the directory data, + * so that someone who does a chmod on the dir will wait until our + * call completes. + */ + lock_ObtainMutex(&dscp->mx); + code = cm_SyncOp(dscp, NULL, userp, reqp, 0, CM_SCACHESYNC_STOREDATA); + lock_ReleaseMutex(&dscp->mx); + if (code) { + return code; + } - cm_StatusFromAttr(&inStatus, NULL, attrp); + cm_StatusFromAttr(&inStatus, NULL, attrp); - /* try the RPC now */ - do { - code = cm_Conn(&dscp->fid, userp, reqp, &connp); - if (code) continue; - - dirAFSFid.Volume = dscp->fid.volume; - dirAFSFid.Vnode = dscp->fid.vnode; - dirAFSFid.Unique = dscp->fid.unique; - code = RXAFS_Symlink(connp->callp, &dirAFSFid, namep, contentsp, - &inStatus, &newAFSFid, &newLinkStatus, - &updatedDirStatus, &volSync); - } while (cm_Analyze(connp, userp, reqp, - &dscp->fid, &volSync, NULL, NULL, code)); - code = cm_MapRPCError(code, reqp); + /* try the RPC now */ + do { + code = cm_Conn(&dscp->fid, userp, reqp, &connp); + if (code) + continue; + + dirAFSFid.Volume = dscp->fid.volume; + dirAFSFid.Vnode = dscp->fid.vnode; + dirAFSFid.Unique = dscp->fid.unique; + + callp = cm_GetRxConn(connp); + code = RXAFS_Symlink(callp, &dirAFSFid, namep, contentsp, + &inStatus, &newAFSFid, &newLinkStatus, + &updatedDirStatus, &volSync); + rx_PutConnection(callp); + + } while (cm_Analyze(connp, userp, reqp, + &dscp->fid, &volSync, NULL, NULL, code)); + code = cm_MapRPCError(code, reqp); - lock_ObtainMutex(&dscp->mx); - cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA); - if (code == 0) { - cm_MergeStatus(dscp, &updatedDirStatus, &volSync, userp, 0); - } - lock_ReleaseMutex(&dscp->mx); + lock_ObtainMutex(&dscp->mx); + cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA); + if (code == 0) { + cm_MergeStatus(dscp, &updatedDirStatus, &volSync, userp, 0); + } + lock_ReleaseMutex(&dscp->mx); - /* now try to create the new dir's entry, too, but be careful to - * make sure that we don't merge in old info. Since we weren't locking - * out any requests during the file's creation, we may have pretty old - * info. - */ - if (code == 0) { - newFid.cell = dscp->fid.cell; - newFid.volume = dscp->fid.volume; - newFid.vnode = newAFSFid.Vnode; - newFid.unique = newAFSFid.Unique; - code = cm_GetSCache(&newFid, &scp, userp, reqp); - if (code == 0) { - lock_ObtainMutex(&scp->mx); - if (!cm_HaveCallback(scp)) { - cm_MergeStatus(scp, &newLinkStatus, &volSync, - userp, 0); - } - lock_ReleaseMutex(&scp->mx); - cm_ReleaseSCache(scp); - } + /* now try to create the new dir's entry, too, but be careful to + * make sure that we don't merge in old info. Since we weren't locking + * out any requests during the file's creation, we may have pretty old + * info. + */ + if (code == 0) { + newFid.cell = dscp->fid.cell; + newFid.volume = dscp->fid.volume; + newFid.vnode = newAFSFid.Vnode; + newFid.unique = newAFSFid.Unique; + code = cm_GetSCache(&newFid, &scp, userp, reqp); + if (code == 0) { + lock_ObtainMutex(&scp->mx); + if (!cm_HaveCallback(scp)) { + cm_MergeStatus(scp, &newLinkStatus, &volSync, + userp, 0); + } + lock_ReleaseMutex(&scp->mx); + cm_ReleaseSCache(scp); } + } - /* and return error code */ - return code; + /* and return error code */ + return code; } long cm_RemoveDir(cm_scache_t *dscp, char *namep, cm_user_t *userp, - cm_req_t *reqp) + cm_req_t *reqp) { - cm_conn_t *connp; - long code; - AFSFid dirAFSFid; - int didEnd; - AFSFetchStatus updatedDirStatus; - AFSVolSync volSync; - - /* before starting the RPC, mark that we're changing the directory data, - * so that someone who does a chmod on the dir will wait until our - * call completes. - */ - lock_ObtainMutex(&dscp->mx); - code = cm_SyncOp(dscp, NULL, userp, reqp, 0, CM_SCACHESYNC_STOREDATA); - lock_ReleaseMutex(&dscp->mx); - if (code) { - return code; - } - didEnd = 0; + cm_conn_t *connp; + long code; + AFSFid dirAFSFid; + int didEnd; + AFSFetchStatus updatedDirStatus; + AFSVolSync volSync; + struct rx_connection * callp; + + /* before starting the RPC, mark that we're changing the directory data, + * so that someone who does a chmod on the dir will wait until our + * call completes. + */ + lock_ObtainMutex(&dscp->mx); + code = cm_SyncOp(dscp, NULL, userp, reqp, 0, CM_SCACHESYNC_STOREDATA); + lock_ReleaseMutex(&dscp->mx); + if (code) { + return code; + } + didEnd = 0; - /* try the RPC now */ - do { - code = cm_Conn(&dscp->fid, userp, reqp, &connp); - if (code) continue; - - dirAFSFid.Volume = dscp->fid.volume; - dirAFSFid.Vnode = dscp->fid.vnode; - dirAFSFid.Unique = dscp->fid.unique; - code = RXAFS_RemoveDir(connp->callp, &dirAFSFid, namep, - &updatedDirStatus, &volSync); - } while (cm_Analyze(connp, userp, reqp, - &dscp->fid, &volSync, NULL, NULL, code)); - code = cm_MapRPCErrorRmdir(code, reqp); + /* try the RPC now */ + do { + code = cm_Conn(&dscp->fid, userp, reqp, &connp); + if (code) + continue; + + dirAFSFid.Volume = dscp->fid.volume; + dirAFSFid.Vnode = dscp->fid.vnode; + dirAFSFid.Unique = dscp->fid.unique; + + callp = cm_GetRxConn(connp); + code = RXAFS_RemoveDir(callp, &dirAFSFid, namep, + &updatedDirStatus, &volSync); + rx_PutConnection(callp); + + } while (cm_Analyze(connp, userp, reqp, + &dscp->fid, &volSync, NULL, NULL, code)); + code = cm_MapRPCErrorRmdir(code, reqp); - lock_ObtainMutex(&dscp->mx); - cm_dnlcRemove(dscp, namep); - cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA); - if (code == 0) { - cm_MergeStatus(dscp, &updatedDirStatus, &volSync, userp, 0); - } - lock_ReleaseMutex(&dscp->mx); + lock_ObtainMutex(&dscp->mx); + cm_dnlcRemove(dscp, namep); + cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA); + if (code == 0) { + cm_MergeStatus(dscp, &updatedDirStatus, &volSync, userp, 0); + } + lock_ReleaseMutex(&dscp->mx); - /* and return error code */ - return code; + /* and return error code */ + return code; } long cm_Open(cm_scache_t *scp, int type, cm_user_t *userp) { - /* grab mutex on contents */ - lock_ObtainMutex(&scp->mx); - - /* reset the prefetch info */ - scp->prefetch.base.LowPart = 0; /* base */ - scp->prefetch.base.HighPart = 0; - scp->prefetch.end.LowPart = 0; /* and end */ - scp->prefetch.end.HighPart = 0; - - /* release mutex on contents */ - lock_ReleaseMutex(&scp->mx); - - /* we're done */ - return 0; -} + /* grab mutex on contents */ + lock_ObtainMutex(&scp->mx); + + /* reset the prefetch info */ + scp->prefetch.base.LowPart = 0; /* base */ + scp->prefetch.base.HighPart = 0; + scp->prefetch.end.LowPart = 0; /* and end */ + scp->prefetch.end.HighPart = 0; + + /* release mutex on contents */ + lock_ReleaseMutex(&scp->mx); + + /* we're done */ + return 0; +} long cm_Rename(cm_scache_t *oldDscp, char *oldNamep, cm_scache_t *newDscp, - char *newNamep, cm_user_t *userp, cm_req_t *reqp) + char *newNamep, cm_user_t *userp, cm_req_t *reqp) { - cm_conn_t *connp; - long code; - AFSFid oldDirAFSFid; - AFSFid newDirAFSFid; - int didEnd; - AFSFetchStatus updatedOldDirStatus; - AFSFetchStatus updatedNewDirStatus; - AFSVolSync volSync; - int oneDir; - - /* before starting the RPC, mark that we're changing the directory data, - * so that someone who does a chmod on the dir will wait until our call - * completes. We do this in vnode order so that we don't deadlock, - * which makes the code a little verbose. + cm_conn_t *connp; + long code; + AFSFid oldDirAFSFid; + AFSFid newDirAFSFid; + int didEnd; + AFSFetchStatus updatedOldDirStatus; + AFSFetchStatus updatedNewDirStatus; + AFSVolSync volSync; + int oneDir; + struct rx_connection * callp; + + /* before starting the RPC, mark that we're changing the directory data, + * so that someone who does a chmod on the dir will wait until our call + * completes. We do this in vnode order so that we don't deadlock, + * which makes the code a little verbose. + */ + if (oldDscp == newDscp) { + /* check for identical names */ + if (strcmp(oldNamep, newNamep) == 0) + return CM_ERROR_RENAME_IDENTICAL; + + oneDir = 1; + lock_ObtainMutex(&oldDscp->mx); + cm_dnlcRemove(oldDscp, oldNamep); + cm_dnlcRemove(oldDscp, newNamep); + code = cm_SyncOp(oldDscp, NULL, userp, reqp, 0, + CM_SCACHESYNC_STOREDATA); + lock_ReleaseMutex(&oldDscp->mx); + } + else { + /* two distinct dir vnodes */ + oneDir = 0; + if (oldDscp->fid.cell != newDscp->fid.cell || + oldDscp->fid.volume != newDscp->fid.volume) + return CM_ERROR_CROSSDEVLINK; + + /* shouldn't happen that we have distinct vnodes for two + * different files, but could due to deliberate attack, or + * stale info. Avoid deadlocks and quit now. */ - if (oldDscp == newDscp) { - /* check for identical names */ - if (strcmp(oldNamep, newNamep) == 0) - return CM_ERROR_RENAME_IDENTICAL; - - oneDir = 1; - lock_ObtainMutex(&oldDscp->mx); - cm_dnlcRemove(oldDscp, oldNamep); - cm_dnlcRemove(oldDscp, newNamep); - code = cm_SyncOp(oldDscp, NULL, userp, reqp, 0, - CM_SCACHESYNC_STOREDATA); - lock_ReleaseMutex(&oldDscp->mx); + if (oldDscp->fid.vnode == newDscp->fid.vnode) + return CM_ERROR_CROSSDEVLINK; + + if (oldDscp->fid.vnode < newDscp->fid.vnode) { + lock_ObtainMutex(&oldDscp->mx); + cm_dnlcRemove(oldDscp, oldNamep); + code = cm_SyncOp(oldDscp, NULL, userp, reqp, 0, + CM_SCACHESYNC_STOREDATA); + lock_ReleaseMutex(&oldDscp->mx); + if (code == 0) { + lock_ObtainMutex(&newDscp->mx); + cm_dnlcRemove(newDscp, newNamep); + code = cm_SyncOp(newDscp, NULL, userp, reqp, 0, + CM_SCACHESYNC_STOREDATA); + lock_ReleaseMutex(&newDscp->mx); + if (code) { + /* cleanup first one */ + cm_SyncOpDone(oldDscp, NULL, + CM_SCACHESYNC_STOREDATA); + } + } } else { - /* two distinct dir vnodes */ - oneDir = 0; - if (oldDscp->fid.cell != newDscp->fid.cell || - oldDscp->fid.volume != newDscp->fid.volume) - return CM_ERROR_CROSSDEVLINK; - - /* shouldn't happen that we have distinct vnodes for two - * different files, but could due to deliberate attack, or - * stale info. Avoid deadlocks and quit now. - */ - if (oldDscp->fid.vnode == newDscp->fid.vnode) - return CM_ERROR_CROSSDEVLINK; - - if (oldDscp->fid.vnode < newDscp->fid.vnode) { - lock_ObtainMutex(&oldDscp->mx); - cm_dnlcRemove(oldDscp, oldNamep); - code = cm_SyncOp(oldDscp, NULL, userp, reqp, 0, - CM_SCACHESYNC_STOREDATA); - lock_ReleaseMutex(&oldDscp->mx); - if (code == 0) { - lock_ObtainMutex(&newDscp->mx); - cm_dnlcRemove(newDscp, newNamep); - code = cm_SyncOp(newDscp, NULL, userp, reqp, 0, - CM_SCACHESYNC_STOREDATA); - lock_ReleaseMutex(&newDscp->mx); - if (code) { - /* cleanup first one */ - cm_SyncOpDone(oldDscp, NULL, - CM_SCACHESYNC_STOREDATA); - } - } - } - else { - /* lock the new vnode entry first */ - lock_ObtainMutex(&newDscp->mx); - cm_dnlcRemove(newDscp, newNamep); - code = cm_SyncOp(newDscp, NULL, userp, reqp, 0, - CM_SCACHESYNC_STOREDATA); - lock_ReleaseMutex(&newDscp->mx); - if (code == 0) { - lock_ObtainMutex(&oldDscp->mx); - cm_dnlcRemove(oldDscp, oldNamep); - code = cm_SyncOp(oldDscp, NULL, userp, reqp, 0, - CM_SCACHESYNC_STOREDATA); - lock_ReleaseMutex(&oldDscp->mx); - if (code) { - /* cleanup first one */ - cm_SyncOpDone(newDscp, NULL, - CM_SCACHESYNC_STOREDATA); - } - } - } - } /* two distinct vnodes */ + /* lock the new vnode entry first */ + lock_ObtainMutex(&newDscp->mx); + cm_dnlcRemove(newDscp, newNamep); + code = cm_SyncOp(newDscp, NULL, userp, reqp, 0, + CM_SCACHESYNC_STOREDATA); + lock_ReleaseMutex(&newDscp->mx); + if (code == 0) { + lock_ObtainMutex(&oldDscp->mx); + cm_dnlcRemove(oldDscp, oldNamep); + code = cm_SyncOp(oldDscp, NULL, userp, reqp, 0, + CM_SCACHESYNC_STOREDATA); + lock_ReleaseMutex(&oldDscp->mx); + if (code) { + /* cleanup first one */ + cm_SyncOpDone(newDscp, NULL, + CM_SCACHESYNC_STOREDATA); + } + } + } + } /* two distinct vnodes */ - if (code) { - return code; - } - didEnd = 0; + if (code) { + return code; + } + didEnd = 0; - /* try the RPC now */ - do { - code = cm_Conn(&oldDscp->fid, userp, reqp, &connp); - if (code) continue; - - oldDirAFSFid.Volume = oldDscp->fid.volume; - oldDirAFSFid.Vnode = oldDscp->fid.vnode; - oldDirAFSFid.Unique = oldDscp->fid.unique; - newDirAFSFid.Volume = newDscp->fid.volume; - newDirAFSFid.Vnode = newDscp->fid.vnode; - newDirAFSFid.Unique = newDscp->fid.unique; - code = RXAFS_Rename(connp->callp, &oldDirAFSFid, oldNamep, - &newDirAFSFid, newNamep, - &updatedOldDirStatus, &updatedNewDirStatus, - &volSync); - } while (cm_Analyze(connp, userp, reqp, &oldDscp->fid, - &volSync, NULL, NULL, code)); - code = cm_MapRPCError(code, reqp); + /* try the RPC now */ + do { + code = cm_Conn(&oldDscp->fid, userp, reqp, &connp); + if (code) + continue; + + oldDirAFSFid.Volume = oldDscp->fid.volume; + oldDirAFSFid.Vnode = oldDscp->fid.vnode; + oldDirAFSFid.Unique = oldDscp->fid.unique; + newDirAFSFid.Volume = newDscp->fid.volume; + newDirAFSFid.Vnode = newDscp->fid.vnode; + newDirAFSFid.Unique = newDscp->fid.unique; + + callp = cm_GetRxConn(connp); + code = RXAFS_Rename(callp, &oldDirAFSFid, oldNamep, + &newDirAFSFid, newNamep, + &updatedOldDirStatus, &updatedNewDirStatus, + &volSync); + rx_PutConnection(callp); + + } while (cm_Analyze(connp, userp, reqp, &oldDscp->fid, + &volSync, NULL, NULL, code)); + code = cm_MapRPCError(code, reqp); - /* update the individual stat cache entries for the directories */ - lock_ObtainMutex(&oldDscp->mx); - cm_SyncOpDone(oldDscp, NULL, CM_SCACHESYNC_STOREDATA); - if (code == 0) { - cm_MergeStatus(oldDscp, &updatedOldDirStatus, &volSync, - userp, 0); - } - lock_ReleaseMutex(&oldDscp->mx); + /* update the individual stat cache entries for the directories */ + lock_ObtainMutex(&oldDscp->mx); + cm_SyncOpDone(oldDscp, NULL, CM_SCACHESYNC_STOREDATA); + if (code == 0) { + cm_MergeStatus(oldDscp, &updatedOldDirStatus, &volSync, + userp, 0); + } + lock_ReleaseMutex(&oldDscp->mx); - /* and update it for the new one, too, if necessary */ - if (!oneDir) { - lock_ObtainMutex(&newDscp->mx); - cm_SyncOpDone(newDscp, NULL, CM_SCACHESYNC_STOREDATA); - if (code == 0) { - cm_MergeStatus(newDscp, &updatedNewDirStatus, &volSync, - userp, 0); - } - lock_ReleaseMutex(&newDscp->mx); - } - - /* and return error code */ - return code; + /* and update it for the new one, too, if necessary */ + if (!oneDir) { + lock_ObtainMutex(&newDscp->mx); + cm_SyncOpDone(newDscp, NULL, CM_SCACHESYNC_STOREDATA); + if (code == 0) { + cm_MergeStatus(newDscp, &updatedNewDirStatus, &volSync, + userp, 0); + } + lock_ReleaseMutex(&newDscp->mx); + } + + /* and return error code */ + return code; } long cm_Lock(cm_scache_t *scp, unsigned char LockType, - LARGE_INTEGER LOffset, LARGE_INTEGER LLength, - u_long Timeout, cm_user_t *userp, cm_req_t *reqp, - void **lockpp) + LARGE_INTEGER LOffset, LARGE_INTEGER LLength, + u_long Timeout, cm_user_t *userp, cm_req_t *reqp, + void **lockpp) { - long code; - int Which = ((LockType & 0x1) ? LockRead : LockWrite); - AFSFid tfid; - AFSVolSync volSync; - cm_conn_t *connp; - cm_file_lock_t *fileLock; - osi_queue_t *q; - int found = 0; - - /* Look for a conflict. Also, if we are asking for a shared lock, - * look for another shared lock, so we don't have to do an RPC. - */ - q = scp->fileLocks; - while (q) { - fileLock = (cm_file_lock_t *) - ((char *) q - offsetof(cm_file_lock_t, fileq)); - if ((fileLock->flags & - (CM_FILELOCK_FLAG_INVALID | CM_FILELOCK_FLAG_WAITING)) - == 0) { - if ((LockType & 0x1) == 0 - || (fileLock->LockType & 0x1) == 0) - return CM_ERROR_WOULDBLOCK; - found = 1; - } - q = osi_QNext(q); - } - - if (found) - code = 0; - else { - tfid.Volume = scp->fid.volume; - tfid.Vnode = scp->fid.vnode; - tfid.Unique = scp->fid.unique; - lock_ReleaseMutex(&scp->mx); - do { - code = cm_Conn(&scp->fid, userp, reqp, &connp); - if (code) break; - code = RXAFS_SetLock(connp->callp, &tfid, Which, - &volSync); - } while (cm_Analyze(connp, userp, reqp, &scp->fid, &volSync, - NULL, NULL, code)); - lock_ObtainMutex(&scp->mx); - code = cm_MapRPCError(code, reqp); - } - - if (code == 0 || Timeout != 0) { - fileLock = malloc(sizeof(cm_file_lock_t)); - fileLock->LockType = LockType; - cm_HoldUser(userp); - fileLock->userp = userp; - fileLock->fid = scp->fid; - fileLock->LOffset = LOffset; - fileLock->LLength = LLength; - fileLock->flags = (code == 0 ? 0 : CM_FILELOCK_FLAG_WAITING); - osi_QAdd(&scp->fileLocks, &fileLock->fileq); - lock_ObtainWrite(&cm_scacheLock); - osi_QAdd(&cm_allFileLocks, &fileLock->q); - lock_ReleaseWrite(&cm_scacheLock); - if (code != 0) *lockpp = fileLock; - } - return code; + long code; + int Which = ((LockType & 0x1) ? LockRead : LockWrite); + AFSFid tfid; + AFSVolSync volSync; + cm_conn_t *connp; + cm_file_lock_t *fileLock; + osi_queue_t *q; + int found = 0; + struct rx_connection * callp; + + /* Look for a conflict. Also, if we are asking for a shared lock, + * look for another shared lock, so we don't have to do an RPC. + */ + q = scp->fileLocks; + while (q) { + fileLock = (cm_file_lock_t *) + ((char *) q - offsetof(cm_file_lock_t, fileq)); + if ((fileLock->flags & + (CM_FILELOCK_FLAG_INVALID | CM_FILELOCK_FLAG_WAITING)) + == 0) { + if ((LockType & 0x1) == 0 + || (fileLock->LockType & 0x1) == 0) + return CM_ERROR_WOULDBLOCK; + found = 1; + } + q = osi_QNext(q); + } + + if (found) + code = 0; + else { + tfid.Volume = scp->fid.volume; + tfid.Vnode = scp->fid.vnode; + tfid.Unique = scp->fid.unique; + lock_ReleaseMutex(&scp->mx); + do { + code = cm_Conn(&scp->fid, userp, reqp, &connp); + if (code) + break; + + callp = cm_GetRxConn(connp); + code = RXAFS_SetLock(callp, &tfid, Which, + &volSync); + rx_PutConnection(callp); + + } while (cm_Analyze(connp, userp, reqp, &scp->fid, &volSync, + NULL, NULL, code)); + lock_ObtainMutex(&scp->mx); + code = cm_MapRPCError(code, reqp); + } + + if (code == 0 || Timeout != 0) { + fileLock = malloc(sizeof(cm_file_lock_t)); + fileLock->LockType = LockType; + cm_HoldUser(userp); + fileLock->userp = userp; + fileLock->fid = scp->fid; + fileLock->LOffset = LOffset; + fileLock->LLength = LLength; + fileLock->flags = (code == 0 ? 0 : CM_FILELOCK_FLAG_WAITING); + osi_QAdd(&scp->fileLocks, &fileLock->fileq); + lock_ObtainWrite(&cm_scacheLock); + osi_QAdd(&cm_allFileLocks, &fileLock->q); + lock_ReleaseWrite(&cm_scacheLock); + if (code != 0) + *lockpp = fileLock; + } + return code; } long cm_Unlock(cm_scache_t *scp, unsigned char LockType, - LARGE_INTEGER LOffset, LARGE_INTEGER LLength, - cm_user_t *userp, cm_req_t *reqp) + LARGE_INTEGER LOffset, LARGE_INTEGER LLength, + cm_user_t *userp, cm_req_t *reqp) { - long code = 0; - int Which = ((LockType & 0x1) ? LockRead : LockWrite); - AFSFid tfid; - AFSVolSync volSync; - cm_conn_t *connp; - cm_file_lock_t *fileLock, *ourLock; - osi_queue_t *q, *qq; - int anotherReader = 0; - int smallLock = 0; - int found = 0; - - if (LargeIntegerLessThan(LLength, scp->length)) - smallLock = 1; - - /* Look for our own lock on the list, so as to remove it. - * Also, determine if we're the last reader; if not, avoid an RPC. - */ - q = scp->fileLocks; - while (q) { - fileLock = (cm_file_lock_t *) + long code = 0; + int Which = ((LockType & 0x1) ? LockRead : LockWrite); + AFSFid tfid; + AFSVolSync volSync; + cm_conn_t *connp; + cm_file_lock_t *fileLock, *ourLock; + osi_queue_t *q, *qq; + int anotherReader = 0; + int smallLock = 0; + int found = 0; + struct rx_connection * callp; + + if (LargeIntegerLessThan(LLength, scp->length)) + smallLock = 1; + + /* Look for our own lock on the list, so as to remove it. + * Also, determine if we're the last reader; if not, avoid an RPC. + */ + q = scp->fileLocks; + while (q) { + fileLock = (cm_file_lock_t *) ((char *) q - offsetof(cm_file_lock_t, fileq)); - if (!found - && fileLock->userp == userp - && LargeIntegerEqualTo(fileLock->LOffset, LOffset) - && LargeIntegerEqualTo(fileLock->LLength, LLength)) { - found = 1; - ourLock = fileLock; - qq = q; - } - else if (fileLock->LockType & 0x1) - anotherReader = 1; - q = osi_QNext(q); - } - - /* ignore byte ranges */ - if (smallLock && !found) - return 0; - - /* don't try to unlock other people's locks */ - if (!found) - return CM_ERROR_WOULDBLOCK; - - /* discard lock record */ - osi_QRemove(&scp->fileLocks, qq); - /* - * Don't delete it here; let the daemon delete it, to simplify - * the daemon's traversal of the list. - */ - lock_ObtainWrite(&cm_scacheLock); - ourLock->flags |= CM_FILELOCK_FLAG_INVALID; - cm_ReleaseUser(ourLock->userp); - lock_ReleaseWrite(&cm_scacheLock); - - if (!anotherReader) { - tfid.Volume = scp->fid.volume; - tfid.Vnode = scp->fid.vnode; - tfid.Unique = scp->fid.unique; - lock_ReleaseMutex(&scp->mx); - do { - code = cm_Conn(&scp->fid, userp, reqp, &connp); - if (code) + if (!found + && fileLock->userp == userp + && LargeIntegerEqualTo(fileLock->LOffset, LOffset) + && LargeIntegerEqualTo(fileLock->LLength, LLength)) { + found = 1; + ourLock = fileLock; + qq = q; + } + else if (fileLock->LockType & 0x1) + anotherReader = 1; + q = osi_QNext(q); + } + + /* ignore byte ranges */ + if (smallLock && !found) + return 0; + + /* don't try to unlock other people's locks */ + if (!found) + return CM_ERROR_WOULDBLOCK; + + /* discard lock record */ + osi_QRemove(&scp->fileLocks, qq); + /* + * Don't delete it here; let the daemon delete it, to simplify + * the daemon's traversal of the list. + */ + lock_ObtainWrite(&cm_scacheLock); + ourLock->flags |= CM_FILELOCK_FLAG_INVALID; + cm_ReleaseUser(ourLock->userp); + lock_ReleaseWrite(&cm_scacheLock); + + if (!anotherReader) { + tfid.Volume = scp->fid.volume; + tfid.Vnode = scp->fid.vnode; + tfid.Unique = scp->fid.unique; + lock_ReleaseMutex(&scp->mx); + do { + code = cm_Conn(&scp->fid, userp, reqp, &connp); + if (code) break; - code = RXAFS_ReleaseLock(connp->callp, &tfid, &volSync); - } while (cm_Analyze(connp, userp, reqp, &scp->fid, &volSync, - NULL, NULL, code)); - code = cm_MapRPCError(code, reqp); - lock_ObtainMutex(&scp->mx); - } - - return code; + + callp = cm_GetRxConn(connp); + code = RXAFS_ReleaseLock(callp, &tfid, &volSync); + rx_PutConnection(callp); + + } while (cm_Analyze(connp, userp, reqp, &scp->fid, &volSync, + NULL, NULL, code)); + code = cm_MapRPCError(code, reqp); + lock_ObtainMutex(&scp->mx); + } + + return code; } void cm_CheckLocks() { - osi_queue_t *q, *nq; - cm_file_lock_t *fileLock; - cm_req_t req; - AFSFid tfid; - AFSVolSync volSync; - cm_conn_t *connp; - long code; - - cm_InitReq(&req); - - lock_ObtainWrite(&cm_scacheLock); - q = cm_allFileLocks; - while (q) { - fileLock = (cm_file_lock_t *) q; - nq = osi_QNext(q); - if (fileLock->flags & CM_FILELOCK_FLAG_INVALID) { - osi_QRemove(&cm_allFileLocks, q); - free(fileLock); - } - else if (!(fileLock->flags & CM_FILELOCK_FLAG_WAITING)) { - tfid.Volume = fileLock->fid.volume; - tfid.Vnode = fileLock->fid.vnode; - tfid.Unique = fileLock->fid.unique; - lock_ReleaseWrite(&cm_scacheLock); - do { - code = cm_Conn(&fileLock->fid, fileLock->userp, - &req, &connp); - if (code) break; - code = RXAFS_ExtendLock(connp->callp, &tfid, - &volSync); - } while (cm_Analyze(connp, fileLock->userp, &req, - &fileLock->fid, &volSync, NULL, NULL, - code)); - code = cm_MapRPCError(code, &req); - lock_ObtainWrite(&cm_scacheLock); - } - q = nq; - } - lock_ReleaseWrite(&cm_scacheLock); -} + osi_queue_t *q, *nq; + cm_file_lock_t *fileLock; + cm_req_t req; + AFSFid tfid; + AFSVolSync volSync; + cm_conn_t *connp; + long code; + struct rx_connection * callp; + + cm_InitReq(&req); + + lock_ObtainWrite(&cm_scacheLock); + q = cm_allFileLocks; + while (q) { + fileLock = (cm_file_lock_t *) q; + nq = osi_QNext(q); + if (fileLock->flags & CM_FILELOCK_FLAG_INVALID) { + osi_QRemove(&cm_allFileLocks, q); + free(fileLock); + } + else if (!(fileLock->flags & CM_FILELOCK_FLAG_WAITING)) { + tfid.Volume = fileLock->fid.volume; + tfid.Vnode = fileLock->fid.vnode; + tfid.Unique = fileLock->fid.unique; + lock_ReleaseWrite(&cm_scacheLock); + do { + code = cm_Conn(&fileLock->fid, fileLock->userp, + &req, &connp); + if (code) + break; + + callp = cm_GetRxConn(connp); + code = RXAFS_ExtendLock(callp, &tfid, + &volSync); + rx_PutConnection(callp); + + } while (cm_Analyze(connp, fileLock->userp, &req, + &fileLock->fid, &volSync, NULL, NULL, + code)); + code = cm_MapRPCError(code, &req); + lock_ObtainWrite(&cm_scacheLock); + } + q = nq; + } + lock_ReleaseWrite(&cm_scacheLock); +} long cm_RetryLock(cm_file_lock_t *oldFileLock, int vcp_is_dead) { - long code; - int Which = ((oldFileLock->LockType & 0x1) ? LockRead : LockWrite); - cm_scache_t *scp; - AFSFid tfid; - AFSVolSync volSync; - cm_conn_t *connp; - cm_file_lock_t *fileLock; - osi_queue_t *q; - cm_req_t req; - int found = 0; - - if (vcp_is_dead) { - code = CM_ERROR_TIMEDOUT; - goto handleCode; - } - - cm_InitReq(&req); - - /* Look for a conflict. Also, if we are asking for a shared lock, - * look for another shared lock, so we don't have to do an RPC. - */ - code = cm_GetSCache(&oldFileLock->fid, &scp, oldFileLock->userp, &req); - if (code) - return code; - - q = scp->fileLocks; - while (q) { - fileLock = (cm_file_lock_t *) - ((char *) q - offsetof(cm_file_lock_t, fileq)); - if ((fileLock->flags & - (CM_FILELOCK_FLAG_INVALID | CM_FILELOCK_FLAG_WAITING)) - == 0) { - if ((oldFileLock->LockType & 0x1) == 0 - || (fileLock->LockType & 0x1) == 0) { - cm_ReleaseSCache(scp); - return CM_ERROR_WOULDBLOCK; - } - found = 1; - } - q = osi_QNext(q); - } - - if (found) - code = 0; - else { - tfid.Volume = oldFileLock->fid.volume; - tfid.Vnode = oldFileLock->fid.vnode; - tfid.Unique = oldFileLock->fid.unique; - do { - code = cm_Conn(&oldFileLock->fid, oldFileLock->userp, - &req, &connp); - if (code) break; - code = RXAFS_SetLock(connp->callp, &tfid, Which, - &volSync); - } while (cm_Analyze(connp, oldFileLock->userp, &req, - &oldFileLock->fid, &volSync, - NULL, NULL, code)); - code = cm_MapRPCError(code, &req); - } + long code; + int Which = ((oldFileLock->LockType & 0x1) ? LockRead : LockWrite); + cm_scache_t *scp; + AFSFid tfid; + AFSVolSync volSync; + cm_conn_t *connp; + cm_file_lock_t *fileLock; + osi_queue_t *q; + cm_req_t req; + int found = 0; + struct rx_connection * callp; + + if (vcp_is_dead) { + code = CM_ERROR_TIMEDOUT; + goto handleCode; + } + + cm_InitReq(&req); + + /* Look for a conflict. Also, if we are asking for a shared lock, + * look for another shared lock, so we don't have to do an RPC. + */ + code = cm_GetSCache(&oldFileLock->fid, &scp, oldFileLock->userp, &req); + if (code) + return code; + + q = scp->fileLocks; + while (q) { + fileLock = (cm_file_lock_t *) + ((char *) q - offsetof(cm_file_lock_t, fileq)); + if ((fileLock->flags & + (CM_FILELOCK_FLAG_INVALID | CM_FILELOCK_FLAG_WAITING)) + == 0) { + if ((oldFileLock->LockType & 0x1) == 0 + || (fileLock->LockType & 0x1) == 0) { + cm_ReleaseSCache(scp); + return CM_ERROR_WOULDBLOCK; + } + found = 1; + } + q = osi_QNext(q); + } + + if (found) + code = 0; + else { + tfid.Volume = oldFileLock->fid.volume; + tfid.Vnode = oldFileLock->fid.vnode; + tfid.Unique = oldFileLock->fid.unique; + do { + code = cm_Conn(&oldFileLock->fid, oldFileLock->userp, + &req, &connp); + if (code) + break; + + callp = cm_GetRxConn(connp); + code = RXAFS_SetLock(callp, &tfid, Which, + &volSync); + rx_PutConnection(callp); + + } while (cm_Analyze(connp, oldFileLock->userp, &req, + &oldFileLock->fid, &volSync, + NULL, NULL, code)); + code = cm_MapRPCError(code, &req); + } handleCode: - if (code != 0 && code != CM_ERROR_WOULDBLOCK) { - lock_ObtainMutex(&scp->mx); - osi_QRemove(&scp->fileLocks, &oldFileLock->fileq); - lock_ReleaseMutex(&scp->mx); - } - lock_ObtainWrite(&cm_scacheLock); - if (code == 0) - oldFileLock->flags = 0; - else if (code != CM_ERROR_WOULDBLOCK) { - oldFileLock->flags |= CM_FILELOCK_FLAG_INVALID; - cm_ReleaseUser(oldFileLock->userp); + if (code != 0 && code != CM_ERROR_WOULDBLOCK) { + lock_ObtainMutex(&scp->mx); + osi_QRemove(&scp->fileLocks, &oldFileLock->fileq); + lock_ReleaseMutex(&scp->mx); + } + lock_ObtainWrite(&cm_scacheLock); + if (code == 0) + oldFileLock->flags = 0; + else if (code != CM_ERROR_WOULDBLOCK) { + oldFileLock->flags |= CM_FILELOCK_FLAG_INVALID; + cm_ReleaseUser(oldFileLock->userp); oldFileLock->userp = NULL; - } - lock_ReleaseWrite(&cm_scacheLock); + } + lock_ReleaseWrite(&cm_scacheLock); - return code; + return code; } diff --git a/src/WINNT/afsd/cm_vnodeops.h b/src/WINNT/afsd/cm_vnodeops.h index ce45999f1..9f2a7a641 100644 --- a/src/WINNT/afsd/cm_vnodeops.h +++ b/src/WINNT/afsd/cm_vnodeops.h @@ -15,7 +15,7 @@ extern unsigned int cm_mountRootGen; /* parms for attribute setting call */ typedef struct cm_attr { int mask; - unsigned long clientModTime; + time_t clientModTime; osi_hyper_t length; int unixModeBits; long owner; @@ -70,6 +70,10 @@ extern long cm_NameI(cm_scache_t *rootSCachep, char *pathp, long flags, extern long cm_Lookup(cm_scache_t *dscp, char *namep, long flags, cm_user_t *userp, cm_req_t *reqp, cm_scache_t **outpScpp); +extern long cm_LookupInternal(cm_scache_t *dscp, char *namep, long flags, + cm_user_t *userp, cm_req_t *reqp, + cm_scache_t **outpScpp); + extern void cm_TryBulkStat(cm_scache_t *dscp, osi_hyper_t *offsetp, cm_user_t *userp, cm_req_t *reqp); @@ -104,10 +108,14 @@ extern long cm_Rename(cm_scache_t *oldDscp, char *oldLastNamep, extern long cm_HandleLink(cm_scache_t *linkScp, struct cm_user *userp, cm_req_t *reqp); +extern long cm_Link(cm_scache_t *dscp, char *namep, cm_scache_t *sscp, + long flags, cm_user_t *userp, cm_req_t *reqp); + extern long cm_SymLink(cm_scache_t *dscp, char *namep, char *contentsp, long flags, cm_attr_t *attrp, cm_user_t *userp, cm_req_t *reqp); -extern int cm_ExpandSysName(char *inp, char *outp, long outSize); +extern int cm_ExpandSysName(char *inp, char *outp, long outSize, + unsigned int sysNameIndex); extern long cm_Open(cm_scache_t *scp, int type, cm_user_t *userp); diff --git a/src/WINNT/afsd/cm_volume.h b/src/WINNT/afsd/cm_volume.h index 89547d7f9..0d017003f 100644 --- a/src/WINNT/afsd/cm_volume.h +++ b/src/WINNT/afsd/cm_volume.h @@ -20,7 +20,7 @@ typedef struct cm_volume { struct cm_fid *dotdotFidp; /* parent of volume root */ osi_mutex_t mx; long flags; /* by mx */ - int refCount; /* by cm_volumeLock */ + unsigned long refCount; /* by cm_volumeLock */ cm_serverRef_t *rwServersp; /* by mx */ cm_serverRef_t *roServersp; /* by mx */ cm_serverRef_t *bkServersp; /* by mx */ diff --git a/src/WINNT/afsd/ctokens.c b/src/WINNT/afsd/ctokens.c index 9b357d9ae..5d74150fd 100644 --- a/src/WINNT/afsd/ctokens.c +++ b/src/WINNT/afsd/ctokens.c @@ -88,7 +88,8 @@ main(argc, argv) if (tokenExpireTime <= current_time) printf("[>> Expired <<]\n"); else { - expireString = ctime(&tokenExpireTime); + time_t t = tokenExpireTime; + expireString = ctime(&t); expireString += 4; /* Skip day of week */ expireString[12] = '\0'; /* Omit secs & year */ printf("[Expires %s]\n", expireString); diff --git a/src/WINNT/afsd/fs.c b/src/WINNT/afsd/fs.c index 5e960c56a..1f3630eec 100644 --- a/src/WINNT/afsd/fs.c +++ b/src/WINNT/afsd/fs.c @@ -609,8 +609,6 @@ BOOL IsAdmin (void) return FALSE; } - fTested = TRUE; - dwSize = 0; dwSize2 = 0; @@ -645,39 +643,76 @@ BOOL IsAdmin (void) if (OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &hToken)) { - /* We'll have to allocate a chunk of memory to store the list of - * groups to which this user belongs; find out how much memory - * we'll need. - */ - DWORD dwSize = 0; - PTOKEN_GROUPS pGroups; - - GetTokenInformation (hToken, TokenGroups, NULL, dwSize, &dwSize); - - pGroups = (PTOKEN_GROUPS)malloc(dwSize); - - /* Allocate that buffer, and read in the list of groups. */ - if (GetTokenInformation (hToken, TokenGroups, pGroups, dwSize, &dwSize)) - { - /* Look through the list of group SIDs and see if any of them - * matches the AFS Client Admin group SID. + + if (!CheckTokenMembership(hToken, psidAdmin, &fAdmin)) { + /* We'll have to allocate a chunk of memory to store the list of + * groups to which this user belongs; find out how much memory + * we'll need. */ - size_t iGroup = 0; - for (; (!fAdmin) && (iGroup < pGroups->GroupCount); ++iGroup) + DWORD dwSize = 0; + PTOKEN_GROUPS pGroups; + + GetTokenInformation (hToken, TokenGroups, NULL, dwSize, &dwSize); + + pGroups = (PTOKEN_GROUPS)malloc(dwSize); + + /* Allocate that buffer, and read in the list of groups. */ + if (GetTokenInformation (hToken, TokenGroups, pGroups, dwSize, &dwSize)) { - if (EqualSid (psidAdmin, pGroups->Groups[ iGroup ].Sid)) { - fAdmin = TRUE; + /* Look through the list of group SIDs and see if any of them + * matches the AFS Client Admin group SID. + */ + size_t iGroup = 0; + for (; (!fAdmin) && (iGroup < pGroups->GroupCount); ++iGroup) + { + if (EqualSid (psidAdmin, pGroups->Groups[ iGroup ].Sid)) { + fAdmin = TRUE; + } } } + + if (pGroups) + free(pGroups); } - if (pGroups) - free(pGroups); + /* if do not have permission because we were not explicitly listed + * in the Admin Client Group let's see if we are the SYSTEM account + */ + if (!fAdmin) { + PTOKEN_USER pTokenUser; + SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY; + PSID pSidLocalSystem = 0; + DWORD gle; + + GetTokenInformation(hToken, TokenUser, NULL, 0, &dwSize); + + pTokenUser = (PTOKEN_USER)malloc(dwSize); + + if (!GetTokenInformation(hToken, TokenUser, pTokenUser, dwSize, &dwSize)) + gle = GetLastError(); + + if (AllocateAndInitializeSid( &SIDAuth, 1, + SECURITY_LOCAL_SYSTEM_RID, + 0, 0, 0, 0, 0, 0, 0, + &pSidLocalSystem)) + { + if (EqualSid(pTokenUser->User.Sid, pSidLocalSystem)) { + fAdmin = TRUE; + } + + FreeSid(pSidLocalSystem); + } + + if ( pTokenUser ) + free(pTokenUser); + } } } free(psidAdmin); free(pszRefDomain); + + fTested = TRUE; } return fAdmin; @@ -2181,19 +2216,19 @@ register struct cmd_syndesc *as; { return 0; } - input = space; - memcpy(&setp, input, sizeof(afs_int32)); - input += sizeof(afs_int32); - if (!setp) { - fprintf(stderr,"No sysname name value was found\n"); + input = space; + memcpy(&setp, input, sizeof(afs_int32)); + input += sizeof(afs_int32); + if (!setp) { + fprintf(stderr,"No sysname name value was found\n"); return 1; - } + } printf("Current sysname%s", setp > 1 ? "s are" : " is"); for (; setp > 0; --setp ) { printf(" \'%s\'", input); input += strlen(input) + 1; - } + } printf("\n"); return 0; } @@ -2447,7 +2482,7 @@ struct afsconf_cell *info; } else { /* got a ticket */ - if (ttoken.kvno >= 0 && ttoken.kvno <= 255) scIndex = 2; /* kerberos */ + if (ttoken.kvno >= 0 && ttoken.kvno <= 256) scIndex = 2; /* kerberos */ else { fprintf (stderr, "fs: funny kvno (%d) in ticket, proceeding\n", ttoken.kvno); @@ -2943,7 +2978,7 @@ int argc; char **argv; { register afs_int32 code; register struct cmd_syndesc *ts; - + #ifdef AFS_AIX32_ENV /* * The following signal action for AIX is necessary so that in case of a @@ -3141,7 +3176,7 @@ char **argv; { cmd_AddParm(ts, "-path", CMD_LIST, CMD_OPTIONAL, "dir/file path"); ts = cmd_CreateSyntax("sysname", SysNameCmd, 0, "get/set sysname (i.e. @sys) value"); - cmd_AddParm(ts, "-newsys", CMD_SINGLE, CMD_OPTIONAL, "new sysname"); + cmd_AddParm(ts, "-newsys", CMD_LIST, CMD_OPTIONAL, "new sysname"); ts = cmd_CreateSyntax("exportafs", ExportAfsCmd, 0, "enable/disable translators to AFS"); cmd_AddParm(ts, "-type", CMD_SINGLE, 0, "exporter name"); diff --git a/src/WINNT/afsd/lanahelper.cpp b/src/WINNT/afsd/lanahelper.cpp index d704adac6..5cdc27bd5 100644 --- a/src/WINNT/afsd/lanahelper.cpp +++ b/src/WINNT/afsd/lanahelper.cpp @@ -394,6 +394,35 @@ extern "C" lana_number_t lana_FindLoopback(void) return LANA_INVALID; } +/* Returns TRUE if all adapters are loopback adapters */ +extern "C" BOOL lana_OnlyLoopback(void) +{ + NCB ncb; + LANA_ENUM lana_list; + int status; + int i; + + memset(&ncb, 0, sizeof(ncb)); + ncb.ncb_command = NCBENUM; + ncb.ncb_buffer = (UCHAR *) &lana_list; + ncb.ncb_length = sizeof(lana_list); + status = Netbios(&ncb); + if (status != 0) { +#ifndef NOLOGGING + afsi_log("Netbios NCBENUM failed: status %ld", status); +#endif + return FALSE; + } + for (i = 0; i < lana_list.length; i++) { + if (!lana_IsLoopback(lana_list.lana[i])) { + // Found one non-Loopback adapter + return FALSE; + } + } + // All adapters are loopback + return TRUE; +} + // Is the given lana a Windows Loopback Adapter? // TODO: implement a better check for loopback // TODO: also check for proper bindings (IPv4) diff --git a/src/WINNT/afsd/lanahelper.h b/src/WINNT/afsd/lanahelper.h index d6ba0ed85..22e88e311 100644 --- a/src/WINNT/afsd/lanahelper.h +++ b/src/WINNT/afsd/lanahelper.h @@ -59,6 +59,8 @@ extern "C" { lana_number_t lana_FindLoopback(void); + BOOL lana_OnlyLoopback(void); + BOOL lana_IsLoopback(lana_number_t lana); long lana_GetUncServerNameEx(char *buffer, lana_number_t * pLana, int * pIsGateway, int flags); diff --git a/src/WINNT/afsd/smb.c b/src/WINNT/afsd/smb.c index 7d0f37d2c..fb3e1aefd 100644 --- a/src/WINNT/afsd/smb.c +++ b/src/WINNT/afsd/smb.c @@ -7,7 +7,8 @@ * directory or online at http://www.openafs.org/dl/license10.html */ -//#define NOSERVICE 1 +//#define NOTSERVICE 1 +#define LOG_PACKET 1 #include #include @@ -189,6 +190,9 @@ extern char cm_confDir[]; *(sizep) = strlen(cm_HostName) #endif /* DJGPP */ +#ifdef LOG_PACKET +void smb_LogPacket(smb_packet_t *packet); +#endif /* LOG_PACKET */ extern char AFSConfigKeyName[]; char smb_ServerDomainName[MAX_COMPUTERNAME_LENGTH + 1] = ""; /* domain name */ @@ -201,356 +205,365 @@ int smb_ServerLanManagerLength = sizeof(smb_ServerLanManager); /* Faux server GUID. This is never checked. */ GUID smb_ServerGUID = { 0x40015cb8, 0x058a, 0x44fc, { 0xae, 0x7e, 0xbb, 0x29, 0x52, 0xee, 0x7e, 0xff }}; -/* - * Demo expiration - * - * To build an expiring version, comment out the definition of NOEXPIRE, - * and set the definition of EXPIREDATE to the desired value. - */ -#define NOEXPIRE 1 -#define EXPIREDATE 834000000 /* Wed Jun 5 1996 */ - - char * myCrt_Dispatch(int i) { - switch (i) - { - default: - return "unknown SMB op"; - case 0x00: - return "(00)ReceiveCoreMakeDir"; - case 0x01: - return "(01)ReceiveCoreRemoveDir"; - case 0x02: - return "(02)ReceiveCoreOpen"; - case 0x03: - return "(03)ReceiveCoreCreate"; - case 0x04: - return "(04)ReceiveCoreClose"; - case 0x05: - return "(05)ReceiveCoreFlush"; - case 0x06: - return "(06)ReceiveCoreUnlink"; - case 0x07: - return "(07)ReceiveCoreRename"; - case 0x08: - return "(08)ReceiveCoreGetFileAttributes"; - case 0x09: - return "(09)ReceiveCoreSetFileAttributes"; - case 0x0a: - return "(0a)ReceiveCoreRead"; - case 0x0b: - return "(0b)ReceiveCoreWrite"; - case 0x0c: - return "(0c)ReceiveCoreLockRecord"; - case 0x0d: - return "(0d)ReceiveCoreUnlockRecord"; - case 0x0e: - return "(0e)SendCoreBadOp"; - case 0x0f: - return "(0f)ReceiveCoreCreate"; - case 0x10: - return "(10)ReceiveCoreCheckPath"; - case 0x11: - return "(11)SendCoreBadOp"; - case 0x12: - return "(12)ReceiveCoreSeek"; - case 0x1a: - return "(1a)ReceiveCoreReadRaw"; - case 0x1d: - return "(1d)ReceiveCoreWriteRawDummy"; - case 0x22: - return "(22)ReceiveV3SetAttributes"; - case 0x23: - return "(23)ReceiveV3GetAttributes"; - case 0x24: - return "(24)ReceiveV3LockingX"; - case 0x25: - return "(25)ReceiveV3Trans"; - case 0x26: - return "(26)ReceiveV3Trans[aux]"; - case 0x29: - return "(29)SendCoreBadOp"; - case 0x2b: - return "(2b)ReceiveCoreEcho"; - case 0x2d: - return "(2d)ReceiveV3OpenX"; - case 0x2e: - return "(2e)ReceiveV3ReadX"; - case 0x32: - return "(32)ReceiveV3Tran2A"; - case 0x33: - return "(33)ReceiveV3Tran2A[aux]"; - case 0x34: - return "(34)ReceiveV3FindClose"; - case 0x35: - return "(35)ReceiveV3FindNotifyClose"; - case 0x70: - return "(70)ReceiveCoreTreeConnect"; - case 0x71: - return "(71)ReceiveCoreTreeDisconnect"; - case 0x72: - return "(72)ReceiveNegotiate"; - case 0x73: - return "(73)ReceiveV3SessionSetupX"; - case 0x74: - return "(74)ReceiveV3UserLogoffX"; - case 0x75: - return "(75)ReceiveV3TreeConnectX"; - case 0x80: - return "(80)ReceiveCoreGetDiskAttributes"; - case 0x81: - return "(81)ReceiveCoreSearchDir"; - case 0xA0: - return "(A0)ReceiveNTTransact"; - case 0xA2: - return "(A2)ReceiveNTCreateX"; - case 0xA4: - return "(A4)ReceiveNTCancel"; - case 0xc0: - return "(c0)SendCoreBadOp"; - case 0xc1: - return "(c1)SendCoreBadOp"; - case 0xc2: - return "(c2)SendCoreBadOp"; - case 0xc3: - return "(c3)SendCoreBadOp"; - } -} + switch (i) + { + case 0x00: + return "(00)ReceiveCoreMakeDir"; + case 0x01: + return "(01)ReceiveCoreRemoveDir"; + case 0x02: + return "(02)ReceiveCoreOpen"; + case 0x03: + return "(03)ReceiveCoreCreate"; + case 0x04: + return "(04)ReceiveCoreClose"; + case 0x05: + return "(05)ReceiveCoreFlush"; + case 0x06: + return "(06)ReceiveCoreUnlink"; + case 0x07: + return "(07)ReceiveCoreRename"; + case 0x08: + return "(08)ReceiveCoreGetFileAttributes"; + case 0x09: + return "(09)ReceiveCoreSetFileAttributes"; + case 0x0a: + return "(0a)ReceiveCoreRead"; + case 0x0b: + return "(0b)ReceiveCoreWrite"; + case 0x0c: + return "(0c)ReceiveCoreLockRecord"; + case 0x0d: + return "(0d)ReceiveCoreUnlockRecord"; + case 0x0e: + return "(0e)SendCoreBadOp"; + case 0x0f: + return "(0f)ReceiveCoreCreate"; + case 0x10: + return "(10)ReceiveCoreCheckPath"; + case 0x11: + return "(11)SendCoreBadOp"; + case 0x12: + return "(12)ReceiveCoreSeek"; + case 0x1a: + return "(1a)ReceiveCoreReadRaw"; + case 0x1d: + return "(1d)ReceiveCoreWriteRawDummy"; + case 0x22: + return "(22)ReceiveV3SetAttributes"; + case 0x23: + return "(23)ReceiveV3GetAttributes"; + case 0x24: + return "(24)ReceiveV3LockingX"; + case 0x25: + return "(25)ReceiveV3Trans"; + case 0x26: + return "(26)ReceiveV3Trans[aux]"; + case 0x29: + return "(29)SendCoreBadOp"; + case 0x2b: + return "(2b)ReceiveCoreEcho"; + case 0x2d: + return "(2d)ReceiveV3OpenX"; + case 0x2e: + return "(2e)ReceiveV3ReadX"; + case 0x32: + return "(32)ReceiveV3Tran2A"; + case 0x33: + return "(33)ReceiveV3Tran2A[aux]"; + case 0x34: + return "(34)ReceiveV3FindClose"; + case 0x35: + return "(35)ReceiveV3FindNotifyClose"; + case 0x70: + return "(70)ReceiveCoreTreeConnect"; + case 0x71: + return "(71)ReceiveCoreTreeDisconnect"; + case 0x72: + return "(72)ReceiveNegotiate"; + case 0x73: + return "(73)ReceiveV3SessionSetupX"; + case 0x74: + return "(74)ReceiveV3UserLogoffX"; + case 0x75: + return "(75)ReceiveV3TreeConnectX"; + case 0x80: + return "(80)ReceiveCoreGetDiskAttributes"; + case 0x81: + return "(81)ReceiveCoreSearchDir"; + case 0x82: + return "(82)Find"; + case 0x83: + return "(83)FindUnique"; + case 0x84: + return "(84)FindClose"; + case 0xA0: + return "(A0)ReceiveNTTransact"; + case 0xA2: + return "(A2)ReceiveNTCreateX"; + case 0xA4: + return "(A4)ReceiveNTCancel"; + case 0xA5: + return "(A5)ReceiveNTRename"; + case 0xc0: + return "(C0)OpenPrintFile"; + case 0xc1: + return "(C1)WritePrintFile"; + case 0xc2: + return "(C2)ClosePrintFile"; + case 0xc3: + return "(C3)GetPrintQueue"; + case 0xd8: + return "(D8)ReadBulk"; + case 0xd9: + return "(D9)WriteBulk"; + case 0xda: + return "(DA)WriteBulkData"; + default: + return "unknown SMB op"; + } +} char * myCrt_2Dispatch(int i) { - switch (i) - { - default: - return "unknown SMB op-2"; - case 0: - return "S(00)CreateFile"; - case 1: - return "S(01)FindFirst"; - case 2: - return "S(02)FindNext"; /* FindNext */ - case 3: - return "S(03)QueryFileSystem_ReceiveTran2QFSInfo"; - case 4: - return "S(04)??"; - case 5: - return "S(05)QueryFileInfo_ReceiveTran2QPathInfo"; - case 6: - return "S(06)SetFileInfo_ReceiveTran2SetPathInfo"; - case 7: - return "S(07)SetInfoHandle_ReceiveTran2QFileInfo"; - case 8: - return "S(08)??_ReceiveTran2SetFileInfo"; - case 9: - return "S(09)??_ReceiveTran2FSCTL"; - case 10: - return "S(0a)_ReceiveTran2IOCTL"; - case 11: - return "S(0b)_ReceiveTran2FindNotifyFirst"; - case 12: - return "S(0c)_ReceiveTran2FindNotifyNext"; - case 13: - return "S(0d)CreateDirectory_ReceiveTran2MKDir"; - } -} + switch (i) + { + default: + return "unknown SMB op-2"; + case 0: + return "S(00)CreateFile"; + case 1: + return "S(01)FindFirst"; + case 2: + return "S(02)FindNext"; /* FindNext */ + case 3: + return "S(03)QueryFileSystem_ReceiveTran2QFSInfo"; + case 4: + return "S(04)??"; + case 5: + return "S(05)QueryFileInfo_ReceiveTran2QPathInfo"; + case 6: + return "S(06)SetFileInfo_ReceiveTran2SetPathInfo"; + case 7: + return "S(07)SetInfoHandle_ReceiveTran2QFileInfo"; + case 8: + return "S(08)??_ReceiveTran2SetFileInfo"; + case 9: + return "S(09)??_ReceiveTran2FSCTL"; + case 10: + return "S(0a)_ReceiveTran2IOCTL"; + case 11: + return "S(0b)_ReceiveTran2FindNotifyFirst"; + case 12: + return "S(0c)_ReceiveTran2FindNotifyNext"; + case 13: + return "S(0d)_ReceiveTran2CreateDirectory"; + case 14: + return "S(0e)_ReceiveTran2SessionSetup"; + } +} char * myCrt_RapDispatch(int i) { - switch(i) - { - default: - return "unknown RAP OP"; - case 0: - return "RAP(0)NetShareEnum"; - case 1: - return "RAP(1)NetShareGetInfo"; - case 13: - return "RAP(13)NetServerGetInfo"; - case 63: - return "RAP(63)NetWkStaGetInfo"; - } -} + switch(i) + { + default: + return "unknown RAP OP"; + case 0: + return "RAP(0)NetShareEnum"; + case 1: + return "RAP(1)NetShareGetInfo"; + case 13: + return "RAP(13)NetServerGetInfo"; + case 63: + return "RAP(63)NetWkStaGetInfo"; + } +} /* scache must be locked */ unsigned int smb_Attributes(cm_scache_t *scp) { - unsigned int attrs; - - if (scp->fileType == CM_SCACHETYPE_DIRECTORY - || scp->fileType == CM_SCACHETYPE_MOUNTPOINT) - attrs = SMB_ATTR_DIRECTORY; - else - attrs = 0; - - /* - * We used to mark a file RO if it was in an RO volume, but that - * turns out to be impolitic in NT. See defect 10007. - */ + unsigned int attrs; + + if (scp->fileType == CM_SCACHETYPE_DIRECTORY + || scp->fileType == CM_SCACHETYPE_MOUNTPOINT) + attrs = SMB_ATTR_DIRECTORY; + else + attrs = 0; + + /* + * We used to mark a file RO if it was in an RO volume, but that + * turns out to be impolitic in NT. See defect 10007. + */ #ifdef notdef - if ((scp->unixModeBits & 0222) == 0 || (scp->flags & CM_SCACHEFLAG_RO)) + if ((scp->unixModeBits & 0222) == 0 || (scp->flags & CM_SCACHEFLAG_RO)) #endif if ((scp->unixModeBits & 0222) == 0) - attrs |= SMB_ATTR_READONLY; /* turn on read-only flag */ + attrs |= SMB_ATTR_READONLY; /* turn on read-only flag */ - return attrs; + return attrs; } /* Check if the named file/dir is a dotfile/dotdir */ /* String pointed to by lastComp can have leading slashes, but otherwise should have no other patch components */ unsigned int smb_IsDotFile(char *lastComp) { - char *s; - if(lastComp) { - /* skip over slashes */ + char *s; + if(lastComp) { + /* skip over slashes */ for(s=lastComp;*s && (*s == '\\' || *s == '/'); s++); - } - else - return 0; + } + else + return 0; /* nulls, curdir and parent dir doesn't count */ - if(!*s) return 0; - if(*s == '.') { - if(!*(s + 1)) return 0; - if(*(s+1) == '.' && !*(s + 2)) return 0; - return 1; - } - return 0; + if (!*s) + return 0; + if (*s == '.') { + if (!*(s + 1)) + return 0; + if(*(s+1) == '.' && !*(s + 2)) + return 0; + return 1; + } + return 0; } static int ExtractBits(WORD bits, short start, short len) { - int end; - WORD num; + int end; + WORD num; - end = start + len; + end = start + len; - num = bits << (16 - end); - num = num >> ((16 - end) + start); + num = bits << (16 - end); + num = num >> ((16 - end) + start); - return (int)num; + return (int)num; } #ifndef DJGPP void ShowUnixTime(char *FuncName, time_t unixTime) { - FILETIME ft; - WORD wDate, wTime; + FILETIME ft; + WORD wDate, wTime; - smb_LargeSearchTimeFromUnixTime(&ft, unixTime); - - if (!FileTimeToDosDateTime(&ft, &wDate, &wTime)) - osi_Log1(smb_logp, "Failed to convert filetime to dos datetime: %d", GetLastError()); - else { - int day, month, year, sec, min, hour; - char msg[256]; - - day = ExtractBits(wDate, 0, 5); - month = ExtractBits(wDate, 5, 4); - year = ExtractBits(wDate, 9, 7) + 1980; - - sec = ExtractBits(wTime, 0, 5); - min = ExtractBits(wTime, 5, 6); - hour = ExtractBits(wTime, 11, 5); - - sprintf(msg, "%s = %02d-%02d-%04d %02d:%02d:%02d", FuncName, month, day, year, hour, min, sec); - osi_Log1(smb_logp, "%s", osi_LogSaveString(smb_logp, msg)); - } -} + smb_LargeSearchTimeFromUnixTime(&ft, unixTime); + + if (!FileTimeToDosDateTime(&ft, &wDate, &wTime)) + osi_Log1(smb_logp, "Failed to convert filetime to dos datetime: %d", GetLastError()); + else { + int day, month, year, sec, min, hour; + char msg[256]; + + day = ExtractBits(wDate, 0, 5); + month = ExtractBits(wDate, 5, 4); + year = ExtractBits(wDate, 9, 7) + 1980; + + sec = ExtractBits(wTime, 0, 5); + min = ExtractBits(wTime, 5, 6); + hour = ExtractBits(wTime, 11, 5); + + sprintf(msg, "%s = %02d-%02d-%04d %02d:%02d:%02d", FuncName, month, day, year, hour, min, sec); + osi_Log1(smb_logp, "%s", osi_LogSaveString(smb_logp, msg)); + } +} #endif /* DJGPP */ #ifndef DJGPP /* Determine if we are observing daylight savings time */ void GetTimeZoneInfo(BOOL *pDST, LONG *pDstBias, LONG *pBias) { - TIME_ZONE_INFORMATION timeZoneInformation; - SYSTEMTIME utc, local, localDST; + TIME_ZONE_INFORMATION timeZoneInformation; + SYSTEMTIME utc, local, localDST; - /* Get the time zone info. NT uses this to calc if we are in DST. */ - GetTimeZoneInformation(&timeZoneInformation); - - /* Return the daylight bias */ - *pDstBias = timeZoneInformation.DaylightBias; - - /* Return the bias */ - *pBias = timeZoneInformation.Bias; - - /* Now determine if DST is being observed */ - - /* Get the UTC (GMT) time */ - GetSystemTime(&utc); - - /* Convert UTC time to local time using the time zone info. If we are - observing DST, the calculated local time will include this. - */ - SystemTimeToTzSpecificLocalTime(&timeZoneInformation, &utc, &localDST); - - /* Set the daylight bias to 0. The daylight bias is the amount of change - in time that we use for daylight savings time. By setting this to 0 - we cause there to be no change in time during daylight savings time. - */ - timeZoneInformation.DaylightBias = 0; - - /* Convert the utc time to local time again, but this time without any - adjustment for daylight savings time. - */ - SystemTimeToTzSpecificLocalTime(&timeZoneInformation, &utc, &local); - - /* If the two times are different, then it means that the localDST that - we calculated includes the daylight bias, and therefore we are - observing daylight savings time. - */ - *pDST = localDST.wHour != local.wHour; -} + /* Get the time zone info. NT uses this to calc if we are in DST. */ + GetTimeZoneInformation(&timeZoneInformation); + + /* Return the daylight bias */ + *pDstBias = timeZoneInformation.DaylightBias; + + /* Return the bias */ + *pBias = timeZoneInformation.Bias; + + /* Now determine if DST is being observed */ + + /* Get the UTC (GMT) time */ + GetSystemTime(&utc); + + /* Convert UTC time to local time using the time zone info. If we are + observing DST, the calculated local time will include this. + */ + SystemTimeToTzSpecificLocalTime(&timeZoneInformation, &utc, &localDST); + + /* Set the daylight bias to 0. The daylight bias is the amount of change + * in time that we use for daylight savings time. By setting this to 0 + * we cause there to be no change in time during daylight savings time. + */ + timeZoneInformation.DaylightBias = 0; + + /* Convert the utc time to local time again, but this time without any + adjustment for daylight savings time. + */ + SystemTimeToTzSpecificLocalTime(&timeZoneInformation, &utc, &local); + + /* If the two times are different, then it means that the localDST that + we calculated includes the daylight bias, and therefore we are + observing daylight savings time. + */ + *pDST = localDST.wHour != local.wHour; +} #else /* Determine if we are observing daylight savings time */ void GetTimeZoneInfo(BOOL *pDST, LONG *pDstBias, LONG *pBias) { - struct timeb t; + struct timeb t; - ftime(&t); - *pDST = t.dstflag; - *pDstBias = -60; /* where can this be different? */ - *pBias = t.timezone; -} + ftime(&t); + *pDST = t.dstflag; + *pDstBias = -60; /* where can this be different? */ + *pBias = t.timezone; +} #endif /* DJGPP */ void CompensateForSmbClientLastWriteTimeBugs(long *pLastWriteTime) { - BOOL dst; /* Will be TRUE if observing DST */ - LONG dstBias; /* Offset from local time if observing DST */ - LONG bias; /* Offset from GMT for local time */ - - /* - * This function will adjust the last write time to compensate - * for two bugs in the smb client: - * - * 1) During Daylight Savings Time, the LastWriteTime is ahead - * in time by the DaylightBias (ignoring the sign - the - * DaylightBias is always stored as a negative number). If - * the DaylightBias is -60, then the LastWriteTime will be - * ahead by 60 minutes. - * - * 2) If the local time zone is a positive offset from GMT, then - * the LastWriteTime will be the correct local time plus the - * Bias (ignoring the sign - a positive offset from GMT is - * always stored as a negative Bias). If the Bias is -120, - * then the LastWriteTime will be ahead by 120 minutes. - * - * These bugs can occur at the same time. - */ - - GetTimeZoneInfo(&dst, &dstBias, &bias); - - /* First adjust for DST */ - if (dst) - *pLastWriteTime -= (-dstBias * 60); /* Convert dstBias to seconds */ - - /* Now adjust for a positive offset from GMT (a negative bias). */ - if (bias < 0) - *pLastWriteTime -= (-bias * 60); /* Convert bias to seconds */ -} + BOOL dst; /* Will be TRUE if observing DST */ + LONG dstBias; /* Offset from local time if observing DST */ + LONG bias; /* Offset from GMT for local time */ + + /* + * This function will adjust the last write time to compensate + * for two bugs in the smb client: + * + * 1) During Daylight Savings Time, the LastWriteTime is ahead + * in time by the DaylightBias (ignoring the sign - the + * DaylightBias is always stored as a negative number). If + * the DaylightBias is -60, then the LastWriteTime will be + * ahead by 60 minutes. + * + * 2) If the local time zone is a positive offset from GMT, then + * the LastWriteTime will be the correct local time plus the + * Bias (ignoring the sign - a positive offset from GMT is + * always stored as a negative Bias). If the Bias is -120, + * then the LastWriteTime will be ahead by 120 minutes. + * + * These bugs can occur at the same time. + */ + + GetTimeZoneInfo(&dst, &dstBias, &bias); + + /* First adjust for DST */ + if (dst) + *pLastWriteTime -= (-dstBias * 60); /* Convert dstBias to seconds */ + + /* Now adjust for a positive offset from GMT (a negative bias). */ + if (bias < 0) + *pLastWriteTime -= (-bias * 60); /* Convert bias to seconds */ +} /* * Calculate the difference (in seconds) between local time and GMT. @@ -559,134 +572,134 @@ void CompensateForSmbClientLastWriteTimeBugs(long *pLastWriteTime) static void smb_CalculateNowTZ() { - time_t t; - struct tm gmt_tm, local_tm; - int days, hours, minutes, seconds; + time_t t; + struct tm gmt_tm, local_tm; + int days, hours, minutes, seconds; - t = time(NULL); - gmt_tm = *(gmtime(&t)); - local_tm = *(localtime(&t)); + t = time(NULL); + gmt_tm = *(gmtime(&t)); + local_tm = *(localtime(&t)); - days = local_tm.tm_yday - gmt_tm.tm_yday; - hours = 24 * days + local_tm.tm_hour - gmt_tm.tm_hour + days = local_tm.tm_yday - gmt_tm.tm_yday; + hours = 24 * days + local_tm.tm_hour - gmt_tm.tm_hour #ifdef COMMENT /* There is a problem with DST immediately after the time change - * which may continue to exist until the machine is rebooted + * which may continue to exist until the machine is rebooted */ - (local_tm.tm_isdst ? 1 : 0) #endif /* COMMENT */ - ; - minutes = 60 * hours + local_tm.tm_min - gmt_tm.tm_min; - seconds = 60 * minutes + local_tm.tm_sec - gmt_tm.tm_sec; + ; + minutes = 60 * hours + local_tm.tm_min - gmt_tm.tm_min; + seconds = 60 * minutes + local_tm.tm_sec - gmt_tm.tm_sec; - smb_NowTZ = seconds; + smb_NowTZ = seconds; } #ifndef DJGPP void smb_LargeSearchTimeFromUnixTime(FILETIME *largeTimep, time_t unixTime) { - struct tm *ltp; - SYSTEMTIME stm; - struct tm localJunk; - time_t ersatz_unixTime; - - /* - * Must use kludge-GMT instead of real GMT. - * kludge-GMT is computed by adding time zone difference to localtime. - * - * real GMT would be: - * ltp = gmtime(&unixTime); - */ - ersatz_unixTime = unixTime - smb_NowTZ; - ltp = localtime(&ersatz_unixTime); - - /* if we fail, make up something */ - if (!ltp) { - ltp = &localJunk; - localJunk.tm_year = 89 - 20; - localJunk.tm_mon = 4; - localJunk.tm_mday = 12; - localJunk.tm_hour = 0; - localJunk.tm_min = 0; - localJunk.tm_sec = 0; - } - - stm.wYear = ltp->tm_year + 1900; - stm.wMonth = ltp->tm_mon + 1; - stm.wDayOfWeek = ltp->tm_wday; - stm.wDay = ltp->tm_mday; - stm.wHour = ltp->tm_hour; - stm.wMinute = ltp->tm_min; - stm.wSecond = ltp->tm_sec; - stm.wMilliseconds = 0; - - SystemTimeToFileTime(&stm, largeTimep); + struct tm *ltp; + SYSTEMTIME stm; + struct tm localJunk; + time_t ersatz_unixTime; + + /* + * Must use kludge-GMT instead of real GMT. + * kludge-GMT is computed by adding time zone difference to localtime. + * + * real GMT would be: + * ltp = gmtime(&unixTime); + */ + ersatz_unixTime = unixTime - smb_NowTZ; + ltp = localtime(&ersatz_unixTime); + + /* if we fail, make up something */ + if (!ltp) { + ltp = &localJunk; + localJunk.tm_year = 89 - 20; + localJunk.tm_mon = 4; + localJunk.tm_mday = 12; + localJunk.tm_hour = 0; + localJunk.tm_min = 0; + localJunk.tm_sec = 0; + } + + stm.wYear = ltp->tm_year + 1900; + stm.wMonth = ltp->tm_mon + 1; + stm.wDayOfWeek = ltp->tm_wday; + stm.wDay = ltp->tm_mday; + stm.wHour = ltp->tm_hour; + stm.wMinute = ltp->tm_min; + stm.wSecond = ltp->tm_sec; + stm.wMilliseconds = 0; + + SystemTimeToFileTime(&stm, largeTimep); } #else /* DJGPP */ void smb_LargeSearchTimeFromUnixTime(FILETIME *largeTimep, time_t unixTime) { - /* unixTime: seconds since 1/1/1970 00:00:00 GMT */ - /* FILETIME: 100ns intervals since 1/1/1601 00:00:00 ??? */ - LARGE_INTEGER *ft = (LARGE_INTEGER *) largeTimep; - LARGE_INTEGER ut; - int leap_years = 89; /* leap years betw 1/1/1601 and 1/1/1970 */ - - /* set ft to number of 100ns intervals betw 1/1/1601 and 1/1/1970 GMT */ - *ft = ConvertLongToLargeInteger(((EPOCH_YEAR-1601) * 365 + leap_years) - * 24 * 60); - *ft = LargeIntegerMultiplyByLong(*ft, 60); - *ft = LargeIntegerMultiplyByLong(*ft, 10000000); - - /* add unix time */ - ut = ConvertLongToLargeInteger(unixTime); - ut = LargeIntegerMultiplyByLong(ut, 10000000); - *ft = LargeIntegerAdd(*ft, ut); -} + /* unixTime: seconds since 1/1/1970 00:00:00 GMT */ + /* FILETIME: 100ns intervals since 1/1/1601 00:00:00 ??? */ + LARGE_INTEGER *ft = (LARGE_INTEGER *) largeTimep; + LARGE_INTEGER ut; + int leap_years = 89; /* leap years betw 1/1/1601 and 1/1/1970 */ + + /* set ft to number of 100ns intervals betw 1/1/1601 and 1/1/1970 GMT */ + *ft = ConvertLongToLargeInteger(((EPOCH_YEAR-1601) * 365 + leap_years) + * 24 * 60); + *ft = LargeIntegerMultiplyByLong(*ft, 60); + *ft = LargeIntegerMultiplyByLong(*ft, 10000000); + + /* add unix time */ + ut = ConvertLongToLargeInteger(unixTime); + ut = LargeIntegerMultiplyByLong(ut, 10000000); + *ft = LargeIntegerAdd(*ft, ut); +} #endif /* !DJGPP */ #ifndef DJGPP void smb_UnixTimeFromLargeSearchTime(time_t *unixTimep, FILETIME *largeTimep) { - SYSTEMTIME stm; - struct tm lt; - long save_timezone; - - FileTimeToSystemTime(largeTimep, &stm); - - lt.tm_year = stm.wYear - 1900; - lt.tm_mon = stm.wMonth - 1; - lt.tm_wday = stm.wDayOfWeek; - lt.tm_mday = stm.wDay; - lt.tm_hour = stm.wHour; - lt.tm_min = stm.wMinute; - lt.tm_sec = stm.wSecond; - lt.tm_isdst = -1; - - save_timezone = _timezone; - _timezone += smb_NowTZ; - *unixTimep = mktime(<); - _timezone = save_timezone; -} + SYSTEMTIME stm; + struct tm lt; + long save_timezone; + + FileTimeToSystemTime(largeTimep, &stm); + + lt.tm_year = stm.wYear - 1900; + lt.tm_mon = stm.wMonth - 1; + lt.tm_wday = stm.wDayOfWeek; + lt.tm_mday = stm.wDay; + lt.tm_hour = stm.wHour; + lt.tm_min = stm.wMinute; + lt.tm_sec = stm.wSecond; + lt.tm_isdst = -1; + + save_timezone = _timezone; + _timezone += smb_NowTZ; + *unixTimep = mktime(<); + _timezone = save_timezone; +} #else /* DJGPP */ void smb_UnixTimeFromLargeSearchTime(time_t *unixTimep, FILETIME *largeTimep) { - /* unixTime: seconds since 1/1/1970 00:00:00 GMT */ - /* FILETIME: 100ns intervals since 1/1/1601 00:00:00 GMT? */ - LARGE_INTEGER *ft = (LARGE_INTEGER *) largeTimep; - LARGE_INTEGER a; - int leap_years = 89; - - /* set to number of 100ns intervals betw 1/1/1601 and 1/1/1970 */ - a = ConvertLongToLargeInteger(((EPOCH_YEAR-1601) * 365 + leap_years) * 24 * 60); - a = LargeIntegerMultiplyByLong(a, 60); - a = LargeIntegerMultiplyByLong(a, 10000000); - - /* subtract it from ft */ - a = LargeIntegerSubtract(*ft, a); - - /* divide down to seconds */ - *unixTimep = LargeIntegerDivideByLong(a, 10000000); -} + /* unixTime: seconds since 1/1/1970 00:00:00 GMT */ + /* FILETIME: 100ns intervals since 1/1/1601 00:00:00 GMT? */ + LARGE_INTEGER *ft = (LARGE_INTEGER *) largeTimep; + LARGE_INTEGER a; + int leap_years = 89; + + /* set to number of 100ns intervals betw 1/1/1601 and 1/1/1970 */ + a = ConvertLongToLargeInteger(((EPOCH_YEAR-1601) * 365 + leap_years) * 24 * 60); + a = LargeIntegerMultiplyByLong(a, 60); + a = LargeIntegerMultiplyByLong(a, 10000000); + + /* subtract it from ft */ + a = LargeIntegerSubtract(*ft, a); + + /* divide down to seconds */ + *unixTimep = LargeIntegerDivideByLong(a, 10000000); +} #endif /* !DJGPP */ void smb_SearchTimeFromUnixTime(long *dosTimep, time_t unixTime) @@ -717,283 +730,283 @@ void smb_SearchTimeFromUnixTime(long *dosTimep, time_t unixTime) void smb_UnixTimeFromSearchTime(time_t *unixTimep, time_t searchTime) { - unsigned short dosDate; - unsigned short dosTime; - struct tm localTm; + unsigned short dosDate; + unsigned short dosTime; + struct tm localTm; - dosDate = searchTime & 0xffff; - dosTime = (searchTime >> 16) & 0xffff; - - localTm.tm_year = 80 + ((dosDate>>9) & 0x3f); - localTm.tm_mon = ((dosDate >> 5) & 0xf) - 1; /* January is 0 in localTm */ - localTm.tm_mday = (dosDate) & 0x1f; - localTm.tm_hour = (dosTime>>11) & 0x1f; - localTm.tm_min = (dosTime >> 5) & 0x3f; - localTm.tm_sec = (dosTime & 0x1f) * 2; - localTm.tm_isdst = -1; /* compute whether DST in effect */ - - *unixTimep = mktime(&localTm); + dosDate = searchTime & 0xffff; + dosTime = (searchTime >> 16) & 0xffff; + + localTm.tm_year = 80 + ((dosDate>>9) & 0x3f); + localTm.tm_mon = ((dosDate >> 5) & 0xf) - 1; /* January is 0 in localTm */ + localTm.tm_mday = (dosDate) & 0x1f; + localTm.tm_hour = (dosTime>>11) & 0x1f; + localTm.tm_min = (dosTime >> 5) & 0x3f; + localTm.tm_sec = (dosTime & 0x1f) * 2; + localTm.tm_isdst = -1; /* compute whether DST in effect */ + + *unixTimep = mktime(&localTm); } void smb_DosUTimeFromUnixTime(time_t *dosUTimep, time_t unixTime) { - *dosUTimep = unixTime - smb_localZero; + *dosUTimep = unixTime - smb_localZero; } void smb_UnixTimeFromDosUTime(time_t *unixTimep, time_t dosTime) { #ifndef DJGPP - *unixTimep = dosTime + smb_localZero; + *unixTimep = dosTime + smb_localZero; #else /* DJGPP */ - /* dosTime seems to be already adjusted for GMT */ - *unixTimep = dosTime; + /* dosTime seems to be already adjusted for GMT */ + *unixTimep = dosTime; #endif /* !DJGPP */ } smb_vc_t *smb_FindVC(unsigned short lsn, int flags, int lana) { - smb_vc_t *vcp; - - lock_ObtainWrite(&smb_rctLock); - for(vcp = smb_allVCsp; vcp; vcp=vcp->nextp) { - if (lsn == vcp->lsn && lana == vcp->lana) { - vcp->refCount++; - break; - } - } - if (!vcp && (flags & SMB_FLAG_CREATE)) { - vcp = malloc(sizeof(*vcp)); - memset(vcp, 0, sizeof(*vcp)); + smb_vc_t *vcp; + + lock_ObtainWrite(&smb_rctLock); + for(vcp = smb_allVCsp; vcp; vcp=vcp->nextp) { + if (lsn == vcp->lsn && lana == vcp->lana) { + vcp->refCount++; + break; + } + } + if (!vcp && (flags & SMB_FLAG_CREATE)) { + vcp = malloc(sizeof(*vcp)); + memset(vcp, 0, sizeof(*vcp)); vcp->vcID = numVCs++; - vcp->refCount = 1; - vcp->tidCounter = 1; - vcp->fidCounter = 1; - vcp->uidCounter = 1; /* UID 0 is reserved for blank user */ - vcp->nextp = smb_allVCsp; - smb_allVCsp = vcp; - lock_InitializeMutex(&vcp->mx, "vc_t mutex"); - vcp->lsn = lsn; - vcp->lana = lana; + vcp->refCount = 1; + vcp->tidCounter = 1; + vcp->fidCounter = 1; + vcp->uidCounter = 1; /* UID 0 is reserved for blank user */ + vcp->nextp = smb_allVCsp; + smb_allVCsp = vcp; + lock_InitializeMutex(&vcp->mx, "vc_t mutex"); + vcp->lsn = lsn; + vcp->lana = lana; vcp->secCtx = NULL; - if (smb_authType == SMB_AUTH_NTLM || smb_authType == SMB_AUTH_EXTENDED) { + if (smb_authType == SMB_AUTH_NTLM || smb_authType == SMB_AUTH_EXTENDED) { /* We must obtain a challenge for extended auth * in case the client negotiates smb v3 */ NTSTATUS nts,ntsEx; - MSV1_0_LM20_CHALLENGE_REQUEST lsaReq; - PMSV1_0_LM20_CHALLENGE_RESPONSE lsaResp; - ULONG lsaRespSize; + MSV1_0_LM20_CHALLENGE_REQUEST lsaReq; + PMSV1_0_LM20_CHALLENGE_RESPONSE lsaResp; + ULONG lsaRespSize; - lsaReq.MessageType = MsV1_0Lm20ChallengeRequest; + lsaReq.MessageType = MsV1_0Lm20ChallengeRequest; - nts = LsaCallAuthenticationPackage( smb_lsaHandle, + nts = LsaCallAuthenticationPackage( smb_lsaHandle, smb_lsaSecPackage, &lsaReq, sizeof(lsaReq), &lsaResp, &lsaRespSize, &ntsEx); - osi_assert(nts == STATUS_SUCCESS); /* this had better work! */ + osi_assert(nts == STATUS_SUCCESS); /* this had better work! */ - memcpy(vcp->encKey, lsaResp->ChallengeToClient, MSV1_0_CHALLENGE_LENGTH); + memcpy(vcp->encKey, lsaResp->ChallengeToClient, MSV1_0_CHALLENGE_LENGTH); LsaFreeReturnBuffer(lsaResp); - } - else - memset(vcp->encKey, 0, MSV1_0_CHALLENGE_LENGTH); - } - lock_ReleaseWrite(&smb_rctLock); - return vcp; + } + else + memset(vcp->encKey, 0, MSV1_0_CHALLENGE_LENGTH); + } + lock_ReleaseWrite(&smb_rctLock); + return vcp; } int smb_IsStarMask(char *maskp) { - int i; - char tc; + int i; + char tc; - for(i=0; i<11; i++) { - tc = *maskp++; - if (tc == '?' || tc == '*' || tc == '>') return 1; - } - return 0; + for(i=0; i<11; i++) { + tc = *maskp++; + if (tc == '?' || tc == '*' || tc == '>') return 1; + } + return 0; } void smb_ReleaseVC(smb_vc_t *vcp) { - lock_ObtainWrite(&smb_rctLock); - osi_assert(vcp->refCount-- > 0); - lock_ReleaseWrite(&smb_rctLock); -} + lock_ObtainWrite(&smb_rctLock); + osi_assert(vcp->refCount-- > 0); + lock_ReleaseWrite(&smb_rctLock); +} void smb_HoldVC(smb_vc_t *vcp) { - lock_ObtainWrite(&smb_rctLock); - vcp->refCount++; - lock_ReleaseWrite(&smb_rctLock); -} + lock_ObtainWrite(&smb_rctLock); + vcp->refCount++; + lock_ReleaseWrite(&smb_rctLock); +} smb_tid_t *smb_FindTID(smb_vc_t *vcp, unsigned short tid, int flags) { - smb_tid_t *tidp; - - lock_ObtainWrite(&smb_rctLock); - for(tidp = vcp->tidsp; tidp; tidp = tidp->nextp) { - if (tid == tidp->tid) { - tidp->refCount++; - break; - } - } - if (!tidp && (flags & SMB_FLAG_CREATE)) { - tidp = malloc(sizeof(*tidp)); - memset(tidp, 0, sizeof(*tidp)); - tidp->nextp = vcp->tidsp; - tidp->refCount = 1; - tidp->vcp = vcp; + smb_tid_t *tidp; + + lock_ObtainWrite(&smb_rctLock); + for (tidp = vcp->tidsp; tidp; tidp = tidp->nextp) { + if (tid == tidp->tid) { + tidp->refCount++; + break; + } + } + if (!tidp && (flags & SMB_FLAG_CREATE)) { + tidp = malloc(sizeof(*tidp)); + memset(tidp, 0, sizeof(*tidp)); + tidp->nextp = vcp->tidsp; + tidp->refCount = 1; + tidp->vcp = vcp; vcp->refCount++; - vcp->tidsp = tidp; - lock_InitializeMutex(&tidp->mx, "tid_t mutex"); - tidp->tid = tid; - } - lock_ReleaseWrite(&smb_rctLock); - return tidp; -} + vcp->tidsp = tidp; + lock_InitializeMutex(&tidp->mx, "tid_t mutex"); + tidp->tid = tid; + } + lock_ReleaseWrite(&smb_rctLock); + return tidp; +} void smb_ReleaseTID(smb_tid_t *tidp) { - smb_tid_t *tp; - smb_tid_t **ltpp; - cm_user_t *userp; + smb_tid_t *tp; + smb_tid_t **ltpp; + cm_user_t *userp; smb_vc_t *vcp; - userp = NULL; + userp = NULL; vcp = NULL; - lock_ObtainWrite(&smb_rctLock); - osi_assert(tidp->refCount-- > 0); - if (tidp->refCount == 0 && (tidp->flags & SMB_TIDFLAG_DELETE)) { - ltpp = &tidp->vcp->tidsp; - for(tp = *ltpp; tp; ltpp = &tp->nextp, tp = *ltpp) { - if (tp == tidp) break; - } - osi_assert(tp != NULL); - *ltpp = tp->nextp; - lock_FinalizeMutex(&tidp->mx); - userp = tidp->userp; /* remember to drop ref later */ + lock_ObtainWrite(&smb_rctLock); + osi_assert(tidp->refCount-- > 0); + if (tidp->refCount == 0 && (tidp->flags & SMB_TIDFLAG_DELETE)) { + ltpp = &tidp->vcp->tidsp; + for(tp = *ltpp; tp; ltpp = &tp->nextp, tp = *ltpp) { + if (tp == tidp) break; + } + osi_assert(tp != NULL); + *ltpp = tp->nextp; + lock_FinalizeMutex(&tidp->mx); + userp = tidp->userp; /* remember to drop ref later */ vcp = tidp->vcp; - } - lock_ReleaseWrite(&smb_rctLock); - if (userp) { - cm_ReleaseUser(userp); - } + } + lock_ReleaseWrite(&smb_rctLock); + if (userp) { + cm_ReleaseUser(userp); + } if (vcp) { smb_ReleaseVC(vcp); - } -} + } +} smb_user_t *smb_FindUID(smb_vc_t *vcp, unsigned short uid, int flags) { - smb_user_t *uidp = NULL; - - lock_ObtainWrite(&smb_rctLock); - for(uidp = vcp->usersp; uidp; uidp = uidp->nextp) { - if (uid == uidp->userID) { - uidp->refCount++; - osi_LogEvent("AFS smb_FindUID (Find by UID)",NULL," VCP[%x] found-uid[%d] name[%s]", - (int)vcp, uidp->userID, - osi_LogSaveString(smb_logp, (uidp->unp) ? uidp->unp->name : "")); - break; - } - } - if (!uidp && (flags & SMB_FLAG_CREATE)) { - uidp = malloc(sizeof(*uidp)); - memset(uidp, 0, sizeof(*uidp)); - uidp->nextp = vcp->usersp; - uidp->refCount = 1; - uidp->vcp = vcp; + smb_user_t *uidp = NULL; + + lock_ObtainWrite(&smb_rctLock); + for(uidp = vcp->usersp; uidp; uidp = uidp->nextp) { + if (uid == uidp->userID) { + uidp->refCount++; + osi_LogEvent("AFS smb_FindUID (Find by UID)",NULL," VCP[%x] found-uid[%d] name[%s]", + (int)vcp, uidp->userID, + osi_LogSaveString(smb_logp, (uidp->unp) ? uidp->unp->name : "")); + break; + } + } + if (!uidp && (flags & SMB_FLAG_CREATE)) { + uidp = malloc(sizeof(*uidp)); + memset(uidp, 0, sizeof(*uidp)); + uidp->nextp = vcp->usersp; + uidp->refCount = 1; + uidp->vcp = vcp; vcp->refCount++; - vcp->usersp = uidp; - lock_InitializeMutex(&uidp->mx, "user_t mutex"); - uidp->userID = uid; - osi_LogEvent("AFS smb_FindUID (Find by UID)",NULL,"VCP[%x] new-uid[%d] name[%s]",(int)vcp,uidp->userID,(uidp->unp ? uidp->unp->name : "")); - } - lock_ReleaseWrite(&smb_rctLock); - return uidp; -} + vcp->usersp = uidp; + lock_InitializeMutex(&uidp->mx, "user_t mutex"); + uidp->userID = uid; + osi_LogEvent("AFS smb_FindUID (Find by UID)",NULL,"VCP[%x] new-uid[%d] name[%s]",(int)vcp,uidp->userID,(uidp->unp ? uidp->unp->name : "")); + } + lock_ReleaseWrite(&smb_rctLock); + return uidp; +} smb_username_t *smb_FindUserByName(char *usern, char *machine, int flags) { - smb_username_t *unp= NULL; - - lock_ObtainWrite(&smb_rctLock); - for(unp = usernamesp; unp; unp = unp->nextp) { - if (stricmp(unp->name, usern) == 0 && - stricmp(unp->machine, machine) == 0) { - unp->refCount++; - break; - } - } - if (!unp && (flags & SMB_FLAG_CREATE)) { - unp = malloc(sizeof(*unp)); - memset(unp, 0, sizeof(*unp)); - unp->refCount = 1; - unp->nextp = usernamesp; - unp->name = strdup(usern); - unp->machine = strdup(machine); - usernamesp = unp; - lock_InitializeMutex(&unp->mx, "username_t mutex"); - } - lock_ReleaseWrite(&smb_rctLock); - return unp; + smb_username_t *unp= NULL; + + lock_ObtainWrite(&smb_rctLock); + for(unp = usernamesp; unp; unp = unp->nextp) { + if (stricmp(unp->name, usern) == 0 && + stricmp(unp->machine, machine) == 0) { + unp->refCount++; + break; + } + } + if (!unp && (flags & SMB_FLAG_CREATE)) { + unp = malloc(sizeof(*unp)); + memset(unp, 0, sizeof(*unp)); + unp->refCount = 1; + unp->nextp = usernamesp; + unp->name = strdup(usern); + unp->machine = strdup(machine); + usernamesp = unp; + lock_InitializeMutex(&unp->mx, "username_t mutex"); + } + lock_ReleaseWrite(&smb_rctLock); + return unp; } smb_user_t *smb_FindUserByNameThisSession(smb_vc_t *vcp, char *usern) { - smb_user_t *uidp= NULL; + smb_user_t *uidp= NULL; - lock_ObtainWrite(&smb_rctLock); - for(uidp = vcp->usersp; uidp; uidp = uidp->nextp) { - if (!uidp->unp) + lock_ObtainWrite(&smb_rctLock); + for(uidp = vcp->usersp; uidp; uidp = uidp->nextp) { + if (!uidp->unp) continue; - if (stricmp(uidp->unp->name, usern) == 0) { + if (stricmp(uidp->unp->name, usern) == 0) { uidp->refCount++; - osi_LogEvent("AFS smb_FindUserByNameThisSession",NULL,"VCP[%x] uid[%d] match-name[%s]",(int)vcp,uidp->userID,usern); + osi_LogEvent("AFS smb_FindUserByNameThisSession",NULL,"VCP[%x] uid[%d] match-name[%s]",(int)vcp,uidp->userID,usern); break; - } else + } else continue; - } - lock_ReleaseWrite(&smb_rctLock); - return uidp; -} + } + lock_ReleaseWrite(&smb_rctLock); + return uidp; +} void smb_ReleaseUID(smb_user_t *uidp) { - smb_user_t *up; - smb_user_t **lupp; - cm_user_t *userp; + smb_user_t *up; + smb_user_t **lupp; + cm_user_t *userp; smb_vc_t *vcp; - userp = NULL; + userp = NULL; vcp = NULL; - lock_ObtainWrite(&smb_rctLock); - osi_assert(uidp->refCount-- > 0); - if (uidp->refCount == 0 && (uidp->flags & SMB_USERFLAG_DELETE)) { - lupp = &uidp->vcp->usersp; - for(up = *lupp; up; lupp = &up->nextp, up = *lupp) { - if (up == uidp) break; - } - osi_assert(up != NULL); - *lupp = up->nextp; - lock_FinalizeMutex(&uidp->mx); - if (uidp->unp) { - userp = uidp->unp->userp; /* remember to drop ref later */ - uidp->unp->userp = NULL; + lock_ObtainWrite(&smb_rctLock); + osi_assert(uidp->refCount-- > 0); + if (uidp->refCount == 0 && (uidp->flags & SMB_USERFLAG_DELETE)) { + lupp = &uidp->vcp->usersp; + for(up = *lupp; up; lupp = &up->nextp, up = *lupp) { + if (up == uidp) break; } + osi_assert(up != NULL); + *lupp = up->nextp; + lock_FinalizeMutex(&uidp->mx); + if (uidp->unp) { + userp = uidp->unp->userp; /* remember to drop ref later */ + uidp->unp->userp = NULL; + } vcp = uidp->vcp; uidp->vcp = NULL; - } - lock_ReleaseWrite(&smb_rctLock); - if (userp) { - cm_ReleaseUserVCRef(userp); - cm_ReleaseUser(userp); - } + } + lock_ReleaseWrite(&smb_rctLock); + if (userp) { + cm_ReleaseUserVCRef(userp); + cm_ReleaseUser(userp); + } if (vcp) { smb_ReleaseVC(vcp); } @@ -1005,23 +1018,23 @@ void smb_ReleaseUID(smb_user_t *uidp) */ cm_user_t *smb_GetUser(smb_vc_t *vcp, smb_packet_t *inp) { - smb_user_t *uidp; - cm_user_t *up; - smb_t *smbp; - - smbp = (smb_t *) inp; - uidp = smb_FindUID(vcp, smbp->uid, 0); - if ((!uidp) || (!uidp->unp)) - return NULL; - - lock_ObtainMutex(&uidp->mx); - up = uidp->unp->userp; - cm_HoldUser(up); - lock_ReleaseMutex(&uidp->mx); + smb_user_t *uidp; + cm_user_t *up; + smb_t *smbp; - smb_ReleaseUID(uidp); - - return up; + smbp = (smb_t *) inp; + uidp = smb_FindUID(vcp, smbp->uid, 0); + if ((!uidp) || (!uidp->unp)) + return NULL; + + lock_ObtainMutex(&uidp->mx); + up = uidp->unp->userp; + cm_HoldUser(up); + lock_ReleaseMutex(&uidp->mx); + + smb_ReleaseUID(uidp); + + return up; } /* @@ -1030,10 +1043,10 @@ cm_user_t *smb_GetUser(smb_vc_t *vcp, smb_packet_t *inp) */ long smb_LookupTIDPath(smb_vc_t *vcp, unsigned short tid, char ** treepath) { - smb_tid_t *tidp; + smb_tid_t *tidp; long code = 0; - tidp = smb_FindTID(vcp, tid, 0); + tidp = smb_FindTID(vcp, tid, 0); if (!tidp) { *treepath = NULL; } else { @@ -1054,16 +1067,16 @@ long smb_LookupTIDPath(smb_vc_t *vcp, unsigned short tid, char ** treepath) */ int smb_ChainFID(int fid, smb_packet_t *inp) { - if (inp->fid == 0 || inp->inCount == 0) - return fid; - else - return inp->fid; + if (inp->fid == 0 || inp->inCount == 0) + return fid; + else + return inp->fid; } /* are we a priv'd user? What does this mean on NT? */ int smb_SUser(cm_user_t *userp) { - return 1; + return 1; } /* find a file ID. If we pass in 0 we select an used File ID. @@ -1072,31 +1085,31 @@ int smb_SUser(cm_user_t *userp) */ smb_fid_t *smb_FindFID(smb_vc_t *vcp, unsigned short fid, int flags) { - smb_fid_t *fidp; - int newFid = 0; + smb_fid_t *fidp; + int newFid = 0; if (fid == 0 && !(flags & SMB_FLAG_CREATE)) return NULL; - lock_ObtainWrite(&smb_rctLock); - /* figure out if we need to allocate a new file ID */ - if (fid == 0) { - newFid = 1; - fid = vcp->fidCounter; - } - -retry: - for(fidp = vcp->fidsp; fidp; fidp = (smb_fid_t *) osi_QNext(&fidp->q)) { - if (fid == fidp->fid) { - if (newFid) { - fid++; + lock_ObtainWrite(&smb_rctLock); + /* figure out if we need to allocate a new file ID */ + if (fid == 0) { + newFid = 1; + fid = vcp->fidCounter; + } + + retry: + for(fidp = vcp->fidsp; fidp; fidp = (smb_fid_t *) osi_QNext(&fidp->q)) { + if (fid == fidp->fid) { + if (newFid) { + fid++; if (fid == 0) - fid = 1; + fid = 1; goto retry; } - fidp->refCount++; + fidp->refCount++; break; - } + } } if (!fidp && (flags & SMB_FLAG_CREATE)) { char eventName[MAX_PATH]; @@ -1112,16 +1125,16 @@ retry: goto retry; } - fidp = malloc(sizeof(*fidp)); + fidp = malloc(sizeof(*fidp)); memset(fidp, 0, sizeof(*fidp)); - osi_QAdd((osi_queue_t **)&vcp->fidsp, &fidp->q); + osi_QAdd((osi_queue_t **)&vcp->fidsp, &fidp->q); fidp->refCount = 1; fidp->vcp = vcp; vcp->refCount++; lock_InitializeMutex(&fidp->mx, "fid_t mutex"); fidp->fid = fid; - fidp->curr_chunk = fidp->prev_chunk = -2; - fidp->raw_write_event = event; + fidp->curr_chunk = fidp->prev_chunk = -2; + fidp->raw_write_event = event; if (newFid) { vcp->fidCounter = fid+1; if (vcp->fidCounter == 0) @@ -1134,43 +1147,43 @@ retry: void smb_ReleaseFID(smb_fid_t *fidp) { - cm_scache_t *scp; + cm_scache_t *scp; smb_vc_t *vcp = NULL; smb_ioctl_t *ioctlp; if (!fidp) return; - scp = NULL; - lock_ObtainWrite(&smb_rctLock); - osi_assert(fidp->refCount-- > 0); + scp = NULL; + lock_ObtainWrite(&smb_rctLock); + osi_assert(fidp->refCount-- > 0); if (fidp->refCount == 0 && (fidp->flags & SMB_FID_DELETE)) { - vcp = fidp->vcp; - if (!(fidp->flags & SMB_FID_IOCTL)) - scp = fidp->scp; - osi_QRemove((osi_queue_t **) &vcp->fidsp, &fidp->q); - thrd_CloseHandle(fidp->raw_write_event); + vcp = fidp->vcp; + if (!(fidp->flags & SMB_FID_IOCTL)) + scp = fidp->scp; + osi_QRemove((osi_queue_t **) &vcp->fidsp, &fidp->q); + thrd_CloseHandle(fidp->raw_write_event); - /* and see if there is ioctl stuff to free */ + /* and see if there is ioctl stuff to free */ ioctlp = fidp->ioctlp; if (ioctlp) { - if (ioctlp->prefix) cm_FreeSpace(ioctlp->prefix); - if (ioctlp->inAllocp) free(ioctlp->inAllocp); - if (ioctlp->outAllocp) free(ioctlp->outAllocp); - free(ioctlp); - } + if (ioctlp->prefix) cm_FreeSpace(ioctlp->prefix); + if (ioctlp->inAllocp) free(ioctlp->inAllocp); + if (ioctlp->outAllocp) free(ioctlp->outAllocp); + free(ioctlp); + } free(fidp); /* do not call smb_ReleaseVC() because we already have the lock */ vcp->refCount--; } - lock_ReleaseWrite(&smb_rctLock); + lock_ReleaseWrite(&smb_rctLock); - /* now release the scache structure */ - if (scp) - cm_ReleaseSCache(scp); -} + /* now release the scache structure */ + if (scp) + cm_ReleaseSCache(scp); +} /* * Case-insensitive search for one string in another; @@ -1178,13 +1191,13 @@ void smb_ReleaseFID(smb_fid_t *fidp) */ static char *smb_stristr(char *str1, char *str2) { - char *cursor; + char *cursor; - for (cursor = str1; *cursor; cursor++) - if (stricmp(cursor, str2) == 0) - return cursor; + for (cursor = str1; *cursor; cursor++) + if (stricmp(cursor, str2) == 0) + return cursor; - return NULL; + return NULL; } /* @@ -1193,14 +1206,14 @@ static char *smb_stristr(char *str1, char *str2) * length (plus one) is in substr_size. Variable value is in newstr. */ static void smb_subst(char *str1, char *substr, unsigned int substr_size, - char *newstr) + char *newstr) { - char temp[1024]; + char temp[1024]; - strcpy(temp, substr + substr_size - 1); - strcpy(substr, newstr); - strcat(str1, temp); -} + strcpy(temp, substr + substr_size - 1); + strcpy(substr, newstr); + strcat(str1, temp); +} char VNUserName[] = "%USERNAME%"; char VNLCUserName[] = "%LCUSERNAME%"; @@ -1211,65 +1224,65 @@ char VNLCComputerName[] = "%LCCOMPUTERNAME%"; /* List available shares */ int smb_ListShares() { - char sbmtpath[256]; - char pathName[256]; - char shareBuf[4096]; - int num_shares=0; - char *this_share; - int len; - char *p; - int print_afs = 0; - int code; - - /*strcpy(shareNameList[num_shares], "all"); - strcpy(pathNameList[num_shares++], "/afs");*/ - fprintf(stderr, "The following shares are available:\n"); - fprintf(stderr, "Share Name (AFS Path)\n"); - fprintf(stderr, "---------------------\n"); - fprintf(stderr, "\\\\%s\\%-16s (%s)\n", smb_localNamep, "ALL", cm_mountRoot); + char sbmtpath[256]; + char pathName[256]; + char shareBuf[4096]; + int num_shares=0; + char *this_share; + int len; + char *p; + int print_afs = 0; + int code; + + /*strcpy(shareNameList[num_shares], "all"); + strcpy(pathNameList[num_shares++], "/afs");*/ + fprintf(stderr, "The following shares are available:\n"); + fprintf(stderr, "Share Name (AFS Path)\n"); + fprintf(stderr, "---------------------\n"); + fprintf(stderr, "\\\\%s\\%-16s (%s)\n", smb_localNamep, "ALL", cm_mountRoot); #ifndef DJGPP - code = GetWindowsDirectory(sbmtpath, sizeof(sbmtpath)); - if (code == 0 || code > sizeof(sbmtpath)) return -1; + code = GetWindowsDirectory(sbmtpath, sizeof(sbmtpath)); + if (code == 0 || code > sizeof(sbmtpath)) return -1; #else - strcpy(sbmtpath, cm_confDir); + strcpy(sbmtpath, cm_confDir); #endif /* !DJGPP */ - strcat(sbmtpath, "/afsdsbmt.ini"); - len = GetPrivateProfileString("AFS Submounts", NULL, NULL, - shareBuf, sizeof(shareBuf), - sbmtpath); - if (len == 0) { - return num_shares; - } - - this_share = shareBuf; - do - { - print_afs = 0; - /*strcpy(shareNameList[num_shares], this_share);*/ - len = GetPrivateProfileString("AFS Submounts", this_share, - NULL, - pathName, 256, - sbmtpath); - if (!len) - return num_shares; - p = pathName; - if (strncmp(p, cm_mountRoot, strlen(cm_mountRoot)) != 0) + strcat(sbmtpath, "/afsdsbmt.ini"); + len = GetPrivateProfileString("AFS Submounts", NULL, NULL, + shareBuf, sizeof(shareBuf), + sbmtpath); + if (len == 0) { + return num_shares; + } + + this_share = shareBuf; + do + { + print_afs = 0; + /*strcpy(shareNameList[num_shares], this_share);*/ + len = GetPrivateProfileString("AFS Submounts", this_share, + NULL, + pathName, 256, + sbmtpath); + if (!len) + return num_shares; + p = pathName; + if (strncmp(p, cm_mountRoot, strlen(cm_mountRoot)) != 0) print_afs = 1; - while (*p) { + while (*p) { if (*p == '\\') *p = '/'; /* change to / */ p++; - } + } - fprintf(stderr, "\\\\%s\\%-16s (%s%s)\n", - smb_localNamep, this_share, (print_afs ? cm_mountRoot : "\0"), - pathName); - num_shares++; - while (*this_share != 0) this_share++; /* find next NUL */ - this_share++; /* skip past the NUL */ - } while (*this_share != 0); /* stop at final NUL */ + fprintf(stderr, "\\\\%s\\%-16s (%s%s)\n", + smb_localNamep, this_share, (print_afs ? cm_mountRoot : "\0"), + pathName); + num_shares++; + while (*this_share != 0) this_share++; /* find next NUL */ + this_share++; /* skip past the NUL */ + } while (*this_share != 0); /* stop at final NUL */ - return num_shares; + return num_shares; } #endif /* DJGPP */ @@ -1283,7 +1296,7 @@ typedef struct smb_findShare_rock { #define SMB_FINDSHARE_PARTIAL_MATCH 2 long smb_FindShareProc(cm_scache_t *scp, cm_dirEntry_t *dep, void *rockp, - osi_hyper_t *offp) + osi_hyper_t *offp) { int matchType = 0; smb_findShare_rock_t * vrock = (smb_findShare_rock_t *) rockp; @@ -1307,17 +1320,17 @@ long smb_FindShareProc(cm_scache_t *scp, cm_dirEntry_t *dep, void *rockp, int smb_FindShare(smb_vc_t *vcp, smb_user_t *uidp, char *shareName, char **pathNamep) { - DWORD len; - char pathName[1024]; - char *var; - char temp[1024]; - DWORD sizeTemp; + DWORD len; + char pathName[1024]; + char *var; + char temp[1024]; + DWORD sizeTemp; #ifdef DJGPP char sbmtpath[MAX_PATH]; #endif char *p, *q; - HKEY parmKey; - DWORD code; + HKEY parmKey; + DWORD code; DWORD allSubmount = 1; /* if allSubmounts == 0, only return the //mountRoot/all share @@ -1325,9 +1338,9 @@ int smb_FindShare(smb_vc_t *vcp, smb_user_t *uidp, char *shareName, * This is to allow sites that want to restrict access to the * world to do so. */ - code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSConfigKeyName, - 0, KEY_QUERY_VALUE, &parmKey); - if (code == ERROR_SUCCESS) { + code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSConfigKeyName, + 0, KEY_QUERY_VALUE, &parmKey); + if (code == ERROR_SUCCESS) { len = sizeof(allSubmount); code = RegQueryValueEx(parmKey, "AllSubmount", NULL, NULL, (BYTE *) &allSubmount, &len); @@ -1335,49 +1348,49 @@ int smb_FindShare(smb_vc_t *vcp, smb_user_t *uidp, char *shareName, allSubmount = 1; } RegCloseKey (parmKey); - } + } - if (allSubmount && _stricmp(shareName, "all") == 0) { - *pathNamep = NULL; - return 1; - } + if (allSubmount && _stricmp(shareName, "all") == 0) { + *pathNamep = NULL; + return 1; + } /* In case, the all share is disabled we need to still be able * to handle ioctl requests */ - if (_stricmp(shareName, "ioctl$") == 0) { - *pathNamep = strdup("/.__ioctl__"); - return 1; - } + if (_stricmp(shareName, "ioctl$") == 0) { + *pathNamep = strdup("/.__ioctl__"); + return 1; + } if (_stricmp(shareName, "IPC$") == 0 || _stricmp(shareName, SMB_IOCTL_FILENAME_NOSLASH) == 0 || _stricmp(shareName, "DESKTOP.INI") == 0 ) { - *pathNamep = NULL; - return 0; - } + *pathNamep = NULL; + return 0; + } #ifndef DJGPP - code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\OpenAFS\\Client\\Submounts", - 0, KEY_QUERY_VALUE, &parmKey); - if (code == ERROR_SUCCESS) { + code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\OpenAFS\\Client\\Submounts", + 0, KEY_QUERY_VALUE, &parmKey); + if (code == ERROR_SUCCESS) { len = sizeof(pathName); code = RegQueryValueEx(parmKey, shareName, NULL, NULL, (BYTE *) pathName, &len); - if (code != ERROR_SUCCESS) - len = 0; + if (code != ERROR_SUCCESS) + len = 0; RegCloseKey (parmKey); - } else { + } else { len = 0; } #else /* DJGPP */ strcpy(sbmtpath, cm_confDir); strcat(sbmtpath, "/afsdsbmt.ini"); - len = GetPrivateProfileString("AFS Submounts", shareName, "", - pathName, sizeof(pathName), sbmtpath); + len = GetPrivateProfileString("AFS Submounts", shareName, "", + pathName, sizeof(pathName), sbmtpath); #endif /* !DJGPP */ - if (len != 0 && len != sizeof(pathName) - 1) { + if (len != 0 && len != sizeof(pathName) - 1) { /* We can accept either unix or PC style AFS pathnames. Convert * Unix-style to PC style here for internal use. */ @@ -1478,7 +1491,7 @@ int smb_FindShare(smb_vc_t *vcp, smb_user_t *uidp, char *shareName, *pathNamep = strdup(strlwr(pathName)); return 1; } - } + } /* failure */ *pathNamep = NULL; return 0; @@ -1492,8 +1505,8 @@ int smb_FindShare(smb_vc_t *vcp, smb_user_t *uidp, char *shareName, int smb_FindShareCSCPolicy(char *shareName) { - DWORD len; - char policy[1024]; + DWORD len; + char policy[1024]; DWORD dwType; HKEY hkCSCPolicy; int retval = CSC_POLICY_MANUAL; @@ -1511,23 +1524,23 @@ int smb_FindShareCSCPolicy(char *shareName) len = sizeof(policy); if ( RegQueryValueEx( hkCSCPolicy, shareName, 0, &dwType, policy, &len ) || len == 0) { - retval = CSC_POLICY_MANUAL; - } - else if (stricmp(policy, "documents") == 0) - { - retval = CSC_POLICY_DOCUMENTS; - } - else if (stricmp(policy, "programs") == 0) - { - retval = CSC_POLICY_PROGRAMS; - } - else if (stricmp(policy, "disable") == 0) - { - retval = CSC_POLICY_DISABLE; - } + retval = stricmp("all",shareName) ? CSC_POLICY_MANUAL : CSC_POLICY_DISABLE; + } + else if (stricmp(policy, "documents") == 0) + { + retval = CSC_POLICY_DOCUMENTS; + } + else if (stricmp(policy, "programs") == 0) + { + retval = CSC_POLICY_PROGRAMS; + } + else if (stricmp(policy, "disable") == 0) + { + retval = CSC_POLICY_DISABLE; + } RegCloseKey(hkCSCPolicy); - return retval; + return retval; } /* find a dir search structure by cookie value, and return it held. @@ -1535,76 +1548,76 @@ int smb_FindShareCSCPolicy(char *shareName) */ smb_dirSearch_t *smb_FindDirSearchNL(long cookie) { - smb_dirSearch_t *dsp; + smb_dirSearch_t *dsp; - for(dsp = smb_firstDirSearchp; dsp; dsp = (smb_dirSearch_t *) osi_QNext(&dsp->q)) { - if (dsp->cookie == cookie) { - if (dsp != smb_firstDirSearchp) { - /* move to head of LRU queue, too, if we're not already there */ - if (smb_lastDirSearchp == (smb_dirSearch_t *) &dsp->q) - smb_lastDirSearchp = (smb_dirSearch_t *) - osi_QPrev(&dsp->q); - osi_QRemove((osi_queue_t **) &smb_firstDirSearchp, &dsp->q); - osi_QAdd((osi_queue_t **) &smb_firstDirSearchp, &dsp->q); - if (!smb_lastDirSearchp) - smb_lastDirSearchp = (smb_dirSearch_t *) &dsp->q; - } - dsp->refCount++; - break; - } - } - return dsp; -} + for(dsp = smb_firstDirSearchp; dsp; dsp = (smb_dirSearch_t *) osi_QNext(&dsp->q)) { + if (dsp->cookie == cookie) { + if (dsp != smb_firstDirSearchp) { + /* move to head of LRU queue, too, if we're not already there */ + if (smb_lastDirSearchp == (smb_dirSearch_t *) &dsp->q) + smb_lastDirSearchp = (smb_dirSearch_t *) + osi_QPrev(&dsp->q); + osi_QRemove((osi_queue_t **) &smb_firstDirSearchp, &dsp->q); + osi_QAdd((osi_queue_t **) &smb_firstDirSearchp, &dsp->q); + if (!smb_lastDirSearchp) + smb_lastDirSearchp = (smb_dirSearch_t *) &dsp->q; + } + dsp->refCount++; + break; + } + } + return dsp; +} void smb_DeleteDirSearch(smb_dirSearch_t *dsp) { - lock_ObtainWrite(&smb_globalLock); - dsp->flags |= SMB_DIRSEARCH_DELETE; - lock_ReleaseWrite(&smb_globalLock); - lock_ObtainMutex(&dsp->mx); - if(dsp->scp != NULL) { - lock_ObtainMutex(&dsp->scp->mx); - if (dsp->flags & SMB_DIRSEARCH_BULKST) { - dsp->flags &= ~SMB_DIRSEARCH_BULKST; - dsp->scp->flags &= ~CM_SCACHEFLAG_BULKSTATTING; - dsp->scp->bulkStatProgress = hones; - } - lock_ReleaseMutex(&dsp->scp->mx); - } - lock_ReleaseMutex(&dsp->mx); -} + lock_ObtainWrite(&smb_globalLock); + dsp->flags |= SMB_DIRSEARCH_DELETE; + lock_ReleaseWrite(&smb_globalLock); + lock_ObtainMutex(&dsp->mx); + if(dsp->scp != NULL) { + lock_ObtainMutex(&dsp->scp->mx); + if (dsp->flags & SMB_DIRSEARCH_BULKST) { + dsp->flags &= ~SMB_DIRSEARCH_BULKST; + dsp->scp->flags &= ~CM_SCACHEFLAG_BULKSTATTING; + dsp->scp->bulkStatProgress = hones; + } + lock_ReleaseMutex(&dsp->scp->mx); + } + lock_ReleaseMutex(&dsp->mx); +} void smb_ReleaseDirSearch(smb_dirSearch_t *dsp) { - cm_scache_t *scp; + cm_scache_t *scp; - scp = NULL; - - lock_ObtainWrite(&smb_globalLock); - osi_assert(dsp->refCount-- > 0); - if (dsp->refCount == 0 && (dsp->flags & SMB_DIRSEARCH_DELETE)) { - if (&dsp->q == (osi_queue_t *) smb_lastDirSearchp) - smb_lastDirSearchp = (smb_dirSearch_t *) osi_QPrev(&smb_lastDirSearchp->q); - osi_QRemove((osi_queue_t **) &smb_firstDirSearchp, &dsp->q); - lock_FinalizeMutex(&dsp->mx); - scp = dsp->scp; - free(dsp); - } - lock_ReleaseWrite(&smb_globalLock); - - /* do this now to avoid spurious locking hierarchy creation */ - if (scp) cm_ReleaseSCache(scp); -} + scp = NULL; + + lock_ObtainWrite(&smb_globalLock); + osi_assert(dsp->refCount-- > 0); + if (dsp->refCount == 0 && (dsp->flags & SMB_DIRSEARCH_DELETE)) { + if (&dsp->q == (osi_queue_t *) smb_lastDirSearchp) + smb_lastDirSearchp = (smb_dirSearch_t *) osi_QPrev(&smb_lastDirSearchp->q); + osi_QRemove((osi_queue_t **) &smb_firstDirSearchp, &dsp->q); + lock_FinalizeMutex(&dsp->mx); + scp = dsp->scp; + free(dsp); + } + lock_ReleaseWrite(&smb_globalLock); + + /* do this now to avoid spurious locking hierarchy creation */ + if (scp) cm_ReleaseSCache(scp); +} /* find a dir search structure by cookie value, and return it held */ smb_dirSearch_t *smb_FindDirSearch(long cookie) { - smb_dirSearch_t *dsp; + smb_dirSearch_t *dsp; - lock_ObtainWrite(&smb_globalLock); - dsp = smb_FindDirSearchNL(cookie); - lock_ReleaseWrite(&smb_globalLock); - return dsp; + lock_ObtainWrite(&smb_globalLock); + dsp = smb_FindDirSearchNL(cookie); + lock_ReleaseWrite(&smb_globalLock); + return dsp; } /* GC some dir search entries, in the address space expected by the specific protocol. @@ -1613,39 +1626,39 @@ smb_dirSearch_t *smb_FindDirSearch(long cookie) #define SMB_DIRSEARCH_GCMAX 10 /* how many at once */ void smb_GCDirSearches(int isV3) { - smb_dirSearch_t *prevp; - smb_dirSearch_t *tp; - smb_dirSearch_t *victimsp[SMB_DIRSEARCH_GCMAX]; - int victimCount; - int i; + smb_dirSearch_t *prevp; + smb_dirSearch_t *tp; + smb_dirSearch_t *victimsp[SMB_DIRSEARCH_GCMAX]; + int victimCount; + int i; - victimCount = 0; /* how many have we got so far */ - for(tp = smb_lastDirSearchp; tp; tp=prevp) { - /* we'll move tp from queue, so - * do this early. - */ - prevp = (smb_dirSearch_t *) osi_QPrev(&tp->q); - /* if no one is using this guy, and we're either in the new protocol, - * or we're in the old one and this is a small enough ID to be useful - * to the old protocol, GC this guy. - */ - if (tp->refCount == 0 && (isV3 || tp->cookie <= 255)) { - /* hold and delete */ - tp->flags |= SMB_DIRSEARCH_DELETE; - victimsp[victimCount++] = tp; - tp->refCount++; - } - - /* don't do more than this */ - if (victimCount >= SMB_DIRSEARCH_GCMAX) break; - } + victimCount = 0; /* how many have we got so far */ + for(tp = smb_lastDirSearchp; tp; tp=prevp) { + /* we'll move tp from queue, so + * do this early. + */ + prevp = (smb_dirSearch_t *) osi_QPrev(&tp->q); + /* if no one is using this guy, and we're either in the new protocol, + * or we're in the old one and this is a small enough ID to be useful + * to the old protocol, GC this guy. + */ + if (tp->refCount == 0 && (isV3 || tp->cookie <= 255)) { + /* hold and delete */ + tp->flags |= SMB_DIRSEARCH_DELETE; + victimsp[victimCount++] = tp; + tp->refCount++; + } + + /* don't do more than this */ + if (victimCount >= SMB_DIRSEARCH_GCMAX) break; + } - /* now release them */ - lock_ReleaseWrite(&smb_globalLock); - for(i = 0; i < victimCount; i++) { - smb_ReleaseDirSearch(victimsp[i]); - } - lock_ObtainWrite(&smb_globalLock); + /* now release them */ + lock_ReleaseWrite(&smb_globalLock); + for(i = 0; i < victimCount; i++) { + smb_ReleaseDirSearch(victimsp[i]); + } + lock_ObtainWrite(&smb_globalLock); } /* function for allocating a dir search entry. We need these to remember enough context @@ -1656,64 +1669,64 @@ void smb_GCDirSearches(int isV3) */ smb_dirSearch_t *smb_NewDirSearch(int isV3) { - smb_dirSearch_t *dsp; - int counter; - int maxAllowed; - - lock_ObtainWrite(&smb_globalLock); - counter = 0; - - /* what's the biggest ID allowed in this version of the protocol */ - if (isV3) maxAllowed = 65535; - else maxAllowed = 255; - - while(1) { - /* twice so we have enough tries to find guys we GC after one pass; - * 10 extra is just in case I mis-counted. - */ - if (++counter > 2*maxAllowed+10) osi_panic("afsd: dir search cookie leak", - __FILE__, __LINE__); - if (smb_dirSearchCounter > maxAllowed) { - smb_dirSearchCounter = 1; - smb_GCDirSearches(isV3); /* GC some (drops global lock) */ - } - dsp = smb_FindDirSearchNL(smb_dirSearchCounter); - if (dsp) { - /* don't need to watch for refcount zero and deleted, since - * we haven't dropped the global lock. - */ - dsp->refCount--; - ++smb_dirSearchCounter; - continue; - } - - dsp = malloc(sizeof(*dsp)); - memset(dsp, 0, sizeof(*dsp)); - osi_QAdd((osi_queue_t **) &smb_firstDirSearchp, &dsp->q); - if (!smb_lastDirSearchp) smb_lastDirSearchp = (smb_dirSearch_t *) &dsp->q; - dsp->cookie = smb_dirSearchCounter; - ++smb_dirSearchCounter; - dsp->refCount = 1; - lock_InitializeMutex(&dsp->mx, "cm_dirSearch_t"); - dsp->lastTime = osi_Time(); - break; - } - lock_ReleaseWrite(&smb_globalLock); - return dsp; + smb_dirSearch_t *dsp; + int counter; + int maxAllowed; + + lock_ObtainWrite(&smb_globalLock); + counter = 0; + + /* what's the biggest ID allowed in this version of the protocol */ + if (isV3) maxAllowed = 65535; + else maxAllowed = 255; + + while(1) { + /* twice so we have enough tries to find guys we GC after one pass; + * 10 extra is just in case I mis-counted. + */ + if (++counter > 2*maxAllowed+10) osi_panic("afsd: dir search cookie leak", + __FILE__, __LINE__); + if (smb_dirSearchCounter > maxAllowed) { + smb_dirSearchCounter = 1; + smb_GCDirSearches(isV3); /* GC some (drops global lock) */ + } + dsp = smb_FindDirSearchNL(smb_dirSearchCounter); + if (dsp) { + /* don't need to watch for refcount zero and deleted, since + * we haven't dropped the global lock. + */ + dsp->refCount--; + ++smb_dirSearchCounter; + continue; + } + + dsp = malloc(sizeof(*dsp)); + memset(dsp, 0, sizeof(*dsp)); + osi_QAdd((osi_queue_t **) &smb_firstDirSearchp, &dsp->q); + if (!smb_lastDirSearchp) smb_lastDirSearchp = (smb_dirSearch_t *) &dsp->q; + dsp->cookie = smb_dirSearchCounter; + ++smb_dirSearchCounter; + dsp->refCount = 1; + lock_InitializeMutex(&dsp->mx, "cm_dirSearch_t"); + dsp->lastTime = osi_Time(); + break; + } + lock_ReleaseWrite(&smb_globalLock); + return dsp; } static smb_packet_t *GetPacket(void) { - smb_packet_t *tbp; + smb_packet_t *tbp; #ifdef DJGPP - unsigned int npar, seg, tb_sel; + unsigned int npar, seg, tb_sel; #endif - lock_ObtainWrite(&smb_globalLock); - tbp = smb_packetFreeListp; + lock_ObtainWrite(&smb_globalLock); + tbp = smb_packetFreeListp; if (tbp) smb_packetFreeListp = tbp->nextp; - lock_ReleaseWrite(&smb_globalLock); + lock_ReleaseWrite(&smb_globalLock); if (!tbp) { #ifndef DJGPP tbp = calloc(65540,1); @@ -1721,16 +1734,16 @@ static smb_packet_t *GetPacket(void) tbp = malloc(sizeof(smb_packet_t)); #endif /* !DJGPP */ tbp->magic = SMB_PACKETMAGIC; - tbp->ncbp = NULL; - tbp->vcp = NULL; - tbp->resumeCode = 0; - tbp->inCount = 0; - tbp->fid = 0; - tbp->wctp = NULL; - tbp->inCom = 0; - tbp->oddByte = 0; - tbp->ncb_length = 0; - tbp->flags = 0; + tbp->ncbp = NULL; + tbp->vcp = NULL; + tbp->resumeCode = 0; + tbp->inCount = 0; + tbp->fid = 0; + tbp->wctp = NULL; + tbp->inCom = 0; + tbp->oddByte = 0; + tbp->ncb_length = 0; + tbp->flags = 0; tbp->spacep = NULL; #ifdef DJGPP @@ -1752,7 +1765,7 @@ static smb_packet_t *GetPacket(void) tbp->dos_pkt = (seg * 16) + 0; /* DOS physical address */ tbp->dos_pkt_sel = tb_sel; #endif /* DJGPP */ - } + } osi_assert(tbp->magic == SMB_PACKETMAGIC); return tbp; @@ -1760,26 +1773,26 @@ static smb_packet_t *GetPacket(void) smb_packet_t *smb_CopyPacket(smb_packet_t *pkt) { - smb_packet_t *tbp; - tbp = GetPacket(); - memcpy(tbp, pkt, sizeof(smb_packet_t)); - tbp->wctp = tbp->data + ((unsigned int)pkt->wctp - (unsigned int)pkt->data); - return tbp; + smb_packet_t *tbp; + tbp = GetPacket(); + memcpy(tbp, pkt, sizeof(smb_packet_t)); + tbp->wctp = tbp->data + ((unsigned int)pkt->wctp - (unsigned int)pkt->data); + return tbp; } static NCB *GetNCB(void) { - smb_ncb_t *tbp; + smb_ncb_t *tbp; NCB *ncbp; #ifdef DJGPP unsigned int npar, seg, tb_sel; #endif /* DJGPP */ - lock_ObtainWrite(&smb_globalLock); - tbp = smb_ncbFreeListp; + lock_ObtainWrite(&smb_globalLock); + tbp = smb_ncbFreeListp; if (tbp) smb_ncbFreeListp = tbp->nextp; - lock_ReleaseWrite(&smb_globalLock); + lock_ReleaseWrite(&smb_globalLock); if (!tbp) { #ifndef DJGPP tbp = calloc(sizeof(*tbp),1); @@ -1803,11 +1816,11 @@ static NCB *GetNCB(void) tbp->dos_ncb_sel = tb_sel; #endif /* !DJGPP */ tbp->magic = SMB_NCBMAGIC; - } + } osi_assert(tbp->magic == SMB_NCBMAGIC); - memset(&tbp->ncb, 0, sizeof(NCB)); + memset(&tbp->ncb, 0, sizeof(NCB)); ncbp = &tbp->ncb; #ifdef DJGPP dos_memset(tbp->dos_ncb, 0, sizeof(NCB)); @@ -1820,32 +1833,32 @@ void smb_FreePacket(smb_packet_t *tbp) osi_assert(tbp->magic == SMB_PACKETMAGIC); lock_ObtainWrite(&smb_globalLock); - tbp->nextp = smb_packetFreeListp; - smb_packetFreeListp = tbp; - tbp->magic = SMB_PACKETMAGIC; - tbp->ncbp = NULL; - tbp->vcp = NULL; - tbp->resumeCode = 0; - tbp->inCount = 0; - tbp->fid = 0; - tbp->wctp = NULL; - tbp->inCom = 0; - tbp->oddByte = 0; - tbp->ncb_length = 0; - tbp->flags = 0; + tbp->nextp = smb_packetFreeListp; + smb_packetFreeListp = tbp; + tbp->magic = SMB_PACKETMAGIC; + tbp->ncbp = NULL; + tbp->vcp = NULL; + tbp->resumeCode = 0; + tbp->inCount = 0; + tbp->fid = 0; + tbp->wctp = NULL; + tbp->inCom = 0; + tbp->oddByte = 0; + tbp->ncb_length = 0; + tbp->flags = 0; lock_ReleaseWrite(&smb_globalLock); } static void FreeNCB(NCB *bufferp) { - smb_ncb_t *tbp; + smb_ncb_t *tbp; tbp = (smb_ncb_t *) bufferp; osi_assert(tbp->magic == SMB_NCBMAGIC); lock_ObtainWrite(&smb_globalLock); - tbp->nextp = smb_ncbFreeListp; - smb_ncbFreeListp = tbp; + tbp->nextp = smb_ncbFreeListp; + smb_ncbFreeListp = tbp; lock_ReleaseWrite(&smb_globalLock); } @@ -1857,12 +1870,12 @@ unsigned char *smb_GetSMBData(smb_packet_t *smbp, int *nbytesp) unsigned char *afterParmsp; parmBytes = *smbp->wctp << 1; - afterParmsp = smbp->wctp + parmBytes + 1; + afterParmsp = smbp->wctp + parmBytes + 1; dataBytes = afterParmsp[0] + (afterParmsp[1]<<8); if (nbytesp) *nbytesp = dataBytes; - /* don't forget to skip the data byte count, since it follows + /* don't forget to skip the data byte count, since it follows * the parameters; that's where the "2" comes from below. */ return (unsigned char *) (afterParmsp + 2); @@ -1874,581 +1887,594 @@ unsigned char *smb_GetSMBData(smb_packet_t *smbp, int *nbytesp) */ void smb_SetSMBDataLength(smb_packet_t *smbp, unsigned int dsize) { - unsigned char *afterParmsp; + unsigned char *afterParmsp; - afterParmsp = smbp->wctp + ((*smbp->wctp)<<1) + 1; + afterParmsp = smbp->wctp + ((*smbp->wctp)<<1) + 1; - *afterParmsp++ = dsize & 0xff; - *afterParmsp = (dsize>>8) & 0xff; -} + *afterParmsp++ = dsize & 0xff; + *afterParmsp = (dsize>>8) & 0xff; +} /* return the parm'th parameter in the smbp packet */ unsigned int smb_GetSMBParm(smb_packet_t *smbp, int parm) { - int parmCount; - unsigned char *parmDatap; + int parmCount; + unsigned char *parmDatap; - parmCount = *smbp->wctp; + parmCount = *smbp->wctp; - if (parm >= parmCount) { - char s[100]; + if (parm >= parmCount) { + char s[100]; #ifndef DJGPP HANDLE h; - char *ptbuf[1]; - h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME); -#endif - sprintf(s, "Bad SMB param %d out of %d, ncb len %d", - parm, parmCount, smbp->ncb_length); -#ifndef DJGPP - ptbuf[0] = s; - ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, 1006, NULL, - 1, smbp->ncb_length, ptbuf, smbp); - DeregisterEventSource(h); + char *ptbuf[1]; + h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME); +#endif + sprintf(s, "Bad SMB param %d out of %d, ncb len %d", + parm, parmCount, smbp->ncb_length); +#ifndef DJGPP + ptbuf[0] = s; + ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, 1006, NULL, + 1, smbp->ncb_length, ptbuf, smbp); + DeregisterEventSource(h); #endif osi_Log0(smb_logp, osi_LogSaveString(smb_logp, s)); - osi_panic(s, __FILE__, __LINE__); - } - parmDatap = smbp->wctp + (2*parm) + 1; + osi_panic(s, __FILE__, __LINE__); + } + parmDatap = smbp->wctp + (2*parm) + 1; - return parmDatap[0] + (parmDatap[1] << 8); + return parmDatap[0] + (parmDatap[1] << 8); } /* return the parm'th parameter in the smbp packet */ unsigned int smb_GetSMBOffsetParm(smb_packet_t *smbp, int parm, int offset) { - int parmCount; - unsigned char *parmDatap; + int parmCount; + unsigned char *parmDatap; - parmCount = *smbp->wctp; + parmCount = *smbp->wctp; - if (parm * 2 + offset >= parmCount * 2) { - char s[100]; + if (parm * 2 + offset >= parmCount * 2) { + char s[100]; #ifndef DJGPP - HANDLE h; - char *ptbuf[1]; - h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME); + HANDLE h; + char *ptbuf[1]; + h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME); #endif - sprintf(s, "Bad SMB param %d offset %d out of %d, ncb len %d", - parm, offset, parmCount, smbp->ncb_length); + sprintf(s, "Bad SMB param %d offset %d out of %d, ncb len %d", + parm, offset, parmCount, smbp->ncb_length); #ifndef DJGPP ptbuf[0] = s; - ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, 1006, NULL, - 1, smbp->ncb_length, ptbuf, smbp); - DeregisterEventSource(h); + ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, 1006, NULL, + 1, smbp->ncb_length, ptbuf, smbp); + DeregisterEventSource(h); #endif osi_Log0(smb_logp, osi_LogSaveString(smb_logp, s)); - osi_panic(s, __FILE__, __LINE__); - } - parmDatap = smbp->wctp + (2*parm) + 1 + offset; + osi_panic(s, __FILE__, __LINE__); + } + parmDatap = smbp->wctp + (2*parm) + 1 + offset; - return parmDatap[0] + (parmDatap[1] << 8); + return parmDatap[0] + (parmDatap[1] << 8); } void smb_SetSMBParm(smb_packet_t *smbp, int slot, unsigned int parmValue) { - char *parmDatap; + char *parmDatap; - /* make sure we have enough slots */ - if (*smbp->wctp <= slot) *smbp->wctp = slot+1; + /* make sure we have enough slots */ + if (*smbp->wctp <= slot) + *smbp->wctp = slot+1; - parmDatap = smbp->wctp + 2*slot + 1 + smbp->oddByte; - *parmDatap++ = parmValue & 0xff; - *parmDatap = (parmValue>>8) & 0xff; -} + parmDatap = smbp->wctp + 2*slot + 1 + smbp->oddByte; + *parmDatap++ = parmValue & 0xff; + *parmDatap = (parmValue>>8) & 0xff; +} void smb_SetSMBParmLong(smb_packet_t *smbp, int slot, unsigned int parmValue) { - char *parmDatap; + char *parmDatap; - /* make sure we have enough slots */ - if (*smbp->wctp <= slot) *smbp->wctp = slot+2; + /* make sure we have enough slots */ + if (*smbp->wctp <= slot) + *smbp->wctp = slot+2; - parmDatap = smbp->wctp + 2*slot + 1 + smbp->oddByte; - *parmDatap++ = parmValue & 0xff; - *parmDatap++ = (parmValue>>8) & 0xff; - *parmDatap++ = (parmValue>>16) & 0xff; - *parmDatap++ = (parmValue>>24) & 0xff; + parmDatap = smbp->wctp + 2*slot + 1 + smbp->oddByte; + *parmDatap++ = parmValue & 0xff; + *parmDatap++ = (parmValue>>8) & 0xff; + *parmDatap++ = (parmValue>>16) & 0xff; + *parmDatap++ = (parmValue>>24) & 0xff; } void smb_SetSMBParmDouble(smb_packet_t *smbp, int slot, char *parmValuep) { - char *parmDatap; - int i; + char *parmDatap; + int i; - /* make sure we have enough slots */ - if (*smbp->wctp <= slot) *smbp->wctp = slot+4; + /* make sure we have enough slots */ + if (*smbp->wctp <= slot) + *smbp->wctp = slot+4; - parmDatap = smbp->wctp + 2*slot + 1 + smbp->oddByte; - for (i=0; i<8; i++) - *parmDatap++ = *parmValuep++; -} + parmDatap = smbp->wctp + 2*slot + 1 + smbp->oddByte; + for (i=0; i<8; i++) + *parmDatap++ = *parmValuep++; +} void smb_SetSMBParmByte(smb_packet_t *smbp, int slot, unsigned int parmValue) { - char *parmDatap; - - /* make sure we have enough slots */ - if (*smbp->wctp <= slot) { - if (smbp->oddByte) { - smbp->oddByte = 0; - *smbp->wctp = slot+1; - } else - smbp->oddByte = 1; - } - - parmDatap = smbp->wctp + 2*slot + 1 + (1 - smbp->oddByte); - *parmDatap++ = parmValue & 0xff; + char *parmDatap; + + /* make sure we have enough slots */ + if (*smbp->wctp <= slot) { + if (smbp->oddByte) { + smbp->oddByte = 0; + *smbp->wctp = slot+1; + } else + smbp->oddByte = 1; + } + + parmDatap = smbp->wctp + 2*slot + 1 + (1 - smbp->oddByte); + *parmDatap++ = parmValue & 0xff; } void smb_StripLastComponent(char *outPathp, char **lastComponentp, char *inPathp) { - char *lastSlashp; + char *lastSlashp; - lastSlashp = strrchr(inPathp, '\\'); - if (lastComponentp) - *lastComponentp = lastSlashp; - if (lastSlashp) { - while (1) { - if (inPathp == lastSlashp) - break; - *outPathp++ = *inPathp++; - } - *outPathp++ = 0; - } - else { - *outPathp++ = 0; - } + lastSlashp = strrchr(inPathp, '\\'); + if (lastComponentp) + *lastComponentp = lastSlashp; + if (lastSlashp) { + while (1) { + if (inPathp == lastSlashp) + break; + *outPathp++ = *inPathp++; + } + *outPathp++ = 0; + } + else { + *outPathp++ = 0; + } } unsigned char *smb_ParseASCIIBlock(unsigned char *inp, char **chainpp) { - if (*inp++ != 0x4) - return NULL; - if (chainpp) { - *chainpp = inp + strlen(inp) + 1; /* skip over null-terminated string */ - } - return inp; + if (*inp++ != 0x4) + return NULL; + if (chainpp) { + *chainpp = inp + strlen(inp) + 1; /* skip over null-terminated string */ + } + return inp; } unsigned char *smb_ParseVblBlock(unsigned char *inp, char **chainpp, int *lengthp) { - int tlen; + int tlen; - if (*inp++ != 0x5) - return NULL; - tlen = inp[0] + (inp[1]<<8); - inp += 2; /* skip length field */ - - if (chainpp) { - *chainpp = inp + tlen; - } + if (*inp++ != 0x5) + return NULL; + tlen = inp[0] + (inp[1]<<8); + inp += 2; /* skip length field */ + + if (chainpp) { + *chainpp = inp + tlen; + } - if (lengthp) - *lengthp = tlen; + if (lengthp) + *lengthp = tlen; - return inp; + return inp; } /* format a packet as a response */ void smb_FormatResponsePacket(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *op) { - smb_t *outp; - smb_t *inSmbp; + smb_t *outp; + smb_t *inSmbp; - outp = (smb_t *) op; + outp = (smb_t *) op; - /* zero the basic structure through the smb_wct field, and zero the data - * size field, assuming that wct stays zero; otherwise, you have to - * explicitly set the data size field, too. - */ - inSmbp = (smb_t *) inp; - memset(outp, 0, sizeof(smb_t)+2); - outp->id[0] = 0xff; - outp->id[1] = 'S'; - outp->id[2] = 'M'; - outp->id[3] = 'B'; - if (inp) { - outp->com = inSmbp->com; - outp->tid = inSmbp->tid; - outp->pid = inSmbp->pid; - outp->uid = inSmbp->uid; - outp->mid = inSmbp->mid; - outp->res[0] = inSmbp->res[0]; - outp->res[1] = inSmbp->res[1]; - op->inCom = inSmbp->com; - } - outp->reb = 0x80; /* SERVER_RESP */ - outp->flg2 = 0x1; /* KNOWS_LONG_NAMES */ - - /* copy fields in generic packet area */ - op->wctp = &outp->wct; -} + /* zero the basic structure through the smb_wct field, and zero the data + * size field, assuming that wct stays zero; otherwise, you have to + * explicitly set the data size field, too. + */ + inSmbp = (smb_t *) inp; + memset(outp, 0, sizeof(smb_t)+2); + outp->id[0] = 0xff; + outp->id[1] = 'S'; + outp->id[2] = 'M'; + outp->id[3] = 'B'; + if (inp) { + outp->com = inSmbp->com; + outp->tid = inSmbp->tid; + outp->pid = inSmbp->pid; + outp->uid = inSmbp->uid; + outp->mid = inSmbp->mid; + outp->res[0] = inSmbp->res[0]; + outp->res[1] = inSmbp->res[1]; + op->inCom = inSmbp->com; + } + outp->reb = 0x80; /* SERVER_RESP */ + outp->flg2 = 0x1; /* KNOWS_LONG_NAMES */ + + /* copy fields in generic packet area */ + op->wctp = &outp->wct; +} /* send a (probably response) packet; vcp tells us to whom to send it. * we compute the length by looking at wct and bcc fields. */ void smb_SendPacket(smb_vc_t *vcp, smb_packet_t *inp) { - NCB *ncbp; - int extra; - long code = 0; - unsigned char *tp; - int localNCB = 0; + NCB *ncbp; + int extra; + long code = 0; + unsigned char *tp; + int localNCB = 0; #ifdef DJGPP - dos_ptr dos_ncb; + dos_ptr dos_ncb; #endif /* DJGPP */ - ncbp = inp->ncbp; - if (ncbp == NULL) { - ncbp = GetNCB(); - localNCB = 1; - } + ncbp = inp->ncbp; + if (ncbp == NULL) { + ncbp = GetNCB(); + localNCB = 1; + } #ifdef DJGPP - dos_ncb = ((smb_ncb_t *)ncbp)->dos_ncb; + dos_ncb = ((smb_ncb_t *)ncbp)->dos_ncb; #endif /* DJGPP */ - memset((char *)ncbp, 0, sizeof(NCB)); + memset((char *)ncbp, 0, sizeof(NCB)); - extra = 2 * (*inp->wctp); /* space used by parms, in bytes */ - tp = inp->wctp + 1+ extra; /* points to count of data bytes */ - extra += tp[0] + (tp[1]<<8); - extra += ((unsigned int)inp->wctp - (unsigned int)inp->data); /* distance to last wct field */ - extra += 3; /* wct and length fields */ + extra = 2 * (*inp->wctp); /* space used by parms, in bytes */ + tp = inp->wctp + 1+ extra; /* points to count of data bytes */ + extra += tp[0] + (tp[1]<<8); + extra += ((unsigned int)inp->wctp - (unsigned int)inp->data); /* distance to last wct field */ + extra += 3; /* wct and length fields */ - ncbp->ncb_length = extra; /* bytes to send */ - ncbp->ncb_lsn = (unsigned char) vcp->lsn; /* vc to use */ - ncbp->ncb_lana_num = vcp->lana; - ncbp->ncb_command = NCBSEND; /* op means send data */ + ncbp->ncb_length = extra; /* bytes to send */ + ncbp->ncb_lsn = (unsigned char) vcp->lsn; /* vc to use */ + ncbp->ncb_lana_num = vcp->lana; + ncbp->ncb_command = NCBSEND; /* op means send data */ #ifndef DJGPP - ncbp->ncb_buffer = (char *) inp;/* packet */ - code = Netbios(ncbp); + ncbp->ncb_buffer = (char *) inp;/* packet */ + code = Netbios(ncbp); #else /* DJGPP */ - ncbp->ncb_buffer = inp->dos_pkt;/* packet */ - ((smb_ncb_t*)ncbp)->orig_pkt = inp; + ncbp->ncb_buffer = inp->dos_pkt;/* packet */ + ((smb_ncb_t*)ncbp)->orig_pkt = inp; - /* copy header information from virtual to DOS address space */ - dosmemput((char*)inp, SMB_PACKETSIZE, inp->dos_pkt); - code = Netbios(ncbp, dos_ncb); + /* copy header information from virtual to DOS address space */ + dosmemput((char*)inp, SMB_PACKETSIZE, inp->dos_pkt); + code = Netbios(ncbp, dos_ncb); #endif /* !DJGPP */ - if (code != 0) - osi_Log1(smb_logp, "SendPacket failure code %d", code); + if (code != 0) + osi_Log1(smb_logp, "SendPacket failure code %d", code); - if (localNCB) - FreeNCB(ncbp); + if (localNCB) + FreeNCB(ncbp); } void smb_MapNTError(long code, unsigned long *NTStatusp) { - unsigned long NTStatus; + unsigned long NTStatus; - /* map CM_ERROR_* errors to NT 32-bit status codes */ + /* map CM_ERROR_* errors to NT 32-bit status codes */ /* NT Status codes are listed in ntstatus.h not winerror.h */ - if (code == CM_ERROR_NOSUCHCELL) { - NTStatus = 0xC000000FL; /* No such file */ - } - else if (code == CM_ERROR_NOSUCHVOLUME) { - NTStatus = 0xC000000FL; /* No such file */ - } - else if (code == CM_ERROR_TIMEDOUT) { - NTStatus = 0xC00000CFL; /* Sharing Paused */ - } - else if (code == CM_ERROR_RETRY) { - NTStatus = 0xC000022DL; /* Retry */ - } - else if (code == CM_ERROR_NOACCESS) { - NTStatus = 0xC0000022L; /* Access denied */ - } - else if (code == CM_ERROR_READONLY) { - NTStatus = 0xC00000A2L; /* Write protected */ - } - else if (code == CM_ERROR_NOSUCHFILE) { - NTStatus = 0xC000000FL; /* No such file */ - } - else if (code == CM_ERROR_NOSUCHPATH) { - NTStatus = 0xC000003AL; /* Object path not found */ - } - else if (code == CM_ERROR_TOOBIG) { - NTStatus = 0xC000007BL; /* Invalid image format */ - } - else if (code == CM_ERROR_INVAL) { - NTStatus = 0xC000000DL; /* Invalid parameter */ - } - else if (code == CM_ERROR_BADFD) { - NTStatus = 0xC0000008L; /* Invalid handle */ - } - else if (code == CM_ERROR_BADFDOP) { - NTStatus = 0xC0000022L; /* Access denied */ - } - else if (code == CM_ERROR_EXISTS) { - NTStatus = 0xC0000035L; /* Object name collision */ - } - else if (code == CM_ERROR_NOTEMPTY) { - NTStatus = 0xC0000101L; /* Directory not empty */ - } - else if (code == CM_ERROR_CROSSDEVLINK) { - NTStatus = 0xC00000D4L; /* Not same device */ - } - else if (code == CM_ERROR_NOTDIR) { - NTStatus = 0xC0000103L; /* Not a directory */ - } - else if (code == CM_ERROR_ISDIR) { - NTStatus = 0xC00000BAL; /* File is a directory */ - } - else if (code == CM_ERROR_BADOP) { - NTStatus = 0xC09820FFL; /* SMB no support */ - } - else if (code == CM_ERROR_BADSHARENAME) { - NTStatus = 0xC00000CCL; /* Bad network name */ - } - else if (code == CM_ERROR_NOIPC) { -#ifdef COMMENT - NTStatus = 0xC0000022L; /* Access Denied */ -#else - NTStatus = 0xC000013DL; /* Remote Resources */ + if (code == CM_ERROR_NOSUCHCELL) { + NTStatus = 0xC000000FL; /* No such file */ + } + else if (code == CM_ERROR_NOSUCHVOLUME) { + NTStatus = 0xC000000FL; /* No such file */ + } + else if (code == CM_ERROR_TIMEDOUT) { + NTStatus = 0xC00000CFL; /* Sharing Paused */ + } + else if (code == CM_ERROR_RETRY) { + NTStatus = 0xC000022DL; /* Retry */ + } + else if (code == CM_ERROR_NOACCESS) { + NTStatus = 0xC0000022L; /* Access denied */ + } + else if (code == CM_ERROR_READONLY) { + NTStatus = 0xC00000A2L; /* Write protected */ + } + else if (code == CM_ERROR_NOSUCHFILE) { + NTStatus = 0xC000000FL; /* No such file */ + } + else if (code == CM_ERROR_NOSUCHPATH) { + NTStatus = 0xC000003AL; /* Object path not found */ + } + else if (code == CM_ERROR_TOOBIG) { + NTStatus = 0xC000007BL; /* Invalid image format */ + } + else if (code == CM_ERROR_INVAL) { + NTStatus = 0xC000000DL; /* Invalid parameter */ + } + else if (code == CM_ERROR_BADFD) { + NTStatus = 0xC0000008L; /* Invalid handle */ + } + else if (code == CM_ERROR_BADFDOP) { + NTStatus = 0xC0000022L; /* Access denied */ + } + else if (code == CM_ERROR_EXISTS) { + NTStatus = 0xC0000035L; /* Object name collision */ + } + else if (code == CM_ERROR_NOTEMPTY) { + NTStatus = 0xC0000101L; /* Directory not empty */ + } + else if (code == CM_ERROR_CROSSDEVLINK) { + NTStatus = 0xC00000D4L; /* Not same device */ + } + else if (code == CM_ERROR_NOTDIR) { + NTStatus = 0xC0000103L; /* Not a directory */ + } + else if (code == CM_ERROR_ISDIR) { + NTStatus = 0xC00000BAL; /* File is a directory */ + } + else if (code == CM_ERROR_BADOP) { +#ifdef COMMENT + /* I have no idea where this comes from */ + NTStatus = 0xC09820FFL; /* SMB no support */ +#else + NTStatus = 0xC00000BBL; /* Not supported */ +#endif /* COMMENT */ + } + else if (code == CM_ERROR_BADSHARENAME) { + NTStatus = 0xC00000CCL; /* Bad network name */ + } + else if (code == CM_ERROR_NOIPC) { +#ifdef COMMENT + NTStatus = 0xC0000022L; /* Access Denied */ +#else + NTStatus = 0xC000013DL; /* Remote Resources */ +#endif + } + else if (code == CM_ERROR_CLOCKSKEW) { + NTStatus = 0xC0000133L; /* Time difference at DC */ + } + else if (code == CM_ERROR_BADTID) { + NTStatus = 0xC0982005L; /* SMB bad TID */ + } + else if (code == CM_ERROR_USESTD) { + NTStatus = 0xC09820FBL; /* SMB use standard */ + } + else if (code == CM_ERROR_QUOTA) { +#ifdef COMMENT + NTStatus = 0xC0000044L; /* Quota exceeded */ +#else + NTStatus = 0xC000007FL; /* Disk full */ #endif - } - else if (code == CM_ERROR_CLOCKSKEW) { - NTStatus = 0xC0000133L; /* Time difference at DC */ - } - else if (code == CM_ERROR_BADTID) { - NTStatus = 0xC0982005L; /* SMB bad TID */ - } - else if (code == CM_ERROR_USESTD) { - NTStatus = 0xC09820FBL; /* SMB use standard */ - } - else if (code == CM_ERROR_QUOTA) { - NTStatus = 0xC0000044L; /* Quota exceeded */ - } - else if (code == CM_ERROR_SPACE) { - NTStatus = 0xC000007FL; /* Disk full */ - } - else if (code == CM_ERROR_ATSYS) { - NTStatus = 0xC0000033L; /* Object name invalid */ - } - else if (code == CM_ERROR_BADNTFILENAME) { - NTStatus = 0xC0000033L; /* Object name invalid */ - } - else if (code == CM_ERROR_WOULDBLOCK) { - NTStatus = 0xC0000055L; /* Lock not granted */ - } - else if (code == CM_ERROR_PARTIALWRITE) { - NTStatus = 0xC000007FL; /* Disk full */ - } - else if (code == CM_ERROR_BUFFERTOOSMALL) { - NTStatus = 0xC0000023L; /* Buffer too small */ - } + } + else if (code == CM_ERROR_SPACE) { + NTStatus = 0xC000007FL; /* Disk full */ + } + else if (code == CM_ERROR_ATSYS) { + NTStatus = 0xC0000033L; /* Object name invalid */ + } + else if (code == CM_ERROR_BADNTFILENAME) { + NTStatus = 0xC0000033L; /* Object name invalid */ + } + else if (code == CM_ERROR_WOULDBLOCK) { + NTStatus = 0xC0000055L; /* Lock not granted */ + } + else if (code == CM_ERROR_PARTIALWRITE) { + NTStatus = 0xC000007FL; /* Disk full */ + } + else if (code == CM_ERROR_BUFFERTOOSMALL) { + NTStatus = 0xC0000023L; /* Buffer too small */ + } else if (code == CM_ERROR_AMBIGUOUS_FILENAME) { - NTStatus = 0xC0000035L; /* Object name collision */ - } - else if (code == CM_ERROR_BADPASSWORD) { - NTStatus = 0xC000006DL; /* unknown username or bad password */ - } - else if (code == CM_ERROR_BADLOGONTYPE) { - NTStatus = 0xC000015BL; /* logon type not granted */ - } - else if (code == CM_ERROR_GSSCONTINUE) { - NTStatus = 0xC0000016L; /* more processing required */ - } - else { - NTStatus = 0xC0982001L; /* SMB non-specific error */ - } - - *NTStatusp = NTStatus; - osi_Log2(smb_logp, "SMB SEND code %lX as NT %lX", code, NTStatus); -} + NTStatus = 0xC0000035L; /* Object name collision */ + } + else if (code == CM_ERROR_BADPASSWORD) { + NTStatus = 0xC000006DL; /* unknown username or bad password */ + } + else if (code == CM_ERROR_BADLOGONTYPE) { + NTStatus = 0xC000015BL; /* logon type not granted */ + } + else if (code == CM_ERROR_GSSCONTINUE) { + NTStatus = 0xC0000016L; /* more processing required */ + } + else { + NTStatus = 0xC0982001L; /* SMB non-specific error */ + } + + *NTStatusp = NTStatus; + osi_Log2(smb_logp, "SMB SEND code %lX as NT %lX", code, NTStatus); +} void smb_MapCoreError(long code, smb_vc_t *vcp, unsigned short *scodep, - unsigned char *classp) + unsigned char *classp) { - unsigned char class; - unsigned short error; - - /* map CM_ERROR_* errors to SMB errors */ - if (code == CM_ERROR_NOSUCHCELL) { - class = 1; - error = 3; /* bad path */ - } - else if (code == CM_ERROR_NOSUCHVOLUME) { - class = 1; - error = 3; /* bad path */ - } - else if (code == CM_ERROR_TIMEDOUT) { - class = 2; - error = 81; /* server is paused */ - } - else if (code == CM_ERROR_RETRY) { - class = 2; /* shouldn't happen */ - error = 1; - } - else if (code == CM_ERROR_NOACCESS) { - class = 2; - error = 4; /* bad access */ - } - else if (code == CM_ERROR_READONLY) { - class = 3; - error = 19; /* read only */ - } - else if (code == CM_ERROR_NOSUCHFILE) { - class = 1; - error = 2; /* ENOENT! */ - } - else if (code == CM_ERROR_NOSUCHPATH) { - class = 1; - error = 3; /* Bad path */ - } - else if (code == CM_ERROR_TOOBIG) { - class = 1; - error = 11; /* bad format */ - } - else if (code == CM_ERROR_INVAL) { - class = 2; /* server non-specific error code */ - error = 1; - } - else if (code == CM_ERROR_BADFD) { - class = 1; - error = 6; /* invalid file handle */ - } - else if (code == CM_ERROR_BADFDOP) { - class = 1; /* invalid op on FD */ - error = 5; - } - else if (code == CM_ERROR_EXISTS) { - class = 1; - error = 80; /* file already exists */ - } - else if (code == CM_ERROR_NOTEMPTY) { - class = 1; - error = 5; /* delete directory not empty */ - } - else if (code == CM_ERROR_CROSSDEVLINK) { - class = 1; - error = 17; /* EXDEV */ - } - else if (code == CM_ERROR_NOTDIR) { - class = 1; /* bad path */ - error = 3; - } - else if (code == CM_ERROR_ISDIR) { - class = 1; /* access denied; DOS doesn't have a good match */ - error = 5; - } - else if (code == CM_ERROR_BADOP) { - class = 2; - error = 65535; - } - else if (code == CM_ERROR_BADSHARENAME) { - class = 2; - error = 6; - } - else if (code == CM_ERROR_NOIPC) { - class = 2; - error = 4; /* bad access */ - } - else if (code == CM_ERROR_CLOCKSKEW) { - class = 1; /* invalid function */ - error = 1; - } - else if (code == CM_ERROR_BADTID) { - class = 2; - error = 5; - } - else if (code == CM_ERROR_USESTD) { - class = 2; - error = 251; - } - else if (code == CM_ERROR_REMOTECONN) { - class = 2; - error = 82; - } - else if (code == CM_ERROR_QUOTA) { - if (vcp->flags & SMB_VCFLAG_USEV3) { - class = 3; - error = 39; /* disk full */ - } - else { - class = 1; - error = 5; /* access denied */ - } - } - else if (code == CM_ERROR_SPACE) { - if (vcp->flags & SMB_VCFLAG_USEV3) { - class = 3; - error = 39; /* disk full */ - } - else { - class = 1; - error = 5; /* access denied */ - } - } - else if (code == CM_ERROR_PARTIALWRITE) { - class = 3; - error = 39; /* disk full */ - } - else if (code == CM_ERROR_ATSYS) { - class = 1; - error = 2; /* ENOENT */ - } - else if (code == CM_ERROR_WOULDBLOCK) { - class = 1; - error = 33; /* lock conflict */ - } - else if (code == CM_ERROR_NOFILES) { - class = 1; - error = 18; /* no files in search */ - } - else if (code == CM_ERROR_RENAME_IDENTICAL) { - class = 1; - error = 183; /* Samba uses this */ - } - else if (code == CM_ERROR_BADPASSWORD || code == CM_ERROR_BADLOGONTYPE) { - /* we don't have a good way of reporting CM_ERROR_BADLOGONTYPE */ - class = 2; - error = 2; /* bad password */ - } - else { - class = 2; - error = 1; - } - - *scodep = error; - *classp = class; - osi_Log3(smb_logp, "SMB SEND code %lX as SMB %d: %d", code, class, error); -} + unsigned char class; + unsigned short error; + + /* map CM_ERROR_* errors to SMB errors */ + if (code == CM_ERROR_NOSUCHCELL) { + class = 1; + error = 3; /* bad path */ + } + else if (code == CM_ERROR_NOSUCHVOLUME) { + class = 1; + error = 3; /* bad path */ + } + else if (code == CM_ERROR_TIMEDOUT) { + class = 2; + error = 81; /* server is paused */ + } + else if (code == CM_ERROR_RETRY) { + class = 2; /* shouldn't happen */ + error = 1; + } + else if (code == CM_ERROR_NOACCESS) { + class = 2; + error = 4; /* bad access */ + } + else if (code == CM_ERROR_READONLY) { + class = 3; + error = 19; /* read only */ + } + else if (code == CM_ERROR_NOSUCHFILE) { + class = 1; + error = 2; /* ENOENT! */ + } + else if (code == CM_ERROR_NOSUCHPATH) { + class = 1; + error = 3; /* Bad path */ + } + else if (code == CM_ERROR_TOOBIG) { + class = 1; + error = 11; /* bad format */ + } + else if (code == CM_ERROR_INVAL) { + class = 2; /* server non-specific error code */ + error = 1; + } + else if (code == CM_ERROR_BADFD) { + class = 1; + error = 6; /* invalid file handle */ + } + else if (code == CM_ERROR_BADFDOP) { + class = 1; /* invalid op on FD */ + error = 5; + } + else if (code == CM_ERROR_EXISTS) { + class = 1; + error = 80; /* file already exists */ + } + else if (code == CM_ERROR_NOTEMPTY) { + class = 1; + error = 5; /* delete directory not empty */ + } + else if (code == CM_ERROR_CROSSDEVLINK) { + class = 1; + error = 17; /* EXDEV */ + } + else if (code == CM_ERROR_NOTDIR) { + class = 1; /* bad path */ + error = 3; + } + else if (code == CM_ERROR_ISDIR) { + class = 1; /* access denied; DOS doesn't have a good match */ + error = 5; + } + else if (code == CM_ERROR_BADOP) { + class = 2; + error = 65535; + } + else if (code == CM_ERROR_BADSHARENAME) { + class = 2; + error = 6; + } + else if (code == CM_ERROR_NOIPC) { + class = 2; + error = 4; /* bad access */ + } + else if (code == CM_ERROR_CLOCKSKEW) { + class = 1; /* invalid function */ + error = 1; + } + else if (code == CM_ERROR_BADTID) { + class = 2; + error = 5; + } + else if (code == CM_ERROR_USESTD) { + class = 2; + error = 251; + } + else if (code == CM_ERROR_REMOTECONN) { + class = 2; + error = 82; + } + else if (code == CM_ERROR_QUOTA) { + if (vcp->flags & SMB_VCFLAG_USEV3) { + class = 3; + error = 39; /* disk full */ + } + else { + class = 1; + error = 5; /* access denied */ + } + } + else if (code == CM_ERROR_SPACE) { + if (vcp->flags & SMB_VCFLAG_USEV3) { + class = 3; + error = 39; /* disk full */ + } + else { + class = 1; + error = 5; /* access denied */ + } + } + else if (code == CM_ERROR_PARTIALWRITE) { + class = 3; + error = 39; /* disk full */ + } + else if (code == CM_ERROR_ATSYS) { + class = 1; + error = 2; /* ENOENT */ + } + else if (code == CM_ERROR_WOULDBLOCK) { + class = 1; + error = 33; /* lock conflict */ + } + else if (code == CM_ERROR_NOFILES) { + class = 1; + error = 18; /* no files in search */ + } + else if (code == CM_ERROR_RENAME_IDENTICAL) { + class = 1; + error = 183; /* Samba uses this */ + } + else if (code == CM_ERROR_BADPASSWORD || code == CM_ERROR_BADLOGONTYPE) { + /* we don't have a good way of reporting CM_ERROR_BADLOGONTYPE */ + class = 2; + error = 2; /* bad password */ + } + else { + class = 2; + error = 1; + } + + *scodep = error; + *classp = class; + osi_Log3(smb_logp, "SMB SEND code %lX as SMB %d: %d", code, class, error); +} long smb_SendCoreBadOp(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - return CM_ERROR_BADOP; + osi_Log0(smb_logp,"SendCoreBadOp - NOT_SUPPORTED"); + return CM_ERROR_BADOP; } long smb_ReceiveCoreEcho(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - unsigned short EchoCount, i; - char *data, *outdata; - int dataSize; - - EchoCount = (unsigned short) smb_GetSMBParm(inp, 0); - - for (i=1; i<=EchoCount; i++) { - data = smb_GetSMBData(inp, &dataSize); - smb_SetSMBParm(outp, 0, i); - smb_SetSMBDataLength(outp, dataSize); - outdata = smb_GetSMBData(outp, NULL); - memcpy(outdata, data, dataSize); - smb_SendPacket(vcp, outp); - } - - return 0; + unsigned short EchoCount, i; + char *data, *outdata; + int dataSize; + + EchoCount = (unsigned short) smb_GetSMBParm(inp, 0); + + for (i=1; i<=EchoCount; i++) { + data = smb_GetSMBData(inp, &dataSize); + smb_SetSMBParm(outp, 0, i); + smb_SetSMBDataLength(outp, dataSize); + outdata = smb_GetSMBData(outp, NULL); + memcpy(outdata, data, dataSize); + smb_SendPacket(vcp, outp); + } + + return 0; } long smb_ReceiveCoreReadRaw(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - osi_hyper_t offset; - long count, minCount, finalCount; - unsigned short fd; - smb_fid_t *fidp; - long code = 0; - cm_user_t *userp = NULL; + osi_hyper_t offset; + long count, minCount, finalCount; + unsigned short fd; + smb_fid_t *fidp; + long code = 0; + cm_user_t *userp = NULL; NCB *ncbp; int rc; #ifndef DJGPP @@ -2458,35 +2484,35 @@ long smb_ReceiveCoreReadRaw(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp dos_ptr dos_ncb; #endif /* DJGPP */ - rawBuf = NULL; - finalCount = 0; + rawBuf = NULL; + finalCount = 0; - fd = smb_GetSMBParm(inp, 0); - count = smb_GetSMBParm(inp, 3); - minCount = smb_GetSMBParm(inp, 4); - offset.HighPart = 0; /* too bad */ - offset.LowPart = smb_GetSMBParm(inp, 1) | (smb_GetSMBParm(inp, 2) << 16); + fd = smb_GetSMBParm(inp, 0); + count = smb_GetSMBParm(inp, 3); + minCount = smb_GetSMBParm(inp, 4); + offset.HighPart = 0; /* too bad */ + offset.LowPart = smb_GetSMBParm(inp, 1) | (smb_GetSMBParm(inp, 2) << 16); - osi_Log3(smb_logp, "smb_ReceieveCoreReadRaw fd %d, off 0x%x, size 0x%x", + osi_Log3(smb_logp, "smb_ReceieveCoreReadRaw fd %d, off 0x%x, size 0x%x", fd, offset.LowPart, count); - fidp = smb_FindFID(vcp, fd, 0); - if (!fidp) - goto send1; + fidp = smb_FindFID(vcp, fd, 0); + if (!fidp) + goto send1; - lock_ObtainMutex(&smb_RawBufLock); - if (smb_RawBufs) { - /* Get a raw buf, from head of list */ - rawBuf = smb_RawBufs; + lock_ObtainMutex(&smb_RawBufLock); + if (smb_RawBufs) { + /* Get a raw buf, from head of list */ + rawBuf = smb_RawBufs; #ifndef DJGPP - smb_RawBufs = *(char **)smb_RawBufs; + smb_RawBufs = *(char **)smb_RawBufs; #else /* DJGPP */ smb_RawBufs = _farpeekl(_dos_ds, smb_RawBufs); #endif /* !DJGPP */ - } - lock_ReleaseMutex(&smb_RawBufLock); - if (!rawBuf) - goto send1a; + } + lock_ReleaseMutex(&smb_RawBufLock); + if (!rawBuf) + goto send1a; if (fidp->flags & SMB_FID_IOCTL) { @@ -2515,173 +2541,177 @@ long smb_ReceiveCoreReadRaw(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp userp = smb_GetUser(vcp, inp); #ifndef DJGPP - code = smb_ReadData(fidp, &offset, count, rawBuf, userp, &finalCount); + code = smb_ReadData(fidp, &offset, count, rawBuf, userp, &finalCount); #else /* DJGPP */ /* have to give ReadData flag so it will treat buffer as DOS mem. */ code = smb_ReadData(fidp, &offset, count, (unsigned char *)rawBuf, userp, &finalCount, TRUE /* rawFlag */); #endif /* !DJGPP */ - if (code != 0) - goto send; + if (code != 0) + goto send; send: cm_ReleaseUser(userp); send1a: - smb_ReleaseFID(fidp); + smb_ReleaseFID(fidp); send1: - ncbp = outp->ncbp; + ncbp = outp->ncbp; #ifdef DJGPP dos_ncb = ((smb_ncb_t *)ncbp)->dos_ncb; #endif /* DJGPP */ - memset((char *)ncbp, 0, sizeof(NCB)); + memset((char *)ncbp, 0, sizeof(NCB)); - ncbp->ncb_length = (unsigned short) finalCount; - ncbp->ncb_lsn = (unsigned char) vcp->lsn; - ncbp->ncb_lana_num = vcp->lana; - ncbp->ncb_command = NCBSEND; - ncbp->ncb_buffer = rawBuf; + ncbp->ncb_length = (unsigned short) finalCount; + ncbp->ncb_lsn = (unsigned char) vcp->lsn; + ncbp->ncb_lana_num = vcp->lana; + ncbp->ncb_command = NCBSEND; + ncbp->ncb_buffer = rawBuf; #ifndef DJGPP - code = Netbios(ncbp); + code = Netbios(ncbp); #else /* DJGPP */ - code = Netbios(ncbp, dos_ncb); + code = Netbios(ncbp, dos_ncb); #endif /* !DJGPP */ - if (code != 0) - osi_Log1(smb_logp, "ReadRaw send failure code %d", code); + if (code != 0) + osi_Log1(smb_logp, "ReadRaw send failure code %d", code); - if (rawBuf) { - /* Give back raw buffer */ - lock_ObtainMutex(&smb_RawBufLock); + if (rawBuf) { + /* Give back raw buffer */ + lock_ObtainMutex(&smb_RawBufLock); #ifndef DJGPP - *((char **) rawBuf) = smb_RawBufs; + *((char **) rawBuf) = smb_RawBufs; #else /* DJGPP */ _farpokel(_dos_ds, rawBuf, smb_RawBufs); #endif /* !DJGPP */ - smb_RawBufs = rawBuf; - lock_ReleaseMutex(&smb_RawBufLock); - } + smb_RawBufs = rawBuf; + lock_ReleaseMutex(&smb_RawBufLock); + } - return 0; + return 0; } long smb_ReceiveCoreLockRecord(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - return 0; + osi_Log1(smb_logp, "SMB receive core lock record (not implemented); %d + 1 ongoing ops", + ongoingOps - 1); + return 0; } long smb_ReceiveCoreUnlockRecord(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - return 0; + osi_Log1(smb_logp, "SMB receive core unlock record (not implemented); %d + 1 ongoing ops", + ongoingOps - 1); + return 0; } long smb_ReceiveNegotiate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - char *namep; + char *namep; char *datap; - int coreProtoIndex; - int v3ProtoIndex; - int NTProtoIndex; - int protoIndex; /* index we're using */ - int namex; - int dbytes; - int entryLength; - int tcounter; - char protocol_array[10][1024]; /* protocol signature of the client */ + int coreProtoIndex; + int v3ProtoIndex; + int NTProtoIndex; + int protoIndex; /* index we're using */ + int namex; + int dbytes; + int entryLength; + int tcounter; + char protocol_array[10][1024]; /* protocol signature of the client */ int caps; /* capabilities */ time_t unixTime; - time_t dosTime; - TIME_ZONE_INFORMATION tzi; + time_t dosTime; + TIME_ZONE_INFORMATION tzi; osi_Log1(smb_logp, "SMB receive negotiate; %d + 1 ongoing ops", ongoingOps - 1); - if (!isGateway) { - if (active_vcp) { - DWORD now = GetCurrentTime(); - if (now - last_msg_time >= 30000 - && now - last_msg_time <= 90000) { - osi_Log1(smb_logp, - "Setting dead_vcp %x", active_vcp); + if (!isGateway) { + if (active_vcp) { + DWORD now = GetCurrentTime(); + if (now - last_msg_time >= 30000 + && now - last_msg_time <= 90000) { + osi_Log1(smb_logp, + "Setting dead_vcp %x", active_vcp); if (dead_vcp) { smb_ReleaseVC(dead_vcp); osi_Log1(smb_logp, - "Previous dead_vcp %x", dead_vcp); + "Previous dead_vcp %x", dead_vcp); } smb_HoldVC(active_vcp); - dead_vcp = active_vcp; - dead_vcp->flags |= SMB_VCFLAG_ALREADYDEAD; - } - } - } - - inp->flags |= SMB_PACKETFLAG_PROFILE_UPDATE_OK; - - namep = smb_GetSMBData(inp, &dbytes); - namex = 0; - tcounter = 0; - coreProtoIndex = -1; /* not found */ - v3ProtoIndex = -1; - NTProtoIndex = -1; - while(namex < dbytes) { - osi_Log1(smb_logp, "Protocol %s", - osi_LogSaveString(smb_logp, namep+1)); - strcpy(protocol_array[tcounter], namep+1); - - /* namep points at the first protocol, or really, a 0x02 - * byte preceding the null-terminated ASCII name. - */ - if (strcmp("PC NETWORK PROGRAM 1.0", namep+1) == 0) { - coreProtoIndex = tcounter; - } - else if (smb_useV3 && strcmp("LM1.2X002", namep+1) == 0) { - v3ProtoIndex = tcounter; - } - else if (smb_useV3 && strcmp("NT LM 0.12", namep+1) == 0) { - NTProtoIndex = tcounter; - } - - /* compute size of protocol entry */ - entryLength = strlen(namep+1); + dead_vcp = active_vcp; + dead_vcp->flags |= SMB_VCFLAG_ALREADYDEAD; + } + } + } + + inp->flags |= SMB_PACKETFLAG_PROFILE_UPDATE_OK; + + namep = smb_GetSMBData(inp, &dbytes); + namex = 0; + tcounter = 0; + coreProtoIndex = -1; /* not found */ + v3ProtoIndex = -1; + NTProtoIndex = -1; + while(namex < dbytes) { + osi_Log1(smb_logp, "Protocol %s", + osi_LogSaveString(smb_logp, namep+1)); + strcpy(protocol_array[tcounter], namep+1); + + /* namep points at the first protocol, or really, a 0x02 + * byte preceding the null-terminated ASCII name. + */ + if (strcmp("PC NETWORK PROGRAM 1.0", namep+1) == 0) { + coreProtoIndex = tcounter; + } + else if (smb_useV3 && strcmp("LM1.2X002", namep+1) == 0) { + v3ProtoIndex = tcounter; + } + else if (smb_useV3 && strcmp("NT LM 0.12", namep+1) == 0) { + NTProtoIndex = tcounter; + } + + /* compute size of protocol entry */ + entryLength = strlen(namep+1); entryLength += 2; /* 0x02 bytes and null termination */ - + /* advance over this protocol entry */ - namex += entryLength; + namex += entryLength; namep += entryLength; tcounter++; /* which proto entry we're looking at */ - } - - if (NTProtoIndex != -1) { - protoIndex = NTProtoIndex; - vcp->flags |= (SMB_VCFLAG_USENT | SMB_VCFLAG_USEV3); - } - else if (v3ProtoIndex != -1) { - protoIndex = v3ProtoIndex; - vcp->flags |= SMB_VCFLAG_USEV3; - } - else if (coreProtoIndex != -1) { - protoIndex = coreProtoIndex; - vcp->flags |= SMB_VCFLAG_USECORE; - } - else protoIndex = -1; - - if (protoIndex == -1) - return CM_ERROR_INVAL; - else if (NTProtoIndex != -1) { + } + + if (NTProtoIndex != -1) { + protoIndex = NTProtoIndex; + vcp->flags |= (SMB_VCFLAG_USENT | SMB_VCFLAG_USEV3); + } + else if (v3ProtoIndex != -1) { + protoIndex = v3ProtoIndex; + vcp->flags |= SMB_VCFLAG_USEV3; + } + else if (coreProtoIndex != -1) { + protoIndex = coreProtoIndex; + vcp->flags |= SMB_VCFLAG_USECORE; + } + else protoIndex = -1; + + if (protoIndex == -1) + return CM_ERROR_INVAL; + else if (NTProtoIndex != -1) { smb_SetSMBParm(outp, 0, protoIndex); - if (smb_authType != SMB_AUTH_NONE) { - smb_SetSMBParmByte(outp, 1, - NEGOTIATE_SECURITY_USER_LEVEL | - NEGOTIATE_SECURITY_CHALLENGE_RESPONSE); /* user level security, challenge response */ - } else { + if (smb_authType != SMB_AUTH_NONE) { + smb_SetSMBParmByte(outp, 1, + NEGOTIATE_SECURITY_USER_LEVEL | + NEGOTIATE_SECURITY_CHALLENGE_RESPONSE); /* user level security, challenge response */ + } else { smb_SetSMBParmByte(outp, 1, 0); /* share level auth with plaintext password. */ - } + } smb_SetSMBParm(outp, 1, smb_maxMpxRequests); /* max multiplexed requests */ smb_SetSMBParm(outp, 2, smb_maxVCPerServer); /* max VCs per consumer/server connection */ smb_SetSMBParmLong(outp, 3, SMB_PACKETSIZE); /* xmit buffer size */ - smb_SetSMBParmLong(outp, 5, SMB_MAXRAWSIZE); /* raw buffer size */ + smb_SetSMBParmLong(outp, 5, SMB_MAXRAWSIZE); /* raw buffer size */ /* The session key is not a well documented field however most clients * will echo back the session key to the server. Currently we are using * the same value for all sessions. We should generate a random value @@ -2689,129 +2719,129 @@ long smb_ReceiveNegotiate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) */ smb_SetSMBParm(outp, 7, 1); /* next 2: session key */ smb_SetSMBParm(outp, 8, 1); - /* - * Tried changing the capabilities to support for W2K - defect 117695 - * Maybe something else needs to be changed here? - */ - /* - if (isWindows2000) - smb_SetSMBParmLong(outp, 9, 0x43fd); - else - smb_SetSMBParmLong(outp, 9, 0x251); - */ - /* Capabilities: * - * 32-bit error codes * - * and NT Find * - * and NT SMB's * - * and raw mode */ + /* + * Tried changing the capabilities to support for W2K - defect 117695 + * Maybe something else needs to be changed here? + */ + /* + if (isWindows2000) + smb_SetSMBParmLong(outp, 9, 0x43fd); + else + smb_SetSMBParmLong(outp, 9, 0x251); + */ + /* Capabilities: * + * 32-bit error codes * + * and NT Find * + * and NT SMB's * + * and raw mode */ caps = NTNEGOTIATE_CAPABILITY_NTSTATUS | - NTNEGOTIATE_CAPABILITY_NTFIND | + NTNEGOTIATE_CAPABILITY_NTFIND | NTNEGOTIATE_CAPABILITY_RAWMODE | - NTNEGOTIATE_CAPABILITY_NTSMB; + NTNEGOTIATE_CAPABILITY_NTSMB; if ( smb_authType == SMB_AUTH_EXTENDED ) caps |= NTNEGOTIATE_CAPABILITY_EXTENDED_SECURITY; smb_SetSMBParmLong(outp, 9, caps); - time(&unixTime); - smb_SearchTimeFromUnixTime(&dosTime, unixTime); - smb_SetSMBParmLong(outp, 11, LOWORD(dosTime));/* server time */ - smb_SetSMBParmLong(outp, 13, HIWORD(dosTime));/* server date */ - - GetTimeZoneInformation(&tzi); - smb_SetSMBParm(outp, 15, (unsigned short) tzi.Bias); /* server tzone */ - - if (smb_authType == SMB_AUTH_NTLM) { - smb_SetSMBParmByte(outp, 16, MSV1_0_CHALLENGE_LENGTH);/* Encryption key length */ - smb_SetSMBDataLength(outp, MSV1_0_CHALLENGE_LENGTH + smb_ServerDomainNameLength); - /* paste in encryption key */ - datap = smb_GetSMBData(outp, NULL); - memcpy(datap,vcp->encKey,MSV1_0_CHALLENGE_LENGTH); - /* and the faux domain name */ - strcpy(datap + MSV1_0_CHALLENGE_LENGTH,smb_ServerDomainName); - } else if ( smb_authType == SMB_AUTH_EXTENDED ) { + time(&unixTime); + smb_SearchTimeFromUnixTime(&dosTime, unixTime); + smb_SetSMBParmLong(outp, 11, LOWORD(dosTime));/* server time */ + smb_SetSMBParmLong(outp, 13, HIWORD(dosTime));/* server date */ + + GetTimeZoneInformation(&tzi); + smb_SetSMBParm(outp, 15, (unsigned short) tzi.Bias); /* server tzone */ + + if (smb_authType == SMB_AUTH_NTLM) { + smb_SetSMBParmByte(outp, 16, MSV1_0_CHALLENGE_LENGTH);/* Encryption key length */ + smb_SetSMBDataLength(outp, MSV1_0_CHALLENGE_LENGTH + smb_ServerDomainNameLength); + /* paste in encryption key */ + datap = smb_GetSMBData(outp, NULL); + memcpy(datap,vcp->encKey,MSV1_0_CHALLENGE_LENGTH); + /* and the faux domain name */ + strcpy(datap + MSV1_0_CHALLENGE_LENGTH,smb_ServerDomainName); + } else if ( smb_authType == SMB_AUTH_EXTENDED ) { void * secBlob; - int secBlobLength; + int secBlobLength; - smb_SetSMBParmByte(outp, 16, 0); /* Encryption key length */ + smb_SetSMBParmByte(outp, 16, 0); /* Encryption key length */ - smb_NegotiateExtendedSecurity(&secBlob, &secBlobLength); + smb_NegotiateExtendedSecurity(&secBlob, &secBlobLength); - smb_SetSMBDataLength(outp, secBlobLength + sizeof(smb_ServerGUID)); + smb_SetSMBDataLength(outp, secBlobLength + sizeof(smb_ServerGUID)); - datap = smb_GetSMBData(outp, NULL); - memcpy(datap, &smb_ServerGUID, sizeof(smb_ServerGUID)); - - if (secBlob) { - datap += sizeof(smb_ServerGUID); - memcpy(datap, secBlob, secBlobLength); - free(secBlob); - } + datap = smb_GetSMBData(outp, NULL); + memcpy(datap, &smb_ServerGUID, sizeof(smb_ServerGUID)); + + if (secBlob) { + datap += sizeof(smb_ServerGUID); + memcpy(datap, secBlob, secBlobLength); + free(secBlob); + } } else { - smb_SetSMBParmByte(outp, 16, 0); /* Encryption key length */ - smb_SetSMBDataLength(outp, 0); /* Perhaps we should specify 8 bytes anyway */ - } - } - else if (v3ProtoIndex != -1) { - smb_SetSMBParm(outp, 0, protoIndex); + smb_SetSMBParmByte(outp, 16, 0); /* Encryption key length */ + smb_SetSMBDataLength(outp, 0); /* Perhaps we should specify 8 bytes anyway */ + } + } + else if (v3ProtoIndex != -1) { + smb_SetSMBParm(outp, 0, protoIndex); /* NOTE: Extended authentication cannot be negotiated with v3 * therefore we fail over to NTLM */ if (smb_authType == SMB_AUTH_NTLM || smb_authType == SMB_AUTH_EXTENDED) { - smb_SetSMBParm(outp, 1, - NEGOTIATE_SECURITY_USER_LEVEL | - NEGOTIATE_SECURITY_CHALLENGE_RESPONSE); /* user level security, challenge response */ - } else { - smb_SetSMBParm(outp, 1, 0); /* share level auth with clear password */ - } - smb_SetSMBParm(outp, 2, SMB_PACKETSIZE); - smb_SetSMBParm(outp, 3, smb_maxMpxRequests); /* max multiplexed requests */ - smb_SetSMBParm(outp, 4, smb_maxVCPerServer); /* max VCs per consumer/server connection */ - smb_SetSMBParm(outp, 5, 0); /* no support of block mode for read or write */ - smb_SetSMBParm(outp, 6, 1); /* next 2: session key */ - smb_SetSMBParm(outp, 7, 1); - time(&unixTime); - smb_SearchTimeFromUnixTime(&dosTime, unixTime); - smb_SetSMBParm(outp, 8, LOWORD(dosTime)); /* server time */ - smb_SetSMBParm(outp, 9, HIWORD(dosTime)); /* server date */ - - GetTimeZoneInformation(&tzi); - smb_SetSMBParm(outp, 10, (unsigned short) tzi.Bias); /* server tzone */ + smb_SetSMBParm(outp, 1, + NEGOTIATE_SECURITY_USER_LEVEL | + NEGOTIATE_SECURITY_CHALLENGE_RESPONSE); /* user level security, challenge response */ + } else { + smb_SetSMBParm(outp, 1, 0); /* share level auth with clear password */ + } + smb_SetSMBParm(outp, 2, SMB_PACKETSIZE); + smb_SetSMBParm(outp, 3, smb_maxMpxRequests); /* max multiplexed requests */ + smb_SetSMBParm(outp, 4, smb_maxVCPerServer); /* max VCs per consumer/server connection */ + smb_SetSMBParm(outp, 5, 0); /* no support of block mode for read or write */ + smb_SetSMBParm(outp, 6, 1); /* next 2: session key */ + smb_SetSMBParm(outp, 7, 1); + time(&unixTime); + smb_SearchTimeFromUnixTime(&dosTime, unixTime); + smb_SetSMBParm(outp, 8, LOWORD(dosTime)); /* server time */ + smb_SetSMBParm(outp, 9, HIWORD(dosTime)); /* server date */ + + GetTimeZoneInformation(&tzi); + smb_SetSMBParm(outp, 10, (unsigned short) tzi.Bias); /* server tzone */ /* NOTE: Extended authentication cannot be negotiated with v3 * therefore we fail over to NTLM */ - if (smb_authType == SMB_AUTH_NTLM || smb_authType == SMB_AUTH_EXTENDED) { - smb_SetSMBParm(outp, 11, MSV1_0_CHALLENGE_LENGTH); /* encryption key length */ + if (smb_authType == SMB_AUTH_NTLM || smb_authType == SMB_AUTH_EXTENDED) { + smb_SetSMBParm(outp, 11, MSV1_0_CHALLENGE_LENGTH); /* encryption key length */ smb_SetSMBParm(outp, 12, 0); /* resvd */ - smb_SetSMBDataLength(outp, MSV1_0_CHALLENGE_LENGTH + smb_ServerDomainNameLength); /* perhaps should specify 8 bytes anyway */ - datap = smb_GetSMBData(outp, NULL); - /* paste in a new encryption key */ - memcpy(datap, vcp->encKey, MSV1_0_CHALLENGE_LENGTH); - /* and the faux domain name */ - strcpy(datap + MSV1_0_CHALLENGE_LENGTH, smb_ServerDomainName); - } else { - smb_SetSMBParm(outp, 11, 0); /* encryption key length */ - smb_SetSMBParm(outp, 12, 0); /* resvd */ - smb_SetSMBDataLength(outp, 0); - } - } - else if (coreProtoIndex != -1) { /* not really supported anymore */ - smb_SetSMBParm(outp, 0, protoIndex); - smb_SetSMBDataLength(outp, 0); - } - return 0; + smb_SetSMBDataLength(outp, MSV1_0_CHALLENGE_LENGTH + smb_ServerDomainNameLength); /* perhaps should specify 8 bytes anyway */ + datap = smb_GetSMBData(outp, NULL); + /* paste in a new encryption key */ + memcpy(datap, vcp->encKey, MSV1_0_CHALLENGE_LENGTH); + /* and the faux domain name */ + strcpy(datap + MSV1_0_CHALLENGE_LENGTH, smb_ServerDomainName); + } else { + smb_SetSMBParm(outp, 11, 0); /* encryption key length */ + smb_SetSMBParm(outp, 12, 0); /* resvd */ + smb_SetSMBDataLength(outp, 0); + } + } + else if (coreProtoIndex != -1) { /* not really supported anymore */ + smb_SetSMBParm(outp, 0, protoIndex); + smb_SetSMBDataLength(outp, 0); + } + return 0; } void smb_Daemon(void *parmp) { - afs_uint32 count = 0; + afs_uint32 count = 0; - while(1) { - count++; - thrd_Sleep(10000); - if ((count % 72) == 0) { /* every five minutes */ + while(1) { + count++; + thrd_Sleep(10000); + if ((count % 72) == 0) { /* every five minutes */ struct tm myTime; long old_localZero = smb_localZero; @@ -2832,159 +2862,159 @@ void smb_Daemon(void *parmp) cm_noteLocalMountPointChange(); #endif } - /* XXX GC dir search entries */ - } + /* XXX GC dir search entries */ + } } void smb_WaitingLocksDaemon() { - smb_waitingLock_t *wL, *nwL; - int first; - smb_vc_t *vcp; - smb_packet_t *inp, *outp; - NCB *ncbp; - long code = 0; - - while(1) { - lock_ObtainWrite(&smb_globalLock); - nwL = smb_allWaitingLocks; - if (nwL == NULL) { - osi_SleepW((long)&smb_allWaitingLocks, &smb_globalLock); - thrd_Sleep(1000); - continue; - } - else first = 1; - do { - if (first) - first = 0; - else - lock_ObtainWrite(&smb_globalLock); - wL = nwL; - nwL = (smb_waitingLock_t *) osi_QNext(&wL->q); - lock_ReleaseWrite(&smb_globalLock); - code = cm_RetryLock((cm_file_lock_t *) wL->lockp, - wL->vcp->flags & SMB_VCFLAG_ALREADYDEAD); - if (code == CM_ERROR_WOULDBLOCK) { - /* no progress */ - if (wL->timeRemaining != 0xffffffff - && (wL->timeRemaining -= 1000) < 0) - goto endWait; - continue; - } - endWait: - vcp = wL->vcp; - inp = wL->inp; - outp = wL->outp; - ncbp = GetNCB(); - ncbp->ncb_length = inp->ncb_length; - inp->spacep = cm_GetSpace(); - - /* Remove waitingLock from list */ - lock_ObtainWrite(&smb_globalLock); - osi_QRemove((osi_queue_t **)&smb_allWaitingLocks, - &wL->q); - lock_ReleaseWrite(&smb_globalLock); - - /* Resume packet processing */ - if (code == 0) - smb_SetSMBDataLength(outp, 0); - outp->flags |= SMB_PACKETFLAG_SUSPENDED; - outp->resumeCode = code; - outp->ncbp = ncbp; - smb_DispatchPacket(vcp, inp, outp, ncbp, NULL); - - /* Clean up */ - cm_FreeSpace(inp->spacep); - smb_FreePacket(inp); - smb_FreePacket(outp); - FreeNCB(ncbp); - free(wL); - } while (nwL); - thrd_Sleep(1000); - } + smb_waitingLock_t *wL, *nwL; + int first; + smb_vc_t *vcp; + smb_packet_t *inp, *outp; + NCB *ncbp; + long code = 0; + + while (1) { + lock_ObtainWrite(&smb_globalLock); + nwL = smb_allWaitingLocks; + if (nwL == NULL) { + osi_SleepW((long)&smb_allWaitingLocks, &smb_globalLock); + thrd_Sleep(1000); + continue; + } + else first = 1; + do { + if (first) + first = 0; + else + lock_ObtainWrite(&smb_globalLock); + wL = nwL; + nwL = (smb_waitingLock_t *) osi_QNext(&wL->q); + lock_ReleaseWrite(&smb_globalLock); + code = cm_RetryLock((cm_file_lock_t *) wL->lockp, + wL->vcp->flags & SMB_VCFLAG_ALREADYDEAD); + if (code == CM_ERROR_WOULDBLOCK) { + /* no progress */ + if (wL->timeRemaining != 0xffffffff + && (wL->timeRemaining -= 1000) < 0) + goto endWait; + continue; + } + endWait: + vcp = wL->vcp; + inp = wL->inp; + outp = wL->outp; + ncbp = GetNCB(); + ncbp->ncb_length = inp->ncb_length; + inp->spacep = cm_GetSpace(); + + /* Remove waitingLock from list */ + lock_ObtainWrite(&smb_globalLock); + osi_QRemove((osi_queue_t **)&smb_allWaitingLocks, + &wL->q); + lock_ReleaseWrite(&smb_globalLock); + + /* Resume packet processing */ + if (code == 0) + smb_SetSMBDataLength(outp, 0); + outp->flags |= SMB_PACKETFLAG_SUSPENDED; + outp->resumeCode = code; + outp->ncbp = ncbp; + smb_DispatchPacket(vcp, inp, outp, ncbp, NULL); + + /* Clean up */ + cm_FreeSpace(inp->spacep); + smb_FreePacket(inp); + smb_FreePacket(outp); + FreeNCB(ncbp); + free(wL); + } while (nwL); + thrd_Sleep(1000); + } } long smb_ReceiveCoreGetDiskAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - osi_Log0(smb_logp, "SMB receive get disk attributes"); - - smb_SetSMBParm(outp, 0, 32000); - smb_SetSMBParm(outp, 1, 64); - smb_SetSMBParm(outp, 2, 1024); - smb_SetSMBParm(outp, 3, 30000); - smb_SetSMBParm(outp, 4, 0); - smb_SetSMBDataLength(outp, 0); - return 0; + osi_Log0(smb_logp, "SMB receive get disk attributes"); + + smb_SetSMBParm(outp, 0, 32000); + smb_SetSMBParm(outp, 1, 64); + smb_SetSMBParm(outp, 2, 1024); + smb_SetSMBParm(outp, 3, 30000); + smb_SetSMBParm(outp, 4, 0); + smb_SetSMBDataLength(outp, 0); + return 0; } long smb_ReceiveCoreTreeConnect(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *rsp) { - smb_tid_t *tidp; + smb_tid_t *tidp; smb_user_t *uidp; - unsigned short newTid; - char shareName[256]; - char *sharePath; - int shareFound; - char *tp; - char *pathp; - char *passwordp; - cm_user_t *userp; - - osi_Log0(smb_logp, "SMB receive tree connect"); - - /* parse input parameters */ - tp = smb_GetSMBData(inp, NULL); - pathp = smb_ParseASCIIBlock(tp, &tp); - passwordp = smb_ParseASCIIBlock(tp, &tp); - tp = strrchr(pathp, '\\'); - if (!tp) - return CM_ERROR_BADSMB; - strcpy(shareName, tp+1); - - userp = smb_GetUser(vcp, inp); - - lock_ObtainMutex(&vcp->mx); - newTid = vcp->tidCounter++; - lock_ReleaseMutex(&vcp->mx); - - tidp = smb_FindTID(vcp, newTid, SMB_FLAG_CREATE); + unsigned short newTid; + char shareName[256]; + char *sharePath; + int shareFound; + char *tp; + char *pathp; + char *passwordp; + cm_user_t *userp; + + osi_Log0(smb_logp, "SMB receive tree connect"); + + /* parse input parameters */ + tp = smb_GetSMBData(inp, NULL); + pathp = smb_ParseASCIIBlock(tp, &tp); + passwordp = smb_ParseASCIIBlock(tp, &tp); + tp = strrchr(pathp, '\\'); + if (!tp) + return CM_ERROR_BADSMB; + strcpy(shareName, tp+1); + + userp = smb_GetUser(vcp, inp); + + lock_ObtainMutex(&vcp->mx); + newTid = vcp->tidCounter++; + lock_ReleaseMutex(&vcp->mx); + + tidp = smb_FindTID(vcp, newTid, SMB_FLAG_CREATE); uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0); - shareFound = smb_FindShare(vcp, uidp, shareName, &sharePath); + shareFound = smb_FindShare(vcp, uidp, shareName, &sharePath); if (uidp) smb_ReleaseUID(uidp); - if (!shareFound) { - smb_ReleaseTID(tidp); - return CM_ERROR_BADSHARENAME; - } - lock_ObtainMutex(&tidp->mx); - tidp->userp = userp; - tidp->pathname = sharePath; - lock_ReleaseMutex(&tidp->mx); - smb_ReleaseTID(tidp); + if (!shareFound) { + smb_ReleaseTID(tidp); + return CM_ERROR_BADSHARENAME; + } + lock_ObtainMutex(&tidp->mx); + tidp->userp = userp; + tidp->pathname = sharePath; + lock_ReleaseMutex(&tidp->mx); + smb_ReleaseTID(tidp); - smb_SetSMBParm(rsp, 0, SMB_PACKETSIZE); - smb_SetSMBParm(rsp, 1, newTid); - smb_SetSMBDataLength(rsp, 0); + smb_SetSMBParm(rsp, 0, SMB_PACKETSIZE); + smb_SetSMBParm(rsp, 1, newTid); + smb_SetSMBDataLength(rsp, 0); - osi_Log1(smb_logp, "SMB tree connect created ID %d", newTid); - return 0; + osi_Log1(smb_logp, "SMB tree connect created ID %d", newTid); + return 0; } unsigned char *smb_ParseDataBlock(unsigned char *inp, char **chainpp, int *lengthp) { - int tlen; + int tlen; - if (*inp++ != 0x1) return NULL; - tlen = inp[0] + (inp[1]<<8); - inp += 2; /* skip length field */ + if (*inp++ != 0x1) return NULL; + tlen = inp[0] + (inp[1]<<8); + inp += 2; /* skip length field */ - if (chainpp) { - *chainpp = inp + tlen; - } - - if (lengthp) *lengthp = tlen; + if (chainpp) { + *chainpp = inp + tlen; + } + + if (lengthp) *lengthp = tlen; - return inp; + return inp; } /* set maskp to the mask part of the incoming path. @@ -2994,30 +3024,30 @@ unsigned char *smb_ParseDataBlock(unsigned char *inp, char **chainpp, int *lengt */ int smb_Get8Dot3MaskFromPath(unsigned char *maskp, unsigned char *pathp) { - char *tp; - char *up; - int i; - int tc; - int valid8Dot3; - - /* starts off valid */ - valid8Dot3 = 1; - - /* mask starts out all blanks */ - memset(maskp, ' ', 11); - - /* find last backslash, or use whole thing if there is none */ - tp = strrchr(pathp, '\\'); - if (!tp) tp = pathp; - else tp++; /* skip slash */ + char *tp; + char *up; + int i; + int tc; + int valid8Dot3; + + /* starts off valid */ + valid8Dot3 = 1; + + /* mask starts out all blanks */ + memset(maskp, ' ', 11); + + /* find last backslash, or use whole thing if there is none */ + tp = strrchr(pathp, '\\'); + if (!tp) tp = pathp; + else tp++; /* skip slash */ - up = maskp; + up = maskp; - /* names starting with a dot are illegal */ - if (*tp == '.') valid8Dot3 = 0; + /* names starting with a dot are illegal */ + if (*tp == '.') valid8Dot3 = 0; for(i=0;; i++) { - tc = *tp++; + tc = *tp++; if (tc == 0) return valid8Dot3; if (tc == '.' || tc == '"') break; if (i < 8) *up++ = tc; @@ -3029,17 +3059,17 @@ int smb_Get8Dot3MaskFromPath(unsigned char *maskp, unsigned char *pathp) for(i=0;;i++) { tc = *tp++; if (tc == 0) - return valid8Dot3; + return valid8Dot3; /* too many dots */ if (tc == '.' || tc == '"') - valid8Dot3 = 0; + valid8Dot3 = 0; /* copy extension if not too long */ if (i < 3) - *up++ = tc; + *up++ = tc; else - valid8Dot3 = 0; + valid8Dot3 = 0; } /* unreachable */ @@ -3047,137 +3077,137 @@ int smb_Get8Dot3MaskFromPath(unsigned char *maskp, unsigned char *pathp) int smb_Match8Dot3Mask(char *unixNamep, char *maskp) { - char umask[11]; - int valid; - int i; - char tc1; - char tc2; - char *tp1; - char *tp2; - - /* XXX redo this, calling smb_V3MatchMask with a converted mask */ - - valid = smb_Get8Dot3MaskFromPath(umask, unixNamep); - if (!valid) - return 0; + char umask[11]; + int valid; + int i; + char tc1; + char tc2; + char *tp1; + char *tp2; + + /* XXX redo this, calling smb_V3MatchMask with a converted mask */ + + valid = smb_Get8Dot3MaskFromPath(umask, unixNamep); + if (!valid) + return 0; - /* otherwise, we have a valid 8.3 name; see if we have a match, - * treating '?' as a wildcard in maskp (but not in the file name). - */ - tp1 = umask; /* real name, in mask format */ - tp2 = maskp; /* mask, in mask format */ - for(i=0; i<11; i++) { - tc1 = *tp1++; /* char from real name */ - tc2 = *tp2++; /* char from mask */ - tc1 = (char) cm_foldUpper[(unsigned char)tc1]; - tc2 = (char) cm_foldUpper[(unsigned char)tc2]; - if (tc1 == tc2) - continue; - if (tc2 == '?' && tc1 != ' ') - continue; - if (tc2 == '>') - continue; - return 0; - } - - /* we got a match */ - return 1; + /* otherwise, we have a valid 8.3 name; see if we have a match, + * treating '?' as a wildcard in maskp (but not in the file name). + */ + tp1 = umask; /* real name, in mask format */ + tp2 = maskp; /* mask, in mask format */ + for(i=0; i<11; i++) { + tc1 = *tp1++; /* char from real name */ + tc2 = *tp2++; /* char from mask */ + tc1 = (char) cm_foldUpper[(unsigned char)tc1]; + tc2 = (char) cm_foldUpper[(unsigned char)tc2]; + if (tc1 == tc2) + continue; + if (tc2 == '?' && tc1 != ' ') + continue; + if (tc2 == '>') + continue; + return 0; + } + + /* we got a match */ + return 1; } char *smb_FindMask(char *pathp) { - char *tp; + char *tp; - tp = strrchr(pathp, '\\'); /* find last slash */ + tp = strrchr(pathp, '\\'); /* find last slash */ - if (tp) - return tp+1; /* skip the slash */ - else - return pathp; /* no slash, return the entire path */ -} + if (tp) + return tp+1; /* skip the slash */ + else + return pathp; /* no slash, return the entire path */ +} long smb_ReceiveCoreSearchVolume(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - unsigned char *pathp; - unsigned char *tp; - unsigned char mask[11]; - unsigned char *statBlockp; - unsigned char initStatBlock[21]; - int statLen; - - osi_Log0(smb_logp, "SMB receive search volume"); - - /* pull pathname and stat block out of request */ - tp = smb_GetSMBData(inp, NULL); - pathp = smb_ParseASCIIBlock(tp, (char **) &tp); - osi_assert(pathp != NULL); - statBlockp = smb_ParseVblBlock(tp, (char **) &tp, &statLen); - osi_assert(statBlockp != NULL); - if (statLen == 0) { - statBlockp = initStatBlock; - statBlockp[0] = 8; - } + unsigned char *pathp; + unsigned char *tp; + unsigned char mask[11]; + unsigned char *statBlockp; + unsigned char initStatBlock[21]; + int statLen; - /* for returning to caller */ - smb_Get8Dot3MaskFromPath(mask, pathp); + osi_Log0(smb_logp, "SMB receive search volume"); + + /* pull pathname and stat block out of request */ + tp = smb_GetSMBData(inp, NULL); + pathp = smb_ParseASCIIBlock(tp, (char **) &tp); + osi_assert(pathp != NULL); + statBlockp = smb_ParseVblBlock(tp, (char **) &tp, &statLen); + osi_assert(statBlockp != NULL); + if (statLen == 0) { + statBlockp = initStatBlock; + statBlockp[0] = 8; + } - smb_SetSMBParm(outp, 0, 1); /* we're returning one entry */ - tp = smb_GetSMBData(outp, NULL); - *tp++ = 5; - *tp++ = 43; /* bytes in a dir entry */ - *tp++ = 0; /* high byte in counter */ - - /* now marshall the dir entry, starting with the search status */ - *tp++ = statBlockp[0]; /* Reserved */ - memcpy(tp, mask, 11); tp += 11; /* FileName */ - - /* now pass back server use info, with 1st byte non-zero */ - *tp++ = 1; - memset(tp, 0, 4); tp += 4; /* reserved for server use */ - - memcpy(tp, statBlockp+17, 4); tp += 4; /* reserved for consumer */ - - *tp++ = 0x8; /* attribute: volume */ - - /* copy out time */ - *tp++ = 0; - *tp++ = 0; - - /* copy out date */ - *tp++ = 18; - *tp++ = 178; - - /* 4 byte file size */ - *tp++ = 0; - *tp++ = 0; - *tp++ = 0; - *tp++ = 0; - - /* finally, null-terminated 8.3 pathname, which we set to AFS */ - memset(tp, ' ', 13); - strcpy(tp, "AFS"); - - /* set the length of the data part of the packet to 43 + 3, for the dir - * entry plus the 5 and the length fields. - */ - smb_SetSMBDataLength(outp, 46); - return 0; -} + /* for returning to caller */ + smb_Get8Dot3MaskFromPath(mask, pathp); + + smb_SetSMBParm(outp, 0, 1); /* we're returning one entry */ + tp = smb_GetSMBData(outp, NULL); + *tp++ = 5; + *tp++ = 43; /* bytes in a dir entry */ + *tp++ = 0; /* high byte in counter */ + + /* now marshall the dir entry, starting with the search status */ + *tp++ = statBlockp[0]; /* Reserved */ + memcpy(tp, mask, 11); tp += 11; /* FileName */ + + /* now pass back server use info, with 1st byte non-zero */ + *tp++ = 1; + memset(tp, 0, 4); tp += 4; /* reserved for server use */ + + memcpy(tp, statBlockp+17, 4); tp += 4; /* reserved for consumer */ + + *tp++ = 0x8; /* attribute: volume */ + + /* copy out time */ + *tp++ = 0; + *tp++ = 0; + + /* copy out date */ + *tp++ = 18; + *tp++ = 178; + + /* 4 byte file size */ + *tp++ = 0; + *tp++ = 0; + *tp++ = 0; + *tp++ = 0; + + /* finally, null-terminated 8.3 pathname, which we set to AFS */ + memset(tp, ' ', 13); + strcpy(tp, "AFS"); + + /* set the length of the data part of the packet to 43 + 3, for the dir + * entry plus the 5 and the length fields. + */ + smb_SetSMBDataLength(outp, 46); + return 0; +} long smb_ApplyDirListPatches(smb_dirListPatch_t **dirPatchespp, - cm_user_t *userp, cm_req_t *reqp) + cm_user_t *userp, cm_req_t *reqp) { - long code = 0; - cm_scache_t *scp; - char *dptr; - time_t dosTime; - u_short shortTemp; - char attr; - smb_dirListPatch_t *patchp; - smb_dirListPatch_t *npatchp; - - for(patchp = *dirPatchespp; patchp; patchp = - (smb_dirListPatch_t *) osi_QNext(&patchp->q)) { + long code = 0; + cm_scache_t *scp; + char *dptr; + time_t dosTime; + u_short shortTemp; + char attr; + smb_dirListPatch_t *patchp; + smb_dirListPatch_t *npatchp; + + for (patchp = *dirPatchespp; patchp; patchp = + (smb_dirListPatch_t *) osi_QNext(&patchp->q)) { dptr = patchp->dptr; @@ -3187,889 +3217,888 @@ long smb_ApplyDirListPatches(smb_dirListPatch_t **dirPatchespp, *dptr++ = SMB_ATTR_HIDDEN; continue; } - lock_ObtainMutex(&scp->mx); - code = cm_SyncOp(scp, NULL, userp, reqp, 0, - CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); - if (code) { - lock_ReleaseMutex(&scp->mx); - cm_ReleaseSCache(scp); - if( patchp->flags & SMB_DIRLISTPATCH_DOTFILE ) + lock_ObtainMutex(&scp->mx); + code = cm_SyncOp(scp, NULL, userp, reqp, 0, + CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + if (code) { + lock_ReleaseMutex(&scp->mx); + cm_ReleaseSCache(scp); + if (patchp->flags & SMB_DIRLISTPATCH_DOTFILE) *dptr++ = SMB_ATTR_HIDDEN; - continue; - } + continue; + } - attr = smb_Attributes(scp); + attr = smb_Attributes(scp); /* check hidden attribute (the flag is only ON when dot file hiding is on ) */ - if( patchp->flags & SMB_DIRLISTPATCH_DOTFILE ) + if (patchp->flags & SMB_DIRLISTPATCH_DOTFILE) attr |= SMB_ATTR_HIDDEN; *dptr++ = attr; /* get dos time */ - smb_SearchTimeFromUnixTime(&dosTime, scp->clientModTime); + smb_SearchTimeFromUnixTime(&dosTime, scp->clientModTime); - /* copy out time */ - shortTemp = dosTime & 0xffff; - *((u_short *)dptr) = shortTemp; - dptr += 2; - - /* and copy out date */ - shortTemp = (dosTime>>16) & 0xffff; - *((u_short *)dptr) = shortTemp; - dptr += 2; + /* copy out time */ + shortTemp = dosTime & 0xffff; + *((u_short *)dptr) = shortTemp; + dptr += 2; + + /* and copy out date */ + shortTemp = (dosTime>>16) & 0xffff; + *((u_short *)dptr) = shortTemp; + dptr += 2; - /* copy out file length */ - *((u_long *)dptr) = scp->length.LowPart; - dptr += 4; - lock_ReleaseMutex(&scp->mx); - cm_ReleaseSCache(scp); - } + /* copy out file length */ + *((u_long *)dptr) = scp->length.LowPart; + dptr += 4; + lock_ReleaseMutex(&scp->mx); + cm_ReleaseSCache(scp); + } - /* now free the patches */ - for(patchp = *dirPatchespp; patchp; patchp = npatchp) { - npatchp = (smb_dirListPatch_t *) osi_QNext(&patchp->q); - free(patchp); - } + /* now free the patches */ + for (patchp = *dirPatchespp; patchp; patchp = npatchp) { + npatchp = (smb_dirListPatch_t *) osi_QNext(&patchp->q); + free(patchp); + } - /* and mark the list as empty */ - *dirPatchespp = NULL; + /* and mark the list as empty */ + *dirPatchespp = NULL; - return code; + return code; } long smb_ReceiveCoreSearchDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - int attribute; - long nextCookie; - char *tp; - long code = 0; - char *pathp; - cm_dirEntry_t *dep; - int maxCount; - smb_dirListPatch_t *dirListPatchesp; - smb_dirListPatch_t *curPatchp; - int dataLength; - cm_buf_t *bufferp; - long temp; - osi_hyper_t dirLength; - osi_hyper_t bufferOffset; - osi_hyper_t curOffset; - osi_hyper_t thyper; - unsigned char *inCookiep; - smb_dirSearch_t *dsp; - cm_scache_t *scp; - long entryInDir; - long entryInBuffer; - unsigned long clientCookie; - cm_pageHeader_t *pageHeaderp; - cm_user_t *userp = NULL; - int slotInPage; - char shortName[13]; - char *actualName; - char *shortNameEnd; - char mask[11]; - int returnedNames; - long nextEntryCookie; - int numDirChunks; /* # of 32 byte dir chunks in this entry */ - char resByte; /* reserved byte from the cookie */ - char *op; /* output data ptr */ - char *origOp; /* original value of op */ - cm_space_t *spacep; /* for pathname buffer */ - int starPattern; - int rootPath = 0; - int caseFold; - char *tidPathp; - cm_req_t req; - cm_fid_t fid; - int fileType; - - cm_InitReq(&req); - - maxCount = smb_GetSMBParm(inp, 0); - - dirListPatchesp = NULL; - - caseFold = CM_FLAG_CASEFOLD; - - tp = smb_GetSMBData(inp, NULL); - pathp = smb_ParseASCIIBlock(tp, &tp); - inCookiep = smb_ParseVblBlock(tp, &tp, &dataLength); - - /* bail out if request looks bad */ - if (!tp || !pathp) { - return CM_ERROR_BADSMB; - } - - /* We can handle long names */ - if (vcp->flags & SMB_VCFLAG_USENT) - ((smb_t *)outp)->flg2 |= 0x40; /* IS_LONG_NAME */ - - /* make sure we got a whole search status */ - if (dataLength < 21) { - nextCookie = 0; /* start at the beginning of the dir */ - resByte = 0; - clientCookie = 0; - attribute = smb_GetSMBParm(inp, 1); - - /* handle volume info in another function */ - if (attribute & 0x8) - return smb_ReceiveCoreSearchVolume(vcp, inp, outp); - - osi_Log2(smb_logp, "SMB receive search dir count %d [%s]", - maxCount, osi_LogSaveString(smb_logp, pathp)); - - if (*pathp == 0) { /* null pathp, treat as root dir */ - if (!(attribute & SMB_ATTR_DIRECTORY)) /* exclude dirs */ - return CM_ERROR_NOFILES; - rootPath = 1; - } - - dsp = smb_NewDirSearch(0); - dsp->attribute = attribute; - smb_Get8Dot3MaskFromPath(mask, pathp); - memcpy(dsp->mask, mask, 11); - - /* track if this is likely to match a lot of entries */ - if (smb_IsStarMask(mask)) starPattern = 1; - else starPattern = 0; - } - else { - /* pull the next cookie value out of the search status block */ - nextCookie = inCookiep[13] + (inCookiep[14]<<8) + (inCookiep[15]<<16) - + (inCookiep[16]<<24); - dsp = smb_FindDirSearch(inCookiep[12]); - if (!dsp) { - /* can't find dir search status; fatal error */ - return CM_ERROR_BADFD; - } - attribute = dsp->attribute; - resByte = inCookiep[0]; - - /* copy out client cookie, in host byte order. Don't bother - * interpreting it, since we're just passing it through, anyway. - */ - memcpy(&clientCookie, &inCookiep[17], 4); - - memcpy(mask, dsp->mask, 11); - - /* assume we're doing a star match if it has continued for more - * than one call. - */ - starPattern = 1; - } - - osi_Log3(smb_logp, "SMB dir search cookie 0x%x, connection %d, attr 0x%x", - nextCookie, dsp->cookie, attribute); - - userp = smb_GetUser(vcp, inp); - - /* try to get the vnode for the path name next */ - lock_ObtainMutex(&dsp->mx); - if (dsp->scp) { - scp = dsp->scp; - cm_HoldSCache(scp); - code = 0; - } - else { - spacep = inp->spacep; - smb_StripLastComponent(spacep->data, NULL, pathp); - lock_ReleaseMutex(&dsp->mx); - code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); - if(code) { - lock_ReleaseMutex(&dsp->mx); - cm_ReleaseUser(userp); - smb_DeleteDirSearch(dsp); - smb_ReleaseDirSearch(dsp); - return CM_ERROR_NOFILES; - } - code = cm_NameI(cm_rootSCachep, spacep->data, - caseFold | CM_FLAG_FOLLOW, userp, tidPathp, &req, &scp); - lock_ObtainMutex(&dsp->mx); - if (code == 0) { - if (dsp->scp != 0) cm_ReleaseSCache(dsp->scp); - dsp->scp = scp; - /* we need one hold for the entry we just stored into, - * and one for our own processing. When we're done with this - * function, we'll drop the one for our own processing. - * We held it once from the namei call, and so we do another hold - * now. - */ - cm_HoldSCache(scp); - lock_ObtainMutex(&scp->mx); - if ((scp->flags & CM_SCACHEFLAG_BULKSTATTING) == 0 - && LargeIntegerGreaterOrEqualToZero(scp->bulkStatProgress)) { - scp->flags |= CM_SCACHEFLAG_BULKSTATTING; - dsp->flags |= SMB_DIRSEARCH_BULKST; - } - lock_ReleaseMutex(&scp->mx); - } - } - lock_ReleaseMutex(&dsp->mx); - if (code) { - cm_ReleaseUser(userp); - smb_DeleteDirSearch(dsp); - smb_ReleaseDirSearch(dsp); - return code; - } - - /* reserves space for parameter; we'll adjust it again later to the - * real count of the # of entries we returned once we've actually - * assembled the directory listing. - */ - smb_SetSMBParm(outp, 0, 0); - - /* get the directory size */ - lock_ObtainMutex(&scp->mx); - code = cm_SyncOp(scp, NULL, userp, &req, 0, - CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); - if (code) { - lock_ReleaseMutex(&scp->mx); - cm_ReleaseSCache(scp); - cm_ReleaseUser(userp); - smb_DeleteDirSearch(dsp); - smb_ReleaseDirSearch(dsp); - return code; - } + int attribute; + long nextCookie; + char *tp; + long code = 0; + char *pathp; + cm_dirEntry_t *dep; + int maxCount; + smb_dirListPatch_t *dirListPatchesp; + smb_dirListPatch_t *curPatchp; + int dataLength; + cm_buf_t *bufferp; + long temp; + osi_hyper_t dirLength; + osi_hyper_t bufferOffset; + osi_hyper_t curOffset; + osi_hyper_t thyper; + unsigned char *inCookiep; + smb_dirSearch_t *dsp; + cm_scache_t *scp; + long entryInDir; + long entryInBuffer; + unsigned long clientCookie; + cm_pageHeader_t *pageHeaderp; + cm_user_t *userp = NULL; + int slotInPage; + char shortName[13]; + char *actualName; + char *shortNameEnd; + char mask[11]; + int returnedNames; + long nextEntryCookie; + int numDirChunks; /* # of 32 byte dir chunks in this entry */ + char resByte; /* reserved byte from the cookie */ + char *op; /* output data ptr */ + char *origOp; /* original value of op */ + cm_space_t *spacep; /* for pathname buffer */ + int starPattern; + int rootPath = 0; + int caseFold; + char *tidPathp; + cm_req_t req; + cm_fid_t fid; + int fileType; + + cm_InitReq(&req); + + maxCount = smb_GetSMBParm(inp, 0); + + dirListPatchesp = NULL; - dirLength = scp->length; - bufferp = NULL; - bufferOffset.LowPart = bufferOffset.HighPart = 0; - curOffset.HighPart = 0; - curOffset.LowPart = nextCookie; - origOp = op = smb_GetSMBData(outp, NULL); - /* and write out the basic header */ - *op++ = 5; /* variable block */ - op += 2; /* skip vbl block length; we'll fill it in later */ - code = 0; - returnedNames = 0; - while (1) { - /* make sure that curOffset.LowPart doesn't point to the first - * 32 bytes in the 2nd through last dir page, and that it doesn't - * point at the first 13 32-byte chunks in the first dir page, - * since those are dir and page headers, and don't contain useful - * information. - */ - temp = curOffset.LowPart & (2048-1); - if (curOffset.HighPart == 0 && curOffset.LowPart < 2048) { - /* we're in the first page */ - if (temp < 13*32) temp = 13*32; - } - else { - /* we're in a later dir page */ - if (temp < 32) temp = 32; - } - - /* make sure the low order 5 bits are zero */ - temp &= ~(32-1); - - /* now put temp bits back ito curOffset.LowPart */ - curOffset.LowPart &= ~(2048-1); - curOffset.LowPart |= temp; - - /* check if we've returned all the names that will fit in the - * response packet. - */ - if (returnedNames >= maxCount) - break; - - /* check if we've passed the dir's EOF */ - if (LargeIntegerGreaterThanOrEqualTo(curOffset, dirLength)) break; - - /* see if we can use the bufferp we have now; compute in which page - * the current offset would be, and check whether that's the offset - * of the buffer we have. If not, get the buffer. - */ - thyper.HighPart = curOffset.HighPart; - thyper.LowPart = curOffset.LowPart & ~(buf_bufferSize-1); - if (!bufferp || !LargeIntegerEqualTo(thyper, bufferOffset)) { - /* wrong buffer */ - if (bufferp) { - buf_Release(bufferp); - bufferp = NULL; - } - lock_ReleaseMutex(&scp->mx); - lock_ObtainRead(&scp->bufCreateLock); - code = buf_Get(scp, &thyper, &bufferp); - lock_ReleaseRead(&scp->bufCreateLock); - - /* now, if we're doing a star match, do bulk fetching of all of - * the status info for files in the dir. - */ - if (starPattern) { - smb_ApplyDirListPatches(&dirListPatchesp, userp, - &req); - if ((dsp->flags & SMB_DIRSEARCH_BULKST) - && LargeIntegerGreaterThanOrEqualTo(thyper, - scp->bulkStatProgress)) { - /* Don't bulk stat if risking timeout */ - int now = GetCurrentTime(); - if (now - req.startTime > 5000) { - scp->bulkStatProgress = thyper; - scp->flags &= ~CM_SCACHEFLAG_BULKSTATTING; - dsp->flags &= ~SMB_DIRSEARCH_BULKST; - } else - cm_TryBulkStat(scp, &thyper, userp, &req); - } - } - - lock_ObtainMutex(&scp->mx); - if (code) - break; - bufferOffset = thyper; - - /* now get the data in the cache */ - while (1) { - code = cm_SyncOp(scp, bufferp, userp, &req, - PRSFS_LOOKUP, - CM_SCACHESYNC_NEEDCALLBACK - | CM_SCACHESYNC_READ); - if (code) break; - - if (cm_HaveBuffer(scp, bufferp, 0)) break; - - /* otherwise, load the buffer and try again */ - code = cm_GetBuffer(scp, bufferp, NULL, userp, - &req); - if (code) break; - } - if (code) { - buf_Release(bufferp); - bufferp = NULL; - break; - } - } /* if (wrong buffer) ... */ - - /* now we have the buffer containing the entry we're interested in; copy - * it out if it represents a non-deleted entry. - */ - entryInDir = curOffset.LowPart & (2048-1); - entryInBuffer = curOffset.LowPart & (buf_bufferSize - 1); - - /* page header will help tell us which entries are free. Page header - * can change more often than once per buffer, since AFS 3 dir page size - * may be less than (but not more than a buffer package buffer. - */ - temp = curOffset.LowPart & (buf_bufferSize - 1); /* only look intra-buffer */ - temp &= ~(2048 - 1); /* turn off intra-page bits */ - pageHeaderp = (cm_pageHeader_t *) (bufferp->datap + temp); - - /* now determine which entry we're looking at in the page. If it is - * free (there's a free bitmap at the start of the dir), we should - * skip these 32 bytes. - */ - slotInPage = (entryInDir & 0x7e0) >> 5; - if (!(pageHeaderp->freeBitmap[slotInPage>>3] & (1 << (slotInPage & 0x7)))) { - /* this entry is free */ - numDirChunks = 1; /* only skip this guy */ - goto nextEntry; - } - - tp = bufferp->datap + entryInBuffer; - dep = (cm_dirEntry_t *) tp; /* now points to AFS3 dir entry */ - - /* while we're here, compute the next entry's location, too, - * since we'll need it when writing out the cookie into the dir - * listing stream. - * - * XXXX Probably should do more sanity checking. - */ - numDirChunks = cm_NameEntries(dep->name, NULL); - - /* compute the offset of the cookie representing the next entry */ - nextEntryCookie = curOffset.LowPart + (CM_DIR_CHUNKSIZE * numDirChunks); - - /* Compute 8.3 name if necessary */ - actualName = dep->name; - if (dep->fid.vnode != 0 && !cm_Is8Dot3(actualName)) { - cm_Gen8Dot3Name(dep, shortName, &shortNameEnd); - actualName = shortName; - } - - if (dep->fid.vnode != 0 && smb_Match8Dot3Mask(actualName, mask)) { - /* this is one of the entries to use: it is not deleted - * and it matches the star pattern we're looking for. - */ - - /* Eliminate entries that don't match requested - attributes */ - - /* no hidden files */ - if(smb_hideDotFiles && !(dsp->attribute & SMB_ATTR_HIDDEN) && smb_IsDotFile(actualName)) - goto nextEntry; - - if (!(dsp->attribute & SMB_ATTR_DIRECTORY)) /* no directories */ - { - /* We have already done the cm_TryBulkStat above */ - fid.cell = scp->fid.cell; - fid.volume = scp->fid.volume; - fid.vnode = ntohl(dep->fid.vnode); - fid.unique = ntohl(dep->fid.unique); - fileType = cm_FindFileType(&fid); - osi_Log2(smb_logp, "smb_ReceiveCoreSearchDir: file %s " - "has filetype %d", osi_LogSaveString(smb_logp, dep->name), - fileType); - if (fileType == CM_SCACHETYPE_DIRECTORY) - goto nextEntry; - } - - *op++ = resByte; - memcpy(op, mask, 11); op += 11; - *op++ = (char) dsp->cookie; /* they say it must be non-zero */ - *op++ = nextEntryCookie & 0xff; - *op++ = (nextEntryCookie>>8) & 0xff; - *op++ = (nextEntryCookie>>16) & 0xff; - *op++ = (nextEntryCookie>>24) & 0xff; - memcpy(op, &clientCookie, 4); op += 4; - - /* now we emit the attribute. This is sort of tricky, - * since we need to really stat the file to find out - * what type of entry we've got. Right now, we're - * copying out data from a buffer, while holding the - * scp locked, so it isn't really convenient to stat - * something now. We'll put in a place holder now, - * and make a second pass before returning this to get - * the real attributes. So, we just skip the data for - * now, and adjust it later. We allocate a patch - * record to make it easy to find this point later. - * The replay will happen at a time when it is safe to - * unlock the directory. - */ - curPatchp = malloc(sizeof(*curPatchp)); - osi_QAdd((osi_queue_t **) &dirListPatchesp, &curPatchp->q); - curPatchp->dptr = op; - curPatchp->fid.cell = scp->fid.cell; - curPatchp->fid.volume = scp->fid.volume; - curPatchp->fid.vnode = ntohl(dep->fid.vnode); - curPatchp->fid.unique = ntohl(dep->fid.unique); - - /* do hidden attribute here since name won't be around when applying - * dir list patches - */ - - if ( smb_hideDotFiles && smb_IsDotFile(actualName) ) - curPatchp->flags = SMB_DIRLISTPATCH_DOTFILE; - else - curPatchp->flags = 0; - - op += 9; /* skip attr, time, date and size */ - - /* zero out name area. The spec says to pad with - * spaces, but Samba doesn't, and neither do we. - */ - memset(op, 0, 13); - - /* finally, we get to copy out the name; we know that - * it fits in 8.3 or the pattern wouldn't match, but it - * never hurts to be sure. - */ - strncpy(op, actualName, 13); - - /* Uppercase if requested by client */ - if ((((smb_t *)inp)->flg2 & 1) == 0) - _strupr(op); - - op += 13; - - /* now, adjust the # of entries copied */ - returnedNames++; - } /* if we're including this name */ - - nextEntry: - /* and adjust curOffset to be where the new cookie is */ - thyper.HighPart = 0; - thyper.LowPart = CM_DIR_CHUNKSIZE * numDirChunks; - curOffset = LargeIntegerAdd(thyper, curOffset); - } /* while copying data for dir listing */ - - /* release the mutex */ - lock_ReleaseMutex(&scp->mx); - if (bufferp) buf_Release(bufferp); - - /* apply and free last set of patches; if not doing a star match, this - * will be empty, but better safe (and freeing everything) than sorry. - */ - smb_ApplyDirListPatches(&dirListPatchesp, userp, &req); - - /* special return code for unsuccessful search */ - if (code == 0 && dataLength < 21 && returnedNames == 0) - code = CM_ERROR_NOFILES; - - osi_Log2(smb_logp, "SMB search dir done, %d names, code %d", - returnedNames, code); - - if (code != 0) { - smb_DeleteDirSearch(dsp); - smb_ReleaseDirSearch(dsp); - cm_ReleaseSCache(scp); - cm_ReleaseUser(userp); - return code; - } - - /* finalize the output buffer */ - smb_SetSMBParm(outp, 0, returnedNames); - temp = (long) (op - origOp); - smb_SetSMBDataLength(outp, temp); - - /* the data area is a variable block, which has a 5 (already there) - * followed by the length of the # of data bytes. We now know this to - * be "temp," although that includes the 3 bytes of vbl block header. - * Deduct for them and fill in the length field. - */ - temp -= 3; /* deduct vbl block info */ - osi_assert(temp == (43 * returnedNames)); - origOp[1] = temp & 0xff; - origOp[2] = (temp>>8) & 0xff; - if (returnedNames == 0) smb_DeleteDirSearch(dsp); - smb_ReleaseDirSearch(dsp); - cm_ReleaseSCache(scp); - cm_ReleaseUser(userp); - return code; -} + caseFold = CM_FLAG_CASEFOLD; -/* verify that this is a valid path to a directory. I don't know why they - * don't use the get file attributes call. - */ + tp = smb_GetSMBData(inp, NULL); + pathp = smb_ParseASCIIBlock(tp, &tp); + inCookiep = smb_ParseVblBlock(tp, &tp, &dataLength); + + /* bail out if request looks bad */ + if (!tp || !pathp) { + return CM_ERROR_BADSMB; + } + + /* We can handle long names */ + if (vcp->flags & SMB_VCFLAG_USENT) + ((smb_t *)outp)->flg2 |= 0x40; /* IS_LONG_NAME */ + + /* make sure we got a whole search status */ + if (dataLength < 21) { + nextCookie = 0; /* start at the beginning of the dir */ + resByte = 0; + clientCookie = 0; + attribute = smb_GetSMBParm(inp, 1); + + /* handle volume info in another function */ + if (attribute & 0x8) + return smb_ReceiveCoreSearchVolume(vcp, inp, outp); + + osi_Log2(smb_logp, "SMB receive search dir count %d [%s]", + maxCount, osi_LogSaveString(smb_logp, pathp)); + + if (*pathp == 0) { /* null pathp, treat as root dir */ + if (!(attribute & SMB_ATTR_DIRECTORY)) /* exclude dirs */ + return CM_ERROR_NOFILES; + rootPath = 1; + } + + dsp = smb_NewDirSearch(0); + dsp->attribute = attribute; + smb_Get8Dot3MaskFromPath(mask, pathp); + memcpy(dsp->mask, mask, 11); + + /* track if this is likely to match a lot of entries */ + if (smb_IsStarMask(mask)) starPattern = 1; + else starPattern = 0; + } + else { + /* pull the next cookie value out of the search status block */ + nextCookie = inCookiep[13] + (inCookiep[14]<<8) + (inCookiep[15]<<16) + + (inCookiep[16]<<24); + dsp = smb_FindDirSearch(inCookiep[12]); + if (!dsp) { + /* can't find dir search status; fatal error */ + return CM_ERROR_BADFD; + } + attribute = dsp->attribute; + resByte = inCookiep[0]; + + /* copy out client cookie, in host byte order. Don't bother + * interpreting it, since we're just passing it through, anyway. + */ + memcpy(&clientCookie, &inCookiep[17], 4); + + memcpy(mask, dsp->mask, 11); + + /* assume we're doing a star match if it has continued for more + * than one call. + */ + starPattern = 1; + } + + osi_Log3(smb_logp, "SMB dir search cookie 0x%x, connection %d, attr 0x%x", + nextCookie, dsp->cookie, attribute); + + userp = smb_GetUser(vcp, inp); + + /* try to get the vnode for the path name next */ + lock_ObtainMutex(&dsp->mx); + if (dsp->scp) { + scp = dsp->scp; + cm_HoldSCache(scp); + code = 0; + } + else { + spacep = inp->spacep; + smb_StripLastComponent(spacep->data, NULL, pathp); + lock_ReleaseMutex(&dsp->mx); + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); + if (code) { + lock_ReleaseMutex(&dsp->mx); + cm_ReleaseUser(userp); + smb_DeleteDirSearch(dsp); + smb_ReleaseDirSearch(dsp); + return CM_ERROR_NOFILES; + } + code = cm_NameI(cm_rootSCachep, spacep->data, + caseFold | CM_FLAG_FOLLOW, userp, tidPathp, &req, &scp); + lock_ObtainMutex(&dsp->mx); + if (code == 0) { + if (dsp->scp != 0) cm_ReleaseSCache(dsp->scp); + dsp->scp = scp; + /* we need one hold for the entry we just stored into, + * and one for our own processing. When we're done with this + * function, we'll drop the one for our own processing. + * We held it once from the namei call, and so we do another hold + * now. + */ + cm_HoldSCache(scp); + lock_ObtainMutex(&scp->mx); + if ((scp->flags & CM_SCACHEFLAG_BULKSTATTING) == 0 + && LargeIntegerGreaterOrEqualToZero(scp->bulkStatProgress)) { + scp->flags |= CM_SCACHEFLAG_BULKSTATTING; + dsp->flags |= SMB_DIRSEARCH_BULKST; + } + lock_ReleaseMutex(&scp->mx); + } + } + lock_ReleaseMutex(&dsp->mx); + if (code) { + cm_ReleaseUser(userp); + smb_DeleteDirSearch(dsp); + smb_ReleaseDirSearch(dsp); + return code; + } + + /* reserves space for parameter; we'll adjust it again later to the + * real count of the # of entries we returned once we've actually + * assembled the directory listing. + */ + smb_SetSMBParm(outp, 0, 0); + + /* get the directory size */ + lock_ObtainMutex(&scp->mx); + code = cm_SyncOp(scp, NULL, userp, &req, 0, + CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + if (code) { + lock_ReleaseMutex(&scp->mx); + cm_ReleaseSCache(scp); + cm_ReleaseUser(userp); + smb_DeleteDirSearch(dsp); + smb_ReleaseDirSearch(dsp); + return code; + } + + dirLength = scp->length; + bufferp = NULL; + bufferOffset.LowPart = bufferOffset.HighPart = 0; + curOffset.HighPart = 0; + curOffset.LowPart = nextCookie; + origOp = op = smb_GetSMBData(outp, NULL); + /* and write out the basic header */ + *op++ = 5; /* variable block */ + op += 2; /* skip vbl block length; we'll fill it in later */ + code = 0; + returnedNames = 0; + while (1) { + /* make sure that curOffset.LowPart doesn't point to the first + * 32 bytes in the 2nd through last dir page, and that it doesn't + * point at the first 13 32-byte chunks in the first dir page, + * since those are dir and page headers, and don't contain useful + * information. + */ + temp = curOffset.LowPart & (2048-1); + if (curOffset.HighPart == 0 && curOffset.LowPart < 2048) { + /* we're in the first page */ + if (temp < 13*32) temp = 13*32; + } + else { + /* we're in a later dir page */ + if (temp < 32) temp = 32; + } + + /* make sure the low order 5 bits are zero */ + temp &= ~(32-1); + + /* now put temp bits back ito curOffset.LowPart */ + curOffset.LowPart &= ~(2048-1); + curOffset.LowPart |= temp; + + /* check if we've returned all the names that will fit in the + * response packet. + */ + if (returnedNames >= maxCount) + break; + + /* check if we've passed the dir's EOF */ + if (LargeIntegerGreaterThanOrEqualTo(curOffset, dirLength)) break; + + /* see if we can use the bufferp we have now; compute in which page + * the current offset would be, and check whether that's the offset + * of the buffer we have. If not, get the buffer. + */ + thyper.HighPart = curOffset.HighPart; + thyper.LowPart = curOffset.LowPart & ~(buf_bufferSize-1); + if (!bufferp || !LargeIntegerEqualTo(thyper, bufferOffset)) { + /* wrong buffer */ + if (bufferp) { + buf_Release(bufferp); + bufferp = NULL; + } + lock_ReleaseMutex(&scp->mx); + lock_ObtainRead(&scp->bufCreateLock); + code = buf_Get(scp, &thyper, &bufferp); + lock_ReleaseRead(&scp->bufCreateLock); + + /* now, if we're doing a star match, do bulk fetching of all of + * the status info for files in the dir. + */ + if (starPattern) { + smb_ApplyDirListPatches(&dirListPatchesp, userp, + &req); + if ((dsp->flags & SMB_DIRSEARCH_BULKST) && + LargeIntegerGreaterThanOrEqualTo(thyper, + scp->bulkStatProgress)) { + /* Don't bulk stat if risking timeout */ + int now = GetCurrentTime(); + if (now - req.startTime > 5000) { + scp->bulkStatProgress = thyper; + scp->flags &= ~CM_SCACHEFLAG_BULKSTATTING; + dsp->flags &= ~SMB_DIRSEARCH_BULKST; + } else + cm_TryBulkStat(scp, &thyper, userp, &req); + } + } + + lock_ObtainMutex(&scp->mx); + if (code) + break; + bufferOffset = thyper; + + /* now get the data in the cache */ + while (1) { + code = cm_SyncOp(scp, bufferp, userp, &req, + PRSFS_LOOKUP, + CM_SCACHESYNC_NEEDCALLBACK | + CM_SCACHESYNC_READ); + if (code) break; + + if (cm_HaveBuffer(scp, bufferp, 0)) break; + + /* otherwise, load the buffer and try again */ + code = cm_GetBuffer(scp, bufferp, NULL, userp, &req); + if (code) break; + } + if (code) { + buf_Release(bufferp); + bufferp = NULL; + break; + } + } /* if (wrong buffer) ... */ + + /* now we have the buffer containing the entry we're interested in; copy + * it out if it represents a non-deleted entry. + */ + entryInDir = curOffset.LowPart & (2048-1); + entryInBuffer = curOffset.LowPart & (buf_bufferSize - 1); + + /* page header will help tell us which entries are free. Page header + * can change more often than once per buffer, since AFS 3 dir page size + * may be less than (but not more than a buffer package buffer. + */ + temp = curOffset.LowPart & (buf_bufferSize - 1); /* only look intra-buffer */ + temp &= ~(2048 - 1); /* turn off intra-page bits */ + pageHeaderp = (cm_pageHeader_t *) (bufferp->datap + temp); + + /* now determine which entry we're looking at in the page. If it is + * free (there's a free bitmap at the start of the dir), we should + * skip these 32 bytes. + */ + slotInPage = (entryInDir & 0x7e0) >> 5; + if (!(pageHeaderp->freeBitmap[slotInPage>>3] & (1 << (slotInPage & 0x7)))) { + /* this entry is free */ + numDirChunks = 1; /* only skip this guy */ + goto nextEntry; + } + + tp = bufferp->datap + entryInBuffer; + dep = (cm_dirEntry_t *) tp; /* now points to AFS3 dir entry */ + + /* while we're here, compute the next entry's location, too, + * since we'll need it when writing out the cookie into the dir + * listing stream. + * + * XXXX Probably should do more sanity checking. + */ + numDirChunks = cm_NameEntries(dep->name, NULL); + + /* compute the offset of the cookie representing the next entry */ + nextEntryCookie = curOffset.LowPart + (CM_DIR_CHUNKSIZE * numDirChunks); + + /* Compute 8.3 name if necessary */ + actualName = dep->name; + if (dep->fid.vnode != 0 && !cm_Is8Dot3(actualName)) { + cm_Gen8Dot3Name(dep, shortName, &shortNameEnd); + actualName = shortName; + } + + if (dep->fid.vnode != 0 && smb_Match8Dot3Mask(actualName, mask)) { + /* this is one of the entries to use: it is not deleted + * and it matches the star pattern we're looking for. + */ + + /* Eliminate entries that don't match requested + * attributes */ + + /* no hidden files */ + if(smb_hideDotFiles && !(dsp->attribute & SMB_ATTR_HIDDEN) && smb_IsDotFile(actualName)) + goto nextEntry; + + if (!(dsp->attribute & SMB_ATTR_DIRECTORY)) /* no directories */ + { + /* We have already done the cm_TryBulkStat above */ + fid.cell = scp->fid.cell; + fid.volume = scp->fid.volume; + fid.vnode = ntohl(dep->fid.vnode); + fid.unique = ntohl(dep->fid.unique); + fileType = cm_FindFileType(&fid); + osi_Log2(smb_logp, "smb_ReceiveCoreSearchDir: file %s " + "has filetype %d", osi_LogSaveString(smb_logp, dep->name), + fileType); + if (fileType == CM_SCACHETYPE_DIRECTORY) + goto nextEntry; + } + + *op++ = resByte; + memcpy(op, mask, 11); op += 11; + *op++ = (char) dsp->cookie; /* they say it must be non-zero */ + *op++ = nextEntryCookie & 0xff; + *op++ = (nextEntryCookie>>8) & 0xff; + *op++ = (nextEntryCookie>>16) & 0xff; + *op++ = (nextEntryCookie>>24) & 0xff; + memcpy(op, &clientCookie, 4); op += 4; + + /* now we emit the attribute. This is sort of tricky, + * since we need to really stat the file to find out + * what type of entry we've got. Right now, we're + * copying out data from a buffer, while holding the + * scp locked, so it isn't really convenient to stat + * something now. We'll put in a place holder now, + * and make a second pass before returning this to get + * the real attributes. So, we just skip the data for + * now, and adjust it later. We allocate a patch + * record to make it easy to find this point later. + * The replay will happen at a time when it is safe to + * unlock the directory. + */ + curPatchp = malloc(sizeof(*curPatchp)); + osi_QAdd((osi_queue_t **) &dirListPatchesp, &curPatchp->q); + curPatchp->dptr = op; + curPatchp->fid.cell = scp->fid.cell; + curPatchp->fid.volume = scp->fid.volume; + curPatchp->fid.vnode = ntohl(dep->fid.vnode); + curPatchp->fid.unique = ntohl(dep->fid.unique); + + /* do hidden attribute here since name won't be around when applying + * dir list patches + */ + + if ( smb_hideDotFiles && smb_IsDotFile(actualName) ) + curPatchp->flags = SMB_DIRLISTPATCH_DOTFILE; + else + curPatchp->flags = 0; + + op += 9; /* skip attr, time, date and size */ + + /* zero out name area. The spec says to pad with + * spaces, but Samba doesn't, and neither do we. + */ + memset(op, 0, 13); + + /* finally, we get to copy out the name; we know that + * it fits in 8.3 or the pattern wouldn't match, but it + * never hurts to be sure. + */ + strncpy(op, actualName, 13); + + /* Uppercase if requested by client */ + if ((((smb_t *)inp)->flg2 & 1) == 0) + _strupr(op); + + op += 13; + + /* now, adjust the # of entries copied */ + returnedNames++; + } /* if we're including this name */ + + nextEntry: + /* and adjust curOffset to be where the new cookie is */ + thyper.HighPart = 0; + thyper.LowPart = CM_DIR_CHUNKSIZE * numDirChunks; + curOffset = LargeIntegerAdd(thyper, curOffset); + } /* while copying data for dir listing */ + + /* release the mutex */ + lock_ReleaseMutex(&scp->mx); + if (bufferp) buf_Release(bufferp); + + /* apply and free last set of patches; if not doing a star match, this + * will be empty, but better safe (and freeing everything) than sorry. + */ + smb_ApplyDirListPatches(&dirListPatchesp, userp, &req); + + /* special return code for unsuccessful search */ + if (code == 0 && dataLength < 21 && returnedNames == 0) + code = CM_ERROR_NOFILES; + + osi_Log2(smb_logp, "SMB search dir done, %d names, code %d", + returnedNames, code); + + if (code != 0) { + smb_DeleteDirSearch(dsp); + smb_ReleaseDirSearch(dsp); + cm_ReleaseSCache(scp); + cm_ReleaseUser(userp); + return code; + } + + /* finalize the output buffer */ + smb_SetSMBParm(outp, 0, returnedNames); + temp = (long) (op - origOp); + smb_SetSMBDataLength(outp, temp); + + /* the data area is a variable block, which has a 5 (already there) + * followed by the length of the # of data bytes. We now know this to + * be "temp," although that includes the 3 bytes of vbl block header. + * Deduct for them and fill in the length field. + */ + temp -= 3; /* deduct vbl block info */ + osi_assert(temp == (43 * returnedNames)); + origOp[1] = temp & 0xff; + origOp[2] = (temp>>8) & 0xff; + if (returnedNames == 0) + smb_DeleteDirSearch(dsp); + smb_ReleaseDirSearch(dsp); + cm_ReleaseSCache(scp); + cm_ReleaseUser(userp); + return code; +} + +/* verify that this is a valid path to a directory. I don't know why they + * don't use the get file attributes call. + */ long smb_ReceiveCoreCheckPath(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - char *pathp; - long code = 0; - cm_scache_t *rootScp; - cm_scache_t *newScp; - cm_user_t *userp; - unsigned int attrs; - int caseFold; - char *tidPathp; - cm_req_t req; - - cm_InitReq(&req); - - pathp = smb_GetSMBData(inp, NULL); - pathp = smb_ParseASCIIBlock(pathp, NULL); - osi_Log1(smb_logp, "SMB receive check path %s", - osi_LogSaveString(smb_logp, pathp)); - - if (!pathp) { - return CM_ERROR_BADFD; - } + char *pathp; + long code = 0; + cm_scache_t *rootScp; + cm_scache_t *newScp; + cm_user_t *userp; + unsigned int attrs; + int caseFold; + char *tidPathp; + cm_req_t req; + + cm_InitReq(&req); + + pathp = smb_GetSMBData(inp, NULL); + pathp = smb_ParseASCIIBlock(pathp, NULL); + osi_Log1(smb_logp, "SMB receive check path %s", + osi_LogSaveString(smb_logp, pathp)); + + if (!pathp) { + return CM_ERROR_BADFD; + } - rootScp = cm_rootSCachep; + rootScp = cm_rootSCachep; - userp = smb_GetUser(vcp, inp); + userp = smb_GetUser(vcp, inp); - caseFold = CM_FLAG_CASEFOLD; + caseFold = CM_FLAG_CASEFOLD; - code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); if(code) { cm_ReleaseUser(userp); return CM_ERROR_NOSUCHPATH; } - code = cm_NameI(rootScp, pathp, - caseFold | CM_FLAG_FOLLOW | CM_FLAG_CHECKPATH, - userp, tidPathp, &req, &newScp); + code = cm_NameI(rootScp, pathp, + caseFold | CM_FLAG_FOLLOW | CM_FLAG_CHECKPATH, + userp, tidPathp, &req, &newScp); - if (code) { - cm_ReleaseUser(userp); - return code; - } + if (code) { + cm_ReleaseUser(userp); + return code; + } - /* now lock the vnode with a callback; returns with newScp locked */ - lock_ObtainMutex(&newScp->mx); - code = cm_SyncOp(newScp, NULL, userp, &req, PRSFS_LOOKUP, - CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK); - if (code && code != CM_ERROR_NOACCESS) { - lock_ReleaseMutex(&newScp->mx); - cm_ReleaseSCache(newScp); - cm_ReleaseUser(userp); - return code; - } - - attrs = smb_Attributes(newScp); - - if (!(attrs & 0x10)) - code = CM_ERROR_NOTDIR; - - lock_ReleaseMutex(&newScp->mx); - - cm_ReleaseSCache(newScp); - cm_ReleaseUser(userp); - return code; + /* now lock the vnode with a callback; returns with newScp locked */ + lock_ObtainMutex(&newScp->mx); + code = cm_SyncOp(newScp, NULL, userp, &req, PRSFS_LOOKUP, + CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK); + if (code && code != CM_ERROR_NOACCESS) { + lock_ReleaseMutex(&newScp->mx); + cm_ReleaseSCache(newScp); + cm_ReleaseUser(userp); + return code; + } + + attrs = smb_Attributes(newScp); + + if (!(attrs & 0x10)) + code = CM_ERROR_NOTDIR; + + lock_ReleaseMutex(&newScp->mx); + + cm_ReleaseSCache(newScp); + cm_ReleaseUser(userp); + return code; } long smb_ReceiveCoreSetFileAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - char *pathp; - long code = 0; - cm_scache_t *rootScp; - unsigned short attribute; - cm_attr_t attr; - cm_scache_t *newScp; - time_t dosTime; - cm_user_t *userp; - int caseFold; - char *tidPathp; - cm_req_t req; - - cm_InitReq(&req); - - /* decode basic attributes we're passed */ - attribute = smb_GetSMBParm(inp, 0); - dosTime = smb_GetSMBParm(inp, 1) | (smb_GetSMBParm(inp, 2) << 16); - - pathp = smb_GetSMBData(inp, NULL); - pathp = smb_ParseASCIIBlock(pathp, NULL); - - if (!pathp) { - return CM_ERROR_BADSMB; - } + char *pathp; + long code = 0; + cm_scache_t *rootScp; + unsigned short attribute; + cm_attr_t attr; + cm_scache_t *newScp; + time_t dosTime; + cm_user_t *userp; + int caseFold; + char *tidPathp; + cm_req_t req; + + cm_InitReq(&req); + + /* decode basic attributes we're passed */ + attribute = smb_GetSMBParm(inp, 0); + dosTime = smb_GetSMBParm(inp, 1) | (smb_GetSMBParm(inp, 2) << 16); + + pathp = smb_GetSMBData(inp, NULL); + pathp = smb_ParseASCIIBlock(pathp, NULL); + + if (!pathp) { + return CM_ERROR_BADSMB; + } - osi_Log2(smb_logp, "SMB receive setfile attributes time %d, attr 0x%x", - dosTime, attribute); + osi_Log2(smb_logp, "SMB receive setfile attributes time %d, attr 0x%x", + dosTime, attribute); - rootScp = cm_rootSCachep; + rootScp = cm_rootSCachep; - userp = smb_GetUser(vcp, inp); + userp = smb_GetUser(vcp, inp); - caseFold = CM_FLAG_CASEFOLD; + caseFold = CM_FLAG_CASEFOLD; - code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); - if(code) { + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); + if (code) { cm_ReleaseUser(userp); return CM_ERROR_NOSUCHFILE; } - code = cm_NameI(rootScp, pathp, caseFold | CM_FLAG_FOLLOW, userp, - tidPathp, &req, &newScp); + code = cm_NameI(rootScp, pathp, caseFold | CM_FLAG_FOLLOW, userp, + tidPathp, &req, &newScp); - if (code) { - cm_ReleaseUser(userp); - return code; - } + if (code) { + cm_ReleaseUser(userp); + return code; + } - /* now lock the vnode with a callback; returns with newScp locked; we - * need the current status to determine what the new status is, in some - * cases. - */ - lock_ObtainMutex(&newScp->mx); - code = cm_SyncOp(newScp, NULL, userp, &req, 0, - CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK); - if (code) { - lock_ReleaseMutex(&newScp->mx); - cm_ReleaseSCache(newScp); - cm_ReleaseUser(userp); - return code; - } - - /* Check for RO volume */ - if (newScp->flags & CM_SCACHEFLAG_RO) { - lock_ReleaseMutex(&newScp->mx); - cm_ReleaseSCache(newScp); - cm_ReleaseUser(userp); - return CM_ERROR_READONLY; - } - - /* prepare for setattr call */ - attr.mask = 0; - if (dosTime != 0) { - attr.mask |= CM_ATTRMASK_CLIENTMODTIME; - smb_UnixTimeFromDosUTime(&attr.clientModTime, dosTime); - } - if ((newScp->unixModeBits & 0222) && (attribute & 1) != 0) { - /* we're told to make a writable file read-only */ - attr.unixModeBits = newScp->unixModeBits & ~0222; - attr.mask |= CM_ATTRMASK_UNIXMODEBITS; - } - else if ((newScp->unixModeBits & 0222) == 0 && (attribute & 1) == 0) { - /* we're told to make a read-only file writable */ - attr.unixModeBits = newScp->unixModeBits | 0222; - attr.mask |= CM_ATTRMASK_UNIXMODEBITS; - } - lock_ReleaseMutex(&newScp->mx); - - /* now call setattr */ - if (attr.mask) - code = cm_SetAttr(newScp, &attr, userp, &req); - else - code = 0; + /* now lock the vnode with a callback; returns with newScp locked; we + * need the current status to determine what the new status is, in some + * cases. + */ + lock_ObtainMutex(&newScp->mx); + code = cm_SyncOp(newScp, NULL, userp, &req, 0, + CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK); + if (code) { + lock_ReleaseMutex(&newScp->mx); + cm_ReleaseSCache(newScp); + cm_ReleaseUser(userp); + return code; + } + + /* Check for RO volume */ + if (newScp->flags & CM_SCACHEFLAG_RO) { + lock_ReleaseMutex(&newScp->mx); + cm_ReleaseSCache(newScp); + cm_ReleaseUser(userp); + return CM_ERROR_READONLY; + } + + /* prepare for setattr call */ + attr.mask = 0; + if (dosTime != 0) { + attr.mask |= CM_ATTRMASK_CLIENTMODTIME; + smb_UnixTimeFromDosUTime(&attr.clientModTime, dosTime); + } + if ((newScp->unixModeBits & 0222) && (attribute & 1) != 0) { + /* we're told to make a writable file read-only */ + attr.unixModeBits = newScp->unixModeBits & ~0222; + attr.mask |= CM_ATTRMASK_UNIXMODEBITS; + } + else if ((newScp->unixModeBits & 0222) == 0 && (attribute & 1) == 0) { + /* we're told to make a read-only file writable */ + attr.unixModeBits = newScp->unixModeBits | 0222; + attr.mask |= CM_ATTRMASK_UNIXMODEBITS; + } + lock_ReleaseMutex(&newScp->mx); + + /* now call setattr */ + if (attr.mask) + code = cm_SetAttr(newScp, &attr, userp, &req); + else + code = 0; - cm_ReleaseSCache(newScp); - cm_ReleaseUser(userp); + cm_ReleaseSCache(newScp); + cm_ReleaseUser(userp); - return code; + return code; } long smb_ReceiveCoreGetFileAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - char *pathp; - long code = 0; - cm_scache_t *rootScp; - cm_scache_t *newScp, *dscp; - time_t dosTime; - int attrs; - cm_user_t *userp; - int caseFold; - char *tidPathp; - cm_space_t *spacep; - char *lastComp; - cm_req_t req; - - cm_InitReq(&req); - - pathp = smb_GetSMBData(inp, NULL); - pathp = smb_ParseASCIIBlock(pathp, NULL); - - if (!pathp) { - return CM_ERROR_BADSMB; - } + char *pathp; + long code = 0; + cm_scache_t *rootScp; + cm_scache_t *newScp, *dscp; + time_t dosTime; + int attrs; + cm_user_t *userp; + int caseFold; + char *tidPathp; + cm_space_t *spacep; + char *lastComp; + cm_req_t req; + + cm_InitReq(&req); + + pathp = smb_GetSMBData(inp, NULL); + pathp = smb_ParseASCIIBlock(pathp, NULL); + + if (!pathp) { + return CM_ERROR_BADSMB; + } - if (*pathp == 0) /* null path */ - pathp = "\\"; + if (*pathp == 0) /* null path */ + pathp = "\\"; - osi_Log1(smb_logp, "SMB receive getfile attributes path %s", - osi_LogSaveString(smb_logp, pathp)); + osi_Log1(smb_logp, "SMB receive getfile attributes path %s", + osi_LogSaveString(smb_logp, pathp)); - rootScp = cm_rootSCachep; + rootScp = cm_rootSCachep; - userp = smb_GetUser(vcp, inp); + userp = smb_GetUser(vcp, inp); - /* we shouldn't need this for V3 requests, but we seem to */ - caseFold = CM_FLAG_CASEFOLD; + /* we shouldn't need this for V3 requests, but we seem to */ + caseFold = CM_FLAG_CASEFOLD; - code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); - if(code) { + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); + if (code) { cm_ReleaseUser(userp); return CM_ERROR_NOSUCHFILE; } - /* - * XXX Strange hack XXX - * - * As of Patch 5 (16 July 97), we are having the following problem: - * In NT Explorer 4.0, whenever we click on a directory, AFS gets - * requests to look up "desktop.ini" in all the subdirectories. - * This can cause zillions of timeouts looking up non-existent cells - * and volumes, especially in the top-level directory. - * - * We have not found any way to avoid this or work around it except - * to explicitly ignore the requests for mount points that haven't - * yet been evaluated and for directories that haven't yet been - * fetched. - * - * We should modify this hack to provide a fake desktop.ini file - * http://msdn.microsoft.com/library/en-us/shellcc/platform/shell/programmersguide/shell_basics/shell_basics_extending/custom.asp - */ - spacep = inp->spacep; - smb_StripLastComponent(spacep->data, &lastComp, pathp); - if (lastComp && stricmp(lastComp, "\\desktop.ini") == 0) { - code = cm_NameI(rootScp, spacep->data, - caseFold | CM_FLAG_DIRSEARCH | CM_FLAG_FOLLOW, - userp, tidPathp, &req, &dscp); - if (code == 0) { - if (dscp->fileType == CM_SCACHETYPE_MOUNTPOINT - && !dscp->mountRootFidp) - code = CM_ERROR_NOSUCHFILE; - else if (dscp->fileType == CM_SCACHETYPE_DIRECTORY) { - cm_buf_t *bp = buf_Find(dscp, &hzero); - if (bp) - buf_Release(bp); - else - code = CM_ERROR_NOSUCHFILE; - } - cm_ReleaseSCache(dscp); - if (code) { - cm_ReleaseUser(userp); - return code; - } - } - } - - code = cm_NameI(rootScp, pathp, caseFold | CM_FLAG_FOLLOW, userp, - tidPathp, &req, &newScp); - - if (code) { - cm_ReleaseUser(userp); - return code; - } + /* + * XXX Strange hack XXX + * + * As of Patch 5 (16 July 97), we are having the following problem: + * In NT Explorer 4.0, whenever we click on a directory, AFS gets + * requests to look up "desktop.ini" in all the subdirectories. + * This can cause zillions of timeouts looking up non-existent cells + * and volumes, especially in the top-level directory. + * + * We have not found any way to avoid this or work around it except + * to explicitly ignore the requests for mount points that haven't + * yet been evaluated and for directories that haven't yet been + * fetched. + * + * We should modify this hack to provide a fake desktop.ini file + * http://msdn.microsoft.com/library/en-us/shellcc/platform/shell/programmersguide/shell_basics/shell_basics_extending/custom.asp + */ + spacep = inp->spacep; + smb_StripLastComponent(spacep->data, &lastComp, pathp); + if (lastComp && stricmp(lastComp, "\\desktop.ini") == 0) { + code = cm_NameI(rootScp, spacep->data, + caseFold | CM_FLAG_DIRSEARCH | CM_FLAG_FOLLOW, + userp, tidPathp, &req, &dscp); + if (code == 0) { + if (dscp->fileType == CM_SCACHETYPE_MOUNTPOINT && + !dscp->mountRootFidp) + code = CM_ERROR_NOSUCHFILE; + else if (dscp->fileType == CM_SCACHETYPE_DIRECTORY) { + cm_buf_t *bp = buf_Find(dscp, &hzero); + if (bp) + buf_Release(bp); + else + code = CM_ERROR_NOSUCHFILE; + } + cm_ReleaseSCache(dscp); + if (code) { + cm_ReleaseUser(userp); + return code; + } + } + } + + code = cm_NameI(rootScp, pathp, caseFold | CM_FLAG_FOLLOW, userp, + tidPathp, &req, &newScp); + if (code) { + cm_ReleaseUser(userp); + return code; + } - /* now lock the vnode with a callback; returns with newScp locked */ - lock_ObtainMutex(&newScp->mx); - code = cm_SyncOp(newScp, NULL, userp, &req, 0, - CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK); - if (code) { - lock_ReleaseMutex(&newScp->mx); - cm_ReleaseSCache(newScp); - cm_ReleaseUser(userp); - return code; - } + /* now lock the vnode with a callback; returns with newScp locked */ + lock_ObtainMutex(&newScp->mx); + code = cm_SyncOp(newScp, NULL, userp, &req, 0, + CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK); + if (code) { + lock_ReleaseMutex(&newScp->mx); + cm_ReleaseSCache(newScp); + cm_ReleaseUser(userp); + return code; + } #ifdef undef /* use smb_Attributes instead. Also the fact that a file is - * in a readonly volume doesn't mean it shojuld be marked as RO - */ - if (newScp->fileType == CM_SCACHETYPE_DIRECTORY - || newScp->fileType == CM_SCACHETYPE_MOUNTPOINT) - attrs = SMB_ATTR_DIRECTORY; - else - attrs = 0; - if ((newScp->unixModeBits & 0222) == 0 || (newScp->flags & CM_SCACHEFLAG_RO)) - attrs |= SMB_ATTR_READONLY; /* turn on read-only flag */ + * in a readonly volume doesn't mean it shojuld be marked as RO + */ + if (newScp->fileType == CM_SCACHETYPE_DIRECTORY || + newScp->fileType == CM_SCACHETYPE_MOUNTPOINT) + attrs = SMB_ATTR_DIRECTORY; + else + attrs = 0; + if ((newScp->unixModeBits & 0222) == 0 || (newScp->flags & CM_SCACHEFLAG_RO)) + attrs |= SMB_ATTR_READONLY; /* turn on read-only flag */ #else attrs = smb_Attributes(newScp); #endif - smb_SetSMBParm(outp, 0, attrs); - - smb_DosUTimeFromUnixTime(&dosTime, newScp->clientModTime); - smb_SetSMBParm(outp, 1, dosTime & 0xffff); - smb_SetSMBParm(outp, 2, (dosTime>>16) & 0xffff); - smb_SetSMBParm(outp, 3, newScp->length.LowPart & 0xffff); - smb_SetSMBParm(outp, 4, (newScp->length.LowPart >> 16) & 0xffff); - smb_SetSMBParm(outp, 5, 0); - smb_SetSMBParm(outp, 6, 0); - smb_SetSMBParm(outp, 7, 0); - smb_SetSMBParm(outp, 8, 0); - smb_SetSMBParm(outp, 9, 0); - smb_SetSMBDataLength(outp, 0); - lock_ReleaseMutex(&newScp->mx); - - cm_ReleaseSCache(newScp); - cm_ReleaseUser(userp); + smb_SetSMBParm(outp, 0, attrs); - return 0; + smb_DosUTimeFromUnixTime(&dosTime, newScp->clientModTime); + smb_SetSMBParm(outp, 1, dosTime & 0xffff); + smb_SetSMBParm(outp, 2, (dosTime>>16) & 0xffff); + smb_SetSMBParm(outp, 3, newScp->length.LowPart & 0xffff); + smb_SetSMBParm(outp, 4, (newScp->length.LowPart >> 16) & 0xffff); + smb_SetSMBParm(outp, 5, 0); + smb_SetSMBParm(outp, 6, 0); + smb_SetSMBParm(outp, 7, 0); + smb_SetSMBParm(outp, 8, 0); + smb_SetSMBParm(outp, 9, 0); + smb_SetSMBDataLength(outp, 0); + lock_ReleaseMutex(&newScp->mx); + + cm_ReleaseSCache(newScp); + cm_ReleaseUser(userp); + + return 0; } long smb_ReceiveCoreTreeDisconnect(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - smb_tid_t *tidp; + smb_tid_t *tidp; - osi_Log0(smb_logp, "SMB receive tree disconnect"); - - /* find the tree and free it */ - tidp = smb_FindTID(vcp, ((smb_t *)inp)->tid, 0); - if (tidp) { - lock_ObtainMutex(&tidp->mx); - tidp->flags |= SMB_TIDFLAG_DELETE; - lock_ReleaseMutex(&tidp->mx); - smb_ReleaseTID(tidp); - } - - return 0; + osi_Log0(smb_logp, "SMB receive tree disconnect"); + + /* find the tree and free it */ + tidp = smb_FindTID(vcp, ((smb_t *)inp)->tid, 0); + if (tidp) { + lock_ObtainMutex(&tidp->mx); + tidp->flags |= SMB_TIDFLAG_DELETE; + lock_ReleaseMutex(&tidp->mx); + smb_ReleaseTID(tidp); + } + + return 0; } long smb_ReceiveCoreOpen(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - smb_fid_t *fidp; + smb_fid_t *fidp; char *pathp; - char *lastNamep; + char *lastNamep; int share; int attribute; - long code = 0; + long code = 0; cm_user_t *userp; cm_scache_t *scp; time_t dosTime; int caseFold; - cm_space_t *spacep; - char *tidPathp; - cm_req_t req; + cm_space_t *spacep; + char *tidPathp; + cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); pathp = smb_GetSMBData(inp, NULL); pathp = smb_ParseASCIIBlock(pathp, NULL); @@ -4086,36 +4115,36 @@ long smb_ReceiveCoreOpen(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) } #endif - share = smb_GetSMBParm(inp, 0); + share = smb_GetSMBParm(inp, 0); attribute = smb_GetSMBParm(inp, 1); - spacep = inp->spacep; - smb_StripLastComponent(spacep->data, &lastNamep, pathp); - if (lastNamep && strcmp(lastNamep, SMB_IOCTL_FILENAME) == 0) { - /* special case magic file name for receiving IOCTL requests + spacep = inp->spacep; + smb_StripLastComponent(spacep->data, &lastNamep, pathp); + if (lastNamep && strcmp(lastNamep, SMB_IOCTL_FILENAME) == 0) { + /* special case magic file name for receiving IOCTL requests * (since IOCTL calls themselves aren't getting through). */ fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE); - smb_SetupIoctlFid(fidp, spacep); - smb_SetSMBParm(outp, 0, fidp->fid); + smb_SetupIoctlFid(fidp, spacep); + smb_SetSMBParm(outp, 0, fidp->fid); smb_SetSMBParm(outp, 1, 0); /* attrs */ smb_SetSMBParm(outp, 2, 0); /* next 2 are DOS time */ smb_SetSMBParm(outp, 3, 0); smb_SetSMBParm(outp, 4, 0); /* next 2 are length */ smb_SetSMBParm(outp, 5, 0x7fff); - /* pass the open mode back */ + /* pass the open mode back */ smb_SetSMBParm(outp, 6, (share & 0xf)); smb_SetSMBDataLength(outp, 0); smb_ReleaseFID(fidp); return 0; } - userp = smb_GetUser(vcp, inp); + userp = smb_GetUser(vcp, inp); - caseFold = CM_FLAG_CASEFOLD; + caseFold = CM_FLAG_CASEFOLD; - code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); - if(code) { + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); + if (code) { cm_ReleaseUser(userp); return CM_ERROR_NOSUCHPATH; } @@ -4124,22 +4153,22 @@ long smb_ReceiveCoreOpen(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) if (code) { cm_ReleaseUser(userp); - return code; - } - + return code; + } + code = cm_CheckOpen(scp, share & 0x7, 0, userp, &req); - if (code) { - cm_ReleaseSCache(scp); - cm_ReleaseUser(userp); - return code; - } - - /* don't need callback to check file type, since file types never - * change, and namei and cm_Lookup all stat the object at least once on - * a successful return. + if (code) { + cm_ReleaseSCache(scp); + cm_ReleaseUser(userp); + return code; + } + + /* don't need callback to check file type, since file types never + * change, and namei and cm_Lookup all stat the object at least once on + * a successful return. */ if (scp->fileType != CM_SCACHETYPE_FILE) { - cm_ReleaseSCache(scp); + cm_ReleaseSCache(scp); cm_ReleaseUser(userp); return CM_ERROR_ISDIR; } @@ -4147,33 +4176,33 @@ long smb_ReceiveCoreOpen(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE); osi_assert(fidp); - /* save a pointer to the vnode */ + /* save a pointer to the vnode */ fidp->scp = scp; if ((share & 0xf) == 0) fidp->flags |= SMB_FID_OPENREAD; - else if ((share & 0xf) == 1) + else if ((share & 0xf) == 1) fidp->flags |= SMB_FID_OPENWRITE; - else + else fidp->flags |= (SMB_FID_OPENREAD | SMB_FID_OPENWRITE); - lock_ObtainMutex(&scp->mx); - smb_SetSMBParm(outp, 0, fidp->fid); + lock_ObtainMutex(&scp->mx); + smb_SetSMBParm(outp, 0, fidp->fid); smb_SetSMBParm(outp, 1, smb_Attributes(scp)); - smb_DosUTimeFromUnixTime(&dosTime, scp->clientModTime); + smb_DosUTimeFromUnixTime(&dosTime, scp->clientModTime); smb_SetSMBParm(outp, 2, dosTime & 0xffff); smb_SetSMBParm(outp, 3, (dosTime >> 16) & 0xffff); smb_SetSMBParm(outp, 4, scp->length.LowPart & 0xffff); smb_SetSMBParm(outp, 5, (scp->length.LowPart >> 16) & 0xffff); - /* pass the open mode back; XXXX add access checks */ + /* pass the open mode back; XXXX add access checks */ smb_SetSMBParm(outp, 6, (share & 0xf)); smb_SetSMBDataLength(outp, 0); - lock_ReleaseMutex(&scp->mx); + lock_ReleaseMutex(&scp->mx); - /* notify open */ + /* notify open */ cm_Open(scp, 0, userp); - /* send and free packet */ + /* send and free packet */ smb_ReleaseFID(fidp); cm_ReleaseUser(userp); /* don't release scp, since we've squirreled away the pointer in the fid struct */ @@ -4181,122 +4210,123 @@ long smb_ReceiveCoreOpen(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) } typedef struct smb_unlinkRock { - cm_scache_t *dscp; - cm_user_t *userp; - cm_req_t *reqp; - smb_vc_t *vcp; - char *maskp; /* pointer to the star pattern */ - int flags; - int any; + cm_scache_t *dscp; + cm_user_t *userp; + cm_req_t *reqp; + smb_vc_t *vcp; + char *maskp; /* pointer to the star pattern */ + int flags; + int any; } smb_unlinkRock_t; int smb_UnlinkProc(cm_scache_t *dscp, cm_dirEntry_t *dep, void *vrockp, osi_hyper_t *offp) { - long code = 0; - smb_unlinkRock_t *rockp; - int caseFold; - int match; - char shortName[13]; - char *matchName; + long code = 0; + smb_unlinkRock_t *rockp; + int caseFold; + int match; + char shortName[13]; + char *matchName; - rockp = vrockp; + rockp = vrockp; caseFold = ((rockp->flags & SMB_MASKFLAG_CASEFOLD)? CM_FLAG_CASEFOLD : 0); if (!(rockp->vcp->flags & SMB_VCFLAG_USEV3)) caseFold |= CM_FLAG_8DOT3; - matchName = dep->name; - match = smb_V3MatchMask(matchName, rockp->maskp, caseFold); - if (!match - && (rockp->flags & SMB_MASKFLAG_TILDE) - && !cm_Is8Dot3(dep->name)) { - cm_Gen8Dot3Name(dep, shortName, NULL); - matchName = shortName; + matchName = dep->name; + match = smb_V3MatchMask(matchName, rockp->maskp, caseFold); + if (!match && + (rockp->flags & SMB_MASKFLAG_TILDE) && + !cm_Is8Dot3(dep->name)) { + cm_Gen8Dot3Name(dep, shortName, NULL); + matchName = shortName; /* 8.3 matches are always case insensitive */ match = smb_V3MatchMask(matchName, rockp->maskp, caseFold | CM_FLAG_CASEFOLD); - } - if (match) { - osi_Log1(smb_logp, "Unlinking %s", - osi_LogSaveString(smb_logp, matchName)); - code = cm_Unlink(dscp, dep->name, rockp->userp, rockp->reqp); - if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) - smb_NotifyChange(FILE_ACTION_REMOVED, - FILE_NOTIFY_CHANGE_FILE_NAME, - dscp, dep->name, NULL, TRUE); - if (code == 0) { - rockp->any = 1; + } + if (match) { + osi_Log1(smb_logp, "Unlinking %s", + osi_LogSaveString(smb_logp, matchName)); + code = cm_Unlink(dscp, dep->name, rockp->userp, rockp->reqp); + if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) + smb_NotifyChange(FILE_ACTION_REMOVED, + FILE_NOTIFY_CHANGE_FILE_NAME, + dscp, dep->name, NULL, TRUE); + if (code == 0) { + rockp->any = 1; + /* If we made a case sensitive exact match, we might as well quit now. */ - if(!(rockp->flags & SMB_MASKFLAG_CASEFOLD) && !strcmp(matchName, rockp->maskp)) + if (!(rockp->flags & SMB_MASKFLAG_CASEFOLD) && !strcmp(matchName, rockp->maskp)) code = CM_ERROR_STOPNOW; } - } - else code = 0; + } + else code = 0; - return code; + return code; } long smb_ReceiveCoreUnlink(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - int attribute; - long code = 0; - char *pathp; - char *tp; - cm_space_t *spacep; - cm_scache_t *dscp; - char *lastNamep; - smb_unlinkRock_t rock; - cm_user_t *userp; - osi_hyper_t thyper; - int caseFold; - char *tidPathp; - cm_req_t req; - - cm_InitReq(&req); - - attribute = smb_GetSMBParm(inp, 0); + int attribute; + long code = 0; + char *pathp; + char *tp; + cm_space_t *spacep; + cm_scache_t *dscp; + char *lastNamep; + smb_unlinkRock_t rock; + cm_user_t *userp; + osi_hyper_t thyper; + int caseFold; + char *tidPathp; + cm_req_t req; + + cm_InitReq(&req); + + attribute = smb_GetSMBParm(inp, 0); - tp = smb_GetSMBData(inp, NULL); - pathp = smb_ParseASCIIBlock(tp, &tp); + tp = smb_GetSMBData(inp, NULL); + pathp = smb_ParseASCIIBlock(tp, &tp); - osi_Log1(smb_logp, "SMB receive unlink %s", - osi_LogSaveString(smb_logp, pathp)); + osi_Log1(smb_logp, "SMB receive unlink %s", + osi_LogSaveString(smb_logp, pathp)); - spacep = inp->spacep; - smb_StripLastComponent(spacep->data, &lastNamep, pathp); + spacep = inp->spacep; + smb_StripLastComponent(spacep->data, &lastNamep, pathp); - userp = smb_GetUser(vcp, inp); + userp = smb_GetUser(vcp, inp); - caseFold = CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD; + caseFold = CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD; - code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); - if(code) { + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); + if (code) { cm_ReleaseUser(userp); return CM_ERROR_NOSUCHPATH; } - code = cm_NameI(cm_rootSCachep, spacep->data, caseFold, userp, tidPathp, - &req, &dscp); + code = cm_NameI(cm_rootSCachep, spacep->data, caseFold, userp, tidPathp, + &req, &dscp); - if (code) { - cm_ReleaseUser(userp); - return code; - } - - /* otherwise, scp points to the parent directory. */ - if (!lastNamep) - lastNamep = pathp; - else - lastNamep++; - - rock.any = 0; - rock.maskp = smb_FindMask(pathp); - rock.flags = ((strchr(rock.maskp, '~') != NULL) ? SMB_MASKFLAG_TILDE : 0); + if (code) { + cm_ReleaseUser(userp); + return code; + } - thyper.LowPart = 0; - thyper.HighPart = 0; - rock.userp = userp; - rock.reqp = &req; - rock.dscp = dscp; - rock.vcp = vcp; + /* otherwise, scp points to the parent directory. */ + if (!lastNamep) + lastNamep = pathp; + else + lastNamep++; + + rock.any = 0; + rock.maskp = smb_FindMask(pathp); + rock.flags = ((strchr(rock.maskp, '~') != NULL) ? SMB_MASKFLAG_TILDE : 0); + + thyper.LowPart = 0; + thyper.HighPart = 0; + rock.userp = userp; + rock.reqp = &req; + rock.dscp = dscp; + rock.vcp = vcp; /* Now, if we aren't dealing with a wildcard match, we first try an exact * match. If that fails, we do a case insensitve match. @@ -4304,7 +4334,7 @@ long smb_ReceiveCoreUnlink(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) if (!(rock.flags & SMB_MASKFLAG_TILDE) && !smb_IsStarMask(rock.maskp)) { code = cm_ApplyDir(dscp, smb_UnlinkProc, &rock, &thyper, userp, &req, NULL); - if(!rock.any) { + if (!rock.any) { thyper.LowPart = 0; thyper.HighPart = 0; rock.flags |= SMB_MASKFLAG_CASEFOLD; @@ -4317,168 +4347,157 @@ long smb_ReceiveCoreUnlink(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) if (code == CM_ERROR_STOPNOW) code = 0; - cm_ReleaseUser(userp); + cm_ReleaseUser(userp); - cm_ReleaseSCache(dscp); + cm_ReleaseSCache(dscp); - if (code == 0 && !rock.any) - code = CM_ERROR_NOSUCHFILE; - return code; -} + if (code == 0 && !rock.any) + code = CM_ERROR_NOSUCHFILE; + return code; +} typedef struct smb_renameRock { - cm_scache_t *odscp; /* old dir */ - cm_scache_t *ndscp; /* new dir */ - cm_user_t *userp; /* user */ - cm_req_t *reqp; /* request struct */ - smb_vc_t *vcp; /* virtual circuit */ - char *maskp; /* pointer to star pattern of old file name */ - int flags; /* tilde, casefold, etc */ - char *newNamep; /* ptr to the new file's name */ + cm_scache_t *odscp; /* old dir */ + cm_scache_t *ndscp; /* new dir */ + cm_user_t *userp; /* user */ + cm_req_t *reqp; /* request struct */ + smb_vc_t *vcp; /* virtual circuit */ + char *maskp; /* pointer to star pattern of old file name */ + int flags; /* tilde, casefold, etc */ + char *newNamep; /* ptr to the new file's name */ } smb_renameRock_t; int smb_RenameProc(cm_scache_t *dscp, cm_dirEntry_t *dep, void *vrockp, osi_hyper_t *offp) { - long code = 0; - smb_renameRock_t *rockp; - int caseFold; - int match; - char shortName[13]; - - rockp = (smb_renameRock_t *) vrockp; + long code = 0; + smb_renameRock_t *rockp; + int caseFold; + int match; + char shortName[13]; + + rockp = (smb_renameRock_t *) vrockp; caseFold = ((rockp->flags & SMB_MASKFLAG_CASEFOLD)? CM_FLAG_CASEFOLD : 0); if (!(rockp->vcp->flags & SMB_VCFLAG_USEV3)) caseFold |= CM_FLAG_8DOT3; - match = smb_V3MatchMask(dep->name, rockp->maskp, caseFold); - if (!match - && (rockp->flags & SMB_MASKFLAG_TILDE) - && !cm_Is8Dot3(dep->name)) { - cm_Gen8Dot3Name(dep, shortName, NULL); - match = smb_V3MatchMask(shortName, rockp->maskp, caseFold); - } - if (match) { - code = cm_Rename(rockp->odscp, dep->name, - rockp->ndscp, rockp->newNamep, rockp->userp, - rockp->reqp); - /* if the call worked, stop doing the search now, since we - * really only want to rename one file. - */ - if (code == 0) - code = CM_ERROR_STOPNOW; - } - else code = 0; - - return code; + match = smb_V3MatchMask(dep->name, rockp->maskp, caseFold); + if (!match && + (rockp->flags & SMB_MASKFLAG_TILDE) && + !cm_Is8Dot3(dep->name)) { + cm_Gen8Dot3Name(dep, shortName, NULL); + match = smb_V3MatchMask(shortName, rockp->maskp, caseFold); + } + if (match) { + code = cm_Rename(rockp->odscp, dep->name, + rockp->ndscp, rockp->newNamep, rockp->userp, + rockp->reqp); + /* if the call worked, stop doing the search now, since we + * really only want to rename one file. + */ + if (code == 0) + code = CM_ERROR_STOPNOW; + } + else code = 0; + + return code; } -long smb_ReceiveCoreRename(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) + +long +smb_Rename(smb_vc_t *vcp, smb_packet_t *inp, char * oldPathp, char * newPathp, int attrs) { - long code = 0; - char *oldPathp; - char *newPathp; - char *tp; - cm_space_t *spacep = NULL; - smb_renameRock_t rock; - cm_scache_t *oldDscp = NULL; - cm_scache_t *newDscp = NULL; - cm_scache_t *tmpscp= NULL; - cm_scache_t *tmpscp2 = NULL; - char *oldLastNamep; - char *newLastNamep; - osi_hyper_t thyper; - cm_user_t *userp; - int caseFold; - char *tidPathp; - DWORD filter; - cm_req_t req; - - cm_InitReq(&req); - - tp = smb_GetSMBData(inp, NULL); - oldPathp = smb_ParseASCIIBlock(tp, &tp); - newPathp = smb_ParseASCIIBlock(tp, &tp); - - osi_Log2(smb_logp, "smb rename [%s] to [%s]", - osi_LogSaveString(smb_logp, oldPathp), - osi_LogSaveString(smb_logp, newPathp)); - - spacep = inp->spacep; - smb_StripLastComponent(spacep->data, &oldLastNamep, oldPathp); - - userp = smb_GetUser(vcp, inp); - - /* - * Changed to use CASEFOLD always. This enables us to rename Foo/baz when - * what actually exists is foo/baz. I don't know why the code used to be - * the way it was. 1/29/96 - * - * caseFold = ((vcp->flags & SMB_VCFLAG_USEV3) ? 0: CM_FLAG_CASEFOLD); - * - * Changed to use CM_FLAG_FOLLOW. 7/24/96 - * - * caseFold = CM_FLAG_CASEFOLD; - */ - caseFold = CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD; - - code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); - if(code) { + long code = 0; + cm_space_t *spacep = NULL; + smb_renameRock_t rock; + cm_scache_t *oldDscp = NULL; + cm_scache_t *newDscp = NULL; + cm_scache_t *tmpscp= NULL; + cm_scache_t *tmpscp2 = NULL; + char *oldLastNamep; + char *newLastNamep; + osi_hyper_t thyper; + cm_user_t *userp; + int caseFold; + char *tidPathp; + DWORD filter; + cm_req_t req; + + userp = smb_GetUser(vcp, inp); + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); + if (code) { cm_ReleaseUser(userp); return CM_ERROR_NOSUCHPATH; } - code = cm_NameI(cm_rootSCachep, spacep->data, caseFold, - userp, tidPathp, &req, &oldDscp); - if (code) { - cm_ReleaseUser(userp); - return code; - } + cm_InitReq(&req); + spacep = inp->spacep; + smb_StripLastComponent(spacep->data, &oldLastNamep, oldPathp); + + /* + * Changed to use CASEFOLD always. This enables us to rename Foo/baz when + * what actually exists is foo/baz. I don't know why the code used to be + * the way it was. 1/29/96 + * + * caseFold = ((vcp->flags & SMB_VCFLAG_USEV3) ? 0: CM_FLAG_CASEFOLD); + * + * Changed to use CM_FLAG_FOLLOW. 7/24/96 + * + * caseFold = CM_FLAG_CASEFOLD; + */ + caseFold = CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD; + code = cm_NameI(cm_rootSCachep, spacep->data, caseFold, + userp, tidPathp, &req, &oldDscp); + + if (code) { + cm_ReleaseUser(userp); + return code; + } - smb_StripLastComponent(spacep->data, &newLastNamep, newPathp); - code = cm_NameI(cm_rootSCachep, spacep->data, caseFold, - userp, tidPathp, &req, &newDscp); - - if (code) { - cm_ReleaseSCache(oldDscp); - cm_ReleaseUser(userp); - return code; - } + smb_StripLastComponent(spacep->data, &newLastNamep, newPathp); + code = cm_NameI(cm_rootSCachep, spacep->data, caseFold, + userp, tidPathp, &req, &newDscp); + + if (code) { + cm_ReleaseSCache(oldDscp); + cm_ReleaseUser(userp); + return code; + } - /* otherwise, oldDscp and newDscp point to the corresponding directories. - * next, get the component names, and lower case them. - */ - - /* handle the old name first */ - if (!oldLastNamep) - oldLastNamep = oldPathp; - else - oldLastNamep++; - - /* and handle the new name, too */ - if (!newLastNamep) - newLastNamep = newPathp; - else - newLastNamep++; + /* otherwise, oldDscp and newDscp point to the corresponding directories. + * next, get the component names, and lower case them. + */ + + /* handle the old name first */ + if (!oldLastNamep) + oldLastNamep = oldPathp; + else + oldLastNamep++; + + /* and handle the new name, too */ + if (!newLastNamep) + newLastNamep = newPathp; + else + newLastNamep++; /* TODO: The old name could be a wildcard. The new name must not be */ - - /* do the vnode call */ - rock.odscp = oldDscp; - rock.ndscp = newDscp; - rock.userp = userp; - rock.reqp = &req; - rock.vcp = vcp; - rock.maskp = oldLastNamep; - rock.flags = ((strchr(oldLastNamep, '~') != NULL) ? SMB_MASKFLAG_TILDE : 0); - rock.newNamep = newLastNamep; + + /* do the vnode call */ + rock.odscp = oldDscp; + rock.ndscp = newDscp; + rock.userp = userp; + rock.reqp = &req; + rock.vcp = vcp; + rock.maskp = oldLastNamep; + rock.flags = ((strchr(oldLastNamep, '~') != NULL) ? SMB_MASKFLAG_TILDE : 0); + rock.newNamep = newLastNamep; /* Check if the file already exists; if so return error */ - code = cm_Lookup(newDscp,newLastNamep,CM_FLAG_CHECKPATH,userp,&req,&tmpscp); - if ((code != CM_ERROR_NOSUCHFILE) && (code != CM_ERROR_NOSUCHPATH) && (code != CM_ERROR_NOSUCHVOLUME) ) { + code = cm_Lookup(newDscp,newLastNamep,CM_FLAG_CHECKPATH,userp,&req,&tmpscp); + if ((code != CM_ERROR_NOSUCHFILE) && (code != CM_ERROR_NOSUCHPATH) && (code != CM_ERROR_NOSUCHVOLUME) ) { osi_Log2(smb_logp, " lookup returns %ld for [%s]", code, osi_LogSaveString(afsd_logp, newLastNamep)); - + /* Check if the old and the new names differ only in case. If so return * success, else return CM_ERROR_EXISTS */ @@ -4502,157 +4521,306 @@ long smb_ReceiveCoreRename(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) code = CM_ERROR_EXISTS; } - if(tmpscp != NULL) + if (tmpscp != NULL) cm_ReleaseSCache(tmpscp); cm_ReleaseSCache(newDscp); cm_ReleaseSCache(oldDscp); cm_ReleaseUser(userp); - return code; - } + return code; + } /* Now search the directory for the pattern, and do the appropriate rename when found */ - thyper.LowPart = 0; /* search dir from here */ + thyper.LowPart = 0; /* search dir from here */ thyper.HighPart = 0; code = cm_ApplyDir(oldDscp, smb_RenameProc, &rock, &thyper, userp, &req, NULL); if (code == CM_ERROR_STOPNOW) - code = 0; - else if (code == 0) - code = CM_ERROR_NOSUCHFILE; - - /* Handle Change Notification */ - /* - * Being lazy, not distinguishing between files and dirs in this - * filter, since we'd have to do a lookup. - */ - filter = FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME; - if (oldDscp == newDscp) { - if (oldDscp->flags & CM_SCACHEFLAG_ANYWATCH) - smb_NotifyChange(FILE_ACTION_RENAMED_OLD_NAME, - filter, oldDscp, oldLastNamep, - newLastNamep, TRUE); - } else { - if (oldDscp->flags & CM_SCACHEFLAG_ANYWATCH) - smb_NotifyChange(FILE_ACTION_RENAMED_OLD_NAME, - filter, oldDscp, oldLastNamep, - NULL, TRUE); - if (newDscp->flags & CM_SCACHEFLAG_ANYWATCH) - smb_NotifyChange(FILE_ACTION_RENAMED_NEW_NAME, - filter, newDscp, newLastNamep, - NULL, TRUE); - } - - if(tmpscp != NULL) + code = 0; + else if (code == 0) + code = CM_ERROR_NOSUCHFILE; + + /* Handle Change Notification */ + /* + * Being lazy, not distinguishing between files and dirs in this + * filter, since we'd have to do a lookup. + */ + filter = FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME; + if (oldDscp == newDscp) { + if (oldDscp->flags & CM_SCACHEFLAG_ANYWATCH) + smb_NotifyChange(FILE_ACTION_RENAMED_OLD_NAME, + filter, oldDscp, oldLastNamep, + newLastNamep, TRUE); + } else { + if (oldDscp->flags & CM_SCACHEFLAG_ANYWATCH) + smb_NotifyChange(FILE_ACTION_RENAMED_OLD_NAME, + filter, oldDscp, oldLastNamep, + NULL, TRUE); + if (newDscp->flags & CM_SCACHEFLAG_ANYWATCH) + smb_NotifyChange(FILE_ACTION_RENAMED_NEW_NAME, + filter, newDscp, newLastNamep, + NULL, TRUE); + } + + if (tmpscp != NULL) + cm_ReleaseSCache(tmpscp); + cm_ReleaseUser(userp); + cm_ReleaseSCache(oldDscp); + cm_ReleaseSCache(newDscp); + return code; +} + +long +smb_Link(smb_vc_t *vcp, smb_packet_t *inp, char * oldPathp, char * newPathp) +{ + long code = 0; + cm_space_t *spacep = NULL; + cm_scache_t *oldDscp = NULL; + cm_scache_t *newDscp = NULL; + cm_scache_t *tmpscp= NULL; + cm_scache_t *tmpscp2 = NULL; + cm_scache_t *sscp = NULL; + char *oldLastNamep; + char *newLastNamep; + cm_user_t *userp; + int caseFold; + char *tidPathp; + DWORD filter; + cm_req_t req; + + userp = smb_GetUser(vcp, inp); + + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); + if (code) { + cm_ReleaseUser(userp); + return CM_ERROR_NOSUCHPATH; + } + + cm_InitReq(&req); + + caseFold = CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD; + + spacep = inp->spacep; + smb_StripLastComponent(spacep->data, &oldLastNamep, oldPathp); + + code = cm_NameI(cm_rootSCachep, spacep->data, caseFold, + userp, tidPathp, &req, &oldDscp); + if (code) { + cm_ReleaseUser(userp); + return code; + } + + smb_StripLastComponent(spacep->data, &newLastNamep, newPathp); + code = cm_NameI(cm_rootSCachep, spacep->data, caseFold, + userp, tidPathp, &req, &newDscp); + if (code) { + cm_ReleaseSCache(oldDscp); + cm_ReleaseUser(userp); + return code; + } + + /* Now, although we did two lookups for the two directories (because the same + * directory can be referenced through different paths), we only allow hard links + * within the same directory. */ + if (oldDscp != newDscp) { + cm_ReleaseSCache(oldDscp); + cm_ReleaseSCache(newDscp); + cm_ReleaseUser(userp); + return CM_ERROR_CROSSDEVLINK; + } + + /* handle the old name first */ + if (!oldLastNamep) + oldLastNamep = oldPathp; + else + oldLastNamep++; + + /* and handle the new name, too */ + if (!newLastNamep) + newLastNamep = newPathp; + else + newLastNamep++; + + /* now lookup the old name */ + osi_Log1(smb_logp," looking up [%s]", osi_LogSaveString(smb_logp,oldLastNamep)); + code = cm_Lookup(oldDscp, oldLastNamep, CM_FLAG_CHECKPATH | CM_FLAG_CASEFOLD, userp, &req, &sscp); + if (code) { + cm_ReleaseSCache(oldDscp); + cm_ReleaseSCache(newDscp); + cm_ReleaseUser(userp); + return code; + } + + /* Check if the file already exists; if so return error */ + code = cm_Lookup(newDscp,newLastNamep,CM_FLAG_CHECKPATH,userp,&req,&tmpscp); + if ((code != CM_ERROR_NOSUCHFILE) && (code != CM_ERROR_NOSUCHPATH) && (code != CM_ERROR_NOSUCHVOLUME) ) { + osi_Log2(smb_logp, " lookup returns %ld for [%s]", code, + osi_LogSaveString(afsd_logp, newLastNamep)); + + /* if the existing link is to the same file, then we return success */ + if (!code) { + if(sscp == tmpscp) { + code = 0; + } else { + osi_Log0(smb_logp, "Can't create hardlink. Target already exists"); + code = CM_ERROR_EXISTS; + } + } + + if (tmpscp != NULL) + cm_ReleaseSCache(tmpscp); + cm_ReleaseSCache(sscp); + cm_ReleaseSCache(newDscp); + cm_ReleaseSCache(oldDscp); + cm_ReleaseUser(userp); + return code; + } + + /* now create the hardlink */ + osi_Log1(smb_logp," Attempting to create new link [%s]", osi_LogSaveString(smb_logp, newLastNamep)); + code = cm_Link(newDscp, newLastNamep, sscp, 0, userp, &req); + osi_Log1(smb_logp," Link returns %d", code); + + /* Handle Change Notification */ + if (code == 0) { + filter = (sscp->fileType == CM_SCACHETYPE_FILE)? FILE_NOTIFY_CHANGE_FILE_NAME : FILE_NOTIFY_CHANGE_DIR_NAME; + if (newDscp->flags & CM_SCACHEFLAG_ANYWATCH) + smb_NotifyChange(FILE_ACTION_ADDED, + filter, newDscp, newLastNamep, + NULL, TRUE); + } + + if (tmpscp != NULL) cm_ReleaseSCache(tmpscp); cm_ReleaseUser(userp); - cm_ReleaseSCache(oldDscp); - cm_ReleaseSCache(newDscp); - return code; + cm_ReleaseSCache(sscp); + cm_ReleaseSCache(oldDscp); + cm_ReleaseSCache(newDscp); + return code; } +long +smb_ReceiveCoreRename(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) +{ + char *oldPathp; + char *newPathp; + char *tp; + + tp = smb_GetSMBData(inp, NULL); + oldPathp = smb_ParseASCIIBlock(tp, &tp); + newPathp = smb_ParseASCIIBlock(tp, &tp); + + osi_Log2(smb_logp, "smb rename [%s] to [%s]", + osi_LogSaveString(smb_logp, oldPathp), + osi_LogSaveString(smb_logp, newPathp)); + + return smb_Rename(vcp,inp,oldPathp,newPathp,0); +} + + + typedef struct smb_rmdirRock { - cm_scache_t *dscp; - cm_user_t *userp; - cm_req_t *reqp; - char *maskp; /* pointer to the star pattern */ - int flags; - int any; + cm_scache_t *dscp; + cm_user_t *userp; + cm_req_t *reqp; + char *maskp; /* pointer to the star pattern */ + int flags; + int any; } smb_rmdirRock_t; int smb_RmdirProc(cm_scache_t *dscp, cm_dirEntry_t *dep, void *vrockp, osi_hyper_t *offp) -{ - long code = 0; - smb_rmdirRock_t *rockp; - int match; - char shortName[13]; - char *matchName; +{ + long code = 0; + smb_rmdirRock_t *rockp; + int match; + char shortName[13]; + char *matchName; - rockp = (smb_rmdirRock_t *) vrockp; + rockp = (smb_rmdirRock_t *) vrockp; - matchName = dep->name; + matchName = dep->name; if (rockp->flags & SMB_MASKFLAG_CASEFOLD) match = (cm_stricmp(matchName, rockp->maskp) == 0); else match = (strcmp(matchName, rockp->maskp) == 0); - if (!match - && (rockp->flags & SMB_MASKFLAG_TILDE) - && !cm_Is8Dot3(dep->name)) { - cm_Gen8Dot3Name(dep, shortName, NULL); - matchName = shortName; - match = (cm_stricmp(matchName, rockp->maskp) == 0); - } - if (match) { - osi_Log1(smb_logp, "Removing directory %s", - osi_LogSaveString(smb_logp, matchName)); - code = cm_RemoveDir(dscp, dep->name, rockp->userp, rockp->reqp); - if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) - smb_NotifyChange(FILE_ACTION_REMOVED, - FILE_NOTIFY_CHANGE_DIR_NAME, - dscp, dep->name, NULL, TRUE); - if (code == 0) - rockp->any = 1; - } - else code = 0; - - return code; + if (!match && + (rockp->flags & SMB_MASKFLAG_TILDE) && + !cm_Is8Dot3(dep->name)) { + cm_Gen8Dot3Name(dep, shortName, NULL); + matchName = shortName; + match = (cm_stricmp(matchName, rockp->maskp) == 0); + } + if (match) { + osi_Log1(smb_logp, "Removing directory %s", + osi_LogSaveString(smb_logp, matchName)); + code = cm_RemoveDir(dscp, dep->name, rockp->userp, rockp->reqp); + if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) + smb_NotifyChange(FILE_ACTION_REMOVED, + FILE_NOTIFY_CHANGE_DIR_NAME, + dscp, dep->name, NULL, TRUE); + if (code == 0) + rockp->any = 1; + } + else code = 0; + + return code; } long smb_ReceiveCoreRemoveDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - long code = 0; - char *pathp; - char *tp; - cm_space_t *spacep; - cm_scache_t *dscp; - char *lastNamep; - smb_rmdirRock_t rock; - cm_user_t *userp; - osi_hyper_t thyper; - int caseFold; - char *tidPathp; - cm_req_t req; + long code = 0; + char *pathp; + char *tp; + cm_space_t *spacep; + cm_scache_t *dscp; + char *lastNamep; + smb_rmdirRock_t rock; + cm_user_t *userp; + osi_hyper_t thyper; + int caseFold; + char *tidPathp; + cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); - tp = smb_GetSMBData(inp, NULL); - pathp = smb_ParseASCIIBlock(tp, &tp); + tp = smb_GetSMBData(inp, NULL); + pathp = smb_ParseASCIIBlock(tp, &tp); - spacep = inp->spacep; - smb_StripLastComponent(spacep->data, &lastNamep, pathp); + spacep = inp->spacep; + smb_StripLastComponent(spacep->data, &lastNamep, pathp); - userp = smb_GetUser(vcp, inp); + userp = smb_GetUser(vcp, inp); - caseFold = CM_FLAG_CASEFOLD; + caseFold = CM_FLAG_CASEFOLD; - code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); - if(code) { + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); + if (code) { cm_ReleaseUser(userp); return CM_ERROR_NOSUCHPATH; } - code = cm_NameI(cm_rootSCachep, spacep->data, caseFold | CM_FLAG_FOLLOW, - userp, tidPathp, &req, &dscp); + code = cm_NameI(cm_rootSCachep, spacep->data, caseFold | CM_FLAG_FOLLOW, + userp, tidPathp, &req, &dscp); - if (code) { - cm_ReleaseUser(userp); - return code; - } + if (code) { + cm_ReleaseUser(userp); + return code; + } - /* otherwise, scp points to the parent directory. */ - if (!lastNamep) - lastNamep = pathp; - else - lastNamep++; + /* otherwise, scp points to the parent directory. */ + if (!lastNamep) + lastNamep = pathp; + else + lastNamep++; - rock.any = 0; - rock.maskp = lastNamep; - rock.flags = ((strchr(rock.maskp, '~') != NULL) ? SMB_MASKFLAG_TILDE : 0); - - thyper.LowPart = 0; - thyper.HighPart = 0; - rock.userp = userp; - rock.reqp = &req; - rock.dscp = dscp; + rock.any = 0; + rock.maskp = lastNamep; + rock.flags = ((strchr(rock.maskp, '~') != NULL) ? SMB_MASKFLAG_TILDE : 0); + + thyper.LowPart = 0; + thyper.HighPart = 0; + rock.userp = userp; + rock.reqp = &req; + rock.dscp = dscp; /* First do a case sensitive match, and if that fails, do a case insensitive match */ code = cm_ApplyDir(dscp, smb_RmdirProc, &rock, &thyper, userp, &req, NULL); if (code == 0 && !rock.any) { @@ -4662,30 +4830,30 @@ long smb_ReceiveCoreRemoveDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou code = cm_ApplyDir(dscp, smb_RmdirProc, &rock, &thyper, userp, &req, NULL); } - cm_ReleaseUser(userp); + cm_ReleaseUser(userp); - cm_ReleaseSCache(dscp); + cm_ReleaseSCache(dscp); - if (code == 0 && !rock.any) - code = CM_ERROR_NOSUCHFILE; - return code; + if (code == 0 && !rock.any) + code = CM_ERROR_NOSUCHFILE; + return code; } long smb_ReceiveCoreFlush(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - unsigned short fid; + unsigned short fid; smb_fid_t *fidp; cm_user_t *userp; long code = 0; cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); - fid = smb_GetSMBParm(inp, 0); - - osi_Log1(smb_logp, "SMB flush fid %d", fid); + fid = smb_GetSMBParm(inp, 0); + + osi_Log1(smb_logp, "SMB flush fid %d", fid); - fid = smb_ChainFID(fid, inp); + fid = smb_ChainFID(fid, inp); fidp = smb_FindFID(vcp, fid, 0); if (!fidp || (fidp->flags & SMB_FID_IOCTL)) { if (fidp) @@ -4698,8 +4866,8 @@ long smb_ReceiveCoreFlush(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) lock_ObtainMutex(&fidp->mx); if (fidp->flags & SMB_FID_OPENWRITE) code = cm_FSync(fidp->scp, userp, &req); - else - code = 0; + else + code = 0; lock_ReleaseMutex(&fidp->mx); smb_ReleaseFID(fidp); @@ -4710,137 +4878,137 @@ long smb_ReceiveCoreFlush(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) } struct smb_FullNameRock { - char *name; - cm_scache_t *vnode; - char *fullName; + char *name; + cm_scache_t *vnode; + char *fullName; }; int smb_FullNameProc(cm_scache_t *scp, cm_dirEntry_t *dep, void *rockp, - osi_hyper_t *offp) + osi_hyper_t *offp) { - char shortName[13]; - struct smb_FullNameRock *vrockp; - - vrockp = (struct smb_FullNameRock *)rockp; - - if (!cm_Is8Dot3(dep->name)) { - cm_Gen8Dot3Name(dep, shortName, NULL); - - if (cm_stricmp(shortName, vrockp->name) == 0) { - vrockp->fullName = strdup(dep->name); - return CM_ERROR_STOPNOW; - } - } - if (cm_stricmp(dep->name, vrockp->name) == 0 - && ntohl(dep->fid.vnode) == vrockp->vnode->fid.vnode - && ntohl(dep->fid.unique) == vrockp->vnode->fid.unique) { - vrockp->fullName = strdup(dep->name); - return CM_ERROR_STOPNOW; - } - return 0; + char shortName[13]; + struct smb_FullNameRock *vrockp; + + vrockp = (struct smb_FullNameRock *)rockp; + + if (!cm_Is8Dot3(dep->name)) { + cm_Gen8Dot3Name(dep, shortName, NULL); + + if (cm_stricmp(shortName, vrockp->name) == 0) { + vrockp->fullName = strdup(dep->name); + return CM_ERROR_STOPNOW; + } + } + if (cm_stricmp(dep->name, vrockp->name) == 0 && + ntohl(dep->fid.vnode) == vrockp->vnode->fid.vnode && + ntohl(dep->fid.unique) == vrockp->vnode->fid.unique) { + vrockp->fullName = strdup(dep->name); + return CM_ERROR_STOPNOW; + } + return 0; } void smb_FullName(cm_scache_t *dscp, cm_scache_t *scp, char *pathp, - char **newPathp, cm_user_t *userp, cm_req_t *reqp) + char **newPathp, cm_user_t *userp, cm_req_t *reqp) { - struct smb_FullNameRock rock; - long code = 0; - - rock.name = pathp; - rock.vnode = scp; - - code = cm_ApplyDir(dscp, smb_FullNameProc, &rock, NULL, - userp, reqp, NULL); - if (code == CM_ERROR_STOPNOW) - *newPathp = rock.fullName; - else - *newPathp = strdup(pathp); + struct smb_FullNameRock rock; + long code = 0; + + rock.name = pathp; + rock.vnode = scp; + + code = cm_ApplyDir(dscp, smb_FullNameProc, &rock, NULL, + userp, reqp, NULL); + if (code == CM_ERROR_STOPNOW) + *newPathp = rock.fullName; + else + *newPathp = strdup(pathp); } long smb_ReceiveCoreClose(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - unsigned short fid; + unsigned short fid; smb_fid_t *fidp; cm_user_t *userp; - long dosTime; + long dosTime; long code = 0; - cm_req_t req; + cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); - fid = smb_GetSMBParm(inp, 0); - dosTime = smb_GetSMBParm(inp, 1) | (smb_GetSMBParm(inp, 2) << 16); - - osi_Log1(smb_logp, "SMB close fid %d", fid); + fid = smb_GetSMBParm(inp, 0); + dosTime = smb_GetSMBParm(inp, 1) | (smb_GetSMBParm(inp, 2) << 16); - fid = smb_ChainFID(fid, inp); + osi_Log1(smb_logp, "SMB close fid %d", fid); + + fid = smb_ChainFID(fid, inp); fidp = smb_FindFID(vcp, fid, 0); if (!fidp) { return CM_ERROR_BADFD; } - userp = smb_GetUser(vcp, inp); + userp = smb_GetUser(vcp, inp); lock_ObtainMutex(&fidp->mx); - /* Don't jump the gun on an async raw write */ - while (fidp->raw_writers) { - lock_ReleaseMutex(&fidp->mx); - thrd_WaitForSingleObject_Event(fidp->raw_write_event, RAWTIMEOUT); - lock_ObtainMutex(&fidp->mx); - } + /* Don't jump the gun on an async raw write */ + while (fidp->raw_writers) { + lock_ReleaseMutex(&fidp->mx); + thrd_WaitForSingleObject_Event(fidp->raw_write_event, RAWTIMEOUT); + lock_ObtainMutex(&fidp->mx); + } - fidp->flags |= SMB_FID_DELETE; + fidp->flags |= SMB_FID_DELETE; - /* watch for ioctl closes, and read-only opens */ - if (fidp->scp != NULL - && (fidp->flags & (SMB_FID_OPENWRITE | SMB_FID_DELONCLOSE)) + /* watch for ioctl closes, and read-only opens */ + if (fidp->scp != NULL && + (fidp->flags & (SMB_FID_OPENWRITE | SMB_FID_DELONCLOSE)) == SMB_FID_OPENWRITE) { - if (dosTime != 0 && dosTime != -1) { - fidp->scp->mask |= CM_SCACHEMASK_CLIENTMODTIME; + if (dosTime != 0 && dosTime != -1) { + fidp->scp->mask |= CM_SCACHEMASK_CLIENTMODTIME; /* This fixes defect 10958 */ CompensateForSmbClientLastWriteTimeBugs(&dosTime); - smb_UnixTimeFromDosUTime(&fidp->scp->clientModTime, dosTime); - } + smb_UnixTimeFromDosUTime(&fidp->scp->clientModTime, dosTime); + } code = cm_FSync(fidp->scp, userp, &req); - } - else + } + else code = 0; - if (fidp->flags & SMB_FID_DELONCLOSE) { - cm_scache_t *dscp = fidp->NTopen_dscp; - char *pathp = fidp->NTopen_pathp; - char *fullPathp; + if (fidp->flags & SMB_FID_DELONCLOSE) { + cm_scache_t *dscp = fidp->NTopen_dscp; + char *pathp = fidp->NTopen_pathp; + char *fullPathp; - smb_FullName(dscp, fidp->scp, pathp, &fullPathp, userp, &req); - if (fidp->scp->fileType == CM_SCACHETYPE_DIRECTORY) { - code = cm_RemoveDir(dscp, fullPathp, userp, &req); - if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) - smb_NotifyChange(FILE_ACTION_REMOVED, + smb_FullName(dscp, fidp->scp, pathp, &fullPathp, userp, &req); + if (fidp->scp->fileType == CM_SCACHETYPE_DIRECTORY) { + code = cm_RemoveDir(dscp, fullPathp, userp, &req); + if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) + smb_NotifyChange(FILE_ACTION_REMOVED, FILE_NOTIFY_CHANGE_DIR_NAME, dscp, fullPathp, NULL, TRUE); - } - else + } + else { - code = cm_Unlink(dscp, fullPathp, userp, &req); - if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) - smb_NotifyChange(FILE_ACTION_REMOVED, + code = cm_Unlink(dscp, fullPathp, userp, &req); + if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) + smb_NotifyChange(FILE_ACTION_REMOVED, FILE_NOTIFY_CHANGE_FILE_NAME, dscp, fullPathp, NULL, TRUE); - } - free(fullPathp); - } + } + free(fullPathp); + } lock_ReleaseMutex(&fidp->mx); if (fidp->flags & SMB_FID_NTOPEN) { - cm_ReleaseSCache(fidp->NTopen_dscp); - free(fidp->NTopen_pathp); - } - if (fidp->NTopen_wholepathp) - free(fidp->NTopen_wholepathp); + cm_ReleaseSCache(fidp->NTopen_dscp); + free(fidp->NTopen_pathp); + } + if (fidp->NTopen_wholepathp) + free(fidp->NTopen_wholepathp); smb_ReleaseFID(fidp); - cm_ReleaseUser(userp); + cm_ReleaseUser(userp); return code; } @@ -4855,147 +5023,147 @@ long smb_ReadData(smb_fid_t *fidp, osi_hyper_t *offsetp, long count, char *op, cm_user_t *userp, long *readp, int dosflag) #endif /* !DJGPP */ { - osi_hyper_t offset; - long code = 0; - cm_scache_t *scp; - cm_buf_t *bufferp; - osi_hyper_t fileLength; - osi_hyper_t thyper; - osi_hyper_t lastByte; - osi_hyper_t bufferOffset; - long bufIndex, nbytes; - int chunk; - int sequential = 0; - cm_req_t req; - - cm_InitReq(&req); - - bufferp = NULL; - offset = *offsetp; - - lock_ObtainMutex(&fidp->mx); - scp = fidp->scp; - lock_ObtainMutex(&scp->mx); - - if (offset.HighPart == 0) { - chunk = offset.LowPart >> cm_logChunkSize; - if (chunk != fidp->curr_chunk) { - fidp->prev_chunk = fidp->curr_chunk; - fidp->curr_chunk = chunk; - } - if (fidp->curr_chunk == fidp->prev_chunk + 1) - sequential = 1; - } - - /* start by looking up the file's end */ - code = cm_SyncOp(scp, NULL, userp, &req, 0, - CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); - if (code) goto done; - - /* now we have the entry locked, look up the length */ - fileLength = scp->length; - - /* adjust count down so that it won't go past EOF */ - thyper.LowPart = count; - thyper.HighPart = 0; - thyper = LargeIntegerAdd(offset, thyper); /* where read should end */ - lastByte = thyper; - if (LargeIntegerGreaterThan(thyper, fileLength)) { - /* we'd read past EOF, so just stop at fileLength bytes. - * Start by computing how many bytes remain in the file. - */ - thyper = LargeIntegerSubtract(fileLength, offset); - - /* if we are past EOF, read 0 bytes */ - if (LargeIntegerLessThanZero(thyper)) - count = 0; - else - count = thyper.LowPart; - } - - *readp = count; - - /* now, copy the data one buffer at a time, - * until we've filled the request packet - */ - while (1) { - /* if we've copied all the data requested, we're done */ - if (count <= 0) break; - - /* otherwise, load up a buffer of data */ - thyper.HighPart = offset.HighPart; - thyper.LowPart = offset.LowPart & ~(buf_bufferSize-1); - if (!bufferp || !LargeIntegerEqualTo(thyper, bufferOffset)) { - /* wrong buffer */ - if (bufferp) { - buf_Release(bufferp); - bufferp = NULL; - } - lock_ReleaseMutex(&scp->mx); - - lock_ObtainRead(&scp->bufCreateLock); - code = buf_Get(scp, &thyper, &bufferp); - lock_ReleaseRead(&scp->bufCreateLock); - - lock_ObtainMutex(&scp->mx); - if (code) goto done; - bufferOffset = thyper; - - /* now get the data in the cache */ - while (1) { - code = cm_SyncOp(scp, bufferp, userp, &req, 0, - CM_SCACHESYNC_NEEDCALLBACK - | CM_SCACHESYNC_READ); - if (code) goto done; + osi_hyper_t offset; + long code = 0; + cm_scache_t *scp; + cm_buf_t *bufferp; + osi_hyper_t fileLength; + osi_hyper_t thyper; + osi_hyper_t lastByte; + osi_hyper_t bufferOffset; + long bufIndex, nbytes; + int chunk; + int sequential = 0; + cm_req_t req; + + cm_InitReq(&req); + + bufferp = NULL; + offset = *offsetp; + + lock_ObtainMutex(&fidp->mx); + scp = fidp->scp; + lock_ObtainMutex(&scp->mx); + + if (offset.HighPart == 0) { + chunk = offset.LowPart >> cm_logChunkSize; + if (chunk != fidp->curr_chunk) { + fidp->prev_chunk = fidp->curr_chunk; + fidp->curr_chunk = chunk; + } + if (fidp->curr_chunk == fidp->prev_chunk + 1) + sequential = 1; + } + + /* start by looking up the file's end */ + code = cm_SyncOp(scp, NULL, userp, &req, 0, + CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + if (code) goto done; + + /* now we have the entry locked, look up the length */ + fileLength = scp->length; + + /* adjust count down so that it won't go past EOF */ + thyper.LowPart = count; + thyper.HighPart = 0; + thyper = LargeIntegerAdd(offset, thyper); /* where read should end */ + lastByte = thyper; + if (LargeIntegerGreaterThan(thyper, fileLength)) { + /* we'd read past EOF, so just stop at fileLength bytes. + * Start by computing how many bytes remain in the file. + */ + thyper = LargeIntegerSubtract(fileLength, offset); + + /* if we are past EOF, read 0 bytes */ + if (LargeIntegerLessThanZero(thyper)) + count = 0; + else + count = thyper.LowPart; + } + + *readp = count; + + /* now, copy the data one buffer at a time, + * until we've filled the request packet + */ + while (1) { + /* if we've copied all the data requested, we're done */ + if (count <= 0) break; + + /* otherwise, load up a buffer of data */ + thyper.HighPart = offset.HighPart; + thyper.LowPart = offset.LowPart & ~(buf_bufferSize-1); + if (!bufferp || !LargeIntegerEqualTo(thyper, bufferOffset)) { + /* wrong buffer */ + if (bufferp) { + buf_Release(bufferp); + bufferp = NULL; + } + lock_ReleaseMutex(&scp->mx); + + lock_ObtainRead(&scp->bufCreateLock); + code = buf_Get(scp, &thyper, &bufferp); + lock_ReleaseRead(&scp->bufCreateLock); + + lock_ObtainMutex(&scp->mx); + if (code) goto done; + bufferOffset = thyper; + + /* now get the data in the cache */ + while (1) { + code = cm_SyncOp(scp, bufferp, userp, &req, 0, + CM_SCACHESYNC_NEEDCALLBACK | + CM_SCACHESYNC_READ); + if (code) goto done; - if (cm_HaveBuffer(scp, bufferp, 0)) break; - - /* otherwise, load the buffer and try again */ - code = cm_GetBuffer(scp, bufferp, NULL, userp, &req); - if (code) break; - } - if (code) { - buf_Release(bufferp); - bufferp = NULL; - goto done; - } - } /* if (wrong buffer) ... */ - - /* now we have the right buffer loaded. Copy out the - * data from here to the user's buffer. - */ - bufIndex = offset.LowPart & (buf_bufferSize - 1); - - /* and figure out how many bytes we want from this buffer */ - nbytes = buf_bufferSize - bufIndex; /* what remains in buffer */ - if (nbytes > count) nbytes = count; /* don't go past EOF */ - - /* now copy the data */ + if (cm_HaveBuffer(scp, bufferp, 0)) break; + + /* otherwise, load the buffer and try again */ + code = cm_GetBuffer(scp, bufferp, NULL, userp, &req); + if (code) break; + } + if (code) { + buf_Release(bufferp); + bufferp = NULL; + goto done; + } + } /* if (wrong buffer) ... */ + + /* now we have the right buffer loaded. Copy out the + * data from here to the user's buffer. + */ + bufIndex = offset.LowPart & (buf_bufferSize - 1); + + /* and figure out how many bytes we want from this buffer */ + nbytes = buf_bufferSize - bufIndex; /* what remains in buffer */ + if (nbytes > count) nbytes = count; /* don't go past EOF */ + + /* now copy the data */ #ifdef DJGPP - if (dosflag) - dosmemput(bufferp->datap + bufIndex, nbytes, (dos_ptr)op); - else + if (dosflag) + dosmemput(bufferp->datap + bufIndex, nbytes, (dos_ptr)op); + else #endif /* DJGPP */ - memcpy(op, bufferp->datap + bufIndex, nbytes); + memcpy(op, bufferp->datap + bufIndex, nbytes); - /* adjust counters, pointers, etc. */ - op += nbytes; - count -= nbytes; - thyper.LowPart = nbytes; - thyper.HighPart = 0; - offset = LargeIntegerAdd(thyper, offset); - } /* while 1 */ + /* adjust counters, pointers, etc. */ + op += nbytes; + count -= nbytes; + thyper.LowPart = nbytes; + thyper.HighPart = 0; + offset = LargeIntegerAdd(thyper, offset); + } /* while 1 */ done: - lock_ReleaseMutex(&scp->mx); - lock_ReleaseMutex(&fidp->mx); - if (bufferp) - buf_Release(bufferp); + lock_ReleaseMutex(&scp->mx); + lock_ReleaseMutex(&fidp->mx); + if (bufferp) + buf_Release(bufferp); - if (code == 0 && sequential) - cm_ConsiderPrefetch(scp, &lastByte, userp, &req); + if (code == 0 && sequential) + cm_ConsiderPrefetch(scp, &lastByte, userp, &req); - return code; + return code; } /* @@ -5009,253 +5177,255 @@ long smb_WriteData(smb_fid_t *fidp, osi_hyper_t *offsetp, long count, char *op, cm_user_t *userp, long *writtenp, int dosflag) #endif /* !DJGPP */ { - osi_hyper_t offset; - long code = 0; - long written = 0; - cm_scache_t *scp; - osi_hyper_t fileLength; /* file's length at start of write */ - osi_hyper_t minLength; /* don't read past this */ - long nbytes; /* # of bytes to transfer this iteration */ - cm_buf_t *bufferp; - osi_hyper_t thyper; /* hyper tmp variable */ - osi_hyper_t bufferOffset; - long bufIndex; /* index in buffer where our data is */ - int doWriteBack; - osi_hyper_t writeBackOffset; /* offset of region to write back when - * I/O is done */ - DWORD filter = 0; - cm_req_t req; + osi_hyper_t offset; + long code = 0; + long written = 0; + cm_scache_t *scp; + osi_hyper_t fileLength; /* file's length at start of write */ + osi_hyper_t minLength; /* don't read past this */ + long nbytes; /* # of bytes to transfer this iteration */ + cm_buf_t *bufferp; + osi_hyper_t thyper; /* hyper tmp variable */ + osi_hyper_t bufferOffset; + long bufIndex; /* index in buffer where our data is */ + int doWriteBack; + osi_hyper_t writeBackOffset;/* offset of region to write back when + * I/O is done */ + DWORD filter = 0; + cm_req_t req; osi_Log3(smb_logp, "smb_WriteData fid %d, off 0x%x, size 0x%x", fidp->fid, offsetp->LowPart, count); - cm_InitReq(&req); + *writtenp = 0; + + cm_InitReq(&req); - bufferp = NULL; - doWriteBack = 0; - offset = *offsetp; + bufferp = NULL; + doWriteBack = 0; + offset = *offsetp; - lock_ObtainMutex(&fidp->mx); - scp = fidp->scp; - lock_ObtainMutex(&scp->mx); + lock_ObtainMutex(&fidp->mx); + scp = fidp->scp; + lock_ObtainMutex(&scp->mx); - /* start by looking up the file's end */ + /* start by looking up the file's end */ osi_Log1(smb_logp, "smb_WriteData fid %d calling cm_SyncOp NEEDCALLBACK|SETSTATUS|GETSTATUS", fidp->fid); - code = cm_SyncOp(scp, NULL, userp, &req, 0, - CM_SCACHESYNC_NEEDCALLBACK - | CM_SCACHESYNC_SETSTATUS - | CM_SCACHESYNC_GETSTATUS); + code = cm_SyncOp(scp, NULL, userp, &req, 0, + CM_SCACHESYNC_NEEDCALLBACK + | CM_SCACHESYNC_SETSTATUS + | CM_SCACHESYNC_GETSTATUS); osi_Log2(smb_logp, "smb_WriteData fid %d calling cm_SyncOp NEEDCALLBACK|SETSTATUS|GETSTATUS returns %d", fidp->fid,code); - if (code) - goto done; - - /* make sure we have a writable FD */ - if (!(fidp->flags & SMB_FID_OPENWRITE)) { - code = CM_ERROR_BADFDOP; - goto done; - } - - /* now we have the entry locked, look up the length */ - fileLength = scp->length; - minLength = fileLength; - if (LargeIntegerGreaterThan(minLength, scp->serverLength)) - minLength = scp->serverLength; - - /* adjust file length if we extend past EOF */ - thyper.LowPart = count; - thyper.HighPart = 0; - thyper = LargeIntegerAdd(offset, thyper); /* where write should end */ - if (LargeIntegerGreaterThan(thyper, fileLength)) { - /* we'd write past EOF, so extend the file */ - scp->mask |= CM_SCACHEMASK_LENGTH; - scp->length = thyper; - filter |= (FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_SIZE); - } else - filter |= FILE_NOTIFY_CHANGE_LAST_WRITE; + if (code) + goto done; - /* now, if the new position (thyper) and the old (offset) are in - * different storeback windows, remember to store back the previous - * storeback window when we're done with the write. - */ - if ((thyper.LowPart & (-cm_chunkSize)) != - (offset.LowPart & (-cm_chunkSize))) { - /* they're different */ - doWriteBack = 1; - writeBackOffset.HighPart = offset.HighPart; - writeBackOffset.LowPart = offset.LowPart & (-cm_chunkSize); - } + /* make sure we have a writable FD */ + if (!(fidp->flags & SMB_FID_OPENWRITE)) { + code = CM_ERROR_BADFDOP; + goto done; + } + + /* now we have the entry locked, look up the length */ + fileLength = scp->length; + minLength = fileLength; + if (LargeIntegerGreaterThan(minLength, scp->serverLength)) + minLength = scp->serverLength; + + /* adjust file length if we extend past EOF */ + thyper.LowPart = count; + thyper.HighPart = 0; + thyper = LargeIntegerAdd(offset, thyper); /* where write should end */ + if (LargeIntegerGreaterThan(thyper, fileLength)) { + /* we'd write past EOF, so extend the file */ + scp->mask |= CM_SCACHEMASK_LENGTH; + scp->length = thyper; + filter |= (FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_SIZE); + } else + filter |= FILE_NOTIFY_CHANGE_LAST_WRITE; + + /* now, if the new position (thyper) and the old (offset) are in + * different storeback windows, remember to store back the previous + * storeback window when we're done with the write. + */ + if ((thyper.LowPart & (-cm_chunkSize)) != + (offset.LowPart & (-cm_chunkSize))) { + /* they're different */ + doWriteBack = 1; + writeBackOffset.HighPart = offset.HighPart; + writeBackOffset.LowPart = offset.LowPart & (-cm_chunkSize); + } - *writtenp = count; - - /* now, copy the data one buffer at a time, until we've filled the - * request packet */ - while (1) { - /* if we've copied all the data requested, we're done */ - if (count <= 0) break; - - /* handle over quota or out of space */ - if (scp->flags & (CM_SCACHEFLAG_OVERQUOTA | CM_SCACHEFLAG_OUTOFSPACE)) { - *writtenp = written; - break; - } - - /* otherwise, load up a buffer of data */ - thyper.HighPart = offset.HighPart; - thyper.LowPart = offset.LowPart & ~(buf_bufferSize-1); - if (!bufferp || !LargeIntegerEqualTo(thyper, bufferOffset)) { - /* wrong buffer */ - if (bufferp) { - lock_ReleaseMutex(&bufferp->mx); - buf_Release(bufferp); - bufferp = NULL; - } - lock_ReleaseMutex(&scp->mx); - - lock_ObtainRead(&scp->bufCreateLock); - code = buf_Get(scp, &thyper, &bufferp); - lock_ReleaseRead(&scp->bufCreateLock); - - lock_ObtainMutex(&bufferp->mx); - lock_ObtainMutex(&scp->mx); - if (code) goto done; - - bufferOffset = thyper; - - /* now get the data in the cache */ - while (1) { + *writtenp = count; + + /* now, copy the data one buffer at a time, until we've filled the + * request packet */ + while (1) { + /* if we've copied all the data requested, we're done */ + if (count <= 0) + break; + + /* handle over quota or out of space */ + if (scp->flags & (CM_SCACHEFLAG_OVERQUOTA | CM_SCACHEFLAG_OUTOFSPACE)) { + *writtenp = written; + code = CM_ERROR_QUOTA; + break; + } + + /* otherwise, load up a buffer of data */ + thyper.HighPart = offset.HighPart; + thyper.LowPart = offset.LowPart & ~(buf_bufferSize-1); + if (!bufferp || !LargeIntegerEqualTo(thyper, bufferOffset)) { + /* wrong buffer */ + if (bufferp) { + lock_ReleaseMutex(&bufferp->mx); + buf_Release(bufferp); + bufferp = NULL; + } + lock_ReleaseMutex(&scp->mx); + + lock_ObtainRead(&scp->bufCreateLock); + code = buf_Get(scp, &thyper, &bufferp); + lock_ReleaseRead(&scp->bufCreateLock); + + lock_ObtainMutex(&bufferp->mx); + lock_ObtainMutex(&scp->mx); + if (code) goto done; + + bufferOffset = thyper; + + /* now get the data in the cache */ + while (1) { osi_Log1(smb_logp, "smb_WriteData fid %d calling cm_SyncOp NEEDCALLBACK|WRITE|BUFLOCKED", fidp->fid); - code = cm_SyncOp(scp, bufferp, userp, &req, 0, - CM_SCACHESYNC_NEEDCALLBACK - | CM_SCACHESYNC_WRITE - | CM_SCACHESYNC_BUFLOCKED); + code = cm_SyncOp(scp, bufferp, userp, &req, 0, + CM_SCACHESYNC_NEEDCALLBACK + | CM_SCACHESYNC_WRITE + | CM_SCACHESYNC_BUFLOCKED); osi_Log2(smb_logp, "smb_WriteData fid %d calling cm_SyncOp NEEDCALLBACK|WRITE|BUFLOCKED returns %d", fidp->fid,code); - if (code) - goto done; - - /* If we're overwriting the entire buffer, or - * if we're writing at or past EOF, mark the - * buffer as current so we don't call - * cm_GetBuffer. This skips the fetch from the - * server in those cases where we're going to - * obliterate all the data in the buffer anyway, - * or in those cases where there is no useful - * data at the server to start with. - * - * Use minLength instead of scp->length, since - * the latter has already been updated by this - * call. - */ - if (LargeIntegerGreaterThanOrEqualTo( - bufferp->offset, minLength) - || LargeIntegerEqualTo(offset, bufferp->offset) - && (count >= buf_bufferSize - || LargeIntegerGreaterThanOrEqualTo( - LargeIntegerAdd(offset, - ConvertLongToLargeInteger(count)), - minLength))) { - if (count < buf_bufferSize - && bufferp->dataVersion == -1) - memset(bufferp->datap, 0, - buf_bufferSize); - bufferp->dataVersion = scp->dataVersion; - } - - if (cm_HaveBuffer(scp, bufferp, 1)) break; - - /* otherwise, load the buffer and try again */ - lock_ReleaseMutex(&bufferp->mx); - code = cm_GetBuffer(scp, bufferp, NULL, userp, - &req); - lock_ReleaseMutex(&scp->mx); - lock_ObtainMutex(&bufferp->mx); - lock_ObtainMutex(&scp->mx); - if (code) break; - } - if (code) { - lock_ReleaseMutex(&bufferp->mx); - buf_Release(bufferp); - bufferp = NULL; - goto done; - } - } /* if (wrong buffer) ... */ - - /* now we have the right buffer loaded. Copy out the - * data from here to the user's buffer. - */ - bufIndex = offset.LowPart & (buf_bufferSize - 1); - - /* and figure out how many bytes we want from this buffer */ - nbytes = buf_bufferSize - bufIndex; /* what remains in buffer */ - if (nbytes > count) - nbytes = count; /* don't go past end of request */ - - /* now copy the data */ + if (code) + goto done; + + /* If we're overwriting the entire buffer, or + * if we're writing at or past EOF, mark the + * buffer as current so we don't call + * cm_GetBuffer. This skips the fetch from the + * server in those cases where we're going to + * obliterate all the data in the buffer anyway, + * or in those cases where there is no useful + * data at the server to start with. + * + * Use minLength instead of scp->length, since + * the latter has already been updated by this + * call. + */ + if (LargeIntegerGreaterThanOrEqualTo(bufferp->offset, minLength) + || LargeIntegerEqualTo(offset, bufferp->offset) + && (count >= buf_bufferSize + || LargeIntegerGreaterThanOrEqualTo(LargeIntegerAdd(offset, + ConvertLongToLargeInteger(count)), + minLength))) { + if (count < buf_bufferSize + && bufferp->dataVersion == -1) + memset(bufferp->datap, 0, + buf_bufferSize); + bufferp->dataVersion = scp->dataVersion; + } + + if (cm_HaveBuffer(scp, bufferp, 1)) break; + + /* otherwise, load the buffer and try again */ + lock_ReleaseMutex(&bufferp->mx); + code = cm_GetBuffer(scp, bufferp, NULL, userp, + &req); + lock_ReleaseMutex(&scp->mx); + lock_ObtainMutex(&bufferp->mx); + lock_ObtainMutex(&scp->mx); + if (code) break; + } + if (code) { + lock_ReleaseMutex(&bufferp->mx); + buf_Release(bufferp); + bufferp = NULL; + goto done; + } + } /* if (wrong buffer) ... */ + + /* now we have the right buffer loaded. Copy out the + * data from here to the user's buffer. + */ + bufIndex = offset.LowPart & (buf_bufferSize - 1); + + /* and figure out how many bytes we want from this buffer */ + nbytes = buf_bufferSize - bufIndex; /* what remains in buffer */ + if (nbytes > count) + nbytes = count; /* don't go past end of request */ + + /* now copy the data */ #ifdef DJGPP - if (dosflag) - dosmemget((dos_ptr)op, nbytes, bufferp->datap + bufIndex); - else + if (dosflag) + dosmemget((dos_ptr)op, nbytes, bufferp->datap + bufIndex); + else #endif /* DJGPP */ - memcpy(bufferp->datap + bufIndex, op, nbytes); - buf_SetDirty(bufferp); + memcpy(bufferp->datap + bufIndex, op, nbytes); + buf_SetDirty(bufferp); - /* and record the last writer */ - if (bufferp->userp != userp) { - cm_HoldUser(userp); - if (bufferp->userp) + /* and record the last writer */ + if (bufferp->userp != userp) { + cm_HoldUser(userp); + if (bufferp->userp) cm_ReleaseUser(bufferp->userp); - bufferp->userp = userp; - } - - /* adjust counters, pointers, etc. */ - op += nbytes; - count -= nbytes; - written += nbytes; - thyper.LowPart = nbytes; - thyper.HighPart = 0; - offset = LargeIntegerAdd(thyper, offset); - } /* while 1 */ + bufferp->userp = userp; + } + + /* adjust counters, pointers, etc. */ + op += nbytes; + count -= nbytes; + written += nbytes; + thyper.LowPart = nbytes; + thyper.HighPart = 0; + offset = LargeIntegerAdd(thyper, offset); + } /* while 1 */ done: - lock_ReleaseMutex(&scp->mx); - lock_ReleaseMutex(&fidp->mx); - if (bufferp) { - lock_ReleaseMutex(&bufferp->mx); - buf_Release(bufferp); - } - - if (code == 0 && filter != 0 && (fidp->flags & SMB_FID_NTOPEN) - && (fidp->NTopen_dscp->flags & CM_SCACHEFLAG_ANYWATCH)) { - smb_NotifyChange(FILE_ACTION_MODIFIED, filter, - fidp->NTopen_dscp, fidp->NTopen_pathp, - NULL, TRUE); - } - - if (code == 0 && doWriteBack) { + lock_ReleaseMutex(&scp->mx); + lock_ReleaseMutex(&fidp->mx); + if (bufferp) { + lock_ReleaseMutex(&bufferp->mx); + buf_Release(bufferp); + } + + if (code == 0 && filter != 0 && (fidp->flags & SMB_FID_NTOPEN) + && (fidp->NTopen_dscp->flags & CM_SCACHEFLAG_ANYWATCH)) { + smb_NotifyChange(FILE_ACTION_MODIFIED, filter, + fidp->NTopen_dscp, fidp->NTopen_pathp, + NULL, TRUE); + } + + if (code == 0 && doWriteBack) { long code2; - lock_ObtainMutex(&scp->mx); + lock_ObtainMutex(&scp->mx); osi_Log1(smb_logp, "smb_WriteData fid %d calling cm_SyncOp ASYNCSTORE", fidp->fid); - code2 = cm_SyncOp(scp, NULL, userp, &req, 0, CM_SCACHESYNC_ASYNCSTORE); + code2 = cm_SyncOp(scp, NULL, userp, &req, 0, CM_SCACHESYNC_ASYNCSTORE); osi_Log2(smb_logp, "smb_WriteData fid %d calling cm_SyncOp ASYNCSTORE returns %d", fidp->fid,code2); - lock_ReleaseMutex(&scp->mx); - cm_QueueBKGRequest(scp, cm_BkgStore, writeBackOffset.LowPart, - writeBackOffset.HighPart, cm_chunkSize, 0, userp); - } - - osi_Log2(smb_logp, "smb_WriteData fid %d returns %d", - fidp->fid, code); - return code; + lock_ReleaseMutex(&scp->mx); + cm_QueueBKGRequest(scp, cm_BkgStore, writeBackOffset.LowPart, + writeBackOffset.HighPart, cm_chunkSize, 0, userp); + } + + osi_Log2(smb_logp, "smb_WriteData fid %d returns %d written %d", + fidp->fid, code, *writtenp); + return code; } long smb_ReceiveCoreWrite(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - osi_hyper_t offset; - long count, written = 0; + osi_hyper_t offset; + long count, written = 0, total_written = 0; unsigned short fd; smb_fid_t *fidp; long code = 0; @@ -5270,267 +5440,283 @@ long smb_ReceiveCoreWrite(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) offset.LowPart = smb_GetSMBParm(inp, 2) | (smb_GetSMBParm(inp, 3) << 16); op = smb_GetSMBData(inp, NULL); - op = smb_ParseDataBlock(op, NULL, &inDataBlockCount); + op = smb_ParseDataBlock(op, NULL, &inDataBlockCount); osi_Log3(smb_logp, "smb_ReceiveCoreWrite fid %d, off 0x%x, size 0x%x", fd, offset.LowPart, count); - fd = smb_ChainFID(fd, inp); + fd = smb_ChainFID(fd, inp); fidp = smb_FindFID(vcp, fd, 0); if (!fidp) { - return CM_ERROR_BADFD; + return CM_ERROR_BADFD; } if (fidp->flags & SMB_FID_IOCTL) return smb_IoctlWrite(fidp, vcp, inp, outp); - userp = smb_GetUser(vcp, inp); + userp = smb_GetUser(vcp, inp); /* special case: 0 bytes transferred means truncate to this position */ if (count == 0) { - cm_req_t req; + cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); - truncAttr.mask = CM_ATTRMASK_LENGTH; + truncAttr.mask = CM_ATTRMASK_LENGTH; truncAttr.length.LowPart = offset.LowPart; truncAttr.length.HighPart = 0; - lock_ObtainMutex(&fidp->mx); + lock_ObtainMutex(&fidp->mx); code = cm_SetAttr(fidp->scp, &truncAttr, userp, &req); - lock_ReleaseMutex(&fidp->mx); - smb_SetSMBParm(outp, 0, /* count */ 0); + lock_ReleaseMutex(&fidp->mx); + smb_SetSMBParm(outp, 0, /* count */ 0); smb_SetSMBDataLength(outp, 0); - fidp->flags |= SMB_FID_LENGTHSETDONE; + fidp->flags |= SMB_FID_LENGTHSETDONE; goto done; } - /* - * Work around bug in NT client - * - * When copying a file, the NT client should first copy the data, - * then copy the last write time. But sometimes the NT client does - * these in the wrong order, so the data copies would inadvertently - * cause the last write time to be overwritten. We try to detect this, - * and don't set client mod time if we think that would go against the - * intention. - */ - if ((fidp->flags & SMB_FID_MTIMESETDONE) != SMB_FID_MTIMESETDONE) { - fidp->scp->mask |= CM_SCACHEMASK_CLIENTMODTIME; - fidp->scp->clientModTime = time(NULL); - } + /* + * Work around bug in NT client + * + * When copying a file, the NT client should first copy the data, + * then copy the last write time. But sometimes the NT client does + * these in the wrong order, so the data copies would inadvertently + * cause the last write time to be overwritten. We try to detect this, + * and don't set client mod time if we think that would go against the + * intention. + */ + if ((fidp->flags & SMB_FID_MTIMESETDONE) != SMB_FID_MTIMESETDONE) { + fidp->scp->mask |= CM_SCACHEMASK_CLIENTMODTIME; + fidp->scp->clientModTime = time(NULL); + } + code = 0; + while ( code == 0 && count > 0 ) { #ifndef DJGPP code = smb_WriteData(fidp, &offset, count, op, userp, &written); #else /* DJGPP */ code = smb_WriteData(fidp, &offset, count, op, userp, &written, FALSE); #endif /* !DJGPP */ - if (code == 0 && written < count) - code = CM_ERROR_PARTIALWRITE; + if (code == 0 && written == 0) + code = CM_ERROR_PARTIALWRITE; - /* set the packet data length to 3 bytes for the data block header, + offset.LowPart += written; + count -= written; + total_written += written; + written = 0; + } + + /* set the packet data length to 3 bytes for the data block header, * plus the size of the data. */ - smb_SetSMBParm(outp, 0, written); + smb_SetSMBParm(outp, 0, total_written); smb_SetSMBDataLength(outp, 0); done: smb_ReleaseFID(fidp); cm_ReleaseUser(userp); - return code; + return code; } void smb_CompleteWriteRaw(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp, - NCB *ncbp, raw_write_cont_t *rwcp) + NCB *ncbp, raw_write_cont_t *rwcp) { - unsigned short fd; - smb_fid_t *fidp; - cm_user_t *userp; + unsigned short fd; + smb_fid_t *fidp; + cm_user_t *userp; #ifndef DJGPP - char *rawBuf; + char *rawBuf; #else /* DJGPP */ - dos_ptr rawBuf; + dos_ptr rawBuf; #endif /* !DJGPP */ - long written = 0; - long code = 0; + long written = 0; + long code = 0; - fd = smb_GetSMBParm(inp, 0); - fidp = smb_FindFID(vcp, fd, 0); + fd = smb_GetSMBParm(inp, 0); + fidp = smb_FindFID(vcp, fd, 0); - osi_Log2(smb_logp, "Completing Raw Write offset %x count %x", - rwcp->offset.LowPart, rwcp->count); + osi_Log2(smb_logp, "Completing Raw Write offset %x count %x", + rwcp->offset.LowPart, rwcp->count); - userp = smb_GetUser(vcp, inp); + userp = smb_GetUser(vcp, inp); #ifndef DJGPP - rawBuf = rwcp->buf; - code = smb_WriteData(fidp, &rwcp->offset, rwcp->count, rawBuf, userp, + rawBuf = rwcp->buf; + code = smb_WriteData(fidp, &rwcp->offset, rwcp->count, rawBuf, userp, &written); #else /* DJGPP */ - rawBuf = (dos_ptr) rwcp->buf; - code = smb_WriteData(fidp, &rwcp->offset, rwcp->count, + rawBuf = (dos_ptr) rwcp->buf; + code = smb_WriteData(fidp, &rwcp->offset, rwcp->count, (unsigned char *) rawBuf, userp, &written, TRUE); #endif /* !DJGPP */ - if (rwcp->writeMode & 0x1) { /* synchronous */ - smb_t *op; - - smb_FormatResponsePacket(vcp, inp, outp); - op = (smb_t *) outp; - op->com = 0x20; /* SMB_COM_WRITE_COMPLETE */ - smb_SetSMBParm(outp, 0, written + rwcp->alreadyWritten); - smb_SetSMBDataLength(outp, 0); - smb_SendPacket(vcp, outp); - smb_FreePacket(outp); - } - else { /* asynchronous */ - lock_ObtainMutex(&fidp->mx); - fidp->raw_writers--; - if (fidp->raw_writers == 0) - thrd_SetEvent(fidp->raw_write_event); - lock_ReleaseMutex(&fidp->mx); - } - - /* Give back raw buffer */ - lock_ObtainMutex(&smb_RawBufLock); + if (rwcp->writeMode & 0x1) { /* synchronous */ + smb_t *op; + + smb_FormatResponsePacket(vcp, inp, outp); + op = (smb_t *) outp; + op->com = 0x20; /* SMB_COM_WRITE_COMPLETE */ + smb_SetSMBParm(outp, 0, written + rwcp->alreadyWritten); + smb_SetSMBDataLength(outp, 0); + smb_SendPacket(vcp, outp); + smb_FreePacket(outp); + } + else { /* asynchronous */ + lock_ObtainMutex(&fidp->mx); + fidp->raw_writers--; + if (fidp->raw_writers == 0) + thrd_SetEvent(fidp->raw_write_event); + lock_ReleaseMutex(&fidp->mx); + } + + /* Give back raw buffer */ + lock_ObtainMutex(&smb_RawBufLock); #ifndef DJGPP - *((char **)rawBuf) = smb_RawBufs; + *((char **)rawBuf) = smb_RawBufs; #else /* DJGPP */ _farpokel(_dos_ds, rawBuf, smb_RawBufs); #endif /* !DJGPP */ - smb_RawBufs = rawBuf; - lock_ReleaseMutex(&smb_RawBufLock); + smb_RawBufs = rawBuf; + lock_ReleaseMutex(&smb_RawBufLock); - smb_ReleaseFID(fidp); - cm_ReleaseUser(userp); + smb_ReleaseFID(fidp); + cm_ReleaseUser(userp); } long smb_ReceiveCoreWriteRawDummy(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - return 0; + return 0; } long smb_ReceiveCoreWriteRaw(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp, raw_write_cont_t *rwcp) { - osi_hyper_t offset; - long count, written = 0; - long totalCount; + osi_hyper_t offset; + long count, written = 0, total_written = 0; + long totalCount; unsigned short fd; smb_fid_t *fidp; long code = 0; cm_user_t *userp; char *op; - unsigned short writeMode; + unsigned short writeMode; #ifndef DJGPP - char *rawBuf; + char *rawBuf; #else /* DJGPP */ dos_ptr rawBuf; #endif /* !DJGPP */ fd = smb_GetSMBParm(inp, 0); - totalCount = smb_GetSMBParm(inp, 1); + totalCount = smb_GetSMBParm(inp, 1); count = smb_GetSMBParm(inp, 10); offset.HighPart = 0; /* too bad */ offset.LowPart = smb_GetSMBParm(inp, 3) | (smb_GetSMBParm(inp, 4) << 16); - writeMode = smb_GetSMBParm(inp, 7); + writeMode = smb_GetSMBParm(inp, 7); - op = (char *) inp->data; - op += smb_GetSMBParm(inp, 11); + op = (char *) inp->data; + op += smb_GetSMBParm(inp, 11); osi_Log4(smb_logp, "smb_ReceiveCoreWriteRaw fd %d, off 0x%x, size 0x%x, WriteMode 0x%x", fd, offset.LowPart, count, writeMode); - fd = smb_ChainFID(fd, inp); + fd = smb_ChainFID(fd, inp); fidp = smb_FindFID(vcp, fd, 0); if (!fidp) { - return CM_ERROR_BADFD; + return CM_ERROR_BADFD; } - userp = smb_GetUser(vcp, inp); - - /* - * Work around bug in NT client - * - * When copying a file, the NT client should first copy the data, - * then copy the last write time. But sometimes the NT client does - * these in the wrong order, so the data copies would inadvertently - * cause the last write time to be overwritten. We try to detect this, - * and don't set client mod time if we think that would go against the - * intention. - */ - if ((fidp->flags & SMB_FID_LOOKSLIKECOPY) != SMB_FID_LOOKSLIKECOPY) { - fidp->scp->mask |= CM_SCACHEMASK_CLIENTMODTIME; - fidp->scp->clientModTime = time(NULL); - } + userp = smb_GetUser(vcp, inp); + /* + * Work around bug in NT client + * + * When copying a file, the NT client should first copy the data, + * then copy the last write time. But sometimes the NT client does + * these in the wrong order, so the data copies would inadvertently + * cause the last write time to be overwritten. We try to detect this, + * and don't set client mod time if we think that would go against the + * intention. + */ + if ((fidp->flags & SMB_FID_LOOKSLIKECOPY) != SMB_FID_LOOKSLIKECOPY) { + fidp->scp->mask |= CM_SCACHEMASK_CLIENTMODTIME; + fidp->scp->clientModTime = time(NULL); + } + + code = 0; + while ( code == 0 && count > 0 ) { #ifndef DJGPP code = smb_WriteData(fidp, &offset, count, op, userp, &written); #else /* DJGPP */ code = smb_WriteData(fidp, &offset, count, op, userp, &written, FALSE); #endif /* !DJGPP */ - if (code == 0 && written < count) - code = CM_ERROR_PARTIALWRITE; - - /* Get a raw buffer */ - if (code == 0) { - rawBuf = NULL; - lock_ObtainMutex(&smb_RawBufLock); - if (smb_RawBufs) { - /* Get a raw buf, from head of list */ - rawBuf = smb_RawBufs; + if (code == 0 && written == 0) + code = CM_ERROR_PARTIALWRITE; + + offset.LowPart += written; + count -= written; + total_written += written; + written = 0; + } + + /* Get a raw buffer */ + if (code == 0) { + rawBuf = NULL; + lock_ObtainMutex(&smb_RawBufLock); + if (smb_RawBufs) { + /* Get a raw buf, from head of list */ + rawBuf = smb_RawBufs; #ifndef DJGPP - smb_RawBufs = *(char **)smb_RawBufs; + smb_RawBufs = *(char **)smb_RawBufs; #else /* DJGPP */ smb_RawBufs = _farpeekl(_dos_ds, smb_RawBufs); #endif /* !DJGPP */ - } - else - code = CM_ERROR_USESTD; + } + else + code = CM_ERROR_USESTD; lock_ReleaseMutex(&smb_RawBufLock); - } - - /* Don't allow a premature Close */ - if (code == 0 && (writeMode & 1) == 0) { - lock_ObtainMutex(&fidp->mx); - fidp->raw_writers++; - thrd_ResetEvent(fidp->raw_write_event); - lock_ReleaseMutex(&fidp->mx); - } - - smb_ReleaseFID(fidp); - cm_ReleaseUser(userp); - - if (code) { - smb_SetSMBParm(outp, 0, written); - smb_SetSMBDataLength(outp, 0); - ((smb_t *)outp)->com = 0x20; /* SMB_COM_WRITE_COMPLETE */ - rwcp->code = code; - return code; - } - - rwcp->code = 0; - rwcp->buf = rawBuf; - rwcp->offset.HighPart = 0; - rwcp->offset.LowPart = offset.LowPart + count; - rwcp->count = totalCount - count; - rwcp->writeMode = writeMode; - rwcp->alreadyWritten = written; - - /* set the packet data length to 3 bytes for the data block header, + } + + /* Don't allow a premature Close */ + if (code == 0 && (writeMode & 1) == 0) { + lock_ObtainMutex(&fidp->mx); + fidp->raw_writers++; + thrd_ResetEvent(fidp->raw_write_event); + lock_ReleaseMutex(&fidp->mx); + } + + smb_ReleaseFID(fidp); + cm_ReleaseUser(userp); + + if (code) { + smb_SetSMBParm(outp, 0, total_written); + smb_SetSMBDataLength(outp, 0); + ((smb_t *)outp)->com = 0x20; /* SMB_COM_WRITE_COMPLETE */ + rwcp->code = code; + return code; + } + + rwcp->code = 0; + rwcp->buf = rawBuf; + rwcp->offset.HighPart = 0; + rwcp->offset.LowPart = offset.LowPart + count; + rwcp->count = totalCount - count; + rwcp->writeMode = writeMode; + rwcp->alreadyWritten = total_written; + + /* set the packet data length to 3 bytes for the data block header, * plus the size of the data. */ - smb_SetSMBParm(outp, 0, 0xffff); + smb_SetSMBParm(outp, 0, 0xffff); smb_SetSMBDataLength(outp, 0); - return 0; + return 0; } long smb_ReceiveCoreRead(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - osi_hyper_t offset; + osi_hyper_t offset; long count, finalCount; unsigned short fd; smb_fid_t *fidp; @@ -5546,49 +5732,49 @@ long smb_ReceiveCoreRead(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) osi_Log3(smb_logp, "smb_ReceiveCoreRead fd %d, off 0x%x, size 0x%x", fd, offset.LowPart, count); - fd = smb_ChainFID(fd, inp); + fd = smb_ChainFID(fd, inp); fidp = smb_FindFID(vcp, fd, 0); if (!fidp) { - return CM_ERROR_BADFD; + return CM_ERROR_BADFD; } if (fidp->flags & SMB_FID_IOCTL) { - return smb_IoctlRead(fidp, vcp, inp, outp); + return smb_IoctlRead(fidp, vcp, inp, outp); } - userp = smb_GetUser(vcp, inp); + userp = smb_GetUser(vcp, inp); - /* remember this for final results */ + /* remember this for final results */ smb_SetSMBParm(outp, 0, count); smb_SetSMBParm(outp, 1, 0); smb_SetSMBParm(outp, 2, 0); smb_SetSMBParm(outp, 3, 0); smb_SetSMBParm(outp, 4, 0); - /* set the packet data length to 3 bytes for the data block header, + /* set the packet data length to 3 bytes for the data block header, * plus the size of the data. */ smb_SetSMBDataLength(outp, count+3); - /* get op ptr after putting in the parms, since otherwise we don't + /* get op ptr after putting in the parms, since otherwise we don't * know where the data really is. */ op = smb_GetSMBData(outp, NULL); - /* now emit the data block header: 1 byte of type and 2 bytes of length */ + /* now emit the data block header: 1 byte of type and 2 bytes of length */ *op++ = 1; /* data block marker */ *op++ = (unsigned char) (count & 0xff); *op++ = (unsigned char) ((count >> 8) & 0xff); #ifndef DJGPP - code = smb_ReadData(fidp, &offset, count, op, userp, &finalCount); + code = smb_ReadData(fidp, &offset, count, op, userp, &finalCount); #else /* DJGPP */ code = smb_ReadData(fidp, &offset, count, op, userp, &finalCount, FALSE); #endif /* !DJGPP */ - /* fix some things up */ - smb_SetSMBParm(outp, 0, finalCount); - smb_SetSMBDataLength(outp, finalCount+3); + /* fix some things up */ + smb_SetSMBParm(outp, 0, finalCount); + smb_SetSMBDataLength(outp, finalCount+3); smb_ReleaseFID(fidp); @@ -5598,9 +5784,9 @@ long smb_ReceiveCoreRead(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) long smb_ReceiveCoreMakeDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - char *pathp; + char *pathp; long code = 0; - cm_space_t *spacep; + cm_space_t *spacep; char *tp; cm_user_t *userp; cm_scache_t *dscp; /* dir we're dealing with */ @@ -5609,36 +5795,36 @@ long smb_ReceiveCoreMakeDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp int initialModeBits; char *lastNamep; int caseFold; - char *tidPathp; - cm_req_t req; + char *tidPathp; + cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); scp = NULL; - /* compute initial mode bits based on read-only flag in attributes */ + /* compute initial mode bits based on read-only flag in attributes */ initialModeBits = 0777; - tp = smb_GetSMBData(inp, NULL); + tp = smb_GetSMBData(inp, NULL); pathp = smb_ParseASCIIBlock(tp, &tp); - if (strcmp(pathp, "\\") == 0) - return CM_ERROR_EXISTS; + if (strcmp(pathp, "\\") == 0) + return CM_ERROR_EXISTS; - spacep = inp->spacep; + spacep = inp->spacep; smb_StripLastComponent(spacep->data, &lastNamep, pathp); - userp = smb_GetUser(vcp, inp); + userp = smb_GetUser(vcp, inp); caseFold = CM_FLAG_CASEFOLD; - code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); - if(code) { + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); + if (code) { cm_ReleaseUser(userp); return CM_ERROR_NOSUCHPATH; } - code = cm_NameI(cm_rootSCachep, spacep->data, + code = cm_NameI(cm_rootSCachep, spacep->data, caseFold | CM_FLAG_FOLLOW | CM_FLAG_CHECKPATH, userp, tidPathp, &req, &dscp); @@ -5648,7 +5834,7 @@ long smb_ReceiveCoreMakeDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp } /* otherwise, scp points to the parent directory. Do a lookup, and - * fail if we find it. Otherwise, we do the create. + * fail if we find it. Otherwise, we do the create. */ if (!lastNamep) lastNamep = pathp; @@ -5658,29 +5844,29 @@ long smb_ReceiveCoreMakeDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp if (scp) cm_ReleaseSCache(scp); if (code != CM_ERROR_NOSUCHFILE) { if (code == 0) code = CM_ERROR_EXISTS; - cm_ReleaseSCache(dscp); + cm_ReleaseSCache(dscp); cm_ReleaseUser(userp); return code; } - setAttr.mask = CM_ATTRMASK_CLIENTMODTIME; - setAttr.clientModTime = time(NULL); - code = cm_MakeDir(dscp, lastNamep, 0, &setAttr, userp, &req); - if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) - smb_NotifyChange(FILE_ACTION_ADDED, + setAttr.mask = CM_ATTRMASK_CLIENTMODTIME; + setAttr.clientModTime = time(NULL); + code = cm_MakeDir(dscp, lastNamep, 0, &setAttr, userp, &req); + if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) + smb_NotifyChange(FILE_ACTION_ADDED, FILE_NOTIFY_CHANGE_DIR_NAME, dscp, lastNamep, NULL, TRUE); - /* we don't need this any longer */ - cm_ReleaseSCache(dscp); + /* we don't need this any longer */ + cm_ReleaseSCache(dscp); if (code) { - /* something went wrong creating or truncating the file */ + /* something went wrong creating or truncating the file */ cm_ReleaseUser(userp); return code; } - /* otherwise we succeeded */ + /* otherwise we succeeded */ smb_SetSMBDataLength(outp, 0); cm_ReleaseUser(userp); @@ -5703,9 +5889,9 @@ BOOL smb_IsLegalFilename(char *filename) long smb_ReceiveCoreCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - char *pathp; + char *pathp; long code = 0; - cm_space_t *spacep; + cm_space_t *spacep; char *tp; int excl; cm_user_t *userp; @@ -5718,10 +5904,10 @@ long smb_ReceiveCoreCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) char *lastNamep; int caseFold; long dosTime; - char *tidPathp; - cm_req_t req; + char *tidPathp; + cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); scp = NULL; excl = (inp->inCom == 0x03)? 0 : 1; @@ -5729,26 +5915,26 @@ long smb_ReceiveCoreCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) attributes = smb_GetSMBParm(inp, 0); dosTime = smb_GetSMBParm(inp, 1) | (smb_GetSMBParm(inp, 2) << 16); - /* compute initial mode bits based on read-only flag in attributes */ + /* compute initial mode bits based on read-only flag in attributes */ initialModeBits = 0666; if (attributes & 1) initialModeBits &= ~0222; - tp = smb_GetSMBData(inp, NULL); + tp = smb_GetSMBData(inp, NULL); pathp = smb_ParseASCIIBlock(tp, &tp); - spacep = inp->spacep; + spacep = inp->spacep; smb_StripLastComponent(spacep->data, &lastNamep, pathp); - userp = smb_GetUser(vcp, inp); + userp = smb_GetUser(vcp, inp); caseFold = CM_FLAG_CASEFOLD; - code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); - if(code) { + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); + if (code) { cm_ReleaseUser(userp); return CM_ERROR_NOSUCHPATH; } - code = cm_NameI(cm_rootSCachep, spacep->data, caseFold | CM_FLAG_FOLLOW, + code = cm_NameI(cm_rootSCachep, spacep->data, caseFold | CM_FLAG_FOLLOW, userp, tidPathp, &req, &dscp); if (code) { @@ -5757,7 +5943,7 @@ long smb_ReceiveCoreCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) } /* otherwise, scp points to the parent directory. Do a lookup, and - * truncate the file if we find it, otherwise we create the file. + * truncate the file if we find it, otherwise we create the file. */ if (!lastNamep) lastNamep = pathp; else lastNamep++; @@ -5777,7 +5963,7 @@ long smb_ReceiveCoreCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) code = cm_Lookup(dscp, lastNamep, 0, userp, &req, &scp); if (code && code != CM_ERROR_NOSUCHFILE) { - cm_ReleaseSCache(dscp); + cm_ReleaseSCache(dscp); cm_ReleaseUser(userp); return code; } @@ -5785,40 +5971,40 @@ long smb_ReceiveCoreCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) /* if we get here, if code is 0, the file exists and is represented by * scp. Otherwise, we have to create it. */ - if (code == 0) { - if (excl) { - /* oops, file shouldn't be there */ + if (code == 0) { + if (excl) { + /* oops, file shouldn't be there */ cm_ReleaseSCache(dscp); cm_ReleaseSCache(scp); cm_ReleaseUser(userp); return CM_ERROR_EXISTS; } - setAttr.mask = CM_ATTRMASK_LENGTH; + setAttr.mask = CM_ATTRMASK_LENGTH; setAttr.length.LowPart = 0; setAttr.length.HighPart = 0; - code = cm_SetAttr(scp, &setAttr, userp, &req); + code = cm_SetAttr(scp, &setAttr, userp, &req); } else { - setAttr.mask = CM_ATTRMASK_CLIENTMODTIME; - smb_UnixTimeFromDosUTime(&setAttr.clientModTime, dosTime); + setAttr.mask = CM_ATTRMASK_CLIENTMODTIME; + smb_UnixTimeFromDosUTime(&setAttr.clientModTime, dosTime); code = cm_Create(dscp, lastNamep, 0, &setAttr, &scp, userp, &req); - if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) - smb_NotifyChange(FILE_ACTION_ADDED, + if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) + smb_NotifyChange(FILE_ACTION_ADDED, FILE_NOTIFY_CHANGE_FILE_NAME, dscp, lastNamep, NULL, TRUE); if (!excl && code == CM_ERROR_EXISTS) { - /* not an exclusive create, and someone else tried - * creating it already, then we open it anyway. We - * don't bother retrying after this, since if this next - * fails, that means that the file was deleted after - * we started this call. + /* not an exclusive create, and someone else tried + * creating it already, then we open it anyway. We + * don't bother retrying after this, since if this next + * fails, that means that the file was deleted after + * we started this call. */ code = cm_Lookup(dscp, lastNamep, caseFold, userp, &req, &scp); if (code == 0) { - setAttr.mask = CM_ATTRMASK_LENGTH; + setAttr.mask = CM_ATTRMASK_LENGTH; setAttr.length.LowPart = 0; setAttr.length.HighPart = 0; code = cm_SetAttr(scp, &setAttr, userp, &req); @@ -5826,39 +6012,39 @@ long smb_ReceiveCoreCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) } } - /* we don't need this any longer */ - cm_ReleaseSCache(dscp); + /* we don't need this any longer */ + cm_ReleaseSCache(dscp); if (code) { - /* something went wrong creating or truncating the file */ + /* something went wrong creating or truncating the file */ if (scp) cm_ReleaseSCache(scp); cm_ReleaseUser(userp); return code; } - /* make sure we only open files */ - if (scp->fileType != CM_SCACHETYPE_FILE) { - cm_ReleaseSCache(scp); + /* make sure we only open files */ + if (scp->fileType != CM_SCACHETYPE_FILE) { + cm_ReleaseSCache(scp); cm_ReleaseUser(userp); return CM_ERROR_ISDIR; - } + } /* now all we have to do is open the file itself */ fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE); osi_assert(fidp); - /* save a pointer to the vnode */ + /* save a pointer to the vnode */ fidp->scp = scp; - /* always create it open for read/write */ - fidp->flags |= (SMB_FID_OPENREAD | SMB_FID_OPENWRITE); + /* always create it open for read/write */ + fidp->flags |= (SMB_FID_OPENREAD | SMB_FID_OPENWRITE); - smb_ReleaseFID(fidp); + smb_ReleaseFID(fidp); - smb_SetSMBParm(outp, 0, fidp->fid); + smb_SetSMBParm(outp, 0, fidp->fid); smb_SetSMBDataLength(outp, 0); - cm_Open(scp, 0, userp); + cm_Open(scp, 0, userp); cm_ReleaseUser(userp); /* leave scp held since we put it in fidp->scp */ @@ -5874,43 +6060,43 @@ long smb_ReceiveCoreSeek(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) smb_fid_t *fidp; cm_scache_t *scp; cm_user_t *userp; - cm_req_t req; + cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); fd = smb_GetSMBParm(inp, 0); - whence = smb_GetSMBParm(inp, 1); + whence = smb_GetSMBParm(inp, 1); offset = smb_GetSMBParm(inp, 2) | (smb_GetSMBParm(inp, 3) << 16); - /* try to find the file descriptor */ - fd = smb_ChainFID(fd, inp); + /* try to find the file descriptor */ + fd = smb_ChainFID(fd, inp); fidp = smb_FindFID(vcp, fd, 0); if (!fidp || (fidp->flags & SMB_FID_IOCTL)) { - return CM_ERROR_BADFD; + return CM_ERROR_BADFD; } - userp = smb_GetUser(vcp, inp); + userp = smb_GetUser(vcp, inp); lock_ObtainMutex(&fidp->mx); scp = fidp->scp; - lock_ObtainMutex(&scp->mx); - code = cm_SyncOp(scp, NULL, userp, &req, 0, + lock_ObtainMutex(&scp->mx); + code = cm_SyncOp(scp, NULL, userp, &req, 0, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); - if (code == 0) { - if (whence == 1) { + if (code == 0) { + if (whence == 1) { /* offset from current offset */ offset += fidp->offset; - } - else if (whence == 2) { + } + else if (whence == 2) { /* offset from current EOF */ offset += scp->length.LowPart; - } + } fidp->offset = offset; smb_SetSMBParm(outp, 0, offset & 0xffff); smb_SetSMBParm(outp, 1, (offset>>16) & 0xffff); smb_SetSMBDataLength(outp, 0); } - lock_ReleaseMutex(&scp->mx); + lock_ReleaseMutex(&scp->mx); lock_ReleaseMutex(&fidp->mx); smb_ReleaseFID(fidp); cm_ReleaseUser(userp); @@ -5921,7 +6107,7 @@ long smb_ReceiveCoreSeek(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) * be more than one request. */ void smb_DispatchPacket(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp, - NCB *ncbp, raw_write_cont_t *rwcp) + NCB *ncbp, raw_write_cont_t *rwcp) { smb_dispatch_t *dp; smb_t *smbp; @@ -5933,225 +6119,232 @@ void smb_DispatchPacket(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp, int temp; unsigned char *tp; unsigned short errCode; - unsigned long NTStatus; + unsigned long NTStatus; int noSend; unsigned char errClass; - unsigned int oldGen; - DWORD oldTime, newTime; + unsigned int oldGen; + DWORD oldTime, newTime; - /* get easy pointer to the data */ - smbp = (smb_t *) inp->data; + /* get easy pointer to the data */ + smbp = (smb_t *) inp->data; - if (!(outp->flags & SMB_PACKETFLAG_SUSPENDED)) { + if (!(outp->flags & SMB_PACKETFLAG_SUSPENDED)) { /* setup the basic parms for the initial request in the packet */ - inp->inCom = smbp->com; + inp->inCom = smbp->com; inp->wctp = &smbp->wct; inp->inCount = 0; - inp->ncb_length = ncbp->ncb_length; - } + inp->ncb_length = ncbp->ncb_length; + } noSend = 0; - /* Sanity check */ - if (ncbp->ncb_length < offsetof(struct smb, vdata)) { - /* log it and discard it */ + /* Sanity check */ + if (ncbp->ncb_length < offsetof(struct smb, vdata)) { + /* log it and discard it */ #ifndef DJGPP - HANDLE h; - char *ptbuf[1]; - char s[100]; - h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME); - sprintf(s, "SMB message too short, len %d", ncbp->ncb_length); - ptbuf[0] = s; - ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, 1007, NULL, - 1, ncbp->ncb_length, ptbuf, inp); - DeregisterEventSource(h); + HANDLE h; + char *ptbuf[1]; + char s[100]; + h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME); + sprintf(s, "SMB message too short, len %d", ncbp->ncb_length); + ptbuf[0] = s; + ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, 1007, NULL, + 1, ncbp->ncb_length, ptbuf, inp); + DeregisterEventSource(h); #else /* DJGPP */ osi_Log1(smb_logp, "SMB message too short, len %d", ncbp->ncb_length); #endif /* !DJGPP */ - return; - } + return; + } - /* We are an ongoing op */ - thrd_Increment(&ongoingOps); + /* We are an ongoing op */ + thrd_Increment(&ongoingOps); /* set up response packet for receiving output */ - if (!(outp->flags & SMB_PACKETFLAG_SUSPENDED)) + if (!(outp->flags & SMB_PACKETFLAG_SUSPENDED)) smb_FormatResponsePacket(vcp, inp, outp); outWctp = outp->wctp; - /* Remember session generation number and time */ - oldGen = sessionGen; - oldTime = GetCurrentTime(); + /* Remember session generation number and time */ + oldGen = sessionGen; + oldTime = GetCurrentTime(); - while(inp->inCom != 0xff) { + while (inp->inCom != 0xff) { dp = &smb_dispatchTable[inp->inCom]; - if (outp->flags & SMB_PACKETFLAG_SUSPENDED) { - outp->flags &= ~SMB_PACKETFLAG_SUSPENDED; - code = outp->resumeCode; - goto resume; - } + if (outp->flags & SMB_PACKETFLAG_SUSPENDED) { + outp->flags &= ~SMB_PACKETFLAG_SUSPENDED; + code = outp->resumeCode; + goto resume; + } /* process each request in the packet; inCom, wctp and inCount * are already set up. */ - osi_Log2(smb_logp, "SMB received op 0x%x lsn %d", inp->inCom, - ncbp->ncb_lsn); + osi_Log2(smb_logp, "SMB received op 0x%x lsn %d", inp->inCom, + ncbp->ncb_lsn); - /* now do the dispatch */ - /* start by formatting the response record a little, as a default */ + /* now do the dispatch */ + /* start by formatting the response record a little, as a default */ if (dp->flags & SMB_DISPATCHFLAG_CHAINED) { - outWctp[0] = 2; + outWctp[0] = 2; outWctp[1] = 0xff; /* no operation */ outWctp[2] = 0; /* padding */ outWctp[3] = 0; outWctp[4] = 0; } - else { - /* not a chained request, this is a more reasonable default */ + else { + /* not a chained request, this is a more reasonable default */ outWctp[0] = 0; /* wct of zero */ outWctp[1] = 0; /* and bcc (word) of zero */ outWctp[2] = 0; - } + } - /* once set, stays set. Doesn't matter, since we never chain + /* once set, stays set. Doesn't matter, since we never chain * "no response" calls. */ - if (dp->flags & SMB_DISPATCHFLAG_NORESPONSE) + if (dp->flags & SMB_DISPATCHFLAG_NORESPONSE) noSend = 1; if (dp->procp) { - /* we have a recognized operation */ - - if (inp->inCom == 0x1d) - /* Raw Write */ - code = smb_ReceiveCoreWriteRaw (vcp, inp, outp, - rwcp); - else { - osi_LogEvent("AFS Dispatch %s",(myCrt_Dispatch(inp->inCom)),"vcp[%x] lana[%d] lsn[%d]",(int)vcp,vcp->lana,vcp->lsn); - osi_Log4(smb_logp,"Dispatch %s vcp[%x] lana[%d] lsn[%d]",(myCrt_Dispatch(inp->inCom)),vcp,vcp->lana,vcp->lsn); - code = (*(dp->procp)) (vcp, inp, outp); - osi_LogEvent("AFS Dispatch return",NULL,"Code[%d]",(code==0)?0:code-CM_ERROR_BASE); - osi_Log1(smb_logp,"Dispatch return code[%d]",(code==0)?0:code-CM_ERROR_BASE); - } + /* we have a recognized operation */ - if (oldGen != sessionGen) { + if (inp->inCom == 0x1d) + /* Raw Write */ + code = smb_ReceiveCoreWriteRaw (vcp, inp, outp, + rwcp); + else { + osi_LogEvent("AFS Dispatch %s",(myCrt_Dispatch(inp->inCom)),"vcp[%x] lana[%d] lsn[%d]",(int)vcp,vcp->lana,vcp->lsn); + osi_Log4(smb_logp,"Dispatch %s vcp[%x] lana[%d] lsn[%d]",(myCrt_Dispatch(inp->inCom)),vcp,vcp->lana,vcp->lsn); + code = (*(dp->procp)) (vcp, inp, outp); + osi_LogEvent("AFS Dispatch return",NULL,"Code[%d]",(code==0)?0:code-CM_ERROR_BASE); + osi_Log1(smb_logp,"Dispatch return code[%d]",(code==0)?0:code-CM_ERROR_BASE); +#ifdef LOG_PACKET + if ( code == CM_ERROR_BADSMB || + code == CM_ERROR_BADOP ) + smb_LogPacket(inp); +#endif /* LOG_PACKET */ + } + + if (oldGen != sessionGen) { #ifndef DJGPP - HANDLE h; - char *ptbuf[1]; - char s[100]; - newTime = GetCurrentTime(); - h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME); - sprintf(s, "Pkt straddled session startup, took %d ms, ncb length %d", - newTime - oldTime, ncbp->ncb_length); - ptbuf[0] = s; - ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, - 1005, NULL, 1, ncbp->ncb_length, ptbuf, smbp); - DeregisterEventSource(h); + HANDLE h; + char *ptbuf[1]; + char s[100]; + newTime = GetCurrentTime(); + h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME); + sprintf(s, "Pkt straddled session startup, took %d ms, ncb length %d", + newTime - oldTime, ncbp->ncb_length); + ptbuf[0] = s; + ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, + 1005, NULL, 1, ncbp->ncb_length, ptbuf, smbp); + DeregisterEventSource(h); #endif /* !DJGPP */ - osi_Log1(smb_logp, "Pkt straddled session startup, " - "ncb length %d", ncbp->ncb_length); - } + osi_Log1(smb_logp, "Pkt straddled session startup, " + "ncb length %d", ncbp->ncb_length); + } } else { - /* bad opcode, fail the request, after displaying it */ -#ifdef NOTSERVICE + /* bad opcode, fail the request, after displaying it */ + osi_Log1(smb_logp, "Received bad SMB req 0x%X", inp->inCom); +#ifdef LOG_PACKET smb_LogPacket(inp); -#endif /* NOTSERVICE */ +#endif /* LOG_PACKET */ #ifndef DJGPP - if (showErrors) { - sprintf(tbuffer, "Received bad SMB req 0x%x", inp->inCom); + if (showErrors) { + sprintf(tbuffer, "Received bad SMB req 0x%x", inp->inCom); code = (*smb_MBfunc)(NULL, tbuffer, "Cancel: don't show again", - MB_OKCANCEL|MB_SERVICE_NOTIFICATION); - if (code == IDCANCEL) showErrors = 0; - } + MB_OKCANCEL|MB_SERVICE_NOTIFICATION); + if (code == IDCANCEL) + showErrors = 0; + } #endif /* DJGPP */ code = CM_ERROR_BADOP; } - /* catastrophic failure: log as much as possible */ - if (code == CM_ERROR_BADSMB) { + /* catastrophic failure: log as much as possible */ + if (code == CM_ERROR_BADSMB) { #ifndef DJGPP - HANDLE h; - char *ptbuf[1]; - char s[100]; + HANDLE h; + char *ptbuf[1]; + char s[100]; - osi_Log1(smb_logp, + osi_Log1(smb_logp, "Invalid SMB, ncb_length %d", ncbp->ncb_length); - h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME); - sprintf(s, "Invalid SMB message, length %d", + h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME); + sprintf(s, "Invalid SMB message, length %d", ncbp->ncb_length); - ptbuf[0] = s; - ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, 1002, NULL, + ptbuf[0] = s; + ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, 1002, NULL, 1, ncbp->ncb_length, ptbuf, smbp); - DeregisterEventSource(h); -#ifdef NOTSERVICE + DeregisterEventSource(h); +#ifdef LOG_PACKET smb_LogPacket(inp); -#endif /* NOTSERVICE */ +#endif /* LOG_PACKET */ #endif /* !DJGPP */ osi_Log1(smb_logp, "Invalid SMB message, length %d", ncbp->ncb_length); - code = CM_ERROR_INVAL; - } + code = CM_ERROR_INVAL; + } - if (outp->flags & SMB_PACKETFLAG_NOSEND) { - thrd_Decrement(&ongoingOps); - return; - } + if (outp->flags & SMB_PACKETFLAG_NOSEND) { + thrd_Decrement(&ongoingOps); + return; + } resume: - /* now, if we failed, turn the current response into an empty + /* now, if we failed, turn the current response into an empty * one, and fill in the response packet's error code. */ - if (code) { - if (vcp->flags & SMB_VCFLAG_STATUS32) { - smb_MapNTError(code, &NTStatus); - outWctp = outp->wctp; - smbp = (smb_t *) &outp->data; - if (code != CM_ERROR_PARTIALWRITE - && code != CM_ERROR_BUFFERTOOSMALL - && code != CM_ERROR_GSSCONTINUE) { - /* nuke wct and bcc. For a partial - * write or an in-process authentication handshake, + if (code) { + if (vcp->flags & SMB_VCFLAG_STATUS32) { + smb_MapNTError(code, &NTStatus); + outWctp = outp->wctp; + smbp = (smb_t *) &outp->data; + if (code != CM_ERROR_PARTIALWRITE + && code != CM_ERROR_BUFFERTOOSMALL + && code != CM_ERROR_GSSCONTINUE) { + /* nuke wct and bcc. For a partial + * write or an in-process authentication handshake, * assume they're OK. - */ - *outWctp++ = 0; - *outWctp++ = 0; - *outWctp++ = 0; - } - smbp->rcls = (unsigned char) (NTStatus & 0xff); - smbp->reh = (unsigned char) ((NTStatus >> 8) & 0xff); - smbp->errLow = (unsigned char) ((NTStatus >> 16) & 0xff); - smbp->errHigh = (unsigned char) ((NTStatus >> 24) & 0xff); - smbp->flg2 |= 0x4000; - break; - } - else { + */ + *outWctp++ = 0; + *outWctp++ = 0; + *outWctp++ = 0; + } + smbp->rcls = (unsigned char) (NTStatus & 0xff); + smbp->reh = (unsigned char) ((NTStatus >> 8) & 0xff); + smbp->errLow = (unsigned char) ((NTStatus >> 16) & 0xff); + smbp->errHigh = (unsigned char) ((NTStatus >> 24) & 0xff); + smbp->flg2 |= 0x4000; + break; + } + else { smb_MapCoreError(code, vcp, &errCode, &errClass); - outWctp = outp->wctp; - smbp = (smb_t *) &outp->data; - if (code != CM_ERROR_PARTIALWRITE) { - /* nuke wct and bcc. For a partial - * write, assume they're OK. - */ - *outWctp++ = 0; - *outWctp++ = 0; - *outWctp++ = 0; - } - smbp->errLow = (unsigned char) (errCode & 0xff); - smbp->errHigh = (unsigned char) ((errCode >> 8) & 0xff); + outWctp = outp->wctp; + smbp = (smb_t *) &outp->data; + if (code != CM_ERROR_PARTIALWRITE) { + /* nuke wct and bcc. For a partial + * write, assume they're OK. + */ + *outWctp++ = 0; + *outWctp++ = 0; + *outWctp++ = 0; + } + smbp->errLow = (unsigned char) (errCode & 0xff); + smbp->errHigh = (unsigned char) ((errCode >> 8) & 0xff); smbp->rcls = errClass; - break; - } - } /* error occurred */ - + break; + } + } /* error occurred */ + /* if we're here, we've finished one request. Look to see if - * this is a chained opcode. If it is, setup things to process - * the chained request, and setup the output buffer to hold the - * chained response. Start by finding the next input record. + * this is a chained opcode. If it is, setup things to process + * the chained request, and setup the output buffer to hold the + * chained response. Start by finding the next input record. */ if (!(dp->flags & SMB_DISPATCHFLAG_CHAINED)) break; /* not a chained req */ @@ -6168,7 +6361,7 @@ void smb_DispatchPacket(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp, /* and now append the next output request to the end of this * last request. Begin by finding out where the last response - * ends, since that's where we'll put our new response. + * ends, since that's where we'll put our new response. */ outWctp = outp->wctp; /* ptr to out parameters */ osi_assert (outWctp[0] >= 2); /* need this for all chained requests */ @@ -6176,35 +6369,35 @@ void smb_DispatchPacket(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp, tp = outWctp + nparms + 1; /* now points to bcc field */ nbytes = tp[0] + (tp[1] << 8); /* # of data bytes */ tp += 2 /* for the count itself */ + nbytes; - /* tp now points to the new output record; go back and patch the + /* tp now points to the new output record; go back and patch the * second parameter (off2) to point to the new record. */ - temp = (unsigned int)tp - ((unsigned int) outp->data); + temp = (unsigned int)tp - ((unsigned int) outp->data); outWctp[3] = (unsigned char) (temp & 0xff); outWctp[4] = (unsigned char) ((temp >> 8) & 0xff); outWctp[2] = 0; /* padding */ outWctp[1] = inp->inCom; /* next opcode */ - /* finally, setup for the next iteration */ + /* finally, setup for the next iteration */ outp->wctp = tp; - outWctp = tp; - } /* while loop over all requests in the packet */ - - /* done logging out, turn off logging-out flag */ - if (!(inp->flags & SMB_PACKETFLAG_PROFILE_UPDATE_OK)) { - vcp->justLoggedOut = NULL; - if (loggedOut) { - loggedOut = 0; - free(loggedOutName); - loggedOutName = NULL; - smb_ReleaseUID(loggedOutUserp); - loggedOutUserp = NULL; - } - } + outWctp = tp; + } /* while loop over all requests in the packet */ + + /* done logging out, turn off logging-out flag */ + if (!(inp->flags & SMB_PACKETFLAG_PROFILE_UPDATE_OK)) { + vcp->justLoggedOut = NULL; + if (loggedOut) { + loggedOut = 0; + free(loggedOutName); + loggedOutName = NULL; + smb_ReleaseUID(loggedOutUserp); + loggedOutUserp = NULL; + } + } /* now send the output packet, and return */ if (!noSend) - smb_SendPacket(vcp, outp); + smb_SendPacket(vcp, outp); thrd_Decrement(&ongoingOps); if (!(vcp->flags & SMB_VCFLAG_ALREADYDEAD)) { @@ -6214,12 +6407,12 @@ void smb_DispatchPacket(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp, "Replacing active_vcp %x with %x", active_vcp, vcp); } smb_HoldVC(vcp); - active_vcp = vcp; - last_msg_time = GetCurrentTime(); - } + active_vcp = vcp; + last_msg_time = GetCurrentTime(); + } else if (active_vcp == vcp) { - smb_ReleaseVC(active_vcp); - active_vcp = NULL; + smb_ReleaseVC(active_vcp); + active_vcp = NULL; } return; @@ -6233,14 +6426,14 @@ void smb_DispatchPacket(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp, */ void smb_ClientWaiter(void *parmp) { - DWORD code; + DWORD code; int idx; - while (1) { - code = thrd_WaitForMultipleObjects_Event(numNCBs, NCBevents, - FALSE, INFINITE); - if (code == WAIT_OBJECT_0) - continue; + while (1) { + code = thrd_WaitForMultipleObjects_Event(numNCBs, NCBevents, + FALSE, INFINITE); + if (code == WAIT_OBJECT_0) + continue; /* error checking */ if (code >= WAIT_ABANDONED_0 && code < (WAIT_ABANDONED_0 + numNCBs)) @@ -6275,9 +6468,9 @@ void smb_ClientWaiter(void *parmp) osi_assert(0); } - thrd_ResetEvent(NCBevents[idx]); - thrd_SetEvent(NCBreturns[0][idx]); - } + thrd_ResetEvent(NCBevents[idx]); + thrd_SetEvent(NCBreturns[0][idx]); + } } #endif /* !DJGPP */ @@ -6287,19 +6480,19 @@ void smb_ClientWaiter(void *parmp) */ void smb_ServerWaiter(void *parmp) { - DWORD code; + DWORD code; int idx_session, idx_NCB; - NCB *ncbp; + NCB *ncbp; #ifdef DJGPP dos_ptr dos_ncb; #endif /* DJGPP */ - while (1) { - /* Get a session */ - code = thrd_WaitForMultipleObjects_Event(numSessions, SessionEvents, - FALSE, INFINITE); - if (code == WAIT_OBJECT_0) - continue; + while (1) { + /* Get a session */ + code = thrd_WaitForMultipleObjects_Event(numSessions, SessionEvents, + FALSE, INFINITE); + if (code == WAIT_OBJECT_0) + continue; if (code >= WAIT_ABANDONED_0 && code < (WAIT_ABANDONED_0 + numSessions)) { @@ -6335,10 +6528,10 @@ void smb_ServerWaiter(void *parmp) /* Get an NCB */ NCBretry: - code = thrd_WaitForMultipleObjects_Event(numNCBs, NCBavails, - FALSE, INFINITE); - if (code == WAIT_OBJECT_0) - goto NCBretry; + code = thrd_WaitForMultipleObjects_Event(numNCBs, NCBavails, + FALSE, INFINITE); + if (code == WAIT_OBJECT_0) + goto NCBretry; /* error checking */ if (code >= WAIT_ABANDONED_0 && code < (WAIT_ABANDONED_0 + numNCBs)) @@ -6373,30 +6566,30 @@ void smb_ServerWaiter(void *parmp) osi_assert(0); } - /* Link them together */ - NCBsessions[idx_NCB] = idx_session; + /* Link them together */ + NCBsessions[idx_NCB] = idx_session; - /* Fire it up */ - ncbp = NCBs[idx_NCB]; + /* Fire it up */ + ncbp = NCBs[idx_NCB]; #ifdef DJGPP dos_ncb = ((smb_ncb_t *)ncbp)->dos_ncb; #endif /* DJGPP */ - ncbp->ncb_lsn = (unsigned char) LSNs[idx_session]; - ncbp->ncb_command = NCBRECV | ASYNCH; - ncbp->ncb_lana_num = lanas[idx_session]; + ncbp->ncb_lsn = (unsigned char) LSNs[idx_session]; + ncbp->ncb_command = NCBRECV | ASYNCH; + ncbp->ncb_lana_num = lanas[idx_session]; #ifndef DJGPP - ncbp->ncb_buffer = (unsigned char *) bufs[idx_NCB]; - ncbp->ncb_event = NCBevents[idx_NCB]; - ncbp->ncb_length = SMB_PACKETSIZE; - Netbios(ncbp); + ncbp->ncb_buffer = (unsigned char *) bufs[idx_NCB]; + ncbp->ncb_event = NCBevents[idx_NCB]; + ncbp->ncb_length = SMB_PACKETSIZE; + Netbios(ncbp); #else /* DJGPP */ - ncbp->ncb_buffer = bufs[idx_NCB]->dos_pkt; - ((smb_ncb_t*)ncbp)->orig_pkt = bufs[idx_NCB]; - ncbp->ncb_event = NCBreturns[0][idx_NCB]; - ncbp->ncb_length = SMB_PACKETSIZE; - Netbios(ncbp, dos_ncb); + ncbp->ncb_buffer = bufs[idx_NCB]->dos_pkt; + ((smb_ncb_t*)ncbp)->orig_pkt = bufs[idx_NCB]; + ncbp->ncb_event = NCBreturns[0][idx_NCB]; + ncbp->ncb_length = SMB_PACKETSIZE; + Netbios(ncbp, dos_ncb); #endif /* !DJGPP */ - } + } } /* @@ -6411,42 +6604,29 @@ void smb_ServerWaiter(void *parmp) */ void smb_Server(VOID *parmp) { - int myIdx = (int) parmp; - NCB *ncbp; - NCB *outncbp; + int myIdx = (int) parmp; + NCB *ncbp; + NCB *outncbp; smb_packet_t *bufp; - smb_packet_t *outbufp; + smb_packet_t *outbufp; DWORD code, rcode; int idx_NCB, idx_session; - UCHAR rc; - smb_vc_t *vcp = NULL; - smb_t *smbp; + UCHAR rc; + smb_vc_t *vcp = NULL; + smb_t *smbp; #ifdef DJGPP dos_ptr dos_ncb; #endif /* DJGPP */ - outncbp = GetNCB(); - outbufp = GetPacket(); - outbufp->ncbp = outncbp; - - while (1) { -#ifndef NOEXPIRE - /* check for demo expiration */ - { - unsigned long tod = time((void *) 0); - if (tod > EXPIREDATE) { - (*smb_MBfunc)(NULL, "AFS demo expiration", - "afsd dispatcher", - MB_OK|MB_ICONSTOP|MB_SETFOREGROUND|MB_SERVICE_NOTIFICATION); - trhd_Exit(1); - } - } -#endif /* !NOEXPIRE */ - - code = thrd_WaitForMultipleObjects_Event(numNCBs, NCBreturns[myIdx], - FALSE, INFINITE); - if (code == WAIT_OBJECT_0) { - continue; + outncbp = GetNCB(); + outbufp = GetPacket(); + outbufp->ncbp = outncbp; + + while (1) { + code = thrd_WaitForMultipleObjects_Event(numNCBs, NCBreturns[myIdx], + FALSE, INFINITE); + if (code == WAIT_OBJECT_0) { + continue; } /* error checking */ @@ -6482,183 +6662,182 @@ void smb_Server(VOID *parmp) osi_assert(0); } - ncbp = NCBs[idx_NCB]; + ncbp = NCBs[idx_NCB]; #ifdef DJGPP - dos_ncb = ((smb_ncb_t *)ncbp)->dos_ncb; + dos_ncb = ((smb_ncb_t *)ncbp)->dos_ncb; #endif /* DJGPP */ - idx_session = NCBsessions[idx_NCB]; - rc = ncbp->ncb_retcode; + idx_session = NCBsessions[idx_NCB]; + rc = ncbp->ncb_retcode; - if (rc != NRC_PENDING && rc != NRC_GOODRET) - osi_Log1(smb_logp, "NCBRECV failure code %d", rc); + if (rc != NRC_PENDING && rc != NRC_GOODRET) + osi_Log1(smb_logp, "NCBRECV failure code %d", rc); - switch (rc) { - case NRC_GOODRET: break; + switch (rc) { + case NRC_GOODRET: break; - case NRC_PENDING: - /* Can this happen? Or is it just my - * UNIX paranoia? - */ - continue; - - case NRC_SCLOSED: - case NRC_SNUMOUT: - /* Client closed session */ - if (reportSessionStartups) - { - osi_Log1(smb_logp, "session [ %d ] closed", idx_session); + case NRC_PENDING: + /* Can this happen? Or is it just my + * UNIX paranoia? + */ + continue; + + case NRC_SCLOSED: + case NRC_SNUMOUT: + /* Client closed session */ + if (reportSessionStartups) + { + osi_Log1(smb_logp, "session [ %d ] closed", idx_session); + } + dead_sessions[idx_session] = TRUE; + if (vcp) + smb_ReleaseVC(vcp); + vcp = smb_FindVC(ncbp->ncb_lsn, 0, lanas[idx_session]); + /* Should also release vcp. [done] 2004-05-11 jaltman + * Also, should do + * sanity check that all TID's are gone. + * + * TODO: check if we could use LSNs[idx_session] instead, + * also cleanup after dead vcp + */ + if (vcp) { + if (dead_vcp) + osi_Log1(smb_logp, + "dead_vcp already set, %x", + dead_vcp); + if (!dead_vcp && !(vcp->flags & SMB_VCFLAG_ALREADYDEAD)) { + osi_Log2(smb_logp, + "setting dead_vcp %x, user struct %x", + vcp, vcp->usersp); + smb_HoldVC(vcp); + dead_vcp = vcp; + vcp->flags |= SMB_VCFLAG_ALREADYDEAD; } - dead_sessions[idx_session] = TRUE; - if (vcp) - smb_ReleaseVC(vcp); - vcp = smb_FindVC(ncbp->ncb_lsn, 0, lanas[idx_session]); - /* Should also release vcp. [done] 2004-05-11 jaltman - * Also, should do - * sanity check that all TID's are gone. - * - * TODO: check if we could use LSNs[idx_session] instead, - * also cleanup after dead vcp - */ - if (vcp) { - if (dead_vcp) - osi_Log1(smb_logp, - "dead_vcp already set, %x", - dead_vcp); - if (!dead_vcp && !(vcp->flags & SMB_VCFLAG_ALREADYDEAD)) { - osi_Log2(smb_logp, - "setting dead_vcp %x, user struct %x", - vcp, vcp->usersp); - smb_HoldVC(vcp); - dead_vcp = vcp; - vcp->flags |= SMB_VCFLAG_ALREADYDEAD; - } - if (vcp->justLoggedOut) { - loggedOut = 1; - loggedOutTime = vcp->logoffTime; - loggedOutName = - strdup(vcp->justLoggedOut->unp->name); - loggedOutUserp = vcp->justLoggedOut; - lock_ObtainWrite(&smb_rctLock); - loggedOutUserp->refCount++; - lock_ReleaseWrite(&smb_rctLock); - } + if (vcp->justLoggedOut) { + loggedOut = 1; + loggedOutTime = vcp->logoffTime; + loggedOutName = strdup(vcp->justLoggedOut->unp->name); + loggedOutUserp = vcp->justLoggedOut; + lock_ObtainWrite(&smb_rctLock); + loggedOutUserp->refCount++; + lock_ReleaseWrite(&smb_rctLock); } - goto doneWithNCB; + } + goto doneWithNCB; - case NRC_INCOMP: - /* Treat as transient error */ - { + case NRC_INCOMP: + /* Treat as transient error */ + { #ifndef DJGPP - EVENT_HANDLE h; - char *ptbuf[1]; - char s[100]; - - h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME); - sprintf(s, "SMB message incomplete, length %d", - ncbp->ncb_length); - ptbuf[0] = s; - ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, - 1001, NULL, 1, - ncbp->ncb_length, ptbuf, - bufp); - DeregisterEventSource(h); + EVENT_HANDLE h; + char *ptbuf[1]; + char s[100]; + + h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME); + sprintf(s, "SMB message incomplete, length %d", + ncbp->ncb_length); + ptbuf[0] = s; + ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, + 1001, NULL, 1, + ncbp->ncb_length, ptbuf, + bufp); + DeregisterEventSource(h); #endif /* !DJGPP */ - osi_Log1(smb_logp, - "dispatch smb recv failed, message incomplete, ncb_length %d", - ncbp->ncb_length); - osi_Log1(smb_logp, - "SMB message incomplete, " - "length %d", ncbp->ncb_length); - - /* - * We used to discard the packet. - * Instead, try handling it normally. - * - continue; - */ - break; - } - - default: - /* A weird error code. Log it, sleep, and - * continue. */ - if (vcp && vcp->errorCount++ > 3) { - osi_Log2(smb_logp, "session [ %d ] closed, vcp->errorCount = %d", idx_session, vcp->errorCount); - dead_sessions[idx_session] = TRUE; - } - else { - thrd_Sleep(1000); - thrd_SetEvent(SessionEvents[idx_session]); - } - continue; - } + osi_Log1(smb_logp, + "dispatch smb recv failed, message incomplete, ncb_length %d", + ncbp->ncb_length); + osi_Log1(smb_logp, + "SMB message incomplete, " + "length %d", ncbp->ncb_length); + + /* + * We used to discard the packet. + * Instead, try handling it normally. + * + continue; + */ + break; + } - /* Success, so now dispatch on all the data in the packet */ + default: + /* A weird error code. Log it, sleep, and + * continue. */ + if (vcp && vcp->errorCount++ > 3) { + osi_Log2(smb_logp, "session [ %d ] closed, vcp->errorCount = %d", idx_session, vcp->errorCount); + dead_sessions[idx_session] = TRUE; + } + else { + thrd_Sleep(1000); + thrd_SetEvent(SessionEvents[idx_session]); + } + continue; + } + + /* Success, so now dispatch on all the data in the packet */ - smb_concurrentCalls++; - if (smb_concurrentCalls > smb_maxObsConcurrentCalls) - smb_maxObsConcurrentCalls = smb_concurrentCalls; + smb_concurrentCalls++; + if (smb_concurrentCalls > smb_maxObsConcurrentCalls) + smb_maxObsConcurrentCalls = smb_concurrentCalls; if (vcp) smb_ReleaseVC(vcp); - vcp = smb_FindVC(ncbp->ncb_lsn, 0, ncbp->ncb_lana_num); + vcp = smb_FindVC(ncbp->ncb_lsn, 0, ncbp->ncb_lana_num); /* - * If at this point vcp is NULL (implies that packet was invalid) - * then we are in big trouble. This means either : - * a) we have the wrong NCB. - * b) Netbios screwed up the call. - * Obviously this implies that - * ( LSNs[idx_session] != ncbp->ncb_lsn || - * lanas[idx_session] != ncbp->ncb_lana_num ) - * Either way, we can't do anything with this packet. - * Log, sleep and resume. - */ - if(!vcp) { - HANDLE h; - char buf[1000]; - char *ptbuf[1]; - - sprintf(buf, - "Bad vcp!! : " - "LSNs[idx_session]=[%d]," - "lanas[idx_session]=[%d]," - "ncbp->ncb_lsn=[%d]," - "ncbp->ncb_lana_num=[%d]", - LSNs[idx_session], - lanas[idx_session], - ncbp->ncb_lsn, - ncbp->ncb_lana_num); - - ptbuf[0] = buf; - - h = RegisterEventSource(NULL,AFS_DAEMON_EVENT_NAME); - if(h) { - ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, 1001, NULL,1,sizeof(*ncbp),ptbuf,(void*)ncbp); - DeregisterEventSource(h); - } - - /* Also log in the trace log. */ - osi_Log4(smb_logp, "Server: BAD VCP!" - "LSNs[idx_session]=[%d]," - "lanas[idx_session]=[%d]," - "ncbp->ncb_lsn=[%d]," - "ncbp->ncb_lana_num=[%d]", - LSNs[idx_session], - lanas[idx_session], - ncbp->ncb_lsn, - ncbp->ncb_lana_num); - - /* thrd_Sleep(1000); Don't bother sleeping */ - thrd_SetEvent(SessionEvents[idx_session]); - smb_concurrentCalls--; - continue; - } - - - vcp->errorCount = 0; - bufp = (struct smb_packet *) ncbp->ncb_buffer; + * If at this point vcp is NULL (implies that packet was invalid) + * then we are in big trouble. This means either : + * a) we have the wrong NCB. + * b) Netbios screwed up the call. + * Obviously this implies that + * ( LSNs[idx_session] != ncbp->ncb_lsn || + * lanas[idx_session] != ncbp->ncb_lana_num ) + * Either way, we can't do anything with this packet. + * Log, sleep and resume. + */ + if(!vcp) { + HANDLE h; + char buf[1000]; + char *ptbuf[1]; + + sprintf(buf, + "Bad vcp!! : " + "LSNs[idx_session]=[%d]," + "lanas[idx_session]=[%d]," + "ncbp->ncb_lsn=[%d]," + "ncbp->ncb_lana_num=[%d]", + LSNs[idx_session], + lanas[idx_session], + ncbp->ncb_lsn, + ncbp->ncb_lana_num); + + ptbuf[0] = buf; + + h = RegisterEventSource(NULL,AFS_DAEMON_EVENT_NAME); + if(h) { + ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, 1001, NULL,1,sizeof(*ncbp),ptbuf,(void*)ncbp); + DeregisterEventSource(h); + } + + /* Also log in the trace log. */ + osi_Log4(smb_logp, "Server: BAD VCP!" + "LSNs[idx_session]=[%d]," + "lanas[idx_session]=[%d]," + "ncbp->ncb_lsn=[%d]," + "ncbp->ncb_lana_num=[%d]", + LSNs[idx_session], + lanas[idx_session], + ncbp->ncb_lsn, + ncbp->ncb_lana_num); + + /* thrd_Sleep(1000); Don't bother sleeping */ + thrd_SetEvent(SessionEvents[idx_session]); + smb_concurrentCalls--; + continue; + } + + + vcp->errorCount = 0; + bufp = (struct smb_packet *) ncbp->ncb_buffer; #ifdef DJGPP - bufp = ((smb_ncb_t *) ncbp)->orig_pkt; + bufp = ((smb_ncb_t *) ncbp)->orig_pkt; /* copy whole packet to virtual memory */ /*fprintf(stderr, "smb_Server: copying dos packet at 0x%x, " "bufp=0x%x\n", @@ -6666,64 +6845,65 @@ void smb_Server(VOID *parmp) fflush(stderr); dosmemget(bufp->dos_pkt, ncbp->ncb_length, bufp->data); #endif /* DJGPP */ - smbp = (smb_t *)bufp->data; - outbufp->flags = 0; + smbp = (smb_t *)bufp->data; + outbufp->flags = 0; #if !defined(DJGPP) && !defined(AFS_WIN32_ENV) __try { #endif - if (smbp->com == 0x1d) { - /* Special handling for Write Raw */ - raw_write_cont_t rwc; - EVENT_HANDLE rwevent; - char eventName[MAX_PATH]; + if (smbp->com == 0x1d) { + /* Special handling for Write Raw */ + raw_write_cont_t rwc; + EVENT_HANDLE rwevent; + char eventName[MAX_PATH]; - smb_DispatchPacket(vcp, bufp, outbufp, ncbp, &rwc); - if (rwc.code == 0) { - rwevent = thrd_CreateEvent(NULL, FALSE, FALSE, TEXT("smb_Server() rwevent")); - if ( GetLastError() == ERROR_ALREADY_EXISTS ) - osi_Log1(smb_logp, "Event Object Already Exists: %s", osi_LogSaveString(smb_logp, eventName)); - ncbp->ncb_command = NCBRECV | ASYNCH; - ncbp->ncb_lsn = (unsigned char) vcp->lsn; - ncbp->ncb_lana_num = vcp->lana; - ncbp->ncb_buffer = rwc.buf; - ncbp->ncb_length = 65535; - ncbp->ncb_event = rwevent; + smb_DispatchPacket(vcp, bufp, outbufp, ncbp, &rwc); + if (rwc.code == 0) { + rwevent = thrd_CreateEvent(NULL, FALSE, FALSE, TEXT("smb_Server() rwevent")); + if ( GetLastError() == ERROR_ALREADY_EXISTS ) + osi_Log1(smb_logp, "Event Object Already Exists: %s", osi_LogSaveString(smb_logp, eventName)); + ncbp->ncb_command = NCBRECV | ASYNCH; + ncbp->ncb_lsn = (unsigned char) vcp->lsn; + ncbp->ncb_lana_num = vcp->lana; + ncbp->ncb_buffer = rwc.buf; + ncbp->ncb_length = 65535; + ncbp->ncb_event = rwevent; #ifndef DJGPP - Netbios(ncbp); + Netbios(ncbp); #else - Netbios(ncbp, dos_ncb); + Netbios(ncbp, dos_ncb); #endif /* !DJGPP */ - rcode = thrd_WaitForSingleObject_Event(rwevent, RAWTIMEOUT); - thrd_CloseHandle(rwevent); - } - thrd_SetEvent(SessionEvents[idx_session]); - if (rwc.code == 0) - smb_CompleteWriteRaw(vcp, bufp, outbufp, ncbp, &rwc); - } else if (smbp->com == 0xa0) { - /* - * Serialize the handling for NT Transact - * (defect 11626) - */ - smb_DispatchPacket(vcp, bufp, outbufp, ncbp, NULL); - thrd_SetEvent(SessionEvents[idx_session]); - } else { - thrd_SetEvent(SessionEvents[idx_session]); - /* TODO: what else needs to be serialized? */ - smb_DispatchPacket(vcp, bufp, outbufp, ncbp, NULL); - } + rcode = thrd_WaitForSingleObject_Event(rwevent, RAWTIMEOUT); + thrd_CloseHandle(rwevent); + } + thrd_SetEvent(SessionEvents[idx_session]); + if (rwc.code == 0) + smb_CompleteWriteRaw(vcp, bufp, outbufp, ncbp, &rwc); + } + else if (smbp->com == 0xa0) { + /* + * Serialize the handling for NT Transact + * (defect 11626) + */ + smb_DispatchPacket(vcp, bufp, outbufp, ncbp, NULL); + thrd_SetEvent(SessionEvents[idx_session]); + } else { + thrd_SetEvent(SessionEvents[idx_session]); + /* TODO: what else needs to be serialized? */ + smb_DispatchPacket(vcp, bufp, outbufp, ncbp, NULL); + } #if !defined(DJGPP) && !defined(AFS_WIN95_ENV) } __except( smb_ServerExceptionFilter() ) { } #endif - smb_concurrentCalls--; + smb_concurrentCalls--; doneWithNCB: - thrd_SetEvent(NCBavails[idx_NCB]); - } + thrd_SetEvent(NCBavails[idx_NCB]); + } if (vcp) smb_ReleaseVC(vcp); } @@ -6736,24 +6916,24 @@ doneWithNCB: */ #if !defined(DJGPP) && !defined(AFS_WIN95_ENV) DWORD smb_ServerExceptionFilter(void) { - /* While this is not the best time to do a trace, if it succeeds, then - * we have a trace (assuming tracing was enabled). Otherwise, this should - * throw a second exception. - */ - HANDLE h; - char *ptbuf[1]; - - ptbuf[0] = "Unhandled exception forcing trace"; - - h = RegisterEventSource(NULL,AFS_DAEMON_EVENT_NAME); - if(h) { - ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, 1001, NULL,1,0,ptbuf,NULL); - DeregisterEventSource(h); - } - - afsd_ForceTrace(TRUE); - return EXCEPTION_CONTINUE_SEARCH; -} + /* While this is not the best time to do a trace, if it succeeds, then + * we have a trace (assuming tracing was enabled). Otherwise, this should + * throw a second exception. + */ + HANDLE h; + char *ptbuf[1]; + + ptbuf[0] = "Unhandled exception forcing trace"; + + h = RegisterEventSource(NULL,AFS_DAEMON_EVENT_NAME); + if(h) { + ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, 1001, NULL,1,0,ptbuf,NULL); + DeregisterEventSource(h); + } + + afsd_ForceTrace(TRUE); + return EXCEPTION_CONTINUE_SEARCH; +} #endif /* @@ -6764,54 +6944,54 @@ DWORD smb_ServerExceptionFilter(void) { */ void InitNCBslot(int idx) { - struct smb_packet *bufp; - EVENT_HANDLE retHandle; - int i; + struct smb_packet *bufp; + EVENT_HANDLE retHandle; + int i; char eventName[MAX_PATH]; osi_assert( idx < (sizeof(NCBs) / sizeof(NCBs[0])) ); - NCBs[idx] = GetNCB(); + NCBs[idx] = GetNCB(); sprintf(eventName,"NCBavails[%d]", idx); - NCBavails[idx] = thrd_CreateEvent(NULL, FALSE, TRUE, eventName); + NCBavails[idx] = thrd_CreateEvent(NULL, FALSE, TRUE, eventName); if ( GetLastError() == ERROR_ALREADY_EXISTS ) osi_Log1(smb_logp, "Event Object Already Exists: %s", osi_LogSaveString(smb_logp, eventName)); #ifndef DJGPP sprintf(eventName,"NCBevents[%d]", idx); - NCBevents[idx] = thrd_CreateEvent(NULL, TRUE, FALSE, eventName); + NCBevents[idx] = thrd_CreateEvent(NULL, TRUE, FALSE, eventName); if ( GetLastError() == ERROR_ALREADY_EXISTS ) osi_Log1(smb_logp, "Event Object Already Exists: %s", osi_LogSaveString(smb_logp, eventName)); #endif /* !DJGPP */ sprintf(eventName,"NCBReturns[0<=ispacep = cm_GetSpace(); - bufs[idx] = bufp; + for (i=0; ispacep = cm_GetSpace(); + bufs[idx] = bufp; } /* listen for new connections */ void smb_Listener(void *parmp) { - NCB *ncbp; + NCB *ncbp; long code = 0; long len; - long i, j; + long i, j; smb_vc_t *vcp; - int flags = 0; - char rname[NCBNAMSZ+1]; - char cname[MAX_COMPUTERNAME_LENGTH+1]; - int cnamelen = MAX_COMPUTERNAME_LENGTH+1; + int flags = 0; + char rname[NCBNAMSZ+1]; + char cname[MAX_COMPUTERNAME_LENGTH+1]; + int cnamelen = MAX_COMPUTERNAME_LENGTH+1; #ifdef DJGPP dos_ptr dos_ncb; time_t now; #endif /* DJGPP */ - int lana = (int) parmp; + int lana = (int) parmp; - ncbp = GetNCB(); + ncbp = GetNCB(); #ifdef DJGPP dos_ncb = ((smb_ncb_t *)ncbp)->dos_ncb; #endif /* DJGPP */ @@ -6820,40 +7000,23 @@ void smb_Listener(void *parmp) GetComputerName(cname, &cnamelen); _strupr(cname); - while (1) { - memset(ncbp, 0, sizeof(NCB)); - flags = 0; - -#ifndef NOEXPIRE - /* check for demo expiration */ - { - unsigned long tod = time((void *) 0); - if (tod > EXPIREDATE) { - (*smb_MBfunc)(NULL, "AFS demo expiration", - "afsd listener", - MB_OK|MB_ICONSTOP|MB_SETFOREGROUND|MB_SERVICE_NOTIFICATION); -#ifndef DJGPP - ExitThread(1); -#else - thrd_Exit(1); -#endif - } - } -#endif /* !NOEXPIRE */ + while (1) { + memset(ncbp, 0, sizeof(NCB)); + flags = 0; ncbp->ncb_command = NCBLISTEN; ncbp->ncb_rto = 0; /* No receive timeout */ ncbp->ncb_sto = 0; /* No send timeout */ - /* pad out with spaces instead of null termination */ - len = strlen(smb_localNamep); + /* pad out with spaces instead of null termination */ + len = strlen(smb_localNamep); strncpy(ncbp->ncb_name, smb_localNamep, NCBNAMSZ); - for(i=len; incb_name[i] = ' '; + for (i=len; incb_name[i] = ' '; strcpy(ncbp->ncb_callname, "*"); - for(i=1; incb_callname[i] = ' '; + for (i=1; incb_callname[i] = ' '; - ncbp->ncb_lana_num = lana; + ncbp->ncb_lana_num = lana; #ifndef DJGPP code = Netbios(ncbp); @@ -6868,13 +7031,13 @@ void smb_Listener(void *parmp) #endif /* terminate silently if shutdown flag is set */ - if (smbShutdownFlag == 1) { + if (smbShutdownFlag == 1) { #ifndef DJGPP - ExitThread(1); + ExitThread(1); #else - thrd_Exit(1); + thrd_Exit(1); #endif - } + } osi_Log2(smb_logp, "NCBLISTEN lana=%d failed with code %d", @@ -6887,9 +7050,9 @@ void smb_Listener(void *parmp) "Client exiting due to network failure. Please restart client.\n" "NCBLISTEN lana=%d failed with code %d", ncbp->ncb_lana_num, code); - if (showErrors) + if (showErrors) code = (*smb_MBfunc)(NULL, tbuffer, "AFS Client Service: Fatal Error", - MB_OK|MB_SERVICE_NOTIFICATION); + MB_OK|MB_SERVICE_NOTIFICATION); osi_assert(tbuffer); ExitThread(1); #else @@ -6898,79 +7061,79 @@ void smb_Listener(void *parmp) fprintf(stderr, "\nClient exiting due to network failure " "(possibly due to power-saving mode)\n"); fprintf(stderr, "Please restart client.\n"); - afs_exit(AFS_EXITCODE_NETWORK_FAILURE); + afs_exit(AFS_EXITCODE_NETWORK_FAILURE); #endif /* !DJGPP */ } - /* check for remote conns */ - /* first get remote name and insert null terminator */ - memcpy(rname, ncbp->ncb_callname, NCBNAMSZ); - for (i=NCBNAMSZ; i>0; i--) { - if (rname[i-1] != ' ' && rname[i-1] != 0) { - rname[i] = 0; - break; - } - } + /* check for remote conns */ + /* first get remote name and insert null terminator */ + memcpy(rname, ncbp->ncb_callname, NCBNAMSZ); + for (i=NCBNAMSZ; i>0; i--) { + if (rname[i-1] != ' ' && rname[i-1] != 0) { + rname[i] = 0; + break; + } + } /* compare with local name */ - if (!isGateway) - if (strncmp(rname, cname, NCBNAMSZ) != 0) - flags |= SMB_VCFLAG_REMOTECONN; + if (!isGateway) + if (strncmp(rname, cname, NCBNAMSZ) != 0) + flags |= SMB_VCFLAG_REMOTECONN; - osi_Log1(smb_logp, "New session lsn %d", ncbp->ncb_lsn); - /* lock */ - lock_ObtainMutex(&smb_ListenerLock); + osi_Log1(smb_logp, "New session lsn %d", ncbp->ncb_lsn); + /* lock */ + lock_ObtainMutex(&smb_ListenerLock); - /* New generation */ - sessionGen++; + /* New generation */ + sessionGen++; - /* Log session startup */ + /* Log session startup */ #ifdef NOTSERVICE fprintf(stderr, "New session(ncb_lsn,ncb_lana_num) %d,%d starting from host " - "%s\n", - ncbp->ncb_lsn,ncbp->ncb_lana_num, rname); -#endif + "%s\n", + ncbp->ncb_lsn,ncbp->ncb_lana_num, rname); +#endif /* NOTSERVICE */ osi_Log4(smb_logp, "New session(ncb_lsn,ncb_lana_num) (%d,%d) starting from host %s, %d ongoing ops", ncbp->ncb_lsn,ncbp->ncb_lana_num, osi_LogSaveString(smb_logp, rname), ongoingOps); if (reportSessionStartups) { #ifndef DJGPP - HANDLE h; - char *ptbuf[1]; - char s[100]; - - h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME); - sprintf(s, "SMB session startup, %d ongoing ops", ongoingOps); - ptbuf[0] = s; - ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, 1004, NULL, - 1, 0, ptbuf, NULL); - DeregisterEventSource(h); + HANDLE h; + char *ptbuf[1]; + char s[100]; + + h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME); + sprintf(s, "SMB session startup, %d ongoing ops", ongoingOps); + ptbuf[0] = s; + ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, 1004, NULL, + 1, 0, ptbuf, NULL); + DeregisterEventSource(h); #else /* DJGPP */ time(&now); fprintf(stderr, "%s: New session %d starting from host %s\n", asctime(localtime(&now)), ncbp->ncb_lsn, rname); fflush(stderr); #endif /* !DJGPP */ - } - osi_Log1(smb_logp, "NCBLISTEN completed, call from %s", osi_LogSaveString(smb_logp, rname)); - osi_Log1(smb_logp, "SMB session startup, %d ongoing ops", - ongoingOps); + } + osi_Log1(smb_logp, "NCBLISTEN completed, call from %s", osi_LogSaveString(smb_logp, rname)); + osi_Log1(smb_logp, "SMB session startup, %d ongoing ops", + ongoingOps); /* now ncbp->ncb_lsn is the connection ID */ vcp = smb_FindVC(ncbp->ncb_lsn, SMB_FLAG_CREATE, ncbp->ncb_lana_num); - vcp->flags |= flags; + vcp->flags |= flags; strcpy(vcp->rname, rname); - /* Allocate slot in session arrays */ - /* Re-use dead session if possible, otherwise add one more */ + /* Allocate slot in session arrays */ + /* Re-use dead session if possible, otherwise add one more */ /* But don't look at session[0], it is reserved */ - for (i = 1; i < numSessions; i++) { - if (dead_sessions[i]) { + for (i = 1; i < numSessions; i++) { + if (dead_sessions[i]) { osi_Log1(smb_logp, "connecting to dead session [ %d ]", i); - dead_sessions[i] = FALSE; - break; - } - } + dead_sessions[i] = FALSE; + break; + } + } /* assert that we do not exceed the maximum number of sessions or NCBs. * we should probably want to wait for a session to be freed in case @@ -6980,34 +7143,34 @@ void smb_Listener(void *parmp) osi_assert(i < Sessionmax - 1); osi_assert(numNCBs < NCBmax - 1); /* if we pass this test we can allocate one more */ - LSNs[i] = ncbp->ncb_lsn; - lanas[i] = ncbp->ncb_lana_num; + LSNs[i] = ncbp->ncb_lsn; + lanas[i] = ncbp->ncb_lana_num; - if (i == numSessions) { - /* Add new NCB for new session */ + if (i == numSessions) { + /* Add new NCB for new session */ char eventName[MAX_PATH]; osi_Log1(smb_logp, "smb_Listener creating new session %d", i); - InitNCBslot(numNCBs); - numNCBs++; - thrd_SetEvent(NCBavails[0]); - thrd_SetEvent(NCBevents[0]); - for (j = 0; j < smb_NumServerThreads; j++) - thrd_SetEvent(NCBreturns[j][0]); - /* Also add new session event */ + InitNCBslot(numNCBs); + numNCBs++; + thrd_SetEvent(NCBavails[0]); + thrd_SetEvent(NCBevents[0]); + for (j = 0; j < smb_NumServerThreads; j++) + thrd_SetEvent(NCBreturns[j][0]); + /* Also add new session event */ sprintf(eventName, "SessionEvents[%d]", i); SessionEvents[i] = thrd_CreateEvent(NULL, FALSE, TRUE, eventName); if ( GetLastError() == ERROR_ALREADY_EXISTS ) osi_Log1(smb_logp, "Event Object Already Exists: %s", osi_LogSaveString(smb_logp, eventName)); - numSessions++; + numSessions++; osi_Log2(smb_logp, "increasing numNCBs [ %d ] numSessions [ %d ]", numNCBs, numSessions); - thrd_SetEvent(SessionEvents[0]); - } else { - thrd_SetEvent(SessionEvents[i]); - } - /* unlock */ - lock_ReleaseMutex(&smb_ListenerLock); + thrd_SetEvent(SessionEvents[0]); + } else { + thrd_SetEvent(SessionEvents[i]); + } + /* unlock */ + lock_ReleaseMutex(&smb_ListenerLock); } /* dispatch while loop */ } @@ -7149,7 +7312,8 @@ void smb_NetbiosInit() #else code = Netbios(ncbp, dos_ncb); #endif /* DJGPP */ - if (code == 0) code = ncbp->ncb_retcode; + if (code == 0) + code = ncbp->ncb_retcode; else { sprintf(s, "Netbios NCBDELNAME lana %d error code %d\n", lana, code); osi_Log0(smb_logp, s); @@ -7198,11 +7362,11 @@ void smb_Init(osi_log_t *logp, char *snamep, int useV3, int LANadapt, ) { - thread_t phandle; + thread_t phandle; int lpid; int i; int len; - struct tm myTime; + struct tm myTime; #ifdef DJGPP int npar, seg, sel; dos_ptr rawBuf; @@ -7211,74 +7375,57 @@ void smb_Init(osi_log_t *logp, char *snamep, int useV3, int LANadapt, char eventName[MAX_PATH]; #ifndef DJGPP - smb_MBfunc = aMBfunc; + smb_MBfunc = aMBfunc; #endif /* DJGPP */ -#ifndef NOEXPIRE - /* check for demo expiration */ - { - unsigned long tod = time((void *) 0); - if (tod > EXPIREDATE) { -#ifndef DJGPP - (*smb_MBfunc)(NULL, "AFS demo expiration", "afsd", - MB_OK|MB_ICONSTOP|MB_SETFOREGROUND|MB_SERVICE_NOTIFICATION); - exit(1); -#else /* DJGPP */ - fprintf(stderr, "AFS demo expiration\n"); - afs_exit(0); -#endif /* !DJGPP */ - } - } -#endif /* !NOEXPIRE */ - - smb_useV3 = useV3; - smb_LANadapter = LANadapt; - - /* Initialize smb_localZero */ - myTime.tm_isdst = -1; /* compute whether on DST or not */ - myTime.tm_year = 70; - myTime.tm_mon = 0; - myTime.tm_mday = 1; - myTime.tm_hour = 0; - myTime.tm_min = 0; - myTime.tm_sec = 0; - smb_localZero = mktime(&myTime); - - /* Initialize kludge-GMT */ - smb_CalculateNowTZ(); + smb_useV3 = useV3; + smb_LANadapter = LANadapt; + + /* Initialize smb_localZero */ + myTime.tm_isdst = -1; /* compute whether on DST or not */ + myTime.tm_year = 70; + myTime.tm_mon = 0; + myTime.tm_mday = 1; + myTime.tm_hour = 0; + myTime.tm_min = 0; + myTime.tm_sec = 0; + smb_localZero = mktime(&myTime); + + /* Initialize kludge-GMT */ + smb_CalculateNowTZ(); #ifdef AFS_FREELANCE_CLIENT /* Make sure the root.afs volume has the correct time */ cm_noteLocalMountPointChange(); #endif - /* initialize the remote debugging log */ - smb_logp = logp; + /* initialize the remote debugging log */ + smb_logp = logp; /* remember the name */ - len = strlen(snamep); + len = strlen(snamep); smb_localNamep = malloc(len+1); strcpy(smb_localNamep, snamep); afsi_log("smb_localNamep is >%s<", smb_localNamep); - /* and the global lock */ + /* and the global lock */ lock_InitializeRWLock(&smb_globalLock, "smb global lock"); lock_InitializeRWLock(&smb_rctLock, "smb refct and tree struct lock"); - /* Raw I/O data structures */ - lock_InitializeMutex(&smb_RawBufLock, "smb raw buffer lock"); + /* Raw I/O data structures */ + lock_InitializeMutex(&smb_RawBufLock, "smb raw buffer lock"); - lock_InitializeMutex(&smb_ListenerLock, "smb listener lock"); + lock_InitializeMutex(&smb_ListenerLock, "smb listener lock"); - /* 4 Raw I/O buffers */ + /* 4 Raw I/O buffers */ #ifndef DJGPP - smb_RawBufs = calloc(65536,1); - *((char **)smb_RawBufs) = NULL; - for (i=0; i<3; i++) { - char *rawBuf = calloc(65536,1); - *((char **)rawBuf) = smb_RawBufs; - smb_RawBufs = rawBuf; - } + smb_RawBufs = calloc(65536,1); + *((char **)smb_RawBufs) = NULL; + for (i=0; i<3; i++) { + char *rawBuf = calloc(65536,1); + *((char **)rawBuf) = smb_RawBufs; + smb_RawBufs = rawBuf; + } #else /* DJGPP */ npar = 65536 >> 4; /* number of paragraphs */ seg = __dpmi_allocate_dos_memory(npar, &smb_RawBufSel[0]); @@ -7313,128 +7460,140 @@ void smb_Init(osi_log_t *logp, char *snamep, int useV3, int LANadapt, } #endif /* !DJGPP */ - /* global free lists */ - smb_ncbFreeListp = NULL; + /* global free lists */ + smb_ncbFreeListp = NULL; smb_packetFreeListp = NULL; smb_NetbiosInit(); - /* Initialize listener and server structures */ + /* Initialize listener and server structures */ numVCs = 0; - memset(dead_sessions, 0, sizeof(dead_sessions)); + memset(dead_sessions, 0, sizeof(dead_sessions)); sprintf(eventName, "SessionEvents[0]"); - SessionEvents[0] = thrd_CreateEvent(NULL, FALSE, FALSE, eventName); + SessionEvents[0] = thrd_CreateEvent(NULL, FALSE, FALSE, eventName); if ( GetLastError() == ERROR_ALREADY_EXISTS ) afsi_log("Event Object Already Exists: %s", eventName); - numSessions = 1; - smb_NumServerThreads = nThreads; + numSessions = 1; + smb_NumServerThreads = nThreads; sprintf(eventName, "NCBavails[0]"); - NCBavails[0] = thrd_CreateEvent(NULL, FALSE, FALSE, eventName); + NCBavails[0] = thrd_CreateEvent(NULL, FALSE, FALSE, eventName); if ( GetLastError() == ERROR_ALREADY_EXISTS ) afsi_log("Event Object Already Exists: %s", eventName); sprintf(eventName, "NCBevents[0]"); - NCBevents[0] = thrd_CreateEvent(NULL, FALSE, FALSE, eventName); + NCBevents[0] = thrd_CreateEvent(NULL, FALSE, FALSE, eventName); if ( GetLastError() == ERROR_ALREADY_EXISTS ) afsi_log("Event Object Already Exists: %s", eventName); - NCBreturns = malloc(nThreads * sizeof(EVENT_HANDLE *)); + NCBreturns = malloc(nThreads * sizeof(EVENT_HANDLE *)); sprintf(eventName, "NCBreturns[0<=incb_command = NCBDELNAME; - ncbp->ncb_lana_num = lana_list.lana[i]; - memcpy(ncbp->ncb_name,smb_sharename,NCBNAMSZ); + for (i = 0; i < lana_list.length; i++) { + if (lana_list.lana[i] == 255) continue; + ncbp->ncb_command = NCBDELNAME; + ncbp->ncb_lana_num = lana_list.lana[i]; + memcpy(ncbp->ncb_name,smb_sharename,NCBNAMSZ); #ifndef DJGPP code = Netbios(ncbp); #else - code = Netbios(ncbp, dos_ncb); + code = Netbios(ncbp, dos_ncb); #endif - if (code == 0) code = ncbp->ncb_retcode; - if (code != 0) { - fprintf(stderr, "Netbios NCBDELNAME lana %d error code %d", - ncbp->ncb_lana_num, code); - } - fflush(stderr); - } + if (code == 0) + code = ncbp->ncb_retcode; + if (code != 0) { + fprintf(stderr, "Netbios NCBDELNAME lana %d error code %d", + ncbp->ncb_lana_num, code); + } + fflush(stderr); + } } /* Get the UNC \\\ prefix. */ @@ -7633,9 +7793,9 @@ char *smb_GetSharename() { char *name; - /* Make sure we have been properly initialized. */ - if (smb_localNamep == NULL) - return NULL; + /* Make sure we have been properly initialized. */ + if (smb_localNamep == NULL) + return NULL; /* Allocate space for \\\, plus the * terminator. @@ -7645,70 +7805,69 @@ char *smb_GetSharename() return name; } -#ifdef NOTSERVICE +#ifdef LOG_PACKET void smb_LogPacket(smb_packet_t *packet) { - BYTE *vp, *cp; - unsigned length, paramlen, datalen, i, j; - char buf[81]; - char hex[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; + BYTE *vp, *cp; + unsigned length, paramlen, datalen, i, j; + char buf[81]; + char hex[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; - if(!packet) return; + if (!packet) return; - osi_Log0(smb_logp, "*** SMB packet dump ***"); + osi_Log0(smb_logp, "*** SMB packet dump ***"); - vp = (BYTE *) packet->data; + vp = (BYTE *) packet->data; - datalen = *((WORD*)(vp + (paramlen = ((unsigned)*(vp+20)) << 1))); - length = paramlen + 2 + datalen; + datalen = *((WORD*)(vp + (paramlen = ((unsigned)*(vp+20)) << 1))); + length = paramlen + 2 + datalen; - for(i=0;i < length; i+=16) - { - memset( buf, ' ', 80 ); - buf[80] = 0; - - itoa( i, buf, 16 ); + for (i=0;i < length; i+=16) + { + memset( buf, ' ', 80 ); + buf[80] = 0; - buf[strlen(buf)] = ' '; + itoa( i, buf, 16 ); - cp = (BYTE*) buf + 7; + buf[strlen(buf)] = ' '; - for(j=0;j < 16 && (i+j)> 4]; - *(cp++) = hex[vp[i+j] & 0xf]; - *(cp++) = ' '; + cp = (BYTE*) buf + 7; - if(j==7) - { - *(cp++) = '-'; - *(cp++) = ' '; - } - } + for (j=0;j < 16 && (i+j)> 4]; + *(cp++) = hex[vp[i+j] & 0xf]; + *(cp++) = ' '; - for(j=0;j < 16 && (i+j) vp[i+j] )? vp[i+j]:'.'; - if(j==7) - { - *(cp++) = ' '; - *(cp++) = '-'; - *(cp++) = ' '; - } - } + if (j==7) + { + *(cp++) = '-'; + *(cp++) = ' '; + } + } - *cp = 0; + for (j=0;j < 16 && (i+j) vp[i+j] )? vp[i+j]:'.'; + if (j==7) + { + *(cp++) = ' '; + *(cp++) = '-'; + *(cp++) = ' '; + } + } - osi_Log0( smb_logp, buf ); - } + *cp = 0; - osi_Log0(smb_logp, "*** End SMB packet dump ***"); + osi_Log0( smb_logp, osi_LogSaveString(smb_logp, buf)); + } + osi_Log0(smb_logp, "*** End SMB packet dump ***"); } +#endif /* LOG_PACKET */ -#endif /* NOTSERVICE */ int smb_DumpVCP(FILE *outputFile, char *cookie) { diff --git a/src/WINNT/afsd/smb.h b/src/WINNT/afsd/smb.h index 4f9bd33fd..9271bcb4c 100644 --- a/src/WINNT/afsd/smb.h +++ b/src/WINNT/afsd/smb.h @@ -141,7 +141,7 @@ typedef struct myncb { /* one per virtual circuit */ typedef struct smb_vc { struct smb_vc *nextp; /* not used */ - int refCount; /* the reference count */ + unsigned long refCount; /* the reference count */ long flags; /* the flags, if any; locked by mx */ osi_mutex_t mx; /* the mutex */ long vcID; /* VC id */ @@ -177,7 +177,7 @@ typedef struct smb_vc { /* one per user session */ typedef struct smb_user { struct smb_user *nextp; /* next sibling */ - long refCount; /* ref count */ + unsigned long refCount; /* ref count */ long flags; /* flags; locked by mx */ osi_mutex_t mx; long userID; /* the session identifier */ @@ -187,7 +187,7 @@ typedef struct smb_user { typedef struct smb_username { struct smb_username *nextp; /* next sibling */ - long refCount; /* ref count */ + unsigned long refCount; /* ref count */ long flags; /* flags; locked by mx */ osi_mutex_t mx; struct cm_user *userp; /* CM user structure */ @@ -202,7 +202,7 @@ typedef struct smb_username { /* one per tree-connect */ typedef struct smb_tid { struct smb_tid *nextp; /* next sibling */ - long refCount; + unsigned long refCount; long flags; osi_mutex_t mx; /* for non-tree-related stuff */ unsigned short tid; /* the tid */ @@ -218,7 +218,7 @@ typedef struct smb_tid { /* one per process ID */ typedef struct smb_pid { struct smb_pid *nextp; /* next sibling */ - long refCount; + unsigned long refCount; long flags; osi_mutex_t mx; /* for non-tree-related stuff */ unsigned short pid; /* the pid */ @@ -260,8 +260,8 @@ typedef struct smb_ioctl { /* one per file ID; these are really file descriptors */ typedef struct smb_fid { osi_queue_t q; - long refCount; - long flags; + unsigned long refCount; + unsigned long flags; osi_mutex_t mx; /* for non-tree-related stuff */ unsigned short fid; /* the file ID */ struct smb_vc *vcp; /* back ptr */ @@ -313,7 +313,7 @@ typedef struct smb_fid { typedef struct smb_dirSearch { osi_queue_t q; /* queue of all outstanding cookies */ osi_mutex_t mx; /* just in case the caller screws up */ - int refCount; /* reference count */ + unsigned long refCount; /* reference count */ long cookie; /* value returned to the caller */ struct cm_scache *scp; /* vnode of the dir we're searching */ time_t lastTime; /* last time we used this */ @@ -561,6 +561,10 @@ extern long smb_ReadData(smb_fid_t *fidp, osi_hyper_t *offsetp, long count, char *op, cm_user_t *userp, long *readp, int dosflag); #endif /* !DJGPP */ +extern long smb_Rename(smb_vc_t *vcp, smb_packet_t *inp, char *oldPathp, char *newPathp, int attrs); + +extern long smb_Link(smb_vc_t *vcp, smb_packet_t *inp, char *oldPathp, char *newPathp); + extern BOOL smb_IsLegalFilename(char *filename); extern char *smb_GetSharename(void); diff --git a/src/WINNT/afsd/smb3.c b/src/WINNT/afsd/smb3.c index 5b43ef969..9c8691f64 100644 --- a/src/WINNT/afsd/smb3.c +++ b/src/WINNT/afsd/smb3.c @@ -44,18 +44,18 @@ smb_tran2Packet_t *smb_tran2AssemblyQueuep; * request */ cm_user_t *smb_GetTran2User(smb_vc_t *vcp, smb_tran2Packet_t *inp) { - smb_user_t *uidp; + smb_user_t *uidp; cm_user_t *up = NULL; uidp = smb_FindUID(vcp, inp->uid, 0); if (!uidp) return NULL; - lock_ObtainMutex(&uidp->mx); + lock_ObtainMutex(&uidp->mx); if (uidp->unp) { up = uidp->unp->userp; cm_HoldUser(up); } - lock_ReleaseMutex(&uidp->mx); + lock_ReleaseMutex(&uidp->mx); smb_ReleaseUID(uidp); @@ -69,44 +69,44 @@ cm_user_t *smb_GetTran2User(smb_vc_t *vcp, smb_tran2Packet_t *inp) */ unsigned long smb_ExtAttributes(cm_scache_t *scp) { - unsigned long attrs; - - if (scp->fileType == CM_SCACHETYPE_DIRECTORY - || scp->fileType == CM_SCACHETYPE_MOUNTPOINT) - attrs = SMB_ATTR_DIRECTORY; - else - attrs = 0; - /* - * We used to mark a file RO if it was in an RO volume, but that - * turns out to be impolitic in NT. See defect 10007. - */ + unsigned long attrs; + + if (scp->fileType == CM_SCACHETYPE_DIRECTORY || + scp->fileType == CM_SCACHETYPE_MOUNTPOINT) + attrs = SMB_ATTR_DIRECTORY; + else + attrs = 0; + /* + * We used to mark a file RO if it was in an RO volume, but that + * turns out to be impolitic in NT. See defect 10007. + */ #ifdef notdef - if ((scp->unixModeBits & 0222) == 0 || (scp->flags & CM_SCACHEFLAG_RO)) + if ((scp->unixModeBits & 0222) == 0 || (scp->flags & CM_SCACHEFLAG_RO)) #endif if ((scp->unixModeBits & 0222) == 0) - attrs |= SMB_ATTR_READONLY; /* Read-only */ + attrs |= SMB_ATTR_READONLY; /* Read-only */ - if (attrs == 0) - attrs = SMB_ATTR_NORMAL; /* FILE_ATTRIBUTE_NORMAL */ + if (attrs == 0) + attrs = SMB_ATTR_NORMAL; /* FILE_ATTRIBUTE_NORMAL */ - return attrs; + return attrs; } int smb_V3IsStarMask(char *maskp) { char tc; - while (tc = *maskp++) + while (tc = *maskp++) if (tc == '?' || tc == '*') return 1; - return 0; + return 0; } unsigned char *smb_ParseString(unsigned char *inp, char **chainpp) { if (chainpp) { - /* skip over null-terminated string */ - *chainpp = inp + strlen(inp) + 1; + /* skip over null-terminated string */ + *chainpp = inp + strlen(inp) + 1; } return inp; } @@ -135,7 +135,7 @@ void OutputDebugHexDump(unsigned char * buffer, int len) { OutputDebugF("Hexdump length [%d]",len); - for(i=0;iflags & SMB_VCFLAG_AUTH_IN_PROGRESS) { - secCtx = vcp->secCtx; - lock_ObtainMutex(&vcp->mx); - vcp->flags &= ~SMB_VCFLAG_AUTH_IN_PROGRESS; - vcp->secCtx = NULL; - lock_ReleaseMutex(&vcp->mx); - } + CredHandle creds; + TimeStamp expiry; + long code = 0; + SecBufferDesc secBufIn; + SecBuffer secTokIn; + SecBufferDesc secBufOut; + SecBuffer secTokOut; + CtxtHandle ctx; + struct smb_ext_context * secCtx = NULL; + struct smb_ext_context * newSecCtx = NULL; + void * assembledBlob = NULL; + int assembledBlobLength = 0; + ULONG flags; + + OutputDebugF("In smb_AuthenticateUserExt"); + + *secBlobOut = NULL; + *secBlobOutLength = 0; + + if (vcp->flags & SMB_VCFLAG_AUTH_IN_PROGRESS) { + secCtx = vcp->secCtx; + lock_ObtainMutex(&vcp->mx); + vcp->flags &= ~SMB_VCFLAG_AUTH_IN_PROGRESS; + vcp->secCtx = NULL; + lock_ReleaseMutex(&vcp->mx); + } if (secBlobIn) { OutputDebugF("Received incoming token:"); @@ -296,130 +294,128 @@ long smb_AuthenticateUserExt(smb_vc_t * vcp, char * usern, char * secBlobIn, int creds = secCtx->creds; ctx = secCtx->ctx; - if (secCtx->partialToken) { - assembledBlobLength = secCtx->partialTokenLen + secBlobInLength; - assembledBlob = malloc(assembledBlobLength); + if (secCtx->partialToken) { + assembledBlobLength = secCtx->partialTokenLen + secBlobInLength; + assembledBlob = malloc(assembledBlobLength); memcpy(assembledBlob,secCtx->partialToken, secCtx->partialTokenLen); - memcpy(((BYTE *)assembledBlob) + secCtx->partialTokenLen, secBlobIn, secBlobInLength); - } - } else { - status = AcquireCredentialsHandle( - NULL, - SMB_EXT_SEC_PACKAGE_NAME, - SECPKG_CRED_INBOUND, - NULL, - NULL, - NULL, - NULL, - &creds, - &expiry); - - if (status != SEC_E_OK) { - OutputDebugF("Can't acquire Credentials handle [%lX]", status); - code = CM_ERROR_BADPASSWORD; /* means "try again when I'm sober" */ - goto aue_0; - } - - ctx.dwLower = 0; - ctx.dwUpper = 0; - } + memcpy(((BYTE *)assembledBlob) + secCtx->partialTokenLen, secBlobIn, secBlobInLength); + } + } else { + status = AcquireCredentialsHandle( NULL, + SMB_EXT_SEC_PACKAGE_NAME, + SECPKG_CRED_INBOUND, + NULL, + NULL, + NULL, + NULL, + &creds, + &expiry); + + if (status != SEC_E_OK) { + OutputDebugF("Can't acquire Credentials handle [%lX]", status); + code = CM_ERROR_BADPASSWORD; /* means "try again when I'm sober" */ + goto aue_0; + } + + ctx.dwLower = 0; + ctx.dwUpper = 0; + } secBufIn.cBuffers = 1; - secBufIn.pBuffers = &secTokIn; - secBufIn.ulVersion = SECBUFFER_VERSION; - - secTokIn.BufferType = SECBUFFER_TOKEN; - if (assembledBlob) { - secTokIn.cbBuffer = assembledBlobLength; - secTokIn.pvBuffer = assembledBlob; - } else { - secTokIn.cbBuffer = secBlobInLength; - secTokIn.pvBuffer = secBlobIn; - } + secBufIn.pBuffers = &secTokIn; + secBufIn.ulVersion = SECBUFFER_VERSION; + + secTokIn.BufferType = SECBUFFER_TOKEN; + if (assembledBlob) { + secTokIn.cbBuffer = assembledBlobLength; + secTokIn.pvBuffer = assembledBlob; + } else { + secTokIn.cbBuffer = secBlobInLength; + secTokIn.pvBuffer = secBlobIn; + } - secBufOut.cBuffers = 1; - secBufOut.pBuffers = &secTokOut; - secBufOut.ulVersion = SECBUFFER_VERSION; - - secTokOut.BufferType = SECBUFFER_TOKEN; - secTokOut.cbBuffer = 0; - secTokOut.pvBuffer = NULL; - - status = AcceptSecurityContext( - &creds, - ((secCtx)?&ctx:NULL), - &secBufIn, - ASC_REQ_CONNECTION | ASC_REQ_EXTENDED_ERROR | ASC_REQ_ALLOCATE_MEMORY, - SECURITY_NETWORK_DREP, - &ctx, - &secBufOut, - &flags, - &expiry - ); - - if (status == SEC_I_COMPLETE_NEEDED || status == SEC_I_COMPLETE_AND_CONTINUE) { - OutputDebugF("Completing token..."); - istatus = CompleteAuthToken(&ctx, &secBufOut); + secBufOut.cBuffers = 1; + secBufOut.pBuffers = &secTokOut; + secBufOut.ulVersion = SECBUFFER_VERSION; + + secTokOut.BufferType = SECBUFFER_TOKEN; + secTokOut.cbBuffer = 0; + secTokOut.pvBuffer = NULL; + + status = AcceptSecurityContext( &creds, + ((secCtx)?&ctx:NULL), + &secBufIn, + ASC_REQ_CONNECTION | ASC_REQ_EXTENDED_ERROR | ASC_REQ_ALLOCATE_MEMORY, + SECURITY_NETWORK_DREP, + &ctx, + &secBufOut, + &flags, + &expiry + ); + + if (status == SEC_I_COMPLETE_NEEDED || status == SEC_I_COMPLETE_AND_CONTINUE) { + OutputDebugF("Completing token..."); + istatus = CompleteAuthToken(&ctx, &secBufOut); if ( istatus != SEC_E_OK ) OutputDebugF("Token completion failed: %lX", istatus); - } + } - if (status == SEC_I_COMPLETE_AND_CONTINUE || status == SEC_I_CONTINUE_NEEDED) { - OutputDebugF("Continue needed"); + if (status == SEC_I_COMPLETE_AND_CONTINUE || status == SEC_I_CONTINUE_NEEDED) { + OutputDebugF("Continue needed"); - newSecCtx = malloc(sizeof(*newSecCtx)); + newSecCtx = malloc(sizeof(*newSecCtx)); - newSecCtx->creds = creds; - newSecCtx->ctx = ctx; - newSecCtx->partialToken = NULL; - newSecCtx->partialTokenLen = 0; + newSecCtx->creds = creds; + newSecCtx->ctx = ctx; + newSecCtx->partialToken = NULL; + newSecCtx->partialTokenLen = 0; - lock_ObtainMutex( &vcp->mx ); - vcp->flags |= SMB_VCFLAG_AUTH_IN_PROGRESS; - vcp->secCtx = newSecCtx; - lock_ReleaseMutex( &vcp->mx ); + lock_ObtainMutex( &vcp->mx ); + vcp->flags |= SMB_VCFLAG_AUTH_IN_PROGRESS; + vcp->secCtx = newSecCtx; + lock_ReleaseMutex( &vcp->mx ); - code = CM_ERROR_GSSCONTINUE; - } + code = CM_ERROR_GSSCONTINUE; + } - if ((status == SEC_I_COMPLETE_NEEDED || status == SEC_E_OK || - status == SEC_I_COMPLETE_AND_CONTINUE || status == SEC_I_CONTINUE_NEEDED) && - secTokOut.pvBuffer) { - OutputDebugF("Need to send token back to client"); + if ((status == SEC_I_COMPLETE_NEEDED || status == SEC_E_OK || + status == SEC_I_COMPLETE_AND_CONTINUE || status == SEC_I_CONTINUE_NEEDED) && + secTokOut.pvBuffer) { + OutputDebugF("Need to send token back to client"); - *secBlobOutLength = secTokOut.cbBuffer; - *secBlobOut = malloc(secTokOut.cbBuffer); - memcpy(*secBlobOut, secTokOut.pvBuffer, secTokOut.cbBuffer); + *secBlobOutLength = secTokOut.cbBuffer; + *secBlobOut = malloc(secTokOut.cbBuffer); + memcpy(*secBlobOut, secTokOut.pvBuffer, secTokOut.cbBuffer); OutputDebugF("Outgoing token:"); OutputDebugHexDump(*secBlobOut,*secBlobOutLength); - } else if (status == SEC_E_INCOMPLETE_MESSAGE) { - OutputDebugF("Incomplete message"); + } else if (status == SEC_E_INCOMPLETE_MESSAGE) { + OutputDebugF("Incomplete message"); - newSecCtx = malloc(sizeof(*newSecCtx)); + newSecCtx = malloc(sizeof(*newSecCtx)); - newSecCtx->creds = creds; - newSecCtx->ctx = ctx; - newSecCtx->partialToken = malloc(secTokOut.cbBuffer); - memcpy(newSecCtx->partialToken, secTokOut.pvBuffer, secTokOut.cbBuffer); - newSecCtx->partialTokenLen = secTokOut.cbBuffer; + newSecCtx->creds = creds; + newSecCtx->ctx = ctx; + newSecCtx->partialToken = malloc(secTokOut.cbBuffer); + memcpy(newSecCtx->partialToken, secTokOut.pvBuffer, secTokOut.cbBuffer); + newSecCtx->partialTokenLen = secTokOut.cbBuffer; - lock_ObtainMutex( &vcp->mx ); - vcp->flags |= SMB_VCFLAG_AUTH_IN_PROGRESS; - vcp->secCtx = newSecCtx; - lock_ReleaseMutex( &vcp->mx ); + lock_ObtainMutex( &vcp->mx ); + vcp->flags |= SMB_VCFLAG_AUTH_IN_PROGRESS; + vcp->secCtx = newSecCtx; + lock_ReleaseMutex( &vcp->mx ); - code = CM_ERROR_GSSCONTINUE; - } + code = CM_ERROR_GSSCONTINUE; + } - if (status == SEC_E_OK || status == SEC_I_COMPLETE_NEEDED) { - /* woo hoo! */ - SecPkgContext_Names names; + if (status == SEC_E_OK || status == SEC_I_COMPLETE_NEEDED) { + /* woo hoo! */ + SecPkgContext_Names names; - OutputDebugF("Authentication completed"); + OutputDebugF("Authentication completed"); OutputDebugF("Returned flags : [%lX]", flags); - if (!QueryContextAttributes(&ctx, SECPKG_ATTR_NAMES, &names)) { + if (!QueryContextAttributes(&ctx, SECPKG_ATTR_NAMES, &names)) { OutputDebugF("Received name [%s]", names.sUserName); strcpy(usern, names.sUserName); strlwr(usern); /* in tandem with smb_GetNormalizedUsername */ @@ -429,7 +425,7 @@ long smb_AuthenticateUserExt(smb_vc_t * vcp, char * usern, char * secBlobIn, int OutputDebugF("QueryContextAttributes Names failed [%x]", GetLastError()); code = CM_ERROR_BADPASSWORD; } - } else if (!code) { + } else if (!code) { switch ( status ) { case SEC_E_INVALID_TOKEN: OutputDebugF("Returning bad password :: INVALID_TOKEN"); @@ -461,28 +457,28 @@ long smb_AuthenticateUserExt(smb_vc_t * vcp, char * usern, char * secBlobIn, int default: OutputDebugF("Returning bad password :: Status == %lX", status); } - code = CM_ERROR_BADPASSWORD; - } + code = CM_ERROR_BADPASSWORD; + } - if (secCtx) { - if (secCtx->partialToken) free(secCtx->partialToken); - free(secCtx); - } + if (secCtx) { + if (secCtx->partialToken) free(secCtx->partialToken); + free(secCtx); + } - if (assembledBlob) { - free(assembledBlob); - } + if (assembledBlob) { + free(assembledBlob); + } - if (secTokOut.pvBuffer) - FreeContextBuffer(secTokOut.pvBuffer); + if (secTokOut.pvBuffer) + FreeContextBuffer(secTokOut.pvBuffer); - if (code != CM_ERROR_GSSCONTINUE) { - DeleteSecurityContext(&ctx); - FreeCredentialsHandle(&creds); - } + if (code != CM_ERROR_GSSCONTINUE) { + DeleteSecurityContext(&ctx); + FreeCredentialsHandle(&creds); + } aue_0: - return code; + return code; } #define P_LEN 256 @@ -491,153 +487,152 @@ long smb_AuthenticateUserExt(smb_vc_t * vcp, char * usern, char * secBlobIn, int /* LsaLogonUser expects input parameters to be in a contiguous block of memory. So put stuff in a struct. */ struct Lm20AuthBlob { - MSV1_0_LM20_LOGON lmlogon; - BYTE ciResponse[P_RESP_LEN]; /* Unicode representation */ - BYTE csResponse[P_RESP_LEN]; /* ANSI representation */ - WCHAR accountNameW[P_LEN]; - WCHAR primaryDomainW[P_LEN]; - WCHAR workstationW[MAX_COMPUTERNAME_LENGTH + 1]; - TOKEN_GROUPS tgroups; - TOKEN_SOURCE tsource; + MSV1_0_LM20_LOGON lmlogon; + BYTE ciResponse[P_RESP_LEN]; /* Unicode representation */ + BYTE csResponse[P_RESP_LEN]; /* ANSI representation */ + WCHAR accountNameW[P_LEN]; + WCHAR primaryDomainW[P_LEN]; + WCHAR workstationW[MAX_COMPUTERNAME_LENGTH + 1]; + TOKEN_GROUPS tgroups; + TOKEN_SOURCE tsource; }; -long smb_AuthenticateUserLM(smb_vc_t *vcp, char * accountName, char * primaryDomain, char * ciPwd, unsigned ciPwdLength, char * csPwd, unsigned csPwdLength) { - - NTSTATUS nts, ntsEx; - struct Lm20AuthBlob lmAuth; - PMSV1_0_LM20_LOGON_PROFILE lmprofilep; - QUOTA_LIMITS quotaLimits; - DWORD size; - ULONG lmprofilepSize; - LUID lmSession; - HANDLE lmToken; - - OutputDebugF("In smb_AuthenticateUser for user [%s] domain [%s]", accountName, primaryDomain); - OutputDebugF("ciPwdLength is %d and csPwdLength is %d", ciPwdLength, csPwdLength); - - if (ciPwdLength > P_RESP_LEN || csPwdLength > P_RESP_LEN) { - OutputDebugF("ciPwdLength or csPwdLength is too long"); - return CM_ERROR_BADPASSWORD; - } +long smb_AuthenticateUserLM(smb_vc_t *vcp, char * accountName, char * primaryDomain, char * ciPwd, unsigned ciPwdLength, char * csPwd, unsigned csPwdLength) +{ + NTSTATUS nts, ntsEx; + struct Lm20AuthBlob lmAuth; + PMSV1_0_LM20_LOGON_PROFILE lmprofilep; + QUOTA_LIMITS quotaLimits; + DWORD size; + ULONG lmprofilepSize; + LUID lmSession; + HANDLE lmToken; + + OutputDebugF("In smb_AuthenticateUser for user [%s] domain [%s]", accountName, primaryDomain); + OutputDebugF("ciPwdLength is %d and csPwdLength is %d", ciPwdLength, csPwdLength); + + if (ciPwdLength > P_RESP_LEN || csPwdLength > P_RESP_LEN) { + OutputDebugF("ciPwdLength or csPwdLength is too long"); + return CM_ERROR_BADPASSWORD; + } - memset(&lmAuth,0,sizeof(lmAuth)); + memset(&lmAuth,0,sizeof(lmAuth)); - lmAuth.lmlogon.MessageType = MsV1_0NetworkLogon; + lmAuth.lmlogon.MessageType = MsV1_0NetworkLogon; - lmAuth.lmlogon.LogonDomainName.Buffer = lmAuth.primaryDomainW; - mbstowcs(lmAuth.primaryDomainW, primaryDomain, P_LEN); - lmAuth.lmlogon.LogonDomainName.Length = wcslen(lmAuth.primaryDomainW) * sizeof(WCHAR); - lmAuth.lmlogon.LogonDomainName.MaximumLength = P_LEN * sizeof(WCHAR); - - lmAuth.lmlogon.UserName.Buffer = lmAuth.accountNameW; - mbstowcs(lmAuth.accountNameW, accountName, P_LEN); - lmAuth.lmlogon.UserName.Length = wcslen(lmAuth.accountNameW) * sizeof(WCHAR); - lmAuth.lmlogon.UserName.MaximumLength = P_LEN * sizeof(WCHAR); - - lmAuth.lmlogon.Workstation.Buffer = lmAuth.workstationW; - lmAuth.lmlogon.Workstation.MaximumLength = (MAX_COMPUTERNAME_LENGTH + 1) * sizeof(WCHAR); - size = MAX_COMPUTERNAME_LENGTH + 1; - GetComputerNameW(lmAuth.workstationW, &size); + lmAuth.lmlogon.LogonDomainName.Buffer = lmAuth.primaryDomainW; + mbstowcs(lmAuth.primaryDomainW, primaryDomain, P_LEN); + lmAuth.lmlogon.LogonDomainName.Length = wcslen(lmAuth.primaryDomainW) * sizeof(WCHAR); + lmAuth.lmlogon.LogonDomainName.MaximumLength = P_LEN * sizeof(WCHAR); + + lmAuth.lmlogon.UserName.Buffer = lmAuth.accountNameW; + mbstowcs(lmAuth.accountNameW, accountName, P_LEN); + lmAuth.lmlogon.UserName.Length = wcslen(lmAuth.accountNameW) * sizeof(WCHAR); + lmAuth.lmlogon.UserName.MaximumLength = P_LEN * sizeof(WCHAR); + + lmAuth.lmlogon.Workstation.Buffer = lmAuth.workstationW; + lmAuth.lmlogon.Workstation.MaximumLength = (MAX_COMPUTERNAME_LENGTH + 1) * sizeof(WCHAR); + size = MAX_COMPUTERNAME_LENGTH + 1; + GetComputerNameW(lmAuth.workstationW, &size); lmAuth.lmlogon.Workstation.Length = wcslen(lmAuth.workstationW) * sizeof(WCHAR); - memcpy(lmAuth.lmlogon.ChallengeToClient, vcp->encKey, MSV1_0_CHALLENGE_LENGTH); - - lmAuth.lmlogon.CaseInsensitiveChallengeResponse.Buffer = lmAuth.ciResponse; - lmAuth.lmlogon.CaseInsensitiveChallengeResponse.Length = ciPwdLength; - lmAuth.lmlogon.CaseInsensitiveChallengeResponse.MaximumLength = P_RESP_LEN; - memcpy(lmAuth.ciResponse, ciPwd, ciPwdLength); - - lmAuth.lmlogon.CaseSensitiveChallengeResponse.Buffer = lmAuth.csResponse; - lmAuth.lmlogon.CaseSensitiveChallengeResponse.Length = csPwdLength; - lmAuth.lmlogon.CaseSensitiveChallengeResponse.MaximumLength = P_RESP_LEN; - memcpy(lmAuth.csResponse, csPwd, csPwdLength); - - lmAuth.lmlogon.ParameterControl = 0; - - lmAuth.tgroups.GroupCount = 0; - lmAuth.tgroups.Groups[0].Sid = NULL; - lmAuth.tgroups.Groups[0].Attributes = 0; - - lmAuth.tsource.SourceIdentifier.HighPart = 0; - lmAuth.tsource.SourceIdentifier.LowPart = (DWORD) vcp; - strcpy(lmAuth.tsource.SourceName,"OpenAFS"); /* 8 char limit */ - - nts = LsaLogonUser( - smb_lsaHandle, - &smb_lsaLogonOrigin, - Network, /*3*/ - smb_lsaSecPackage, - &lmAuth, - sizeof(lmAuth), - &lmAuth.tgroups, - &lmAuth.tsource, - &lmprofilep, - &lmprofilepSize, - &lmSession, - &lmToken, - "aLimits, - &ntsEx); - - OutputDebugF("Return from LsaLogonUser is 0x%lX", nts); - OutputDebugF("Extended status is 0x%lX", ntsEx); - - if (nts == ERROR_SUCCESS) { - /* free the token */ - LsaFreeReturnBuffer(lmprofilep); + memcpy(lmAuth.lmlogon.ChallengeToClient, vcp->encKey, MSV1_0_CHALLENGE_LENGTH); + + lmAuth.lmlogon.CaseInsensitiveChallengeResponse.Buffer = lmAuth.ciResponse; + lmAuth.lmlogon.CaseInsensitiveChallengeResponse.Length = ciPwdLength; + lmAuth.lmlogon.CaseInsensitiveChallengeResponse.MaximumLength = P_RESP_LEN; + memcpy(lmAuth.ciResponse, ciPwd, ciPwdLength); + + lmAuth.lmlogon.CaseSensitiveChallengeResponse.Buffer = lmAuth.csResponse; + lmAuth.lmlogon.CaseSensitiveChallengeResponse.Length = csPwdLength; + lmAuth.lmlogon.CaseSensitiveChallengeResponse.MaximumLength = P_RESP_LEN; + memcpy(lmAuth.csResponse, csPwd, csPwdLength); + + lmAuth.lmlogon.ParameterControl = 0; + + lmAuth.tgroups.GroupCount = 0; + lmAuth.tgroups.Groups[0].Sid = NULL; + lmAuth.tgroups.Groups[0].Attributes = 0; + + lmAuth.tsource.SourceIdentifier.HighPart = 0; + lmAuth.tsource.SourceIdentifier.LowPart = (DWORD) vcp; + strcpy(lmAuth.tsource.SourceName,"OpenAFS"); /* 8 char limit */ + + nts = LsaLogonUser( smb_lsaHandle, + &smb_lsaLogonOrigin, + Network, /*3*/ + smb_lsaSecPackage, + &lmAuth, + sizeof(lmAuth), + &lmAuth.tgroups, + &lmAuth.tsource, + &lmprofilep, + &lmprofilepSize, + &lmSession, + &lmToken, + "aLimits, + &ntsEx); + + OutputDebugF("Return from LsaLogonUser is 0x%lX", nts); + OutputDebugF("Extended status is 0x%lX", ntsEx); + + if (nts == ERROR_SUCCESS) { + /* free the token */ + LsaFreeReturnBuffer(lmprofilep); CloseHandle(lmToken); - return 0; - } else { - /* No AFS for you */ - if (nts == 0xC000015BL) - return CM_ERROR_BADLOGONTYPE; - else /* our catchall is a bad password though we could be more specific */ - return CM_ERROR_BADPASSWORD; - } + return 0; + } else { + /* No AFS for you */ + if (nts == 0xC000015BL) + return CM_ERROR_BADLOGONTYPE; + else /* our catchall is a bad password though we could be more specific */ + return CM_ERROR_BADPASSWORD; + } } /* The buffer pointed to by usern is assumed to be at least SMB_MAX_USERNAME_LENGTH bytes */ -long smb_GetNormalizedUsername(char * usern, const char * accountName, const char * domainName) { - - char * atsign; - const char * domain; - - /* check if we have sane input */ - if ((strlen(accountName) + strlen(domainName) + 1) > SMB_MAX_USERNAME_LENGTH) - return 1; - - /* we could get : [accountName][domainName] - [user][domain] - [user@domain][] - [user][]/[user][?] - [][]/[][?] */ - - atsign = strchr(accountName, '@'); - - if (atsign) /* [user@domain][] -> [user@domain][domain] */ - domain = atsign + 1; - else - domain = domainName; - - /* if for some reason the client doesn't know what domain to use, - it will either return an empty string or a '?' */ - if (!domain[0] || domain[0] == '?') - /* Empty domains and empty usernames are usually sent from tokenless contexts. - This way such logins will get an empty username (easy to check). I don't know - when a non-empty username would be supplied with an anonymous domain, but *shrug* */ - strcpy(usern,accountName); - else { - /* TODO: what about WIN.MIT.EDU\user vs. WIN\user? */ - strcpy(usern,domain); - strcat(usern,"\\"); - if (atsign) - strncat(usern,accountName,atsign - accountName); - else - strcat(usern,accountName); - } +long smb_GetNormalizedUsername(char * usern, const char * accountName, const char * domainName) +{ + char * atsign; + const char * domain; + + /* check if we have sane input */ + if ((strlen(accountName) + strlen(domainName) + 1) > SMB_MAX_USERNAME_LENGTH) + return 1; + + /* we could get : [accountName][domainName] + [user][domain] + [user@domain][] + [user][]/[user][?] + [][]/[][?] */ + + atsign = strchr(accountName, '@'); + + if (atsign) /* [user@domain][] -> [user@domain][domain] */ + domain = atsign + 1; + else + domain = domainName; + + /* if for some reason the client doesn't know what domain to use, + it will either return an empty string or a '?' */ + if (!domain[0] || domain[0] == '?') + /* Empty domains and empty usernames are usually sent from tokenless contexts. + This way such logins will get an empty username (easy to check). I don't know + when a non-empty username would be supplied with an anonymous domain, but *shrug* */ + strcpy(usern,accountName); + else { + /* TODO: what about WIN.MIT.EDU\user vs. WIN\user? */ + strcpy(usern,domain); + strcat(usern,"\\"); + if (atsign) + strncat(usern,accountName,atsign - accountName); + else + strcat(usern,accountName); + } - strlwr(usern); + strlwr(usern); - return 0; + return 0; } /* When using SMB auth, all SMB sessions have to pass through here first to @@ -739,52 +734,52 @@ long smb_ReceiveV3SessionSetupX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t * } else { /* V3 */ unsigned ciPwdLength; char *ciPwd; - char *accountName; - char *primaryDomain; + char *accountName; + char *primaryDomain; - ciPwdLength = smb_GetSMBParm(inp, 7); + ciPwdLength = smb_GetSMBParm(inp, 7); tp = smb_GetSMBData(inp, NULL); - ciPwd = tp; - tp += ciPwdLength; + ciPwd = tp; + tp += ciPwdLength; - accountName = smb_ParseString(tp, &tp); - primaryDomain = smb_ParseString(tp, NULL); + accountName = smb_ParseString(tp, &tp); + primaryDomain = smb_ParseString(tp, NULL); - if ( smb_GetNormalizedUsername(usern, accountName, primaryDomain)) { - /* shouldn't happen */ - code = CM_ERROR_BADSMB; + if ( smb_GetNormalizedUsername(usern, accountName, primaryDomain)) { + /* shouldn't happen */ + code = CM_ERROR_BADSMB; goto after_read_packet; - } + } /* even if we wanted extended auth, if we only negotiated V3, we have to fallback * to NTLM. */ - if (smb_authType == SMB_AUTH_NTLM || smb_authType == SMB_AUTH_EXTENDED) { - code = smb_AuthenticateUserLM(vcp,accountName,primaryDomain,ciPwd,ciPwdLength,"",0); - } - } + if (smb_authType == SMB_AUTH_NTLM || smb_authType == SMB_AUTH_EXTENDED) { + code = smb_AuthenticateUserLM(vcp,accountName,primaryDomain,ciPwd,ciPwdLength,"",0); + } + } after_read_packet: - /* note down that we received a session setup X and set the capabilities flag */ - if (!(vcp->flags & SMB_VCFLAG_SESSX_RCVD)) { - lock_ObtainMutex(&vcp->mx); - vcp->flags |= SMB_VCFLAG_SESSX_RCVD; + /* note down that we received a session setup X and set the capabilities flag */ + if (!(vcp->flags & SMB_VCFLAG_SESSX_RCVD)) { + lock_ObtainMutex(&vcp->mx); + vcp->flags |= SMB_VCFLAG_SESSX_RCVD; /* for the moment we can only deal with NTSTATUS */ if (caps & NTNEGOTIATE_CAPABILITY_NTSTATUS) { vcp->flags |= SMB_VCFLAG_STATUS32; - } - lock_ReleaseMutex(&vcp->mx); - } + } + lock_ReleaseMutex(&vcp->mx); + } - /* code would be non-zero if there was an authentication failure. - Ideally we would like to invalidate the uid for this session or break - early to avoid accidently stealing someone else's tokens. */ + /* code would be non-zero if there was an authentication failure. + Ideally we would like to invalidate the uid for this session or break + early to avoid accidently stealing someone else's tokens. */ - if (code) { - return code; - } + if (code) { + return code; + } - OutputDebugF("Received username=[%s]", usern); + OutputDebugF("Received username=[%s]", usern); /* On Windows 2000, this function appears to be called more often than it is expected to be called. This resulted in multiple smb_user_t @@ -800,8 +795,8 @@ long smb_ReceiveV3SessionSetupX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t * unp = uidp->unp; userp = unp->userp; newUid = (unsigned short)uidp->userID; /* For some reason these are different types!*/ - osi_LogEvent("AFS smb_ReceiveV3SessionSetupX",NULL,"FindUserByName:Lana[%d],lsn[%d],userid[%d],name[%s]",vcp->lana,vcp->lsn,newUid,osi_LogSaveString(smb_logp, usern)); - osi_Log3(smb_logp,"smb_ReceiveV3SessionSetupX FindUserByName:Lana[%d],lsn[%d],userid[%d]",vcp->lana,vcp->lsn,newUid); + osi_LogEvent("AFS smb_ReceiveV3SessionSetupX",NULL,"FindUserByName:Lana[%d],lsn[%d],userid[%d],name[%s]",vcp->lana,vcp->lsn,newUid,osi_LogSaveString(smb_logp, usern)); + osi_Log3(smb_logp,"smb_ReceiveV3SessionSetupX FindUserByName:Lana[%d],lsn[%d],userid[%d]",vcp->lana,vcp->lsn,newUid); smb_ReleaseUID(uidp); } else { @@ -826,8 +821,8 @@ long smb_ReceiveV3SessionSetupX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t * uidp = smb_FindUID(vcp, newUid, SMB_FLAG_CREATE); lock_ObtainMutex(&uidp->mx); uidp->unp = unp; - osi_LogEvent("AFS smb_ReceiveV3SessionSetupX",NULL,"MakeNewUser:VCP[%x],Lana[%d],lsn[%d],userid[%d],TicketKTCName[%s]",(int)vcp,vcp->lana,vcp->lsn,newUid,osi_LogSaveString(smb_logp, usern)); - osi_Log4(smb_logp,"smb_ReceiveV3SessionSetupX MakeNewUser:VCP[%x],Lana[%d],lsn[%d],userid[%d]",vcp,vcp->lana,vcp->lsn,newUid); + osi_LogEvent("AFS smb_ReceiveV3SessionSetupX",NULL,"MakeNewUser:VCP[%x],Lana[%d],lsn[%d],userid[%d],TicketKTCName[%s]",(int)vcp,vcp->lana,vcp->lsn,newUid,osi_LogSaveString(smb_logp, usern)); + osi_Log4(smb_logp,"smb_ReceiveV3SessionSetupX MakeNewUser:VCP[%x],Lana[%d],lsn[%d],userid[%d]",vcp,vcp->lana,vcp->lsn,newUid); lock_ReleaseMutex(&uidp->mx); smb_ReleaseUID(uidp); } @@ -881,35 +876,35 @@ long smb_ReceiveV3SessionSetupX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t * long smb_ReceiveV3UserLogoffX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - smb_user_t *uidp; + smb_user_t *uidp; - /* don't get tokens from this VC */ - vcp->flags |= SMB_VCFLAG_ALREADYDEAD; + /* don't get tokens from this VC */ + vcp->flags |= SMB_VCFLAG_ALREADYDEAD; - inp->flags |= SMB_PACKETFLAG_PROFILE_UPDATE_OK; + inp->flags |= SMB_PACKETFLAG_PROFILE_UPDATE_OK; - /* find the tree and free it */ + /* find the tree and free it */ uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0); /* TODO: smb_ReleaseUID() ? */ if (uidp) { - char *s1 = NULL, *s2 = NULL; + char *s1 = NULL, *s2 = NULL; - if (s2 == NULL) s2 = " "; - if (s1 == NULL) {s1 = s2; s2 = " ";} + if (s2 == NULL) s2 = " "; + if (s1 == NULL) {s1 = s2; s2 = " ";} - osi_Log4(smb_logp, "SMB3 user logoffX uid %d name %s%s%s", uidp->userID, - osi_LogSaveString(smb_logp, (uidp->unp) ? uidp->unp->name: " "), s1, s2); + osi_Log4(smb_logp, "SMB3 user logoffX uid %d name %s%s%s", uidp->userID, + osi_LogSaveString(smb_logp, (uidp->unp) ? uidp->unp->name: " "), s1, s2); - lock_ObtainMutex(&uidp->mx); - uidp->flags |= SMB_USERFLAG_DELETE; - /* - * it doesn't get deleted right away - * because the vcp points to it - */ + lock_ObtainMutex(&uidp->mx); + uidp->flags |= SMB_USERFLAG_DELETE; + /* + * it doesn't get deleted right away + * because the vcp points to it + */ lock_ReleaseMutex(&uidp->mx); } - else - osi_Log0(smb_logp, "SMB3 user logoffX"); + else + osi_Log0(smb_logp, "SMB3 user logoffX"); smb_SetSMBDataLength(outp, 0); return 0; @@ -923,89 +918,89 @@ long smb_ReceiveV3TreeConnectX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *o smb_user_t *uidp; unsigned short newTid; char shareName[256]; - char *sharePath; - int shareFound; + char *sharePath; + int shareFound; char *tp; char *pathp; char *passwordp; - char *servicep; + char *servicep; cm_user_t *userp; - int ipc = 0; + int ipc = 0; - osi_Log0(smb_logp, "SMB3 receive tree connect"); + osi_Log0(smb_logp, "SMB3 receive tree connect"); - /* parse input parameters */ - tp = smb_GetSMBData(inp, NULL); + /* parse input parameters */ + tp = smb_GetSMBData(inp, NULL); passwordp = smb_ParseString(tp, &tp); - pathp = smb_ParseString(tp, &tp); - servicep = smb_ParseString(tp, &tp); + pathp = smb_ParseString(tp, &tp); + servicep = smb_ParseString(tp, &tp); - tp = strrchr(pathp, '\\'); + tp = strrchr(pathp, '\\'); if (!tp) { return CM_ERROR_BADSMB; } strcpy(shareName, tp+1); osi_Log2(smb_logp, "Tree connect pathp[%s] shareName[%s]", - osi_LogSaveString(smb_logp, pathp), - osi_LogSaveString(smb_logp, shareName)); + osi_LogSaveString(smb_logp, pathp), + osi_LogSaveString(smb_logp, shareName)); - if (strcmp(servicep, "IPC") == 0 || strcmp(shareName, "IPC$") == 0) { + if (strcmp(servicep, "IPC") == 0 || strcmp(shareName, "IPC$") == 0) { #ifndef NO_IPC - osi_Log0(smb_logp, "TreeConnectX connecting to IPC$"); - ipc = 1; + osi_Log0(smb_logp, "TreeConnectX connecting to IPC$"); + ipc = 1; #else - return CM_ERROR_NOIPC; + return CM_ERROR_NOIPC; #endif - } + } userp = smb_GetUser(vcp, inp); - lock_ObtainMutex(&vcp->mx); + lock_ObtainMutex(&vcp->mx); newTid = vcp->tidCounter++; - lock_ReleaseMutex(&vcp->mx); + lock_ReleaseMutex(&vcp->mx); - tidp = smb_FindTID(vcp, newTid, SMB_FLAG_CREATE); + tidp = smb_FindTID(vcp, newTid, SMB_FLAG_CREATE); - if(!ipc) { - uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0); + if(!ipc) { + uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0); shareFound = smb_FindShare(vcp, uidp, shareName, &sharePath); - if (uidp) - smb_ReleaseUID(uidp); + if (uidp) + smb_ReleaseUID(uidp); if (!shareFound) { - smb_ReleaseTID(tidp); - return CM_ERROR_BADSHARENAME; + smb_ReleaseTID(tidp); + return CM_ERROR_BADSHARENAME; } if (vcp->flags & SMB_VCFLAG_USENT) - { - int policy = smb_FindShareCSCPolicy(shareName); - smb_SetSMBParm(outp, 2, SMB_SUPPORT_SEARCH_BITS | (policy << 2)); + { + int policy = smb_FindShareCSCPolicy(shareName); + smb_SetSMBParm(outp, 2, SMB_SUPPORT_SEARCH_BITS | (policy << 2)); + } + } else { + smb_SetSMBParm(outp, 2, 0); + sharePath = NULL; } - } else { - smb_SetSMBParm(outp, 2, 0); - sharePath = NULL; - } lock_ObtainMutex(&tidp->mx); tidp->userp = userp; - tidp->pathname = sharePath; - if(ipc) tidp->flags |= SMB_TIDFLAG_IPC; + tidp->pathname = sharePath; + if(ipc) tidp->flags |= SMB_TIDFLAG_IPC; lock_ReleaseMutex(&tidp->mx); smb_ReleaseTID(tidp); - ((smb_t *)outp)->tid = newTid; - ((smb_t *)inp)->tid = newTid; - tp = smb_GetSMBData(outp, NULL); - if(!ipc) { - *tp++ = 'A'; - *tp++ = ':'; - *tp++ = 0; - smb_SetSMBDataLength(outp, 3); - } else { - strcpy(tp, "IPC"); - smb_SetSMBDataLength(outp, 4); - } + ((smb_t *)outp)->tid = newTid; + ((smb_t *)inp)->tid = newTid; + tp = smb_GetSMBData(outp, NULL); + if (!ipc) { + *tp++ = 'A'; + *tp++ = ':'; + *tp++ = 0; + smb_SetSMBDataLength(outp, 3); + } else { + strcpy(tp, "IPC"); + smb_SetSMBDataLength(outp, 4); + } osi_Log1(smb_logp, "SMB3 tree connect created ID %d", newTid); return 0; @@ -1014,12 +1009,12 @@ long smb_ReceiveV3TreeConnectX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *o /* must be called with global tran lock held */ smb_tran2Packet_t *smb_FindTran2Packet(smb_vc_t *vcp, smb_packet_t *inp) { - smb_tran2Packet_t *tp; + smb_tran2Packet_t *tp; smb_t *smbp; smbp = (smb_t *) inp->data; - for(tp = smb_tran2AssemblyQueuep; tp; tp = (smb_tran2Packet_t *) osi_QNext(&tp->q)) { - if (tp->vcp == vcp && tp->mid == smbp->mid && tp->tid == smbp->tid) + for (tp = smb_tran2AssemblyQueuep; tp; tp = (smb_tran2Packet_t *) osi_QNext(&tp->q)) { + if (tp->vcp == vcp && tp->mid == smbp->mid && tp->tid == smbp->tid) return tp; } return NULL; @@ -1028,11 +1023,11 @@ smb_tran2Packet_t *smb_FindTran2Packet(smb_vc_t *vcp, smb_packet_t *inp) smb_tran2Packet_t *smb_NewTran2Packet(smb_vc_t *vcp, smb_packet_t *inp, int totalParms, int totalData) { - smb_tran2Packet_t *tp; + smb_tran2Packet_t *tp; smb_t *smbp; smbp = (smb_t *) inp->data; - tp = malloc(sizeof(*tp)); + tp = malloc(sizeof(*tp)); memset(tp, 0, sizeof(*tp)); tp->vcp = vcp; smb_HoldVC(vcp); @@ -1043,74 +1038,74 @@ smb_tran2Packet_t *smb_NewTran2Packet(smb_vc_t *vcp, smb_packet_t *inp, tp->mid = smbp->mid; tp->uid = smbp->uid; tp->pid = smbp->pid; - tp->res[0] = smbp->res[0]; - osi_QAdd((osi_queue_t **)&smb_tran2AssemblyQueuep, &tp->q); - if (totalParms != 0) + tp->res[0] = smbp->res[0]; + osi_QAdd((osi_queue_t **)&smb_tran2AssemblyQueuep, &tp->q); + if (totalParms != 0) tp->parmsp = malloc(totalParms); - if (totalData != 0) + if (totalData != 0) tp->datap = malloc(totalData); - if (smbp->com == 0x25 || smbp->com == 0x26) - tp->com = 0x25; - else { - tp->opcode = smb_GetSMBParm(inp, 14); - tp->com = 0x32; - } - tp->flags |= SMB_TRAN2PFLAG_ALLOC; + if (smbp->com == 0x25 || smbp->com == 0x26) + tp->com = 0x25; + else { + tp->opcode = smb_GetSMBParm(inp, 14); + tp->com = 0x32; + } + tp->flags |= SMB_TRAN2PFLAG_ALLOC; return tp; } smb_tran2Packet_t *smb_GetTran2ResponsePacket(smb_vc_t *vcp, - smb_tran2Packet_t *inp, smb_packet_t *outp, - int totalParms, int totalData) + smb_tran2Packet_t *inp, smb_packet_t *outp, + int totalParms, int totalData) { - smb_tran2Packet_t *tp; - unsigned short parmOffset; - unsigned short dataOffset; - unsigned short dataAlign; + smb_tran2Packet_t *tp; + unsigned short parmOffset; + unsigned short dataOffset; + unsigned short dataAlign; - tp = malloc(sizeof(*tp)); + tp = malloc(sizeof(*tp)); memset(tp, 0, sizeof(*tp)); tp->vcp = NULL; tp->curData = tp->curParms = 0; tp->totalData = totalData; tp->totalParms = totalParms; - tp->oldTotalParms = totalParms; + tp->oldTotalParms = totalParms; tp->tid = inp->tid; tp->mid = inp->mid; tp->uid = inp->uid; tp->pid = inp->pid; - tp->res[0] = inp->res[0]; + tp->res[0] = inp->res[0]; tp->opcode = inp->opcode; - tp->com = inp->com; + tp->com = inp->com; - /* - * We calculate where the parameters and data will start. - * This calculation must parallel the calculation in - * smb_SendTran2Packet. - */ + /* + * We calculate where the parameters and data will start. + * This calculation must parallel the calculation in + * smb_SendTran2Packet. + */ - parmOffset = 10*2 + 35; - parmOffset++; /* round to even */ - tp->parmsp = (unsigned short *) (outp->data + parmOffset); + parmOffset = 10*2 + 35; + parmOffset++; /* round to even */ + tp->parmsp = (unsigned short *) (outp->data + parmOffset); - dataOffset = parmOffset + totalParms; - dataAlign = dataOffset & 2; /* quad-align */ - dataOffset += dataAlign; - tp->datap = outp->data + dataOffset; + dataOffset = parmOffset + totalParms; + dataAlign = dataOffset & 2; /* quad-align */ + dataOffset += dataAlign; + tp->datap = outp->data + dataOffset; return tp; -} +} /* free a tran2 packet; must be called with smb_globalLock held */ void smb_FreeTran2Packet(smb_tran2Packet_t *t2p) { if (t2p->vcp) smb_ReleaseVC(t2p->vcp); - if (t2p->flags & SMB_TRAN2PFLAG_ALLOC) { - if (t2p->parmsp) - free(t2p->parmsp); - if (t2p->datap) - free(t2p->datap); - } + if (t2p->flags & SMB_TRAN2PFLAG_ALLOC) { + if (t2p->parmsp) + free(t2p->parmsp); + if (t2p->datap) + free(t2p->datap); + } free(t2p); } @@ -1123,19 +1118,19 @@ void smb_SendTran2Error(smb_vc_t *vcp, smb_tran2Packet_t *t2p, smb_t *smbp; unsigned short errCode; unsigned char errClass; - unsigned long NTStatus; + unsigned long NTStatus; if (vcp->flags & SMB_VCFLAG_STATUS32) - smb_MapNTError(code, &NTStatus); - else - smb_MapCoreError(code, vcp, &errCode, &errClass); + smb_MapNTError(code, &NTStatus); + else + smb_MapCoreError(code, vcp, &errCode, &errClass); smb_FormatResponsePacket(vcp, NULL, tp); smbp = (smb_t *) tp; - /* We can handle long names */ - if (vcp->flags & SMB_VCFLAG_USENT) - smbp->flg2 |= 0x40; /* IS_LONG_NAME */ + /* We can handle long names */ + if (vcp->flags & SMB_VCFLAG_USENT) + smbp->flg2 |= 0x40; /* IS_LONG_NAME */ /* now copy important fields from the tran 2 packet */ smbp->com = t2p->com; @@ -1143,19 +1138,19 @@ void smb_SendTran2Error(smb_vc_t *vcp, smb_tran2Packet_t *t2p, smbp->mid = t2p->mid; smbp->pid = t2p->pid; smbp->uid = t2p->uid; - smbp->res[0] = t2p->res[0]; - if (vcp->flags & SMB_VCFLAG_STATUS32) { - smbp->rcls = (unsigned char) (NTStatus & 0xff); - smbp->reh = (unsigned char) ((NTStatus >> 8) & 0xff); - smbp->errLow = (unsigned char) ((NTStatus >> 16) & 0xff); - smbp->errHigh = (unsigned char) ((NTStatus >> 24) & 0xff); - smbp->flg2 |= 0x4000; - } - else { + smbp->res[0] = t2p->res[0]; + if (vcp->flags & SMB_VCFLAG_STATUS32) { + smbp->rcls = (unsigned char) (NTStatus & 0xff); + smbp->reh = (unsigned char) ((NTStatus >> 8) & 0xff); + smbp->errLow = (unsigned char) ((NTStatus >> 16) & 0xff); + smbp->errHigh = (unsigned char) ((NTStatus >> 24) & 0xff); + smbp->flg2 |= 0x4000; + } + else { smbp->rcls = errClass; - smbp->errLow = (unsigned char) (errCode & 0xff); - smbp->errHigh = (unsigned char) ((errCode >> 8) & 0xff); - } + smbp->errLow = (unsigned char) (errCode & 0xff); + smbp->errHigh = (unsigned char) ((errCode >> 8) & 0xff); + } /* send packet */ smb_SendPacket(vcp, tp); @@ -1165,17 +1160,17 @@ void smb_SendTran2Packet(smb_vc_t *vcp, smb_tran2Packet_t *t2p, smb_packet_t *tp { smb_t *smbp; unsigned short parmOffset; - unsigned short dataOffset; - unsigned short totalLength; - unsigned short dataAlign; + unsigned short dataOffset; + unsigned short totalLength; + unsigned short dataAlign; char *datap; - + smb_FormatResponsePacket(vcp, NULL, tp); smbp = (smb_t *) tp; - /* We can handle long names */ - if (vcp->flags & SMB_VCFLAG_USENT) - smbp->flg2 |= 0x40; /* IS_LONG_NAME */ + /* We can handle long names */ + if (vcp->flags & SMB_VCFLAG_USENT) + smbp->flg2 |= 0x40; /* IS_LONG_NAME */ /* now copy important fields from the tran 2 packet */ smbp->com = t2p->com; @@ -1183,7 +1178,7 @@ void smb_SendTran2Packet(smb_vc_t *vcp, smb_tran2Packet_t *t2p, smb_packet_t *tp smbp->mid = t2p->mid; smbp->pid = t2p->pid; smbp->uid = t2p->uid; - smbp->res[0] = t2p->res[0]; + smbp->res[0] = t2p->res[0]; totalLength = 1 + t2p->totalData + t2p->totalParms; @@ -1192,24 +1187,24 @@ void smb_SendTran2Packet(smb_vc_t *vcp, smb_tran2Packet_t *t2p, smb_packet_t *tp smb_SetSMBParm(tp, 1, t2p->totalData); /* data bytes */ smb_SetSMBParm(tp, 2, 0); /* reserved */ smb_SetSMBParm(tp, 3, t2p->totalParms); /* parm bytes in this packet */ - parmOffset = 10*2 + 35; /* parm offset in packet */ - parmOffset++; /* round to even */ + parmOffset = 10*2 + 35; /* parm offset in packet */ + parmOffset++; /* round to even */ smb_SetSMBParm(tp, 4, parmOffset); /* 11 parm words plus * * hdr, bcc and wct */ smb_SetSMBParm(tp, 5, 0); /* parm displacement */ smb_SetSMBParm(tp, 6, t2p->totalData); /* data in this packet */ - dataOffset = parmOffset + t2p->oldTotalParms; - dataAlign = dataOffset & 2; /* quad-align */ - dataOffset += dataAlign; + dataOffset = parmOffset + t2p->oldTotalParms; + dataAlign = dataOffset & 2; /* quad-align */ + dataOffset += dataAlign; smb_SetSMBParm(tp, 7, dataOffset); /* offset of data */ smb_SetSMBParm(tp, 8, 0); /* data displacement */ smb_SetSMBParm(tp, 9, 0); /* low: setup word count * * high: resvd */ datap = smb_GetSMBData(tp, NULL); - *datap++ = 0; /* we rounded to even */ + *datap++ = 0; /* we rounded to even */ - totalLength += dataAlign; + totalLength += dataAlign; smb_SetSMBDataLength(tp, totalLength); /* next, send the datagram */ @@ -1228,56 +1223,56 @@ long smb_ReceiveV3Trans(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) int parmCount; int dataCount; int firstPacket; - int rapOp; + int rapOp; long code = 0; - /* We sometimes see 0 word count. What to do? */ - if (*inp->wctp == 0) { + /* We sometimes see 0 word count. What to do? */ + if (*inp->wctp == 0) { #ifndef DJGPP - HANDLE h; - char *ptbuf[1]; + HANDLE h; + char *ptbuf[1]; - osi_Log0(smb_logp, "TRANSACTION word count = 0"); + osi_Log0(smb_logp, "TRANSACTION word count = 0"); - h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME); - ptbuf[0] = "Transaction2 word count = 0"; - ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, 1003, NULL, - 1, inp->ncb_length, ptbuf, inp); - DeregisterEventSource(h); + h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME); + ptbuf[0] = "Transaction2 word count = 0"; + ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, 1003, NULL, + 1, inp->ncb_length, ptbuf, inp); + DeregisterEventSource(h); #else /* DJGPP */ - osi_Log0(smb_logp, "TRANSACTION word count = 0"); + osi_Log0(smb_logp, "TRANSACTION word count = 0"); #endif /* !DJGPP */ smb_SetSMBDataLength(outp, 0); smb_SendPacket(vcp, outp); - return 0; - } + return 0; + } totalParms = smb_GetSMBParm(inp, 0); totalData = smb_GetSMBParm(inp, 1); firstPacket = (inp->inCom == 0x25); - /* find the packet we're reassembling */ - lock_ObtainWrite(&smb_globalLock); + /* find the packet we're reassembling */ + lock_ObtainWrite(&smb_globalLock); asp = smb_FindTran2Packet(vcp, inp); if (!asp) { asp = smb_NewTran2Packet(vcp, inp, totalParms, totalData); - } + } lock_ReleaseWrite(&smb_globalLock); /* now merge in this latest packet; start by looking up offsets */ - if (firstPacket) { - parmDisp = dataDisp = 0; + if (firstPacket) { + parmDisp = dataDisp = 0; parmOffset = smb_GetSMBParm(inp, 10); dataOffset = smb_GetSMBParm(inp, 12); parmCount = smb_GetSMBParm(inp, 9); dataCount = smb_GetSMBParm(inp, 11); - asp->maxReturnParms = smb_GetSMBParm(inp, 2); + asp->maxReturnParms = smb_GetSMBParm(inp, 2); asp->maxReturnData = smb_GetSMBParm(inp, 3); - osi_Log3(smb_logp, "SMB3 received Trans init packet total data %d, cur data %d, max return data %d", - totalData, dataCount, asp->maxReturnData); + osi_Log3(smb_logp, "SMB3 received Trans init packet total data %d, cur data %d, max return data %d", + totalData, dataCount, asp->maxReturnData); } else { parmDisp = smb_GetSMBParm(inp, 4); @@ -1309,13 +1304,13 @@ long smb_ReceiveV3Trans(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) asp->curParms > 0 && asp->totalData <= asp->curData && asp->totalParms <= asp->curParms) { - /* we've received it all */ + /* we've received it all */ lock_ObtainWrite(&smb_globalLock); - osi_QRemove((osi_queue_t **) &smb_tran2AssemblyQueuep, &asp->q); + osi_QRemove((osi_queue_t **) &smb_tran2AssemblyQueuep, &asp->q); lock_ReleaseWrite(&smb_globalLock); /* now dispatch it */ - rapOp = asp->parmsp[0]; + rapOp = asp->parmsp[0]; if ( rapOp >= 0 && rapOp < SMB_RAP_NOPCODES && smb_rapDispatchTable[rapOp].procp) { osi_LogEvent("AFS-Dispatch-RAP[%s]",myCrt_RapDispatch(rapOp),"vcp[%x] lana[%d] lsn[%d]",(int)vcp,vcp->lana,vcp->lsn); @@ -1328,7 +1323,7 @@ long smb_ReceiveV3Trans(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) code = CM_ERROR_BADOP; } - /* if an error is returned, we're supposed to send an error packet, + /* if an error is returned, we're supposed to send an error packet, * otherwise the dispatched function already did the data sending. * We give dispatched proc the responsibility since it knows how much * space to allocate. @@ -1337,436 +1332,436 @@ long smb_ReceiveV3Trans(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) smb_SendTran2Error(vcp, asp, outp, code); } - /* free the input tran 2 packet */ - lock_ObtainWrite(&smb_globalLock); + /* free the input tran 2 packet */ + lock_ObtainWrite(&smb_globalLock); smb_FreeTran2Packet(asp); - lock_ReleaseWrite(&smb_globalLock); + lock_ReleaseWrite(&smb_globalLock); } else if (firstPacket) { - /* the first packet in a multi-packet request, we need to send an + /* the first packet in a multi-packet request, we need to send an * ack to get more data. */ smb_SetSMBDataLength(outp, 0); smb_SendPacket(vcp, outp); } - return 0; + return 0; } /* ANSI versions. The unicode versions support arbitrary length share names, but we don't support unicode yet. */ typedef struct smb_rap_share_info_0 { - char shi0_netname[13]; + char shi0_netname[13]; } smb_rap_share_info_0_t; typedef struct smb_rap_share_info_1 { - char shi1_netname[13]; - char shi1_pad; - WORD shi1_type; - DWORD shi1_remark; /* char *shi1_remark; data offset */ + char shi1_netname[13]; + char shi1_pad; + WORD shi1_type; + DWORD shi1_remark; /* char *shi1_remark; data offset */ } smb_rap_share_info_1_t; typedef struct smb_rap_share_info_2 { - char shi2_netname[13]; - char shi2_pad; - unsigned short shi2_type; - DWORD shi2_remark; /* char *shi2_remark; data offset */ - unsigned short shi2_permissions; - unsigned short shi2_max_uses; - unsigned short shi2_current_uses; - DWORD shi2_path; /* char *shi2_path; data offset */ - unsigned short shi2_passwd[9]; - unsigned short shi2_pad2; + char shi2_netname[13]; + char shi2_pad; + unsigned short shi2_type; + DWORD shi2_remark; /* char *shi2_remark; data offset */ + unsigned short shi2_permissions; + unsigned short shi2_max_uses; + unsigned short shi2_current_uses; + DWORD shi2_path; /* char *shi2_path; data offset */ + unsigned short shi2_passwd[9]; + unsigned short shi2_pad2; } smb_rap_share_info_2_t; #define SMB_RAP_MAX_SHARES 512 typedef struct smb_rap_share_list { - int cShare; - int maxShares; - smb_rap_share_info_0_t * shares; + int cShare; + int maxShares; + smb_rap_share_info_0_t * shares; } smb_rap_share_list_t; int smb_rapCollectSharesProc(cm_scache_t *dscp, cm_dirEntry_t *dep, void *vrockp, osi_hyper_t *offp) { - smb_rap_share_list_t * sp; - char * name; + smb_rap_share_list_t * sp; + char * name; - name = dep->name; + name = dep->name; - if(name[0] == '.' && (!name[1] || (name[1] == '.' && !name[2]))) - return 0; /* skip over '.' and '..' */ + if (name[0] == '.' && (!name[1] || (name[1] == '.' && !name[2]))) + return 0; /* skip over '.' and '..' */ - sp = (smb_rap_share_list_t *) vrockp; + sp = (smb_rap_share_list_t *) vrockp; - strncpy(sp->shares[sp->cShare].shi0_netname, name, 12); - sp->shares[sp->cShare].shi0_netname[12] = 0; + strncpy(sp->shares[sp->cShare].shi0_netname, name, 12); + sp->shares[sp->cShare].shi0_netname[12] = 0; - sp->cShare++; + sp->cShare++; - if(sp->cShare >= sp->maxShares) - return CM_ERROR_STOPNOW; - else - return 0; -} + if (sp->cShare >= sp->maxShares) + return CM_ERROR_STOPNOW; + else + return 0; +} long smb_ReceiveRAPNetShareEnum(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) { - smb_tran2Packet_t *outp; - unsigned short * tp; - int len; - int infoLevel; - int bufsize; - int outParmsTotal; /* total parameter bytes */ - int outDataTotal; /* total data bytes */ - int code = 0; - DWORD rv; - DWORD allSubmount; - USHORT nShares; - DWORD nRegShares; - DWORD nSharesRet; - HKEY hkParam; - HKEY hkSubmount = NULL; - smb_rap_share_info_1_t * shares; - USHORT cshare = 0; - char * cstrp; - char thisShare[256]; - int i,j; - int nonrootShares; - smb_rap_share_list_t rootShares; - cm_req_t req; - cm_user_t * userp; - osi_hyper_t thyper; - - tp = p->parmsp + 1; /* skip over function number (always 0) */ - (void) smb_ParseString((char *) tp, (char **) &tp); /* skip over parm descriptor */ - (void) smb_ParseString((char *) tp, (char **) &tp); /* skip over data descriptor */ - infoLevel = tp[0]; + smb_tran2Packet_t *outp; + unsigned short * tp; + int len; + int infoLevel; + int bufsize; + int outParmsTotal; /* total parameter bytes */ + int outDataTotal; /* total data bytes */ + int code = 0; + DWORD rv; + DWORD allSubmount; + USHORT nShares; + DWORD nRegShares; + DWORD nSharesRet; + HKEY hkParam; + HKEY hkSubmount = NULL; + smb_rap_share_info_1_t * shares; + USHORT cshare = 0; + char * cstrp; + char thisShare[256]; + int i,j; + int nonrootShares; + smb_rap_share_list_t rootShares; + cm_req_t req; + cm_user_t * userp; + osi_hyper_t thyper; + + tp = p->parmsp + 1; /* skip over function number (always 0) */ + (void) smb_ParseString((char *) tp, (char **) &tp); /* skip over parm descriptor */ + (void) smb_ParseString((char *) tp, (char **) &tp); /* skip over data descriptor */ + infoLevel = tp[0]; bufsize = tp[1]; - if(infoLevel != 1) { - return CM_ERROR_INVAL; - } + if (infoLevel != 1) { + return CM_ERROR_INVAL; + } - /* first figure out how many shares there are */ + /* first figure out how many shares there are */ rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSConfigKeyName, 0, - KEY_QUERY_VALUE, &hkParam); - if (rv == ERROR_SUCCESS) { + KEY_QUERY_VALUE, &hkParam); + if (rv == ERROR_SUCCESS) { len = sizeof(allSubmount); rv = RegQueryValueEx(hkParam, "AllSubmount", NULL, NULL, - (BYTE *) &allSubmount, &len); - if (rv != ERROR_SUCCESS || allSubmount != 0) { - allSubmount = 1; - } + (BYTE *) &allSubmount, &len); + if (rv != ERROR_SUCCESS || allSubmount != 0) { + allSubmount = 1; + } RegCloseKey (hkParam); - } + } - rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\OpenAFS\\Client\\Submounts", - 0, KEY_QUERY_VALUE, &hkSubmount); - if (rv == ERROR_SUCCESS) { + rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\OpenAFS\\Client\\Submounts", + 0, KEY_QUERY_VALUE, &hkSubmount); + if (rv == ERROR_SUCCESS) { rv = RegQueryInfoKey(hkSubmount, NULL, NULL, NULL, NULL, - NULL, NULL, &nRegShares, NULL, NULL, NULL, NULL); - if (rv != ERROR_SUCCESS) - nRegShares = 0; - } else { - hkSubmount = NULL; - } + NULL, NULL, &nRegShares, NULL, NULL, NULL, NULL); + if (rv != ERROR_SUCCESS) + nRegShares = 0; + } else { + hkSubmount = NULL; + } - /* fetch the root shares */ - rootShares.maxShares = SMB_RAP_MAX_SHARES; - rootShares.cShare = 0; - rootShares.shares = malloc( sizeof(smb_rap_share_info_0_t) * SMB_RAP_MAX_SHARES ); + /* fetch the root shares */ + rootShares.maxShares = SMB_RAP_MAX_SHARES; + rootShares.cShare = 0; + rootShares.shares = malloc( sizeof(smb_rap_share_info_0_t) * SMB_RAP_MAX_SHARES ); - cm_InitReq(&req); + cm_InitReq(&req); - userp = smb_GetTran2User(vcp,p); + userp = smb_GetTran2User(vcp,p); - thyper.HighPart = 0; - thyper.LowPart = 0; + thyper.HighPart = 0; + thyper.LowPart = 0; - cm_HoldSCache(cm_rootSCachep); - cm_ApplyDir(cm_rootSCachep, smb_rapCollectSharesProc, &rootShares, &thyper, userp, &req, NULL); - cm_ReleaseSCache(cm_rootSCachep); + cm_HoldSCache(cm_rootSCachep); + cm_ApplyDir(cm_rootSCachep, smb_rapCollectSharesProc, &rootShares, &thyper, userp, &req, NULL); + cm_ReleaseSCache(cm_rootSCachep); - cm_ReleaseUser(userp); + cm_ReleaseUser(userp); - nShares = rootShares.cShare + nRegShares + allSubmount; + nShares = rootShares.cShare + nRegShares + allSubmount; #define REMARK_LEN 1 - outParmsTotal = 8; /* 4 dwords */ - outDataTotal = (sizeof(smb_rap_share_info_1_t) + REMARK_LEN) * nShares ; - if(outDataTotal > bufsize) { - nSharesRet = bufsize / (sizeof(smb_rap_share_info_1_t) + REMARK_LEN); - outDataTotal = (sizeof(smb_rap_share_info_1_t) + REMARK_LEN) * nSharesRet; - } - else { - nSharesRet = nShares; - } + outParmsTotal = 8; /* 4 dwords */ + outDataTotal = (sizeof(smb_rap_share_info_1_t) + REMARK_LEN) * nShares ; + if(outDataTotal > bufsize) { + nSharesRet = bufsize / (sizeof(smb_rap_share_info_1_t) + REMARK_LEN); + outDataTotal = (sizeof(smb_rap_share_info_1_t) + REMARK_LEN) * nSharesRet; + } + else { + nSharesRet = nShares; + } - outp = smb_GetTran2ResponsePacket(vcp, p, op, outParmsTotal, outDataTotal); + outp = smb_GetTran2ResponsePacket(vcp, p, op, outParmsTotal, outDataTotal); - /* now for the submounts */ + /* now for the submounts */ shares = (smb_rap_share_info_1_t *) outp->datap; - cstrp = outp->datap + sizeof(smb_rap_share_info_1_t) * nSharesRet; + cstrp = outp->datap + sizeof(smb_rap_share_info_1_t) * nSharesRet; - memset(outp->datap, 0, (sizeof(smb_rap_share_info_1_t) + REMARK_LEN) * nSharesRet); + memset(outp->datap, 0, (sizeof(smb_rap_share_info_1_t) + REMARK_LEN) * nSharesRet); - if(allSubmount) { - strcpy( shares[cshare].shi1_netname, "all" ); - shares[cshare].shi1_remark = cstrp - outp->datap; - /* type and pad are zero already */ - cshare++; - cstrp+=REMARK_LEN; - } + if (allSubmount) { + strcpy( shares[cshare].shi1_netname, "all" ); + shares[cshare].shi1_remark = cstrp - outp->datap; + /* type and pad are zero already */ + cshare++; + cstrp+=REMARK_LEN; + } - if(hkSubmount) { - for(i=0; i < nRegShares && cshare < nSharesRet; i++) { - len = sizeof(thisShare); + if (hkSubmount) { + for (i=0; i < nRegShares && cshare < nSharesRet; i++) { + len = sizeof(thisShare); rv = RegEnumValue(hkSubmount, i, thisShare, &len, NULL, NULL, NULL, NULL); - if(rv == ERROR_SUCCESS && strlen(thisShare) && (!allSubmount || stricmp(thisShare,"all"))) { - strncpy(shares[cshare].shi1_netname, thisShare, sizeof(shares->shi1_netname)-1); - shares[cshare].shi1_netname[sizeof(shares->shi1_netname)-1] = 0; /* unfortunate truncation */ - shares[cshare].shi1_remark = cstrp - outp->datap; - cshare++; - cstrp+=REMARK_LEN; - } - else - nShares--; /* uncount key */ - } - - RegCloseKey(hkSubmount); - } + if (rv == ERROR_SUCCESS && strlen(thisShare) && (!allSubmount || stricmp(thisShare,"all"))) { + strncpy(shares[cshare].shi1_netname, thisShare, sizeof(shares->shi1_netname)-1); + shares[cshare].shi1_netname[sizeof(shares->shi1_netname)-1] = 0; /* unfortunate truncation */ + shares[cshare].shi1_remark = cstrp - outp->datap; + cshare++; + cstrp+=REMARK_LEN; + } + else + nShares--; /* uncount key */ + } + + RegCloseKey(hkSubmount); + } - nonrootShares = cshare; + nonrootShares = cshare; - for(i=0; i < rootShares.cShare && cshare < nSharesRet; i++) { + for (i=0; i < rootShares.cShare && cshare < nSharesRet; i++) { /* in case there are collisions with submounts, submounts have higher priority */ - for(j=0; j < nonrootShares; j++) - if(!stricmp(shares[j].shi1_netname, rootShares.shares[i].shi0_netname)) - break; + for (j=0; j < nonrootShares; j++) + if (!stricmp(shares[j].shi1_netname, rootShares.shares[i].shi0_netname)) + break; - if(j < nonrootShares) { - nShares--; /* uncount */ - continue; - } - - strcpy(shares[cshare].shi1_netname, rootShares.shares[i].shi0_netname); - shares[cshare].shi1_remark = cstrp - outp->datap; - cshare++; - cstrp+=REMARK_LEN; - } + if (j < nonrootShares) { + nShares--; /* uncount */ + continue; + } + + strcpy(shares[cshare].shi1_netname, rootShares.shares[i].shi0_netname); + shares[cshare].shi1_remark = cstrp - outp->datap; + cshare++; + cstrp+=REMARK_LEN; + } - outp->parmsp[0] = ((cshare == nShares)? ERROR_SUCCESS : ERROR_MORE_DATA); - outp->parmsp[1] = 0; - outp->parmsp[2] = cshare; - outp->parmsp[3] = nShares; + outp->parmsp[0] = ((cshare == nShares)? ERROR_SUCCESS : ERROR_MORE_DATA); + outp->parmsp[1] = 0; + outp->parmsp[2] = cshare; + outp->parmsp[3] = nShares; - outp->totalData = cstrp - outp->datap; - outp->totalParms = outParmsTotal; + outp->totalData = cstrp - outp->datap; + outp->totalParms = outParmsTotal; - smb_SendTran2Packet(vcp, outp, op); - smb_FreeTran2Packet(outp); + smb_SendTran2Packet(vcp, outp, op); + smb_FreeTran2Packet(outp); - free(rootShares.shares); + free(rootShares.shares); - return code; + return code; } long smb_ReceiveRAPNetShareGetInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) { - smb_tran2Packet_t *outp; - unsigned short * tp; - char * shareName; - BOOL shareFound = FALSE; - unsigned short infoLevel; - unsigned short bufsize; - int totalData; - int totalParam; - DWORD len; - HKEY hkParam; - HKEY hkSubmount; - DWORD allSubmount; - LONG rv; - long code = 0; - - tp = p->parmsp + 1; /* skip over function number (always 1) */ - (void) smb_ParseString( (char *) tp, (char **) &tp); /* skip over param descriptor */ - (void) smb_ParseString( (char *) tp, (char **) &tp); /* skip over data descriptor */ - shareName = smb_ParseString( (char *) tp, (char **) &tp); + smb_tran2Packet_t *outp; + unsigned short * tp; + char * shareName; + BOOL shareFound = FALSE; + unsigned short infoLevel; + unsigned short bufsize; + int totalData; + int totalParam; + DWORD len; + HKEY hkParam; + HKEY hkSubmount; + DWORD allSubmount; + LONG rv; + long code = 0; + + tp = p->parmsp + 1; /* skip over function number (always 1) */ + (void) smb_ParseString( (char *) tp, (char **) &tp); /* skip over param descriptor */ + (void) smb_ParseString( (char *) tp, (char **) &tp); /* skip over data descriptor */ + shareName = smb_ParseString( (char *) tp, (char **) &tp); infoLevel = *tp++; bufsize = *tp++; - totalParam = 6; - - if(infoLevel == 0) - totalData = sizeof(smb_rap_share_info_0_t); - else if(infoLevel == 1) - totalData = sizeof(smb_rap_share_info_1_t) + 1; /* + empty string */ - else if(infoLevel == 2) - totalData = sizeof(smb_rap_share_info_2_t) + 2; /* + two empty strings */ - else - return CM_ERROR_INVAL; - - outp = smb_GetTran2ResponsePacket(vcp, p, op, totalParam, totalData); - - if(!stricmp(shareName,"all")) { - rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSConfigKeyName, 0, - KEY_QUERY_VALUE, &hkParam); - if (rv == ERROR_SUCCESS) { - len = sizeof(allSubmount); - rv = RegQueryValueEx(hkParam, "AllSubmount", NULL, NULL, - (BYTE *) &allSubmount, &len); - if (rv != ERROR_SUCCESS || allSubmount != 0) { - allSubmount = 1; - } - RegCloseKey (hkParam); - } - - if(allSubmount) - shareFound = TRUE; - - } else { - rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\OpenAFS\\Client\\Submounts", 0, - KEY_QUERY_VALUE, &hkSubmount); - if(rv == ERROR_SUCCESS) { + totalParam = 6; + + if (infoLevel == 0) + totalData = sizeof(smb_rap_share_info_0_t); + else if(infoLevel == 1) + totalData = sizeof(smb_rap_share_info_1_t) + 1; /* + empty string */ + else if(infoLevel == 2) + totalData = sizeof(smb_rap_share_info_2_t) + 2; /* + two empty strings */ + else + return CM_ERROR_INVAL; + + outp = smb_GetTran2ResponsePacket(vcp, p, op, totalParam, totalData); + + if(!stricmp(shareName,"all")) { + rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSConfigKeyName, 0, + KEY_QUERY_VALUE, &hkParam); + if (rv == ERROR_SUCCESS) { + len = sizeof(allSubmount); + rv = RegQueryValueEx(hkParam, "AllSubmount", NULL, NULL, + (BYTE *) &allSubmount, &len); + if (rv != ERROR_SUCCESS || allSubmount != 0) { + allSubmount = 1; + } + RegCloseKey (hkParam); + } + + if (allSubmount) + shareFound = TRUE; + + } else { + rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\OpenAFS\\Client\\Submounts", 0, + KEY_QUERY_VALUE, &hkSubmount); + if (rv == ERROR_SUCCESS) { rv = RegQueryValueEx(hkSubmount, shareName, NULL, NULL, NULL, NULL); - if(rv == ERROR_SUCCESS) { - shareFound = TRUE; - } - RegCloseKey(hkSubmount); - } - } + if (rv == ERROR_SUCCESS) { + shareFound = TRUE; + } + RegCloseKey(hkSubmount); + } + } - if(!shareFound) { - smb_FreeTran2Packet(outp); - return CM_ERROR_BADSHARENAME; - } + if (!shareFound) { + smb_FreeTran2Packet(outp); + return CM_ERROR_BADSHARENAME; + } - memset(outp->datap, 0, totalData); + memset(outp->datap, 0, totalData); - outp->parmsp[0] = 0; - outp->parmsp[1] = 0; - outp->parmsp[2] = totalData; + outp->parmsp[0] = 0; + outp->parmsp[1] = 0; + outp->parmsp[2] = totalData; - if(infoLevel == 0) { - smb_rap_share_info_0_t * info = (smb_rap_share_info_0_t *) outp->datap; - strncpy(info->shi0_netname, shareName, sizeof(info->shi0_netname)-1); - info->shi0_netname[sizeof(info->shi0_netname)-1] = 0; - } else if(infoLevel == 1) { - smb_rap_share_info_1_t * info = (smb_rap_share_info_1_t *) outp->datap; + if (infoLevel == 0) { + smb_rap_share_info_0_t * info = (smb_rap_share_info_0_t *) outp->datap; + strncpy(info->shi0_netname, shareName, sizeof(info->shi0_netname)-1); + info->shi0_netname[sizeof(info->shi0_netname)-1] = 0; + } else if(infoLevel == 1) { + smb_rap_share_info_1_t * info = (smb_rap_share_info_1_t *) outp->datap; strncpy(info->shi1_netname, shareName, sizeof(info->shi1_netname)-1); - info->shi1_netname[sizeof(info->shi1_netname)-1] = 0; - info->shi1_remark = ((unsigned char *) (info + 1)) - outp->datap; - /* type and pad are already zero */ - } else { /* infoLevel==2 */ - smb_rap_share_info_2_t * info = (smb_rap_share_info_2_t *) outp->datap; - strncpy(info->shi2_netname, shareName, sizeof(info->shi2_netname)-1); - info->shi2_netname[sizeof(info->shi2_netname)-1] = 0; - info->shi2_remark = ((unsigned char *) (info + 1)) - outp->datap; + info->shi1_netname[sizeof(info->shi1_netname)-1] = 0; + info->shi1_remark = ((unsigned char *) (info + 1)) - outp->datap; + /* type and pad are already zero */ + } else { /* infoLevel==2 */ + smb_rap_share_info_2_t * info = (smb_rap_share_info_2_t *) outp->datap; + strncpy(info->shi2_netname, shareName, sizeof(info->shi2_netname)-1); + info->shi2_netname[sizeof(info->shi2_netname)-1] = 0; + info->shi2_remark = ((unsigned char *) (info + 1)) - outp->datap; info->shi2_permissions = ACCESS_ALL; - info->shi2_max_uses = (unsigned short) -1; + info->shi2_max_uses = (unsigned short) -1; info->shi2_path = 1 + (((unsigned char *) (info + 1)) - outp->datap); - } + } - outp->totalData = totalData; - outp->totalParms = totalParam; + outp->totalData = totalData; + outp->totalParms = totalParam; - smb_SendTran2Packet(vcp, outp, op); - smb_FreeTran2Packet(outp); + smb_SendTran2Packet(vcp, outp, op); + smb_FreeTran2Packet(outp); - return code; + return code; } typedef struct smb_rap_wksta_info_10 { - DWORD wki10_computername; /*char *wki10_computername;*/ - DWORD wki10_username; /* char *wki10_username; */ - DWORD wki10_langroup; /* char *wki10_langroup;*/ - unsigned char wki10_ver_major; - unsigned char wki10_ver_minor; - DWORD wki10_logon_domain; /*char *wki10_logon_domain;*/ - DWORD wki10_oth_domains; /* char *wki10_oth_domains;*/ + DWORD wki10_computername; /*char *wki10_computername;*/ + DWORD wki10_username; /* char *wki10_username; */ + DWORD wki10_langroup; /* char *wki10_langroup;*/ + unsigned char wki10_ver_major; + unsigned char wki10_ver_minor; + DWORD wki10_logon_domain; /*char *wki10_logon_domain;*/ + DWORD wki10_oth_domains; /* char *wki10_oth_domains;*/ } smb_rap_wksta_info_10_t; long smb_ReceiveRAPNetWkstaGetInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) { - smb_tran2Packet_t *outp; + smb_tran2Packet_t *outp; long code = 0; - int infoLevel; - int bufsize; - unsigned short * tp; - int totalData; - int totalParams; - smb_rap_wksta_info_10_t * info; - char * cstrp; - smb_user_t *uidp; - - tp = p->parmsp + 1; /* Skip over function number */ - (void) smb_ParseString((unsigned char*) tp, (char **) &tp); /* skip over param descriptor */ - (void) smb_ParseString((unsigned char*) tp, (char **) &tp); /* skip over data descriptor */ - infoLevel = *tp++; - bufsize = *tp++; - - if(infoLevel != 10) { - return CM_ERROR_INVAL; - } + int infoLevel; + int bufsize; + unsigned short * tp; + int totalData; + int totalParams; + smb_rap_wksta_info_10_t * info; + char * cstrp; + smb_user_t *uidp; + + tp = p->parmsp + 1; /* Skip over function number */ + (void) smb_ParseString((unsigned char*) tp, (char **) &tp); /* skip over param descriptor */ + (void) smb_ParseString((unsigned char*) tp, (char **) &tp); /* skip over data descriptor */ + infoLevel = *tp++; + bufsize = *tp++; + + if (infoLevel != 10) { + return CM_ERROR_INVAL; + } - totalParams = 6; + totalParams = 6; - /* infolevel 10 */ - totalData = sizeof(*info) + /* info */ - MAX_COMPUTERNAME_LENGTH + /* wki10_computername */ - SMB_MAX_USERNAME_LENGTH + /* wki10_username */ - MAX_COMPUTERNAME_LENGTH + /* wki10_langroup */ - MAX_COMPUTERNAME_LENGTH + /* wki10_logon_domain */ - 1; /* wki10_oth_domains (null)*/ + /* infolevel 10 */ + totalData = sizeof(*info) + /* info */ + MAX_COMPUTERNAME_LENGTH + /* wki10_computername */ + SMB_MAX_USERNAME_LENGTH + /* wki10_username */ + MAX_COMPUTERNAME_LENGTH + /* wki10_langroup */ + MAX_COMPUTERNAME_LENGTH + /* wki10_logon_domain */ + 1; /* wki10_oth_domains (null)*/ - outp = smb_GetTran2ResponsePacket(vcp, p, op, totalParams, totalData); + outp = smb_GetTran2ResponsePacket(vcp, p, op, totalParams, totalData); - memset(outp->parmsp,0,totalParams); - memset(outp->datap,0,totalData); + memset(outp->parmsp,0,totalParams); + memset(outp->datap,0,totalData); info = (smb_rap_wksta_info_10_t *) outp->datap; - cstrp = (char *) (info + 1); - - info->wki10_computername = (DWORD) (cstrp - outp->datap); - strcpy(cstrp, smb_localNamep); - cstrp += strlen(cstrp) + 1; - - info->wki10_username = (DWORD) (cstrp - outp->datap); - uidp = smb_FindUID(vcp, p->uid, 0); - if(uidp) { - lock_ObtainMutex(&uidp->mx); - if(uidp->unp && uidp->unp->name) - strcpy(cstrp, uidp->unp->name); - lock_ReleaseMutex(&uidp->mx); - smb_ReleaseUID(uidp); - } - cstrp += strlen(cstrp) + 1; + cstrp = (char *) (info + 1); + + info->wki10_computername = (DWORD) (cstrp - outp->datap); + strcpy(cstrp, smb_localNamep); + cstrp += strlen(cstrp) + 1; + + info->wki10_username = (DWORD) (cstrp - outp->datap); + uidp = smb_FindUID(vcp, p->uid, 0); + if (uidp) { + lock_ObtainMutex(&uidp->mx); + if(uidp->unp && uidp->unp->name) + strcpy(cstrp, uidp->unp->name); + lock_ReleaseMutex(&uidp->mx); + smb_ReleaseUID(uidp); + } + cstrp += strlen(cstrp) + 1; - info->wki10_langroup = (DWORD) (cstrp - outp->datap); - strcpy(cstrp, "WORKGROUP"); - cstrp += strlen(cstrp) + 1; + info->wki10_langroup = (DWORD) (cstrp - outp->datap); + strcpy(cstrp, "WORKGROUP"); + cstrp += strlen(cstrp) + 1; - /* TODO: Not sure what values these should take, but these work */ - info->wki10_ver_major = 5; - info->wki10_ver_minor = 1; + /* TODO: Not sure what values these should take, but these work */ + info->wki10_ver_major = 5; + info->wki10_ver_minor = 1; - info->wki10_logon_domain = (DWORD) (cstrp - outp->datap); - strcpy(cstrp, smb_ServerDomainName); - cstrp += strlen(cstrp) + 1; + info->wki10_logon_domain = (DWORD) (cstrp - outp->datap); + strcpy(cstrp, smb_ServerDomainName); + cstrp += strlen(cstrp) + 1; - info->wki10_oth_domains = (DWORD) (cstrp - outp->datap); - cstrp ++; /* no other domains */ + info->wki10_oth_domains = (DWORD) (cstrp - outp->datap); + cstrp ++; /* no other domains */ - outp->totalData = (unsigned short) (cstrp - outp->datap); /* actual data size */ - outp->parmsp[2] = outp->totalData; - outp->totalParms = totalParams; + outp->totalData = (unsigned short) (cstrp - outp->datap); /* actual data size */ + outp->parmsp[2] = outp->totalData; + outp->totalParms = totalParams; - smb_SendTran2Packet(vcp,outp,op); - smb_FreeTran2Packet(outp); + smb_SendTran2Packet(vcp,outp,op); + smb_FreeTran2Packet(outp); - return code; + return code; } typedef struct smb_rap_server_info_0 { @@ -1790,39 +1785,39 @@ int smb_ServerCommentLen = sizeof(smb_ServerComment); long smb_ReceiveRAPNetServerGetInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) { - smb_tran2Packet_t *outp; + smb_tran2Packet_t *outp; long code = 0; - int infoLevel; - int bufsize; - unsigned short * tp; - int totalData; - int totalParams; + int infoLevel; + int bufsize; + unsigned short * tp; + int totalData; + int totalParams; smb_rap_server_info_0_t * info0; smb_rap_server_info_1_t * info1; char * cstrp; - tp = p->parmsp + 1; /* Skip over function number */ - (void) smb_ParseString((unsigned char*) tp, (char **) &tp); /* skip over param descriptor */ - (void) smb_ParseString((unsigned char*) tp, (char **) &tp); /* skip over data descriptor */ - infoLevel = *tp++; - bufsize = *tp++; + tp = p->parmsp + 1; /* Skip over function number */ + (void) smb_ParseString((unsigned char*) tp, (char **) &tp); /* skip over param descriptor */ + (void) smb_ParseString((unsigned char*) tp, (char **) &tp); /* skip over data descriptor */ + infoLevel = *tp++; + bufsize = *tp++; - if(infoLevel != 0 && infoLevel != 1) { + if (infoLevel != 0 && infoLevel != 1) { return CM_ERROR_INVAL; } - totalParams = 6; - - totalData = + totalParams = 6; + + totalData = (infoLevel == 0) ? sizeof(smb_rap_server_info_0_t) : (sizeof(smb_rap_server_info_1_t) + smb_ServerCommentLen); - outp = smb_GetTran2ResponsePacket(vcp, p, op, totalParams, totalData); + outp = smb_GetTran2ResponsePacket(vcp, p, op, totalParams, totalData); - memset(outp->parmsp,0,totalParams); - memset(outp->datap,0,totalData); + memset(outp->parmsp,0,totalParams); + memset(outp->datap,0,totalData); - if(infoLevel == 0) { + if (infoLevel == 0) { info0 = (smb_rap_server_info_0_t *) outp->datap; cstrp = (char *) (info0 + 1); strcpy(info0->sv0_name, "AFS"); @@ -1846,13 +1841,13 @@ long smb_ReceiveRAPNetServerGetInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_pac } totalData = cstrp - outp->datap; - outp->totalData = min(bufsize,totalData); /* actual data size */ + outp->totalData = min(bufsize,totalData); /* actual data size */ outp->parmsp[0] = (outp->totalData == totalData)? 0 : ERROR_MORE_DATA; - outp->parmsp[2] = totalData; - outp->totalParms = totalParams; + outp->parmsp[2] = totalData; + outp->totalParms = totalParams; - smb_SendTran2Packet(vcp,outp,op); - smb_FreeTran2Packet(outp); + smb_SendTran2Packet(vcp,outp,op); + smb_FreeTran2Packet(outp); return code; } @@ -1871,52 +1866,52 @@ long smb_ReceiveV3Tran2A(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) int firstPacket; long code = 0; - /* We sometimes see 0 word count. What to do? */ - if (*inp->wctp == 0) { + /* We sometimes see 0 word count. What to do? */ + if (*inp->wctp == 0) { #ifndef DJGPP - HANDLE h; - char *ptbuf[1]; + HANDLE h; + char *ptbuf[1]; - osi_Log0(smb_logp, "TRANSACTION2 word count = 0"); + osi_Log0(smb_logp, "TRANSACTION2 word count = 0"); - h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME); - ptbuf[0] = "Transaction2 word count = 0"; - ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, 1003, NULL, - 1, inp->ncb_length, ptbuf, inp); - DeregisterEventSource(h); + h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME); + ptbuf[0] = "Transaction2 word count = 0"; + ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, 1003, NULL, + 1, inp->ncb_length, ptbuf, inp); + DeregisterEventSource(h); #else /* DJGPP */ - osi_Log0(smb_logp, "TRANSACTION2 word count = 0"); + osi_Log0(smb_logp, "TRANSACTION2 word count = 0"); #endif /* !DJGPP */ smb_SetSMBDataLength(outp, 0); smb_SendPacket(vcp, outp); - return 0; - } + return 0; + } totalParms = smb_GetSMBParm(inp, 0); totalData = smb_GetSMBParm(inp, 1); firstPacket = (inp->inCom == 0x32); - /* find the packet we're reassembling */ - lock_ObtainWrite(&smb_globalLock); + /* find the packet we're reassembling */ + lock_ObtainWrite(&smb_globalLock); asp = smb_FindTran2Packet(vcp, inp); if (!asp) { asp = smb_NewTran2Packet(vcp, inp, totalParms, totalData); - } + } lock_ReleaseWrite(&smb_globalLock); /* now merge in this latest packet; start by looking up offsets */ - if (firstPacket) { - parmDisp = dataDisp = 0; + if (firstPacket) { + parmDisp = dataDisp = 0; parmOffset = smb_GetSMBParm(inp, 10); dataOffset = smb_GetSMBParm(inp, 12); parmCount = smb_GetSMBParm(inp, 9); dataCount = smb_GetSMBParm(inp, 11); - asp->maxReturnParms = smb_GetSMBParm(inp, 2); + asp->maxReturnParms = smb_GetSMBParm(inp, 2); asp->maxReturnData = smb_GetSMBParm(inp, 3); - osi_Log3(smb_logp, "SMB3 received T2 init packet total data %d, cur data %d, max return data %d", + osi_Log3(smb_logp, "SMB3 received T2 init packet total data %d, cur data %d, max return data %d", totalData, dataCount, asp->maxReturnData); } else { @@ -1949,9 +1944,9 @@ long smb_ReceiveV3Tran2A(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) asp->curParms > 0 && asp->totalData <= asp->curData && asp->totalParms <= asp->curParms) { - /* we've received it all */ + /* we've received it all */ lock_ObtainWrite(&smb_globalLock); - osi_QRemove((osi_queue_t **) &smb_tran2AssemblyQueuep, &asp->q); + osi_QRemove((osi_queue_t **) &smb_tran2AssemblyQueuep, &asp->q); lock_ReleaseWrite(&smb_globalLock); /* now dispatch it */ @@ -1966,7 +1961,7 @@ long smb_ReceiveV3Tran2A(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) code = CM_ERROR_BADOP; } - /* if an error is returned, we're supposed to send an error packet, + /* if an error is returned, we're supposed to send an error packet, * otherwise the dispatched function already did the data sending. * We give dispatched proc the responsibility since it knows how much * space to allocate. @@ -1975,28 +1970,28 @@ long smb_ReceiveV3Tran2A(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) smb_SendTran2Error(vcp, asp, outp, code); } - /* free the input tran 2 packet */ - lock_ObtainWrite(&smb_globalLock); + /* free the input tran 2 packet */ + lock_ObtainWrite(&smb_globalLock); smb_FreeTran2Packet(asp); - lock_ReleaseWrite(&smb_globalLock); + lock_ReleaseWrite(&smb_globalLock); } else if (firstPacket) { - /* the first packet in a multi-packet request, we need to send an + /* the first packet in a multi-packet request, we need to send an * ack to get more data. */ smb_SetSMBDataLength(outp, 0); smb_SendPacket(vcp, outp); } - return 0; + return 0; } long smb_ReceiveTran2Open(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) { - char *pathp; + char *pathp; smb_tran2Packet_t *outp; long code = 0; - cm_space_t *spacep; + cm_space_t *spacep; int excl; cm_user_t *userp; cm_scache_t *dscp; /* dir we're dealing with */ @@ -2006,7 +2001,7 @@ long smb_ReceiveTran2Open(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) smb_fid_t *fidp; int attributes; char *lastNamep; - long dosTime; + time_t dosTime; int openFun; int trunc; int openMode; @@ -2014,26 +2009,26 @@ long smb_ReceiveTran2Open(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) int openAction; int parmSlot; /* which parm we're dealing with */ long returnEALength; - char *tidPathp; - cm_req_t req; + char *tidPathp; + cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); scp = NULL; - extraInfo = (p->parmsp[0] & 1); /* return extra info */ + extraInfo = (p->parmsp[0] & 1); /* return extra info */ returnEALength = (p->parmsp[0] & 8); /* return extended attr length */ - openFun = p->parmsp[6]; /* open function */ + openFun = p->parmsp[6]; /* open function */ excl = ((openFun & 3) == 0); trunc = ((openFun & 3) == 2); /* truncate it */ - openMode = (p->parmsp[1] & 0x7); + openMode = (p->parmsp[1] & 0x7); openAction = 0; /* tracks what we did */ attributes = p->parmsp[3]; dosTime = p->parmsp[4] | (p->parmsp[5] << 16); - /* compute initial mode bits based on read-only flag in attributes */ + /* compute initial mode bits based on read-only flag in attributes */ initialModeBits = 0666; if (attributes & 1) initialModeBits &= ~0222; @@ -2041,20 +2036,20 @@ long smb_ReceiveTran2Open(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) outp = smb_GetTran2ResponsePacket(vcp, p, op, 40, 0); - spacep = cm_GetSpace(); + spacep = cm_GetSpace(); smb_StripLastComponent(spacep->data, &lastNamep, pathp); - if (lastNamep && strcmp(lastNamep, SMB_IOCTL_FILENAME) == 0) { - /* special case magic file name for receiving IOCTL requests + if (lastNamep && strcmp(lastNamep, SMB_IOCTL_FILENAME) == 0) { + /* special case magic file name for receiving IOCTL requests * (since IOCTL calls themselves aren't getting through). */ fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE); smb_SetupIoctlFid(fidp, spacep); /* copy out remainder of the parms */ - parmSlot = 0; - outp->parmsp[parmSlot] = fidp->fid; parmSlot++; - if (extraInfo) { + parmSlot = 0; + outp->parmsp[parmSlot] = fidp->fid; parmSlot++; + if (extraInfo) { outp->parmsp[parmSlot] = /* attrs */ 0; parmSlot++; outp->parmsp[parmSlot] = 0; parmSlot++; /* mod time */ outp->parmsp[parmSlot] = 0; parmSlot++; @@ -2063,17 +2058,17 @@ long smb_ReceiveTran2Open(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) outp->parmsp[parmSlot] = openMode; parmSlot++; outp->parmsp[parmSlot] = 0; parmSlot++; /* file type 0 ==> normal file or dir */ outp->parmsp[parmSlot] = 0; parmSlot++; /* IPC junk */ - } - /* and the final "always present" stuff */ + } + /* and the final "always present" stuff */ outp->parmsp[parmSlot] = /* openAction found existing file */ 1; parmSlot++; - /* next write out the "unique" ID */ - outp->parmsp[parmSlot] = 0x1234; parmSlot++; - outp->parmsp[parmSlot] = 0x5678; parmSlot++; + /* next write out the "unique" ID */ + outp->parmsp[parmSlot] = 0x1234; parmSlot++; + outp->parmsp[parmSlot] = 0x5678; parmSlot++; outp->parmsp[parmSlot] = 0; parmSlot++; - if (returnEALength) { - outp->parmsp[parmSlot] = 0; parmSlot++; - outp->parmsp[parmSlot] = 0; parmSlot++; - } + if (returnEALength) { + outp->parmsp[parmSlot] = 0; parmSlot++; + outp->parmsp[parmSlot] = 0; parmSlot++; + } outp->totalData = 0; outp->totalParms = parmSlot * 2; @@ -2082,22 +2077,22 @@ long smb_ReceiveTran2Open(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) smb_FreeTran2Packet(outp); - /* and clean up fid reference */ + /* and clean up fid reference */ smb_ReleaseFID(fidp); return 0; } #ifdef DEBUG_VERBOSE - { - char *hexp, *asciip; - asciip = (lastNamep ? lastNamep : pathp); - hexp = osi_HexifyString( asciip ); - DEBUG_EVENT2("AFS","T2Open H[%s] A[%s]", hexp, asciip); - free(hexp); - } + { + char *hexp, *asciip; + asciip = (lastNamep ? lastNamep : pathp); + hexp = osi_HexifyString( asciip ); + DEBUG_EVENT2("AFS","T2Open H[%s] A[%s]", hexp, asciip); + free(hexp); + } #endif - userp = smb_GetTran2User(vcp, p); + userp = smb_GetTran2User(vcp, p); /* In the off chance that userp is NULL, we log and abandon */ if (!userp) { osi_Log1(smb_logp, "ReceiveTran2Open user [%d] not resolvable", p->uid); @@ -2105,8 +2100,8 @@ long smb_ReceiveTran2Open(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) return CM_ERROR_BADSMB; } - code = smb_LookupTIDPath(vcp, p->tid, &tidPathp); - if(code == CM_ERROR_TIDIPC) { + code = smb_LookupTIDPath(vcp, p->tid, &tidPathp); + if (code == CM_ERROR_TIDIPC) { /* Attempt to use TID allocated for IPC. The client is probably trying to locate DCE RPC end points, which we don't support. */ @@ -2116,154 +2111,174 @@ long smb_ReceiveTran2Open(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) return CM_ERROR_NOSUCHPATH; } - dscp = NULL; - code = cm_NameI(cm_rootSCachep, pathp, - CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, - userp, tidPathp, &req, &scp); - if (code != 0) { - code = cm_NameI(cm_rootSCachep, spacep->data, - CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, - userp, tidPathp, &req, &dscp); - cm_FreeSpace(spacep); + dscp = NULL; + code = cm_NameI(cm_rootSCachep, pathp, + CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, + userp, tidPathp, &req, &scp); + if (code != 0) { + code = cm_NameI(cm_rootSCachep, spacep->data, + CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, + userp, tidPathp, &req, &dscp); + cm_FreeSpace(spacep); if (code) { cm_ReleaseUser(userp); - smb_FreeTran2Packet(outp); + smb_FreeTran2Packet(outp); return code; } /* otherwise, scp points to the parent directory. Do a lookup, - * and truncate the file if we find it, otherwise we create the - * file. + * and truncate the file if we find it, otherwise we create the + * file. */ - if (!lastNamep) lastNamep = pathp; - else lastNamep++; + if (!lastNamep) + lastNamep = pathp; + else + lastNamep++; code = cm_Lookup(dscp, lastNamep, CM_FLAG_CASEFOLD, userp, &req, &scp); if (code && code != CM_ERROR_NOSUCHFILE) { - cm_ReleaseSCache(dscp); + cm_ReleaseSCache(dscp); cm_ReleaseUser(userp); - smb_FreeTran2Packet(outp); + smb_FreeTran2Packet(outp); return code; } - } + } else { cm_FreeSpace(spacep); - } + } /* if we get here, if code is 0, the file exists and is represented by * scp. Otherwise, we have to create it. */ - if (code == 0) { + if (code == 0) { code = cm_CheckOpen(scp, openMode, trunc, userp, &req); if (code) { if (dscp) cm_ReleaseSCache(dscp); cm_ReleaseSCache(scp); cm_ReleaseUser(userp); - smb_FreeTran2Packet(outp); + smb_FreeTran2Packet(outp); return code; } - if (excl) { - /* oops, file shouldn't be there */ + if (excl) { + /* oops, file shouldn't be there */ if (dscp) cm_ReleaseSCache(dscp); cm_ReleaseSCache(scp); cm_ReleaseUser(userp); - smb_FreeTran2Packet(outp); + smb_FreeTran2Packet(outp); return CM_ERROR_EXISTS; } - if (trunc) { - setAttr.mask = CM_ATTRMASK_LENGTH; + if (trunc) { + setAttr.mask = CM_ATTRMASK_LENGTH; setAttr.length.LowPart = 0; setAttr.length.HighPart = 0; - code = cm_SetAttr(scp, &setAttr, userp, &req); + code = cm_SetAttr(scp, &setAttr, userp, &req); openAction = 3; /* truncated existing file */ - } - else openAction = 1; /* found existing file */ + } + else + openAction = 1; /* found existing file */ } - else if (!(openFun & SMB_ATTR_DIRECTORY)) { - /* don't create if not found */ + else if (!(openFun & SMB_ATTR_DIRECTORY)) { + /* don't create if not found */ if (dscp) cm_ReleaseSCache(dscp); osi_assert(scp == NULL); cm_ReleaseUser(userp); - smb_FreeTran2Packet(outp); + smb_FreeTran2Packet(outp); return CM_ERROR_NOSUCHFILE; } else { - osi_assert(dscp != NULL && scp == NULL); - openAction = 2; /* created file */ - setAttr.mask = CM_ATTRMASK_CLIENTMODTIME; - smb_UnixTimeFromSearchTime(&setAttr.clientModTime, dosTime); + osi_assert(dscp != NULL && scp == NULL); + openAction = 2; /* created file */ + setAttr.mask = CM_ATTRMASK_CLIENTMODTIME; + smb_UnixTimeFromSearchTime(&setAttr.clientModTime, dosTime); code = cm_Create(dscp, lastNamep, 0, &setAttr, &scp, userp, - &req); - if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) - smb_NotifyChange(FILE_ACTION_ADDED, + &req); + if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) + smb_NotifyChange(FILE_ACTION_ADDED, FILE_NOTIFY_CHANGE_FILE_NAME, dscp, lastNamep, NULL, TRUE); if (!excl && code == CM_ERROR_EXISTS) { - /* not an exclusive create, and someone else tried - * creating it already, then we open it anyway. We - * don't bother retrying after this, since if this next - * fails, that means that the file was deleted after we - * started this call. + /* not an exclusive create, and someone else tried + * creating it already, then we open it anyway. We + * don't bother retrying after this, since if this next + * fails, that means that the file was deleted after we + * started this call. */ code = cm_Lookup(dscp, lastNamep, CM_FLAG_CASEFOLD, - userp, &req, &scp); + userp, &req, &scp); if (code == 0) { if (trunc) { - setAttr.mask = CM_ATTRMASK_LENGTH; + setAttr.mask = CM_ATTRMASK_LENGTH; setAttr.length.LowPart = 0; setAttr.length.HighPart = 0; code = cm_SetAttr(scp, &setAttr, userp, - &req); + &req); } - } /* lookup succeeded */ + } /* lookup succeeded */ } } - /* we don't need this any longer */ - if (dscp) cm_ReleaseSCache(dscp); + /* we don't need this any longer */ + if (dscp) cm_ReleaseSCache(dscp); if (code) { - /* something went wrong creating or truncating the file */ + /* something went wrong creating or truncating the file */ if (scp) cm_ReleaseSCache(scp); cm_ReleaseUser(userp); - smb_FreeTran2Packet(outp); + smb_FreeTran2Packet(outp); return code; } - /* make sure we're about to open a file */ - if (scp->fileType != CM_SCACHETYPE_FILE) { - cm_ReleaseSCache(scp); - cm_ReleaseUser(userp); - smb_FreeTran2Packet(outp); - return CM_ERROR_ISDIR; - } + /* make sure we're about to open a file */ + if (scp->fileType != CM_SCACHETYPE_FILE) { + code = 0; + while (code == 0 && scp->fileType == CM_SCACHETYPE_SYMLINK) { + cm_scache_t * targetScp = 0; + code = cm_EvaluateSymLink(dscp, scp, &targetScp, userp, &req); + if (code == 0) { + /* we have a more accurate file to use (the + * target of the symbolic link). Otherwise, + * we'll just use the symlink anyway. + */ + osi_Log2(smb_logp, "symlink vp %x to vp %x", + scp, targetScp); + cm_ReleaseSCache(scp); + scp = targetScp; + } + } + if (scp->fileType != CM_SCACHETYPE_FILE) { + cm_ReleaseSCache(scp); + cm_ReleaseUser(userp); + smb_FreeTran2Packet(outp); + return CM_ERROR_ISDIR; + } + } /* now all we have to do is open the file itself */ fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE); osi_assert(fidp); - /* save a pointer to the vnode */ + /* save a pointer to the vnode */ fidp->scp = scp; - /* compute open mode */ + /* compute open mode */ if (openMode != 1) fidp->flags |= SMB_FID_OPENREAD; if (openMode == 1 || openMode == 2) fidp->flags |= SMB_FID_OPENWRITE; - smb_ReleaseFID(fidp); + smb_ReleaseFID(fidp); - cm_Open(scp, 0, userp); + cm_Open(scp, 0, userp); /* copy out remainder of the parms */ - parmSlot = 0; - outp->parmsp[parmSlot] = fidp->fid; parmSlot++; - lock_ObtainMutex(&scp->mx); - if (extraInfo) { + parmSlot = 0; + outp->parmsp[parmSlot] = fidp->fid; parmSlot++; + lock_ObtainMutex(&scp->mx); + if (extraInfo) { outp->parmsp[parmSlot] = smb_Attributes(scp); parmSlot++; - smb_SearchTimeFromUnixTime(&dosTime, scp->clientModTime); + smb_SearchTimeFromUnixTime(&dosTime, scp->clientModTime); outp->parmsp[parmSlot] = (unsigned short)(dosTime & 0xffff); parmSlot++; outp->parmsp[parmSlot] = (unsigned short)((dosTime>>16) & 0xffff); parmSlot++; outp->parmsp[parmSlot] = (unsigned short) (scp->length.LowPart & 0xffff); @@ -2273,23 +2288,23 @@ long smb_ReceiveTran2Open(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) outp->parmsp[parmSlot] = openMode; parmSlot++; outp->parmsp[parmSlot] = 0; parmSlot++; /* file type 0 ==> normal file or dir */ outp->parmsp[parmSlot] = 0; parmSlot++; /* IPC junk */ - } - /* and the final "always present" stuff */ + } + /* and the final "always present" stuff */ outp->parmsp[parmSlot] = openAction; parmSlot++; - /* next write out the "unique" ID */ - outp->parmsp[parmSlot] = (unsigned short) (scp->fid.vnode & 0xffff); parmSlot++; - outp->parmsp[parmSlot] = (unsigned short) (scp->fid.volume & 0xffff); parmSlot++; + /* next write out the "unique" ID */ + outp->parmsp[parmSlot] = (unsigned short) (scp->fid.vnode & 0xffff); parmSlot++; + outp->parmsp[parmSlot] = (unsigned short) (scp->fid.volume & 0xffff); parmSlot++; outp->parmsp[parmSlot] = 0; parmSlot++; if (returnEALength) { - outp->parmsp[parmSlot] = 0; parmSlot++; - outp->parmsp[parmSlot] = 0; parmSlot++; - } - lock_ReleaseMutex(&scp->mx); - outp->totalData = 0; /* total # of data bytes */ + outp->parmsp[parmSlot] = 0; parmSlot++; + outp->parmsp[parmSlot] = 0; parmSlot++; + } + lock_ReleaseMutex(&scp->mx); + outp->totalData = 0; /* total # of data bytes */ outp->totalParms = parmSlot * 2; /* shorts are two bytes */ - smb_SendTran2Packet(vcp, outp, op); - + smb_SendTran2Packet(vcp, outp, op); + smb_FreeTran2Packet(outp); cm_ReleaseUser(userp); @@ -2299,103 +2314,105 @@ long smb_ReceiveTran2Open(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) long smb_ReceiveTran2FindFirst(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp) { + osi_Log0(smb_logp,"ReceiveTran2FindFirst - NOT_SUPPORTED"); return CM_ERROR_BADOP; } long smb_ReceiveTran2FindNext(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp) { + osi_Log0(smb_logp,"ReceiveTran2FindNext - NOT_SUPPORTED"); return CM_ERROR_BADOP; } long smb_ReceiveTran2QFSInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) { - smb_tran2Packet_t *outp; + smb_tran2Packet_t *outp; smb_tran2QFSInfo_t qi; - int responseSize; - osi_hyper_t temp; - static char FSname[6] = {'A', 0, 'F', 0, 'S', 0}; + int responseSize; + osi_hyper_t temp; + static char FSname[6] = {'A', 0, 'F', 0, 'S', 0}; - osi_Log1(smb_logp, "T2 QFSInfo type 0x%x", p->parmsp[0]); - - switch (p->parmsp[0]) { - case 1: responseSize = sizeof(qi.u.allocInfo); break; - case 2: responseSize = sizeof(qi.u.volumeInfo); break; - case 0x102: responseSize = sizeof(qi.u.FSvolumeInfo); break; - case 0x103: responseSize = sizeof(qi.u.FSsizeInfo); break; - case 0x104: responseSize = sizeof(qi.u.FSdeviceInfo); break; - case 0x105: responseSize = sizeof(qi.u.FSattributeInfo); break; - default: return CM_ERROR_INVAL; - } + osi_Log1(smb_logp, "T2 QFSInfo type 0x%x", p->parmsp[0]); + + switch (p->parmsp[0]) { + case 1: responseSize = sizeof(qi.u.allocInfo); break; + case 2: responseSize = sizeof(qi.u.volumeInfo); break; + case 0x102: responseSize = sizeof(qi.u.FSvolumeInfo); break; + case 0x103: responseSize = sizeof(qi.u.FSsizeInfo); break; + case 0x104: responseSize = sizeof(qi.u.FSdeviceInfo); break; + case 0x105: responseSize = sizeof(qi.u.FSattributeInfo); break; + default: return CM_ERROR_INVAL; + } outp = smb_GetTran2ResponsePacket(vcp, p, op, 0, responseSize); - switch (p->parmsp[0]) { - case 1: - /* alloc info */ + switch (p->parmsp[0]) { + case 1: + /* alloc info */ qi.u.allocInfo.FSID = 0; qi.u.allocInfo.sectorsPerAllocUnit = 1; qi.u.allocInfo.totalAllocUnits = 0x7fffffff; qi.u.allocInfo.availAllocUnits = 0x3fffffff; qi.u.allocInfo.bytesPerSector = 1024; - break; + break; case 2: - /* volume info */ + /* volume info */ qi.u.volumeInfo.vsn = 1234; qi.u.volumeInfo.vnCount = 4; - /* we're supposed to pad it out with zeroes to the end */ - memset(&qi.u.volumeInfo.label, 0, sizeof(qi.u.volumeInfo.label)); + /* we're supposed to pad it out with zeroes to the end */ + memset(&qi.u.volumeInfo.label, 0, sizeof(qi.u.volumeInfo.label)); memcpy(qi.u.volumeInfo.label, "AFS", 4); - break; - - case 0x102: - /* FS volume info */ - memset((char *)&qi.u.FSvolumeInfo.vct, 0, sizeof(FILETIME)); - qi.u.FSvolumeInfo.vsn = 1234; - qi.u.FSvolumeInfo.vnCount = 8; - memcpy(qi.u.FSvolumeInfo.label, "A\0F\0S\0\0", 8); - break; - - case 0x103: - /* FS size info */ - temp.HighPart = 0; - temp.LowPart = 0x7fffffff; - qi.u.FSsizeInfo.totalAllocUnits = temp; - temp.LowPart = 0x3fffffff; - qi.u.FSsizeInfo.availAllocUnits = temp; - qi.u.FSsizeInfo.sectorsPerAllocUnit = 1; - qi.u.FSsizeInfo.bytesPerSector = 1024; - break; - - case 0x104: - /* FS device info */ - qi.u.FSdeviceInfo.devType = 0; /* don't have a number */ - qi.u.FSdeviceInfo.characteristics = 0x50; /* remote, virtual */ - break; + break; + + case 0x102: + /* FS volume info */ + memset((char *)&qi.u.FSvolumeInfo.vct, 0, sizeof(FILETIME)); + qi.u.FSvolumeInfo.vsn = 1234; + qi.u.FSvolumeInfo.vnCount = 8; + memcpy(qi.u.FSvolumeInfo.label, "A\0F\0S\0\0", 8); + break; + + case 0x103: + /* FS size info */ + temp.HighPart = 0; + temp.LowPart = 0x7fffffff; + qi.u.FSsizeInfo.totalAllocUnits = temp; + temp.LowPart = 0x3fffffff; + qi.u.FSsizeInfo.availAllocUnits = temp; + qi.u.FSsizeInfo.sectorsPerAllocUnit = 1; + qi.u.FSsizeInfo.bytesPerSector = 1024; + break; + + case 0x104: + /* FS device info */ + qi.u.FSdeviceInfo.devType = 0; /* don't have a number */ + qi.u.FSdeviceInfo.characteristics = 0x50; /* remote, virtual */ + break; case 0x105: - /* FS attribute info */ - /* attributes, defined in WINNT.H: - * FILE_CASE_SENSITIVE_SEARCH 0x1 - * FILE_CASE_PRESERVED_NAMES 0x2 - * 0x4000 - * If bit 0x4000 is not set, Windows 95 thinks - * we can't handle long (non-8.3) names, - * despite our protestations to the contrary. - */ - qi.u.FSattributeInfo.attributes = 0x4003; - qi.u.FSattributeInfo.maxCompLength = 255; - qi.u.FSattributeInfo.FSnameLength = 6; - memcpy(qi.u.FSattributeInfo.FSname, FSname, 6); - break; - } + /* FS attribute info */ + /* attributes, defined in WINNT.H: + * FILE_CASE_SENSITIVE_SEARCH 0x1 + * FILE_CASE_PRESERVED_NAMES 0x2 + * 0x4000 + * If bit 0x4000 is not set, Windows 95 thinks + * we can't handle long (non-8.3) names, + * despite our protestations to the contrary. + */ + qi.u.FSattributeInfo.attributes = 0x4003; + qi.u.FSattributeInfo.maxCompLength = 255; + qi.u.FSattributeInfo.FSnameLength = 6; + memcpy(qi.u.FSattributeInfo.FSname, FSname, 6); + break; + } - /* copy out return data, and set corresponding sizes */ - outp->totalParms = 0; + /* copy out return data, and set corresponding sizes */ + outp->totalParms = 0; outp->totalData = responseSize; memcpy(outp->datap, &qi, responseSize); - /* send and free the packets */ - smb_SendTran2Packet(vcp, outp, op); + /* send and free the packets */ + smb_SendTran2Packet(vcp, outp, op); smb_FreeTran2Packet(outp); return 0; @@ -2403,132 +2420,133 @@ long smb_ReceiveTran2QFSInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t * long smb_ReceiveTran2SetFSInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp) { + osi_Log0(smb_logp,"ReceiveTran2SetFSInfo - NOT_SUPPORTED"); return CM_ERROR_BADOP; } struct smb_ShortNameRock { - char *maskp; - unsigned int vnode; - char *shortName; - size_t shortNameLen; -}; + char *maskp; + unsigned int vnode; + char *shortName; + size_t shortNameLen; +}; int cm_GetShortNameProc(cm_scache_t *scp, cm_dirEntry_t *dep, void *vrockp, - osi_hyper_t *offp) -{ - struct smb_ShortNameRock *rockp; - char *shortNameEnd; - - rockp = vrockp; - /* compare both names and vnodes, though probably just comparing vnodes - * would be safe enough. - */ - if (cm_stricmp(dep->name, rockp->maskp) != 0) - return 0; - if (ntohl(dep->fid.vnode) != rockp->vnode) - return 0; - /* This is the entry */ - cm_Gen8Dot3Name(dep, rockp->shortName, &shortNameEnd); - rockp->shortNameLen = shortNameEnd - rockp->shortName; - return CM_ERROR_STOPNOW; -} + osi_hyper_t *offp) +{ + struct smb_ShortNameRock *rockp; + char *shortNameEnd; + + rockp = vrockp; + /* compare both names and vnodes, though probably just comparing vnodes + * would be safe enough. + */ + if (cm_stricmp(dep->name, rockp->maskp) != 0) + return 0; + if (ntohl(dep->fid.vnode) != rockp->vnode) + return 0; + /* This is the entry */ + cm_Gen8Dot3Name(dep, rockp->shortName, &shortNameEnd); + rockp->shortNameLen = shortNameEnd - rockp->shortName; + return CM_ERROR_STOPNOW; +} long cm_GetShortName(char *pathp, cm_user_t *userp, cm_req_t *reqp, char *tidPathp, int vnode, char *shortName, size_t *shortNameLenp) { - struct smb_ShortNameRock rock; - char *lastNamep; - cm_space_t *spacep; - cm_scache_t *dscp; - int caseFold = CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD; - long code = 0; - osi_hyper_t thyper; - - spacep = cm_GetSpace(); - smb_StripLastComponent(spacep->data, &lastNamep, pathp); - - code = cm_NameI(cm_rootSCachep, spacep->data, caseFold, userp, tidPathp, + struct smb_ShortNameRock rock; + char *lastNamep; + cm_space_t *spacep; + cm_scache_t *dscp; + int caseFold = CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD; + long code = 0; + osi_hyper_t thyper; + + spacep = cm_GetSpace(); + smb_StripLastComponent(spacep->data, &lastNamep, pathp); + + code = cm_NameI(cm_rootSCachep, spacep->data, caseFold, userp, tidPathp, reqp, &dscp); - cm_FreeSpace(spacep); - if (code) return code; - - if (!lastNamep) lastNamep = pathp; - else lastNamep++; - thyper.LowPart = 0; - thyper.HighPart = 0; - rock.shortName = shortName; - rock.vnode = vnode; - rock.maskp = lastNamep; - code = cm_ApplyDir(dscp, cm_GetShortNameProc, &rock, &thyper, userp, + cm_FreeSpace(spacep); + if (code) return code; + + if (!lastNamep) lastNamep = pathp; + else lastNamep++; + thyper.LowPart = 0; + thyper.HighPart = 0; + rock.shortName = shortName; + rock.vnode = vnode; + rock.maskp = lastNamep; + code = cm_ApplyDir(dscp, cm_GetShortNameProc, &rock, &thyper, userp, reqp, NULL); - cm_ReleaseSCache(dscp); + cm_ReleaseSCache(dscp); - if (code == 0) - return CM_ERROR_NOSUCHFILE; - if (code == CM_ERROR_STOPNOW) { - *shortNameLenp = rock.shortNameLen; - return 0; - } - return code; + if (code == 0) + return CM_ERROR_NOSUCHFILE; + if (code == CM_ERROR_STOPNOW) { + *shortNameLenp = rock.shortNameLen; + return 0; + } + return code; } long smb_ReceiveTran2QPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *opx) { - smb_tran2Packet_t *outp; - unsigned long dosTime; - FILETIME ft; + smb_tran2Packet_t *outp; + time_t dosTime; + FILETIME ft; unsigned short infoLevel; int nbytesRequired; unsigned short attributes; - unsigned long extAttributes; - char shortName[13]; - unsigned int len; + unsigned long extAttributes; + char shortName[13]; + unsigned int len; cm_user_t *userp; - cm_space_t *spacep; + cm_space_t *spacep; cm_scache_t *scp, *dscp; long code = 0; char *op; - char *tidPathp; - char *lastComp; - cm_req_t req; + char *tidPathp; + char *lastComp; + cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); - infoLevel = p->parmsp[0]; + infoLevel = p->parmsp[0]; if (infoLevel == 6) nbytesRequired = 0; else if (infoLevel == 1) nbytesRequired = 22; else if (infoLevel == 2) nbytesRequired = 26; - else if (infoLevel == 0x101) nbytesRequired = 40; - else if (infoLevel == 0x102) nbytesRequired = 24; - else if (infoLevel == 0x103) nbytesRequired = 4; - else if (infoLevel == 0x108) nbytesRequired = 30; + else if (infoLevel == 0x101) nbytesRequired = 40; + else if (infoLevel == 0x102) nbytesRequired = 24; + else if (infoLevel == 0x103) nbytesRequired = 4; + else if (infoLevel == 0x108) nbytesRequired = 30; else { - osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x", + osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x", p->opcode, infoLevel); - smb_SendTran2Error(vcp, p, opx, CM_ERROR_INVAL); + smb_SendTran2Error(vcp, p, opx, CM_ERROR_INVAL); return 0; } - osi_Log2(smb_logp, "T2 QPathInfo type 0x%x path %s", infoLevel, - osi_LogSaveString(smb_logp, (char *)(&p->parmsp[3]))); + osi_Log2(smb_logp, "T2 QPathInfo type 0x%x path %s", infoLevel, + osi_LogSaveString(smb_logp, (char *)(&p->parmsp[3]))); outp = smb_GetTran2ResponsePacket(vcp, p, opx, 2, nbytesRequired); - if (infoLevel > 0x100) - outp->totalParms = 2; - else - outp->totalParms = 0; - outp->totalData = nbytesRequired; + if (infoLevel > 0x100) + outp->totalParms = 2; + else + outp->totalParms = 0; + outp->totalData = nbytesRequired; /* now, if we're at infoLevel 6, we're only being asked to check * the syntax, so we just OK things now. In particular, we're *not* * being asked to verify anything about the state of any parent dirs. */ - if (infoLevel == 6) { - smb_SendTran2Packet(vcp, outp, opx); + if (infoLevel == 6) { + smb_SendTran2Packet(vcp, outp, opx); smb_FreeTran2Packet(outp); - return 0; - } + return 0; + } userp = smb_GetTran2User(vcp, p); if (!userp) { @@ -2537,7 +2555,7 @@ long smb_ReceiveTran2QPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t return CM_ERROR_BADSMB; } - code = smb_LookupTIDPath(vcp, p->tid, &tidPathp); + code = smb_LookupTIDPath(vcp, p->tid, &tidPathp); if(code) { cm_ReleaseUser(userp); smb_SendTran2Error(vcp, p, opx, CM_ERROR_NOSUCHPATH); @@ -2545,32 +2563,32 @@ long smb_ReceiveTran2QPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t return 0; } - /* - * XXX Strange hack XXX - * - * As of Patch 7 (13 January 98), we are having the following problem: - * In NT Explorer 4.0, whenever we click on a directory, AFS gets - * requests to look up "desktop.ini" in all the subdirectories. - * This can cause zillions of timeouts looking up non-existent cells - * and volumes, especially in the top-level directory. - * - * We have not found any way to avoid this or work around it except - * to explicitly ignore the requests for mount points that haven't - * yet been evaluated and for directories that haven't yet been - * fetched. - */ - if (infoLevel == 0x101) { - spacep = cm_GetSpace(); - smb_StripLastComponent(spacep->data, &lastComp, - (char *)(&p->parmsp[3])); - /* Make sure that lastComp is not NULL */ - if (lastComp) { - if (strcmp(lastComp, "\\desktop.ini") == 0) { + /* + * XXX Strange hack XXX + * + * As of Patch 7 (13 January 98), we are having the following problem: + * In NT Explorer 4.0, whenever we click on a directory, AFS gets + * requests to look up "desktop.ini" in all the subdirectories. + * This can cause zillions of timeouts looking up non-existent cells + * and volumes, especially in the top-level directory. + * + * We have not found any way to avoid this or work around it except + * to explicitly ignore the requests for mount points that haven't + * yet been evaluated and for directories that haven't yet been + * fetched. + */ + if (infoLevel == 0x101) { + spacep = cm_GetSpace(); + smb_StripLastComponent(spacep->data, &lastComp, + (char *)(&p->parmsp[3])); + /* Make sure that lastComp is not NULL */ + if (lastComp) { + if (strcmp(lastComp, "\\desktop.ini") == 0) { code = cm_NameI(cm_rootSCachep, spacep->data, - CM_FLAG_CASEFOLD - | CM_FLAG_DIRSEARCH - | CM_FLAG_FOLLOW, - userp, tidPathp, &req, &dscp); + CM_FLAG_CASEFOLD + | CM_FLAG_DIRSEARCH + | CM_FLAG_FOLLOW, + userp, tidPathp, &req, &dscp); if (code == 0) { if (dscp->fileType == CM_SCACHETYPE_MOUNTPOINT && !dscp->mountRootFidp) @@ -2593,90 +2611,90 @@ long smb_ReceiveTran2QPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t } } } - cm_FreeSpace(spacep); - } + cm_FreeSpace(spacep); + } - /* now do namei and stat, and copy out the info */ + /* now do namei and stat, and copy out the info */ code = cm_NameI(cm_rootSCachep, (char *)(&p->parmsp[3]), - CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, tidPathp, &req, &scp); + CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, tidPathp, &req, &scp); - if (code) { - cm_ReleaseUser(userp); + if (code) { + cm_ReleaseUser(userp); smb_SendTran2Error(vcp, p, opx, code); smb_FreeTran2Packet(outp); return 0; } lock_ObtainMutex(&scp->mx); - code = cm_SyncOp(scp, NULL, userp, &req, 0, - CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); - if (code) goto done; + code = cm_SyncOp(scp, NULL, userp, &req, 0, + CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + if (code) goto done; /* now we have the status in the cache entry, and everything is locked. - * Marshall the output data. + * Marshall the output data. */ - op = outp->datap; - /* for info level 108, figure out short name */ - if (infoLevel == 0x108) { - code = cm_GetShortName((char *)(&p->parmsp[3]), userp, &req, + op = outp->datap; + /* for info level 108, figure out short name */ + if (infoLevel == 0x108) { + code = cm_GetShortName((char *)(&p->parmsp[3]), userp, &req, tidPathp, scp->fid.vnode, shortName, (size_t *) &len); - if (code) { - goto done; - } + if (code) { + goto done; + } - op = outp->datap; - *((u_long *)op) = len * 2; op += 4; - mbstowcs((unsigned short *)op, shortName, len); - op += (len * 2); + op = outp->datap; + *((u_long *)op) = len * 2; op += 4; + mbstowcs((unsigned short *)op, shortName, len); + op += (len * 2); - goto done; - } - if (infoLevel == 1 || infoLevel == 2) { - smb_SearchTimeFromUnixTime(&dosTime, scp->clientModTime); + goto done; + } + if (infoLevel == 1 || infoLevel == 2) { + smb_SearchTimeFromUnixTime(&dosTime, scp->clientModTime); *((u_long *)op) = dosTime; op += 4; /* creation time */ *((u_long *)op) = dosTime; op += 4; /* access time */ *((u_long *)op) = dosTime; op += 4; /* write time */ *((u_long *)op) = scp->length.LowPart; op += 4; /* length */ *((u_long *)op) = scp->length.LowPart; op += 4; /* alloc size */ - attributes = smb_Attributes(scp); - *((u_short *)op) = attributes; op += 2; /* attributes */ - } - else if (infoLevel == 0x101) { - smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime); - *((FILETIME *)op) = ft; op += 8; /* creation time */ - *((FILETIME *)op) = ft; op += 8; /* last access time */ - *((FILETIME *)op) = ft; op += 8; /* last write time */ - *((FILETIME *)op) = ft; op += 8; /* last change time */ - extAttributes = smb_ExtAttributes(scp); - *((u_long *)op) = extAttributes; op += 4; /* extended attribs */ - *((u_long *)op) = 0; op += 4; /* don't know what this is */ - } - else if (infoLevel == 0x102) { - *((LARGE_INTEGER *)op) = scp->length; op += 8; /* alloc size */ - *((LARGE_INTEGER *)op) = scp->length; op += 8; /* EOF */ - *((u_long *)op) = scp->linkCount; op += 4; - *op++ = 0; - *op++ = 0; - *op++ = (scp->fileType == CM_SCACHETYPE_DIRECTORY ? 1 : 0); - *op++ = 0; - } - else if (infoLevel == 0x103) { - memset(op, 0, 4); op += 4; /* EA size */ - } + attributes = smb_Attributes(scp); + *((u_short *)op) = attributes; op += 2; /* attributes */ + } + else if (infoLevel == 0x101) { + smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime); + *((FILETIME *)op) = ft; op += 8; /* creation time */ + *((FILETIME *)op) = ft; op += 8; /* last access time */ + *((FILETIME *)op) = ft; op += 8; /* last write time */ + *((FILETIME *)op) = ft; op += 8; /* last change time */ + extAttributes = smb_ExtAttributes(scp); + *((u_long *)op) = extAttributes; op += 4; /* extended attribs */ + *((u_long *)op) = 0; op += 4; /* don't know what this is */ + } + else if (infoLevel == 0x102) { + *((LARGE_INTEGER *)op) = scp->length; op += 8; /* alloc size */ + *((LARGE_INTEGER *)op) = scp->length; op += 8; /* EOF */ + *((u_long *)op) = scp->linkCount; op += 4; + *op++ = 0; + *op++ = 0; + *op++ = (scp->fileType == CM_SCACHETYPE_DIRECTORY ? 1 : 0); + *op++ = 0; + } + else if (infoLevel == 0x103) { + memset(op, 0, 4); op += 4; /* EA size */ + } + + /* now, if we are being asked about extended attrs, return a 0 size */ + if (infoLevel == 2) { + *((u_long *)op) = 0; op += 4; + } - /* now, if we are being asked about extended attrs, return a 0 size */ - if (infoLevel == 2) { - *((u_long *)op) = 0; op += 4; - } - - /* send and free the packets */ + /* send and free the packets */ done: - lock_ReleaseMutex(&scp->mx); + lock_ReleaseMutex(&scp->mx); cm_ReleaseSCache(scp); cm_ReleaseUser(userp); - if (code == 0) + if (code == 0) smb_SendTran2Packet(vcp, outp, opx); else smb_SendTran2Error(vcp, p, opx, code); @@ -2687,304 +2705,344 @@ long smb_ReceiveTran2QPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t long smb_ReceiveTran2SetPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp) { + osi_Log0(smb_logp,"ReceiveTran2SetPathInfo - NOT_SUPPORTED"); return CM_ERROR_BADOP; } long smb_ReceiveTran2QFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *opx) { - smb_tran2Packet_t *outp; - FILETIME ft; - unsigned long attributes; - unsigned short infoLevel; - int nbytesRequired; - unsigned short fid; - cm_user_t *userp; + smb_tran2Packet_t *outp; + FILETIME ft; + unsigned long attributes; + unsigned short infoLevel; + int nbytesRequired; + unsigned short fid; + cm_user_t *userp; smb_fid_t *fidp; - cm_scache_t *scp; - char *op; - long code = 0; - cm_req_t req; + cm_scache_t *scp; + char *op; + long code = 0; + cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); fid = p->parmsp[0]; fidp = smb_FindFID(vcp, fid, 0); - if (fidp == NULL) { - smb_SendTran2Error(vcp, p, opx, CM_ERROR_BADFD); - return 0; - } + if (fidp == NULL) { + smb_SendTran2Error(vcp, p, opx, CM_ERROR_BADFD); + return 0; + } - infoLevel = p->parmsp[1]; - if (infoLevel == 0x101) nbytesRequired = 40; - else if (infoLevel == 0x102) nbytesRequired = 24; - else if (infoLevel == 0x103) nbytesRequired = 4; - else if (infoLevel == 0x104) nbytesRequired = 6; - else { - osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x", - p->opcode, infoLevel); - smb_SendTran2Error(vcp, p, opx, CM_ERROR_INVAL); + infoLevel = p->parmsp[1]; + if (infoLevel == 0x101) nbytesRequired = 40; + else if (infoLevel == 0x102) nbytesRequired = 24; + else if (infoLevel == 0x103) nbytesRequired = 4; + else if (infoLevel == 0x104) nbytesRequired = 6; + else { + osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x", + p->opcode, infoLevel); + smb_SendTran2Error(vcp, p, opx, CM_ERROR_INVAL); smb_ReleaseFID(fidp); - return 0; - } - osi_Log2(smb_logp, "T2 QFileInfo type 0x%x fid %d", infoLevel, fid); + return 0; + } + osi_Log2(smb_logp, "T2 QFileInfo type 0x%x fid %d", infoLevel, fid); - outp = smb_GetTran2ResponsePacket(vcp, p, opx, 2, nbytesRequired); + outp = smb_GetTran2ResponsePacket(vcp, p, opx, 2, nbytesRequired); - if (infoLevel > 0x100) - outp->totalParms = 2; - else - outp->totalParms = 0; - outp->totalData = nbytesRequired; + if (infoLevel > 0x100) + outp->totalParms = 2; + else + outp->totalParms = 0; + outp->totalData = nbytesRequired; - userp = smb_GetTran2User(vcp, p); + userp = smb_GetTran2User(vcp, p); if (!userp) { osi_Log1(smb_logp, "ReceiveTran2QFileInfo unable to resolve user [%d]", p->uid); code = CM_ERROR_BADSMB; goto done; - } + } - scp = fidp->scp; - lock_ObtainMutex(&scp->mx); - code = cm_SyncOp(scp, NULL, userp, &req, 0, - CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); - if (code) goto done; + scp = fidp->scp; + lock_ObtainMutex(&scp->mx); + code = cm_SyncOp(scp, NULL, userp, &req, 0, + CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + if (code) + goto done; - /* now we have the status in the cache entry, and everything is locked. - * Marshall the output data. - */ - op = outp->datap; - if (infoLevel == 0x101) { - smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime); - *((FILETIME *)op) = ft; op += 8; /* creation time */ - *((FILETIME *)op) = ft; op += 8; /* last access time */ - *((FILETIME *)op) = ft; op += 8; /* last write time */ - *((FILETIME *)op) = ft; op += 8; /* last change time */ - attributes = smb_ExtAttributes(scp); - *((u_long *)op) = attributes; op += 4; - *((u_long *)op) = 0; op += 4; - } - else if (infoLevel == 0x102) { - *((LARGE_INTEGER *)op) = scp->length; op += 8; /* alloc size */ - *((LARGE_INTEGER *)op) = scp->length; op += 8; /* EOF */ - *((u_long *)op) = scp->linkCount; op += 4; - *op++ = ((fidp->flags & SMB_FID_DELONCLOSE) ? 1 : 0); - *op++ = (scp->fileType == CM_SCACHETYPE_DIRECTORY ? 1 : 0); - *op++ = 0; - *op++ = 0; - } - else if (infoLevel == 0x103) { - *((u_long *)op) = 0; op += 4; - } - else if (infoLevel == 0x104) { - unsigned long len; - char *name; - - if (fidp->NTopen_wholepathp) - name = fidp->NTopen_wholepathp; - else - name = "\\"; /* probably can't happen */ - len = strlen(name); - outp->totalData = (len*2) + 4; /* this is actually what we want to return */ - *((u_long *)op) = len * 2; op += 4; - mbstowcs((unsigned short *)op, name, len); op += (len * 2); - } + /* now we have the status in the cache entry, and everything is locked. + * Marshall the output data. + */ + op = outp->datap; + if (infoLevel == 0x101) { + smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime); + *((FILETIME *)op) = ft; op += 8; /* creation time */ + *((FILETIME *)op) = ft; op += 8; /* last access time */ + *((FILETIME *)op) = ft; op += 8; /* last write time */ + *((FILETIME *)op) = ft; op += 8; /* last change time */ + attributes = smb_ExtAttributes(scp); + *((u_long *)op) = attributes; op += 4; + *((u_long *)op) = 0; op += 4; + } + else if (infoLevel == 0x102) { + *((LARGE_INTEGER *)op) = scp->length; op += 8; /* alloc size */ + *((LARGE_INTEGER *)op) = scp->length; op += 8; /* EOF */ + *((u_long *)op) = scp->linkCount; op += 4; + *op++ = ((fidp->flags & SMB_FID_DELONCLOSE) ? 1 : 0); + *op++ = (scp->fileType == CM_SCACHETYPE_DIRECTORY ? 1 : 0); + *op++ = 0; + *op++ = 0; + } + else if (infoLevel == 0x103) { + *((u_long *)op) = 0; op += 4; + } + else if (infoLevel == 0x104) { + unsigned long len; + char *name; + + if (fidp->NTopen_wholepathp) + name = fidp->NTopen_wholepathp; + else + name = "\\"; /* probably can't happen */ + len = strlen(name); + outp->totalData = (len*2) + 4; /* this is actually what we want to return */ + *((u_long *)op) = len * 2; op += 4; + mbstowcs((unsigned short *)op, name, len); op += (len * 2); + } - /* send and free the packets */ + /* send and free the packets */ done: - lock_ReleaseMutex(&scp->mx); - cm_ReleaseUser(userp); - smb_ReleaseFID(fidp); - if (code == 0) smb_SendTran2Packet(vcp, outp, opx); - else smb_SendTran2Error(vcp, p, opx, code); - smb_FreeTran2Packet(outp); - - return 0; -} + lock_ReleaseMutex(&scp->mx); + cm_ReleaseUser(userp); + smb_ReleaseFID(fidp); + if (code == 0) + smb_SendTran2Packet(vcp, outp, opx); + else + smb_SendTran2Error(vcp, p, opx, code); + smb_FreeTran2Packet(outp); + + return 0; +} long smb_ReceiveTran2SetFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) { - long code = 0; - unsigned short fid; - smb_fid_t *fidp; - unsigned short infoLevel; - smb_tran2Packet_t *outp; - cm_user_t *userp; - cm_scache_t *scp; - cm_req_t req; + long code = 0; + unsigned short fid; + smb_fid_t *fidp; + unsigned short infoLevel; + smb_tran2Packet_t *outp; + cm_user_t *userp; + cm_scache_t *scp; + cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); fid = p->parmsp[0]; - fidp = smb_FindFID(vcp, fid, 0); + fidp = smb_FindFID(vcp, fid, 0); - if (fidp == NULL) { - smb_SendTran2Error(vcp, p, op, CM_ERROR_BADFD); - return 0; - } + if (fidp == NULL) { + smb_SendTran2Error(vcp, p, op, CM_ERROR_BADFD); + return 0; + } - infoLevel = p->parmsp[1]; - if (infoLevel > 0x104 || infoLevel < 0x101) { - osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x", - p->opcode, infoLevel); - smb_SendTran2Error(vcp, p, op, CM_ERROR_INVAL); + infoLevel = p->parmsp[1]; + osi_Log2(smb_logp,"ReceiveTran2SetFileInfo type=[%x] fid=[%x]", infoLevel, fid); + if (infoLevel > 0x104 || infoLevel < 0x101) { + osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x", + p->opcode, infoLevel); + smb_SendTran2Error(vcp, p, op, CM_ERROR_INVAL); smb_ReleaseFID(fidp); - return 0; - } + return 0; + } - if (infoLevel == 0x102 && !(fidp->flags & SMB_FID_OPENDELETE)) { - smb_SendTran2Error(vcp, p, op, CM_ERROR_NOACCESS); + if (infoLevel == 0x102 && !(fidp->flags & SMB_FID_OPENDELETE)) { + smb_SendTran2Error(vcp, p, op, CM_ERROR_NOACCESS); smb_ReleaseFID(fidp); - return 0; - } - if ((infoLevel == 0x103 || infoLevel == 0x104) - && !(fidp->flags & SMB_FID_OPENWRITE)) { - smb_SendTran2Error(vcp, p, op, CM_ERROR_NOACCESS); + return 0; + } + if ((infoLevel == 0x103 || infoLevel == 0x104) + && !(fidp->flags & SMB_FID_OPENWRITE)) { + smb_SendTran2Error(vcp, p, op, CM_ERROR_NOACCESS); smb_ReleaseFID(fidp); - return 0; - } + return 0; + } - osi_Log1(smb_logp, "T2 SFileInfo type 0x%x", infoLevel); + osi_Log1(smb_logp, "T2 SFileInfo type 0x%x", infoLevel); - outp = smb_GetTran2ResponsePacket(vcp, p, op, 2, 0); + outp = smb_GetTran2ResponsePacket(vcp, p, op, 2, 0); - outp->totalParms = 2; - outp->totalData = 0; + outp->totalParms = 2; + outp->totalData = 0; - userp = smb_GetTran2User(vcp, p); + userp = smb_GetTran2User(vcp, p); if (!userp) { osi_Log1(smb_logp,"ReceiveTran2SetFileInfo unable to resolve user [%d]", p->uid); code = CM_ERROR_BADSMB; goto done; - } + } - scp = fidp->scp; + scp = fidp->scp; - if (infoLevel == 0x101) { - FILETIME lastMod; - unsigned int attribute; - cm_attr_t attr; + if (infoLevel == 0x101) { + FILETIME lastMod; + unsigned int attribute; + cm_attr_t attr; - /* lock the vnode with a callback; we need the current status - * to determine what the new status is, in some cases. - */ - lock_ObtainMutex(&scp->mx); - code = cm_SyncOp(scp, NULL, userp, &req, 0, - CM_SCACHESYNC_GETSTATUS + /* lock the vnode with a callback; we need the current status + * to determine what the new status is, in some cases. + */ + lock_ObtainMutex(&scp->mx); + code = cm_SyncOp(scp, NULL, userp, &req, 0, + CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK); - if (code) { - lock_ReleaseMutex(&scp->mx); - goto done; - } + if (code) { + lock_ReleaseMutex(&scp->mx); + goto done; + } - /* prepare for setattr call */ - attr.mask = 0; - - lastMod = *((FILETIME *)(p->datap + 16)); - /* when called as result of move a b, lastMod is (-1, -1). + /* prepare for setattr call */ + attr.mask = 0; + + lastMod = *((FILETIME *)(p->datap + 16)); + /* when called as result of move a b, lastMod is (-1, -1). * If the check for -1 is not present, timestamp - * of the resulting file will be 1969 (-1) - */ - if (LargeIntegerNotEqualToZero(*((LARGE_INTEGER *)&lastMod)) && - lastMod.dwLowDateTime != -1 && lastMod.dwHighDateTime != -1) { - attr.mask |= CM_ATTRMASK_CLIENTMODTIME; - smb_UnixTimeFromLargeSearchTime(&attr.clientModTime, - &lastMod); - fidp->flags |= SMB_FID_MTIMESETDONE; - } + * of the resulting file will be 1969 (-1) + */ + if (LargeIntegerNotEqualToZero(*((LARGE_INTEGER *)&lastMod)) && + lastMod.dwLowDateTime != -1 && lastMod.dwHighDateTime != -1) { + attr.mask |= CM_ATTRMASK_CLIENTMODTIME; + smb_UnixTimeFromLargeSearchTime(&attr.clientModTime, + &lastMod); + fidp->flags |= SMB_FID_MTIMESETDONE; + } - attribute = *((u_long *)(p->datap + 32)); - if (attribute != 0) { - if ((scp->unixModeBits & 0222) - && (attribute & 1) != 0) { - /* make a writable file read-only */ - attr.mask |= CM_ATTRMASK_UNIXMODEBITS; - attr.unixModeBits = scp->unixModeBits & ~0222; - } - else if ((scp->unixModeBits & 0222) == 0 - && (attribute & 1) == 0) { - /* make a read-only file writable */ - attr.mask |= CM_ATTRMASK_UNIXMODEBITS; - attr.unixModeBits = scp->unixModeBits | 0222; - } - } - lock_ReleaseMutex(&scp->mx); - - /* call setattr */ - if (attr.mask) - code = cm_SetAttr(scp, &attr, userp, &req); - else - code = 0; - } - else if (infoLevel == 0x103 || infoLevel == 0x104) { - LARGE_INTEGER size = *((LARGE_INTEGER *)(p->datap)); - cm_attr_t attr; - - attr.mask = CM_ATTRMASK_LENGTH; - attr.length.LowPart = size.LowPart; - attr.length.HighPart = size.HighPart; - code = cm_SetAttr(scp, &attr, userp, &req); - } - else if (infoLevel == 0x102) { - if (*((char *)(p->datap))) { - code = cm_CheckNTDelete(fidp->NTopen_dscp, scp, userp, - &req); - if (code == 0) - fidp->flags |= SMB_FID_DELONCLOSE; - } - else { - code = 0; - fidp->flags &= ~SMB_FID_DELONCLOSE; - } - } + attribute = *((u_long *)(p->datap + 32)); + if (attribute != 0) { + if ((scp->unixModeBits & 0222) + && (attribute & 1) != 0) { + /* make a writable file read-only */ + attr.mask |= CM_ATTRMASK_UNIXMODEBITS; + attr.unixModeBits = scp->unixModeBits & ~0222; + } + else if ((scp->unixModeBits & 0222) == 0 + && (attribute & 1) == 0) { + /* make a read-only file writable */ + attr.mask |= CM_ATTRMASK_UNIXMODEBITS; + attr.unixModeBits = scp->unixModeBits | 0222; + } + } + lock_ReleaseMutex(&scp->mx); + + /* call setattr */ + if (attr.mask) + code = cm_SetAttr(scp, &attr, userp, &req); + else + code = 0; + } + else if (infoLevel == 0x103 || infoLevel == 0x104) { + LARGE_INTEGER size = *((LARGE_INTEGER *)(p->datap)); + cm_attr_t attr; + + attr.mask = CM_ATTRMASK_LENGTH; + attr.length.LowPart = size.LowPart; + attr.length.HighPart = size.HighPart; + code = cm_SetAttr(scp, &attr, userp, &req); + } + else if (infoLevel == 0x102) { + if (*((char *)(p->datap))) { + code = cm_CheckNTDelete(fidp->NTopen_dscp, scp, userp, + &req); + if (code == 0) + fidp->flags |= SMB_FID_DELONCLOSE; + } + else { + code = 0; + fidp->flags &= ~SMB_FID_DELONCLOSE; + } + } + done: - cm_ReleaseUser(userp); - smb_ReleaseFID(fidp); - if (code == 0) smb_SendTran2Packet(vcp, outp, op); - else smb_SendTran2Error(vcp, p, op, code); - smb_FreeTran2Packet(outp); + cm_ReleaseUser(userp); + smb_ReleaseFID(fidp); + if (code == 0) + smb_SendTran2Packet(vcp, outp, op); + else + smb_SendTran2Error(vcp, p, op, code); + smb_FreeTran2Packet(outp); - return 0; + return 0; +} + +long +smb_ReceiveTran2FSCTL(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp) +{ + osi_Log0(smb_logp,"ReceiveTran2FSCTL - NOT_SUPPORTED"); + return CM_ERROR_BADOP; } -long smb_ReceiveTran2FSCTL(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp) +long +smb_ReceiveTran2IOCTL(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp) { + osi_Log0(smb_logp,"ReceiveTran2IOCTL - NOT_SUPPORTED"); return CM_ERROR_BADOP; } -long smb_ReceiveTran2IOCTL(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp) +long +smb_ReceiveTran2FindNotifyFirst(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp) { + osi_Log0(smb_logp,"ReceiveTran2FindNotifyFirst - NOT_SUPPORTED"); return CM_ERROR_BADOP; } -long smb_ReceiveTran2FindNotifyFirst(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp) +long +smb_ReceiveTran2FindNotifyNext(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp) { + osi_Log0(smb_logp,"ReceiveTran2FindNotifyNext - NOT_SUPPORTED"); return CM_ERROR_BADOP; } -long smb_ReceiveTran2FindNotifyNext(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp) +long +smb_ReceiveTran2CreateDirectory(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp) { + osi_Log0(smb_logp,"ReceiveTran2CreateDirectory - NOT_SUPPORTED"); return CM_ERROR_BADOP; } -long smb_ReceiveTran2MKDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp) +long +smb_ReceiveTran2SessionSetup(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp) { + osi_Log0(smb_logp,"ReceiveTran2SessionSetup - NOT_SUPPORTED"); return CM_ERROR_BADOP; } -long smb_ApplyV3DirListPatches(cm_scache_t *dscp, +long +smb_ReceiveTran2GetDFSReferral(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp) +{ + osi_Log0(smb_logp,"ReceiveTran2GetDFSReferral - NOT_SUPPORTED"); + return CM_ERROR_BADOP; +} + +long +smb_ReceiveTran2ReportDFSInconsistency(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp) +{ + osi_Log0(smb_logp,"ReceiveTran2ReportDFSInconsistency - NOT_SUPPORTED"); + return CM_ERROR_BADOP; +} + +long +smb_ApplyV3DirListPatches(cm_scache_t *dscp, smb_dirListPatch_t **dirPatchespp, int infoLevel, cm_user_t *userp, cm_req_t *reqp) { - long code = 0; + long code = 0; cm_scache_t *scp; cm_scache_t *targetScp; /* target if scp is a symlink */ char *dptr; - long dosTime; - FILETIME ft; + time_t dosTime; + FILETIME ft; int shortTemp; unsigned short attr; - unsigned long lattr; + unsigned long lattr; smb_dirListPatch_t *patchp; smb_dirListPatch_t *npatchp; @@ -2995,9 +3053,9 @@ long smb_ApplyV3DirListPatches(cm_scache_t *dscp, lock_ObtainMutex(&scp->mx); code = cm_SyncOp(scp, NULL, userp, reqp, 0, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); - if (code) { - lock_ReleaseMutex(&scp->mx); - cm_ReleaseSCache(scp); + if (code) { + lock_ReleaseMutex(&scp->mx); + cm_ReleaseSCache(scp); dptr = patchp->dptr; @@ -3008,184 +3066,185 @@ long smb_ApplyV3DirListPatches(cm_scache_t *dscp, ft.dwHighDateTime = 0x19DB200; ft.dwLowDateTime = 0x5BB78980; - /* copy to Creation Time */ - *((FILETIME *)dptr) = ft; - dptr += 8; + /* copy to Creation Time */ + *((FILETIME *)dptr) = ft; + dptr += 8; - /* copy to Last Access Time */ - *((FILETIME *)dptr) = ft; - dptr += 8; + /* copy to Last Access Time */ + *((FILETIME *)dptr) = ft; + dptr += 8; - /* copy to Last Write Time */ - *((FILETIME *)dptr) = ft; - dptr += 8; + /* copy to Last Write Time */ + *((FILETIME *)dptr) = ft; + dptr += 8; - /* copy to Change Time */ - *((FILETIME *)dptr) = ft; + /* copy to Change Time */ + *((FILETIME *)dptr) = ft; dptr += 24; /* merge in hidden attribute */ if ( patchp->flags & SMB_DIRLISTPATCH_DOTFILE ) { - *((u_long *)dptr) = SMB_ATTR_HIDDEN; + *((u_long *)dptr) = SMB_ATTR_HIDDEN; } - dptr += 4; + dptr += 4; } else { /* 1969-12-31 23:59:58 +00*/ dosTime = 0xEBBFBF7D; - /* and copy out date */ - shortTemp = (dosTime>>16) & 0xffff; - *((u_short *)dptr) = shortTemp; - dptr += 2; + /* and copy out date */ + shortTemp = (dosTime>>16) & 0xffff; + *((u_short *)dptr) = shortTemp; + dptr += 2; - /* copy out creation time */ - shortTemp = dosTime & 0xffff; - *((u_short *)dptr) = shortTemp; - dptr += 2; + /* copy out creation time */ + shortTemp = dosTime & 0xffff; + *((u_short *)dptr) = shortTemp; + dptr += 2; - /* and copy out date */ - shortTemp = (dosTime>>16) & 0xffff; - *((u_short *)dptr) = shortTemp; - dptr += 2; + /* and copy out date */ + shortTemp = (dosTime>>16) & 0xffff; + *((u_short *)dptr) = shortTemp; + dptr += 2; - /* copy out access time */ - shortTemp = dosTime & 0xffff; - *((u_short *)dptr) = shortTemp; - dptr += 2; - - /* and copy out date */ - shortTemp = (dosTime>>16) & 0xffff; - *((u_short *)dptr) = shortTemp; - dptr += 2; + /* copy out access time */ + shortTemp = dosTime & 0xffff; + *((u_short *)dptr) = shortTemp; + dptr += 2; + + /* and copy out date */ + shortTemp = (dosTime>>16) & 0xffff; + *((u_short *)dptr) = shortTemp; + dptr += 2; - /* copy out mod time */ - shortTemp = dosTime & 0xffff; - *((u_short *)dptr) = shortTemp; - dptr += 10; + /* copy out mod time */ + shortTemp = dosTime & 0xffff; + *((u_short *)dptr) = shortTemp; + dptr += 10; /* merge in hidden (dot file) attribute */ if ( patchp->flags & SMB_DIRLISTPATCH_DOTFILE ) { attr = SMB_ATTR_HIDDEN; - *dptr++ = attr & 0xff; - *dptr++ = (attr >> 8) & 0xff; - } + *dptr++ = attr & 0xff; + *dptr++ = (attr >> 8) & 0xff; + } } - continue; + continue; } /* now watch for a symlink */ - if (scp->fileType == CM_SCACHETYPE_SYMLINK) { - lock_ReleaseMutex(&scp->mx); + code = 0; + while (code == 0 && scp->fileType == CM_SCACHETYPE_SYMLINK) { + lock_ReleaseMutex(&scp->mx); code = cm_EvaluateSymLink(dscp, scp, &targetScp, userp, reqp); if (code == 0) { - /* we have a more accurate file to use (the - * target of the symbolic link). Otherwise, - * we'll just use the symlink anyway. + /* we have a more accurate file to use (the + * target of the symbolic link). Otherwise, + * we'll just use the symlink anyway. */ - osi_Log2(smb_logp, "symlink vp %x to vp %x", - scp, targetScp); - cm_ReleaseSCache(scp); + osi_Log2(smb_logp, "symlink vp %x to vp %x", + scp, targetScp); + cm_ReleaseSCache(scp); scp = targetScp; } lock_ObtainMutex(&scp->mx); } - dptr = patchp->dptr; + dptr = patchp->dptr; - if (infoLevel >= 0x101) { - /* get filetime */ - smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime); + if (infoLevel >= 0x101) { + /* get filetime */ + smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime); - /* copy to Creation Time */ - *((FILETIME *)dptr) = ft; - dptr += 8; + /* copy to Creation Time */ + *((FILETIME *)dptr) = ft; + dptr += 8; - /* copy to Last Access Time */ - *((FILETIME *)dptr) = ft; - dptr += 8; + /* copy to Last Access Time */ + *((FILETIME *)dptr) = ft; + dptr += 8; - /* copy to Last Write Time */ - *((FILETIME *)dptr) = ft; - dptr += 8; + /* copy to Last Write Time */ + *((FILETIME *)dptr) = ft; + dptr += 8; - /* copy to Change Time */ - *((FILETIME *)dptr) = ft; - dptr += 8; + /* copy to Change Time */ + *((FILETIME *)dptr) = ft; + dptr += 8; - /* Use length for both file length and alloc length */ - *((LARGE_INTEGER *)dptr) = scp->length; - dptr += 8; - *((LARGE_INTEGER *)dptr) = scp->length; - dptr += 8; + /* Use length for both file length and alloc length */ + *((LARGE_INTEGER *)dptr) = scp->length; + dptr += 8; + *((LARGE_INTEGER *)dptr) = scp->length; + dptr += 8; - /* Copy attributes */ - lattr = smb_ExtAttributes(scp); + /* Copy attributes */ + lattr = smb_ExtAttributes(scp); /* merge in hidden (dot file) attribute */ - if ( patchp->flags & SMB_DIRLISTPATCH_DOTFILE ) - lattr |= SMB_ATTR_HIDDEN; - *((u_long *)dptr) = lattr; - dptr += 4; - } - else { - /* get dos time */ - smb_SearchTimeFromUnixTime(&dosTime, scp->clientModTime); - - /* and copy out date */ - shortTemp = (dosTime>>16) & 0xffff; - *((u_short *)dptr) = shortTemp; - dptr += 2; - - /* copy out creation time */ - shortTemp = dosTime & 0xffff; - *((u_short *)dptr) = shortTemp; - dptr += 2; - - /* and copy out date */ - shortTemp = (dosTime>>16) & 0xffff; - *((u_short *)dptr) = shortTemp; - dptr += 2; - - /* copy out access time */ - shortTemp = dosTime & 0xffff; - *((u_short *)dptr) = shortTemp; - dptr += 2; - - /* and copy out date */ - shortTemp = (dosTime>>16) & 0xffff; - *((u_short *)dptr) = shortTemp; - dptr += 2; - - /* copy out mod time */ - shortTemp = dosTime & 0xffff; - *((u_short *)dptr) = shortTemp; - dptr += 2; - - /* copy out file length and alloc length, - * using the same for both - */ - *((u_long *)dptr) = scp->length.LowPart; - dptr += 4; - *((u_long *)dptr) = scp->length.LowPart; - dptr += 4; - - /* finally copy out attributes as short */ - attr = smb_Attributes(scp); + if ( patchp->flags & SMB_DIRLISTPATCH_DOTFILE ) + lattr |= SMB_ATTR_HIDDEN; + *((u_long *)dptr) = lattr; + dptr += 4; + } + else { + /* get dos time */ + smb_SearchTimeFromUnixTime(&dosTime, scp->clientModTime); + + /* and copy out date */ + shortTemp = (dosTime>>16) & 0xffff; + *((u_short *)dptr) = shortTemp; + dptr += 2; + + /* copy out creation time */ + shortTemp = dosTime & 0xffff; + *((u_short *)dptr) = shortTemp; + dptr += 2; + + /* and copy out date */ + shortTemp = (dosTime>>16) & 0xffff; + *((u_short *)dptr) = shortTemp; + dptr += 2; + + /* copy out access time */ + shortTemp = dosTime & 0xffff; + *((u_short *)dptr) = shortTemp; + dptr += 2; + + /* and copy out date */ + shortTemp = (dosTime>>16) & 0xffff; + *((u_short *)dptr) = shortTemp; + dptr += 2; + + /* copy out mod time */ + shortTemp = dosTime & 0xffff; + *((u_short *)dptr) = shortTemp; + dptr += 2; + + /* copy out file length and alloc length, + * using the same for both + */ + *((u_long *)dptr) = scp->length.LowPart; + dptr += 4; + *((u_long *)dptr) = scp->length.LowPart; + dptr += 4; + + /* finally copy out attributes as short */ + attr = smb_Attributes(scp); /* merge in hidden (dot file) attribute */ if ( patchp->flags & SMB_DIRLISTPATCH_DOTFILE ) attr |= SMB_ATTR_HIDDEN; - *dptr++ = attr & 0xff; - *dptr++ = (attr >> 8) & 0xff; - } + *dptr++ = attr & 0xff; + *dptr++ = (attr >> 8) & 0xff; + } lock_ReleaseMutex(&scp->mx); cm_ReleaseSCache(scp); - } + } /* now free the patches */ - for(patchp = *dirPatchespp; patchp; patchp = npatchp) { - npatchp = (smb_dirListPatch_t *) osi_QNext(&patchp->q); + for (patchp = *dirPatchespp; patchp; patchp = npatchp) { + npatchp = (smb_dirListPatch_t *) osi_QNext(&patchp->q); free(patchp); - } + } /* and mark the list as empty */ *dirPatchespp = NULL; @@ -3219,40 +3278,41 @@ VOID initUpperCaseTable(VOID) // Return value // BOOL : TRUE/FALSE (match/mistmatch) -BOOL szWildCardMatchFileName(PSZ pattern, PSZ name) { - PSZ pename; // points to the last 'name' character - PSZ p; - pename = name + strlen(name) - 1; - while (*name) { - switch (*pattern) { - case '?': - case '>': - if (*(++pattern) != '<' || *(++pattern) != '*') { - if (*name == '.') - return FALSE; - ++name; - break; - } /* endif */ - case '<': +BOOL +szWildCardMatchFileName(PSZ pattern, PSZ name) +{ + PSZ pename; // points to the last 'name' character + PSZ p; + pename = name + strlen(name) - 1; + while (*name) { + switch (*pattern) { + case '?': + if (*name == '.') + return FALSE; + ++pattern, ++name; + break; case '*': - while ((*pattern == '<') || (*pattern == '*') || (*pattern == '?') || (*pattern == '>')) - ++pattern; - if (!*pattern) + ++pattern; + if (*pattern == '\0') return TRUE; for (p = pename; p >= name; --p) { - if ((mapCaseTable[*p] == mapCaseTable[*pattern]) && - szWildCardMatchFileName(pattern + 1, p + 1)) - return TRUE; + if ((mapCaseTable[*p] == mapCaseTable[*pattern]) && + szWildCardMatchFileName(pattern + 1, p + 1)) + return TRUE; } /* endfor */ return FALSE; - default: + default: if (mapCaseTable[*name] != mapCaseTable[*pattern]) return FALSE; ++pattern, ++name; break; - } /* endswitch */ - } /* endwhile */ - return !*pattern; + } /* endswitch */ + } /* endwhile */ + + if (*pattern == '\0' || *pattern == '*' && *(pattern+1) == '\0') + return TRUE; + else + return FALSE; } /* do a case-folding search of the star name mask with the name in namep. @@ -3260,11 +3320,53 @@ BOOL szWildCardMatchFileName(PSZ pattern, PSZ name) { */ int smb_V3MatchMask(char *namep, char *maskp, int flags) { - /* make sure we only match 8.3 names, if requested */ - if ((flags & CM_FLAG_8DOT3) && !cm_Is8Dot3(namep)) + char * newmask; + int i, j, star, qmark, retval; + + /* make sure we only match 8.3 names, if requested */ + if ((flags & CM_FLAG_8DOT3) && !cm_Is8Dot3(namep)) return 0; - - return szWildCardMatchFileName(maskp, namep) ? 1:0; + + /* optimize the pattern: + * if there is a mixture of '?' and '*', + * for example the sequence "*?*?*?*" + * must be turned into the form "*" + */ + newmask = (char *)malloc(strlen(maskp)+1); + for ( i=0, j=0, star=0, qmark=0; maskp[i]; i++) { + switch ( maskp[i] ) { + case '?': + case '>': + qmark++; + break; + case '<': + case '*': + star++; + break; + default: + if ( star ) { + newmask[j++] = '*'; + } else if ( qmark ) { + while ( qmark-- ) + newmask[j++] = '?'; + } + newmask[j++] = maskp[i]; + star = 0; + qmark = 0; + } + } + if ( star ) { + newmask[j++] = '*'; + } else if ( qmark ) { + while ( qmark-- ) + newmask[j++] = '?'; + } + newmask[j++] = '\0'; + + retval = szWildCardMatchFileName(newmask, namep) ? 1:0; + + free(newmask); + return retval; } #else /* USE_OLD_MATCHING */ @@ -3273,143 +3375,143 @@ int smb_V3MatchMask(char *namep, char *maskp, int flags) */ int smb_V3MatchMask(char *namep, char *maskp, int flags) { - unsigned char tcp1, tcp2; /* Pattern characters */ + unsigned char tcp1, tcp2; /* Pattern characters */ unsigned char tcn1; /* Name characters */ - int sawDot = 0, sawStar = 0, req8dot3 = 0; - char *starNamep, *starMaskp; - static char nullCharp[] = {0}; + int sawDot = 0, sawStar = 0, req8dot3 = 0; + char *starNamep, *starMaskp; + static char nullCharp[] = {0}; int casefold = flags & CM_FLAG_CASEFOLD; - /* make sure we only match 8.3 names, if requested */ + /* make sure we only match 8.3 names, if requested */ req8dot3 = (flags & CM_FLAG_8DOT3); - if (req8dot3 && !cm_Is8Dot3(namep)) + if (req8dot3 && !cm_Is8Dot3(namep)) return 0; - /* loop */ - while (1) { - /* Next pattern character */ - tcp1 = *maskp++; - - /* Next name character */ - tcn1 = *namep; - - if (tcp1 == 0) { - /* 0 - end of pattern */ - if (tcn1 == 0) - return 1; - else - return 0; - } - else if (tcp1 == '.' || tcp1 == '"') { - if (sawDot) { - if (tcn1 == '.') { - namep++; - continue; - } else - return 0; - } - else { - /* - * first dot in pattern; - * must match dot or end of name - */ - sawDot = 1; - if (tcn1 == 0) - continue; - else if (tcn1 == '.') { - sawStar = 0; - namep++; - continue; - } - else - return 0; - } - } - else if (tcp1 == '?') { - if (tcn1 == 0 || tcn1 == '.') - return 0; - namep++; - continue; - } - else if (tcp1 == '>') { - if (tcn1 != 0 && tcn1 != '.') - namep++; - continue; - } - else if (tcp1 == '*' || tcp1 == '<') { - tcp2 = *maskp++; - if (tcp2 == 0) - return 1; - else if ((req8dot3 && tcp2 == '.') || tcp2 == '"') { - while (req8dot3 && tcn1 != '.' && tcn1 != 0) - tcn1 = *++namep; - if (tcn1 == 0) { - if (sawDot) - return 0; - else - continue; - } - else { - namep++; - continue; - } - } - else { - /* - * pattern character after '*' is not null or - * period. If it is '?' or '>', we are not - * going to understand it. If it is '*' or - * '<', we are going to skip over it. None of - * these are likely, I hope. - */ - /* skip over '*' and '<' */ - while (tcp2 == '*' || tcp2 == '<') - tcp2 = *maskp++; - - /* skip over characters that don't match tcp2 */ - while (req8dot3 && tcn1 != '.' && tcn1 != 0 && - ((casefold && cm_foldUpper[tcn1] != cm_foldUpper[tcp2]) || - (!casefold && tcn1 != tcp2))) - tcn1 = *++namep; - - /* No match */ - if ((req8dot3 && tcn1 == '.') || tcn1 == 0) - return 0; - - /* Remember where we are */ - sawStar = 1; - starMaskp = maskp; - starNamep = namep; - - namep++; - continue; - } - } - else { - /* tcp1 is not a wildcard */ + /* loop */ + while (1) { + /* Next pattern character */ + tcp1 = *maskp++; + + /* Next name character */ + tcn1 = *namep; + + if (tcp1 == 0) { + /* 0 - end of pattern */ + if (tcn1 == 0) + return 1; + else + return 0; + } + else if (tcp1 == '.' || tcp1 == '"') { + if (sawDot) { + if (tcn1 == '.') { + namep++; + continue; + } else + return 0; + } + else { + /* + * first dot in pattern; + * must match dot or end of name + */ + sawDot = 1; + if (tcn1 == 0) + continue; + else if (tcn1 == '.') { + sawStar = 0; + namep++; + continue; + } + else + return 0; + } + } + else if (tcp1 == '?') { + if (tcn1 == 0 || tcn1 == '.') + return 0; + namep++; + continue; + } + else if (tcp1 == '>') { + if (tcn1 != 0 && tcn1 != '.') + namep++; + continue; + } + else if (tcp1 == '*' || tcp1 == '<') { + tcp2 = *maskp++; + if (tcp2 == 0) + return 1; + else if ((req8dot3 && tcp2 == '.') || tcp2 == '"') { + while (req8dot3 && tcn1 != '.' && tcn1 != 0) + tcn1 = *++namep; + if (tcn1 == 0) { + if (sawDot) + return 0; + else + continue; + } + else { + namep++; + continue; + } + } + else { + /* + * pattern character after '*' is not null or + * period. If it is '?' or '>', we are not + * going to understand it. If it is '*' or + * '<', we are going to skip over it. None of + * these are likely, I hope. + */ + /* skip over '*' and '<' */ + while (tcp2 == '*' || tcp2 == '<') + tcp2 = *maskp++; + + /* skip over characters that don't match tcp2 */ + while (req8dot3 && tcn1 != '.' && tcn1 != 0 && + ((casefold && cm_foldUpper[tcn1] != cm_foldUpper[tcp2]) || + (!casefold && tcn1 != tcp2))) + tcn1 = *++namep; + + /* No match */ + if ((req8dot3 && tcn1 == '.') || tcn1 == 0) + return 0; + + /* Remember where we are */ + sawStar = 1; + starMaskp = maskp; + starNamep = namep; + + namep++; + continue; + } + } + else { + /* tcp1 is not a wildcard */ if ((casefold && cm_foldUpper[tcn1] == cm_foldUpper[tcp1]) || - (!casefold && tcn1 == tcp1)) { - /* they match */ - namep++; - continue; - } - /* if trying to match a star pattern, go back */ - if (sawStar) { - maskp = starMaskp - 2; - namep = starNamep + 1; - sawStar = 0; - continue; - } - /* that's all */ - return 0; - } - } + (!casefold && tcn1 == tcp1)) { + /* they match */ + namep++; + continue; + } + /* if trying to match a star pattern, go back */ + if (sawStar) { + maskp = starMaskp - 2; + namep = starNamep + 1; + sawStar = 0; + continue; + } + /* that's all */ + return 0; + } + } } #endif /* USE_OLD_MATCHING */ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *opx) { - int attribute; + int attribute; long nextCookie; char *tp; long code = 0; @@ -3431,14 +3533,14 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t cm_scache_t *scp; long entryInDir; long entryInBuffer; - cm_pageHeader_t *pageHeaderp; + cm_pageHeader_t *pageHeaderp; cm_user_t *userp = NULL; int slotInPage; int returnedNames; long nextEntryCookie; int numDirChunks; /* # of 32 byte dir chunks in this entry */ char *op; /* output data ptr */ - char *origOp; /* original value of op */ + char *origOp; /* original value of op */ cm_space_t *spacep; /* for pathname buffer */ long maxReturnData; /* max # of return data */ long maxReturnParms; /* max # of return parms */ @@ -3449,22 +3551,21 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t int searchFlags; int eos; smb_tran2Packet_t *outp; /* response packet */ - char *tidPathp; - int align; - char shortName[13]; /* 8.3 name if needed */ - int NeedShortName; + char *tidPathp; + int align; + char shortName[13]; /* 8.3 name if needed */ + int NeedShortName; int foundInexact; - char *shortNameEnd; + char *shortNameEnd; int fileType; cm_fid_t fid; - cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); - eos = 0; - if (p->opcode == 1) { - /* find first; obtain basic parameters from request */ + eos = 0; + if (p->opcode == 1) { + /* find first; obtain basic parameters from request */ attribute = p->parmsp[0]; maxCount = p->parmsp[1]; infoLevel = p->parmsp[3]; @@ -3475,13 +3576,13 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t nextCookie = 0; maskp = strrchr(pathp, '\\'); if (maskp == NULL) maskp = pathp; - else maskp++; /* skip over backslash */ + else maskp++; /* skip over backslash */ strcpy(dsp->mask, maskp); /* and save mask */ - /* track if this is likely to match a lot of entries */ + /* track if this is likely to match a lot of entries */ starPattern = smb_V3IsStarMask(maskp); - } + } else { - osi_assert(p->opcode == 2); + osi_assert(p->opcode == 2); /* find next; obtain basic parameters from request or open dir file */ dsp = smb_FindDirSearch(p->parmsp[0]); if (!dsp) return CM_ERROR_BADFD; @@ -3492,25 +3593,25 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t pathp = NULL; nextCookie = p->parmsp[3] | (p->parmsp[4] << 16); maskp = dsp->mask; - starPattern = 1; /* assume, since required a Find Next */ + starPattern = 1; /* assume, since required a Find Next */ } - osi_Log4(smb_logp, + osi_Log4(smb_logp, "T2 search dir attr 0x%x, info level %d, max count %d, flags 0x%x", attribute, infoLevel, maxCount, searchFlags); - osi_Log2(smb_logp, "...T2 search op %d, nextCookie 0x%x", + osi_Log2(smb_logp, "...T2 search op %d, nextCookie 0x%x", p->opcode, nextCookie); - if (infoLevel >= 0x101) - searchFlags &= ~4; /* no resume keys */ + if (infoLevel >= 0x101) + searchFlags &= ~4; /* no resume keys */ dirListPatchesp = NULL; - maxReturnData = p->maxReturnData; + maxReturnData = p->maxReturnData; if (p->opcode == 1) /* find first */ maxReturnParms = 10; /* bytes */ - else + else maxReturnParms = 8; /* bytes */ #ifndef CM_CONFIG_MULTITRAN2RESPONSES @@ -3518,7 +3619,7 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t maxReturnData = 6000; #endif /* CM_CONFIG_MULTITRAN2RESPONSES */ - outp = smb_GetTran2ResponsePacket(vcp, p, opx, maxReturnParms, + outp = smb_GetTran2ResponsePacket(vcp, p, opx, maxReturnParms, maxReturnData); osi_Log1(smb_logp, "T2 receive search dir %s", @@ -3531,10 +3632,10 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t return CM_ERROR_BADSMB; } - osi_Log2(smb_logp, "T2 dir search cookie 0x%x, connection %d", + osi_Log2(smb_logp, "T2 dir search cookie 0x%x, connection %d", nextCookie, dsp->cookie); - userp = smb_GetTran2User(vcp, p); + userp = smb_GetTran2User(vcp, p); if (!userp) { osi_Log1(smb_logp, "T2 dir search unable to resolve user [%d]", p->uid); smb_ReleaseDirSearch(dsp); @@ -3542,25 +3643,25 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t return CM_ERROR_BADSMB; } - /* try to get the vnode for the path name next */ - lock_ObtainMutex(&dsp->mx); - if (dsp->scp) { - scp = dsp->scp; + /* try to get the vnode for the path name next */ + lock_ObtainMutex(&dsp->mx); + if (dsp->scp) { + scp = dsp->scp; cm_HoldSCache(scp); code = 0; } else { - spacep = cm_GetSpace(); + spacep = cm_GetSpace(); smb_StripLastComponent(spacep->data, NULL, pathp); lock_ReleaseMutex(&dsp->mx); - code = smb_LookupTIDPath(vcp, p->tid, &tidPathp); - if(code) { - cm_ReleaseUser(userp); + code = smb_LookupTIDPath(vcp, p->tid, &tidPathp); + if (code) { + cm_ReleaseUser(userp); smb_SendTran2Error(vcp, p, opx, CM_ERROR_NOFILES); smb_FreeTran2Packet(outp); - smb_DeleteDirSearch(dsp); - smb_ReleaseDirSearch(dsp); + smb_DeleteDirSearch(dsp); + smb_ReleaseDirSearch(dsp); return 0; } code = cm_NameI(cm_rootSCachep, spacep->data, @@ -3569,45 +3670,45 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t cm_FreeSpace(spacep); lock_ObtainMutex(&dsp->mx); - if (code == 0) { + if (code == 0) { if (dsp->scp != 0) cm_ReleaseSCache(dsp->scp); - dsp->scp = scp; - /* we need one hold for the entry we just stored into, + dsp->scp = scp; + /* we need one hold for the entry we just stored into, * and one for our own processing. When we're done - * with this function, we'll drop the one for our own - * processing. We held it once from the namei call, - * and so we do another hold now. + * with this function, we'll drop the one for our own + * processing. We held it once from the namei call, + * and so we do another hold now. */ cm_HoldSCache(scp); - lock_ObtainMutex(&scp->mx); - if ((scp->flags & CM_SCACHEFLAG_BULKSTATTING) == 0 - && LargeIntegerGreaterOrEqualToZero(scp->bulkStatProgress)) { + lock_ObtainMutex(&scp->mx); + if ((scp->flags & CM_SCACHEFLAG_BULKSTATTING) == 0 && + LargeIntegerGreaterOrEqualToZero(scp->bulkStatProgress)) { scp->flags |= CM_SCACHEFLAG_BULKSTATTING; - dsp->flags |= SMB_DIRSEARCH_BULKST; - } - lock_ReleaseMutex(&scp->mx); - } + dsp->flags |= SMB_DIRSEARCH_BULKST; + } + lock_ReleaseMutex(&scp->mx); + } } - lock_ReleaseMutex(&dsp->mx); + lock_ReleaseMutex(&dsp->mx); if (code) { - cm_ReleaseUser(userp); + cm_ReleaseUser(userp); smb_FreeTran2Packet(outp); - smb_DeleteDirSearch(dsp); - smb_ReleaseDirSearch(dsp); + smb_DeleteDirSearch(dsp); + smb_ReleaseDirSearch(dsp); return code; - } + } /* get the directory size */ - lock_ObtainMutex(&scp->mx); + lock_ObtainMutex(&scp->mx); code = cm_SyncOp(scp, NULL, userp, &req, 0, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); - if (code) { - lock_ReleaseMutex(&scp->mx); + if (code) { + lock_ReleaseMutex(&scp->mx); cm_ReleaseSCache(scp); cm_ReleaseUser(userp); smb_FreeTran2Packet(outp); - smb_DeleteDirSearch(dsp); - smb_ReleaseDirSearch(dsp); + smb_DeleteDirSearch(dsp); + smb_ReleaseDirSearch(dsp); return code; } @@ -3617,31 +3718,31 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t bufferOffset.LowPart = bufferOffset.HighPart = 0; curOffset.HighPart = 0; curOffset.LowPart = nextCookie; - origOp = outp->datap; + origOp = outp->datap; foundInexact = 0; code = 0; returnedNames = 0; bytesInBuffer = 0; while (1) { - op = origOp; - if (searchFlags & 4) - /* skip over resume key */ - op += 4; + op = origOp; + if (searchFlags & 4) + /* skip over resume key */ + op += 4; - /* make sure that curOffset.LowPart doesn't point to the first + /* make sure that curOffset.LowPart doesn't point to the first * 32 bytes in the 2nd through last dir page, and that it doesn't * point at the first 13 32-byte chunks in the first dir page, * since those are dir and page headers, and don't contain useful * information. */ - temp = curOffset.LowPart & (2048-1); + temp = curOffset.LowPart & (2048-1); if (curOffset.HighPart == 0 && curOffset.LowPart < 2048) { - /* we're in the first page */ + /* we're in the first page */ if (temp < 13*32) temp = 13*32; - } - else { - /* we're in a later dir page */ + } + else { + /* we're in a later dir page */ if (temp < 32) temp = 32; } @@ -3674,35 +3775,35 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t thyper.HighPart = curOffset.HighPart; thyper.LowPart = curOffset.LowPart & ~(buf_bufferSize-1); if (!bufferp || !LargeIntegerEqualTo(thyper, bufferOffset)) { - /* wrong buffer */ + /* wrong buffer */ if (bufferp) { buf_Release(bufferp); bufferp = NULL; - } - lock_ReleaseMutex(&scp->mx); - lock_ObtainRead(&scp->bufCreateLock); + } + lock_ReleaseMutex(&scp->mx); + lock_ObtainRead(&scp->bufCreateLock); code = buf_Get(scp, &thyper, &bufferp); - lock_ReleaseRead(&scp->bufCreateLock); + lock_ReleaseRead(&scp->bufCreateLock); - /* now, if we're doing a star match, do bulk fetching - * of all of the status info for files in the dir. + /* now, if we're doing a star match, do bulk fetching + * of all of the status info for files in the dir. */ if (starPattern) { - smb_ApplyV3DirListPatches(scp, &dirListPatchesp, - infoLevel, userp, - &req); - if ((dsp->flags & SMB_DIRSEARCH_BULKST) - && LargeIntegerGreaterThanOrEqualTo(thyper, scp->bulkStatProgress)) { - /* Don't bulk stat if risking timeout */ - int now = GetCurrentTime(); - if (now - req.startTime > 5000) { - scp->bulkStatProgress = thyper; - scp->flags &= ~CM_SCACHEFLAG_BULKSTATTING; - dsp->flags &= ~SMB_DIRSEARCH_BULKST; - } else + smb_ApplyV3DirListPatches(scp, &dirListPatchesp, + infoLevel, userp, + &req); + if ((dsp->flags & SMB_DIRSEARCH_BULKST) && + LargeIntegerGreaterThanOrEqualTo(thyper, scp->bulkStatProgress)) { + /* Don't bulk stat if risking timeout */ + int now = GetCurrentTime(); + if (now - req.startTime > 5000) { + scp->bulkStatProgress = thyper; + scp->flags &= ~CM_SCACHEFLAG_BULKSTATTING; + dsp->flags &= ~SMB_DIRSEARCH_BULKST; + } else cm_TryBulkStat(scp, &thyper, userp, &req); - } - } + } + } lock_ObtainMutex(&scp->mx); if (code) break; @@ -3710,11 +3811,11 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t /* now get the data in the cache */ while (1) { - code = cm_SyncOp(scp, bufferp, userp, &req, + code = cm_SyncOp(scp, bufferp, userp, &req, PRSFS_LOOKUP, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ); - if (code) break; + if (code) break; if (cm_HaveBuffer(scp, bufferp, 0)) break; @@ -3724,70 +3825,70 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t if (code) break; } if (code) { - buf_Release(bufferp); + buf_Release(bufferp); bufferp = NULL; break; - } + } } /* if (wrong buffer) ... */ /* now we have the buffer containing the entry we're interested * in; copy it out if it represents a non-deleted entry. */ - entryInDir = curOffset.LowPart & (2048-1); + entryInDir = curOffset.LowPart & (2048-1); entryInBuffer = curOffset.LowPart & (buf_bufferSize - 1); - /* page header will help tell us which entries are free. Page - * header can change more often than once per buffer, since - * AFS 3 dir page size may be less than (but not more than) - * a buffer package buffer. + /* page header will help tell us which entries are free. Page + * header can change more often than once per buffer, since + * AFS 3 dir page size may be less than (but not more than) + * a buffer package buffer. */ - /* only look intra-buffer */ - temp = curOffset.LowPart & (buf_bufferSize - 1); + /* only look intra-buffer */ + temp = curOffset.LowPart & (buf_bufferSize - 1); temp &= ~(2048 - 1); /* turn off intra-page bits */ - pageHeaderp = (cm_pageHeader_t *) (bufferp->datap + temp); + pageHeaderp = (cm_pageHeader_t *) (bufferp->datap + temp); - /* now determine which entry we're looking at in the page. - * If it is free (there's a free bitmap at the start of the - * dir), we should skip these 32 bytes. + /* now determine which entry we're looking at in the page. + * If it is free (there's a free bitmap at the start of the + * dir), we should skip these 32 bytes. */ slotInPage = (entryInDir & 0x7e0) >> 5; - if (!(pageHeaderp->freeBitmap[slotInPage>>3] - & (1 << (slotInPage & 0x7)))) { - /* this entry is free */ + if (!(pageHeaderp->freeBitmap[slotInPage>>3] & + (1 << (slotInPage & 0x7)))) { + /* this entry is free */ numDirChunks = 1; /* only skip this guy */ goto nextEntry; } - tp = bufferp->datap + entryInBuffer; + tp = bufferp->datap + entryInBuffer; dep = (cm_dirEntry_t *) tp; /* now points to AFS3 dir entry */ /* while we're here, compute the next entry's location, too, - * since we'll need it when writing out the cookie into the dir - * listing stream. + * since we'll need it when writing out the cookie into the dir + * listing stream. * * XXXX Probably should do more sanity checking. */ - numDirChunks = cm_NameEntries(dep->name, &onbytes); + numDirChunks = cm_NameEntries(dep->name, &onbytes); /* compute offset of cookie representing next entry */ nextEntryCookie = curOffset.LowPart + (CM_DIR_CHUNKSIZE * numDirChunks); - /* Need 8.3 name? */ - NeedShortName = 0; - if (infoLevel == 0x104 - && dep->fid.vnode != 0 - && !cm_Is8Dot3(dep->name)) { - cm_Gen8Dot3Name(dep, shortName, &shortNameEnd); - NeedShortName = 1; - } + /* Need 8.3 name? */ + NeedShortName = 0; + if (infoLevel == 0x104 + && dep->fid.vnode != 0 + && !cm_Is8Dot3(dep->name)) { + cm_Gen8Dot3Name(dep, shortName, &shortNameEnd); + NeedShortName = 1; + } /* When matching, we are using doing a case fold if we have a wildcard mask. * If we get a non-wildcard match, it's a lookup for a specific file. */ if (dep->fid.vnode != 0 && - (smb_V3MatchMask(dep->name, maskp, (starPattern? CM_FLAG_CASEFOLD : 0)) - || (NeedShortName - && smb_V3MatchMask(shortName, maskp, CM_FLAG_CASEFOLD)))) { + (smb_V3MatchMask(dep->name, maskp, (starPattern? CM_FLAG_CASEFOLD : 0)) || + (NeedShortName && + smb_V3MatchMask(shortName, maskp, CM_FLAG_CASEFOLD)))) { /* Eliminate entries that don't match requested attributes */ if (smb_hideDotFiles && !(dsp->attribute & SMB_ATTR_HIDDEN) && @@ -3809,132 +3910,131 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t goto nextEntry; } - /* finally check if this name will fit */ + /* finally check if this name will fit */ - /* standard dir entry stuff */ - if (infoLevel < 0x101) - ohbytes = 23; /* pre-NT */ - else if (infoLevel == 0x103) - ohbytes = 12; /* NT names only */ - else - ohbytes = 64; /* NT */ + /* standard dir entry stuff */ + if (infoLevel < 0x101) + ohbytes = 23; /* pre-NT */ + else if (infoLevel == 0x103) + ohbytes = 12; /* NT names only */ + else + ohbytes = 64; /* NT */ - if (infoLevel == 0x104) - ohbytes += 26; /* Short name & length */ + if (infoLevel == 0x104) + ohbytes += 26; /* Short name & length */ if (searchFlags & 4) { ohbytes += 4; /* if resume key required */ - } + } if (infoLevel != 1 && infoLevel != 0x101 && infoLevel != 0x103) - ohbytes += 4; /* EASIZE */ + ohbytes += 4; /* EASIZE */ - /* add header to name & term. null */ - orbytes = onbytes + ohbytes + 1; + /* add header to name & term. null */ + orbytes = onbytes + ohbytes + 1; - /* now, we round up the record to a 4 byte alignment, - * and we make sure that we have enough room here for - * even the aligned version (so we don't have to worry - * about an * overflow when we pad things out below). - * That's the reason for the alignment arithmetic below. + /* now, we round up the record to a 4 byte alignment, + * and we make sure that we have enough room here for + * even the aligned version (so we don't have to worry + * about an * overflow when we pad things out below). + * That's the reason for the alignment arithmetic below. */ - if (infoLevel >= 0x101) - align = (4 - (orbytes & 3)) & 3; - else - align = 0; - if (orbytes + bytesInBuffer + align > maxReturnData) + if (infoLevel >= 0x101) + align = (4 - (orbytes & 3)) & 3; + else + align = 0; + if (orbytes + bytesInBuffer + align > maxReturnData) break; - /* this is one of the entries to use: it is not deleted - * and it matches the star pattern we're looking for. - * Put out the name, preceded by its length. + /* this is one of the entries to use: it is not deleted + * and it matches the star pattern we're looking for. + * Put out the name, preceded by its length. */ - /* First zero everything else */ - memset(origOp, 0, ohbytes); + /* First zero everything else */ + memset(origOp, 0, ohbytes); - if (infoLevel <= 0x101) + if (infoLevel <= 0x101) *(origOp + ohbytes - 1) = (unsigned char) onbytes; - else if (infoLevel == 0x103) - *((u_long *)(op + 8)) = onbytes; - else - *((u_long *)(op + 60)) = onbytes; + else if (infoLevel == 0x103) + *((u_long *)(op + 8)) = onbytes; + else + *((u_long *)(op + 60)) = onbytes; strcpy(origOp+ohbytes, dep->name); - /* Short name if requested and needed */ + /* Short name if requested and needed */ if (infoLevel == 0x104) { - if (NeedShortName) { - strcpy(op + 70, shortName); - *(op + 68) = shortNameEnd - shortName; - } - } + if (NeedShortName) { + strcpy(op + 70, shortName); + *(op + 68) = shortNameEnd - shortName; + } + } /* now, adjust the # of entries copied */ returnedNames++; - /* NextEntryOffset and FileIndex */ - if (infoLevel >= 101) { - int entryOffset = orbytes + align; - *((u_long *)op) = entryOffset; - *((u_long *)(op+4)) = nextEntryCookie; - } + /* NextEntryOffset and FileIndex */ + if (infoLevel >= 101) { + int entryOffset = orbytes + align; + *((u_long *)op) = entryOffset; + *((u_long *)(op+4)) = nextEntryCookie; + } /* now we emit the attribute. This is tricky, since * we need to really stat the file to find out what - * type of entry we've got. Right now, we're copying - * out data from * a buffer, while holding the scp - * locked, so it isn't really convenient to stat - * something now. We'll put in a place holder + * type of entry we've got. Right now, we're copying + * out data from * a buffer, while holding the scp + * locked, so it isn't really convenient to stat + * something now. We'll put in a place holder * now, and make a second pass before returning this - * to get the real attributes. So, we just skip the - * data for now, and adjust it later. We allocate a - * patch record to make it easy to find this point - * later. The replay will happen at a time when it is - * safe to unlock the directory. + * to get the real attributes. So, we just skip the + * data for now, and adjust it later. We allocate a + * patch record to make it easy to find this point + * later. The replay will happen at a time when it is + * safe to unlock the directory. */ - if (infoLevel != 0x103) { - curPatchp = malloc(sizeof(*curPatchp)); + if (infoLevel != 0x103) { + curPatchp = malloc(sizeof(*curPatchp)); osi_QAdd((osi_queue_t **) &dirListPatchesp, &curPatchp->q); - curPatchp->dptr = op; - if (infoLevel >= 0x101) - curPatchp->dptr += 8; + curPatchp->dptr = op; + if (infoLevel >= 0x101) + curPatchp->dptr += 8; if (smb_hideDotFiles && smb_IsDotFile(dep->name)) { curPatchp->flags = SMB_DIRLISTPATCH_DOTFILE; - } - else + } + else curPatchp->flags = 0; - curPatchp->fid.cell = scp->fid.cell; - curPatchp->fid.volume = scp->fid.volume; - curPatchp->fid.vnode = ntohl(dep->fid.vnode); - curPatchp->fid.unique = ntohl(dep->fid.unique); + curPatchp->fid.cell = scp->fid.cell; + curPatchp->fid.volume = scp->fid.volume; + curPatchp->fid.vnode = ntohl(dep->fid.vnode); + curPatchp->fid.unique = ntohl(dep->fid.unique); /* temp */ curPatchp->dep = dep; - } + } - if (searchFlags & 4) - /* put out resume key */ - *((u_long *)origOp) = nextEntryCookie; + if (searchFlags & 4) + /* put out resume key */ + *((u_long *)origOp) = nextEntryCookie; - /* Adjust byte ptr and count */ - origOp += orbytes; /* skip entire record */ + /* Adjust byte ptr and count */ + origOp += orbytes; /* skip entire record */ bytesInBuffer += orbytes; - /* and pad the record out */ + /* and pad the record out */ while (--align >= 0) { - *origOp++ = 0; + *origOp++ = 0; bytesInBuffer++; } - - } /* if we're including this name */ + } /* if we're including this name */ else if (!NeedShortName && !starPattern && !foundInexact && - dep->fid.vnode != 0 && + dep->fid.vnode != 0 && smb_V3MatchMask(dep->name, maskp, CM_FLAG_CASEFOLD)) { /* We were looking for exact matches, but here's an inexact one*/ foundInexact = 1; @@ -3942,10 +4042,10 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t nextEntry: /* and adjust curOffset to be where the new cookie is */ - thyper.HighPart = 0; + thyper.HighPart = 0; thyper.LowPart = CM_DIR_CHUNKSIZE * numDirChunks; curOffset = LargeIntegerAdd(thyper, curOffset); - } /* while copying data for dir listing */ + } /* while copying data for dir listing */ /* If we didn't get a star pattern, we did an exact match during the first pass. * If there were no exact matches found, we fail over to inexact matches by @@ -3958,20 +4058,20 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t goto startsearch; } - /* release the mutex */ - lock_ReleaseMutex(&scp->mx); + /* release the mutex */ + lock_ReleaseMutex(&scp->mx); if (bufferp) buf_Release(bufferp); - /* apply and free last set of patches; if not doing a star match, this - * will be empty, but better safe (and freeing everything) than sorry. + /* apply and free last set of patches; if not doing a star match, this + * will be empty, but better safe (and freeing everything) than sorry. */ smb_ApplyV3DirListPatches(scp, &dirListPatchesp, infoLevel, userp, &req); /* now put out the final parameters */ - if (returnedNames == 0) eos = 1; + if (returnedNames == 0) eos = 1; if (p->opcode == 1) { - /* find first */ + /* find first */ outp->parmsp[0] = (unsigned short) dsp->cookie; outp->parmsp[1] = returnedNames; outp->parmsp[2] = eos; @@ -3993,30 +4093,30 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t outp->totalParms = 8; /* in bytes */ } - /* return # of bytes in the buffer */ + /* return # of bytes in the buffer */ outp->totalData = bytesInBuffer; - osi_Log2(smb_logp, "T2 search dir done, %d names, code %d", - returnedNames, code); + osi_Log2(smb_logp, "T2 search dir done, %d names, code %d", + returnedNames, code); - /* Return error code if unsuccessful on first request */ - if (code == 0 && p->opcode == 1 && returnedNames == 0) - code = CM_ERROR_NOSUCHFILE; + /* Return error code if unsuccessful on first request */ + if (code == 0 && p->opcode == 1 && returnedNames == 0) + code = CM_ERROR_NOSUCHFILE; - /* if we're supposed to close the search after this request, or if + /* if we're supposed to close the search after this request, or if * we're supposed to close the search if we're done, and we're done, * or if something went wrong, close the search. */ /* ((searchFlags & 1) || ((searchFlags & 2) && eos) */ - if ((searchFlags & 1) || (returnedNames == 0) || + if ((searchFlags & 1) || (returnedNames == 0) || ((searchFlags & 2) && eos) || code != 0) - smb_DeleteDirSearch(dsp); - if (code) + smb_DeleteDirSearch(dsp); + if (code) smb_SendTran2Error(vcp, p, opx, code); - else { + else { smb_SendTran2Packet(vcp, outp, opx); - } - smb_FreeTran2Packet(outp); + } + smb_FreeTran2Packet(outp); smb_ReleaseDirSearch(dsp); cm_ReleaseSCache(scp); cm_ReleaseUser(userp); @@ -4035,29 +4135,29 @@ long smb_ReceiveV3FindClose(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp dsp = smb_FindDirSearch(dirHandle); if (!dsp) - return CM_ERROR_BADFD; + return CM_ERROR_BADFD; /* otherwise, we have an FD to destroy */ smb_DeleteDirSearch(dsp); smb_ReleaseDirSearch(dsp); - /* and return results */ - smb_SetSMBDataLength(outp, 0); + /* and return results */ + smb_SetSMBDataLength(outp, 0); return 0; } long smb_ReceiveV3FindNotifyClose(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - smb_SetSMBDataLength(outp, 0); + smb_SetSMBDataLength(outp, 0); return 0; } long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - char *pathp; + char *pathp; long code = 0; - cm_space_t *spacep; + cm_space_t *spacep; int excl; cm_user_t *userp; cm_scache_t *dscp; /* dir we're dealing with */ @@ -4067,25 +4167,25 @@ long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) smb_fid_t *fidp; int attributes; char *lastNamep; - long dosTime; + time_t dosTime; int openFun; int trunc; int openMode; int extraInfo; int openAction; int parmSlot; /* which parm we're dealing with */ - char *tidPathp; - cm_req_t req; + char *tidPathp; + cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); scp = NULL; - extraInfo = (smb_GetSMBParm(inp, 2) & 1); /* return extra info */ - openFun = smb_GetSMBParm(inp, 8); /* open function */ + extraInfo = (smb_GetSMBParm(inp, 2) & 1); /* return extra info */ + openFun = smb_GetSMBParm(inp, 8); /* open function */ excl = ((openFun & 3) == 0); trunc = ((openFun & 3) == 2); /* truncate it */ - openMode = (smb_GetSMBParm(inp, 3) & 0x7); + openMode = (smb_GetSMBParm(inp, 3) & 0x7); openAction = 0; /* tracks what we did */ attributes = smb_GetSMBParm(inp, 5); @@ -4097,11 +4197,11 @@ long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) pathp = smb_GetSMBData(inp, NULL); - spacep = inp->spacep; + spacep = inp->spacep; smb_StripLastComponent(spacep->data, &lastNamep, pathp); - if (lastNamep && strcmp(lastNamep, SMB_IOCTL_FILENAME) == 0) { - /* special case magic file name for receiving IOCTL requests + if (lastNamep && strcmp(lastNamep, SMB_IOCTL_FILENAME) == 0) { + /* special case magic file name for receiving IOCTL requests * (since IOCTL calls themselves aren't getting through). */ #ifdef NOTSERVICE @@ -4111,13 +4211,13 @@ long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE); smb_SetupIoctlFid(fidp, spacep); - /* set inp->fid so that later read calls in same msg can find fid */ + /* set inp->fid so that later read calls in same msg can find fid */ inp->fid = fidp->fid; /* copy out remainder of the parms */ - parmSlot = 2; - smb_SetSMBParm(outp, parmSlot, fidp->fid); parmSlot++; - if (extraInfo) { + parmSlot = 2; + smb_SetSMBParm(outp, parmSlot, fidp->fid); parmSlot++; + if (extraInfo) { smb_SetSMBParm(outp, parmSlot, /* attrs */ 0); parmSlot++; smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* mod time */ smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; @@ -4126,16 +4226,16 @@ long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) smb_SetSMBParm(outp, parmSlot, openMode); parmSlot++; smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* file type 0 ==> normal file or dir */ smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* IPC junk */ - } - /* and the final "always present" stuff */ + } + /* and the final "always present" stuff */ smb_SetSMBParm(outp, parmSlot, /* openAction found existing file */ 1); parmSlot++; - /* next write out the "unique" ID */ - smb_SetSMBParm(outp, parmSlot, 0x1234); parmSlot++; - smb_SetSMBParm(outp, parmSlot, 0x5678); parmSlot++; + /* next write out the "unique" ID */ + smb_SetSMBParm(outp, parmSlot, 0x1234); parmSlot++; + smb_SetSMBParm(outp, parmSlot, 0x5678); parmSlot++; smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; smb_SetSMBDataLength(outp, 0); - /* and clean up fid reference */ + /* and clean up fid reference */ smb_ReleaseFID(fidp); return 0; } @@ -4151,17 +4251,17 @@ long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) #endif userp = smb_GetUser(vcp, inp); - dscp = NULL; - code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); - if(code) { + dscp = NULL; + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); + if (code) { cm_ReleaseUser(userp); return CM_ERROR_NOSUCHPATH; } - code = cm_NameI(cm_rootSCachep, pathp, + code = cm_NameI(cm_rootSCachep, pathp, CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, tidPathp, &req, &scp); - if (code != 0) { - code = cm_NameI(cm_rootSCachep, spacep->data, + if (code != 0) { + code = cm_NameI(cm_rootSCachep, spacep->data, CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, tidPathp, &req, &dscp); @@ -4183,14 +4283,14 @@ long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) cm_ReleaseUser(userp); return code; } - } + } /* if we get here, if code is 0, the file exists and is represented by * scp. Otherwise, we have to create it. The dir may be represented * by dscp, or we may have found the file directly. If code is non-zero, * scp is NULL. */ - if (code == 0) { + if (code == 0) { code = cm_CheckOpen(scp, openMode, trunc, userp, &req); if (code) { if (dscp) cm_ReleaseSCache(dscp); @@ -4199,105 +4299,105 @@ long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) return code; } - if (excl) { - /* oops, file shouldn't be there */ + if (excl) { + /* oops, file shouldn't be there */ if (dscp) cm_ReleaseSCache(dscp); cm_ReleaseSCache(scp); cm_ReleaseUser(userp); return CM_ERROR_EXISTS; } - if (trunc) { - setAttr.mask = CM_ATTRMASK_LENGTH; + if (trunc) { + setAttr.mask = CM_ATTRMASK_LENGTH; setAttr.length.LowPart = 0; setAttr.length.HighPart = 0; - code = cm_SetAttr(scp, &setAttr, userp, &req); + code = cm_SetAttr(scp, &setAttr, userp, &req); openAction = 3; /* truncated existing file */ - } + } else openAction = 1; /* found existing file */ } - else if (!(openFun & 0x10)) { - /* don't create if not found */ + else if (!(openFun & 0x10)) { + /* don't create if not found */ if (dscp) cm_ReleaseSCache(dscp); cm_ReleaseUser(userp); return CM_ERROR_NOSUCHFILE; } else { - osi_assert(dscp != NULL); - osi_Log1(smb_logp, "smb_ReceiveV3OpenX creating file %s", + osi_assert(dscp != NULL); + osi_Log1(smb_logp, "smb_ReceiveV3OpenX creating file %s", osi_LogSaveString(smb_logp, lastNamep)); - openAction = 2; /* created file */ - setAttr.mask = CM_ATTRMASK_CLIENTMODTIME; - smb_UnixTimeFromDosUTime(&setAttr.clientModTime, dosTime); + openAction = 2; /* created file */ + setAttr.mask = CM_ATTRMASK_CLIENTMODTIME; + smb_UnixTimeFromDosUTime(&setAttr.clientModTime, dosTime); code = cm_Create(dscp, lastNamep, 0, &setAttr, &scp, userp, &req); - if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) - smb_NotifyChange(FILE_ACTION_ADDED, + if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) + smb_NotifyChange(FILE_ACTION_ADDED, FILE_NOTIFY_CHANGE_FILE_NAME, dscp, lastNamep, NULL, TRUE); if (!excl && code == CM_ERROR_EXISTS) { - /* not an exclusive create, and someone else tried - * creating it already, then we open it anyway. We - * don't bother retrying after this, since if this next - * fails, that means that the file was deleted after we - * started this call. + /* not an exclusive create, and someone else tried + * creating it already, then we open it anyway. We + * don't bother retrying after this, since if this next + * fails, that means that the file was deleted after we + * started this call. */ code = cm_Lookup(dscp, lastNamep, CM_FLAG_CASEFOLD, userp, &req, &scp); if (code == 0) { if (trunc) { - setAttr.mask = CM_ATTRMASK_LENGTH; + setAttr.mask = CM_ATTRMASK_LENGTH; setAttr.length.LowPart = 0; setAttr.length.HighPart = 0; code = cm_SetAttr(scp, &setAttr, userp, &req); } - } /* lookup succeeded */ + } /* lookup succeeded */ } } - /* we don't need this any longer */ - if (dscp) cm_ReleaseSCache(dscp); + /* we don't need this any longer */ + if (dscp) cm_ReleaseSCache(dscp); if (code) { - /* something went wrong creating or truncating the file */ + /* something went wrong creating or truncating the file */ if (scp) cm_ReleaseSCache(scp); cm_ReleaseUser(userp); return code; } - /* make sure we're about to open a file */ - if (scp->fileType != CM_SCACHETYPE_FILE) { - cm_ReleaseSCache(scp); - cm_ReleaseUser(userp); - return CM_ERROR_ISDIR; - } + /* make sure we're about to open a file */ + if (scp->fileType != CM_SCACHETYPE_FILE) { + cm_ReleaseSCache(scp); + cm_ReleaseUser(userp); + return CM_ERROR_ISDIR; + } /* now all we have to do is open the file itself */ fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE); osi_assert(fidp); - /* save a pointer to the vnode */ + /* save a pointer to the vnode */ fidp->scp = scp; - /* compute open mode */ + /* compute open mode */ if (openMode != 1) fidp->flags |= SMB_FID_OPENREAD; if (openMode == 1 || openMode == 2) fidp->flags |= SMB_FID_OPENWRITE; - smb_ReleaseFID(fidp); + smb_ReleaseFID(fidp); - cm_Open(scp, 0, userp); + cm_Open(scp, 0, userp); - /* set inp->fid so that later read calls in same msg can find fid */ + /* set inp->fid so that later read calls in same msg can find fid */ inp->fid = fidp->fid; /* copy out remainder of the parms */ - parmSlot = 2; - smb_SetSMBParm(outp, parmSlot, fidp->fid); parmSlot++; - lock_ObtainMutex(&scp->mx); - if (extraInfo) { + parmSlot = 2; + smb_SetSMBParm(outp, parmSlot, fidp->fid); parmSlot++; + lock_ObtainMutex(&scp->mx); + if (extraInfo) { smb_SetSMBParm(outp, parmSlot, smb_Attributes(scp)); parmSlot++; - smb_DosUTimeFromUnixTime(&dosTime, scp->clientModTime); + smb_DosUTimeFromUnixTime(&dosTime, scp->clientModTime); smb_SetSMBParm(outp, parmSlot, dosTime & 0xffff); parmSlot++; smb_SetSMBParm(outp, parmSlot, (dosTime>>16) & 0xffff); parmSlot++; smb_SetSMBParm(outp, parmSlot, scp->length.LowPart & 0xffff); parmSlot++; @@ -4305,59 +4405,59 @@ long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) smb_SetSMBParm(outp, parmSlot, openMode); parmSlot++; smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* file type 0 ==> normal file or dir */ smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* IPC junk */ - } - /* and the final "always present" stuff */ + } + /* and the final "always present" stuff */ smb_SetSMBParm(outp, parmSlot, openAction); parmSlot++; - /* next write out the "unique" ID */ - smb_SetSMBParm(outp, parmSlot, scp->fid.vnode & 0xffff); parmSlot++; - smb_SetSMBParm(outp, parmSlot, scp->fid.volume & 0xffff); parmSlot++; + /* next write out the "unique" ID */ + smb_SetSMBParm(outp, parmSlot, scp->fid.vnode & 0xffff); parmSlot++; + smb_SetSMBParm(outp, parmSlot, scp->fid.volume & 0xffff); parmSlot++; smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; - lock_ReleaseMutex(&scp->mx); + lock_ReleaseMutex(&scp->mx); smb_SetSMBDataLength(outp, 0); - osi_Log1(smb_logp, "SMB OpenX opening fid %d", fidp->fid); + osi_Log1(smb_logp, "SMB OpenX opening fid %d", fidp->fid); cm_ReleaseUser(userp); /* leave scp held since we put it in fidp->scp */ return 0; -} +} long smb_ReceiveV3LockingX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - cm_req_t req; - cm_user_t *userp; - unsigned short fid; - smb_fid_t *fidp; - cm_scache_t *scp; - unsigned char LockType; - unsigned short NumberOfUnlocks, NumberOfLocks; - unsigned long Timeout; - char *op; - LARGE_INTEGER LOffset, LLength; - smb_waitingLock_t *waitingLock; - void *lockp; - long code = 0; - int i; - - cm_InitReq(&req); - - fid = smb_GetSMBParm(inp, 2); - fid = smb_ChainFID(fid, inp); - - fidp = smb_FindFID(vcp, fid, 0); - if (!fidp || (fidp->flags & SMB_FID_IOCTL)) { - return CM_ERROR_BADFD; - } - /* set inp->fid so that later read calls in same msg can find fid */ + cm_req_t req; + cm_user_t *userp; + unsigned short fid; + smb_fid_t *fidp; + cm_scache_t *scp; + unsigned char LockType; + unsigned short NumberOfUnlocks, NumberOfLocks; + unsigned long Timeout; + char *op; + LARGE_INTEGER LOffset, LLength; + smb_waitingLock_t *waitingLock; + void *lockp; + long code = 0; + int i; + + cm_InitReq(&req); + + fid = smb_GetSMBParm(inp, 2); + fid = smb_ChainFID(fid, inp); + + fidp = smb_FindFID(vcp, fid, 0); + if (!fidp || (fidp->flags & SMB_FID_IOCTL)) { + return CM_ERROR_BADFD; + } + /* set inp->fid so that later read calls in same msg can find fid */ inp->fid = fid; - userp = smb_GetUser(vcp, inp); + userp = smb_GetUser(vcp, inp); - scp = fidp->scp; + scp = fidp->scp; - lock_ObtainMutex(&scp->mx); - code = cm_SyncOp(scp, NULL, userp, &req, 0, - CM_SCACHESYNC_NEEDCALLBACK + lock_ObtainMutex(&scp->mx); + code = cm_SyncOp(scp, NULL, userp, &req, 0, + CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_LOCK); if (code) goto doneSync; @@ -4370,106 +4470,106 @@ long smb_ReceiveV3LockingX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) op = smb_GetSMBData(inp, NULL); for (i=0; ilength)) - continue; - - code = cm_Lock(scp, LockType, LOffset, LLength, Timeout, - userp, &req, &lockp); - if (code == CM_ERROR_WOULDBLOCK && Timeout != 0) { - /* Put on waiting list */ - waitingLock = malloc(sizeof(smb_waitingLock_t)); - waitingLock->vcp = vcp; - waitingLock->inp = smb_CopyPacket(inp); - waitingLock->outp = smb_CopyPacket(outp); - waitingLock->timeRemaining = Timeout; - waitingLock->lockp = lockp; - lock_ObtainWrite(&smb_globalLock); - osi_QAdd((osi_queue_t **)&smb_allWaitingLocks, - &waitingLock->q); - osi_Wakeup((long) &smb_allWaitingLocks); - lock_ReleaseWrite(&smb_globalLock); - /* don't send reply immediately */ - outp->flags |= SMB_PACKETFLAG_NOSEND; - } - if (code) break; - } + if (LockType & 0x10) { + /* Large Files */ + LOffset.HighPart = *((LONG *)(op + 4)); + LOffset.LowPart = *((DWORD *)(op + 8)); + LLength.HighPart = *((LONG *)(op + 12)); + LLength.LowPart = *((DWORD *)(op + 16)); + op += 20; + } + else { + /* Not Large Files */ + LOffset.HighPart = 0; + LOffset.LowPart = *((DWORD *)(op + 2)); + LLength.HighPart = 0; + LLength.LowPart = *((DWORD *)(op + 6)); + op += 10; + } + if (LargeIntegerNotEqualToZero(LOffset)) + continue; + if (LargeIntegerLessThan(LOffset, scp->length)) + continue; + + code = cm_Lock(scp, LockType, LOffset, LLength, Timeout, + userp, &req, &lockp); + if (code == CM_ERROR_WOULDBLOCK && Timeout != 0) { + /* Put on waiting list */ + waitingLock = malloc(sizeof(smb_waitingLock_t)); + waitingLock->vcp = vcp; + waitingLock->inp = smb_CopyPacket(inp); + waitingLock->outp = smb_CopyPacket(outp); + waitingLock->timeRemaining = Timeout; + waitingLock->lockp = lockp; + lock_ObtainWrite(&smb_globalLock); + osi_QAdd((osi_queue_t **)&smb_allWaitingLocks, + &waitingLock->q); + osi_Wakeup((long) &smb_allWaitingLocks); + lock_ReleaseWrite(&smb_globalLock); + /* don't send reply immediately */ + outp->flags |= SMB_PACKETFLAG_NOSEND; + } + if (code) break; + } - if (code) { - /* release any locks acquired before the failure */ - } - else - smb_SetSMBDataLength(outp, 0); -done: - cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_LOCK); -doneSync: - lock_ReleaseMutex(&scp->mx); - cm_ReleaseUser(userp); - smb_ReleaseFID(fidp); - - return code; + if (code) { + /* release any locks acquired before the failure */ + } + else + smb_SetSMBDataLength(outp, 0); + done: + cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_LOCK); + doneSync: + lock_ReleaseMutex(&scp->mx); + cm_ReleaseUser(userp); + smb_ReleaseFID(fidp); + + return code; } long smb_ReceiveV3GetAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - unsigned short fid; + unsigned short fid; smb_fid_t *fidp; cm_scache_t *scp; long code = 0; - long searchTime; + time_t searchTime; cm_user_t *userp; - cm_req_t req; + cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); fid = smb_GetSMBParm(inp, 0); fid = smb_ChainFID(fid, inp); fidp = smb_FindFID(vcp, fid, 0); if (!fidp || (fidp->flags & SMB_FID_IOCTL)) { - return CM_ERROR_BADFD; + return CM_ERROR_BADFD; } userp = smb_GetUser(vcp, inp); @@ -4477,16 +4577,16 @@ long smb_ReceiveV3GetAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t * scp = fidp->scp; /* otherwise, stat the file */ - lock_ObtainMutex(&scp->mx); + lock_ObtainMutex(&scp->mx); code = cm_SyncOp(scp, NULL, userp, &req, 0, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); - if (code) goto done; + if (code) goto done; - /* decode times. We need a search time, but the response to this + /* decode times. We need a search time, but the response to this * call provides the date first, not the time, as returned in the * searchTime variable. So we take the high-order bits first. */ - smb_SearchTimeFromUnixTime(&searchTime, scp->clientModTime); + smb_SearchTimeFromUnixTime(&searchTime, scp->clientModTime); smb_SetSMBParm(outp, 0, (searchTime >> 16) & 0xffff); /* ctime */ smb_SetSMBParm(outp, 1, searchTime & 0xffff); smb_SetSMBParm(outp, 2, (searchTime >> 16) & 0xffff); /* atime */ @@ -4500,7 +4600,7 @@ long smb_ReceiveV3GetAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t * smb_SetSMBParm(outp, 8, scp->length.LowPart & 0xffff); /* alloc size */ smb_SetSMBParm(outp, 9, (scp->length.LowPart >> 16) & 0xffff); - /* file attribute */ + /* file attribute */ smb_SetSMBParm(outp, 10, smb_Attributes(scp)); /* and finalize stuff */ @@ -4508,46 +4608,46 @@ long smb_ReceiveV3GetAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t * code = 0; done: - lock_ReleaseMutex(&scp->mx); - cm_ReleaseUser(userp); - smb_ReleaseFID(fidp); - return code; -} + lock_ReleaseMutex(&scp->mx); + cm_ReleaseUser(userp); + smb_ReleaseFID(fidp); + return code; +} long smb_ReceiveV3SetAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - unsigned short fid; + unsigned short fid; smb_fid_t *fidp; cm_scache_t *scp; long code = 0; - long searchTime; - long unixTime; + time_t searchTime; + time_t unixTime; cm_user_t *userp; cm_attr_t attrs; - cm_req_t req; + cm_req_t req; - cm_InitReq(&req); + cm_InitReq(&req); fid = smb_GetSMBParm(inp, 0); fid = smb_ChainFID(fid, inp); fidp = smb_FindFID(vcp, fid, 0); if (!fidp || (fidp->flags & SMB_FID_IOCTL)) { - return CM_ERROR_BADFD; + return CM_ERROR_BADFD; } userp = smb_GetUser(vcp, inp); scp = fidp->scp; - /* now prepare to call cm_setattr. This message only sets various times, + /* now prepare to call cm_setattr. This message only sets various times, * and AFS only implements mtime, and we'll set the mtime if that's * requested. The others we'll ignore. */ - searchTime = smb_GetSMBParm(inp, 5) | (smb_GetSMBParm(inp, 6) << 16); + searchTime = smb_GetSMBParm(inp, 5) | (smb_GetSMBParm(inp, 6) << 16); if (searchTime != 0) { - smb_UnixTimeFromSearchTime(&unixTime, searchTime); + smb_UnixTimeFromSearchTime(&unixTime, searchTime); if ( unixTime != -1 ) { attrs.mask = CM_ATTRMASK_CLIENTMODTIME; @@ -4561,15 +4661,15 @@ long smb_ReceiveV3SetAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t * } else code = 0; - cm_ReleaseUser(userp); - smb_ReleaseFID(fidp); - return code; + cm_ReleaseUser(userp); + smb_ReleaseFID(fidp); + return code; } long smb_ReceiveV3ReadX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - osi_hyper_t offset; + osi_hyper_t offset; long count, finalCount; unsigned short fd; smb_fid_t *fidp; @@ -4585,35 +4685,35 @@ long smb_ReceiveV3ReadX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) osi_Log3(smb_logp, "smb_ReceiveV3Read fd %d, off 0x%x, size 0x%x", fd, offset.LowPart, count); - fd = smb_ChainFID(fd, inp); + fd = smb_ChainFID(fd, inp); fidp = smb_FindFID(vcp, fd, 0); if (!fidp) { - return CM_ERROR_BADFD; + return CM_ERROR_BADFD; } - /* set inp->fid so that later read calls in same msg can find fid */ + /* set inp->fid so that later read calls in same msg can find fid */ inp->fid = fd; if (fidp->flags & SMB_FID_IOCTL) { - return smb_IoctlV3Read(fidp, vcp, inp, outp); + return smb_IoctlV3Read(fidp, vcp, inp, outp); } - userp = smb_GetUser(vcp, inp); + userp = smb_GetUser(vcp, inp); - /* 0 and 1 are reserved for request chaining, were setup by our caller, + /* 0 and 1 are reserved for request chaining, were setup by our caller, * and will be further filled in after we return. */ smb_SetSMBParm(outp, 2, 0); /* remaining bytes, for pipes */ smb_SetSMBParm(outp, 3, 0); /* resvd */ smb_SetSMBParm(outp, 4, 0); /* resvd */ - smb_SetSMBParm(outp, 5, count); /* # of bytes we're going to read */ + smb_SetSMBParm(outp, 5, count); /* # of bytes we're going to read */ /* fill in #6 when we have all the parameters' space reserved */ smb_SetSMBParm(outp, 7, 0); /* resv'd */ smb_SetSMBParm(outp, 8, 0); /* resv'd */ smb_SetSMBParm(outp, 9, 0); /* resv'd */ smb_SetSMBParm(outp, 10, 0); /* resv'd */ - smb_SetSMBParm(outp, 11, 0); /* reserved */ + smb_SetSMBParm(outp, 11, 0); /* reserved */ - /* get op ptr after putting in the parms, since otherwise we don't + /* get op ptr after putting in the parms, since otherwise we don't * know where the data really is. */ op = smb_GetSMBData(outp, NULL); @@ -4621,18 +4721,18 @@ long smb_ReceiveV3ReadX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) /* now fill in offset from start of SMB header to first data byte (to op) */ smb_SetSMBParm(outp, 6, ((int) (op - outp->data))); - /* set the packet data length the count of the # of bytes */ + /* set the packet data length the count of the # of bytes */ smb_SetSMBDataLength(outp, count); #ifndef DJGPP - code = smb_ReadData(fidp, &offset, count, op, userp, &finalCount); + code = smb_ReadData(fidp, &offset, count, op, userp, &finalCount); #else /* DJGPP */ - code = smb_ReadData(fidp, &offset, count, op, userp, &finalCount, FALSE); + code = smb_ReadData(fidp, &offset, count, op, userp, &finalCount, FALSE); #endif /* !DJGPP */ - /* fix some things up */ - smb_SetSMBParm(outp, 5, finalCount); - smb_SetSMBDataLength(outp, finalCount); + /* fix some things up */ + smb_SetSMBParm(outp, 5, finalCount); + smb_SetSMBDataLength(outp, finalCount); smb_ReleaseFID(fidp); @@ -4642,146 +4742,147 @@ long smb_ReceiveV3ReadX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) /* * Values for createDisp, copied from NTDDK.H - * - * FILE_SUPERSEDE 0 (???) - * FILE_OPEN 1 (open) - * FILE_CREATE 2 (exclusive) - * FILE_OPEN_IF 3 (non-exclusive) - * FILE_OVERWRITE 4 (open & truncate, but do not create) - * FILE_OVERWRITE_IF 5 (open & truncate, or create) */ +#define FILE_SUPERSEDE 0 // (???) +#define FILE_OPEN 1 // (open) +#define FILE_CREATE 2 // (exclusive) +#define FILE_OPEN_IF 3 // (non-exclusive) +#define FILE_OVERWRITE 4 // (open & truncate, but do not create) +#define FILE_OVERWRITE_IF 5 // (open & truncate, or create) long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - char *pathp, *realPathp; - long code = 0; - cm_space_t *spacep; - cm_user_t *userp; - cm_scache_t *dscp; /* parent dir */ - cm_scache_t *scp; /* file to create or open */ - cm_attr_t setAttr; - char *lastNamep; + char *pathp, *realPathp; + long code = 0; + cm_space_t *spacep; + cm_user_t *userp; + cm_scache_t *dscp; /* parent dir */ + cm_scache_t *scp; /* file to create or open */ + cm_scache_t *targetScp; /* if scp is a symlink */ + cm_attr_t setAttr; + char *lastNamep; char *treeStartp; - unsigned short nameLength; - unsigned int flags; - unsigned int requestOpLock; - unsigned int requestBatchOpLock; - unsigned int mustBeDir; + unsigned short nameLength; + unsigned int flags; + unsigned int requestOpLock; + unsigned int requestBatchOpLock; + unsigned int mustBeDir; unsigned int treeCreate; - int realDirFlag; - unsigned int desiredAccess; - unsigned int extAttributes; - unsigned int createDisp; - unsigned int createOptions; - int initialModeBits; - unsigned short baseFid; - smb_fid_t *baseFidp; - smb_fid_t *fidp; - cm_scache_t *baseDirp; - unsigned short openAction; - int parmSlot; - long fidflags; - FILETIME ft; - LARGE_INTEGER sz; - char *tidPathp; - BOOL foundscp; - cm_req_t req; - - cm_InitReq(&req); + int realDirFlag; + unsigned int desiredAccess; + unsigned int extAttributes; + unsigned int createDisp; + unsigned int createOptions; + int initialModeBits; + unsigned short baseFid; + smb_fid_t *baseFidp; + smb_fid_t *fidp; + cm_scache_t *baseDirp; + unsigned short openAction; + int parmSlot; + long fidflags; + FILETIME ft; + LARGE_INTEGER sz; + char *tidPathp; + BOOL foundscp; + cm_req_t req; + + cm_InitReq(&req); treeCreate = FALSE; - foundscp = FALSE; - scp = NULL; - - nameLength = smb_GetSMBOffsetParm(inp, 2, 1); - flags = smb_GetSMBOffsetParm(inp, 3, 1) - | (smb_GetSMBOffsetParm(inp, 4, 1) << 16); - requestOpLock = flags & 0x02; - requestBatchOpLock = flags & 0x04; - mustBeDir = flags & 0x08; - - /* - * Why all of a sudden 32-bit FID? - * We will reject all bits higher than 16. - */ - if (smb_GetSMBOffsetParm(inp, 6, 1) != 0) - return CM_ERROR_INVAL; - baseFid = smb_GetSMBOffsetParm(inp, 5, 1); - desiredAccess = smb_GetSMBOffsetParm(inp, 7, 1) - | (smb_GetSMBOffsetParm(inp, 8, 1) << 16); - extAttributes = smb_GetSMBOffsetParm(inp, 13, 1) - | (smb_GetSMBOffsetParm(inp, 14, 1) << 16); - createDisp = smb_GetSMBOffsetParm(inp, 17, 1) - | (smb_GetSMBOffsetParm(inp, 18, 1) << 16); - createOptions = smb_GetSMBOffsetParm(inp, 19, 1) - | (smb_GetSMBOffsetParm(inp, 20, 1) << 16); - - /* mustBeDir is never set; createOptions directory bit seems to be + foundscp = FALSE; + scp = NULL; + + nameLength = smb_GetSMBOffsetParm(inp, 2, 1); + flags = smb_GetSMBOffsetParm(inp, 3, 1) + | (smb_GetSMBOffsetParm(inp, 4, 1) << 16); + requestOpLock = flags & 0x02; + requestBatchOpLock = flags & 0x04; + mustBeDir = flags & 0x08; + + /* + * Why all of a sudden 32-bit FID? + * We will reject all bits higher than 16. + */ + if (smb_GetSMBOffsetParm(inp, 6, 1) != 0) + return CM_ERROR_INVAL; + baseFid = smb_GetSMBOffsetParm(inp, 5, 1); + desiredAccess = smb_GetSMBOffsetParm(inp, 7, 1) + | (smb_GetSMBOffsetParm(inp, 8, 1) << 16); + extAttributes = smb_GetSMBOffsetParm(inp, 13, 1) + | (smb_GetSMBOffsetParm(inp, 14, 1) << 16); + createDisp = smb_GetSMBOffsetParm(inp, 17, 1) + | (smb_GetSMBOffsetParm(inp, 18, 1) << 16); + createOptions = smb_GetSMBOffsetParm(inp, 19, 1) + | (smb_GetSMBOffsetParm(inp, 20, 1) << 16); + + /* mustBeDir is never set; createOptions directory bit seems to be * more important - */ - if (createOptions & 1) - realDirFlag = 1; - else if (createOptions & 0x40) - realDirFlag = 0; - else - realDirFlag = -1; - - /* - * compute initial mode bits based on read-only flag in - * extended attributes - */ - initialModeBits = 0666; - if (extAttributes & 1) initialModeBits &= ~0222; + */ + if (createOptions & 1) + realDirFlag = 1; + else if (createOptions & 0x40) + realDirFlag = 0; + else + realDirFlag = -1; + + /* + * compute initial mode bits based on read-only flag in + * extended attributes + */ + initialModeBits = 0666; + if (extAttributes & 1) + initialModeBits &= ~0222; - pathp = smb_GetSMBData(inp, NULL); - /* Sometimes path is not null-terminated, so we make a copy. */ - realPathp = malloc(nameLength+1); - memcpy(realPathp, pathp, nameLength); - realPathp[nameLength] = 0; + pathp = smb_GetSMBData(inp, NULL); + /* Sometimes path is not null-terminated, so we make a copy. */ + realPathp = malloc(nameLength+1); + memcpy(realPathp, pathp, nameLength); + realPathp[nameLength] = 0; - spacep = inp->spacep; - smb_StripLastComponent(spacep->data, &lastNamep, realPathp); + spacep = inp->spacep; + smb_StripLastComponent(spacep->data, &lastNamep, realPathp); osi_Log1(smb_logp,"NTCreateX for [%s]",osi_LogSaveString(smb_logp,realPathp)); - osi_Log4(smb_logp,"NTCreateX da=[%x] ea=[%x] cd=[%x] co=[%x]", desiredAccess, extAttributes, createDisp, createOptions); - osi_Log1(smb_logp,"NTCreateX lastNamep=[%s]",osi_LogSaveString(smb_logp,(lastNamep?lastNamep:"null"))); - - if (lastNamep && strcmp(lastNamep, SMB_IOCTL_FILENAME) == 0) { - /* special case magic file name for receiving IOCTL requests - * (since IOCTL calls themselves aren't getting through). - */ - fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE); - smb_SetupIoctlFid(fidp, spacep); - osi_Log1(smb_logp,"NTCreateX Setting up IOCTL on fid[%d]",fidp->fid); - - /* set inp->fid so that later read calls in same msg can find fid */ - inp->fid = fidp->fid; - - /* out parms */ - parmSlot = 2; - smb_SetSMBParmByte(outp, parmSlot, 0); /* oplock */ - smb_SetSMBParm(outp, parmSlot, fidp->fid); parmSlot++; - smb_SetSMBParmLong(outp, parmSlot, 1); parmSlot += 2; /* Action */ - /* times */ - memset(&ft, 0, sizeof(ft)); - smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4; - smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4; - smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4; - smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4; - smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2; /* attr */ - sz.HighPart = 0x7fff; sz.LowPart = 0; - smb_SetSMBParmDouble(outp, parmSlot, (char *)&sz); parmSlot += 4; /* alen */ - smb_SetSMBParmDouble(outp, parmSlot, (char *)&sz); parmSlot += 4; /* len */ - smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* filetype */ - smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* dev state */ - smb_SetSMBParmByte(outp, parmSlot, 0); /* is a dir? */ - smb_SetSMBDataLength(outp, 0); - - /* clean up fid reference */ - smb_ReleaseFID(fidp); - free(realPathp); - return 0; - } + osi_Log4(smb_logp,"... da=[%x] ea=[%x] cd=[%x] co=[%x]", desiredAccess, extAttributes, createDisp, createOptions); + osi_Log2(smb_logp,"... flags=[%x] lastNamep=[%s]", flags, osi_LogSaveString(smb_logp,(lastNamep?lastNamep:"null"))); + + if (lastNamep && strcmp(lastNamep, SMB_IOCTL_FILENAME) == 0) { + /* special case magic file name for receiving IOCTL requests + * (since IOCTL calls themselves aren't getting through). + */ + fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE); + smb_SetupIoctlFid(fidp, spacep); + osi_Log1(smb_logp,"NTCreateX Setting up IOCTL on fid[%d]",fidp->fid); + + /* set inp->fid so that later read calls in same msg can find fid */ + inp->fid = fidp->fid; + + /* out parms */ + parmSlot = 2; + smb_SetSMBParmByte(outp, parmSlot, 0); /* oplock */ + smb_SetSMBParm(outp, parmSlot, fidp->fid); parmSlot++; + smb_SetSMBParmLong(outp, parmSlot, 1); parmSlot += 2; /* Action */ + /* times */ + memset(&ft, 0, sizeof(ft)); + smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4; + smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4; + smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4; + smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4; + smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2; /* attr */ + sz.HighPart = 0x7fff; sz.LowPart = 0; + smb_SetSMBParmDouble(outp, parmSlot, (char *)&sz); parmSlot += 4; /* alen */ + smb_SetSMBParmDouble(outp, parmSlot, (char *)&sz); parmSlot += 4; /* len */ + smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* filetype */ + smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* dev state */ + smb_SetSMBParmByte(outp, parmSlot, 0); /* is a dir? */ + smb_SetSMBDataLength(outp, 0); + + /* clean up fid reference */ + smb_ReleaseFID(fidp); + free(realPathp); + return 0; + } #ifdef DEBUG_VERBOSE { @@ -4799,46 +4900,48 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) return CM_ERROR_INVAL; } - if (baseFid == 0) { - baseDirp = cm_rootSCachep; - code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); - if(code == CM_ERROR_TIDIPC) { + if (baseFid == 0) { + baseDirp = cm_rootSCachep; + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); + if (code == CM_ERROR_TIDIPC) { /* Attempt to use a TID allocated for IPC. The client - is probably looking for DCE RPC end points which we - don't support. */ + * is probably looking for DCE RPC end points which we + * don't support. */ osi_Log0(smb_logp, "NTCreateX received IPC TID"); free(realPathp); cm_ReleaseUser(userp); return CM_ERROR_NOSUCHFILE; } - } - else { + } + else { baseFidp = smb_FindFID(vcp, baseFid, 0); if (!baseFidp) { - osi_Log1(smb_logp, "NTCreateX Invalid base fid [%d]", baseFid); - free(realPathp); - cm_ReleaseUser(userp); - return CM_ERROR_INVAL; - } - baseDirp = baseFidp->scp; - tidPathp = NULL; - } + osi_Log1(smb_logp, "NTCreateX Invalid base fid [%d]", baseFid); + free(realPathp); + cm_ReleaseUser(userp); + return CM_ERROR_INVAL; + } + baseDirp = baseFidp->scp; + tidPathp = NULL; + } osi_Log1(smb_logp, "NTCreateX tidPathp=[%s]", (tidPathp==NULL)?"null": osi_LogSaveString(smb_logp,tidPathp)); - + /* compute open mode */ - fidflags = 0; - if (desiredAccess & DELETE) - fidflags |= SMB_FID_OPENDELETE; - if (desiredAccess & AFS_ACCESS_READ) - fidflags |= SMB_FID_OPENREAD; - if (desiredAccess & AFS_ACCESS_WRITE) - fidflags |= SMB_FID_OPENWRITE; - - dscp = NULL; - code = 0; + fidflags = 0; + if (desiredAccess & DELETE) + fidflags |= SMB_FID_OPENDELETE; + if (desiredAccess & AFS_ACCESS_READ) + fidflags |= SMB_FID_OPENREAD; + if (desiredAccess & AFS_ACCESS_WRITE) + fidflags |= SMB_FID_OPENWRITE; + + dscp = NULL; + code = 0; /* For an exclusive create, we want to do a case sensitive match for the last component. */ - if (createDisp == 2 || createDisp == 4 || createDisp == 5) { + if ( createDisp == FILE_CREATE || + createDisp == FILE_OVERWRITE || + createDisp == FILE_OVERWRITE_IF) { code = cm_NameI(baseDirp, spacep->data, CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, tidPathp, &req, &dscp); if (code == 0) { @@ -4848,7 +4951,7 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) code = cm_Lookup(dscp, (lastNamep)?(lastNamep+1):realPathp, CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, &req, &scp); if (code == 0 && realDirFlag == 1) { - cm_ReleaseSCache(scp); + cm_ReleaseSCache(scp); cm_ReleaseSCache(dscp); cm_ReleaseUser(userp); free(realPathp); @@ -4862,10 +4965,10 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) userp, tidPathp, &req, &scp); } if (code == 0) - foundscp = TRUE; + foundscp = TRUE; - if (!foundscp || (fidflags & (SMB_FID_OPENDELETE | SMB_FID_OPENWRITE))) { - /* look up parent directory */ + if (!foundscp || (fidflags & (SMB_FID_OPENDELETE | SMB_FID_OPENWRITE))) { + /* look up parent directory */ /* If we are trying to create a path (i.e. multiple nested directories), then we don't *need* * the immediate parent. We have to work our way up realPathp until we hit something that we * recognize. @@ -4881,7 +4984,7 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) if (code && (tp = strrchr(spacep->data,'\\')) && - (createDisp == 2) && + (createDisp == FILE_CREATE) && (realDirFlag == 1)) { *tp++ = 0; treeCreate = TRUE; @@ -4902,7 +5005,7 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) code = 0; if (baseFid != 0) - smb_ReleaseFID(baseFidp); + smb_ReleaseFID(baseFidp); if (code) { osi_Log0(smb_logp,"NTCreateX parent not found"); @@ -4932,25 +5035,29 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) } if (!foundscp && !treeCreate) { - if (createDisp == 2 || createDisp == 4) + if ( createDisp == FILE_CREATE || + createDisp == FILE_OVERWRITE || + createDisp == FILE_OVERWRITE_IF) + { code = cm_Lookup(dscp, lastNamep, CM_FLAG_FOLLOW, userp, &req, &scp); - else + } else { code = cm_Lookup(dscp, lastNamep, CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, &req, &scp); - if (code && code != CM_ERROR_NOSUCHFILE) { - cm_ReleaseSCache(dscp); - cm_ReleaseUser(userp); - free(realPathp); - return code; - } - } - } - else { - if (baseFid != 0) - smb_ReleaseFID(baseFidp); - } + } + if (code && code != CM_ERROR_NOSUCHFILE) { + cm_ReleaseSCache(dscp); + cm_ReleaseUser(userp); + free(realPathp); + return code; + } + } + } + else { + if (baseFid != 0) + smb_ReleaseFID(baseFidp); + } /* if we get here, if code is 0, the file exists and is represented by * scp. Otherwise, we have to create it. The dir may be represented @@ -4958,229 +5065,283 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) * scp is NULL. */ if (code == 0 && !treeCreate) { - code = cm_CheckNTOpen(scp, desiredAccess, createDisp, userp, - &req); - if (code) { - if (dscp) cm_ReleaseSCache(dscp); - cm_ReleaseSCache(scp); - cm_ReleaseUser(userp); - free(realPathp); - return code; - } - - if (createDisp == 2) { - /* oops, file shouldn't be there */ - if (dscp) cm_ReleaseSCache(dscp); - cm_ReleaseSCache(scp); - cm_ReleaseUser(userp); - free(realPathp); - return CM_ERROR_EXISTS; - } - - if (createDisp == 4 - || createDisp == 5) { - setAttr.mask = CM_ATTRMASK_LENGTH; - setAttr.length.LowPart = 0; - setAttr.length.HighPart = 0; - code = cm_SetAttr(scp, &setAttr, userp, &req); - openAction = 3; /* truncated existing file */ - } - else openAction = 1; /* found existing file */ - } - else if (createDisp == 1 || createDisp == 4) { - /* don't create if not found */ - if (dscp) cm_ReleaseSCache(dscp); - cm_ReleaseUser(userp); - free(realPathp); - return CM_ERROR_NOSUCHFILE; - } + if (createDisp == FILE_CREATE) { + /* oops, file shouldn't be there */ + if (dscp) cm_ReleaseSCache(dscp); + cm_ReleaseSCache(scp); + cm_ReleaseUser(userp); + free(realPathp); + return CM_ERROR_EXISTS; + } + + if ( createDisp == FILE_OVERWRITE || + createDisp == FILE_OVERWRITE_IF) { + setAttr.mask = CM_ATTRMASK_LENGTH; + setAttr.length.LowPart = 0; + setAttr.length.HighPart = 0; + /* now watch for a symlink */ + code = 0; + while (code == 0 && scp->fileType == CM_SCACHETYPE_SYMLINK) { + targetScp = 0; + code = cm_EvaluateSymLink(dscp, scp, &targetScp, userp, &req); + if (code == 0) { + /* we have a more accurate file to use (the + * target of the symbolic link). Otherwise, + * we'll just use the symlink anyway. + */ + osi_Log2(smb_logp, "symlink vp %x to vp %x", + scp, targetScp); + cm_ReleaseSCache(scp); + scp = targetScp; + } + } + code = cm_SetAttr(scp, &setAttr, userp, &req); + openAction = 3; /* truncated existing file */ + } + else + openAction = 1; /* found existing file */ + + code = cm_CheckNTOpen(scp, desiredAccess, createDisp, userp, + &req); + if (code) { + if (dscp) cm_ReleaseSCache(dscp); + cm_ReleaseSCache(scp); + cm_ReleaseUser(userp); + free(realPathp); + return code; + } + } + else if (createDisp == FILE_OPEN || createDisp == FILE_OVERWRITE) { + /* don't create if not found */ + if (dscp) cm_ReleaseSCache(dscp); + cm_ReleaseUser(userp); + free(realPathp); + return CM_ERROR_NOSUCHFILE; + } else if (realDirFlag == 0 || realDirFlag == -1) { - osi_assert(dscp != NULL); - osi_Log1(smb_logp, "smb_ReceiveNTCreateX creating file %s", - osi_LogSaveString(smb_logp, lastNamep)); - openAction = 2; /* created file */ - setAttr.mask = CM_ATTRMASK_CLIENTMODTIME; - setAttr.clientModTime = time(NULL); - code = cm_Create(dscp, lastNamep, 0, &setAttr, &scp, userp, - &req); - if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) - smb_NotifyChange(FILE_ACTION_ADDED, - FILE_NOTIFY_CHANGE_FILE_NAME, - dscp, lastNamep, NULL, TRUE); - if (code == CM_ERROR_EXISTS && createDisp != 2) { - /* Not an exclusive create, and someone else tried - * creating it already, then we open it anyway. We - * don't bother retrying after this, since if this next - * fails, that means that the file was deleted after we - * started this call. - */ - code = cm_Lookup(dscp, lastNamep, CM_FLAG_CASEFOLD, - userp, &req, &scp); - if (code == 0) { - if (createDisp == 5) { - setAttr.mask = CM_ATTRMASK_LENGTH; - setAttr.length.LowPart = 0; - setAttr.length.HighPart = 0; - code = cm_SetAttr(scp, &setAttr, userp, - &req); - } - } /* lookup succeeded */ - } - } + osi_assert(dscp != NULL); + osi_Log1(smb_logp, "smb_ReceiveNTCreateX creating file %s", + osi_LogSaveString(smb_logp, lastNamep)); + openAction = 2; /* created file */ + setAttr.mask = CM_ATTRMASK_CLIENTMODTIME; + setAttr.clientModTime = time(NULL); + code = cm_Create(dscp, lastNamep, 0, &setAttr, &scp, userp, + &req); + if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) + smb_NotifyChange(FILE_ACTION_ADDED, + FILE_NOTIFY_CHANGE_FILE_NAME, + dscp, lastNamep, NULL, TRUE); + if (code == CM_ERROR_EXISTS && createDisp != FILE_CREATE) { + /* Not an exclusive create, and someone else tried + * creating it already, then we open it anyway. We + * don't bother retrying after this, since if this next + * fails, that means that the file was deleted after we + * started this call. + */ + code = cm_Lookup(dscp, lastNamep, CM_FLAG_CASEFOLD, + userp, &req, &scp); + if (code == 0) { + if (createDisp == FILE_OVERWRITE_IF) { + setAttr.mask = CM_ATTRMASK_LENGTH; + setAttr.length.LowPart = 0; + setAttr.length.HighPart = 0; + + /* now watch for a symlink */ + code = 0; + while (code == 0 && scp->fileType == CM_SCACHETYPE_SYMLINK) { + targetScp = 0; + code = cm_EvaluateSymLink(dscp, scp, &targetScp, userp, &req); + if (code == 0) { + /* we have a more accurate file to use (the + * target of the symbolic link). Otherwise, + * we'll just use the symlink anyway. + */ + osi_Log2(smb_logp, "symlink vp %x to vp %x", + scp, targetScp); + cm_ReleaseSCache(scp); + scp = targetScp; + } + } + code = cm_SetAttr(scp, &setAttr, userp, &req); + } + } /* lookup succeeded */ + } + } else { - char *tp, *pp; - char *cp; /* This component */ - int clen = 0; /* length of component */ - cm_scache_t *tscp; - int isLast = 0; + char *tp, *pp; + char *cp; /* This component */ + int clen = 0; /* length of component */ + cm_scache_t *tscp; + int isLast = 0; - /* create directory */ - if ( !treeCreate ) treeStartp = lastNamep; - osi_assert(dscp != NULL); - osi_Log1(smb_logp, "smb_ReceiveNTCreateX creating directory [%s]", - osi_LogSaveString(smb_logp, treeStartp)); - openAction = 2; /* created directory */ - - setAttr.mask = CM_ATTRMASK_CLIENTMODTIME; - setAttr.clientModTime = time(NULL); + /* create directory */ + if ( !treeCreate ) + treeStartp = lastNamep; + osi_assert(dscp != NULL); + osi_Log1(smb_logp, "smb_ReceiveNTCreateX creating directory [%s]", + osi_LogSaveString(smb_logp, treeStartp)); + openAction = 2; /* created directory */ + + setAttr.mask = CM_ATTRMASK_CLIENTMODTIME; + setAttr.clientModTime = time(NULL); - pp = treeStartp; - cp = spacep->data; - tscp = dscp; - - while (pp && *pp) { - tp = strchr(pp, '\\'); - if (!tp) { - strcpy(cp,pp); - clen = strlen(cp); - isLast = 1; /* indicate last component. the supplied path never ends in a slash */ - } - else { - clen = tp - pp; - strncpy(cp,pp,clen); - *(cp + clen) = 0; - tp++; - } - pp = tp; - - if (clen == 0) continue; /* the supplied path can't have consecutive slashes either , but */ - - /* cp is the next component to be created. */ - code = cm_MakeDir(tscp, cp, 0, &setAttr, userp, &req); - if (code == 0 && (tscp->flags & CM_SCACHEFLAG_ANYWATCH)) - smb_NotifyChange(FILE_ACTION_ADDED, - FILE_NOTIFY_CHANGE_DIR_NAME, - tscp, cp, NULL, TRUE); - if (code == 0 || - (code == CM_ERROR_EXISTS && createDisp != 2)) { - /* Not an exclusive create, and someone else tried - * creating it already, then we open it anyway. We - * don't bother retrying after this, since if this next - * fails, that means that the file was deleted after we - * started this call. - */ - code = cm_Lookup(tscp, cp, CM_FLAG_CASEFOLD, - userp, &req, &scp); - } - if (code) break; - - if (!isLast) { /* for anything other than dscp, release it unless it's the last one */ - cm_ReleaseSCache(tscp); - tscp = scp; /* Newly created directory will be next parent */ - } - } - - /* - if we get here and code == 0, then scp is the last directory created, and tscp is the - parent of scp. dscp got released if dscp != tscp. both tscp and scp are held. - */ - dscp = tscp; - } + pp = treeStartp; + cp = spacep->data; + tscp = dscp; + + while (pp && *pp) { + tp = strchr(pp, '\\'); + if (!tp) { + strcpy(cp,pp); + clen = strlen(cp); + isLast = 1; /* indicate last component. the supplied path never ends in a slash */ + } + else { + clen = tp - pp; + strncpy(cp,pp,clen); + *(cp + clen) = 0; + tp++; + } + pp = tp; + + if (clen == 0) + continue; /* the supplied path can't have consecutive slashes either , but */ + + /* cp is the next component to be created. */ + code = cm_MakeDir(tscp, cp, 0, &setAttr, userp, &req); + if (code == 0 && (tscp->flags & CM_SCACHEFLAG_ANYWATCH)) + smb_NotifyChange(FILE_ACTION_ADDED, + FILE_NOTIFY_CHANGE_DIR_NAME, + tscp, cp, NULL, TRUE); + if (code == 0 || + (code == CM_ERROR_EXISTS && createDisp != FILE_CREATE)) { + /* Not an exclusive create, and someone else tried + * creating it already, then we open it anyway. We + * don't bother retrying after this, since if this next + * fails, that means that the file was deleted after we + * started this call. + */ + code = cm_Lookup(tscp, cp, CM_FLAG_CASEFOLD, + userp, &req, &scp); + } + if (code) break; - if (code) { - /* something went wrong creating or truncating the file */ - if (scp) cm_ReleaseSCache(scp); - if (dscp) cm_ReleaseSCache(dscp); - cm_ReleaseUser(userp); - free(realPathp); - return code; + if (!isLast) { /* for anything other than dscp, release it unless it's the last one */ + cm_ReleaseSCache(tscp); + tscp = scp; /* Newly created directory will be next parent */ + } + } + + /* + * if we get here and code == 0, then scp is the last directory created, and tscp is the + * parent of scp. dscp got released if dscp != tscp. both tscp and scp are held. + */ + dscp = tscp; } - /* make sure we have file vs. dir right (only applies for single component case) */ - if (realDirFlag == 0 && scp->fileType != CM_SCACHETYPE_FILE) { - cm_ReleaseSCache(scp); + if (code) { + /* something went wrong creating or truncating the file */ + if (scp) cm_ReleaseSCache(scp); if (dscp) cm_ReleaseSCache(dscp); - cm_ReleaseUser(userp); - free(realPathp); - return CM_ERROR_ISDIR; - } + cm_ReleaseUser(userp); + free(realPathp); + return code; + } + + /* make sure we have file vs. dir right (only applies for single component case) */ + if (realDirFlag == 0 && scp->fileType != CM_SCACHETYPE_FILE) { + /* now watch for a symlink */ + code = 0; + while (code == 0 && scp->fileType == CM_SCACHETYPE_SYMLINK) { + cm_scache_t * targetScp = 0; + code = cm_EvaluateSymLink(dscp, scp, &targetScp, userp, &req); + if (code == 0) { + /* we have a more accurate file to use (the + * target of the symbolic link). Otherwise, + * we'll just use the symlink anyway. + */ + osi_Log2(smb_logp, "symlink vp %x to vp %x", + scp, targetScp); + cm_ReleaseSCache(scp); + scp = targetScp; + } + } + + if (scp->fileType != CM_SCACHETYPE_FILE) { + cm_ReleaseSCache(scp); + cm_ReleaseUser(userp); + free(realPathp); + return CM_ERROR_ISDIR; + } + } + /* (only applies to single component case) */ - if (realDirFlag == 1 && scp->fileType == CM_SCACHETYPE_FILE) { - cm_ReleaseSCache(scp); + if (realDirFlag == 1 && scp->fileType == CM_SCACHETYPE_FILE) { + cm_ReleaseSCache(scp); if (dscp) cm_ReleaseSCache(dscp); - cm_ReleaseUser(userp); - free(realPathp); - return CM_ERROR_NOTDIR; - } + cm_ReleaseUser(userp); + free(realPathp); + return CM_ERROR_NOTDIR; + } - /* open the file itself */ - fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE); - osi_assert(fidp); - /* save a pointer to the vnode */ - fidp->scp = scp; + /* open the file itself */ + fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE); + osi_assert(fidp); + /* save a pointer to the vnode */ + fidp->scp = scp; - fidp->flags = fidflags; + fidp->flags = fidflags; - /* save parent dir and pathname for delete or change notification */ - if (fidflags & (SMB_FID_OPENDELETE | SMB_FID_OPENWRITE)) { - fidp->flags |= SMB_FID_NTOPEN; - fidp->NTopen_dscp = dscp; - cm_HoldSCache(dscp); - fidp->NTopen_pathp = strdup(lastNamep); - } - fidp->NTopen_wholepathp = realPathp; - - /* we don't need this any longer */ - if (dscp) cm_ReleaseSCache(dscp); - cm_Open(scp, 0, userp); - - /* set inp->fid so that later read calls in same msg can find fid */ - inp->fid = fidp->fid; - - /* out parms */ - parmSlot = 2; - lock_ObtainMutex(&scp->mx); - smb_SetSMBParmByte(outp, parmSlot, 0); /* oplock */ - smb_SetSMBParm(outp, parmSlot, fidp->fid); parmSlot++; - smb_SetSMBParmLong(outp, parmSlot, openAction); parmSlot += 2; - smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime); - smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4; - smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4; - smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4; - smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4; - smb_SetSMBParmLong(outp, parmSlot, smb_ExtAttributes(scp)); - parmSlot += 2; - smb_SetSMBParmDouble(outp, parmSlot, (char *)&scp->length); parmSlot += 4; - smb_SetSMBParmDouble(outp, parmSlot, (char *)&scp->length); parmSlot += 4; - smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* filetype */ - smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* dev state */ - smb_SetSMBParmByte(outp, parmSlot, - scp->fileType == CM_SCACHETYPE_DIRECTORY); /* is a dir? */ - lock_ReleaseMutex(&scp->mx); - smb_SetSMBDataLength(outp, 0); - - osi_Log2(smb_logp, "SMB NT CreateX opening fid %d path %s", fidp->fid, - osi_LogSaveString(smb_logp, realPathp)); - - smb_ReleaseFID(fidp); - - cm_ReleaseUser(userp); + /* save parent dir and pathname for delete or change notification */ + if (fidflags & (SMB_FID_OPENDELETE | SMB_FID_OPENWRITE)) { + fidp->flags |= SMB_FID_NTOPEN; + fidp->NTopen_dscp = dscp; + cm_HoldSCache(dscp); + fidp->NTopen_pathp = strdup(lastNamep); + } + fidp->NTopen_wholepathp = realPathp; + + /* we don't need this any longer */ + if (dscp) cm_ReleaseSCache(dscp); + cm_Open(scp, 0, userp); + + /* set inp->fid so that later read calls in same msg can find fid */ + inp->fid = fidp->fid; + + /* out parms */ + parmSlot = 2; + lock_ObtainMutex(&scp->mx); + smb_SetSMBParmByte(outp, parmSlot, 0); /* oplock */ + smb_SetSMBParm(outp, parmSlot, fidp->fid); parmSlot++; + smb_SetSMBParmLong(outp, parmSlot, openAction); parmSlot += 2; + smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime); + smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4; + smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4; + smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4; + smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4; + smb_SetSMBParmLong(outp, parmSlot, smb_ExtAttributes(scp)); + parmSlot += 2; + smb_SetSMBParmDouble(outp, parmSlot, (char *)&scp->length); parmSlot += 4; + smb_SetSMBParmDouble(outp, parmSlot, (char *)&scp->length); parmSlot += 4; + smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* filetype */ + smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* dev state */ + smb_SetSMBParmByte(outp, parmSlot, + scp->fileType == CM_SCACHETYPE_DIRECTORY); /* is a dir? */ + lock_ReleaseMutex(&scp->mx); + smb_SetSMBDataLength(outp, 0); + + osi_Log2(smb_logp, "SMB NT CreateX opening fid %d path %s", fidp->fid, + osi_LogSaveString(smb_logp, realPathp)); + + smb_ReleaseFID(fidp); + + cm_ReleaseUser(userp); /* Can't free realPathp if we get here since fidp->NTopen_wholepathp is pointing there */ - /* leave scp held since we put it in fidp->scp */ - return 0; -} + /* leave scp held since we put it in fidp->scp */ + return 0; +} /* * A lot of stuff copied verbatim from NT Create&X to NT Tran Create. @@ -5188,165 +5349,167 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) */ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - char *pathp, *realPathp; - long code = 0; - cm_space_t *spacep; - cm_user_t *userp; - cm_scache_t *dscp; /* parent dir */ - cm_scache_t *scp; /* file to create or open */ - cm_attr_t setAttr; - char *lastNamep; - unsigned long nameLength; - unsigned int flags; - unsigned int requestOpLock; - unsigned int requestBatchOpLock; - unsigned int mustBeDir; + char *pathp, *realPathp; + long code = 0; + cm_space_t *spacep; + cm_user_t *userp; + cm_scache_t *dscp; /* parent dir */ + cm_scache_t *scp; /* file to create or open */ + cm_scache_t *targetScp; /* if scp is a symlink */ + cm_attr_t setAttr; + char *lastNamep; + unsigned long nameLength; + unsigned int flags; + unsigned int requestOpLock; + unsigned int requestBatchOpLock; + unsigned int mustBeDir; unsigned int extendedRespRequired; - int realDirFlag; - unsigned int desiredAccess; + int realDirFlag; + unsigned int desiredAccess; #ifdef DEBUG_VERBOSE unsigned int allocSize; unsigned int shareAccess; #endif - unsigned int extAttributes; - unsigned int createDisp; + unsigned int extAttributes; + unsigned int createDisp; #ifdef DEBUG_VERBOSE unsigned int sdLen; #endif - unsigned int createOptions; - int initialModeBits; - unsigned short baseFid; - smb_fid_t *baseFidp; - smb_fid_t *fidp; - cm_scache_t *baseDirp; - unsigned short openAction; - int parmSlot; - long fidflags; - FILETIME ft; - char *tidPathp; - BOOL foundscp; - int parmOffset, dataOffset; - char *parmp; - ULONG *lparmp; - char *outData; - cm_req_t req; - - cm_InitReq(&req); - - foundscp = FALSE; - scp = NULL; - - parmOffset = smb_GetSMBOffsetParm(inp, 11, 1) - | (smb_GetSMBOffsetParm(inp, 12, 1) << 16); - parmp = inp->data + parmOffset; - lparmp = (ULONG *) parmp; - - flags = lparmp[0]; - requestOpLock = flags & 0x02; - requestBatchOpLock = flags & 0x04; - mustBeDir = flags & 0x08; + unsigned int createOptions; + int initialModeBits; + unsigned short baseFid; + smb_fid_t *baseFidp; + smb_fid_t *fidp; + cm_scache_t *baseDirp; + unsigned short openAction; + int parmSlot; + long fidflags; + FILETIME ft; + char *tidPathp; + BOOL foundscp; + int parmOffset, dataOffset; + char *parmp; + ULONG *lparmp; + char *outData; + cm_req_t req; + + cm_InitReq(&req); + + foundscp = FALSE; + scp = NULL; + + parmOffset = smb_GetSMBOffsetParm(inp, 11, 1) + | (smb_GetSMBOffsetParm(inp, 12, 1) << 16); + parmp = inp->data + parmOffset; + lparmp = (ULONG *) parmp; + + flags = lparmp[0]; + requestOpLock = flags & 0x02; + requestBatchOpLock = flags & 0x04; + mustBeDir = flags & 0x08; extendedRespRequired = flags & 0x10; - /* - * Why all of a sudden 32-bit FID? - * We will reject all bits higher than 16. - */ - if (lparmp[1] & 0xFFFF0000) - return CM_ERROR_INVAL; - baseFid = (unsigned short)lparmp[1]; - desiredAccess = lparmp[2]; + /* + * Why all of a sudden 32-bit FID? + * We will reject all bits higher than 16. + */ + if (lparmp[1] & 0xFFFF0000) + return CM_ERROR_INVAL; + baseFid = (unsigned short)lparmp[1]; + desiredAccess = lparmp[2]; #ifdef DEBUG_VERBOSE allocSize = lparmp[3]; #endif /* DEBUG_VERSOSE */ - extAttributes = lparmp[5]; + extAttributes = lparmp[5]; #ifdef DEBUG_VEROSE shareAccess = lparmp[6]; #endif - createDisp = lparmp[7]; - createOptions = lparmp[8]; + createDisp = lparmp[7]; + createOptions = lparmp[8]; #ifdef DEBUG_VERBOSE sdLen = lparmp[9]; #endif - nameLength = lparmp[11]; + nameLength = lparmp[11]; #ifdef DEBUG_VERBOSE - osi_Log4(smb_logp,"NTTransCreate with da[%x],ea[%x],sa[%x],cd[%x]",desiredAccess,extAttributes,shareAccess,createDisp); - osi_Log2(smb_logp,"... co[%x],sdl[%x],as[%x]",createOptions,sdLen,allocSize); - osi_Log1(smb_logp,"... flags[%x]",flags); + osi_Log4(smb_logp,"NTTranCreate with da[%x],ea[%x],sa[%x],cd[%x]",desiredAccess,extAttributes,shareAccess,createDisp); + osi_Log3(smb_logp,"... co[%x],sdl[%x],as[%x]",createOptions,sdLen,allocSize); + osi_Log1(smb_logp,"... flags[%x]",flags); #endif - /* mustBeDir is never set; createOptions directory bit seems to be - * more important - */ - if (createOptions & 1) - realDirFlag = 1; - else if (createOptions & 0x40) - realDirFlag = 0; - else - realDirFlag = -1; - - /* - * compute initial mode bits based on read-only flag in - * extended attributes - */ - initialModeBits = 0666; - if (extAttributes & 1) initialModeBits &= ~0222; + /* mustBeDir is never set; createOptions directory bit seems to be + * more important + */ + if (createOptions & 1) + realDirFlag = 1; + else if (createOptions & 0x40) + realDirFlag = 0; + else + realDirFlag = -1; - pathp = parmp + (13 * sizeof(ULONG)) + sizeof(UCHAR); - /* Sometimes path is not null-terminated, so we make a copy. */ - realPathp = malloc(nameLength+1); - memcpy(realPathp, pathp, nameLength); - realPathp[nameLength] = 0; + /* + * compute initial mode bits based on read-only flag in + * extended attributes + */ + initialModeBits = 0666; + if (extAttributes & 1) + initialModeBits &= ~0222; - spacep = cm_GetSpace(); - smb_StripLastComponent(spacep->data, &lastNamep, realPathp); + pathp = parmp + (13 * sizeof(ULONG)) + sizeof(UCHAR); + /* Sometimes path is not null-terminated, so we make a copy. */ + realPathp = malloc(nameLength+1); + memcpy(realPathp, pathp, nameLength); + realPathp[nameLength] = 0; - /* - * Nothing here to handle SMB_IOCTL_FILENAME. - * Will add it if necessary. - */ + spacep = cm_GetSpace(); + smb_StripLastComponent(spacep->data, &lastNamep, realPathp); + + /* + * Nothing here to handle SMB_IOCTL_FILENAME. + * Will add it if necessary. + */ #ifdef DEBUG_VERBOSE - { - char *hexp, *asciip; - asciip = (lastNamep? lastNamep : realPathp); - hexp = osi_HexifyString( asciip ); - DEBUG_EVENT2("AFS", "NTTranCreate H[%s] A[%s]", hexp, asciip); - free(hexp); - } + { + char *hexp, *asciip; + asciip = (lastNamep? lastNamep : realPathp); + hexp = osi_HexifyString( asciip ); + DEBUG_EVENT2("AFS", "NTTranCreate H[%s] A[%s]", hexp, asciip); + free(hexp); + } #endif - userp = smb_GetUser(vcp, inp); + userp = smb_GetUser(vcp, inp); if (!userp) { osi_Log1(smb_logp, "NTTranCreate invalid user [%d]", ((smb_t *) inp)->uid); free(realPathp); return CM_ERROR_INVAL; } - if (baseFid == 0) { - baseDirp = cm_rootSCachep; - code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); + if (baseFid == 0) { + baseDirp = cm_rootSCachep; + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); if(code == CM_ERROR_TIDIPC) { /* Attempt to use TID allocated for IPC. The client is - probably trying to locate DCE RPC endpoints, which we - don't support. */ + * probably trying to locate DCE RPC endpoints, which we + * don't support. */ osi_Log0(smb_logp, "NTTranCreate received IPC TID"); free(realPathp); cm_ReleaseUser(userp); return CM_ERROR_NOSUCHPATH; } - } - else { + } + else { baseFidp = smb_FindFID(vcp, baseFid, 0); if (!baseFidp) { osi_Log1(smb_logp, "NTTranCreate Invalid fid [%d]", baseFid); - free(realPathp); - cm_ReleaseUser(userp); - return CM_ERROR_INVAL; - } - baseDirp = baseFidp->scp; - tidPathp = NULL; - } + free(realPathp); + cm_ReleaseUser(userp); + return CM_ERROR_INVAL; + } + baseDirp = baseFidp->scp; + tidPathp = NULL; + } /* compute open mode */ fidflags = 0; @@ -5357,9 +5520,11 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out if (desiredAccess & AFS_ACCESS_WRITE) fidflags |= SMB_FID_OPENWRITE; - dscp = NULL; - code = 0; - if (createDisp == 2 || createDisp == 4 || createDisp == 5) { + dscp = NULL; + code = 0; + if ( createDisp == FILE_OPEN || + createDisp == FILE_OVERWRITE || + createDisp == FILE_OVERWRITE_IF) { code = cm_NameI(baseDirp, spacep->data, CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, tidPathp, &req, &dscp); if (code == 0) { @@ -5369,7 +5534,7 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out code = cm_Lookup(dscp, (lastNamep)?(lastNamep+1):realPathp, CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, &req, &scp); if (code == 0 && realDirFlag == 1) { - cm_ReleaseSCache(scp); + cm_ReleaseSCache(scp); cm_ReleaseSCache(dscp); cm_ReleaseUser(userp); free(realPathp); @@ -5383,10 +5548,11 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out userp, tidPathp, &req, &scp); } - if (code == 0) foundscp = TRUE; - if (code != 0 - || (fidflags & (SMB_FID_OPENDELETE | SMB_FID_OPENWRITE))) { - /* look up parent directory */ + if (code == 0) + foundscp = TRUE; + if (code != 0 + || (fidflags & (SMB_FID_OPENDELETE | SMB_FID_OPENWRITE))) { + /* look up parent directory */ if ( !dscp ) { code = cm_NameI(baseDirp, spacep->data, CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, @@ -5396,179 +5562,233 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out cm_FreeSpace(spacep); - if (baseFid != 0) { - smb_ReleaseFID(baseFidp); - baseFidp = 0; + if (baseFid != 0) { + smb_ReleaseFID(baseFidp); + baseFidp = 0; } - if (code) { - cm_ReleaseUser(userp); - free(realPathp); - return code; - } + if (code) { + cm_ReleaseUser(userp); + free(realPathp); + return code; + } - if (!lastNamep) lastNamep = realPathp; - else lastNamep++; + if (!lastNamep) lastNamep = realPathp; + else lastNamep++; if (!smb_IsLegalFilename(lastNamep)) return CM_ERROR_BADNTFILENAME; - if (!foundscp) { - if (createDisp == 2 || createDisp == 4) + if (!foundscp) { + if (createDisp == FILE_CREATE || createDisp == FILE_OVERWRITE_IF) { code = cm_Lookup(dscp, lastNamep, - CM_FLAG_FOLLOW, userp, &req, &scp); - else + CM_FLAG_FOLLOW, userp, &req, &scp); + } else { code = cm_Lookup(dscp, lastNamep, CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, &req, &scp); - if (code && code != CM_ERROR_NOSUCHFILE) { - cm_ReleaseSCache(dscp); - cm_ReleaseUser(userp); - free(realPathp); - return code; - } - } - } - else { - if (baseFid != 0) { + } + if (code && code != CM_ERROR_NOSUCHFILE) { + cm_ReleaseSCache(dscp); + cm_ReleaseUser(userp); + free(realPathp); + return code; + } + } + } + else { + if (baseFid != 0) { smb_ReleaseFID(baseFidp); baseFidp = 0; } - cm_FreeSpace(spacep); - } + cm_FreeSpace(spacep); + } - /* if we get here, if code is 0, the file exists and is represented by - * scp. Otherwise, we have to create it. The dir may be represented - * by dscp, or we may have found the file directly. If code is non-zero, - * scp is NULL. - */ - if (code == 0) { - code = cm_CheckNTOpen(scp, desiredAccess, createDisp, userp, - &req); - if (code) { - if (dscp) cm_ReleaseSCache(dscp); - cm_ReleaseSCache(scp); - cm_ReleaseUser(userp); - free(realPathp); - return code; - } - - if (createDisp == 2) { - /* oops, file shouldn't be there */ - if (dscp) cm_ReleaseSCache(dscp); - cm_ReleaseSCache(scp); - cm_ReleaseUser(userp); - free(realPathp); - return CM_ERROR_EXISTS; - } - - if (createDisp == 4 - || createDisp == 5) { - setAttr.mask = CM_ATTRMASK_LENGTH; - setAttr.length.LowPart = 0; - setAttr.length.HighPart = 0; - code = cm_SetAttr(scp, &setAttr, userp, &req); - openAction = 3; /* truncated existing file */ - } - else openAction = 1; /* found existing file */ - } - else if (createDisp == 1 || createDisp == 4) { - /* don't create if not found */ - if (dscp) cm_ReleaseSCache(dscp); - cm_ReleaseUser(userp); - free(realPathp); - return CM_ERROR_NOSUCHFILE; - } - else if (realDirFlag == 0 || realDirFlag == -1) { - osi_assert(dscp != NULL); - osi_Log1(smb_logp, "smb_ReceiveNTTranCreate creating file %s", - osi_LogSaveString(smb_logp, lastNamep)); - openAction = 2; /* created file */ - setAttr.mask = CM_ATTRMASK_CLIENTMODTIME; - setAttr.clientModTime = time(NULL); - code = cm_Create(dscp, lastNamep, 0, &setAttr, &scp, userp, - &req); - if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) - smb_NotifyChange(FILE_ACTION_ADDED, - FILE_NOTIFY_CHANGE_FILE_NAME, - dscp, lastNamep, NULL, TRUE); - if (code == CM_ERROR_EXISTS && createDisp != 2) { - /* Not an exclusive create, and someone else tried - * creating it already, then we open it anyway. We - * don't bother retrying after this, since if this next - * fails, that means that the file was deleted after we - * started this call. - */ - code = cm_Lookup(dscp, lastNamep, CM_FLAG_CASEFOLD, - userp, &req, &scp); - if (code == 0) { - if (createDisp == 5) { - setAttr.mask = CM_ATTRMASK_LENGTH; - setAttr.length.LowPart = 0; - setAttr.length.HighPart = 0; - code = cm_SetAttr(scp, &setAttr, userp, - &req); - } - } /* lookup succeeded */ - } - } - else { - /* create directory */ - osi_assert(dscp != NULL); - osi_Log1(smb_logp, - "smb_ReceiveNTTranCreate creating directory %s", - osi_LogSaveString(smb_logp, lastNamep)); - openAction = 2; /* created directory */ - setAttr.mask = CM_ATTRMASK_CLIENTMODTIME; - setAttr.clientModTime = time(NULL); - code = cm_MakeDir(dscp, lastNamep, 0, &setAttr, userp, &req); - if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) - smb_NotifyChange(FILE_ACTION_ADDED, - FILE_NOTIFY_CHANGE_DIR_NAME, - dscp, lastNamep, NULL, TRUE); - if (code == 0 - || (code == CM_ERROR_EXISTS && createDisp != 2)) { - /* Not an exclusive create, and someone else tried - * creating it already, then we open it anyway. We - * don't bother retrying after this, since if this next - * fails, that means that the file was deleted after we - * started this call. - */ - code = cm_Lookup(dscp, lastNamep, CM_FLAG_CASEFOLD, - userp, &req, &scp); - } - } + /* if we get here, if code is 0, the file exists and is represented by + * scp. Otherwise, we have to create it. The dir may be represented + * by dscp, or we may have found the file directly. If code is non-zero, + * scp is NULL. + */ + if (code == 0) { + code = cm_CheckNTOpen(scp, desiredAccess, createDisp, userp, + &req); + if (code) { + if (dscp) cm_ReleaseSCache(dscp); + cm_ReleaseSCache(scp); + cm_ReleaseUser(userp); + free(realPathp); + return code; + } - if (code) { - /* something went wrong creating or truncating the file */ - if (scp) cm_ReleaseSCache(scp); - cm_ReleaseUser(userp); - free(realPathp); - return code; - } + if (createDisp == FILE_CREATE) { + /* oops, file shouldn't be there */ + if (dscp) cm_ReleaseSCache(dscp); + cm_ReleaseSCache(scp); + cm_ReleaseUser(userp); + free(realPathp); + return CM_ERROR_EXISTS; + } - /* make sure we have file vs. dir right */ - if (realDirFlag == 0 && scp->fileType != CM_SCACHETYPE_FILE) { - cm_ReleaseSCache(scp); - cm_ReleaseUser(userp); - free(realPathp); - return CM_ERROR_ISDIR; - } - if (realDirFlag == 1 && scp->fileType == CM_SCACHETYPE_FILE) { - cm_ReleaseSCache(scp); - cm_ReleaseUser(userp); - free(realPathp); - return CM_ERROR_NOTDIR; - } + if (createDisp == FILE_OVERWRITE || + createDisp == FILE_OVERWRITE_IF) { + setAttr.mask = CM_ATTRMASK_LENGTH; + setAttr.length.LowPart = 0; + setAttr.length.HighPart = 0; + + /* now watch for a symlink */ + code = 0; + while (code == 0 && scp->fileType == CM_SCACHETYPE_SYMLINK) { + targetScp = 0; + code = cm_EvaluateSymLink(dscp, scp, &targetScp, userp, &req); + if (code == 0) { + /* we have a more accurate file to use (the + * target of the symbolic link). Otherwise, + * we'll just use the symlink anyway. + */ + osi_Log2(smb_logp, "symlink vp %x to vp %x", + scp, targetScp); + cm_ReleaseSCache(scp); + scp = targetScp; + } + } + code = cm_SetAttr(scp, &setAttr, userp, &req); + openAction = 3; /* truncated existing file */ + } + else openAction = 1; /* found existing file */ + } + else if (createDisp == FILE_OPEN || createDisp == FILE_OVERWRITE) { + /* don't create if not found */ + if (dscp) cm_ReleaseSCache(dscp); + cm_ReleaseUser(userp); + free(realPathp); + return CM_ERROR_NOSUCHFILE; + } + else if (realDirFlag == 0 || realDirFlag == -1) { + osi_assert(dscp != NULL); + osi_Log1(smb_logp, "smb_ReceiveNTTranCreate creating file %s", + osi_LogSaveString(smb_logp, lastNamep)); + openAction = 2; /* created file */ + setAttr.mask = CM_ATTRMASK_CLIENTMODTIME; + setAttr.clientModTime = time(NULL); + code = cm_Create(dscp, lastNamep, 0, &setAttr, &scp, userp, + &req); + if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) + smb_NotifyChange(FILE_ACTION_ADDED, + FILE_NOTIFY_CHANGE_FILE_NAME, + dscp, lastNamep, NULL, TRUE); + if (code == CM_ERROR_EXISTS && createDisp != FILE_CREATE) { + /* Not an exclusive create, and someone else tried + * creating it already, then we open it anyway. We + * don't bother retrying after this, since if this next + * fails, that means that the file was deleted after we + * started this call. + */ + code = cm_Lookup(dscp, lastNamep, CM_FLAG_CASEFOLD, + userp, &req, &scp); + if (code == 0) { + if (createDisp == FILE_OVERWRITE_IF) { + setAttr.mask = CM_ATTRMASK_LENGTH; + setAttr.length.LowPart = 0; + setAttr.length.HighPart = 0; + + /* now watch for a symlink */ + code = 0; + while (code == 0 && scp->fileType == CM_SCACHETYPE_SYMLINK) { + targetScp = 0; + code = cm_EvaluateSymLink(dscp, scp, &targetScp, userp, &req); + if (code == 0) { + /* we have a more accurate file to use (the + * target of the symbolic link). Otherwise, + * we'll just use the symlink anyway. + */ + osi_Log2(smb_logp, "symlink vp %x to vp %x", + scp, targetScp); + cm_ReleaseSCache(scp); + scp = targetScp; + } + } + code = cm_SetAttr(scp, &setAttr, userp, &req); + } + } /* lookup succeeded */ + } + } + else { + /* create directory */ + osi_assert(dscp != NULL); + osi_Log1(smb_logp, + "smb_ReceiveNTTranCreate creating directory %s", + osi_LogSaveString(smb_logp, lastNamep)); + openAction = 2; /* created directory */ + setAttr.mask = CM_ATTRMASK_CLIENTMODTIME; + setAttr.clientModTime = time(NULL); + code = cm_MakeDir(dscp, lastNamep, 0, &setAttr, userp, &req); + if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) + smb_NotifyChange(FILE_ACTION_ADDED, + FILE_NOTIFY_CHANGE_DIR_NAME, + dscp, lastNamep, NULL, TRUE); + if (code == 0 || + (code == CM_ERROR_EXISTS && createDisp != FILE_CREATE)) { + /* Not an exclusive create, and someone else tried + * creating it already, then we open it anyway. We + * don't bother retrying after this, since if this next + * fails, that means that the file was deleted after we + * started this call. + */ + code = cm_Lookup(dscp, lastNamep, CM_FLAG_CASEFOLD, + userp, &req, &scp); + } + } - /* open the file itself */ - fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE); - osi_assert(fidp); + if (code) { + /* something went wrong creating or truncating the file */ + if (scp) cm_ReleaseSCache(scp); + cm_ReleaseUser(userp); + free(realPathp); + return code; + } + + /* make sure we have file vs. dir right */ + if (realDirFlag == 0 && scp->fileType != CM_SCACHETYPE_FILE) { + /* now watch for a symlink */ + code = 0; + while (code == 0 && scp->fileType == CM_SCACHETYPE_SYMLINK) { + targetScp = 0; + code = cm_EvaluateSymLink(dscp, scp, &targetScp, userp, &req); + if (code == 0) { + /* we have a more accurate file to use (the + * target of the symbolic link). Otherwise, + * we'll just use the symlink anyway. + */ + osi_Log2(smb_logp, "symlink vp %x to vp %x", + scp, targetScp); + cm_ReleaseSCache(scp); + scp = targetScp; + } + } + + if (scp->fileType != CM_SCACHETYPE_FILE) { + cm_ReleaseSCache(scp); + cm_ReleaseUser(userp); + free(realPathp); + return CM_ERROR_ISDIR; + } + } + + if (realDirFlag == 1 && scp->fileType == CM_SCACHETYPE_FILE) { + cm_ReleaseSCache(scp); + cm_ReleaseUser(userp); + free(realPathp); + return CM_ERROR_NOTDIR; + } + + /* open the file itself */ + fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE); + osi_assert(fidp); - /* save a pointer to the vnode */ - fidp->scp = scp; + /* save a pointer to the vnode */ + fidp->scp = scp; - fidp->flags = fidflags; + fidp->flags = fidflags; /* save parent dir and pathname for deletion or change notification */ if (fidflags & (SMB_FID_OPENDELETE | SMB_FID_OPENWRITE)) { @@ -5577,15 +5797,15 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out cm_HoldSCache(dscp); fidp->NTopen_pathp = strdup(lastNamep); } - fidp->NTopen_wholepathp = realPathp; + fidp->NTopen_wholepathp = realPathp; - /* we don't need this any longer */ - if (dscp) cm_ReleaseSCache(dscp); + /* we don't need this any longer */ + if (dscp) cm_ReleaseSCache(dscp); - cm_Open(scp, 0, userp); + cm_Open(scp, 0, userp); - /* set inp->fid so that later read calls in same msg can find fid */ - inp->fid = fidp->fid; + /* set inp->fid so that later read calls in same msg can find fid */ + inp->fid = fidp->fid; /* check whether we are required to send an extended response */ if (!extendedRespRequired) { @@ -5689,29 +5909,29 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out lock_ReleaseMutex(&scp->mx); } - osi_Log1(smb_logp, "SMB NTTranCreate opening fid %d", fidp->fid); + osi_Log1(smb_logp, "SMB NTTranCreate opening fid %d", fidp->fid); - smb_ReleaseFID(fidp); + smb_ReleaseFID(fidp); - cm_ReleaseUser(userp); + cm_ReleaseUser(userp); - /* free(realPathp); Can't free realPathp here because fidp->NTopen_wholepathp points there */ - /* leave scp held since we put it in fidp->scp */ - return 0; + /* free(realPathp); Can't free realPathp here because fidp->NTopen_wholepathp points there */ + /* leave scp held since we put it in fidp->scp */ + return 0; } long smb_ReceiveNTTranNotifyChange(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - smb_packet_t *savedPacketp; - ULONG filter; USHORT fid, watchtree; - smb_fid_t *fidp; - cm_scache_t *scp; + smb_packet_t *savedPacketp; + ULONG filter; USHORT fid, watchtree; + smb_fid_t *fidp; + cm_scache_t *scp; - filter = smb_GetSMBParm(inp, 19) - | (smb_GetSMBParm(inp, 20) << 16); - fid = smb_GetSMBParm(inp, 21); - watchtree = smb_GetSMBParm(inp, 22) && 0xffff; /* TODO: should this be 0xff ? */ + filter = smb_GetSMBParm(inp, 19) | + (smb_GetSMBParm(inp, 20) << 16); + fid = smb_GetSMBParm(inp, 21); + watchtree = smb_GetSMBParm(inp, 22) && 0xffff; /* TODO: should this be 0xff ? */ fidp = smb_FindFID(vcp, fid, 0); if (!fidp) { @@ -5719,13 +5939,13 @@ long smb_ReceiveNTTranNotifyChange(smb_vc_t *vcp, smb_packet_t *inp, return CM_ERROR_BADFD; } - savedPacketp = smb_CopyPacket(inp); + savedPacketp = smb_CopyPacket(inp); smb_HoldVC(vcp); - savedPacketp->vcp = vcp; - lock_ObtainMutex(&smb_Dir_Watch_Lock); - savedPacketp->nextp = smb_Directory_Watches; - smb_Directory_Watches = savedPacketp; - lock_ReleaseMutex(&smb_Dir_Watch_Lock); + savedPacketp->vcp = vcp; + lock_ObtainMutex(&smb_Dir_Watch_Lock); + savedPacketp->nextp = smb_Directory_Watches; + smb_Directory_Watches = savedPacketp; + lock_ReleaseMutex(&smb_Dir_Watch_Lock); osi_Log4(smb_logp, "Request for NotifyChange filter 0x%x fid %d wtree %d file %s", filter, fid, watchtree, osi_LogSaveString(smb_logp, fidp->NTopen_wholepathp)); @@ -5739,115 +5959,115 @@ long smb_ReceiveNTTranNotifyChange(smb_vc_t *vcp, smb_packet_t *inp, lock_ReleaseMutex(&scp->mx); smb_ReleaseFID(fidp); - outp->flags |= SMB_PACKETFLAG_NOSEND; - return 0; + outp->flags |= SMB_PACKETFLAG_NOSEND; + return 0; } unsigned char nullSecurityDesc[36] = { - 0x01, /* security descriptor revision */ - 0x00, /* reserved, should be zero */ - 0x00, 0x80, /* security descriptor control; - * 0x8000 : self-relative format */ - 0x14, 0x00, 0x00, 0x00, /* offset of owner SID */ - 0x1c, 0x00, 0x00, 0x00, /* offset of group SID */ - 0x00, 0x00, 0x00, 0x00, /* offset of DACL would go here */ - 0x00, 0x00, 0x00, 0x00, /* offset of SACL would go here */ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* "null SID" owner SID */ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - /* "null SID" group SID */ -}; + 0x01, /* security descriptor revision */ + 0x00, /* reserved, should be zero */ + 0x00, 0x80, /* security descriptor control; + * 0x8000 : self-relative format */ + 0x14, 0x00, 0x00, 0x00, /* offset of owner SID */ + 0x1c, 0x00, 0x00, 0x00, /* offset of group SID */ + 0x00, 0x00, 0x00, 0x00, /* offset of DACL would go here */ + 0x00, 0x00, 0x00, 0x00, /* offset of SACL would go here */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* "null SID" owner SID */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + /* "null SID" group SID */ +}; long smb_ReceiveNTTranQuerySecurityDesc(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - int parmOffset, parmCount, dataOffset, dataCount; - int parmSlot; - int maxData; - char *outData; - char *parmp; - USHORT *sparmp; - ULONG *lparmp; - USHORT fid; - ULONG securityInformation; - - parmOffset = smb_GetSMBOffsetParm(inp, 11, 1) - | (smb_GetSMBOffsetParm(inp, 12, 1) << 16); - parmp = inp->data + parmOffset; - sparmp = (USHORT *) parmp; - lparmp = (ULONG *) parmp; - - fid = sparmp[0]; - securityInformation = lparmp[1]; - - maxData = smb_GetSMBOffsetParm(inp, 7, 1) - | (smb_GetSMBOffsetParm(inp, 8, 1) << 16); - - if (maxData < 36) - dataCount = 0; - else - dataCount = 36; - - /* out parms */ - parmOffset = 8*4 + 39; - parmOffset += 1; /* pad to 4 */ - parmCount = 4; - dataOffset = parmOffset + parmCount; - - parmSlot = 1; - outp->oddByte = 1; - /* Total Parameter Count */ - smb_SetSMBParmLong(outp, parmSlot, parmCount); parmSlot += 2; - /* Total Data Count */ - smb_SetSMBParmLong(outp, parmSlot, dataCount); parmSlot += 2; - /* Parameter Count */ - smb_SetSMBParmLong(outp, parmSlot, parmCount); parmSlot += 2; - /* Parameter Offset */ - smb_SetSMBParmLong(outp, parmSlot, parmOffset); parmSlot += 2; - /* Parameter Displacement */ - smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2; - /* Data Count */ - smb_SetSMBParmLong(outp, parmSlot, dataCount); parmSlot += 2; - /* Data Offset */ - smb_SetSMBParmLong(outp, parmSlot, dataOffset); parmSlot += 2; - /* Data Displacement */ - smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2; - smb_SetSMBParmByte(outp, parmSlot, 0); /* Setup Count */ - smb_SetSMBDataLength(outp, 1 + parmCount + dataCount); - - outData = smb_GetSMBData(outp, NULL); - outData++; /* round to get to parmOffset */ - *((ULONG *)outData) = 36; outData += 4; /* length */ - - if (maxData >= 36) { - memcpy(outData, nullSecurityDesc, 36); - outData += 36; - return 0; - } else - return CM_ERROR_BUFFERTOOSMALL; + int parmOffset, parmCount, dataOffset, dataCount; + int parmSlot; + int maxData; + char *outData; + char *parmp; + USHORT *sparmp; + ULONG *lparmp; + USHORT fid; + ULONG securityInformation; + + parmOffset = smb_GetSMBOffsetParm(inp, 11, 1) + | (smb_GetSMBOffsetParm(inp, 12, 1) << 16); + parmp = inp->data + parmOffset; + sparmp = (USHORT *) parmp; + lparmp = (ULONG *) parmp; + + fid = sparmp[0]; + securityInformation = lparmp[1]; + + maxData = smb_GetSMBOffsetParm(inp, 7, 1) + | (smb_GetSMBOffsetParm(inp, 8, 1) << 16); + + if (maxData < 36) + dataCount = 0; + else + dataCount = 36; + + /* out parms */ + parmOffset = 8*4 + 39; + parmOffset += 1; /* pad to 4 */ + parmCount = 4; + dataOffset = parmOffset + parmCount; + + parmSlot = 1; + outp->oddByte = 1; + /* Total Parameter Count */ + smb_SetSMBParmLong(outp, parmSlot, parmCount); parmSlot += 2; + /* Total Data Count */ + smb_SetSMBParmLong(outp, parmSlot, dataCount); parmSlot += 2; + /* Parameter Count */ + smb_SetSMBParmLong(outp, parmSlot, parmCount); parmSlot += 2; + /* Parameter Offset */ + smb_SetSMBParmLong(outp, parmSlot, parmOffset); parmSlot += 2; + /* Parameter Displacement */ + smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2; + /* Data Count */ + smb_SetSMBParmLong(outp, parmSlot, dataCount); parmSlot += 2; + /* Data Offset */ + smb_SetSMBParmLong(outp, parmSlot, dataOffset); parmSlot += 2; + /* Data Displacement */ + smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2; + smb_SetSMBParmByte(outp, parmSlot, 0); /* Setup Count */ + smb_SetSMBDataLength(outp, 1 + parmCount + dataCount); + + outData = smb_GetSMBData(outp, NULL); + outData++; /* round to get to parmOffset */ + *((ULONG *)outData) = 36; outData += 4; /* length */ + + if (maxData >= 36) { + memcpy(outData, nullSecurityDesc, 36); + outData += 36; + return 0; + } else + return CM_ERROR_BUFFERTOOSMALL; } long smb_ReceiveNTTransact(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - unsigned short function; + unsigned short function; - function = smb_GetSMBParm(inp, 18); + function = smb_GetSMBParm(inp, 18); - osi_Log1(smb_logp, "SMB NT Transact function %d", function); + osi_Log1(smb_logp, "SMB NT Transact function %d", function); - /* We can handle long names */ - if (vcp->flags & SMB_VCFLAG_USENT) - ((smb_t *)outp)->flg2 |= 0x40; /* IS_LONG_NAME */ + /* We can handle long names */ + if (vcp->flags & SMB_VCFLAG_USENT) + ((smb_t *)outp)->flg2 |= 0x40; /* IS_LONG_NAME */ - switch (function) { - - case 6: return smb_ReceiveNTTranQuerySecurityDesc(vcp, inp, outp); - - case 4: return smb_ReceiveNTTranNotifyChange(vcp, inp, outp); - - case 1: return smb_ReceiveNTTranCreate(vcp, inp, outp); - - default: return CM_ERROR_INVAL; - } + switch (function) { + case 6: + return smb_ReceiveNTTranQuerySecurityDesc(vcp, inp, outp); + case 4: + return smb_ReceiveNTTranNotifyChange(vcp, inp, outp); + case 1: + return smb_ReceiveNTTranCreate(vcp, inp, outp); + default: + return CM_ERROR_INVAL; + } } /* @@ -6103,9 +6323,52 @@ long smb_ReceiveNTCancel(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) return 0; } +/* + * NT rename also does hard links. + */ + +#define RENAME_FLAG_MOVE_CLUSTER_INFORMATION 0x102 +#define RENAME_FLAG_HARD_LINK 0x103 +#define RENAME_FLAG_RENAME 0x104 +#define RENAME_FLAG_COPY 0x105 + +long smb_ReceiveNTRename(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) +{ + char *oldname, *newname; + long code = 0; + cm_user_t *userp; + char * tp; + int attrs; + int rename_type; + + attrs = smb_GetSMBParm(inp, 0); + rename_type = smb_GetSMBParm(inp, 1); + + if (rename_type != RENAME_FLAG_RENAME && rename_type != RENAME_FLAG_HARD_LINK) { + osi_Log1(smb_logp, "NTRename invalid infolevel [%x]", rename_type); + return CM_ERROR_NOACCESS; + } + + tp = smb_GetSMBData(inp, NULL); + oldname = smb_ParseASCIIBlock(tp, &tp); + newname = smb_ParseASCIIBlock(tp, &tp); + + osi_Log3(smb_logp, "NTRename for [%s]->[%s] type [%s]", + osi_LogSaveString(smb_logp, oldname), + osi_LogSaveString(smb_logp, newname), + ((rename_type==RENAME_FLAG_RENAME)?"rename":"hardlink")); + + if (rename_type == RENAME_FLAG_RENAME) { + code = smb_Rename(vcp,inp,oldname,newname,attrs); + } else { /* RENAME_FLAG_HARD_LINK */ + code = smb_Link(vcp,inp,oldname,newname); + } + return code; +} + void smb3_Init() { - lock_InitializeMutex(&smb_Dir_Watch_Lock, "Directory Watch List Lock"); + lock_InitializeMutex(&smb_Dir_Watch_Lock, "Directory Watch List Lock"); } cm_user_t *smb_FindCMUserByName(/*smb_vc_t *vcp,*/ char *usern, char *machine) diff --git a/src/WINNT/afsd/smb3.h b/src/WINNT/afsd/smb3.h index 03f3a5aa9..99f5ca580 100644 --- a/src/WINNT/afsd/smb3.h +++ b/src/WINNT/afsd/smb3.h @@ -149,7 +149,16 @@ extern long smb_ReceiveTran2FindNotifyFirst(smb_vc_t *vcp, smb_tran2Packet_t *p, extern long smb_ReceiveTran2FindNotifyNext(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp); -extern long smb_ReceiveTran2MKDir(smb_vc_t *vcp, smb_tran2Packet_t *p, +extern long smb_ReceiveTran2CreateDirectory(smb_vc_t *vcp, smb_tran2Packet_t *p, + smb_packet_t *outp); + +extern long smb_ReceiveTran2SessionSetup(smb_vc_t *vcp, smb_tran2Packet_t *p, + smb_packet_t *outp); + +extern long smb_ReceiveTran2GetDFSReferral(smb_vc_t *vcp, smb_tran2Packet_t *p, + smb_packet_t *outp); + +extern long smb_ReceiveTran2ReportDFSInconsistency(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp); extern long smb_ReceiveV3FindClose(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp); @@ -178,6 +187,8 @@ extern void smb_NotifyChange(DWORD action, DWORD notifyFilter, extern long smb_ReceiveNTCancel(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp); +extern long smb_ReceiveNTRename(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp); + extern int smb_V3MatchMask(char *namep, char *maskp, int flags); extern void smb3_Init(); diff --git a/src/WINNT/aklog/aklog.c b/src/WINNT/aklog/aklog.c index e9e1dc14a..a226d3a15 100644 --- a/src/WINNT/aklog/aklog.c +++ b/src/WINNT/aklog/aklog.c @@ -134,8 +134,8 @@ get_cellconfig_callback(void *cellconfig, struct sockaddr_in *addrp, char *namep #define VOLMARKERSTRING ":" /* String form of above */ typedef struct { - char cell[BUFSIZ]; - char realm[REALM_SZ]; + char cell[BUFSIZ]; + char realm[REALM_SZ]; } cellinfo_t; @@ -148,29 +148,30 @@ static int force = FALSE; /* Bash identical tokens? */ static linked_list authedcells; /* List of cells already logged to */ static int usev5 = TRUE; /* use kerberos 5? */ +static int use524 = FALSE; /* use krb524? */ static krb5_ccache _krb425_ccache; long GetLocalCell(struct afsconf_dir **pconfigdir, char *local_cell) { - if (!(*pconfigdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH))) - { - fprintf(stderr, "%s: can't get afs configuration (afsconf_Open(%s))\n", - progname, AFSDIR_CLIENT_ETC_DIRPATH); - exit(AKLOG_AFS); - } + if (!(*pconfigdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH))) + { + fprintf(stderr, "%s: can't get afs configuration (afsconf_Open(%s))\n", + progname, AFSDIR_CLIENT_ETC_DIRPATH); + exit(AKLOG_AFS); + } - return afsconf_GetLocalCell(*pconfigdir, local_cell, MAXCELLCHARS); + return afsconf_GetLocalCell(*pconfigdir, local_cell, MAXCELLCHARS); } long GetCellInfo(struct afsconf_dir **pconfigdir, char* cell, struct afsconf_cell **pcellconfig) { - return afsconf_GetCellInfo(*pconfigdir, cell, NULL, *pcellconfig); + return afsconf_GetCellInfo(*pconfigdir, cell, NULL, *pcellconfig); } void CloseConf(struct afsconf_dir **pconfigdir) -{ - (void) afsconf_Close(*pconfigdir); +{ + (void) afsconf_Close(*pconfigdir); } #define ALLOW_REGISTER 1 @@ -182,7 +183,7 @@ void ViceIDToUsername(char *username, char *realm_of_user, char *realm_of_cell, static char lastcell[MAXCELLCHARS+1] = { 0 }; static char confname[512] = { 0 }; char username_copy[BUFSIZ]; - long viceId; /* AFS uid of user */ + long viceId; /* AFS uid of user */ #ifdef ALLOW_REGISTER afs_int32 id; #endif /* ALLOW_REGISTER */ @@ -192,8 +193,8 @@ void ViceIDToUsername(char *username, char *realm_of_user, char *realm_of_cell, confname[sizeof(confname) - 2] = '\0'; } - if (dflag) - printf("About to resolve name %s to id\n", username); + if (dflag) + printf("About to resolve name %s to id\n", username); /* * Talk about DUMB! It turns out that there is a bug in @@ -217,31 +218,31 @@ void ViceIDToUsername(char *username, char *realm_of_user, char *realm_of_cell, strcpy(lastcell, aserver->cell); - if (!pr_Initialize (0, confname, aserver->cell)) - *status = pr_SNameToId (username, &viceId); + if (!pr_Initialize (0, confname, aserver->cell)) + *status = pr_SNameToId (username, &viceId); - if (dflag) - { - if (*status) - printf("Error %d\n", *status); - else - printf("Id %d\n", viceId); - } + if (dflag) + { + if (*status) + printf("Error %d\n", *status); + else + printf("Id %d\n", viceId); + } - /* - * This is a crock, but it is Transarc's crock, so - * we have to play along in order to get the - * functionality. The way the afs id is stored is - * as a string in the username field of the token. - * Contrary to what you may think by looking at - * the code for tokens, this hack (AFS ID %d) will - * not work if you change %d to something else. - */ + /* + * This is a crock, but it is Transarc's crock, so + * we have to play along in order to get the + * functionality. The way the afs id is stored is + * as a string in the username field of the token. + * Contrary to what you may think by looking at + * the code for tokens, this hack (AFS ID %d) will + * not work if you change %d to something else. + */ /* - * This code is taken from cklog -- it lets people - * automatically register with the ptserver in foreign cells - */ + * This code is taken from cklog -- it lets people + * automatically register with the ptserver in foreign cells + */ #ifdef ALLOW_REGISTER if (*status == 0) { @@ -256,91 +257,91 @@ void ViceIDToUsername(char *username, char *realm_of_user, char *realm_of_cell, #endif /* AFS_ID_TO_NAME */ } #ifdef ALLOW_REGISTER - } else if (strcmp(realm_of_user, realm_of_cell) != 0) { - if (dflag) { - printf("doing first-time registration of %s " - "at %s\n", username, cell_to_use); - } - id = 0; - strncpy(aclient->name, username, MAXKTCNAMELEN - 1); - strcpy(aclient->instance, ""); - strncpy(aclient->cell, c->realm, MAXKTCREALMLEN - 1); - if ((*status = ktc_SetToken(aserver, atoken, aclient, 0))) { - printf("%s: unable to obtain tokens for cell %s " - "(status: %d).\n", progname, cell_to_use, status); - *status = AKLOG_TOKEN; + } else if (strcmp(realm_of_user, realm_of_cell) != 0) { + if (dflag) { + printf("doing first-time registration of %s " + "at %s\n", username, cell_to_use); + } + id = 0; + strncpy(aclient->name, username, MAXKTCNAMELEN - 1); + strcpy(aclient->instance, ""); + strncpy(aclient->cell, c->realm, MAXKTCREALMLEN - 1); + if ((*status = ktc_SetToken(aserver, atoken, aclient, 0))) { + printf("%s: unable to obtain tokens for cell %s " + "(status: %d).\n", progname, cell_to_use, status); + *status = AKLOG_TOKEN; return ; - } + } - /* - * In case you're wondering, we don't need to change the - * filename here because we're still connecting to the - * same cell -- we're just using a different authentication - * level - */ - - if ((*status = pr_Initialize(1L, confname, aserver->cell, 0))) { - printf("Error %d\n", status); + /* + * In case you're wondering, we don't need to change the + * filename here because we're still connecting to the + * same cell -- we're just using a different authentication + * level + */ + + if ((*status = pr_Initialize(1L, confname, aserver->cell, 0))) { + printf("Error %d\n", status); return; - } + } - if ((*status = pr_CreateUser(username, &id))) { - printf("%s: unable to create remote PTS " - "user %s in cell %s (status: %d).\n", progname, - username, cell_to_use, *status); - } else { - printf("created cross-cell entry for %s at %s\n", - username, cell_to_use); + if ((*status = pr_CreateUser(username, &id))) { + printf("%s: unable to create remote PTS " + "user %s in cell %s (status: %d).\n", progname, + username, cell_to_use, *status); + } else { + printf("created cross-cell entry for %s at %s\n", + username, cell_to_use); #ifdef AFS_ID_TO_NAME strncpy(username_copy, username, BUFSIZ); snprintf (username, BUFSIZ, "%s (AFS ID %d)", username_copy, (int) viceId); #endif /* AFS_ID_TO_NAME */ - } } } + } #endif /* ALLOW_REGISTER */ } char *LastComponent(char *str) { - char *ret = strrchr(str, DIR); + char *ret = strrchr(str, DIR); #ifdef WIN32 - if (!ret) - ret = strrchr(str, BDIR); + if (!ret) + ret = strrchr(str, BDIR); #endif - return ret; + return ret; } int FirstComponent(char *str) { - return (int)( + return (int)( #ifdef WIN32 - strchr(str, BDIR) || + strchr(str, BDIR) || #endif - strchr(str, DIR)); + strchr(str, DIR)); } void CopyPathColon(char *origpath, char *path, char *pathtocheck) { #ifdef WIN32 - if (origpath[1] == DRIVECOLON) - { - strncpy(pathtocheck, origpath, 2); - strcpy(path, origpath+2); - } - else + if (origpath[1] == DRIVECOLON) + { + strncpy(pathtocheck, origpath, 2); + strcpy(path, origpath+2); + } + else #endif - strcpy(path, origpath); + strcpy(path, origpath); } int BeginsWithDir(char *str, int colon) { - return (str[0] == DIR) || + return (str[0] == DIR) || #ifdef WIN32 - ((str[0] == BDIR) || (colon && str[1] == DRIVECOLON)); + ((str[0] == BDIR) || (colon && str[1] == DRIVECOLON)); #else - FALSE; + FALSE; #endif } @@ -356,32 +357,32 @@ int BeginsWithDir(char *str, int colon) */ int des_pcbc_init() { - abort(); + abort(); } static int get_cred(char *name, char *inst, char *realm, CREDENTIALS *c) { - int status; + int status; - status = krb_get_cred(name, inst, realm, c); - if (status != KSUCCESS) - { + status = krb_get_cred(name, inst, realm, c); + if (status != KSUCCESS) + { #ifdef DONT_HAVE_GET_AD_TKT - KTEXT_ST ticket; - status = krb_mk_req(&ticket, name, inst, realm, 0); + KTEXT_ST ticket; + status = krb_mk_req(&ticket, name, inst, realm, 0); #else - status = get_ad_tkt(name, inst, realm, 255); + status = get_ad_tkt(name, inst, realm, 255); #endif - if (status == KSUCCESS) - status = krb_get_cred(name, inst, realm, c); - } + if (status == KSUCCESS) + status = krb_get_cred(name, inst, realm, c); + } - return (status); + return (status); } static int get_v5cred(krb5_context context, - char *name, char *inst, char *realm, CREDENTIALS *c, - krb5_creds **creds) + char *name, char *inst, char *realm, CREDENTIALS *c, + krb5_creds **creds) { krb5_creds increds; krb5_error_code r; @@ -389,11 +390,11 @@ static int get_v5cred(krb5_context context, memset((char *)&increds, 0, sizeof(increds)); - if ((r = krb5_build_principal(context, &increds.server, - strlen(realm), realm, - name, - (inst && strlen(inst)) ? inst : 0, - 0))) { + if ((r = krb5_build_principal(context, &increds.server, + strlen(realm), realm, + name, + (inst && strlen(inst)) ? inst : 0, + 0))) { return((int)r); } @@ -547,137 +548,145 @@ static int get_v5_user_realm(krb5_context context,char *realm) * to. */ static int auth_to_cell(krb5_context context, char *cell, char *realm) { - int status = AKLOG_SUCCESS; - char username[BUFSIZ]; /* To hold client username structure */ + int status = AKLOG_SUCCESS; + char username[BUFSIZ]; /* To hold client username structure */ + + char name[ANAME_SZ]; /* Name of afs key */ + char instance[INST_SZ]; /* Instance of afs key */ + char realm_of_user[REALM_SZ]; /* Kerberos realm of user */ + char realm_of_cell[REALM_SZ]; /* Kerberos realm of cell */ + char local_cell[MAXCELLCHARS+1]; + char cell_to_use[MAXCELLCHARS+1]; /* Cell to authenticate to */ + + krb5_creds *v5cred = NULL; + CREDENTIALS c; + struct ktc_principal aserver; + struct ktc_principal aclient; + struct ktc_token atoken, btoken; + + + /* try to avoid an expensive call to get_cellconfig */ + if (cell && ll_string_check(&authedcells, cell)) + { + if (dflag) + printf("Already authenticated to %s (or tried to)\n", cell); + return(AKLOG_SUCCESS); + } - char name[ANAME_SZ]; /* Name of afs key */ - char instance[INST_SZ]; /* Instance of afs key */ - char realm_of_user[REALM_SZ]; /* Kerberos realm of user */ - char realm_of_cell[REALM_SZ]; /* Kerberos realm of cell */ - char local_cell[MAXCELLCHARS+1]; - char cell_to_use[MAXCELLCHARS+1]; /* Cell to authenticate to */ + memset(name, 0, sizeof(name)); + memset(instance, 0, sizeof(instance)); + memset(realm_of_user, 0, sizeof(realm_of_user)); + memset(realm_of_cell, 0, sizeof(realm_of_cell)); - krb5_creds *v5cred = NULL; - CREDENTIALS c; - struct ktc_principal aserver; - struct ktc_principal aclient; - struct ktc_token atoken, btoken; + /* NULL or empty cell returns information on local cell */ + if (status = get_cellconfig(cell, &ak_cellconfig, local_cell)) + return(status); + strncpy(cell_to_use, ak_cellconfig.name, MAXCELLCHARS); + cell_to_use[MAXCELLCHARS] = 0; - /* try to avoid an expensive call to get_cellconfig */ - if (cell && ll_string_check(&authedcells, cell)) - { - if (dflag) - printf("Already authenticated to %s (or tried to)\n", cell); - return(AKLOG_SUCCESS); - } - - memset(name, 0, sizeof(name)); - memset(instance, 0, sizeof(instance)); - memset(realm_of_user, 0, sizeof(realm_of_user)); - memset(realm_of_cell, 0, sizeof(realm_of_cell)); - - /* NULL or empty cell returns information on local cell */ - if (status = get_cellconfig(cell, &ak_cellconfig, local_cell)) - return(status); + if (ll_string_check(&authedcells, cell_to_use)) + { + if (dflag) + printf("Already authenticated to %s (or tried to)\n", cell_to_use); + return(AKLOG_SUCCESS); + } - strncpy(cell_to_use, ak_cellconfig.name, MAXCELLCHARS); - cell_to_use[MAXCELLCHARS] = 0; + /* + * Record that we have attempted to log to this cell. We do this + * before we try rather than after so that we will not try + * and fail repeatedly for one cell. + */ + (void)ll_add_string(&authedcells, cell_to_use); + + if (dflag) + printf("Authenticating to cell %s.\n", cell_to_use); + + if (realm && realm[0]) + strcpy(realm_of_cell, realm); + else + strcpy(realm_of_cell, + (usev5)? + afs_realm_of_cell5(context, &ak_cellconfig) : + afs_realm_of_cell(&ak_cellconfig)); + + /* We use the afs. convention here... */ + strcpy(name, AFSKEY); + strncpy(instance, cell_to_use, sizeof(instance)); + instance[sizeof(instance)-1] = '\0'; - if (ll_string_check(&authedcells, cell_to_use)) - { - if (dflag) - printf("Already authenticated to %s (or tried to)\n", cell_to_use); - return(AKLOG_SUCCESS); - } + /* + * Extract the session key from the ticket file and hand-frob an + * afs style authenticator. + */ - /* - * Record that we have attempted to log to this cell. We do this - * before we try rather than after so that we will not try - * and fail repeatedly for one cell. - */ - (void)ll_add_string(&authedcells, cell_to_use); - - if (dflag) - printf("Authenticating to cell %s.\n", cell_to_use); - - if (realm && realm[0]) - strcpy(realm_of_cell, realm); - else - strcpy(realm_of_cell, - (usev5)? - afs_realm_of_cell5(context, &ak_cellconfig) : - afs_realm_of_cell(&ak_cellconfig)); - - /* We use the afs. convention here... */ - strcpy(name, AFSKEY); - strncpy(instance, cell_to_use, sizeof(instance)); - instance[sizeof(instance)-1] = '\0'; - - /* - * Extract the session key from the ticket file and hand-frob an - * afs style authenticator. - */ - - if (usev5) - { /* using krb5 */ + if (usev5) + { /* using krb5 */ int retry = 1; + if ( strchr(name,'.') != NULL ) { + fprintf(stderr, "%s: Can't support principal names including a dot.\n", + progname); + return(AKLOG_MISC); + } + try_v5: - if (dflag) - printf("Getting v5 tickets: %s/%s@%s\n", name, instance, realm_of_cell); - status = get_v5cred(context, name, instance, realm_of_cell, NULL, &v5cred); - if (status == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN) { - if (dflag) - printf("Getting v5 tickets: %s@%s\n", name, realm_of_cell); - status = get_v5cred(context, name, "", realm_of_cell, NULL, &v5cred); - } + if (dflag) + printf("Getting v5 tickets: %s/%s@%s\n", name, instance, realm_of_cell); + status = get_v5cred(context, name, instance, realm_of_cell, + use524 ? &c : NULL, &v5cred); + if (status == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN) { + if (dflag) + printf("Getting v5 tickets: %s@%s\n", name, realm_of_cell); + status = get_v5cred(context, name, "", realm_of_cell, + use524 ? &c : NULL, &v5cred); + } if ( status == KRB5KRB_AP_ERR_MSG_TYPE && retry ) { retry = 0; goto try_v5; + } + } + else + { + /* + * Try to obtain AFS tickets. Because there are two valid service + * names, we will try both, but trying the more specific first. + * + * afs.@ + * afs@ + */ + if (dflag) + printf("Getting tickets: %s.%s@%s\n", name, instance, realm_of_cell); + status = get_cred(name, instance, realm_of_cell, &c); + if (status == KDC_PR_UNKNOWN) + { + if (dflag) + printf("Getting tickets: %s@%s\n", name, realm_of_cell); + status = get_cred(name, "", realm_of_cell, &c); } - } - else - { - /* - * Try to obtain AFS tickets. Because there are two valid service - * names, we will try both, but trying the more specific first. - * - * afs.@ - * afs@ - */ - if (dflag) - printf("Getting tickets: %s.%s@%s\n", name, instance, realm_of_cell); - status = get_cred(name, instance, realm_of_cell, &c); - if (status == KDC_PR_UNKNOWN) - { - if (dflag) - printf("Getting tickets: %s@%s\n", name, realm_of_cell); - status = get_cred(name, "", realm_of_cell, &c); - } - } - - /* TODO: get k5 error text */ - if (status != KSUCCESS) - { - if (dflag) - printf("Kerberos error code returned by get_cred: %d\n", status); - fprintf(stderr, "%s: Couldn't get %s AFS tickets: %s\n", - progname, cell_to_use, - (usev5)?"": - krb_err_text(status)); - return(AKLOG_KERBEROS); - } + } + + /* TODO: get k5 error text */ + if (status != KSUCCESS) + { + if (dflag) + printf("Kerberos error code returned by get_cred: %d\n", status); + fprintf(stderr, "%s: Couldn't get %s AFS tickets: %s\n", + progname, cell_to_use, + (usev5)?"": + krb_err_text(status)); + return(AKLOG_KERBEROS); + } - strncpy(aserver.name, AFSKEY, MAXKTCNAMELEN - 1); - strncpy(aserver.instance, AFSINST, MAXKTCNAMELEN - 1); - strncpy(aserver.cell, cell_to_use, MAXKTCREALMLEN - 1); + strncpy(aserver.name, AFSKEY, MAXKTCNAMELEN - 1); + strncpy(aserver.instance, AFSINST, MAXKTCNAMELEN - 1); + strncpy(aserver.cell, cell_to_use, MAXKTCREALMLEN - 1); - if (usev5) { + if (usev5 && !use524) { /* This code inserts the entire K5 ticket into the token - * No need to perform a krb524 translation which is - * commented out in the code below - */ + * No need to perform a krb524 translation which is + * commented out in the code below + */ char * p; int len; @@ -718,131 +727,131 @@ static int auth_to_cell(krb5_context context, char *cell, char *realm) memcpy(atoken.ticket, c.ticket_st.dat, atoken.ticketLen); } - if (!force && - !ktc_GetToken(&aserver, &btoken, sizeof(btoken), &aclient) && - atoken.kvno == btoken.kvno && - atoken.ticketLen == btoken.ticketLen && - !memcmp(&atoken.sessionKey, &btoken.sessionKey, sizeof(atoken.sessionKey)) && - !memcmp(atoken.ticket, btoken.ticket, atoken.ticketLen)) - { - if (dflag) - printf("Identical tokens already exist; skipping.\n"); - return 0; - } + if (!force && + !ktc_GetToken(&aserver, &btoken, sizeof(btoken), &aclient) && + atoken.kvno == btoken.kvno && + atoken.ticketLen == btoken.ticketLen && + !memcmp(&atoken.sessionKey, &btoken.sessionKey, sizeof(atoken.sessionKey)) && + !memcmp(atoken.ticket, btoken.ticket, atoken.ticketLen)) + { + if (dflag) + printf("Identical tokens already exist; skipping.\n"); + return 0; + } - if (noprdb) - { - if (dflag) - printf("Not resolving name %s to id (-noprdb set)\n", username); - } - else - { - if(usev5) { - if((status = get_v5_user_realm(context, realm_of_user)) != KSUCCESS) { - fprintf(stderr, "%s: Couldn't determine realm of user: %d\n", - progname, status); - return(AKLOG_KERBEROS); - } + if (noprdb) + { + if (dflag) + printf("Not resolving name %s to id (-noprdb set)\n", username); + } + else + { + if (usev5) { + if((status = get_v5_user_realm(context, realm_of_user)) != KSUCCESS) { + fprintf(stderr, "%s: Couldn't determine realm of user: %d\n", + progname, status); + return(AKLOG_KERBEROS); + } } else { - if ((status = krb_get_tf_realm(TKT_FILE, realm_of_user)) != KSUCCESS) - { - fprintf(stderr, "%s: Couldn't determine realm of user: %s)", - progname, krb_err_text(status)); - return(AKLOG_KERBEROS); - } - } + if ((status = krb_get_tf_realm(TKT_FILE, realm_of_user)) != KSUCCESS) + { + fprintf(stderr, "%s: Couldn't determine realm of user: %s)", + progname, krb_err_text(status)); + return(AKLOG_KERBEROS); + } + } - if (strcmp(realm_of_user, realm_of_cell)) - { - strcat(username, "@"); - strcat(username, realm_of_user); - } + if (strcmp(realm_of_user, realm_of_cell)) + { + strcat(username, "@"); + strcat(username, realm_of_user); + } - ViceIDToUsername(username, realm_of_user, realm_of_cell, cell_to_use, &c, &status, &aclient, &aserver, &atoken); - } + ViceIDToUsername(username, realm_of_user, realm_of_cell, cell_to_use, &c, &status, &aclient, &aserver, &atoken); + } - if (dflag) - printf("Set username to %s\n", username); + if (dflag) + printf("Set username to %s\n", username); - /* Reset the "aclient" structure before we call ktc_SetToken. - * This structure was first set by the ktc_GetToken call when - * we were comparing whether identical tokens already existed. - */ - strncpy(aclient.name, username, MAXKTCNAMELEN - 1); - strcpy(aclient.instance, ""); + /* Reset the "aclient" structure before we call ktc_SetToken. + * This structure was first set by the ktc_GetToken call when + * we were comparing whether identical tokens already existed. + */ + strncpy(aclient.name, username, MAXKTCNAMELEN - 1); + strcpy(aclient.instance, ""); - if (usev5) { + if (usev5 && !use524) { int len = min(v5cred->client->realm.length,MAXKTCNAMELEN - 1); strncpy(aclient.cell, v5cred->client->realm.data, len); aclient.cell[len] = '\0'; } else strncpy(aclient.cell, c.realm, MAXKTCREALMLEN - 1); - if (dflag) - printf("Getting tokens.\n"); - if (status = ktc_SetToken(&aserver, &atoken, &aclient, 0)) - { - fprintf(stderr, - "%s: unable to obtain tokens for cell %s (status: %d).\n", - progname, cell_to_use, status); - status = AKLOG_TOKEN; - } + if (dflag) + printf("Getting tokens.\n"); + if (status = ktc_SetToken(&aserver, &atoken, &aclient, 0)) + { + fprintf(stderr, + "%s: unable to obtain tokens for cell %s (status: %d).\n", + progname, cell_to_use, status); + status = AKLOG_TOKEN; + } - return(status); + return(status); } static int get_afs_mountpoint(char *file, char *mountpoint, int size) { - char our_file[MAXPATHLEN + 1]; - char *parent_dir; - char *last_component; - struct ViceIoctl vio; - char cellname[BUFSIZ]; - - memset(our_file, 0, sizeof(our_file)); - strcpy(our_file, file); + char our_file[MAXPATHLEN + 1]; + char *parent_dir; + char *last_component; + struct ViceIoctl vio; + char cellname[BUFSIZ]; + + memset(our_file, 0, sizeof(our_file)); + strcpy(our_file, file); + + if (last_component = LastComponent(our_file)) + { + *last_component++ = 0; + parent_dir = our_file; + } + else + { + last_component = our_file; + parent_dir = "."; + } - if (last_component = LastComponent(our_file)) - { - *last_component++ = 0; - parent_dir = our_file; - } - else - { - last_component = our_file; - parent_dir = "."; - } + memset(cellname, 0, sizeof(cellname)); - memset(cellname, 0, sizeof(cellname)); + vio.in = last_component; + vio.in_size = strlen(last_component)+1; + vio.out_size = size; + vio.out = mountpoint; - vio.in = last_component; - vio.in_size = strlen(last_component)+1; - vio.out_size = size; - vio.out = mountpoint; + if (!pioctl(parent_dir, VIOC_AFS_STAT_MT_PT, &vio, 0)) + { + if (strchr(mountpoint, VOLMARKER) == NULL) + { + vio.in = file; + vio.in_size = strlen(file) + 1; + vio.out_size = sizeof(cellname); + vio.out = cellname; - if (!pioctl(parent_dir, VIOC_AFS_STAT_MT_PT, &vio, 0)) - { - if (strchr(mountpoint, VOLMARKER) == NULL) - { - vio.in = file; - vio.in_size = strlen(file) + 1; - vio.out_size = sizeof(cellname); - vio.out = cellname; - - if (!pioctl(file, VIOC_FILE_CELL_NAME, &vio, 1)) - { - strcat(cellname, VOLMARKERSTRING); - strcat(cellname, mountpoint + 1); - memset(mountpoint + 1, 0, size - 1); - strcpy(mountpoint + 1, cellname); - } - } - return(TRUE); - } - else { - return(FALSE); - } -} + if (!pioctl(file, VIOC_FILE_CELL_NAME, &vio, 1)) + { + strcat(cellname, VOLMARKERSTRING); + strcat(cellname, mountpoint + 1); + memset(mountpoint + 1, 0, size - 1); + strcpy(mountpoint + 1, cellname); + } + } + return(TRUE); + } + else { + return(FALSE); + } +} /* * This routine each time it is called returns the next directory @@ -853,92 +862,92 @@ static int get_afs_mountpoint(char *file, char *mountpoint, int size) */ static char *next_path(char *origpath) { - static char path[MAXPATHLEN + 1]; - static char pathtocheck[MAXPATHLEN + 1]; - - int link = FALSE; /* Is this a symbolic link? */ - char linkbuf[MAXPATHLEN + 1]; - char tmpbuf[MAXPATHLEN + 1]; - - static char *last_comp; /* last component of directory name */ - static char *elast_comp; /* End of last component */ - char *t; - int len; - - static int symlinkcount = 0; /* We can't exceed MAXSYMLINKS */ - - /* If we are given something for origpath, we are initializing only. */ - if (origpath) - { - memset(path, 0, sizeof(path)); - memset(pathtocheck, 0, sizeof(pathtocheck)); - CopyPathColon(origpath, path, pathtocheck); - last_comp = path; - symlinkcount = 0; - return(NULL); - } - - /* We were not given origpath; find then next path to check */ - - /* If we've gotten all the way through already, return NULL */ - if (last_comp == NULL) - return(NULL); + static char path[MAXPATHLEN + 1]; + static char pathtocheck[MAXPATHLEN + 1]; + + int link = FALSE; /* Is this a symbolic link? */ + char linkbuf[MAXPATHLEN + 1]; + char tmpbuf[MAXPATHLEN + 1]; + + static char *last_comp; /* last component of directory name */ + static char *elast_comp; /* End of last component */ + char *t; + int len; + + static int symlinkcount = 0; /* We can't exceed MAXSYMLINKS */ + + /* If we are given something for origpath, we are initializing only. */ + if (origpath) + { + memset(path, 0, sizeof(path)); + memset(pathtocheck, 0, sizeof(pathtocheck)); + CopyPathColon(origpath, path, pathtocheck); + last_comp = path; + symlinkcount = 0; + return(NULL); + } - do - { - while (BeginsWithDir(last_comp, FALSE)) - strncat(pathtocheck, last_comp++, 1); - len = (elast_comp = LastComponent(last_comp)) - ? elast_comp - last_comp : strlen(last_comp); - strncat(pathtocheck, last_comp, len); - memset(linkbuf, 0, sizeof(linkbuf)); - if (link = (readlink(pathtocheck, linkbuf, sizeof(linkbuf)) > 0)) - { - if (++symlinkcount > MAXSYMLINKS) - { - fprintf(stderr, "%s: %s\n", progname, strerror(ELOOP)); - exit(AKLOG_BADPATH); - } - memset(tmpbuf, 0, sizeof(tmpbuf)); - if (elast_comp) - strcpy(tmpbuf, elast_comp); - if (BeginsWithDir(linkbuf, FALSE)) - { - /* - * If this is a symbolic link to an absolute path, - * replace what we have by the absolute path. - */ - memset(path, 0, strlen(path)); - memcpy(path, linkbuf, sizeof(linkbuf)); - strcat(path, tmpbuf); - last_comp = path; - elast_comp = NULL; - memset(pathtocheck, 0, sizeof(pathtocheck)); - } - else - { - /* - * If this is a symbolic link to a relative path, - * replace only the last component with the link name. - */ - strncpy(last_comp, linkbuf, strlen(linkbuf) + 1); - strcat(path, tmpbuf); - elast_comp = NULL; - if (t = LastComponent(pathtocheck)) - { - t++; - memset(t, 0, strlen(t)); - } - else - memset(pathtocheck, 0, sizeof(pathtocheck)); - } - } - else - last_comp = elast_comp; - } - while(link); + /* We were not given origpath; find then next path to check */ + + /* If we've gotten all the way through already, return NULL */ + if (last_comp == NULL) + return(NULL); + + do + { + while (BeginsWithDir(last_comp, FALSE)) + strncat(pathtocheck, last_comp++, 1); + len = (elast_comp = LastComponent(last_comp)) + ? elast_comp - last_comp : strlen(last_comp); + strncat(pathtocheck, last_comp, len); + memset(linkbuf, 0, sizeof(linkbuf)); + if (link = (readlink(pathtocheck, linkbuf, sizeof(linkbuf)) > 0)) + { + if (++symlinkcount > MAXSYMLINKS) + { + fprintf(stderr, "%s: %s\n", progname, strerror(ELOOP)); + exit(AKLOG_BADPATH); + } + memset(tmpbuf, 0, sizeof(tmpbuf)); + if (elast_comp) + strcpy(tmpbuf, elast_comp); + if (BeginsWithDir(linkbuf, FALSE)) + { + /* + * If this is a symbolic link to an absolute path, + * replace what we have by the absolute path. + */ + memset(path, 0, strlen(path)); + memcpy(path, linkbuf, sizeof(linkbuf)); + strcat(path, tmpbuf); + last_comp = path; + elast_comp = NULL; + memset(pathtocheck, 0, sizeof(pathtocheck)); + } + else + { + /* + * If this is a symbolic link to a relative path, + * replace only the last component with the link name. + */ + strncpy(last_comp, linkbuf, strlen(linkbuf) + 1); + strcat(path, tmpbuf); + elast_comp = NULL; + if (t = LastComponent(pathtocheck)) + { + t++; + memset(t, 0, strlen(t)); + } + else + memset(pathtocheck, 0, sizeof(pathtocheck)); + } + } + else + last_comp = elast_comp; + } + while(link); - return(pathtocheck); + return(pathtocheck); } /* @@ -947,314 +956,317 @@ static char *next_path(char *origpath) */ static int auth_to_path(krb5_context context, char *path) { - int status = AKLOG_SUCCESS; - int auth_to_cell_status = AKLOG_SUCCESS; - - char *nextpath; - char pathtocheck[MAXPATHLEN + 1]; - char mountpoint[MAXPATHLEN + 1]; - - char *cell; - char *endofcell; - - /* Initialize */ - if (BeginsWithDir(path, TRUE)) - strcpy(pathtocheck, path); - else - { - if (getcwd(pathtocheck, sizeof(pathtocheck)) == NULL) - { - fprintf(stderr, "Unable to find current working directory:\n"); - fprintf(stderr, "%s\n", pathtocheck); - fprintf(stderr, "Try an absolute pathname.\n"); - exit(AKLOG_BADPATH); - } - else - { - /* in WIN32, if getcwd returns a root dir (eg: c:\), the returned string - * will already have a trailing slash ('\'). Otherwise, the string will - * end in the last directory name */ -#ifdef WIN32 - if(pathtocheck[strlen(pathtocheck) - 1] != BDIR) -#endif - strcat(pathtocheck, DIRSTRING); - strcat(pathtocheck, path); - } - } - next_path(pathtocheck); + int status = AKLOG_SUCCESS; + int auth_to_cell_status = AKLOG_SUCCESS; + + char *nextpath; + char pathtocheck[MAXPATHLEN + 1]; + char mountpoint[MAXPATHLEN + 1]; + + char *cell; + char *endofcell; + + /* Initialize */ + if (BeginsWithDir(path, TRUE)) + strcpy(pathtocheck, path); + else + { + if (getcwd(pathtocheck, sizeof(pathtocheck)) == NULL) + { + fprintf(stderr, "Unable to find current working directory:\n"); + fprintf(stderr, "%s\n", pathtocheck); + fprintf(stderr, "Try an absolute pathname.\n"); + exit(AKLOG_BADPATH); + } + else + { + /* in WIN32, if getcwd returns a root dir (eg: c:\), the returned string + * will already have a trailing slash ('\'). Otherwise, the string will + * end in the last directory name */ +#ifdef WIN32 + if(pathtocheck[strlen(pathtocheck) - 1] != BDIR) +#endif + strcat(pathtocheck, DIRSTRING); + strcat(pathtocheck, path); + } + } + next_path(pathtocheck); + + /* Go on to the next level down the path */ + while (nextpath = next_path(NULL)) + { + strcpy(pathtocheck, nextpath); + if (dflag) + printf("Checking directory [%s]\n", pathtocheck); + /* + * If this is an afs mountpoint, determine what cell from + * the mountpoint name which is of the form + * #cellname:volumename or %cellname:volumename. + */ + if (get_afs_mountpoint(pathtocheck, mountpoint, sizeof(mountpoint))) + { + if(dflag) + printf("Found mount point [%s]\n", mountpoint); + /* skip over the '#' or '%' */ + cell = mountpoint + 1; + if (endofcell = strchr(mountpoint, VOLMARKER)) + { + *endofcell = '\0'; + if (auth_to_cell_status = auth_to_cell(context, cell, NULL)) + { + if (status == AKLOG_SUCCESS) + status = auth_to_cell_status; + else if (status != auth_to_cell_status) + status = AKLOG_SOMETHINGSWRONG; + } + } + } + else + { + struct stat st; - /* Go on to the next level down the path */ - while (nextpath = next_path(NULL)) - { - strcpy(pathtocheck, nextpath); - if (dflag) - printf("Checking directory [%s]\n", pathtocheck); - /* - * If this is an afs mountpoint, determine what cell from - * the mountpoint name which is of the form - * #cellname:volumename or %cellname:volumename. - */ - if (get_afs_mountpoint(pathtocheck, mountpoint, sizeof(mountpoint))) - { - if(dflag) - printf("Found mount point [%s]\n", mountpoint); - /* skip over the '#' or '%' */ - cell = mountpoint + 1; - if (endofcell = strchr(mountpoint, VOLMARKER)) - { - *endofcell = '\0'; - if (auth_to_cell_status = auth_to_cell(context, cell, NULL)) - { - if (status == AKLOG_SUCCESS) - status = auth_to_cell_status; - else if (status != auth_to_cell_status) - status = AKLOG_SOMETHINGSWRONG; - } - } - } - else - { - struct stat st; - - if (lstat(pathtocheck, &st) < 0) - { - /* - * If we've logged and still can't stat, there's - * a problem... - */ - fprintf(stderr, "%s: stat(%s): %s\n", progname, - pathtocheck, strerror(errno)); - return(AKLOG_BADPATH); - } - else if (!S_ISDIR(st.st_mode)) - { - /* Allow only directories */ - fprintf(stderr, "%s: %s: %s\n", progname, pathtocheck, - strerror(ENOTDIR)); - return(AKLOG_BADPATH); - } - } - } + if (lstat(pathtocheck, &st) < 0) + { + /* + * If we've logged and still can't stat, there's + * a problem... + */ + fprintf(stderr, "%s: stat(%s): %s\n", progname, + pathtocheck, strerror(errno)); + return(AKLOG_BADPATH); + } + else if (!S_ISDIR(st.st_mode)) + { + /* Allow only directories */ + fprintf(stderr, "%s: %s: %s\n", progname, pathtocheck, + strerror(ENOTDIR)); + return(AKLOG_BADPATH); + } + } + } - return(status); + return(status); } /* Print usage message and exit */ static void usage(void) { - fprintf(stderr, "\nUsage: %s %s%s%s%s\n", progname, - "[-d] [[-cell | -c] cell [-k krb_realm]] ", - "[[-p | -path] pathname]\n", - " [-noprdb] [-force]\n", - " [-5 | -4]\n" - ); - fprintf(stderr, " -d gives debugging information.\n"); - fprintf(stderr, " krb_realm is the kerberos realm of a cell.\n"); - fprintf(stderr, " pathname is the name of a directory to which "); - fprintf(stderr, "you wish to authenticate.\n"); - fprintf(stderr, " -noprdb means don't try to determine AFS ID.\n"); - fprintf(stderr, " -5 or -4 selects whether to use Kerberos V or Kerberos IV.\n" - " (default is Kerberos V)\n"); - fprintf(stderr, " No commandline arguments means "); - fprintf(stderr, "authenticate to the local cell.\n"); - fprintf(stderr, "\n"); - exit(AKLOG_USAGE); + fprintf(stderr, "\nUsage: %s %s%s%s%s\n", progname, + "[-d] [[-cell | -c] cell [-k krb_realm]] ", + "[[-p | -path] pathname]\n", + " [-noprdb] [-force]\n", + " [-5 [-m]| -4]\n" + ); + fprintf(stderr, " -d gives debugging information.\n"); + fprintf(stderr, " krb_realm is the kerberos realm of a cell.\n"); + fprintf(stderr, " pathname is the name of a directory to which "); + fprintf(stderr, "you wish to authenticate.\n"); + fprintf(stderr, " -noprdb means don't try to determine AFS ID.\n"); + fprintf(stderr, " -5 or -4 selects whether to use Kerberos V or Kerberos IV.\n" + " (default is Kerberos V)\n"); + fprintf(stderr, " -m means use krb524d to convert Kerberos V tickets.\n"); + fprintf(stderr, " No commandline arguments means "); + fprintf(stderr, "authenticate to the local cell.\n"); + fprintf(stderr, "\n"); + exit(AKLOG_USAGE); } int main(int argc, char *argv[]) { - int status = AKLOG_SUCCESS; - int i; - int somethingswrong = FALSE; - - cellinfo_t cellinfo; - - extern char *progname; /* Name of this program */ - - extern int dflag; /* Debug mode */ - - int cmode = FALSE; /* Cellname mode */ - int pmode = FALSE; /* Path name mode */ - - char realm[REALM_SZ]; /* Kerberos realm of afs server */ - char cell[BUFSIZ]; /* Cell to which we are authenticating */ - char path[MAXPATHLEN + 1]; /* Path length for path mode */ - - linked_list cells; /* List of cells to log to */ - linked_list paths; /* List of paths to log to */ - ll_node *cur_node; - - krb5_context context = 0; - - memset(&cellinfo, 0, sizeof(cellinfo)); - - memset(realm, 0, sizeof(realm)); - memset(cell, 0, sizeof(cell)); - memset(path, 0, sizeof(path)); - - ll_init(&cells); - ll_init(&paths); - - /* Store the program name here for error messages */ - if (progname = LastComponent(argv[0])) - progname++; - else - progname = argv[0]; - - /* Initialize list of cells to which we have authenticated */ - (void)ll_init(&authedcells); - - /* Parse commandline arguments and make list of what to do. */ - for (i = 1; i < argc; i++) - { - if (strcmp(argv[i], "-d") == 0) - dflag++; - else if (strcmp(argv[i], "-5") == 0) - usev5++; - else if (strcmp(argv[i], "-4") == 0) - usev5 = 0; - else if (strcmp(argv[i], "-noprdb") == 0) - noprdb++; - else if (strcmp(argv[i], "-force") == 0) - force++; - else if (((strcmp(argv[i], "-cell") == 0) || - (strcmp(argv[i], "-c") == 0)) && !pmode) - { - if (++i < argc) - { - cmode++; - strcpy(cell, argv[i]); - } - else - usage(); - } - else if (((strcmp(argv[i], "-path") == 0) || - (strcmp(argv[i], "-p") == 0)) && !cmode) - { - if (++i < argc) - { - pmode++; - strcpy(path, argv[i]); - } - else - usage(); - } - else if (argv[i][0] == '-') - usage(); - else if (!pmode && !cmode) - { - if (FirstComponent(argv[i]) || (strcmp(argv[i], ".") == 0) || - (strcmp(argv[i], "..") == 0)) - { - pmode++; - strcpy(path, argv[i]); - } - else - { - cmode++; - strcpy(cell, argv[i]); - } - } - else - usage(); + int status = AKLOG_SUCCESS; + int i; + int somethingswrong = FALSE; + + cellinfo_t cellinfo; + + extern char *progname; /* Name of this program */ + + extern int dflag; /* Debug mode */ + + int cmode = FALSE; /* Cellname mode */ + int pmode = FALSE; /* Path name mode */ + + char realm[REALM_SZ]; /* Kerberos realm of afs server */ + char cell[BUFSIZ]; /* Cell to which we are authenticating */ + char path[MAXPATHLEN + 1]; /* Path length for path mode */ + + linked_list cells; /* List of cells to log to */ + linked_list paths; /* List of paths to log to */ + ll_node *cur_node; + + krb5_context context = 0; + + memset(&cellinfo, 0, sizeof(cellinfo)); + + memset(realm, 0, sizeof(realm)); + memset(cell, 0, sizeof(cell)); + memset(path, 0, sizeof(path)); + + ll_init(&cells); + ll_init(&paths); + + /* Store the program name here for error messages */ + if (progname = LastComponent(argv[0])) + progname++; + else + progname = argv[0]; + + /* Initialize list of cells to which we have authenticated */ + (void)ll_init(&authedcells); + + /* Parse commandline arguments and make list of what to do. */ + for (i = 1; i < argc; i++) + { + if (strcmp(argv[i], "-d") == 0) + dflag++; + else if (strcmp(argv[i], "-5") == 0) + usev5++; + else if (strcmp(argv[i], "-m") == 0) + use524++; + else if (strcmp(argv[i], "-4") == 0) + usev5 = 0; + else if (strcmp(argv[i], "-noprdb") == 0) + noprdb++; + else if (strcmp(argv[i], "-force") == 0) + force++; + else if (((strcmp(argv[i], "-cell") == 0) || + (strcmp(argv[i], "-c") == 0)) && !pmode) + { + if (++i < argc) + { + cmode++; + strcpy(cell, argv[i]); + } + else + usage(); + } + else if (((strcmp(argv[i], "-path") == 0) || + (strcmp(argv[i], "-p") == 0)) && !cmode) + { + if (++i < argc) + { + pmode++; + strcpy(path, argv[i]); + } + else + usage(); + } + else if (argv[i][0] == '-') + usage(); + else if (!pmode && !cmode) + { + if (FirstComponent(argv[i]) || (strcmp(argv[i], ".") == 0) || + (strcmp(argv[i], "..") == 0)) + { + pmode++; + strcpy(path, argv[i]); + } + else + { + cmode++; + strcpy(cell, argv[i]); + } + } + else + usage(); - if (cmode) - { - if (((i + 1) < argc) && (strcmp(argv[i + 1], "-k") == 0)) - { - i += 2; - if (i < argc) - strcpy(realm, argv[i]); - else - usage(); - } - /* Add this cell to list of cells */ - strcpy(cellinfo.cell, cell); - strcpy(cellinfo.realm, realm); - if (cur_node = ll_add_node(&cells, ll_tail)) - { - char *new_cellinfo; - if (new_cellinfo = copy_cellinfo(&cellinfo)) - ll_add_data(cur_node, new_cellinfo); - else - { - fprintf(stderr, "%s: failure copying cellinfo.\n", progname); - exit(AKLOG_MISC); - } - } - else - { - fprintf(stderr, "%s: failure adding cell to cells list.\n", - progname); - exit(AKLOG_MISC); - } - memset(&cellinfo, 0, sizeof(cellinfo)); - cmode = FALSE; - memset(cell, 0, sizeof(cell)); - memset(realm, 0, sizeof(realm)); - } - else if (pmode) - { - /* Add this path to list of paths */ - if (cur_node = ll_add_node(&paths, ll_tail)) - { - char *new_path; - if (new_path = copy_string(path)) - ll_add_data(cur_node, new_path); - else - { - fprintf(stderr, "%s: failure copying path name.\n", - progname); - exit(AKLOG_MISC); - } - } - else - { - fprintf(stderr, "%s: failure adding path to paths list.\n", - progname); - exit(AKLOG_MISC); - } - pmode = FALSE; - memset(path, 0, sizeof(path)); - } - } + if (cmode) + { + if (((i + 1) < argc) && (strcmp(argv[i + 1], "-k") == 0)) + { + i += 2; + if (i < argc) + strcpy(realm, argv[i]); + else + usage(); + } + /* Add this cell to list of cells */ + strcpy(cellinfo.cell, cell); + strcpy(cellinfo.realm, realm); + if (cur_node = ll_add_node(&cells, ll_tail)) + { + char *new_cellinfo; + if (new_cellinfo = copy_cellinfo(&cellinfo)) + ll_add_data(cur_node, new_cellinfo); + else + { + fprintf(stderr, "%s: failure copying cellinfo.\n", progname); + exit(AKLOG_MISC); + } + } + else + { + fprintf(stderr, "%s: failure adding cell to cells list.\n", + progname); + exit(AKLOG_MISC); + } + memset(&cellinfo, 0, sizeof(cellinfo)); + cmode = FALSE; + memset(cell, 0, sizeof(cell)); + memset(realm, 0, sizeof(realm)); + } + else if (pmode) + { + /* Add this path to list of paths */ + if (cur_node = ll_add_node(&paths, ll_tail)) + { + char *new_path; + if (new_path = copy_string(path)) + ll_add_data(cur_node, new_path); + else + { + fprintf(stderr, "%s: failure copying path name.\n", + progname); + exit(AKLOG_MISC); + } + } + else + { + fprintf(stderr, "%s: failure adding path to paths list.\n", + progname); + exit(AKLOG_MISC); + } + pmode = FALSE; + memset(path, 0, sizeof(path)); + } + } - if(usev5) - krb5_init_context(&context); + if(usev5) + krb5_init_context(&context); - /* If nothing was given, log to the local cell. */ - if ((cells.nelements + paths.nelements) == 0) - status = auth_to_cell(context, NULL, NULL); - else - { - /* Log to all cells in the cells list first */ - for (cur_node = cells.first; cur_node; cur_node = cur_node->next) - { - memcpy(&cellinfo, cur_node->data, sizeof(cellinfo)); + /* If nothing was given, log to the local cell. */ + if ((cells.nelements + paths.nelements) == 0) + status = auth_to_cell(context, NULL, NULL); + else + { + /* Log to all cells in the cells list first */ + for (cur_node = cells.first; cur_node; cur_node = cur_node->next) + { + memcpy(&cellinfo, cur_node->data, sizeof(cellinfo)); if (status = auth_to_cell(context, - cellinfo.cell, cellinfo.realm)) - somethingswrong++; - } + cellinfo.cell, cellinfo.realm)) + somethingswrong++; + } - /* Then, log to all paths in the paths list */ - for (cur_node = paths.first; cur_node; cur_node = cur_node->next) - { + /* Then, log to all paths in the paths list */ + for (cur_node = paths.first; cur_node; cur_node = cur_node->next) + { if (status = auth_to_path(context, - cur_node->data)) - somethingswrong++; - } + cur_node->data)) + somethingswrong++; + } - /* - * If only one thing was logged to, we'll return the status - * of the single call. Otherwise, we'll return a generic - * something failed status. - */ - if (somethingswrong && ((cells.nelements + paths.nelements) > 1)) - status = AKLOG_SOMETHINGSWRONG; - } + /* + * If only one thing was logged to, we'll return the status + * of the single call. Otherwise, we'll return a generic + * something failed status. + */ + if (somethingswrong && ((cells.nelements + paths.nelements) > 1)) + status = AKLOG_SOMETHINGSWRONG; + } - if(usev5) - krb5_free_context(context); + if(usev5) + krb5_free_context(context); - exit(status); -} + exit(status); +} diff --git a/src/WINNT/client_config/drivemap.cpp b/src/WINNT/client_config/drivemap.cpp index 2681847e8..5305f3c65 100644 --- a/src/WINNT/client_config/drivemap.cpp +++ b/src/WINNT/client_config/drivemap.cpp @@ -26,6 +26,7 @@ extern "C" { #endif #include #include +#include extern void Config_GetLanAdapter (ULONG *pnLanAdapter); @@ -75,6 +76,28 @@ WriteRegistryString(HKEY key, TCHAR * subkey, LPTSTR lhs, LPTSTR rhs) return (status == ERROR_SUCCESS); } +static BOOL +WriteExpandedRegistryString(HKEY key, TCHAR * subkey, LPTSTR lhs, LPTSTR rhs) +{ + HKEY hkSub = NULL; + RegCreateKeyEx( key, + subkey, + 0, + NULL, + REG_OPTION_NON_VOLATILE, + KEY_WRITE, + NULL, + &hkSub, + NULL); + + DWORD status = RegSetValueEx( hkSub, lhs, 0, REG_EXPAND_SZ, (const BYTE *)rhs, strlen(rhs)+1 ); + + if ( hkSub ) + RegCloseKey( hkSub ); + + return (status == ERROR_SUCCESS); +} + static BOOL ReadRegistryString(HKEY key, TCHAR * subkey, LPTSTR lhs, LPTSTR rhs, DWORD * size) { @@ -89,8 +112,19 @@ ReadRegistryString(HKEY key, TCHAR * subkey, LPTSTR lhs, LPTSTR rhs, DWORD * siz &hkSub, NULL); - DWORD dwType; - DWORD status = RegQueryValueEx( hkSub, lhs, 0, &dwType, (LPBYTE)rhs, size ); + DWORD dwType = 0; + DWORD localSize = *size; + + DWORD status = RegQueryValueEx( hkSub, lhs, 0, &dwType, (LPBYTE)rhs, &localSize); + if (status == 0 && dwType == REG_EXPAND_SZ) { + TCHAR * buf = (TCHAR *)malloc((*size) * sizeof(TCHAR)); + memcpy(buf, rhs, (*size) * sizeof(TCHAR)); + localSize = ExpandEnvironmentStrings(buf, rhs, *size); + free(buf); + if ( localSize > *size ) + status = !ERROR_SUCCESS; + } + *size = localSize; if ( hkSub ) RegCloseKey( hkSub ); @@ -112,7 +146,6 @@ DeleteRegistryString(HKEY key, TCHAR * subkey, LPTSTR lhs) &hkSub, NULL); - DWORD dwType; DWORD status = RegDeleteValue( hkSub, lhs ); if ( hkSub ) @@ -385,7 +418,7 @@ void QueryDriveMapList_ReadSubmounts (PDRIVEMAPLIST pList) HKEY hkSubmounts; RegCreateKeyEx( HKEY_LOCAL_MACHINE, - "SOFTWARE\\OpenAFS\\Client\\Submounts", + cszSECTION_SUBMOUNTS, 0, "AFS", REG_OPTION_NON_VOLATILE, @@ -414,11 +447,19 @@ void QueryDriveMapList_ReadSubmounts (PDRIVEMAPLIST pList) DWORD submountPathLen = MAX_PATH; TCHAR submountName[MAX_PATH]; DWORD submountNameLen = MAX_PATH; - DWORD dwType; + DWORD dwType = 0; RegEnumValue( hkSubmounts, dwIndex, submountName, &submountNameLen, NULL, &dwType, (LPBYTE)submountPath, &submountPathLen); + if (dwType == REG_EXPAND_SZ) { + char buf[MAX_PATH]; + StringCbCopyA(buf, MAX_PATH, submountPath); + submountPathLen = ExpandEnvironmentStrings(buf, submountPath, MAX_PATH); + if (submountPathLen > MAX_PATH) + continue; + } + SUBMOUNT Submount; memset (&Submount, 0x00, sizeof(SUBMOUNT)); lstrcpy (Submount.szSubmount, submountName); @@ -482,7 +523,7 @@ void QueryDriveMapList_ReadMappings (PDRIVEMAPLIST pList) &dwType, (LPBYTE)mapping, &mappingLen); if ( dwType == REG_EXPAND_SZ ) { TCHAR buf[MAX_PATH]; - DWORD dummyLen = ExpandEnvironmentStrings(buf, mapping, MAX_PATH); + DWORD dummyLen = ExpandEnvironmentStrings(mapping, buf, MAX_PATH); if (dummyLen > MAX_PATH) continue; _tcsncpy(mapping, buf, MAX_PATH); @@ -805,7 +846,7 @@ void AddSubMount (LPTSTR pszSubmount, LPTSTR pszMapping) if (!szRHS[0]) lstrcpy (szRHS, TEXT("/")); - WriteRegistryString(HKEY_LOCAL_MACHINE, cszSECTION_SUBMOUNTS, pszSubmount, szRHS); + WriteExpandedRegistryString(HKEY_LOCAL_MACHINE, cszSECTION_SUBMOUNTS, pszSubmount, szRHS); } diff --git a/src/WINNT/client_config/isadmin.cpp b/src/WINNT/client_config/isadmin.cpp index 2013b7b9c..8cf1dafeb 100644 --- a/src/WINNT/client_config/isadmin.cpp +++ b/src/WINNT/client_config/isadmin.cpp @@ -76,8 +76,6 @@ BOOL IsAdmin (void) return FALSE; } - fTested = TRUE; - dwSize = 0; dwSize2 = 0; @@ -99,7 +97,7 @@ BOOL IsAdmin (void) return TRUE; } - psidAdmin = (PSID) malloc(dwSize); memset(psidAdmin,0,dwSize); + psidAdmin = (PSID)malloc(dwSize); memset(psidAdmin,0,dwSize); pszRefDomain = (char *)malloc(dwSize2); if (!LookupAccountName(NULL, pszAdminGroup, psidAdmin, &dwSize, pszRefDomain, &dwSize2, &snu)) { @@ -112,39 +110,76 @@ BOOL IsAdmin (void) if (OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &hToken)) { - /* We'll have to allocate a chunk of memory to store the list of - * groups to which this user belongs; find out how much memory - * we'll need. - */ - DWORD dwSize = 0; - PTOKEN_GROUPS pGroups; - - GetTokenInformation (hToken, TokenGroups, NULL, dwSize, &dwSize); - - pGroups = (PTOKEN_GROUPS)malloc(dwSize); - - /* Allocate that buffer, and read in the list of groups. */ - if (GetTokenInformation (hToken, TokenGroups, pGroups, dwSize, &dwSize)) - { - /* Look through the list of group SIDs and see if any of them - * matches the AFS Client Admin group SID. + + if (!CheckTokenMembership(hToken, psidAdmin, &fAdmin)) { + /* We'll have to allocate a chunk of memory to store the list of + * groups to which this user belongs; find out how much memory + * we'll need. */ - size_t iGroup = 0; - for (; (!fAdmin) && (iGroup < pGroups->GroupCount); ++iGroup) + DWORD dwSize = 0; + PTOKEN_GROUPS pGroups; + + GetTokenInformation (hToken, TokenGroups, NULL, dwSize, &dwSize); + + pGroups = (PTOKEN_GROUPS)malloc(dwSize); + + /* Allocate that buffer, and read in the list of groups. */ + if (GetTokenInformation (hToken, TokenGroups, pGroups, dwSize, &dwSize)) { - if (EqualSid (psidAdmin, pGroups->Groups[ iGroup ].Sid)) { - fAdmin = TRUE; + /* Look through the list of group SIDs and see if any of them + * matches the AFS Client Admin group SID. + */ + size_t iGroup = 0; + for (; (!fAdmin) && (iGroup < pGroups->GroupCount); ++iGroup) + { + if (EqualSid (psidAdmin, pGroups->Groups[ iGroup ].Sid)) { + fAdmin = TRUE; + } } } + + if (pGroups) + free(pGroups); } - if (pGroups) - free(pGroups); + /* if do not have permission because we were not explicitly listed + * in the Admin Client Group let's see if we are the SYSTEM account + */ + if (!fAdmin) { + PTOKEN_USER pTokenUser; + SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY; + PSID pSidLocalSystem = 0; + DWORD gle; + + GetTokenInformation(hToken, TokenUser, NULL, 0, &dwSize); + + pTokenUser = (PTOKEN_USER)malloc(dwSize); + + if (!GetTokenInformation(hToken, TokenUser, pTokenUser, dwSize, &dwSize)) + gle = GetLastError(); + + if (AllocateAndInitializeSid( &SIDAuth, 1, + SECURITY_LOCAL_SYSTEM_RID, + 0, 0, 0, 0, 0, 0, 0, + &pSidLocalSystem)) + { + if (EqualSid(pTokenUser->User.Sid, pSidLocalSystem)) { + fAdmin = TRUE; + } + + FreeSid(pSidLocalSystem); + } + + if ( pTokenUser ) + free(pTokenUser); + } } } free(psidAdmin); free(pszRefDomain); + + fTested = TRUE; } return fAdmin; diff --git a/src/WINNT/client_creds/ipaddrchg.c b/src/WINNT/client_creds/ipaddrchg.c index 2d640dcd1..03feba3d7 100644 --- a/src/WINNT/client_creds/ipaddrchg.c +++ b/src/WINNT/client_creds/ipaddrchg.c @@ -304,13 +304,13 @@ ObtainTokensFromUserIfNeeded(HWND hWnd) strcpy(aserver.name, "afs"); strcpy(aserver.cell, rootcell); + GetLocalTime (&stNow); + SystemTimeToFileTime (&stNow, &ftNow); + llNow = (((LONGLONG)ftNow.dwHighDateTime) << 32) + (LONGLONG)(ftNow.dwLowDateTime); + llNow /= c100ns1SECOND; + rc = ktc_GetToken(&aserver, &atoken, sizeof(atoken), &aclient); if ( rc == 0 ) { - GetLocalTime (&stNow); - SystemTimeToFileTime (&stNow, &ftNow); - llNow = (((LONGLONG)ftNow.dwHighDateTime) << 32) + (LONGLONG)(ftNow.dwLowDateTime); - llNow /= c100ns1SECOND; - TimeToSystemTime (&stExpires, atoken.endTime); SystemTimeToFileTime (&stExpires, &ftExpires); llExpires = (((LONGLONG)ftExpires.dwHighDateTime) << 32) + (LONGLONG)(ftExpires.dwLowDateTime); @@ -371,14 +371,15 @@ ObtainTokensFromUserIfNeeded(HWND hWnd) KFW_AFS_renew_token_for_cell(rootcell); rc = ktc_GetToken(&aserver, &atoken, sizeof(atoken), &aclient); - - TimeToSystemTime (&stExpires, atoken.endTime); - SystemTimeToFileTime (&stExpires, &ftExpires); - llExpires = (((LONGLONG)ftExpires.dwHighDateTime) << 32) + (LONGLONG)(ftExpires.dwLowDateTime); - llExpires /= c100ns1SECOND; + if ( rc == 0 ) { + TimeToSystemTime (&stExpires, atoken.endTime); + SystemTimeToFileTime (&stExpires, &ftExpires); + llExpires = (((LONGLONG)ftExpires.dwHighDateTime) << 32) + (LONGLONG)(ftExpires.dwLowDateTime); + llExpires /= c100ns1SECOND; - if (!rc && (llNow < llExpires)) - goto cleanup; + if (llNow < llExpires) + goto cleanup; + } } SendMessage(hWnd, WM_OBTAIN_TOKENS, FALSE, (long)rootcell); diff --git a/src/WINNT/client_osi/osisleep.h b/src/WINNT/client_osi/osisleep.h index 0fb873d00..4bf61751d 100644 --- a/src/WINNT/client_osi/osisleep.h +++ b/src/WINNT/client_osi/osisleep.h @@ -35,7 +35,7 @@ typedef struct osi_sleepInfo { unsigned short states; /* states bits */ unsigned short idx; /* sleep hash table we're in, if in hash */ unsigned short waitFor; /* what are we waiting for; used for bulk wakeups */ - unsigned short refCount;/* reference count from FDs */ + unsigned long refCount;/* reference count from FDs */ } osi_sleepInfo_t; /* first guy is the most recently added process */ diff --git a/src/WINNT/client_osi/osistatl.h b/src/WINNT/client_osi/osistatl.h index 0bcfa6da3..e2dd99f4c 100644 --- a/src/WINNT/client_osi/osistatl.h +++ b/src/WINNT/client_osi/osistatl.h @@ -56,8 +56,8 @@ typedef struct osi_qiStat { */ typedef struct osi_mutexStat { osi_queue_t q; /* queue of all mutexes */ - osi_turnstile_t turn; /* the real turnstile */ - short refCount; /* so we can iterate cleanly */ + osi_turnstile_t turn; /* the real turnstile */ + unsigned long refCount; /* so we can iterate cleanly */ short states; /* track # of lock calls and blocks */ @@ -79,7 +79,7 @@ typedef struct osi_mutexStat { typedef struct osi_rwlockStat { osi_queue_t q; /* queue of all mutexes */ osi_turnstile_t turn; /* the real turnstile */ - short refCount; /* so we can iterate cleanly */ + unsigned long refCount; /* so we can iterate cleanly */ short states; /* statistics */ diff --git a/src/WINNT/install/NSIS/AdminGroup.cpp b/src/WINNT/install/NSIS/AdminGroup.cpp index e3adcacce..7d9f170fc 100644 --- a/src/WINNT/install/NSIS/AdminGroup.cpp +++ b/src/WINNT/install/NSIS/AdminGroup.cpp @@ -62,7 +62,7 @@ int main(int argc, char ** argv) { return 1; } - if(stricmp(argv[1], "-create")) { + if(!stricmp(argv[1], "-create")) { rv = createAfsAdminGroup(); if(rv) { if(rv != ERROR_ALIAS_EXISTS) { @@ -77,7 +77,7 @@ int main(int argc, char ** argv) { if(rv) fprintf(stderr, "%s: Can't populate AFS Client Admin group. NetApi error %u\n", rv); } - } else if(stricmp(argv[1], "-remove")) { + } else if(!stricmp(argv[1], "-remove")) { removeAfsAdminGroup(); rv = 0; } else { diff --git a/src/WINNT/install/NSIS/NTMakefile b/src/WINNT/install/NSIS/NTMakefile index 69a67918f..467882336 100644 --- a/src/WINNT/install/NSIS/NTMakefile +++ b/src/WINNT/install/NSIS/NTMakefile @@ -30,9 +30,11 @@ $(EXEDIR)\AdminGroup.exe: $(OUT)\AdminGroup.obj prebuild: !IF ("$(AFSDEV_BUILDTYPE)" == "FREE") -!IF ("$(AFSVER_CL)"=="1310") +!IF ("$(AFSVER_CL)"=="1400") + $(COPY) %SystemRoot%\System32\Msvcr80.dll $(EXEDIR) + $(COPY) %SystemRoot%\System32\MFC80.DLL $(EXEDIR) +!ELSE IF ("$(AFSVER_CL)"=="1310") $(COPY) %SystemRoot%\System32\Msvcr71.dll $(EXEDIR) - $(COPY) %SystemRoot%\System32\MSVCRT.DLL $(EXEDIR) $(COPY) %SystemRoot%\System32\MFC71.DLL $(EXEDIR) !ELSE IF ("$(AFSVER_CL)"=="1300") $(COPY) %SystemRoot%\System32\Msvcp70.dll $(EXEDIR) @@ -45,7 +47,12 @@ prebuild: !ERROR Unknown Compiler Version !ENDIF !ELSE # NOT FREE - CHECKED -!IF ("$(AFSVER_CL)"=="1310") +!IF ("$(AFSVER_CL)"=="1400") + $(COPY) %SystemRoot%\System32\Msvcr80d.dll $(EXEDIR) + $(COPY) %SystemRoot%\System32\Msvcr80d.pdb $(EXEDIR) + $(COPY) %SystemRoot%\System32\MFC80D.DLL $(EXEDIR) + $(COPY) %SystemRoot%\System32\MFC80D.pdb $(EXEDIR) +!ELSE IF ("$(AFSVER_CL)"=="1310") $(COPY) %SystemRoot%\System32\Msvcr71d.dll $(EXEDIR) $(COPY) %SystemRoot%\System32\Msvcr71d.pdb $(EXEDIR) $(COPY) %SystemRoot%\System32\MFC71D.DLL $(EXEDIR) @@ -75,7 +82,9 @@ prebuild: $(DESTDIR)\bin\util_cr.exe _echo "!define " >>$(OUT)\nsi-includes.nsi "$(NSISDIR)\makensis.exe" /VERSION >>$(OUT)\nsi-includes.nsi echo. >>$(OUT)\nsi-includes.nsi -!if ("$(AFSVER_CL)" == "1310") +!if ("$(AFSVER_CL)" == "1400") + echo !define CL_1310 1 >> $(OUT)\nsi-includes.nsi +!else if ("$(AFSVER_CL)" == "1310") echo !define CL_1310 1 >> $(OUT)\nsi-includes.nsi !else if ("$(AFSVER_CL)" == "1300") echo !define CL_1300 1 >> $(OUT)\nsi-includes.nsi diff --git a/src/WINNT/install/NSIS/OpenAFS.nsi b/src/WINNT/install/NSIS/OpenAFS.nsi index 9c53ae3ba..686a8ea62 100644 --- a/src/WINNT/install/NSIS/OpenAFS.nsi +++ b/src/WINNT/install/NSIS/OpenAFS.nsi @@ -1177,6 +1177,11 @@ DoControl: DoCommon: SetOutPath "$INSTDIR\Common" +!IFDEF CL_1400 + File "${SYSTEMDIR}\msvcr80d.pdb" + File "${SYSTEMDIR}\msvcp80d.pdb" + File "${SYSTEMDIR}\mfc80d.pdb" +!ELSE !IFDEF CL_1310 File "${SYSTEMDIR}\msvcr71d.pdb" File "${SYSTEMDIR}\msvcp71d.pdb" @@ -1192,6 +1197,7 @@ DoCommon: File "${SYSTEMDIR}\msvcrtd.pdb" !ENDIF !ENDIF +!ENDIF ; Common Areas SetOutPath "$INSTDIR\Common" @@ -1631,6 +1637,14 @@ StartRemove: Delete /REBOOTOK "$INSTDIR\Common\afskasadmin.pdb" Delete /REBOOTOK "$INSTDIR\Common\afsptsadmin.pdb" !IFDEF DEBUG +!IFDEF CL_1400 + Delete /REBOOTOK "$INSTDIR\bin\msvcr80d.dll" + Delete /REBOOTOK "$INSTDIR\bin\msvcr80d.pdb" + Delete /REBOOTOK "$INSTDIR\bin\msvcp80d.dll" + Delete /REBOOTOK "$INSTDIR\bin\msvcp80d.pdb" + Delete /REBOOTOK "$INSTDIR\bin\mfc80d.dll" + Delete /REBOOTOK "$INSTDIR\bin\mfc80d.pdb" +!ELSE !IFDEF CL_1310 Delete /REBOOTOK "$INSTDIR\bin\msvcr71d.dll" Delete /REBOOTOK "$INSTDIR\bin\msvcr71d.pdb" @@ -1655,6 +1669,21 @@ StartRemove: Delete /REBOOTOK "$INSTDIR\bin\msvcrtd.pdb" !ENDIF !ENDIF +!ENDIF +!ELSE +!IFDEF CL_1400 + Delete /REBOOTOK "$INSTDIR\bin\mfc80.dll" + Delete /REBOOTOK "$INSTDIR\bin\msvcr80.dll" + Delete /REBOOTOK "$INSTDIR\bin\msvcp80.dll" + Delete /REBOOTOK "$INSTDIR\bin\MFC80CHS.DLL" + Delete /REBOOTOK "$INSTDIR\bin\MFC80CHT.DLL" + Delete /REBOOTOK "$INSTDIR\bin\MFC80DEU.DLL" + Delete /REBOOTOK "$INSTDIR\bin\MFC80ENU.DLL" + Delete /REBOOTOK "$INSTDIR\bin\MFC80ESP.DLL" + Delete /REBOOTOK "$INSTDIR\bin\MFC80FRA.DLL" + Delete /REBOOTOK "$INSTDIR\bin\MFC80ITA.DLL" + Delete /REBOOTOK "$INSTDIR\bin\MFC80JPN.DLL" + Delete /REBOOTOK "$INSTDIR\bin\MFC80KOR.DLL" !ELSE !IFDEF CL_1310 Delete /REBOOTOK "$INSTDIR\bin\mfc71.dll" @@ -1689,6 +1718,7 @@ StartRemove: Delete /REBOOTOK "$INSTDIR\bin\msvcrt.dll" !ENDIF !ENDIF +!ENDIF !ENDIF IfSilent SkipDel @@ -1790,6 +1820,14 @@ StartRemove: RMDir "$INSTDIR\Client" !IFDEF DEBUG +!IFDEF CL_1400 + Delete /REBOOTOK "$INSTDIR\bin\msvcr80d.dll" + Delete /REBOOTOK "$INSTDIR\bin\msvcr80d.pdb" + Delete /REBOOTOK "$INSTDIR\bin\msvcp80d.dll" + Delete /REBOOTOK "$INSTDIR\bin\msvcp80d.pdb" + Delete /REBOOTOK "$INSTDIR\bin\mfc80d.dll" + Delete /REBOOTOK "$INSTDIR\bin\mfc80d.pdb" +!ELSE !IFDEF CL_1310 Delete /REBOOTOK "$INSTDIR\bin\msvcr71d.dll" Delete /REBOOTOK "$INSTDIR\bin\msvcr71d.pdb" @@ -1814,6 +1852,21 @@ StartRemove: Delete /REBOOTOK "$INSTDIR\bin\msvcrtd.pdb" !ENDIF !ENDIF +!ENDIF +!ELSE +!IFDEF CL_1400 + Delete /REBOOTOK "$INSTDIR\bin\mfc80.dll" + Delete /REBOOTOK "$INSTDIR\bin\msvcr80.dll" + Delete /REBOOTOK "$INSTDIR\bin\msvcp80.dll" + Delete /REBOOTOK "$INSTDIR\bin\MFC80CHS.DLL" + Delete /REBOOTOK "$INSTDIR\bin\MFC80CHT.DLL" + Delete /REBOOTOK "$INSTDIR\bin\MFC80DEU.DLL" + Delete /REBOOTOK "$INSTDIR\bin\MFC80ENU.DLL" + Delete /REBOOTOK "$INSTDIR\bin\MFC80ESP.DLL" + Delete /REBOOTOK "$INSTDIR\bin\MFC80FRA.DLL" + Delete /REBOOTOK "$INSTDIR\bin\MFC80ITA.DLL" + Delete /REBOOTOK "$INSTDIR\bin\MFC80JPN.DLL" + Delete /REBOOTOK "$INSTDIR\bin\MFC80KOR.DLL" !ELSE !IFDEF CL_1310 Delete /REBOOTOK "$INSTDIR\bin\mfc71.dll" @@ -1848,6 +1901,7 @@ StartRemove: Delete /REBOOTOK "$INSTDIR\bin\msvcrt.dll" !ENDIF !ENDIF +!ENDIF !ENDIF Delete /REBOOTOK "$INSTDIR\Common\*" @@ -2597,6 +2651,20 @@ Function AFSLangFiles SetOutPath "$INSTDIR\Common" !IFDEF DEBUG +!IFDEF CL_1400 + !insertmacro ReplaceDLL "${SYSTEMDIR}\msvcr80d.dll" "$INSTDIR\Common\msvcr80d.dll" "$INSTDIR" + !insertmacro ReplaceDLL "${SYSTEMDIR}\msvcp80d.dll" "$INSTDIR\Common\msvcp80d.dll" "$INSTDIR" + !insertmacro ReplaceDLL "${SYSTEMDIR}\mfc80d.dll" "$INSTDIR\Common\mfc80d.dll" "$INSTDIR" + !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC80CHS.DLL" "$INSTDIR\Common\MFC80CHS.DLL" "$INSTDIR" + !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC80CHT.DLL" "$INSTDIR\Common\MFC80CHT.DLL" "$INSTDIR" + !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC80DEU.DLL" "$INSTDIR\Common\MFC80DEU.DLL" "$INSTDIR" + !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC80ENU.DLL" "$INSTDIR\Common\MFC80ENU.DLL" "$INSTDIR" + !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC80ESP.DLL" "$INSTDIR\Common\MFC80ESP.DLL" "$INSTDIR" + !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC80FRA.DLL" "$INSTDIR\Common\MFC80FRA.DLL" "$INSTDIR" + !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC80ITA.DLL" "$INSTDIR\Common\MFC80ITA.DLL" "$INSTDIR" + !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC80JPN.DLL" "$INSTDIR\Common\MFC80JPN.DLL" "$INSTDIR" + !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC80KOR.DLL" "$INSTDIR\Common\MFC80KOR.DLL" "$INSTDIR" +!ELSE !IFDEF CL_1310 !insertmacro ReplaceDLL "${SYSTEMDIR}\msvcr71d.dll" "$INSTDIR\Common\msvcr71d.dll" "$INSTDIR" !insertmacro ReplaceDLL "${SYSTEMDIR}\msvcp71d.dll" "$INSTDIR\Common\msvcp71d.dll" "$INSTDIR" @@ -2630,6 +2698,21 @@ Function AFSLangFiles !insertmacro ReplaceDLL "${SYSTEMDIR}\msvcrtd.dll" "$INSTDIR\Common\msvcrtd.dll" "$INSTDIR" !ENDIF !ENDIF +!ENDIF +!ELSE +!IFDEF CL_1400 + !insertmacro ReplaceDLL "${SYSTEMDIR}\mfc80.dll" "$INSTDIR\Common\mfc80.dll" "$INSTDIR" + !insertmacro ReplaceDLL "${SYSTEMDIR}\msvcr80.dll" "$INSTDIR\Common\msvcr80.dll" "$INSTDIR" + !insertmacro ReplaceDLL "${SYSTEMDIR}\msvcp80.dll" "$INSTDIR\Common\msvcp80.dll" "$INSTDIR" + !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC80CHS.DLL" "$INSTDIR\Common\MFC80CHS.DLL" "$INSTDIR" + !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC80CHT.DLL" "$INSTDIR\Common\MFC80CHT.DLL" "$INSTDIR" + !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC80DEU.DLL" "$INSTDIR\Common\MFC80DEU.DLL" "$INSTDIR" + !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC80ENU.DLL" "$INSTDIR\Common\MFC80ENU.DLL" "$INSTDIR" + !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC80ESP.DLL" "$INSTDIR\Common\MFC80ESP.DLL" "$INSTDIR" + !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC80FRA.DLL" "$INSTDIR\Common\MFC80FRA.DLL" "$INSTDIR" + !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC80ITA.DLL" "$INSTDIR\Common\MFC80ITA.DLL" "$INSTDIR" + !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC80JPN.DLL" "$INSTDIR\Common\MFC80JPN.DLL" "$INSTDIR" + !insertmacro ReplaceDLL "${SYSTEMDIR}\MFC80KOR.DLL" "$INSTDIR\Common\MFC80KOR.DLL" "$INSTDIR" !ELSE !IFDEF CL_1310 !insertmacro ReplaceDLL "${SYSTEMDIR}\mfc71.dll" "$INSTDIR\Common\mfc71.dll" "$INSTDIR" @@ -2665,6 +2748,7 @@ Function AFSLangFiles !ENDIF !ENDIF !ENDIF +!ENDIF StrCmp $LANGUAGE ${LANG_ENGLISH} DoEnglish StrCmp $LANGUAGE ${LANG_GERMAN} DoGerman diff --git a/src/WINNT/install/wix/NTMakefile b/src/WINNT/install/wix/NTMakefile index 0dff735c0..8ea9570bf 100644 --- a/src/WINNT/install/wix/NTMakefile +++ b/src/WINNT/install/wix/NTMakefile @@ -30,7 +30,7 @@ languages: # ) $(MAKE) /f NTMakefile /nologo LANG=en_US lang -lang:: $(MSIFILE) +lang:: lang_clean $(MSIFILE) customactions: $(CD) custom diff --git a/src/afs/LINUX/osi_groups.c b/src/afs/LINUX/osi_groups.c index 4b729d695..f338c99c7 100644 --- a/src/afs/LINUX/osi_groups.c +++ b/src/afs/LINUX/osi_groups.c @@ -17,7 +17,7 @@ #include "afs/param.h" RCSID - ("$Header: /cvs/openafs/src/afs/LINUX/osi_groups.c,v 1.25 2004/07/14 04:09:12 shadow Exp $"); + ("$Header: /cvs/openafs/src/afs/LINUX/osi_groups.c,v 1.25.2.1 2004/10/18 07:11:46 shadow Exp $"); #include "afs/sysincludes.h" #include "afsincludes.h" @@ -222,7 +222,7 @@ setpag(cred_t ** cr, afs_uint32 pagvalue, afs_uint32 * newpag, /* Intercept the standard system call. */ -extern long (*sys_setgroupsp) (int gidsetsize, gid_t * grouplist); +extern asmlinkage long (*sys_setgroupsp) (int gidsetsize, gid_t * grouplist); asmlinkage long afs_xsetgroups(int gidsetsize, gid_t * grouplist) { @@ -256,7 +256,7 @@ afs_xsetgroups(int gidsetsize, gid_t * grouplist) #if defined(AFS_LINUX24_ENV) /* Intercept the standard uid32 system call. */ -extern long (*sys_setgroups32p) (int gidsetsize, gid_t * grouplist); +extern asmlinkage long (*sys_setgroups32p) (int gidsetsize, gid_t * grouplist); asmlinkage long afs_xsetgroups32(int gidsetsize, gid_t * grouplist) { diff --git a/src/afs/LINUX/osi_module.c b/src/afs/LINUX/osi_module.c index 03cc06582..d9b92521f 100644 --- a/src/afs/LINUX/osi_module.c +++ b/src/afs/LINUX/osi_module.c @@ -15,7 +15,7 @@ #include "afs/param.h" RCSID - ("$Header: /cvs/openafs/src/afs/LINUX/osi_module.c,v 1.52.2.1 2004/08/25 07:03:36 shadow Exp $"); + ("$Header: /cvs/openafs/src/afs/LINUX/osi_module.c,v 1.52.2.2 2004/10/18 17:43:51 shadow Exp $"); #include "afs/sysincludes.h" #include "afsincludes.h" @@ -223,11 +223,6 @@ asmlinkage int (*sys_setgroups32p) (int gidsetsize, #define SYSCALL2POINTER (void *) #endif -#ifdef AFS_PPC64_LINUX20_ENV -extern void *set_afs_syscall(void*); -extern void *set_afs_xsetgroups_syscall(void*); -extern void *set_afs_xsetgroups_syscall32(void*); -#endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) int __init @@ -525,11 +520,6 @@ init_module(void) #endif /* AFS_AMD64_LINUX20_ENV */ #endif /* AFS_IA64_LINUX20_ENV */ -#ifdef AFS_PPC64_LINUX20_ENV - afs_ni_syscall = set_afs_syscall(afs_syscall); - sys_setgroupsp = set_afs_xsetgroups_syscall(afs_xsetgroups); - sys32_setgroupsp = set_afs_xsetgroups_syscall32(afs32_xsetgroups); -#endif } osi_sysctl_init(); @@ -582,11 +572,6 @@ cleanup_module(void) } #endif } -#ifdef AFS_PPC64_LINUX20_ENV - set_afs_syscall(afs_ni_syscall); - set_afs_xsetgroups_syscall(sys_setgroupsp); - set_afs_xsetgroups_syscall32(sys32_setgroupsp); -#endif unregister_filesystem(&afs_fs_type); osi_linux_free_inode_pages(); /* Invalidate all pages using AFS inodes. */ diff --git a/src/afs/LINUX/osi_prototypes.h b/src/afs/LINUX/osi_prototypes.h index b39361a6d..233e8af93 100644 --- a/src/afs/LINUX/osi_prototypes.h +++ b/src/afs/LINUX/osi_prototypes.h @@ -36,9 +36,6 @@ extern int osi_lookupname(char *aname, uio_seg_t seg, int followlink, extern int osi_InitCacheInfo(char *aname); extern int osi_rdwr(int rw, struct osi_file *file, caddr_t addrp, size_t asize, size_t * resid); -extern void inline setup_uio(uio_t * uiop, struct iovec *iovecp, char *buf, - afs_offs_t pos, int count, uio_flag_t flag, - uio_seg_t seg); extern int osi_file_uio_rdwr(struct osi_file *osifile, uio_t * uiop, int rw); extern void afs_osi_SetTime(osi_timeval_t * tvp); extern void osi_linux_free_inode_pages(void); diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c index 7e985af7b..fda7e6a3e 100644 --- a/src/afs/LINUX/osi_vnodeops.c +++ b/src/afs/LINUX/osi_vnodeops.c @@ -22,7 +22,7 @@ #include "afs/param.h" RCSID - ("$Header: /cvs/openafs/src/afs/LINUX/osi_vnodeops.c,v 1.81.2.2 2004/08/25 07:10:39 shadow Exp $"); + ("$Header: /cvs/openafs/src/afs/LINUX/osi_vnodeops.c,v 1.81.2.3 2004/10/18 17:43:51 shadow Exp $"); #include "afs/sysincludes.h" #include "afsincludes.h" @@ -333,11 +333,11 @@ afs_linux_readdir(struct file *fp, void *dirbuf, filldir_t filldir) code = 0; offset = (int) fp->f_pos; while (1) { - dirpos = BlobScan(&tdc->f.inode, offset); + dirpos = BlobScan(&tdc->f, offset); if (!dirpos) break; - de = afs_dir_GetBlob(&tdc->f.inode, dirpos); + de = afs_dir_GetBlob(&tdc->f, dirpos); if (!de) break; @@ -649,12 +649,7 @@ afs_linux_lock(struct file *fp, int cmd, struct file_lock *flp) int code = 0; struct vcache *vcp = ITOAFS(FILE_INODE(fp)); cred_t *credp = crref(); -#ifdef AFS_LINUX24_ENV - struct flock64 flock; -#else - struct flock flock; -#endif - + struct AFS_FLOCK flock; /* Convert to a lock format afs_lockctl understands. */ memset((char *)&flock, 0, sizeof(flock)); flock.l_type = flp->fl_type; @@ -1485,6 +1480,12 @@ afs_linux_writepage(struct page *pp) unsigned offset = PAGE_CACHE_SIZE; long status; +#ifdef PageLaunder + if (PageLaunder(pp)) { + return(fail_writepage(pp)); + } +#endif + inode = (struct inode *)mapping->host; end_index = inode->i_size >> PAGE_CACHE_SHIFT; diff --git a/src/afs/SOLARIS/osi_vnodeops.c b/src/afs/SOLARIS/osi_vnodeops.c index 9270e1ab0..d0ad7a0e9 100644 --- a/src/afs/SOLARIS/osi_vnodeops.c +++ b/src/afs/SOLARIS/osi_vnodeops.c @@ -11,7 +11,7 @@ #include "afs/param.h" RCSID - ("$Header: /cvs/openafs/src/afs/SOLARIS/osi_vnodeops.c,v 1.20 2004/06/24 17:38:24 shadow Exp $"); + ("$Header: /cvs/openafs/src/afs/SOLARIS/osi_vnodeops.c,v 1.20.2.1 2004/10/18 07:11:47 shadow Exp $"); #if defined(AFS_SUN_ENV) || defined(AFS_SUN5_ENV) /* @@ -1069,7 +1069,7 @@ afs_nfsrdwr(avc, auio, arw, ioflag, acred) /* do ulimit processing; shrink resid or fail */ #if defined(AFS_SUN56_ENV) if (auio->uio_loffset + auio->afsio_resid > auio->uio_llimit) { - if (auio->uio_llimit >= auio->uio_llimit) { + if (auio->uio_loffset >= auio->uio_llimit) { ReleaseWriteLock(&avc->lock); afs_BozonUnlock(&avc->pvnLock, avc); return EFBIG; diff --git a/src/afs/VNOPS/afs_vnop_create.c b/src/afs/VNOPS/afs_vnop_create.c index d31d91959..73705c288 100644 --- a/src/afs/VNOPS/afs_vnop_create.c +++ b/src/afs/VNOPS/afs_vnop_create.c @@ -17,7 +17,7 @@ #include "afs/param.h" RCSID - ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_create.c,v 1.16.2.1 2004/08/25 07:09:35 shadow Exp $"); + ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_create.c,v 1.16.2.2 2004/10/18 17:43:51 shadow Exp $"); #include "afs/sysincludes.h" /* Standard vendor system headers */ #include "afsincludes.h" /* Afs-based standard headers */ @@ -154,7 +154,7 @@ afs_create(OSI_VC_DECL(adp), char *aname, struct vattr *attrs, if (tdc) { /* see if file already exists. If it does, we only set * the size attributes (to handle O_TRUNC) */ - code = afs_dir_Lookup(&tdc->f.inode, aname, &newFid.Fid); /* use dnlc first xxx */ + code = afs_dir_Lookup(&tdc->f, aname, &newFid.Fid); /* use dnlc first xxx */ if (code == 0) { ReleaseSharedLock(&tdc->lock); afs_PutDCache(tdc); @@ -368,10 +368,10 @@ afs_create(OSI_VC_DECL(adp), char *aname, struct vattr *attrs, UpgradeSToWLock(&tdc->lock, 631); if (afs_LocalHero(adp, tdc, &OutDirStatus, 1)) { /* we can do it locally */ - code = afs_dir_Create(&tdc->f.inode, aname, &newFid.Fid); + code = afs_dir_Create(&tdc->f, aname, &newFid.Fid); if (code) { ZapDCE(tdc); - DZap(&tdc->f.inode); + DZap(&tdc->f); } } if (tdc) { @@ -531,7 +531,7 @@ afs_LocalHero(register struct vcache *avc, register struct dcache *adc, } else { if (adc) { ZapDCE(adc); - DZap(&adc->f.inode); + DZap(&adc->f); } if (avc->states & CStatd) { osi_dnlc_purgedp(avc); diff --git a/src/afs/VNOPS/afs_vnop_dirops.c b/src/afs/VNOPS/afs_vnop_dirops.c index 067e96be6..d7e2028e6 100644 --- a/src/afs/VNOPS/afs_vnop_dirops.c +++ b/src/afs/VNOPS/afs_vnop_dirops.c @@ -21,7 +21,7 @@ #include "afs/param.h" RCSID - ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_dirops.c,v 1.14.2.1 2004/08/25 07:09:35 shadow Exp $"); + ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_dirops.c,v 1.14.2.2 2004/10/18 17:43:51 shadow Exp $"); #include "afs/sysincludes.h" /* Standard vendor system headers */ #include "afsincludes.h" /* Afs-based standard headers */ @@ -147,10 +147,10 @@ afs_mkdir(OSI_VC_ARG(adp), aname, attrs, avcp, acred) ObtainWriteLock(&tdc->lock, 632); if (afs_LocalHero(adp, tdc, &OutDirStatus, 1)) { /* we can do it locally */ - code = afs_dir_Create(&tdc->f.inode, aname, &newFid.Fid); + code = afs_dir_Create(&tdc->f, aname, &newFid.Fid); if (code) { ZapDCE(tdc); /* surprise error -- use invalid value */ - DZap(&tdc->f.inode); + DZap(&tdc->f); } } if (tdc) { @@ -250,7 +250,7 @@ afs_rmdir(adp, aname, acred) struct VenusFid unlinkFid; unlinkFid.Fid.Vnode = 0; - code = afs_dir_Lookup(&tdc->f.inode, aname, &unlinkFid.Fid); + code = afs_dir_Lookup(&tdc->f, aname, &unlinkFid.Fid); if (code == 0) { afs_int32 cached = 0; @@ -304,10 +304,10 @@ afs_rmdir(adp, aname, acred) UpgradeSToWLock(&tdc->lock, 634); if (afs_LocalHero(adp, tdc, &OutDirStatus, 1)) { /* we can do it locally */ - code = afs_dir_Delete(&tdc->f.inode, aname); + code = afs_dir_Delete(&tdc->f, aname); if (code) { ZapDCE(tdc); /* surprise error -- invalid value */ - DZap(&tdc->f.inode); + DZap(&tdc->f); } } if (tdc) { diff --git a/src/afs/VNOPS/afs_vnop_link.c b/src/afs/VNOPS/afs_vnop_link.c index d5c085df3..a8621422f 100644 --- a/src/afs/VNOPS/afs_vnop_link.c +++ b/src/afs/VNOPS/afs_vnop_link.c @@ -17,7 +17,7 @@ #include "afs/param.h" RCSID - ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_link.c,v 1.15.2.1 2004/08/25 07:09:35 shadow Exp $"); + ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_link.c,v 1.15.2.2 2004/10/18 17:43:51 shadow Exp $"); #include "afs/sysincludes.h" /* Standard vendor system headers */ #include "afsincludes.h" /* Afs-based standard headers */ @@ -137,10 +137,10 @@ afs_link(avc, OSI_VC_ARG(adp), aname, acred) ObtainWriteLock(&tdc->lock, 635); if (afs_LocalHero(adp, tdc, &OutDirStatus, 1)) { /* we can do it locally */ - code = afs_dir_Create(&tdc->f.inode, aname, &avc->fid.Fid); + code = afs_dir_Create(&tdc->f, aname, &avc->fid.Fid); if (code) { ZapDCE(tdc); /* surprise error -- invalid value */ - DZap(&tdc->f.inode); + DZap(&tdc->f); } } if (tdc) { diff --git a/src/afs/VNOPS/afs_vnop_lookup.c b/src/afs/VNOPS/afs_vnop_lookup.c index 077608dcc..874395788 100644 --- a/src/afs/VNOPS/afs_vnop_lookup.c +++ b/src/afs/VNOPS/afs_vnop_lookup.c @@ -18,7 +18,7 @@ #include "afs/param.h" RCSID - ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_lookup.c,v 1.50.2.1 2004/08/25 07:09:35 shadow Exp $"); + ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_lookup.c,v 1.50.2.3 2004/10/18 17:43:51 shadow Exp $"); #include "afs/sysincludes.h" /* Standard vendor system headers */ #include "afsincludes.h" /* Afs-based standard headers */ @@ -674,7 +674,7 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp) /* look for first safe entry to examine in the directory. BlobScan * looks for a the 1st allocated dir after the dirCookie slot. */ - newIndex = BlobScan(&dcp->f.inode, (dirCookie >> 5)); + newIndex = BlobScan(&dcp->f, (dirCookie >> 5)); if (newIndex == 0) break; @@ -683,7 +683,7 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp) /* get a ptr to the dir entry */ dirEntryp = - (struct DirEntry *)afs_dir_GetBlob(&dcp->f.inode, newIndex); + (struct DirEntry *)afs_dir_GetBlob(&dcp->f, newIndex); if (!dirEntryp) break; @@ -1128,13 +1128,13 @@ afs_lookup(adp, aname, avcp, acred) int pass = 0, hit = 0; long dirCookie; extern afs_int32 afs_mariner; /*Writing activity to log? */ - OSI_VC_CONVERT(adp); afs_hyper_t versionNo; int no_read_access = 0; struct sysname_info sysState; /* used only for @sys checking */ int dynrootRetry = 1; struct afs_fakestat_state fakestate; int tryEvalOnly = 0; + OSI_VC_CONVERT(adp); AFS_STATCNT(afs_lookup); afs_InitFakeStat(&fakestate); @@ -1293,7 +1293,7 @@ afs_lookup(adp, aname, avcp, acred) { /* sub-block just to reduce stack usage */ register struct dcache *tdc; afs_size_t dirOffset, dirLen; - ino_t theDir; + struct fcache *theDir; struct VenusFid tfid; /* now we have to lookup the next fid */ @@ -1351,15 +1351,15 @@ afs_lookup(adp, aname, avcp, acred) /* lookup the name in the appropriate dir, and return a cache entry * on the resulting fid */ - theDir = tdc->f.inode; + theDir = &tdc->f; code = - afs_dir_LookupOffset(&theDir, sysState.name, &tfid.Fid, + afs_dir_LookupOffset(theDir, sysState.name, &tfid.Fid, &dirCookie); /* If the first lookup doesn't succeed, maybe it's got @sys in the name */ while (code == ENOENT && Next_AtSys(adp, &treq, &sysState)) code = - afs_dir_LookupOffset(&theDir, sysState.name, &tfid.Fid, + afs_dir_LookupOffset(theDir, sysState.name, &tfid.Fid, &dirCookie); tname = sysState.name; diff --git a/src/afs/VNOPS/afs_vnop_readdir.c b/src/afs/VNOPS/afs_vnop_readdir.c index a1f351a42..0eb41e088 100644 --- a/src/afs/VNOPS/afs_vnop_readdir.c +++ b/src/afs/VNOPS/afs_vnop_readdir.c @@ -23,7 +23,7 @@ #include "afs/param.h" RCSID - ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_readdir.c,v 1.24.2.1 2004/08/25 07:09:35 shadow Exp $"); + ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_readdir.c,v 1.24.2.2 2004/10/18 17:43:53 shadow Exp $"); #include "afs/sysincludes.h" /* Standard vendor system headers */ #include "afsincludes.h" /* Afs-based standard headers */ @@ -66,24 +66,8 @@ extern struct DirEntry *afs_dir_GetBlob(); BlobScan is used by the Linux port in a separate file, so it should not become static. */ -#if defined(AFS_SGI62_ENV) || defined(AFS_SUN57_64BIT_ENV) int -BlobScan(ino64_t * afile, afs_int32 ablob) -#else -#if defined(AFS_HPUX1123_ENV) -/*DEE should use afs_inode_t for all */ -int -BlobScan(ino_t * afile, afs_int32 ablob) -#else -#ifdef AFS_LINUX_64BIT_KERNEL -int -BlobScan(long *afile, afs_int32 ablob) -#else -int -BlobScan(afs_int32 * afile, afs_int32 ablob) -#endif -#endif -#endif +BlobScan(struct fcache * afile, afs_int32 ablob) { register afs_int32 relativeBlob; afs_int32 pageBlob; @@ -657,8 +641,8 @@ afs_readdir(OSI_VC_ARG(avc), auio, acred) origOffset = auio->afsio_offset; /* scan for the next interesting entry scan for in-use blob otherwise up point at * this blob note that ode, if non-zero, also represents a held dir page */ - if (!(us = BlobScan(&tdc->f.inode, (origOffset >> 5))) - || !(nde = (struct DirEntry *)afs_dir_GetBlob(&tdc->f.inode, us))) { + if (!(us = BlobScan(&tdc->f, (origOffset >> 5))) + || !(nde = (struct DirEntry *)afs_dir_GetBlob(&tdc->f, us))) { /* failed to setup nde, return what we've got, and release ode */ if (len) { /* something to hand over. */ @@ -948,8 +932,8 @@ afs1_readdir(avc, auio, acred) /* scan for the next interesting entry scan for in-use blob otherwise up point at * this blob note that ode, if non-zero, also represents a held dir page */ - if (!(us = BlobScan(&tdc->f.inode, (origOffset >> 5))) - || !(nde = (struct DirEntry *)afs_dir_GetBlob(&tdc->f.inode, us))) { + if (!(us = BlobScan(&tdc->f, (origOffset >> 5))) + || !(nde = (struct DirEntry *)afs_dir_GetBlob(&tdc->f, us))) { /* failed to setup nde, return what we've got, and release ode */ if (len) { /* something to hand over. */ diff --git a/src/afs/VNOPS/afs_vnop_remove.c b/src/afs/VNOPS/afs_vnop_remove.c index 9c3c107c1..70521a5ae 100644 --- a/src/afs/VNOPS/afs_vnop_remove.c +++ b/src/afs/VNOPS/afs_vnop_remove.c @@ -23,7 +23,7 @@ #include "afs/param.h" RCSID - ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_remove.c,v 1.31.2.1 2004/08/25 07:09:35 shadow Exp $"); + ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_remove.c,v 1.31.2.2 2004/10/18 17:43:53 shadow Exp $"); #include "afs/sysincludes.h" /* Standard vendor system headers */ #include "afsincludes.h" /* Afs-based standard headers */ @@ -154,10 +154,10 @@ afsremove(register struct vcache *adp, register struct dcache *tdc, UpgradeSToWLock(&tdc->lock, 637); if (afs_LocalHero(adp, tdc, &OutDirStatus, 1)) { /* we can do it locally */ - code = afs_dir_Delete(&tdc->f.inode, aname); + code = afs_dir_Delete(&tdc->f, aname); if (code) { ZapDCE(tdc); /* surprise error -- invalid value */ - DZap(&tdc->f.inode); + DZap(&tdc->f); } } if (tdc) { @@ -357,7 +357,7 @@ afs_remove(OSI_VC_ARG(adp), aname, acred) * done the work */ if (!tvc) if (tdc) { - code = afs_dir_Lookup(&tdc->f.inode, aname, &unlinkFid.Fid); + code = afs_dir_Lookup(&tdc->f, aname, &unlinkFid.Fid); if (code == 0) { afs_int32 cached = 0; diff --git a/src/afs/VNOPS/afs_vnop_rename.c b/src/afs/VNOPS/afs_vnop_rename.c index 701913856..b23fc3eeb 100644 --- a/src/afs/VNOPS/afs_vnop_rename.c +++ b/src/afs/VNOPS/afs_vnop_rename.c @@ -18,7 +18,7 @@ #include "afs/param.h" RCSID - ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_rename.c,v 1.16.2.1 2004/08/25 07:09:35 shadow Exp $"); + ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_rename.c,v 1.16.2.2 2004/10/18 17:43:53 shadow Exp $"); #include "afs/sysincludes.h" /* Standard vendor system headers */ #include "afsincludes.h" /* Afs-based standard headers */ @@ -146,7 +146,7 @@ afsrename(struct vcache *aodp, char *aname1, struct vcache *andp, } if (code == 0) - code = afs_dir_Lookup(&tdc1->f.inode, aname1, &fileFid.Fid); + code = afs_dir_Lookup(&tdc1->f, aname1, &fileFid.Fid); if (code) { if (tdc1) { ReleaseWriteLock(&tdc1->lock); @@ -205,38 +205,38 @@ afsrename(struct vcache *aodp, char *aname1, struct vcache *andp, if (!doLocally) { if (tdc1) { ZapDCE(tdc1); - DZap(&tdc1->f.inode); + DZap(&tdc1->f); } if (tdc2) { ZapDCE(tdc2); - DZap(&tdc2->f.inode); + DZap(&tdc2->f); } } } /* now really do the work */ if (doLocally) { /* first lookup the fid of the dude we're moving */ - code = afs_dir_Lookup(&tdc1->f.inode, aname1, &fileFid.Fid); + code = afs_dir_Lookup(&tdc1->f, aname1, &fileFid.Fid); if (code == 0) { /* delete the source */ - code = afs_dir_Delete(&tdc1->f.inode, aname1); + code = afs_dir_Delete(&tdc1->f, aname1); } /* first see if target is there */ if (code == 0 - && afs_dir_Lookup(&tdc2->f.inode, aname2, + && afs_dir_Lookup(&tdc2->f, aname2, &unlinkFid.Fid) == 0) { /* target already exists, and will be unlinked by server */ - code = afs_dir_Delete(&tdc2->f.inode, aname2); + code = afs_dir_Delete(&tdc2->f, aname2); } if (code == 0) { - code = afs_dir_Create(&tdc2->f.inode, aname2, &fileFid.Fid); + code = afs_dir_Create(&tdc2->f, aname2, &fileFid.Fid); } if (code != 0) { ZapDCE(tdc1); - DZap(&tdc1->f.inode); + DZap(&tdc1->f); if (!oneDir) { ZapDCE(tdc2); - DZap(&tdc2->f.inode); + DZap(&tdc2->f); } } } @@ -339,7 +339,7 @@ afsrename(struct vcache *aodp, char *aname1, struct vcache *andp, if (tdc1) { ObtainWriteLock(&tdc1->lock, 648); ZapDCE(tdc1); /* mark as unknown */ - DZap(&tdc1->f.inode); + DZap(&tdc1->f); ReleaseWriteLock(&tdc1->lock); afs_PutDCache(tdc1); /* put it back */ } diff --git a/src/afs/VNOPS/afs_vnop_symlink.c b/src/afs/VNOPS/afs_vnop_symlink.c index ae746ffd2..1710bc4e0 100644 --- a/src/afs/VNOPS/afs_vnop_symlink.c +++ b/src/afs/VNOPS/afs_vnop_symlink.c @@ -22,7 +22,7 @@ #include "afs/param.h" RCSID - ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_symlink.c,v 1.19.2.1 2004/08/25 07:09:35 shadow Exp $"); + ("$Header: /cvs/openafs/src/afs/VNOPS/afs_vnop_symlink.c,v 1.19.2.2 2004/10/18 17:43:53 shadow Exp $"); #include "afs/sysincludes.h" /* Standard vendor system headers */ #include "afsincludes.h" /* Afs-based standard headers */ @@ -184,10 +184,10 @@ int afs_symlink /* otherwise, we should see if we can make the change to the dir locally */ if (afs_LocalHero(adp, tdc, &OutDirStatus, 1)) { /* we can do it locally */ - code = afs_dir_Create(&tdc->f.inode, aname, &newFid.Fid); + code = afs_dir_Create(&tdc->f, aname, &newFid.Fid); if (code) { ZapDCE(tdc); /* surprise error -- use invalid value */ - DZap(&tdc->f.inode); + DZap(&tdc->f); } } if (tdc) { diff --git a/src/afs/afs.h b/src/afs/afs.h index 11e4843e5..334277dd4 100644 --- a/src/afs/afs.h +++ b/src/afs/afs.h @@ -43,7 +43,7 @@ extern int afs_shuttingdown; #if defined(AFS_HPUX102_ENV) #define AFS_FLOCK k_flock #else -#if defined(AFS_SUN56_ENV) || defined(AFS_LINUX24_ENV) +#if defined(AFS_SUN56_ENV) || (defined(AFS_LINUX24_ENV) && !defined(AFS_PPC64_LINUX26_ENV) && !defined(AFS_AMD64_LINUX26_ENV)) #define AFS_FLOCK flock64 #else #define AFS_FLOCK flock @@ -1195,7 +1195,7 @@ struct afs_fakestat_state { extern int afs_fakestat_enable; struct buffer { - ino_t fid[1]; /* Unique cache key + i/o addressing */ + struct fcache *fid; afs_int32 page; afs_int32 accesstime; struct buffer *hashNext; diff --git a/src/afs/afs_buffer.c b/src/afs/afs_buffer.c index 5783f25bf..fdf1e5cf3 100644 --- a/src/afs/afs_buffer.c +++ b/src/afs/afs_buffer.c @@ -11,7 +11,7 @@ #include "afs/param.h" RCSID - ("$Header: /cvs/openafs/src/afs/afs_buffer.c,v 1.16 2004/01/23 16:53:35 rees Exp $"); + ("$Header: /cvs/openafs/src/afs/afs_buffer.c,v 1.16.2.1 2004/10/18 07:11:45 shadow Exp $"); #include "afs/sysincludes.h" #include "afsincludes.h" @@ -63,7 +63,7 @@ RCSID /* page hash table size - this is pretty intertwined with pHash */ #define PHSIZE (PHPAGEMASK + PHFIDMASK + 1) /* the pHash macro */ -#define pHash(fid,page) ((((afs_int32)((fid)[0])) & PHFIDMASK) \ +#define pHash(fid,page) ((((afs_int32)((fid)->inode)) & PHFIDMASK) \ | (page & PHPAGEMASK)) #ifdef dirty @@ -88,7 +88,7 @@ static int nbuffers; static afs_int32 timecounter; /* Prototypes for static routines */ -static struct buffer *afs_newslot(afs_inode_t * afid, afs_int32 apage, +static struct buffer *afs_newslot(struct fcache * afid, afs_int32 apage, register struct buffer *lp); static int dinit_flag = 0; @@ -150,7 +150,7 @@ DInit(int abuffers) } void * -DRead(register afs_inode_t * fid, register int page) +DRead(register struct fcache * fid, register int page) { /* Read a page from the disk. */ register struct buffer *tb, *tb2; @@ -224,14 +224,13 @@ DRead(register afs_inode_t * fid, register int page) MObtainWriteLock(&tb->lock, 260); MReleaseWriteLock(&afs_bufferLock); tb->lockers++; - tfile = afs_CFileOpen(fid[0]); - if (page * AFS_BUFFER_PAGESIZE >= tfile->size) { + if (page * AFS_BUFFER_PAGESIZE >= fid->chunkBytes) { dirp_Zap(tb->fid); tb->lockers--; MReleaseWriteLock(&tb->lock); - afs_CFileClose(tfile); return NULL; } + tfile = afs_CFileOpen(fid->inode); code = afs_CFileRead(tfile, tb->page * AFS_BUFFER_PAGESIZE, tb->data, AFS_BUFFER_PAGESIZE); @@ -274,7 +273,7 @@ FixupBucket(register struct buffer *ap) /* lp is pointer to a fairly-old buffer */ static struct buffer * -afs_newslot(afs_inode_t * afid, afs_int32 apage, register struct buffer *lp) +afs_newslot(struct fcache * afid, afs_int32 apage, register struct buffer *lp) { /* Find a usable buffer slot */ register afs_int32 i; @@ -341,7 +340,7 @@ afs_newslot(afs_inode_t * afid, afs_int32 apage, register struct buffer *lp) } if (lp->dirty) { - tfile = afs_CFileOpen(lp->fid[0]); + tfile = afs_CFileOpen(lp->fid->inode); afs_CFileWrite(tfile, lp->page * AFS_BUFFER_PAGESIZE, lp->data, AFS_BUFFER_PAGESIZE); lp->dirty = 0; @@ -433,7 +432,7 @@ DVOffset(register void *ap) * method of DRead... */ void -DZap(afs_inode_t * fid) +DZap(struct fcache * fid) { register int i; /* Destroy all buffers pertaining to a particular fid. */ @@ -470,7 +469,7 @@ DFlush(void) tb->lockers++; MReleaseReadLock(&afs_bufferLock); if (tb->dirty) { - tfile = afs_CFileOpen(tb->fid[0]); + tfile = afs_CFileOpen(tb->fid->inode); afs_CFileWrite(tfile, tb->page * AFS_BUFFER_PAGESIZE, tb->data, AFS_BUFFER_PAGESIZE); tb->dirty = 0; /* Clear the dirty flag */ @@ -485,7 +484,7 @@ DFlush(void) } void * -DNew(register afs_inode_t * fid, register int page) +DNew(register struct fcache * fid, register int page) { /* Same as read, only do *not* even try to read the page, since it probably doesn't exist. */ register struct buffer *tb; diff --git a/src/afs/afs_dcache.c b/src/afs/afs_dcache.c index eb5207dfd..858bdea7e 100644 --- a/src/afs/afs_dcache.c +++ b/src/afs/afs_dcache.c @@ -14,7 +14,7 @@ #include "afs/param.h" RCSID - ("$Header: /cvs/openafs/src/afs/afs_dcache.c,v 1.42.2.1 2004/08/25 07:09:32 shadow Exp $"); + ("$Header: /cvs/openafs/src/afs/afs_dcache.c,v 1.42.2.2 2004/10/18 17:43:49 shadow Exp $"); #include "afs/sysincludes.h" /*Standard vendor system headers */ #include "afsincludes.h" /*AFS-based standard headers */ @@ -686,7 +686,7 @@ afs_HashOutDCache(struct dcache *adc) AFS_STATCNT(afs_glink); #endif /* we know this guy's in the LRUQ. We'll move dude into DCQ below */ - DZap(&adc->f.inode); + DZap(&adc->f); /* if this guy is in the hash table, pull him out */ if (adc->f.fid.Fid.Volume != 0) { /* remove entry from first hash chains */ @@ -2038,7 +2038,7 @@ afs_GetDCache(register struct vcache *avc, afs_size_t abyte, * Right now, we only have one tool, and it's a hammer. So, we * fetch the whole file. */ - DZap(&tdc->f.inode); /* pages in cache may be old */ + DZap(&tdc->f); /* pages in cache may be old */ #ifdef IHINT if (file = tdc->ihint) { if (tdc->f.inode == file->inum) @@ -2415,7 +2415,7 @@ afs_GetDCache(register struct vcache *avc, afs_size_t abyte, afs_CFileClose(file); ZapDCE(tdc); /* sets DFEntryMod */ if (vType(avc) == VDIR) { - DZap(&tdc->f.inode); + DZap(&tdc->f); } ReleaseWriteLock(&tdc->lock); afs_PutDCache(tdc); diff --git a/src/afs/afs_osi.h b/src/afs/afs_osi.h index 923c92e95..9471ba8e1 100644 --- a/src/afs/afs_osi.h +++ b/src/afs/afs_osi.h @@ -187,9 +187,9 @@ typedef struct timeval osi_timeval_t; * The following three routines provide the fid routines used by the buffer * and directory packages. */ -#define dirp_Zap(afid) (*(afid) = -1) -#define dirp_Eq(afid, bfid) (*(afid) == *(bfid)) -#define dirp_Cpy(dfid,sfid) (*(dfid) = *(sfid)) +#define dirp_Zap(afid) ((afid) = 0) +#define dirp_Eq(afid, bfid) ((afid) == (bfid)) +#define dirp_Cpy(dfid,sfid) ((dfid) = (sfid)) /* diff --git a/src/afs/afs_osi_pag.c b/src/afs/afs_osi_pag.c index 9ed4b9181..6760c824d 100644 --- a/src/afs/afs_osi_pag.c +++ b/src/afs/afs_osi_pag.c @@ -23,7 +23,7 @@ #include "afs/param.h" RCSID - ("$Header: /cvs/openafs/src/afs/afs_osi_pag.c,v 1.21 2004/07/29 03:13:37 shadow Exp $"); + ("$Header: /cvs/openafs/src/afs/afs_osi_pag.c,v 1.21.2.1 2004/10/18 07:11:45 shadow Exp $"); #include "afs/sysincludes.h" /* Standard vendor system headers */ #include "afsincludes.h" /* Afs-based standard headers */ @@ -139,6 +139,43 @@ getpag(void) * activates tokens repeatedly) for that entire period. */ +static int afs_pag_sleepcnt = 0; + +static int +afs_pag_sleep(struct AFS_UCRED **acred) +{ + int rv = 0; + if(!afs_suser(acred)) { + if(osi_Time() - pag_epoch < pagCounter) { + rv = 1; + } + } + + return rv; +} + +static int +afs_pag_wait(struct AFS_UCRED **acred) +{ + if(afs_pag_sleep(acred)) { + if(!afs_pag_sleepcnt) { + printf("%s() PAG throttling triggered, pid %d... sleeping. sleepcnt %d\n", + __func__, getpid(), afs_pag_sleepcnt); + } + + afs_pag_sleepcnt++; + + do { + /* XXX spins on EINTR */ + afs_osi_Wait(1000, (struct afs_osi_WaitHandle *)0, 0); + } while(afs_pag_sleep(acred)); + + afs_pag_sleepcnt--; + } + + return 0; +} + int #if defined(AFS_SUN5_ENV) afs_setpag(struct AFS_UCRED **credpp) @@ -148,6 +185,15 @@ afs_setpag(struct proc *p, void *args, int *retval) afs_setpag(void) #endif { + +#if defined(AFS_SUN5_ENV) + struct AFS_UCRED **acred = *credpp; +#elif defined(AFS_OBSD_ENV) + struct AFS_UCRED **acred = p->p_ucred; +#else + struct AFS_UCRED **acred = NULL; +#endif + int code = 0; #if defined(AFS_SGI53_ENV) && defined(MP) @@ -156,18 +202,10 @@ afs_setpag(void) #endif /* defined(AFS_SGI53_ENV) && defined(MP) */ AFS_STATCNT(afs_setpag); -#if defined(AFS_SUN5_ENV) - if (!afs_suser(*credpp)) -#elif defined(AFS_OBSD_ENV) - if (!afs_osi_suser(p->p_ucred)) -#else - if (!afs_suser(NULL)) -#endif - { - while (osi_Time() - pag_epoch < pagCounter) { - afs_osi_Wait(1000, (struct afs_osi_WaitHandle *)0, 0); - } - } + + afs_pag_wait(acred); + + #if defined(AFS_SUN5_ENV) code = AddPag(genpag(), credpp); #elif defined(AFS_OSF_ENV) || defined(AFS_XBSD_ENV) @@ -213,13 +251,16 @@ afs_setpag(void) #endif afs_Trace1(afs_iclSetp, CM_TRACE_SETPAG, ICL_TYPE_INT32, code); + #if defined(KERNEL_HAVE_UERROR) if (!getuerror()) setuerror(code); #endif + #if defined(AFS_SGI53_ENV) && defined(MP) AFS_GUNLOCK(); #endif /* defined(AFS_SGI53_ENV) && defined(MP) */ + return (code); } @@ -240,6 +281,15 @@ afs_setpag_val(struct proc *p, void *args, int *retval, int pagval) afs_setpag_val(int pagval) #endif { + +#if defined(AFS_SUN5_ENV) + struct AFS_UCRED **acred = *credp; +#elif defined(AFS_OBSD_ENV) + struct AFS_UCRED **acred = p->p_ucred; +#else + struct AFS_UCRED **acred = NULL; +#endif + int code = 0; #if defined(AFS_SGI53_ENV) && defined(MP) @@ -248,16 +298,9 @@ afs_setpag_val(int pagval) #endif /* defined(AFS_SGI53_ENV) && defined(MP) */ AFS_STATCNT(afs_setpag); -#ifdef AFS_SUN5_ENV - if (!afs_suser(*credpp)) -#else - if (!afs_suser(NULL)) -#endif - { - while (osi_Time() - pag_epoch < pagCounter) { - afs_osi_Wait(1000, (struct afs_osi_WaitHandle *)0, 0); - } - } + + afs_pag_wait(acred); + #if defined(AFS_SUN5_ENV) code = AddPag(pagval, credpp); #elif defined(AFS_OSF_ENV) || defined(AFS_XBSD_ENV) diff --git a/src/afs/afs_pioctl.c b/src/afs/afs_pioctl.c index d202c953e..ab8fb38ca 100644 --- a/src/afs/afs_pioctl.c +++ b/src/afs/afs_pioctl.c @@ -11,7 +11,7 @@ #include "afs/param.h" RCSID - ("$Header: /cvs/openafs/src/afs/afs_pioctl.c,v 1.81.2.1 2004/08/25 07:03:35 shadow Exp $"); + ("$Header: /cvs/openafs/src/afs/afs_pioctl.c,v 1.81.2.2 2004/10/18 17:43:49 shadow Exp $"); #include "afs/sysincludes.h" /* Standard vendor system headers */ #ifdef AFS_OBSD_ENV @@ -268,7 +268,11 @@ copyin_afs_ioctl(caddr_t cmarg, struct afs_ioctl *dst) #elif defined(AFS_AMD64_LINUX20_ENV) if (current->thread.flags & THREAD_IA32) #elif defined(AFS_PPC64_LINUX20_ENV) - if (current->thread.flags & PPC_FLAG_32BIT) +#ifdef AFS_PPC64_LINUX26_ENV + if (current->thread_info->flags & _TIF_32BIT) +#else /*Linux 2.6*/ + if (current->thread.flags & PPC_FLAG_32BIT) +#endif #elif defined(AFS_S390X_LINUX20_ENV) if (current->thread.flags & S390_FLAG_31BIT) #else @@ -488,7 +492,7 @@ struct afs_ioctl_sys { unsigned int com; unsigned long arg; }; -asmlinkage int +int afs_xioctl(struct inode *ip, struct file *fp, unsigned int com, unsigned long arg) { @@ -1713,7 +1717,7 @@ DECL_PIOCTL(PNewStatMount) Check_AtSys(avc, ain, &sysState, areq); ObtainReadLock(&tdc->lock); do { - code = afs_dir_Lookup(&tdc->f.inode, sysState.name, &tfid.Fid); + code = afs_dir_Lookup(&tdc->f, sysState.name, &tfid.Fid); } while (code == ENOENT && Next_AtSys(avc, areq, &sysState)); ReleaseReadLock(&tdc->lock); afs_PutDCache(tdc); /* we're done with the data */ @@ -2393,7 +2397,7 @@ DECL_PIOCTL(PRemoveMount) Check_AtSys(avc, ain, &sysState, areq); ObtainReadLock(&tdc->lock); do { - code = afs_dir_Lookup(&tdc->f.inode, sysState.name, &tfid.Fid); + code = afs_dir_Lookup(&tdc->f, sysState.name, &tfid.Fid); } while (code == ENOENT && Next_AtSys(avc, areq, &sysState)); ReleaseReadLock(&tdc->lock); bufp = sysState.name; @@ -2464,10 +2468,10 @@ DECL_PIOCTL(PRemoveMount) ObtainWriteLock(&tdc->lock, 661); if (afs_LocalHero(avc, tdc, &OutDirStatus, 1)) { /* we can do it locally */ - code = afs_dir_Delete(&tdc->f.inode, bufp); + code = afs_dir_Delete(&tdc->f, bufp); if (code) { ZapDCE(tdc); /* surprise error -- invalid value */ - DZap(&tdc->f.inode); + DZap(&tdc->f); } } ReleaseWriteLock(&tdc->lock); @@ -3499,7 +3503,7 @@ DECL_PIOCTL(PFlushMount) Check_AtSys(avc, ain, &sysState, areq); ObtainReadLock(&tdc->lock); do { - code = afs_dir_Lookup(&tdc->f.inode, sysState.name, &tfid.Fid); + code = afs_dir_Lookup(&tdc->f, sysState.name, &tfid.Fid); } while (code == ENOENT && Next_AtSys(avc, areq, &sysState)); ReleaseReadLock(&tdc->lock); afs_PutDCache(tdc); /* we're done with the data */ diff --git a/src/afs/afs_prototypes.h b/src/afs/afs_prototypes.h index c08265e4c..a185eaf4e 100644 --- a/src/afs/afs_prototypes.h +++ b/src/afs/afs_prototypes.h @@ -31,12 +31,12 @@ extern void afs_FreeAllAxs(struct axscache **headp); /* afs_buffer.c */ extern void DInit(int abuffers); -extern void *DRead(register afs_inode_t * fid, register int page); +extern void *DRead(register struct fcache * fid, register int page); extern void DRelease(register struct buffer *bp, int flag); extern int DVOffset(register void *ap); -extern void DZap(afs_inode_t * fid); +extern void DZap(struct fcache * fid); extern void DFlush(void); -extern void *DNew(register afs_inode_t * fid, register int page); +extern void *DNew(register struct fcache * fid, register int page); extern void shutdown_bufferpackage(void); /* afs_call.c */ diff --git a/src/afs/afs_segments.c b/src/afs/afs_segments.c index efbd1f8fd..b759abbc0 100644 --- a/src/afs/afs_segments.c +++ b/src/afs/afs_segments.c @@ -14,7 +14,7 @@ #include "afs/param.h" RCSID - ("$Header: /cvs/openafs/src/afs/afs_segments.c,v 1.16.2.1 2004/08/25 07:09:32 shadow Exp $"); + ("$Header: /cvs/openafs/src/afs/afs_segments.c,v 1.16.2.2 2004/10/18 17:43:50 shadow Exp $"); #include "afs/sysincludes.h" /*Standard vendor system headers */ #include "afsincludes.h" /*AFS-based standard headers */ @@ -898,7 +898,7 @@ afs_InvalidateAllSegments(struct vcache *avc) ObtainWriteLock(&tdc->lock, 679); ZapDCE(tdc); if (vType(avc) == VDIR) - DZap(&tdc->f.inode); + DZap(&tdc->f); ReleaseWriteLock(&tdc->lock); afs_PutDCache(tdc); } @@ -1041,6 +1041,12 @@ afs_TruncateAllSegments(register struct vcache *avc, afs_size_t alen, afs_CFileTruncate(tfile, newSize); afs_CFileClose(tfile); afs_AdjustSize(tdc, newSize); + if (alen < tdc->validPos) { + if (alen < AFS_CHUNKTOBASE(tdc->f.chunk)) + tdc->validPos = 0; + else + tdc->validPos = alen; + } ConvertWToSLock(&tdc->lock); } ReleaseSharedLock(&tdc->lock); diff --git a/src/afs/afs_stats.h b/src/afs/afs_stats.h index 35f6575a1..2fa76aa2a 100644 --- a/src/afs/afs_stats.h +++ b/src/afs/afs_stats.h @@ -46,7 +46,7 @@ typedef struct timeval osi_timeval_t; #endif /* !KERNEL */ #define XSTATS_DECLS struct afs_stats_opTimingData *opP; \ - osi_timeval_t opStartTime, opStopTime, elapsedTime; + osi_timeval_t opStartTime, opStopTime, elapsedTime #define XSTATS_START_TIME(arg) \ opP = &(afs_stats_cmfullperf.rpc.fsRPCTimes[arg]); \ diff --git a/src/afs/afs_vcache.c b/src/afs/afs_vcache.c index 6f7b0b60a..9208fbd4e 100644 --- a/src/afs/afs_vcache.c +++ b/src/afs/afs_vcache.c @@ -39,7 +39,7 @@ #include "afs/param.h" RCSID - ("$Header: /cvs/openafs/src/afs/afs_vcache.c,v 1.65.2.3 2004/08/25 07:16:11 shadow Exp $"); + ("$Header: /cvs/openafs/src/afs/afs_vcache.c,v 1.65.2.4 2004/10/18 17:43:50 shadow Exp $"); #include "afs/sysincludes.h" /*Standard vendor system headers */ #include "afsincludes.h" /*AFS-based standard headers */ @@ -840,9 +840,18 @@ afs_NewVCache(struct VenusFid *afid, struct server *serverp) #elif defined(AFS_LINUX22_ENV) if (tvc != afs_globalVp && VREFCOUNT(tvc) && tvc->opens == 0) { #if defined(AFS_LINUX26_ENV) - AFS_GUNLOCK(); - d_prune_aliases(AFSTOI(tvc)); - AFS_GLOCK(); + struct dentry *dentry; + struct list_head *cur, *head = &(AFSTOI(tvc))->i_dentry; + AFS_GUNLOCK(); + cur=head; + while ((cur = cur->next) != head) { + dentry = list_entry(cur, struct dentry, d_alias); + if (!d_unhashed(dentry) && + !list_empty(&dentry->d_subdirs)) + shrink_dcache_parent(dentry); + } + d_prune_aliases(AFSTOI(tvc)); + AFS_GLOCK(); #else afs_TryFlushDcacheChildren(tvc); #endif diff --git a/src/auth/Makefile.in b/src/auth/Makefile.in index f768f1b77..33797066b 100644 --- a/src/auth/Makefile.in +++ b/src/auth/Makefile.in @@ -36,7 +36,7 @@ copyauth.o: copyauth.c ${INCLS} AFS_component_version_number.o setkey.o: setkey.c ${INCLS} AFS_component_version_number.o ktc.krb.o: ktc.c ${INCLS} ${TOP_INCDIR}/afs/vice.h - ${CC} ${CFLAGS} -DAFS_KERBEROS_ENV -c ${srcdir}/ktc.c -o ktc.krb.o + ${CCOBJ} ${CFLAGS} -DAFS_KERBEROS_ENV -c ${srcdir}/ktc.c -o ktc.krb.o libauth.a: $(OBJS) AFS_component_version_number.o -$(RM) -f libauth.a diff --git a/src/bozo/bos.c b/src/bozo/bos.c index 3184b4f8e..8403baa8a 100644 --- a/src/bozo/bos.c +++ b/src/bozo/bos.c @@ -11,7 +11,7 @@ #include RCSID - ("$Header: /cvs/openafs/src/bozo/bos.c,v 1.20.2.1 2004/08/25 07:03:36 shadow Exp $"); + ("$Header: /cvs/openafs/src/bozo/bos.c,v 1.20.2.2 2004/10/18 17:43:53 shadow Exp $"); #include #include @@ -239,7 +239,7 @@ GetConn(as, aencrypt) code = ktc_GetToken(&sname, &ttoken, sizeof(ttoken), NULL); if (code == 0) { /* have tickets, will travel */ - if (ttoken.kvno >= 0 && ttoken.kvno <= 255); + if (ttoken.kvno >= 0 && ttoken.kvno <= 256); else { fprintf(stderr, "bos: funny kvno (%d) in ticket, proceeding\n", diff --git a/src/bucoord/commands.c b/src/bucoord/commands.c index 43567b864..1290aa18c 100644 --- a/src/bucoord/commands.c +++ b/src/bucoord/commands.c @@ -11,7 +11,7 @@ #include RCSID - ("$Header: /cvs/openafs/src/bucoord/commands.c,v 1.14 2003/12/08 01:45:28 jaltman Exp $"); + ("$Header: /cvs/openafs/src/bucoord/commands.c,v 1.14.2.1 2004/10/18 07:11:50 shadow Exp $"); #include #include @@ -626,7 +626,8 @@ compactDateString(date_long, string, size) if (*date_long == NEVERDATE) { sprintf(string, "NEVER"); } else { - ltime = localtime(date_long); + time_t t = *date_long; + ltime = localtime(&t); /* prints date in U.S. format of mm/dd/yyyy */ strftime(string, size, "%m/%d/%Y %H:%M", ltime); } @@ -2902,13 +2903,14 @@ dumpInfo(dumpid, detailFlag) printf("----\n"); printDumpEntry(&dumpEntry); } else { + time_t t = dumpEntry.created; if (dbDump) printf("Dump: id %u, created: %s\n", dumpEntry.id, - ctime(&dumpEntry.created)); - else + ctime(&t)); + else printf("Dump: id %u, level %d, volumes %d, created: %s\n", dumpEntry.id, dumpEntry.level, dumpEntry.nVolumes, - ctime(&dumpEntry.created)); + ctime(&t)); } if (!detailFlag && (strlen(dumpEntry.tapes.tapeServer) > 0) diff --git a/src/bucoord/dump_sched.c b/src/bucoord/dump_sched.c index e9467503e..45a5c8e68 100644 --- a/src/bucoord/dump_sched.c +++ b/src/bucoord/dump_sched.c @@ -17,7 +17,7 @@ #include RCSID - ("$Header: /cvs/openafs/src/bucoord/dump_sched.c,v 1.7 2003/11/23 04:53:30 jaltman Exp $"); + ("$Header: /cvs/openafs/src/bucoord/dump_sched.c,v 1.7.2.1 2004/10/18 07:11:50 shadow Exp $"); #ifdef AFS_NT40_ENV #include @@ -581,7 +581,8 @@ ListDumpSchedule(adump, alevel) case BC_ABS_EXPDATE: /* absolute expiration date. Never expires if date is 0 */ if (adump->expDate) { - printf("expires at %.24s", cTIME(&adump->expDate)); + time_t t = adump->expDate; + printf("expires at %.24s", cTIME(&t)); } break; diff --git a/src/bucoord/restore.c b/src/bucoord/restore.c index 73f3a6310..b557e9149 100644 --- a/src/bucoord/restore.c +++ b/src/bucoord/restore.c @@ -15,7 +15,7 @@ #include RCSID - ("$Header: /cvs/openafs/src/bucoord/restore.c,v 1.8 2003/12/07 22:49:19 jaltman Exp $"); + ("$Header: /cvs/openafs/src/bucoord/restore.c,v 1.8.2.1 2004/10/18 07:11:50 shadow Exp $"); #include #include @@ -195,7 +195,7 @@ bc_Restorer(aindex) afs_int32 partitionAll; /* Likewise for partition */ struct hostent *hostPtr; long haddr; - u_long did; + time_t did; int foundtape, c; extern statusP createStatusNode(); diff --git a/src/butc/lwps.c b/src/butc/lwps.c index 49c7dad3f..faa8f23cd 100644 --- a/src/butc/lwps.c +++ b/src/butc/lwps.c @@ -11,7 +11,7 @@ #include RCSID - ("$Header: /cvs/openafs/src/butc/lwps.c,v 1.12 2003/12/08 01:45:29 jaltman Exp $"); + ("$Header: /cvs/openafs/src/butc/lwps.c,v 1.12.2.1 2004/10/18 07:11:51 shadow Exp $"); #include #ifdef AFS_NT40_ENV @@ -2287,6 +2287,7 @@ PrintTapeLabel(labelptr) struct butm_tapeLabel *labelptr; { char tapeName[BU_MAXTAPELEN + 32]; + time_t t; printf("Tape label\n"); printf("----------\n"); @@ -2294,9 +2295,12 @@ PrintTapeLabel(labelptr) printf("permanent tape name = %s\n", tapeName); TAPENAME(tapeName, labelptr->AFSName, labelptr->dumpid); printf("AFS tape name = %s\n", tapeName); - printf("creationTime = %s", ctime(&labelptr->creationTime)); - if (labelptr->expirationDate) - printf("expirationDate = %s", cTIME(&labelptr->expirationDate)); + t = labelptr->creationTime; + printf("creationTime = %s", ctime(&t)); + if (labelptr->expirationDate) { + t = labelptr->expirationDate; + printf("expirationDate = %s", cTIME(&t)); + } printf("cell = %s\n", labelptr->cell); printf("size = %u Kbytes\n", labelptr->size); printf("dump path = %s\n", labelptr->dumpPath); diff --git a/src/butc/recoverDb.c b/src/butc/recoverDb.c index 3aa2be5f6..31803983c 100644 --- a/src/butc/recoverDb.c +++ b/src/butc/recoverDb.c @@ -11,7 +11,7 @@ #include RCSID - ("$Header: /cvs/openafs/src/butc/recoverDb.c,v 1.10 2003/12/07 22:49:23 jaltman Exp $"); + ("$Header: /cvs/openafs/src/butc/recoverDb.c,v 1.10.2.1 2004/10/18 07:11:51 shadow Exp $"); #include #ifdef AFS_NT40_ENV @@ -59,6 +59,7 @@ PrintDumpLabel(labelptr) struct butm_tapeLabel *labelptr; { char tapeName[BU_MAXTAPELEN + 32]; + time_t t; printf("Dump label\n"); printf("----------\n"); @@ -66,9 +67,12 @@ PrintDumpLabel(labelptr) printf("permanent tape name = %s\n", tapeName); TAPENAME(tapeName, labelptr->AFSName, labelptr->dumpid); printf("AFS tape name = %s\n", tapeName); - printf("creationTime = %s", ctime(&labelptr->creationTime)); - if (labelptr->expirationDate) - printf("expirationDate = %s", cTIME(&labelptr->expirationDate)); + t = labelptr->creationTime; + printf("creationTime = %s", ctime(&t)); + if (labelptr->expirationDate) { + t = labelptr->expirationDate; + printf("expirationDate = %s", cTIME(&t)); + } printf("cell = %s\n", labelptr->cell); printf("size = %u Kbytes\n", labelptr->size); printf("dump path = %s\n", labelptr->dumpPath); @@ -87,6 +91,8 @@ static PrintVolumeHeader(volHeader) struct volumeHeader *volHeader; { + time_t t; + printf("-- volume --\n"); printf("volume name: %s\n", volHeader->volumeName); printf("volume ID %d\n", volHeader->volumeID); @@ -97,7 +103,8 @@ PrintVolumeHeader(volHeader) printf("parentID %d\n", volHeader->parentID); printf("endTime %d\n", volHeader->endTime); /* printf("versionflags %d\n", volHeader->versionflags); */ - printf("clonedate %s\n", ctime(&volHeader->cloneDate)); + t = volHeader->cloneDate; + printf("clonedate %s\n", ctime(&t)); } /* Ask diff --git a/src/butc/tcmain.c b/src/butc/tcmain.c index 181260cdc..31e77544d 100644 --- a/src/butc/tcmain.c +++ b/src/butc/tcmain.c @@ -11,7 +11,7 @@ #include RCSID - ("$Header: /cvs/openafs/src/butc/tcmain.c,v 1.14.2.1 2004/08/25 07:12:37 shadow Exp $"); + ("$Header: /cvs/openafs/src/butc/tcmain.c,v 1.14.2.2 2004/10/18 17:43:54 shadow Exp $"); #include #include @@ -856,6 +856,7 @@ WorkerBee(as, arock) #else PROCESS dbWatcherPid; #endif + time_t t; debugLevel = 0; @@ -1131,7 +1132,8 @@ WorkerBee(as, arock) TLog(0, "Starting Tape Coordinator: Port offset %u Debug level %u\n", portOffset, debugLevel); - TLog(0, "Token expires: %s\n", cTIME(&ttoken.endTime)); + t = ttoken.endTime; + TLog(0, "Token expires: %s\n", cTIME(&t)); rx_StartServer(1); /* Donate this process to the server process pool */ TLog(0, "Error: StartServer returned"); diff --git a/src/butm/test_ftm.c b/src/butm/test_ftm.c index d7299926c..c712aaf95 100644 --- a/src/butm/test_ftm.c +++ b/src/butm/test_ftm.c @@ -11,7 +11,7 @@ #include RCSID - ("$Header: /cvs/openafs/src/butm/test_ftm.c,v 1.10 2003/11/29 21:37:57 jaltman Exp $"); + ("$Header: /cvs/openafs/src/butm/test_ftm.c,v 1.10.2.1 2004/10/18 07:11:52 shadow Exp $"); #include #include @@ -324,8 +324,8 @@ PerformDumpTest(TestInfo * tip) } past = time(0) - label.creationTime; if ((past < 0) || (past > 5 * 60)) { - printf("label creation time is long ago: %s\n", - ctime(&label.creationTime)); + time_t t = label.creationTime; + printf("label creation time is long ago: %s\n", ctime(&t)); ERROR_EXIT(5); } if (strcmp(label.AFSName, tip->tapeName) != 0) { diff --git a/src/cf/linux-test3.m4 b/src/cf/linux-test3.m4 index 1f2afc072..d72f8e79c 100644 --- a/src/cf/linux-test3.m4 +++ b/src/cf/linux-test3.m4 @@ -94,3 +94,20 @@ AC_TRY_COMPILE( ac_cv_linux_kernel_is_selinux=no)]) AC_MSG_RESULT($ac_cv_linux_kernel_is_selinux) CPPFLAGS="$save_CPPFLAGS"]) + +AC_DEFUN([LINUX_KERNEL_SOCK_CREATE],[ +AC_MSG_CHECKING(for 5th argument in sock_create found in some SELinux kernels) +save_CPPFLAGS="$CPPFLAGS" +CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -D__KERNEL__ $CPPFLAGS" +AC_CACHE_VAL(ac_cv_linux_kernel_sock_create_v, +[ +AC_TRY_COMPILE( + [#include ], + [ + sock_create(0,0,0,0,0) + ], + ac_cv_linux_kernel_sock_create_v=yes, + ac_cv_linux_kernel_sock_create_v=no)]) +AC_MSG_RESULT($ac_cv_linux_kernel_sock_create_v) +CPPFLAGS="$save_CPPFLAGS"]) + diff --git a/src/cf/osconf.m4 b/src/cf/osconf.m4 index 688b752c3..5712e488c 100644 --- a/src/cf/osconf.m4 +++ b/src/cf/osconf.m4 @@ -229,12 +229,14 @@ case $AFS_SYSNAME in SHLIB_LINKER="${MT_CC} -shared" ;; - amd64_linux24) + amd64_linux*) + CCOBJ="${CC} -fPIC" KERN_OPTMZ=-O2 LEX="flex -l" MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}' MT_LIBS="-lpthread" PAM_CFLAGS="-g -O2 -Dlinux -DLINUX_PAM -fPIC" + SHLIB_CFLAGS="-fPIC" SHLIB_LDFLAGS="-shared -Xlinker -x" TXLIBS="-lncurses" XCFLAGS="-g -O2 -D_LARGEFILE64_SOURCE" diff --git a/src/config/NTMakefile.i386_nt40 b/src/config/NTMakefile.i386_nt40 index 9bf0a4921..feae26095 100644 --- a/src/config/NTMakefile.i386_nt40 +++ b/src/config/NTMakefile.i386_nt40 @@ -80,7 +80,7 @@ LIB = $(AFSDEV_LIB) #define used in WinNT/2000 installation and program version display AFSPRODUCT_VER_MAJOR=1 AFSPRODUCT_VER_MINOR=3 -AFSPRODUCT_VER_PATCH=7100 +AFSPRODUCT_VER_PATCH=7200 AFSPRODUCT_VER_BUILD=0 # For MSI installer, each major release should have a different GUID diff --git a/src/config/afs_sysnames.h b/src/config/afs_sysnames.h index db042c3b1..ac6d74cf1 100644 --- a/src/config/afs_sysnames.h +++ b/src/config/afs_sysnames.h @@ -206,6 +206,7 @@ #define SYS_NAME_ID_amd64_linux2 2700 #define SYS_NAME_ID_amd64_linux22 2701 #define SYS_NAME_ID_amd64_linux24 2702 +#define SYS_NAME_ID_amd64_linux26 2703 #define SYS_NAME_ID_i386_umlinux2 2800 #define SYS_NAME_ID_i386_umlinux22 2801 @@ -214,6 +215,7 @@ #define SYS_NAME_ID_ppc64_linux2 2900 #define SYS_NAME_ID_ppc64_linux22 2901 #define SYS_NAME_ID_ppc64_linux24 2902 +#define SYS_NAME_ID_ppc64_linux26 2903 /* * Placeholder to keep system-wide standard flags since this file is included by all diff --git a/src/config/afsconfig.h.in b/src/config/afsconfig.h.in index f5b9c74a3..3022b035c 100644 --- a/src/config/afsconfig.h.in +++ b/src/config/afsconfig.h.in @@ -287,6 +287,9 @@ /* define if your linux kernel uses SELinux features */ #undef LINUX_KERNEL_IS_SELINUX +/* define if your linux kernel uses 5 arguments for sock_create */ +#undef LINUX_KERNEL_SOCK_CREATE_V + /* define if your linux kernel has linux/syscall.h */ #undef HAVE_KERNEL_LINUX_SYSCALL_H diff --git a/src/config/param.amd64_linux26.h b/src/config/param.amd64_linux26.h new file mode 100644 index 000000000..9a8444e41 --- /dev/null +++ b/src/config/param.amd64_linux26.h @@ -0,0 +1,147 @@ +#ifndef UKERNEL +/* This section for kernel libafs compiles only */ + +#ifndef AFS_PARAM_H +#define AFS_PARAM_H + +/* In user space the AFS_LINUX20_ENV should be sufficient. In the kernel, + * it's a judgment call. If something is obviously amd64 specific, use that + * #define instead. Note that "20" refers to the linux 2.0 kernel. The "2" + * in the sysname is the current version of the client. This takes into + * account the perferred OS user space configuration as well as the kernel. + */ + +#define AFS_LINUX20_ENV 1 +#define AFS_LINUX22_ENV 1 +#define AFS_LINUX24_ENV 1 +#define AFS_LINUX26_ENV 1 +#define AFS_AMD64_LINUX20_ENV 1 +#define AFS_AMD64_LINUX22_ENV 1 +#define AFS_AMD64_LINUX24_ENV 1 +#define AFS_AMD64_LINUX26_ENV 1 +#define AFS_NONFSTRANS 1 + +#define AFS_MOUNT_AFS "afs" /* The name of the filesystem type. */ +#define AFS_SYSCALL 183 +#define AFS_64BIT_IOPS_ENV 1 +#define AFS_NAMEI_ENV 1 /* User space interface to file system */ +#define AFS_64BIT_ENV 1 +#define AFS_64BIT_CLIENT 1 +#define AFS_64BITPOINTER_ENV 1 /* pointers are 64 bits */ + +#if defined(__KERNEL__) && !defined(KDUMP_KERNEL) +#include + +#include +#ifdef CONFIG_SMP +#ifndef AFS_SMP +#define AFS_SMP 1 +#endif +#endif +/* Using "AFS_SMP" to map to however many #define's are required to get + * MP to compile for Linux + */ +#ifdef AFS_SMP +#ifndef CONFIG_SMP +#define CONFIG_SMP 1 +#endif +#ifndef __SMP__ +#define __SMP__ +#endif +#define AFS_GLOBAL_SUNLOCK +#endif + +#endif /* __KERNEL__ && !DUMP_KERNEL */ + +#include +#define AFS_USERSPACE_IP_ADDR 1 +#define RXK_LISTENER_ENV 1 +#define AFS_GCPAGS 2 /* Set to Userdisabled, allow sysctl to override */ + +#define AFSLITTLE_ENDIAN 1 +#define AFS_HAVE_FFS 1 /* Use system's ffs. */ +#define AFS_HAVE_STATVFS 0 /* System doesn't support statvfs */ +#define AFS_VM_RDWR_ENV 1 /* read/write implemented via VM */ + +#ifdef KERNEL +#ifndef MIN +#define MIN(A,B) ((A) < (B) ? (A) : (B)) +#endif +#ifndef MAX +#define MAX(A,B) ((A) > (B) ? (A) : (B)) +#endif +#endif /* KERNEL */ + +/* Machine / Operating system information */ +#define SYS_NAME "amd64_linux26" +#define SYS_NAME_ID SYS_NAME_ID_amd64_linux26 + +#define USE_UCONTEXT + +#endif /* AFS_PARAM_H */ + + + +#else /* !defined(UKERNEL) */ + +/* This section for user space compiles only */ + +#ifndef AFS_PARAM_H +#define AFS_PARAM_H + +/* In user space the AFS_LINUX20_ENV should be sufficient. In the kernel, + * it's a judgment call. If something is obviously amd64 specific, use that + * #define instead. Note that "20" refers to the linux 2.0 kernel. The "2" + * in the sysname is the current version of the client. This takes into + * account the perferred OS user space configuration as well as the kernel. + */ + +#define UKERNEL 1 /* user space kernel */ +#define AFS_ENV 1 +#define AFS_USR_LINUX20_ENV 1 +#define AFS_USR_LINUX22_ENV 1 +#define AFS_USR_LINUX24_ENV 1 +#define AFS_USR_LINUX26_ENV 1 +#define AFS_NONFSTRANS 1 + +#define AFS_MOUNT_AFS "afs" /* The name of the filesystem type. */ +#define AFS_SYSCALL 183 +#define AFS_64BIT_IOPS_ENV 1 +#define AFS_NAMEI_ENV 1 /* User space interface to file system */ +#include + +#define AFS_USERSPACE_IP_ADDR 1 +#define RXK_LISTENER_ENV 1 +#define AFS_GCPAGS 0 /* if nonzero, garbage collect PAGs */ + + +/* Machine / Operating system information */ +#define SYS_NAME "amd64_linux26" +#define SYS_NAME_ID SYS_NAME_ID_amd64_linux26 +#define AFSLITTLE_ENDIAN 1 +#define AFS_HAVE_FFS 1 /* Use system's ffs. */ +#define AFS_HAVE_STATVFS 0 /* System doesn't support statvfs */ +#define AFS_VM_RDWR_ENV 1 /* read/write implemented via VM */ + +#define afsio_iov uio_iov +#define afsio_iovcnt uio_iovcnt +#define afsio_offset uio_offset +#define afsio_seg uio_segflg +#define afsio_fmode uio_fmode +#define afsio_resid uio_resid +#define AFS_UIOSYS 1 +#define AFS_UIOUSER UIO_USERSPACE +#define AFS_CLBYTES MCLBYTES +#define AFS_MINCHANGE 2 +#define VATTR_NULL usr_vattr_null + +#define AFS_DIRENT +#ifndef CMSERVERPREF +#define CMSERVERPREF +#endif + +#define USE_UCONTEXT + +#endif /* AFS_PARAM_H */ + +#endif /* !defined(UKERNEL) */ diff --git a/src/des/Makefile.in b/src/des/Makefile.in index 8f8d08ba9..a415f1470 100644 --- a/src/des/Makefile.in +++ b/src/des/Makefile.in @@ -88,9 +88,9 @@ make_s: make_s.o misc.o main.o crypt.o: crypt.c case ${SYS_NAME} in \ rs_aix*)\ - ${CC} -c ${COMMON_INCL} -o crypt.o crypt.c ;;\ + ${CCOBJ} -c ${COMMON_INCL} -o crypt.o crypt.c ;;\ *)\ - ${CC} -c ${CFLAGS} -o crypt.o crypt.c ;;\ + ${CCOBJ} -c ${CFLAGS} -o crypt.o crypt.c ;;\ esac # # Table/code generation targets diff --git a/src/des/cbc_encrypt.c b/src/des/cbc_encrypt.c index 50881c786..0115836c3 100644 --- a/src/des/cbc_encrypt.c +++ b/src/des/cbc_encrypt.c @@ -29,7 +29,7 @@ #include "des_prototypes.h" RCSID - ("$Header: /cvs/openafs/src/des/cbc_encrypt.c,v 1.9 2003/07/15 23:14:59 shadow Exp $"); + ("$Header: /cvs/openafs/src/des/cbc_encrypt.c,v 1.9.2.1 2004/10/18 07:11:56 shadow Exp $"); #define XPRT_CBC_ENCRYPT @@ -61,7 +61,7 @@ RCSID des_cblock *iv; * 8 bytes of ivec * */ afs_int32 -des_cbc_encrypt(des_cblock * in, des_cblock * out, register afs_int32 length, +des_cbc_encrypt(void * in, void * out, register afs_int32 length, des_key_schedule key, des_cblock * iv, int encrypt) { register afs_uint32 *input = (afs_uint32 *) in; diff --git a/src/des/des.c b/src/des/des.c index 3512e0976..cc92c82dd 100644 --- a/src/des/des.c +++ b/src/des/des.c @@ -37,7 +37,7 @@ #include RCSID - ("$Header: /cvs/openafs/src/des/des.c,v 1.11.2.1 2004/08/25 07:09:37 shadow Exp $"); + ("$Header: /cvs/openafs/src/des/des.c,v 1.11.2.2 2004/10/18 17:43:56 shadow Exp $"); #ifndef KERNEL #include @@ -72,12 +72,13 @@ pthread_mutex_t rxkad_stats_mutex; /* encrypt == 0 ==> decrypt, else encrypt */ afs_int32 -des_ecb_encrypt(afs_uint32 * clear, afs_uint32 * cipher, +des_ecb_encrypt(void * clear, void * cipher, register des_key_schedule schedule, int encrypt) { /* better pass 8 bytes, length not checked here */ - register afs_uint32 R1 = 0, L1 = 0; /* R1 = r10, L1 = r9 */ + register afs_uint32 R1 = 0; + register afs_uint32 L1 = 0; /* R1 = r10, L1 = r9 */ register afs_uint32 R2 = 0, L2 = 0; /* R2 = r8, L2 = r7 */ afs_int32 i; /* one more registers left on VAX, see below P_temp_p */ @@ -128,20 +129,22 @@ des_ecb_encrypt(afs_uint32 * clear, afs_uint32 * cipher, abort(); } #endif - if ((afs_int32) clear & 3) { - memcpy((char *)&L_save, (char *)clear++, sizeof(L_save)); - memcpy((char *)&R_save, (char *)clear, sizeof(R_save)); + if ((afs_uint32) clear & 3) { + memcpy((char *)(&L_save), (char *)clear, sizeof(L_save)); + clear=((afs_uint32*)clear)+1; + memcpy((char *)(&R_save), (char *)clear, sizeof(R_save)); L1 = L_save; R1 = R_save; } else #endif { - if (clear) - L1 = *clear++; - else + if (clear) { + L1 = *((afs_uint32 *)clear); + clear=((afs_uint32*)clear)+1; + } else L1 = 0; if (clear) - R1 = *clear; + R1 = *((afs_uint32 *)clear); else R1 = 0; } @@ -441,13 +444,15 @@ des_ecb_encrypt(afs_uint32 * clear, afs_uint32 * cipher, if ((afs_int32) cipher & 3) { L_save = L2; /* cant bcopy a reg */ R_save = R2; - memcpy((char *)cipher++, (char *)&L_save, sizeof(L_save)); + memcpy((char *)cipher, (char *)&L_save, sizeof(L_save)); + cipher=((afs_uint32*)cipher)+1; memcpy((char *)cipher, (char *)&R_save, sizeof(R_save)); } else #endif { - *cipher++ = L2; - *cipher = R2; + *((afs_uint32*)cipher)= L2; + cipher = ((afs_int32 *)cipher)+1; + *((afs_uint32 *)cipher) = R2; } #ifdef DEBUG diff --git a/src/des/des_prototypes.h b/src/des/des_prototypes.h index d7871d22a..dee7c20f1 100644 --- a/src/des/des_prototypes.h +++ b/src/des/des_prototypes.h @@ -18,19 +18,19 @@ extern void test_set(FILE * stream, const char *src, int testbit, extern int des_debug; /* cbc_encrypt.c */ -extern afs_int32 des_cbc_encrypt(des_cblock * in, des_cblock * out, +extern afs_int32 des_cbc_encrypt(void * in, void * out, register afs_int32 length, des_key_schedule key, des_cblock * iv, int encrypt); /* pcbc_encrypt.c */ -extern afs_int32 des_pcbc_encrypt(des_cblock * in, des_cblock * out, +extern afs_int32 des_pcbc_encrypt(void * in, void * out, register afs_int32 length, des_key_schedule key, des_cblock * iv, int encrypt); /* des.c */ -extern afs_int32 des_ecb_encrypt(afs_uint32 * clear, afs_uint32 * cipher, +extern afs_int32 des_ecb_encrypt(void * clear, void * cipher, register des_key_schedule schedule, int encrypt); diff --git a/src/des/pcbc_encrypt.c b/src/des/pcbc_encrypt.c index 186213432..cb28d1fd0 100644 --- a/src/des/pcbc_encrypt.c +++ b/src/des/pcbc_encrypt.c @@ -30,7 +30,7 @@ #include "des_prototypes.h" RCSID - ("$Header: /cvs/openafs/src/des/pcbc_encrypt.c,v 1.9 2003/07/15 23:15:00 shadow Exp $"); + ("$Header: /cvs/openafs/src/des/pcbc_encrypt.c,v 1.9.2.1 2004/10/18 07:11:56 shadow Exp $"); #include "des_internal.h" @@ -74,7 +74,7 @@ RCSID des_cblock *iv; * 8 bytes of ivec * */ afs_int32 -des_pcbc_encrypt(des_cblock * in, des_cblock * out, register afs_int32 length, +des_pcbc_encrypt(void * in, void * out, register afs_int32 length, des_key_schedule key, des_cblock * iv, int encrypt) { register afs_uint32 *input = (afs_uint32 *) in; diff --git a/src/kauth/Makefile.in b/src/kauth/Makefile.in index 921267042..853eaedfa 100644 --- a/src/kauth/Makefile.in +++ b/src/kauth/Makefile.in @@ -185,10 +185,10 @@ kpwvalid: kpwvalid.o $(LIBS) ${CC} ${LDFLAGS} -o kpwvalid kpwvalid.o ${LIBS} ${XLIBS} user.krb.o: user.c ${INCLS} ${TOP_INCDIR}/afs/vice.h - ${CC} ${CFLAGS} -DAFS_KERBEROS_ENV -c ${srcdir}/user.c -o user.krb.o + ${CCOBJ} ${CFLAGS} -DAFS_KERBEROS_ENV -c ${srcdir}/user.c -o user.krb.o user.o: user.c ${INCLS} ${TOP_INCDIR}/afs/vice.h - ${CC} ${CFLAGS} -c ${srcdir}/user.c + ${CCOBJ} ${CFLAGS} -c ${srcdir}/user.c kdb: kdb.o ${INCLS} ${LIBS} libkauth.a ${CC} ${LDFLAGS} -o kdb kdb.o libkauth.a ${LIBS} ${XLIBS} diff --git a/src/libafs/MakefileProto.LINUX.in b/src/libafs/MakefileProto.LINUX.in index 3527948cd..6d6673834 100644 --- a/src/libafs/MakefileProto.LINUX.in +++ b/src/libafs/MakefileProto.LINUX.in @@ -144,29 +144,29 @@ ${COMPDIRS} ${INSTDIRS} ${DESTDIRS}: $(RM) -f asm-generic ln -fs ${LINUX_KERNEL_PATH}/include/asm-generic asm-generic $(RM) -f asm - + ln -fs ${LINUX_KERNEL_PATH}/include/asm-parisc asm - + ln -fs ${LINUX_KERNEL_PATH}/include/asm-alpha asm - + ln -fs ${LINUX_KERNEL_PATH}/include/asm-i386 asm - + ln -fs ${LINUX_KERNEL_PATH}/include/asm-um asm - + ln -fs ${LINUX_KERNEL_PATH}/include/asm-x86_64 asm - + ln -fs ${LINUX_KERNEL_PATH}/include/asm-s390 asm - + ln -fs ${LINUX_KERNEL_PATH}/include/asm-s390x asm - + ln -fs ${LINUX_KERNEL_PATH}/include/asm-ppc asm - + ln -s ${LINUX_KERNEL_PATH}/include/asm-ppc64 asm - + ln -fs ${LINUX_KERNEL_PATH}/include/asm-sparc asm - + ln -fs ${LINUX_KERNEL_PATH}/include/asm-sparc64 asm - + ln -fs ${LINUX_KERNEL_PATH}/include/asm-ia64 asm for m in ${MPS} ; do \ diff --git a/src/libafsauthent/Makefile.in b/src/libafsauthent/Makefile.in index dbd6b4ac8..04e57910d 100644 --- a/src/libafsauthent/Makefile.in +++ b/src/libafsauthent/Makefile.in @@ -48,6 +48,7 @@ KAUTHOBJS = \ read_passwd.o UBIKOBJS = \ + uinit.o \ ubikclient.o \ uerrors.o \ ubik_int.cs.o \ @@ -160,6 +161,9 @@ read_passwd.o: ${KAUTH}/read_passwd.c ubikclient.o: ${UBIK}/ubikclient.c ${CCRULE} +uinit.o: ${UBIK}/uinit.c + ${CCRULE} + uerrors.o: ${UBIK}/uerrors.c ${CCRULE} diff --git a/src/libafsauthent/NTMakefile b/src/libafsauthent/NTMakefile index 0e65c5eaf..5b8669e7f 100644 --- a/src/libafsauthent/NTMakefile +++ b/src/libafsauthent/NTMakefile @@ -53,6 +53,7 @@ KAUTHOBJS = \ $(OUT)\user_nt.obj UBIKOBJS = \ + $(OUT)\uinit.obj \ $(OUT)\ubikclient.obj \ $(OUT)\uerrors.obj \ $(OUT)\ubik_int.cs.obj \ diff --git a/src/libafsrpc/Makefile.in b/src/libafsrpc/Makefile.in index 9038ef558..422a735f0 100644 --- a/src/libafsrpc/Makefile.in +++ b/src/libafsrpc/Makefile.in @@ -202,11 +202,11 @@ md4.o: ${RXKAD}/md4.c md5.o: ${RXKAD}/md5.c ${CCRULE} ${RXKAD}/md5.c -fcrypt.o: ${TOP_OBJDIR}/src/rxkad/fcrypt.c - ${CCRULE} ${TOP_OBJDIR}/src/rxkad/fcrypt.c +fcrypt.o: ${TOP_OBJDIR}/src/rxkad/domestic/fcrypt.c + ${CCRULE} ${TOP_OBJDIR}/src/rxkad/domestic/fcrypt.c -crypt_conn.o: ${TOP_OBJDIR}/src/rxkad/crypt_conn.c - ${CCRULE} ${TOP_OBJDIR}/src/rxkad/crypt_conn.c +crypt_conn.o: ${TOP_OBJDIR}/src/rxkad/domestic/crypt_conn.c + ${CCRULE} ${TOP_OBJDIR}/src/rxkad/domestic/crypt_conn.c AFS_component_version_number.o: ${TOP_OBJDIR}/src/rx/AFS_component_version_number.c ${CCRULE} ${TOP_OBJDIR}/src/rx/AFS_component_version_number.c @@ -266,7 +266,7 @@ xdr_afsuuid.o: ${RX}/xdr_afsuuid.c # # $ what /opt/langtools/bin/pxdb32 # /opt/langtools/bin/pxdb32: -# HP92453-02 A.10.0A HP-UX SYMBOLIC DEBUGGER (PXDB) $Revision: 1.29 $ +# HP92453-02 A.10.0A HP-UX SYMBOLIC DEBUGGER (PXDB) $Revision: 1.29.2.1 $ # # The problem occurs when -g and -O are both used when compiling des.c. # The simplest way to work around the problem is to leave out either -g or -O. diff --git a/src/libafsrpc/afsrpc.def b/src/libafsrpc/afsrpc.def index 37cfd4d87..943267bb1 100644 --- a/src/libafsrpc/afsrpc.def +++ b/src/libafsrpc/afsrpc.def @@ -198,4 +198,5 @@ EXPORTS rx_enable_hot_thread @203 DATA xdr_int64 @204 xdr_uint64 @205 - rx_SetMaxMTU @206 + rx_SetMaxMTU @206 + rx_GetConnection @207 diff --git a/src/libafsrpc/mapfile b/src/libafsrpc/mapfile deleted file mode 100644 index ab298407a..000000000 --- a/src/libafsrpc/mapfile +++ /dev/null @@ -1,117 +0,0 @@ -# Copyright 2000, International Business Machines Corporation and others. -# All Rights Reserved. -# -# This software has been released under the terms of the IBM Public -# License. For details, see the LICENSE file in the top-level source -# directory or online at http://www.openafs.org/dl/license10.html - -{ - global: - des_cbc_init; - des_check_key_parity; - des_cksum_init; - des_des_init; - des_fixup_key_parity; - des_init_random_number_generator; - des_is_weak_key; - des_key_sched; - des_random_key; - des_string_to_key; - ktohl; - life_to_time; - rx_DestroyConnection; - rx_EndCall; - rx_Finalize; - rx_GetCachedConnection; - rx_GetCall; - rx_GetIFInfo; - rx_GetSpecific; - rx_Init; - rx_KeyCreate; - rx_NewCall; - rx_NewConnection; - rx_NewService; - rx_PrintPeerStats; - rx_PrintStats; - rx_PrintTheseStats; - rx_ReadProc; - rx_ReleaseCachedConnection; - rx_ServerProc; - rx_SetSpecific; - rx_StartServer; - rx_WriteProc; - rxevent_Init; - rxevent_Post; - rxkad_GetServerInfo; - rxkad_NewClientSecurityObject; - rxkad_NewServerSecurityObject; - rxkad_client_init; - rxkad_crypt_init; - rxnull_NewClientSecurityObject; - rxnull_NewServerSecurityObject; - rxs_Release; - time_to_life; - tkt_CheckTimes; - tkt_DecodeTicket; - tkt_MakeTicket; - xdrrx_create; - hton_syserr_conv; - rxkad_stats; - com_err; - error_message; - rx_socket; - des_pcbc_init; - rxevent_debugFile; - rx_debugFile; - rx_connDeadTime; - rx_maxReceiveSize; - rx_UdpBufSize; - rx_extraQuota; - rx_extraPackets; - rx_tranquil; - rx_getAllAddr; - rx_nWaiting; - rx_stats; - rx_SetNoJumbo; - rx_SetConnDeadTime; - rx_FlushWrite; - rx_thread_id_key; - multi_Finalize; - multi_Select; - multi_Init; - multi_Finalize_Ignore; - add_to_error_table; - xdr_afsUUID; - rx_IncrementTimeAndCount; - rx_enable_stats; - rx_GetServerDebug; - rx_GetServerStats; - rx_GetServerVersion; - rx_GetServerConnections; - rx_stats_mutex; - rx_GetServerPeers; - rx_RetrieveProcessRPCStats; - rx_RetrievePeerRPCStats; - rx_FreeRPCStats; - rx_queryProcessRPCStats; - rx_queryPeerRPCStats; - rx_enableProcessRPCStats; - rx_enablePeerRPCStats; - rx_disableProcessRPCStats; - rx_disablePeerRPCStats; - RXSTATS_ExecuteRequest; - RXSTATS_RetrieveProcessRPCStats; - RXSTATS_RetrievePeerRPCStats; - RXSTATS_QueryProcessRPCStats; - RXSTATS_QueryPeerRPCStats; - RXSTATS_EnableProcessRPCStats; - RXSTATS_EnablePeerRPCStats; - RXSTATS_DisableProcessRPCStats; - RXSTATS_DisablePeerRPCStats; - RXSTATS_QueryRPCStatsVersion; - RXSTATS_ClearProcessRPCStats; - RXSTATS_ClearPeerRPCStats; - - local: - *; -}; diff --git a/src/ptserver/pts.c b/src/ptserver/pts.c index 2377b9199..1b2f95d80 100644 --- a/src/ptserver/pts.c +++ b/src/ptserver/pts.c @@ -23,7 +23,7 @@ #include RCSID - ("$Header: /cvs/openafs/src/ptserver/pts.c,v 1.13 2004/06/23 14:27:42 shadow Exp $"); + ("$Header: /cvs/openafs/src/ptserver/pts.c,v 1.13.2.1 2004/10/18 07:12:04 shadow Exp $"); #include #include @@ -853,7 +853,7 @@ SetFields(register struct cmd_syndesc *as) idlist ids; namelist names; int i; - afs_int32 mask, flags, ngroups, nusers; + afs_int32 mask, flags=0, ngroups, nusers; if (GetNameOrId(as, &ids, &names)) return PRBADARG; diff --git a/src/ptserver/ptuser.c b/src/ptserver/ptuser.c index 5d6ba833c..bacdbe657 100644 --- a/src/ptserver/ptuser.c +++ b/src/ptserver/ptuser.c @@ -15,7 +15,7 @@ #endif RCSID - ("$Header: /cvs/openafs/src/ptserver/ptuser.c,v 1.16 2004/06/23 14:27:42 shadow Exp $"); + ("$Header: /cvs/openafs/src/ptserver/ptuser.c,v 1.16.2.1 2004/10/18 07:12:04 shadow Exp $"); #if defined(UKERNEL) #include "afs/sysincludes.h" @@ -86,6 +86,8 @@ pr_Initialize(IN afs_int32 secLevel, IN char *confDir, IN char *cell) /* * Different conf dir; force re-evaluation. */ + if (tdir) + afsconf_Close(tdir); tdir = (struct afsconf_dir *)0; pruclient = (struct ubik_client *)0; } @@ -168,7 +170,7 @@ pr_Initialize(IN afs_int32 secLevel, IN char *confDir, IN char *cell) if (code) scIndex = 0; else { - if (ttoken.kvno >= 0 && ttoken.kvno <= 255) + if (ttoken.kvno >= 0 && ttoken.kvno <= 256) /* this is a kerberos ticket, set scIndex accordingly */ scIndex = 2; else { @@ -178,7 +180,7 @@ pr_Initialize(IN afs_int32 secLevel, IN char *confDir, IN char *cell) scIndex = 2; } sc[2] = - rxkad_NewClientSecurityObject(secLevel, &ttoken.sessionKey, + rxkad_NewClientSecurityObject(rxkad_clear, &ttoken.sessionKey, ttoken.kvno, ttoken.ticketLen, ttoken.ticket); } diff --git a/src/rx/LINUX/rx_knet.c b/src/rx/LINUX/rx_knet.c index ef4dec3b6..e614bb399 100644 --- a/src/rx/LINUX/rx_knet.c +++ b/src/rx/LINUX/rx_knet.c @@ -16,7 +16,7 @@ #include "afs/param.h" RCSID - ("$Header: /cvs/openafs/src/rx/LINUX/rx_knet.c,v 1.23.2.1 2004/08/25 07:41:00 shadow Exp $"); + ("$Header: /cvs/openafs/src/rx/LINUX/rx_knet.c,v 1.23.2.3 2004/10/18 17:43:59 shadow Exp $"); #include #ifdef AFS_LINUX22_ENV @@ -35,12 +35,14 @@ rxk_NewSocketHost(afs_uint32 ahost, short aport) struct socket *sockp; struct sockaddr_in myaddr; int code; + KERNEL_SPACE_DECL; + int pmtu = IP_PMTUDISC_DONT; /* We need a better test for this. if you need it back, tell us * how to detect it. */ -#if 0/*def LINUX_KERNEL_IS_SELINUX*/ +#ifdef LINUX_KERNEL_SOCK_CREATE_V code = sock_create(AF_INET, SOCK_DGRAM, IPPROTO_UDP, &sockp, 0); #else code = sock_create(AF_INET, SOCK_DGRAM, IPPROTO_UDP, &sockp); @@ -64,6 +66,9 @@ rxk_NewSocketHost(afs_uint32 ahost, short aport) return NULL; } + TO_USER_SPACE(); + sockp->ops->setsockopt(sockp, SOL_IP, IP_MTU_DISCOVER, &pmtu, sizeof(pmtu)); + TO_KERNEL_SPACE(); return (struct osi_socket *)sockp; } diff --git a/src/rx/rx.c b/src/rx/rx.c index 612ad30e0..2fb93036f 100644 --- a/src/rx/rx.c +++ b/src/rx/rx.c @@ -17,7 +17,7 @@ #endif RCSID - ("$Header: /cvs/openafs/src/rx/rx.c,v 1.58.2.2 2004/08/25 07:13:09 shadow Exp $"); + ("$Header: /cvs/openafs/src/rx/rx.c,v 1.58.2.3 2004/10/18 17:43:57 shadow Exp $"); #ifdef KERNEL #include "afs/sysincludes.h" @@ -662,7 +662,7 @@ void rx_StartServer(int donateMe) { register struct rx_service *service; - register int i, nProcs = 0; + register int i; SPLVAR; clock_NewTime(); @@ -701,6 +701,7 @@ rx_StartServer(int donateMe) #ifndef AFS_NT40_ENV #ifndef KERNEL char name[32]; + static int nProcs; #ifdef AFS_PTHREAD_ENV pid_t pid; pid = (pid_t) pthread_self(); @@ -816,15 +817,16 @@ rxi_CleanupConnection(struct rx_connection *conn) * idle (refCount == 0) after rx_idlePeerTime (60 seconds) have passed. */ MUTEX_ENTER(&rx_peerHashTable_lock); - if (--conn->peer->refCount <= 0) { + if (conn->peer->refCount < 2) { conn->peer->idleWhen = clock_Sec(); - if (conn->peer->refCount < 0) { - conn->peer->refCount = 0; + if (conn->peer->refCount < 1) { + conn->peer->refCount = 1; MUTEX_ENTER(&rx_stats_mutex); rxi_lowPeerRefCount++; MUTEX_EXIT(&rx_stats_mutex); } } + conn->peer->refCount--; MUTEX_EXIT(&rx_peerHashTable_lock); MUTEX_ENTER(&rx_stats_mutex); @@ -1014,6 +1016,20 @@ rx_DestroyConnection(register struct rx_connection *conn) USERPRI; } +void +rx_GetConnection(register struct rx_connection *conn) +{ + SPLVAR; + + NETPRI; + AFS_RXGLOCK(); + MUTEX_ENTER(&conn->conn_data_lock); + conn->refCount++; + MUTEX_EXIT(&conn->conn_data_lock); + AFS_RXGUNLOCK(); + USERPRI; +} + /* Start a new rx remote procedure call, on the specified connection. * If wait is set to 1, wait for a free call channel; otherwise return * 0. Maxtime gives the maximum number of seconds this call may take, @@ -3984,6 +4000,7 @@ rxi_AttachServerProc(register struct rx_call *call, call->flags |= RX_CALL_WAIT_PROC; MUTEX_ENTER(&rx_stats_mutex); rx_nWaiting++; + rx_nWaited++; MUTEX_EXIT(&rx_stats_mutex); rxi_calltrace(RX_CALL_ARRIVAL, call); SET_CALL_QUEUE_LOCK(call, &rx_serverPool_lock); @@ -5747,7 +5764,7 @@ rxi_ReapConnections(void) MUTEX_ENTER(&rx_stats_mutex); rx_stats.nPeerStructs--; MUTEX_EXIT(&rx_stats_mutex); - if (prev == *peer_ptr) { + if (peer == *peer_ptr) { *peer_ptr = next; prev = next; } else @@ -6218,6 +6235,9 @@ rx_GetServerDebug(osi_socket socket, afs_uint32 remoteAddr, if (stat->version >= RX_DEBUGI_VERSION_W_GETPEER) { *supportedValues |= RX_SERVER_DEBUG_ALL_PEER; } + if (stat->version >= RX_DEBUGI_VERSION_W_WAITED) { + *supportedValues |= RX_SERVER_DEBUG_WAITED_CNT; + } stat->nFreePackets = ntohl(stat->nFreePackets); stat->packetReclaims = ntohl(stat->packetReclaims); diff --git a/src/rx/rx.h b/src/rx/rx.h index c4da3756a..6778bbcf4 100644 --- a/src/rx/rx.h +++ b/src/rx/rx.h @@ -211,6 +211,8 @@ returned with an error code of RX_CALL_DEAD ( transient error ) */ #define rx_EnableHotThread() (rx_enable_hot_thread = 1) #define rx_DisableHotThread() (rx_enable_hot_thread = 0) +#define rx_PutConnection(conn) rx_DestroyConnection(conn) + /* A connection is an authenticated communication path, allowing limited multiple asynchronous conversations. */ #ifdef KDUMP_RX_LOCK @@ -248,7 +250,7 @@ struct rx_connection { /* client-- to retransmit the challenge */ struct rx_service *service; /* used by servers only */ u_short serviceId; /* To stamp on requests (clients only) */ - u_short refCount; /* Reference count */ + afs_uint32 refCount; /* Reference count */ u_char flags; /* Defined below */ u_char type; /* Type of connection, defined below */ u_char secondsUntilPing; /* how often to ping for each active call */ @@ -363,7 +365,7 @@ struct rx_peer { /* For garbage collection */ afs_uint32 idleWhen; /* When the refcountwent to zero */ - short refCount; /* Reference count for this structure */ + afs_uint32 refCount; /* Reference count for this structure */ /* Congestion control parameters */ u_char burstSize; /* Reinitialization size for the burst parameter */ @@ -817,7 +819,7 @@ struct rx_debugIn { #define RX_DEBUGI_BADTYPE (-8) #define RX_DEBUGI_VERSION_MINIMUM ('L') /* earliest real version */ -#define RX_DEBUGI_VERSION ('Q') /* Latest version */ +#define RX_DEBUGI_VERSION ('R') /* Latest version */ /* first version w/ secStats */ #define RX_DEBUGI_VERSION_W_SECSTATS ('L') /* version M is first supporting GETALLCONN and RXSTATS type */ @@ -829,6 +831,7 @@ struct rx_debugIn { #define RX_DEBUGI_VERSION_W_IDLETHREADS ('O') #define RX_DEBUGI_VERSION_W_NEWPACKETTYPES ('P') #define RX_DEBUGI_VERSION_W_GETPEER ('Q') +#define RX_DEBUGI_VERSION_W_WAITED ('R') #define RX_DEBUGI_GETSTATS 1 /* get basic rx stats */ #define RX_DEBUGI_GETCONN 2 /* get connection info */ @@ -846,7 +849,8 @@ struct rx_debugStats { char spare1; afs_int32 nWaiting; afs_int32 idleThreads; /* Number of server threads that are idle */ - afs_int32 spare2[8]; + afs_int32 nWaited; + afs_int32 spare2[7]; }; struct rx_debugConn_vL { @@ -971,6 +975,7 @@ extern int rx_callHoldType; #define RX_SERVER_DEBUG_OLD_CONN 0x20 #define RX_SERVER_DEBUG_NEW_PACKETS 0x40 #define RX_SERVER_DEBUG_ALL_PEER 0x80 +#define RX_SERVER_DEBUG_WAITED_CNT 0x100 #define AFS_RX_STATS_CLEAR_ALL 0xffffffff #define AFS_RX_STATS_CLEAR_INVOCATIONS 0x1 diff --git a/src/rx/rx_getaddr.c b/src/rx/rx_getaddr.c index 16019908a..08a7ac7eb 100644 --- a/src/rx/rx_getaddr.c +++ b/src/rx/rx_getaddr.c @@ -11,7 +11,7 @@ #include RCSID - ("$Header: /cvs/openafs/src/rx/rx_getaddr.c,v 1.15 2003/07/15 23:16:09 shadow Exp $"); + ("$Header: /cvs/openafs/src/rx/rx_getaddr.c,v 1.15.2.1 2004/10/18 07:12:06 shadow Exp $"); #ifndef AFS_DJGPP_ENV #ifndef KERNEL @@ -118,9 +118,7 @@ rxi_getaddr(void) #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) static void -rt_xaddrs(cp, cplim, rtinfo) - caddr_t cp, cplim; - struct rt_addrinfo *rtinfo; +rt_xaddrs(caddr_t cp, caddr_t cplim, struct rt_addrinfo *rtinfo) { struct sockaddr *sa; int i; @@ -141,9 +139,7 @@ rt_xaddrs(cp, cplim, rtinfo) */ #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) int -rx_getAllAddr(buffer, maxSize) - afs_int32 buffer[]; - int maxSize; /* sizeof of buffer in afs_int32 units */ +rx_getAllAddr(afs_int32 buffer[], int maxSize) { size_t needed; int mib[6]; @@ -221,11 +217,8 @@ rx_getAllAddr(buffer, maxSize) } int -rxi_getAllAddrMaskMtu(addrBuffer, maskBuffer, mtuBuffer, maxSize) - afs_int32 addrBuffer[]; /* the network addrs in net byte order */ - afs_int32 maskBuffer[]; /* the subnet masks */ - afs_int32 mtuBuffer[]; /* the MTU sizes */ - int maxSize; /* sizeof of buffer in afs_int32 units */ +rxi_getAllAddrMaskMtu(afs_int32 addrBuffer[], afs_int32 maskBuffer[], + afs_int32 mtuBuffer[], int maxSize) { int s; @@ -279,9 +272,6 @@ rxi_getAllAddrMaskMtu(addrBuffer, maskBuffer, mtuBuffer, maxSize) } if ((ifm->ifm_flags & IFF_UP) == 0) continue; /* not up */ - if (ifm->ifm_flags & IFF_LOOPBACK) { - continue; /* skip aliased loopbacks as well. */ - } while (addrcount > 0) { struct sockaddr_in *a; @@ -322,13 +312,9 @@ rxi_getAllAddrMaskMtu(addrBuffer, maskBuffer, mtuBuffer, maxSize) free(buf); return count; } - - #else -int -rx_getAllAddr(buffer, maxSize) - afs_int32 buffer[]; - int maxSize; /* sizeof of buffer in afs_int32 units */ +static int +rx_getAllAddr_internal(afs_int32 buffer[], int maxSize, int loopbacks) { int s; int i, len, count = 0; @@ -381,7 +367,7 @@ rx_getAllAddr(buffer, maxSize) continue; /* ignore this address */ } if (a->sin_addr.s_addr != 0) { - if (ifr->ifr_flags & IFF_LOOPBACK) { + if (!loopbacks && (ifr->ifr_flags & IFF_LOOPBACK)) { continue; /* skip aliased loopbacks as well. */ } if (count >= maxSize) /* no more space */ @@ -395,6 +381,12 @@ rx_getAllAddr(buffer, maxSize) return count; } +int +rx_getAllAddr(afs_int32 buffer[], int maxSize) +{ + return rx_getAllAddr_internal(buffer, maxSize, 0); +} + /* this function returns the total number of interface addresses * the buffer has to be passed in by the caller. It also returns * the interface mask. If AFS_USERSPACE_IP_ADDR is defined, it @@ -402,11 +394,8 @@ rx_getAllAddr(buffer, maxSize) * by afsi_SetServerIPRank(). */ int -rxi_getAllAddrMaskMtu(addrBuffer, maskBuffer, mtuBuffer, maxSize) - afs_int32 addrBuffer[]; /* the network addrs in net byte order */ - afs_int32 maskBuffer[]; /* the subnet masks */ - afs_int32 mtuBuffer[]; /* the MTU sizes */ - int maxSize; /* sizeof of buffer in afs_int32 units */ +rxi_getAllAddrMaskMtu(afs_int32 addrBuffer[], afs_int32 maskBuffer[], + afs_int32 mtuBuffer[], int maxSize) { int s; int i, len, count = 0; @@ -418,7 +407,7 @@ rxi_getAllAddrMaskMtu(addrBuffer, maskBuffer, mtuBuffer, maxSize) #endif #if !defined(AFS_USERSPACE_IP_ADDR) - count = rx_getAllAddr(addrBuffer, 1024); + count = rx_getAllAddr_internal(addrBuffer, 1024, 1); for (i = 0; i < count; i++) { maskBuffer[i] = htonl(0xffffffff); mtuBuffer[i] = htonl(1500); @@ -458,9 +447,6 @@ rxi_getAllAddrMaskMtu(addrBuffer, maskBuffer, mtuBuffer, maxSize) perror("SIOCGIFFLAGS"); continue; /* ignore this address */ } - if (ifr->ifr_flags & IFF_LOOPBACK) { - continue; /* skip aliased loopbacks as well. */ - } if (count >= maxSize) { /* no more space */ printf("Too many interfaces..ignoring 0x%x\n", diff --git a/src/rx/rx_globals.h b/src/rx/rx_globals.h index a492d1129..b47f4a8a1 100644 --- a/src/rx/rx_globals.h +++ b/src/rx/rx_globals.h @@ -151,6 +151,7 @@ EXT afs_kmutex_t rx_freePktQ_lock; EXT int rx_nFreePackets INIT(0); EXT int rxi_NeedMorePackets INIT(0); EXT int rx_nWaiting INIT(0); +EXT int rx_nWaited INIT(0); EXT int rx_packetReclaims INIT(0); /* largest packet which we can safely receive, initialized to AFS 3.2 value diff --git a/src/rx/rx_packet.c b/src/rx/rx_packet.c index 533b84bdb..bf8f9c3f5 100644 --- a/src/rx/rx_packet.c +++ b/src/rx/rx_packet.c @@ -15,7 +15,7 @@ #endif RCSID - ("$Header: /cvs/openafs/src/rx/rx_packet.c,v 1.35.2.1 2004/08/25 07:09:42 shadow Exp $"); + ("$Header: /cvs/openafs/src/rx/rx_packet.c,v 1.35.2.2 2004/10/18 17:43:58 shadow Exp $"); #ifdef KERNEL #if defined(UKERNEL) @@ -865,7 +865,11 @@ rxi_ReadPacket(int socket, register struct rx_packet *p, afs_uint32 * host, * never be cleaned up. */ peer = rxi_FindPeer(*host, *port, 0, 0); - if (peer) { + /* Since this may not be associated with a connection, + * it may have no refCount, meaning we could race with + * ReapConnections + */ + if (peer && (peer->refCount > 0)) { MUTEX_ENTER(&peer->peer_lock); hadd32(peer->bytesReceived, p->length); MUTEX_EXIT(&peer->peer_lock); @@ -1160,6 +1164,7 @@ rxi_ReceiveDebugPacket(register struct rx_packet *ap, osi_socket asocket, tstat.packetReclaims = htonl(rx_packetReclaims); tstat.usedFDs = CountFDs(64); tstat.nWaiting = htonl(rx_nWaiting); + tstat.nWaited = htonl(rx_nWaited); queue_Count(&rx_idleServerQueue, np, nqe, rx_serverQueueEntry, tstat.idleThreads); MUTEX_EXIT(&rx_serverPool_lock); diff --git a/src/rx/rx_prototypes.h b/src/rx/rx_prototypes.h index f06ec425d..6d57e165e 100644 --- a/src/rx/rx_prototypes.h +++ b/src/rx/rx_prototypes.h @@ -26,6 +26,7 @@ extern void rx_SetConnDeadTime(register struct rx_connection *conn, register int seconds); extern void rxi_CleanupConnection(struct rx_connection *conn); extern void rxi_DestroyConnection(register struct rx_connection *conn); +extern void rx_GetConnection(register struct rx_connection *conn); extern void rx_DestroyConnection(register struct rx_connection *conn); extern struct rx_call *rx_NewCall(register struct rx_connection *conn); extern int rxi_HasActiveCalls(register struct rx_connection *aconn); diff --git a/src/rx/rx_rdwr.c b/src/rx/rx_rdwr.c index 0afd4569e..c2521f83d 100644 --- a/src/rx/rx_rdwr.c +++ b/src/rx/rx_rdwr.c @@ -15,7 +15,7 @@ #endif RCSID - ("$Header: /cvs/openafs/src/rx/rx_rdwr.c,v 1.21 2003/07/15 23:16:10 shadow Exp $"); + ("$Header: /cvs/openafs/src/rx/rx_rdwr.c,v 1.21.2.1 2004/10/18 07:12:06 shadow Exp $"); #ifdef KERNEL #ifndef UKERNEL @@ -1301,7 +1301,7 @@ rxi_FlushWrite(register struct rx_call *call) return; } cp->length = 0; - cp->niovecs = 1; /* just the header */ + cp->niovecs = 2; /* header + space for rxkad stuff */ call->nFree = 0; } diff --git a/src/rx/rx_user.c b/src/rx/rx_user.c index efa712236..495a66f1f 100644 --- a/src/rx/rx_user.c +++ b/src/rx/rx_user.c @@ -13,7 +13,7 @@ #include RCSID - ("$Header: /cvs/openafs/src/rx/rx_user.c,v 1.18.2.1 2004/08/25 07:09:42 shadow Exp $"); + ("$Header: /cvs/openafs/src/rx/rx_user.c,v 1.18.2.2 2004/10/18 17:43:58 shadow Exp $"); # include # include @@ -100,7 +100,9 @@ rxi_GetHostUDPSocket(u_int ahost, u_short port) osi_socket socketFd = OSI_NULLSOCKET; struct sockaddr_in taddr; char *name = "rxi_GetUDPSocket: "; - int greedy = 0; +#ifdef AFS_LINUX22_ENV + int pmtu=IP_PMTUDISC_DONT; +#endif #if !defined(AFS_NT40_ENV) && !defined(AFS_DJGPP_ENV) if (ntohs(port) >= IPPORT_RESERVED && ntohs(port) < IPPORT_USERRESERVED) { @@ -147,15 +149,16 @@ rxi_GetHostUDPSocket(u_int ahost, u_short port) fcntl(socketFd, F_SETFD, 1); #endif +#ifndef AFS_DJGPP_ENV /* Use one of three different ways of getting a socket buffer expanded to * a reasonable size. */ { + int greedy = 0; int len1, len2; len1 = 32766; len2 = rx_UdpBufSize; -#ifndef AFS_DJGPP_ENV greedy = (setsockopt (socketFd, SOL_SOCKET, SO_RCVBUF, (char *)&len2, @@ -172,14 +175,19 @@ rxi_GetHostUDPSocket(u_int ahost, u_short port) (setsockopt (socketFd, SOL_SOCKET, SO_RCVBUF, (char *)&len2, sizeof(len2)) >= 0); -#endif /* AFS_DJGPP_ENV */ + if (!greedy) + (osi_Msg "%s*WARNING* Unable to increase buffering on socket\n", + name); + MUTEX_ENTER(&rx_stats_mutex); + rx_stats.socketGreedy = greedy; + MUTEX_EXIT(&rx_stats_mutex); } - -#ifndef AFS_DJGPP_ENV - if (!greedy) - (osi_Msg "%s*WARNING* Unable to increase buffering on socket\n", - name); #endif /* AFS_DJGPP_ENV */ + +#ifdef AFS_LINUX22_ENV + setsockopt(socketFd, SOL_IP, IP_MTU_DISCOVER, &pmtu, sizeof(pmtu)); +#endif + if (rxi_Listen(socketFd) < 0) { goto error; } @@ -195,9 +203,6 @@ rxi_GetHostUDPSocket(u_int ahost, u_short port) close(socketFd); #endif - MUTEX_ENTER(&rx_stats_mutex); - rx_stats.socketGreedy = greedy; - MUTEX_EXIT(&rx_stats_mutex); return OSI_NULLSOCKET; } diff --git a/src/rx/rxdebug.c b/src/rx/rxdebug.c index b96b227dd..a6c9560e3 100644 --- a/src/rx/rxdebug.c +++ b/src/rx/rxdebug.c @@ -11,7 +11,7 @@ #include RCSID - ("$Header: /cvs/openafs/src/rx/rxdebug.c,v 1.15.2.1 2004/08/25 07:09:42 shadow Exp $"); + ("$Header: /cvs/openafs/src/rx/rxdebug.c,v 1.15.2.2 2004/10/18 17:43:59 shadow Exp $"); #include #include @@ -109,6 +109,7 @@ MainCommand(as, arock) int withRxStats; int withWaiters; int withIdleThreads; + int withWaited; int withPeers; struct rx_debugStats tstats; char *portName, *hostName; @@ -253,6 +254,7 @@ MainCommand(as, arock) withRxStats = (supportedDebugValues & RX_SERVER_DEBUG_RX_STATS); withWaiters = (supportedDebugValues & RX_SERVER_DEBUG_WAITER_CNT); withIdleThreads = (supportedDebugValues & RX_SERVER_DEBUG_IDLE_THREADS); + withIdleThreads = (supportedDebugValues & RX_SERVER_DEBUG_WAITED_CNT); withPeers = (supportedDebugValues & RX_SERVER_DEBUG_ALL_PEER); printf("Free packets: %d, packet reclaims: %d, calls: %d, used FDs: %d\n", @@ -265,6 +267,8 @@ MainCommand(as, arock) printf("%d calls waiting for a thread\n", tstats.nWaiting); if (withIdleThreads) printf("%d threads are idle\n", tstats.idleThreads); + if (withWaited) + printf("%d calls have waited for a thread\n", tstats.nWaited); if (rxstats) { if (!withRxStats) { diff --git a/src/rxkad/Makefile.in b/src/rxkad/Makefile.in index 40d1b6fe9..c19ae6854 100644 --- a/src/rxkad/Makefile.in +++ b/src/rxkad/Makefile.in @@ -65,8 +65,6 @@ librxkad.a: ${OBJS} AFS_component_version_number.o $(AR) crv $@ ${OBJS} AFS_component_version_number.o $(RANLIB) $@ -crypt_conn.o: fcrypt.h private_data.h crypt_conn.c ${INCLS} - rxkad_client.o: fcrypt.h private_data.h rxkad_client.c ${INCLS} rxkad_server.o: fcrypt.h private_data.h rxkad_server.c ${INCLS} @@ -89,14 +87,18 @@ md4.o: md4.c ${INCLS} md5.o: md5.c ${INCLS} -fcrypt.o: fcrypt.c fcrypt.h sboxes.h rxkad.h rxkad_prototypes.h - ${CCOBJ} ${CFLAGS} -c fcrypt.c +fcrypt.o: domestic/fcrypt.c fcrypt.h sboxes.h rxkad.h rxkad_prototypes.h + ${CCOBJ} ${CFLAGS} -c domestic/fcrypt.c + +crypt_conn.o: domestic/crypt_conn.c fcrypt.h private_data.h ${INCLS} + ${CCOBJ} ${CFLAGS} -c domestic/crypt_conn.c + +tcrypt.o: domestic/tcrypt.c AFS_component_version_number.o + ${CCOBJ} ${CFLAGS} -c domestic/fcrypt.c tcrypt: tcrypt.o librxkad.a ${CC} -o tcrypt tcrypt.o librxkad.a -tcrypt.o: tcrypt.c AFS_component_version_number.o - fc_test: ${fc_test_OBJS} ${fc_test_LIBS} ${CC} ${CFLAGS} -o fc_test ${fc_test_OBJS} ${fc_test_LIBS} ${XLIBS} @@ -109,7 +111,7 @@ fc_test.o: ${INCLS} clean: $(RM) -f *.o *.a tcrypt core rxkad_errs.c rxkad.h \ AFS_component_version_number.c \ - crypt_conn.c fcrypt.c fcrypt.h sboxes.h \ + fcrypt.h sboxes.h \ fc_test test: @@ -117,21 +119,12 @@ test: # These sources are kept in a separate directory so that we can use an # ACL to comply with source export restrictions. -crypt_conn.c: domestic/crypt_conn.c - ${INSTALL} $? $@ - -fcrypt.c: domestic/fcrypt.c - ${INSTALL} $? $@ - fcrypt.h: domestic/fcrypt.h ${INSTALL} $? $@ sboxes.h: domestic/sboxes.h ${INSTALL} $? $@ -tcrypt.c: domestic/tcrypt.c - ${INSTALL} $? $@ - include ../config/Makefile.version ${DESTDIR}${libdir}/librxkad.a: librxkad.a ${INSTALL} $? $@ diff --git a/src/rxkad/domestic/fcrypt.c b/src/rxkad/domestic/fcrypt.c index 4e949a428..b5543d86d 100644 --- a/src/rxkad/domestic/fcrypt.c +++ b/src/rxkad/domestic/fcrypt.c @@ -20,7 +20,7 @@ #endif RCSID - ("$Header: /cvs/openafs/src/rxkad/domestic/fcrypt.c,v 1.11.2.1 2004/08/25 07:17:01 shadow Exp $"); + ("$Header: /cvs/openafs/src/rxkad/domestic/fcrypt.c,v 1.11.2.2 2004/10/18 17:44:01 shadow Exp $"); #define DEBUG 0 #ifdef KERNEL @@ -110,7 +110,7 @@ fc_keysched(struct ktc_encryptionKey *key, fc_KeySchedule schedule) /* IN int encrypt; * 0 ==> decrypt, else encrypt */ afs_int32 -fc_ecb_encrypt(afs_uint32 * clear, afs_uint32 * cipher, +fc_ecb_encrypt(void * clear, void * cipher, fc_KeySchedule schedule, int encrypt) { afs_uint32 L, R; @@ -135,8 +135,8 @@ fc_ecb_encrypt(afs_uint32 * clear, afs_uint32 * cipher, memcpy(&L, clear, sizeof(afs_int32)); memcpy(&R, clear + 1, sizeof(afs_int32)); #else - L = ntohl(*clear); - R = ntohl(*(clear + 1)); + L = ntohl(*((afs_uint32 *)clear)); + R = ntohl(*((afs_uint32 *)clear + 1)); #endif if (encrypt) { @@ -185,8 +185,8 @@ fc_ecb_encrypt(afs_uint32 * clear, afs_uint32 * cipher, memcpy(cipher, &L, sizeof(afs_int32)); memcpy(cipher + 1, &R, sizeof(afs_int32)); #else - *cipher = htonl(L); - *(cipher + 1) = htonl(R); + *((afs_int32 *)cipher) = htonl(L); + *((afs_int32 *)cipher + 1) = htonl(R); #endif return 0; } @@ -203,7 +203,7 @@ fc_ecb_encrypt(afs_uint32 * clear, afs_uint32 * cipher, afs_uint32 *xor; * 8 bytes of initialization vector * */ afs_int32 -fc_cbc_encrypt(char *input, char *output, afs_int32 length, +fc_cbc_encrypt(void *input, void *output, afs_int32 length, fc_KeySchedule key, afs_uint32 * xor, int encrypt) { afs_uint32 i, j; @@ -215,7 +215,7 @@ fc_cbc_encrypt(char *input, char *output, afs_int32 length, for (i = 0; length > 0; i++, length -= 8) { /* get input */ memcpy(t_input, input, sizeof(t_input)); - input += sizeof(t_input); + input=((char *)input) + sizeof(t_input); /* zero pad */ for (j = length; j <= 7; j++) @@ -229,7 +229,7 @@ fc_cbc_encrypt(char *input, char *output, afs_int32 length, /* copy temp output and save it for cbc */ memcpy(output, t_output, sizeof(t_output)); - output += sizeof(t_output); + output=(char *)output + sizeof(t_output); /* calculate xor value for next round from plain & cipher text */ xor[0] = t_input[0] ^ t_output[0]; @@ -244,7 +244,7 @@ fc_cbc_encrypt(char *input, char *output, afs_int32 length, for (i = 0; length > 0; i++, length -= 8) { /* get input */ memcpy(t_input, input, sizeof(t_input)); - input += sizeof(t_input); + input=((char *)input) + sizeof(t_input); /* no padding for decrypt */ fc_ecb_encrypt(t_input, t_output, key, encrypt); @@ -255,7 +255,7 @@ fc_cbc_encrypt(char *input, char *output, afs_int32 length, /* copy temp output */ memcpy(output, t_output, sizeof(t_output)); - output += sizeof(t_output); + output=((char *)output) + sizeof(t_output); /* calculate xor value for next round from plain & cipher text */ xor[0] = t_input[0] ^ t_output[0]; diff --git a/src/rxkad/rxkad.p.h b/src/rxkad/rxkad.p.h index 83a4f53fb..5887d23cf 100644 --- a/src/rxkad/rxkad.p.h +++ b/src/rxkad/rxkad.p.h @@ -16,12 +16,7 @@ /* no ticket good for longer than 30 days */ #define MAXKTCTICKETLIFETIME (30*24*3600) #define MINKTCTICKETLEN 32 -#ifdef AFS_AIX_ENV -#define MAXKTCTICKETLEN 344 /* XXX why must this be small? */ -#else #define MAXKTCTICKETLEN 12000 /* was 344 */ -#endif - #define MAXKTCNAMELEN 64 /* name & inst should be 256 */ #define MAXKTCREALMLEN 64 /* should be 256 */ #define KTC_TIME_UNCERTAINTY (15*60) /* max skew bet. machines' clocks */ diff --git a/src/rxkad/rxkad_prototypes.h b/src/rxkad/rxkad_prototypes.h index adffe54fa..471b8ac13 100644 --- a/src/rxkad/rxkad_prototypes.h +++ b/src/rxkad/rxkad_prototypes.h @@ -28,9 +28,9 @@ extern afs_int32 rxkad_EncryptPacket(const struct rx_connection *conn, /* domestic/fcrypt.c */ extern int fc_keysched(struct ktc_encryptionKey *key, fc_KeySchedule schedule); -extern afs_int32 fc_ecb_encrypt(afs_uint32 * clear, afs_uint32 * cipher, +extern afs_int32 fc_ecb_encrypt(void * clear, void * cipher, fc_KeySchedule schedule, int encrypt); -extern afs_int32 fc_cbc_encrypt(char *input, char *output, afs_int32 length, +extern afs_int32 fc_cbc_encrypt(void *input, void *output, afs_int32 length, fc_KeySchedule key, afs_uint32 * xor, int encrypt); diff --git a/src/scout/Makefile.in b/src/scout/Makefile.in index db42c140e..5007c85ee 100644 --- a/src/scout/Makefile.in +++ b/src/scout/Makefile.in @@ -24,6 +24,7 @@ INCLS=${TOP_INCDIR}/afs/gtxobjects.h \ LIBS=${TOP_LIBDIR}/libgtx.a \ ${TOP_LIBDIR}/libfsprobe.a \ ${TOP_LIBDIR}/libvolser.a \ + ${TOP_LIBDIR}/libubik.a \ ${TOP_LIBDIR}/libkauth.a \ ${TOP_LIBDIR}/libauth.a \ ${TOP_LIBDIR}/librxkad.a \ @@ -31,7 +32,6 @@ LIBS=${TOP_LIBDIR}/libgtx.a \ ${TOP_LIBDIR}/libcmd.a \ ${TOP_LIBDIR}/vlib.a ${TOP_LIBDIR}/libacl.a \ ${TOP_LIBDIR}/libvldb.a \ - ${TOP_LIBDIR}/libubik.a \ ${TOP_LIBDIR}/libafsint.a \ ${TOP_LIBDIR}/libsys.a \ ${TOP_LIBDIR}/librx.a \ diff --git a/src/shlibafsauthent/Makefile.in b/src/shlibafsauthent/Makefile.in index 4c01bf03a..306423f26 100644 --- a/src/shlibafsauthent/Makefile.in +++ b/src/shlibafsauthent/Makefile.in @@ -53,6 +53,7 @@ KAUTHOBJS = \ read_passwd.o UBIKOBJS = \ + uinit.o \ ubikclient.o \ uerrors.o \ ubik_int.cs.o \ @@ -175,6 +176,9 @@ read_passwd.o: ${KAUTH}/read_passwd.c ubikclient.o: ${UBIK}/ubikclient.c ${CCRULE} +uinit.o: ${UBIK}/uinit.c + ${CCRULE} + uerrors.o: ${UBIK}/uerrors.c ${CCRULE} diff --git a/src/shlibafsrpc/Makefile.in b/src/shlibafsrpc/Makefile.in index 8421acc06..86588b401 100644 --- a/src/shlibafsrpc/Makefile.in +++ b/src/shlibafsrpc/Makefile.in @@ -209,10 +209,10 @@ md4.o: ${RXKAD}/md4.c md5.o: ${RXKAD}/md5.c ${CCRULE} -fcrypt.o: ${RXKAD}/fcrypt.c +fcrypt.o: ${RXKAD}/domestic/fcrypt.c ${CCRULE} -crypt_conn.o: ${RXKAD}/crypt_conn.c +crypt_conn.o: ${RXKAD}/domestic/crypt_conn.c ${CCRULE} AFS_component_version_number.o: ${RX}/AFS_component_version_number.c @@ -273,7 +273,7 @@ xdr_afsuuid.o: ${RX}/xdr_afsuuid.c # # $ what /opt/langtools/bin/pxdb32 # /opt/langtools/bin/pxdb32: -# HP92453-02 A.10.0A HP-UX SYMBOLIC DEBUGGER (PXDB) $Revision: 1.15 $ +# HP92453-02 A.10.0A HP-UX SYMBOLIC DEBUGGER (PXDB) $Revision: 1.15.2.1 $ # # The problem occurs when -g and -O are both used when compiling des.c. # The simplest way to work around the problem is to leave out either -g or -O. diff --git a/src/shlibafsrpc/NTMakefile b/src/shlibafsrpc/NTMakefile deleted file mode 100644 index 3fc15fa23..000000000 --- a/src/shlibafsrpc/NTMakefile +++ /dev/null @@ -1,349 +0,0 @@ -# Copyright 2000, International Business Machines Corporation and others. -# All Rights Reserved. -# -# This software has been released under the terms of the IBM Public -# License. For details, see the LICENSE file in the top-level source -# directory or online at http://www.openafs.org/dl/license10.html - -RELDIR=shlibafsrpc -!include ..\config\NTMakefile.$(SYS_NAME) -!include ..\config\NTMakefile.version - -RX = ..\rx -RXSTAT = ..\rxstat -RXKAD = ..\rxkad -DES = ..\des -UTIL = ..\util -FSINT = ..\fsint -COMERR = ..\comerr - -# Additional debugging flag for RX. -AFSDEV_AUXCDEFINES = -DRXDEBUG -DAFS_PTHREAD_ENV - -LIBFILE = $(DESTDIR)\lib\afsrpc.dll - -# Object files by category. -MULTIOBJS = $(OUT)\rx_multi.obj - -XDROBJS = $(OUT)\xdr.obj \ - $(OUT)\xdr_array.obj \ - $(OUT)\xdr_arrayn.obj \ - $(OUT)\xdr_float.obj \ - $(OUT)\xdr_mem.obj \ - $(OUT)\xdr_rec.obj \ - $(OUT)\xdr_refernce.obj \ - $(OUT)\xdr_rx.obj \ - $(OUT)\xdr_update.obj \ - $(OUT)\xdr_afsuuid.obj \ - $(OUT)\xdr_int64.obj - -RXOBJS = $(OUT)\rx_event.obj \ - $(OUT)\rx_user.obj \ - $(OUT)\rx_pthread.obj \ - $(OUT)\rx.obj \ - $(OUT)\rx_null.obj \ - $(OUT)\rx_globals.obj \ - $(OUT)\rx_getaddr.obj \ - $(OUT)\rx_misc.obj - $(OUT)\rx_packet.obj \ - $(OUT)\rx_rdwr.obj \ - $(OUT)\rx_trace.obj \ - $(OUT)\rx_xmit_nt.obj \ - $(OUT)\rx_conncache.obj - -RXSTATOBJS = $(OUT)\rxstat.obj \ - $(OUT)\rxstat.ss.obj \ - $(OUT)\rxstat.xdr.obj \ - $(OUT)\rxstat.cs.obj - -LIBRXKAD_OBJS = $(OUT)\rxkad_client.obj \ - $(OUT)\rxkad_server.obj \ - $(OUT)\rxkad_common.obj \ - $(OUT)\ticket.obj \ - $(OUT)\ticket5.obj \ - $(OUT)\crc.obj \ - $(OUT)\md4.obj \ - $(OUT)\md5.obj \ - $(OUT)\AFS_component_version_number.obj - -LIBRXKAD_REGOBJS = $(OUT)\fcrypt.obj \ - $(OUT)\crypt_conn.obj - -DESOBJS = $(OUT)\des.obj \ - $(OUT)\cbc_encrypt.obj \ - $(OUT)\pcbc_encrypt.obj \ - $(OUT)\cksum.obj \ - $(OUT)\new_rnd_key.obj \ - $(OUT)\key_sched.obj \ - $(OUT)\debug_decl.obj \ - $(OUT)\quad_cksum.obj \ - $(OUT)\key_parity.obj \ - $(OUT)\weak_key.obj \ - $(OUT)\strng_to_key.obj \ - $(OUT)\misc.obj \ - $(OUT)\util.obj - -UTILOBJS = $(OUT)\casestrcpy.obj \ - $(OUT)\winsock_nt.obj - -COMERROBJS = $(OUT)\error_msg.obj \ - $(OUT)\et_name.obj \ - $(OUT)\com_err.obj - -FSINTOBJS = $(OUT)\afsint.cs.obj \ - $(OUT)\afsint.xdr.obj \ - $(OUT)\afscbint.cs.obj \ - $(OUT)\afscbint.xdr.obj \ - $(OUT)\afsaux.obj - -DLLOBJS = $(MULTIOBJS) $(RXOBJS) $(XDROBJS) $(RXSTATOBJS) $(LIBRXKAD_OBJS) \ - $(DESOBJS) $(LIBRXKAD_REGOBJS) $(UTILOBJS) $(COMERROBJS) \ - $(FSINTOBJS) afsrpc.res - -rx_multi.obj: $(RX)\rx_multi.c - $(C2OBJ) $(RX)\rx_multi.c - -xdr.obj: $(RX)\xdr.c - $(C2OBJ) $(RX)\xdr.c - -xdr_array.obj: $(RX)\xdr_array.c - $(C2OBJ) $(RX)\xdr_array.c - -xdr_arrayn.obj: $(RX)\xdr_arrayn.c - $(C2OBJ) $(RX)\xdr_arrayn.c - -xdr_float.obj: $(RX)\xdr_float.c - $(C2OBJ) $(RX)\xdr_float.c - -xdr_mem.obj: $(RX)\xdr_mem.c - $(C2OBJ) $(RX)\xdr_mem.c - -xdr_rec.obj: $(RX)\xdr_rec.c - $(C2OBJ) $(RX)\xdr_rec.c - -xdr_refernce.obj: $(RX)\xdr_refernce.c - $(C2OBJ) $(RX)\xdr_refernce.c - -xdr_rx.obj: $(RX)\xdr_rx.c - $(C2OBJ) $(RX)\xdr_rx.c - -xdr_update.obj: $(RX)\xdr_update.c - $(C2OBJ) $(RX)\xdr_update.c - -xdr_afsuuid.obj: $(RX)\xdr_afsuuid.c - $(C2OBJ) $(RX)\xdr_afsuuid.c - -xdr_int64.obj: $(RX)\xdr_int64.c - $(C2OBJ) $(RX)\xdr_int64.c - -rx_event.obj: $(RX)\rx_event.c - $(C2OBJ) $(RX)\rx_event.c - -rx_user.obj: $(RX)\rx_user.c - $(C2OBJ) $(RX)\rx_user.c - -rx_pthread.obj: $(RX)\rx_pthread.c - $(C2OBJ) $(RX)\rx_pthread.c - -rx.obj: $(RX)\rx.c - $(C2OBJ) $(RX)\rx.c - -rx_null.obj: $(RX)\rx_null.c - $(C2OBJ) $(RX)\rx_null.c - -rx_globals.obj: $(RX)\rx_globals.c - $(C2OBJ) $(RX)\rx_globals.c - -rx_getaddr.obj: $(RX)\rx_getaddr.c - $(C2OBJ) $(RX)\rx_getaddr.c - -rx_misc.obj: $(RX)\rx_misc.c - $(C2OBJ) $(RX)\rx_misc.c - -rx_packet.obj: $(RX)\rx_packet.c - $(C2OBJ) $(RX)\rx_packet.c - -rx_rdwr.obj: $(RX)\rx_rdwr.c - $(C2OBJ) $(RX)\rx_rdwr.c - -rx_trace.obj: $(RX)\rx_trace.c - $(C2OBJ) $(RX)\rx_trace.c - -rx_xmit_nt.obj: $(RX)\rx_xmit_nt.c - $(C2OBJ) $(RX)\rx_xmit_nt.c - -rx_conncache.obj: $(RX)\rx_conncache.c - $(C2OBJ) $(RX)\rx_conncache.c - -rxstat.cs.obj:$(RXSTAT)\rxstat.cs.c - $(C2OBJ) $(RXSTAT)\rxstat.cs.c - -rxstat.ss.obj:$(RXSTAT)\rxstat.ss.c - $(C2OBJ) $(RXSTAT)\rxstat.ss.c - -rxstat.xdr.obj:$(RXSTAT)\rxstat.xdr.c - $(C2OBJ) $(RXSTAT)\rxstat.xdr.c - -rxstat.obj:$(RXSTAT)\rxstat.c - $(C2OBJ) $(RXSTAT)\rxstat.c - -rxkad_client.obj:$(RXKAD)\rxkad_client.c - $(C2OBJ) $(RXKAD)\rxkad_client.c - -rxkad_server.obj:$(RXKAD)\rxkad_server.c - $(C2OBJ) $(RXKAD)\rxkad_server.c - -rxkad_common.obj:$(RXKAD)\rxkad_common.c - $(C2OBJ) $(RXKAD)\rxkad_common.c - -ticket.obj:$(RXKAD)\ticket.c - $(C2OBJ) $(RXKAD)\ticket.c - -fcrypt.obj:$(RXKAD)\fcrypt.c - $(C2OBJ) $(RXKAD)\fcrypt.c - -crypt_conn.obj:$(RXKAD)\crypt_conn.c - $(C2OBJ) $(RXKAD)\crypt_conn.c - -AFS_component_version_number.obj:$(RXKAD)\AFS_component_version_number.c - $(C2OBJ) $(RXKAD)\AFS_component_version_number.c - -fcrypt_x.obj:$(RXKAD)\fcrypt.c - $(C2OBJ) $(RXKAD)\fcrypt.c /Fofcrypt_x.obj - -crypt_conn_x.obj:$(RXKAD)\crypt_conn.c - $(C2OBJ) $(RXKAD)\crypt_conn.c /Focrypt_conn_x.obj - -des.obj:$(DES)\des.c - $(C2OBJ) $(DES)\des.c - -cbc_encrypt.obj:$(DES)\cbc_encrypt.c - $(C2OBJ) $(DES)\cbc_encrypt.c - -pcbc_encrypt.obj:$(DES)\pcbc_encrypt.c - $(C2OBJ) $(DES)\pcbc_encrypt.c - -cksum.obj:$(DES)\cksum.c - $(C2OBJ) $(DES)\cksum.c - -new_rnd_key.obj:$(DES)\new_rnd_key.c - $(C2OBJ) $(DES)\new_rnd_key.c - -key_sched.obj:$(DES)\key_sched.c - $(C2OBJ) $(DES)\key_sched.c - -debug_decl.obj:$(DES)\debug_decl.c - $(C2OBJ) $(DES)\debug_decl.c - -quad_cksum.obj:$(DES)\quad_cksum.c - $(C2OBJ) $(DES)\quad_cksum.c - -key_parity.obj:$(DES)\key_parity.c - $(C2OBJ) $(DES)\key_parity.c - -weak_key.obj:$(DES)\weak_key.c - $(C2OBJ) $(DES)\weak_key.c - -strng_to_key.obj:$(DES)\strng_to_key.c - $(C2OBJ) $(DES)\strng_to_key.c - -misc.obj:$(DES)\misc.c - $(C2OBJ) -DDONT_INCL_MAIN $(DES)\misc.c - -util.obj:$(DES)\util.c - $(C2OBJ) $(DES)\util.c - -des_x.obj:$(DES)\des.c - $(C2OBJ) $(DES)\des.c /Fodes_x.obj - -cbc_crypt_x.obj:$(DES)\cbc_encrypt.c - $(C2OBJ) $(DES)\cbc_encrypt.c /Focbc_crypt_x.obj - -pcbc_crypt_x.obj:$(DES)\pcbc_encrypt.c - $(C2OBJ) $(DES)\pcbc_encrypt.c /Fopcbc_crypt_x.obj - -cksum_x.obj:$(DES)\cksum.c - $(C2OBJ) $(DES)\cksum.c /Focksum_x.obj - -nrnd_key_x.obj:$(DES)\new_rnd_key.c - $(C2OBJ) $(DES)\new_rnd_key.c /Fonrnd_key_x.obj - -error_msg.obj:$(COMERR)\error_msg.c - $(C2OBJ) $(COMERR)\error_msg.c - -et_name.obj:$(COMERR)\et_name.c - $(C2OBJ) $(COMERR)\et_name.c - -com_err.obj:$(COMERR)\com_err.c - $(C2OBJ) $(COMERR)\com_err.c - -casestrcpy.obj:$(UTIL)\casestrcpy.c - $(C2OBJ) $(UTIL)\casestrcpy.c - -winsock_nt.obj:$(UTIL)\winsock_nt.c - $(C2OBJ) $(UTIL)\winsock_nt.c - -afsint.cs.obj:$(FSINT)\afsint.cs.c - $(C2OBJ) $(FSINT)\afsint.cs.c - -afsint.xdr.obj:$(FSINT)\afsint.xdr.c - $(C2OBJ) $(FSINT)\afsint.xdr.c - -afscbint.cs.obj:$(FSINT)\afscbint.cs.c - $(C2OBJ) $(FSINT)\afscbint.cs.c - -afscbint.xdr.obj:$(FSINT)\afscbint.xdr.c - $(C2OBJ) $(FSINT)\afscbint.xdr.c - -afsaux.obj:$(FSINT)\afsaux.c - $(C2OBJ) $(FSINT)\afsaux.c - -NTMAKE = nmake /nologo /f ntmakefile - - -DLLLIBS =\ -!IF (("$(SYS_NAME)"=="i386_win95" ) || ("$(SYS_NAME)"=="I386_WIN95" )) - $(DESTDIR)\lib\win95\afspthread.lib \ -!ELSE - $(DESTDIR)\lib\afspthread.lib \ -!ENDIF - $(DESTDIR)\lib\afs\afsutil.lib \ - $(DESTDIR)\lib\afs\afsreg.lib - -$(DESTDIR)\lib\afsrpc.dll: $(DLLOBJS) $(DLLLIBS) - $(DLLCONLINK) /DEF:afsrpc.def - $(DLLPREP) - -# Definitions for generating versioninfo resources -afsrpc.res: afsrpc.rc AFS_component_version_number.h - $(RC) $*.rc - - -install: -! IF (EXIST(..\..\src\des\NTMakefile)) - $(NTMAKE) $(LIBFILE) -! else - $(NTMAKE) libstub -! endif - -install9x: install - -!IF (EXIST(..\..\src\des\NTMakefile)) -!ELSE IF (EXIST(..\..\DESLIB)) -DESPAR = ..\..\DESLIB\dest -!ELSE IF (EXIST(..\..\..\DESLIB)) -DESPAR = ..\..\..\DESLIB\dest -!ELSE -!ERROR Must create DESLIB link in the same directory as PARENT link. -!ENDIF - -libstub: - $(COPY) $(DESPAR)\lib\afsrpc.dll \ - $(DESTDIR)\lib\afsrpc.dll - $(COPY) $(DESPAR)\lib\afsrpc.lib \ - $(DESTDIR)\lib\afsrpc.lib - $(COPY) $(DESPAR)\lib\afsrpc.exp \ - $(DESTDIR)\lib\afsrpc.exp - -clean:: - $(DEL) $(DESTDIR)\lib\afsrpc.dll $(DESTDIR)\lib\afsrpc.lib $(DESTDIR)\lib\afsrpc.exp \ No newline at end of file diff --git a/src/shlibafsrpc/afsrpc.def b/src/shlibafsrpc/afsrpc.def deleted file mode 100644 index 95ec3c992..000000000 --- a/src/shlibafsrpc/afsrpc.def +++ /dev/null @@ -1,200 +0,0 @@ -EXPORTS - des_check_key_parity @2 - des_fixup_key_parity @5 - des_init_random_number_generator @6 - des_is_weak_key @7 - des_key_sched @8 - des_random_key @9 - des_string_to_key @10 - ktohl @11 - life_to_time @12 - rx_DestroyConnection @13 - rx_EndCall @14 - rx_Finalize @15 - rx_GetCachedConnection @16 - rx_GetCall @17 - rx_GetIFInfo @18 - rx_Init @19 - rx_NewCall @20 - rx_NewConnection @21 - rx_NewService @22 - rx_PrintPeerStats @23 - rx_PrintStats @24 - rx_PrintTheseStats @25 - rx_ReadProc @26 - rx_ReleaseCachedConnection @27 - rx_ServerProc @28 - rx_StartServer @29 - rx_WriteProc @30 - rxevent_Init @31 - rxevent_Post @32 - rxkad_GetServerInfo @33 - rxkad_NewClientSecurityObject @34 - rxkad_NewServerSecurityObject @35 - rxnull_NewClientSecurityObject @38 - rxnull_NewServerSecurityObject @39 - rxs_Release @40 - time_to_life @41 - tkt_CheckTimes @42 - tkt_DecodeTicket @43 - tkt_MakeTicket @44 - xdr_array @45 - xdr_bool @46 - xdr_bytes @47 - xdr_char @48 - xdr_double @49 - xdr_enum @50 - xdr_float @51 - xdr_int @52 - xdr_long @53 - xdr_opaque @54 - xdr_pointer @55 - xdr_reference @56 - xdr_short @57 - xdr_string @58 - xdr_u_char @59 - xdr_u_int @60 - xdr_u_long @61 - xdr_u_short @62 - xdr_union @63 - xdr_vector @64 - xdr_void @65 - xdr_wrapstring @66 - xdrmem_create @67 - xdrrec_create @68 - xdrrec_endofrecord @69 - xdrrec_eof @70 - xdrrec_skiprecord @71 - xdrrx_create @72 - hton_syserr_conv @73 - rxkad_stats @74 DATA - com_err @75 - error_message @76 - rx_socket @77 DATA - AssertionFailed @79 - afs_winsockInit @80 - rxevent_debugFile @81 DATA - rx_debugFile @82 DATA - rx_connDeadTime @83 DATA - rx_maxReceiveSize @84 DATA - rx_UdpBufSize @85 DATA - rx_extraQuota @86 DATA - rx_extraPackets @87 DATA - rx_tranquil @88 DATA - rx_getAllAddr @89 - rx_nWaiting @90 DATA - rx_stats @91 DATA - rx_SetNoJumbo @92 - rx_SetConnDeadTime @93 - rx_FlushWrite @94 - rx_thread_id_key @95 DATA - multi_Finalize @96 - multi_Select @97 - multi_Init @98 - multi_Finalize_Ignore @99 - add_to_error_table @100 - xdr_afsUUID @101 - rx_GetSpecific @102 - rx_SetSpecific @103 - rx_KeyCreate @104 - rx_BusyError @105 DATA - rx_BusyThreshold @106 DATA - rx_IncrementTimeAndCount @107 - rx_enable_stats @108 DATA - rx_GetServerDebug @109 - rx_GetServerStats @110 - rx_GetServerVersion @111 - rx_GetServerConnections @112 - rx_stats_mutex @113 DATA - rx_GetServerPeers @114 - rx_RetrieveProcessRPCStats @115 - rx_RetrievePeerRPCStats @116 - rx_FreeRPCStats @117 - rx_queryProcessRPCStats @118 - rx_queryPeerRPCStats @119 - rx_enableProcessRPCStats @120 - rx_enablePeerRPCStats @121 - rx_disableProcessRPCStats @122 - rx_disablePeerRPCStats @123 - RXSTATS_ExecuteRequest @124 - RXSTATS_RetrieveProcessRPCStats @125 - RXSTATS_RetrievePeerRPCStats @126 - RXSTATS_QueryProcessRPCStats @127 - RXSTATS_QueryPeerRPCStats @128 - RXSTATS_EnableProcessRPCStats @129 - RXSTATS_EnablePeerRPCStats @130 - RXSTATS_DisableProcessRPCStats @131 - RXSTATS_DisablePeerRPCStats @132 - RXSTATS_QueryRPCStatsVersion @133 - RXSTATS_ClearProcessRPCStats @134 - RXSTATS_ClearPeerRPCStats @135 - - - rxi_connAbortThreshhold @138 DATA - rxi_connAbortDelay @139 DATA - rxi_callAbortThreshhold @140 DATA - rxi_callAbortDelay @141 DATA - RXSTATS_function_names @142 DATA - RXAFSCB_function_names @143 DATA - RXAFSCB_CallBack @144 - StartRXAFSCB_CallBack @145 - EndRXAFSCB_CallBack @146 - RXAFSCB_InitCallBackState @147 - RXAFSCB_Probe @148 - StartRXAFSCB_Probe @149 - EndRXAFSCB_Probe @150 - RXAFSCB_GetLock @151 - RXAFSCB_GetCE @152 - RXAFSCB_XStatsVersion @153 - RXAFSCB_GetXStats @154 - RXAFSCB_InitCallBackState2 @155 - RXAFSCB_WhoAreYou @156 - RXAFSCB_InitCallBackState3 @157 - RXAFSCB_ProbeUuid @158 - StartRXAFSCB_ProbeUuid @159 - EndRXAFSCB_ProbeUuid @160 - RXAFSCB_GetServerPrefs @161 - RXAFSCB_GetCellServDB @162 - RXAFSCB_GetLocalCell @163 - RXAFSCB_GetCacheConfig @164 - StartRXAFS_FetchData @165 - EndRXAFS_FetchData @166 - RXAFS_FetchACL @167 - RXAFS_FetchStatus @168 - StartRXAFS_StoreData @169 - EndRXAFS_StoreData @170 - RXAFS_StoreACL @171 - RXAFS_StoreStatus @172 - RXAFS_RemoveFile @173 - RXAFS_CreateFile @174 - RXAFS_Rename @175 - RXAFS_Symlink @176 - RXAFS_Link @177 - RXAFS_MakeDir @178 - RXAFS_RemoveDir @179 - RXAFS_OldSetLock @180 - RXAFS_OldExtendLock @181 - RXAFS_OldReleaseLock @182 - RXAFS_GetStatistics @183 - RXAFS_GiveUpCallBacks @184 - RXAFS_GetVolumeInfo @185 - RXAFS_GetVolumeStatus @186 - RXAFS_SetVolumeStatus @187 - RXAFS_GetRootVolume @188 - RXAFS_CheckToken @189 - RXAFS_GetTime @190 - RXAFS_NGetVolumeInfo @191 - RXAFS_BulkStatus @192 - RXAFS_SetLock @193 - RXAFS_ExtendLock @194 - RXAFS_ReleaseLock @195 - RXAFS_XStatsVersion @196 - RXAFS_GetXStats @197 - RXAFS_Lookup @198 - RXAFS_FlushCPS @199 - RXAFS_DFSSymlink @200 - rx_SetRxStatUserOk @201 - rx_RxStatUserOk @202 - rx_enable_hot_thread @203 DATA - xdr_int64 @204 - xdr_uint64 @205 diff --git a/src/shlibafsrpc/afsrpc.rc b/src/shlibafsrpc/afsrpc.rc deleted file mode 100644 index 218fd55c0..000000000 --- a/src/shlibafsrpc/afsrpc.rc +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2000, International Business Machines Corporation and others. - * All Rights Reserved. - * - * This software has been released under the terms of the IBM Public - * License. For details, see the LICENSE file in the top-level source - * directory or online at http://www.openafs.org/dl/license10.html - */ - -/* Define VERSIONINFO resource */ - -#define AFS_VERINFO_FILE_DESCRIPTION "AFS Rx RPC DLL" -#define AFS_VERINFO_DLL -#define AFS_VERINFO_NAME "afsrpc" -#define AFS_VERINFO_FILENAME "afsrpc.dll" - -#include "AFS_component_version_number.h" -#include "..\config\NTVersioninfo.rc" diff --git a/src/sys/pioctl_nt.c b/src/sys/pioctl_nt.c index 33af2dcf9..7fcceb320 100644 --- a/src/sys/pioctl_nt.c +++ b/src/sys/pioctl_nt.c @@ -11,7 +11,7 @@ #include RCSID - ("$Header: /cvs/openafs/src/sys/pioctl_nt.c,v 1.18 2004/08/05 16:28:10 jaltman Exp $"); + ("$Header: /cvs/openafs/src/sys/pioctl_nt.c,v 1.18.2.2 2004/10/18 17:44:02 shadow Exp $"); #include #include @@ -98,6 +98,30 @@ InitFSRequest(fs_ioctlRequest_t * rp) rp->nbytes = 0; } +static BOOL +IoctlDebug(void) +{ + static int init = 0; + static BOOL debug = 0; + + if ( !init ) { + HKEY hk; + + if (RegOpenKey (HKEY_LOCAL_MACHINE, + TEXT("Software\\OpenAFS\\Client"), &hk) == 0) + { + DWORD dwSize = sizeof(BOOL); + DWORD dwType = REG_DWORD; + RegQueryValueEx (hk, TEXT("IoctlDebug"), NULL, &dwType, (PBYTE)&debug, &dwSize); + RegCloseKey (hk); + } + + init = 1; + } + + return debug; +} + static long GetIoctlHandle(char *fileNamep, HANDLE * handlep) { @@ -150,8 +174,8 @@ GetIoctlHandle(char *fileNamep, HANDLE * handlep) strcat(tbuffer, SMB_IOCTL_FILENAME_NOSLASH); } } - } - if (!tbuffer[0]) { + } + if (!tbuffer[0]) { /* No file name starting with drive colon specified, use UNC name */ lana_GetNetbiosName(netbiosName,LANA_NETBIOS_NAME_FULL); sprintf(tbuffer,"\\\\%s\\all%s",netbiosName,SMB_IOCTL_FILENAME); @@ -163,16 +187,34 @@ GetIoctlHandle(char *fileNamep, HANDLE * handlep) FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_WRITE_THROUGH, NULL); fflush(stdout); - if (fh == INVALID_HANDLE_VALUE) { + if (fh == INVALID_HANDLE_VALUE) { HKEY hk; char szUser[64] = ""; char szClient[MAX_PATH] = ""; char szPath[MAX_PATH] = ""; NETRESOURCE nr; DWORD res; - - if (GetLastError() != ERROR_DOWNGRADE_DETECTED) - return -1; + DWORD ioctlDebug = IoctlDebug(); + DWORD gle; + + gle = GetLastError(); + if (gle && ioctlDebug ) { + char buf[4096]; + + if ( FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + gle, + MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US), + buf, + 4096, + (va_list *) NULL + ) ) + { + fprintf(stderr,"pioctl CreateFile(%s) failed: [%s]\r\n",tbuffer,buf); + } + } + if (gle != ERROR_DOWNGRADE_DETECTED) + return -1; lana_GetNetbiosName(szClient, LANA_NETBIOS_NAME_FULL); sprintf(szPath, "\\\\%s", szClient); @@ -186,22 +228,46 @@ GetIoctlHandle(char *fileNamep, HANDLE * handlep) RegQueryValueEx (hk, TEXT("Logon User Name"), NULL, &dwType, (PBYTE)szUser, &dwSize); RegCloseKey (hk); } + if ( ioctlDebug ) + fprintf(stderr, "pioctl logon user: [%s]\r\n",szUser); memset (&nr, 0x00, sizeof(NETRESOURCE)); nr.dwType=RESOURCETYPE_DISK; nr.lpLocalName=0; nr.lpRemoteName=szPath; res = WNetAddConnection2(&nr,NULL,szUser,0); - if (res) + if (res) { + if ( ioctlDebug ) { + fprintf(stderr, "pioctl WNetAddConnection2(%s,%s) failed: 0x%X\r\n", + szPath,szUser,res); + } return -1; + } fh = CreateFile(tbuffer, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_WRITE_THROUGH, NULL); fflush(stdout); - if (fh == INVALID_HANDLE_VALUE) + if (fh == INVALID_HANDLE_VALUE) { + gle = GetLastError(); + if (gle && ioctlDebug ) { + char buf[4096]; + + if ( FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + gle, + MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US), + buf, + 4096, + (va_list *) NULL + ) ) + { + fprintf(stderr,"pioctl CreateFile(%s) failed: [%s]\r\n",tbuffer,buf); + } + } return -1; - } + } + } /* return fh and success code */ *handlep = fh; @@ -213,19 +279,31 @@ Transceive(HANDLE handle, fs_ioctlRequest_t * reqp) { long rcount; long ioCount; + DWORD gle; rcount = reqp->mp - reqp->data; - if (rcount <= 0) + if (rcount <= 0) { + if ( IoctlDebug() ) + fprintf(stderr, "pioctl Transceive rcount <= 0: %d\r\n",rcount); return EINVAL; /* not supposed to happen */ + } if (!WriteFile(handle, reqp->data, rcount, &ioCount, NULL)) { /* failed to write */ - return GetLastError(); + gle = GetLastError(); + + if ( IoctlDebug() ) + fprintf(stderr, "pioctl Transceive WriteFile failed: 0x%X\r\n",gle); + return gle; } if (!ReadFile(handle, reqp->data, sizeof(reqp->data), &ioCount, NULL)) { /* failed to read */ - return GetLastError(); + gle = GetLastError(); + + if ( IoctlDebug() ) + fprintf(stderr, "pioctl Transceive ReadFile failed: 0x%X\r\n",gle); + return gle; } reqp->nbytes = ioCount; /* set # of bytes available */ @@ -248,6 +326,9 @@ UnmarshallLong(fs_ioctlRequest_t * reqp, long *valp) { /* not enough data left */ if (reqp->nbytes < 4) { + if ( IoctlDebug() ) + fprintf(stderr, "pioctl UnmarshallLong reqp->nbytes < 4: %d\r\n", + reqp->nbytes); return -1; } @@ -269,8 +350,11 @@ MarshallString(fs_ioctlRequest_t * reqp, char *stringp) count = 1; /* watch for buffer overflow */ - if ((reqp->mp - reqp->data) + count > sizeof(reqp->data)) + if ((reqp->mp - reqp->data) + count > sizeof(reqp->data)) { + if ( IoctlDebug() ) + fprintf(stderr, "pioctl MarshallString buffer overflow\r\n"); return -1; + } if (stringp) memcpy(reqp->mp, stringp, count); @@ -338,15 +422,19 @@ fs_GetFullPath(char *pathp, char *outPathp, long outSize) newPath[2] = 0; if (!SetCurrentDirectory(newPath)) { code = GetLastError(); + + if ( IoctlDebug() ) + fprintf(stderr, "pioctl fs_GetFullPath SetCurrentDirectory(%s) failed: 0x%X\r\n", + newPath, code); return code; } } /* now get the absolute path to the current wdir in this drive */ GetCurrentDirectory(sizeof(tpath), tpath); - if (tpath[1] == ':') - strcpy(outPathp, tpath + 2); /* skip drive letter */ - else if ( tpath[0] == '\\' && tpath[1] == '\\') { + if (tpath[1] == ':') + strcpy(outPathp, tpath + 2); /* skip drive letter */ + else if ( tpath[0] == '\\' && tpath[1] == '\\') { /* UNC path - strip off the server and sharename */ int i, count; for ( i=2,count=2; count < 4 && tpath[i]; i++ ) { @@ -366,10 +454,10 @@ fs_GetFullPath(char *pathp, char *outPathp, long outSize) /* if there is a non-null name after the drive, append it */ if (*firstp != 0) { - int len = strlen(outPathp); - if (outPathp[len-1] != '\\' && outPathp[len-1] != '/') - strcat(outPathp, "\\"); - strcat(outPathp, firstp); + int len = strlen(outPathp); + if (outPathp[len-1] != '\\' && outPathp[len-1] != '/') + strcat(outPathp, "\\"); + strcat(outPathp, firstp); } /* finally, if necessary, switch back to our home drive letter */ @@ -433,10 +521,16 @@ pioctl(char *pathp, long opcode, struct ViceIoctl *blobp, int follow) } /* now unmarshall the return value */ - UnmarshallLong(&preq, &temp); + if (UnmarshallLong(&preq, &temp) != 0) { + CloseHandle(reqHandle); + return -1; + } + if (temp != 0) { CloseHandle(reqHandle); errno = CMtoUNIXerror(temp); + if ( IoctlDebug() ) + fprintf(stderr, "pioctl temp != 0: %d\r\n",temp); return -1; } diff --git a/src/ubik/Makefile.in b/src/ubik/Makefile.in index 8f2ee4113..018173863 100644 --- a/src/ubik/Makefile.in +++ b/src/ubik/Makefile.in @@ -10,7 +10,7 @@ include @TOP_OBJDIR@/src/config/Makefile.config LIBOBJS=disk.o remote.o beacon.o recovery.o ubik.o vote.o lock.o phys.o \ ubik_int.cs.o ubik_int.ss.o ubik_int.xdr.o ubikcmd.o \ - ubikclient.o uerrors.o + ubikclient.o uerrors.o uinit.o INCLS=${TOP_INCDIR}/lwp.h ${TOP_INCDIR}/lock.h \ ${TOP_INCDIR}/rx/rx.h ${TOP_INCDIR}/rx/xdr.h \ @@ -99,6 +99,7 @@ libubik.a: ${LIBOBJS} AFS_component_version_number.o $(RANLIB) $@ disk.o: disk.c ${INCLS} +uinit.o: uinit.c ${INCLS} remote.o: remote.c ${INCLS} beacon.o: beacon.c ${INCLS} lock.o: lock.c ${INCLS} diff --git a/src/ubik/NTMakefile b/src/ubik/NTMakefile index f3cfd550a..b81948450 100644 --- a/src/ubik/NTMakefile +++ b/src/ubik/NTMakefile @@ -31,6 +31,7 @@ LIBOBJS =\ $(OUT)\beacon.obj \ $(OUT)\recovery.obj \ $(OUT)\ubik.obj \ + $(OUT)\uinit.obj \ $(OUT)\vote.obj \ $(OUT)\lock.obj \ $(OUT)\phys.obj \ diff --git a/src/ubik/beacon.c b/src/ubik/beacon.c index 7c54c43fa..a161aa899 100644 --- a/src/ubik/beacon.c +++ b/src/ubik/beacon.c @@ -11,7 +11,7 @@ #include RCSID - ("$Header: /cvs/openafs/src/ubik/beacon.c,v 1.19.2.2 2004/08/25 07:11:03 shadow Exp $"); + ("$Header: /cvs/openafs/src/ubik/beacon.c,v 1.19.2.3 2004/10/18 17:44:03 shadow Exp $"); #include #ifdef AFS_NT40_ENV @@ -569,8 +569,7 @@ verifyInterfaceAddress(ame, info, aservers) for (j = 0, found = 0; j < count; j++) { for (i = 0; i < totalServers; i++) { if (info) - tmpAddr = - (afs_uint32) info->hostAddr[i].sin_addr.s_addr; + tmpAddr = (afs_uint32) info->hostAddr[i].sin_addr.s_addr; else tmpAddr = aservers[i]; if (myAddr[j] == tmpAddr) { diff --git a/src/ubik/ubik.p.h b/src/ubik/ubik.p.h index b72a82232..b69a66fe4 100644 --- a/src/ubik/ubik.p.h +++ b/src/ubik/ubik.p.h @@ -359,4 +359,15 @@ extern int ubik_BeginTrans(register struct ubik_dbase *dbase, afs_int32 transMode, struct ubik_trans **transPtr); extern int ubik_EndTrans(register struct ubik_trans *transPtr); +/* uinit.c */ + +extern afs_int32 ugen_ClientInit(int noAuthFlag, char *confDir, char *cellName, + afs_int32 sauth, + struct ubik_client **uclientp, + int (*secproc) (), char *funcName, + afs_int32 gen_rxkad_level, + afs_int32 maxservers, afs_int32 serviceid, + afs_int32 deadtime, afs_uint32 server, + afs_uint32 port, afs_int32 usrvid); + #endif /* UBIK_H */ diff --git a/src/ubik/udebug.c b/src/ubik/udebug.c index 0e4318aec..346d82d7d 100644 --- a/src/ubik/udebug.c +++ b/src/ubik/udebug.c @@ -11,7 +11,7 @@ #include RCSID - ("$Header: /cvs/openafs/src/ubik/udebug.c,v 1.16 2004/01/01 05:56:25 shadow Exp $"); + ("$Header: /cvs/openafs/src/ubik/udebug.c,v 1.16.2.1 2004/10/18 07:12:16 shadow Exp $"); #include #include @@ -97,7 +97,7 @@ CommandProc(struct cmd_syndesc *as, char *arock) register afs_int32 i, j, code; short port; int int32p; - afs_int32 now, diff, newtime; + time_t now, diff, newtime; struct hostent *th; struct rx_connection *tconn; struct rx_securityClass *sc; diff --git a/src/ubik/uinit.c b/src/ubik/uinit.c new file mode 100644 index 000000000..dd53bc95e --- /dev/null +++ b/src/ubik/uinit.c @@ -0,0 +1,206 @@ +/* + * Copyright 2000, International Business Machines Corporation and others. + * All Rights Reserved. + * + * This software has been released under the terms of the IBM Public + * License. For details, see the LICENSE file in the top-level source + * directory or online at http://www.openafs.org/dl/license10.html + */ + +#include +#include + +RCSID + ("$Header: /cvs/openafs/src/ubik/uinit.c,v 1.6.2.1 2004/10/18 07:12:16 shadow Exp $"); + +#include +#ifdef AFS_NT40_ENV +#include +#include +#else +#include +#include +#include +#include +#endif /* AFS_NT40_ENV */ +#include +#ifdef AFS_AIX_ENV +#include +#endif + +#ifdef HAVE_STRING_H +#include +#else +#ifdef HAVE_STRINGS_H +#include +#endif +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + Get the appropriate type of ubik client structure out from the system. +*/ +afs_int32 +ugen_ClientInit(int noAuthFlag, char *confDir, char *cellName, afs_int32 sauth, + struct ubik_client **uclientp, int (*secproc) (), + char *funcName, afs_int32 gen_rxkad_level, + afs_int32 maxservers, afs_int32 serviceid, afs_int32 deadtime, + afs_uint32 server, afs_uint32 port, afs_int32 usrvid) +{ + afs_int32 code, scIndex, i; + struct afsconf_cell info; + struct afsconf_dir *tdir; + struct ktc_principal sname; + struct ktc_token ttoken; + struct rx_securityClass *sc; + /* This must change if VLDB_MAXSERVERS becomes larger than MAXSERVERS */ + static struct rx_connection *serverconns[MAXSERVERS]; + char cellstr[64]; + + code = rx_Init(0); + if (code) { + fprintf(stderr, "%s: could not initialize rx.\n", funcName); + return code; + } + rx_SetRxDeadTime(deadtime); + + if (sauth) { /* -localauth */ + tdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH); + if (!tdir) { + fprintf(stderr, + "%s: Could not process files in configuration directory (%s).\n", + funcName, AFSDIR_SERVER_ETC_DIRPATH); + return -1; + } + code = afsconf_ClientAuth(tdir, &sc, &scIndex); /* sets sc,scIndex */ + if (code) { + fprintf(stderr, + "%s: Could not get security object for -localAuth\n", + funcName); + return -1; + } + code = + afsconf_GetCellInfo(tdir, tdir->cellName, serviceid, + &info); + if (code) { + fprintf(stderr, + "%s: can't find cell %s's hosts in %s/%s\n", + funcName, cellName, AFSDIR_SERVER_ETC_DIRPATH, + AFSDIR_CELLSERVDB_FILE); + exit(1); + } + } else { /* not -localauth */ + tdir = afsconf_Open(confDir); + if (!tdir) { + fprintf(stderr, + "%s: Could not process files in configuration directory (%s).\n", + funcName, confDir); + return -1; + } + + if (!cellName) { + code = afsconf_GetLocalCell(tdir, cellstr, sizeof(cellstr)); + if (code) { + fprintf(stderr, + "%s: can't get local cellname, check %s/%s\n", + funcName, confDir, AFSDIR_THISCELL_FILE); + exit(1); + } + cellName = cellstr; + } + + code = + afsconf_GetCellInfo(tdir, cellName, serviceid, &info); + if (code) { + fprintf(stderr, + "%s: can't find cell %s's hosts in %s/%s\n", + funcName, cellName, confDir, AFSDIR_CELLSERVDB_FILE); + exit(1); + } + if (noAuthFlag) /* -noauth */ + scIndex = 0; + else { /* not -noauth */ + strcpy(sname.cell, info.name); + sname.instance[0] = 0; + strcpy(sname.name, "afs"); + code = ktc_GetToken(&sname, &ttoken, sizeof(ttoken), NULL); + if (code) { /* did not get ticket */ + fprintf(stderr, + "%s: Could not get afs tokens, running unauthenticated.\n", + funcName); + scIndex = 0; + } else { /* got a ticket */ + scIndex = 2; + if ((ttoken.kvno < 0) || (ttoken.kvno > 256)) { + fprintf(stderr, + "%s: funny kvno (%d) in ticket, proceeding\n", + funcName, ttoken.kvno); + } + } + } + + switch (scIndex) { + case 0: + sc = rxnull_NewClientSecurityObject(); + break; + case 2: + sc = rxkad_NewClientSecurityObject(gen_rxkad_level, + &ttoken.sessionKey, + ttoken.kvno, ttoken.ticketLen, + ttoken.ticket); + break; + default: + fprintf(stderr, "%s: unsupported security index %d\n", + funcName, scIndex); + exit(1); + break; + } + } + + afsconf_Close(tdir); + + if (secproc) /* tell UV module about default authentication */ + (*secproc) (sc, scIndex); + if (server) { + serverconns[0] = rx_NewConnection(server, port, + usrvid, sc, scIndex); + } else { + if (info.numServers > maxservers) { + fprintf(stderr, + "%s: info.numServers=%d (> maxservers=%d)\n", + funcName, info.numServers, maxservers); + exit(1); + } + for (i = 0; i < info.numServers; i++) { + serverconns[i] = + rx_NewConnection(info.hostAddr[i].sin_addr.s_addr, + info.hostAddr[i].sin_port, usrvid, + sc, scIndex); + } + } + /* Are we just setting up connections, or is this really ubik stuff? */ + if (uclientp) { + *uclientp = 0; + code = ubik_ClientInit(serverconns, uclientp); + if (code) { + fprintf(stderr, "%s: ubik client init failed.\n", funcName); + return code; + } + } + return 0; +} + + diff --git a/src/util/Makefile.in b/src/util/Makefile.in index 924bae2c1..4ce6b9004 100644 --- a/src/util/Makefile.in +++ b/src/util/Makefile.in @@ -62,10 +62,10 @@ util.a: ${objects} AFS_component_version_number.o $(RANLIB) util.a assert.o: ${srcdir}/assert.c ${includes} - ${CC} ${CFLAGS} -c ${srcdir}/assert.c + ${CCOBJ} ${CFLAGS} -c ${srcdir}/assert.c casestrcpy.o: ${srcdir}/casestrcpy.c ${includes} - ${CC} ${CFLAGS} -c ${srcdir}/casestrcpy.c + ${CCOBJ} ${CFLAGS} -c ${srcdir}/casestrcpy.c hputil.o: ${srcdir}/hputil.c ${includes} ${CC} ${CFLAGS} -c ${srcdir}/hputil.c @@ -110,10 +110,10 @@ serverLog.o: ${srcdir}/serverLog.c ${includes} ${CC} ${CFLAGS} -c ${srcdir}/serverLog.c dirpath.o: ${srcdir}/dirpath.c ${includes} - ${CC} ${CFLAGS} -c ${srcdir}/dirpath.c + ${CCOBJ} ${CFLAGS} -c ${srcdir}/dirpath.c fileutil.o: ${srcdir}/fileutil.c ${includes} - ${CC} ${CFLAGS} -c ${srcdir}/fileutil.c + ${CCOBJ} ${CFLAGS} -c ${srcdir}/fileutil.c netutils.o: ${srcdir}/netutils.c ${includes} ${CC} ${CFLAGS} -c ${srcdir}/netutils.c diff --git a/src/util/ktime.c b/src/util/ktime.c index 492a59165..fe62da831 100644 --- a/src/util/ktime.c +++ b/src/util/ktime.c @@ -11,7 +11,7 @@ #include RCSID - ("$Header: /cvs/openafs/src/util/ktime.c,v 1.10 2003/11/29 21:38:03 jaltman Exp $"); + ("$Header: /cvs/openafs/src/util/ktime.c,v 1.10.2.1 2004/10/18 07:12:17 shadow Exp $"); #include #include @@ -165,7 +165,8 @@ ktime_DateOf(afs_int32 atime) { static char tbuffer[30]; register char *tp; - tp = ctime((time_t *) & atime); + time_t t = atime; + tp = ctime(&t); if (tp) { strcpy(tbuffer, tp); tbuffer[24] = 0; /* get rid of new line */ diff --git a/src/util/netutils.c b/src/util/netutils.c index 63563987f..9375eb3af 100644 --- a/src/util/netutils.c +++ b/src/util/netutils.c @@ -20,7 +20,7 @@ #endif RCSID - ("$Header: /cvs/openafs/src/util/netutils.c,v 1.13 2003/07/15 23:17:16 shadow Exp $"); + ("$Header: /cvs/openafs/src/util/netutils.c,v 1.13.2.1 2004/10/18 07:12:18 shadow Exp $"); #include #include @@ -53,6 +53,10 @@ RCSID #define MAX_NETFILE_LINE 2048 /* length of a line in the netrestrict file */ #define MAXIPADDRS 1024 /* from afsd.c */ +#ifndef INADDR_LOOPBACK +#define INADDR_LOOPBACK (afs_uint32)0x7f000001 +#endif + /* * The line parameter is a pointer to a buffer containing a string of * bytes of the form @@ -382,6 +386,11 @@ filterAddrs(afs_uint32 addr1[], afs_uint32 addr2[], afs_uint32 mask1[], break; } } + + /* Always mask loopback address */ + if (found && addr1[i] == INADDR_LOOPBACK) + found = 0; + if (found) { taddr[count] = addr1[i]; tmask[count] = mask1[i]; diff --git a/src/util/serverLog.c b/src/util/serverLog.c index bb8e90959..9f831c191 100644 --- a/src/util/serverLog.c +++ b/src/util/serverLog.c @@ -20,7 +20,7 @@ #include RCSID - ("$Header: /cvs/openafs/src/util/serverLog.c,v 1.22 2003/12/07 22:49:40 jaltman Exp $"); + ("$Header: /cvs/openafs/src/util/serverLog.c,v 1.22.2.1 2004/10/18 07:12:18 shadow Exp $"); #include #ifdef AFS_NT40_ENV @@ -235,8 +235,9 @@ OpenLog(const char *fileName) #endif if (mrafsStyleLogs) { + time_t t = Start.tv_sec; TM_GetTimeOfDay(&Start, 0); - TimeFields = localtime(&Start.tv_sec); + TimeFields = localtime(&t); if (fileName) { if (strncmp(fileName, (char *)&ourName, strlen(fileName))) strcpy((char *)&ourName, (char *)fileName); diff --git a/src/util/snprintf.c b/src/util/snprintf.c index caef48c8d..d9f5cfbb3 100644 --- a/src/util/snprintf.c +++ b/src/util/snprintf.c @@ -4,7 +4,7 @@ #include RCSID - ("$Header: /cvs/openafs/src/util/snprintf.c,v 1.21.2.1 2004/08/09 20:57:10 shadow Exp $"); + ("$Header: /cvs/openafs/src/util/snprintf.c,v 1.21.2.2 2004/10/18 17:44:05 shadow Exp $"); #include #include @@ -436,9 +436,11 @@ afs_vsnprintf(char *p, size_t avail, const char *fmt, va_list ap) } else { x = "%u.%u.%u.%u"; } - sprintf(xbuf, x, (UVAL & 0xff000000) >> 24, - (UVAL & 0x00ff0000) >> 16, (UVAL & 0x0000ff00) >> 8, - (UVAL & 0x000000ff)); + /* typecast to whatever '%u' is! */ + sprintf(xbuf, x, (unsigned int)((UVAL & 0xff000000) >> 24), + (unsigned int)((UVAL & 0x00ff0000) >> 16), + (unsigned int)((UVAL & 0x0000ff00) >> 8), + (unsigned int)(UVAL & 0x000000ff)); x = xbuf; len = strlen(xbuf); } diff --git a/src/venus/fs.c b/src/venus/fs.c index 89143d6f9..ce06bce0f 100644 --- a/src/venus/fs.c +++ b/src/venus/fs.c @@ -11,7 +11,7 @@ #include RCSID - ("$Header: /cvs/openafs/src/venus/fs.c,v 1.24 2004/06/02 06:57:37 shadow Exp $"); + ("$Header: /cvs/openafs/src/venus/fs.c,v 1.24.2.1 2004/10/18 07:12:20 shadow Exp $"); #include #include @@ -724,7 +724,7 @@ AclToString(struct Acl *acl) } static int -SetACLCmd(struct cmd_syndesc *as) +SetACLCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code; struct ViceIoctl blob; @@ -858,7 +858,7 @@ SetACLCmd(struct cmd_syndesc *as) static int -CopyACLCmd(struct cmd_syndesc *as) +CopyACLCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code; struct ViceIoctl blob; @@ -1038,7 +1038,7 @@ CleanAcl(struct Acl *aa, char *fname) /* clean up an acl to not have bogus entries */ static int -CleanACLCmd(struct cmd_syndesc *as) +CleanACLCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code; struct Acl *ta = 0; @@ -1125,7 +1125,7 @@ CleanACLCmd(struct cmd_syndesc *as) } static int -ListACLCmd(struct cmd_syndesc *as) +ListACLCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code; struct Acl *ta; @@ -1189,7 +1189,7 @@ ListACLCmd(struct cmd_syndesc *as) } static int -FlushVolumeCmd(struct cmd_syndesc *as) +FlushVolumeCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code; struct ViceIoctl blob; @@ -1211,7 +1211,7 @@ FlushVolumeCmd(struct cmd_syndesc *as) } static int -FlushCmd(struct cmd_syndesc *as) +FlushCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code; struct ViceIoctl blob; @@ -1238,7 +1238,7 @@ FlushCmd(struct cmd_syndesc *as) /* all this command does is repackage its args and call SetVolCmd */ static int -SetQuotaCmd(struct cmd_syndesc *as) +SetQuotaCmd(struct cmd_syndesc *as, char *arock) { struct cmd_syndesc ts; @@ -1248,7 +1248,7 @@ SetQuotaCmd(struct cmd_syndesc *as) } static int -SetVolCmd(struct cmd_syndesc *as) +SetVolCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code; struct ViceIoctl blob; @@ -1312,7 +1312,7 @@ struct VenusFid { }; static int -ExamineCmd(struct cmd_syndesc *as) +ExamineCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code; struct ViceIoctl blob; @@ -1353,7 +1353,7 @@ ExamineCmd(struct cmd_syndesc *as) } static int -ListQuotaCmd(struct cmd_syndesc *as) +ListQuotaCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code; struct ViceIoctl blob; @@ -1384,7 +1384,7 @@ ListQuotaCmd(struct cmd_syndesc *as) } static int -WhereIsCmd(struct cmd_syndesc *as) +WhereIsCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code; struct ViceIoctl blob; @@ -1423,7 +1423,7 @@ WhereIsCmd(struct cmd_syndesc *as) static int -DiskFreeCmd(struct cmd_syndesc *as) +DiskFreeCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code; struct ViceIoctl blob; @@ -1454,7 +1454,7 @@ DiskFreeCmd(struct cmd_syndesc *as) } static int -QuotaCmd(struct cmd_syndesc *as) +QuotaCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code; struct ViceIoctl blob; @@ -1487,7 +1487,7 @@ QuotaCmd(struct cmd_syndesc *as) } static int -ListMountCmd(struct cmd_syndesc *as) +ListMountCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code; struct ViceIoctl blob; @@ -1608,7 +1608,7 @@ ListMountCmd(struct cmd_syndesc *as) } static -MakeMountCmd(struct cmd_syndesc *as) +MakeMountCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code; char *cellName, *volName, *tmpName; @@ -1716,7 +1716,7 @@ defect #3069 * tp: Set to point to the actual name of the mount point to nuke. */ static int -RemoveMountCmd(struct cmd_syndesc *as) +RemoveMountCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code = 0; struct ViceIoctl blob; @@ -1768,7 +1768,7 @@ RemoveMountCmd(struct cmd_syndesc *as) */ static int -CheckServersCmd(struct cmd_syndesc *as) +CheckServersCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code; struct ViceIoctl blob; @@ -1867,7 +1867,7 @@ CheckServersCmd(struct cmd_syndesc *as) } static int -MessagesCmd(struct cmd_syndesc *as) +MessagesCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code = 0; struct ViceIoctl blob; @@ -1913,7 +1913,7 @@ MessagesCmd(struct cmd_syndesc *as) } static int -CheckVolumesCmd(struct cmd_syndesc *as) +CheckVolumesCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code; struct ViceIoctl blob; @@ -1931,7 +1931,7 @@ CheckVolumesCmd(struct cmd_syndesc *as) } static int -SetCacheSizeCmd(struct cmd_syndesc *as) +SetCacheSizeCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code; struct ViceIoctl blob; @@ -1970,7 +1970,7 @@ SetCacheSizeCmd(struct cmd_syndesc *as) #define MAXGCSIZE 16 static int -GetCacheParmsCmd(struct cmd_syndesc *as) +GetCacheParmsCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code; struct ViceIoctl blob; @@ -1995,7 +1995,7 @@ GetCacheParmsCmd(struct cmd_syndesc *as) } static int -ListCellsCmd(struct cmd_syndesc *as) +ListCellsCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code; afs_int32 i, j; @@ -2046,7 +2046,7 @@ ListCellsCmd(struct cmd_syndesc *as) } static int -ListAliasesCmd(struct cmd_syndesc *as) +ListAliasesCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code, i; char *tp, *aliasName, *realName; @@ -2076,7 +2076,7 @@ ListAliasesCmd(struct cmd_syndesc *as) } static int -CallBackRxConnCmd(struct cmd_syndesc *as) +CallBackRxConnCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code; struct ViceIoctl blob; @@ -2115,7 +2115,7 @@ CallBackRxConnCmd(struct cmd_syndesc *as) } static int -NewCellCmd(struct cmd_syndesc *as) +NewCellCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code, linkedstate = 0, size = 0, *lp; struct ViceIoctl blob; @@ -2227,7 +2227,7 @@ NewCellCmd(struct cmd_syndesc *as) } static int -NewAliasCmd(struct cmd_syndesc *as) +NewAliasCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code; struct ViceIoctl blob; @@ -2262,7 +2262,7 @@ NewAliasCmd(struct cmd_syndesc *as) } static int -WhichCellCmd(struct cmd_syndesc *as) +WhichCellCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code; struct cmd_item *ti; @@ -2287,7 +2287,7 @@ WhichCellCmd(struct cmd_syndesc *as) } static int -WSCellCmd(struct cmd_syndesc *as) +WSCellCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code; struct ViceIoctl blob; @@ -2317,7 +2317,7 @@ static PrimaryCellCmd(as) */ static int -MonitorCmd(struct cmd_syndesc *as) +MonitorCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code; struct ViceIoctl blob; @@ -2378,7 +2378,7 @@ MonitorCmd(struct cmd_syndesc *as) } static int -SysNameCmd(struct cmd_syndesc *as) +SysNameCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code; struct ViceIoctl blob; @@ -2432,7 +2432,7 @@ SysNameCmd(struct cmd_syndesc *as) static char *exported_types[] = { "null", "nfs", "" }; static int -ExportAfsCmd(struct cmd_syndesc *as) +ExportAfsCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code; struct ViceIoctl blob; @@ -2531,7 +2531,7 @@ ExportAfsCmd(struct cmd_syndesc *as) static int -GetCellCmd(struct cmd_syndesc *as) +GetCellCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code; struct ViceIoctl blob; @@ -2582,7 +2582,7 @@ GetCellCmd(struct cmd_syndesc *as) } static int -SetCellCmd(struct cmd_syndesc *as) +SetCellCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code; struct ViceIoctl blob; @@ -2659,75 +2659,14 @@ static int VLDBInit(int noAuthFlag, struct afsconf_cell *info) { afs_int32 code; - struct ktc_principal sname; - struct ktc_token ttoken; - afs_int32 scIndex; - struct rx_securityClass *sc; - struct rx_connection *serverconns[VLDB_MAXSERVERS]; - afs_int32 i; - - code = rx_Init(0); - if (code) { - fprintf(stderr, "%s: could not initialize rx.\n", pn); - return code; - } - rxInitDone = 1; - rx_SetRxDeadTime(50); - if (!noAuthFlag) { /* we don't need tickets for null */ - strcpy(sname.cell, info->name); - sname.instance[0] = 0; - strcpy(sname.name, "afs"); - code = ktc_GetToken(&sname, &ttoken, sizeof(ttoken), NULL); - if (code) { - fprintf(stderr, - "%s: Could not get afs tokens, running unauthenticated.\n", - pn); - scIndex = 0; - } else { - /* got a ticket */ - if (ttoken.kvno >= 0 && ttoken.kvno <= 255) - scIndex = 2; /* kerberos */ - else { - fprintf(stderr, "%s: funny kvno (%d) in ticket, proceeding\n", - pn, ttoken.kvno); - scIndex = 2; - } - } - } else - scIndex = 0; /* don't authenticate */ - switch (scIndex) { - case 0: - sc = rxnull_NewClientSecurityObject(); - break; - case 1: - break; - case 2: - sc = (struct rx_securityClass *) - rxkad_NewClientSecurityObject(rxkad_clear, &ttoken.sessionKey, - ttoken.kvno, ttoken.ticketLen, - ttoken.ticket); - break; - } - if (info->numServers > VLDB_MAXSERVERS) { - fprintf(stderr, "%s: info.numServers=%d (> VLDB_MAXSERVERS=%d)\n", pn, - info->numServers, VLDB_MAXSERVERS); - exit(1); - } - memset(serverconns, 0, sizeof(serverconns)); - for (i = 0; i < info->numServers; i++) - serverconns[i] = - rx_NewConnection(info->hostAddr[i].sin_addr.s_addr, - info->hostAddr[i].sin_port, USER_SERVICE_ID, sc, - scIndex); - - code = ubik_ClientInit(serverconns, &uclient); - - if (code) { - fprintf(stderr, "%s: ubik client init failed.\n", pn); - return code; - } - return 0; + code = ugen_ClientInit(noAuthFlag, AFSDIR_CLIENT_ETC_DIRPATH, + info->name, 0, &uclient, + NULL, pn, rxkad_clear, + VLDB_MAXSERVERS, AFSCONF_VLDBSERVICE, 50, + 0, 0, USER_SERVICE_ID); + rxInitDone = 1; + return code; } static struct ViceIoctl gblob; @@ -2827,7 +2766,7 @@ addServer(char *name, afs_int32 rank) static int -SetPrefCmd(struct cmd_syndesc *as) +SetPrefCmd(struct cmd_syndesc *as, char *arock) { FILE *infd; afs_int32 code; @@ -2933,7 +2872,7 @@ SetPrefCmd(struct cmd_syndesc *as) static int -GetPrefCmd(struct cmd_syndesc *as) +GetPrefCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code; struct cmd_item *ti; @@ -3003,7 +2942,7 @@ GetPrefCmd(struct cmd_syndesc *as) } static int -StoreBehindCmd(struct cmd_syndesc *as) +StoreBehindCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code = 0; struct ViceIoctl blob; @@ -3104,7 +3043,7 @@ StoreBehindCmd(struct cmd_syndesc *as) static afs_int32 -SetCryptCmd(struct cmd_syndesc *as) +SetCryptCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code = 0, flag; struct ViceIoctl blob; @@ -3131,7 +3070,7 @@ SetCryptCmd(struct cmd_syndesc *as) static afs_int32 -GetCryptCmd(struct cmd_syndesc *as) +GetCryptCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code = 0, flag; struct ViceIoctl blob; @@ -3511,7 +3450,7 @@ Die(int errnum, char *filename) /* get clients interface addresses */ static int -GetClientAddrsCmd(struct cmd_syndesc *as) +GetClientAddrsCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code; struct cmd_item *ti; @@ -3557,7 +3496,7 @@ GetClientAddrsCmd(struct cmd_syndesc *as) } static int -SetClientAddrsCmd(struct cmd_syndesc *as) +SetClientAddrsCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code, addr; struct cmd_item *ti; @@ -3631,7 +3570,7 @@ SetClientAddrsCmd(struct cmd_syndesc *as) } static int -FlushMountCmd(struct cmd_syndesc *as) +FlushMountCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code; struct ViceIoctl blob; @@ -3747,7 +3686,7 @@ FlushMountCmd(struct cmd_syndesc *as) } static int -RxStatProcCmd(struct cmd_syndesc *as) +RxStatProcCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code; afs_int32 flags = 0; @@ -3782,7 +3721,7 @@ RxStatProcCmd(struct cmd_syndesc *as) } static int -RxStatPeerCmd(struct cmd_syndesc *as) +RxStatPeerCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code; afs_int32 flags = 0; diff --git a/src/viced/callback.c b/src/viced/callback.c index 59a7f7c40..e28fca63d 100644 --- a/src/viced/callback.c +++ b/src/viced/callback.c @@ -83,7 +83,7 @@ #include RCSID - ("$Header: /cvs/openafs/src/viced/callback.c,v 1.55 2003/12/08 01:45:34 jaltman Exp $"); + ("$Header: /cvs/openafs/src/viced/callback.c,v 1.55.2.1 2004/10/18 07:12:22 shadow Exp $"); #include #include /* for malloc() */ @@ -776,6 +776,7 @@ MultiBreakCallBack_r(struct cbstruct cba[], int ncbas, if (!thishost || (thishost->hostFlags & HOSTDELETED)) { continue; } + rx_GetConnection(thishost->callback_rxcon); conns[j++] = thishost->callback_rxcon; #ifdef ADAPT_MTU @@ -832,14 +833,14 @@ MultiBreakCallBack_r(struct cbstruct cba[], int ncbas, } H_LOCK; - h_Lock_r(hp); + h_Lock_r(hp); hp->hostFlags |= VENUSDOWN; /** * We always go into AddCallBack1_r with the host locked */ AddCallBack1_r(hp, afidp->AFSCBFids_val, itot(idx), CB_DELAYED, 1); - h_Unlock_r(hp); + h_Unlock_r(hp); H_UNLOCK; } } @@ -853,8 +854,10 @@ MultiBreakCallBack_r(struct cbstruct cba[], int ncbas, for (i = 0; i < ncbas; i++) { struct host *hp; hp = cba[i].hp; - if (hp && xhost != hp) + if (hp && xhost != hp) { + rx_PutConnection(hp->callback_rxcon); h_Release_r(hp); + } } return; diff --git a/src/viced/host.c b/src/viced/host.c index 69a36eff6..8e4fc8220 100644 --- a/src/viced/host.c +++ b/src/viced/host.c @@ -11,7 +11,7 @@ #include RCSID - ("$Header: /cvs/openafs/src/viced/host.c,v 1.57 2004/08/05 14:48:09 shadow Exp $"); + ("$Header: /cvs/openafs/src/viced/host.c,v 1.57.2.1 2004/10/18 07:12:22 shadow Exp $"); #include #include @@ -781,6 +781,7 @@ h_TossStuff_r(register struct host *host) *hp = th->next; h_DeleteList_r(host); FreeHT(host); + free(th); break; } } diff --git a/src/viced/viced.c b/src/viced/viced.c index b7dbf3f9c..6483ec457 100644 --- a/src/viced/viced.c +++ b/src/viced/viced.c @@ -20,7 +20,7 @@ #include RCSID - ("$Header: /cvs/openafs/src/viced/viced.c,v 1.58 2004/03/24 17:36:57 shadow Exp $"); + ("$Header: /cvs/openafs/src/viced/viced.c,v 1.58.2.1 2004/10/18 07:12:24 shadow Exp $"); #include #include @@ -1564,6 +1564,7 @@ main(int argc, char *argv[]) struct rlimit rlim; /* max number of open file descriptors */ #endif int curLimit; + time_t t; #ifdef AFS_AIX32_ENV struct sigaction nsa; @@ -1868,9 +1869,10 @@ main(int argc, char *argv[]) TM_GetTimeOfDay(&tp, 0); #ifndef AFS_QUIETFS_ENV - if (console != NULL) { + if (console != NULL) { + time_t t = tp.tv_sec; fprintf(console, "File server has started at %s\r", - afs_ctime(&tp.tv_sec, tbuffer, sizeof(tbuffer))); + afs_ctime(&t, tbuffer, sizeof(tbuffer))); } #endif @@ -1907,9 +1909,10 @@ main(int argc, char *argv[]) (void)signal(SIGQUIT, ShutDown_Signal); #endif + t = tp.tv_sec; ViceLog(0, ("File Server started %s", - afs_ctime(&tp.tv_sec, tbuffer, sizeof(tbuffer)))); + afs_ctime(&t, tbuffer, sizeof(tbuffer)))); #if FS_STATS_DETAILED afs_FullPerfStats.det.epoch.tv_sec = StartTime = tp.tv_sec; #endif diff --git a/src/vlserver/vlclient.c b/src/vlserver/vlclient.c index 9e1dae583..26b006531 100644 --- a/src/vlserver/vlclient.c +++ b/src/vlserver/vlclient.c @@ -11,7 +11,7 @@ #include RCSID - ("$Header: /cvs/openafs/src/vlserver/vlclient.c,v 1.12 2003/12/07 22:49:42 jaltman Exp $"); + ("$Header: /cvs/openafs/src/vlserver/vlclient.c,v 1.12.2.1 2004/10/18 07:12:25 shadow Exp $"); #include #include @@ -162,102 +162,17 @@ GetVolume(vol, entry) /* Almost identical's to pr_Initialize in vlserver/pruser.c */ afs_int32 -vl_Initialize(auth, confDir, server, cellp) - int auth, server; - char *confDir, *cellp; +vl_Initialize(int auth, char *confDir, int server, char *cellp) { - afs_int32 code; - struct afsconf_dir *tdir; - struct ktc_principal sname; - struct ktc_token ttoken; - afs_int32 scIndex = 0; - struct rx_securityClass *sc; - struct afsconf_cell info; - afs_int32 i; - - code = rx_Init(0); - if (code) { - fprintf(stderr, "vl_Initialize: Could not initialize rx.\n"); - return code; - } - - rx_SetRxDeadTime(50); - if (!server) { - tdir = afsconf_Open(confDir); - if (!tdir) { - fprintf(stderr, "Could not open configuration directory (%s).\n", - confDir); - return -1; - } - } - if (auth) { /* we don't need tickets for null */ - if (!server) { - code = afsconf_GetLocalCell(tdir, sname.cell, sizeof(sname.cell)); - if (code) { - fprintf(stderr, - "vl_Initialize: Could not get local cell name.\n"); - return code; - } - } else - strncpy(sname.cell, cellp, sizeof(sname.cell)); - sname.instance[0] = 0; - strcpy(sname.name, "afs"); - code = ktc_GetToken(&sname, &ttoken, sizeof(ttoken), NULL); - if (code) { - fprintf(stderr, - "vl_Initialize: Could not get afs tokens, running unauthenticated.\n"); - scIndex = 0; - } else if (ttoken.kvno <= 255) - scIndex = 2; - else { /* bcrypt */ - fprintf(stderr, - "vl_Initialize: funny kvno (%d) in ticket, proceeding\n", - ttoken.kvno); - scIndex = 2; - } - } - switch (scIndex) { - case 0: - sc = rxnull_NewClientSecurityObject(); - break; - case 1: - return -1; - case 2: - sc = rxkad_NewClientSecurityObject(rxkad_clear, &ttoken.sessionKey, - ttoken.kvno, ttoken.ticketLen, - ttoken.ticket); - } - if (!server) { - code = afsconf_GetCellInfo(tdir, NULL, AFSCONF_VLDBSERVICE, &info); - if (info.numServers > MAXSERVERS) { - fprintf(stderr, - "vl_Initialize: info.numServers=%d (> MAXSERVERS=%d)\n", - info.numServers, MAXSERVERS); - exit(1); - } - for (i = 0; i < info.numServers; i++) - serverconns[i] = - rx_NewConnection(info.hostAddr[i].sin_addr.s_addr, - info.hostAddr[i].sin_port, USER_SERVICE_ID, - sc, scIndex); - } else { - serverconns[0] = - rx_NewConnection(server, htons(AFSCONF_VLDBPORT), USER_SERVICE_ID, - sc, scIndex); - } - code = ubik_ClientInit(serverconns, &cstruct); - - if (code) { - fprintf(stderr, "vl_Initialize: ubik client init failed.\n"); - return code; - } - return 0; + return ugen_ClientInit(auth?0:1, confDir, cellp, 0, + &cstruct, NULL, "vl_Initialize", rxkad_clear, + MAXSERVERS, AFSCONF_VLDBSERVICE, 50, server, + htons(AFSCONF_VLDBPORT), USER_SERVICE_ID); } /* return host address in network byte order */ afs_int32 -GetServer(aname) - char *aname; +GetServer(char *aname) { register struct hostent *th; afs_int32 addr; diff --git a/src/vol/listinodes.c b/src/vol/listinodes.c index d3d4ca456..61b149018 100644 --- a/src/vol/listinodes.c +++ b/src/vol/listinodes.c @@ -21,7 +21,7 @@ #include RCSID - ("$Header: /cvs/openafs/src/vol/listinodes.c,v 1.13 2003/07/15 23:17:39 shadow Exp $"); + ("$Header: /cvs/openafs/src/vol/listinodes.c,v 1.13.2.1 2004/10/18 07:12:27 shadow Exp $"); #ifndef AFS_NAMEI_ENV #if defined(AFS_LINUX20_ENV) || defined(AFS_SUN4_ENV) @@ -35,7 +35,7 @@ RCSID int ListViceInodes(char *devname, char *mountedOn, char *resultFile, int (*judgeInode) (), int judgeParam, int *forcep, int forceR, - char *wpath) + char *wpath, void *rock) { Log("ListViceInodes not implemented for this platform!\n"); return -1; @@ -167,7 +167,7 @@ struct dinode *ginode(); int ListViceInodes(char *devname, char *mountedOn, char *resultFile, int (*judgeInode) (), int judgeParam, int *forcep, int forceR, - char *wpath) + char *wpath, void *rock) { FILE *inodeFile = NULL; char dev[50], rdev[51]; @@ -301,7 +301,7 @@ ListViceInodes(char *devname, char *mountedOn, char *resultFile, info.u.param[2] = p->di_vicep3; info.u.param[3] = p->di_vicep4; - if (judgeInode && (*judgeInode) (&info, judgeParam) == 0) + if (judgeInode && (*judgeInode) (&info, judgeParam, rock) == 0) continue; if (fwrite(&info, sizeof info, 1, inodeFile) != 1) { @@ -469,7 +469,7 @@ afs_efs_figet(EFS_MOUNT * mp, struct efs_dinode *dinodeBuf, int *last_cgno, int efs_ListViceInodes(char *devname, char *mountedOn, char *resultFile, int (*judgeInode) (), int judgeParam, int *forcep, - int forceR, char *wpath) + int forceR, char *wpath, void *rock) { FILE *inodeFile = NULL; char dev[50], rdev[51]; @@ -570,7 +570,7 @@ efs_ListViceInodes(char *devname, char *mountedOn, char *resultFile, p->di_nlink, info.u.param[0], info.u.param[1], info.u.param[2], info.u.param[3]); #endif - if (judgeInode && (*judgeInode) (&info, judgeParam) == 0) + if (judgeInode && (*judgeInode) (&info, judgeParam, rock) == 0) continue; if (fwrite(&info, sizeof info, 1, inodeFile) != 1) { @@ -823,7 +823,7 @@ xfs_RenameFiles(char *dir, xfs_Rename_t * renames, int n_renames) int xfs_ListViceInodes(char *devname, char *mountedOn, char *resultFile, int (*judgeInode) (), int judgeParam, int *forcep, - int forceR, char *wpath) + int forceR, char *wpath, void *rock) { FILE *inodeFile = NULL; i_list_inode_t info; @@ -931,7 +931,7 @@ xfs_ListViceInodes(char *devname, char *mountedOn, char *resultFile, goto err1_exit; } - if (judgeInode && (*judgeInode) (&info.ili_info, judgeParam) == 0) + if (judgeInode && (*judgeInode) (&info.ili_info, judgeParam, rock) == 0) continue; rename = 0; @@ -1039,7 +1039,7 @@ xfs_ListViceInodes(char *devname, char *mountedOn, char *resultFile, int ListViceInodes(char *devname, char *mountedOn, char *resultFile, int (*judgeInode) (), int judgeParam, int *forcep, int forceR, - char *wpath) + char *wpath, void *rock) { FILE *inodeFile = NULL; char dev[50], rdev[51]; @@ -1070,13 +1070,13 @@ ListViceInodes(char *devname, char *mountedOn, char *resultFile, #ifdef AFS_SGI_XFS_IOPS_ENV if (!strcmp("xfs", root_inode.st_fstype)) { return xfs_ListViceInodes(devname, mountedOn, resultFile, judgeInode, - judgeParam, forcep, forceR, wpath); + judgeParam, forcep, forceR, wpath, rock); } else #endif #ifdef AFS_SGI_EFS_IOPS_ENV if (root_inode.st_ino == EFS_ROOTINO) { return efs_ListViceInodes(devname, mountedOn, resultFile, judgeInode, - judgeParam, forcep, forceR, wpath); + judgeParam, forcep, forceR, wpath, rock); } else #endif { @@ -1114,7 +1114,7 @@ extern char *afs_rawname(); int ListViceInodes(char *devname, char *mountedOn, char *resultFile, int (*judgeInode) (), int judgeParam, int *forcep, int forceR, - char *wpath) + char *wpath, void *rock) { union { #ifdef AFS_AIX_ENV @@ -1212,7 +1212,7 @@ ListViceInodes(char *devname, char *mountedOn, char *resultFile, info.u.param[1] = auxp->aux_param2; info.u.param[2] = auxp->aux_param3; info.u.param[3] = auxp->aux_param4; - if (judgeInode && (*judgeInode) (&info, judgeParam) == 0) + if (judgeInode && (*judgeInode) (&info, judgeParam, rock) == 0) continue; if (fwrite(&info, sizeof info, 1, inodeFile) != 1) { Log("Error writing inode file for partition %s\n", partition); @@ -1421,7 +1421,7 @@ ListViceInodes(char *devname, char *mountedOn, char *resultFile, info.inodeNumber = i; info.byteCount = p->di_size; info.linkCount = p->di_nlink; - if (judgeInode && (*judgeInode) (&info, judgeParam) == 0) + if (judgeInode && (*judgeInode) (&info, judgeParam, rock) == 0) continue; if (fwrite(&info, sizeof info, 1, inodeFile) != 1) { Log("Error writing inode file for partition %s\n", diff --git a/src/vol/namei_ops.c b/src/vol/namei_ops.c index 0b9858cc1..7b7a9c191 100644 --- a/src/vol/namei_ops.c +++ b/src/vol/namei_ops.c @@ -13,7 +13,7 @@ #include RCSID - ("$Header: /cvs/openafs/src/vol/namei_ops.c,v 1.21.2.1 2004/08/25 07:14:19 shadow Exp $"); + ("$Header: /cvs/openafs/src/vol/namei_ops.c,v 1.21.2.2 2004/10/18 17:44:06 shadow Exp $"); #ifdef AFS_NAMEI_ENV #include @@ -1041,8 +1041,8 @@ static int namei_ListAFSSubDirs(IHandle_t * dirIH, struct ViceInodeInfo *, char *, char *), FILE * fp, int (*judgeFun) (struct ViceInodeInfo *, - int vid), - int singleVolumeNumber); + int vid, void *), + int singleVolumeNumber, void *rock); /* WriteInodeInfo @@ -1093,8 +1093,9 @@ VerifyDirPerms(char *path) */ int ListViceInodes(char *devname, char *mountedOn, char *resultFile, - int (*judgeInode) (struct ViceInodeInfo * info, int vid), - int singleVolumeNumber, int *forcep, int forceR, char *wpath) + int (*judgeInode) (struct ViceInodeInfo * info, int vid, void *rock), + int singleVolumeNumber, int *forcep, int forceR, char *wpath, + void *rock) { FILE *fp = (FILE *) - 1; int ninodes; @@ -1114,7 +1115,7 @@ ListViceInodes(char *devname, char *mountedOn, char *resultFile, ninodes = namei_ListAFSFiles(mountedOn, WriteInodeInfo, fp, judgeInode, - singleVolumeNumber); + singleVolumeNumber, rock); if (!resultFile) return ninodes; @@ -1167,8 +1168,8 @@ int namei_ListAFSFiles(char *dev, int (*writeFun) (FILE *, struct ViceInodeInfo *, char *, char *), FILE * fp, - int (*judgeFun) (struct ViceInodeInfo *, int), - int singleVolumeNumber) + int (*judgeFun) (struct ViceInodeInfo *, int, void *), + int singleVolumeNumber, void *rock) { IHandle_t ih; namei_t name; @@ -1188,7 +1189,7 @@ namei_ListAFSFiles(char *dev, namei_HandleToVolDir(&name, &ih); ninodes = namei_ListAFSSubDirs(&ih, writeFun, fp, judgeFun, - singleVolumeNumber); + singleVolumeNumber, rock); if (ninodes < 0) return ninodes; } else { @@ -1212,7 +1213,7 @@ namei_ListAFSFiles(char *dev, if (!DecodeVolumeName(dp2->d_name, &ih.ih_vid)) { ninodes += namei_ListAFSSubDirs(&ih, writeFun, fp, judgeFun, - 0); + 0, rock); } } closedir(dirp2); @@ -1239,8 +1240,8 @@ static int namei_ListAFSSubDirs(IHandle_t * dirIH, int (*writeFun) (FILE *, struct ViceInodeInfo *, char *, char *), FILE * fp, - int (*judgeFun) (struct ViceInodeInfo *, int), - int singleVolumeNumber) + int (*judgeFun) (struct ViceInodeInfo *, int, void *), + int singleVolumeNumber, void *rock) { IHandle_t myIH = *dirIH; namei_t name; @@ -1283,7 +1284,7 @@ namei_ListAFSSubDirs(IHandle_t * dirIH, info.linkCount = namei_GetLinkCount(&linkHandle, (Inode) 0, 0); } - if (judgeFun && !(*judgeFun) (&info, singleVolumeNumber)) + if (judgeFun && !(*judgeFun) (&info, singleVolumeNumber, rock)) continue; if ((*writeFun) (fp, &info, path1, dp1->d_name) < 0) { @@ -1345,7 +1346,7 @@ namei_ListAFSSubDirs(IHandle_t * dirIH, continue; } if (judgeFun - && !(*judgeFun) (&info, singleVolumeNumber)) + && !(*judgeFun) (&info, singleVolumeNumber, rock)) continue; if ((*writeFun) (fp, &info, path3, dp3->d_name) < diff --git a/src/vol/namei_ops.h b/src/vol/namei_ops.h index 64a476655..9f0df4a92 100644 --- a/src/vol/namei_ops.h +++ b/src/vol/namei_ops.h @@ -50,11 +50,13 @@ int namei_ListAFSFiles(char *dev, struct ViceInodeInfo * info, char *dir, char *file), FILE * fp, int (*judge_fun) (struct ViceInodeInfo * info, - int vid), int singleVolumeNumber); + int vid, void *rock), + int singleVolumeNumber, void *rock); int ListViceInodes(char *devname, char *mountedOn, char *resultFile, - int (*judgeInode) (struct ViceInodeInfo * info, int vid), + int (*judgeInode) (struct ViceInodeInfo * info, int vid, + void *rock), int singleVolumeNumber, int *forcep, int forceR, - char *wpath); + char *wpath, void *rock); #define NAMEI_LCOMP_LEN 32 diff --git a/src/vol/ntops.c b/src/vol/ntops.c index 77f3bb9f8..f64644acc 100644 --- a/src/vol/ntops.c +++ b/src/vol/ntops.c @@ -13,7 +13,7 @@ #include RCSID - ("$Header: /cvs/openafs/src/vol/ntops.c,v 1.7 2003/12/07 22:49:43 jaltman Exp $"); + ("$Header: /cvs/openafs/src/vol/ntops.c,v 1.7.2.1 2004/10/18 07:12:28 shadow Exp $"); #ifdef AFS_NT40_ENV #include @@ -935,8 +935,8 @@ static int nt_ListAFSSubDirs(IHandle_t * dirIH, int (*write_fun) (FILE *, struct ViceInodeInfo *, char *, char *), FILE * fp, int (*judgeFun) (struct ViceInodeInfo *, - int vid), - int singleVolumeNumber); + int vid, void *rock), + int singleVolumeNumber, void *rock); /* WriteInodeInfo @@ -972,8 +972,9 @@ WriteInodeInfo(FILE * fp, struct ViceInodeInfo *info, char *dir, char *name) */ int ListViceInodes(char *devname, char *mountedOn, char *resultFile, - int (*judgeInode) (struct ViceInodeInfo * info, int vid), - int singleVolumeNumber, int *forcep, int forceR, char *wpath) + int (*judgeInode) (struct ViceInodeInfo * info, int vid, void *rock), + int singleVolumeNumber, int *forcep, int forceR, char *wpath, + void *rock) { FILE *fp = (FILE *) - 1; int ninodes; @@ -988,7 +989,7 @@ ListViceInodes(char *devname, char *mountedOn, char *resultFile, } ninodes = nt_ListAFSFiles(wpath, WriteInodeInfo, fp, judgeInode, - singleVolumeNumber); + singleVolumeNumber, rock); if (!resultFile) return ninodes; @@ -1041,8 +1042,8 @@ int nt_ListAFSFiles(char *dev, int (*writeFun) (FILE *, struct ViceInodeInfo *, char *, char *), FILE * fp, - int (*judgeFun) (struct ViceInodeInfo *, int), - int singleVolumeNumber) + int (*judgeFun) (struct ViceInodeInfo *, int, void *), + int singleVolumeNumber, void *rock) { IHandle_t h; char name[MAX_PATH]; @@ -1059,7 +1060,7 @@ nt_ListAFSFiles(char *dev, if (!nt_HandleToVolDir(name, &h)) return -1; ninodes = - nt_ListAFSSubDirs(&h, writeFun, fp, judgeFun, singleVolumeNumber); + nt_ListAFSSubDirs(&h, writeFun, fp, judgeFun, singleVolumeNumber, rock); if (ninodes < 0) return ninodes; } else { @@ -1072,7 +1073,7 @@ nt_ListAFSFiles(char *dev, return -1; while (dp = readdir(dirp)) { if (!DecodeVolumeName(dp->d_name, &h.ih_vid)) { - ninodes += nt_ListAFSSubDirs(&h, writeFun, fp, judgeFun, 0); + ninodes += nt_ListAFSSubDirs(&h, writeFun, fp, judgeFun, 0, rock); } } } @@ -1094,8 +1095,8 @@ static int nt_ListAFSSubDirs(IHandle_t * dirIH, int (*writeFun) (FILE *, struct ViceInodeInfo *, char *, char *), FILE * fp, - int (*judgeFun) (struct ViceInodeInfo *, int), - int singleVolumeNumber) + int (*judgeFun) (struct ViceInodeInfo *, int, void *), + int singleVolumeNumber, void *rock) { int i; IHandle_t myIH = *dirIH; @@ -1179,7 +1180,7 @@ nt_ListAFSSubDirs(IHandle_t * dirIH, info.u.param[2] = data.ftCreationTime.dwHighDateTime; info.u.param[3] = data.ftCreationTime.dwLowDateTime; } - if (judgeFun && !(*judgeFun) (&info, singleVolumeNumber)) + if (judgeFun && !(*judgeFun) (&info, singleVolumeNumber, rock)) goto next_file; if ((*writeFun) (fp, &info, path, data.cFileName) < 0) { nt_close(linkHandle.fd_fd); diff --git a/src/vol/ntops.h b/src/vol/ntops.h index e5098e1f0..f1f1f36a4 100644 --- a/src/vol/ntops.h +++ b/src/vol/ntops.h @@ -49,12 +49,12 @@ extern int nt_GetLinkCount(FdHandle_t * h, Inode ino, int lockit); int nt_ListAFSFiles(char *dev, int (*write_fun) (FILE * fp, struct ViceInodeInfo *, char *dir, char *file), FILE * fp, - int (*judge_fun) (struct ViceInodeInfo *, int vid), - int singleVolumeNumber); + int (*judge_fun) (struct ViceInodeInfo *, int vid, void *rock), + int singleVolumeNumber, void *rock); int ListViceInodes(char *devname, char *mountedOn, char *resultFile, - int (*judgeInode) (struct ViceInodeInfo * info, int vid), + int (*judgeInode) (struct ViceInodeInfo * info, int vid, void *rock), int singleVolumeNumber, int *forcep, int forceR, - char *wpath); + char *wpath, void *rock); int nt_HandleToName(char *name, IHandle_t * h); diff --git a/src/vol/nuke.c b/src/vol/nuke.c index fc753f7ba..d9172c48c 100644 --- a/src/vol/nuke.c +++ b/src/vol/nuke.c @@ -11,7 +11,7 @@ #include RCSID - ("$Header: /cvs/openafs/src/vol/nuke.c,v 1.13.2.1 2004/08/25 07:14:19 shadow Exp $"); + ("$Header: /cvs/openafs/src/vol/nuke.c,v 1.13.2.2 2004/10/18 17:44:06 shadow Exp $"); #include #include @@ -65,14 +65,14 @@ struct ilist { afs_int32 freePtr; /* first free index in this table */ Inode inode[MAXATONCE]; /* inode # */ afs_int32 count[MAXATONCE]; /* link count */ -} *allInodes = 0; +}; /* called with a structure specifying info about the inode, and our rock (which * is the volume ID. Returns true if we should keep this inode, otherwise false. * Note that ainfo->u.param[0] is always the volume ID, for any vice inode. */ static int -NukeProc(struct ViceInodeInfo *ainfo, afs_int32 avolid) +NukeProc(struct ViceInodeInfo *ainfo, afs_int32 avolid, struct ilist *allInodes) { struct ilist *ti; register afs_int32 i; @@ -113,7 +113,7 @@ nuke(char *aname, afs_int32 avolid) { /* first process the partition containing this junk */ struct afs_stat tstat; - struct ilist *ti, *ni; + struct ilist *ti, *ni, *li=NULL; register afs_int32 code; int i, forceSal; char devName[64], wpath[100]; @@ -127,6 +127,7 @@ nuke(char *aname, afs_int32 avolid) #endif #endif /* AFS_NAMEI_ENV */ IHandle_t *fileH; + struct ilist *allInodes = 0; if (avolid == 0) return EINVAL; @@ -169,11 +170,11 @@ nuke(char *aname, afs_int32 avolid) #ifdef AFS_NAMEI_ENV code = ListViceInodes(lastDevComp, aname, NULL, NukeProc, avolid, &forceSal, - 0, wpath); + 0, wpath, allInodes); #else code = ListViceInodes(lastDevComp, aname, "/tmp/vNukeXX", NukeProc, avolid, - &forceSal, 0, wpath); + &forceSal, 0, wpath, allInodes); unlink("/tmp/vNukeXX"); /* clean it up now */ #endif if (code == 0) { @@ -211,8 +212,10 @@ nuke(char *aname, afs_int32 avolid) #endif /* AFS_NAMEI_ENV */ } ni = ti->next; - free(ti); + if (li) free(li); + li = ti; } + if (li) free(li); code = 0; /* we really don't care about it except for debugging */ allInodes = NULL; @@ -236,8 +239,10 @@ nuke(char *aname, afs_int32 avolid) /* just free things */ for (ti = allInodes; ti; ti = ni) { ni = ti->next; - free(ti); + if (li) free(li); + li = ti; } + if (li) free(li); allInodes = NULL; } ReleaseWriteLock(&localLock); diff --git a/src/vol/vol-salvage.c b/src/vol/vol-salvage.c index a8e956d24..f5f65926e 100644 --- a/src/vol/vol-salvage.c +++ b/src/vol/vol-salvage.c @@ -92,7 +92,7 @@ Vnodes with 0 inode pointers in RW volumes are now deleted. #include RCSID - ("$Header: /cvs/openafs/src/vol/vol-salvage.c,v 1.41.2.1 2004/08/25 07:14:19 shadow Exp $"); + ("$Header: /cvs/openafs/src/vol/vol-salvage.c,v 1.41.2.2 2004/10/18 17:44:06 shadow Exp $"); #include #include @@ -1520,7 +1520,7 @@ CountVolumeInodes(register struct ViceInodeInfo *ip, int maxInodes, } int -OnlyOneVolume(struct ViceInodeInfo *inodeinfo, VolumeId singleVolumeNumber) +OnlyOneVolume(struct ViceInodeInfo *inodeinfo, VolumeId singleVolumeNumber, void *rock) { if (inodeinfo->u.vnode.vnodeNumber == INODESPECIAL) return (inodeinfo->u.special.parentId == singleVolumeNumber); @@ -1556,7 +1556,7 @@ GetInodeSummary(char *path, VolumeId singleVolumeNumber) if ((err = ListViceInodes(dev, fileSysPath, path, singleVolumeNumber ? OnlyOneVolume : 0, - singleVolumeNumber, &forceSal, forceR, wpath)) < 0) { + singleVolumeNumber, &forceSal, forceR, wpath, NULL)) < 0) { if (err == -2) { Log("*** I/O error %d when writing a tmp inode file %s; Not salvaged %s ***\nIncrease space on partition or use '-tmpdir'\n", errno, path, dev); return -1; diff --git a/src/volser/volmain.c b/src/volser/volmain.c index 237d32ea6..9d3708800 100644 --- a/src/volser/volmain.c +++ b/src/volser/volmain.c @@ -11,7 +11,7 @@ #include RCSID - ("$Header: /cvs/openafs/src/volser/volmain.c,v 1.18 2003/12/07 22:49:44 jaltman Exp $"); + ("$Header: /cvs/openafs/src/volser/volmain.c,v 1.18.2.1 2004/10/18 07:12:29 shadow Exp $"); #include #ifdef AFS_NT40_ENV @@ -100,7 +100,7 @@ int Testing = 0; /* for ListViceInodes */ } -static +static afs_int32 MyBeforeProc(struct rx_call *acall) { VTRANS_LOCK; @@ -109,7 +109,7 @@ MyBeforeProc(struct rx_call *acall) return 0; } -static +static afs_int32 MyAfterProc(struct rx_call *acall, afs_int32 code) { VTRANS_LOCK; @@ -121,7 +121,7 @@ MyAfterProc(struct rx_call *acall, afs_int32 code) /* Called every GCWAKEUP seconds to try to unlock all our partitions, * if we're idle and there are no active transactions */ -static +static void TryUnlock() { /* if there are no running calls, and there are no active transactions, then @@ -135,7 +135,7 @@ TryUnlock() } /* background daemon for timing out transactions */ -static +static void BKGLoop() { struct timeval tv; @@ -161,7 +161,7 @@ BKGLoop() /* Background daemon for sleeping so the volserver does not become I/O bound */ afs_int32 TTsleep, TTrun; -static +static void BKGSleep() { struct volser_trans *tt; @@ -194,9 +194,7 @@ BKGSleep() #ifndef AFS_NT40_ENV int -volser_syscall(a3, a4, a5) - afs_uint32 a3, a4; - void *a5; +volser_syscall(afs_uint32 a3, afs_uint32 a4, void *a5) { afs_uint32 rcode; void (*old) (); @@ -218,16 +216,14 @@ volser_syscall(a3, a4, a5) /* check whether caller is authorized to manage RX statistics */ int -vol_rxstat_userok(call) - struct rx_call *call; +vol_rxstat_userok(struct rx_call *call) { return afsconf_SuperUser(tdir, call, NULL); } #include "AFS_component_version_number.c" -main(argc, argv) - int argc; - char **argv; +int +main(int argc, char **argv) { register afs_int32 code; struct rx_securityClass *(securityObjects[3]); diff --git a/src/volser/volprocs.c b/src/volser/volprocs.c index 55079ea90..796d31cf4 100644 --- a/src/volser/volprocs.c +++ b/src/volser/volprocs.c @@ -11,7 +11,7 @@ #include RCSID - ("$Header: /cvs/openafs/src/volser/volprocs.c,v 1.34 2004/07/29 03:44:08 shadow Exp $"); + ("$Header: /cvs/openafs/src/volser/volprocs.c,v 1.34.2.1 2004/10/18 07:12:29 shadow Exp $"); #include #include @@ -425,7 +425,7 @@ VolCreateVolume(struct rx_call *acid, afs_int32 apart, char *aname, if (error) { Log("1 Volser: CreateVolume: Unable to create the volume; aborted, error code %u\n", error); LogError(error); - DeleteTrans(tt); + DeleteTrans(tt, 1); return EIO; } V_uniquifier(vp) = 1; @@ -442,7 +442,7 @@ VolCreateVolume(struct rx_call *acid, afs_int32 apart, char *aname, if (error) { Log("1 Volser: create UpdateVolume failed, code %d\n", error); LogError(error); - DeleteTrans(tt); + DeleteTrans(tt, 1); VDetachVolume(&junk, vp); /* rather return the real error code */ return error; } @@ -677,7 +677,7 @@ VolClone(struct rx_call *acid, afs_int32 atrans, afs_int32 purgeId, error = VOLSERTRELE_ERROR; goto fail; } - DeleteTrans(ttc); + DeleteTrans(ttc, 1); return 0; fail: @@ -690,7 +690,7 @@ VolClone(struct rx_call *acid, afs_int32 atrans, afs_int32 purgeId, TRELE(tt); } if (ttc) - DeleteTrans(ttc); + DeleteTrans(ttc, 1); return error; } @@ -840,7 +840,7 @@ VolReClone(struct rx_call *acid, afs_int32 atrans, afs_int32 cloneId) goto fail; } - DeleteTrans(ttc); + DeleteTrans(ttc, 1); { struct DiskPartition *tpartp = originalvp->partition; @@ -856,7 +856,7 @@ VolReClone(struct rx_call *acid, afs_int32 atrans, afs_int32 cloneId) TRELE(tt); } if (ttc) - DeleteTrans(ttc); + DeleteTrans(ttc, 1); return error; } @@ -913,7 +913,7 @@ VolTransCreate(struct rx_call *acid, afs_int32 volume, afs_int32 partition, /* give up */ if (tv) VDetachVolume(&code, tv); - DeleteTrans(tt); + DeleteTrans(tt, 1); return error; } tt->volume = tv; @@ -1387,7 +1387,7 @@ VolEndTrans(struct rx_call *acid, afs_int32 destTrans, afs_int32 *rcode) return ENOENT; } *rcode = tt->returnCode; - DeleteTrans(tt); /* this does an implicit TRELE */ + DeleteTrans(tt, 1); /* this does an implicit TRELE */ return 0; } @@ -1540,10 +1540,6 @@ VolSetInfo(struct rx_call *acid, afs_int32 atrans, td->maxquota = astatus->maxquota; if (astatus->dayUse != -1) td->dayUse = astatus->dayUse; - if (astatus->creationDate != -1) - td->creationDate = astatus->creationDate; - if (astatus->updateDate != -1) - td->updateDate = astatus->updateDate; VUpdateVolume(&error, tv); tt->rxCallPtr = (struct rx_call *)0; if (TRELE(tt)) @@ -1868,7 +1864,7 @@ VolListOneVolume(struct rx_call *acid, afs_int32 partid, afs_int32 tv = (Volume *) 0; } if (ttc) { - DeleteTrans(ttc); + DeleteTrans(ttc, 1); ttc = (struct volser_trans *)0; } @@ -2099,7 +2095,7 @@ VolXListOneVolume(struct rx_call *a_rxCidP, afs_int32 a_partID, tv = (Volume *) 0; } if (ttc) { - DeleteTrans(ttc); + DeleteTrans(ttc, 1); ttc = (struct volser_trans *)0; } @@ -2241,7 +2237,7 @@ VolListVolumes(struct rx_call *acid, afs_int32 partid, afs_int32 flags, drop: if (ttc) { - DeleteTrans(ttc); + DeleteTrans(ttc, 1); ttc = (struct volser_trans *)0; } pntr++; @@ -2258,7 +2254,7 @@ VolListVolumes(struct rx_call *acid, afs_int32 partid, afs_int32 flags, tv = (Volume *) 0; } if (ttc) { - DeleteTrans(ttc); + DeleteTrans(ttc, 1); ttc = (struct volser_trans *)0; } closedir(dirp); @@ -2276,7 +2272,7 @@ VolListVolumes(struct rx_call *acid, afs_int32 partid, afs_int32 flags, tv = (Volume *) 0; } if (ttc) { - DeleteTrans(ttc); + DeleteTrans(ttc, 1); ttc = (struct volser_trans *)0; } GetNextVol(dirp, volname, &volid); @@ -2284,7 +2280,7 @@ VolListVolumes(struct rx_call *acid, afs_int32 partid, afs_int32 flags, } closedir(dirp); if (ttc) - DeleteTrans(ttc); + DeleteTrans(ttc, 1); return 0; } @@ -2495,7 +2491,7 @@ VolXListVolumes(struct rx_call *a_rxCidP, afs_int32 a_partID, * Drop the transaction we have for this volume. */ if (ttc) { - DeleteTrans(ttc); + DeleteTrans(ttc, 1); ttc = (struct volser_trans *)0; } @@ -2522,7 +2518,7 @@ VolXListVolumes(struct rx_call *a_rxCidP, afs_int32 a_partID, tv = (Volume *) 0; } if (ttc) { - DeleteTrans(ttc); + DeleteTrans(ttc, 1); ttc = (struct volser_trans *)0; } closedir(dirp); @@ -2550,7 +2546,7 @@ VolXListVolumes(struct rx_call *a_rxCidP, afs_int32 a_partID, tv = (Volume *) 0; } if (ttc) { - DeleteTrans(ttc); + DeleteTrans(ttc, 1); ttc = (struct volser_trans *)0; } GetNextVol(dirp, volname, &volid); @@ -2562,7 +2558,7 @@ VolXListVolumes(struct rx_call *a_rxCidP, afs_int32 a_partID, */ closedir(dirp); if (ttc) - DeleteTrans(ttc); + DeleteTrans(ttc, 1); return (0); } /*SAFSVolXListVolumes */ diff --git a/src/volser/voltrans.c b/src/volser/voltrans.c index 4c28fbec0..af2d6f121 100644 --- a/src/volser/voltrans.c +++ b/src/volser/voltrans.c @@ -18,7 +18,7 @@ #include RCSID - ("$Header: /cvs/openafs/src/volser/voltrans.c,v 1.10 2003/11/22 02:57:04 shadow Exp $"); + ("$Header: /cvs/openafs/src/volser/voltrans.c,v 1.10.2.1 2004/10/18 07:12:29 shadow Exp $"); #ifdef AFS_NT40_ENV #include @@ -79,9 +79,7 @@ static afs_int32 transCounter = 1; /* create a new transaction, returning ptr to same with high ref count */ struct volser_trans * -NewTrans(avol, apart) - afs_int32 avol; - afs_int32 apart; +NewTrans(afs_int32 avol, afs_int32 apart) { /* set volid, next, partition */ register struct volser_trans *tt; @@ -117,8 +115,7 @@ NewTrans(avol, apart) /* find a trans, again returning with high ref count */ struct volser_trans * -FindTrans(atrans) - register afs_int32 atrans; +FindTrans(register afs_int32 atrans) { register struct volser_trans *tt; VTRANS_LOCK; @@ -135,8 +132,8 @@ FindTrans(atrans) } /* delete transaction if refcount == 1, otherwise queue delete for later. Does implicit TRELE */ -DeleteTrans(atrans) - register struct volser_trans *atrans; +afs_int32 +DeleteTrans(register struct volser_trans *atrans, afs_int32 lock) { register struct volser_trans *tt, **lt; afs_int32 error; @@ -149,7 +146,7 @@ DeleteTrans(atrans) } /* otherwise we zap it ourselves */ - VTRANS_LOCK; + if (lock) VTRANS_LOCK; lt = &allTrans; for (tt = *lt; tt; lt = &tt->next, tt = *lt) { if (tt == atrans) { @@ -158,19 +155,19 @@ DeleteTrans(atrans) tt->volume = NULL; *lt = tt->next; free(tt); - VTRANS_UNLOCK; + if (lock) VTRANS_UNLOCK; return 0; } } - VTRANS_UNLOCK; + if (lock) VTRANS_UNLOCK; return -1; /* failed to find the transaction in the generic list */ } /* THOLD is a macro defined in volser.h */ /* put a transaction back */ -TRELE(at) - register struct volser_trans *at; +afs_int32 +TRELE(register struct volser_trans *at) { if (at->refCount == 0) { Log("TRELE: bad refcount\n"); @@ -179,7 +176,7 @@ TRELE(at) at->time = FT_ApproxTime(); /* we're still using it */ if (at->refCount == 1 && (at->tflags & TTDeleted)) { - DeleteTrans(at); + DeleteTrans(at, 1); return 0; } /* otherwise simply drop refcount */ @@ -191,6 +188,7 @@ TRELE(at) #define OLDTRANSTIME 600 /* seconds */ #define OLDTRANSWARN 300 /* seconds */ static int GCDeletes = 0; +afs_int32 GCTrans() { register struct volser_trans *tt, *nt; @@ -212,7 +210,7 @@ GCTrans() if (tt->time + OLDTRANSTIME < now) { Log("trans %u on volume %u has timed out\n", tt->tid, tt->volid); tt->refCount++; /* we're using it now */ - DeleteTrans(tt); /* drops refCount or deletes it */ + DeleteTrans(tt, 0); /* drops refCount or deletes it */ GCDeletes++; } } diff --git a/src/volser/vsutils.c b/src/volser/vsutils.c index 0f825be9e..8191bb377 100644 --- a/src/volser/vsutils.c +++ b/src/volser/vsutils.c @@ -11,7 +11,7 @@ #include RCSID - ("$Header: /cvs/openafs/src/volser/vsutils.c,v 1.16 2003/12/07 22:49:46 jaltman Exp $"); + ("$Header: /cvs/openafs/src/volser/vsutils.c,v 1.16.2.1 2004/10/18 07:12:29 shadow Exp $"); #include #ifdef AFS_NT40_ENV @@ -445,128 +445,10 @@ vsu_ClientInit(noAuthFlag, confDir, cellName, sauth, uclientp, secproc) static struct rx_connection *serverconns[VLDB_MAXSERVERS]; char cellstr[64]; - - code = rx_Init(0); - if (code) { - fprintf(STDERR, "vsu_ClientInit: could not initialize rx.\n"); - return code; - } - rx_SetRxDeadTime(90); - - if (sauth) { /* -localauth */ - tdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH); - if (!tdir) { - fprintf(STDERR, - "vsu_ClientInit: Could not process files in configuration directory (%s).\n", - AFSDIR_SERVER_ETC_DIRPATH); - return -1; - } - code = afsconf_ClientAuth(tdir, &sc, &scIndex); /* sets sc,scIndex */ - if (code) { - fprintf(STDERR, - "vsu_ClientInit: Could not get security object for -localAuth\n"); - return -1; - } - code = - afsconf_GetCellInfo(tdir, tdir->cellName, AFSCONF_VLDBSERVICE, - &info); - if (code) { - fprintf(STDERR, - "vsu_ClientInit: can't find cell %s's hosts in %s/%s\n", - cellName, AFSDIR_SERVER_ETC_DIRPATH, - AFSDIR_CELLSERVDB_FILE); - exit(1); - } - } else { /* not -localauth */ - tdir = afsconf_Open(confDir); - if (!tdir) { - fprintf(STDERR, - "vsu_ClientInit: Could not process files in configuration directory (%s).\n", - confDir); - return -1; - } - - if (!cellName) { - code = afsconf_GetLocalCell(tdir, cellstr, sizeof(cellstr)); - if (code) { - fprintf(STDERR, - "vsu_ClientInit: can't get local cellname, check %s/%s\n", - confDir, AFSDIR_THISCELL_FILE); - exit(1); - } - cellName = cellstr; - } - - code = - afsconf_GetCellInfo(tdir, cellName, AFSCONF_VLDBSERVICE, &info); - if (code) { - fprintf(STDERR, - "vsu_ClientInit: can't find cell %s's hosts in %s/%s\n", - cellName, confDir, AFSDIR_CELLSERVDB_FILE); - exit(1); - } - if (noAuthFlag) /* -noauth */ - scIndex = 0; - else { /* not -noauth */ - strcpy(sname.cell, info.name); - sname.instance[0] = 0; - strcpy(sname.name, "afs"); - code = ktc_GetToken(&sname, &ttoken, sizeof(ttoken), NULL); - if (code) { /* did not get ticket */ - fprintf(STDERR, - "vsu_ClientInit: Could not get afs tokens, running unauthenticated.\n"); - scIndex = 0; - } else { /* got a ticket */ - scIndex = 2; - if ((ttoken.kvno < 0) || (ttoken.kvno > 255)) { - fprintf(STDERR, - "vsu_ClientInit: funny kvno (%d) in ticket, proceeding\n", - ttoken.kvno); - } - } - } - - switch (scIndex) { - case 0: - sc = rxnull_NewClientSecurityObject(); - break; - case 2: - sc = rxkad_NewClientSecurityObject(vsu_rxkad_level, - &ttoken.sessionKey, - ttoken.kvno, ttoken.ticketLen, - ttoken.ticket); - break; - default: - fprintf(STDERR, "vsu_ClientInit: unsupported security index %d\n", - scIndex); - exit(1); - break; - } - } - - afsconf_Close(tdir); - - if (secproc) /* tell UV module about default authentication */ - (*secproc) (sc, scIndex); - if (info.numServers > VLDB_MAXSERVERS) { - fprintf(STDERR, - "vsu_ClientInit: info.numServers=%d (> VLDB_MAXSERVERS=%d)\n", - info.numServers, VLDB_MAXSERVERS); - exit(1); - } - for (i = 0; i < info.numServers; i++) { - serverconns[i] = - rx_NewConnection(info.hostAddr[i].sin_addr.s_addr, - info.hostAddr[i].sin_port, USER_SERVICE_ID, sc, - scIndex); - } - *uclientp = 0; - code = ubik_ClientInit(serverconns, uclientp); - if (code) { - fprintf(STDERR, "vsu_ClientInit: ubik client init failed.\n"); - return code; - } - return 0; + return ugen_ClientInit(noAuthFlag, confDir, cellName, sauth, uclientp, + secproc, "vsu_ClientInit", vsu_rxkad_level, + VLDB_MAXSERVERS, AFSCONF_VLDBSERVICE, 90, + 0, 0, USER_SERVICE_ID); } -- 2.39.5