--- /dev/null
+# Top-level Makefile for Win95/DJGPP AFS client
+# Assumes you are doing cross-compiling from Linux
+# Set LINUX_SYS to the proper sysname for your Linux system
+
+OBJ = $(SYS_NAME)/obj
+DEST = $(SYS_NAME)/dest
+#LINUX_SYS = i386_linux22
+
+all: afsd
+
+afsd: config pinstall libs
+ make -C $(OBJ)/WINNT/afsd -f Makefile.djgpp depends
+ make -C $(OBJ)/WINNT/afsd -f Makefile.djgpp install
+
+utils: pinstall rxgen comerr
+includes: afsdinc osiinc authinc
+libs: fsint cmd lwp osi rx rxkad vldb rxstat acl
+
+clean:
+ -rm -f $(SYS_NAME)/dest/include/*
+ -rm -f $(SYS_NAME)/dest/include/afs/*
+ -rm -f $(SYS_NAME)/dest/lib/*
+ -rm -f $(SYS_NAME)/dest/lib/afs/*
+ -rm -f $(SYS_NAME)/dest/bin/*
+
+config:
+ -make -C $(OBJ)/config install
+
+# pinstall, rxgen, comerr, and util are built to run on Linux
+pinstall: config
+ -mkdir $(OBJ)/pinstall/afs
+ -cp $(OBJ)/config/param.$(LINUX_SYS).h $(OBJ)/pinstall/afs/param.h
+ make -C $(OBJ)/pinstall SYS_NAME=$(LINUX_SYS) install
+rxgen: config
+ -mkdir $(OBJ)/rxgen/afs
+ -cp $(OBJ)/config/param.$(LINUX_SYS).h $(OBJ)/rxgen/afs/param.h
+ make -C $(OBJ)/rxgen SYS_NAME=$(LINUX_SYS) install
+comerr: config util
+ -mkdir $(OBJ)/comerr/afs
+ -cp $(OBJ)/config/param.$(LINUX_SYS).h $(OBJ)/comerr/afs/param.h
+ make -C $(OBJ)/comerr SYS_NAME=$(LINUX_SYS) install
+util: config procmgmt
+ -mkdir $(OBJ)/util/afs
+ -cp $(OBJ)/util/param.$(LINUX_SYS).h $(OBJ)/util/afs/param.h
+ make -C $(OBJ)/util SYS_NAME=$(LINUX_SYS) install
+
+procmgmt:
+ make -C $(OBJ)/procmgmt includes
+lwp: util afsdinc osiinc lwpinc
+ make -C $(OBJ)/lwp install
+lwpinc:
+ make -C $(OBJ)/lwp includes
+rx: rxgen lwp
+ make -C $(OBJ)/rx install-djgpp
+des: desprogs
+ make -C $(OBJ)/des install
+desprogs:
+ make -C $(OBJ)/des SYS_NAME=$(LINUX_SYS) gprogs
+ubik: rx lwp
+ make -C $(OBJ)/ubik install
+fsint: rx rxgen
+ make -C $(OBJ)/fsint install
+rxkad: rx des
+ make -C $(OBJ)/rxkad install
+audit: fsint
+ make -C $(OBJ)/audit install
+authinc: comerr
+ make -C $(OBJ)/auth includes
+vldb: rxgen rx authinc audit ubik rxkad
+ make -C $(OBJ)/vlserver libinstall
+rxstat: rxgen rx
+ make -C $(OBJ)/rxstat install
+cmd: comerr
+ make -C $(OBJ)/cmd install
+afsdinc:
+ make -C $(OBJ)/WINNT/afsd -f Makefile.djgpp includes
+osiinc:
+ make -C $(OBJ)/WINNT/client_osi -f Makefile.djgpp includes
+osi: config
+ make -C $(OBJ)/WINNT/client_osi -f Makefile.djgpp depends
+ make -C $(OBJ)/WINNT/client_osi -f Makefile.djgpp install
+acl: config ptlib
+ make -C $(OBJ)/libacl install
+ptlib: config rxgen comerr
+ make -C $(OBJ)/ptserver libinstall
--- /dev/null
+# 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
+
+# Top level nmake NTMakefile driver for building AFS.
+#
+# This file simply imposes a reasonable total ordering on the set of
+# directories to build; this ordering is of course more strict than the
+# partial ordering established by the actual directory dependencies.
+#
+# When porting a new directory, simply add the directory into the
+# dependence chain at the earliest point possible, updating its successor
+# appropriately; if the new directory is the last in the chain, then
+# update the 'finale' dependency to be the new directory.
+
+
+CD = cd
+NTMAKE = nmake /nologo /f ntmakefile install9x
+NTMAKELANG = nmake /nologo /f ntmakefile en_install
+NTMAKE_HEADERS = nmake /nologo /f ntmakefile install_headers
+NTMAKE_LIBUTILS = nmake /nologo /f ntmakefile install_libutils
+MKDIR = mkdir
+OBJ = src
+
+# Standard install directory.
+!IFDEF AFSDEV_DESTDIR
+DESTDIR = $(AFSDEV_DESTDIR)
+!ELSE
+DESTDIR = $(AFSROOT)\DEST
+!ENDIF
+
+
+start:
+! IF (!EXIST(src))
+! ERROR Execute nmake from directory above src, e.g., afs\3.5.
+! ENDIF
+! IF (!EXIST($(DESTDIR)))
+ $(MKDIR) $(DESTDIR)
+! ENDIF
+
+config:
+ echo ***** $@
+ $(CD) $(OBJ)\$@
+ $(NTMAKE)
+ $(CD) ..\..
+
+procmgmt_headers: config
+ echo ***** $@
+ $(CD) $(OBJ)\procmgmt
+ $(NTMAKE_HEADERS)
+ $(CD) ..\..
+
+afsreg_headers: config
+ echo ***** $@
+ $(CD) $(OBJ)\WINNT\afsreg
+ $(NTMAKE_HEADERS)
+ $(CD) ..\..\..
+
+util: procmgmt_headers afsreg_headers
+ echo ***** $@
+ $(CD) $(OBJ)\$@
+ $(NTMAKE)
+ $(CD) ..\..
+
+comerr: util
+ echo ***** $@
+ $(CD) $(OBJ)\$@
+ $(NTMAKE)
+ $(CD) ..\..
+
+cmd: comerr
+ echo ***** $@
+ $(CD) $(OBJ)\$@
+ $(NTMAKE)
+ $(CD) ..\..
+
+afsreg: cmd
+ echo ***** $@
+ $(CD) $(OBJ)\WINNT\$@
+ $(NTMAKE)
+ $(CD) ..\..\..
+
+eventlog: afsreg
+ echo ***** $@
+ $(CD) $(OBJ)\WINNT\$@
+ $(NTMAKE)
+ $(CD) ..\..\..
+
+lwp: eventlog
+ echo ***** $@
+ $(CD) $(OBJ)\$@
+ $(NTMAKE)
+ $(CD) ..\..
+
+rxgen: lwp
+ echo ***** $@
+ $(CD) $(OBJ)\$@
+ $(NTMAKE)
+ $(CD) ..\..
+
+des: rxgen
+ echo ***** $@
+! IF (EXIST($(OBJ)\des\NTMakefile))
+ $(CD) $(OBJ)\des
+ $(NTMAKE)
+ $(CD) ..\..
+! ELSE
+ $(CD) $(OBJ)\des_stub
+ $(NTMAKE)
+ $(CD) ..\..
+! ENDIF
+
+rx: des
+ echo ***** $@
+ $(CD) $(OBJ)\$@
+ $(NTMAKE)
+ $(CD) ..\..
+
+rxstat: rx
+ echo ***** $@
+ $(CD) $(OBJ)\$@
+ $(NTMAKE)
+ $(CD) ..\..
+
+rxkad: rxstat
+ echo ***** $@
+ $(CD) $(OBJ)\$@
+ $(NTMAKE)
+ $(CD) ..\..
+
+pthread: rxkad
+ echo ***** $@
+ $(CD) $(OBJ)\WINNT\$@
+ $(NTMAKE)
+ $(CD) ..\..\..
+
+procmgmt: pthread
+ echo ***** $@
+ $(CD) $(OBJ)\$@
+ $(NTMAKE)
+ $(CD) ..\..
+
+fsint: procmgmt
+ echo ***** $@
+ $(CD) $(OBJ)\$@
+ $(NTMAKE)
+ $(CD) ..\..
+
+audit: fsint
+ echo ***** $@
+ $(CD) $(OBJ)\$@
+ $(NTMAKE)
+ $(CD) ..\..
+
+osi_headers: audit
+ echo ***** $@
+ $(CD) $(OBJ)\WINNT\client_osi
+ $(NTMAKE_HEADERS)
+ $(CD) ..\..\..
+
+libacl_headers: osi_headers
+ echo ***** $@
+ $(CD) $(OBJ)\libacl
+ $(NTMAKE_HEADERS)
+ $(CD) ..\..
+
+cm_headers: libacl_headers
+ echo ***** $@
+ $(CD) $(OBJ)\WINNT\afsd
+ $(NTMAKE_HEADERS)
+ $(CD) ..\..\..
+
+sys: cm_headers
+ echo ***** $@
+ $(CD) $(OBJ)\$@
+ $(NTMAKE)
+ $(CD) ..\..
+
+auth: sys
+ echo ***** $@
+ $(CD) $(OBJ)\$@
+ $(NTMAKE)
+ $(CD) ..\..
+
+ubik: auth
+ echo ***** $@
+ $(CD) $(OBJ)\$@
+ $(NTMAKE)
+ $(CD) ..\..
+
+ptserver: ubik
+ echo ***** $@
+ $(CD) $(OBJ)\$@
+ $(NTMAKE_LIBUTILS)
+ $(CD) ..\..
+
+libacl: ptserver
+ echo ***** $@
+ $(CD) $(OBJ)\$@
+ $(NTMAKE)
+ $(CD) ..\..
+
+kauth: libacl
+ echo ***** $@
+ $(CD) $(OBJ)\$@
+ $(NTMAKE)
+ $(CD) ..\..
+
+vlserver: kauth
+ echo ***** $@
+ $(CD) $(OBJ)\$@
+ $(NTMAKE_LIBUTILS)
+ $(CD) ..\..
+
+usd: vlserver
+ echo ***** $@
+ $(CD) $(OBJ)\$@
+ $(NTMAKE)
+ $(CD) ..\..
+
+libafsrpc: usd
+ echo ***** $@
+ $(CD) $(OBJ)\$@
+ $(NTMAKE)
+ $(CD) ..\..
+
+libafsauthent: libafsrpc
+ echo ***** $@
+ $(CD) $(OBJ)\$@
+ $(NTMAKE)
+ $(CD) ..\..
+
+libadmin: libafsauthent
+ echo ***** $@
+ $(CD) $(OBJ)\$@
+ $(NTMAKE)
+ $(CD) ..\..
+
+client_talocale: libadmin
+ echo ***** $@
+ $(CD) $(OBJ)\WINNT\talocale
+ $(NTMAKE)
+ $(CD) ..\..\..
+
+client_osi: client_talocale
+ echo ***** $@
+ $(CD) $(OBJ)\WINNT\$@
+ $(NTMAKE)
+ $(CD) ..\..\..
+
+afsd: client_osi
+ echo ***** $@
+ $(CD) $(OBJ)\WINNT\$@
+ $(NTMAKE_LIBUTILS)
+ $(CD) ..\..\..
+
+client_cpa: afsd
+ echo ***** $@
+ $(CD) $(OBJ)\WINNT\$@
+ $(NTMAKE)
+ $(CD) ..\..\..
+
+client_config: client_cpa
+ echo ***** $@
+ $(CD) $(OBJ)\WINNT\$@
+ $(NTMAKE)
+ $(CD) ..\..\..
+
+client_exp: client_config
+ echo ***** $@
+ $(CD) $(OBJ)\WINNT\$@
+ $(NTMAKE)
+ $(CD) ..\..\..
+
+
+#Leave last echo in - it helps the build reconize the last $(CD)
+win9xpanel :
+ echo ***** $@
+ $(CD) $(OBJ)\WINNT\$@
+ $(NTMAKE)
+ $(CD) ..\..\..
+ echo ***** End of Build
+
+install: start client_exp win9xpanel
+
+install9x: install
+
+# InstallShield dependencies
+
+#Leave last echo in - it helps the build reconize the last $(CD)
+Win9x::
+ $(CD) $(OBJ)\WINNT\install\$@
+ nmake /nologo /f NTMakefile install9x
+ $(CD) ..\..\..\..
+ echo **** End of Install Scripts
+
+media: Win9x
+
+# Clean target for obj tree
+# Fake the version copy so clean will go through the complete cycle with undefines
+clean: start
+ if not exist .\src\config\NTMakefile.version copy .\src\config\NTMakefile.version-NOCML .\src\config\NTMakefile.version
+ nmake /nologo /f ntmake9x "NTMAKE = nmake /nologo /f ntmakefile clean" "NTMAKE_HEADERS = nmake /nologo /f ntmakefile clean" "NTMAKE_LIBUTILS = nmake /nologo /f ntmakefile clean" install
+ $(CD) $(OBJ)\WINNT\install\Win9x
+ nmake /nologo /f NTMakefile clean
+ $(CD) ..\..\..\..
+ .\src\rmbat $(DESTDIR)\include\*.* $(DESTDIR)\include\afs\*.* $(DESTDIR)\include\WINNT\*.* $(DESTDIR)\include\rx\*.*
+ .\src\rmbat $(DESTDIR)\LIB\*.LIB $(DESTDIR)\LIB\*.DLL $(DESTDIR)\LIB\AFS\*.LIB
+ .\src\RMBAT $(DESTDIR)\root.client\usr\vice\etc\*.*
+ $(CD) $(OBJ)\config
+ nmake /nologo /f ntmakefile clean_version
+ $(CD) ..\..
+ echo **** End of Clean
+
+# Language-only build target
+lang:
+ nmake /nologo /f ntmakefile "NTMAKE = nmake /nologo /f ntmakefile lang" "NTMAKE_HEADERS = nmake /nologo /f ntmakefile lang" install
CD = cd
NTMAKE = nmake /nologo /f ntmakefile install
+NTMAKELANG = nmake /nologo /f ntmakefile en_US
NTMAKE_HEADERS = nmake /nologo /f ntmakefile install_headers
MKDIR = mkdir
+OBJ = obj
# Standard install directory.
!IFDEF AFSDEV_DESTDIR
! ENDIF
config:
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
procmgmt_headers: config
- $(CD) src\procmgmt
+ echo ***** $@
+ $(CD) $(OBJ)\procmgmt
$(NTMAKE_HEADERS)
$(CD) ..\..
afsreg_headers: config
- $(CD) src\WINNT\afsreg
+ echo ***** $@
+ $(CD) $(OBJ)\WINNT\afsreg
$(NTMAKE_HEADERS)
$(CD) ..\..\..
util: procmgmt_headers afsreg_headers
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
comerr: util
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
cmd: comerr
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
afsreg: cmd
- $(CD) src\WINNT\$@
+ echo ***** $@
+ $(CD) $(OBJ)\WINNT\$@
$(NTMAKE)
$(CD) ..\..\..
eventlog: afsreg
- $(CD) src\WINNT\$@
+ echo ***** $@
+ $(CD) $(OBJ)\WINNT\$@
$(NTMAKE)
$(CD) ..\..\..
lwp: eventlog
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
rxgen: lwp
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
des: rxgen
-! IF (EXIST(src\des\NTMakefile))
- $(CD) src\des
+ echo ***** $@
+! IF (EXIST($(OBJ)\des\NTMakefile))
+ $(CD) $(OBJ)\des
$(NTMAKE)
$(CD) ..\..
! ELSE
- $(CD) src\des_stub
+ $(CD) $(OBJ)\des_stub
$(NTMAKE)
$(CD) ..\..
! ENDIF
rx: des
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
rxstat: rx
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
rxkad: rxstat
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
pthread: rxkad
- $(CD) src\WINNT\$@
+ echo ***** $@
+ $(CD) $(OBJ)\WINNT\$@
$(NTMAKE)
$(CD) ..\..\..
procmgmt: pthread
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
fsint: procmgmt
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
audit: fsint
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
osi_headers: audit
- $(CD) src\WINNT\client_osi
+ echo ***** $@
+ $(CD) $(OBJ)\WINNT\client_osi
$(NTMAKE_HEADERS)
$(CD) ..\..\..
libacl_headers: osi_headers
- $(CD) src\libacl
+ echo ***** $@
+ $(CD) $(OBJ)\libacl
$(NTMAKE_HEADERS)
$(CD) ..\..
cm_headers: libacl_headers
- $(CD) src\WINNT\afsd
+ echo ***** $@
+ $(CD) $(OBJ)\WINNT\afsd
$(NTMAKE_HEADERS)
$(CD) ..\..\..
sys: cm_headers
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
auth: sys
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
ubik: auth
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
ptserver: ubik
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
libacl: ptserver
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
kauth: libacl
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
vlserver: kauth
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
usd: vlserver
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
bubasics: usd
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
budb: bubasics
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
butm: budb
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
dir: butm
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
vol: dir
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
volser: vol
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
viced: volser
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
update: viced
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
bucoord: update
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
butc: bucoord
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
bozo: butc
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
bosctlsvc: bozo
- $(CD) src\WINNT\$@
+ echo ***** $@
+ $(CD) $(OBJ)\WINNT\$@
$(NTMAKE)
$(CD) ..\..\..
bu_utils: bosctlsvc
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
libafsrpc: bu_utils
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
libafsauthent: libafsrpc
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
tviced: libafsauthent
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
tbutc: tviced
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
libadmin: tbutc
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
adminutil: libadmin
- $(CD) src\libadmin\$@
+ echo ***** $@
+ $(CD) $(OBJ)\libadmin\$@
$(NTMAKE)
$(CD) ..\..\..
vos: adminutil
- $(CD) src\libadmin\$@
+ echo ***** $@
+ $(CD) $(OBJ)\libadmin\$@
$(NTMAKE)
$(CD) ..\..\..
client: vos
- $(CD) src\libadmin\$@
+ echo ***** $@
+ $(CD) $(OBJ)\libadmin\$@
$(NTMAKE)
$(CD) ..\..\..
kas: client
- $(CD) src\libadmin\$@
+ echo ***** $@
+ $(CD) $(OBJ)\libadmin\$@
$(NTMAKE)
$(CD) ..\..\..
pts: kas
- $(CD) src\libadmin\$@
+ echo ***** $@
+ $(CD) $(OBJ)\libadmin\$@
$(NTMAKE)
$(CD) ..\..\..
bos: pts
- $(CD) src\libadmin\$@
+ echo ***** $@
+ $(CD) $(OBJ)\libadmin\$@
$(NTMAKE)
$(CD) ..\..\..
cfg: bos
- $(CD) src\libadmin\$@
+ echo ***** $@
+ $(CD) $(OBJ)\libadmin\$@
$(NTMAKE)
$(CD) ..\..\..
admintest: cfg
- $(CD) src\libadmin\test
+ echo ***** $@
+ $(CD) $(OBJ)\libadmin\test
$(NTMAKE)
$(CD) ..\..\..
talocale: admintest
- $(CD) src\WINNT\$@
+ echo ***** $@
+ $(CD) $(OBJ)\WINNT\$@
$(NTMAKE)
$(CD) ..\..\..
license: talocale
- $(CD) src\WINNT\$@
+ echo ***** $@
+ $(CD) $(OBJ)\WINNT\$@
$(NTMAKE)
$(CD) ..\..\..
afsadmsvr: license
- $(CD) src\WINNT\$@
+ echo ***** $@
+ $(CD) $(OBJ)\WINNT\$@
$(NTMAKE)
$(CD) ..\..\..
afsusrmgr: afsadmsvr
- $(CD) src\WINNT\$@
+ echo ***** $@
+ $(CD) $(OBJ)\WINNT\$@
$(NTMAKE)
$(CD) ..\..\..
afssvrmgr: afsusrmgr
- $(CD) src\WINNT\$@
+ echo ***** $@
+ $(CD) $(OBJ)\WINNT\$@
$(NTMAKE)
$(CD) ..\..\..
afssvrcfg: afssvrmgr
- $(CD) src\WINNT\$@
+ echo ***** $@
+ $(CD) $(OBJ)\WINNT\$@
$(NTMAKE)
$(CD) ..\..\..
afssvrcpa: afssvrcfg
- $(CD) src\WINNT\$@
+ echo ***** $@
+ $(CD) $(OBJ)\WINNT\$@
$(NTMAKE)
$(CD) ..\..\..
afs_setup_utils: afssvrcpa
- $(CD) src\WINNT\$@
+ echo ***** $@
+ $(CD) $(OBJ)\WINNT\$@
$(NTMAKE)
$(CD) ..\..\..
client_talocale: afs_setup_utils
- $(CD) src\WINNT\talocale
+ echo ***** $@
+ $(CD) $(OBJ)\WINNT\talocale
$(NTMAKE)
$(CD) ..\..\..
client_osi: client_talocale
- $(CD) src\WINNT\$@
+ echo ***** $@
+ $(CD) $(OBJ)\WINNT\$@
$(NTMAKE)
$(CD) ..\..\..
afsd: client_osi
- $(CD) src\WINNT\$@
+ echo ***** $@
+ $(CD) $(OBJ)\WINNT\$@
$(NTMAKE)
$(CD) ..\..\..
client_cpa: afsd
- $(CD) src\WINNT\$@
+ echo ***** $@
+ $(CD) $(OBJ)\WINNT\$@
$(NTMAKE)
$(CD) ..\..\..
client_config: client_cpa
- $(CD) src\WINNT\$@
+ echo ***** $@
+ $(CD) $(OBJ)\WINNT\$@
$(NTMAKE)
$(CD) ..\..\..
client_exp: client_config
- $(CD) src\WINNT\$@
+ echo ***** $@
+ $(CD) $(OBJ)\WINNT\$@
$(NTMAKE)
$(CD) ..\..\..
client_creds: client_exp
- $(CD) src\WINNT\$@
+ echo ***** $@
+ $(CD) $(OBJ)\WINNT\$@
$(NTMAKE)
$(CD) ..\..\..
finale: client_creds
- $(CD) src\$@
+ echo ***** $@
+ $(CD) $(OBJ)\$@
$(NTMAKE)
$(CD) ..\..
# InstallShield dependencies
InstallShield5: install
- $(CD) src\WINNT\install\$@
+ $(CD) $(OBJ)\WINNT\install\$@
$(NTMAKE)
$(CD) ..\..\..\..
-# Clean target for src tree
+# Clean target for obj tree
clean: start
nmake /nologo /f ntmakefile "NTMAKE = nmake /nologo /f ntmakefile clean" "NTMAKE_HEADERS = nmake /nologo /f ntmakefile clean" install
- $(CD) src\config
+ $(CD) $(OBJ)\config
nmake /nologo /f ntmakefile clean_version
$(CD) ..\..
--- /dev/null
+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
+
+Building Open AFS on Win 95
+---------------------------
+
+The Windows 95 Open AFS client consists of two main components: the client
+program afsd.exe, which is compiled with the DJGPP compiler and runs in a
+DOS virtual machine; and the utility programs, which are built on Windows
+NT or 9x using the Microsoft Visual C++ compiler V6.0.
+
+afsd.exe
+--------
+
+afsd.exe is built using the DJGPP cross-compiler, executed from Linux.
+It should also be possible to build it using the native DOS DJGPP compiler,
+but we did not try this. You will need to install the following packages
+from DJGPP and the Coda project.
+
+ftp://ftp.coda.cs.cmu.edu/pub/tools/djgpp-2.01_0.93_glibc-1.i386.rpm
+ftp://ftp.coda.cs.cmu.edu/pub/tools/djgpp-win95ext-2.01_0.93_glibc-1.i386.rpm
+ftp://ftp.coda.cs.cmu.edu/pub/tools/gdb-djgpp-4.16-2.i386.rpm
+
+You will also need the MMAP.VXD and SOCK.VXD from the Coda project. Source
+is available here:
+ftp://ftp.coda.cs.cmu.edu/pub/coda/src/win95-coda-5.2.0.zip
+
+Follow the Coda instructions to build these VXD's, which you can read here:
+http://www.coda.cs.cmu.edu/doc/html/coda-howto-6.html#ss6.4
+
+Once you have the necessary tools installed, set the following environment
+variables:
+SYS_NAME: set to i386_djgpp
+LINUX_SYS: set to the sysname of the Linux version you are using, e.g.,
+ i386_linux22
+
+The makefile expects to build into a platform directory with symlinks
+into the source directory. The Perl script "mkdest.pl" in this dir. will
+set this up for you. To use it, create a directory under the top-level
+dir. (the directory above src) called "i386_djgpp". Then cd to that
+directory and type "../src/mkdest.pl <absolute path of your src dir.>"
+
+Then execute "make -f Makefile.djgpp" from the top-level directory.
+(You can create a symlink to src/Makefile.djgpp from this dir.)
+The afsd.exe will be built into i386_djgpp/dest/bin.
+
+Build notes:
+
+ The Makefile.djgpp actually builds Linux versions of the utilities
+ rxgen, install, compile_et, and util.a. It uses the Linux version
+ of param.h which it copies to the afs subdirectory of the above
+ components. You will need to set SYS_NAME to your Linux system name
+ manually if you want to build these utilities separately.
+
+Utilities and GUI programs
+--------------------------
+
+The rest of the support programs are built as Win32 executables from a
+Windows 9x or NT system. You will need to set the following environment
+variables:
+
+set SYS_NAME=i386_win95
+set AFSDEV_BUILDTYPE=CHECKED (or FREE if you want to skip debugging info.)
+set AFSDEV_INCLUDE=<path of your Visual C include files>
+set AFSDEV_LIB=<path of your Visual C libs>
+set AFSDEV_BIN=.
+set AFSROOT=<PATH to base of development directory>
+ e.g. AFSROOT\SRC is source directory of the build tree
+SET _WIN32_IE=0x400
+set OBJ=src or obj, see below
+set MSSDK=<path to sdk header files>, see below
+
+If you are building on a Unix directory exported to Windows through Samba
+or AFS, you can create a platform directory named "i386_win95" using the
+"mkdest.pl" script as described above (run from a Unix system). This will
+only work on a file system that supports symbolic links. If you are using
+a platform directory, set the OBJ environment var. to "obj" and create
+a symlink "obj" in the top-level dir. that points to "i386_win95/obj".
+Otherwise, set OBJ to "src" to build the objects with the sources.
+
+The environment variable AFSROOT points to the parent of the AFS src
+directory. Executables will be built by default in AFSROOT\dest.
+
+Copy the file src\NTMake9x to the parent of the src directory. You only
+need to do this once. If you are building on a local drive, copy
+AFSROOT\src\symlink.bat to AFSROOT\.
+
+Follow the NT build instructions in file "README-NT" to perform the build.
+You will be using "NTMake9x" as the top-level makefile, instead of
+"NTMakefile". Most of the instructions in "README-NT" apply to the Win9x
+build as well.
+
+Build Notes:
+
+1) If you are building the Windows 9x AFS Client Control Panel
+ (win9xpanel), it requires shlwapi.h. This file can be found in the
+ header files associated with the Windows SDK (95/98 NT or W2000).
+
+2) You can build the Windows 9x client from a Windows NT or W2000 system.
+ This requires you to edit AFSROOT\config\NTMakefile.i386_win95.
+ Change line: DEL = $(AFSROOT)\src\rmbat
+ to: DEL = -del /q /f
+
+3) If you build the W2000 client, then switch to building the Windows 95
+ client (or vice versa), you should clean the previous build by either:
+ nmake -f ntmakefile clean
+or nmake -f ntmake9x clean
+
+4) When building the "comerr" component, the makefile now uses the
+ existing error_table_nt.c file (and touches it so it will be up to date
+ by default.) If you make changes to the lex or yacc source files and want
+ to rebuild error_table_nt.c, you can simply delete it and rerun make,
+ which will cause the file to be built using lex and yacc. Make sure
+ you have these utilities on your system.
+
+5) Required DLL's for redistribution
+
+ The AFS Control Panel for Win95/98 requires Microsoft DLL's that can
+ be installed using:
+ VC6RedistSetup_enu.exe
+ This is located at:
+ http://support.microsoft.com/support/kb/articles/Q259/4/03.ASP
+
+6) Installation
+
+ First, execute "nmake /f ntmake9x media" to copy all the client
+ executables and other files to DEST\WinInstall.
+
+ You can then install the client onto a target Windows 9x machine by
+ executing:
+ install.bat <source> <drive> <install dir.> <home cell> <cache size in 1K blocks>
+ For example,
+ install.bat DEST\WinInstall\ c: \afscli almaden.ibm.com 40000
+
+ If you do not wish to use the batch file, you can install the client
+ manually by performing the following steps.
+
+ 1. On the target machine, copy all the files from DEST\WinInstall to the
+ install location (usually c:\afscli).
+ 2. Add entries to the target's AUTOEXEC.BAT file as follows:
+ set AFSCONF=c:\afscli (replace with your install dir.)
+ path %path%;c:\afscli
+ 3. Copy the template.reg file to afscli.reg. Replace any references
+ to c: and afscli with your install location. Double click on the
+ afscli.reg file to add the registry entries to the target system.
+ 4. Create the following AFS configuration files in the install dir.:
+ - ThisCell:
+ containing the name of your home cell
+ - cache.info:
+ containing your cache configuration. For example,
+ to configure a cache of 40,000 1KB blocks with a disk cache
+ location of c:\afscache, you would enter in this file:
+ /afs:c:\afscache;40000
+ (The cache location has no effect unless you have enabled
+ the experimental disk cache support.)
+ - CellServDB:
+ the cell server database. You can get the latest version from AFS:
+ /afs/transarc.com/service/etc/CellServDB.export
+ 5. Reboot the target machine.
+ 6. You can now start the client by executing the program WinAfsLoad.exe
+ from the install directory.
--- /dev/null
+Win9x AFS Client: Technical Notes
+---------------------------------
+
+This file gives a technical overview of the Win9x AFS client and describes
+the main differences from the NT client.
+
+
+Overview
+--------
+
+The Windows 9x client is based on the Windows NT/2000 client. Like the
+NT client, it exports AFS through an SMB interface. Programs access AFS
+files by mounting AFS submounts as SMB shares and using the built-in
+Windows SMB client to communicate with the AFS client. The AFS client
+acts as an SMB server. It runs entirely at user level.
+
+DOS box implementation and VXD's
+--------------------------------
+
+The main program of the Win9x client, afsd.exe, is implemented as a
+32-bit DOS program. It is compiled using the DJGPP compiler and runs in
+a Windows 9x DOS virtual machine. This approach was necessary to avoid
+a well-known deadlock problem in Windows 9x when the kernel calls up
+to a user-level Win32 daemon: the original requesting program grabs the
+Win16Mutex before entering the kernel. The request is then passed up to
+the daemon, who attempts to service it using network or file I/O calls.
+These calls also attempt to obtain the Win16Mutex, which is still being
+held by the original requester, so there is a deadlock.
+
+To avoid this problem, the daemon runs in a DOS box. I/O calls from
+a DOS program do not attempt to obtain the Win16Mutex, so the deadlock
+is avoided. This approach was discovered by the Coda team at Carnegie
+Mellon University and used to implement a Win9x version of their client.
+The Win9x AFS client uses the same approach. It also uses the Coda team's
+SOCK.VXD which was written to provide network functions to a DOS program.
+Sockets functions which call SOCK.VXD were added to the DJGPP library.
+
+For more information about the Coda team's approach to this problem, see
+their paper from Usenix 1999:
+http://www.cs.cmu.edu/afs/cs/project/coda/Web/docdir/freenix99.pdf
+
+Note that the AFS client also requires the Coda team's MMAP.VXD. We are
+not actually calling this VXD, but afsd crashes if it is built without
+it (i.e., by building with dos-gcc -bw95 instead of -bmmap). Solutions to
+this problem welcomed..
+
+Netbios functions
+-----------------
+
+The Windows AFS clients communicate with user applications using the
+SMB protocol, as described above. SMB communication is done using the
+Netbios interface. In Win32, there is a built-in function Netbios()
+which accomplishes this. In a DOS program, however, this function is
+unavailable. However, Netbios functionality is available in the BIOS
+by calling interrupt 0x5c. The NCB (Netbios Control Block) and data
+buffer must be in conventional DOS memory, i.e., below 1 MB. This memory
+can only be accessed in DJGPP by using the DOS memory access functions:
+dosmemget(), dosmemput(), _farpeekX() and _farpokeX(). The Win9x client
+uses a separately-allocated DOS memory buffer and copies data to and from
+DOS memory for network communication.
+
+Functions were also added to LWP's iomgr.c to check for the completion
+of Netbios requests. The IOMGR now checks for NCB completion in addition
+to checking for timer expiration, signal delivery, and performing select()
+on file descriptors.
+
+See the new files: netbios95.c, dosutils95.c, and the various changes
+(marked by "#ifdef DJGPP") to smb.c in WINNT/afsd. Also see lwp/iomgr.c.
+
+Thread functions
+----------------
+
+Unlike the NT client which uses Win32 thread and locking functions,
+the Win9x client uses the LWP package from the AFS source distribution.
+An interface layer was added to allow NT and Win9x to make the same calls.
+For example, thrd_Create() is now used to create a thread. In NT, this
+is just a macro to the Win32 function CreateThread(). In Win9x, it is a
+function which calls the LWP function LWP_CreateProcess(). See the new
+files osithrd95.c, osithrd95.h, and osithrdnt.h in WINNT/client_osi.
+
+Configuration parameters
+------------------------
+
+In DJGPP, it is not feasible to access the system registry, which is
+where the NT client stores its configuration info. For the Win9x client,
+the Unix approach is followed instead: the local cell is in a file called
+"ThisCell", cache configuration is in a file called "cache.info", and
+the cell database is stored in "CellServDB" instead of "afsdcell.ini".
+Many parameters are passed via the command line to afsd.exe and are
+processed just like the Unix clients.
+
+See the new files afsd_init95.c and afsd95.c in WINNT/afsd.
+
+Authentication
+--------------
+
+In the functions SetToken() and GetToken(), the NT client sends and
+receives the session key using a separate RPC which should use encryption,
+rather than including the session key in the pioctl packet. The Win9x
+version avoids this RPC and puts the session key back into the pioctl.
+This should not be a security issue on Win9x since it is a single-user
+machine. (The pioctl packet will not be visible externally.) See files
+WINNT/afsd/cm_ioctl.c and auth/ktc_nt.c.
+
+Persistent (disk) caching
+-------------------------
+
+Disk caching support was added for the 9x client. This has barely been
+tested and is still very experimental! In addition, there are numerous
+performance issues. It relies on the fact that LWP is a non-preemptive
+threads package, so no locking is done to protect shared data structures.
+In addition, it uses synchronous I/O to read and write disk files. Since
+LWP is a user-level threads package, any calls to normal I/O system calls
+like read() or write() will block the entire process. One better approach
+would be to add support for local disk file descriptors to the select()
+call used by IOMGR, and then to use IOMGR_Select to enqueue I/O requests
+to the disk. Currently, the select() function supports only sockets.
+
+It should be fairly easy to adapt this code for the NT client. See the
+implementation in WINNT/afsd/cm_diskcache95.c. To enable this code,
+define DISKCACHE95 in WINNT/afsd/Makefile.djgpp.
+
+Utility programs
+----------------
+
+The utility programs, such as klog.exe and fs.exe, are Win32 programs and
+are built using the Microsoft compiler. Changes to the code for these
+files are marked by "#ifdef AFS_WIN95_ENV".
+
+GUI interface
+-------------
+
+The Win9x client does not use the NT configuration GUI programs in
+client_creds and client_cpa (Control Panel Applet.) It uses a separate
+GUI program called WinAfsLoad.exe in WINNT/win9xpanel. This program can
+start afsd.exe and keep track of submounts and token expiration.
+
+The Explorer shell extension, which allows right clicking on a file
+in Windows Explorer to get an AFS submenu, is supported in Win9x.
+See WINNT/client_exp.
+
+Integrated logon
+----------------
+
+Integrated logon is not supported in the 9x client.
+
+Known issues
+------------
+
+1) The Microsoft linker LINK386.exe causes a deadlock when attempting to
+create an executable on an AFS filesystem. Somehow, the linker appears
+to be preempting the entire machine so afsd.exe cannot run to service
+requests. Solutions to this problem eagerly sought! (This problem does
+not seem to occur with the Win9x Coda client.)
--- /dev/null
+#
+# Makefile.djgpp
+# make information for this directory
+# requires gmake
+#
+
+SOURCES = afsd95.c afsd_init95.c cm_access.c cm_aclent.c cm_buf.c \
+ cm_callback.c cm_cell.c cm_config.c cm_conn.c cm_daemon.c \
+ cm_dcache.c cm_dir.c cm_dnlc.c cm_ioctl.c cm_scache.c \
+ cm_server.c cm_user.c cm_utils.c cm_vnodeops.c cm_volume.c \
+ dosutils95.c largeint95.c netbios95.c smb.c smb_ioctl.c \
+ cm_diskcache95.c queue95.c afsmsg95.c smb3.c
+
+include ../../config/Makefile.djgpp.common
+
+# apply changes from common for this directory
+#
+# no changes for this directory
+
+# what this directory builds
+#
+TARGETS = afsd.exe
+all : $(TARGETS)
+install : $(DESTBIN)/afsd.exe #$(DESTBIN)/klog.exe
+#CFLAGS += -I../vxd_lib
+#CFLAGS += -DAFS_VXD
+CFLAGS += -DDOS_PKT_WHOLE
+
+INCFILES = \
+ $(DESTINC)/netbios95.h \
+ $(DESTINC)/largeint95.h \
+ $(DESTINC)/dosdefs95.h \
+ $(DESTINC)/afs/afsmsg95.h
+
+# hard-wired dependency information
+#
+REQUIRED_LIBS = $(DESTLIB)/liblwp.a $(DESTLIB)/libosi.a \
+ $(DESTLIB)/afs/libcmd.a $(DESTLIB)/afs/libafsint.a \
+ $(DESTLIB)/afs/libvldb.a $(DESTLIB)/librxkad.a \
+ $(DESTLIB)/librx.a $(DESTLIB)/librxstat.a
+
+
+afsd.exe : $(ALL_OBJS) $(REQUIRED_LIBS)
+
+includes: $(INCFILES)
+
+EXECUTABLES = afsd afsd.exe
+
+$(DESTLIB)/liblwp.a :
+ $(MAKE) -C ../lwp install
+
+$(DESTLIB)/librx.a :
+ $(MAKE) -C ../rx install
+
+$(DESTLIB)/libosi.a :
+ $(MAKE) -C ../client_osi install
+
+$(DESTLIB)/libcmd.a :
+ $(MAKE) -C ../../cmd install
+
+$(DESTLIB)/libafsint.a :
+ $(MAKE) -C ../../fsint install
+
+$(DESTLIB)/librxkad.a :
+ $(MAKE) -C ../../rxkad install
+
+$(DESTLIB)/libvldb.a :
+ $(MAKE) -C ../../vlserver install
$(INCFILEDIR)\smb3.h \
$(INCFILEDIR)\smb_iocons.h \
$(INCFILEDIR)\smb_ioctl.h \
+ $(INCFILEDIR)\afsmsg95.h \
$(INCFILEDIR)\afsrpc.h
IDLFILES =\
$(EXEDIR)\afsshare.exe \
$(DESTDIR)\bin\kpasswd.exe
+install9X: install_headers $(CONF_DLLFILE) \
+ $(EXEDIR)\klog.exe \
+ $(EXEDIR)\tokens.exe \
+ $(EXEDIR)\unlog.exe $(EXEDIR)\afsd_service.exe \
+ $(EXEDIR)\fs.exe $(EXEDIR)\symlink.exe \
+ $(LOGON_DLLFILE) $(LOG95_DLLFILE) \
+ $(EXEDIR)\afsshare.exe \
+ $(DESTDIR)\bin\kpasswd.exe
+
+install_libutils: install_headers $(CONF_DLLFILE) \
+ $(EXEDIR)\klog.exe \
+ $(EXEDIR)\tokens.exe \
+ $(EXEDIR)\unlog.exe \
+ $(EXEDIR)\fs.exe $(EXEDIR)\symlink.exe \
+ $(EXEDIR)\afsshare.exe \
+ $(DESTDIR)\bin\kpasswd.exe
+
############################################################################
# Local clean target; augments predefined clean target
-clean::
- $(DEL) *.res
-
############################################################################
# assorted exe's
afslog95.res: afslog95.rc AFS_component_version_number.h
libafsconf.res: libafsconf.rc AFS_component_version_number.h
+
+clean::
+ $(DEL) *.res
+ $(DEL) afsrpc.h
+ $(DEL) afsrpc_?.*
+ $(DEL) $(EXELIBS)
#ifndef __AFSD_H_ENV__
#define __AFSD_H_ENV__ 1
+#include <afs/param.h>
+
+#ifndef DJGPP
BOOL InitClass(HANDLE);
BOOL InitInstance(HANDLE, int);
LONG APIENTRY MainWndProc(HWND, unsigned int, unsigned int, long);
BOOL APIENTRY About(HWND, unsigned int, unsigned int, long);
+#endif /* !DJGPP */
+#ifndef DJGPP
#include <nb30.h>
+#else /* DJGPP */
+#include <sys/farptr.h>
+#include <go32.h>
+#include "dosdefs95.h"
+#include "largeint95.h"
+#endif /* !DJGPP */
+
#include "afsdicon.h"
#include "cm.h"
#include <crypt.h>
#include <afs/prs_fs.h>
-#include "cm_access.h"
+#include <osi.h>
+#include "cm_user.h"
+#include "cm_callback.h"
+#ifdef DISKCACHE95
+#include "cm_diskcache95.h"
+#endif /* DISKCACHE95 */
+#include "cm_conn.h"
#include "cm_aclent.h"
#include "cm_cell.h"
#include "cm_config.h"
#include "cm_server.h"
-#include "cm_user.h"
-#include "cm_conn.h"
#include "cm_volume.h"
-#include "cm_access.h"
#include "cm_scache.h"
#include "cm_dcache.h"
-#include "cm_buf.h"
-#include "cm_callback.h"
+#include "cm_access.h"
#include "cm_vnodeops.h"
#include "cm_dir.h"
#include "cm_utils.h"
#include "cm_daemon.h"
#include "cm_ioctl.h"
#include "cm_dnlc.h"
+#include "cm_buf.h"
+#ifdef DJGPP
+#include "afs/afsmsg95.h"
+#endif
#include <afs/vldbint.h>
#include <afs/afsint.h>
#define AFS_DAEMON_SERVICE_NAME "TransarcAFSDaemon"
#define AFS_DAEMON_EVENT_NAME "AFS Client"
+void afs_exit();
+
/* globals from the base afsd */
extern int cm_logChunkSize;
--- /dev/null
+/*
+ * 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 <afs/param.h>
+#include <afs/stds.h>
+
+/*#include <windows.h>*/
+#include <string.h>
+/*#include <nb30.h>*/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <osi.h>
+#include <signal.h>
+#include <afs/cmd.h>
+/*#include <winsock2.h>*/
+#include "afsd.h"
+#include "afsd_init.h"
+
+
+char main_statusText[100];
+osi_log_t *afsd_logp;
+
+extern int traceOnPanic;
+BOOL InitInstance(struct cmd_syndesc *as, char *arock);
+extern int afs_shutdown;
+int tried_shutdown=0;
+
+int afs_current_status = AFS_STATUS_INIT;
+
+/*
+ * Notifier function for use by osi_panic
+ */
+void afsd_notifier(char *msgp, char *filep, long line)
+{
+ char tbuffer[100];
+ if (filep)
+ sprintf(tbuffer, "Error at file %s, line %d", filep, line);
+ else
+ strcpy(tbuffer, "Error at unknown location");
+
+ if (!msgp)
+ msgp = "Assertion failure";
+
+ /*MessageBox(NULL, tbuffer, msgp, MB_OK|MB_ICONSTOP|MB_SETFOREGROUND);*/
+
+ afsd_ForceTrace(TRUE);
+
+ if (traceOnPanic) {
+ /*asm("int 3");*/
+ }
+
+ afs_exit(AFS_EXITCODE_PANIC);
+}
+
+/* Init function called when window application starts. Inits instance and
+ * application together, since in Win32 they're essentially the same.
+ *
+ * Function then goes into a loop handling user interface messages. Most are
+ * used to handle redrawing the icon.
+ */
+int main(int argc, char *argv[])
+{
+ struct cmd_syndesc *ts;
+
+ fprintf(stderr, "AFS Client for Windows 95.\n");
+ /*fprintf(stderr, "Use Ctrl-C to shut down client.\n\n\n");*/
+ ts = cmd_CreateSyntax((char *) 0, (int (*)()) InitInstance, (char *) 0, "start AFS");
+ cmd_AddParm(ts, "-lanadapt", CMD_SINGLE, CMD_OPTIONAL, "LAN adapter number");
+ cmd_AddParm(ts, "-threads", CMD_SINGLE, CMD_OPTIONAL, "Number of server threads");
+ cmd_AddParm(ts, "-rootvol", CMD_SINGLE, CMD_OPTIONAL, "name of AFS root volume");
+ cmd_AddParm(ts, "-stat", CMD_SINGLE, CMD_OPTIONAL, "number of stat entries");
+ cmd_AddParm(ts, "-memcache", CMD_FLAG, CMD_OPTIONAL, "use memory cache");
+ cmd_AddParm(ts, "-cachedir", CMD_SINGLE, CMD_OPTIONAL, "cache directory");
+ cmd_AddParm(ts, "-mountdir", CMD_SINGLE, CMD_OPTIONAL, "mount location");
+ cmd_AddParm(ts, "-daemons", CMD_SINGLE, CMD_OPTIONAL, "number of daemons to use");
+ cmd_AddParm(ts, "-nosettime", CMD_FLAG, CMD_OPTIONAL, "don't set the time");
+ cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, "display lots of information");
+ cmd_AddParm(ts, "-debug", CMD_FLAG, CMD_OPTIONAL, "display debug info");
+ cmd_AddParm(ts, "-chunksize", CMD_SINGLE, CMD_OPTIONAL, "log(2) of chunk size");
+ cmd_AddParm(ts, "-dcache", CMD_SINGLE, CMD_OPTIONAL, "number of dcache entries");
+ cmd_AddParm(ts, "-confdir", CMD_SINGLE, CMD_OPTIONAL, "configuration directory");
+ cmd_AddParm(ts, "-logfile", CMD_SINGLE, CMD_OPTIONAL, "Place to keep the CM log");
+ cmd_AddParm(ts, "-waitclose", CMD_FLAG, CMD_OPTIONAL, "make close calls synchronous");
+ cmd_AddParm(ts, "-shutdown", CMD_FLAG, CMD_OPTIONAL, "Shutdown all afs state");
+ cmd_AddParm(ts, "-sysname", CMD_SINGLE, CMD_OPTIONAL, "System name (@sys value)");
+ cmd_AddParm(ts, "-gateway", CMD_FLAG, CMD_OPTIONAL, "machine is a gateway");
+ cmd_AddParm(ts, "-tracebuf", CMD_SINGLE, CMD_OPTIONAL, "trace buffer size");
+ cmd_AddParm(ts, "-startup", CMD_FLAG, CMD_OPTIONAL, "start AFS client");
+ cmd_AddParm(ts, "-diskcache", CMD_SINGLE, CMD_OPTIONAL, "diskcache size");
+
+ return (cmd_Dispatch(argc, argv));
+}
+
+/* initialize the process. Reads the init files to get the appropriate
+ * information. */
+void vxd_Shutdown(void);
+int afsd_shutdown(int);
+int shutdown_handler(int);
+
+BOOL InitInstance(struct cmd_syndesc *as, char *arock)
+{
+ long code;
+ char *reason;
+
+#ifdef DJGPP
+ osi_Init();
+#endif
+
+#ifndef DJGPP
+ osi_InitPanic(afsd_notifier);
+#endif
+
+ /*sleep(10);*/
+
+ afsi_start();
+
+ code = afsMsg_Init();
+ if (code != 0)
+ osi_panic("socket failure", __FILE__, __LINE__);
+
+ code = afsd_InitCM(&reason, as, arock);
+ if (code != 0)
+ osi_panic(reason, __FILE__, __LINE__);
+
+ code = afsd_InitDaemons(&reason);
+ if (code != 0)
+ osi_panic(reason, __FILE__, __LINE__);
+
+ code = afsd_InitSMB(&reason);
+ if (code != 0)
+ osi_panic(reason, __FILE__, __LINE__);
+
+ signal(SIGINT, shutdown_handler);
+
+ thrd_Yield(); /* give new threads a chance to run */
+
+ /* send message to GUI caller indicating successful init */
+ afs_current_status = AFS_STATUS_RUNNING;
+ afsMsg_StatusChange(afs_current_status, 0, NULL);
+
+#ifdef DJGPP
+ /* Keep the process from just terminating */
+ while(afs_shutdown == 0)
+ {
+ /*IOMGR_Sleep(180);*/
+ IOMGR_Sleep(8);
+ /* workaround: WaitForKeystroke(nonzero num) calls
+ IOMGR_Select, though Win95 select works only on sockets */
+ /* so, we poll instead */
+ /*if (LWP_WaitForKeystroke(0))
+ break;*/
+ }
+ afsd_shutdown(0);
+#endif
+ afs_exit(0);
+
+ return (TRUE);
+}
+
+int shutdown_handler(int x)
+{
+ if (!tried_shutdown)
+ {
+ fprintf(stderr, "This program should not be shut down manually. It should "
+ "be shut down by the\nWindows AFS Client Control Center. Press Ctrl-C "
+ "again if you really want to do this.\n");
+ fflush(stderr);
+ tried_shutdown = 1;
+ }
+ else
+ {
+ fprintf(stderr, "Shutting down AFSD...\n");
+ fflush(stderr);
+ afs_shutdown = 1;
+ }
+}
+
+int afsd_shutdown(int x)
+{
+#ifdef AFS_VXD
+ vxd_Shutdown();
+#else
+ smb_Shutdown();
+#endif
+
+ fprintf(stderr, "AFSD shutdown complete.\n");
+ /*exit(0);*/
+}
+
+void afs_exit(int exitCode)
+{
+ afs_current_status = AFS_STATUS_EXITING;
+ afsMsg_StatusChange(afs_current_status,
+ exitCode, NULL);
+ afsMsg_Shutdown();
+ exit(exitCode);
+}
void afsi_start();
+#ifndef DJGPP
int afsd_InitCM(char **reasonP);
-int afsd_InitDaemons(char **reasonP);
int afsd_InitSMB(char **reasonP, void *aMBfunc);
+#else /* DJGPP */
+int afsd_InitCM(char **reasonP, struct cmd_syndesc *as, char *arock);
+int afsd_InitSMB(char **reasonP);
+#endif /* !DJGPP */
+int afsd_InitDaemons(char **reasonP);
void afsd_ForceTrace(BOOL flush);
--- /dev/null
+/*
+ * 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 <afs/param.h>
+#include <afs/stds.h>
+#include <afs/afs_args.h>
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <stdarg.h>
+
+#include <osi.h>
+#include "afsd.h"
+#include <rx/rx.h>
+#include <rx/rx_null.h>
+#include <afs/cmd.h>
+#include <netdb.h>
+#include "cm_rpc.h"
+
+#define AFSDIR_CLIENT_ETC_DIRPATH "c:/"
+#define AFSLOGFILE "afs.log"
+#define CACHEINFOFILE "cache.info"
+
+extern int RXAFSCB_ExecuteRequest();
+extern int RXSTATS_ExecuteRequest();
+
+osi_log_t *afsd_logp;
+
+char cm_rootVolumeName[64];
+DWORD cm_rootVolumeNameLen;
+cm_volume_t *cm_rootVolumep = NULL;
+cm_cell_t *cm_rootCellp = NULL;
+cm_fid_t cm_rootFid;
+cm_scache_t *cm_rootSCachep;
+char cm_mountRoot[1024];
+DWORD cm_mountRootLen;
+int cm_logChunkSize;
+int cm_chunkSize;
+int afs_diskCacheChunks;
+char cm_cachePath[128];
+int cm_diskCacheEnabled = 0;
+
+int smb_UseV3;
+
+int LANadapter;
+int lanAdaptSet = 0;
+int rootVolSet = 0;
+int cacheSetTime = TRUE;
+int afsd_verbose = 0;
+int chunkSize;
+
+int numBkgD;
+int numSvThreads;
+
+int traceOnPanic = 0;
+
+int logReady = 0;
+
+char cm_HostName[200];
+long cm_HostAddr;
+
+/*char cm_CachePath[200];*/
+/*DWORD cm_CachePathLen;*/
+char cm_CacheInfoPath[1024];
+int cacheBlocks;
+int sawCacheSize=0, sawDiskCacheSize=0, sawMountRoot=0;
+int sawCacheBaseDir=0;
+char cm_AFSLogFile[200];
+int afsd_CloseSynch = 0;
+int afs_shutdown = 0;
+char cm_confDir[200];
+
+BOOL isGateway = FALSE;
+BOOL reportSessionStartups = FALSE;
+
+int afsd_debug;
+cm_initparams_v1 cm_initParams;
+
+/*
+ * AFSD Initialization Log
+ *
+ * This is distinct from the regular debug logging facility.
+ * Log items go directly to a file, not to an array in memory, so that even
+ * if AFSD crashes, the log can be inspected.
+ */
+
+FILE *afsi_file;
+
+void
+afsi_start()
+{
+ char wd[100];
+ char t[100], u[100];
+ int zilch;
+ int code;
+ time_t now;
+ char *p;
+
+ afsi_file = NULL;
+ /*code = GetWindowsDirectory(wd, sizeof(wd));
+ if (code == 0) return;*/
+ strcpy (wd, "C:");
+ strcat(wd, "\\afsd_init.log");
+ /*GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, NULL, t, sizeof(t));*/
+ time (&now);
+ strcpy(t, asctime(localtime(&now)));
+ /*afsi_file = CreateFile(wd, GENERIC_WRITE, FILE_SHARE_READ, NULL,
+ CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH, NULL);*/
+ /*afsi_file = open(wd, O_RDWR | O_CREAT | O_RSHARE);*/
+ afsi_file = fopen(wd, "wt");
+ setbuf(afsi_file, NULL);
+
+ /*GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, NULL, u, sizeof(u));*/
+ time (&now);
+ strcpy(u, asctime(localtime(&now)));
+ p = strchr(u, '\n'); if (p) *p = 0;
+ p = strchr(u, '\r'); if (p) *p = 0;
+ strcat(t, ": Create log file\n");
+ strcat(u, ": Created log file\n");
+ /*WriteFile(afsi_file, t, strlen(t), &zilch, NULL);
+ WriteFile(afsi_file, u, strlen(u), &zilch, NULL);*/
+ /*write(afsi_file, t, strlen(t));
+ write(afsi_file, u, strlen(u));*/
+ fputs(t, afsi_file);
+ fputs(u, afsi_file);
+}
+
+void
+afsi_log(char *pattern, ...)
+{
+ char s[100], t[100], u[100];
+ int zilch;
+ time_t now;
+ va_list ap;
+#ifndef DEBUG
+ return;
+#endif
+ va_start(ap, pattern);
+
+ vsprintf(s, pattern, ap);
+ /*GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, NULL, t, sizeof(t));*/
+ time(&now);
+ strcpy(t, asctime(localtime(&now)));
+ sprintf(u, "%s: %s\n", t, s);
+ if (afsi_file != NULL)
+ /* fputs(u, stderr); */
+ fputs(u, afsi_file);
+ /*write(afsi_file, u, strlen(u));*/
+ /*WriteFile(afsi_file, u, strlen(u), &zilch, NULL);*/
+}
+
+/*
+ * Standard AFSD trace
+ */
+
+void afsd_ForceTrace(BOOL flush)
+{
+ FILE *handle;
+ int len;
+ char buf[100];
+
+ if (!logReady) return;
+
+ /*len = GetTempPath(99, buf);*/
+ /*strcpy(&buf[len], "/afsd.log");*/
+ strcpy(buf, "c:/afsd.log");
+ /*handle = CreateFile(buf, GENERIC_WRITE, FILE_SHARE_READ,
+ NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);*/
+ /*handle = open(buf, O_RDWR | O_CREAT | O_RSHARE);*/
+ handle = fopen(buf, "wt");
+ if (handle == NULL) {
+ logReady = 0;
+ osi_panic("Cannot create log file", __FILE__, __LINE__);
+ }
+ osi_LogPrint(afsd_logp, handle);
+ if (flush)
+ fflush(handle);
+ /*FlushFileBuffers(handle);*/
+ /*CloseHandle(handle);*/
+ fclose(handle);
+}
+
+/*------------------------------------------------------------------------------
+ * ParseCacheInfoFile
+ *
+ * Description:
+ * Open the file containing the description of the workstation's AFS cache
+ * and pull out its contents. The format of this file is as follows:
+ *
+ * cm_mountRoot:cacheBaseDir:cacheBlocks
+ *
+ * Arguments:
+ * None.
+ *
+ * Returns:
+ * 0 if everything went well,
+ * 1 otherwise.
+ *
+ * Environment:
+ * Nothing interesting.
+ *
+ * Side Effects:
+ * Sets globals.
+ *---------------------------------------------------------------------------*/
+
+int ParseCacheInfoFile()
+{
+ static char rn[]="ParseCacheInfoFile"; /*This routine's name*/
+ FILE *cachefd; /*Descriptor for cache info file*/
+ int parseResult; /*Result of our fscanf()*/
+ int32 tCacheBlocks;
+ char tCacheBaseDir[1024], *tbd, tCacheMountDir[1024], *tmd;
+ /*char cacheBaseDir[1024]; /* cache in mem, this is ignored */
+
+ if (afsd_debug)
+ printf("%s: Opening cache info file '%s'...\n",
+ rn, cm_CacheInfoPath);
+
+ cachefd = fopen(cm_CacheInfoPath, "r");
+ if (!cachefd) {
+ printf("%s: Can't read cache info file '%s'\n",
+ rn, cm_CacheInfoPath);
+ return(1);
+ }
+
+ /*
+ * Parse the contents of the cache info file. All chars up to the first
+ * colon are the AFS mount directory, all chars to the next colon are the
+ * full path name of the workstation cache directory and all remaining chars
+ * represent the number of blocks in the cache.
+ */
+ tCacheMountDir[0] = tCacheBaseDir[0] = '\0';
+ parseResult = fscanf(cachefd,
+ "%1024[^;];%1024[^;];%d",
+ tCacheMountDir, tCacheBaseDir, &tCacheBlocks);
+
+ /*
+ * Regardless of how the parse went, we close the cache info file.
+ */
+ fclose(cachefd);
+
+ if (parseResult == EOF || parseResult < 3) {
+ printf("%s: Format error in cache info file!\n",
+ rn);
+ if (parseResult == EOF)
+ printf("\tEOF encountered before any field parsed.\n");
+ else
+ printf("\t%d out of 3 fields successfully parsed.\n",
+ parseResult);
+
+ printf("\tcm_mountRoot: '%s'\n\tcm_cachePath: '%s'\n\tcacheBlocks: %d\n",
+ cm_mountRoot, cm_cachePath, cacheBlocks);
+ return(1);
+ }
+
+ for (tmd = tCacheMountDir; *tmd == '\n' || *tmd == ' ' || *tmd == '\t'; tmd++) ;
+ for (tbd = tCacheBaseDir; *tbd == '\n' || *tbd == ' ' || *tbd == '\t'; tbd++) ;
+ /* now copy in the fields not explicitly overridden by cmd args */
+ if (!sawMountRoot)
+ {
+ strcpy(cm_mountRoot, tmd);
+ cm_mountRootLen = strlen(tmd);
+ }
+ if (!sawCacheBaseDir)
+ strcpy(cm_cachePath, tbd);
+ if (!sawCacheSize)
+ cacheBlocks = tCacheBlocks;
+
+ if (afsd_debug) {
+ printf("%s: Cache info file successfully parsed:\n",
+ rn);
+ printf("\tcm_mountRoot: '%s'\n\tcm_cachePath: '%s'\n\tcacheBlocks: %d\n",
+ tmd, tbd, tCacheBlocks);
+ }
+ /*printf("cm_cachePath: %s\n", cm_cachePath);*/
+
+ /*PartSizeOverflow(tbd, cacheBlocks);*/
+
+ return(0);
+}
+
+/*
+ * AFSD Initialization
+ */
+
+int afsd_InitCM(char **reasonP, struct cmd_syndesc *as, char *arock)
+{
+ osi_uid_t debugID;
+ long cacheBlocks;
+ long cacheSize;
+ long logChunkSize;
+ long stats;
+ long traceBufSize;
+ long ltt, ltto;
+ char rootCellName[256];
+ struct rx_service *serverp;
+ static struct rx_securityClass *nullServerSecurityClassp;
+ struct hostent *thp;
+ char *msgBuf;
+ char buf[200];
+ DWORD dummyLen;
+ long code;
+ struct cmd_syndesc *ts;
+ char *afsconf_path;
+ long diskCacheSize;
+ /*WSADATA WSAjunk;
+
+ WSAStartup(0x0101, &WSAjunk);*/
+
+#ifndef DJGPP
+ /* 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;
+ }
+#endif
+
+ /* who are we ? */
+ gethostname(cm_HostName, sizeof(cm_HostName));
+#ifdef DJGPP
+ /* For some reason, we may be getting space-padded hostnames.
+ If so, we take out the padding so that we can append -AFS later. */
+ {
+ char *space = strchr(cm_HostName,' ');
+ if (space) *space = '\0';
+ }
+#endif
+ 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));
+
+ /* Get configuration parameters from command line */
+
+ /* call atoi on the appropriate parsed results */
+
+ if (!as->parms[20].items) {
+ /* -startup */
+ fprintf(stderr, "Please do not run this program directly. Use the AFS Client Windows loader\nto start AFS.\n");
+ exit(1);
+ }
+
+ if (as->parms[0].items) {
+ /* -lanadapt */
+ LANadapter = atoi(as->parms[0].items->data);
+ lanAdaptSet = 1;
+ afsi_log("LAN adapter number %d", LANadapter);
+ }
+ else
+ {
+ LANadapter = 0;
+ afsi_log("Default LAN adapter number 0");
+ }
+
+ if (as->parms[1].items) {
+ /* -threads */
+ numSvThreads = atoi(as->parms[1].items->data);
+ afsi_log("%d server threads", numSvThreads);
+ }
+ else
+ {
+ numSvThreads = CM_CONFIGDEFAULT_SVTHREADS;
+ afsi_log("Defaulting to %d server threads", numSvThreads);
+ }
+
+ if (as->parms[2].items) {
+ /* -rootvol */
+ strcpy(cm_rootVolumeName, as->parms[2].items->data);
+ rootVolSet = 1;
+ afsi_log("Root volume %s", cm_rootVolumeName);
+ }
+ else
+ {
+ strcpy(cm_rootVolumeName, "root.afs");
+ afsi_log("Default root volume name root.afs");
+ }
+
+ if (as->parms[3].items) {
+ /* -stat */
+ stats = atoi(as->parms[3].items->data);
+ afsi_log("Status cache size %d", stats);
+ }
+ else
+ {
+ stats = CM_CONFIGDEFAULT_STATS;
+ afsi_log("Default status cache size %d", stats);
+ }
+
+ if (as->parms[4].items) {
+ /* -memcache */
+ /* no-op */
+ }
+
+ if (as->parms[5].items) {
+ /* -cachedir */
+ /* no-op; cache is in memory, not mapped file */
+ strcpy(cm_cachePath, as->parms[5].items->data);
+ sawCacheBaseDir = 1;
+ }
+
+ if (as->parms[6].items) {
+ /* -mountdir */
+ strcpy(cm_mountRoot, as->parms[6].items->data);
+ cm_mountRootLen = strlen(cm_mountRoot);
+ sawMountRoot = 1;
+ afsi_log("Mount root %s", cm_mountRoot);
+ }
+ else
+ {
+ strcpy(cm_mountRoot, "/afs");
+ cm_mountRootLen = 4;
+ /* Don't log */
+ }
+
+ if (as->parms[7].items) {
+ /* -daemons */
+ numBkgD = atoi(as->parms[7].items->data);
+ afsi_log("%d background daemons", numBkgD);
+ }
+ else
+ {
+ numBkgD = CM_CONFIGDEFAULT_DAEMONS;
+ afsi_log("Defaulting to %d background daemons", numBkgD);
+ }
+
+ if (as->parms[8].items) {
+ /* -nosettime */
+ cacheSetTime = FALSE;
+ }
+
+ if (as->parms[9].items) {
+ /* -verbose */
+ afsd_verbose = 1;
+ }
+
+ if (as->parms[10].items) {
+ /* -debug */
+ afsd_debug = 1;
+ afsd_verbose = 1;
+ }
+
+ if (as->parms[11].items) {
+ /* -chunksize */
+ chunkSize = atoi(as->parms[11].items->data);
+ if (chunkSize < 12 || chunkSize > 30) {
+ afsi_log("Invalid chunk size %d, using default",
+ logChunkSize);
+ logChunkSize = CM_CONFIGDEFAULT_CHUNKSIZE;
+ }
+ } else {
+ logChunkSize = CM_CONFIGDEFAULT_CHUNKSIZE;
+ afsi_log("Default chunk size %d", logChunkSize);
+ }
+ cm_logChunkSize = logChunkSize;
+ cm_chunkSize = 1 << logChunkSize;
+
+ if (as->parms[12].items) {
+ /* -dcache */
+ cacheSize = atoi(as->parms[12].items->data);
+ afsi_log("Cache size %d", cacheSize);
+ sawCacheSize = 1;
+ }
+ else
+ {
+ cacheSize = CM_CONFIGDEFAULT_CACHESIZE;
+ afsi_log("Default cache size %d", cacheSize);
+ }
+
+ afsconf_path = getenv("AFSCONF");
+ if (!afsconf_path)
+ strcpy(cm_confDir, AFSDIR_CLIENT_ETC_DIRPATH);
+ else
+ strcpy(cm_confDir, afsconf_path);
+ if (as->parms[13].items) {
+ /* -confdir */
+ strcpy(cm_confDir, as->parms[13].items->data);
+ }
+
+ sprintf(cm_CacheInfoPath, "%s/%s", cm_confDir, CACHEINFOFILE);
+
+ sprintf(cm_AFSLogFile, "%s/%s", cm_confDir, AFSLOGFILE);
+ if (as->parms[14].items) {
+ /* -logfile */
+ strcpy(cm_AFSLogFile, as->parms[14].items->data);
+ }
+
+ if (as->parms[15].items) {
+ /* -waitclose */
+ afsd_CloseSynch = 1;
+ }
+
+ if (as->parms[16].items) {
+ /* -shutdown */
+ afs_shutdown = 1;
+ /*
+ * Cold shutdown is the default
+ */
+ printf("afsd: Shutting down all afs processes and afs state\n");
+ /*call_syscall(AFSOP_SHUTDOWN, 1);*/
+ exit(0);
+ }
+
+ if (as->parms[17].items) {
+ /* -sysname */
+ strcpy(cm_sysName, as->parms[17].items->data);
+ }
+ else
+ strcpy(cm_sysName, "i386_win95");
+
+ if (as->parms[18].items) {
+ /* -gateway */
+ isGateway = 1;
+ afsi_log("Set for %s service",
+ isGateway ? "gateway" : "stand-alone");
+ }
+ else
+ isGateway = 0;
+
+ if (as->parms[19].items) {
+ /* -tracebuf */
+ traceBufSize = atoi(as->parms[19].items->data);
+ afsi_log("Trace Buffer size %d", traceBufSize);
+ }
+ else
+ {
+ traceBufSize = CM_CONFIGDEFAULT_TRACEBUFSIZE;
+ afsi_log("Default trace buffer size %d", traceBufSize);
+ }
+
+ if (as->parms[21].items) {
+ /* -diskcache */
+ diskCacheSize = atoi(as->parms[21].items->data);
+ cm_diskCacheEnabled = 1;
+ afsi_log("Disk cache size %d K", diskCacheSize);
+ /*printf("Disk cache size %d K", diskCacheSize);*/
+ sawDiskCacheSize = 1;
+ }
+ else
+ {
+ diskCacheSize = 50000; /*CM_CONFIGDEFAULT_DISKCACHESIZE;*/
+ afsi_log("Default disk cache size %d", diskCacheSize);
+ }
+
+ if (ParseCacheInfoFile()) {
+ exit(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 */
+ cacheBlocks = (cacheSize * 1024) / buf_bufferSize;
+ afs_diskCacheChunks = (diskCacheSize * 1024) / buf_bufferSize;
+ /*printf("afs_diskCacheChunks=%d\n", afs_diskCacheChunks);*/
+
+ /*
+ * 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;
+
+ /* setup and enable debug log */
+ afsd_logp = osi_LogCreate("afsd", traceBufSize);
+ afsi_log("osi_LogCreate log addr %x", afsd_logp);
+ osi_LogEnable(afsd_logp);
+ logReady = 1;
+
+#if 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]);
+#endif
+
+ /* 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;
+ }
+
+ /* Initialize the RPC server for session keys */
+ /*RpcInit();*/
+
+ /* 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", serverp);
+ if (serverp == NULL) {
+ *reasonP = "unknown error";
+ return -1;
+ }
+
+ nullServerSecurityClassp = rxnull_NewServerSecurityObject();
+ serverp = rx_NewService(0, RX_STATS_SERVICE_ID, "rpcstats",
+ &nullServerSecurityClassp, 1, RXSTATS_ExecuteRequest);
+ afsi_log("rx_NewService addr %x", 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");
+
+ /* init user daemon, and other packages */
+ cm_InitUser();
+
+ cm_InitACLCache(2*stats);
+
+ cm_InitConn();
+
+ cm_InitCell();
+
+ cm_InitServer();
+
+ cm_InitVolume();
+
+ cm_InitIoctl();
+
+ smb_InitIoctl();
+
+ cm_InitCallback();
+
+ cm_InitSCache(stats);
+
+ code = cm_InitDCache(0, cacheBlocks);
+
+ afsi_log("cm_InitDCache code %x", code);
+ if (code != 0) {
+ *reasonP = "error initializing cache";
+ return -1;
+ }
+
+ code = cm_GetRootCellName(rootCellName);
+ afsi_log("cm_GetRootCellName code %d rcn %s", code,
+ (code ? "<none>" : rootCellName));
+ if (code != 0) {
+ *reasonP = "can't find root cell name in ThisCell";
+ return -1;
+ }
+
+ cm_rootCellp = cm_GetCell(rootCellName, CM_FLAG_CREATE);
+ afsi_log("cm_GetCell addr %x", cm_rootCellp);
+ if (cm_rootCellp == NULL) {
+ *reasonP = "can't find root cell in CellServDB";
+ return -1;
+ }
+
+ return 0;
+}
+
+int afsd_InitDaemons(char **reasonP)
+{
+ long code;
+ cm_req_t req;
+
+ cm_InitReq(&req);
+
+ /* this should really be in an init daemon from here on down */
+
+ code = cm_GetVolumeByName(cm_rootCellp, cm_rootVolumeName, cm_rootUserp, &req, CM_FLAG_CREATE, &cm_rootVolumep);
+ afsi_log("cm_GetVolumeByName code %x root vol %x", code,
+ (code ? 0xffffffff : cm_rootVolumep));
+ if (code != 0) {
+ *reasonP = "can't find root volume in root cell";
+ return -1;
+ }
+
+ /* compute the root fid */
+ cm_rootFid.cell = cm_rootCellp->cellID;
+ cm_rootFid.volume = cm_GetROVolumeID(cm_rootVolumep);
+ cm_rootFid.vnode = 1;
+ cm_rootFid.unique = 1;
+
+ code = cm_GetSCache(&cm_rootFid, &cm_rootSCachep, cm_rootUserp, &req);
+ afsi_log("cm_GetSCache code %x scache %x", code,
+ (code ? 0xffffffff : cm_rootSCachep));
+ if (code != 0) {
+ *reasonP = "unknown error";
+ return -1;
+ }
+
+ cm_InitDaemon(numBkgD);
+ afsi_log("cm_InitDaemon");
+
+ return 0;
+}
+
+int afsd_InitSMB(char **reasonP)
+{
+ char hostName[200];
+ char *ctemp;
+
+ /* Do this last so that we don't handle requests before init is done.
+ * Here we initialize the SMB listener.
+ */
+ strcpy(hostName, cm_HostName);
+ ctemp = strchr(hostName, '.'); /* turn ntdfs.* into ntdfs */
+ if (ctemp) *ctemp = 0;
+ hostName[11] = 0; /* ensure that even after adding the -A, we
+ * leave one byte free for the netbios server
+ * type.
+ */
+ strcat(hostName, "-AFS");
+ strupr(hostName);
+ smb_Init(afsd_logp, hostName, smb_UseV3, LANadapter, numSvThreads);
+ afsi_log("smb_Init");
+
+ return 0;
+}
--- /dev/null
+/*
+ * 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
+ */
+
+/* This file contains functions used by the Windows 95 (DJGPP) AFS client
+ to communicate with the startup executable. */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include "afs/afsmsg95.h"
+
+int sock;
+struct sockaddr_in addr;
+extern int errno;
+
+int afsMsg_Init()
+{
+ int rc;
+ struct sockaddr_in myaddr;
+
+ sock = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sock < 0)
+ return -1;
+
+ addr.sin_addr.s_addr = htonl(0x7f000001); /* 127.0.0.1 */
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(AFS_MSG_PORT);
+
+ myaddr.sin_addr.s_addr = INADDR_ANY;
+ myaddr.sin_family = AF_INET;
+ myaddr.sin_port = 0;
+
+ rc = bind(sock, (struct sockaddr *) &myaddr, sizeof(myaddr));
+#ifdef DEBUG
+ fprintf(stderr, "afsMsg_Init: bind sock %d rc=%d\n", sock, rc);
+#endif
+
+ return 0;
+}
+
+int afsMsg_StatusChange(int status, int exitCode, char *string)
+{
+ afsMsg_statChange_t *msgP;
+ int rc;
+ int slen = 0;
+ char msgBuf[AFS_MAX_MSG_LEN];
+ int now;
+
+ msgP = (afsMsg_statChange_t *) msgBuf;
+
+ msgP->hdr.msgtype = AFS_MSG_STATUS_CHANGE;
+
+ msgP->newStatus = status;
+ msgP->exitCode = exitCode;
+
+ if (string)
+ {
+ slen = strlen(string); /* one extra for NULL */
+ if (slen > AFS_MAX_MSG_LEN - sizeof(afsMsg_statChange_t))
+ slen = AFS_MAX_MSG_LEN - sizeof(afsMsg_statChange_t);
+ strncpy(&msgP->message, string, slen);
+ }
+
+ msgP->hdr.length = sizeof(afsMsg_statChange_t) + slen;
+
+ rc = sendto(sock, msgP, msgP->hdr.length, 0, (struct sockaddr *) &addr,
+ sizeof(addr));
+ /*rc = send(sock, &msg, msg.hdr.length, 0);*/
+ time(&now);
+#ifdef DEBUG
+ fprintf(stderr, "%s: sent status change %d to sock %d length %d size=%d errno=%d\n",
+ asctime(localtime(&now)), status,
+ sock, msgP->hdr.length, rc, (rc < 0 ? errno:0));
+#endif
+ fflush(stdout);
+
+ return rc;
+}
+
+int afsMsg_Print(char *str, int level)
+{
+ afsMsg_print_t *msgP;
+ int rc;
+ char msgBuf[AFS_MAX_MSG_LEN];
+ int slen;
+
+ slen = strlen(str); /* one extra for NULL */
+ if (slen > AFS_MAX_MSG_LEN - sizeof(afsMsg_statChange_t))
+ slen = AFS_MAX_MSG_LEN - sizeof(afsMsg_statChange_t);
+ strncpy(&msgP->message, str, slen);
+
+ msgP->hdr.msgtype = AFS_MSG_PRINT;
+ msgP->hdr.length = sizeof(afsMsg_hdr_t) + slen;
+ msgP->debugLevel = level;
+ strcpy(&msgP->message, str);
+
+ rc = sendto(sock, msgP, msgP->hdr.length, 0, (struct sockaddr *) &addr,
+ sizeof(addr));
+ return rc;
+}
+
+int afsMsg_Shutdown()
+{
+ int rc;
+ rc = close(sock);
+ if (rc < 0) fprintf(stderr, "error closing socket, rc=%d\n", rc);
+#ifdef DEBUG
+ else fprintf(stderr, "socket closed\n");
+#endif
+ fflush(stderr);
+}
--- /dev/null
+#ifndef _AFSMSG_H
+#define _AFSMSG_H
+
+#define AFS_MSG_PORT 2020
+
+#define AFS_MAX_MSG_LEN 512
+
+typedef struct _afsMsg_hdr {
+ int msgtype;
+ int length;
+} afsMsg_hdr_t;
+
+#define AFS_MSG_STATUS_CHANGE 1
+#define AFS_MSG_PRINT 2
+
+typedef struct _afsMsg_statChange {
+ afsMsg_hdr_t hdr;
+ int oldStatus;
+ int newStatus;
+ int exitCode;
+ char message;
+} afsMsg_statChange_t;
+
+#define AFS_STATUS_NOSTATUS -1
+#define AFS_STATUS_INIT 1
+#define AFS_STATUS_RUNNING 2
+#define AFS_STATUS_EXITING 3
+
+#define AFS_EXITCODE_NORMAL 0
+#define AFS_EXITCODE_PANIC 2
+#define AFS_EXITCODE_NETWORK_FAILURE 3
+#define AFS_EXITCODE_GENERAL_FAILURE 100
+
+typedef struct _afsMsg_print {
+ afsMsg_hdr_t hdr;
+ int debugLevel;
+ char message;
+} afsMsg_print_t;
+
+#endif
--- /dev/null
+#ifndef AFSRPC_H
+#define AFSRPC_H
+
+/* Copied from declaration of GUID in RPCDCE.H */
+typedef struct afs_uuid {
+ unsigned long Data1;
+ unsigned short Data2;
+ unsigned short Data3;
+ unsigned char Data4[8];
+} afs_uuid_t;
+
+long AFSRPC_SetToken(
+ afs_uuid_t uuid,
+ unsigned char sessionKey[8]
+);
+
+long AFSRPC_GetToken(
+ afs_uuid_t uuid,
+ unsigned char sessionKey[8]
+);
+
+#endif
#define __CM_H_ENV__ 1
#include <rx/rx.h>
+#ifdef DJGPP /* we need these for vldbentry decl., etc. */
+#include <afs/vldbint.h>
+#include <afs/afsint.h>
+#endif /* DJGPP */
/* from .xg file */
long VL_GetEntryByID(struct rx_connection *, long, long, struct vldbentry *);
struct AFSCallBack *CallBack,
struct AFSVolSync *Sync);
-StartRXAFS_StoreData (struct rx_call *,
+int StartRXAFS_StoreData (struct rx_call *,
struct AFSFid *Fid,
struct AFSStoreStatus *InStatus,
afs_int32 Pos,
afs_int32 Length,
afs_int32 FileLength);
-EndRXAFS_StoreData(struct rx_call *,
+int EndRXAFS_StoreData(struct rx_call *,
struct AFSFetchStatus *OutStatus,
struct AFSVolSync *Sync);
-RXAFS_StoreACL (struct rx_connection *,
+int RXAFS_StoreACL (struct rx_connection *,
struct AFSFid *Fid,
struct AFSOpaque *AccessList,
struct AFSFetchStatus *OutStatus,
struct AFSVolSync *Sync);
-RXAFS_StoreStatus(struct rx_connection *,
+int RXAFS_StoreStatus(struct rx_connection *,
struct AFSFid *Fid,
struct AFSStoreStatus *InStatus,
struct AFSFetchStatus *OutStatus,
struct AFSVolSync *Sync);
-RXAFS_RemoveFile (struct rx_connection *,
+int RXAFS_RemoveFile (struct rx_connection *,
struct AFSFid *DirFid,
char *namep,
struct AFSFetchStatus *OutStatus,
struct AFSVolSync *Sync);
-RXAFS_CreateFile (struct rx_connection *,
+int RXAFS_CreateFile (struct rx_connection *,
struct AFSFid *DirFid,
char *Name,
struct AFSStoreStatus *InStatus,
struct AFSCallBack *CallBack,
struct AFSVolSync *Sync);
-RXAFS_Rename (struct rx_connection *,
+int RXAFS_Rename (struct rx_connection *,
struct AFSFid *OldDirFid,
char *OldName,
struct AFSFid *NewDirFid,
struct AFSFetchStatus *OutNewDirStatus,
struct AFSVolSync *Sync);
-RXAFS_Symlink (struct rx_connection *,
+int RXAFS_Symlink (struct rx_connection *,
struct AFSFid *DirFid,
char *name,
char *LinkContents,
struct AFSFetchStatus *OutDirStatus,
struct AFSVolSync *Sync);
-RXAFS_Link (struct rx_connection *,
+int RXAFS_Link (struct rx_connection *,
struct AFSFid *DirFid,
char *Name,
struct AFSFid *ExistingFid,
struct AFSFetchStatus *OutDirStatus,
struct AFSVolSync *Sync);
-RXAFS_MakeDir (struct rx_connection *,
+int RXAFS_MakeDir (struct rx_connection *,
struct AFSFid *DirFid,
char *name,
struct AFSStoreStatus *InStatus,
struct AFSCallBack *CallBack,
struct AFSVolSync *Sync);
-RXAFS_RemoveDir (struct rx_connection *,
+int RXAFS_RemoveDir (struct rx_connection *,
struct AFSFid *DirFid,
char *Name,
struct AFSFetchStatus *OutDirStatus,
struct AFSVolSync *Sync);
-RXAFS_GetStatistics (struct rx_connection *,
+int RXAFS_GetStatistics (struct rx_connection *,
struct ViceStatistics *Statistics);
-RXAFS_GiveUpCallBacks (struct rx_connection *,
+int RXAFS_GiveUpCallBacks (struct rx_connection *,
struct AFSCBFids *Fids_Array,
struct AFSCBs *CallBacks_Array);
-RXAFS_GetVolumeInfo (struct rx_connection *,
+int RXAFS_GetVolumeInfo (struct rx_connection *,
char *VolumeName,
struct VolumeInfo *Volumeinfo);
-RXAFS_GetVolumeStatus (struct rx_connection *,
+int RXAFS_GetVolumeStatus (struct rx_connection *,
afs_int32 Volumeid,
struct AFSFetchVolumeStatus *Volumestatus,
char **name,
char **offlineMsg,
char **motd);
-RXAFS_SetVolumeStatus (struct rx_connection *,
+int RXAFS_SetVolumeStatus (struct rx_connection *,
afs_int32 Volumeid,
struct AFSStoreVolumeStatus *Volumestatus,
char *name,
char *olm,
char *motd);
-RXAFS_GetRootVolume (struct rx_connection *,
+int RXAFS_GetRootVolume (struct rx_connection *,
char **VolumeName);
-RXAFS_CheckToken (struct rx_connection *,
+int RXAFS_CheckToken (struct rx_connection *,
afs_int32 ViceId,
struct AFSOpaque *token);
-RXAFS_GetTime (struct rx_connection *,
+int RXAFS_GetTime (struct rx_connection *,
afs_uint32 *Seconds,
afs_uint32 *USeconds);
-RXAFS_BulkStatus (struct rx_connection *,
+int RXAFS_BulkStatus (struct rx_connection *,
struct AFSCBFids *FidsArray,
struct AFSBulkStats *StatArray,
struct AFSCBs *CBArray,
struct AFSVolSync *Sync);
-RXAFS_SetLock (struct rx_connection *,
+int RXAFS_SetLock (struct rx_connection *,
struct AFSFid *Fid,
int Type,
struct AFSVolSync *Sync);
-RXAFS_ExtendLock (struct rx_connection *,
+int RXAFS_ExtendLock (struct rx_connection *,
struct AFSFid *Fid,
struct AFSVolSync *Sync);
-RXAFS_ReleaseLock (struct rx_connection *,
+int RXAFS_ReleaseLock (struct rx_connection *,
struct AFSFid *Fid,
struct AFSVolSync *Sync);
/* This interface is to supported the AFS/DFS Protocol Translator */
-RXAFS_Lookup (struct rx_connection *,
+int RXAFS_Lookup (struct rx_connection *,
struct AFSFid *DirFid,
char *Name,
struct AFSFid *OutFid,
#define CM_ERROR_NOIPC (CM_ERROR_BASE+36)
#define CM_ERROR_BADNTFILENAME (CM_ERROR_BASE+37)
#define CM_ERROR_BUFFERTOOSMALL (CM_ERROR_BASE+38)
+#define CM_ERROR_RENAME_IDENTICAL (CM_ERROR_BASE+39)
#endif /* __CM_H_ENV__ */
#include <afs/param.h>
#include <afs/stds.h>
+#ifndef DJGPP
#include <windows.h>
#include <winsock2.h>
+#endif
#include <malloc.h>
#include <string.h>
#include <stdlib.h>
+#ifndef DJGPP
#include <nb30.h>
+#endif
#include <osi.h>
#include "afsd.h"
#ifndef _CM_ACCESS_H_ENV__
#define _CM_ACCESS_H_ENV__ 1
+#include "cm_user.h"
+
extern int cm_HaveAccessRights(struct cm_scache *scp, struct cm_user *up,
long rights, long *outRights);
#include <afs/param.h>
#include <afs/stds.h>
+#ifndef DJGPP
#include <windows.h>
+#endif
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <afs/param.h>
#include <afs/stds.h>
+#ifndef DJGPP
#include <windows.h>
+#endif
#include <osi.h>
#include <malloc.h>
#include <stdio.h>
long buf_bufferSize = CM_BUF_SIZE;
long buf_hashSize = CM_BUF_HASHSIZE;
+#ifndef DJGPP
static
HANDLE CacheHandle;
static
SYSTEM_INFO sysInfo;
+#endif /* !DJGPP */
/* buffer reservation variables */
long buf_reservedBufs;
/* another hash table */
cm_buf_t **buf_fileHashTablepp;
+#ifdef DISKCACHE95
+/* for experimental disk caching support in Win95 client */
+cm_buf_t *buf_diskFreeListp;
+cm_buf_t *buf_diskFreeListEndp;
+cm_buf_t *buf_diskAllp;
+extern int cm_diskCacheEnabled;
+#endif /* DISKCACHE95 */
+
/* hold a reference to an already held buffer */
void buf_Hold(cm_buf_t *bp)
{
lock_ReleaseWrite(&buf_globalLock);
nAtOnce = buf_nbuffers / 10;
while (1) {
- i = SleepEx(5000, 1);
+#ifndef DJGPP
+ i = SleepEx(5000, 1);
if (i != 0) continue;
+#else
+ thrd_Sleep(5000);
+#endif /* DJGPP */
/* now go through our percentage of the buffers */
for(i=0; i<nAtOnce; i++) {
} /* whole daemon's while loop */
}
+#ifndef DJGPP
/* Create a security attribute structure suitable for use when the cache file
* is created. What we mainly want is that only the administrator should be
* able to do anything with the file. We create an ACL with only one entry,
return psa;
}
+#endif /* !DJGPP */
+#ifndef DJGPP
/* Free a security attribute structure created by CreateCacheFileSA() */
VOID FreeCacheFileSA(PSECURITY_ATTRIBUTES psa)
{
GlobalFree(psa->lpSecurityDescriptor);
GlobalFree(psa);
}
+#endif /* !DJGPP */
/* initialize the buffer package; called with no locks
* held during the initialization phase.
static osi_once_t once;
cm_buf_t *bp;
long sectorSize;
- HANDLE phandle;
+ thread_t phandle;
+#ifndef DJGPP
+ HANDLE hf, hm;
+ PSECURITY_ATTRIBUTES psa;
+#endif /* !DJGPP */
long i;
unsigned long pid;
- HANDLE hf, hm;
char *data;
- PSECURITY_ATTRIBUTES psa;
long cs;
+#ifndef DJGPP
/* 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)
/* initialize global locks */
lock_InitializeRWLock(&buf_globalLock, "Global buffer lock");
+#ifndef DJGPP
/*
* Cache file mapping constrained by
* system allocation granularity;
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;
/* min value for which this works */
sectorSize = 1;
+#ifndef DJGPP
/* Reserve buffer space by mapping cache file */
psa = CreateCacheFileSA();
hf = CreateFile(cm_CachePath,
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));
osi_EndOnce(&once);
/* and create the incr-syncer */
- phandle = CreateThread((SECURITY_ATTRIBUTES *) 0, 0,
- (LPTHREAD_START_ROUTINE) buf_IncrSyncer, 0, 0, &pid);
+ 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);
+#endif /* !DJGPP */
}
return 0;
cm_buf_t *bp;
int i;
char *data;
+#ifndef DJGPP
HANDLE hm;
long cs;
return CM_ERROR_INVAL;
}
CloseHandle(hm);
+#else
+ data = malloc(buf_nbuffers * buf_bufferSize);
+#endif /* DJGPP */
/* Create buffer headers and put in free list */
bp = malloc(nbuffers * sizeof(*bp));
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);
+#endif /* DISKCACHE95 */
};
/* do logging after call to GetLastError, or else */
osi_hyper_t pageOffset;
unsigned long tcount;
int created;
+#ifdef DISKCACHE95
+ cm_diskcache_t *dcp;
+#endif /* DISKCACHE95 */
created = 0;
pageOffset.HighPart = offsetp->HighPart;
/* lock it and break out */
lock_ObtainMutex(&bp->mx);
break;
+
+#ifdef DISKCACHE95
+ /* touch disk chunk to update LRU info */
+ diskcache_Touch(bp->dcp);
+#endif /* DISKCACHE95 */
}
/* otherwise, we have to create a page */
osi_assert(!(bp->flags & (CM_BUF_READING | CM_BUF_WRITING)));
/* setup offset, event */
+#ifndef DJGPP /* doesn't seem to be used */
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);
+
+#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. */
+#endif /* DISKCACHE95 */
+
if (code != 0) {
/* failure or queued */
+#ifndef DJGPP /* cm_bufRead always returns 0 */
if (code != ERROR_IO_PENDING) {
+#endif
bp->error = code;
bp->flags |= CM_BUF_ERROR;
bp->flags &= ~CM_BUF_READING;
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
#define _BUF_H__ENV_ 1
#include <osi.h>
+#ifdef DISKCACHE95
+#include "cm_diskcache.h"
+#endif /* DISKCACHE95 */
/* default # of buffers if not changed */
#define CM_BUF_BUFFERS 100
char *datap; /* data in this buffer */
unsigned long error; /* last error code, if CM_BUF_ERROR is set */
struct cm_user *userp; /* user who wrote to the buffer last */
+#ifndef DJGPP
OVERLAPPED over; /* overlapped structure for I/O */
+#endif
/* fields added for the CM; locked by scp->mx */
long dataVersion; /* data version of this page */
long cmFlags; /* flags for cm */
+#ifdef DISKCACHE95
+ cm_diskcache_t *dcp; /* diskcache structure */
+#endif /* DISKCACHE95 */
} cm_buf_t;
/* values for cmFlags */
extern cm_buf_t *buf_Find(struct cm_scache *, osi_hyper_t *);
+#ifndef DJGPP
extern HANDLE buf_GetFileHandle(long);
+#endif /* !DJGPP */
extern void buf_LockedCleanAsync(cm_buf_t *, cm_req_t *);
#include <afs/afs_args.h>
#include <afs/stds.h>
+#ifndef DJGPP
#include <windows.h>
#include <winsock2.h>
+#else
+#include <sys/socket.h>
+#endif /* !DJGPP */
#include <malloc.h>
#include <string.h>
#include <stdlib.h>
#define _CM_CALLBACK_H_ENV__ 1
#include <osi.h>
-#include "cm_scache.h"
typedef struct cm_callbackRequest {
long callbackCount; /* callback count at start of the request */
struct cm_server *serverp; /* server we really got the callback from */
} cm_callbackRequest_t;
+#include "cm_scache.h"
+
typedef struct cm_racingRevokes {
osi_queue_t q; /* queue for forward/backward searches */
cm_fid_t fid; /* fid revoked */
#include <afs/param.h>
#include <afs/stds.h>
+#ifndef DJGPP
#include <windows.h>
#include <nb30.h>
#include <winsock2.h>
+#endif /* !DJGPP */
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#include <afs/param.h>
#include <afs/stds.h>
+#ifndef DJGPP
#include <windows.h>
#include <winsock2.h>
+#else
+#include <sys/socket.h>
+#include <netdb.h>
+#endif /* !DJGPP */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
char AFSConfigKeyName[] =
"SYSTEM\\CurrentControlSet\\Services\\TransarcAFSDaemon\\Parameters";
+#define AFS_THISCELL "ThisCell"
+#define AFS_CELLSERVDB_UNIX "CellServDB"
+#define AFS_CELLSERVDB_NT "afsdcell.ini"
+#define AFSDIR_CLIENT_ETC_DIRPATH "c:/afs"
+#if defined(DJGPP) || defined(AFS_WIN95_ENV)
+#define AFS_CELLSERVDB AFS_CELLSERVDB_UNIX
+#ifdef DJGPP
+extern char cm_confDir[];
+extern int errno;
+#endif /* DJGPP */
+#else
+#define AFS_CELLSERVDB AFS_CELLSERVDB_NT
+#endif /* DJGPP || WIN95 */
+
+
static long cm_ParsePair(char *lineBufferp, char *leftp, char *rightp)
{
char *tp;
int foundCell;
long code;
int tracking = 1, partial = 0;
+ long ip_addr;
+#if defined(DJGPP) || defined(AFS_WIN95_ENV)
+ int c1, c2, c3, c4;
+ char aname[256];
+#endif
+ char *afsconf_path;
foundCell = 0;
+#if !defined(DJGPP)
code = GetWindowsDirectory(wdir, sizeof(wdir));
if (code == 0 || code > sizeof(wdir)) return -1;
-
+
/* add trailing backslash, if required */
tlen = strlen(wdir);
if (wdir[tlen-1] != '\\') strcat(wdir, "\\");
-
- strcat(wdir, "afsdcell.ini");
+#else
+ strcpy(wdir, cm_confDir);
+ strcat(wdir,"/");
+#endif /* !DJGPP */
+ strcat(wdir, AFS_CELLSERVDB);
+
tfilep = fopen(wdir, "r");
- if (!tfilep) return -2;
+
+ if (!tfilep) {
+ /* If we are using DJGPP client, cellservdb will be in afsconf dir. */
+ /* If we are in Win95 here, we are linking with klog etc. and are
+ using DJGPP client even though DJGPP is not defined. So we still
+ need to check AFSCONF for location. */
+ afsconf_path = getenv("AFSCONF");
+ if (!afsconf_path)
+ strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
+ else
+ strcpy(wdir, afsconf_path);
+ strcat(wdir, "/");
+ strcat(wdir, AFS_CELLSERVDB_UNIX);
+ /*fprintf(stderr, "opening cellservdb file %s\n", wdir);*/
+ tfilep = fopen(wdir, "r");
+ if (!tfilep) return -2;
+ }
+
bestp = fopen(wdir, "r");
/* have we seen the cell line for the guy we're looking for? */
else inRightCell = 0;
}
else {
+#if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
valuep = strchr(lineBuffer, '#');
if (valuep == NULL) {
fclose(tfilep);
return -4;
}
valuep++; /* skip the "#" */
+
valuep += strspn(valuep, " "); /* skip SP & TAB */
+#endif /* !DJGPP */
if (inRightCell) {
+#if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
/* add the server to the VLDB list */
thp = gethostbyname(valuep);
if (thp) {
(*procp)(rockp, &vlSockAddr, valuep);
foundCell = 1;
}
+#else
+ /* For DJGPP, we will read IP address instead
+ of name/comment field */
+ code = sscanf(lineBuffer, "%d.%d.%d.%d #%s",
+ &c1, &c2, &c3, &c4, aname);
+ tp = (char *) &ip_addr;
+ *tp++ = c1;
+ *tp++ = c2;
+ *tp++ = c3;
+ *tp++ = c4;
+ memcpy(&vlSockAddr.sin_addr.s_addr, &ip_addr,
+ sizeof(long));
+ vlSockAddr.sin_family = AF_INET;
+ /* sin_port supplied by connection code */
+ if (procp)
+ (*procp)(rockp, &vlSockAddr, valuep);
+ foundCell = 1;
+#endif /* !DJGPP */
}
} /* a vldb line */
} /* while loop processing all lines */
}
+#if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
/* look up the root cell's name in the Registry */
long cm_GetRootCellName(char *cellNamep)
{
return 0;
}
+#else
+/* look up the root cell's name in the THISCELL file */
+long cm_GetRootCellName(char *cellNamep)
+{
+ FILE *thisCell;
+ char thisCellPath[256];
+ char *afsconf_path;
+ char *newline;
+
+#ifdef DJGPP
+ strcpy(thisCellPath, cm_confDir);
+#else
+ /* Win 95 */
+ afsconf_path = getenv("AFSCONF");
+ if (!afsconf_path)
+ strcpy(thisCellPath, AFSDIR_CLIENT_ETC_DIRPATH);
+ else
+ strcpy(thisCellPath, afsconf_path);
+#endif
+ strcat(thisCellPath,"/");
+
+ strcat(thisCellPath, AFS_THISCELL);
+ thisCell = fopen(thisCellPath, "r");
+ if (thisCell == NULL)
+ return -1;
+
+ fgets(cellNamep, 256, thisCell);
+ fclose(thisCell);
+
+ newline = strrchr(cellNamep,'\n');
+ if (newline) *newline = '\0';
+ newline = strrchr(cellNamep,'\r');
+ if (newline) *newline = '\0';
+
+ return 0;
+}
+#endif /* !DJGPP */
cm_configFile_t *cm_CommonOpen(char *namep, char *rwp)
{
long code;
long tlen;
FILE *tfilep;
+ char *afsconf_path;
+#if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
code = GetWindowsDirectory(wdir, sizeof(wdir));
if (code == 0 || code > sizeof(wdir)) return NULL;
/* add trailing backslash, if required */
tlen = strlen(wdir);
if (wdir[tlen-1] != '\\') strcat(wdir, "\\");
+#else
+#ifdef DJGPP
+ strcpy(wdir,cm_confDir);
+#else
+ afsconf_path = getenv("AFSCONF");
+ if (!afsconf_path)
+ strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
+ else
+ strcpy(wdir, afsconf_path);
+#endif /* !DJGPP */
+ strcat(wdir,"/");
+#endif /* DJGPP || WIN95 */
strcat(wdir, namep);
return ((cm_configFile_t *) tfilep);
}
+#ifndef DJGPP
long cm_WriteConfigString(char *labelp, char *valuep)
{
DWORD code, dummyDisp;
return 0;
}
+#endif /* !DJGPP */
+#ifndef DJGPP
long cm_WriteConfigInt(char *labelp, long value)
{
DWORD code, dummyDisp;
return 0;
}
+#endif /* !DJGPP */
cm_configFile_t *cm_OpenCellFile(void)
{
int inRightCell;
int foundCell;
- tfilep = cm_CommonOpen("afsdcell.ini", "r");
+ tfilep = cm_CommonOpen(AFS_CELLSERVDB, "r");
if (!tfilep) return -1;
foundCell = 0;
long code;
long closeCode;
int tlen;
+ char *afsconf_path;
closeCode = fclose((FILE *)filep);
+#if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
code = GetWindowsDirectory(wdir, sizeof(wdir));
- if (code == 0 || code > sizeof(wdir)) return -1;
+ if (code == 0 || code > sizeof(wdir)) return NULL;
/* add trailing backslash, if required */
tlen = strlen(wdir);
if (wdir[tlen-1] != '\\') strcat(wdir, "\\");
+#else
+#ifdef DJGPP
+ strcpy(wdir,cm_confDir);
+#else
+ afsconf_path = getenv("AFSCONF");
+ if (!afsconf_path)
+ strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH);
+ else
+ strcpy(wdir, afsconf_path);
+#endif /* !DJGPP */
+ strcat(wdir,"/");
+#endif /* DJGPP || WIN95 */
+
strcpy(sdir, wdir);
if (closeCode != 0) {
return closeCode;
}
- strcat(wdir, "afsdcell.ini");
+ strcat(wdir, AFS_CELLSERVDB);
strcat(sdir, "afsdcel2.ini"); /* new file */
unlink(wdir); /* delete old file */
#ifndef __CM_CONFIG_INTERFACES_ONLY__
#include <stdio.h>
+#ifdef DJGPP
+#include <netinet/in.h>
+#endif /* DJGPP */
extern char AFSConfigKeyName[];
#include <afs/param.h>
#include <afs/stds.h>
+#ifndef DJGPP
#include <windows.h>
+#endif /* !DJGPP */
#include <string.h>
#include <malloc.h>
#include <osi.h>
#include <rx/rx.h>
+#ifndef DJGPP
#include <rxkad.h>
+#else
+#include <rx/rxkad.h>
+#endif
#include "afsd.h"
void cm_InitReq(cm_req_t *reqp)
{
memset((char *)reqp, 0, sizeof(cm_req_t));
+#ifndef DJGPP
reqp->startTime = GetCurrentTime();
+#else
+ gettimeofday(&reqp->startTime, NULL);
+#endif
+
}
long cm_GetServerList(struct cm_fid *fidp, struct cm_user *userp,
if (tsrp->status == busy)
tsrp->status = not_busy;
}
- Sleep(5000);
+ thrd_Sleep(5000);
retry = 1;
}
int same;
/* Back off to allow move to complete */
- Sleep(2000);
+ thrd_Sleep(2000);
/* Update the volume location and see if it changed */
cm_GetServerList(fidp, userp, reqp, &serversp);
* this is to prevent the SMB session from timing out
* In addition, we log an event to the event log
*/
+#ifndef DJGPP
HANDLE h;
char *ptbuf[1];
char s[100];
ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, 1009, NULL,
1, 0, ptbuf, NULL);
DeregisterEventSource(h);
+#endif /* !DJGPP */
retry = 0;
osi_Log0(afsd_logp, "cm_Analyze: hardDeadTime exceeded");
long firstError = 0;
int someBusy = 0, someOffline = 0;
long timeUsed, timeLeft, hardTimeLeft;
+#ifdef DJGPP
+ struct timeval now;
+#endif /* DJGPP */
*connpp = NULL;
+#ifndef DJGPP
timeUsed = (GetCurrentTime() - reqp->startTime) / 1000;
+#else
+ gettimeofday(&now, NULL);
+ timeUsed = sub_time(now, reqp->startTime) / 1000;
+#endif
+
/* leave 5 seconds margin of safety */
timeLeft = RDRtimeout - timeUsed - 5;
hardTimeLeft = timeLeft;
VBUSY above. This is negative so that old
cache managers treat it as "server is down"*/
+#include "cm_server.h"
+
extern void cm_InitConn(void);
extern void cm_InitReq(cm_req_t *reqp);
#include <afs/param.h>
#include <afs/stds.h>
+#ifndef DJGPP
#include <windows.h>
#include <winsock2.h>
+#else
+#include <netdb.h>
+#endif /* !DJGPP */
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
*/
gethostname(thostName, sizeof(thostName));
thp = gethostbyname(thostName);
- memcpy(&code, thp->h_addr_list[0], 4);
+ if (thp == NULL) /* In djgpp, gethostname returns the netbios
+ name of the machine. gethostbyname will fail
+ looking this up if it differs from DNS name. */
+ code = 0;
+ else
+ memcpy(&code, thp->h_addr_list[0], 4);
srand(ntohl(code));
now = osi_Time();
lastTokenCacheCheck = now - cm_daemonTokenCheckInterval/2 + (rand() % cm_daemonTokenCheckInterval);
while (1) {
- Sleep(30 * 1000); /* sleep 30 seconds */
+ thrd_Sleep(30 * 1000); /* sleep 30 seconds */
/* find out what time it is */
now = osi_Time();
{
static osi_once_t once;
long pid;
- HANDLE phandle;
+ thread_t phandle;
int i;
if (osi_Once(&once)) {
osi_EndOnce(&once);
/* creating pinging daemon */
- phandle = CreateThread((SECURITY_ATTRIBUTES *) 0, 0,
- (LPTHREAD_START_ROUTINE) cm_Daemon, 0, 0, &pid);
+ phandle = thrd_Create((SecurityAttrib) 0, 0,
+ (ThreadFunc) cm_Daemon, 0, 0, &pid, "cm_Daemon");
osi_assert(phandle != NULL);
- CloseHandle(phandle);
+ thrd_CloseHandle(phandle);
for(i=0; i < nDaemons; i++) {
- phandle = CreateThread((SECURITY_ATTRIBUTES *) 0, 0,
- (LPTHREAD_START_ROUTINE) cm_BkgDaemon, 0, 0, &pid);
+ phandle = thrd_Create((SecurityAttrib) 0, 0,
+ (ThreadFunc) cm_BkgDaemon, 0, 0, &pid,
+ "cm_BkgDaemon");
osi_assert(phandle != NULL);
- CloseHandle(phandle);
+ thrd_CloseHandle(phandle);
}
}
}
#include <afs/param.h>
#include <afs/stds.h>
+#ifndef DJGPP
#include <windows.h>
#include <winsock2.h>
+#include <nb30.h>
+#endif /* !DJGPP */
#include <malloc.h>
#include <string.h>
#include <stdlib.h>
-#include <nb30.h>
#include <osi.h>
#include "afsd.h"
lock_ReleaseMutex(&scp->mx);
+#ifdef DISKCACHE95
+ DPRINTF("cm_GetBuffer: fetching data scpDV=%d bufDV=%d scp=%x bp=%x dcp=%x\n",
+ scp->dataVersion, bufp->dataVersion, scp, bufp, bufp->dcp);
+#endif /* DISKCACHE95 */
+
/* now make the call */
do {
code = cm_Conn(&scp->fid, up, reqp, &connp);
qdp = (osi_queueData_t *) osi_QNext(&qdp->q)) {
tbufp = osi_GetQData(qdp);
tbufp->dataVersion = afsStatus.DataVersion;
+
+#ifdef DISKCACHE95
+ /* write buffer out to disk cache */
+ diskcache_Update(tbufp->dcp, tbufp->datap, buf_bufferSize,
+ tbufp->dataVersion);
+#endif /* DISKCACHE95 */
}
}
#include <afs/param.h>
#include <afs/stds.h>
+#ifndef DJGPP
#include <windows.h>
+#endif /* !DJGPP */
#include <string.h>
#include <malloc.h>
#include <osi.h>
--- /dev/null
+/*
+ * 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
+ */
+
+/* This code is experimental persistent disk cache support for the
+ Windows 95/DJGPP AFS client. It uses synchronous I/O and assumes
+ non-preemptible threads (which is the case in DJGPP), so it has
+ no locking. */
+
+
+#ifdef DISKCACHE95
+
+#include <afs/param.h>
+#include <afs/stds.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/errno.h>
+#include <sys/stat.h>
+
+#include "afsd.h"
+
+cm_diskcache_t **diskHashTable; /* pointers to hash chains */
+Queue diskLRUList;
+Queue openFileList;
+cm_diskcache_t *diskCBBuf;
+
+extern int afs_diskCacheChunks;
+/*extern int cm_diskCacheChunkSize;*/
+extern long buf_bufferSize;
+long cm_diskCacheChunkSize;
+extern char cm_cachePath[];
+extern int cm_cachePathLen;
+extern int cm_diskCacheEnabled;
+
+int cacheInfo_fd;
+int accessOrd = 0; /* monotonically increasing access ordinal */
+int updates = 0;
+int afs_dhashsize = 2048;
+int openCacheFiles = 0;
+
+char cacheInfoPath[128];
+char cacheFileName[128];
+
+extern int errno;
+
+#define MAX_OPEN_FILES 22
+
+/* internal functions */
+void diskcache_WriteCacheInfo(cm_diskcache_t *dcp);
+int diskcache_New();
+cm_diskcache_t *diskcache_Find(cm_fid_t *fid, int chunk);
+cm_diskcache_t *diskcache_Alloc(cm_fid_t *fid, int chunk, int dataVersion);
+int diskcache_Read(cm_diskcache_t *dcp, char *buf, int size);
+int diskcache_Write(cm_diskcache_t *dcp, char *buf, int size);
+
+#define complain printf
+
+#define OFFSET_TO_CHUNK(a) (LargeIntegerDivideByLong((a), cm_diskCacheChunkSize))
+#define GEN_CACHE_DIR_NAME(name, path, i) \
+ sprintf(name, "%s\\D%07d", cm_cachePath, (i) / CACHE_FILES_PER_DIR)
+#define GEN_CACHE_FILE_NAME(name, path, i) \
+ sprintf(name, "%s\\D%07d\\C%07d", path, (i) / CACHE_FILES_PER_DIR, \
+ (i) % CACHE_FILES_PER_DIR)
+
+/* Initialize the disk cache */
+int diskcache_Init()
+{
+ int i;
+ int rc;
+ int fd;
+ int invalid;
+ int index;
+ char *chunkBuf;
+ char tmpBuf[512];
+ struct stat cacheInfoStat, chunkStat;
+ cm_cacheInfoHdr_t hdr;
+ cm_diskcache_t *dcp;
+ int validCount = 0;
+
+ if (!cm_diskCacheEnabled)
+ return 0;
+
+ cm_diskCacheChunkSize = buf_bufferSize;
+ if (cm_diskCacheChunkSize % buf_bufferSize != 0)
+ {
+ complain("Error: disk cache chunk size %d not a multiple of buffer size %d\n",
+ cm_diskCacheChunkSize, buf_bufferSize);
+ return CM_ERROR_INVAL;
+ }
+
+ /* alloc mem for chunk file control blocks */
+ diskCBBuf = (cm_diskcache_t *) malloc(afs_diskCacheChunks * sizeof(cm_diskcache_t));
+ if (diskCBBuf == NULL)
+ return CM_ERROR_SPACE;
+ memset(diskCBBuf, 0, afs_diskCacheChunks * sizeof(cm_diskcache_t));
+
+ /* alloc mem for hash table pointers */
+ diskHashTable = (cm_diskcache_t **) malloc(afs_dhashsize * sizeof(cm_diskcache_t *));
+ if (diskHashTable == NULL)
+ return CM_ERROR_SPACE;
+ memset(diskHashTable, 0, afs_dhashsize*sizeof(cm_diskcache_t *));
+
+ QInit(&diskLRUList);
+ QInit(&openFileList);
+
+ /*sprintf(cacheInfoPath, "%s\\%s", cm_cachePath, CACHE_INFO_FILE);*/
+ memset(cacheInfoPath, 0, 128);
+ DPRINTF("cm_cachePath=%s\n", cm_cachePath);
+ strncpy(cacheInfoPath, cm_cachePath, 50);
+ strcat(cacheInfoPath, "\\");
+ strcat(cacheInfoPath, CACHE_INFO_FILE);
+ DPRINTF("cacheInfoPath=%s\n", cacheInfoPath);
+
+ cacheInfo_fd = open(cacheInfoPath, O_RDWR | O_BINARY);
+
+ if (cacheInfo_fd < 0)
+ {
+ /* file not present */
+ return diskcache_New(); /* initialize new empty disk cache */
+ }
+
+ /* get stat of cache info file */
+ rc = fstat(cacheInfo_fd, &cacheInfoStat);
+
+ /* Check for valid header in cache info file */
+ rc = read(cacheInfo_fd, &hdr, sizeof(cm_cacheInfoHdr_t));
+ if (rc < sizeof(cm_cacheInfoHdr_t) ||
+ hdr.magic != CACHE_INFO_MAGIC)
+ /*hdrp = (cm_cacheInfoHdr_t *) tmpBuf;*/
+ {
+ close(cacheInfo_fd);
+ return diskcache_New();
+ }
+
+ if (hdr.chunks != afs_diskCacheChunks ||
+ hdr.chunkSize != cm_diskCacheChunkSize)
+ {
+ /* print error message saying params don't match */
+ return CM_ERROR_INVAL;
+ }
+
+ chunkBuf = (char *) malloc(cm_diskCacheChunkSize);
+ if (chunkBuf == NULL)
+ return CM_ERROR_SPACE;
+
+ /* read metadata from cache info file into control blocks */
+ /* reconstruct hash chains based on fid, chunk */
+ for (i = 0; i < afs_diskCacheChunks; i++)
+ { /* for all cache chunks */
+ if (i % 500 == 0)
+ {
+ printf("%d...", i);
+ fflush(stdout);
+ }
+ dcp = &diskCBBuf[i];
+ dcp->refCount = 0;
+ rc = read(cacheInfo_fd, &dcp->f, sizeof(struct fcache));
+ if (rc < sizeof(struct fcache))
+ {
+ /* print error message about reading cache info file */
+ /* this isn't the right error code for a read error */
+ return CM_ERROR_INVAL;
+ }
+
+ if (dcp->f.index != i)
+ return CM_ERROR_INVAL; /* index should match position in cache info file */
+
+ /* Try to open cache file. This chunk will be invalidated if we can't
+ find the file, the file is newer than the cache info file, the file
+ size doesn't match the cache info file, or the file's header is
+ invalid. */
+ GEN_CACHE_FILE_NAME(cacheFileName, cm_cachePath, i);
+#if 1
+ /*fd = open(cacheFileName, O_RDWR | O_BINARY);
+ if (fd < 0) invalid = 1;
+ else
+ {
+ rc = fstat(fd, &chunkStat);*/
+ rc = stat(cacheFileName, &chunkStat);
+
+ if (rc < 0) invalid = 1;
+ /*else if (cacheInfoStat.st_mtime < chunkStat.st_mtime + 120) invalid = 1;*/
+ else if (cacheInfoStat.st_mtime < chunkStat.st_mtime) invalid = 1;
+ /*else if (cacheInfoStat.st_mtime < dcp->f.modTime + 120) invalid = 1;*/
+ else if (cacheInfoStat.st_mtime < dcp->f.modTime) invalid = 1;
+ else if (cm_diskCacheChunkSize != chunkStat.st_size ||
+ dcp->f.chunkBytes != chunkStat.st_size) invalid = 1;
+ /*else
+ {*/
+ /*rc = read(fd, chunkBuf, cm_diskCacheChunkSize);
+ if (rc < 0) invalid = 1;*/
+
+ /*else
+ {
+ cacheFileHdrP = (cm_cacheFileHdr_t *) chunkBuf;
+ if (cacheFileHdrP->magic != CACHE_FILE_MAGIC ||
+ cacheFileHdrP->index != i)
+ {
+ invalid = 1;
+ }
+ }*/
+ /*}*/
+ /*}*/
+#else
+ invalid = 0;
+#endif
+
+ if (invalid == 0)
+ {
+ /* Cache file seems to be valid */
+
+ validCount++;
+ DPRINTF("Found fid/chunk=%08x-%08x-%08x-%08x/%04d in slot=%d dcp=%x\n",
+ dcp->f.fid.cell, dcp->f.fid.volume, dcp->f.fid.vnode,
+ dcp->f.fid.unique, dcp->f.chunk, i, dcp);
+ /* Put control block in hash table */
+ index = DCHash(&dcp->f.fid, dcp->f.chunk);
+ /*osi_QAdd(&diskHashTable[index], &dcp->f.hashq);*/
+
+ /* add to head of hash list. (we should probably look at
+ ord here instead. use queues?) */
+ dcp->hash_next = diskHashTable[index];
+ dcp->hash_prev = NULL;
+ if (diskHashTable[index]) diskHashTable[index]->hash_prev = dcp;
+ diskHashTable[index] = dcp;
+
+ /* Add to LRU queue in access time order (lowest at tail) */
+ QAddOrd(&diskLRUList, &dcp->lruq, dcp->f.accessOrd);
+
+ close(fd);
+ }
+ else
+ {
+ /* Cache file is invalid */
+
+ /* Create the cache file with correct size */
+ memset(chunkBuf, 0, cm_diskCacheChunkSize);
+ /*cacheFileHdrP->magic = CACHE_FILE_MAGIC;
+ cacheFileHdrP->index = i;*/
+
+ if (fd != 0) close(fd);
+ /* Note that if the directory this file is supposed to be in doesn't
+ exist, the creat call will fail and we will return an error. */
+ /*fd = creat(cacheFileName, S_IRUSR|S_IWUSR);*/
+ fd = open(cacheFileName, O_RDWR | O_BINARY | O_CREAT | O_TRUNC,
+ S_IRUSR | S_IWUSR);
+ if (fd < 0) return CM_ERROR_INVAL; /* couldn't create file */
+ rc = write(fd, chunkBuf, cm_diskCacheChunkSize);
+ if (rc < 0) /* ran out of space? */
+ return CM_ERROR_INVAL;
+ close(fd);
+
+ /* We consider an invalid chunk as empty, so we put it at tail of LRU */
+ memset(dcp, 0, sizeof(cm_diskcache_t));
+ dcp->f.accessOrd = 0;
+ dcp->f.states = DISK_CACHE_EMPTY;
+ dcp->f.index = i;
+ dcp->f.chunkBytes = cm_diskCacheChunkSize;
+ /*osi_QAdd(diskLRUList, &dcp->lruq);*/
+ QAddOrd(&diskLRUList, &dcp->lruq, dcp->f.accessOrd); /* head is LRU */
+
+ /* write out cache info modifications */
+ lseek(cacheInfo_fd, -sizeof(struct fcache), SEEK_CUR);
+ write(cacheInfo_fd, &dcp->f, sizeof(struct fcache));
+ }
+ } /* for all cache chunks */
+
+ free(chunkBuf);
+ /*close(cacheInfo_fd);*/
+ fprintf(stderr, "\nFound %d of %d valid %d-byte blocks\n", validCount,
+ afs_diskCacheChunks, cm_diskCacheChunkSize);
+
+ return 0;
+}
+
+/* create empty disk cache files */
+/* assumes tables have already been malloc'd by diskcache_Init */
+int diskcache_New()
+{
+ int i;
+ int rc;
+ int fd;
+ int invalid;
+ int index;
+ /*char cacheInfoPath[256];
+ char cacheFileName[256];*/
+ char dirName[256];
+ char *chunkBuf;
+ struct stat cacheInfoStat, chunkStat;
+ cm_cacheInfoHdr_t hdr;
+ cm_diskcache_t *dcp;
+
+ sprintf(cacheInfoPath, "%s\\%s", cm_cachePath, CACHE_INFO_FILE);
+ /*cacheInfo_fd = creat(cacheInfoPath, S_IRUSR | S_IWUSR);*/
+ cacheInfo_fd = open(cacheInfoPath, O_RDWR | O_BINARY | O_CREAT | O_TRUNC,
+ S_IRUSR | S_IWUSR);
+ if (cacheInfo_fd < 0)
+ {
+ complain("diskcache_New: Error creating cache info file in cache directory %s\n",
+ cm_cachePath);
+ return CM_ERROR_INVAL;
+ }
+
+ /* write valid header */
+ hdr.magic = CACHE_INFO_MAGIC;
+ hdr.chunks = afs_diskCacheChunks;
+ hdr.chunkSize = cm_diskCacheChunkSize;
+ rc = write(cacheInfo_fd, (char *) &hdr, sizeof(cm_cacheInfoHdr_t));
+ if (rc < 0)
+ return CM_ERROR_INVAL;
+
+ chunkBuf = (char *) malloc(cm_diskCacheChunkSize);
+ if (chunkBuf == NULL)
+ return CM_ERROR_SPACE;
+ memset(chunkBuf, 0, cm_diskCacheChunkSize);
+
+ for (i = 0; i < afs_diskCacheChunks; i++)
+ { /* for all cache chunks */
+ if (i % 500 == 0)
+ {
+ printf("%d...", i);
+ fflush(stdout);
+ }
+
+ dcp = &diskCBBuf[i];
+
+ dcp->refCount = 0;
+ /* $$$: init mutex mx */
+ memset(dcp, 0, sizeof(cm_diskcache_t));
+ dcp->f.accessOrd = 0;
+ dcp->f.index = i;
+ dcp->f.states = DISK_CACHE_EMPTY;
+ dcp->f.chunkBytes = cm_diskCacheChunkSize;
+ QAddT(&diskLRUList, &dcp->lruq, dcp->f.accessOrd); /* head is LRU */
+ rc = write(cacheInfo_fd, &dcp->f, sizeof(struct fcache));
+
+ if (i % CACHE_FILES_PER_DIR == 0)
+ {
+ GEN_CACHE_DIR_NAME(dirName, cm_cachePath, i);
+ rc = mkdir(dirName, S_IRUSR | S_IWUSR);
+ if (rc < 0 && errno != EEXIST)
+ {
+ complain("diskcache_New: Couldn't create cache directory %s\n", dirName);
+ return CM_ERROR_INVAL;
+ }
+ }
+
+ GEN_CACHE_FILE_NAME(cacheFileName, cm_cachePath, i);
+ /*fd = creat(cacheFileName, S_IRUSR | S_IWUSR);*/
+ fd = open(cacheFileName, O_RDWR | O_BINARY | O_CREAT | O_TRUNC,
+ S_IRUSR | S_IWUSR);
+ if (fd < 0)
+ {
+ if (errno == ENOSPC)
+ complain("diskcache_New: Not enough space in cache path to create file %s\n",
+ cacheFileName);
+ else
+ complain("diskcache_New: Couldn't create cache file %s\n", cacheFileName);
+ return CM_ERROR_INVAL;
+ }
+
+ /*fileHdr.magic = CACHE_FILE_MAGIC;
+ fileHdr.index = i;
+ rc = write(fd, &fileHdr, sizeof(cm_cacheFileHdr_t)); /* maybe we should write
+ a full block? */
+ /*if (rc == 0)
+ {*/
+ rc = write(fd, chunkBuf, cm_diskCacheChunkSize);
+ /*}*/
+
+ if (rc < 0)
+ {
+ if (errno == ENOSPC)
+ complain("diskcache_New: Not enough space in cache path to write to file %s\n",
+ cacheFileName);
+ else
+ complain("diskcache_New: Couldn't write to cache file %s\n",
+ cacheFileName);
+ return CM_ERROR_INVAL;
+ }
+
+ close(fd);
+ } /* for all cache chunks */
+
+ free(chunkBuf);
+
+ /*close(cacheInfo_fd);*/
+
+ return 0;
+}
+
+/* Get chunk from the cache or allocate a new chunk */
+int diskcache_Get(cm_fid_t *fid, osi_hyper_t *offset, char *buf, int size, int *dataVersion, int *dataCount, cm_diskcache_t **dcpRet)
+{
+ cm_diskcache_t *dcp;
+ int rc;
+ int chunk;
+
+
+ if (!cm_diskCacheEnabled)
+ {
+ *dcpRet = NULL;
+ return 0;
+ }
+
+ chunk = OFFSET_TO_CHUNK(*offset); /* chunk number */
+
+ DPRINTF("diskcache_Get: fid/chunk=%08x-%08x-%08x-%08x/%04d\n",
+ fid->cell, fid->volume, fid->vnode, fid->unique, chunk);
+
+ dcp = diskcache_Find(fid, chunk);
+ if (dcp != NULL)
+ {
+ rc = diskcache_Read(dcp, buf, size);
+ *dataVersion = dcp->f.dataVersion; /* update caller's data version */
+ if (rc < 0)
+ return -1;
+ else
+ *dataCount = rc;
+ }
+ else
+ {
+ dcp = diskcache_Alloc(fid, chunk, *dataVersion);
+ if (dcp == NULL)
+ return -1;
+ }
+
+ if (++updates >= CACHE_INFO_UPDATES_PER_WRITE)
+ {
+ updates = 0;
+ diskcache_WriteCacheInfo(dcp); /* update cache info for this slot */
+ }
+
+ *dcpRet = dcp;
+ /*printf("diskcache_Get: returning dcp=%x\n", dcp);*/
+ return 0;
+}
+
+
+/* Look for a file chunk in the cache */
+cm_diskcache_t *diskcache_Find(cm_fid_t *fid, int chunk)
+{
+ int index;
+ cm_diskcache_t *dcp;
+ cm_diskcache_t *prev;
+
+ index = DCHash(fid, chunk);
+ dcp = diskHashTable[index];
+ prev = NULL;
+
+ while (dcp != NULL)
+ {
+ if (cm_FidCmp(&dcp->f.fid, fid) == 0 && chunk == dcp->f.chunk)
+ {
+ dcp->f.accessOrd = accessOrd++;
+ /* Move it to the beginning of the list */
+ if (diskHashTable[index] != dcp)
+ {
+ assert(dcp->hash_prev->hash_next == dcp);
+ dcp->hash_prev->hash_next = dcp->hash_next;
+ if (dcp->hash_next)
+ {
+ assert(dcp->hash_next->hash_prev == dcp);
+ dcp->hash_next->hash_prev = dcp->hash_prev;
+ }
+ dcp->hash_next = diskHashTable[index];
+ dcp->hash_prev = NULL;
+ if (diskHashTable[index]) diskHashTable[index]->hash_prev = dcp;
+ diskHashTable[index] = dcp;
+ }
+ break;
+ }
+ prev = dcp;
+ dcp = dcp->hash_next;
+ }
+
+ if (dcp)
+ DPRINTF("diskcache_Find: fid/chunk=%08x-%08x-%08x-%08x/%04d slot=%d hash=%d dcp=%x\n",
+ fid->cell, fid->volume, fid->vnode, fid->unique, chunk, dcp->f.index, index, dcp);
+ else
+ DPRINTF("diskcache_Find: fid/chunk=%08x/%04d not found\n",
+ fid->unique, chunk);
+
+ return dcp;
+}
+
+int diskcache_Read(cm_diskcache_t *dcp, char *buf, int size)
+{
+ char cacheFileName[256];
+ int fd;
+ int rc;
+ int opened = 0;
+
+ GEN_CACHE_FILE_NAME(cacheFileName, cm_cachePath, dcp->f.index);
+
+ DPRINTF("diskcache_Read: filename=%s dcp=%x\n", cacheFileName,
+ dcp);
+
+ /* For reads, we will use the fd if already open, but we won't leave
+ the file open. Note that if we use async I/O, we will need to
+ do locking to prevent someone from closing the file while I/O
+ is going on. But for now, all I/O is synchronous, and threads
+ are non-preemptible. */
+
+ if (dcp->openfd == 0)
+ {
+ fd = open(cacheFileName, O_RDWR | O_BINARY);
+ if (fd < 0)
+ {
+ complain("diskcache_Read: Couldn't open cache file %s\n", cacheFileName);
+ return -1;
+ }
+ opened = 1;
+ }
+ else
+ fd = dcp->openfd;
+
+ if (fd < 0)
+ {
+ complain("diskcache_Read: Couldn't open cache file %s\n", cacheFileName);
+ return -1;
+ }
+
+ rc = read(fd, buf, size);
+ if (rc < 0)
+ {
+ complain("diskcache_Read: Couldn't read cache file %s\n", cacheFileName);
+ close(fd); return -1;
+ }
+
+ if (opened)
+ close(fd); /* close it if we opened it */
+ return rc; /* bytes read */
+}
+
+/* Write out buffer to disk */
+int diskcache_Update(cm_diskcache_t *dcp, char *buf, int size, int dataVersion)
+{
+ if (!cm_diskCacheEnabled)
+ return 0;
+
+ DPRINTF("diskcache_Update dcp=%x, dataVersion=%d\n", dcp, dataVersion);
+ diskcache_Write(dcp, buf, size);
+ /*diskcache_SetMRU(dcp);*/
+ dcp->f.dataVersion = dataVersion;
+ /*dcp->f.accessOrd = accessOrd++;*/
+ /*QMoveToTail(&diskLRUList, &dcp->lruq, dcp->f.accessOrd);*/
+
+ if (++updates >= CACHE_INFO_UPDATES_PER_WRITE)
+ {
+ updates = 0;
+ diskcache_WriteCacheInfo(dcp); /* update cache info */
+ }
+ return 0;
+}
+
+/* Allocate a new chunk file control block for this fid/chunk */
+cm_diskcache_t *diskcache_Alloc(cm_fid_t *fid, int chunk, int dataVersion)
+{
+ cm_diskcache_t *dcp;
+ QLink* q;
+ int index;
+ int stole=0, stolen_chunk, stolen_fid_unique;
+
+ /* Remove LRU elt. (head) from free list */
+ q = QServe(&diskLRUList);
+ if (q == NULL)
+ dcp = NULL;
+ else
+ dcp = (cm_diskcache_t *) MEM_TO_OBJ(cm_diskcache_t, lruq, q);
+ if (dcp == NULL)
+ {
+ DPRINTF("diskcache_Alloc: fid/chunk=%08x/%04d allocation failed\n",
+ fid->unique, chunk);
+ return NULL;
+ }
+
+ /* Use this element for this fid/chunk */
+ if (dcp->f.states == DISK_CACHE_USED)
+ {
+ /* Remove from old hash chain */
+ if (dcp->hash_prev)
+ {
+ assert(dcp->hash_prev->hash_next == dcp);
+ dcp->hash_prev->hash_next = dcp->hash_next;
+ }
+ else
+ {
+ index = DCHash(&dcp->f.fid, dcp->f.chunk);
+ diskHashTable[index] = dcp->hash_next;
+ }
+ if (dcp->hash_next)
+ {
+ assert(dcp->hash_next->hash_prev == dcp);
+ dcp->hash_next->hash_prev = dcp->hash_prev;
+ }
+
+ stole = 1;
+ stolen_chunk = dcp->f.chunk;
+ stolen_fid_unique = dcp->f.fid.unique;
+ }
+
+ memcpy(&dcp->f.fid, fid, sizeof(cm_fid_t));
+ dcp->f.chunk = chunk;
+ dcp->f.dataVersion = dataVersion;
+ dcp->f.accessOrd = accessOrd++;
+ dcp->f.states = DISK_CACHE_USED;
+
+ /* allocate at head of new hash chain */
+ index = DCHash(fid, chunk);
+ /*osi_QAddH(&diskHashTable[index], &dcp->hashq);*/
+ dcp->hash_next = diskHashTable[index];
+ dcp->hash_prev = NULL;
+ if (diskHashTable[index]) diskHashTable[index]->hash_prev = dcp;
+ diskHashTable[index] = dcp;
+
+ /* put at tail of queue */
+ QAddT(&diskLRUList, &dcp->lruq, dcp->f.accessOrd);
+
+ if (stole)
+ DPRINTF("diskcache_Alloc: fid/chunk=%08x/%04d (recyc fid/chunk=%08x/%04d) "
+ "slot=%d hash=%d dcp=%x\n",
+ fid->unique, chunk, stolen_fid_unique, stolen_chunk,
+ dcp->f.index, index, dcp);
+ else
+ DPRINTF("diskcache_Alloc: fid/chunk=%08x/%04d slot=%d hash=%d dcp=%x\n",
+ fid->unique, chunk, dcp->f.index, index, dcp);
+ return dcp;
+}
+
+/* Write this chunk to its disk file */
+int diskcache_Write(cm_diskcache_t *dcp, /*int bufferNum,*/ char *buf, int size)
+{
+ char cacheFileName[256];
+ int fd;
+ int rc;
+ int opened = 0;
+ QLink *q;
+
+ /*return 0;*/
+
+ DPRINTF("diskcache_Write\n");
+
+ /* write bytes of buf into chunk file */
+ GEN_CACHE_FILE_NAME(cacheFileName, cm_cachePath, dcp->f.index);
+ if (dcp->openfd == 0)
+ {
+ dcp->openfd = open(cacheFileName, O_RDWR | O_BINARY);
+ if (dcp->openfd < 0)
+ {
+ dcp->openfd = 0;
+ complain("diskcache_Write: Couldn't open cache file %s\n", cacheFileName);
+ return -1;
+ }
+ opened = 1;
+ }
+
+ /*lseek(dcp->openfd, bufferNum * buf_bufferSize, SEEK_SET);*/
+ /* only write size bytes */
+ rc = write(dcp->openfd, buf, size);
+ if (rc < 0)
+ {
+ complain("diskcache_Write: Couldn't write cache file %s\n", cacheFileName);
+ close(dcp->openfd); dcp->openfd = 0; return rc;
+ }
+
+ if (opened)
+ {
+ /* add to open file list */
+ QAddT(&openFileList, &dcp->openq, 0);
+ openCacheFiles++;
+ }
+ else
+ QMoveToTail(&openFileList, &dcp->openq, 0);
+
+ if (openCacheFiles >= MAX_OPEN_FILES)
+ {
+ /* close longest-open file */
+ q = QServe(&openFileList);
+ dcp = (cm_diskcache_t *) MEM_TO_OBJ(cm_diskcache_t, openq, q);
+ assert(dcp != NULL);
+ if (dcp->openfd > 0)
+ close(dcp->openfd);
+ dcp->openfd = 0;
+ openCacheFiles--;
+ }
+
+ return 0;
+}
+
+/* we accessed this chunk (hit on buffer read), so move to MRU */
+void diskcache_Touch(cm_diskcache_t *dcp)
+{
+ if (!cm_diskCacheEnabled || !dcp) return;
+ dcp->f.accessOrd = accessOrd++;
+ QMoveToTail(&diskLRUList, &dcp->lruq, dcp->f.accessOrd); /* tail is MRU */
+}
+
+/* invalidate this disk cache entry */
+int diskcache_Invalidate(cm_diskcache_t *dcp)
+{
+ /* We consider an invalid chunk as empty, so we put it at tail of LRU */
+ QRemove(&diskLRUList, &dcp->lruq);
+
+ dcp->f.accessOrd = 0;
+ dcp->f.states = DISK_CACHE_EMPTY;
+ dcp->f.chunk = 0;
+ memset(&dcp->f.fid, sizeof(cm_fid_t));
+ /*osi_QAdd(diskLRUList, &dcp->lruq);*/
+ QAddH(&diskLRUList, &dcp->lruq, dcp->f.accessOrd); /* head is LRU */
+}
+
+void diskcache_WriteCacheInfo(cm_diskcache_t *dcp)
+{
+ /*char cacheInfoPath[256];
+ int cacheInfo_fd;*/
+ int rc;
+
+ /*return; /* skip this for perf. testing */
+ /*sprintf(cacheInfoPath, "%s\\%s", cm_cachePath, CACHE_INFO_FILE);
+ cacheInfo_fd = open(cacheInfoPath, O_RDWR);*/
+
+ DPRINTF("diskcache_WriteCacheInfo\n");
+
+ lseek(cacheInfo_fd, dcp->f.index * sizeof(struct fcache) +
+ sizeof(cm_cacheInfoHdr_t), SEEK_SET);
+
+ rc = write(cacheInfo_fd, &dcp->f, sizeof(struct fcache));
+ if (rc < 0)
+ complain("diskcache_WriteCacheInfo: Couldn't write cache info file, error=%d\n", errno);
+ /*fsync(cacheInfo_fd);*/
+
+ /*close(cacheInfo_fd);*/
+}
+
+void diskcache_Shutdown()
+{
+ cm_diskcache_t *dcp;
+ QLink *q;
+
+ /* close cache info file */
+ close (cacheInfo_fd);
+
+ /* close all open cache files */
+ q = QServe(&openFileList);
+ while (q)
+ {
+ dcp = (cm_diskcache_t *) MEM_TO_OBJ(cm_diskcache_t, openq, q);
+ if (dcp->openfd)
+ close(dcp->openfd);
+ q = QServe(&openFileList);
+ }
+}
+
+#endif /* DISKCACHE95 */
--- /dev/null
+/*
+ * 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
+ */
+
+#ifndef CM_DISKCACHE_H
+#define CM_DISKCACHE_H
+
+#include "queue95.h"
+
+#define DCHash(v, c) ((((v)->vnode + (v)->volume + (c))) & (afs_dhashsize-1))
+
+#define CACHE_INFO_FILE "cacheInfo"
+
+#define CACHE_INFO_MAGIC 0x34564321
+#define CACHE_FILE_MAGIC 0x78931230
+#define CACHE_FILES_PER_DIR 1000
+#define CACHE_INFO_UPDATES_PER_WRITE 1
+
+#define DPRINTF if (0) printf
+
+/* kept on disk and in dcache entries */
+struct fcache {
+ cm_fid_t fid; /* Fid for this file */
+ int32 modTime; /* last time this entry was modified */
+ /*afs_hyper_t versionNo; /* Associated data version number */
+ int dataVersion;
+ int chunk; /* Relative chunk number */
+ int chunkBytes; /* Num bytes in this chunk */
+ char states; /* Has this chunk been modified? */
+ int accessOrd; /* change to 64 bit later */
+#define DISK_CACHE_EMPTY 0
+#define DISK_CACHE_USED 1
+ int index; /* absolute chunk number */
+ int checksum;
+ /*char pad[464]; /* pad up to 512 bytes */
+};
+
+/* in-memory chunk file control block */
+typedef struct cm_diskcache {
+ struct fcache f;
+
+ /*osi_queue_t lruq;
+ osi_queue_t hashq;*/
+ QLink lruq;
+ QLink openq;
+ int openfd; /* open file descriptor */
+ struct cm_diskcache *hash_next;
+ struct cm_diskcache *hash_prev;
+ int refCount;
+ osi_mutex_t mx;
+} cm_diskcache_t;
+
+typedef struct cm_cacheInfoHdr {
+ int magic;
+ int chunks; /* total chunks in cache */
+ int chunkSize;
+ char pad[500]; /* pad up to 512 bytes */
+} cm_cacheInfoHdr_t;
+
+typedef struct cm_cacheFileHdr {
+ int magic;
+ int index;
+} cm_cacheFileHdr_t;
+
+/* external functions */
+
+/* Initialize the disk cache */
+int diskcache_Init();
+/* Get chunk from the cache or allocate a new chunk */
+int diskcache_Get(cm_fid_t *fid, osi_hyper_t *offset, char *buf, int size, int *dataVersion, int *dataCount, cm_diskcache_t **dcpRet);
+/* Write out buffer to disk */
+int diskcache_Update(cm_diskcache_t *dcp, char *buf, int size, int dataVersion);
+/* we accessed this chunk, so move to MRU */
+void diskcache_Touch(cm_diskcache_t *dcp);
+
+#endif /* CM_DISKCACHE_H */
#include <afs/param.h>
#include <afs/stds.h>
+#ifndef DJGPP
#include <windows.h>
#include <winsock2.h>
+#endif /* !DJGPP */
#include <string.h>
#include <stdlib.h>
#include <osi.h>
struct nc* nameHash[NHSIZE];
+#ifndef DJGPP
#define dnlcNotify(x,debug){ \
HANDLE hh; \
char *ptbuf[1]; \
DeregisterEventSource(hh); \
} \
}
+#else
+#define dnlcNotify(x,debug)
+#endif /* !DJGPP */
static struct nc *
#include <afs/param.h>
#include <afs/stds.h>
+#ifndef DJGPP
#include <windows.h>
+#else
+#include <sys/socket.h>
+#endif /* !DJGPP */
#include <errno.h>
#include <stdlib.h>
#include <malloc.h>
#include "smb.h"
+#ifndef DJGPP
#include <rxkad.h>
-
#include "afsrpc.h"
+#else
+#include <rx/rxkad.h>
+#include "afsrpc95.h"
+#endif
+
#include "cm_rpc.h"
/* Copied from afs_tokens.h */
#define PIOCTL_LOGON 0x1
+#define MAX_PATH 260
osi_mutex_t cm_Afsdsbmt_Lock;
*/
void TranslateExtendedChars(char *str)
{
+ char *p;
+
if (!str || !*str)
return;
+#ifndef DJGPP
CharToOem(str, str);
+#else
+ p = str;
+ while (*p) *p++ &= 0x7f; /* turn off high bit; probably not right */
+#endif
}
/* parse the passed-in file name and do a namei on it. If we fail,
uname = tp;
tp += strlen(tp) + 1;
+#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;
+#endif /* !DJGPP */
} else
cellp = cm_rootCellp;
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));
+#else
+ /* 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++;
/* 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));
+#else
+ memcpy(ct.HandShakeKey, &ucellp->sessionKey, sizeof(ct.HandShakeKey));
+#endif /* !DJGPP */
ct.ViceId = 37; /* XXX */
ct.BeginTimestamp = 0; /* XXX */
ct.EndTimestamp = ucellp->expirationTime;
cm_ucell_t *ucellp;
struct ClearToken ct;
char *tp;
+#ifndef DJGPP
afs_uuid_t uuid;
+#endif /* !DJGPP */
cm_SkipIoctlPath(ioctlp);
if (!cellp) return CM_ERROR_NOSUCHCELL;
tp += strlen(tp) + 1;
+#ifndef DJGPP
/* uuid */
memcpy(&uuid, tp, sizeof(uuid));
+#endif /* !DJGPP */
lock_ObtainMutex(&userp->mx);
/* 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));
+#else
+ memcpy(ct.HandShakeKey, &ucellp->sessionKey, sizeof(ct.HandShakeKey));
+#endif /* !DJGPP */
ct.ViceId = 37; /* XXX */
ct.BeginTimestamp = 0; /* XXX */
ct.EndTimestamp = ucellp->expirationTime;
lock_ReleaseMutex(&userp->mx);
+#ifndef DJGPP
cm_RegisterNewTokenEvent(uuid, ucellp->sessionKey.data);
+#endif /* !DJGPP */
return 0;
}
return 0;
}
+
+#ifdef DJGPP
+extern int afsd_shutdown(int);
+extern int afs_shutdown;
+
+long cm_IoctlShutdown(smb_ioctl_t *ioctlp, cm_user_t *userp)
+{
+ afs_shutdown = 1; /* flag to shut down */
+ return 0;
+}
+#endif /* DJGPP */
extern long cm_IoctlSetRxkcrypt(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern long cm_IoctlShutdown(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+
#endif /* __CM_IOCTL_INTERFACES_ONLY__ */
#endif /* __CM_IOCTL_H_ENV__ */
#include <malloc.h>
#include <osi.h>
+#ifndef DJGPP
#include "afsrpc.h"
+#else
+#include "afsrpc95.h"
+#endif
#include "afsd.h"
#include "afsd_init.h"
#ifndef __CM_RPC_H__
#define __CM_RPC_H__
+#ifndef DJGPP
#include "afsrpc.h"
+#else
+#include "afsrpc95.h"
+#endif
void cm_RegisterNewTokenEvent(afs_uuid_t uuid, char sessionKey[8]);
BOOL cm_FindTokenEvent(afs_uuid_t uuid, char sessionKey[8]);
--- /dev/null
+/*
+ * 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
+ */
+
+#ifndef __CM_RPC_H__
+#define __CM_RPC_H__
+
+/* Copied from declaration of GUID in RPCDCE.H */
+typedef struct afs_uuid {
+ unsigned long Data1;
+ unsigned short Data2;
+ unsigned short Data3;
+ unsigned char Data4[8];
+} afs_uuid_t;
+
+long AFSRPC_SetToken(
+ afs_uuid_t uuid,
+ unsigned char sessionKey[8]
+);
+
+long AFSRPC_GetToken(
+ afs_uuid_t uuid,
+ unsigned char sessionKey[8]
+);
+
+#endif /* __CM_RPC_H__ */
#include <afs/param.h>
#include <afs/stds.h>
+#ifndef DJGPP
#include <windows.h>
#include <winsock2.h>
+#include <nb30.h>
+#endif /* !DJGPP */
#include <malloc.h>
#include <string.h>
#include <stdlib.h>
-#include <nb30.h>
#include <osi.h>
#include "afsd.h"
osi_assert(scp->refCount-- > 0);
lock_ReleaseWrite(&cm_scacheLock);
}
+
+/* just look for the scp entry to get filetype */
+/* doesn't need to be perfectly accurate, so locking doesn't matter too much */
+int cm_FindFileType(cm_fid_t *fidp)
+{
+ long hash;
+ cm_scache_t *scp;
+
+ hash = CM_SCACHE_HASH(fidp);
+
+ osi_assert(fidp->cell != 0);
+
+ lock_ObtainWrite(&cm_scacheLock);
+ for(scp=cm_hashTablep[hash]; scp; scp=scp->nextp) {
+ if (cm_FidCmp(fidp, &scp->fid) == 0) {
+ /*scp->refCount++;*/
+ /*cm_AdjustLRU(scp);*/
+ lock_ReleaseWrite(&cm_scacheLock);
+ return scp->fileType;
+ }
+ }
+ lock_ReleaseWrite(&cm_scacheLock);
+ return NULL;
+}
#ifndef __CM_SCACHE_H_ENV__
#define __CM_SCACHE_H_ENV__ 1
+#ifdef DJGPP
+#include "largeint95.h"
+#endif /* DJGPP */
+
typedef struct cm_fid {
unsigned long cell;
unsigned long volume;
(fidp)->unique)) \
% cm_hashTableSize)
+#include "cm_conn.h"
+#include "cm_buf.h"
+
extern cm_scache_t cm_fakeSCache;
extern void cm_InitSCache(long);
#include <afs/param.h>
#include <afs/stds.h>
+#ifndef DJGPP
#include <windows.h>
#include <winsock2.h>
+#include <nb30.h>
+#else
+#include <sys/socket.h>
+#endif /* !DJGPP */
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <osi.h>
#include <rx/rx.h>
-#include <nb30.h>
#include "afsd.h"
osi_rwlock_t cm_serverLock;
#ifndef __CM_SERVER_H_ENV__
#define __CM_SERVER_H_ENV__ 1
+#ifndef DJGPP
#include <winsock2.h>
+#else /* DJGPP */
+#include <netinet/in.h>
+#endif /* !DJGPP */
#include <osi.h>
/* pointed to by volumes and cells without holds; cm_serverLock is obtained
#include <afs/param.h>
#include <afs/stds.h>
+#ifndef DJGPP
#include <windows.h>
+#endif /* !DJGPP */
#include <malloc.h>
#include <string.h>
#include <afs/param.h>
#include <afs/stds.h>
+#ifndef DJGPP
#include <windows.h>
+#include <winsock2.h>
+#endif /* !DJGPP */
#include <string.h>
#include <malloc.h>
-#include <winsock2.h>
#include <osi.h>
#include <rx/rx.h>
#include <afs/param.h>
#include <afs/stds.h>
+#ifndef DJGPP
#include <windows.h>
-#include <stddef.h>
#include <winsock2.h>
+#endif /* !DJGPP */
+#include <stddef.h>
#include <malloc.h>
#include <string.h>
#include <stdlib.h>
* 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);
int hasTilde;
} cm_lookupSearch_t;
+#include "cm_dir.h"
+
typedef int (*cm_DirFuncp_t)(struct cm_scache *, struct cm_dirEntry *, void *,
osi_hyper_t *entryOffsetp);
#include <afs/param.h>
#include <afs/stds.h>
+#ifndef DJGPP
#include <windows.h>
-#include <string.h>
-#include <malloc.h>
#include <winsock2.h>
#include <nb30.h>
+#else
+#include <sys/socket.h>
+#endif /* !DJGPP */
+#include <string.h>
+#include <malloc.h>
#include <osi.h>
#include <rx/rx.h>
--- /dev/null
+#ifndef DOSDEFS_H
+#define DOSDEFS_H
+
+/* dos_ptr is the phys. addr. accepted by farpeek/farpoke functions, i.e.,
+ dos_ptr = segment * 16 + offset */
+#define dos_ptr unsigned long
+
+/* get/set structure member of a struct in DOS memory */
+#define get_dos_member_b(T, ptr, memb) _farpeekb(_dos_ds, (ptr) + (dos_ptr)&(((T*)0)->memb))
+#define get_dos_member_w(T, ptr, memb) _farpeekw(_dos_ds, (ptr) + (dos_ptr)&(((T*)0)->memb))
+#define get_dos_member_l(T, ptr, memb) _farpeekl(_dos_ds, (ptr) + (dos_ptr)&(((T*)0)->memb))
+
+#define set_dos_member_b(T, ptr, memb, val) \
+ _farpokeb(_dos_ds, (ptr) + (dos_ptr)&(((T*)0)->memb), val)
+#define set_dos_member_w(T, ptr, memb, val) \
+ _farpokew(_dos_ds, (ptr) + (dos_ptr)&(((T*)0)->memb), val)
+#define set_dos_member_l(T, ptr, memb, val) \
+ _farpokel(_dos_ds, (ptr) + (dos_ptr)&(((T*)0)->memb), val)
+
+typedef struct _filetime
+{
+ unsigned int dwLowDateTime;
+ unsigned int dwHighDateTime;
+} FILETIME;
+
+#define FILE_ACTION_ADDED 0x00000001
+#define FILE_ACTION_REMOVED 0x00000002
+#define FILE_ACTION_MODIFIED 0x00000003
+#define FILE_ACTION_RENAMED_OLD_NAME 0x00000004
+#define FILE_ACTION_RENAMED_NEW_NAME 0x00000005
+
+#define FILE_NOTIFY_CHANGE_FILE_NAME 0x00000001
+#define FILE_NOTIFY_CHANGE_DIR_NAME 0x00000002
+#define FILE_NOTIFY_CHANGE_ATTRIBUTES 0x00000004
+#define FILE_NOTIFY_CHANGE_SIZE 0x00000008
+#define FILE_NOTIFY_CHANGE_LAST_WRITE 0x00000010
+#define FILE_NOTIFY_CHANGE_LAST_ACCESS 0x00000020
+#define FILE_NOTIFY_CHANGE_CREATION 0x00000040
+#define FILE_NOTIFY_CHANGE_SECURITY 0x00000100
+
+#define ULONG unsigned long
+#define USHORT unsigned short
+#define WCHAR wchar_t
+
+#define GetTickCount gettime_ms
+#define GetCurrentTime gettime_ms
+
+#define lstrcpy strcpy
+#define strcmpi stricmp
+#define lstrlen strlen
+#define _stricmp stricmp
+#define _strlwr strlwr
+#define _strupr strupr
+
+#endif
--- /dev/null
+/*
+ * 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
+ */
+
+/* functions for DJGPP to write to DOS memory or duplicate Win32 functions. */
+
+#include <stdio.h>
+#include <sys/farptr.h>
+#include <go32.h>
+#include <sys/time.h>
+#include "dosdefs95.h"
+
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+
+dos_memset(dos_ptr offset, int val, int size)
+{
+ int i;
+
+ for (i = 0; i < size; i++)
+ {
+ _farpokeb(_dos_ds, offset++, val);
+ }
+}
+
+char *dos_strcpy_get(char *str, unsigned int offset)
+{
+ register char a;
+
+ while ((a = _farpeekb(_dos_ds, offset++)) != 0)
+ *str++ = a;
+ *str = 0;
+
+ return str;
+}
+
+char *dos_strncpy_get(char *str, unsigned int offset, int len)
+{
+ register char a;
+ register int n=0;
+
+ while ((a = _farpeekb(_dos_ds, offset++)) != 0 && n++ < len)
+ *str++ = a;
+ *str = 0;
+
+ return str;
+}
+
+dos_ptr dos_strcpy_put(dos_ptr offset, char *str)
+{
+ char a;
+
+ while ((a = *str++) != 0)
+ _farpokeb(_dos_ds, offset++, a);
+ _farpokeb(_dos_ds, offset, 0);
+
+ return offset;
+}
+
+dos_ptr dos_strncpy_put(dos_ptr offset, char *str, int len)
+{
+ register char a;
+ register int n=0;
+
+ while ((a = *str++) != 0 && n++ < len)
+ _farpokeb(_dos_ds, offset++, a);
+ _farpokeb(_dos_ds, offset, 0);
+
+ return offset;
+}
+
+dos_ptr dos_strrchr(dos_ptr offset, char c)
+{
+ dos_ptr temp = 0;
+ char a;
+
+ while ((a = _farpeekb(_dos_ds, offset++)) != 0)
+ {
+ if (a == c) temp = offset-1;
+ }
+
+ return temp;
+}
+
+int dos_strcmp(unsigned char *str, dos_ptr offset)
+{
+ register unsigned char a, b;
+
+ while (((a = *str++) == (b = _farpeekb(_dos_ds, offset++))) && a && b);
+ return a-b;
+}
+
+int dos_strncmp(unsigned char *str, dos_ptr offset, int len)
+{
+ register unsigned char a, b;
+ register int i=0;
+
+ while (i++ < len && ((a = *str++) == (b = _farpeekb(_dos_ds, offset++))) && a && b);
+ return a-b;
+}
+
+int dos_strlen(dos_ptr offset)
+{
+ int len=0;
+
+ while (_farpeekb(_dos_ds, offset++))
+ len++;
+
+ return len;
+}
+
+
+int sub_time(struct timeval a, struct timeval b)
+{
+ int n = a.tv_sec - b.tv_sec;
+ n *= 1000000;
+ n += a.tv_usec - b.tv_usec;
+ return n / 1000;
+}
+
+int tm_to_ms(struct timeval t)
+{
+ int n = t.tv_sec * 1000;
+ n += t.tv_usec / 1000;
+ return n;
+}
+
+int gettime_ms()
+{
+ struct timeval t;
+ int n = t.tv_sec * 1000;
+
+ gettimeofday(&t, NULL);
+ n += t.tv_usec / 1000;
+ return n;
+}
+
+int gettime_us()
+{
+ struct timeval t;
+ int n;
+
+ gettimeofday(&t, NULL);
+ n = t.tv_sec * 1000000;
+ n += t.tv_usec;
+ return n;
+}
+
+int GetPrivateProfileString(char *sect, char *key, char *def,
+ char *buf, int len, char *file)
+{
+ char s[256];
+ char skey[128];
+ int nchars=0;
+ int amt;
+ int offset;
+ char sectstr[256];
+ char *p;
+ FILE *f = fopen(file, "r");
+ if (!f) return 0;
+
+ sprintf(sectstr, "[%s]", sect);
+ while (1)
+ {
+ fgets(s, 256, f);
+ if (feof(f)) break;
+
+ /* look for section names */
+ if (s[0] != '[')
+ continue;
+
+ /* if sect is NULL, copy all section names */
+ if (!sect)
+ {
+ amt = MIN(strlen(s)+1, len-1);
+ strncpy(buf, s, amt-1);
+ buf[amt] = 0;
+ len -= amt;
+ buf += amt;
+ nchars += amt;
+ continue;
+ }
+
+ /* continue if non-matching section name */
+ if (sect && strnicmp(s+1, sect, strlen(sect)) != 0)
+ continue;
+
+ /* else we have the correct section */
+
+ while (len > 0)
+ {
+ fgets(s, 256, f);
+ if (feof(f)) break;
+
+ /* get the key part */
+ strcpy(skey, s);
+ p = strrchr(skey, '=');
+ if (!p) { fclose(f); return 0; }
+ *p = 0;
+
+ /* continue if key doesn't match */
+ if (key && stricmp(skey, key) != 0)
+ continue;
+
+ /* if NULL key, copy key names */
+ if (!key)
+ {
+ amt = MIN(strlen(skey)+1, len-2);
+ strncpy(buf, skey, amt);
+ buf[amt] = 0;
+ buf[amt+1] = 0; /* final trailing NULL */
+ len -= amt;
+ buf += amt;
+ nchars += amt;
+ continue;
+ }
+
+ /* discard key= and newline */
+ offset = strlen(key) + 1;
+ amt = MIN(strlen(s+offset)-1, len-1);
+ strncpy(buf, s+offset, amt);
+ buf[amt] = 0;
+ len -= amt;
+ buf += amt;
+ nchars += amt;
+ }
+ }
+
+ if (nchars == 0)
+ {
+ if (def)
+ {
+ strcpy(buf, def);
+ nchars = strlen(def);
+ }
+ }
+
+ fclose(f);
+ return nchars;
+}
+
+int WritePrivateProfileString(char *sect, char *key, char *str, char *file)
+{
+ char tmpfile[256], s[256], sectstr[256];
+ int found = 0;
+ char *p;
+ FILE *fr = fopen(file, "r");
+ FILE *fw = fopen(tmpfile, "w");
+
+ strcpy(tmpfile, file);
+ p = strrchr(tmpfile, '.');
+ *p = 0;
+ strcat(tmpfile, ".tmp"); /* change extension to .tmp */
+
+ sprintf(sectstr, "[%s]", sect);
+ while (1)
+ {
+ fgets(s, 256, fr);
+ if (feof(fr)) break;
+
+ fputs(s, fw);
+
+ /* look for section names */
+ if (found || s[0] != '[')
+ {
+ continue;
+ }
+
+ if (stricmp(s, sectstr) == 0)
+ {
+ /* found section, print new item */
+ found = 1;
+ strcpy(s, key);
+ strcat(s, "=");
+ strcat(s, str);
+ strcat(s, "\n");
+ fputs(s, fw);
+ }
+ }
+ fclose(fw);
+ fclose(fr);
+
+ /* delete old file */
+ remove(file);
+
+ /* rename .tmp */
+ rename(tmpfile, file);
+
+ return found;
+}
#include <afs/prs_fs.h>
#include <afs/pioctl_nt.h>
+#ifndef _MFC_VER
#include <winsock2.h>
+#endif
/* Fake error code since NT errno.h doesn't define it */
#include <afs/errmap_nt.h>
--- /dev/null
+/*
+ * 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
+ */
+
+/* Large integer support for DJGPP */
+
+#include <stdlib.h>
+#include "largeint95.h"
+
+LARGE_INTEGER LargeIntegerAdd(LARGE_INTEGER a, LARGE_INTEGER b)
+{
+ LARGE_INTEGER c;
+ long long *c1 = (long long *) &c;
+ long long *a1 = (long long *) &a;
+ long long *b1 = (long long *) &b;
+ *c1 = *a1 + *b1;
+ return c;
+}
+
+LARGE_INTEGER LargeIntegerSubtract(LARGE_INTEGER a, LARGE_INTEGER b)
+{
+ LARGE_INTEGER c;
+ long long *c1 = (long long *) &c;
+ long long *a1 = (long long *) &a;
+ long long *b1 = (long long *) &b;
+ *c1 = *a1 - *b1;
+ return c;
+}
+
+LARGE_INTEGER ConvertLongToLargeInteger(unsigned long a)
+{
+ LARGE_INTEGER n;
+
+ n.LowPart = a;
+ n.HighPart = 0;
+ return n;
+}
+
+LARGE_INTEGER LargeIntegerMultiplyLongByLong(unsigned long a, unsigned long b)
+{
+ LARGE_INTEGER c;
+ long long *c1 = (long long *) &c;
+
+ *c1 = (long long) a * (long long) b;
+ return c;
+}
+
+LARGE_INTEGER LargeIntegerMultiplyByLong(LARGE_INTEGER a, unsigned long b)
+{
+ LARGE_INTEGER c;
+ long long *c1 = (long long *) &c;
+ long long *a1 = (long long *) &a;
+
+ *c1 = *a1 * (long long) b;
+ return c;
+}
+
+unsigned long LargeIntegerDivideByLong(LARGE_INTEGER a, unsigned long b)
+{
+ lldiv_t q;
+ long long *a1 = (long long *) &a;
+
+ q = lldiv(*a1, (long long) b);
+ return (unsigned long) q.quot;
+}
+
+#if 0
+LARGE_INTEGER LargeIntegerAdd(LARGE_INTEGER a, LARGE_INTEGER b)
+{
+ LARGE_INTEGER c;
+
+ c.LowPart = a.LowPart + b.LowPart;
+ c.HighPart = a.HighPart + b.HighPart;
+
+ /* not sure how to do a real carry */
+ if (c.LowPart < a.LowPart)
+ c.HighPart++;
+
+ return c;
+}
+
+LARGE_INTEGER LargeIntegerSubtract(LARGE_INTEGER a, LARGE_INTEGER b)
+{
+ LARGE_INTEGER c;
+
+ c.LowPart = a.LowPart - b.LowPart;
+ c.HighPart = a.HighPart - b.HighPart;
+
+ /* borrow */
+ if (c.LowPart > a.LowPart)
+ c.HighPart--;
+
+ return c;
+}
+
+__inline__ unsigned long mult32(unsigned long a, unsigned long b,
+ unsigned long *ov)
+{
+ unsigned long p, o;
+
+ /* multiply low part and save the overflow bits */
+ __asm__ __volatile__ ("movl %2, %%eax\n
+ mull %3, %%eax\n
+ movl %%eax, %0\n
+ movl %%edx, %1"
+ : "=g" (p), "=g" (o)
+ : "g" (a), "g" (b)
+ : "ax", "dx", "memory"
+ );
+ *ov = o;
+ return p;
+}
+
+__inline__ unsigned long div32(unsigned long a, unsigned long b,
+ unsigned long *rem)
+{
+ unsigned long q, r;
+
+ /* multiply low part and save the overflow bits */
+ __asm__ __volatile__ ("movl %2, %%eax\n
+ divl %3, %%eax\n
+ movl %%eax, %0\n
+ movl %%edx, %1"
+ : "=g" (q), "=g" (r)
+ : "g" (a), "g" (b)
+ : "ax", "dx", "memory"
+ );
+ *rem = r;
+ return q;
+}
+
+LARGE_INTEGER LargeIntegerMultiplyLongByLong(unsigned long a, unsigned long b)
+{
+ LARGE_INTEGER prod;
+
+ prod.LowPart = mult32(a, b, &prod.HighPart);
+ return prod;
+}
+
+LARGE_INTEGER LargeIntegerMultiplyByLong(LARGE_INTEGER a, unsigned long b)
+{
+ LARGE_INTEGER prod;
+ unsigned long x, prodl, prodh, ovl, ovh;
+
+ /* multiply low part and save the overflow bits */
+ prod.LowPart = mult32(a.LowPart, b, &ovl);
+
+ /* multiply high part */
+ prod.HighPart = mult32(a.HighPart, b, &ovh);
+
+ /* add overflow from low part */
+ prod.HighPart += ovl;
+
+ return prod;
+}
+
+unsigned long LargeIntegerDivideByLong(LARGE_INTEGER a, unsigned long b, unsigned long *rem)
+{
+ unsigned long n, r, q;
+ LARGE_INTEGER t;
+
+ if (b == 0) { return 0; }
+ if (b == 1) { *rem = 0; return a.LowPart; }
+
+ n = div32(a.LowPart, b, &r);
+ if (a.HighPart == 0)
+ {
+ *rem = r;
+ return n;
+ }
+ else
+ {
+ q = div32(0xffffffff-b+1, b, &r);
+ q++;
+ n += q * a.HighPart;
+ n += LargeIntegerDivideByLong(LargeIntegerMultiplyLongByLong(r, a.HighPart), b, rem);
+ return n;
+ }
+}
+#endif
+
+#if 0
+int LargeIntegerGreaterThan(LARGE_INTEGER a, LARGE_INTEGER b)
+{
+ if (a.HighPart > b.HighPart) return 1;
+ else if (a.HighPart == b.HighPart && a.LowPart > b.LowPart) return 1;
+ else return 0;
+}
+
+int LargeIntegerGreaterThanOrEqualTo(LARGE_INTEGER a, LARGE_INTEGER b)
+{
+ if (a.HighPart > b.HighPart) return 1;
+ else if (a.HighPart == b.HighPart && a.LowPart >= b.LowPart) return 1;
+ else return 0;
+}
+
+int LargeIntegerEqualTo(LARGE_INTEGER a, LARGE_INTEGER b)
+{
+ if (a.HighPart == b.HighPart && a.LowPart == b.LowPart) return 1;
+ else return 0;
+}
+
+int LargeIntegerGreaterOrEqualToZero(LARGE_INTEGER a)
+{
+ return ((a.HighPart & 0x8fffffff) ? 0 : 1);
+}
+
+int LargeIntegerLessThanZero(LARGE_INTEGER a)
+{
+ return ((a.HighPart & 0x8fffffff) ? 1 : 0);
+}
+#endif
--- /dev/null
+#ifndef LARGEINT_H
+#define LARGEINT_H
+
+typedef struct {
+ unsigned long LowPart;
+ unsigned long HighPart;
+} LARGE_INTEGER;
+
+LARGE_INTEGER LargeIntegerAdd(LARGE_INTEGER a, LARGE_INTEGER b);
+LARGE_INTEGER LargeIntegerSubtract(LARGE_INTEGER a, LARGE_INTEGER b);
+/*int LargeIntegerGreaterThan(LARGE_INTEGER a, LARGE_INTEGER b);
+int LargeIntegerGreaterThanOrEqualTo(LARGE_INTEGER a, LARGE_INTEGER b);
+int LargeIntegerEqualTo(LARGE_INTEGER a, LARGE_INTEGER b);
+int LargeIntegerGreaterOrEqualToZero(LARGE_INTEGER a);
+int LargeIntegerLessThanZero(LARGE_INTEGER a);*/
+LARGE_INTEGER ConvertLongToLargeInteger(unsigned long a);
+LARGE_INTEGER LargeIntegerMultiplyByLong(LARGE_INTEGER a, unsigned long b);
+unsigned long LargeIntegerDivideByLong(LARGE_INTEGER a, unsigned long b);
+
+#define LargeIntegerGreaterThan(a, b) \
+ ((a).HighPart > (b).HighPart || \
+ ((a).HighPart == (b).HighPart && (a).LowPart > (b).LowPart))
+
+#define LargeIntegerGreaterThanOrEqualTo(a, b) \
+ ((a).HighPart > (b).HighPart || \
+ ((a).HighPart == (b).HighPart && (a).LowPart >= (b).LowPart))
+
+#define LargeIntegerLessThan(a, b) \
+ ((a).HighPart < (b).HighPart || \
+ ((a).HighPart == (b).HighPart && (a).LowPart < (b).LowPart))
+
+#define LargeIntegerLessThanOrEqualTo(a, b) \
+ ((a).HighPart < (b).HighPart || \
+ ((a).HighPart == (b).HighPart && (a).LowPart <= (b).LowPart))
+
+#define LargeIntegerEqualTo(a, b) \
+ ((a).HighPart == (b).HighPart && (a).LowPart == (b).LowPart)
+
+#define LargeIntegerGreaterOrEqualToZero(a) ((a).HighPart >= 0)
+
+#define LargeIntegerLessThanZero(a) ((a).HighPart < 0)
+
+#define LargeIntegerNotEqualToZero(a) ((a).HighPart || (a).LowPart)
+
+#endif
--- /dev/null
+/*
+ * 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
+ */
+
+/* Netbios function for DJGPP: calls interrupt 5Ch for Netbios function.
+ NCB and buffer space must be in DOS memory (below 1MB). */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <dpmi.h>
+#include <go32.h>
+#include "dosdefs95.h"
+#include "netbios95.h"
+
+extern int handler_seg, handler_off;
+
+int Netbios(NCB *Ncb, dos_ptr dos_ncb)
+{
+ __dpmi_regs regs;
+ int asynch = 1;
+ dos_ptr oldncb_buffer;
+
+#if 1
+ if (Ncb->ncb_command == NCBRESET ||
+ Ncb->ncb_command == NCBCANCEL ||
+ Ncb->ncb_command == NCBUNLINK ||
+ Ncb->ncb_command == NCBADDNAME ||
+ Ncb->ncb_command == NCBENUM ||
+ Ncb->ncb_command == NCBDELNAME) /* temp */
+ asynch = 0;
+#else
+ if (1)
+ asynch = 0;
+#endif
+ else
+ /* set to asynchronous */
+ Ncb->ncb_command |= ASYNCH;
+
+ /* adjust ncb_buffer pointer to be a segment:zero-offset pointer
+ for __dpmi_int */
+ oldncb_buffer = Ncb->ncb_buffer;
+ Ncb->ncb_buffer = Ncb->ncb_buffer << 12;
+
+ /*if (asynch)
+ Ncb->ncb_post = (handler_seg << 16) | handler_off;*/
+
+ /* copy to DOS space */
+ dosmemput(Ncb, sizeof(NCB), dos_ncb);
+
+ /* set address of NCB in registers */
+ memset(®s, 0, sizeof(regs));
+ regs.d.ebx = 0;
+ regs.x.ds = regs.x.es = dos_ncb/16;
+
+ __dpmi_int(0x5c,®s);
+ /*dosmemget(__tb, sizeof(NCB), Ncb);*/
+
+ if (asynch)
+ IOMGR_NCBSelect(Ncb, dos_ncb, NULL);
+
+ /* undo the change to ncb_buffer */
+ Ncb->ncb_buffer = oldncb_buffer;
+
+ return regs.x.ax;
+}
+
--- /dev/null
+/*
+ * 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
+ */
+
+#ifndef NETBIOS_H
+#define NETBIOS_H
+
+#define BYTE char
+#define WORD short
+
+#define NCBNAMSZ 16 /* absolute length of a net name */
+#define MAX_LANA 254 /* lana's in range 0 to MAX_LANA inclusive */
+
+#define MAX_COMPUTERNAME_LENGTH 15
+
+
+#define UCHAR unsigned char
+#define PUCHAR unsigned char *
+#define WORD short
+
+#include "osithrd95.h"
+
+typedef struct _NCB {
+ UCHAR ncb_command;
+ UCHAR ncb_retcode;
+ UCHAR ncb_lsn;
+ UCHAR ncb_num;
+ unsigned int ncb_buffer;
+ WORD ncb_length;
+ UCHAR ncb_callname[NCBNAMSZ];
+ UCHAR ncb_name[NCBNAMSZ];
+ UCHAR ncb_rto;
+ UCHAR ncb_sto;
+ int (*ncb_post)();
+ UCHAR ncb_lana_num;
+ UCHAR ncb_cmd_cplt;
+ UCHAR ncb_reserve[10];
+ UCHAR ncb_reserve2[4];
+ EVENT_HANDLE ncb_event;
+} NCB, *PNCB;
+
+
+#define NCBCALL 0x10
+#define NCBLISTEN 0x11
+#define NCBHANGUP 0x12
+#define NCBSEND 0x14
+#define NCBRECV 0x15
+#define NCBRECVANY 0x16
+#define NCBCHAINSEND 0x17
+#define NCBDGSEND 0x20
+#define NCBDGRECV 0x21
+#define NCBDGSENDBC 0x22
+#define NCBDGRECVBC 0x23
+#define NCBADDNAME 0x30
+#define NCBDELNAME 0x31
+#define NCBRESET 0x32
+#define NCBASTAT 0x33
+#define NCBSSTAT 0x34
+#define NCBCANCEL 0x35
+#define NCBADDGRNAME 0x36
+#define NCBENUM 0x37
+#define NCBUNLINK 0x70
+#define NCBSENDNA 0x71
+#define NCBCHAINSENDNA 0x72
+#define NCBLANSTALERT 0x73
+#define NCBACTION 0x77
+#define NCBFINDNAME 0x78
+#define NCBTRACE 0x79
+#define ASYNCH 0x80
+
+
+#define NRC_GOODRET 0x00
+#define NRC_BUFLEN 0x01
+#define NRC_ILLCMD 0x03
+#define NRC_CMDTMO 0x05
+#define NRC_INCOMP 0x06
+#define NRC_BADDR 0x07
+#define NRC_SNUMOUT 0x08
+#define NRC_NORES 0x09
+#define NRC_SCLOSED 0x0a
+#define NRC_CMDCAN 0x0b
+#define NRC_DUPNAME 0x0d
+#define NRC_NAMTFUL 0x0e
+#define NRC_ACTSES 0x0f
+#define NRC_LOCTFUL 0x11
+#define NRC_REMTFUL 0x12
+#define NRC_ILLNN 0x13
+#define NRC_NOCALL 0x14
+#define NRC_NOWILD 0x15
+#define NRC_INUSE 0x16
+#define NRC_NAMERR 0x17
+#define NRC_SABORT 0x18
+#define NRC_NAMCONF 0x19
+#define NRC_IFBUSY 0x21
+#define NRC_TOOMANY 0x22
+#define NRC_BRIDGE 0x23
+#define NRC_CANOCCR 0x24
+#define NRC_CANCEL 0x26
+#define NRC_DUPENV 0x30
+#define NRC_ENVNOTDEF 0x34
+#define NRC_OSRESNOTAV 0x35
+#define NRC_MAXAPPS 0x36
+#define NRC_NOSAPS 0x37
+#define NRC_NORESOURCES 0x38
+#define NRC_INVADDRESS 0x39
+#define NRC_INVDDID 0x3B
+#define NRC_LOCKFAIL 0x3C
+#define NRC_OPENERR 0x3f
+#define NRC_SYSTEM 0x40
+#define NRC_PENDING 0xff
+
+#endif /* NETBIOS_H */
--- /dev/null
+/*
+ * 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
+ */
+
+/* queue.c
+ *
+ * Generic queue for use with Windows 95/DJGPP disk cache
+ *
+ ************************************************************************/
+
+#ifdef DISKCACHE95
+
+#define NULL 0
+#include "queue95.h"
+#include <stdio.h>
+
+void QInit(Queue *queue)
+{
+ queue->head = NULL;
+ queue->tail = NULL;
+ queue->currpos = NULL;
+}
+
+void QAddT(Queue *queue, QLink* node, int ord)
+{
+ /*QLink* node = new QLink;*/
+
+ /*node->item = x;*/
+ node->ord = ord;
+ node->next = NULL;
+ node->prev = NULL;
+ if (!queue->tail)
+ queue->head = queue->tail = node;
+ else {
+ queue->tail->next = node;
+ queue->tail = node;
+ node->prev = queue->tail;
+ }
+ queue->size++;
+}
+
+void QAddH(Queue *queue, QLink *node, int ord)
+{
+ node->ord = ord;
+ node->next = NULL;
+ node->prev = NULL;
+ if (!queue->head)
+ queue->head = queue->tail = node;
+ else {
+ node->next = queue->head;
+ queue->head->prev = node;
+ queue->head = node;
+ }
+ queue->size++;
+}
+
+void QAddOrd(Queue *queue, QLink *node, int ord)
+{
+ /*QLink<T>* node = new QLink<T>;*/
+ QLink* p, *prev;
+
+ node->ord = ord;
+ node->next = NULL;
+ node->prev = NULL;
+ if (!queue->tail)
+ queue->head = queue->tail = node;
+ else {
+ p = queue->head;
+ while (p && ord >= p->ord) { /* add towards tail end if equals found */
+ prev = p;
+ p = p->next;
+ }
+ if (p == queue->head) {
+ QAddH(queue, node, ord);
+ }
+ else if (p == NULL) {
+ QAddT(queue, node, ord);
+ }
+ else {
+ node->next = p;
+ node->prev = prev;
+ prev->next = node;
+ }
+ }
+ queue->size++;
+}
+
+QLink* QServe(Queue *queue)
+{
+ QLink *n = queue->head;
+
+ if (!queue->head) return NULL;
+ if (queue->head == queue->tail)
+ queue->head = queue->tail = NULL;
+ else
+ queue->head = n->next;
+ queue->size--;
+ return n;
+}
+
+void QMoveToTail(Queue *queue, QLink *n, int ord)
+{
+ QRemove(queue, n);
+ QAddT(queue, n, ord);
+}
+
+void QRemove(Queue *queue, QLink *n)
+{
+ /*QLink* n2 = NULL;*/
+
+ if (!queue->head) return;
+ /*while(n && n != x) {
+ n2 = n;
+ n = n->next;
+ }*/
+ if (n == queue->currpos) {
+ if (n == queue->head) queue->currpos = n->next;
+ if (n == queue->tail) queue->currpos = n->prev;
+ if (n->prev) queue->currpos = n->prev;
+ }
+
+ if (n->prev)
+ {
+ /*assert(n->prev->next == n);*/
+ n->prev->next = n->next;
+ }
+ else
+ queue->head = n->next;
+
+ if (n->next)
+ {
+ /*assert(n->next->prev == n);*/
+ n->next->prev = n->prev;
+ }
+ else
+ queue->tail = n->prev;
+
+ queue->size--;
+}
+
+QLink *QCurrent(Queue *queue)
+{
+ /*if (currpos) return currpos->item;
+ else return NULL;*/
+ return queue->currpos;
+}
+
+void QIterate(Queue *queue)
+{
+ QLink* node;
+
+ node = queue->head;
+ while (node) {
+ printf("node=%x, ord=%f\n", node, node->ord);
+ node = node->next;
+ }
+ fflush(stdout);
+}
+
+#endif /* DISKCACHE95 */
--- /dev/null
+/*
+ * 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
+ */
+
+/* queue.h
+ *
+ * Class declaration for generic queue for use with Windows 95/DJGPP client
+ * disk cache
+ *
+ ***************************************************************************/
+
+#ifndef _QUEUE_H
+#define _QUEUE_H
+
+/* offset of member m in struct T */
+#define OFFSETOF(T, m) ((USHORT) &(((T *) NULL)->m))
+
+/* get pointer to parent struct T containing member m at address p */
+#define MEM_TO_OBJ(T, m, p) ((char *)(p) - OFFSETOF(T, m))
+
+typedef struct _QLink {
+ struct _QLink *next;
+ struct _QLink *prev;
+ int ord;
+} QLink;
+
+typedef struct _Queue {
+ QLink *head;
+ QLink *tail;
+ int size;
+ QLink *currpos;
+} Queue;
+
+/* add item to tail of queue */
+void QAddT(Queue *queue, QLink* node, int ord);
+
+/* add item to head of queue */
+void QAddH(Queue *queue, QLink *node, int ord);
+
+/* add item based on order value */
+void QAddOrd(Queue *queue, QLink *node, int ord);
+
+/* remove and return head of queue */
+QLink* QServe(Queue *queue);
+
+/* move item to tail of queue */
+void QMoveToTail(Queue *queue, QLink *x, int ord);
+
+/* remove item from queue */
+void QRemove(Queue *queue, QLink* x);
+
+/* return current position */
+QLink *QCurrent(Queue *queue);
+
+/* print out list of queued items */
+void QIterate(Queue *queue);
+
+#endif
#include <afs/param.h>
#include <afs/stds.h>
+#ifndef DJGPP
#include <windows.h>
+#else
+#include <sys/timeb.h>
+#include <tzfile.h>
+#endif /* !DJGPP */
#include <stddef.h>
#include <stdlib.h>
#include <malloc.h>
smb_user_t *loggedOutUserp = NULL;
unsigned long loggedOutTime;
int loggedOut = 0;
+#ifdef DJGPP
+int smbShutdownFlag = 0;
+#endif /* DJGPP */
int smb_LogoffTokenTransfer;
unsigned long smb_LogoffTransferTimeout;
osi_rwlock_t smb_rctLock;
unsigned char smb_LANadapter;
+unsigned char smb_sharename[NCBNAMSZ+1] = {0};
/* for debugging */
long smb_maxObsConcurrentCalls=0;
int numNCBs, numSessions;
#define NCBmax 100
-HANDLE NCBavails[NCBmax], NCBevents[NCBmax];
-HANDLE **NCBreturns;
+EVENT_HANDLE NCBavails[NCBmax], NCBevents[NCBmax];
+EVENT_HANDLE **NCBreturns;
DWORD NCBsessions[NCBmax];
NCB *NCBs[NCBmax];
struct smb_packet *bufs[NCBmax];
#define Sessionmax 100
-HANDLE SessionEvents[Sessionmax];
+EVENT_HANDLE SessionEvents[Sessionmax];
unsigned short LSNs[Sessionmax];
BOOL dead_sessions[Sessionmax];
/* for raw I/O */
osi_mutex_t smb_RawBufLock;
+#ifdef DJGPP
+#define SMB_RAW_BUFS 4
+dos_ptr smb_RawBufs;
+int smb_RawBufSel[SMB_RAW_BUFS];
+#else
char *smb_RawBufs;
+#endif /* DJGPP */
#define RAWTIMEOUT INFINITE
long code;
osi_hyper_t offset;
long count;
+#ifndef DJGPP
char *buf;
+#else
+ dos_ptr buf;
+#endif /* DJGPP */
int writeMode;
long alreadyWritten;
} raw_write_cont_t;
/* global state about V3 protocols */
int smb_useV3; /* try to negotiate V3 */
+#ifndef DJGPP
/* MessageBox or something like it */
int (WINAPI *smb_MBfunc)(HWND, LPCTSTR, LPCTSTR, UINT) = NULL;
+#endif /* DJGPP */
/* GMT time info:
* Time in Unix format of midnight, 1/1/1970 local time.
/* forward decl */
void smb_DispatchPacket(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp,
NCB *ncbp, raw_write_cont_t *rwcp);
+void smb_NetbiosInit();
+extern char cm_HostName[];
+#ifdef DJGPP
+extern char cm_confDir[];
+#endif
+
+#ifdef DJGPP
+#define LPTSTR char *
+#define GetComputerName(str, sizep) \
+ strcpy((str), cm_HostName); \
+ *(sizep) = strlen(cm_HostName)
+#endif /* DJGPP */
/*
* Demo expiration
return (int)num;
}
+#ifndef DJGPP
void ShowUnixTime(char *FuncName, long unixTime)
{
FILETIME ft;
osi_Log1(afsd_logp, "%s", osi_LogSaveString(afsd_logp, msg));
}
}
+#endif /* DJGPP */
+#ifndef DJGPP
/* Determine if we are observing daylight savings time */
void GetTimeZoneInfo(BOOL *pDST, LONG *pDstBias, LONG *pBias)
{
*/
*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;
+
+ ftime(&t);
+ *pDST = t.dstflag;
+ *pDstBias = -60; /* where can this be different? */
+ *pBias = t.timezone;
+}
+#endif /* DJGPP */
+
void CompensateForSmbClientLastWriteTimeBugs(long *pLastWriteTime)
{
smb_NowTZ = seconds;
}
+
+#ifndef DJGPP
void smb_LargeSearchTimeFromUnixTime(FILETIME *largeTimep, long unixTime)
{
struct tm *ltp;
SystemTimeToFileTime(&stm, largeTimep);
}
+#else /* DJGPP */
+void smb_LargeSearchTimeFromUnixTime(FILETIME *largeTimep, long 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);
+}
+#endif /* !DJGPP */
+#ifndef DJGPP
void smb_UnixTimeFromLargeSearchTime(long *unixTimep, FILETIME *largeTimep)
{
SYSTEMTIME stm;
*unixTimep = mktime(<);
_timezone = save_timezone;
}
+#else /* DJGPP */
+void smb_UnixTimeFromLargeSearchTime(long *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);
+}
+#endif /* !DJGPP */
void smb_SearchTimeFromUnixTime(long *dosTimep, long unixTime)
{
int dosTime;
struct tm localJunk;
- ltp = localtime(&unixTime);
+ ltp = localtime((time_t*) &unixTime);
/* if we fail, make up something */
if (!ltp) {
void smb_UnixTimeFromDosUTime(long *unixTimep, long dosTime)
{
+#ifndef DJGPP
*unixTimep = dosTime + smb_localZero;
+#else /* DJGPP */
+ /* dosTime seems to be already adjusted for GMT */
+ *unixTimep = dosTime;
+#endif /* !DJGPP */
}
smb_vc_t *smb_FindVC(unsigned short lsn, int flags)
lock_InitializeMutex(&fidp->mx, "fid_t mutex");
fidp->fid = fid;
fidp->curr_chunk = fidp->prev_chunk = -2;
- fidp->raw_write_event = CreateEvent(NULL, FALSE, TRUE, NULL);
+ fidp->raw_write_event = thrd_CreateEvent(NULL, FALSE, TRUE, NULL);
if (newFid) {
vcp->fidCounter = fid+1;
if (vcp->fidCounter == 0) vcp->fidCounter = 1;
if (!(fidp->flags & SMB_FID_IOCTL))
scp = fidp->scp;
osi_QRemove((osi_queue_t **) &vcp->fidsp, &fidp->q);
- CloseHandle(fidp->raw_write_event);
+ thrd_CloseHandle(fidp->raw_write_event);
/* and see if there is ioctl stuff to free */
ioctlp = fidp->ioctlp;
char VNComputerName[] = "%COMPUTERNAME%";
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 (/afs)\n", smb_localNamep, "ALL");
+
+#ifndef DJGPP
+ code = GetWindowsDirectory(sbmtpath, sizeof(sbmtpath));
+ if (code == 0 || code > sizeof(sbmtpath)) return -1;
+#else
+ 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, "/afs", 4) != 0)
+ print_afs = 1;
+ while (*p) {
+ if (*p == '\\') *p = '/'; /* change to / */
+ p++;
+ }
+
+ fprintf(stderr, "\\\\%s\\%-16s (%s%s)\n",
+ smb_localNamep, this_share, (print_afs ? "/afs" : "\0"),
+ pathName);
+ num_shares++;
+ while (*this_share != NULL) this_share++; /* find next NULL */
+ this_share++; /* skip past the NULL */
+ } while (*this_share != NULL); /* stop at final NULL */
+
+ return num_shares;
+}
+
/* find a shareName in the table of submounts */
int smb_FindShare(smb_vc_t *vcp, smb_packet_t *inp, char *shareName,
char **pathNamep)
smb_user_t *uidp;
char temp[1024];
DWORD sizeTemp;
+ char sbmtpath[256];
+ char *p, *q;
if (strcmp(shareName, "IPC$") == 0) {
*pathNamep = NULL;
return 1;
}
+#ifndef DJGPP
+ strcpy(sbmtpath, "afsdsbmt.ini");
+#else /* DJGPP */
+ strcpy(sbmtpath, cm_confDir);
+ strcat(sbmtpath, "/afsdsbmt.ini");
+#endif /* !DJGPP */
len = GetPrivateProfileString("AFS Submounts", shareName, "",
- pathName, sizeof(pathName), "afsdsbmt.ini");
+ pathName, sizeof(pathName), sbmtpath);
if (len == 0 || len == sizeof(pathName) - 1) {
*pathNamep = NULL;
return 0;
}
+
+ /* We can accept either unix or PC style AFS pathnames. Convert
+ Unix-style to PC style here for internal use. */
+ p = pathName;
+ if (strncmp(p, "/afs", 4) == 0)
+ p += 4; /* skip /afs */
+ q = p;
+ while (*q) {
+ if (*q == '/') *q = '\\'; /* change to \ */
+ q++;
+ }
while (1)
{
- if (var = smb_stristr(pathName, VNUserName)) {
+ if (var = smb_stristr(p, VNUserName)) {
uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0);
- smb_subst(pathName, var, sizeof(VNUserName),
+ smb_subst(p, var, sizeof(VNUserName),
uidp->name);
smb_ReleaseUID(uidp);
}
- else if (var = smb_stristr(pathName, VNLCUserName)) {
+ else if (var = smb_stristr(p, VNLCUserName)) {
uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0);
strcpy(temp, uidp->name);
_strlwr(temp);
- smb_subst(pathName, var, sizeof(VNLCUserName), temp);
+ smb_subst(p, var, sizeof(VNLCUserName), temp);
smb_ReleaseUID(uidp);
}
- else if (var = smb_stristr(pathName, VNComputerName)) {
+ else if (var = smb_stristr(p, VNComputerName)) {
sizeTemp = sizeof(temp);
GetComputerName((LPTSTR)temp, &sizeTemp);
- smb_subst(pathName, var, sizeof(VNComputerName),
+ smb_subst(p, var, sizeof(VNComputerName),
temp);
}
- else if (var = smb_stristr(pathName, VNLCComputerName)) {
+ else if (var = smb_stristr(p, VNLCComputerName)) {
sizeTemp = sizeof(temp);
GetComputerName((LPTSTR)temp, &sizeTemp);
_strlwr(temp);
- smb_subst(pathName, var, sizeof(VNLCComputerName),
+ smb_subst(p, var, sizeof(VNLCComputerName),
temp);
}
else break;
}
- *pathNamep = strdup(pathName);
+ *pathNamep = strdup(p);
return 1;
}
static smb_packet_t *GetPacket(void)
{
smb_packet_t *tbp;
+#ifdef DJGPP
+ unsigned int npar, seg, tb_sel;
+#endif
+
lock_ObtainWrite(&smb_globalLock);
tbp = smb_packetFreeListp;
if (tbp) smb_packetFreeListp = tbp->nextp;
lock_ReleaseWrite(&smb_globalLock);
if (!tbp) {
+#ifndef DJGPP
tbp = GlobalAlloc(GMEM_FIXED, 65540);
+#else /* DJGPP */
+ tbp = malloc(sizeof(smb_packet_t));
+#endif /* !DJGPP */
tbp->magic = SMB_PACKETMAGIC;
tbp->ncbp = NULL;
tbp->vcp = NULL;
tbp->oddByte = 0;
tbp->ncb_length = 0;
tbp->flags = 0;
- }
+#ifdef DJGPP
+ npar = SMB_PACKETSIZE >> 4; /* number of paragraphs */
+ {
+ signed int retval =
+ __dpmi_allocate_dos_memory(npar, &tb_sel); /* DOS segment */
+ if (retval == -1) {
+ afsi_log("Cannot allocate %d paragraphs of DOS memory",
+ npar);
+ osi_panic("",__FILE__,__LINE__);
+ }
+ else {
+ afsi_log("Allocated %d paragraphs of DOS mem at 0x%X",
+ npar, retval);
+ seg = retval;
+ }
+ }
+ 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;
smb_packet_t *tbp;
tbp = GetPacket();
memcpy(tbp, pkt, sizeof(smb_packet_t));
- tbp->wctp = tbp->data + (pkt->wctp - pkt->data);
+ tbp->wctp = tbp->data + ((unsigned int)pkt->wctp -
+ (unsigned int)pkt->data);
return tbp;
}
static NCB *GetNCB(void)
{
smb_ncb_t *tbp;
+ NCB *ncbp;
+#ifdef DJGPP
+ unsigned int npar, seg, tb_sel;
+#endif /* DJGPP */
+
lock_ObtainWrite(&smb_globalLock);
tbp = smb_ncbFreeListp;
if (tbp) smb_ncbFreeListp = tbp->nextp;
lock_ReleaseWrite(&smb_globalLock);
if (!tbp) {
+#ifndef DJGPP
tbp = GlobalAlloc(GMEM_FIXED, sizeof(*tbp));
+#else /* DJGPP */
+ tbp = malloc(sizeof(*tbp));
+ npar = (sizeof(NCB)+15) >> 4; /* number of paragraphs */
+ {
+ signed int retval =
+ __dpmi_allocate_dos_memory(npar, &tb_sel); /* DOS segment */
+ if (retval == -1) {
+ afsi_log("Cannot allocate %d paragraphs of DOS mem in GetNCB",
+ npar);
+ osi_panic("",__FILE__,__LINE__);
+ } else {
+ afsi_log("Allocated %d paragraphs of DOS mem at 0x%X in GetNCB",
+ npar, retval);
+ seg = retval;
+ }
+ }
+ tbp->dos_ncb = (seg * 16) + 0; /* DOS physical address */
+ tbp->dos_ncb_sel = tb_sel;
+#endif /* !DJGPP */
tbp->magic = SMB_NCBMAGIC;
}
osi_assert(tbp->magic == SMB_NCBMAGIC);
memset(&tbp->ncb, 0, sizeof(NCB));
- return &tbp->ncb;
+ ncbp = &tbp->ncb;
+#ifdef DJGPP
+ dos_memset(tbp->dos_ncb, 0, sizeof(NCB));
+#endif /* DJGPP */
+ return ncbp;
}
void smb_FreePacket(smb_packet_t *tbp)
parmCount = *smbp->wctp;
if (parm >= parmCount) {
+#ifndef DJGPP
HANDLE h;
char *ptbuf[1];
char s[100];
ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, 1006, NULL,
1, smbp->ncb_length, ptbuf, smbp);
DeregisterEventSource(h);
+#else /* DJGPP */
+ char s[100];
+
+ sprintf(s, "Bad SMB param %d out of %d, ncb len %d",
+ parm, parmCount, smbp->ncb_length);
+ osi_Log0(afsd_logp, s);
+#endif /* !DJGPP */
osi_panic(s, __FILE__, __LINE__);
}
parmDatap = smbp->wctp + (2*parm) + 1;
parmCount = *smbp->wctp;
if (parm * 2 + offset >= parmCount * 2) {
+#ifndef DJGPP
HANDLE h;
char *ptbuf[1];
char s[100];
ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, 1006, NULL,
1, smbp->ncb_length, ptbuf, smbp);
DeregisterEventSource(h);
+#else /* DJGPP */
+ char s[100];
+
+ sprintf(s, "Bad SMB param %d offset %d out of %d, "
+ "ncb len %d",
+ parm, offset, parmCount, smbp->ncb_length);
+ osi_Log0(afsd_logp, s);
+#endif /* !DJGPP */
+
osi_panic(s, __FILE__, __LINE__);
}
parmDatap = smbp->wctp + (2*parm) + 1 + offset;
long code;
unsigned char *tp;
int localNCB = 0;
+#ifdef DJGPP
+ dos_ptr dos_ncb;
+#endif /* DJGPP */
ncbp = inp->ncbp;
if (ncbp == NULL) {
ncbp = GetNCB();
localNCB = 1;
}
+#ifdef DJGPP
+ dos_ncb = ((smb_ncb_t *)ncbp)->dos_ncb;
+#endif /* DJGPP */
+
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 += (inp->wctp - inp->data); /* distance to last wct field */
+ 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 = smb_LANadapter;
ncbp->ncb_command = NCBSEND; /* op means send data */
+#ifndef DJGPP
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;
+
+ /* 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(afsd_logp, "SendPacket failure code %d", code);
class = 1;
error = 18; /* no files in search */
}
+ else if (code == CM_ERROR_RENAME_IDENTICAL) {
+ class = 1;
+ error = 183; /* Samba uses this */
+ }
else {
class = 2;
error = 1;
smb_fid_t *fidp;
long code;
cm_user_t *userp = NULL;
- char *rawBuf;
- NCB *ncbp;
+ NCB *ncbp;
+ int rc;
+#ifndef DJGPP
+ char *rawBuf = NULL;
+#else
+ dos_ptr rawBuf = NULL;
+ dos_ptr dos_ncb;
+#endif /* DJGPP */
rawBuf = NULL;
finalCount = 0;
if (!fidp)
goto send1;
- if (fidp->flags & SMB_FID_IOCTL)
- return smb_IoctlReadRaw(fidp, vcp, inp, outp);
-
- userp = smb_GetUser(vcp, inp);
-
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;
+#else /* DJGPP */
+ smb_RawBufs = _farpeekl(_dos_ds, smb_RawBufs);
+#endif /* !DJGPP */
}
lock_ReleaseMutex(&smb_RawBufLock);
if (!rawBuf)
- goto send;
+ goto send1a;
+
+ if (fidp->flags & SMB_FID_IOCTL)
+ {
+#ifndef DJGPP
+ rc = smb_IoctlReadRaw(fidp, vcp, inp, outp);
+#else
+ rc = smb_IoctlReadRaw(fidp, vcp, inp, outp, rawBuf);
+#endif
+ if (rawBuf) {
+ /* Give back raw buffer */
+ lock_ObtainMutex(&smb_RawBufLock);
+#ifndef DJGPP
+ *((char **) rawBuf) = smb_RawBufs;
+#else /* DJGPP */
+ _farpokel(_dos_ds, rawBuf, smb_RawBufs);
+#endif /* !DJGPP */
+
+ smb_RawBufs = rawBuf;
+ lock_ReleaseMutex(&smb_RawBufLock);
+ }
+ return rc;
+ }
+
+ userp = smb_GetUser(vcp, inp);
+#ifndef DJGPP
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;
send:
+ cm_ReleaseUser(userp);
+send1a:
smb_ReleaseFID(fidp);
- cm_ReleaseUser(userp);
send1:
ncbp = outp->ncbp;
+#ifdef DJGPP
+ dos_ncb = ((smb_ncb_t *)ncbp)->dos_ncb;
+#endif /* DJGPP */
memset((char *)ncbp, 0, sizeof(NCB));
ncbp->ncb_length = (unsigned short) finalCount;
ncbp->ncb_command = NCBSEND;
ncbp->ncb_buffer = rawBuf;
+#ifndef DJGPP
code = Netbios(ncbp);
+#else /* DJGPP */
+ code = Netbios(ncbp, dos_ncb);
+#endif /* !DJGPP */
if (code != 0)
osi_Log1(afsd_logp, "ReadRaw send failure code %d", code);
if (rawBuf) {
/* Give back raw buffer */
lock_ObtainMutex(&smb_RawBufLock);
+#ifndef DJGPP
*((char **) rawBuf) = smb_RawBufs;
+#else /* DJGPP */
+ _farpokel(_dos_ds, rawBuf, smb_RawBufs);
+#endif /* !DJGPP */
+
smb_RawBufs = rawBuf;
lock_ReleaseMutex(&smb_RawBufLock);
}
int NTProtoIndex;
int protoIndex; /* index we're using */
int namex;
- long dbytes;
+ int dbytes;
int entryLength;
int tcounter;
char protocol_array[10][1024]; /* protocol signature of the client */
while(1) {
count++;
- Sleep(10000);
+ thrd_Sleep(10000);
if ((count % 360) == 0) /* every hour */
smb_CalculateNowTZ();
/* XXX GC dir search entries */
nwL = smb_allWaitingLocks;
if (nwL == NULL) {
osi_SleepW((long)&smb_allWaitingLocks, &smb_globalLock);
- Sleep(1000);
+ thrd_Sleep(1000);
continue;
}
else first = 1;
FreeNCB(ncbp);
free(wL);
} while (nwL);
- Sleep(1000);
+ thrd_Sleep(1000);
}
}
/* pull pathname and stat block out of request */
tp = smb_GetSMBData(inp, NULL);
- pathp = smb_ParseASCIIBlock(tp, &tp);
+ pathp = smb_ParseASCIIBlock(tp, (char **) &tp);
osi_assert(pathp != NULL);
- statBlockp = smb_ParseVblBlock(tp, &tp, &statLen);
+ statBlockp = smb_ParseVblBlock(tp, (char **) &tp, &statLen);
osi_assert(statBlockp != NULL);
if (statLen == 0) {
statBlockp = initStatBlock;
int maxCount;
smb_dirListPatch_t *dirListPatchesp;
smb_dirListPatch_t *curPatchp;
- long dataLength;
+ int dataLength;
cm_buf_t *bufferp;
long temp;
osi_hyper_t dirLength;
int caseFold;
char *tidPathp;
cm_req_t req;
+ cm_fid_t fid;
+ int fileType;
cm_InitReq(&req);
/* 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 */
+ if (!(dsp->attribute & 0x10)) /* 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(afsd_logp, "smb_ReceiveCoreSearchDir: file %s "
+ "has filetype %d", 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 */
int any;
} smb_unlinkRock_t;
-long smb_UnlinkProc(cm_scache_t *dscp, cm_dirEntry_t *dep, void *vrockp, osi_hyper_t *offp)
+int smb_UnlinkProc(cm_scache_t *dscp, cm_dirEntry_t *dep, void *vrockp, osi_hyper_t *offp)
{
long code;
smb_unlinkRock_t *rockp;
char *newNamep; /* ptr to the new file's name */
} smb_renameRock_t;
-long smb_RenameProc(cm_scache_t *dscp, cm_dirEntry_t *dep, void *vrockp, osi_hyper_t *offp)
+int smb_RenameProc(cm_scache_t *dscp, cm_dirEntry_t *dep, void *vrockp, osi_hyper_t *offp)
{
long code;
smb_renameRock_t *rockp;
int any;
} smb_rmdirRock_t;
-long smb_RmdirProc(cm_scache_t *dscp, cm_dirEntry_t *dep, void *vrockp, osi_hyper_t *offp)
+int smb_RmdirProc(cm_scache_t *dscp, cm_dirEntry_t *dep, void *vrockp, osi_hyper_t *offp)
{
long code;
smb_rmdirRock_t *rockp;
char *fullName;
};
-long smb_FullNameProc(cm_scache_t *scp, cm_dirEntry_t *dep, void *rockp,
+int smb_FullNameProc(cm_scache_t *scp, cm_dirEntry_t *dep, void *rockp,
osi_hyper_t *offp)
{
char shortName[13];
/* Don't jump the gun on an async raw write */
while (fidp->raw_writers) {
lock_ReleaseMutex(&fidp->mx);
- WaitForSingleObject(fidp->raw_write_event, RAWTIMEOUT);
+ thrd_WaitForSingleObject_Event(fidp->raw_write_event, RAWTIMEOUT);
lock_ObtainMutex(&fidp->mx);
}
/*
* smb_ReadData -- common code for Read, Read And X, and Raw Read
*/
+#ifndef DJGPP
long smb_ReadData(smb_fid_t *fidp, osi_hyper_t *offsetp, long count, char *op,
cm_user_t *userp, long *readp)
+#else /* DJGPP */
+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;
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
+#endif /* DJGPP */
memcpy(op, bufferp->datap + bufIndex, nbytes);
/* adjust counters, pointers, etc. */
/*
* smb_WriteData -- common code for Write and Raw Write
*/
+#ifndef DJGPP
long smb_WriteData(smb_fid_t *fidp, osi_hyper_t *offsetp, long count, char *op,
cm_user_t *userp, long *writtenp)
+#else /* DJGPP */
+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;
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
+#endif /* DJGPP */
memcpy(bufferp->datap + bufIndex, op, nbytes);
buf_SetDirty(bufferp);
cm_user_t *userp;
cm_attr_t truncAttr; /* attribute struct used for truncating file */
char *op;
- long inDataBlockCount;
+ int inDataBlockCount;
fd = smb_GetSMBParm(inp, 0);
count = smb_GetSMBParm(inp, 1);
fidp->scp->clientModTime = time(NULL);
}
+#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;
unsigned short fd;
smb_fid_t *fidp;
cm_user_t *userp;
+#ifndef DJGPP
char *rawBuf;
- int written = 0;
+#else /* DJGPP */
+ dos_ptr rawBuf;
+#endif /* !DJGPP */
+ long written = 0;
long code;
fd = smb_GetSMBParm(inp, 0);
userp = smb_GetUser(vcp, inp);
+#ifndef DJGPP
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,
+ (unsigned char *) rawBuf, userp,
+ &written, TRUE);
+#endif /* !DJGPP */
if (rwcp->writeMode & 0x1) { /* synchronous */
smb_t *op;
lock_ObtainMutex(&fidp->mx);
fidp->raw_writers--;
if (fidp->raw_writers == 0)
- SetEvent(fidp->raw_write_event);
+ thrd_SetEvent(fidp->raw_write_event);
lock_ReleaseMutex(&fidp->mx);
}
/* Give back raw buffer */
lock_ObtainMutex(&smb_RawBufLock);
+#ifndef DJGPP
*((char **)rawBuf) = smb_RawBufs;
+#else /* DJGPP */
+ _farpokel(_dos_ds, rawBuf, smb_RawBufs);
+#endif /* !DJGPP */
smb_RawBufs = rawBuf;
lock_ReleaseMutex(&smb_RawBufLock);
cm_user_t *userp;
char *op;
unsigned short writeMode;
+#ifndef DJGPP
char *rawBuf;
+#else /* DJGPP */
+ dos_ptr rawBuf;
+#endif /* !DJGPP */
fd = smb_GetSMBParm(inp, 0);
totalCount = smb_GetSMBParm(inp, 1);
fidp->scp->clientModTime = time(NULL);
}
+#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 (smb_RawBufs) {
/* Get a raw buf, from head of list */
rawBuf = smb_RawBufs;
+#ifndef DJGPP
smb_RawBufs = *(char **)smb_RawBufs;
+#else /* DJGPP */
+ smb_RawBufs = _farpeekl(_dos_ds, smb_RawBufs);
+#endif /* !DJGPP */
}
else
code = CM_ERROR_USESTD;
if (code == 0 && (writeMode & 1) == 0) {
lock_ObtainMutex(&fidp->mx);
fidp->raw_writers++;
- ResetEvent(fidp->raw_write_event);
+ thrd_ResetEvent(fidp->raw_write_event);
lock_ReleaseMutex(&fidp->mx);
}
*op++ = (unsigned char) (count & 0xff);
*op++ = (unsigned char) ((count >> 8) & 0xff);
+#ifndef DJGPP
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);
/* 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];
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;
}
/* We are an ongoing op */
- InterlockedIncrement(&ongoingOps);
+ thrd_Increment(&ongoingOps);
/* set up response packet for receiving output */
if (!(outp->flags & SMB_PACKETFLAG_SUSPENDED))
code = (*(dp->procp)) (vcp, inp, outp);
if (oldGen != sessionGen) {
+#ifndef DJGPP
HANDLE h;
char *ptbuf[1];
char s[100];
ReportEvent(h, EVENTLOG_WARNING_TYPE, 0,
1005, NULL, 1, ncbp->ncb_length, ptbuf, smbp);
DeregisterEventSource(h);
+#else /* DJGPP */
+ osi_Log1(afsd_logp, "Pkt straddled session startup, "
+ "ncb length %d", ncbp->ncb_length);
+#endif /* !DJGPP */
}
}
else {
/* bad opcode, fail the request, after displaying it */
+#ifndef DJGPP
if (showErrors) {
sprintf(tbuffer, "Received bad SMB req 0x%x", inp->inCom);
code = (*smb_MBfunc)(NULL, tbuffer, "Cancel: don't show again",
MB_OKCANCEL);
if (code == IDCANCEL) showErrors = 0;
}
+#endif /* DJGPP */
code = CM_ERROR_BADOP;
}
/* catastrophic failure: log as much as possible */
if (code == CM_ERROR_BADSMB) {
+#ifndef DJGPP
HANDLE h;
char *ptbuf[1];
char s[100];
ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, 1002, NULL,
1, ncbp->ncb_length, ptbuf, smbp);
DeregisterEventSource(h);
+#else /* DJGPP */
+ osi_Log1(afsd_logp, "Invalid SMB message, length %d",
+ ncbp->ncb_length);
+#endif /* !DJGPP */
code = CM_ERROR_INVAL;
}
if (outp->flags & SMB_PACKETFLAG_NOSEND) {
- InterlockedDecrement(&ongoingOps);
+ thrd_Decrement(&ongoingOps);
return;
}
/* tp now points to the new output record; go back and patch the
* second parameter (off2) to point to the new record.
*/
- temp = tp - ((char *) 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 */
/* now send the output packet, and return */
if (!noSend)
smb_SendPacket(vcp, outp);
- InterlockedDecrement(&ongoingOps);
+ thrd_Decrement(&ongoingOps);
if (!(vcp->flags & SMB_VCFLAG_ALREADYDEAD)) {
active_vcp = vcp;
return;
}
+#ifndef DJGPP
/* Wait for Netbios() calls to return, and make the results available to server
* threads. Note that server threads can't wait on the NCBevents array
* themselves, because NCB events are manual-reset, and the servers would race
DWORD code, idx;
while (1) {
- code = WaitForMultipleObjects(numNCBs, NCBevents,
+ code = thrd_WaitForMultipleObjects_Event(numNCBs, NCBevents,
FALSE, INFINITE);
if (code == WAIT_OBJECT_0)
continue;
idx = code - WAIT_OBJECT_0;
- ResetEvent(NCBevents[idx]);
- SetEvent(NCBreturns[0][idx]);
+ thrd_ResetEvent(NCBevents[idx]);
+ thrd_SetEvent(NCBreturns[0][idx]);
}
}
+#endif /* !DJGPP */
/*
* Try to have one NCBRECV request waiting for every live session. Not more
{
DWORD code, idx_session, idx_NCB;
NCB *ncbp;
+#ifdef DJGPP
+ dos_ptr dos_ncb;
+#endif /* DJGPP */
while (1) {
/* Get a session */
- code = WaitForMultipleObjects(numSessions, SessionEvents,
- FALSE, INFINITE);
+ code = thrd_WaitForMultipleObjects_Event(numSessions, SessionEvents,
+ FALSE, INFINITE);
if (code == WAIT_OBJECT_0)
continue;
idx_session = code - WAIT_OBJECT_0;
/* Get an NCB */
NCBretry:
- code = WaitForMultipleObjects(numNCBs, NCBavails,
- FALSE, INFINITE);
+ code = thrd_WaitForMultipleObjects_Event(numNCBs, NCBavails,
+ FALSE, INFINITE);
if (code == WAIT_OBJECT_0)
goto NCBretry;
idx_NCB = code - WAIT_OBJECT_0;
/* 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 = smb_LANadapter;
+#ifndef DJGPP
ncbp->ncb_buffer = (unsigned char *) bufs[idx_NCB];
- ncbp->ncb_length = SMB_PACKETSIZE;
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);
+#endif /* !DJGPP */
}
}
UCHAR rc;
smb_vc_t *vcp;
smb_t *smbp;
+#ifdef DJGPP
+ dos_ptr dos_ncb;
+#endif /* DJGPP */
outncbp = GetNCB();
outbufp = GetPacket();
(*smb_MBfunc)(NULL, "AFS demo expiration",
"afsd dispatcher",
MB_OK|MB_ICONSTOP|MB_SETFOREGROUND);
- ExitThread(1);
+ trhd_Exit(1);
}
}
#endif /* !NOEXPIRE */
- code = WaitForMultipleObjects(numNCBs, NCBreturns[myIdx],
- FALSE, INFINITE);
+ code = thrd_WaitForMultipleObjects_Event(numNCBs, NCBreturns[myIdx],
+ FALSE, INFINITE);
if (code == WAIT_OBJECT_0)
continue;
idx_NCB = code - WAIT_OBJECT_0;
ncbp = NCBs[idx_NCB];
+#ifdef DJGPP
+ dos_ncb = ((smb_ncb_t *)ncbp)->dos_ncb;
+#endif /* DJGPP */
idx_session = NCBsessions[idx_NCB];
rc = ncbp->ncb_retcode;
case NRC_INCOMP:
/* Treat as transient error */
{
- HANDLE h;
+#ifndef DJGPP
+ EVENT_HANDLE h;
char *ptbuf[1];
char s[100];
ncbp->ncb_length, ptbuf,
bufp);
DeregisterEventSource(h);
+#else /* 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);
+#endif /* !DJGPP */
+
/*
* We used to discard the packet.
* Instead, try handling it normally.
if (vcp->errorCount++ > 3)
dead_sessions[idx_session] = TRUE;
else {
- Sleep(1000);
- SetEvent(SessionEvents[idx_session]);
+ thrd_Sleep(1000);
+ thrd_SetEvent(SessionEvents[idx_session]);
}
continue;
}
vcp = smb_FindVC(ncbp->ncb_lsn, 0);
vcp->errorCount = 0;
bufp = (struct smb_packet *) ncbp->ncb_buffer;
+#ifdef DJGPP
+ 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",
+ bufp->dos_pkt / 16, bufp);*/
+ fflush(stderr);
+ dosmemget(bufp->dos_pkt, ncbp->ncb_length, bufp->data);
+#endif /* DJGPP */
smbp = (smb_t *)bufp->data;
outbufp->flags = 0;
if (smbp->com == 0x1d) {
/* Special handling for Write Raw */
raw_write_cont_t rwc;
- HANDLE rwevent;
+ EVENT_HANDLE rwevent;
smb_DispatchPacket(vcp, bufp, outbufp, ncbp, &rwc);
if (rwc.code == 0) {
- rwevent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ rwevent = thrd_CreateEvent(NULL, FALSE, FALSE, NULL);
ncbp->ncb_command = NCBRECV | ASYNCH;
ncbp->ncb_lsn = (unsigned char) vcp->lsn;
ncbp->ncb_lana_num = smb_LANadapter;
ncbp->ncb_buffer = rwc.buf;
ncbp->ncb_length = 65535;
ncbp->ncb_event = rwevent;
+#ifndef DJGPP
Netbios(ncbp);
- rcode = WaitForSingleObject(rwevent,
- RAWTIMEOUT);
- CloseHandle(rwevent);
+#else
+ Netbios(ncbp, dos_ncb);
+#endif /* !DJGPP */
+ rcode = thrd_WaitForSingleObject_Event(rwevent,
+ RAWTIMEOUT);
+ thrd_CloseHandle(rwevent);
}
- SetEvent(SessionEvents[idx_session]);
+ thrd_SetEvent(SessionEvents[idx_session]);
if (rwc.code == 0)
smb_CompleteWriteRaw(vcp, bufp, outbufp, ncbp,
&rwc);
* (defect 11626)
*/
smb_DispatchPacket(vcp, bufp, outbufp, ncbp, NULL);
- SetEvent(SessionEvents[idx_session]);
+ thrd_SetEvent(SessionEvents[idx_session]);
} else {
- SetEvent(SessionEvents[idx_session]);
+ thrd_SetEvent(SessionEvents[idx_session]);
smb_DispatchPacket(vcp, bufp, outbufp, ncbp, NULL);
}
smb_concurrentCalls--;
doneWithNCB:
- SetEvent(NCBavails[idx_NCB]);
+ thrd_SetEvent(NCBavails[idx_NCB]);
}
}
void InitNCBslot(int idx)
{
struct smb_packet *bufp;
- HANDLE retHandle;
+ EVENT_HANDLE retHandle;
int i;
NCBs[idx] = GetNCB();
- NCBavails[idx] = CreateEvent(NULL, FALSE, TRUE, NULL);
- NCBevents[idx] = CreateEvent(NULL, TRUE, FALSE, NULL);
- retHandle = CreateEvent(NULL, FALSE, FALSE, NULL);
+ NCBavails[idx] = thrd_CreateEvent(NULL, FALSE, TRUE, NULL);
+#ifndef DJGPP
+ NCBevents[idx] = thrd_CreateEvent(NULL, TRUE, FALSE, NULL);
+#endif /* !DJGPP */
+ retHandle = thrd_CreateEvent(NULL, FALSE, FALSE, NULL);
for (i=0; i<smb_NumServerThreads; i++)
NCBreturns[i][idx] = retHandle;
bufp = GetPacket();
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 */
ncbp = GetNCB();
+#ifdef DJGPP
+ dos_ncb = ((smb_ncb_t *)ncbp)->dos_ncb;
+#endif /* DJGPP */
while (1) {
+#ifdef DJGPP
+ /* terminate if shutdown flag is set */
+ if (smbShutdownFlag == 1)
+ thrd_Exit(1);
+#endif /* DJGPP */
+
#ifndef NOEXPIRE
/* check for demo expiration */
{
ncbp->ncb_lana_num = smb_LANadapter;
+#ifndef DJGPP
code = Netbios(ncbp);
+#else /* DJGPP */
+ code = Netbios(ncbp, dos_ncb);
+
+ if (code != 0)
+ {
+ fprintf(stderr, "NCBLISTEN lana=%d (smb_LANadapter=%d) "
+ "failed with code %d\n",
+ ncbp->ncb_lana_num, smb_LANadapter, code);
+ osi_Log3(0, "NCBLISTEN lana=%d (smb_LANadapter=%d) "
+ "failed with code %d",
+ ncbp->ncb_lana_num, smb_LANadapter, code);
+ 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);
+ }
+#endif /* !DJGPP */
osi_assert(code == 0);
/* check for remote conns */
/* Log session startup */
if (reportSessionStartups) {
+#ifndef DJGPP
HANDLE h;
char *ptbuf[1];
char s[100];
ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, 1004, NULL,
1, 0, ptbuf, NULL);
DeregisterEventSource(h);
+#else /* DJGPP */
+ afsi_log("NCBLISTEN completed, call from %s",rname);
+ osi_Log1(afsd_logp, "SMB session startup, %d ongoing o
+ps",
+ ongoingOps);
+ time(&now);
+ fprintf(stderr, "%s: New session starting from host %s
+\n",
+ asctime(localtime(&now)), rname);
+ fflush(stderr);
+#endif /* !DJGPP */
}
/* now ncbp->ncb_lsn is the connection ID */
/* Add new NCB for new session */
InitNCBslot(numNCBs);
numNCBs++;
- SetEvent(NCBavails[0]);
- SetEvent(NCBevents[0]);
+ thrd_SetEvent(NCBavails[0]);
+ thrd_SetEvent(NCBevents[0]);
for (j = 0; j < smb_NumServerThreads; j++)
- SetEvent(NCBreturns[j][0]);
+ thrd_SetEvent(NCBreturns[j][0]);
/* Also add new session event */
- SessionEvents[i] = CreateEvent(NULL, FALSE, TRUE, NULL);
+ SessionEvents[i] = thrd_CreateEvent(NULL, FALSE, TRUE, NULL);
numSessions++;
- SetEvent(SessionEvents[0]);
+ thrd_SetEvent(SessionEvents[0]);
} else {
- SetEvent(SessionEvents[i]);
+ thrd_SetEvent(SessionEvents[i]);
}
} /* dispatch while loop */
}
+/* initialize Netbios */
+void smb_NetbiosInit()
+{
+ NCB *ncbp;
+#ifdef DJGPP
+ dos_ptr dos_ncb;
+#endif /* DJGPP */
+ int i, lana, code;
+ char s[100];
+ int delname_tried=0;
+ int len;
+
+ /* setup the NCB system */
+ ncbp = GetNCB();
+#ifdef DJGPP
+ dos_ncb = ((smb_ncb_t *)ncbp)->dos_ncb;
+#endif /* DJGPP */
+
+#ifndef DJGPP
+ /* reset the adaptor: in Win32, this is required for every process, and
+ * acts as an init call, not as a real hardware reset.
+ */
+ ncbp->ncb_command = NCBRESET;
+ ncbp->ncb_callname[0] = 100;
+ ncbp->ncb_callname[2] = 100;
+ ncbp->ncb_lana_num = smb_LANadapter;
+ code = Netbios(ncbp);
+ if (code == 0) code = ncbp->ncb_retcode;
+ if (code != 0) {
+ sprintf(s, "Netbios NCBRESET error code %d", code);
+ afsi_log(s);
+ osi_panic(s, __FILE__, __LINE__);
+ }
+#endif /* !DJGPP */
+
+ try_addname:
+ /* and declare our name so we can receive connections */
+ memset(ncbp, 0, sizeof(*ncbp));
+ ncbp->ncb_lana_num = smb_LANadapter;
+ ncbp->ncb_command = NCBADDNAME;
+ strcpy(ncbp->ncb_name, smb_localNamep);
+ len = strlen(smb_localNamep);
+ for(i=len; i<NCBNAMSZ; i++) ncbp->ncb_name[i] = ' ';
+ /* Keep the name so we can unregister it later */
+ memcpy(smb_sharename,ncbp->ncb_name,NCBNAMSZ);
+ lana = smb_LANadapter;
+
+ do { /* try multiple LANA numbers until we find one that works */
+ ncbp->ncb_lana_num = lana;
+#ifndef DJGPP
+ code = Netbios(ncbp);
+#else /* DJGPP */
+ code = Netbios(ncbp, dos_ncb);
+#endif /* !DJGPP */
+
+ afsi_log("Netbios NCBADDNAME code=%d retcode=%d complete=%d",code,
+ ncbp->ncb_retcode,ncbp->ncb_cmd_cplt);
+ {
+ char name[200];
+ int i;
+ for (i=0;i<NCBNAMSZ;++i)
+ name[i] = ncbp->ncb_name[i];
+ name[i] = '\0';
+ afsi_log("Netbios NCBADDNAME added new name >%s<",name);
+ }
+
+ if (code == 0)
+ {
+ code = ncbp->ncb_retcode;
+ smb_LANadapter = lana; /* correct LANA number */
+ break;
+ }
+ else
+ {
+ sprintf(s, "Netbios NCBADDNAME lana %d error code %d", lana, code);
+ afsi_log(s);
+ if (code != NRC_BRIDGE) /* invalid LANA num */
+ break;
+ else
+ lana = (lana + 1) % 8;
+ }
+ } while (lana != smb_LANadapter); /* quit when we loop back to orig. */
+
+ if (code == NRC_DUPNAME)
+ {
+ /* Name already exists; try to delete it */
+ memset(ncbp, 0, sizeof(*ncbp));
+ ncbp->ncb_command = NCBDELNAME;
+ memcpy(ncbp->ncb_name,smb_sharename,NCBNAMSZ);
+ ncbp->ncb_lana_num = smb_LANadapter;
+#ifndef DJGPP
+ code = Netbios(ncbp);
+#else
+ code = Netbios(ncbp, dos_ncb);
+#endif /* DJGPP */
+ if (code == 0) code = ncbp->ncb_retcode;
+ if (code != 0) {
+ fprintf(stderr, "Netbios NCBDELNAME error code %d", code);
+ }
+ fflush(stderr);
+ if (code == 0 && !delname_tried)
+ {
+ delname_tried = 1;
+ goto try_addname;
+ }
+ }
+
+ if (code != 0)
+ osi_panic(s, __FILE__, __LINE__);
+
+ fprintf(stderr, "Using LAN Adapter %d\n", smb_LANadapter, code);
+ afsi_log("Netbios NCBADDNAME lana=%d name number=%d", smb_LANadapter,
+ ncbp->ncb_num);
+
+ /* we're done with the NCB now */
+ FreeNCB(ncbp);
+}
+
void smb_Init(osi_log_t *logp, char *snamep, int useV3, int LANadapt,
- int nThreads, void *aMBfunc)
+ int nThreads
+#ifndef DJGPP
+ , void *aMBfunc
+#endif
+ )
+
{
- HANDLE phandle;
- long lpid;
+ thread_t phandle;
+ int lpid;
int i;
long code;
int len;
NCB *ncbp;
struct tm myTime;
char s[100];
+#ifdef DJGPP
+ int npar, seg, sel;
+ dos_ptr rawBuf;
+#endif /* DJGPP */
+#ifndef DJGPP
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);
exit(1);
+#else /* DJGPP */
+ fprintf(stderr, "AFS demo expiration\n");
+ afs_exit(0);
+#endif /* !DJGPP */
}
}
#endif /* !NOEXPIRE */
lock_InitializeMutex(&smb_RawBufLock, "smb raw buffer lock");
/* 4 Raw I/O buffers */
+#ifndef DJGPP
smb_RawBufs = GlobalAlloc(GMEM_FIXED, 65536);
*((char **)smb_RawBufs) = NULL;
for (i=0; i<3; i++) {
*((char **)rawBuf) = smb_RawBufs;
smb_RawBufs = rawBuf;
}
+#else /* DJGPP */
+ npar = 65536 >> 4; /* number of paragraphs */
+ seg = __dpmi_allocate_dos_memory(npar, &smb_RawBufSel[0]);
+ if (seg == -1) {
+ afsi_log("Cannot allocate %d paragraphs of DOS memory",
+ npar);
+ osi_panic("",__FILE__,__LINE__);
+ }
+ else {
+ afsi_log("Allocated %d paragraphs of DOS mem at 0x%X",
+ npar, seg);
+ }
+ smb_RawBufs = (seg * 16) + 0; /* DOS physical address */
+
+ _farpokel(_dos_ds, smb_RawBufs, NULL);
+ for (i=0; i<SMB_RAW_BUFS-1; i++) {
+ npar = 65536 >> 4; /* number of paragraphs */
+ seg = __dpmi_allocate_dos_memory(npar, &smb_RawBufSel[i+1]);
+ if (seg == -1) {
+ afsi_log("Cannot allocate %d paragraphs of DOS memory",
+ npar);
+ osi_panic("",__FILE__,__LINE__);
+ }
+ else {
+ afsi_log("Allocated %d paragraphs of DOS mem at 0x%X",
+ npar, seg);
+ }
+ rawBuf = (seg * 16) + 0; /* DOS physical address */
+ /*_farpokel(_dos_ds, smb_RawBufs, smb_RawBufs);*/
+ _farpokel(_dos_ds, rawBuf, smb_RawBufs);
+ smb_RawBufs = rawBuf;
+ }
+#endif /* !DJGPP */
/* global free lists */
smb_ncbFreeListp = NULL;
smb_packetFreeListp = NULL;
- /* setup the NCB system */
- ncbp = GetNCB();
-
- /* reset the adaptor: in Win32, this is required for every process, and
- * acts as an init call, not as a real hardware reset.
- */
- ncbp->ncb_command = NCBRESET;
- ncbp->ncb_callname[0] = 100;
- ncbp->ncb_callname[2] = 100;
- ncbp->ncb_lana_num = smb_LANadapter;
- code = Netbios(ncbp);
- if (code == 0) code = ncbp->ncb_retcode;
- if (code != 0) {
- sprintf(s, "Netbios NCBRESET error code %d", code);
- afsi_log(s);
- osi_panic(s, __FILE__, __LINE__);
- }
-
- /* and declare our name so we can receive connections */
- memset(ncbp, 0, sizeof(*ncbp));
- ncbp->ncb_lana_num = smb_LANadapter;
- ncbp->ncb_command = NCBADDNAME;
- strncpy(ncbp->ncb_name, snamep, len);
- for(i=len; i<NCBNAMSZ; i++) ncbp->ncb_name[i] = ' ';
- code = Netbios(ncbp);
- if (code == 0) {
- code = ncbp->ncb_retcode;
- }
- if (code != 0) {
- afsi_log("Netbios NCBADDNAME error code %d", code);
- }
-
- /* we're done with the NCB now */
- FreeNCB(ncbp);
+ smb_NetbiosInit();
/* Initialize listener and server structures */
memset(dead_sessions, 0, sizeof(dead_sessions));
- SessionEvents[0] = CreateEvent(NULL, FALSE, FALSE, NULL);
+ SessionEvents[0] = thrd_CreateEvent(NULL, FALSE, FALSE, NULL);
numSessions = 1;
smb_NumServerThreads = nThreads;
- NCBavails[0] = CreateEvent(NULL, FALSE, FALSE, NULL);
- NCBevents[0] = CreateEvent(NULL, FALSE, FALSE, NULL);
- NCBreturns = malloc(nThreads * sizeof(HANDLE *));
+ NCBavails[0] = thrd_CreateEvent(NULL, FALSE, FALSE, NULL);
+ NCBevents[0] = thrd_CreateEvent(NULL, FALSE, FALSE, NULL);
+ NCBreturns = malloc(nThreads * sizeof(EVENT_HANDLE *));
for (i = 0; i < nThreads; i++) {
- NCBreturns[i] = malloc(NCBmax * sizeof(HANDLE));
- NCBreturns[i][0] = CreateEvent(NULL, FALSE, FALSE, NULL);
+ NCBreturns[i] = malloc(NCBmax * sizeof(EVENT_HANDLE));
+ NCBreturns[i][0] = thrd_CreateEvent(NULL, FALSE, FALSE, NULL);
}
for (i = 1; i <= nThreads; i++)
InitNCBslot(i);
/* Start listeners, waiters, servers, and daemons */
- phandle = CreateThread(NULL, 65536, (LPTHREAD_START_ROUTINE) smb_Listener,
- NULL, 0, &lpid);
+ phandle = thrd_Create(NULL, 65536, (ThreadFunc) smb_Listener,
+ NULL, 0, &lpid, "smb_Listener");
osi_assert(phandle != NULL);
- CloseHandle(phandle);
+ thrd_CloseHandle(phandle);
- phandle = CreateThread(NULL, 65536, (LPTHREAD_START_ROUTINE) smb_ClientWaiter,
- NULL, 0, &lpid);
+#ifndef DJGPP
+ phandle = thrd_Create(NULL, 65536, (ThreadFunc) smb_ClientWaiter,
+ NULL, 0, &lpid, "smb_ClientWaiter");
osi_assert(phandle != NULL);
- CloseHandle(phandle);
+ thrd_CloseHandle(phandle);
+#endif /* !DJGPP */
- phandle = CreateThread(NULL, 65536, (LPTHREAD_START_ROUTINE) smb_ServerWaiter,
- NULL, 0, &lpid);
+ phandle = thrd_Create(NULL, 65536, (ThreadFunc) smb_ServerWaiter,
+ NULL, 0, &lpid, "smb_ServerWaiter");
osi_assert(phandle != NULL);
- CloseHandle(phandle);
+ thrd_CloseHandle(phandle);
for (i=0; i<nThreads; i++) {
- phandle = CreateThread(NULL, 65536,
- (LPTHREAD_START_ROUTINE) smb_Server,
- (void *) i, 0, &lpid);
+ phandle = thrd_Create(NULL, 65536,
+ (ThreadFunc) smb_Server,
+ (void *) i, 0, &lpid, "smb_Server");
osi_assert(phandle != NULL);
- CloseHandle(phandle);
+ thrd_CloseHandle(phandle);
}
- phandle = CreateThread(NULL, 65536, (LPTHREAD_START_ROUTINE) smb_Daemon,
- NULL, 0, &lpid);
+ phandle = thrd_Create(NULL, 65536, (ThreadFunc) smb_Daemon,
+ NULL, 0, &lpid, "smb_Daemon");
osi_assert(phandle != NULL);
- CloseHandle(phandle);
+ thrd_CloseHandle(phandle);
- phandle = CreateThread(NULL, 65536,
- (LPTHREAD_START_ROUTINE) smb_WaitingLocksDaemon,
- NULL, 0, &lpid);
+ phandle = thrd_Create(NULL, 65536,
+ (ThreadFunc) smb_WaitingLocksDaemon,
+ NULL, 0, &lpid, "smb_WaitingLocksDaemon");
osi_assert(phandle != NULL);
- CloseHandle(phandle);
+ thrd_CloseHandle(phandle);
+
+#ifdef DJGPP
+ smb_ListShares();
+#endif
return;
}
+
+#ifdef DJGPP
+void smb_Shutdown(void)
+{
+ NCB *ncbp;
+ dos_ptr dos_ncb;
+ long code;
+ int i;
+
+ /*fprintf(stderr, "Entering smb_Shutdown\n");*/
+
+ /* setup the NCB system */
+ ncbp = GetNCB();
+ dos_ncb = ((smb_ncb_t *)ncbp)->dos_ncb;
+
+ /* Block new sessions by setting shutdown flag */
+ /*smbShutdownFlag = 1;*/
+
+ /* Hang up all sessions */
+ for (i = 1; i < numSessions; i++)
+ {
+ if (dead_sessions[i])
+ continue;
+
+ /*fprintf(stderr, "NCBHANGUP session %d LSN %d\n", i, LSNs[i]);*/
+ ncbp->ncb_command = NCBHANGUP;
+ ncbp->ncb_lana_num = smb_LANadapter;
+ ncbp->ncb_lsn = LSNs[i];
+ code = Netbios(ncbp, dos_ncb);
+ /*fprintf(stderr, "returned from NCBHANGUP session %d LSN %d\n", i, LS
+ Ns[i]);*/
+ if (code == 0) code = ncbp->ncb_retcode;
+ if (code != 0) {
+ fprintf(stderr, "Session %d Netbios NCBHANGUP error code %d", i, code);
+ }
+ }
+
+ /* Delete Netbios name */
+ ncbp->ncb_command = NCBDELNAME;
+ memcpy(ncbp->ncb_name,smb_sharename,NCBNAMSZ);
+ ncbp->ncb_lana_num = smb_LANadapter;
+ code = Netbios(ncbp, dos_ncb);
+ if (code == 0) code = ncbp->ncb_retcode;
+ if (code != 0) {
+ fprintf(stderr, "Netbios NCBDELNAME error code %d", code);
+ }
+ fflush(stderr);
+}
+#endif /* DJGPP */
#ifndef __SMB_H_ENV__
#define __SMB_H_ENV__ 1
+#ifdef DJGPP
+#include "netbios95.h"
+#endif /* DJGPP */
+
/* basic core protocol SMB structure */
typedef struct smb {
unsigned char id[4];
unsigned char oddByte;
unsigned short ncb_length;
unsigned char flags;
+#ifdef DJGPP
+ dos_ptr dos_pkt;
+ unsigned int dos_pkt_sel;
+#endif /* DJGPP */
} smb_packet_t;
/* smb_packet flags */
NCB ncb; /* ncb to use */
struct myncb *nextp; /* when on free list */
long magic;
+#ifdef DJGPP
+ dos_ptr dos_ncb;
+ smb_packet_t *orig_pkt;
+ unsigned int dos_ncb_sel;
+#endif /* DJGPP */
} smb_ncb_t;
/* structures representing environments from kernel / SMB network.
int curr_chunk; /* chunk being read */
int prev_chunk; /* previous chunk read */
int raw_writers; /* pending async raw writes */
- HANDLE raw_write_event; /* signal this when raw_writers zero */
+ EVENT_HANDLE raw_write_event; /* signal this when raw_writers zero */
} smb_fid_t;
#define SMB_FID_OPENREAD 1 /* open for reading */
* the response was already
* sent.
*/
+#define SMB_MAX_PATH 256 /* max path length */
/* prototypes */
extern void smb_Init(osi_log_t *logp, char *smbNamep, int useV3, int LANadapt,
- int nThreads, void *aMBfunc);
+ int nThreads
+#ifndef DJGPP
+ , void *aMBfunc
+#endif
+ );
extern void smb_LargeSearchTimeFromUnixTime(FILETIME *largeTimep, long unixTime);
extern int smb_SUser(cm_user_t *userp);
+#ifndef DJGPP
extern long smb_ReadData(smb_fid_t *fidp, osi_hyper_t *offsetp, long count,
char *op, cm_user_t *userp, long *readp);
+#else /* DJGPP */
+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 BOOL smb_IsLegalFilename(char *filename);