Index: openafs/src/NTMake9x
diff -c openafs/src/NTMake9x:1.4.2.1 openafs/src/NTMake9x:1.4.2.3
*** openafs/src/NTMake9x:1.4.2.1	Sat Oct 13 00:19:06 2001
--- openafs/src/NTMake9x	Sun Jan 20 04:09:08 2002
***************
*** 22,27 ****
--- 22,28 ----
  NTMAKELANG = nmake /nologo /f ntmakefile en_install
  NTMAKE_HEADERS = nmake /nologo /f ntmakefile install_headers
  NTMAKE_LIBUTILS = nmake /nologo /f ntmakefile install_libutils
+ NTMAKE_OBJS = nmake /nologo /f ntmakefile install_objs
  MKDIR = mkdir
  OBJ = src
  
***************
*** 41,47 ****
      $(MKDIR) $(DESTDIR)
  !	ENDIF
  
! config:
       echo ***** $@
  	$(CD) $(OBJ)\$@
  	$(NTMAKE)
--- 42,48 ----
      $(MKDIR) $(DESTDIR)
  !	ENDIF
  
! config: start
       echo ***** $@
  	$(CD) $(OBJ)\$@
  	$(NTMAKE)
***************
*** 306,312 ****
  	$(CD) $(OBJ)\WINNT\install\Win9x
  	nmake /nologo /f NTMakefile  isinstall
  	$(CD) ..\..\..\..
! 	eho **** End of Install Scripts
  
  media: Win9x
  
--- 307,313 ----
  	$(CD) $(OBJ)\WINNT\install\Win9x
  	nmake /nologo /f NTMakefile  isinstall
  	$(CD) ..\..\..\..
! 	echo **** End of Install Scripts
  
  media: Win9x
  
***************
*** 314,320 ****
  # 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) ..\..\..\..
--- 315,321 ----
  # 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" "NTMAKE_OBJS = nmake /nologo /f ntmakefile clean" install
  	$(CD) $(OBJ)\WINNT\install\Win9x
  	nmake /nologo /f NTMakefile clean
  	$(CD) ..\..\..\..
Index: openafs/src/NTMakefile
diff -c openafs/src/NTMakefile:1.4.2.1 openafs/src/NTMakefile:1.4.2.3
*** openafs/src/NTMakefile:1.4.2.1	Sat Oct 13 00:19:06 2001
--- openafs/src/NTMakefile	Sun Jan 20 04:09:08 2002
***************
*** 471,482 ****
  	$(CD) $(OBJ)\$@
  	$(NTMAKE)
  	$(CD) ..\..	
  
  install: start finale
  
  # InstallShield dependencies
  
! InstallShield5: install
  	echo ***** afs_setup_utils
  	$(CD) $(OBJ)\WINNT\afs_setup_utils
  	$(NTMAKE)
--- 471,483 ----
  	$(CD) $(OBJ)\$@
  	$(NTMAKE)
  	$(CD) ..\..	
+ 	echo Build Finished Successfully
  
  install: start finale
  
  # InstallShield dependencies
  
! InstallShield5:
  	echo ***** afs_setup_utils
  	$(CD) $(OBJ)\WINNT\afs_setup_utils
  	$(NTMAKE)
***************
*** 487,498 ****
  	$(CD) ..\..\..\..
  
  media: InstallShield5
  
  
- 
  # 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) $(OBJ)\config
  	nmake /nologo /f ntmakefile clean_version
  	$(CD) ..\..
--- 488,499 ----
  	$(CD) ..\..\..\..
  
  media: InstallShield5
+ 	echo Install Script Finished Successfully
  
  
  # Clean target for obj tree
  clean: start
! 	nmake /nologo /f ntmakefile "NTMAKE = nmake /nologo /f ntmakefile clean" "NTMAKE_HEADERS = nmake /nologo /f ntmakefile clean" "NTMAKE_OBJS = nmake /nologo /f ntmakefile clean" install
  	$(CD) $(OBJ)\config
  	nmake /nologo /f ntmakefile clean_version
  	$(CD) ..\..
Index: openafs/src/WINNT/afs_setup_utils/NTMakefile
diff -c openafs/src/WINNT/afs_setup_utils/NTMakefile:1.6 openafs/src/WINNT/afs_setup_utils/NTMakefile:1.6.2.1
*** openafs/src/WINNT/afs_setup_utils/NTMakefile:1.6	Mon Sep 10 11:39:50 2001
--- openafs/src/WINNT/afs_setup_utils/NTMakefile	Wed Nov 14 22:38:47 2001
***************
*** 90,97 ****
  
  install : $(INSTALL_UTILS_DLLFILE) $(SERVER_UNINST_DLLFILE) $(CLIENT_UNINST_DLLFILE) \
            $(CC_UNINST_DLLFILE) $(LIGHT_CLIENT_UNINST_DLLFILE) $(DOCS_UNINST_DLLFILE) \
- 
- media : install
            $(AFSRM_EXEFILE) $(DIRLANG)
  		  cd _isuser
  		  nmake -fntmakefile install
--- 90,95 ----
Index: openafs/src/WINNT/afs_setup_utils/afs_setup_utils.cpp
diff -c openafs/src/WINNT/afs_setup_utils/afs_setup_utils.cpp:1.4 openafs/src/WINNT/afs_setup_utils/afs_setup_utils.cpp:1.4.2.2
*** openafs/src/WINNT/afs_setup_utils/afs_setup_utils.cpp:1.4	Thu Sep  6 22:54:54 2001
--- openafs/src/WINNT/afs_setup_utils/afs_setup_utils.cpp	Sun Jan 20 04:09:11 2002
***************
*** 419,425 ****
      { TARGETDIR"\\Common\\afsadminutil.dll",            SERVER | CLIENT | LCLIENT | CC },
      { TARGETDIR"\\Common\\afsrpc.dll",                  SERVER | CLIENT | LCLIENT | CC },
      { TARGETDIR"\\Common\\afsauthent.dll",              SERVER | CLIENT | LCLIENT | CC },
!     { TARGETDIR"\\Common\\pthread.dll",                 SERVER | CLIENT | LCLIENT | CC },
      { TARGETDIR"\\Common\\TaAfsAppLib.dll",             SERVER | CLIENT | LCLIENT | CC },
      { TARGETDIR"\\Common\\afsprocmgmt.dll",             SERVER | CLIENT | LCLIENT },
      { TARGETDIR"\\Common\\afs_config.exe",              CLIENT | LCLIENT| CC },
--- 419,425 ----
      { TARGETDIR"\\Common\\afsadminutil.dll",            SERVER | CLIENT | LCLIENT | CC },
      { TARGETDIR"\\Common\\afsrpc.dll",                  SERVER | CLIENT | LCLIENT | CC },
      { TARGETDIR"\\Common\\afsauthent.dll",              SERVER | CLIENT | LCLIENT | CC },
!     { TARGETDIR"\\Common\\afspthread.dll",              SERVER | CLIENT | LCLIENT | CC },
      { TARGETDIR"\\Common\\TaAfsAppLib.dll",             SERVER | CLIENT | LCLIENT | CC },
      { TARGETDIR"\\Common\\afsprocmgmt.dll",             SERVER | CLIENT | LCLIENT },
      { TARGETDIR"\\Common\\afs_config.exe",              CLIENT | LCLIENT| CC },
***************
*** 908,913 ****
--- 908,917 ----
      SC_HANDLE hServer = 0, hSCM;
      BOOL bRestoreOldConfig = FALSE;
  
+     if (!AddToProviderOrder(AFSREG_CLT_SVC_NAME)) {
+         ShowError(ERROR_FILE_NOT_FOUND, GetLastError());
+ 		return -1;
+     }
      hSCM = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
      if (!hSCM) {
          ShowError(IDS_SCM_OPEN_FAILED, GetLastError());
***************
*** 976,981 ****
--- 980,989 ----
      BOOL bServer = FALSE;
      BOOL bShowingProgressDlg = FALSE;
  
+     if (!RemoveFromProviderOrder(AFSREG_CLT_SVC_NAME)) {
+         ShowError(ERROR_FILE_NOT_FOUND, GetLastError());
+ 		return -1;
+     }
      hSCM = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
      if (!hSCM) {
          ShowError(IDS_SCM_OPEN_FAILED, GetLastError());
Index: openafs/src/WINNT/afs_setup_utils/_isuser/_IsUser.RC
diff -c openafs/src/WINNT/afs_setup_utils/_isuser/_IsUser.RC:1.2 openafs/src/WINNT/afs_setup_utils/_isuser/_IsUser.RC:1.2.2.1
*** openafs/src/WINNT/afs_setup_utils/_isuser/_IsUser.RC:1.2	Thu Sep  6 22:54:59 2001
--- openafs/src/WINNT/afs_setup_utils/_isuser/_IsUser.RC	Sun Jan 20 04:09:11 2002
***************
*** 10,16 ****
  #define APSTUDIO_HIDDEN_SYMBOLS
  #include "windows.h"
  #undef APSTUDIO_HIDDEN_SYMBOLS
! #include <.\sdrc.h>
  
  /////////////////////////////////////////////////////////////////////////////
  #undef APSTUDIO_READONLY_SYMBOLS
--- 10,16 ----
  #define APSTUDIO_HIDDEN_SYMBOLS
  #include "windows.h"
  #undef APSTUDIO_HIDDEN_SYMBOLS
! #include <sdrc.h>
  
  /////////////////////////////////////////////////////////////////////////////
  #undef APSTUDIO_READONLY_SYMBOLS
Index: openafs/src/WINNT/afs_setup_utils/_isuser/_IsUser.dep
diff -c openafs/src/WINNT/afs_setup_utils/_isuser/_IsUser.dep:1.2 openafs/src/WINNT/afs_setup_utils/_isuser/_IsUser.dep:removed
*** openafs/src/WINNT/afs_setup_utils/_isuser/_IsUser.dep:1.2	Thu Sep  6 22:54:59 2001
--- openafs/src/WINNT/afs_setup_utils/_isuser/_IsUser.dep	Wed Jan 30 16:23:07 2002
***************
*** 1,5 ****
- # Microsoft Developer Studio Generated Dependency File, included by _IsUser.mak
- 
- .\_Isuser.RC : \
- 	".\sdrc.h"\
- 	
--- 0 ----
Index: openafs/src/WINNT/afs_setup_utils/_isuser/ntmakefile
diff -c openafs/src/WINNT/afs_setup_utils/_isuser/ntmakefile:1.3 openafs/src/WINNT/afs_setup_utils/_isuser/ntmakefile:1.3.2.1
*** openafs/src/WINNT/afs_setup_utils/_isuser/ntmakefile:1.3	Mon Sep 10 11:39:50 2001
--- openafs/src/WINNT/afs_setup_utils/_isuser/ntmakefile	Sun Jan 20 04:09:11 2002
***************
*** 30,43 ****
  "$(OUTDIR)" ::
      if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
  
- HEADERS = ".\sdrc.h"
- 
- ".\sdrc.h" : $(IS5ROOT)\INCLUDE\sdrc.h
-     $(COPY) $(IS5ROOT)\INCLUDE\sdrc.h .
- !   IF EXIST($(IS5ROOT)\Script\ISRT\Include\sdrc.h)
-     $(COPY) $(IS5ROOT)\Script\ISRT\Include\sdrc.h .
- !      ENDIF
- 
  CPP=cl.exe
  CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "_ISUSER_EXPORTS" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c 
  
--- 30,35 ----
***************
*** 85,104 ****
  	"$(INTDIR)\_isuser.obj" \
  	"$(INTDIR)\_Isuser.res"
  
! "$(OUTDIR)\_IsUser.dll" : "$(OUTDIR)" $(HEADERS) $(DEF_FILE) $(LINK32_OBJS)
      $(LINK32) @<<
    $(LINK32_FLAGS) $(LINK32_OBJS)
  <<
- 
- 
- !IF "$(NO_EXTERNAL_DEPS)" != "1"
- !IF EXISTS("_IsUser.dep")
- !INCLUDE "_IsUser.dep"
- !ELSE 
- !MESSAGE Warning: cannot find "_IsUser.dep"
- !ENDIF 
- !ENDIF 
- 
  
  SOURCE=.\_isuser.c
  
--- 77,86 ----
  	"$(INTDIR)\_isuser.obj" \
  	"$(INTDIR)\_Isuser.res"
  
! "$(OUTDIR)\_IsUser.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
      $(LINK32) @<<
    $(LINK32_FLAGS) $(LINK32_OBJS)
  <<
  
  SOURCE=.\_isuser.c
  
Index: openafs/src/WINNT/afsd/NTMakefile
diff -c openafs/src/WINNT/afsd/NTMakefile:1.4.4.1 openafs/src/WINNT/afsd/NTMakefile:1.4.4.3
*** openafs/src/WINNT/afsd/NTMakefile:1.4.4.1	Sat Oct 13 00:19:06 2001
--- openafs/src/WINNT/afsd/NTMakefile	Sun Jan 20 04:09:11 2002
***************
*** 5,10 ****
--- 5,11 ----
  # License.  For details, see the LICENSE file in the top-level source
  # directory or online at http://www.openafs.org/dl/license10.html
  
+ AFSDEV_NETGUI = 1
  !INCLUDE ..\..\config\NTMakefile.$(SYS_NAME)
  !INCLUDE ..\..\config\NTMakefile.version
  
***************
*** 168,174 ****
  	$(EXEDIR)\tokens.exe \
  	$(EXEDIR)\unlog.exe $(EXEDIR)\afsd.exe $(EXEDIR)\afsd_service.exe \
  	$(EXEDIR)\fs.exe $(EXEDIR)\symlink.exe \
! 	$(LOGON_DLLFILE) $(LOG95_DLLFILE) \
  	$(EXEDIR)\afsshare.exe \
  	$(DESTDIR)\bin\kpasswd.exe
  
--- 169,175 ----
  	$(EXEDIR)\tokens.exe \
  	$(EXEDIR)\unlog.exe $(EXEDIR)\afsd.exe $(EXEDIR)\afsd_service.exe \
  	$(EXEDIR)\fs.exe $(EXEDIR)\symlink.exe \
! 	$(LOGON_DLLFILE) \
  	$(EXEDIR)\afsshare.exe \
  	$(DESTDIR)\bin\kpasswd.exe
  
***************
*** 305,312 ****
  	$(DEL) $(DESTDIR)\bin\kpasswd.exe
  	$(EXECONLINK)
  	$(EXEPREP)
  
- 	
  ############################################################################
  # generate versioninfo resources
  
--- 306,313 ----
  	$(DEL) $(DESTDIR)\bin\kpasswd.exe
  	$(EXECONLINK)
  	$(EXEPREP)
+ 
  
  ############################################################################
  # generate versioninfo resources
  
Index: openafs/src/WINNT/afsd/afsd_service.c
diff -c openafs/src/WINNT/afsd/afsd_service.c:1.3 openafs/src/WINNT/afsd/afsd_service.c:1.3.4.2
*** openafs/src/WINNT/afsd/afsd_service.c:1.3	Sat Jun 23 13:26:07 2001
--- openafs/src/WINNT/afsd/afsd_service.c	Sun Jan 20 04:09:11 2002
***************
*** 137,142 ****
--- 137,144 ----
  	}
  }
  
+ #if 0
+ /* This code was moved to Drivemap.cpp*/
  /* Mount a drive into AFS if the user wants us to */
  void CheckMountDrive()
  {
***************
*** 177,182 ****
--- 179,185 ----
  
          RegCloseKey(hKey);
  }
+ #endif
  
  void afsd_Main()
  {
***************
*** 185,190 ****
--- 188,194 ----
  	int jmpret;
  
  	osi_InitPanic(afsd_notifier);
+ 	osi_InitTraceOption();
  
  	GlobalStatus = 0;
  
***************
*** 247,256 ****
  	}
  
          /* Check if we should mount a drive into AFS */
!         CheckMountDrive();
  
  	WaitForSingleObject(WaitToTerminate, INFINITE);
! 
  {   
          HANDLE h; char *ptbuf[1];
  	h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
--- 251,260 ----
  	}
  
          /* Check if we should mount a drive into AFS */
! /*        CheckMountDrive();*/
  
  	WaitForSingleObject(WaitToTerminate, INFINITE);
! 	
  {   
          HANDLE h; char *ptbuf[1];
  	h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
Index: openafs/src/WINNT/afsd/afslogon.c
diff -c openafs/src/WINNT/afsd/afslogon.c:1.2 openafs/src/WINNT/afsd/afslogon.c:1.2.8.2
*** openafs/src/WINNT/afsd/afslogon.c:1.2	Sat Nov  4 05:01:35 2000
--- openafs/src/WINNT/afsd/afslogon.c	Sun Jan 20 04:09:11 2002
***************
*** 19,38 ****
  #include "cm_config.h"
  #include "krb.h"
  
  
  HANDLE hDLL;
  
  WSADATA WSAjunk;
  
- char NPName[] = "System\\CurrentControlSet\\Services\\TransarcAFSDaemon\\NetworkProvider";
- 
  #define REG_CLIENT_PARMS_KEY            "SYSTEM\\CurrentControlSet\\Services\\TransarcAFSDaemon\\Parameters"
  #define REG_CLIENT_RETRY_INTERVAL_PARM  "LoginRetryInterval"
  #define REG_CLIENT_FAIL_SILENTLY_PARM   "FailLoginsSilently"
! #define DEFAULT_RETRY_INTERVAL          30                        // seconds
  #define DEFAULT_FAIL_SILENTLY           FALSE
! #define DEFAULT_SLEEP_INTERVAL          5                         // seconds
  
  
  /* Structure def copied from DDK (NTDEF.H) */
  typedef struct UNICODE_STRING {
--- 19,48 ----
  #include "cm_config.h"
  #include "krb.h"
  
+ #include <io.h>
+ #include <sys/stat.h>
+ #include <sys/types.h>
+ #include <fcntl.h>
  
+ DWORD LogonOption,TraceOption;
+ 
  HANDLE hDLL;
  
  WSADATA WSAjunk;
  
  #define REG_CLIENT_PARMS_KEY            "SYSTEM\\CurrentControlSet\\Services\\TransarcAFSDaemon\\Parameters"
+ #define REG_CLIENT_PROVIDER_KEY			"SYSTEM\\CurrentControlSet\\Services\\TransarcAFSDaemon\\NetworkProvider"
  #define REG_CLIENT_RETRY_INTERVAL_PARM  "LoginRetryInterval"
  #define REG_CLIENT_FAIL_SILENTLY_PARM   "FailLoginsSilently"
! #define DEFAULT_RETRY_INTERVAL          30                        /* seconds*/
  #define DEFAULT_FAIL_SILENTLY           FALSE
! #define DEFAULT_SLEEP_INTERVAL          5                         /* seconds*/
! 
! #define ISLOGONINTEGRATED(v) ( ((v) & LOGON_OPTION_INTEGRATED)==LOGON_OPTION_INTEGRATED)
! #define ISHIGHSECURITY(v) ( ((v) & LOGON_OPTION_HIGHSECURITY)==LOGON_OPTION_HIGHSECURITY)
  
+ #define TRACE_OPTION_EVENT 1
+ #define ISLOGONTRACE(v) ( ((v) & TRACE_OPTION_EVENT)==TRACE_OPTION_EVENT)
  
  /* Structure def copied from DDK (NTDEF.H) */
  typedef struct UNICODE_STRING {
***************
*** 57,80 ****
   *
   * Returns NULL on failure.
   */
! WCHAR *GetLogonScript(void)
  {
! 	WCHAR *script;
  	DWORD code;
  	DWORD LSPtype, LSPsize;
  	HKEY NPKey;
  
  	/*
  	 * Get Network Provider key.
  	 * Assume this works or we wouldn't be here.
  	 */
! 	(void) RegOpenKeyEx(HKEY_LOCAL_MACHINE, NPName,
  			    0, KEY_QUERY_VALUE, &NPKey);
  
  	/*
  	 * Get Logon Script pathname length
  	 */
! 	code = RegQueryValueEx(NPKey, "LogonScript", NULL,
  				&LSPtype, NULL, &LSPsize);
  
  	if (code) {
--- 67,131 ----
   *
   * Returns NULL on failure.
   */
! 
! 
! void DebugEvent0(char *a) 
! {
! 	HANDLE h; char *ptbuf[1];
! 	if (!ISLOGONTRACE(TraceOption))
! 		return;
! 	h = RegisterEventSource(NULL, a);
! 	ptbuf[0] = a;
! 	ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (const char **)ptbuf, NULL);
! 	DeregisterEventSource(h);
! }
! 
! #define MAXBUF_ 131
! void DebugEvent(char *a,char *b,...) 
! {
! 	HANDLE h; char *ptbuf[1],buf[MAXBUF_+1];
! 	va_list marker;
! 	if (!ISLOGONTRACE(TraceOption))
! 		return;
! 	h = RegisterEventSource(NULL, a);
! 	va_start(marker,b);
! 	_vsnprintf(buf,MAXBUF_,b,marker);
! 	ptbuf[0] = buf;
! 	ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (const char **)ptbuf, NULL);\
! 	DeregisterEventSource(h);
! 	va_end(marker);
! }
! 
! CHAR *GenRandomName(CHAR *pbuf)
  {
! 	int i;
! 	srand( (unsigned)time( NULL ) );
! 	for (i=0;i<MAXRANDOMNAMELEN-1;i++)
! 		pbuf[i]='a'+(rand() % 26);
! 	pbuf[MAXRANDOMNAMELEN-1]=0;
! 	return pbuf;
! }
! 
! WCHAR *GetLogonScript(CHAR *pname)
! {
! 	WCHAR *script,*buf;
  	DWORD code;
  	DWORD LSPtype, LSPsize;
  	HKEY NPKey;
+ 	WCHAR randomName[MAXRANDOMNAMELEN];
  
  	/*
  	 * Get Network Provider key.
  	 * Assume this works or we wouldn't be here.
  	 */
! 	(void) RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_CLIENT_PROVIDER_KEY,
  			    0, KEY_QUERY_VALUE, &NPKey);
  
  	/*
  	 * Get Logon Script pathname length
  	 */
! 
! 	code = RegQueryValueExW(NPKey, L"LogonScript", NULL,
  				&LSPtype, NULL, &LSPsize);
  
  	if (code) {
***************
*** 86,100 ****
  		RegCloseKey (NPKey);
  		return NULL;
  	}
- 
- 	script = (WCHAR *)LocalAlloc(LMEM_FIXED, LSPsize);
  
  	/*
  	 * Explicitly call UNICODE version
  	 * Assume it will succeed since it did before
  	 */
  	(void) RegQueryValueExW(NPKey, L"LogonScript", NULL,
! 				&LSPtype, (LPBYTE)script, &LSPsize);
  
  	RegCloseKey (NPKey);
  	return script;
--- 137,166 ----
  		RegCloseKey (NPKey);
  		return NULL;
  	}
  
+ 	buf=(WCHAR *)LocalAlloc(LMEM_FIXED, LSPsize);
+ 	script=(WCHAR *)LocalAlloc(LMEM_FIXED,LSPsize+(MAXRANDOMNAMELEN)*sizeof(WCHAR));
  	/*
  	 * Explicitly call UNICODE version
  	 * Assume it will succeed since it did before
  	 */
  	(void) RegQueryValueExW(NPKey, L"LogonScript", NULL,
! 				&LSPtype, (LPBYTE)buf, &LSPsize);
! 	MultiByteToWideChar(CP_ACP,0,pname,strlen(pname)+1,randomName,(strlen(pname)+1)*sizeof(WCHAR));
! 	swprintf(script,buf,randomName);
! 	free(buf);
! 
! #ifdef DEBUG_VERBOSE
! 		{
!         HANDLE h; char *ptbuf[1],buf[132],tbuf[255];
! 		WideCharToMultiByte(CP_ACP,0,script,LSPsize,tbuf,255,NULL,NULL);
!         h = RegisterEventSource(NULL, "AFS AfsLogon - GetLogonScript");
!         sprintf(buf, "Script[%s,%d] Return Code[%x]",tbuf,LSPsize,code);
!         ptbuf[0] = buf;
!         ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, ptbuf, NULL);
!         DeregisterEventSource(h);
! 		}
! #endif
  
  	RegCloseKey (NPKey);
  	return script;
***************
*** 153,161 ****
  DWORD MapAuthError(DWORD code)
  {
  	switch (code) {
! 		case INTK_BADPW: return WN_BAD_PASSWORD;
! 		case KERB_ERR_PRINCIPAL_UNKNOWN: return WN_BAD_USER;
! 		default: return WN_NO_NETWORK;
  	}
  }
  
--- 219,230 ----
  DWORD MapAuthError(DWORD code)
  {
  	switch (code) {
! 	case KTC_NOCM:
! 	case KTC_NOCMRPC:
! 		return WN_NO_NETWORK;
! /*	case INTK_BADPW: return WN_BAD_PASSWORD;*/
! /*	case KERB_ERR_PRINCIPAL_UNKNOWN: return WN_BAD_USER;*/
! 	default: return WN_SUCCESS;
  	}
  }
  
***************
*** 212,223 ****
         	if (result != ERROR_SUCCESS)
         	        *pFailSilently = DEFAULT_FAIL_SILENTLY;
  
!         // Make sure this is really a bool value in the strict sense
          *pFailSilently = !!*pFailSilently;
         	        
          RegCloseKey(hKey);
  }
  
  DWORD APIENTRY NPLogonNotify(
  	PLUID lpLogonId,
  	LPCWSTR lpAuthentInfoType,
--- 281,314 ----
         	if (result != ERROR_SUCCESS)
         	        *pFailSilently = DEFAULT_FAIL_SILENTLY;
  
!         /* Make sure this is really a bool value in the strict sense*/
          *pFailSilently = !!*pFailSilently;
         	        
          RegCloseKey(hKey);
  }
  
+ BOOL IsServiceRunning (void)
+ {
+       SERVICE_STATUS Status;
+       SC_HANDLE hManager;
+       memset (&Status, 0x00, sizeof(Status));
+       Status.dwCurrentState = SERVICE_STOPPED;
+ 
+       if ((hManager = OpenSCManager (NULL, NULL, GENERIC_READ)) != NULL)
+          {
+          SC_HANDLE hService;
+          if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"), GENERIC_READ)) != NULL)
+             {
+             QueryServiceStatus (hService, &Status);
+             CloseServiceHandle (hService);
+             }
+ 
+          CloseServiceHandle (hManager);
+          }
+ 		 DebugEvent("AFS AfsLogon - Test Service Running","Return Code[%x] ?Running[%d]",Status.dwCurrentState,(Status.dwCurrentState == SERVICE_RUNNING));
+ 		return (Status.dwCurrentState == SERVICE_RUNNING);
+ }
+ 
  DWORD APIENTRY NPLogonNotify(
  	PLUID lpLogonId,
  	LPCWSTR lpAuthentInfoType,
***************
*** 237,247 ****
  	char *reason;
  	BOOLEAN interactive;
  	BOOLEAN flag;
  	HWND hwndOwner = (HWND)StationHandle;
!         BOOLEAN failSilently;
!         int retryInterval;
!         int sleepInterval = DEFAULT_SLEEP_INTERVAL;        // seconds        
!         BOOLEAN afsWillAutoStart;
          
  	IL = (MSV1_0_INTERACTIVE_LOGON *) lpAuthentInfo;
  
--- 328,342 ----
  	char *reason;
  	BOOLEAN interactive;
  	BOOLEAN flag;
+ 	DWORD LSPtype, LSPsize;
+ 	HKEY NPKey;
  	HWND hwndOwner = (HWND)StationHandle;
!     BOOLEAN failSilently;
!     int retryInterval;
!     int sleepInterval = DEFAULT_SLEEP_INTERVAL;        /* seconds        */
!     BOOLEAN afsWillAutoStart;
! 	CHAR RandomName[MAXRANDOMNAMELEN];
! 	*lpLogonScript=NULL;
          
  	IL = (MSV1_0_INTERACTIVE_LOGON *) lpAuthentInfo;
  
***************
*** 251,323 ****
  	/* Convert from Unicode to ANSI */
  	wcstombs(uname, IL->UserName.Buffer, 256);
  	wcstombs(password, IL->Password.Buffer, 256);
  
! 	/* Check for zero length password */
! 	if (password[0] == 0) {
  		code = GT_PW_NULL;
  		reason = "zero length password is illegal";
! 		goto checkauth;
  	}
  
! 	/* Get cell name */
! 	code = cm_GetRootCellName(cell);
! 	if (code < 0) {
! 		code = KTC_NOCELL;
! 		reason = "unknown cell";
! 		goto checkauth;
  	}
  
!         /* Get user specified login behavior (or defaults) */
!         GetLoginBehavior(&retryInterval, &failSilently);
          
!         afsWillAutoStart = AFSWillAutoStart();
          
!         /* Possibly loop until AFS is started. */
!         while (1) {
!                 code = ka_UserAuthenticateGeneral(
! 			KA_USERAUTH_VERSION+KA_USERAUTH_AUTHENT_LOGON,
! 			uname, "", cell, password, 0, &pw_exp, 0,
! 			&reason);
  			
  		/* If we've failed because the client isn't running yet and the
  		 * client is set to autostart (and therefore it makes sense for
  		 * us to wait for it to start) then sleep a while and try again. 
  		 * If the error was something else, then give up. */
  		if (code != KTC_NOCM && code != KTC_NOCMRPC || !afsWillAutoStart)
! 		        break;
  		
                  /* If the retry interval has expired and we still aren't
                   * logged in, then just give up if we are not in interactive
                   * mode or the failSilently flag is set, otherwise let the
                   * user know we failed and give them a chance to try again. */
!                 if (retryInterval <= 0) {
!                         if (!interactive || failSilently)
!                                 break;
! 
  			flag = MessageBox(hwndOwner,
  				"AFS is still starting.  Retry?",
  				"AFS Logon",
  				MB_ICONQUESTION | MB_RETRYCANCEL);
  			if (flag == IDCANCEL)
! 				break;
                          
                          /* Wait just a little while and try again */
!                         retryInterval = sleepInterval = DEFAULT_SLEEP_INTERVAL;
!                 }
                                          
!                 if (retryInterval < sleepInterval)
!                         sleepInterval = retryInterval;
                          
!                 Sleep(sleepInterval * 1000);
  
!                 retryInterval -= sleepInterval;
!         }
  
- checkauth:
  	if (code) {
                  char msg[128];
!                 
!                 sprintf(msg, "Integrated login failed: %s", reason);
                  
  		if (interactive && !failSilently)
  			MessageBox(hwndOwner, msg, "AFS Logon", MB_OK);
--- 346,464 ----
  	/* Convert from Unicode to ANSI */
  	wcstombs(uname, IL->UserName.Buffer, 256);
  	wcstombs(password, IL->Password.Buffer, 256);
+ 
+ 	(void) RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_CLIENT_PARMS_KEY,
+ 		    0, KEY_QUERY_VALUE, &NPKey);
+ 	LSPsize=sizeof(TraceOption);
+ 	RegQueryValueEx(NPKey, "TraceOption", NULL,
+ 				&LSPtype, (LPBYTE)&TraceOption, &LSPsize);
+ 	 RegCloseKey (NPKey);
+ 	
+ 	/*
+ 	 * Get Logon OPTIONS
+ 	 */
+ 
+ 	(void) RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_CLIENT_PROVIDER_KEY,
+ 		    0, KEY_QUERY_VALUE, &NPKey);
  
! 	LSPsize=sizeof(LogonOption);
! 	code = RegQueryValueEx(NPKey, "LogonOptions", NULL,
! 				&LSPtype, (LPBYTE)&LogonOption, &LSPsize);
! 
! 	RegCloseKey (NPKey);
! 	if ((code!=0) || (LSPtype!=REG_DWORD))
! 		LogonOption=LOGON_OPTION_INTEGRATED;	/*default to integrated logon only*/
! 	DebugEvent("AFS AfsLogon - NPLogonNotify","LogonOption[%x], Service AutoStart[%d]",LogonOption,AFSWillAutoStart());
! 	/* Check for zero length password if integrated logon*/
! 	if ( ISLOGONINTEGRATED(LogonOption) && (password[0] == 0) )  {
  		code = GT_PW_NULL;
  		reason = "zero length password is illegal";
! 		code=0;
  	}
  
! 	/* Get cell name if doing integrated logon */
! 	if (ISLOGONINTEGRATED(LogonOption))
! 	{
! 		code = cm_GetRootCellName(cell);
! 		if (code < 0) { 
! 			code = KTC_NOCELL;
! 			reason = "unknown cell";
! 			code=0;
! 		}
  	}
  
!     /* Get user specified login behavior (or defaults) */
!     GetLoginBehavior(&retryInterval, &failSilently);
          
!     afsWillAutoStart = AFSWillAutoStart();
          
!     *lpLogonScript = GetLogonScript(GenRandomName(RandomName));	/*only do if high security option is on*/
! 
! 
!     /* loop until AFS is started. */
!     while (TRUE) {
! 	code=0;
! 		
! 	/* is service started yet?*/
! 	if (ISLOGONINTEGRATED(LogonOption) && !ISHIGHSECURITY(LogonOption))	/* if Integrated Logon only */
! 		{			
! 			DebugEvent("AFS AfsLogon - ka_UserAuthenticateGeneral2","Code[%x],uame[%s] Cell[%s]",code,uname,cell);
! 			code = ka_UserAuthenticateGeneral2(
! 				KA_USERAUTH_VERSION+KA_USERAUTH_AUTHENT_LOGON,
! 				uname, "", cell, password,uname, 0, &pw_exp, 0,
! 				&reason);
! 			DebugEvent("AFS AfsLogon - (INTEGERTED only)ka_UserAuthenticateGeneral2","Code[%x]",code);
! 		} else if (ISLOGONINTEGRATED(LogonOption) && ISHIGHSECURITY(LogonOption))	/* if Integrated Logon and High Security pass random generated name*/
! 		{
! 			code = ka_UserAuthenticateGeneral2(
! 				KA_USERAUTH_VERSION+KA_USERAUTH_AUTHENT_LOGON,
! 				uname, "", cell, password,RandomName, 0, &pw_exp, 0,
! 				&reason);
! 			DebugEvent("AFS AfsLogon - (Both)ka_UserAuthenticateGeneral2","Code[%x],RandomName[%s]",code,RandomName);
! 		} else {  /*JUST check to see if its running*/
! 		    if (IsServiceRunning())
! 			break;
! 		    code = KTC_NOCM;
! 		    if (!afsWillAutoStart)
! 			break;
! 		}
  			
  		/* If we've failed because the client isn't running yet and the
  		 * client is set to autostart (and therefore it makes sense for
  		 * us to wait for it to start) then sleep a while and try again. 
  		 * If the error was something else, then give up. */
  		if (code != KTC_NOCM && code != KTC_NOCMRPC || !afsWillAutoStart)
! 			break;
  		
                  /* If the retry interval has expired and we still aren't
                   * logged in, then just give up if we are not in interactive
                   * mode or the failSilently flag is set, otherwise let the
                   * user know we failed and give them a chance to try again. */
!         if (retryInterval <= 0) {
!              if (!interactive || failSilently)
!                  break;
  			flag = MessageBox(hwndOwner,
  				"AFS is still starting.  Retry?",
  				"AFS Logon",
  				MB_ICONQUESTION | MB_RETRYCANCEL);
  			if (flag == IDCANCEL)
! 					break;
                          
                          /* Wait just a little while and try again */
!                  retryInterval = sleepInterval = DEFAULT_SLEEP_INTERVAL;
!         }
                                          
!         if (retryInterval < sleepInterval)
! 			sleepInterval = retryInterval;
                          
! 		Sleep(sleepInterval * 1000);
  
!         retryInterval -= sleepInterval;
!      }
  
  	if (code) {
                  char msg[128];
!         sprintf(msg, "Integrated login failed: %s", reason);
                  
  		if (interactive && !failSilently)
  			MessageBox(hwndOwner, msg, "AFS Logon", MB_OK);
***************
*** 331,347 ****
                  		    1, 0, ptbuf, NULL);
                  	DeregisterEventSource(h);
                  }
! 	}
! 
! 	/* Get logon script */
! 	if (interactive)
! 		*lpLogonScript = GetLogonScript();
! 
! 	if (code) {
! 	        code = MapAuthError(code);
  		SetLastError(code);
! 	}
  
  	return code;
  }
  
--- 472,490 ----
                  		    1, 0, ptbuf, NULL);
                  	DeregisterEventSource(h);
                  }
! 	    code = MapAuthError(code);
  		SetLastError(code);
! 		if (ISHIGHSECURITY(LogonOption) && (code!=0))
! 		{
! 			if (*lpLogonScript)
! 				LocalFree(*lpLogonScript);
! 			*lpLogonScript = NULL;
! 			if (!(afsWillAutoStart || ISLOGONINTEGRATED(LogonOption)))	// its not running, so if not autostart or integrated logon then just skip
! 				return 0;
  
+ 		}
+ 	}
+ 	DebugEvent("AFS AfsLogon - Exit","Return Code[%x]",code);
  	return code;
  }
  
***************
*** 354,359 ****
--- 497,503 ----
  	LPVOID StationHandle,
  	DWORD dwChangeInfo)
  {
+ 	DebugEvent0("AFS AfsLogon - NPPasswordChangeNotify");
  	return 0;
  }
  
Index: openafs/src/WINNT/afsd/cm_callback.c
diff -c openafs/src/WINNT/afsd/cm_callback.c:1.4.2.1 openafs/src/WINNT/afsd/cm_callback.c:1.4.2.2
*** openafs/src/WINNT/afsd/cm_callback.c:1.4.2.1	Sat Oct 13 00:19:06 2001
--- openafs/src/WINNT/afsd/cm_callback.c	Sun Jan 20 04:09:11 2002
***************
*** 312,317 ****
--- 312,324 ----
  }
  
  /* debug interface: not implemented */
+ SRXAFSCB_GetCE64(struct rx_call *callp, long index, AFSDBCacheEntry *cep)
+ {
+     /* XXXX */
+     return RXGEN_OPCODE;
+ }
+ 
+ /* debug interface: not implemented */
  SRXAFSCB_GetLock(struct rx_call *callp, long index, AFSDBLock *lockp)
  {
  	/* XXXX */
Index: openafs/src/WINNT/afsd/cm_cell.c
diff -c openafs/src/WINNT/afsd/cm_cell.c:1.3.4.1 openafs/src/WINNT/afsd/cm_cell.c:1.3.4.2
*** openafs/src/WINNT/afsd/cm_cell.c:1.3.4.1	Sat Oct 13 00:19:06 2001
--- openafs/src/WINNT/afsd/cm_cell.c	Wed Nov 14 22:30:08 2001
***************
*** 57,70 ****
  /* load up a cell structure from the cell database, afsdcell.ini */
  cm_cell_t *cm_GetCell(char *namep, long flags)
  {
  	cm_cell_t *cp;
          long code;
          static cellCounter = 1;		/* locked by cm_cellLock */
  	int ttl;
  
  	lock_ObtainWrite(&cm_cellLock);
  	for(cp = cm_allCellsp; cp; cp=cp->nextp) {
! 		if (strcmp(namep, cp->namep) == 0) break;
          }
  
  	if ((!cp && (flags & CM_FLAG_CREATE))
--- 57,79 ----
  /* load up a cell structure from the cell database, afsdcell.ini */
  cm_cell_t *cm_GetCell(char *namep, long flags)
  {
+   return cm_GetCell_Gen(namep, NULL, flags);
+ }
+ 
+ cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, long flags)
+ {
  	cm_cell_t *cp;
          long code;
          static cellCounter = 1;		/* locked by cm_cellLock */
  	int ttl;
+ 	char fullname[200];
  
  	lock_ObtainWrite(&cm_cellLock);
  	for(cp = cm_allCellsp; cp; cp=cp->nextp) {
! 		if (strcmp(namep, cp->namep) == 0) {
! 		  strcpy(fullname, cp->namep);
! 		  break;
! 		}
          }
  
  	if ((!cp && (flags & CM_FLAG_CREATE))
***************
*** 75,84 ****
  	  ) {
  		if (!cp) cp = malloc(sizeof(*cp));
                  memset(cp, 0, sizeof(*cp));
!                 code = cm_SearchCellFile(namep, NULL, cm_AddCellProc, cp);
  #ifdef AFS_AFSDB_ENV
!                 if (code && cm_dnsEnabled) {
!                   code = cm_SearchCellByDNS(namep, NULL, &ttl, cm_AddCellProc, cp);
  #endif
  		  if (code) {
  		    free(cp);
--- 84,94 ----
  	  ) {
  		if (!cp) cp = malloc(sizeof(*cp));
                  memset(cp, 0, sizeof(*cp));
!                 code = cm_SearchCellFile(namep, fullname, cm_AddCellProc, cp);
! 		if (code) {
  #ifdef AFS_AFSDB_ENV
! 		  if (cm_dnsEnabled /*&& cm_DomainValid(namep)*/)
! 		    code = cm_SearchCellByDNS(namep, fullname, &ttl, cm_AddCellProc, cp);
  #endif
  		  if (code) {
  		    free(cp);
***************
*** 90,97 ****
  		    cp->flags |= CM_CELLFLAG_DNS;
  		    cp->timeout = time(0) + ttl;
  		  }
- 		}
  #endif
  
  		/* randomise among those vlservers having the same rank*/ 
  		cm_RandomizeServer(&cp->vlServersp);
--- 100,107 ----
  		    cp->flags |= CM_CELLFLAG_DNS;
  		    cp->timeout = time(0) + ttl;
  		  }
  #endif
+ 		}
  
  		/* randomise among those vlservers having the same rank*/ 
  		cm_RandomizeServer(&cp->vlServersp);
***************
*** 100,107 ****
                  lock_InitializeMutex(&cp->mx, "cm_cell_t mutex");
  
  		/* copy in name */
!                 cp->namep = malloc(strlen(namep)+1);
!                 strcpy(cp->namep, namep);
  
  		/* thread on global list */
                  cp->nextp = cm_allCellsp;
--- 110,117 ----
                  lock_InitializeMutex(&cp->mx, "cm_cell_t mutex");
  
  		/* copy in name */
!                 cp->namep = malloc(strlen(fullname)+1);
!                 strcpy(cp->namep, fullname);
  
  		/* thread on global list */
                  cp->nextp = cm_allCellsp;
***************
*** 111,116 ****
--- 121,128 ----
          }
  
  done:
+ 	if (newnamep)
+ 	  strcpy(newnamep, fullname);
  	lock_ReleaseWrite(&cm_cellLock);
          return cp;
  }
Index: openafs/src/WINNT/afsd/cm_cell.h
diff -c openafs/src/WINNT/afsd/cm_cell.h:1.2.8.1 openafs/src/WINNT/afsd/cm_cell.h:1.2.8.2
*** openafs/src/WINNT/afsd/cm_cell.h:1.2.8.1	Sat Oct 13 00:19:06 2001
--- openafs/src/WINNT/afsd/cm_cell.h	Wed Nov 14 22:30:08 2001
***************
*** 30,35 ****
--- 30,37 ----
  
  extern cm_cell_t *cm_GetCell(char *namep, long flags);
  
+ extern cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, long flags);
+ 
  extern cm_cell_t *cm_FindCellByID(long cellID);
  
  extern void cm_ChangeRankCellVLServer(cm_server_t       *tsp);
Index: openafs/src/WINNT/afsd/cm_config.c
diff -c openafs/src/WINNT/afsd/cm_config.c:1.3.4.2 openafs/src/WINNT/afsd/cm_config.c:1.3.4.3
*** openafs/src/WINNT/afsd/cm_config.c:1.3.4.2	Sat Oct 13 00:19:06 2001
--- openafs/src/WINNT/afsd/cm_config.c	Wed Nov 14 22:38:47 2001
***************
*** 438,444 ****
  		return -1;
  
  	code = RegSetValueEx(parmKey, labelp, 0, REG_DWORD,
! 			     &value, sizeof(value));
  	RegCloseKey (parmKey);
  	if (code != ERROR_SUCCESS)
  		return -1;
--- 438,444 ----
  		return -1;
  
  	code = RegSetValueEx(parmKey, labelp, 0, REG_DWORD,
! 			     (LPBYTE)&value, sizeof(value));
  	RegCloseKey (parmKey);
  	if (code != ERROR_SUCCESS)
  		return -1;
***************
*** 535,541 ****
          return 0;
  }
  
! extern long cm_CloseCellFile(cm_configFile_t *filep)
  {
  	char wdir[256];
          char sdir[256];
--- 535,541 ----
          return 0;
  }
  
! long cm_CloseCellFile(cm_configFile_t *filep)
  {
  	char wdir[256];
          char sdir[256];
Index: openafs/src/WINNT/afsd/cm_dcache.c
diff -c openafs/src/WINNT/afsd/cm_dcache.c:1.3.4.1 openafs/src/WINNT/afsd/cm_dcache.c:1.3.4.2
*** openafs/src/WINNT/afsd/cm_dcache.c:1.3.4.1	Sat Oct 13 00:19:06 2001
--- openafs/src/WINNT/afsd/cm_dcache.c	Sun Jan 20 04:09:11 2002
***************
*** 1155,1161 ****
  		afsStatus.UnixModeBits = 0x1ff;
  		afsStatus.ParentVnode = 0x1;
  		afsStatus.ParentUnique = 0x1;
! 		afsStatus.SegSize = 0;
  		afsStatus.ClientModTime = 0x3b49f6e2;
  		afsStatus.ServerModTime = 0x3b49f6e2;
  		afsStatus.Group = 0;
--- 1155,1161 ----
  		afsStatus.UnixModeBits = 0x1ff;
  		afsStatus.ParentVnode = 0x1;
  		afsStatus.ParentUnique = 0x1;
! 		afsStatus.ResidencyMask = 0;
  		afsStatus.ClientModTime = 0x3b49f6e2;
  		afsStatus.ServerModTime = 0x3b49f6e2;
  		afsStatus.Group = 0;
Index: openafs/src/WINNT/afsd/cm_freelance.c
diff -c openafs/src/WINNT/afsd/cm_freelance.c:1.2.2.1 openafs/src/WINNT/afsd/cm_freelance.c:1.2.2.3
*** openafs/src/WINNT/afsd/cm_freelance.c:1.2.2.1	Sat Oct 13 00:39:53 2001
--- openafs/src/WINNT/afsd/cm_freelance.c	Wed Nov 14 22:31:26 2001
***************
*** 82,88 ****
  	int curDirEntryInPage = 0;
  	int sizeOfCurEntry;
  	int dirSize;
! 	
  
  	while (curDirEntry!=cm_noLocalMountPoints) {
  		sizeOfCurEntry = cm_NameEntries((cm_localMountPoints+curDirEntry)->namep, 0);
--- 82,90 ----
  	int curDirEntryInPage = 0;
  	int sizeOfCurEntry;
  	int dirSize;
! 
! 	/* Reserve 2 directory chunks for "." and ".." */
! 	curChunk += 2;
  
  	while (curDirEntry!=cm_noLocalMountPoints) {
  		sizeOfCurEntry = cm_NameEntries((cm_localMountPoints+curDirEntry)->namep, 0);
***************
*** 435,447 ****
  	return 0;
  }
  
! long cm_FreelanceAddMount(char *filename, char *cellname, char *volume)
  {
      FILE *fp;
      char hfile[120];
      char line[200];
      int n;
  
      lock_ObtainMutex(&cm_Freelance_Lock);
  
       cm_GetConfigDir(hfile);
--- 437,460 ----
  	return 0;
  }
  
! long cm_FreelanceAddMount(char *filename, char *cellname, char *volume, cm_fid_t *fidp)
  {
      FILE *fp;
      char hfile[120];
      char line[200];
+     char fullname[200];
      int n;
  
+     /* before adding, verify the cell name; if it is not a valid cell,
+        don't add the mount point */
+     /* major performance issue? */
+     if (!cm_GetCell_Gen(cellname, fullname, CM_FLAG_CREATE))
+       return -1;
+ #if 0
+     if (strcmp(cellname, fullname) != 0)   /* no partial matches allowed */
+       return -1;
+ #endif
+     
      lock_ObtainMutex(&cm_Freelance_Lock);
  
       cm_GetConfigDir(hfile);
***************
*** 455,466 ****
       fseek(fp, 0, SEEK_SET);
       fprintf(fp, "%d", n);
       fseek(fp, 0, SEEK_END);
!      fprintf(fp, "%s#%s:%s\n", filename, cellname, volume);
       fclose(fp);
       lock_ReleaseMutex(&cm_Freelance_Lock);
  
       cm_noteLocalMountPointChange();
! 
       return 0;
  }
  
--- 468,484 ----
       fseek(fp, 0, SEEK_SET);
       fprintf(fp, "%d", n);
       fseek(fp, 0, SEEK_END);
!      fprintf(fp, "%s#%s:%s\n", filename, fullname, volume);
       fclose(fp);
       lock_ReleaseMutex(&cm_Freelance_Lock);
  
+      /*cm_reInitLocalMountPoints(&vnode);*/
+      if (fidp) {
+        fidp->unique = 1;
+        fidp->vnode = cm_noLocalMountPoints + 1;   /* vnode value of last mt pt */
+      }
       cm_noteLocalMountPointChange();
!      
       return 0;
  }
  
Index: openafs/src/WINNT/afsd/cm_ioctl.c
diff -c openafs/src/WINNT/afsd/cm_ioctl.c:1.5.4.1 openafs/src/WINNT/afsd/cm_ioctl.c:1.5.4.3
*** openafs/src/WINNT/afsd/cm_ioctl.c:1.5.4.1	Sat Oct 13 00:19:06 2001
--- openafs/src/WINNT/afsd/cm_ioctl.c	Wed Nov 21 01:45:40 2001
***************
*** 1176,1182 ****
  	if (cm_freelanceEnabled && dscp == cm_rootSCachep) {
  	  /* we are adding the mount point to the root dir., so call
  	     the freelance code to do the add. */
! 	  code = cm_FreelanceAddMount(leaf, fullCell, volume);
  	  return code;
  	}
  #endif
--- 1176,1182 ----
  	if (cm_freelanceEnabled && dscp == cm_rootSCachep) {
  	  /* we are adding the mount point to the root dir., so call
  	     the freelance code to do the add. */
! 	  code = cm_FreelanceAddMount(leaf, fullCell, volume, NULL);
  	  return code;
  	}
  #endif
***************
*** 1356,1361 ****
--- 1356,1362 ----
  	afs_uuid_t uuid;
  	int flags;
  	char sessionKey[8];
+ 	char *smbname;
  
  	saveDataPtr = ioctlp->inDatap;
  
***************
*** 1400,1405 ****
--- 1401,1413 ----
  		uname = tp;
  		tp += strlen(tp) + 1;
  
+         if (flags & PIOCTL_LOGON) {
+ 		  /* SMB user name with which to associate tokens */
+ 		  smbname = tp;
+ 		  fprintf(stderr, "SMB name = %s\n", smbname);
+ 		  tp += strlen(tp) + 1;
+         }
+ 
  #ifndef DJGPP   /* for win95, session key is back in pioctl */
  		/* uuid */
  		memcpy(&uuid, tp, sizeof(uuid));
***************
*** 1410,1417 ****
  		cellp = cm_rootCellp;
  
  	if (flags & PIOCTL_LOGON) {
!           userp = smb_FindCMUserByName(/*ioctlp->fidp->vcp,*/ uname,
!                                                               ioctlp->fidp->vcp->rname);
  	}
  	
  	/* store the token */
--- 1418,1424 ----
  		cellp = cm_rootCellp;
  
  	if (flags & PIOCTL_LOGON) {
!           userp = smb_FindCMUserByName(smbname, ioctlp->fidp->vcp->rname);
  	}
  	
  	/* store the token */
***************
*** 1875,1878 ****
--- 1882,1897 ----
    return 0;
  }
  #endif /* DJGPP */
+ 
+ long cm_IoctlGetSMBName(smb_ioctl_t *ioctlp, cm_user_t *userp)
+ {
+   smb_user_t *uidp = ioctlp->uidp;
+ 
+   if (uidp && uidp->unp) {
+     memcpy(ioctlp->outDatap, uidp->unp->name, strlen(uidp->unp->name));
+     ioctlp->outDatap += strlen(uidp->unp->name);
+ 	}
+ 
+   return 0;
+ }
  
Index: openafs/src/WINNT/afsd/cm_scache.c
diff -c openafs/src/WINNT/afsd/cm_scache.c:1.3.4.1 openafs/src/WINNT/afsd/cm_scache.c:1.3.4.2
*** openafs/src/WINNT/afsd/cm_scache.c:1.3.4.1	Sat Oct 13 00:19:06 2001
--- openafs/src/WINNT/afsd/cm_scache.c	Sun Jan 20 04:09:12 2002
***************
*** 806,812 ****
  		statusp->UnixModeBits = 0x1ff;
  		statusp->ParentVnode = 0x1;
  		statusp->ParentUnique = 0x1;
! 		statusp->SegSize = 0;
  		statusp->ClientModTime = 0x3b49f6e2;
  		statusp->ServerModTime = 0x3b49f6e2;
  		statusp->Group = 0;
--- 806,812 ----
  		statusp->UnixModeBits = 0x1ff;
  		statusp->ParentVnode = 0x1;
  		statusp->ParentUnique = 0x1;
! 		statusp->ResidencyMask = 0;
  		statusp->ClientModTime = 0x3b49f6e2;
  		statusp->ServerModTime = 0x3b49f6e2;
  		statusp->Group = 0;
Index: openafs/src/WINNT/afsd/cm_vnodeops.c
diff -c openafs/src/WINNT/afsd/cm_vnodeops.c:1.3.4.1 openafs/src/WINNT/afsd/cm_vnodeops.c:1.3.4.2
*** openafs/src/WINNT/afsd/cm_vnodeops.c:1.3.4.1	Sat Oct 13 00:19:06 2001
--- openafs/src/WINNT/afsd/cm_vnodeops.c	Wed Nov 14 22:30:08 2001
***************
*** 959,964 ****
--- 959,965 ----
          cm_scache_t *mountedScp;
          cm_lookupSearch_t rock;
          char tname[256];
+ 	int getroot;
  
  	if (dscp->fid.vnode == 1 && dscp->fid.unique == 1
  	    && strcmp(namep, "..") == 0) {
***************
*** 988,999 ****
  	 * looking for.  Any other non-zero code is an error.
           */
          if (code && code != CM_ERROR_STOPNOW) return code;
!         
!         if (!rock.found)
  		if (flags & CM_FLAG_CHECKPATH)
  			return CM_ERROR_NOSUCHPATH;
  		else
  			return CM_ERROR_NOSUCHFILE;
          
  haveFid:       
  	if ( !tscp )    /* we did not find it in the dnlc */
--- 989,1015 ----
  	 * looking for.  Any other non-zero code is an error.
           */
          if (code && code != CM_ERROR_STOPNOW) return code;
! 
! 	getroot = (dscp==cm_rootSCachep) ;
!         if (!rock.found) {
! 	  if (!cm_freelanceEnabled || !getroot) {
  		if (flags & CM_FLAG_CHECKPATH)
  			return CM_ERROR_NOSUCHPATH;
  		else
  			return CM_ERROR_NOSUCHFILE;
+ 	  }
+ 	  else {  /* nonexistent dir on freelance root, so add it */
+ 	    code = cm_FreelanceAddMount(namep, namep, "root.cell.",
+ 					&rock.fid);
+ 	    if (code < 0) {   /* add mount point failed, so give up */
+ 	      if (flags & CM_FLAG_CHECKPATH)
+ 		return CM_ERROR_NOSUCHPATH;
+ 	      else
+ 		return CM_ERROR_NOSUCHFILE;
+ 	    }
+ 	    tscp = NULL;   /* to force call of cm_GetSCache */
+ 	  }
+ 	}
          
  haveFid:       
  	if ( !tscp )    /* we did not find it in the dnlc */
***************
*** 1190,1198 ****
--- 1206,1222 ----
                  *newRootScpp = cm_rootSCachep;
                  cm_HoldSCache(cm_rootSCachep);
          } else if (*linkp == '\\' || *linkp == '/') {
+ 	  /* formerly, this was considered to be from the AFS root,
+ 	     but this seems to create problems.  instead, we will just
+ 	     reject the link */
+ #if 0
  		strcpy(tsp->data, linkp+1);
                  *newRootScpp = cm_rootSCachep;
                  cm_HoldSCache(cm_rootSCachep);
+ #else
+ 		code = CM_ERROR_NOSUCHPATH;
+ 		goto done;
+ #endif
          }
          else {
  		/* a relative link */
Index: openafs/src/WINNT/afsd/fs.c
diff -c openafs/src/WINNT/afsd/fs.c:1.4 openafs/src/WINNT/afsd/fs.c:1.4.2.1
*** openafs/src/WINNT/afsd/fs.c:1.4	Tue Aug  7 20:03:24 2001
--- openafs/src/WINNT/afsd/fs.c	Wed Nov 14 22:38:47 2001
***************
*** 1754,1760 ****
  	tp = (char *)(space + sizeof(afs_int32));
  	lp = (afs_int32 *)tp;
  	*lp++ = 0x12345678;
! 	size == sizeof(afs_int32) + sizeof(afs_int32);
  	blob.out_size = MAXSIZE;
  	blob.in_size = sizeof(afs_int32);
  	blob.in = space;
--- 1754,1760 ----
  	tp = (char *)(space + sizeof(afs_int32));
  	lp = (afs_int32 *)tp;
  	*lp++ = 0x12345678;
! 	size = sizeof(afs_int32) + sizeof(afs_int32);
  	blob.out_size = MAXSIZE;
  	blob.in_size = sizeof(afs_int32);
  	blob.in = space;
Index: openafs/src/WINNT/afsd/smb.c
diff -c openafs/src/WINNT/afsd/smb.c:1.4 openafs/src/WINNT/afsd/smb.c:1.4.4.1
*** openafs/src/WINNT/afsd/smb.c:1.4	Sat Jun 23 13:26:07 2001
--- openafs/src/WINNT/afsd/smb.c	Wed Nov 14 22:38:47 2001
***************
*** 778,793 ****
  	for(uidp = vcp->usersp; uidp; uidp = uidp->nextp) {
  		if (uid == uidp->userID) {
  			uidp->refCount++;
! #ifdef DEBUG_VERBOSE 
! 		{
!         HANDLE h; char *ptbuf[1],buf[132];
!         h = RegisterEventSource(NULL, "AFS Service - smb_FindUID (Find by UID)");
!         sprintf(buf, "VCP[%x] found-uid[%d] name[%s]",vcp,uidp->userID,(uidp->unp ? uidp->unp->name : ""));
!         ptbuf[0] = buf;
!         ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, ptbuf, NULL);
!         DeregisterEventSource(h);
! 		}
! #endif
          	break;
  		}
          }
--- 778,784 ----
  	for(uidp = vcp->usersp; uidp; uidp = uidp->nextp) {
  		if (uid == uidp->userID) {
  			uidp->refCount++;
! 			osi_LogEvent("AFS smb_FindUID (Find by UID)",NULL," VCP[%x] found-uid[%d] name[%s]",vcp,uidp->userID,(uidp->unp) ? uidp->unp->name : "");
          	break;
  		}
          }
***************
*** 800,815 ****
                  vcp->usersp = uidp;
                  lock_InitializeMutex(&uidp->mx, "uid_t mutex");
                  uidp->userID = uid;
! #ifdef DEBUG_VERBOSE 
! 		{
!         HANDLE h; char *ptbuf[1],buf[132];
!         h = RegisterEventSource(NULL, "AFS Service - smb_FindUID (Find by UID)");
!         sprintf(buf, "VCP[%x] new-uid[%d] name[%s]",vcp,uidp->userID,(uidp->unp ? uidp->unp->name : ""));
!         ptbuf[0] = buf;
!         ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, ptbuf, NULL);
!         DeregisterEventSource(h);
! 		}
! #endif
          }
          lock_ReleaseWrite(&smb_rctLock);
          return uidp;
--- 791,797 ----
                  vcp->usersp = uidp;
                  lock_InitializeMutex(&uidp->mx, "uid_t mutex");
                  uidp->userID = uid;
! 				osi_LogEvent("AFS smb_FindUID (Find by UID)",NULL,"VCP[%x] new-uid[%d] name[%s]",vcp,uidp->userID,(uidp->unp ? uidp->unp->name : ""));
          }
          lock_ReleaseWrite(&smb_rctLock);
          return uidp;
***************
*** 850,865 ****
              continue;
            if (stricmp(uidp->unp->name, usern) == 0) {
              uidp->refCount++;
! #ifdef DEBUG_VERBOSE 
!             {
!               HANDLE h; char *ptbuf[1],buf[132];
!               h = RegisterEventSource(NULL, "AFS Service - smb_FindUserByNameThisSession");
!               sprintf(buf, "VCP[%x] uid[%d] match-name[%s]",vcp,uidp->userID,usern);
!               ptbuf[0] = buf;
!               ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, ptbuf, NULL);
!               DeregisterEventSource(h);
!             }
! #endif
              break;
            } else
              continue;
--- 832,838 ----
              continue;
            if (stricmp(uidp->unp->name, usern) == 0) {
              uidp->refCount++;
! 			osi_LogEvent("AFS smb_FindUserByNameThisSession",NULL,"VCP[%x] uid[%d] match-name[%s]",vcp,uidp->userID,usern);
              break;
            } else
              continue;
***************
*** 5391,5417 ****
  				code = smb_ReceiveCoreWriteRaw (vcp, inp, outp,
  								rwcp);
  			else {
! 				
! #ifdef DEBUG_VERBOSE
! 			    HANDLE h; char *ptbuf[1],buf[132];DWORD err;
! 			 	h = RegisterEventSource(NULL, "AFS Server - Dispatch");
! 		 		sprintf(buf,"%s vcp[%x] lana[%d] lsn[%d]",myCrt_Dispatch(inp->inCom),vcp,vcp->lana,vcp->lsn);
! 			 	ptbuf[0] = buf;
! 			 	ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, ptbuf, NULL);
! 			 	DeregisterEventSource(h);
! #endif
  					code = (*(dp->procp)) (vcp, inp, outp);
! 
! #ifdef DEBUG_VERBOSE
! 					h = RegisterEventSource(NULL, "AFS Server - Dispatch return ");
! 					sprintf(buf,"code[%d]",code-CM_ERROR_BASE);
! 					if (code)
! 						ptbuf[0] = buf;
! 					else
! 						ptbuf[0] = "code[0]";
! 					ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, ptbuf, NULL);
! 					DeregisterEventSource(h);
! #endif
  				}
  
  			if (oldGen != sessionGen) {
--- 5364,5374 ----
  				code = smb_ReceiveCoreWriteRaw (vcp, inp, outp,
  								rwcp);
  			else {
! 					osi_LogEvent("AFS Dispatch %s",(myCrt_Dispatch(inp->inCom)),"vcp[%x] lana[%d] lsn[%d]",vcp,vcp->lana,vcp->lsn);
! 					osi_Log4(afsd_logp,"Dispatch %s vcp[%x] lana[%d] lsn[%d]",(myCrt_Dispatch(inp->inCom)),vcp,vcp->lana,vcp->lsn);
  					code = (*(dp->procp)) (vcp, inp, outp);
! 					osi_LogEvent("AFS Dispatch return",NULL,"Code[%d]",(code==0)?0:code-CM_ERROR_BASE,"");
! 					osi_Log1(afsd_logp,"Dispatch return  code[%d]",(code==0)?0:code-CM_ERROR_BASE);
  				}
  
  			if (oldGen != sessionGen) {
***************
*** 5465,5471 ****
  				    1, ncbp->ncb_length, ptbuf, smbp);
  			DeregisterEventSource(h);
  #else /* DJGPP */
!                         osi_Log1(afsd_logp, "Invalid SMB message, length %d",
                                   ncbp->ncb_length);
  #endif /* !DJGPP */
  
--- 5422,5428 ----
  				    1, ncbp->ncb_length, ptbuf, smbp);
  			DeregisterEventSource(h);
  #else /* DJGPP */
!             osi_Log1(afsd_logp, "Invalid SMB message, length %d",
                                   ncbp->ncb_length);
  #endif /* !DJGPP */
  
Index: openafs/src/WINNT/afsd/smb.h
diff -c openafs/src/WINNT/afsd/smb.h:1.4 openafs/src/WINNT/afsd/smb.h:1.4.4.1
*** openafs/src/WINNT/afsd/smb.h:1.4	Sat Jun 23 13:26:07 2001
--- openafs/src/WINNT/afsd/smb.h	Wed Nov 21 01:45:40 2001
***************
*** 208,213 ****
--- 208,217 ----
  
          /* fid pointer */
          struct smb_fid *fidp;
+ 
+   /* uid pointer */
+   smb_user_t *uidp;
+ 
  } smb_ioctl_t;
  
  /* flags for smb_ioctl_t */
Index: openafs/src/WINNT/afsd/smb3.c
diff -c openafs/src/WINNT/afsd/smb3.c:1.5 openafs/src/WINNT/afsd/smb3.c:1.5.4.1
*** openafs/src/WINNT/afsd/smb3.c:1.5	Sat Jun 23 13:26:07 2001
--- openafs/src/WINNT/afsd/smb3.c	Wed Nov 14 22:38:48 2001
***************
*** 139,162 ****
      pwd = smb_ParseString(tp, &tp);
      usern = smb_ParseString(tp, &tp);
  
-     if (strlen(usern)==0) {
-         /*return CM_ERROR_NOACCESS;*/
-         newUid = 0;   /* always assign uid 0 for blank username */
-         uidp = smb_FindUID(vcp, newUid, SMB_FLAG_CREATE);
- #ifdef DEBUG_VERBOSE
- 		{
-         HANDLE h; char *ptbuf[1],buf[132];
-         h = RegisterEventSource(NULL, "AFS Service - smb_ReceiveV3SessionSetupX");
-         sprintf(buf, "VCP[%x] lsn[%d] anonymous, uid[%d]",vcp,vcp->lsn,uidp->userID);
-         ptbuf[0] = buf;
-         ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, ptbuf, NULL);
-         DeregisterEventSource(h);
- 		}
- #endif
-         smb_ReleaseUID(uidp);
-         goto done;
-     }
- 
      /* On Windows 2000, this function appears to be called more often than
         it is expected to be called. This resulted in multiple smb_user_t
         records existing all for the same user session which results in all
--- 139,144 ----
***************
*** 171,186 ****
          unp = uidp->unp;
          userp = unp->userp;
          newUid = (unsigned short)uidp->userID;  /* For some reason these are different types!*/
! #ifdef DEBUG_VERBOSE
!         {
! 		   HANDLE h; char *ptbuf[1],buf[132];
! 			h = RegisterEventSource(NULL, "AFS Service - smb_ReceiveV3SessionSetupX");
! 			sprintf(buf,"FindUserByName:VCP[%x],Lana[%d],lsn[%d],userid[%d],name[%s]",vcp,vcp->lana,vcp->lsn,newUid,usern);
! 			ptbuf[0] = buf;
! 			ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, ptbuf, NULL);
! 			DeregisterEventSource(h);
!         }
! #endif
          smb_ReleaseUID(uidp);
      }
      else {
--- 153,160 ----
          unp = uidp->unp;
          userp = unp->userp;
          newUid = (unsigned short)uidp->userID;  /* For some reason these are different types!*/
! 		osi_LogEvent("AFS smb_ReceiveV3SessionSetupX",NULL,"FindUserByName:Lana[%d],lsn[%d],userid[%d],name[%s]",vcp->lana,vcp->lsn,newUid,usern);
! 		osi_Log3(afsd_logp,"smb_ReceiveV3SessionSetupX FindUserByName:Lana[%d],lsn[%d],userid[%d]",vcp->lana,vcp->lsn,newUid);
          smb_ReleaseUID(uidp);
      }
      else {
***************
*** 192,198 ****
          if (!userp)
            userp = cm_NewUser();
          lock_ObtainMutex(&vcp->mx);
!         newUid = vcp->uidCounter++;
          lock_ReleaseMutex(&vcp->mx);
  
          /* Create a new smb_user_t structure and connect them up */
--- 166,172 ----
          if (!userp)
            userp = cm_NewUser();
          lock_ObtainMutex(&vcp->mx);
!         newUid = (strlen(usern)==0)?0:vcp->uidCounter++;
          lock_ReleaseMutex(&vcp->mx);
  
          /* Create a new smb_user_t structure and connect them up */
***************
*** 203,223 ****
          uidp = smb_FindUID(vcp, newUid, SMB_FLAG_CREATE);
          lock_ObtainMutex(&uidp->mx);
          uidp->unp = unp;
! #ifdef DEBUG_VERBOSE
! 		{
! 		   HANDLE h; char *ptbuf[1],buf[132];
! 			h = RegisterEventSource(NULL, "AFS Service - smb_ReceiveV3SessionSetupX");
! 			sprintf(buf,"NewUser:VCP[%x],Lana[%d],lsn[%d],userid[%d],name[%s]",vcp,vcp->lana,vcp->lsn,newUid,usern);
! 			ptbuf[0] = buf;
! 			ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, ptbuf, NULL);
! 			DeregisterEventSource(h);
! 		}
! #endif
          lock_ReleaseMutex(&uidp->mx);
          smb_ReleaseUID(uidp);
      }
  
-  done:
      /* Return UID to the client */
      ((smb_t *)outp)->uid = newUid;
      /* Also to the next chained message */
--- 177,188 ----
          uidp = smb_FindUID(vcp, newUid, SMB_FLAG_CREATE);
          lock_ObtainMutex(&uidp->mx);
          uidp->unp = unp;
! 		osi_LogEvent("AFS smb_ReceiveV3SessionSetupX",NULL,"MakeNewUser:VCP[%x],Lana[%d],lsn[%d],userid[%d],TicketKTCName[%s]",vcp,vcp->lana,vcp->lsn,newUid,usern);
! 		osi_Log4(afsd_logp,"smb_ReceiveV3SessionSetupX MakeNewUser:VCP[%x],Lana[%d],lsn[%d],userid[%d]",vcp,vcp->lana,vcp->lsn,newUid);
          lock_ReleaseMutex(&uidp->mx);
          smb_ReleaseUID(uidp);
      }
  
      /* Return UID to the client */
      ((smb_t *)outp)->uid = newUid;
      /* Also to the next chained message */
***************
*** 619,624 ****
--- 584,591 ----
                  lock_ReleaseWrite(&smb_globalLock);
                  
                  /* now dispatch it */
+ 				osi_LogEvent("AFS-Dispatch-2[%s]",myCrt_2Dispatch(asp->opcode),"vcp[%x] lana[%d] lsn[%d]",vcp,vcp->lana,vcp->lsn);
+ 				osi_Log4(afsd_logp,"AFS Server - Dispatch-2 %s vcp[%x] lana[%d] lsn[%d]",myCrt_2Dispatch(asp->opcode),vcp,vcp->lana,vcp->lsn);
                  code = (*smb_tran2DispatchTable[asp->opcode].procp)(vcp, asp, outp);
  
  		/* if an error is returned, we're supposed to send an error packet,
***************
*** 4137,4143 ****
  {
      cm_user_t *userp;
      /*int newUid;*/
-     smb_user_t *uidp;
      smb_username_t *unp;
  
      unp = smb_FindUserByName(usern, machine, SMB_FLAG_CREATE);
--- 4104,4109 ----
***************
*** 4145,4171 ****
          lock_ObtainMutex(&unp->mx);
          unp->userp = cm_NewUser();
          lock_ReleaseMutex(&unp->mx);
! #ifdef DEBUG_VERBOSE
! 		{       //jimpeter
! 		   HANDLE h; char *ptbuf[1],buf[132];
! 			h = RegisterEventSource(NULL, "AFS Service - smb_FindCMUserByName");
! 			sprintf(buf,"New User name[%s] machine[%s]",usern,machine);
! 			ptbuf[0] = buf;
! 			ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, ptbuf, NULL);
! 			DeregisterEventSource(h);
! 		}
! #endif
!     } 
! #ifdef DEBUG_VERBOSE
! 	  else	{       //jimpeter
! 		   HANDLE h; char *ptbuf[1],buf[132];
! 			h = RegisterEventSource(NULL, "AFS Service - smb_FindCMUserByName");
! 			sprintf(buf,"Found-name[%s] machine[%s]",usern,machine);
! 			ptbuf[0] = buf;
! 			ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, ptbuf, NULL);
! 			DeregisterEventSource(h);
! 		}
! #endif
      return unp->userp;
  }
  
--- 4111,4120 ----
          lock_ObtainMutex(&unp->mx);
          unp->userp = cm_NewUser();
          lock_ReleaseMutex(&unp->mx);
! 		osi_LogEvent("AFS smb_FindCMUserByName New User",NULL,"name[%s] machine[%s]",usern,machine);
!     }  else	{
! 		osi_LogEvent("AFS smb_FindCMUserByName Found",NULL,"name[%s] machine[%s]",usern,machine);
! 	}
      return unp->userp;
  }
  
Index: openafs/src/WINNT/afsd/smb3.h
diff -c openafs/src/WINNT/afsd/smb3.h:1.3 openafs/src/WINNT/afsd/smb3.h:1.3.4.1
*** openafs/src/WINNT/afsd/smb3.h:1.3	Mon Apr 30 02:48:10 2001
--- openafs/src/WINNT/afsd/smb3.h	Wed Nov 21 01:45:40 2001
***************
*** 164,169 ****
--- 164,170 ----
  extern int smb_V3MatchMask(char *namep, char *maskp, int flags);
  
  extern void smb3_Init();
+ extern cm_user_t *smb_FindCMUserByName(/*smb_vc_t *vcp,*/ char *usern, char *machine);
  
  #ifdef DJGPP
  #define DELETE (0x00010000)
Index: openafs/src/WINNT/afsd/smb_ioctl.c
diff -c openafs/src/WINNT/afsd/smb_ioctl.c:1.6 openafs/src/WINNT/afsd/smb_ioctl.c:1.6.2.1
*** openafs/src/WINNT/afsd/smb_ioctl.c:1.6	Thu Sep  6 23:33:10 2001
--- openafs/src/WINNT/afsd/smb_ioctl.c	Wed Nov 14 22:38:48 2001
***************
*** 283,291 ****
  		    osi_Log3(afsd_logp, "Ioctl uid %d user %x name %s",
  			     uidp->userID, userp,
  			     osi_LogSaveString(afsd_logp, uidp->unp->name));
! 		else
  		    osi_Log2(afsd_logp, "Ioctl uid %d user %x no name",
  			     uidp->userID, userp);
  		smb_ReleaseUID(uidp);
  	}
  
--- 283,296 ----
  		    osi_Log3(afsd_logp, "Ioctl uid %d user %x name %s",
  			     uidp->userID, userp,
  			     osi_LogSaveString(afsd_logp, uidp->unp->name));
! 		else {
! 			if (uidp)
  		    osi_Log2(afsd_logp, "Ioctl uid %d user %x no name",
  			     uidp->userID, userp);
+ 			else
+ 		    osi_Log1(afsd_logp, "Ioctl no uid user %x no name",
+ 			     userp);
+ 		}
  		smb_ReleaseUID(uidp);
  	}
  
Index: openafs/src/WINNT/client_config/config.cpp
diff -c openafs/src/WINNT/client_config/config.cpp:1.2 openafs/src/WINNT/client_config/config.cpp:1.2.8.1
*** openafs/src/WINNT/client_config/config.cpp:1.2	Sat Nov  4 05:02:36 2000
--- openafs/src/WINNT/client_config/config.cpp	Wed Nov 14 22:38:48 2001
***************
*** 217,223 ****
     return TRUE;
  }
  
! 
  void Config_GetAuthentFlag (BOOL *pfFlag)
  {
     *pfFlag = FALSE;
--- 217,231 ----
     return TRUE;
  }
  
! #if 0
! /* 	These two functions are not needed as of the 1.2.2a updates.
! 	The old implementation used to 'bind' afslogon.dll to the credentials manager
! 	when the Integrated Logon was selected.
! 
! 	With version 1.2.2a afslogon.dll is always 'bound' to the credentials manager; therefore,
! 	the binding operation is done during installation.  Note: the Integrated Logon is
! 	selected by an entry in the registry (LogonOptions).
! */
  void Config_GetAuthentFlag (BOOL *pfFlag)
  {
     *pfFlag = FALSE;
***************
*** 335,341 ****
        Message (MB_ICONHAND, GetErrorTitle(), IDS_FAILCONFIG_AUTHENT, TEXT("%ld"), status);
     return rc;
  }
! 
  
  void Config_GetTrayIconFlag (BOOL *pfFlag)
  {
--- 343,349 ----
        Message (MB_ICONHAND, GetErrorTitle(), IDS_FAILCONFIG_AUTHENT, TEXT("%ld"), status);
     return rc;
  }
! #endif
  
  void Config_GetTrayIconFlag (BOOL *pfFlag)
  {
***************
*** 811,817 ****
  void Config_GetLanAdapter (ULONG *pnLanAdapter)
  {
     if (!Config_ReadNum (TEXT("LANadapter"), (DWORD*)pnLanAdapter))
!       *pnLanAdapter = 0;
  }
  
  BOOL Config_SetLanAdapter (ULONG nLanAdapter, ULONG *pStatus)
--- 819,825 ----
  void Config_GetLanAdapter (ULONG *pnLanAdapter)
  {
     if (!Config_ReadNum (TEXT("LANadapter"), (DWORD*)pnLanAdapter))
!       *pnLanAdapter = -1;
  }
  
  BOOL Config_SetLanAdapter (ULONG nLanAdapter, ULONG *pStatus)
Index: openafs/src/WINNT/client_config/config.h
diff -c openafs/src/WINNT/client_config/config.h:1.2 openafs/src/WINNT/client_config/config.h:1.2.8.1
*** openafs/src/WINNT/client_config/config.h:1.2	Sat Nov  4 05:02:37 2000
--- openafs/src/WINNT/client_config/config.h	Wed Nov 14 22:38:48 2001
***************
*** 57,65 ****
  BOOL Config_ContactGateway (LPTSTR pszGateway, LPTSTR pszCell);
  void Config_FixGatewayDrives (void);
  
- void Config_GetAuthentFlag (BOOL *pfFlag);
- BOOL Config_SetAuthentFlag (BOOL fFlag, ULONG *pStatus = NULL);
- 
  void Config_GetTrayIconFlag (BOOL *pfFlag);
  BOOL Config_SetTrayIconFlag (BOOL fFlag, ULONG *pStatus = NULL);
  
--- 57,62 ----
Index: openafs/src/WINNT/client_config/dlg_automap.cpp
diff -c openafs/src/WINNT/client_config/dlg_automap.cpp:1.3 openafs/src/WINNT/client_config/dlg_automap.cpp:1.3.4.1
*** openafs/src/WINNT/client_config/dlg_automap.cpp:1.3	Wed Apr  4 08:43:45 2001
--- openafs/src/WINNT/client_config/dlg_automap.cpp	Sun Jan 20 04:09:12 2002
***************
*** 237,265 ****
  
  BOOL DefineDosDrive(DRIVEMAP *pDrive, DDDACTION dddAction)
  {
!    TCHAR szAfsPath[MAX_PATH];
!    TCHAR szDrive[3] = TEXT("?:");
     BOOL fResult = FALSE;
  
     if (!pDrive)
        return FALSE;
  
-    szDrive[0] = pDrive->chDrive;
-    _stprintf(szAfsPath, TEXT("\\Device\\LanmanRedirector\\%s\\%s-AFS\\%s"), szDrive, szHostName, pDrive->szSubmount);
- 
     if (dddAction == DDD_REMOVE) {
!       fResult = DefineDosDevice(DDD_RAW_TARGET_PATH | DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE, szDrive, szAfsPath);
!       if (!fResult)
!          Message (MB_OK | MB_ICONHAND, IDS_ERROR_UNMAP, IDS_ERROR_UNMAP_DESC, TEXT("%08lX"), GetLastError());
     } else if (dddAction == DDD_ADD) {
!       fResult = DefineDosDevice(DDD_RAW_TARGET_PATH, szDrive, szAfsPath);
!       if (!fResult)
!          Message (MB_OK | MB_ICONHAND, IDS_ERROR_MAP, IDS_ERROR_MAP_DESC, TEXT("%08lX"), GetLastError());
     }
  
!    if (fResult)
!          UpdateRegistry(pDrive, dddAction == DDD_REMOVE);
  
     return fResult;
  }   
  
--- 237,275 ----
  
  BOOL DefineDosDrive(DRIVEMAP *pDrive, DDDACTION dddAction)
  {
!     // TCHAR szAfsPath[MAX_PATH];
!     // TCHAR szDrive[3] = TEXT("?:");
     BOOL fResult = FALSE;
  
     if (!pDrive)
        return FALSE;
  
     if (dddAction == DDD_REMOVE) {
!        if (!(fResult=(DisMountDOSDrive(pDrive->chDrive)==NO_ERROR)))
!            Message (MB_OK | MB_ICONHAND, IDS_ERROR_UNMAP, IDS_ERROR_UNMAP_DESC, TEXT("%08lX"), GetLastError());
     } else if (dddAction == DDD_ADD) {
!        if (!(fResult=(MountDOSDrive(pDrive->chDrive, pDrive->szSubmount,FALSE)==NO_ERROR)))
! 	   Message (MB_OK | MB_ICONHAND, IDS_ERROR_MAP, IDS_ERROR_MAP_DESC, TEXT("%08lX"), GetLastError());
     }
+    /*
+      Replace this code with Drive mapping routine that doesn't require different formats for each OS
+      szDrive[0] = pDrive->chDrive;
+      _stprintf(szAfsPath, TEXT("\\Device\\LanmanRedirector\\%s\\%s-AFS\\%s"), szDrive, szHostName, pDrive->szSubmount);
  
!      if (dddAction == DDD_REMOVE) {
!          fResult = DefineDosDevice(DDD_RAW_TARGET_PATH | DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE, szDrive, szAfsPath);
! 	 if (!fResult)
!              Message (MB_OK | MB_ICONHAND, IDS_ERROR_UNMAP, IDS_ERROR_UNMAP_DESC, TEXT("%08lX"), GetLastError());
!      } else if (dddAction == DDD_ADD) {
!           fResult = DefineDosDevice(DDD_RAW_TARGET_PATH, szDrive, szAfsPath);
! 	  if (!fResult)
! 	      Message (MB_OK | MB_ICONHAND, IDS_ERROR_MAP, IDS_ERROR_MAP_DESC, TEXT("%08lX"), GetLastError());
!      }
  
+     */
+    if (fResult)
+        UpdateRegistry(pDrive, dddAction == DDD_REMOVE);
+    
     return fResult;
  }   
  
Index: openafs/src/WINNT/client_config/dlg_misc.cpp
diff -c openafs/src/WINNT/client_config/dlg_misc.cpp:1.2 openafs/src/WINNT/client_config/dlg_misc.cpp:1.2.8.1
*** openafs/src/WINNT/client_config/dlg_misc.cpp:1.2	Sat Nov  4 05:02:37 2000
--- openafs/src/WINNT/client_config/dlg_misc.cpp	Wed Nov 14 22:38:48 2001
***************
*** 95,100 ****
--- 95,107 ----
              case IDCANCEL:
                  Misc_OnCancel(hDlg);
                  break;
+ 			case IDC_AUTOLANA:
+ 				if (IsDlgButtonChecked(hDlg,IDC_AUTOLANA))
+ 					nLanAdapter=-1;
+ 				else
+ 					nLanAdapter=0;
+ 				SP_SetPos (GetDlgItem (hDlg, IDC_LAN_ADAPTER),nLanAdapter);
+ 				EnableWindow(GetDlgItem(hDlg,IDC_LAN_ADAPTER),(nLanAdapter!=-1));
              }
           break;
  
***************
*** 129,135 ****
        fFirstTime = FALSE;
     }
  
!    CreateSpinner (GetDlgItem (hDlg, IDC_LAN_ADAPTER), 10, FALSE, nLANA_MIN, nLanAdapter, nLANA_MAX);
     CreateSpinner (GetDlgItem (hDlg, IDC_PROBE), 10, FALSE, csecPROBE_MIN, csecProbe, csecPROBE_MAX);
     CreateSpinner (GetDlgItem (hDlg, IDC_THREADS), 10, FALSE, cTHREADS_MIN, nThreads, cTHREADS_MAX);
     CreateSpinner (GetDlgItem (hDlg, IDC_DAEMONS), 10, FALSE, cDAEMONS_MIN, nDaemons, cDAEMONS_MAX);
--- 136,142 ----
        fFirstTime = FALSE;
     }
  
!    CreateSpinner (GetDlgItem (hDlg, IDC_LAN_ADAPTER), 99, FALSE, nLANA_MIN, nLanAdapter, nLANA_MAX);
     CreateSpinner (GetDlgItem (hDlg, IDC_PROBE), 10, FALSE, csecPROBE_MIN, csecProbe, csecPROBE_MAX);
     CreateSpinner (GetDlgItem (hDlg, IDC_THREADS), 10, FALSE, cTHREADS_MIN, nThreads, cTHREADS_MAX);
     CreateSpinner (GetDlgItem (hDlg, IDC_DAEMONS), 10, FALSE, cDAEMONS_MIN, nDaemons, cDAEMONS_MAX);
***************
*** 137,147 ****
     SetDlgItemText (hDlg, IDC_SYSNAME, szSysName);
     SetDlgItemText (hDlg, IDC_ROOTVOLUME, szRootVolume);
     SetDlgItemText (hDlg, IDC_MOUNTDIR, szMountDir);
  }
  
  void Misc_OnOK (HWND hDlg)
  {
!    nLanAdapter = SP_GetPos (GetDlgItem (hDlg, IDC_LAN_ADAPTER));
  
     csecProbe = SP_GetPos (GetDlgItem (hDlg, IDC_PROBE));
    
--- 144,157 ----
     SetDlgItemText (hDlg, IDC_SYSNAME, szSysName);
     SetDlgItemText (hDlg, IDC_ROOTVOLUME, szRootVolume);
     SetDlgItemText (hDlg, IDC_MOUNTDIR, szMountDir);
+    CheckDlgButton (hDlg, IDC_AUTOLANA, (nLanAdapter==-1));
+    EnableWindow(GetDlgItem(hDlg,IDC_LAN_ADAPTER),(nLanAdapter!=-1));
  }
  
  void Misc_OnOK (HWND hDlg)
  {
! 	nLanAdapter =  (IsDlgButtonChecked(hDlg,IDC_AUTOLANA))?-1
! 		:SP_GetPos (GetDlgItem (hDlg, IDC_LAN_ADAPTER));
  
     csecProbe = SP_GetPos (GetDlgItem (hDlg, IDC_PROBE));
    
***************
*** 161,167 ****
  {
     if (fFirstTime)
        return TRUE;
!    
     if (nLanAdapter != g.Configuration.nLanAdapter) {
        if (!Config_SetLanAdapter (nLanAdapter))
           return FALSE;
--- 171,177 ----
  {
     if (fFirstTime)
        return TRUE;
! 
     if (nLanAdapter != g.Configuration.nLanAdapter) {
        if (!Config_SetLanAdapter (nLanAdapter))
           return FALSE;
Index: openafs/src/WINNT/client_config/drivemap.cpp
diff -c openafs/src/WINNT/client_config/drivemap.cpp:1.5 openafs/src/WINNT/client_config/drivemap.cpp:1.5.4.3
*** openafs/src/WINNT/client_config/drivemap.cpp:1.5	Thu Mar 29 18:18:55 2001
--- openafs/src/WINNT/client_config/drivemap.cpp	Sun Jan 20 04:09:12 2002
***************
*** 10,30 ****
  extern "C" {
  #include <afs/param.h>
  #include <afs/stds.h>
  }
- 
  #include <windows.h>
  #include <stdlib.h>
  #include <stdio.h>
  #include <WINNT/TaLocale.h>
  #include "drivemap.h"
! 
  
  /*
   * REGISTRY ___________________________________________________________________
   *
   */
  
! static const TCHAR AFSConfigKeyName[] = TEXT("SYSTEM\\CurrentControlSet\\Services\\TransarcAFSDaemon\\Parameters");
  
  
  /*
--- 10,33 ----
  extern "C" {
  #include <afs/param.h>
  #include <afs/stds.h>
+ #include <rx/rxkad.h>
  }
  #include <windows.h>
  #include <stdlib.h>
  #include <stdio.h>
  #include <WINNT/TaLocale.h>
  #include "drivemap.h"
! #include <time.h>
! #include <adssts.h>
! #include <osilog.h>
  
  /*
   * REGISTRY ___________________________________________________________________
   *
   */
  
! #undef AFSConfigKeyName
! const TCHAR sAFSConfigKeyName[] = TEXT("SYSTEM\\CurrentControlSet\\Services\\TransarcAFSDaemon\\Parameters");
  
  
  /*
***************
*** 452,458 ****
     TCHAR szValue[128];
     HKEY hKey;
  
!    _stprintf(szKeyName, TEXT("%s\\GlobalAutoMapper"), AFSConfigKeyName);
  
     if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
        return FALSE;
--- 455,461 ----
     TCHAR szValue[128];
     HKEY hKey;
  
!    _stprintf(szKeyName, TEXT("%s\\GlobalAutoMapper"), sAFSConfigKeyName);
  
     if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
        return FALSE;
***************
*** 637,643 ****
     Resource.lpLocalName = szLocal;
     Resource.lpRemoteName = szRemote;
  
!    DWORD rc = WNetAddConnection2 (&Resource, NULL, NULL, ((fPersistent) ? CONNECT_UPDATE_PROFILE : 0));
     if (rc == NO_ERROR)
        return TRUE;
  
--- 640,647 ----
     Resource.lpLocalName = szLocal;
     Resource.lpRemoteName = szRemote;
  
!    // DWORD rc = WNetAddConnection2 (&Resource, NULL, NULL, ((fPersistent) ? CONNECT_UPDATE_PROFILE : 0));
!    DWORD rc=MountDOSDrive(chDrive,szSubmount,fPersistent);
     if (rc == NO_ERROR)
        return TRUE;
  
***************
*** 649,658 ****
  
  BOOL InactivateDriveMap (TCHAR chDrive, DWORD *pdwStatus)
  {
!    TCHAR szLocal[ MAX_PATH ] = TEXT("*:");
!    szLocal[0] = chDrive;
! 
!    DWORD rc = WNetCancelConnection (szLocal, FALSE);
     if (rc == NO_ERROR)
        return TRUE;
  
--- 653,659 ----
  
  BOOL InactivateDriveMap (TCHAR chDrive, DWORD *pdwStatus)
  {
!    DWORD rc = DisMountDOSDrive(chDrive, FALSE);
     if (rc == NO_ERROR)
        return TRUE;
  
***************
*** 745,752 ****
--- 746,756 ----
        pszSubmount = &szMapping[ lstrlen(cszLANMANDEVICE) ];
  
        if (IsWindows2000())
+ 	  {
            if (*(pszSubmount) != TEXT(';'))
               return FALSE;
+ 	  } else 
+ 		--pszSubmount;
  
        if (toupper(*(++pszSubmount)) != chDrive)
           return FALSE;
***************
*** 758,765 ****
            if (*(++pszSubmount) != TEXT('0'))
               return FALSE;
  
!       if (*(++pszSubmount) != TEXT('\\'))
!          return FALSE;
        for (++pszSubmount; *pszSubmount && (*pszSubmount != TEXT('\\')); ++pszSubmount)
           if (!lstrncmpi (pszSubmount, TEXT("-afs\\"), lstrlen(TEXT("-afs\\"))))
              break;
--- 762,773 ----
            if (*(++pszSubmount) != TEXT('0'))
               return FALSE;
  
!       // scan for next "\"
!       while (*(++pszSubmount) != TEXT('\\'))
!       {
! 	  if (*pszSubmount==0)
!               return FALSE;
!       }
        for (++pszSubmount; *pszSubmount && (*pszSubmount != TEXT('\\')); ++pszSubmount)
           if (!lstrncmpi (pszSubmount, TEXT("-afs\\"), lstrlen(TEXT("-afs\\"))))
              break;
***************
*** 791,793 ****
--- 799,1182 ----
     return TRUE;
  }
  
+ /* Generate Random User name random acording to time*/
+ DWORD dwOldState=0;
+ TCHAR pUserName[MAXRANDOMNAMELEN];
+ BOOL fUserName=FALSE;
+ #define AFSLogonOptionName TEXT("System\\CurrentControlSet\\Services\\TransarcAFSDaemon\\NetworkProvider")
+ 
+ void SetBitLogonOption(BOOL set,DWORD value)
+ {
+ 
+    RWLogonOption(FALSE,((set)?value | RWLogonOption(TRUE,0):RWLogonOption(TRUE,0) & ~value) );	
+ }
+ 
+ DWORD RWLogonOption(BOOL read,DWORD value)
+ {
+ 	// if read is true then if value==0 return registry value
+ 	// if read and value!=0 then use value to test registry, return TRUE if value bits match value read
+    HKEY hk;
+    DWORD dwDisp;
+ 	DWORD LSPtype, LSPsize;
+ 	DWORD rval;
+    if (read)
+    {
+ 	   rval=0;
+ 		if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSLogonOptionName,0, KEY_QUERY_VALUE, &hk)==ERROR_SUCCESS)
+ 		{
+ 			LSPsize=sizeof(rval);
+ 			RegQueryValueEx(hk, "LogonOptions", NULL,
+ 						&LSPtype, (LPBYTE)&rval, &LSPsize);
+ 			RegCloseKey (hk);
+ 		}
+ 		return (value==0)?rval:((rval & value)==value);
+ 
+    } else {	//write
+ 		if (RegCreateKeyEx (HKEY_LOCAL_MACHINE, AFSLogonOptionName, 0, NULL, 0, KEY_SET_VALUE, NULL, &hk, &dwDisp) == ERROR_SUCCESS)
+ 		{
+ 			RegSetValueEx(hk,TEXT("LogonOptions"),NULL,REG_DWORD,(LPBYTE)&value,sizeof(value));
+ 			RegCloseKey (hk);
+ 		}
+ 		return TRUE;
+    }
+ }
+ 
+ void MapShareName(char *pszCmdLineA)
+ {
+ 	fUserName = TRUE;
+ 	TCHAR *p=pUserName;
+ 	pszCmdLineA++;
+ 	while (*pszCmdLineA && (*pszCmdLineA != ' '))
+ 	{
+ 	  *p++=*pszCmdLineA++;
+ 	}
+ }
+ 
+ void GenRandomName(TCHAR *pname,int len)
+ {
+ 	if (fUserName)
+ 	{		//user name was passed through command line, use once
+ 		fUserName=FALSE;
+ 		return;
+ 	}
+ 	srand( (unsigned)time( NULL ) );
+ 	for (int i=0;i<len;i++)
+ 		pname[i]='a'+(rand() % 26);
+ 	pname[len]=0;
+ 	return;
+ }
+ 
+ /*
+ 	Make a connection using users name
+ 	if fUserName then force a connection
+ */
+ 
+ BOOL TestAndDoMapShare(DWORD dwState)
+ {
+     if ((dwState!=SERVICE_RUNNING) || (dwOldState!=SERVICE_START_PENDING))
+ 	{
+ 		dwOldState=dwState;
+ 		return TRUE;
+ 	}
+ 	dwOldState=SERVICE_RUNNING;
+ 	if (RWLogonOption(TRUE,LOGON_OPTION_HIGHSECURITY))
+ 	    return (DoMapShare() && GlobalMountDrive());
+ 	return GlobalMountDrive();
+ }
+ 
+ BOOL IsServiceActive()
+ {
+    SC_HANDLE hManager;
+    SERVICE_STATUS Status;
+    if ((hManager = OpenSCManager (NULL, NULL, GENERIC_READ)) != NULL)
+       {
+       SC_HANDLE hService;
+       if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"), GENERIC_READ)) != NULL)
+          {
+          QueryServiceStatus (hService, &Status);
+          CloseServiceHandle (hService);
+          }
+ 
+       CloseServiceHandle (hManager);
+       }
+ 
+    return (Status.dwCurrentState == SERVICE_RUNNING) ? TRUE : FALSE;
+ }
+ 
+ void TestAndDoUnMapShare()
+ {
+ 	if (!RWLogonOption(TRUE,LOGON_OPTION_HIGHSECURITY))
+ 		return;
+ 	DoUnMapShare(FALSE);	
+ }
+ 
+ void DoUnMapShare(BOOL drivemap)	//disconnect drivemap 
+ {
+ 	TCHAR szMachine[ MAX_PATH],szPath[MAX_PATH];
+ 	DWORD rc=28;
+ 	HANDLE hEnum;
+ 	LPNETRESOURCE lpnrLocal,lpnr=NULL;
+ 	DWORD res;
+ 	DWORD cbBuffer=16384;
+ 	DWORD cEntries=-1;
+ 	GetComputerName(szMachine,&rc);
+ 	CHAR *pSubmount="";
+    // Initialize the data structure
+ 	if ((res=WNetOpenEnum(RESOURCE_CONNECTED,RESOURCETYPE_DISK,RESOURCEUSAGE_CONNECTABLE,lpnr,&hEnum))!=NO_ERROR)
+ 		return;
+ 	sprintf(szPath,"\\\\%s-afs\\",szMachine);
+ 	_strlwr(szPath);
+ 	lpnrLocal=(LPNETRESOURCE) GlobalAlloc(GPTR,cbBuffer);
+ 	do {
+ 		memset(lpnrLocal,0,cbBuffer);
+ 		if ((res = WNetEnumResource(hEnum,&cEntries,lpnrLocal,&cbBuffer))==NO_ERROR)
+ 		{
+ 			for (DWORD i=0;i<cEntries;i++)
+ 			{
+ 				if (strstr(_strlwr(lpnrLocal[i].lpRemoteName),szPath))
+ 				{
+ 					if ((lpnrLocal[i].lpLocalName) && (strlen(lpnrLocal[i].lpLocalName)>0))
+ 					{
+ 						if (drivemap)
+ 						    DisMountDOSDrive(*lpnrLocal[i].lpLocalName);
+                                                 //WNetCancelConnection(lpnrLocal[i].lpLocalName,TRUE);
+ 					} else
+ 					    DisMountDOSDriveFull(lpnrLocal[i].lpRemoteName);
+ 					//WNetCancelConnection(lpnrLocal[i].lpRemoteName,TRUE);
+ 					DEBUG_EVENT1("AFS DriveUnMap","UnMap-Remote=%x",res);
+ 				}
+ 			}
+ 		}
+ 	} while (res!=ERROR_NO_MORE_ITEMS);
+ 	GlobalFree((HGLOBAL)lpnrLocal);
+ 	WNetCloseEnum(hEnum);
+ }
+ 
+ BOOL DoMapShareChange()
+ {
+ 	DRIVEMAPLIST List;
+ 	TCHAR szMachine[ MAX_PATH],szPath[MAX_PATH];
+ 	DWORD rc=28;
+ 	HANDLE hEnum;
+ 	LPNETRESOURCE lpnrLocal,lpnr=NULL;
+ 	DWORD res;
+ 	DWORD cbBuffer=16384;
+ 	DWORD cEntries=-1;
+ 	GetComputerName(szMachine,&rc);
+ 	CHAR szUser[MAXRANDOMNAMELEN];
+    // Initialize the data structure
+ 	if (!IsServiceActive())
+ 		return TRUE;
+ 	memset (&List, 0x00, sizeof(DRIVEMAPLIST));
+ 	for (size_t ii = 0; ii < 26; ++ii)
+ 		List.aDriveMap[ii].chDrive = chDRIVE_A + ii;
+ 	QueryDriveMapList_ReadSubmounts (&List);
+ 	if ((res=WNetOpenEnum(RESOURCE_CONNECTED,RESOURCETYPE_DISK,RESOURCEUSAGE_CONNECTABLE,lpnr,&hEnum))!=NO_ERROR)
+ 		return FALSE;
+ 	lpnrLocal=(LPNETRESOURCE) GlobalAlloc(GPTR,cbBuffer);
+ 	sprintf(szPath,"\\\\%s-afs\\",szMachine);
+ 	_strlwr(szPath);
+ 	do {
+ 		memset(lpnrLocal,0,cbBuffer);
+ 		if ((res = WNetEnumResource(hEnum,&cEntries,lpnrLocal,&cbBuffer))==NO_ERROR)
+ 		{
+ 			for (DWORD i=0;i<cEntries;i++)
+ 			{
+ 				if (strstr(_strlwr(lpnrLocal[i].lpRemoteName),szPath)==NULL)
+ 					continue;	//only look at real afs mappings
+ 				CHAR * pSubmount=strrchr(lpnrLocal[i].lpRemoteName,'\\')+1;
+ 				if (strcmpi(pSubmount,"all")==0) 
+ 					continue;				// do not remove 'all'
+ 				for (DWORD j=0;j<List.cSubmounts;j++)
+ 				{
+ 					if (
+ 						(List.aSubmounts[j].szSubmount[0]) &&
+ 						(strcmpi(List.aSubmounts[j].szSubmount,pSubmount)==0)
+ 						) 
+ 					{
+ 						List.aSubmounts[j].fInUse=TRUE; 
+ 						goto nextname;
+ 					}
+ 				}
+ 				// wasn't on list so lets remove
+ 				DisMountDOSDrive(pSubmount);
+ 				nextname:;
+ 			}
+ 		}
+ 	} while (res!=ERROR_NO_MORE_ITEMS);
+ 	GlobalFree((HGLOBAL)lpnrLocal);
+ 	WNetCloseEnum(hEnum);
+ 	sprintf(szPath,"\\\\%s-afs\\all",szMachine);
+ 	cbBuffer=MAXRANDOMNAMELEN-1;
+ 	// Lets connect all submounts that weren't connectd
+ 	CHAR * pUser=szUser;
+ 	if (WNetGetUser(szPath,(LPSTR)szUser,&cbBuffer)!=NO_ERROR)
+ 		GenRandomName(szUser,MAXRANDOMNAMELEN-1);
+ 	else {
+ 		if ((pUser=strchr(szUser,'\\'))==NULL)
+ 			return FALSE;
+ 		pUser++;
+ 	}
+ 	for (DWORD j=0;j<List.cSubmounts;j++)
+ 	{
+ 		if (List.aSubmounts[j].fInUse)
+ 			continue;
+ 		sprintf(szPath,"\\\\%s-afs\\%s",szMachine,List.aSubmounts[j].szSubmount);
+ 		NETRESOURCE nr;
+ 		memset (&nr, 0x00, sizeof(NETRESOURCE));
+ 		nr.dwType=RESOURCETYPE_DISK;
+ 		nr.lpLocalName="";
+ 		nr.lpRemoteName=szPath;
+ 		//DWORD res=WNetAddConnection2(&nr,NULL,pUser,0);
+ 		DWORD res=MountDOSDrive(0,List.aSubmounts[j].szSubmount,FALSE,pUser);
+ 	}
+ 	return TRUE;
+ }
+ 
+ BOOL DoMapShare()
+ {
+ 	DRIVEMAPLIST List;
+ 	TCHAR szMachine[ MAX_PATH ];
+ 	TCHAR szPath[ MAX_PATH ];
+ 	DWORD rc=28;
+ 	BOOL bMappedAll=FALSE;
+ 	GetComputerName(szMachine,&rc);
+    // Initialize the data structure
+ 	DEBUG_EVENT0("AFS DoMapShare");
+ 	QueryDriveMapList (&List);
+ 	DoUnMapShare(TRUE);
+ 	// All connections have been removed
+ 	// Lets restore them after making the connection from the random name
+ 
+ 	GenRandomName(pUserName,MAXRANDOMNAMELEN-1);
+ 	for (DWORD i=0;i<List.cSubmounts;i++)
+ 	{
+ 		if (List.aSubmounts[i].szSubmount[0])
+ 		{
+ 			sprintf(szPath,"\\\\%s-afs\\%s",szMachine,List.aSubmounts[i].szSubmount);
+ 			NETRESOURCE nr;
+ 			memset (&nr, 0x00, sizeof(NETRESOURCE));
+ 			nr.dwType=RESOURCETYPE_DISK;
+ 			nr.lpLocalName="";
+ 			nr.lpRemoteName=szPath;
+ 			//DWORD res=WNetAddConnection2(&nr,NULL,pUserName,0);
+ 			DWORD res=MountDOSDrive(0,List.aSubmounts[i].szSubmount,FALSE,pUserName);
+ 			DEBUG_EVENT2("AFS DriveMap","Remote[%s]=%x",szPath,res);
+ 			if (strcmpi("all",List.aSubmounts[i].szSubmount)==0)
+ 				bMappedAll=TRUE;
+ 		}
+ 	}
+ 	if (!bMappedAll)	//make sure all is mapped also
+ 	{
+ 			sprintf(szPath,"\\\\%s-afs\\all",szMachine);
+ 			NETRESOURCE nr;
+ 			memset (&nr, 0x00, sizeof(NETRESOURCE));
+ 			nr.dwType=RESOURCETYPE_DISK;
+ 			nr.lpLocalName="";
+ 			nr.lpRemoteName=szPath;
+ 			DWORD res=MountDOSDrive(0,"all",FALSE,pUserName);
+ 			DEBUG_EVENT2("AFS DriveMap","Remote[%s]=%x",szPath,res);
+ 			if (res==ERROR_SESSION_CREDENTIAL_CONFLICT)
+ 			{
+ 			    DisMountDOSDrive("all");
+ 			    MountDOSDrive(0,"all",FALSE,pUserName);
+ 			}
+ 	}
+ 	for (TCHAR chDrive = chDRIVE_A; chDrive <= chDRIVE_Z; ++chDrive)
+ 	{
+ 		if (List.aDriveMap[chDrive-chDRIVE_A].fActive)
+ 		{
+ 		    DWORD res=MountDOSDrive(chDrive
+ 					    ,List.aDriveMap[chDrive-chDRIVE_A].szSubmount
+ 					    ,List.aDriveMap[chDrive-chDRIVE_A].fPersistent);
+ 		}
+ 	}
+ 	return TRUE;
+ }
+ 
+ BOOL GlobalMountDrive()
+ {
+     char szDriveToMapTo[5];
+     DWORD dwResult;
+     char szKeyName[256];
+     HKEY hKey;
+     DWORD dwIndex = 0;
+     DWORD dwDriveSize;
+     DWORD dwSubMountSize;
+     char unsigned szSubMount[256];
+     char cm_HostName[200];
+     DWORD dwType=sizeof(cm_HostName);
+     if (!IsServiceActive())
+ 	return TRUE;
+     if (!GetComputerName(cm_HostName, &dwType))
+         return TRUE;
+     sprintf(szKeyName, "%s\\GlobalAutoMapper", sAFSConfigKeyName);
+     
+     dwResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_QUERY_VALUE,
+ 			    &hKey);
+     if (dwResult != ERROR_SUCCESS)
+ 	return TRUE;
+     
+     while (1) {
+         dwDriveSize = sizeof(szDriveToMapTo);
+         dwSubMountSize = sizeof(szSubMount);
+         dwResult = RegEnumValue(hKey, dwIndex++, szDriveToMapTo, &dwDriveSize, 
+ 				0, &dwType, szSubMount, &dwSubMountSize);
+         if (dwResult != ERROR_MORE_DATA) {
+ 	    if (dwResult != ERROR_SUCCESS) {
+ 		if (dwResult != ERROR_NO_MORE_ITEMS)
+ 		{
+ 		    DEBUG_EVENT1("AFS DriveMap","Failed to read \GlobalAutoMapper values: %d",dwResult);
+ 		}
+ 		break;
+ 	    }
+ 	}
+ 	dwResult=MountDOSDrive(*szDriveToMapTo,(const char *)szSubMount,FALSE);
+     }
+     RegCloseKey(hKey);
+     return TRUE;
+ }
+ 
+ DWORD MountDOSDrive(char chDrive,const char *szSubmount,BOOL bPersistent,const char * pUsername)
+ {
+     TCHAR szPath[MAX_PATH];
+     TCHAR szClient[MAX_PATH];
+     TCHAR szDrive[3] = TEXT("?:");
+     sprintf(szDrive,"%c:",chDrive);
+     GetClientNetbiosName (szClient);
+     sprintf(szPath,"\\\\%s\\%s",szClient,szSubmount);
+     NETRESOURCE nr;
+     memset (&nr, 0x00, sizeof(NETRESOURCE));
+     nr.dwType=RESOURCETYPE_DISK;
+     nr.lpLocalName=szDrive;
+     nr.lpRemoteName=szPath;
+     nr.dwDisplayType = RESOURCEDISPLAYTYPE_GENERIC;
+     nr.dwDisplayType = RESOURCEDISPLAYTYPE_SHARE;
+     DWORD res=WNetAddConnection2(&nr,NULL,pUsername,(bPersistent)?CONNECT_UPDATE_PROFILE:0);
+     DEBUG_EVENT3("AFS DriveMap","Mount %s Remote[%s]=%x",(bPersistent)?"Persistant" : "NonPresistant",szPath,res);
+     return res;
+ }
+ 
+ DWORD DisMountDOSDriveFull(const char *szPath,BOOL bForce)
+ {
+     DWORD res=WNetCancelConnection(szPath,bForce);
+     DEBUG_EVENT2("AFS DriveMap","Dismount Remote[%s]=%x",szPath,res);
+     return (res==ERROR_NOT_CONNECTED)?NO_ERROR:res;
+ }
+ 
+ DWORD DisMountDOSDrive(const char *pSubmount,BOOL bForce)
+ {
+     TCHAR szPath[MAX_PATH];
+     TCHAR szClient[MAX_PATH];
+     GetClientNetbiosName (szClient);
+     sprintf(szPath,"\\\\%s\\%s",szClient,pSubmount);
+     return DisMountDOSDriveFull(szPath,bForce);
+ }
+ 
+ 
+ DWORD DisMountDOSDrive(const char chDrive,BOOL bForce)
+ {
+     TCHAR szPath[MAX_PATH];
+     sprintf(szPath,"%c:",chDrive);
+     return DisMountDOSDriveFull(szPath,bForce);
+ }
Index: openafs/src/WINNT/client_config/drivemap.h
diff -c openafs/src/WINNT/client_config/drivemap.h:1.2 openafs/src/WINNT/client_config/drivemap.h:1.2.8.2
*** openafs/src/WINNT/client_config/drivemap.h:1.2	Sat Nov  4 05:02:38 2000
--- openafs/src/WINNT/client_config/drivemap.h	Sun Jan 20 04:09:12 2002
***************
*** 85,89 ****
--- 85,108 ----
  BOOL SubmountToPath (PDRIVEMAPLIST pList, LPTSTR pszPath, LPTSTR pszSubmount, BOOL fMarkInUse);
  BOOL PathToSubmount (LPTSTR pszSubmount, LPTSTR pszMapping, LPTSTR pszSubmountReq, ULONG *pStatus);
  
+ BOOL TestAndDoMapShare(DWORD);
+ BOOL DoMapShare();
+ void MapShareName(char *);
+ void DoUnMapShare(BOOL);
+ BOOL DoMapShareChange();
+ DWORD RWLogonOption(BOOL read,DWORD value);
+ BOOL GlobalMountDrive();
+ DWORD MountDOSDrive(char chDrive,const char *szSubmount,BOOL bPresistant=TRUE,const char *puser=NULL);
+ DWORD DisMountDOSDrive(const char *szSubmount,BOOL bForce=TRUE);
+ DWORD DisMountDOSDrive(char chDrive,BOOL bForce=TRUE);
+ DWORD DisMountDOSDriveFull(const char *pPath,BOOL bForce=TRUE);
+ #ifndef DRIVEMAP_DEF_H
+ extern void TestAndDoUnMapShare();
+ extern TCHAR pUserName[];
+ extern BOOL fUserName;
+ extern DWORD RWLogonOption(BOOL read,DWORD value);
+ extern void SetBitLogonOption(BOOL set,DWORD value);
+ extern BOOL TestAndDoMapShare(DWORD);
+ #endif
  #endif
  
Index: openafs/src/WINNT/client_config/resource.h
diff -c openafs/src/WINNT/client_config/resource.h:1.2 openafs/src/WINNT/client_config/resource.h:1.2.8.1
*** openafs/src/WINNT/client_config/resource.h:1.2	Sat Nov  4 05:02:39 2000
--- openafs/src/WINNT/client_config/resource.h	Wed Nov 14 22:38:48 2001
***************
*** 163,168 ****
--- 163,170 ----
  #define IDC_CHANGE                      1059
  #define IDC_DIAG_PARMS                  1060
  #define IDC_ROOTVOLUME					1061
+ #define IDC_AUTOLANA                    1062
+ #define IDC_STATICLANA                  1063
  #define IDC_STATIC                      -1
  
  // Next default values for new objects
***************
*** 173,179 ****
  #define _APS_3D_CONTROLS                     1
  #define _APS_NEXT_RESOURCE_VALUE        122
  #define _APS_NEXT_COMMAND_VALUE         40001
! #define _APS_NEXT_CONTROL_VALUE         1062
  #define _APS_NEXT_SYMED_VALUE           101
  #endif
  #endif
--- 175,181 ----
  #define _APS_3D_CONTROLS                     1
  #define _APS_NEXT_RESOURCE_VALUE        122
  #define _APS_NEXT_COMMAND_VALUE         40001
! #define _APS_NEXT_CONTROL_VALUE         1064
  #define _APS_NEXT_SYMED_VALUE           101
  #endif
  #endif
Index: openafs/src/WINNT/client_config/tab_drives.cpp
diff -c openafs/src/WINNT/client_config/tab_drives.cpp:1.2 openafs/src/WINNT/client_config/tab_drives.cpp:1.2.8.1
*** openafs/src/WINNT/client_config/tab_drives.cpp:1.2	Sat Nov  4 05:02:39 2000
--- openafs/src/WINNT/client_config/tab_drives.cpp	Wed Nov 14 22:38:48 2001
***************
*** 618,623 ****
--- 618,625 ----
  
     FreeDriveMapList (&g.Configuration.NetDrives);
     QueryDriveMapList (&g.Configuration.NetDrives);
+    if (g.Configuration.fLogonAuthent)
+ 	   DoMapShareChange();
  }
  
  
***************
*** 682,687 ****
--- 684,690 ----
        }
  }
  
+ // Action - On Remove submount item
  
  void Submounts_OnRemove (HWND hDlg)
  {
***************
*** 698,703 ****
--- 701,707 ----
  }
  
  
+ // Action - On Add or On Edit a submount item
  void Submounts_EditSubmount (HWND hDlg, PSUBMOUNT pSubmount)
  {
     HWND hList = GetDlgItem (hDlg, IDC_LIST);
Index: openafs/src/WINNT/client_config/tab_general.cpp
diff -c openafs/src/WINNT/client_config/tab_general.cpp:1.2 openafs/src/WINNT/client_config/tab_general.cpp:1.2.8.1
*** openafs/src/WINNT/client_config/tab_general.cpp:1.2	Sat Nov  4 05:02:39 2000
--- openafs/src/WINNT/client_config/tab_general.cpp	Wed Nov 14 22:38:48 2001
***************
*** 10,15 ****
--- 10,16 ----
  extern "C" {
  #include <afs/param.h>
  #include <afs/stds.h>
+ #include <rx/rxkad.h>
  }
  
  #include "afs_config.h"
***************
*** 17,22 ****
--- 18,25 ----
  #include "tab_hosts.h"
  #include "tab_advanced.h"
  
+ #include "drivemap.h"
+ #include <adssts.h>
  
  /*
   * VARIABLES __________________________________________________________________
***************
*** 70,76 ****
  BOOL CALLBACK Status_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
  void Status_OnRefresh (HWND hDlg);
  
- 
  /*
   * ROUTINES ___________________________________________________________________
   *
--- 73,78 ----
***************
*** 220,226 ****
     return TRUE;
  }
  
- 
  BOOL GeneralTab_OnApply (HWND hDlg, BOOL fForce, BOOL fComplainIfInvalid)
  {
     if (!fForce)
--- 222,227 ----
***************
*** 260,267 ****
     BOOL fLogonAuthent = IsDlgButtonChecked (hDlg, IDC_LOGON);
     if (fLogonAuthent != g.Configuration.fLogonAuthent)
        {
!       if (!Config_SetAuthentFlag (fLogonAuthent))
!          return FALSE;
        g.Configuration.fLogonAuthent = fLogonAuthent;
        }
  
--- 261,267 ----
     BOOL fLogonAuthent = IsDlgButtonChecked (hDlg, IDC_LOGON);
     if (fLogonAuthent != g.Configuration.fLogonAuthent)
        {
! 	   SetBitLogonOption(fLogonAuthent,LOGON_OPTION_INTEGRATED);
        g.Configuration.fLogonAuthent = fLogonAuthent;
        }
  
***************
*** 325,331 ****
           Config_GetGatewayName (g.Configuration.szGateway);
  
        Config_GetCellName (g.Configuration.szCell);
!       Config_GetAuthentFlag (&g.Configuration.fLogonAuthent);
        Config_GetTrayIconFlag (&g.Configuration.fShowTrayIcon);
  
        if (!g.fIsWinNT)
--- 325,331 ----
           Config_GetGatewayName (g.Configuration.szGateway);
  
        Config_GetCellName (g.Configuration.szCell);
!       g.Configuration.fLogonAuthent=RWLogonOption(TRUE,LOGON_OPTION_INTEGRATED);
        Config_GetTrayIconFlag (&g.Configuration.fShowTrayIcon);
  
        if (!g.fIsWinNT)
***************
*** 406,411 ****
--- 406,412 ----
  {
     DWORD CurrentState = Config_GetServiceState();
     DWORD DisplayState = GeneralTab_GetDisplayState(hDlg);
+    TestAndDoMapShare(CurrentState);		//Re map mounted drives if necessary
  
     BOOL fInEndState = ((CurrentState == SERVICE_RUNNING) || (CurrentState == SERVICE_STOPPED));
     if (fInEndState && l.hStatus)
***************
*** 684,689 ****
--- 685,691 ----
              {
              g.fNeedRestart = FALSE;
              if (StartService (hService, 0, 0))
+ 				TestAndDoMapShare(SERVICE_START_PENDING);
                 fSuccess = TRUE;
              }
           else // (!fStart)
***************
*** 691,696 ****
--- 693,700 ----
              SERVICE_STATUS Status;
              if (ControlService (hService, SERVICE_CONTROL_STOP, &Status))
                 fSuccess = TRUE;
+ 			   if (g.Configuration.fLogonAuthent)
+ 				   DoUnMapShare(FALSE);
              }
  
           CloseServiceHandle (hService);
Index: openafs/src/WINNT/client_config/lang/en_US/afs_config.rc
diff -c openafs/src/WINNT/client_config/lang/en_US/afs_config.rc:1.2 openafs/src/WINNT/client_config/lang/en_US/afs_config.rc:1.2.8.1
*** openafs/src/WINNT/client_config/lang/en_US/afs_config.rc:1.2	Sat Nov  4 05:02:41 2000
--- openafs/src/WINNT/client_config/lang/en_US/afs_config.rc	Wed Nov 14 22:38:48 2001
***************
*** 348,354 ****
  CAPTION "Miscellaneous Configuration"
  FONT 8, "MS Sans Serif"
  BEGIN
!     EDITTEXT        IDC_LAN_ADAPTER,90,20,32,13,ES_AUTOHSCROLL
      EDITTEXT        IDC_PROBE,90,40,32,13,ES_AUTOHSCROLL
      EDITTEXT        IDC_THREADS,90,60,32,13,ES_AUTOHSCROLL
      EDITTEXT        IDC_DAEMONS,90,80,32,13,ES_AUTOHSCROLL
--- 348,354 ----
  CAPTION "Miscellaneous Configuration"
  FONT 8, "MS Sans Serif"
  BEGIN
!     EDITTEXT        IDC_LAN_ADAPTER,162,22,32,13,ES_AUTOHSCROLL
      EDITTEXT        IDC_PROBE,90,40,32,13,ES_AUTOHSCROLL
      EDITTEXT        IDC_THREADS,90,60,32,13,ES_AUTOHSCROLL
      EDITTEXT        IDC_DAEMONS,90,80,32,13,ES_AUTOHSCROLL
***************
*** 367,374 ****
      LTEXT           "threads",IDC_STATIC,138,82,68,8
      LTEXT           "S&ystem Name:",IDC_STATIC,15,102,71,8
      LTEXT           "&Mount Directory:",IDC_STATIC,15,122,71,8
-     LTEXT           "&Lan Adapter Number:",IDC_STATIC,15,22,71,8
      LTEXT           "&Root Volume:",IDC_STATIC,15,141,71,8
  END
  
  IDD_DIAG_PARMS DIALOG DISCARDABLE  0, 0, 217, 135
--- 367,376 ----
      LTEXT           "threads",IDC_STATIC,138,82,68,8
      LTEXT           "S&ystem Name:",IDC_STATIC,15,102,71,8
      LTEXT           "&Mount Directory:",IDC_STATIC,15,122,71,8
      LTEXT           "&Root Volume:",IDC_STATIC,15,141,71,8
+     CONTROL         "Automatic Lana scan",IDC_AUTOLANA,"Button",
+                     BS_AUTOCHECKBOX | WS_TABSTOP,19,22,82,10
+     RTEXT           "Lana Number:",IDC_STATICLANA,106,24,53,8
  END
  
  IDD_DIAG_PARMS DIALOG DISCARDABLE  0, 0, 217, 135
Index: openafs/src/WINNT/client_creds/NTMakefile
diff -c openafs/src/WINNT/client_creds/NTMakefile:1.2 openafs/src/WINNT/client_creds/NTMakefile:1.2.8.1
*** openafs/src/WINNT/client_creds/NTMakefile:1.2	Sat Nov  4 05:02:45 2000
--- openafs/src/WINNT/client_creds/NTMakefile	Sun Jan 20 04:09:13 2002
***************
*** 14,20 ****
  AFSDEV_AUXCDEFINES = $(AFSDEV_AUXCDEFINES) -I ..\afsd
  
  # include the primary makefile
- 
  !INCLUDE ..\..\config\NTMakefile.$(SYS_NAME)
  !INCLUDE ..\..\config\NTMakefile.version
  
--- 14,19 ----
Index: openafs/src/WINNT/client_creds/advtab.cpp
diff -c openafs/src/WINNT/client_creds/advtab.cpp:1.2 openafs/src/WINNT/client_creds/advtab.cpp:1.2.8.2
*** openafs/src/WINNT/client_creds/advtab.cpp:1.2	Sat Nov  4 05:02:45 2000
--- openafs/src/WINNT/client_creds/advtab.cpp	Wed Nov 21 01:45:44 2001
***************
*** 122,127 ****
--- 122,128 ----
           DWORD dwSize = sizeof(Config);
           QueryServiceConfig (hService, (QUERY_SERVICE_CONFIG*)&Config, sizeof(Config), &dwSize);
           QueryServiceStatus (hService, &Status);
+ 		 TestAndDoMapShare(Status.dwCurrentState);
  
           CloseServiceHandle (hService);
           }
***************
*** 156,161 ****
--- 157,163 ----
        GetString (szStatus, IDS_SERVICE_STARTING);
     else
        GetString (szStatus, IDS_SERVICE_UNKNOWN);
+    TestAndDoMapShare(Status.dwCurrentState);
     SetDlgItemText (hDlg, IDC_SERVICE_STATUS, szStatus);
  
     if (fFinal && GetWindowLong (hDlg, DWL_USER))
***************
*** 194,206 ****
  
              case IDC_SERVICE_START:
                 if (StartService (hService, 0, 0))
                    fSuccess = TRUE;
                 break;
  
              case IDC_SERVICE_STOP:
                 SERVICE_STATUS Status;
!                if (ControlService (hService, SERVICE_CONTROL_STOP, &Status))
!                   fSuccess = TRUE;
                 break;
              }
  
--- 196,212 ----
  
              case IDC_SERVICE_START:
                 if (StartService (hService, 0, 0))
+ 			   {
+ 				  TestAndDoMapShare(SERVICE_START_PENDING);
                    fSuccess = TRUE;
+ 			   }
                 break;
  
              case IDC_SERVICE_STOP:
                 SERVICE_STATUS Status;
! 			   TestAndDoUnMapShare();
!                ControlService (hService, SERVICE_CONTROL_STOP, &Status);
!                fSuccess = TRUE;
                 break;
              }
  
Index: openafs/src/WINNT/client_creds/afswiz.cpp
diff -c openafs/src/WINNT/client_creds/afswiz.cpp:1.2 openafs/src/WINNT/client_creds/afswiz.cpp:1.2.8.1
*** openafs/src/WINNT/client_creds/afswiz.cpp:1.2	Sat Nov  4 05:02:46 2000
--- openafs/src/WINNT/client_creds/afswiz.cpp	Wed Nov 14 22:38:49 2001
***************
*** 225,231 ****
        SC_HANDLE hService;
        if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"), SERVICE_ALL_ACCESS)) != NULL)
           {
!          StartService (hService, 0, 0);
  
           CloseServiceHandle (hService);
           }
--- 225,232 ----
        SC_HANDLE hService;
        if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"), SERVICE_ALL_ACCESS)) != NULL)
           {
!          if (StartService (hService, 0, 0))
! 			TestAndDoMapShare(SERVICE_START_PENDING);
  
           CloseServiceHandle (hService);
           }
***************
*** 253,258 ****
--- 254,260 ----
           {
           QueryServiceStatus (hService, &Status);
           CloseServiceHandle (hService);
+ 		 TestAndDoMapShare(Status.dwCurrentState);
           }
  
        CloseServiceHandle (hManager);
Index: openafs/src/WINNT/client_creds/main.cpp
diff -c openafs/src/WINNT/client_creds/main.cpp:1.2 openafs/src/WINNT/client_creds/main.cpp:1.2.8.2
*** openafs/src/WINNT/client_creds/main.cpp:1.2	Sat Nov  4 05:02:47 2000
--- openafs/src/WINNT/client_creds/main.cpp	Sun Jan 20 04:09:13 2002
***************
*** 14,21 ****
  
  #include "afscreds.h"
  #include "..\afsreg\afsreg.h" // So we can see if the server's installed
  
- 
  /*
   * DEFINITIONS ________________________________________________________________
   *
--- 14,25 ----
  
  #include "afscreds.h"
  #include "..\afsreg\afsreg.h" // So we can see if the server's installed
+ #include "drivemap.h"
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <osilog.h>
+ #include "rxkad.h"
  
  /*
   * DEFINITIONS ________________________________________________________________
   *
***************
*** 69,74 ****
--- 73,80 ----
     return 0;
  }
  
+ #define ISHIGHSECURITY(v) ( ((v) & LOGON_OPTION_HIGHSECURITY)==LOGON_OPTION_HIGHSECURITY)
+ #define REG_CLIENT_PROVIDER_KEY "SYSTEM\\CurrentControlSet\\Services\\TransarcAFSDaemon\\NetworkProvider"
  
  BOOL InitApp (LPSTR pszCmdLineA)
  {
***************
*** 111,120 ****
--- 117,145 ----
           case 'U':
              fUninstall = TRUE;
              break;
+ 		 case ':':
+ 			 MapShareName(pszCmdLineA);
+ 			 break;
+          case 'x':
+          case 'X':
+ 	     DWORD LogonOption;
+ 	     DWORD LSPtype, LSPsize;
+ 	     HKEY NPKey;
+ 	     LSPsize=sizeof(LogonOption);
+ 	     (void) RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_CLIENT_PROVIDER_KEY,
+ 				 0, KEY_QUERY_VALUE, &NPKey);
+ 	     RegQueryValueEx(NPKey, "LogonOptions", NULL,
+                              &LSPtype, (LPBYTE)&LogonOption, &LSPsize);
+ 	     RegCloseKey (NPKey);
+ 	     if (ISHIGHSECURITY(LogonOption))
+ 		 DoMapShare();
+ 	     GlobalMountDrive();
+ 	     return 0;
           }
  
        while (*pszCmdLineA && (*pszCmdLineA != ' '))
           ++pszCmdLineA;
+ 	  if (*pszCmdLineA==' ') ++pszCmdLineA;
        }
  
     if (fInstall)
Index: openafs/src/WINNT/client_osi/libosi.def
diff -c openafs/src/WINNT/client_osi/libosi.def:1.1 openafs/src/WINNT/client_osi/libosi.def:1.1.12.1
*** openafs/src/WINNT/client_osi/libosi.def:1.1	Fri Nov  3 21:16:48 2000
--- openafs/src/WINNT/client_osi/libosi.def	Wed Nov 14 22:38:50 2001
***************
*** 65,67 ****
--- 65,70 ----
  	osi_LogPrint		@58
  	osi_LogSaveString	@59
  	osi_InitPanic		@60
+ 	osi_InitTraceOption @61
+ 	osi_LogEvent0		@62
+ 	osi_LogEvent		@63
Index: openafs/src/WINNT/client_osi/osilog.c
diff -c openafs/src/WINNT/client_osi/osilog.c:1.2 openafs/src/WINNT/client_osi/osilog.c:1.2.4.1
*** openafs/src/WINNT/client_osi/osilog.c:1.2	Mon Apr 30 02:49:51 2001
--- openafs/src/WINNT/client_osi/osilog.c	Wed Nov 14 22:38:50 2001
***************
*** 330,332 ****
--- 330,384 ----
  	if (logp)
  		logp->enabled = 0;
  }
+ 
+ #define REG_CLIENT_PARMS_KEY  "SYSTEM\\CurrentControlSet\\Services\\TransarcAFSDaemon\\Parameters"
+ #define TRACE_OPTION_EVENT 1
+ #define ISLOGONTRACE(v) ( ((v) & TRACE_OPTION_EVENT)==TRACE_OPTION_EVENT)
+ 
+ DWORD osi_TraceOption=0;
+ 
+ void osi_InitTraceOption()
+ {
+ 	DWORD LSPtype, LSPsize;
+ 	HKEY NPKey;
+ 	(void) RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_CLIENT_PARMS_KEY,
+ 		    0, KEY_QUERY_VALUE, &NPKey);
+ 	LSPsize=sizeof(osi_TraceOption);
+ 	RegQueryValueEx(NPKey, "TraceOption", NULL,
+ 				&LSPtype, (LPBYTE)&osi_TraceOption, &LSPsize);
+ }
+ 
+ 
+ #define MAXBUF_ 131
+ void osi_LogEvent0(char *a,char *b) 
+ {
+ 	HANDLE h; char *ptbuf[1],buf[MAXBUF_+1];
+ 	if (!ISLOGONTRACE(osi_TraceOption))
+ 		return;
+ 	h = RegisterEventSource(NULL, a);
+ 	ptbuf[0] = b;
+ 	ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (const char **)ptbuf, NULL);
+ 	DeregisterEventSource(h);
+ }
+ 
+ 
+ void osi_LogEvent(char *a,char *b,char *c,...) 
+ {
+ 	HANDLE h; char *ptbuf[1],buf[MAXBUF_+1];
+ 	va_list marker;
+ 	if (!ISLOGONTRACE(osi_TraceOption))
+ 		return;
+ 	if (b)
+ 	{
+ 		wsprintf(buf,a,b);
+ 		h = RegisterEventSource(NULL, buf);
+ 	}
+ 	else
+ 		h = RegisterEventSource(NULL, a);
+ 	va_start(marker,c);
+ 	_vsnprintf(buf,MAXBUF_,c,marker);
+ 	ptbuf[0] = buf;
+ 	ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (const char **)ptbuf, NULL);\
+ 	DeregisterEventSource(h);
+ 	va_end(marker);
+ }
Index: openafs/src/WINNT/client_osi/osilog.h
diff -c openafs/src/WINNT/client_osi/osilog.h:1.2 openafs/src/WINNT/client_osi/osilog.h:1.2.4.1
*** openafs/src/WINNT/client_osi/osilog.h:1.2	Mon Apr 30 02:49:51 2001
--- openafs/src/WINNT/client_osi/osilog.h	Wed Nov 14 22:38:50 2001
***************
*** 6,13 ****
   *
   */
  
- /* Copyright (C) 1994 Cazamar Systems, Inc. */
- 
  #ifndef _OSI_LOG_H__
  #define _OSI_LOG_H__ 1
  
--- 6,11 ----
***************
*** 82,87 ****
--- 80,88 ----
  extern void osi_LogPrint(osi_log_t *logp, FILE_HANDLE handle);
  
  extern char *osi_LogSaveString(osi_log_t *logp, char *s);
+ extern void osi_InitTraceOption();
+ extern void osi_LogEvent0(char *a,char *b);
+ extern void osi_LogEvent(char *a,char *b,char *c,...);
  
  /* define macros */
  #define osi_Log0(l,f)		osi_LogAdd((l), (f), 0, 0, 0, 0)
***************
*** 89,93 ****
--- 90,146 ----
  #define osi_Log2(l,f,a,b)	osi_LogAdd((l), (f), (long) (a), (long) (b), 0, 0)
  #define osi_Log3(l,f,a,b,c)	osi_LogAdd((l), (f), (long) (a), (long) (b), (long) (c), 0)
  #define osi_Log4(l,f,a,b,c,d)	osi_LogAdd((l), (f), (long) (a), (long) (b), (long) (c), (long) (d))
+ 
+ #ifdef DEBUG_VERBOSE
+ #define DEBUG_EVENT1(a,b,c) {HANDLE h; char *ptbuf[1],buf[132];\
+ 	h = RegisterEventSource(NULL, a);\
+ 	sprintf(buf, b,c);\
+ 	ptbuf[0] = buf;\
+ 	ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (const char **)ptbuf, NULL);\
+ 	DeregisterEventSource(h);}
+ #define DEBUG_EVENT0(a) {HANDLE h; char *ptbuf[1];\
+ 	h = RegisterEventSource(NULL, a);\
+ 	ptbuf[0] = "";\
+ 	ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0,(const char **) ptbuf, NULL);\
+ 	DeregisterEventSource(h);}
+ #define DEBUG_EVENT2(a,b,c,d) {HANDLE h; char *ptbuf[1],buf[132];\
+ 	h = RegisterEventSource(NULL, a);\
+ 	sprintf(buf, b,c,d);\
+ 	ptbuf[0] = buf;\
+ 	ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0,(const char **) ptbuf, NULL);\
+ 	DeregisterEventSource(h);}
+ #define DEBUG_EVENT3(a,b,c,d,e) {HANDLE h; char *ptbuf[1],buf[132];\
+ 	h = RegisterEventSource(NULL, a);\
+ 	sprintf(buf, b,c,d,e);\
+ 	ptbuf[0] = buf;\
+ 	ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0,(const char **)ptbuf, NULL);\
+ 	DeregisterEventSource(h);}
+ #define DEBUG_EVENT4(a,b,c,d,e,f) {HANDLE h; char *ptbuf[1],buf[132];\
+ 	h = RegisterEventSource(NULL, a);\
+ 	sprintf(buf, b,c,d,e,f);\
+ 	ptbuf[0] = buf;\
+ 	ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0,(const char **) ptbuf, NULL);\
+ 	DeregisterEventSource(h);}
+ #define DEBUG_EVENT5(a,b,c,d,e,f,g) {HANDLE h; char *ptbuf[1],buf[132];\
+ 	h = RegisterEventSource(NULL, a);\
+ 	sprintf(buf, b,c,d,e,f,g);\
+ 	ptbuf[0] = buf;\
+ 	ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0,(const char **) ptbuf, NULL);\
+ 	DeregisterEventSource(h);}
+ #define DEBUG_EVENT6(a,b,c,d,e,f,g,h) {HANDLE h; char *ptbuf[1],buf[132];\
+ 	h = RegisterEventSource(NULL, a);\
+ 	sprintf(buf,b,c,d,e,f,g,h);\
+ 	ptbuf[0] = buf;\
+ 	ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0,(const char **) ptbuf, NULL);\
+ 	DeregisterEventSource(h);}
+ #else
+ #define DEBUG_EVENT0(a)
+ #define DEBUG_EVENT1(a,b,c)
+ #define DEBUG_EVENT2(a,b,c,d)
+ #define DEBUG_EVENT3(a,b,c,d,e)
+ #define DEBUG_EVENT4(a,b,c,d,e,f)
+ #define DEBUG_EVENT5(a,b,c,d,e,f,g)
+ #define DEBUG_EVENT6(a,b,c,d,e,f,g,h)
+ #endif
  
  #endif /*  _OSI_LOG_H__ */
Index: openafs/src/WINNT/install/InstallShield5/Default.txt
diff -c openafs/src/WINNT/install/InstallShield5/Default.txt:1.2 openafs/src/WINNT/install/InstallShield5/Default.txt:1.2.2.2
*** openafs/src/WINNT/install/InstallShield5/Default.txt:1.2	Thu Sep  6 22:55:00 2001
--- openafs/src/WINNT/install/InstallShield5/Default.txt	Sun Jan 20 04:09:13 2002
***************
*** 195,201 ****
--- 195,203 ----
  ---Comment---=
  (Default)=S,
  Class=N,2
+ LogonOptions=N,0
  Name=S,TransarcAFSDaemon
+ LogonScript=S,<TARGETDIR>\Client\Program\afscreds.exe -:%s -x
  ProviderPath=S,<LOGON_DLL>
  AuthentProviderPath=S,<LOGON_DLL>
  
Index: openafs/src/WINNT/install/InstallShield5/GenFileGroups.bat
diff -c openafs/src/WINNT/install/InstallShield5/GenFileGroups.bat:1.5 openafs/src/WINNT/install/InstallShield5/GenFileGroups.bat:1.5.2.1
*** openafs/src/WINNT/install/InstallShield5/GenFileGroups.bat:1.5	Thu Sep  6 22:55:00 2001
--- openafs/src/WINNT/install/InstallShield5/GenFileGroups.bat	Sun Jan 20 04:09:13 2002
***************
*** 54,60 ****
  echo file0=%IS5_DEST%\root.client\usr\vice\etc\afs_config.exe >> Client_Common_Files.fgl
  echo file1=%IS5_DEST%\lib\afsrpc.dll >> Client_Common_Files.fgl
  echo file2=%IS5_DEST%\lib\afsauthent.dll >> Client_Common_Files.fgl
! echo file3=%IS5_DEST%\lib\pthread.dll >> Client_Common_Files.fgl
  echo file4=%IS5_DEST%\root.server\usr\afs\bin\afsprocmgmt.dll >> Client_Common_Files.fgl
  echo file5=%IS5_DEST%\root.server\usr\afs\bin\TaAfsAppLib.dll >> Client_Common_Files.fgl
  echo file6=%IS5_DEST%\root.server\usr\afs\bin\afsadminutil.dll >> Client_Common_Files.fgl
--- 54,60 ----
  echo file0=%IS5_DEST%\root.client\usr\vice\etc\afs_config.exe >> Client_Common_Files.fgl
  echo file1=%IS5_DEST%\lib\afsrpc.dll >> Client_Common_Files.fgl
  echo file2=%IS5_DEST%\lib\afsauthent.dll >> Client_Common_Files.fgl
! echo file3=%IS5_DEST%\lib\afspthread.dll >> Client_Common_Files.fgl
  echo file4=%IS5_DEST%\root.server\usr\afs\bin\afsprocmgmt.dll >> Client_Common_Files.fgl
  echo file5=%IS5_DEST%\root.server\usr\afs\bin\TaAfsAppLib.dll >> Client_Common_Files.fgl
  echo file6=%IS5_DEST%\root.server\usr\afs\bin\afsadminutil.dll >> Client_Common_Files.fgl
***************
*** 130,136 ****
  echo file0=%IS5_DEST%\root.client\usr\vice\etc\afs_config.exe >> Light_Client_Common_Files.fgl
  echo file1=%IS5_DEST%\lib\afsrpc.dll >> Light_Client_Common_Files.fgl
  echo file2=%IS5_DEST%\lib\afsauthent.dll >> Light_Client_Common_Files.fgl
! echo file3=%IS5_DEST%\lib\pthread.dll >> Light_Client_Common_Files.fgl
  echo file4=%IS5_DEST%\root.server\usr\afs\bin\afsprocmgmt.dll >> Light_Client_Common_Files.fgl
  echo file5=%IS5_DEST%\root.server\usr\afs\bin\TaAfsAppLib.dll >> Light_Client_Common_Files.fgl
  echo file6=%IS5_DEST%\root.server\usr\afs\bin\afsadminutil.dll >> Light_Client_Common_Files.fgl
--- 130,136 ----
  echo file0=%IS5_DEST%\root.client\usr\vice\etc\afs_config.exe >> Light_Client_Common_Files.fgl
  echo file1=%IS5_DEST%\lib\afsrpc.dll >> Light_Client_Common_Files.fgl
  echo file2=%IS5_DEST%\lib\afsauthent.dll >> Light_Client_Common_Files.fgl
! echo file3=%IS5_DEST%\lib\afspthread.dll >> Light_Client_Common_Files.fgl
  echo file4=%IS5_DEST%\root.server\usr\afs\bin\afsprocmgmt.dll >> Light_Client_Common_Files.fgl
  echo file5=%IS5_DEST%\root.server\usr\afs\bin\TaAfsAppLib.dll >> Light_Client_Common_Files.fgl
  echo file6=%IS5_DEST%\root.server\usr\afs\bin\afsadminutil.dll >> Light_Client_Common_Files.fgl
***************
*** 188,194 ****
  echo file0=%IS5_DEST%\root.client\usr\vice\etc\afs_config.exe >> Light95_Client_Common_Files.fgl
  echo file1=%IS5_DEST%\lib\afsrpc.dll >> Light95_Client_Common_Files.fgl
  echo file2=%IS5_DEST%\lib\afsauthent.dll >> Light95_Client_Common_Files.fgl
! echo file3=%IS5_DEST%\lib\win95\pthread.dll >> Light95_Client_Common_Files.fgl
  echo file4=%IS5_DEST%\root.server\usr\afs\bin\TaAfsAppLib.dll >> Light95_Client_Common_Files.fgl
  echo file5=%IS5_DEST%\root.server\usr\afs\bin\afsadminutil.dll >> Light95_Client_Common_Files.fgl
  echo file6=%IS5_DEST%\root.server\usr\afs\bin\afsclientadmin.dll >> Light95_Client_Common_Files.fgl
--- 188,194 ----
  echo file0=%IS5_DEST%\root.client\usr\vice\etc\afs_config.exe >> Light95_Client_Common_Files.fgl
  echo file1=%IS5_DEST%\lib\afsrpc.dll >> Light95_Client_Common_Files.fgl
  echo file2=%IS5_DEST%\lib\afsauthent.dll >> Light95_Client_Common_Files.fgl
! echo file3=%IS5_DEST%\lib\win95\afspthread.dll >> Light95_Client_Common_Files.fgl
  echo file4=%IS5_DEST%\root.server\usr\afs\bin\TaAfsAppLib.dll >> Light95_Client_Common_Files.fgl
  echo file5=%IS5_DEST%\root.server\usr\afs\bin\afsadminutil.dll >> Light95_Client_Common_Files.fgl
  echo file6=%IS5_DEST%\root.server\usr\afs\bin\afsclientadmin.dll >> Light95_Client_Common_Files.fgl
***************
*** 258,264 ****
  echo file6=%IS5_DEST%\root.server\usr\afs\bin\afsadminutil.dll >> Server_Common_Files.fgl
  echo file7=%IS5_DEST%\lib\afsrpc.dll >> Server_Common_Files.fgl
  echo file8=%IS5_DEST%\lib\afsauthent.dll >> Server_Common_Files.fgl
! echo file9=%IS5_DEST%\lib\pthread.dll >> Server_Common_Files.fgl
  echo file10=%IS5_DEST%\root.server\usr\afs\bin\TaAfsAppLib.dll >> Server_Common_Files.fgl
  echo file11=%IS5_DEST%\root.server\usr\afs\bin\afsprocmgmt.dll >> Server_Common_Files.fgl
  echo.  >> Server_Common_Files.fgl
--- 258,264 ----
  echo file6=%IS5_DEST%\root.server\usr\afs\bin\afsadminutil.dll >> Server_Common_Files.fgl
  echo file7=%IS5_DEST%\lib\afsrpc.dll >> Server_Common_Files.fgl
  echo file8=%IS5_DEST%\lib\afsauthent.dll >> Server_Common_Files.fgl
! echo file9=%IS5_DEST%\lib\afspthread.dll >> Server_Common_Files.fgl
  echo file10=%IS5_DEST%\root.server\usr\afs\bin\TaAfsAppLib.dll >> Server_Common_Files.fgl
  echo file11=%IS5_DEST%\root.server\usr\afs\bin\afsprocmgmt.dll >> Server_Common_Files.fgl
  echo.  >> Server_Common_Files.fgl
***************
*** 312,318 ****
  echo file6=%IS5_DEST%\root.server\usr\afs\bin\afsadminutil.dll >> Control_Center_Common_Files.fgl
  echo file7=%IS5_DEST%\lib\afsrpc.dll >> Control_Center_Common_Files.fgl
  echo file8=%IS5_DEST%\lib\afsauthent.dll >> Control_Center_Common_Files.fgl
! echo file9=%IS5_DEST%\lib\pthread.dll >> Control_Center_Common_Files.fgl
  echo file10=%IS5_DEST%\root.server\usr\afs\bin\TaAfsAppLib.dll >> Control_Center_Common_Files.fgl
  echo file11=%IS5_DEST%\root.client\usr\vice\etc\afs_config.exe >> Control_Center_Common_Files.fgl
  echo.  >> Control_Center_Common_Files.fgl
--- 312,318 ----
  echo file6=%IS5_DEST%\root.server\usr\afs\bin\afsadminutil.dll >> Control_Center_Common_Files.fgl
  echo file7=%IS5_DEST%\lib\afsrpc.dll >> Control_Center_Common_Files.fgl
  echo file8=%IS5_DEST%\lib\afsauthent.dll >> Control_Center_Common_Files.fgl
! echo file9=%IS5_DEST%\lib\afspthread.dll >> Control_Center_Common_Files.fgl
  echo file10=%IS5_DEST%\root.server\usr\afs\bin\TaAfsAppLib.dll >> Control_Center_Common_Files.fgl
  echo file11=%IS5_DEST%\root.client\usr\vice\etc\afs_config.exe >> Control_Center_Common_Files.fgl
  echo.  >> Control_Center_Common_Files.fgl
Index: openafs/src/WINNT/install/InstallShield5/NTMakefile
diff -c openafs/src/WINNT/install/InstallShield5/NTMakefile:1.6 openafs/src/WINNT/install/InstallShield5/NTMakefile:1.6.2.1
*** openafs/src/WINNT/install/InstallShield5/NTMakefile:1.6	Thu Sep  6 22:55:00 2001
--- openafs/src/WINNT/install/InstallShield5/NTMakefile	Wed Nov 14 22:38:50 2001
***************
*** 35,41 ****
  	$(DESTDIR)\bin\util_cr.exe @ "$(AFSROOT)\src\WINNT\install\InstallShield5\packageweb.pfw" "[Options] Comments=$(AFSBUILDCOMMENTS)"
  	$(DESTDIR)\bin\util_cr.exe @ "$(AFSROOT)\src\WINNT\install\InstallShield5\packageweb.pfw" "[Options] ApplicationName=AFSforWindows"
  	$(DESTDIR)\bin\util_cr.exe @ "$(AFSROOT)\src\WINNT\install\InstallShield5\packageweb.pfw" "[Options] Company=Open AFS"
! 	$(DESTDIR)\bin\util_cr.exe @ "$(AFSROOT)\src\WINNT\install\InstallShield5\packageweb.pfw" "[Options] Title=AFS for Windows"
  	$(DESTDIR)\bin\util_cr.exe @ "$(AFSROOT)\src\WINNT\install\InstallShield5\packageweb.pfw" "[Options] OutputSpec="$(DESTDIR)\WinInstall\PackageWeb\AFSforWindows.exe"
  !     ENDIF
      CreateISDirTree.bat
--- 35,41 ----
  	$(DESTDIR)\bin\util_cr.exe @ "$(AFSROOT)\src\WINNT\install\InstallShield5\packageweb.pfw" "[Options] Comments=$(AFSBUILDCOMMENTS)"
  	$(DESTDIR)\bin\util_cr.exe @ "$(AFSROOT)\src\WINNT\install\InstallShield5\packageweb.pfw" "[Options] ApplicationName=AFSforWindows"
  	$(DESTDIR)\bin\util_cr.exe @ "$(AFSROOT)\src\WINNT\install\InstallShield5\packageweb.pfw" "[Options] Company=Open AFS"
! 	$(DESTDIR)\bin\util_cr.exe @ "$(AFSROOT)\src\WINNT\install\InstallShield5\packageweb.pfw" "[Options] Title=Open AFS for Windows"
  	$(DESTDIR)\bin\util_cr.exe @ "$(AFSROOT)\src\WINNT\install\InstallShield5\packageweb.pfw" "[Options] OutputSpec="$(DESTDIR)\WinInstall\PackageWeb\AFSforWindows.exe"
  !     ENDIF
      CreateISDirTree.bat
***************
*** 62,69 ****
  	$(DEL) /q $(DESTDIR)\Wininstall\PackageWeb\*.*
  	$(ISWEB)\Pftwwiz.exe $(AFSROOT)\src\winnt\install\InstallShield5\PackageWeb.pfw -s -a 
  !ENDIF
! 	xcopy/s/e/y "Media\Transarc AFS\Disk Images\disk1\*.*" $(DESTDIR)\WinInstall
  	copy AFS_component_version_number.txt $(DESTDIR)\WinInstall\Version.txt
! 	$(DEL) /q "Media\Transarc AFS\Disk Images\disk1\*.*"
  
  install: prep build
--- 62,69 ----
  	$(DEL) /q $(DESTDIR)\Wininstall\PackageWeb\*.*
  	$(ISWEB)\Pftwwiz.exe $(AFSROOT)\src\winnt\install\InstallShield5\PackageWeb.pfw -s -a 
  !ENDIF
! 	xcopy /s/e/y "Media\OpenAFS\Disk Images\disk1\*.*" $(DESTDIR)\WinInstall
  	copy AFS_component_version_number.txt $(DESTDIR)\WinInstall\Version.txt
! 	$(DEL) /q "Media\OpenAFS\Disk Images\disk1\*.*"
  
  install: prep build
Index: openafs/src/WINNT/install/InstallShield5/PackageWeb.pfw
diff -c openafs/src/WINNT/install/InstallShield5/PackageWeb.pfw:1.1 openafs/src/WINNT/install/InstallShield5/PackageWeb.pfw:1.1.2.1
*** openafs/src/WINNT/install/InstallShield5/PackageWeb.pfw:1.1	Thu Sep  6 22:55:00 2001
--- openafs/src/WINNT/install/InstallShield5/PackageWeb.pfw	Wed Nov 14 22:38:50 2001
***************
*** 2,21 ****
  Version=2.0
  
  [Options]
! Title=AFS for Windows
! Company=Open AFS
! CompanyEMail=
! BasePath=.\Media\Transarc AFS\Disk Images
! ImportPath=.\Media\Transarc AFS
  UseRTF=0
  SaveFiles=0
  SubFolders=1
  ApplicationName=AFSforWindows
  Description=
! Comments=Build:09/05/01 09:41 CellServDB:CellServDB.IBM_Internal
  Notice=
! Version=1.1.1 a
! OutputSpec=W:\DEST\WinInstall\PackageWeb\AFSforWindows.exe
  GUIDs=0
  Type=2
  Compress=1
--- 2,21 ----
  Version=2.0
  
  [Options]
! Title=OpenAFS for Windows
! Company=OpenAFS
! CompanyEMail=openafs-info@openafs.org
! BasePath=.\Media\OpenAFS\Disk Images
! ImportPath=.\Media\OpenAFS
  UseRTF=0
  SaveFiles=0
  SubFolders=1
  ApplicationName=AFSforWindows
  Description=
! Comments=Build:11/07/01 10:26 CellServDB:
  Notice=
! Version=1.2.2 a
! OutputSpec=Y:\DEST\WinInstall\PackageWeb\AFSforWindows.exe
  GUIDs=0
  Type=2
  Compress=1
***************
*** 70,267 ****
  
  [File 1]
  Name=_ISDel.exe
! Path=.\Media\Transarc AFS\Disk Images\Disk1\
  Flags=589825
  Disk=0
  
  [File 2]
  Name=Setup.exe
! Path=.\Media\Transarc AFS\Disk Images\Disk1\
  Flags=589825
  Disk=0
  
  [File 3]
  Name=_inst32i.ex_
! Path=.\Media\Transarc AFS\Disk Images\Disk1\
  Flags=524289
  Disk=0
  
  [File 4]
  Name=os.dat
! Path=.\Media\Transarc AFS\Disk Images\Disk1\
  Flags=1
  Disk=0
  
  [File 5]
  Name=lang.dat
! Path=.\Media\Transarc AFS\Disk Images\Disk1\
  Flags=1
  Disk=0
  
  [File 6]
  Name=_Setup.dll
! Path=.\Media\Transarc AFS\Disk Images\Disk1\setupdir\0009\
  Flags=655377
  Disk=0
  
  [File 7]
  Name=_Setup.dll
! Path=.\Media\Transarc AFS\Disk Images\Disk1\setupdir\0416\
  Flags=655377
  Disk=0
  
  [File 8]
  Name=_Setup.dll
! Path=.\Media\Transarc AFS\Disk Images\Disk1\setupdir\0804\
  Flags=655377
  Disk=0
  
  [File 9]
  Name=_Setup.dll
! Path=.\Media\Transarc AFS\Disk Images\Disk1\setupdir\0404\
  Flags=655377
  Disk=0
  
  [File 10]
  Name=_Setup.dll
! Path=.\Media\Transarc AFS\Disk Images\Disk1\setupdir\0007\
  Flags=655377
  Disk=0
  
  [File 11]
  Name=_Setup.dll
! Path=.\Media\Transarc AFS\Disk Images\Disk1\setupdir\0011\
  Flags=655377
  Disk=0
  
  [File 12]
  Name=_Setup.dll
! Path=.\Media\Transarc AFS\Disk Images\Disk1\setupdir\0012\
  Flags=655377
  Disk=0
  
  [File 13]
  Name=_Setup.dll
! Path=.\Media\Transarc AFS\Disk Images\Disk1\setupdir\000a\
  Flags=655377
  Disk=0
  
  [File 14]
  Name=setup.ins
! Path=.\Media\Transarc AFS\Disk Images\Disk1\
  Flags=1
  Disk=0
  
  [File 15]
  Name=_sys1.hdr
! Path=.\Media\Transarc AFS\Disk Images\Disk1\
  Flags=2097153
  Disk=0
  
  [File 16]
  Name=_sys1.cab
! Path=.\Media\Transarc AFS\Disk Images\Disk1\
  Flags=2097153
  Disk=0
  
  [File 17]
  Name=_user1.hdr
! Path=.\Media\Transarc AFS\Disk Images\Disk1\
  Flags=2097153
  Disk=0
  
  [File 18]
  Name=_user1.cab
! Path=.\Media\Transarc AFS\Disk Images\Disk1\
  Flags=2097153
  Disk=0
  
  [File 19]
  Name=DATA.TAG
! Path=.\Media\Transarc AFS\Disk Images\Disk1\
  Flags=1
  Disk=0
  
  [File 20]
  Name=SETUP.INI
! Path=.\Media\Transarc AFS\Disk Images\Disk1\
  Flags=1
  Disk=0
  
  [File 21]
  Name=setup.lid
! Path=.\Media\Transarc AFS\Disk Images\Disk1\
  Flags=1
  Disk=0
  
  [File 22]
  Name=setup.bmp
! Path=.\Media\Transarc AFS\Disk Images\Disk1\
  Flags=1
  Disk=0
  
  [File 23]
  Name=data1.hdr
! Path=.\Media\Transarc AFS\Disk Images\Disk1\
  Flags=2097153
  Disk=0
  
  [File 24]
  Name=data1.cab
! Path=.\Media\Transarc AFS\Disk Images\Disk1\
  Flags=2097153
  Disk=0
  
  [File 25]
  Name=layout.bin
! Path=.\Media\Transarc AFS\Disk Images\Disk1\
  Flags=1
  Disk=0
  
  [File 26]
  Name=en_US.rtf
! Path=.\Media\Transarc AFS\Disk Images\Disk1\License\
  Flags=1
  Disk=0
  
  [File 27]
  Name=ja_JP.rtf
! Path=.\Media\Transarc AFS\Disk Images\Disk1\License\
  Flags=1
  Disk=0
  
  [File 28]
  Name=ko_KR.rtf
! Path=.\Media\Transarc AFS\Disk Images\Disk1\License\
  Flags=1
  Disk=0
  
  [File 29]
  Name=zh_CN.rtf
! Path=.\Media\Transarc AFS\Disk Images\Disk1\License\
  Flags=1
  Disk=0
  
  [File 30]
  Name=zh_TW.rtf
! Path=.\Media\Transarc AFS\Disk Images\Disk1\License\
  Flags=1
  Disk=0
  
  [File 31]
  Name=pt_BR.rtf
! Path=.\Media\Transarc AFS\Disk Images\Disk1\License\
  Flags=1
  Disk=0
  
  [File 32]
  Name=es_ES.rtf
! Path=.\Media\Transarc AFS\Disk Images\Disk1\License\
  Flags=1
  Disk=0
  
  [File 33]
  Name=de_DE.rtf
! Path=.\Media\Transarc AFS\Disk Images\Disk1\License\
  Flags=1
  Disk=0
--- 70,267 ----
  
  [File 1]
  Name=_ISDel.exe
! Path=.\Media\OpenAFS\Disk Images\Disk1\
  Flags=589825
  Disk=0
  
  [File 2]
  Name=Setup.exe
! Path=.\Media\OpenAFS\Disk Images\Disk1\
  Flags=589825
  Disk=0
  
  [File 3]
  Name=_inst32i.ex_
! Path=.\Media\OpenAFS\Disk Images\Disk1\
  Flags=524289
  Disk=0
  
  [File 4]
  Name=os.dat
! Path=.\Media\OpenAFS\Disk Images\Disk1\
  Flags=1
  Disk=0
  
  [File 5]
  Name=lang.dat
! Path=.\Media\OpenAFS\Disk Images\Disk1\
  Flags=1
  Disk=0
  
  [File 6]
  Name=_Setup.dll
! Path=.\Media\OpenAFS\Disk Images\Disk1\setupdir\0009\
  Flags=655377
  Disk=0
  
  [File 7]
  Name=_Setup.dll
! Path=.\Media\OpenAFS\Disk Images\Disk1\setupdir\0416\
  Flags=655377
  Disk=0
  
  [File 8]
  Name=_Setup.dll
! Path=.\Media\OpenAFS\Disk Images\Disk1\setupdir\0804\
  Flags=655377
  Disk=0
  
  [File 9]
  Name=_Setup.dll
! Path=.\Media\OpenAFS\Disk Images\Disk1\setupdir\0404\
  Flags=655377
  Disk=0
  
  [File 10]
  Name=_Setup.dll
! Path=.\Media\OpenAFS\Disk Images\Disk1\setupdir\0007\
  Flags=655377
  Disk=0
  
  [File 11]
  Name=_Setup.dll
! Path=.\Media\OpenAFS\Disk Images\Disk1\setupdir\0011\
  Flags=655377
  Disk=0
  
  [File 12]
  Name=_Setup.dll
! Path=.\Media\OpenAFS\Disk Images\Disk1\setupdir\0012\
  Flags=655377
  Disk=0
  
  [File 13]
  Name=_Setup.dll
! Path=.\Media\OpenAFS\Disk Images\Disk1\setupdir\000a\
  Flags=655377
  Disk=0
  
  [File 14]
  Name=setup.ins
! Path=.\Media\OpenAFS\Disk Images\Disk1\
  Flags=1
  Disk=0
  
  [File 15]
  Name=_sys1.hdr
! Path=.\Media\OpenAFS\Disk Images\Disk1\
  Flags=2097153
  Disk=0
  
  [File 16]
  Name=_sys1.cab
! Path=.\Media\OpenAFS\Disk Images\Disk1\
  Flags=2097153
  Disk=0
  
  [File 17]
  Name=_user1.hdr
! Path=.\Media\OpenAFS\Disk Images\Disk1\
  Flags=2097153
  Disk=0
  
  [File 18]
  Name=_user1.cab
! Path=.\Media\OpenAFS\Disk Images\Disk1\
  Flags=2097153
  Disk=0
  
  [File 19]
  Name=DATA.TAG
! Path=.\Media\OpenAFS\Disk Images\Disk1\
  Flags=1
  Disk=0
  
  [File 20]
  Name=SETUP.INI
! Path=.\Media\OpenAFS\Disk Images\Disk1\
  Flags=1
  Disk=0
  
  [File 21]
  Name=setup.lid
! Path=.\Media\OpenAFS\Disk Images\Disk1\
  Flags=1
  Disk=0
  
  [File 22]
  Name=setup.bmp
! Path=.\Media\OpenAFS\Disk Images\Disk1\
  Flags=1
  Disk=0
  
  [File 23]
  Name=data1.hdr
! Path=.\Media\OpenAFS\Disk Images\Disk1\
  Flags=2097153
  Disk=0
  
  [File 24]
  Name=data1.cab
! Path=.\Media\OpenAFS\Disk Images\Disk1\
  Flags=2097153
  Disk=0
  
  [File 25]
  Name=layout.bin
! Path=.\Media\OpenAFS\Disk Images\Disk1\
  Flags=1
  Disk=0
  
  [File 26]
  Name=en_US.rtf
! Path=.\Media\OpenAFS\Disk Images\Disk1\License\
  Flags=1
  Disk=0
  
  [File 27]
  Name=ja_JP.rtf
! Path=.\Media\OpenAFS\Disk Images\Disk1\License\
  Flags=1
  Disk=0
  
  [File 28]
  Name=ko_KR.rtf
! Path=.\Media\OpenAFS\Disk Images\Disk1\License\
  Flags=1
  Disk=0
  
  [File 29]
  Name=zh_CN.rtf
! Path=.\Media\OpenAFS\Disk Images\Disk1\License\
  Flags=1
  Disk=0
  
  [File 30]
  Name=zh_TW.rtf
! Path=.\Media\OpenAFS\Disk Images\Disk1\License\
  Flags=1
  Disk=0
  
  [File 31]
  Name=pt_BR.rtf
! Path=.\Media\OpenAFS\Disk Images\Disk1\License\
  Flags=1
  Disk=0
  
  [File 32]
  Name=es_ES.rtf
! Path=.\Media\OpenAFS\Disk Images\Disk1\License\
  Flags=1
  Disk=0
  
  [File 33]
  Name=de_DE.rtf
! Path=.\Media\OpenAFS\Disk Images\Disk1\License\
  Flags=1
  Disk=0
Index: openafs/src/WINNT/install/InstallShield5/setup.rul
diff -c openafs/src/WINNT/install/InstallShield5/setup.rul:1.5 openafs/src/WINNT/install/InstallShield5/setup.rul:1.5.2.1
*** openafs/src/WINNT/install/InstallShield5/setup.rul:1.5	Thu Sep  6 22:55:00 2001
--- openafs/src/WINNT/install/InstallShield5/setup.rul	Sun Jan 20 04:09:13 2002
***************
*** 442,447 ****
--- 442,448 ----
  	szErrMsg="                                                                 ";
  	Enable (STATUS);
  	SetStatusWindow (50, "Now Downloading CellServDB file...");
+ 	CreateDir(TARGETDIR);
  	nResult=GetWebPage(szErrMsg,szDestFile,szDefaultWeb);
  	SetStatusWindow (100, "Downloading completed.");
  	Delay (2);
Index: openafs/src/WINNT/install/Win9x/NTMakeFile
diff -c openafs/src/WINNT/install/Win9x/NTMakeFile:1.3 openafs/src/WINNT/install/Win9x/NTMakeFile:1.3.2.2
*** openafs/src/WINNT/install/Win9x/NTMakeFile:1.3	Sun Aug 19 10:44:46 2001
--- openafs/src/WINNT/install/Win9x/NTMakeFile	Sun Jan 20 04:09:14 2002
***************
*** 12,51 ****
  ############################################################################
  
  COMPONENTS = \
- 	INSTALL.BAT \
  	afsd.pif \
  	readme.RTF \
- 	license.txt \
- 	templet.reg \
- 	runonce.pif \
  	$(DESTDIR)\bin\util_cr.exe \
  	$(DESTDIR)\root.client\usr\vice\etc\unlog.exe \
- 	$(DESTDIR)\root.client\usr\vice\etc\afs_shl_ext_1033.dll \
- 	$(DESTDIR)\lib\afsauthent.dll \
  	$(DESTDIR)\root.client\usr\vice\etc\afsshare.exe \
  	$(DESTDIR)\root.client\usr\vice\etc\fs.exe \
  	$(DESTDIR)\root.client\usr\vice\etc\klog.exe \
  	$(DESTDIR)\bin\kpasswd.exe \
  	$(DESTDIR)\root.client\usr\vice\etc\libosi.dll \
  	$(DESTDIR)\root.client\usr\vice\etc\libafsconf.dll \
- 	$(DESTDIR)\bin\pts.exe \
- 	$(DESTDIR)\root.client\usr\vice\etc\tokens.exe \
  	$(DESTDIR)\root.client\usr\vice\etc\afs_shl_ext.dll \
! 	$(DESTDIR)\lib\win95\pthread.dll \
  	$(DESTDIR)\lib\afsrpc.dll
  		
  $(COMPONENTS)::
  	$(DESTDIR)\bin\util_cr.exe ~ $@
  	$(COPY) $@ $(DESTDIR)\WinInstall\.
  
  !IF (EXIST(ISBUILD.MAK))
  !INCLUDE ISBUILD.MAK
  !ENDIF
  
  build:
- 	copy install.bat $(OUTDIR)\.
  
! install: prep $(COMPONENTS) build
  
  install9x: install
  
--- 12,52 ----
  ############################################################################
  
  COMPONENTS = \
  	afsd.pif \
  	readme.RTF \
  	$(DESTDIR)\bin\util_cr.exe \
  	$(DESTDIR)\root.client\usr\vice\etc\unlog.exe \
  	$(DESTDIR)\root.client\usr\vice\etc\afsshare.exe \
  	$(DESTDIR)\root.client\usr\vice\etc\fs.exe \
  	$(DESTDIR)\root.client\usr\vice\etc\klog.exe \
  	$(DESTDIR)\bin\kpasswd.exe \
+ 	$(DESTDIR)\bin\pts.exe \
+ 	$(DESTDIR)\root.client\usr\vice\etc\tokens.exe
+ 		
+ DLLCOMPONENTS = \
+ 	$(DESTDIR)\root.client\usr\vice\etc\afs_shl_ext_1033.dll \
+ 	$(DESTDIR)\lib\afsauthent.dll \
  	$(DESTDIR)\root.client\usr\vice\etc\libosi.dll \
  	$(DESTDIR)\root.client\usr\vice\etc\libafsconf.dll \
  	$(DESTDIR)\root.client\usr\vice\etc\afs_shl_ext.dll \
! 	$(DESTDIR)\lib\win95\afspthread.dll \
  	$(DESTDIR)\lib\afsrpc.dll
  		
  $(COMPONENTS)::
  	$(DESTDIR)\bin\util_cr.exe ~ $@
  	$(COPY) $@ $(DESTDIR)\WinInstall\.
  
+ $(DLLCOMPONENTS)::
+ 	$(DESTDIR)\bin\util_cr.exe ~ $@
+ 	$(COPY) $@ $(DESTDIR)\WinInstall\Dll\.
+ 
  !IF (EXIST(ISBUILD.MAK))
  !INCLUDE ISBUILD.MAK
  !ENDIF
  
  build:
  
! install: prep $(COMPONENTS) $(DLLCOMPONENTS) build
  
  install9x: install
  
***************
*** 54,59 ****
--- 55,63 ----
      $(DEL) $(OUTDIR)\DiskIm~1\WebInstall\*
  
  prep :
+ 	$(COPY) "$(DESTDIR)\WinInstall\config\sock.vxd" "$(DESTDIR)\WinInstall\."
+ 	$(COPY) "$(DESTDIR)\WinInstall\config\MMAP.vxd" "$(DESTDIR)\WinInstall\."
+ 	$(COPY) "$(DESTDIR)\WinInstall\config\AFSD.EXE" "$(DESTDIR)\WinInstall\."
  	$(DESTDIR)\bin\util_cr.exe ~ "$(DESTDIR)\WinInstall\sock.vxd"
  	$(DESTDIR)\bin\util_cr.exe ~ "$(DESTDIR)\WinInstall\MMAP.vxd"
  	$(DESTDIR)\bin\util_cr.exe ~ "$(DESTDIR)\WinInstall\AFSD.EXE"
Index: openafs/src/WINNT/pthread/NTMakefile
diff -c openafs/src/WINNT/pthread/NTMakefile:1.5 openafs/src/WINNT/pthread/NTMakefile:1.5.2.1
*** openafs/src/WINNT/pthread/NTMakefile:1.5	Sat Sep  8 00:31:27 2001
--- openafs/src/WINNT/pthread/NTMakefile	Sun Jan 20 04:09:14 2002
***************
*** 16,24 ****
  	$(DESTDIR)\include\pthread.h
  
  ############################################################################
! # Build standard pthread.dll
  
! PTHR_DLLFILE = $(DESTDIR)\lib\pthread.dll
  
  PTHR_DLLOBJS = \
  	pthread.obj \
--- 16,24 ----
  	$(DESTDIR)\include\pthread.h
  
  ############################################################################
! # Build standard afspthread.dll
  
! PTHR_DLLFILE = $(DESTDIR)\lib\afspthread.dll
  
  PTHR_DLLOBJS = \
  	pthread.obj \
***************
*** 29,37 ****
  	$(DLLPREP)
  
  ############################################################################
! # Build Windows 95 version of pthread.dll
  
! PTHR95_DLLFILE = $(DESTDIR)\lib\win95\pthread.dll
  
  PTHR95_DLLOBJS = \
  	pthread_95.obj \
--- 29,37 ----
  	$(DLLPREP)
  
  ############################################################################
! # Build Windows 95 version of afspthread.dll
  
! PTHR95_DLLFILE = $(DESTDIR)\lib\win95\afspthread.dll
  
  PTHR95_DLLOBJS = \
  	pthread_95.obj \
Index: openafs/src/WINNT/pthread/test/NTMakefile
diff -c openafs/src/WINNT/pthread/test/NTMakefile:1.2 openafs/src/WINNT/pthread/test/NTMakefile:1.2.8.1
*** openafs/src/WINNT/pthread/test/NTMakefile:1.2	Sat Nov  4 05:03:05 2000
--- openafs/src/WINNT/pthread/test/NTMakefile	Sun Jan 20 04:09:15 2002
***************
*** 10,21 ****
  test tests: ptest.exe tsd.exe native.exe
  
  
! ptest.exe: ptest.obj $(DESTDIR)/lib/pthread.lib $(DESTDIR)/lib/afs/afsutil.lib
  	$(EXECONLINK)
  
! tsd.exe: tsd.obj $(DESTDIR)/lib/pthread.lib $(DESTDIR)/lib/afs/afsutil.lib
  	$(EXECONLINK)
  
! native.exe: native.obj $(DESTDIR)/lib/pthread.lib $(DESTDIR)/lib/afs/afsutil.lib
  	$(EXECONLINK)
  
--- 10,21 ----
  test tests: ptest.exe tsd.exe native.exe
  
  
! ptest.exe: ptest.obj $(DESTDIR)/lib/afspthread.lib $(DESTDIR)/lib/afs/afsutil.lib
  	$(EXECONLINK)
  
! tsd.exe: tsd.obj $(DESTDIR)/lib/afspthread.lib $(DESTDIR)/lib/afs/afsutil.lib
  	$(EXECONLINK)
  
! native.exe: native.obj $(DESTDIR)/lib/afspthread.lib $(DESTDIR)/lib/afs/afsutil.lib
  	$(EXECONLINK)
  
Index: openafs/src/WINNT/win9xpanel/WinAfsLoad.cpp
diff -c openafs/src/WINNT/win9xpanel/WinAfsLoad.cpp:1.2 openafs/src/WINNT/win9xpanel/WinAfsLoad.cpp:1.2.2.1
*** openafs/src/WINNT/win9xpanel/WinAfsLoad.cpp:1.2	Sun Aug 19 10:44:46 2001
--- openafs/src/WINNT/win9xpanel/WinAfsLoad.cpp	Wed Nov 14 22:38:51 2001
***************
*** 408,414 ****
  		m_wParam=wp;
  		m_sMsg=msg;	
  		SetEvent(CMyUIThread::m_hEventThreadKilled);
! 		m_uNntifyMessage=0;
  		break;
  	default:
  		break;
--- 408,414 ----
  		m_wParam=wp;
  		m_sMsg=msg;	
  		SetEvent(CMyUIThread::m_hEventThreadKilled);
! 		m_uNotifyMessage=0;
  		break;
  	default:
  		break;
Index: openafs/src/afs/Makefile.in
diff -c openafs/src/afs/Makefile.in:1.4 openafs/src/afs/Makefile.in:1.4.2.1
*** openafs/src/afs/Makefile.in:1.4	Fri Sep  7 19:34:45 2001
--- openafs/src/afs/Makefile.in	Wed Dec 26 15:09:03 2001
***************
*** 35,46 ****
  		pmax_ul43 | pmax_ul43a) \
  			${INSTALL} longc_procs.h ${TOP_INCDIR}/afs ;; \
  	esac
- 	case ${SYS_NAME} in \
- 		*linux* ) \
- 			${INSTALL} ${AFS_OSTYPE}/osi_vfs.h ${TOP_INCDIR}/afs ;;\
- 		* ) \
- 			echo No vfs headers to install for ${SYS_NAME};; \
- 	esac
  
  # NOTE: linux case uses --new as well to work around bug in some versions of
  # gencat.
--- 35,40 ----
Index: openafs/src/afs/afs.h
diff -c openafs/src/afs/afs.h:1.9.2.1 openafs/src/afs/afs.h:1.9.2.4
*** openafs/src/afs/afs.h:1.9.2.1	Sat Oct 13 00:20:23 2001
--- openafs/src/afs/afs.h	Sun Jan 20 03:59:21 2002
***************
*** 202,208 ****
      short states;			    /* state flags */
      short cellIndex;			    /* relative index number per cell */
      time_t timeout;			    /* data expire time, if non-zero */
!     struct cell *alias;			    /* what this cell is an alias for */
  };
  
  #define	afs_PutCell(cellp, locktype)
--- 202,208 ----
      short states;			    /* state flags */
      short cellIndex;			    /* relative index number per cell */
      time_t timeout;			    /* data expire time, if non-zero */
!     char *realName;			    /* who this cell is an alias for */
  };
  
  #define	afs_PutCell(cellp, locktype)
***************
*** 529,539 ****
--- 529,547 ----
  #define VREFCOUNT_SET(v, c)	atomic_set(&((vnode_t *) v)->v_count, c)
  #define VREFCOUNT_DEC(v)	atomic_dec(&((vnode_t *) v)->v_count)
  #define VREFCOUNT_INC(v)	atomic_inc(&((vnode_t *) v)->v_count)
+ #define DLOCK()      spin_lock(&dcache_lock)
+ #define DUNLOCK()    spin_unlock(&dcache_lock)
+ #define DGET(d)      dget_locked(d)
+ #define DCOUNT(d)    atomic_read(&(d)->d_count)
  #else
  #define VREFCOUNT(v)		((v)->vrefCount)
  #define VREFCOUNT_SET(v, c)	(v)->vrefCount = c;
  #define VREFCOUNT_DEC(v)	(v)->vrefCount--;
  #define VREFCOUNT_INC(v)	(v)->vrefCount++;
+ #define DLOCK()
+ #define DUNLOCK()
+ #define DGET(d)      dget(d)
+ #define DCOUNT(d)    ((d)->d_count)
  #endif
  
  #define	AFS_MAXDV   0x7fffffff	    /* largest dataversion number */
***************
*** 959,965 ****
--- 967,975 ----
  #define	FVHash(acell,avol)  (((avol)+(acell)) & (NFENTRIES-1))
  
  extern struct cell	    *afs_GetCell();
+ extern struct cell	    *afs_GetCellNoLock();
  extern struct cell	    *afs_GetCellByName();
+ extern struct cell	    *afs_GetCellByName2();
  extern struct cell	    *afs_GetCellByIndex();
  extern struct unixuser	    *afs_GetUser();
  extern struct volume	    *afs_GetVolume();
***************
*** 1003,1008 ****
--- 1013,1020 ----
  extern int afs_DynrootNewVnode();
  extern int afs_SetDynrootEnable();
  extern int afs_GetDynrootEnable();
+ extern int afs_DynrootVOPSymlink();
+ extern int afs_DynrootVOPRemove();
  
  
  /* Performance hack - we could replace VerifyVCache2 with the appropriate
Index: openafs/src/afs/afs_call.c
diff -c openafs/src/afs/afs_call.c:1.14.2.1 openafs/src/afs/afs_call.c:1.14.2.5
*** openafs/src/afs/afs_call.c:1.14.2.1	Sat Oct 13 00:20:23 2001
--- openafs/src/afs/afs_call.c	Thu Jan 24 05:43:15 2002
***************
*** 10,16 ****
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/afs_call.c,v 1.14.2.1 2001/10/13 04:20:23 shadow Exp $");
  
  #include "../afs/sysincludes.h"	/* Standard vendor system headers */
  #include "../afs/afsincludes.h"	/* Afs-based standard headers */
--- 10,16 ----
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/afs_call.c,v 1.14.2.5 2002/01/24 10:43:15 shadow Exp $");
  
  #include "../afs/sysincludes.h"	/* Standard vendor system headers */
  #include "../afs/afsincludes.h"	/* Afs-based standard headers */
***************
*** 191,196 ****
--- 191,199 ----
  	    afs_osi_Invisible();
  	    afs_RX_Running = 2;
  	    afs_osi_Wakeup(&afs_RX_Running);
+ #ifndef UKERNEL
+ 	    afs_osi_RxkRegister();
+ #endif
  	    rxk_Listener();
  	}
  #ifdef	AFS_SGI_ENV
***************
*** 326,331 ****
--- 329,361 ----
  	osi_FreeSmallSpace(tbuffer);
  	osi_FreeSmallSpace(tbuffer1);
      }
+     else if (parm == AFSOP_ADDCELLALIAS) {
+ 	/*
+ 	 * Call arguments:
+ 	 * parm2 is the alias name
+ 	 * parm3 is the real cell name
+ 	 */
+ #if defined(AFS_SGI61_ENV) || defined(AFS_SUN57_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
+ 	size_t bufferSize;
+ #else /* AFS_SGI61_ENV */
+ 	u_int bufferSize;	
+ #endif /* AFS_SGI61_ENV */
+ 	char *aliasName = osi_AllocSmallSpace(AFS_SMALLOCSIZ);
+ 	char *cellName = osi_AllocSmallSpace(AFS_SMALLOCSIZ);
+ 
+ 	AFS_COPYINSTR((char *)parm2, aliasName, AFS_SMALLOCSIZ, &bufferSize, code);
+ 	if (!code) AFS_COPYINSTR((char *)parm3, cellName, AFS_SMALLOCSIZ, &bufferSize, code);
+ 	if (!code) afs_NewCell(aliasName,	/* new entry name */
+ 			       0,		/* host list */
+ 			       CAlias,		/* flags */
+ 			       (char *) 0,	/* linked cell */
+ 			       0, 0,		/* fs & vl ports */
+ 			       0,		/* timeout */
+ 			       cellName);	/* real cell name */
+ 
+ 	osi_FreeSmallSpace(aliasName);
+ 	osi_FreeSmallSpace(cellName);
+     }
      else if (parm == AFSOP_CACHEINIT) {
  	struct afs_cacheParams cparms;
  
***************
*** 610,615 ****
--- 640,648 ----
  	afs_int32 *kmsg = afs_osi_Alloc(kmsgLen);
  	char *cellname = afs_osi_Alloc(cellLen);
  
+ #ifndef UKERNEL
+ 	afs_osi_MaskSignals();
+ #endif
  	AFS_COPYIN((afs_int32 *)parm2, cellname, cellLen, code);
  	AFS_COPYIN((afs_int32 *)parm3, kmsg, kmsgLen, code);
  	if (!code) {
***************
*** 1227,1232 ****
--- 1260,1268 ----
  	afs_osi_Sleep(&afs_termState);
  #if defined(RXK_LISTENER_ENV)
      afs_warn("RxListener... ");
+ #ifndef UKERNEL
+     afs_osi_UnmaskRxkSignals();
+ #endif
      /* cancel rx listener */
      osi_StopListener(); /* This closes rx_socket. */
      while (afs_termState == AFSOP_STOP_RXK_LISTENER) 
Index: openafs/src/afs/afs_cell.c
diff -c openafs/src/afs/afs_cell.c:1.7.2.1 openafs/src/afs/afs_cell.c:1.7.2.5
*** openafs/src/afs/afs_cell.c:1.7.2.1	Sat Oct 13 00:20:23 2001
--- openafs/src/afs/afs_cell.c	Sun Jan 20 03:33:04 2002
***************
*** 13,19 ****
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/afs_cell.c,v 1.7.2.1 2001/10/13 04:20:23 shadow Exp $");
  
  #include "../afs/stds.h"
  #include "../afs/sysincludes.h"	/* Standard vendor system headers */
--- 13,19 ----
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/afs_cell.c,v 1.7.2.5 2002/01/20 08:33:04 shadow Exp $");
  
  #include "../afs/stds.h"
  #include "../afs/sysincludes.h"	/* Standard vendor system headers */
***************
*** 78,84 ****
  char afs_AfsdbHandler_Completed = 0;
  
  
! static struct cell *afs_GetCellByName_int();
  
  int afs_strcasecmp(s1, s2)
      register char *s1, *s2;
--- 78,84 ----
  char afs_AfsdbHandler_Completed = 0;
  
  
! struct cell *afs_GetCellByName2();
  
  int afs_strcasecmp(s1, s2)
      register char *s1, *s2;
***************
*** 220,236 ****
  }
  
  
! void afs_RefreshCell(tc)
!     register struct cell *tc;
  {
      afs_int32 cellHosts[MAXCELLHOSTS];
      char *realName = NULL;
      int timeout;
  
      /* Don't need to do anything if no timeout or it's not expired */
!     if (!tc->timeout || tc->timeout > osi_Time()) return;
  
!     if (afs_GetCellHostsFromDns(tc->cellName, cellHosts, &timeout, &realName))
  	/* In case of lookup failure, keep old data */
  	goto done;
  
--- 220,237 ----
  }
  
  
! void afs_RefreshCell(ac)
!     register struct cell *ac;
  {
      afs_int32 cellHosts[MAXCELLHOSTS];
      char *realName = NULL;
+     struct cell *tc;
      int timeout;
  
      /* Don't need to do anything if no timeout or it's not expired */
!     if (!ac->timeout || ac->timeout > osi_Time()) return;
  
!     if (afs_GetCellHostsFromDns(ac->cellName, cellHosts, &timeout, &realName))
  	/* In case of lookup failure, keep old data */
  	goto done;
  
***************
*** 238,246 ****
      afs_NewCell(realName, cellHosts, 0, (char *) 0, 0, 0, timeout, (char *) 0);
  
      /* If this is an alias, update the alias entry too */
!     if (afs_strcasecmp(tc->cellName, realName))
! 	afs_NewCell(tc->cellName, 0, CAlias, (char *) 0, 0, 0,
! 		    timeout, realName);
  
  done:
      if (realName)
--- 239,257 ----
      afs_NewCell(realName, cellHosts, 0, (char *) 0, 0, 0, timeout, (char *) 0);
  
      /* If this is an alias, update the alias entry too */
!     if (afs_strcasecmp(ac->cellName, realName)) {
! 	/*
! 	 * Look up the entry we just updated, to compensate for
! 	 * uppercase-vs-lowercase lossage with DNS.
! 	 */
! 	tc = afs_GetCellByName2(realName, READ_LOCK, 0 /* no AFSDB */);
! 
! 	if (tc) {
! 	    afs_NewCell(ac->cellName, 0, CAlias, (char *) 0, 0, 0,
! 			timeout, tc->cellName);
! 	    afs_PutCell(tc, READ_LOCK);
! 	}
!     }
  
  done:
      if (realName)
***************
*** 254,259 ****
--- 265,271 ----
  {
      afs_int32 cellHosts[MAXCELLHOSTS];
      char *realName = NULL;
+     struct cell *tc;
      int timeout;
  
      if (afs_GetCellHostsFromDns(acellName, cellHosts, &timeout, &realName))
***************
*** 264,277 ****
  
      /* If this is an alias, create an entry for it too */
      if (afs_strcasecmp(acellName, realName)) {
  	if (afs_NewCell(acellName, 0, CAlias, (char *) 0, 0, 0,
! 			timeout, realName))
  	    goto bad;
      }
  
      if (realName)
  	afs_osi_Free(realName, strlen(realName) + 1);
!     return afs_GetCellByName_int(acellName, locktype, 0);
  
  bad:
      if (realName)
--- 276,301 ----
  
      /* If this is an alias, create an entry for it too */
      if (afs_strcasecmp(acellName, realName)) {
+ 	/*
+ 	 * Look up the entry we just updated, to compensate for
+ 	 * uppercase-vs-lowercase lossage with DNS.
+ 	 */
+ 	tc = afs_GetCellByName2(realName, READ_LOCK, 0 /* no AFSDB */);
+ 	if (!tc)
+ 	    goto bad;
+ 
  	if (afs_NewCell(acellName, 0, CAlias, (char *) 0, 0, 0,
! 			timeout, tc->cellName)) {
! 	    afs_PutCell(tc, READ_LOCK);
  	    goto bad;
+ 	}
+ 
+ 	afs_PutCell(tc, READ_LOCK);
      }
  
      if (realName)
  	afs_osi_Free(realName, strlen(realName) + 1);
!     return afs_GetCellByName2(acellName, locktype, 0);
  
  bad:
      if (realName)
***************
*** 280,294 ****
  }
  
  
! static struct cell *afs_GetCellByName_int(acellName, locktype, trydns)
      register char *acellName;
      afs_int32 locktype;
      char trydns;
  {
      register struct cell *tc;
      register struct afs_q *cq, *tq;
  
      AFS_STATCNT(afs_GetCellByName);
      ObtainWriteLock(&afs_xcell,100);
      for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
  	tc = QTOC(cq); tq = QNext(cq);
--- 304,320 ----
  }
  
  
! struct cell *afs_GetCellByName2(acellName, locktype, trydns)
      register char *acellName;
      afs_int32 locktype;
      char trydns;
  {
      register struct cell *tc;
      register struct afs_q *cq, *tq;
+     int didAlias = 0;
  
      AFS_STATCNT(afs_GetCellByName);
+ retry:
      ObtainWriteLock(&afs_xcell,100);
      for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
  	tc = QTOC(cq); tq = QNext(cq);
***************
*** 297,305 ****
  	    QAdd(&CellLRU, &tc->lruq);
  	    ReleaseWriteLock(&afs_xcell);
  	    afs_RefreshCell(tc);
! 	    if (tc->states & CAlias) {
! 		tc = tc->alias;
! 		afs_RefreshCell(tc);
  	    }
  	    return tc;
  	}
--- 323,333 ----
  	    QAdd(&CellLRU, &tc->lruq);
  	    ReleaseWriteLock(&afs_xcell);
  	    afs_RefreshCell(tc);
! 	    if ((tc->states & CAlias) && (didAlias == 0)) {
! 		acellName = tc->realName;
! 		if (!acellName) return (struct cell *) 0;
! 		didAlias = 1;
! 		goto retry;
  	    }
  	    return tc;
  	}
***************
*** 308,354 ****
      return trydns ? afs_GetCellByName_Dns(acellName, locktype)
  		  : (struct cell *) 0;
  
! } /*afs_GetCellByName_int*/
  
  
  struct cell *afs_GetCellByName(acellName, locktype)
      register char *acellName;
      afs_int32 locktype;
  {
!     return afs_GetCellByName_int(acellName, locktype, 1);
  
  } /*afs_GetCellByName*/
- 
  
! struct cell *afs_GetCell(acell, locktype)
      register afs_int32 acell;
      afs_int32 locktype;
  {
      register struct cell *tc;
      register struct afs_q *cq, *tq;
  
      AFS_STATCNT(afs_GetCell);
      if (acell == 1 && afs_rootcell) return afs_rootcell;
!     ObtainWriteLock(&afs_xcell,101);
      for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
  	tc = QTOC(cq); tq = QNext(cq);
  	if (tc->cell == acell) {
  	    QRemove(&tc->lruq);
  	    QAdd(&CellLRU, &tc->lruq);
! 	    ReleaseWriteLock(&afs_xcell);
  	    afs_RefreshCell(tc);
  	    return tc;
  	}
      }
!     ReleaseWriteLock(&afs_xcell);
      return (struct cell *) 0;
  
  } /*afs_GetCell*/
  
  
! struct cell *afs_GetCellByIndex(cellindex, locktype)
      register afs_int32 cellindex;
      afs_int32 locktype;
  {
      register struct cell *tc;
      register struct afs_q *cq, *tq;
--- 336,400 ----
      return trydns ? afs_GetCellByName_Dns(acellName, locktype)
  		  : (struct cell *) 0;
  
! } /*afs_GetCellByName2*/
  
  
  struct cell *afs_GetCellByName(acellName, locktype)
      register char *acellName;
      afs_int32 locktype;
  {
!     return afs_GetCellByName2(acellName, locktype, 1);
  
  } /*afs_GetCellByName*/
  
! static struct cell *afs_GetCellInternal(acell, locktype, holdxcell)
      register afs_int32 acell;
      afs_int32 locktype;
+     int holdxcell;
  {
      register struct cell *tc;
      register struct afs_q *cq, *tq;
  
      AFS_STATCNT(afs_GetCell);
      if (acell == 1 && afs_rootcell) return afs_rootcell;
!     if (holdxcell)
! 	ObtainWriteLock(&afs_xcell,101);
      for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
  	tc = QTOC(cq); tq = QNext(cq);
  	if (tc->cell == acell) {
  	    QRemove(&tc->lruq);
  	    QAdd(&CellLRU, &tc->lruq);
! 	    if (holdxcell)
! 		ReleaseWriteLock(&afs_xcell);
  	    afs_RefreshCell(tc);
  	    return tc;
  	}
      }
!     if (holdxcell)
! 	ReleaseWriteLock(&afs_xcell);
      return (struct cell *) 0;
  
  } /*afs_GetCell*/
  
+ struct cell *afs_GetCell(acell, locktype)
+     register afs_int32 acell;
+     afs_int32 locktype;
+ {
+     return afs_GetCellInternal(acell, locktype, 1);
+ }
+ 
+ /* This is only to be called if the caller is already holding afs_xcell */
+ struct cell *afs_GetCellNoLock(acell, locktype)
+     register afs_int32 acell;
+     afs_int32 locktype;
+ {
+     return afs_GetCellInternal(acell, locktype, 0);
+ }
  
! struct cell *afs_GetCellByIndex(cellindex, locktype, refresh)
      register afs_int32 cellindex;
      afs_int32 locktype;
+     afs_int32 refresh;
  {
      register struct cell *tc;
      register struct afs_q *cq, *tq;
***************
*** 361,367 ****
  	    QRemove(&tc->lruq);
  	    QAdd(&CellLRU, &tc->lruq);
  	    ReleaseWriteLock(&afs_xcell);
! 	    afs_RefreshCell(tc);
  	    return tc;
  	}
      }
--- 407,413 ----
  	    QRemove(&tc->lruq);
  	    QAdd(&CellLRU, &tc->lruq);
  	    ReleaseWriteLock(&afs_xcell);
! 	    if (refresh) afs_RefreshCell(tc);
  	    return tc;
  	}
      }
***************
*** 419,424 ****
--- 465,471 ----
      }
      else {
  	tc = (struct cell *) afs_osi_Alloc(sizeof(struct cell));
+ 	memset((char *)tc, 0, sizeof(*tc));
  	QAdd(&CellLRU, &tc->lruq);		       	/* put in lruq */
  	tc->cellName = (char *) afs_osi_Alloc(strlen(acellName)+1);
  	strcpy(tc->cellName, acellName);
***************
*** 464,488 ****
      }
      tc->states |= aflags;
      tc->timeout = timeout;
   
      memset((char *)tc->cellHosts, 0, sizeof(tc->cellHosts));
      if (aflags & CAlias) {
- 	struct cell *tca = NULL;
- 
  	if (!aliasFor) {
  	    code = EINVAL;
  	    goto bad;
- 	}
- 	for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
- 	    tca = QTOC(cq); tq = QNext(cq);
- 	    if (!afs_strcasecmp(tca->cellName, aliasFor))
- 		break;
- 	}
- 	if (!tca) {
- 	    code = ENOENT;
- 	    goto bad;
  	}
! 	tc->alias = tca;
  	goto done;
      }
  
--- 511,529 ----
      }
      tc->states |= aflags;
      tc->timeout = timeout;
+ 
+     /* Allow converting an alias into a real cell */
+     if (!(aflags & CAlias)) tc->states &= ~CAlias;
   
      memset((char *)tc->cellHosts, 0, sizeof(tc->cellHosts));
      if (aflags & CAlias) {
  	if (!aliasFor) {
  	    code = EINVAL;
  	    goto bad;
  	}
! 	if (tc->realName) afs_osi_Free(tc->realName, strlen(tc->realName)+1);
! 	tc->realName = (char *) afs_osi_Alloc(strlen(aliasFor)+1);
! 	strcpy(tc->realName, aliasFor);
  	goto done;
      }
  
Index: openafs/src/afs/afs_dynroot.c
diff -c openafs/src/afs/afs_dynroot.c:1.1.2.1 openafs/src/afs/afs_dynroot.c:1.1.2.3
*** openafs/src/afs/afs_dynroot.c:1.1.2.1	Sat Oct 13 00:40:48 2001
--- openafs/src/afs/afs_dynroot.c	Sun Jan 20 03:20:54 2002
***************
*** 20,25 ****
--- 20,27 ----
   * afs_DynrootNewVnode
   * afs_SetDynrootEnable
   * afs_GetDynrootEnable
+  * afs_DynrootVOPRemove
+  * afs_DynrootVOPSymlink
   *
   */
  
***************
*** 41,49 ****
  #define AFS_DYNROOT_VNODE	1
  #define AFS_DYNROOT_UNIQUE	1
  
! #define VNUM2CIDX(vnum)		((vnum) >> 2)
! #define VNUM2RW(vnum)		(((vnum) >> 1) & 1)
! #define CIDXRW2VNUM(cidx, rw)	(((cidx) << 2) | ((rw) << 1))
  
  static int afs_dynrootEnable = 0;
  
--- 43,64 ----
  #define AFS_DYNROOT_VNODE	1
  #define AFS_DYNROOT_UNIQUE	1
  
! /*
!  * Vnode numbers in dynroot are composed of a type field (upper 8 bits)
!  * and a type-specific identifier in the lower 24 bits.
!  */
! #define VN_TYPE_CELL		0x01	/* Corresponds to a struct cell */
! #define VN_TYPE_SYMLINK		0x02	/* User-created symlink in /afs */
! 
! #define VNUM_TO_VNTYPE(vnum)	((vnum) >> 24)
! #define VNUM_TO_VNID(vnum)	((vnum) & 0x00ffffff)
! #define VNUM_FROM_TYPEID(type, id) \
! 				((type) << 24 | (id))
! #define VNUM_TO_CIDX(vnum)	(VNUM_TO_VNID(vnum) >> 2)
! #define VNUM_TO_RW(vnum)	(VNUM_TO_VNID(vnum) >> 1 & 1)
! #define VNUM_FROM_CIDX_RW(cidx, rw) \
! 				VNUM_FROM_TYPEID(VN_TYPE_CELL, \
! 						 ((cidx) << 2 | (rw) << 1))
  
  static int afs_dynrootEnable = 0;
  
***************
*** 57,62 ****
--- 72,91 ----
  static int afs_dynrootVersionHigh = 1;
  /* End of variables protected by afs_dynrootDirLock */
  
+ /* A dynamically-created symlink in a dynroot /afs */
+ struct afs_dynSymlink {
+     struct afs_dynSymlink *next;
+     int index;
+     char *name;
+     char *target;
+ };
+ 
+ static afs_rwlock_t afs_dynSymlinkLock;
+ /* Start of variables protected by afs_dynSymlinkLock */
+ static struct afs_dynSymlink *afs_dynSymlinkBase = NULL;
+ static int afs_dynSymlinkIndex = 0;
+ /* End of variables protected by afs_dynSymlinkLock */
+ 
  extern afs_int32 afs_cellindex;
  extern afs_rwlock_t afs_xvcache;
  
***************
*** 178,190 ****
      int cellidx, maxcellidx, i;
      struct cell *c;
      int curChunk, curPage;
!     int dirSize;
      char *newDir, *dotCell;
      struct DirHeader *dirHeader;
      struct PageHeader *pageHeader;
      struct DirEntry *dirEntry;
      int doFlush = 0;
      int linkCount = 0;
  
      /*
       * Save afs_cellindex here, in case it changes between the
--- 207,221 ----
      int cellidx, maxcellidx, i;
      struct cell *c;
      int curChunk, curPage;
!     int dirSize, sizeOfCurEntry;
      char *newDir, *dotCell;
      struct DirHeader *dirHeader;
      struct PageHeader *pageHeader;
      struct DirEntry *dirEntry;
      int doFlush = 0;
      int linkCount = 0;
+     struct afs_dynSymlink *ts;
+     int newCellCount;
  
      /*
       * Save afs_cellindex here, in case it changes between the
***************
*** 199,207 ****
      curPage = 0;
  
      for (cellidx = 0; cellidx < maxcellidx; cellidx++) {
! 	int sizeOfCurEntry;
! 
! 	c = afs_GetCellByIndex(cellidx, READ_LOCK);
  	if (!c) continue;
  
  	sizeOfCurEntry = afs_dir_NameBlobs(c->cellName);
--- 230,236 ----
      curPage = 0;
  
      for (cellidx = 0; cellidx < maxcellidx; cellidx++) {
! 	c = afs_GetCellByIndex(cellidx, READ_LOCK, 0 /* don't refresh */);
  	if (!c) continue;
  
  	sizeOfCurEntry = afs_dir_NameBlobs(c->cellName);
***************
*** 224,229 ****
--- 253,270 ----
  	afs_PutCell(c, READ_LOCK);
      }
  
+     ObtainReadLock(&afs_dynSymlinkLock);
+     ts = afs_dynSymlinkBase;
+     while (ts) {
+ 	sizeOfCurEntry = afs_dir_NameBlobs(ts->name);
+ 	if (curChunk + sizeOfCurEntry > EPP) {
+ 	    curPage++;
+ 	    curChunk = 1;
+ 	}
+ 	curChunk += sizeOfCurEntry;
+ 	ts = ts->next;
+     }
+ 
      dirSize = (curPage + 1) * AFS_PAGESIZE;
      newDir = afs_osi_Alloc(dirSize);
  
***************
*** 253,284 ****
      afs_dynroot_addDirEnt(dirHeader, &curPage, &curChunk, "..", 1);
      linkCount += 2;
  
      for (cellidx = 0; cellidx < maxcellidx; cellidx++) {
! 	c = afs_GetCellByIndex(cellidx, READ_LOCK);
  	afs_dynroot_addDirEnt(dirHeader, &curPage, &curChunk,
! 			      c->cellName, CIDXRW2VNUM(cellidx, 0));
  
  	dotCell = afs_osi_Alloc(strlen(c->cellName) + 2);
  	strcpy(dotCell, ".");
  	strcat(dotCell, c->cellName);
  	afs_dynroot_addDirEnt(dirHeader, &curPage, &curChunk,
! 			      dotCell, CIDXRW2VNUM(cellidx, 1));
! 
! 	linkCount += 2;
  
  	afs_PutCell(c, READ_LOCK);
      }
  
      ObtainWriteLock(&afs_dynrootDirLock, 549);
      if (afs_dynrootDir) afs_osi_Free(afs_dynrootDir, afs_dynrootDirLen);
      afs_dynrootDir = newDir;
      afs_dynrootDirLen = dirSize;
      afs_dynrootDirLinkcnt = linkCount;
!     if (afs_dynrootCellCount != maxcellidx) {
  	/*
! 	 * New cells added -- bump data version, invalidate vcache.
  	 */
! 	afs_dynrootCellCount = maxcellidx;
  	afs_dynrootVersion++;
  	afs_dynrootVersionHigh = osi_Time();
  	doFlush = 1;
--- 294,338 ----
      afs_dynroot_addDirEnt(dirHeader, &curPage, &curChunk, "..", 1);
      linkCount += 2;
  
+     /* Reserve space for "." and ".." */
+     curChunk += 2;
+ 
      for (cellidx = 0; cellidx < maxcellidx; cellidx++) {
! 	c = afs_GetCellByIndex(cellidx, READ_LOCK, 0 /* don't refresh */);
  	afs_dynroot_addDirEnt(dirHeader, &curPage, &curChunk,
! 			      c->cellName, VNUM_FROM_CIDX_RW(cellidx, 0));
  
  	dotCell = afs_osi_Alloc(strlen(c->cellName) + 2);
  	strcpy(dotCell, ".");
  	strcat(dotCell, c->cellName);
  	afs_dynroot_addDirEnt(dirHeader, &curPage, &curChunk,
! 			      dotCell, VNUM_FROM_CIDX_RW(cellidx, 1));
  
+ 	if (!(c->states & CAlias)) linkCount += 2;
  	afs_PutCell(c, READ_LOCK);
      }
  
+     ts = afs_dynSymlinkBase;
+     while (ts) {
+ 	int vnum = VNUM_FROM_TYPEID(VN_TYPE_SYMLINK, ts->index);
+ 	afs_dynroot_addDirEnt(dirHeader, &curPage, &curChunk,
+ 			      ts->name, vnum);
+ 	ts = ts->next;
+     }
+ 
+     newCellCount = maxcellidx + afs_dynSymlinkIndex;
+     ReleaseReadLock(&afs_dynSymlinkLock);
+ 
      ObtainWriteLock(&afs_dynrootDirLock, 549);
      if (afs_dynrootDir) afs_osi_Free(afs_dynrootDir, afs_dynrootDirLen);
      afs_dynrootDir = newDir;
      afs_dynrootDirLen = dirSize;
      afs_dynrootDirLinkcnt = linkCount;
!     if (afs_dynrootCellCount != newCellCount) {
  	/*
! 	 * New cells/symlinks added -- bump data version, invalidate vcache.
  	 */
! 	afs_dynrootCellCount = newCellCount;
  	afs_dynrootVersion++;
  	afs_dynrootVersionHigh = osi_Time();
  	doFlush = 1;
***************
*** 376,412 ****
  	struct cell *c;
  	int namelen, linklen, cellidx, rw;
  
! 	cellidx = VNUM2CIDX(avc->fid.Fid.Vnode);
! 	rw = VNUM2RW(avc->fid.Fid.Vnode);
  
! 	c = afs_GetCellByIndex(cellidx, READ_LOCK);
  	if (!c) {
  	    afs_warn("dynroot vnode inconsistency, can't find cell %d\n",
  		     cellidx);
  	    return 0;
  	}
  
- 	memset(status, 0, sizeof(struct AFSFetchStatus));
- 
  	if (c->states & CAlias) {
  	    /*
  	     * linkData needs to contain the name of the cell
  	     * we're aliasing for.
  	     */
! 	    struct cell *tca = c->alias;
  
! 	    if (!tca) {
! 		afs_warn("dynroot: alias %s missing cell alias pointer\n",
  			 c->cellName);
  		linklen = 7;
  		avc->linkData = afs_osi_Alloc(linklen + 1);
  		strcpy(avc->linkData, "unknown");
  	    } else {
! 		int namelen = strlen(tca->cellName);
  		linklen = rw + namelen;
  		avc->linkData = afs_osi_Alloc(linklen + 1);
  		strcpy(avc->linkData, rw ? "." : "");
! 		strcat(avc->linkData, tca->cellName);
  	    }
  
  	    status->UnixModeBits = 0755;
--- 430,504 ----
  	struct cell *c;
  	int namelen, linklen, cellidx, rw;
  
! 	memset(status, 0, sizeof(struct AFSFetchStatus));
  
! 	status->FileType        = SymbolicLink;
! 	status->LinkCount       = 1;
! 	status->DataVersion     = 1;
! 	status->CallerAccess    = PRSFS_LOOKUP | PRSFS_READ;
! 	status->AnonymousAccess = PRSFS_LOOKUP | PRSFS_READ;
! 	status->ParentVnode     = 1;
! 	status->ParentUnique    = 1;
! 
! 	if (VNUM_TO_VNTYPE(avc->fid.Fid.Vnode) == VN_TYPE_SYMLINK) {
! 	    struct afs_dynSymlink *ts;
! 	    int index = VNUM_TO_VNID(avc->fid.Fid.Vnode);
! 
! 	    ObtainReadLock(&afs_dynSymlinkLock);
! 	    ts = afs_dynSymlinkBase;
! 	    while (ts) {
! 		if (ts->index == index) break;
! 		ts = ts->next;
! 	    }
! 
! 	    if (ts) {
! 		linklen = strlen(ts->target);
! 		avc->linkData = afs_osi_Alloc(linklen + 1);
! 		strcpy(avc->linkData, ts->target);
! 
! 		status->Length       = linklen;
! 		status->UnixModeBits = 0755;
! 	    }
! 	    ReleaseReadLock(&afs_dynSymlinkLock);
! 
! 	    return ts ? 1 : 0;
! 	}
! 
! 	if (VNUM_TO_VNTYPE(avc->fid.Fid.Vnode) != VN_TYPE_CELL) {
! 	    afs_warn("dynroot vnode inconsistency, unknown VNTYPE %d\n",
! 		     VNUM_TO_VNTYPE(avc->fid.Fid.Vnode));
! 	    return 0;
! 	}
! 
! 	cellidx = VNUM_TO_CIDX(avc->fid.Fid.Vnode);
! 	rw = VNUM_TO_RW(avc->fid.Fid.Vnode);
! 
! 	c = afs_GetCellByIndex(cellidx, READ_LOCK, 1 /* refresh */);
  	if (!c) {
  	    afs_warn("dynroot vnode inconsistency, can't find cell %d\n",
  		     cellidx);
  	    return 0;
  	}
  
  	if (c->states & CAlias) {
  	    /*
  	     * linkData needs to contain the name of the cell
  	     * we're aliasing for.
  	     */
! 	    char *realName = c->realName;
  
! 	    if (!realName) {
! 		afs_warn("dynroot: alias %s missing real cell name\n",
  			 c->cellName);
  		linklen = 7;
  		avc->linkData = afs_osi_Alloc(linklen + 1);
  		strcpy(avc->linkData, "unknown");
  	    } else {
! 		int namelen = strlen(realName);
  		linklen = rw + namelen;
  		avc->linkData = afs_osi_Alloc(linklen + 1);
  		strcpy(avc->linkData, rw ? "." : "");
! 		strcat(avc->linkData, realName);
  	    }
  
  	    status->UnixModeBits = 0755;
***************
*** 424,438 ****
  	    status->UnixModeBits = 0644;
  	}
  
! 	status->FileType        = SymbolicLink;
! 	status->LinkCount       = 1;
! 	status->Length          = linklen;
! 	status->DataVersion     = 1;
! 	status->CallerAccess    = PRSFS_LOOKUP | PRSFS_READ;
! 	status->AnonymousAccess = PRSFS_LOOKUP | PRSFS_READ;
! 	status->ParentVnode     = 1;
! 	status->ParentUnique    = 1;
! 
  	afs_PutCell(c, READ_LOCK);
  	return 1;
      }
--- 516,522 ----
  	    status->UnixModeBits = 0644;
  	}
  
! 	status->Length = linklen;
  	afs_PutCell(c, READ_LOCK);
  	return 1;
      }
***************
*** 458,461 ****
--- 542,642 ----
  afs_GetDynrootEnable()
  {
      return afs_dynrootEnable;
+ }
+ 
+ /*
+  * Remove a temporary symlink entry from /afs.
+  */
+ int
+ afs_DynrootVOPRemove(avc, acred, aname)
+     struct vcache *avc;
+     struct AFS_UCRED *acred;
+     char *aname;
+ {
+     struct afs_dynSymlink **tpps;
+     struct afs_dynSymlink *tps;
+     struct cell *c;
+     int found = 0;
+ 
+     if (acred->cr_uid)
+ 	return EPERM;
+ 
+     ObtainWriteLock(&afs_dynSymlinkLock, 97);
+     tpps = &afs_dynSymlinkBase;
+     while (*tpps) {
+ 	tps = *tpps;
+ 	if (afs_strcasecmp(aname, tps->name) == 0) {
+ 	    afs_osi_Free(tps->name, strlen(tps->name) + 1);
+ 	    afs_osi_Free(tps->target, strlen(tps->target) + 1);
+ 	    *tpps = tps->next;
+ 	    afs_osi_Free(tps, sizeof(*tps));
+ 	    afs_dynSymlinkIndex++;
+ 	    found = 1;
+ 	    break;
+ 	}
+ 	tpps = &(tps->next);
+     }
+     ReleaseWriteLock(&afs_dynSymlinkLock);
+     if (found) {
+ 	afs_RefreshDynroot();
+ 	return 0;
+     }
+ 
+     /* Check if this is an actual cell? */
+     c = afs_GetCellByName2(aname, READ_LOCK, 0 /* no AFSDB */);
+     if (c) {
+ 	afs_PutCell(c, READ_LOCK);
+ 	return EROFS;
+     } else {
+ 	return ENOENT;
+     }
+ }
+ 
+ /*
+  * Create a temporary symlink entry in /afs.
+  */
+ int
+ afs_DynrootVOPSymlink(avc, acred, aname, atargetName)
+     struct vcache *avc;
+     struct AFS_UCRED *acred;
+     char *aname;
+     char *atargetName;
+ {
+     struct afs_dynSymlink *tps;
+     struct cell *c;
+ 
+     if (acred->cr_uid)
+ 	return EPERM;
+ 
+     /* Check if it's already a cell */
+     c = afs_GetCellByName2(aname, READ_LOCK, 0 /* no AFSDB */);
+     if (c) {
+ 	afs_PutCell(c, READ_LOCK);
+ 	return EEXIST;
+     }
+ 
+     /* Check if it's already a symlink */
+     ObtainWriteLock(&afs_dynSymlinkLock, 91);
+     tps = afs_dynSymlinkBase;
+     while (tps) {
+ 	if (afs_strcasecmp(aname, tps->name) == 0) {
+ 	    ReleaseWriteLock(&afs_dynSymlinkLock);
+ 	    return EEXIST;
+ 	}
+ 	tps = tps->next;
+     }
+ 
+     /* Doesn't already exist -- go ahead and create it */
+     tps = afs_osi_Alloc(sizeof(*tps));
+     tps->index = afs_dynSymlinkIndex++;
+     tps->next = afs_dynSymlinkBase;
+     tps->name = afs_osi_Alloc(strlen(aname) + 1);
+     strcpy(tps->name, aname);
+     tps->target = afs_osi_Alloc(strlen(atargetName) + 1);
+     strcpy(tps->target, atargetName);
+     afs_dynSymlinkBase = tps;
+     ReleaseWriteLock(&afs_dynSymlinkLock);
+ 
+     afs_RefreshDynroot();
+     return 0;
  }
Index: openafs/src/afs/afs_nfsdisp.c
diff -c openafs/src/afs/afs_nfsdisp.c:1.1.2.1 openafs/src/afs/afs_nfsdisp.c:1.1.2.2
*** openafs/src/afs/afs_nfsdisp.c:1.1.2.1	Sat Oct 13 00:40:48 2001
--- openafs/src/afs/afs_nfsdisp.c	Sun Jan 20 04:05:44 2002
***************
*** 10,16 ****
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/afs_nfsdisp.c,v 1.1.2.1 2001/10/13 04:40:48 shadow Exp $");
  
  #include "../afs/stds.h"
  #include "../afs/sysincludes.h" /* Standard vendor system headers */
--- 10,16 ----
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/afs_nfsdisp.c,v 1.1.2.2 2002/01/20 09:05:44 shadow Exp $");
  
  #include "../afs/stds.h"
  #include "../afs/sysincludes.h" /* Standard vendor system headers */
***************
*** 494,500 ****
          case NFSPROC3_LOOKUP: 
  	{
              LOOKUP3args *arg = (LOOKUP3args *)args;
!             fhp1 = (nfs_fh3 *) &arg->what.dir;
              break;
          } 
          case NFSPROC3_ACCESS: 
--- 494,500 ----
          case NFSPROC3_LOOKUP: 
  	{
              LOOKUP3args *arg = (LOOKUP3args *)args;
!             fhp1 = (nfs_fh3 *) &arg->what.dirp;
              break;
          } 
          case NFSPROC3_ACCESS: 
Index: openafs/src/afs/afs_osi.c
diff -c openafs/src/afs/afs_osi.c:1.8 openafs/src/afs/afs_osi.c:1.8.2.5
*** openafs/src/afs/afs_osi.c:1.8	Tue Aug  7 20:03:28 2001
--- openafs/src/afs/afs_osi.c	Thu Jan 24 05:43:15 2002
***************
*** 10,16 ****
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/afs_osi.c,v 1.8 2001/08/08 00:03:28 shadow Exp $");
  
  #include "../afs/sysincludes.h"	/* Standard vendor system headers */
  #include "../afs/afsincludes.h"	/* Afs-based standard headers */
--- 10,16 ----
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/afs_osi.c,v 1.8.2.5 2002/01/24 10:43:15 shadow Exp $");
  
  #include "../afs/sysincludes.h"	/* Standard vendor system headers */
  #include "../afs/afsincludes.h"	/* Afs-based standard headers */
***************
*** 280,315 ****
  
  #endif /* AFS_TEXT_ENV */
  
  /* procedure for making our processes as invisible as we can */
  void afs_osi_Invisible() {
! #ifndef	AFS_AIX32_ENV
!     /* called once per "kernel" lwp to make it invisible */
  #ifdef AFS_DEC_ENV
      u.u_procp->p_type |= SSYS;
! #else
! #if	defined(AFS_SUN5_ENV)
      curproc->p_flag |= SSYS;
- #else
- #if defined(AFS_SGI_ENV)
-     vrelvm();
  #endif
! #ifdef	AFS_SUN_ENV
!     relvm(u.u_procp); 	/* release all the resources */
! #endif
! #if	defined(AFS_HPUX101_ENV)
      set_system_proc(u.u_procp);
! #else
  #if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
      current_proc()->p_flag |= P_SYSTEM;
- #else
- #if !defined(AFS_SGI64_ENV) && !defined(AFS_LINUX20_ENV)
-     u.u_procp->p_flag |= SSYS;
- #endif /* AFS_SGI64_ENV */
- #endif
- #endif
  #endif
! #endif
! #endif
      AFS_STATCNT(osi_Invisible);
  }
  
--- 280,328 ----
  
  #endif /* AFS_TEXT_ENV */
  
+ /* mask signals in afsds */
+ void afs_osi_MaskSignals(){
+ #ifdef AFS_LINUX22_ENV
+     osi_linux_mask();
+ #endif
+ }
+     
+ /* unmask signals in rxk listener */
+ void afs_osi_UnmaskRxkSignals(){
+ #ifdef AFS_LINUX22_ENV
+     osi_linux_unmask();
+ #endif
+ }
+     
+ /* register rxk listener proc info */
+ void afs_osi_RxkRegister(){
+ #ifdef AFS_LINUX22_ENV
+     osi_linux_rxkreg();
+ #endif
+ }
+ 
  /* procedure for making our processes as invisible as we can */
  void afs_osi_Invisible() {
! #ifdef AFS_LINUX22_ENV
!     afs_osi_MaskSignals();
! #endif 
  #ifdef AFS_DEC_ENV
      u.u_procp->p_type |= SSYS;
! #endif 
! #if AFS_SUN5_ENV
      curproc->p_flag |= SSYS;
  #endif
! #if AFS_HPUX101_ENV
      set_system_proc(u.u_procp);
! #endif
  #if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
+     /* maybe call init_process instead? */
      current_proc()->p_flag |= P_SYSTEM;
  #endif
! #if defined(AFS_SGI_ENV)
!     vrelvm();
! #endif /* AFS_SGI_ENV */
! 
      AFS_STATCNT(osi_Invisible);
  }
  
Index: openafs/src/afs/afs_osi_vget.c
diff -c openafs/src/afs/afs_osi_vget.c:1.5 openafs/src/afs/afs_osi_vget.c:1.5.2.1
*** openafs/src/afs/afs_osi_vget.c:1.5	Tue Aug  7 20:03:28 2001
--- openafs/src/afs/afs_osi_vget.c	Sun Jan 20 03:20:54 2002
***************
*** 14,20 ****
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/afs_osi_vget.c,v 1.5 2001/08/08 00:03:28 shadow Exp $");
  
  #include "../afs/sysincludes.h"	/* Standard vendor system headers */
  #include "../afs/afsincludes.h"	/* Afs-based standard headers */
--- 14,20 ----
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/afs_osi_vget.c,v 1.5.2.1 2002/01/20 08:20:54 shadow Exp $");
  
  #include "../afs/sysincludes.h"	/* Standard vendor system headers */
  #include "../afs/afsincludes.h"	/* Afs-based standard headers */
***************
*** 55,61 ****
  	 */
  	struct cell *tcell;
  	cellindex = (Sfid.CellAndUnique >> 24) & 0xff;
! 	tcell = afs_GetCellByIndex(cellindex, READ_LOCK);
  	if (!tcell) {
  	    return ENOENT;
          }
--- 55,61 ----
  	 */
  	struct cell *tcell;
  	cellindex = (Sfid.CellAndUnique >> 24) & 0xff;
! 	tcell = afs_GetCellByIndex(cellindex, READ_LOCK, 0 /* don't refresh */);
  	if (!tcell) {
  	    return ENOENT;
          }
Index: openafs/src/afs/afs_pioctl.c
diff -c openafs/src/afs/afs_pioctl.c:1.22.2.1 openafs/src/afs/afs_pioctl.c:1.22.2.3
*** openafs/src/afs/afs_pioctl.c:1.22.2.1	Sat Oct 13 00:20:23 2001
--- openafs/src/afs/afs_pioctl.c	Sun Jan 20 03:20:54 2002
***************
*** 10,16 ****
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/afs_pioctl.c,v 1.22.2.1 2001/10/13 04:20:23 shadow Exp $");
  
  #include "../afs/sysincludes.h"	/* Standard vendor system headers */
  #include "../afs/afsincludes.h"	/* Afs-based standard headers */
--- 10,16 ----
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/afs_pioctl.c,v 1.22.2.3 2002/01/20 08:20:54 shadow Exp $");
  
  #include "../afs/sysincludes.h"	/* Standard vendor system headers */
  #include "../afs/afsincludes.h"	/* Afs-based standard headers */
***************
*** 66,78 ****
  static int PGetInitParams(), PFlushMount(), PRxStatProc(), PRxStatPeer();
  static int PGetRxkcrypt(), PSetRxkcrypt();
  static int PPrefetchFromTape(), PResidencyCmd();
  int PExportAfs();
  
  static int HandleClientContext(struct afs_ioctl *ablob, int *com, struct AFS_UCRED **acred, struct AFS_UCRED *credp);
  
  extern struct cm_initparams cm_initParams;
  
! static int (*(pioctlSw[]))() = {
    PBogus,			/* 0 */
    PSetAcl,			/* 1 */
    PGetAcl,			/* 2 */
--- 66,79 ----
  static int PGetInitParams(), PFlushMount(), PRxStatProc(), PRxStatPeer();
  static int PGetRxkcrypt(), PSetRxkcrypt();
  static int PPrefetchFromTape(), PResidencyCmd();
+ static int PNewAlias(), PListAliases();
  int PExportAfs();
  
  static int HandleClientContext(struct afs_ioctl *ablob, int *com, struct AFS_UCRED **acred, struct AFS_UCRED *credp);
  
  extern struct cm_initparams cm_initParams;
  
! static int (*(VpioctlSw[]))() = {
    PBogus,			/* 0 */
    PSetAcl,			/* 1 */
    PGetAcl,			/* 2 */
***************
*** 141,148 ****
--- 142,156 ----
    PNoop,			/* 65 -- arla: break callback */
    PPrefetchFromTape,            /* 66 -- MR-AFS: prefetch file from tape */
    PResidencyCmd,                /* 67 -- MR-AFS: generic commnd interface */
+   PNoop,			/* 68 -- arla: fetch stats */
  };
  
+ static int (*(CpioctlSw[]))() = {
+   PBogus,			/* 0 */
+   PNewAlias,			/* 1 -- create new cell alias */
+   PListAliases,			/* 2 -- list cell aliases */
+ };
+ 
  #define PSetClientContext 99	/*  Special pioctl to setup caller's creds  */
  int afs_nobody = NFS_NOBODY;
  
***************
*** 741,761 ****
  #endif
      AFS_STATCNT(afs_syscall_pioctl);
      if (follow) follow = 1;	/* compat. with old venus */
- #ifndef	AFS_SUN5_ENV
-     if (! _VALIDVICEIOCTL(com)) {
- 	PIOCTL_FREE_CRED();
- #if defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
-         return EINVAL;
- #else	/* AFS_OSF_ENV */
- #if defined(AFS_SGI64_ENV) || defined(AFS_LINUX22_ENV)
-         return EINVAL;
- #else
- 	setuerror(EINVAL);
- 	return EINVAL;
- #endif
- #endif
-     }
- #endif
      code = copyin_afs_ioctl(cmarg, &data);
      if (code) {
  	PIOCTL_FREE_CRED();
--- 749,754 ----
***************
*** 1036,1051 ****
  {
      struct vrequest treq;
      register afs_int32 code;
!     register afs_int32 function;
      afs_int32 inSize, outSize;
      char *inData, *outData;
  
      afs_Trace3(afs_iclSetp, CM_TRACE_PIOCTL, ICL_TYPE_INT32, acom & 0xff,
  	       ICL_TYPE_POINTER, avc, ICL_TYPE_INT32, afollow);
      AFS_STATCNT(HandlePioctl);
      if (code = afs_InitReq(&treq, *acred)) return code;
      function = acom & 0xff;
!     if (function >= (sizeof(pioctlSw) / sizeof(char *))) {
        return EINVAL;	/* out of range */
      }
      inSize = ablob->in_size;
--- 1029,1059 ----
  {
      struct vrequest treq;
      register afs_int32 code;
!     register afs_int32 function, device;
      afs_int32 inSize, outSize;
      char *inData, *outData;
+     int (*(*pioctlSw))();
+     int pioctlSwSize;
  
      afs_Trace3(afs_iclSetp, CM_TRACE_PIOCTL, ICL_TYPE_INT32, acom & 0xff,
  	       ICL_TYPE_POINTER, avc, ICL_TYPE_INT32, afollow);
      AFS_STATCNT(HandlePioctl);
      if (code = afs_InitReq(&treq, *acred)) return code;
+     device = (acom & 0xff00) >> 8;
+     switch (device) {
+ 	case 'V':	/* Original pioctl's */
+ 		pioctlSw = VpioctlSw;
+ 		pioctlSwSize = sizeof(VpioctlSw);
+ 		break;
+ 	case 'C':	/* Coordinated/common pioctl's */
+ 		pioctlSw = CpioctlSw;
+ 		pioctlSwSize = sizeof(CpioctlSw);
+ 		break;
+ 	default:
+ 		return EINVAL;
+     }
      function = acom & 0xff;
!     if (function >= (pioctlSwSize / sizeof(char *))) {
        return EINVAL;	/* out of range */
      }
      inSize = ablob->in_size;
***************
*** 1061,1067 ****
      }
      outData = osi_AllocLargeSpace(AFS_LRALLOCSIZ);
      outSize = 0;
!     if (function == 3)	/* PSetTokens */
  	code = (*pioctlSw[function])(avc, function, &treq, inData, outData, inSize, &outSize, acred);
      else
  	code = (*pioctlSw[function])(avc, function, &treq, inData, outData, inSize, &outSize, *acred);
--- 1069,1075 ----
      }
      outData = osi_AllocLargeSpace(AFS_LRALLOCSIZ);
      outSize = 0;
!     if (function == 3 && device == 'V')	/* PSetTokens */
  	code = (*pioctlSw[function])(avc, function, &treq, inData, outData, inSize, &outSize, acred);
      else
  	code = (*pioctlSw[function])(avc, function, &treq, inData, outData, inSize, &outSize, *acred);
***************
*** 2299,2304 ****
--- 2307,2359 ----
      return code;
  }
  
+ static PNewAlias(avc, afun, areq, ain, aout, ainSize, aoutSize, acred)
+     struct vcache *avc;
+     int afun;
+     struct vrequest *areq;
+     register char *ain;
+     char *aout;
+     afs_int32 ainSize;
+     struct AFS_UCRED *acred;
+     afs_int32 *aoutSize;	/* set this */
+ {
+     /* create a new cell alias */
+     register struct cell *tcell;
+     char *tp = ain;
+     register afs_int32 code;
+     char *realName, *aliasName;
+     register struct afs_q *cq, *tq;
+     
+     if ( !afs_resourceinit_flag ) 	/* afs deamons havn't started yet */
+ 	return EIO;          /* Inappropriate ioctl for device */
+ 
+     if (!afs_osi_suser(acred))
+ 	return EACCES;
+ 
+     aliasName = tp;
+     tp += strlen(aliasName) + 1;
+     realName = tp;
+ 
+     /*
+      * Prevent user from shooting themselves in the foot -- don't allow
+      * creation of aliases when a real cell already exists with that name.
+      */
+     ObtainReadLock(&afs_xcell);
+     for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
+ 	tcell = QTOC(cq); tq = QNext(cq);
+ 	if ((afs_strcasecmp(tcell->cellName, aliasName) == 0) &&
+ 	    !(tcell->states & CAlias)) {
+ 	    ReleaseReadLock(&afs_xcell);
+ 	    return EEXIST;
+ 	}
+     }
+     ReleaseReadLock(&afs_xcell);
+ 
+     code = afs_NewCell(aliasName, 0, CAlias, 0, 0, 0, 0, realName);
+     *aoutSize = 0;
+     return code;
+ }
+ 
  static PListCells(avc, afun, areq, ain, aout, ainSize, aoutSize)
      struct vcache *avc;
      int afun;
***************
*** 2321,2328 ****
      ObtainReadLock(&afs_xcell);
      for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
  	tcell = QTOC(cq); tq = QNext(cq);
  	if (whichCell == 0) break;
! 	if (tq == &CellLRU) tcell = 0;
  	whichCell--;
      }
      if (tcell) {
--- 2376,2387 ----
      ObtainReadLock(&afs_xcell);
      for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
  	tcell = QTOC(cq); tq = QNext(cq);
+ 	if (tcell->states & CAlias) {
+ 	    tcell = 0;
+ 	    continue;
+ 	}
  	if (whichCell == 0) break;
! 	tcell = 0;
  	whichCell--;
      }
      if (tcell) {
***************
*** 2343,2348 ****
--- 2402,2452 ----
      else return EDOM;
  }
  
+ static PListAliases(avc, afun, areq, ain, aout, ainSize, aoutSize)
+     struct vcache *avc;
+     int afun;
+     struct vrequest *areq;
+     char *ain, *aout;
+     afs_int32 ainSize;
+     afs_int32 *aoutSize;	/* set this */
+ {
+     afs_int32 whichAlias;
+     register struct cell *tcell=0;
+     register char *cp, *tp = ain;
+     register struct afs_q *cq, *tq;
+ 
+     if ( !afs_resourceinit_flag ) 	/* afs deamons havn't started yet */
+ 	return EIO;          /* Inappropriate ioctl for device */
+     if (ainSize < sizeof(afs_int32))
+ 	return EINVAL;
+ 
+     memcpy((char *)&whichAlias, tp, sizeof(afs_int32));
+     tp += sizeof(afs_int32);
+ 
+     ObtainReadLock(&afs_xcell);
+     for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
+ 	tcell = QTOC(cq); tq = QNext(cq);
+ 	if (!(tcell->states & CAlias)) {
+ 	    tcell = 0;
+ 	    continue;
+ 	}
+ 	if (whichAlias == 0) break;
+ 	tcell = 0;
+ 	whichAlias--;
+     }
+     if (tcell) {	
+ 	cp = aout;
+ 	strcpy(cp, tcell->cellName);
+ 	cp += strlen(tcell->cellName)+1;
+ 	strcpy(cp, tcell->realName);
+ 	cp += strlen(tcell->realName)+1;
+ 	*aoutSize = cp - aout;
+     }
+     ReleaseReadLock(&afs_xcell);
+     if (tcell) return 0;
+     else return EDOM;
+ }
+ 
  static PRemoveMount(avc, afun, areq, ain, aout, ainSize, aoutSize)
      struct vcache *avc;
      int afun;
***************
*** 2836,2862 ****
    register int  k;
  
    if (vlonly) {
!      struct cell *tcell;
!      for(k=0;k<s;k++) {
!         tcell = afs_GetCell(l[k], WRITE_LOCK);
! 	if (!tcell) continue;
! 	afs_SortServers(tcell->cellHosts, MAXCELLHOSTS);
! 	afs_PutCell(tcell, WRITE_LOCK);
!      }
!      return;
    }
  
    ObtainReadLock(&afs_xvolume);
    for (i= 0; i< NVOLS; i++) {
!      for (j=afs_volumes[i];j;j=j->next) {
!         for (k=0;k<s;k++)
! 	   if (j->cell == l[k]) {
! 	      ObtainWriteLock(&j->lock,233);
! 	      afs_SortServers(j->serverHost, MAXHOSTS);
! 	      ReleaseWriteLock(&j->lock);
! 	      break; 
! 	   }
!      }
    }
    ReleaseReadLock(&afs_xvolume);
  }
--- 2940,2968 ----
    register int  k;
  
    if (vlonly) {
!       struct cell *tcell;
!       ObtainWriteLock(&afs_xcell,300);
!       for(k=0;k<s;k++) {
! 	  tcell = afs_GetCellNoLock(l[k], WRITE_LOCK);
! 	  if (!tcell) continue;
! 	  afs_SortServers(tcell->cellHosts, MAXCELLHOSTS);
! 	  afs_PutCell(tcell, WRITE_LOCK);
!       }
!       ReleaseWriteLock(&afs_xcell);
!       return;
    }
  
    ObtainReadLock(&afs_xvolume);
    for (i= 0; i< NVOLS; i++) {
!       for (j=afs_volumes[i];j;j=j->next) {
! 	  for (k=0;k<s;k++)
! 	      if (j->cell == l[k]) {
! 		  ObtainWriteLock(&j->lock,233);
! 		  afs_SortServers(j->serverHost, MAXHOSTS);
! 		  ReleaseWriteLock(&j->lock);
! 		  break; 
! 	      }
!       }
    }
    ReleaseReadLock(&afs_xvolume);
  }
Index: openafs/src/afs/afs_segments.c
diff -c openafs/src/afs/afs_segments.c:1.5 openafs/src/afs/afs_segments.c:1.5.2.1
*** openafs/src/afs/afs_segments.c:1.5	Tue Aug  7 20:03:28 2001
--- openafs/src/afs/afs_segments.c	Wed Dec 26 15:29:19 2001
***************
*** 13,19 ****
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/afs_segments.c,v 1.5 2001/08/08 00:03:28 shadow Exp $");
  
  #include "../afs/sysincludes.h" /*Standard vendor system headers*/
  #include "../afs/afsincludes.h" /*AFS-based standard headers*/
--- 13,19 ----
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/afs_segments.c,v 1.5.2.1 2001/12/26 20:29:19 shadow Exp $");
  
  #include "../afs/sysincludes.h" /*Standard vendor system headers*/
  #include "../afs/afsincludes.h" /*AFS-based standard headers*/
***************
*** 182,194 ****
      dcList = (struct dcache **) osi_AllocLargeSpace(AFS_LRALLOCSIZ);
      afs_Trace2(afs_iclSetp, CM_TRACE_STOREALL, ICL_TYPE_POINTER, avc,
  	       ICL_TYPE_INT32, avc->m.Length);
! #ifndef AFS_AIX32_ENV
      /* In the aix vm implementation we need to do the vm_writep even
       * on the memcache case since that's we adjust the file's size
       * and finish flushing partial vm pages.
       */
      if (cacheDiskType != AFS_FCACHE_TYPE_MEM) 
! #endif /* AFS_AIX32_ENV */
      {
  	/* If we're not diskless, reading a file may stress the VM
  	 * system enough to cause a pageout, and this vnode would be
--- 182,194 ----
      dcList = (struct dcache **) osi_AllocLargeSpace(AFS_LRALLOCSIZ);
      afs_Trace2(afs_iclSetp, CM_TRACE_STOREALL, ICL_TYPE_POINTER, avc,
  	       ICL_TYPE_INT32, avc->m.Length);
! #if !defined(AFS_AIX32_ENV) && !defined(AFS_SGI65_ENV)
      /* In the aix vm implementation we need to do the vm_writep even
       * on the memcache case since that's we adjust the file's size
       * and finish flushing partial vm pages.
       */
      if (cacheDiskType != AFS_FCACHE_TYPE_MEM) 
! #endif /* !AFS_AIX32_ENV && !AFS_SGI65_ENV */
      {
  	/* If we're not diskless, reading a file may stress the VM
  	 * system enough to cause a pageout, and this vnode would be
Index: openafs/src/afs/afs_server.c
diff -c openafs/src/afs/afs_server.c:1.11.2.1 openafs/src/afs/afs_server.c:1.11.2.2
*** openafs/src/afs/afs_server.c:1.11.2.1	Sat Oct 13 00:20:24 2001
--- openafs/src/afs/afs_server.c	Sat Dec 29 18:13:44 2001
***************
*** 32,38 ****
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/afs_server.c,v 1.11.2.1 2001/10/13 04:20:24 shadow Exp $");
  
  #include "../afs/stds.h"
  #include "../afs/sysincludes.h"	/* Standard vendor system headers */
--- 32,38 ----
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/afs_server.c,v 1.11.2.2 2001/12/29 23:13:44 shadow Exp $");
  
  #include "../afs/stds.h"
  #include "../afs/sysincludes.h"	/* Standard vendor system headers */
***************
*** 504,516 ****
      struct server *ts;
      struct srvAddr *sa;
      struct conn *tc;
!     afs_int32 i;
      afs_int32 code;
      afs_int32 start, end, delta;
      osi_timeval_t tv;
      int setTimer;
      struct unixuser *tu;
      char tbuffer[CVBS];
      XSTATS_DECLS;
  
      AFS_STATCNT(afs_CheckServers);
--- 504,518 ----
      struct server *ts;
      struct srvAddr *sa;
      struct conn *tc;
!     afs_int32 i, j;
      afs_int32 code;
      afs_int32 start, end, delta;
      osi_timeval_t tv;
      int setTimer;
      struct unixuser *tu;
      char tbuffer[CVBS];
+     int srvAddrCount;
+     struct srvAddr **addrs;
      XSTATS_DECLS;
  
      AFS_STATCNT(afs_CheckServers);
***************
*** 518,645 ****
      ObtainReadLock(&afs_xserver);  /* Necessary? */
      ObtainReadLock(&afs_xsrvAddr);	
  
      for (i=0;i<NSERVERS;i++) {
!        for (sa = afs_srvAddrs[i]; sa; sa = sa->next_bkt) { 
! 	  ts = sa->server;
! 	  if (!ts)
! 	     continue;
! 	  /* See if a cell to check was specified.  If it is spec'd and not
! 	   * this server's cell, just skip the server.
! 	   */
! 	  if (acellp && acellp != ts->cell)
! 	       continue;
! 
! 	  if ((!adown && (sa->sa_flags & SRVADDR_ISDOWN)) 
! 	      || (adown && !(sa->sa_flags & SRVADDR_ISDOWN)))
! 	       continue;
! 	  /* check vlserver with special code */
! 	  if (sa->sa_portal == AFS_VLPORT) {
! 	     CheckVLServer(sa, &treq);
! 	     continue;
! 	  }
! 
! 	  if (!ts->cell) /* not really an active server, anyway, it must */
! 	     continue;   /* have just been added by setsprefs */ 
! 	  
! 	  /* get a connection, even if host is down; bumps conn ref count */
! 	  tu = afs_GetUser(treq.uid, ts->cell, SHARED_LOCK);
! 	  tc = afs_ConnBySA(sa, ts->cell->fsport, ts->cell->cell, tu,
! 			    1/*force*/, 1/*create*/, SHARED_LOCK);
! 	  afs_PutUser(tu, SHARED_LOCK);
! 	  if (!tc)
! 	       continue;
! 
! 	  if ((sa->sa_flags & SRVADDR_ISDOWN) || HaveCallBacksFrom(ts) ||
! 	      (tc->srvr->server == afs_setTimeHost)) {
! 	     if (sa->sa_flags & SRVADDR_ISDOWN) {
  		rx_SetConnDeadTime(tc->id, 3);
  		setTimer = 1;
! 	     } else
! 		  setTimer = 0;
! 	     XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_GETTIME);
! 	     start = osi_Time();	/* time the gettimeofday call */
  #ifdef RX_ENABLE_LOCKS
! 	     AFS_GUNLOCK();
  #endif /* RX_ENABLE_LOCKS */
! 	     code = RXAFS_GetTime(tc->id, &tv.tv_sec, &tv.tv_usec);
  #ifdef RX_ENABLE_LOCKS
! 	     AFS_GLOCK();
  #endif /* RX_ENABLE_LOCKS */
! 	     end = osi_Time();
! 	     XSTATS_END_TIME;
! 	     /*
! 	      * If we're supposed to set the time, and the call worked
! 	      * quickly (same second response) and this is the host we
! 	      * use for the time and the time is really different, then
! 	      * really set the time
! 	      */
! 	     if (code == 0 && start == end && afs_setTime != 0 &&
! 		 (tc->srvr->server == afs_setTimeHost ||
! 		  /*
! 		   * Sync only to a server in the local cell: cell(id)==1
! 		   * or CPrimary.
! 		   */
! 		  (afs_setTimeHost == (struct server *)0 &&
! 		   (ts->cell->cell == 1 || (ts->cell->states&CPrimary))))) {
! 		char msgbuf[90];	/* strlen("afs: setting clock...") + slop */
  		/* set the time */
  		delta = end - tv.tv_sec;   /* how many secs fast we are */
  		/* see if clock has changed enough to make it worthwhile */
  		if (delta >= AFS_MINCHANGE || delta <= -AFS_MINCHANGE) {
! 		   if (delta > AFS_MAXCHANGEBACK) {
! 		      /* setting clock too far back, just do it a little */
! 		      tv.tv_sec = end - AFS_MAXCHANGEBACK;
! 		   }
! 		   afs_osi_SetTime(&tv);
! 		   if (delta > 0) {
! 		      strcpy(msgbuf, "afs: setting clock back ");
! 		      if (delta > AFS_MAXCHANGEBACK) {
! 			 afs_strcat(msgbuf, afs_cv2string(&tbuffer[CVBS], AFS_MAXCHANGEBACK));
! 			 afs_strcat(msgbuf, " seconds (of ");
! 			 afs_strcat(msgbuf, afs_cv2string(&tbuffer[CVBS], delta - AFS_MAXCHANGEBACK));
! 			 afs_strcat(msgbuf, ", via ");
! 			 print_internet_address(msgbuf, sa, "); clock is still fast.", 0);
! 		      } else {
! 			 afs_strcat(msgbuf, afs_cv2string(&tbuffer[CVBS], delta));
! 			 afs_strcat(msgbuf, " seconds (via ");
! 			 print_internet_address(msgbuf, sa, ").", 0);
! 		      }
! 		   }
! 		   else {
! 		      strcpy(msgbuf, "afs: setting clock ahead ");
! 		      afs_strcat(msgbuf, afs_cv2string(&tbuffer[CVBS], -delta));
! 		      afs_strcat(msgbuf, " seconds (via ");
! 		      print_internet_address(msgbuf, sa, ").", 0);
! 		   }
  		}
  		afs_setTimeHost = tc->srvr->server;
! 	     }
! 	     if (setTimer)
! 		  rx_SetConnDeadTime(tc->id, 50);
! 	     if (code >= 0 && (sa->sa_flags & SRVADDR_ISDOWN) && (tc->srvr == sa)) {
  		/* server back up */
  		print_internet_address("afs: file server ", sa, " is back up", 2);
! 		/* 
! 		 * XXX We should hold a server write lock here XXX
! 		 */
  		afs_MarkServerUpOrDown(sa, 0);
  		if (afs_waitForeverCount) {
! 		   afs_osi_Wakeup(&afs_waitForever);
  		}
! 	     }
! 	     else
! 		  if (code < 0) {
! 		     /* server crashed */
! 		     afs_ServerDown(sa);
! 		     ForceNewConnections(sa);  /* multi homed clients */
! 		  }
! 	  }
! 
! 	  afs_PutConn(tc, SHARED_LOCK);	/* done with it now */
!        }   /* for each server loop */
!     }	    /* for each server hash bucket loop */
!     ReleaseReadLock(&afs_xsrvAddr);	
!     ReleaseReadLock(&afs_xserver);
  
  } /*afs_CheckServers*/
  
--- 520,671 ----
      ObtainReadLock(&afs_xserver);  /* Necessary? */
      ObtainReadLock(&afs_xsrvAddr);	
  
+     srvAddrCount = 0;
      for (i=0;i<NSERVERS;i++) {
! 	for (sa = afs_srvAddrs[i]; sa; sa = sa->next_bkt) { 
! 	    srvAddrCount++;
! 	}
!     }
! 
!     addrs = afs_osi_Alloc(srvAddrCount * sizeof(*addrs));
!     j = 0;
!     for (i=0;i<NSERVERS;i++) {
! 	for (sa = afs_srvAddrs[i]; sa; sa = sa->next_bkt) { 
! 	    if (j >= srvAddrCount) break;
! 	    addrs[j++] = sa;
! 	}
!     }
! 
!     ReleaseReadLock(&afs_xsrvAddr);	
!     ReleaseReadLock(&afs_xserver);
! 
!     for (i=0; i<j; i++) {
! 	sa = addrs[i];
! 	ts = sa->server;
! 	if (!ts)
! 	    continue;
! 
! 	/* See if a cell to check was specified.  If it is spec'd and not
! 	 * this server's cell, just skip the server.
! 	 */
! 	if (acellp && acellp != ts->cell)
! 	    continue;
! 
! 	if ((!adown && (sa->sa_flags & SRVADDR_ISDOWN)) ||
! 	    (adown && !(sa->sa_flags & SRVADDR_ISDOWN)))
! 	    continue;
! 
! 	/* check vlserver with special code */
! 	if (sa->sa_portal == AFS_VLPORT) {
! 	    CheckVLServer(sa, &treq);
! 	    continue;
! 	}
! 
! 	if (!ts->cell) /* not really an active server, anyway, it must */
! 	    continue;  /* have just been added by setsprefs */ 
! 
! 	/* get a connection, even if host is down; bumps conn ref count */
! 	tu = afs_GetUser(treq.uid, ts->cell, SHARED_LOCK);
! 	tc = afs_ConnBySA(sa, ts->cell->fsport, ts->cell->cell, tu,
! 			  1/*force*/, 1/*create*/, SHARED_LOCK);
! 	afs_PutUser(tu, SHARED_LOCK);
! 	if (!tc) continue;
! 
! 	if ((sa->sa_flags & SRVADDR_ISDOWN) || HaveCallBacksFrom(ts) ||
! 	    (tc->srvr->server == afs_setTimeHost)) {
! 	    if (sa->sa_flags & SRVADDR_ISDOWN) {
  		rx_SetConnDeadTime(tc->id, 3);
  		setTimer = 1;
! 	    } else {
! 		setTimer = 0;
! 	    }
! 
! 	    XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_GETTIME);
! 	    start = osi_Time();		/* time the gettimeofday call */
  #ifdef RX_ENABLE_LOCKS
! 	    AFS_GUNLOCK();
  #endif /* RX_ENABLE_LOCKS */
! 	    code = RXAFS_GetTime(tc->id, &tv.tv_sec, &tv.tv_usec);
  #ifdef RX_ENABLE_LOCKS
! 	    AFS_GLOCK();
  #endif /* RX_ENABLE_LOCKS */
! 	    end = osi_Time();
! 	    XSTATS_END_TIME;
! 	    /*
! 	     * If we're supposed to set the time, and the call worked
! 	     * quickly (same second response) and this is the host we
! 	     * use for the time and the time is really different, then
! 	     * really set the time
! 	     */
! 	    if (code == 0 && start == end && afs_setTime != 0 &&
! 		(tc->srvr->server == afs_setTimeHost ||
! 		/*
! 		 * Sync only to a server in the local cell: cell(id)==1
! 		 * or CPrimary.
! 		 */
! 		(afs_setTimeHost == (struct server *)0 &&
! 		 (ts->cell->cell == 1 || (ts->cell->states&CPrimary))))) {
! 
! 		char msgbuf[90];  /* strlen("afs: setting clock...") + slop */
  		/* set the time */
  		delta = end - tv.tv_sec;   /* how many secs fast we are */
  		/* see if clock has changed enough to make it worthwhile */
  		if (delta >= AFS_MINCHANGE || delta <= -AFS_MINCHANGE) {
! 		    if (delta > AFS_MAXCHANGEBACK) {
! 			/* setting clock too far back, just do it a little */
! 			tv.tv_sec = end - AFS_MAXCHANGEBACK;
! 		    }
! 		    afs_osi_SetTime(&tv);
! 		    if (delta > 0) {
! 			strcpy(msgbuf, "afs: setting clock back ");
! 			if (delta > AFS_MAXCHANGEBACK) {
! 			    afs_strcat(msgbuf, afs_cv2string(&tbuffer[CVBS], AFS_MAXCHANGEBACK));
! 			    afs_strcat(msgbuf, " seconds (of ");
! 			    afs_strcat(msgbuf, afs_cv2string(&tbuffer[CVBS], delta - AFS_MAXCHANGEBACK));
! 			    afs_strcat(msgbuf, ", via ");
! 			    print_internet_address(msgbuf, sa, "); clock is still fast.", 0);
! 			} else {
! 			    afs_strcat(msgbuf, afs_cv2string(&tbuffer[CVBS], delta));
! 			    afs_strcat(msgbuf, " seconds (via ");
! 			    print_internet_address(msgbuf, sa, ").", 0);
! 			}
! 		    } else {
! 			strcpy(msgbuf, "afs: setting clock ahead ");
! 			afs_strcat(msgbuf, afs_cv2string(&tbuffer[CVBS], -delta));
! 			afs_strcat(msgbuf, " seconds (via ");
! 			print_internet_address(msgbuf, sa, ").", 0);
! 		    }
  		}
  		afs_setTimeHost = tc->srvr->server;
! 	    }
! 	    if (setTimer)
! 		rx_SetConnDeadTime(tc->id, 50);
! 	    if (code >= 0 && (sa->sa_flags & SRVADDR_ISDOWN) && (tc->srvr == sa)) {
  		/* server back up */
  		print_internet_address("afs: file server ", sa, " is back up", 2);
! 
! 		ObtainWriteLock(&afs_xserver, 244);
! 		ObtainWriteLock(&afs_xsrvAddr, 245);	
  		afs_MarkServerUpOrDown(sa, 0);
+ 		ReleaseWriteLock(&afs_xsrvAddr);
+ 		ReleaseWriteLock(&afs_xserver);
+ 
  		if (afs_waitForeverCount) {
! 		    afs_osi_Wakeup(&afs_waitForever);
  		}
! 	    } else {
! 		if (code < 0) {
! 		    /* server crashed */
! 		    afs_ServerDown(sa);
! 		    ForceNewConnections(sa);  /* multi homed clients */
! 		}
! 	    }
! 	}
! 
! 	afs_PutConn(tc, SHARED_LOCK);	/* done with it now */
!     } /* Outer loop over addrs */
! 
!     afs_osi_Free(addrs, srvAddrCount * sizeof(*addrs));
  
  } /*afs_CheckServers*/
  
Index: openafs/src/afs/afs_vcache.c
diff -c openafs/src/afs/afs_vcache.c:1.9.2.1 openafs/src/afs/afs_vcache.c:1.9.2.6
*** openafs/src/afs/afs_vcache.c:1.9.2.1	Sat Oct 13 00:20:24 2001
--- openafs/src/afs/afs_vcache.c	Wed Jan 23 04:30:36 2002
***************
*** 38,44 ****
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/afs_vcache.c,v 1.9.2.1 2001/10/13 04:20:24 shadow Exp $");
  
  #include "../afs/sysincludes.h" /*Standard vendor system headers*/
  #include "../afs/afsincludes.h" /*AFS-based standard headers*/
--- 38,44 ----
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/afs_vcache.c,v 1.9.2.6 2002/01/23 09:30:36 shadow Exp $");
  
  #include "../afs/sysincludes.h" /*Standard vendor system headers*/
  #include "../afs/afsincludes.h" /*AFS-based standard headers*/
***************
*** 525,531 ****
  } /*afs_RemoveVCB*/
  
  
- 
  /*
   * afs_NewVCache
   *
--- 525,530 ----
***************
*** 563,591 ****
  #ifdef AFS_LINUX22_ENV
      if (!freeVCList) {
  	/* Free some if possible. */
! 	 struct afs_q *tq, *uq;
! 	 int i; char *panicstr;
! 	 int vmax = 2 * afs_cacheStats;
! 	 int vn = VCACHE_FREE;
! 
!          AFS_GUNLOCK();
! 	 shrink_dcache_sb(afs_globalVFS);
! 	 AFS_GLOCK();
! 
! 	 i = 0;
! 	 for(tq = VLRU.prev; tq != &VLRU && vn > 0; tq = uq) {
  	    tvc = QTOV(tq);
  	    uq = QPrev(tq);
  	    if (tvc->states & CVFlushed) 
! 		 refpanic ("CVFlushed on VLRU");
  	    else if (i++ > vmax)
! 		 refpanic ("Exceeded pool of AFS vnodes(VLRU cycle?)");
  	    else if (QNext(uq) != tq)
! 		 refpanic ("VLRU inconsistent");
! 
  	    if (tvc == afs_globalVp)
  		continue;
! 
  	    if ( VREFCOUNT(tvc) && tvc->opens == 0 ) {
  		struct inode *ip = (struct inode*)tvc;
  		if (list_empty(&ip->i_dentry)) {
--- 562,586 ----
  #ifdef AFS_LINUX22_ENV
      if (!freeVCList) {
  	/* Free some if possible. */
!         struct afs_q *tq, *uq;
!         int i; char *panicstr;
!         int vmax = 2 * afs_cacheStats;
!         int vn = VCACHE_FREE;
! 	
!         i = 0;
!         for(tq = VLRU.prev; tq != &VLRU && vn > 0; tq = uq) {
  	    tvc = QTOV(tq);
  	    uq = QPrev(tq);
  	    if (tvc->states & CVFlushed) 
!                 refpanic ("CVFlushed on VLRU");
  	    else if (i++ > vmax)
!                 refpanic ("Exceeded pool of AFS vnodes(VLRU cycle?)");
  	    else if (QNext(uq) != tq)
!                 refpanic ("VLRU inconsistent");
! 	    
  	    if (tvc == afs_globalVp)
  		continue;
! 	    
  	    if ( VREFCOUNT(tvc) && tvc->opens == 0 ) {
  		struct inode *ip = (struct inode*)tvc;
  		if (list_empty(&ip->i_dentry)) {
***************
*** 596,619 ****
  		    struct list_head *head = &ip->i_dentry;
  		    int all = 1;
  		restart:
! #if defined(AFS_LINUX24_ENV)
! 		    spin_lock(&dcache_lock);
! #endif
  		    cur = head;
  		    while ((cur = cur->next) != head) {
  			struct dentry *dentry = list_entry(cur, struct dentry, d_alias);
! #if defined(AFS_LINUX24_ENV)
! 			if (!atomic_read(&dentry->d_count)) {
! #else
! 			if (!dentry->d_count) {
! #endif
  			    AFS_GUNLOCK();
! #if defined(AFS_LINUX24_ENV)
! 			    dget_locked(dentry);
! 			    spin_unlock(&dcache_lock);
! #else
! 			    dget(dentry);
! #endif
  			    d_drop(dentry);
  			    dput(dentry);
  			    AFS_GLOCK();
--- 591,604 ----
  		    struct list_head *head = &ip->i_dentry;
  		    int all = 1;
  		restart:
! 		    DLOCK();
  		    cur = head;
  		    while ((cur = cur->next) != head) {
  			struct dentry *dentry = list_entry(cur, struct dentry, d_alias);
! 			if (!DCOUNT(dentry)) {
  			    AFS_GUNLOCK();
! 			    DGET(dentry);
! 			    DUNLOCK();
  			    d_drop(dentry);
  			    dput(dentry);
  			    AFS_GLOCK();
***************
*** 623,636 ****
  			    all = 0;
  			}
  		    }
! #if defined(AFS_LINUX24_ENV)
! 		    spin_unlock(&dcache_lock);
! #endif
  		    if (all) vn --;
  		}
  	    }
  	    if (tq == uq) break;
! 	 }
      }
  #endif /* AFS_LINUX22_ENV */
  #ifdef	AFS_OSF_ENV
--- 608,619 ----
  			    all = 0;
  			}
  		    }
! 		    DUNLOCK();
  		    if (all) vn --;
  		}
  	    }
  	    if (tq == uq) break;
!         }
      }
  #endif /* AFS_LINUX22_ENV */
  #ifdef	AFS_OSF_ENV
***************
*** 962,969 ****
--- 945,961 ----
  	INIT_LIST_HEAD(&ip->i_data.dirty_pages);
  	INIT_LIST_HEAD(&ip->i_data.locked_pages);
  	INIT_LIST_HEAD(&ip->i_dirty_buffers);
+ #ifdef STRUCT_INODE_HAS_I_DIRTY_DATA_BUFFERS
+ 	INIT_LIST_HEAD(&ip->i_dirty_data_buffers);
+ #endif
+ #ifdef STRUCT_INODE_HAS_I_DEVICES
+ 	INIT_LIST_HEAD(&ip->i_devices);
+ #endif
  	ip->i_data.host = (void*) ip;
  	ip->i_mapping = &ip->i_data;
+ #ifdef STRUCT_INODE_HAS_I_TRUNCATE_SEM
+ 	init_rwsem(&ip->i_truncate_sem);
+ #endif
  #else
  	sema_init(&ip->i_atomic_write, 1);
  	init_waitqueue(&ip->i_wait);
Index: openafs/src/afs/afs_volume.c
diff -c openafs/src/afs/afs_volume.c:1.6.2.2 openafs/src/afs/afs_volume.c:1.6.2.3
*** openafs/src/afs/afs_volume.c:1.6.2.2	Sat Oct 13 00:20:24 2001
--- openafs/src/afs/afs_volume.c	Wed Dec 26 15:44:31 2001
***************
*** 18,24 ****
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/afs_volume.c,v 1.6.2.2 2001/10/13 04:20:24 shadow Exp $");
  
  #include "../afs/stds.h"
  #include "../afs/sysincludes.h"	/* Standard vendor system headers */
--- 18,24 ----
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/afs_volume.c,v 1.6.2.3 2001/12/26 20:44:31 shadow Exp $");
  
  #include "../afs/stds.h"
  #include "../afs/sysincludes.h"	/* Standard vendor system headers */
***************
*** 225,230 ****
--- 225,231 ----
       for (vp=afs_volumes[j]; vp; vp=vp->next) {
  	for (k=0; k<MAXHOSTS; k++) {
  	   if (!srvp || (vp->serverHost[k] == srvp)) {
+ 	      vp->serverHost[k] = 0;
  	      afs_ResetVolumeInfo(vp);
  	      break;
  	   }
Index: openafs/src/afs/lock.h
diff -c openafs/src/afs/lock.h:1.5.4.1 openafs/src/afs/lock.h:1.5.4.2
*** openafs/src/afs/lock.h:1.5.4.1	Sat Oct 13 00:20:24 2001
--- openafs/src/afs/lock.h	Sat Dec 29 18:15:19 2001
***************
*** 175,181 ****
  	(lock)->src_indicator = src;\
     ENDMAC
  
! #define NBObtainWriteLock(lock, src) (((lock)->excl_locked || (lock)->readers_reading) ? EWOULDBLOCK : ((lock) -> excl_locked = WRITE_LOCK), ((lock)->pid_writer = MyPidxx), ((lock)->src_indicator = src), 0)
  
  #define ObtainSharedLock(lock, src)\
    BEGINMAC  \
--- 175,181 ----
  	(lock)->src_indicator = src;\
     ENDMAC
  
! #define NBObtainWriteLock(lock, src) (((lock)->excl_locked || (lock)->readers_reading) ? EWOULDBLOCK : (((lock) -> excl_locked = WRITE_LOCK), ((lock)->pid_writer = MyPidxx), ((lock)->src_indicator = src), 0))
  
  #define ObtainSharedLock(lock, src)\
    BEGINMAC  \
***************
*** 188,193 ****
--- 188,195 ----
  	(lock)->src_indicator = src;\
     ENDMAC
  
+ #define NBObtainSharedLock(lock, src) (((lock)->excl_locked) ? EWOULDBLOCK : (((lock) -> excl_locked = SHARED_LOCK), ((lock)->pid_writer = MyPidxx), ((lock)->src_indicator = src), 0))
+ 
  #define UpgradeSToWLock(lock, src)\
    BEGINMAC  \
  /*       if (afs_trclock) {icl_Trace2(cm_iclSetp, CM_TRACE_LOCKOBTAIN, ICL_TYPE_POINTER, (long)lock, ICL_TYPE_LONG, (long)BOOSTED_LOCK);} */ \
***************
*** 274,280 ****
  	    Afs_Lock_Obtain(lock, WRITE_LOCK); \
     ENDMAC
  
! #define NBObtainWriteLock(lock, src) (((lock)->excl_locked || (lock)->readers_reading) ? EWOULDBLOCK : ((lock) -> excl_locked = WRITE_LOCK),  0)
  
  #define ObtainSharedLock(lock, src)\
    BEGINMAC  \
--- 276,282 ----
  	    Afs_Lock_Obtain(lock, WRITE_LOCK); \
     ENDMAC
  
! #define NBObtainWriteLock(lock, src) (((lock)->excl_locked || (lock)->readers_reading) ? EWOULDBLOCK : (((lock) -> excl_locked = WRITE_LOCK),  0))
  
  #define ObtainSharedLock(lock, src)\
    BEGINMAC  \
***************
*** 285,290 ****
--- 287,294 ----
  	    Afs_Lock_Obtain(lock, SHARED_LOCK); \
     ENDMAC
  
+ #define NBObtainSharedLock(lock, src) (((lock)->excl_locked) ? EWOULDBLOCK : (((lock) -> excl_locked = SHARED_LOCK), 0))
+    
  #define UpgradeSToWLock(lock, src)\
    BEGINMAC  \
  /*       if (afs_trclock) {icl_Trace2(cm_iclSetp, CM_TRACE_LOCKOBTAIN, ICL_TYPE_POINTER, (long)lock, ICL_TYPE_LONG, (long)BOOSTED_LOCK);} */ \
Index: openafs/src/afs/DARWIN/osi_module.c
diff -c openafs/src/afs/DARWIN/osi_module.c:1.6 openafs/src/afs/DARWIN/osi_module.c:1.6.2.1
*** openafs/src/afs/DARWIN/osi_module.c:1.6	Fri Sep  7 00:00:05 2001
--- openafs/src/afs/DARWIN/osi_module.c	Sat Nov 10 18:22:52 2001
***************
*** 1,7 ****
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/DARWIN/osi_module.c,v 1.6 2001/09/07 04:00:05 shadow Exp $");
  
  #include "../afs/sysincludes.h"
  #include "../afs/afsincludes.h"
--- 1,7 ----
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/DARWIN/osi_module.c,v 1.6.2.1 2001/11/10 23:22:52 shadow Exp $");
  
  #include "../afs/sysincludes.h"
  #include "../afs/afsincludes.h"
***************
*** 58,61 ****
     return KERN_SUCCESS;
   } 
  
! KMOD_EXPLICIT_DECL(openafs, VERSION, afs_modload, afs_modunload)
--- 58,61 ----
     return KERN_SUCCESS;
   } 
  
! KMOD_EXPLICIT_DECL(org.openafs.filesystems.afs, VERSION, afs_modload, afs_modunload)
Index: openafs/src/afs/DARWIN/osi_sleep.c
diff -c openafs/src/afs/DARWIN/osi_sleep.c:1.3 openafs/src/afs/DARWIN/osi_sleep.c:1.3.4.1
*** openafs/src/afs/DARWIN/osi_sleep.c:1.3	Thu Jul 12 15:58:19 2001
--- openafs/src/afs/DARWIN/osi_sleep.c	Sat Nov 10 18:22:52 2001
***************
*** 10,16 ****
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/DARWIN/osi_sleep.c,v 1.3 2001/07/12 19:58:19 shadow Exp $");
  
  #include "../afs/sysincludes.h" /* Standard vendor system headers */
  #include "../afs/afsincludes.h" /* Afs-based standard headers */
--- 10,16 ----
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/DARWIN/osi_sleep.c,v 1.3.4.1 2001/11/10 23:22:52 shadow Exp $");
  
  #include "../afs/sysincludes.h" /* Standard vendor system headers */
  #include "../afs/afsincludes.h" /* Afs-based standard headers */
***************
*** 131,139 ****
      seq = evp->seq;
      while (seq == evp->seq) {
  	AFS_ASSERT_GLOCK();
- 	assert_wait((event_t)event, 0);
  	AFS_GUNLOCK();
  	thread_block(0);
  	AFS_GLOCK();
      }
      relevent(evp);
--- 131,144 ----
      seq = evp->seq;
      while (seq == evp->seq) {
  	AFS_ASSERT_GLOCK();
  	AFS_GUNLOCK();
+ #ifdef AFS_DARWIN14_ENV
+         /* this is probably safe for all versions, but testing is hard */
+         sleep(event, PVFS);
+ #else
+ 	assert_wait((event_t)event, 0);
  	thread_block(0);
+ #endif
  	AFS_GLOCK();
      }
      relevent(evp);
***************
*** 153,176 ****
      int code = 0;
      struct afs_event *evp;
      int ticks,seq;
  
      ticks = ( ams * afs_hz )/1000;
  
  
      evp = afs_getevent(event);
      seq=evp->seq;
-     assert_wait((event_t)event, aintok ? THREAD_ABORTSAFE : 0);
      AFS_GUNLOCK();
      thread_set_timer(ticks, NSEC_PER_SEC / hz);
      thread_block(0);
      AFS_GLOCK();
- #if 0 /* thread_t structure only available if MACH_KERNEL_PRIVATE */
-     if (current_thread()->wait_result != THREAD_AWAKENED)
- 	code = EINTR;
- #else
      if (seq == evp->seq)
  	code = EINTR;
- #endif
      
      relevent(evp);
      return code;
--- 158,194 ----
      int code = 0;
      struct afs_event *evp;
      int ticks,seq;
+     int prio;
  
      ticks = ( ams * afs_hz )/1000;
  
  
      evp = afs_getevent(event);
      seq=evp->seq;
      AFS_GUNLOCK();
+ #ifdef AFS_DARWIN14_ENV
+     /* this is probably safe for all versions, but testing is hard. */
+     /* using tsleep instead of assert_wait/thread_set_timer/thread_block
+        allows shutdown to work in 1.4 */
+     /* lack of PCATCH does *not* prevent signal delivery, neither does 
+        a low priority. We would need to deal with ERESTART here if we 
+        wanted to mess with p->p_sigmask, and messing with p_sigignore is
+        not the way to go.... (someone correct me if I'm wrong)
+     */
+     if (aintok)
+        prio=PCATCH|PPAUSE;
+     else
+        prio=PVFS;
+     code=tsleep(event, prio, "afs_osi_TimedSleep", ticks);
+ #else 
+     assert_wait((event_t)event, aintok ? THREAD_ABORTSAFE : THREAD_UNINT);
      thread_set_timer(ticks, NSEC_PER_SEC / hz);
      thread_block(0);
+     code=0;
+ #endif
      AFS_GLOCK();
      if (seq == evp->seq)
  	code = EINTR;
      
      relevent(evp);
      return code;
***************
*** 184,190 ****
--- 202,213 ----
      evp = afs_getevent(event);
      if (evp->refcount > 1) {
  	evp->seq++;    
+ #ifdef AFS_DARWIN14_ENV
+     /* this is probably safe for all versions, but testing is hard. */
+         wakeup(event);
+ #else
  	thread_wakeup((event_t)event);
+ #endif
      }
      relevent(evp);
  }
Index: openafs/src/afs/DARWIN/osi_vm.c
diff -c openafs/src/afs/DARWIN/osi_vm.c:1.3 openafs/src/afs/DARWIN/osi_vm.c:1.3.4.1
*** openafs/src/afs/DARWIN/osi_vm.c:1.3	Thu Jul 12 15:58:19 2001
--- openafs/src/afs/DARWIN/osi_vm.c	Sat Nov 10 18:22:52 2001
***************
*** 10,16 ****
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/DARWIN/osi_vm.c,v 1.3 2001/07/12 19:58:19 shadow Exp $");
  
  #include "../afs/sysincludes.h" /* Standard vendor system headers */
  #include "../afs/afsincludes.h" /* Afs-based standard headers */
--- 10,16 ----
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/DARWIN/osi_vm.c,v 1.3.4.1 2001/11/10 23:22:52 shadow Exp $");
  
  #include "../afs/sysincludes.h" /* Standard vendor system headers */
  #include "../afs/afsincludes.h" /* Afs-based standard headers */
***************
*** 39,44 ****
--- 39,48 ----
      int *slept;
  {
      struct vnode *vp=(struct vnode *)avc;
+ #ifdef AFS_DARWIN14_ENV
+     if (UBCINFOEXISTS(vp))
+ 	return EBUSY;
+ #endif
      if (avc->vrefCount)
  	return EBUSY;
  
***************
*** 51,56 ****
--- 55,61 ----
  
      AFS_GUNLOCK();
      cache_purge(vp);
+ #ifndef AFS_DARWIN14_ENV
      if (UBCINFOEXISTS(vp))
  	{
                  ubc_clean(vp, 1);
***************
*** 58,63 ****
--- 63,69 ----
                  ubc_release(vp);
  	        ubc_info_free(vp);
  	}
+ #endif
  
      AFS_GLOCK();
  
***************
*** 186,196 ****
--- 192,210 ----
          AFS_RELE(vp);
          return;
      }
+ #ifdef AFS_DARWIN14_ENV
+     if (vp->v_ubcinfo->ui_refcount > 1) {
+         simple_unlock(&vp->v_interlock);
+         AFS_RELE(vp);
+         return;
+     }
+ #else
      if (vp->v_ubcinfo->ui_holdcnt) {
          simple_unlock(&vp->v_interlock);
          AFS_RELE(vp);
          return;
      }
+ #endif
      if (slept && ubc_issetflags(vp, UI_WASMAPPED)) {
         /* We can't possibly release this in time for this NewVCache to get it */
          simple_unlock(&vp->v_interlock);
***************
*** 209,229 ****
      obj=0;
      if (ubc_issetflags(vp, UI_WASMAPPED)) {
          simple_unlock(&vp->v_interlock);
          ubc_release(vp);
          if (ubc_issetflags(vp, UI_HASOBJREF))
              printf("ubc_release didn't release the reference?!\n");
      } else if (!vn_lock(vp, LK_EXCLUSIVE|LK_INTERLOCK,current_proc())) {
! #ifdef UBC_NOREACTIVATE
          obj = ubc_getobject(vp,(UBC_NOREACTIVATE|UBC_HOLDOBJECT));
  #else
          obj = ubc_getobject(vp);
  #endif
          (void)ubc_clean(vp, 1);
          vinvalbuf(vp, V_SAVE, &afs_osi_cred, p, 0, 0);
          if (vp->v_usecount == 1)
             VOP_INACTIVE(vp, p);
          else
             VOP_UNLOCK(vp, 0, p);
          if (ISSET(vp->v_flag, VTERMINATE))
              panic("afs_vnreclaim: already teminating");
          SET(vp->v_flag, VTERMINATE);
--- 223,252 ----
      obj=0;
      if (ubc_issetflags(vp, UI_WASMAPPED)) {
          simple_unlock(&vp->v_interlock);
+ #ifdef  AFS_DARWIN14_ENV
+         ubc_release_named(vp);
+ #else
          ubc_release(vp);
+ #endif
          if (ubc_issetflags(vp, UI_HASOBJREF))
              printf("ubc_release didn't release the reference?!\n");
      } else if (!vn_lock(vp, LK_EXCLUSIVE|LK_INTERLOCK,current_proc())) {
! #ifdef AFS_DARWIN14_ENV
!         obj = ubc_getobject(vp,UBC_HOLDOBJECT);
! #else
! #ifdef AFS_DARWIN13_ENV
          obj = ubc_getobject(vp,(UBC_NOREACTIVATE|UBC_HOLDOBJECT));
  #else
          obj = ubc_getobject(vp);
  #endif
+ #endif
          (void)ubc_clean(vp, 1);
          vinvalbuf(vp, V_SAVE, &afs_osi_cred, p, 0, 0);
          if (vp->v_usecount == 1)
             VOP_INACTIVE(vp, p);
          else
             VOP_UNLOCK(vp, 0, p);
+         if (obj) {
          if (ISSET(vp->v_flag, VTERMINATE))
              panic("afs_vnreclaim: already teminating");
          SET(vp->v_flag, VTERMINATE);
***************
*** 232,244 ****
                SET(vp->v_flag, VTERMWANT);
                tsleep((caddr_t)&vp->v_ubcinfo, PINOD, "afs_vnreclaim", 0);
          }
     } else {
          if (simple_lock_try(&vp->v_interlock))
              panic("afs_vnreclaim: slept, but did no work :(");
          if (UBCINFOEXISTS(vp) && vp->v_count == 1) {
             vp->v_usecount++;
             simple_unlock(&vp->v_interlock);
!            AFS_RELE(vp);
          } else 
             simple_unlock(&vp->v_interlock);
     }
--- 255,268 ----
                SET(vp->v_flag, VTERMWANT);
                tsleep((caddr_t)&vp->v_ubcinfo, PINOD, "afs_vnreclaim", 0);
          }
+         }
     } else {
          if (simple_lock_try(&vp->v_interlock))
              panic("afs_vnreclaim: slept, but did no work :(");
          if (UBCINFOEXISTS(vp) && vp->v_count == 1) {
             vp->v_usecount++;
             simple_unlock(&vp->v_interlock);
!            VN_RELE(vp);
          } else 
             simple_unlock(&vp->v_interlock);
     }
***************
*** 254,261 ****
      void *object;
      struct vcache *avc = (struct vcache *)vp;
  
      object=NULL;
! #ifdef UBC_NOREACTIVATE
      if (UBCINFOEXISTS(vp))
          object = ubc_getobject(vp, UBC_NOREACTIVATE);
  #else
--- 278,296 ----
      void *object;
      struct vcache *avc = (struct vcache *)vp;
  
+ #ifdef AFS_DARWIN14_ENV
+     offset=trunc_page(offset);
+     size=round_page(size+1);
+     while (size) {
+         ubc_page_op(vp, (vm_offset_t)offset, 
+                               UPL_POP_SET | UPL_POP_BUSY | UPL_POP_DUMP,
+                               0, 0);
+         size-=PAGE_SIZE;
+         offset+=PAGE_SIZE;
+     }
+ #else
      object=NULL;
! #ifdef AFS_DARWIN13_ENV
      if (UBCINFOEXISTS(vp))
          object = ubc_getobject(vp, UBC_NOREACTIVATE);
  #else
***************
*** 268,274 ****
      offset=trunc_page(offset);
      size=round_page(size+1);
  
! #ifdef UBC_NOREACTIVATE
      while (size) {
          memory_object_page_op(object, (vm_offset_t)offset, 
                                UPL_POP_SET | UPL_POP_BUSY | UPL_POP_DUMP,
--- 303,309 ----
      offset=trunc_page(offset);
      size=round_page(size+1);
  
! #ifdef AFS_DARWIN13_ENV
      while (size) {
          memory_object_page_op(object, (vm_offset_t)offset, 
                                UPL_POP_SET | UPL_POP_BUSY | UPL_POP_DUMP,
***************
*** 277,286 ****
--- 312,323 ----
          offset+=PAGE_SIZE;
      }
  #else 
+     /* This is all we can do, and it's not enough. sucks to be us */
      ubc_setsize(vp, offset);
      size=(offset + size > avc->m.Length) ? offset + size : avc->m.Length;
      ubc_setsize(vp, size);
  #endif
+ #endif
  
  }
  int osi_VM_Setup(struct vcache *avc) {
***************
*** 296,310 ****
               AFS_RELE(avc);
               return error;
           }
           simple_lock(&avc->v.v_interlock);
           if (!ubc_issetflags(&avc->v, UI_HASOBJREF))
! #ifdef UBC_NOREACTIVATE
              if (ubc_getobject(&avc->v, (UBC_NOREACTIVATE|UBC_HOLDOBJECT)))
                     panic("VM_Setup: null object");
  #else
              (void)_ubc_getobject(&avc->v, 1); /* return value not used */
  #endif
           simple_unlock(&avc->v.v_interlock);
           AFS_GLOCK();
           AFS_RELE(avc);
        }
--- 333,349 ----
               AFS_RELE(avc);
               return error;
           }
+ #ifndef AFS_DARWIN14_ENV
           simple_lock(&avc->v.v_interlock);
           if (!ubc_issetflags(&avc->v, UI_HASOBJREF))
! #ifdef AFS_DARWIN13_ENV
              if (ubc_getobject(&avc->v, (UBC_NOREACTIVATE|UBC_HOLDOBJECT)))
                     panic("VM_Setup: null object");
  #else
              (void)_ubc_getobject(&avc->v, 1); /* return value not used */
  #endif
           simple_unlock(&avc->v.v_interlock);
+ #endif
           AFS_GLOCK();
           AFS_RELE(avc);
        }
Index: openafs/src/afs/DARWIN/osi_vnodeops.c
diff -c openafs/src/afs/DARWIN/osi_vnodeops.c:1.4 openafs/src/afs/DARWIN/osi_vnodeops.c:1.4.2.1
*** openafs/src/afs/DARWIN/osi_vnodeops.c:1.4	Tue Aug  7 20:03:29 2001
--- openafs/src/afs/DARWIN/osi_vnodeops.c	Sat Nov 10 18:22:52 2001
***************
*** 1,7 ****
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/afs/DARWIN/osi_vnodeops.c,v 1.4 2001/08/08 00:03:29 shadow Exp $");
  
  #include <afs/sysincludes.h>            /* Standard vendor system headers */
  #include <afs/afsincludes.h>            /* Afs-based standard headers */
--- 1,7 ----
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/afs/DARWIN/osi_vnodeops.c,v 1.4.2.1 2001/11/10 23:22:52 shadow Exp $");
  
  #include <afs/sysincludes.h>            /* Standard vendor system headers */
  #include <afs/afsincludes.h>            /* Afs-based standard headers */
***************
*** 755,766 ****
      error =  afs_remove((struct vcache *)dvp, name, cnp->cn_cred);
      AFS_GUNLOCK();
      cache_purge(vp);
!     if (dvp == vp)
! 	vrele(vp);
!     else
! 	vput(vp);
!     vput(dvp);
!     if (UBCINFOEXISTS(vp)) {
               int wasmapped=ubc_issetflags(vp, UI_WASMAPPED);
               int hasobjref=ubc_issetflags(vp, UI_HASOBJREF);
               if (wasmapped)
--- 755,764 ----
      error =  afs_remove((struct vcache *)dvp, name, cnp->cn_cred);
      AFS_GUNLOCK();
      cache_purge(vp);
!     if (!error && UBCINFOEXISTS(vp)) {
! #ifdef AFS_DARWIN14_ENV
!              (void) ubc_uncache(vp); 
! #else
               int wasmapped=ubc_issetflags(vp, UI_WASMAPPED);
               int hasobjref=ubc_issetflags(vp, UI_HASOBJREF);
               if (wasmapped)
***************
*** 768,774 ****
--- 766,778 ----
               if (hasobjref)
                  ubc_release(vp);
               /* WARNING vp may not be valid after this */
+ #endif
      }
+     if (dvp == vp)
+ 	vrele(vp);
+     else
+ 	vput(vp);
+     vput(dvp);
  
      FREE_ZONE(cnp->cn_pnbuf, cnp->cn_pnlen, M_NAMEI);
      DROPNAME();
***************
*** 1218,1225 ****
--- 1222,1234 ----
      if (UBCISVALID(vp))
          printf("\n  UBC: %s%s",
                 UBCINFOEXISTS(vp) ? "exists, " : "does not exist",
+ #ifdef AFS_DARWIN14_ENV
                 UBCINFOEXISTS(vp) ?
+                  sprintf(buf, "refs %d", vp->v_ubcinfo->ui_refcount),buf : "");
+ #else
+                UBCINFOEXISTS(vp) ?
                   sprintf(buf, "holdcnt %d", vp->v_ubcinfo->ui_holdcnt),buf : "");
+ #endif
      printf("\n");
      return 0;
  }
Index: openafs/src/afs/IRIX/osi_misc.c
diff -c openafs/src/afs/IRIX/osi_misc.c:1.4 openafs/src/afs/IRIX/osi_misc.c:1.4.4.1
*** openafs/src/afs/IRIX/osi_misc.c:1.4	Thu Jul 12 15:58:20 2001
--- openafs/src/afs/IRIX/osi_misc.c	Wed Dec 26 15:07:53 2001
***************
*** 13,19 ****
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/IRIX/osi_misc.c,v 1.4 2001/07/12 19:58:20 shadow Exp $");
  
  #ifdef	AFS_SGI62_ENV
  #include "../afs/sysincludes.h"	/* Standard vendor system headers */
--- 13,19 ----
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/IRIX/osi_misc.c,v 1.4.4.1 2001/12/26 20:07:53 shadow Exp $");
  
  #ifdef	AFS_SGI62_ENV
  #include "../afs/sysincludes.h"	/* Standard vendor system headers */
***************
*** 51,64 ****
  	    inventory_t *pinv;
  	    /* test for numa arch. */
  	    /* Determine if thisis a NUMA platform. Currently, this is true
! 	     * only if it's an IP27.
  	     */
  	    pinv = find_inventory((inventory_t*)NULL, INV_PROCESSOR,
  				  INV_CPUBOARD, -1, -1, -1);
  	    if (!pinv)
  		code = ENODEV;
! 	    else
! 		afs_is_numa_arch = (pinv->inv_state == INV_IP27BOARD) ? 1 : 0;
  	}
  	else
  	    afs_is_numa_arch = flag;
--- 51,66 ----
  	    inventory_t *pinv;
  	    /* test for numa arch. */
  	    /* Determine if thisis a NUMA platform. Currently, this is true
! 	     * only if it's an IP27 or IP35.
  	     */
  	    pinv = find_inventory((inventory_t*)NULL, INV_PROCESSOR,
  				  INV_CPUBOARD, -1, -1, -1);
  	    if (!pinv)
  		code = ENODEV;
! 	    else 
! 		afs_is_numa_arch = ((pinv->inv_state == INV_IP27BOARD) || 
! 				    (pinv->inv_state == INV_IP35BOARD)) 
! 		  ? 1 : 0;
  	}
  	else
  	    afs_is_numa_arch = flag;
***************
*** 85,90 ****
--- 87,94 ----
  int afs_ipno = 28;
  #elif defined(IP30)
  int afs_ipno = 30;
+ #elif defined(IP35)
+ int afs_ipno = 35;
  #else
  int afs_ipno = -1;
  #endif
Index: openafs/src/afs/IRIX/osi_vfs.h
diff -c openafs/src/afs/IRIX/osi_vfs.h:1.2 openafs/src/afs/IRIX/osi_vfs.h:1.2.8.2
*** openafs/src/afs/IRIX/osi_vfs.h:1.2	Sat Nov  4 05:03:23 2000
--- openafs/src/afs/IRIX/osi_vfs.h	Wed Dec 26 15:36:17 2001
***************
*** 88,94 ****
   */
  #ifdef AFS_SGI65_ENV
  #define	PTOSSVP(vp, off, len)  VOP_TOSS_PAGES((vp), (off), (len), 0)
! #define PFLUSHINVALVP(vp, off, len) VOP_INVALFREE_PAGES((vp), (len))
  #define PFLUSHVP(vp, len, flags, code) \
  		VOP_FLUSH_PAGES((vp), 0, (len), (flags), 0, code)
  #define PINVALFREE(vp, off)    VOP_INVALFREE_PAGES((vp), (off))
--- 88,94 ----
   */
  #ifdef AFS_SGI65_ENV
  #define	PTOSSVP(vp, off, len)  VOP_TOSS_PAGES((vp), (off), (len), 0)
! #define PFLUSHINVALVP(vp, off, len) VOP_FLUSHINVAL_PAGES((vp), (off), (len), 0)
  #define PFLUSHVP(vp, len, flags, code) \
  		VOP_FLUSH_PAGES((vp), 0, (len), (flags), 0, code)
  #define PINVALFREE(vp, off)    VOP_INVALFREE_PAGES((vp), (off))
***************
*** 290,295 ****
--- 290,298 ----
  						 */
  #ifdef VNODE_TRACING
  	struct ktrace 	*v_trace;		/* trace header structure    */
+ #endif
+ #ifdef CKPT
+ 	ckpt_handle_t	v_ckpt;			/* ckpt lookup info */
  #endif
  } vnode1_t;
  
Index: openafs/src/afs/IRIX/osi_vfsops.c
diff -c openafs/src/afs/IRIX/osi_vfsops.c:1.4 openafs/src/afs/IRIX/osi_vfsops.c:1.4.4.2
*** openafs/src/afs/IRIX/osi_vfsops.c:1.4	Thu Jul 12 15:58:20 2001
--- openafs/src/afs/IRIX/osi_vfsops.c	Sun Jan 20 03:20:56 2002
***************
*** 13,19 ****
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/IRIX/osi_vfsops.c,v 1.4 2001/07/12 19:58:20 shadow Exp $");
  
  #include "../afs/sysincludes.h"	/* Standard vendor system headers */
  #include "../afs/afsincludes.h"	/* Afs-based standard headers */
--- 13,19 ----
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/IRIX/osi_vfsops.c,v 1.4.4.2 2002/01/20 08:20:56 shadow Exp $");
  
  #include "../afs/sysincludes.h"	/* Standard vendor system headers */
  #include "../afs/afsincludes.h"	/* Afs-based standard headers */
***************
*** 523,529 ****
      register afs_int32 code = 0;
      afs_int32 ret;
  
! #if defined(AFS_SGI64_ENV) && defined(CKPT)
      afs_fid2_t *afid2;
  #endif    
  
--- 523,529 ----
      register afs_int32 code = 0;
      afs_int32 ret;
  
! #if defined(AFS_SGI64_ENV) && defined(CKPT) && !defined(_R5000_CVT_WAR)
      afs_fid2_t *afid2;
  #endif    
  
***************
*** 533,543 ****
  
      *avcp = NULL;
  
! #if defined(AFS_SGI64_ENV) && defined(CKPT)
      afid2 = (afs_fid2_t*)fidp;
      if (afid2->af_len == sizeof(afs_fid2_t) - sizeof(afid2->af_len)) {
  	/* It's a checkpoint restart fid. */
! 	tcell = afs_GetCellByIndex(afid2->af_cell, READ_LOCK);
  	if (!tcell) {
  	    code = ENOENT;
  	    goto out;
--- 533,543 ----
  
      *avcp = NULL;
  
! #if defined(AFS_SGI64_ENV) && defined(CKPT) && !defined(_R5000_CVT_WAR)
      afid2 = (afs_fid2_t*)fidp;
      if (afid2->af_len == sizeof(afs_fid2_t) - sizeof(afid2->af_len)) {
  	/* It's a checkpoint restart fid. */
! 	tcell = afs_GetCellByIndex(afid2->af_cell, READ_LOCK, 0 /* !refresh */);
  	if (!tcell) {
  	    code = ENOENT;
  	    goto out;
Index: openafs/src/afs/IRIX/osi_vnodeops.c
diff -c openafs/src/afs/IRIX/osi_vnodeops.c:1.6 openafs/src/afs/IRIX/osi_vnodeops.c:1.6.2.1
*** openafs/src/afs/IRIX/osi_vnodeops.c:1.6	Tue Aug  7 20:03:30 2001
--- openafs/src/afs/IRIX/osi_vnodeops.c	Wed Dec 26 15:04:45 2001
***************
*** 13,19 ****
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/IRIX/osi_vnodeops.c,v 1.6 2001/08/08 00:03:30 shadow Exp $");
  
  #ifdef	AFS_SGI62_ENV
  #include "../afs/sysincludes.h"	/* Standard vendor system headers */
--- 13,19 ----
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/IRIX/osi_vnodeops.c,v 1.6.2.1 2001/12/26 20:04:45 shadow Exp $");
  
  #ifdef	AFS_SGI62_ENV
  #include "../afs/sysincludes.h"	/* Standard vendor system headers */
***************
*** 1258,1264 ****
      return 0;
  }
  
! #if defined(AFS_SGI64_ENV) && defined(CKPT)
  int afs_fid2(OSI_VC_DECL(avc), struct fid *fidp)
  {
      struct cell *tcell;
--- 1258,1264 ----
      return 0;
  }
  
! #if defined(AFS_SGI64_ENV) && defined(CKPT) && !defined(_R5000_CVT_WAR)
  int afs_fid2(OSI_VC_DECL(avc), struct fid *fidp)
  {
      struct cell *tcell;
***************
*** 1283,1292 ****
--- 1283,1303 ----
   * return of ENOSYS would make the code fail over to VOP_FID. We can't let
   * that happen, since we do a VN_HOLD there in the expectation that 
   * posthandle will be called to release the vnode.
+  *
+  * afs_fid2 is used to support the R5000 workarounds (_R5000_CVT_WAR)
   */
  int afs_fid2(OSI_VC_DECL(avc), struct fid *fidp)
  {
+ #if defined(_R5000_CVT_WAR)
+     extern int R5000_cvt_war;
+ 
+     if (R5000_cvt_war)
+ 	return ENOSYS;
+     else
+ 	return EINVAL;
+ #else
      return EINVAL;
+ #endif
  }
  #endif /* AFS_SGI64_ENV && CKPT */
  
Index: openafs/src/afs/LINUX/osi_alloc.c
diff -c openafs/src/afs/LINUX/osi_alloc.c:1.9 openafs/src/afs/LINUX/osi_alloc.c:1.9.2.2
*** openafs/src/afs/LINUX/osi_alloc.c:1.9	Mon Aug  6 20:04:59 2001
--- openafs/src/afs/LINUX/osi_alloc.c	Sun Jan 20 03:42:32 2002
***************
*** 14,20 ****
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/LINUX/osi_alloc.c,v 1.9 2001/08/07 00:04:59 shadow Exp $");
  
  #include "../afs/sysincludes.h"
  #include "../afs/afsincludes.h"
--- 14,20 ----
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/LINUX/osi_alloc.c,v 1.9.2.2 2002/01/20 08:42:32 shadow Exp $");
  
  #include "../afs/sysincludes.h"
  #include "../afs/afsincludes.h"
***************
*** 87,93 ****
  
      /*  if we can use kmalloc use it to allocate the required memory. */
      if (asize <  MAX_KMALLOC_SIZE) {
!         new = (void *)(unsigned long)kmalloc(asize, GFP_KERNEL);
          if (new) /* piggy back alloc type */
              (unsigned long)new |= KM_TYPE;
      }
--- 87,99 ----
  
      /*  if we can use kmalloc use it to allocate the required memory. */
      if (asize <  MAX_KMALLOC_SIZE) {
!         new = (void *)(unsigned long)kmalloc(asize, 
! #ifdef GFP_NOFS
! 					     GFP_NOFS
! #else
! 					     GFP_KERNEL
! #endif
! 					     );
          if (new) /* piggy back alloc type */
              (unsigned long)new |= KM_TYPE;
      }
***************
*** 97,103 ****
              if (--max_wait <=0) {
  		break;
              }
! 	    schedule();
          }
  	if (new) /* piggy back alloc type */
  	    (unsigned long)new |= VM_TYPE;
--- 103,114 ----
              if (--max_wait <=0) {
  		break;
              }
! #ifdef set_current_state
! 	    set_current_state(TASK_INTERRUPTIBLE);
! #else
! 	    current->state = TASK_INTERRUPTIBLE;
! #endif
! 	    schedule_timeout(HZ);
          }
  	if (new) /* piggy back alloc type */
  	    (unsigned long)new |= VM_TYPE;
Index: openafs/src/afs/LINUX/osi_machdep.h
diff -c openafs/src/afs/LINUX/osi_machdep.h:1.5 openafs/src/afs/LINUX/osi_machdep.h:1.5.2.1
*** openafs/src/afs/LINUX/osi_machdep.h:1.5	Tue Aug  7 20:03:31 2001
--- openafs/src/afs/LINUX/osi_machdep.h	Sun Jan 20 03:57:44 2002
***************
*** 100,109 ****
  #else
      int cr_ref;
  #endif
!     unsigned short cr_uid;	/* euid */
!     unsigned short cr_ruid;	/* uid */
!     unsigned short cr_gid;	/* egid */
!     unsigned short cr_rgid;	/* gid */
      gid_t cr_groups[NGROUPS];	/* 32 groups - empty set to NOGROUP */
      int cr_ngroups;
  } cred_t;
--- 100,109 ----
  #else
      int cr_ref;
  #endif
!     uid_t cr_uid;	/* euid */
!     uid_t cr_ruid;	/* uid */
!     gid_t cr_gid;	/* egid */
!     gid_t cr_rgid;	/* gid */
      gid_t cr_groups[NGROUPS];	/* 32 groups - empty set to NOGROUP */
      int cr_ngroups;
  } cred_t;
Index: openafs/src/afs/LINUX/osi_misc.c
diff -c openafs/src/afs/LINUX/osi_misc.c:1.12 openafs/src/afs/LINUX/osi_misc.c:1.12.2.1
*** openafs/src/afs/LINUX/osi_misc.c:1.12	Thu Sep  6 15:07:12 2001
--- openafs/src/afs/LINUX/osi_misc.c	Thu Jan 24 05:43:17 2002
***************
*** 14,20 ****
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/LINUX/osi_misc.c,v 1.12 2001/09/06 19:07:12 shadow Exp $");
  
  #include "../afs/sysincludes.h"
  #include "../afs/afsincludes.h"
--- 14,20 ----
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/LINUX/osi_misc.c,v 1.12.2.1 2002/01/24 10:43:17 shadow Exp $");
  
  #include "../afs/sysincludes.h"
  #include "../afs/afsincludes.h"
***************
*** 426,429 ****
--- 426,449 ----
    } /* if bad parent */
   
    return;
+ }
+ 
+ struct task_struct *rxk_ListenerTask;
+ 
+ void osi_linux_mask() {
+     spin_lock_irq(&current->sigmask_lock);
+     sigfillset(&current->blocked);
+     recalc_sigpending(current);
+     spin_unlock_irq(&current->sigmask_lock);
+ }
+ 
+ void osi_linux_unmask() {
+     spin_lock_irq(&rxk_ListenerTask->sigmask_lock);
+     sigemptyset(&rxk_ListenerTask->blocked);
+     recalc_sigpending(rxk_ListenerTask);
+     spin_unlock_irq(&rxk_ListenerTask->sigmask_lock);
+ }
+ 
+ void osi_linux_rxkreg() {
+     rxk_ListenerTask = current;
  }
Index: openafs/src/afs/LINUX/osi_sleep.c
diff -c openafs/src/afs/LINUX/osi_sleep.c:1.6 openafs/src/afs/LINUX/osi_sleep.c:1.6.4.4
*** openafs/src/afs/LINUX/osi_sleep.c:1.6	Thu Jul 12 15:58:21 2001
--- openafs/src/afs/LINUX/osi_sleep.c	Tue Jan 29 14:45:39 2002
***************
*** 10,16 ****
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/LINUX/osi_sleep.c,v 1.6 2001/07/12 19:58:21 shadow Exp $");
  
  #include "../afs/sysincludes.h"	/* Standard vendor system headers */
  #include "../afs/afsincludes.h"	/* Afs-based standard headers */
--- 10,16 ----
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/LINUX/osi_sleep.c,v 1.6.4.4 2002/01/29 19:45:39 shadow Exp $");
  
  #include "../afs/sysincludes.h"	/* Standard vendor system headers */
  #include "../afs/afsincludes.h"	/* Afs-based standard headers */
***************
*** 25,31 ****
  void afs_osi_Wakeup(char *event);
  void afs_osi_Sleep(char *event);
  
! static char waitV;
  
  #if ! defined(AFS_GLOBAL_SUNLOCK)
  
--- 25,31 ----
  void afs_osi_Wakeup(char *event);
  void afs_osi_Sleep(char *event);
  
! static char waitV, dummyV;
  
  #if ! defined(AFS_GLOBAL_SUNLOCK)
  
***************
*** 96,110 ****
      if (ahandle)
  	ahandle->proc = (caddr_t) current;
  
      do {
- 	AFS_ASSERT_GLOCK();
- 	code = 0;
  #if	defined(AFS_GLOBAL_SUNLOCK)
          code = osi_TimedSleep(&waitV, ams, 1);
!         if (code) {
!                 if (aintok) break;
!                 flush_signals(current);
!                 code = 0;
          }
  #else
  	timer = afs_osi_CallProc(AfsWaitHack, (char *) current, ams);
--- 96,108 ----
      if (ahandle)
  	ahandle->proc = (caddr_t) current;
  
+     AFS_ASSERT_GLOCK();
      do {
  #if	defined(AFS_GLOBAL_SUNLOCK)
          code = osi_TimedSleep(&waitV, ams, 1);
!         if (code == EINTR) {
!                 if (aintok) 
! 		    return EINTR;
          }
  #else
  	timer = afs_osi_CallProc(AfsWaitHack, (char *) current, ams);
***************
*** 113,122 ****
  #endif /* AFS_GLOBAL_SUNLOCK */
  	if (ahandle && (ahandle->proc == (caddr_t) 0)) {
  	    /* we've been signalled */
! 	    break;
  	}
      } while (osi_Time() < endTime);
!     return code;
  }
  
  
--- 111,120 ----
  #endif /* AFS_GLOBAL_SUNLOCK */
  	if (ahandle && (ahandle->proc == (caddr_t) 0)) {
  	    /* we've been signalled */
! 	    return EINTR;
  	}
      } while (osi_Time() < endTime);
!     return 0;
  }
  
  
***************
*** 160,185 ****
  	    newp = evp;
  	evp = evp->next;
      }
!     if (!newp) {
! 	newp = (afs_event_t *) osi_AllocSmallSpace(sizeof (afs_event_t));
! 	afs_evhashcnt++;
! 	newp->next = afs_evhasht[hashcode];
! 	afs_evhasht[hashcode] = newp;
! #if defined(AFS_LINUX24_ENV)
! 	init_waitqueue_head(&newp->cond);
! #else
! 	init_waitqueue(&newp->cond);
! #endif
! 	newp->seq = 0;
!     }
      newp->event = event;
      newp->refcount = 1;
      return newp;
  }
  
  /* Release the specified event */
  #define relevent(evp) ((evp)->refcount--)
  
  
  void afs_osi_Sleep(char *event)
  {
--- 158,209 ----
  	    newp = evp;
  	evp = evp->next;
      }
!     if (!newp)
! 	return NULL;
! 
      newp->event = event;
      newp->refcount = 1;
      return newp;
  }
  
+ /* afs_addevent -- allocates a new event for the address.  It isn't returned;
+  *     instead, afs_getevent should be called again.  Thus, the real effect of
+  *     this routine is to add another event to the hash bucket for this
+  *     address.
+  *
+  * Locks:
+  *     Called with GLOCK held. However the function might drop
+  *     GLOCK when it calls osi_AllocSmallSpace for allocating
+  *     a new event (In Linux, the allocator drops GLOCK to avoid
+  *     a deadlock).
+  */
+ 
+ static void afs_addevent(char *event)
+ {
+     int hashcode;
+     afs_event_t *newp;
+     
+     AFS_ASSERT_GLOCK();
+     hashcode = afs_evhash(event);
+     newp = osi_AllocSmallSpace(sizeof(afs_event_t));
+     afs_evhashcnt++;
+     newp->next = afs_evhasht[hashcode];
+     afs_evhasht[hashcode] = newp;
+ #if defined(AFS_LINUX24_ENV)
+     init_waitqueue_head(&newp->cond);
+ #else
+     init_waitqueue(&newp->cond);
+ #endif
+     newp->seq = 0;
+     newp->event = &dummyV;  /* Dummy address for new events */
+     newp->refcount = 0;
+ }
+ 
+ 
  /* Release the specified event */
  #define relevent(evp) ((evp)->refcount--)
  
+ /* afs_osi_Sleep -- waits for an event to be notified. */
  
  void afs_osi_Sleep(char *event)
  {
***************
*** 187,197 ****
--- 211,244 ----
      int seq;
  
      evp = afs_getevent(event);
+     if (!evp) {
+ 	/* Can't block because allocating a new event would require dropping
+          * the GLOCK, which may cause us to miss the wakeup.  So call the
+          * allocator then return immediately.  We'll find the new event next
+          * time around without dropping the GLOCK. */
+         afs_addevent(event);
+         return;
+     }
+ 
      seq = evp->seq;
+ 
      while (seq == evp->seq) {
+ 	sigset_t saved_set;
+ 
  	AFS_ASSERT_GLOCK();
  	AFS_GUNLOCK();
+ 	spin_lock_irq(&current->sigmask_lock);
+ 	saved_set = current->blocked;
+ 	sigfillset(&current->blocked);
+ 	recalc_sigpending(current);
+ 	spin_unlock_irq(&current->sigmask_lock);
+ 
  	interruptible_sleep_on(&evp->cond);
+ 
+ 	spin_lock_irq(&current->sigmask_lock);
+ 	current->blocked = saved_set;
+ 	recalc_sigpending(current);
+ 	spin_unlock_irq(&current->sigmask_lock);
  	AFS_GLOCK();
      }
      relevent(evp);
***************
*** 203,214 ****
   * event - event to sleep on
   * ams --- max sleep time in milliseconds
   * aintok - 1 if should sleep interruptibly
-  *
-  * Returns 0 if timeout and EINTR if signalled.
   *
!  * While the Linux kernel still has a global lock, we can use the standard
!  * sleep calls and drop our locks early. The kernel lock will protect us
!  * until we get to sleep.
   */
  static int osi_TimedSleep(char *event, afs_int32 ams, int aintok)
  {
--- 250,258 ----
   * event - event to sleep on
   * ams --- max sleep time in milliseconds
   * aintok - 1 if should sleep interruptibly
   *
!  * Returns 0 if timeout, EINTR if signalled, and EGAIN if it might
!  * have raced.
   */
  static int osi_TimedSleep(char *event, afs_int32 ams, int aintok)
  {
***************
*** 216,221 ****
--- 260,273 ----
      struct afs_event *evp;
  
      evp = afs_getevent(event);
+     if (!evp) {
+         /* Can't block because allocating a new event would require dropping
+          * the GLOCK, which may cause us to miss the wakeup.  So call the
+          * allocator then return immediately.  We'll find the new event next
+          * time around without dropping the GLOCK. */
+         afs_addevent(event);
+         return EAGAIN;
+     }
  
      AFS_GUNLOCK();
      if (aintok)
***************
*** 224,229 ****
--- 276,283 ----
  	t = sleep_on_timeout(&evp->cond, t);
      AFS_GLOCK();
  
+     relevent(evp);
+ 
      return t ? EINTR : 0;
  }
  
***************
*** 233,238 ****
--- 287,295 ----
      struct afs_event *evp;
  
      evp = afs_getevent(event);
+     if (!evp)                          /* No sleepers */
+ 	return;
+ 
      if (evp->refcount > 1) {
  	evp->seq++;    
  	wake_up(&evp->cond);
Index: openafs/src/afs/LINUX/osi_vfsops.c
diff -c openafs/src/afs/LINUX/osi_vfsops.c:1.11.2.1 openafs/src/afs/LINUX/osi_vfsops.c:1.11.2.2
*** openafs/src/afs/LINUX/osi_vfsops.c:1.11.2.1	Sat Oct 13 00:20:26 2001
--- openafs/src/afs/LINUX/osi_vfsops.c	Tue Jan 29 14:45:07 2002
***************
*** 15,21 ****
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/LINUX/osi_vfsops.c,v 1.11.2.1 2001/10/13 04:20:26 shadow Exp $");
  
  #include "../afs/sysincludes.h"
  #include "../afs/afsincludes.h"
--- 15,21 ----
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/LINUX/osi_vfsops.c,v 1.11.2.2 2002/01/29 19:45:07 shadow Exp $");
  
  #include "../afs/sysincludes.h"
  #include "../afs/afsincludes.h"
***************
*** 78,83 ****
--- 78,84 ----
      AFS_GLOCK();
      if (afs_was_mounted) {
  	printf("You must reload the AFS kernel extensions before remounting AFS.\n");
+ 	AFS_GUNLOCK();
  	return NULL;
      }
      afs_was_mounted = 1;
Index: openafs/src/afs/LINUX/osi_vm.c
diff -c openafs/src/afs/LINUX/osi_vm.c:1.8.4.1 openafs/src/afs/LINUX/osi_vm.c:1.8.4.3
*** openafs/src/afs/LINUX/osi_vm.c:1.8.4.1	Sat Oct 13 00:20:26 2001
--- openafs/src/afs/LINUX/osi_vm.c	Tue Jan 29 11:18:58 2002
***************
*** 10,16 ****
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/LINUX/osi_vm.c,v 1.8.4.1 2001/10/13 04:20:26 shadow Exp $");
  
  #include "../afs/sysincludes.h"	/* Standard vendor system headers */
  #include "../afs/afsincludes.h"	/* Afs-based standard headers */
--- 10,16 ----
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/LINUX/osi_vm.c,v 1.8.4.3 2002/01/29 16:18:58 shadow Exp $");
  
  #include "../afs/sysincludes.h"	/* Standard vendor system headers */
  #include "../afs/afsincludes.h"	/* Afs-based standard headers */
***************
*** 89,95 ****
--- 89,105 ----
   */
  void osi_VM_StoreAllSegments(struct vcache *avc)
  {
+     struct inode *ip = (struct inode *) avc;
  
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,5)
+     /* filemap_fdatasync() only exported in 2.4.5 and above */
+     ReleaseWriteLock(&avc->lock);
+     AFS_GUNLOCK();
+     filemap_fdatasync(ip->i_mapping);
+     filemap_fdatawait(ip->i_mapping);
+     AFS_GLOCK();
+     ObtainWriteLock(&avc->lock, 121);
+ #endif
  }
  
  /* Purge VM for a file when its callback is revoked.
Index: openafs/src/afs/LINUX/osi_vnodeops.c
diff -c openafs/src/afs/LINUX/osi_vnodeops.c:1.29.2.2 openafs/src/afs/LINUX/osi_vnodeops.c:1.29.2.3
*** openafs/src/afs/LINUX/osi_vnodeops.c:1.29.2.2	Sat Oct 13 00:20:26 2001
--- openafs/src/afs/LINUX/osi_vnodeops.c	Sun Jan 20 04:01:51 2002
***************
*** 23,29 ****
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/LINUX/osi_vnodeops.c,v 1.29.2.2 2001/10/13 04:20:26 shadow Exp $");
  
  #include "../afs/sysincludes.h"
  #include "../afs/afsincludes.h"
--- 23,29 ----
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/LINUX/osi_vnodeops.c,v 1.29.2.3 2002/01/20 09:01:51 shadow Exp $");
  
  #include "../afs/sysincludes.h"
  #include "../afs/afsincludes.h"
***************
*** 685,690 ****
--- 685,766 ----
      return -code ;
  }
  
+ 
+ /* Validate a dentry. Return 1 if unchanged, 0 if VFS layer should re-evaluate.
+  * In kernels 2.2.10 and above, we are passed an additional flags var which
+  * may have either the LOOKUP_FOLLOW OR LOOKUP_DIRECTORY set in which case
+  * we are advised to follow the entry if it is a link or to make sure that 
+  * it is a directory. But since the kernel itself checks these possibilities
+  * later on, we shouldn't have to do it until later. Perhaps in the future..
+  */
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,10)
+ static int afs_linux_dentry_revalidate(struct dentry *dp, int flags)
+ #else
+ static int afs_linux_dentry_revalidate(struct dentry *dp)
+ #endif
+ {
+     char *name;
+     cred_t *credp = crref();
+     struct vrequest treq;
+     struct vcache *lookupvcp = NULL;
+     int code, bad_dentry = 1;
+     struct sysname_info sysState;
+     struct vcache *vcp = (struct vcache*) dp->d_inode;
+     struct vcache *parentvcp = (struct vcache*) dp->d_parent->d_inode;
+ 
+     AFS_GLOCK();
+ 
+     /* If it's a negative dentry, then there's nothing to do. */
+     if (!vcp || !parentvcp)
+         goto done;
+ 
+     if (code = afs_InitReq(&treq, credp))
+         goto done;
+ 
+     Check_AtSys(parentvcp, dp->d_name.name, &sysState, &treq);
+     name = sysState.name;
+ 
+     /* First try looking up the DNLC */
+     if (lookupvcp = osi_dnlc_lookup(parentvcp, name, WRITE_LOCK)) {
+         /* Verify that the dentry does not point to an old inode */
+         if (vcp != lookupvcp)
+             goto done;
+         /* Check and correct mvid */
+         if (*name != '/' && vcp->mvstat == 2) 
+             check_bad_parent(dp);
+ 	vcache2inode(vcp);
+         bad_dentry = 0;
+         goto done;
+     }
+ 
+     /* A DNLC lookup failure cannot be trusted. Try a real lookup */
+     code = afs_lookup(parentvcp, name, &lookupvcp, credp);
+ 
+     /* Verify that the dentry does not point to an old inode */
+     if (vcp != lookupvcp)
+         goto done;
+ 
+     bad_dentry = 0;
+ 
+ done:
+     /* Clean up */
+     if (lookupvcp)
+         afs_PutVCache(lookupvcp, WRITE_LOCK);
+     if (sysState.allocked)
+         osi_FreeLargeSpace(name);
+ 
+     AFS_GUNLOCK();
+     crfree(credp);
+ 
+     if (bad_dentry) {
+         shrink_dcache_parent(dp);
+         d_drop(dp);
+     }
+ 
+     return !bad_dentry;
+ }
+ 
+ #ifdef notdef
  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,10)
  static int afs_linux_dentry_revalidate(struct dentry *dp, int flags)
  #else
***************
*** 698,703 ****
--- 774,782 ----
      
      unsigned long timeout = 3*HZ; /* 3 seconds */
      
+     if (!ip)
+ 	printk("negative dentry: %s\n", dp->d_name.name);
+  
      if (!(flags & LOOKUP_CONTINUE)) {
  	long diff = CURRENT_TIME - dp->d_parent->d_inode->i_mtime;
  	
***************
*** 714,719 ****
--- 793,799 ----
   out_bad:
      return 0;
  }
+ #endif
  
  /* afs_dentry_iput */
  static void afs_dentry_iput(struct dentry *dp, struct inode *ip)
***************
*** 831,847 ****
             ip->i_data.a_ops = &afs_symlink_aops;
             ip->i_mapping = &ip->i_data;
  	} else
!            printk("afs_linux_lookup: FIXME\n");
  #else
  	if (S_ISDIR(ip->i_mode))
  	    ip->i_op = &afs_dir_iops;
  	else if (S_ISLNK(ip->i_mode))
  	    ip->i_op = &afs_symlink_iops;
  #endif
-     }
      dp->d_time = jiffies;
      dp->d_op = afs_dops;
      d_add(dp, (struct inode*)vcp);
  
      AFS_GUNLOCK();
      crfree(credp);
--- 911,927 ----
             ip->i_data.a_ops = &afs_symlink_aops;
             ip->i_mapping = &ip->i_data;
  	} else
!            printk("afs_linux_lookup: ip->i_mode 0x%x  dp->d_name.name %s  code %d\n", ip->i_mode, dp->d_name.name, code);
  #else
  	if (S_ISDIR(ip->i_mode))
  	    ip->i_op = &afs_dir_iops;
  	else if (S_ISLNK(ip->i_mode))
  	    ip->i_op = &afs_symlink_iops;
  #endif
      dp->d_time = jiffies;
      dp->d_op = afs_dops;
      d_add(dp, (struct inode*)vcp);
+     } 
  
      AFS_GUNLOCK();
      crfree(credp);
***************
*** 889,915 ****
      const char *name = dp->d_name.name;
      int putback = 0;
  
-     if (!list_empty(&dp->d_hash)) {
- 	d_drop(dp);
- 	/* Install a definite non-existence if we're the only user. */
- #if defined(AFS_LINUX24_ENV)
- 	if (atomic_read(&dp->d_count) == 1)
- #else
- 	if (dp->d_count == 1)
- #endif
- 	    putback = 1;
-     }
- 
      AFS_GLOCK();
      code = afs_remove((struct vcache*)dip, name, credp);
      AFS_GUNLOCK();
!     if (!code) {
! 	d_delete(dp);
! 	if (putback) {
! 	    dp->d_time = jiffies;
! 	    d_add(dp, NULL); /* means definitely does _not_ exist */
!     }
!     }
      crfree(credp);
      return -code;
  }
--- 969,979 ----
      const char *name = dp->d_name.name;
      int putback = 0;
  
      AFS_GLOCK();
      code = afs_remove((struct vcache*)dip, name, credp);
      AFS_GUNLOCK();
!     if (!code)
! 	d_drop(dp);
      crfree(credp);
      return -code;
  }
***************
*** 959,964 ****
--- 1023,1029 ----
  	dp->d_time = jiffies;
  	d_instantiate(dp, (struct inode*)tvcp);
      }
+ 
      AFS_GUNLOCK();
      crfree(credp);
      return -code;
***************
*** 982,988 ****
      }
      
      if (!code) {
! 	d_delete(dp);
      }
  
      AFS_GUNLOCK();
--- 1047,1053 ----
      }
      
      if (!code) {
! 	d_drop(dp);
      }
  
      AFS_GUNLOCK();
Index: openafs/src/afs/VNOPS/afs_vnop_remove.c
diff -c openafs/src/afs/VNOPS/afs_vnop_remove.c:1.4.4.1 openafs/src/afs/VNOPS/afs_vnop_remove.c:1.4.4.2
*** openafs/src/afs/VNOPS/afs_vnop_remove.c:1.4.4.1	Sat Oct 13 00:20:26 2001
--- openafs/src/afs/VNOPS/afs_vnop_remove.c	Sun Jan 20 03:20:57 2002
***************
*** 22,28 ****
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/VNOPS/afs_vnop_remove.c,v 1.4.4.1 2001/10/13 04:20:26 shadow Exp $");
  
  #include "../afs/sysincludes.h"	/* Standard vendor system headers */
  #include "../afs/afsincludes.h"	/* Afs-based standard headers */
--- 22,28 ----
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/VNOPS/afs_vnop_remove.c,v 1.4.4.2 2002/01/20 08:20:57 shadow Exp $");
  
  #include "../afs/sysincludes.h"	/* Standard vendor system headers */
  #include "../afs/afsincludes.h"	/* Afs-based standard headers */
***************
*** 232,237 ****
--- 232,241 ----
      AFS_STATCNT(afs_remove);
      afs_Trace2(afs_iclSetp, CM_TRACE_REMOVE, ICL_TYPE_POINTER, adp,
  	       ICL_TYPE_STRING, aname);
+ 
+     /* Check if this is dynroot */
+     if (afs_IsDynroot(adp))
+ 	return afs_DynrootVOPRemove(adp, acred, aname);
  
      if (code = afs_InitReq(&treq, acred))
        return code;
Index: openafs/src/afs/VNOPS/afs_vnop_symlink.c
diff -c openafs/src/afs/VNOPS/afs_vnop_symlink.c:1.4 openafs/src/afs/VNOPS/afs_vnop_symlink.c:1.4.4.1
*** openafs/src/afs/VNOPS/afs_vnop_symlink.c:1.4	Thu Jul 12 15:58:22 2001
--- openafs/src/afs/VNOPS/afs_vnop_symlink.c	Sun Jan 20 03:20:57 2002
***************
*** 21,27 ****
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/VNOPS/afs_vnop_symlink.c,v 1.4 2001/07/12 19:58:22 shadow Exp $");
  
  #include "../afs/sysincludes.h"	/* Standard vendor system headers */
  #include "../afs/afsincludes.h"	/* Afs-based standard headers */
--- 21,27 ----
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/afs/VNOPS/afs_vnop_symlink.c,v 1.4.4.1 2002/01/20 08:20:57 shadow Exp $");
  
  #include "../afs/sysincludes.h"	/* Standard vendor system headers */
  #include "../afs/afsincludes.h"	/* Afs-based standard headers */
***************
*** 77,82 ****
--- 77,86 ----
      AFS_STATCNT(afs_symlink);
      afs_Trace2(afs_iclSetp, CM_TRACE_SYMLINK, ICL_TYPE_POINTER, adp,
                  ICL_TYPE_STRING, aname);
+ 
+     if (afs_IsDynroot(adp))
+ 	return afs_DynrootVOPSymlink(adp, acred, aname, atargetName);
+ 
      if (code = afs_InitReq(&treq, acred))
         return code;
  
Index: openafs/src/afsd/afs.ppc_darwin.plist
diff -c openafs/src/afsd/afs.ppc_darwin.plist:1.2.2.1 openafs/src/afsd/afs.ppc_darwin.plist:removed
*** openafs/src/afsd/afs.ppc_darwin.plist:1.2.2.1	Sat Oct 13 00:41:21 2001
--- openafs/src/afsd/afs.ppc_darwin.plist	Wed Jan 30 16:23:34 2002
***************
*** 1,31 ****
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
- <plist version="0.9">
- <dict>
- 	<key>CFBundleDevelopmentRegion</key>
- 	<string>English</string>
- 	<key>CFBundleExecutable</key>
- 	<string>afs</string>
- 	<key>CFBundleIdentifier</key>
- 	<string>org.openafs.filesystems.afs</string>
- 	<key>CFBundleInfoDictionaryVersion</key>
- 	<string>6.0</string>
- 	<key>CFBundleName</key>
- 	<string>afs</string>
- 	<key>CFBundlePackageType</key>
- 	<string>KEXT</string>
- 	<key>CFBundleShortVersionString</key>
- 	<string>1.1.1</string>
- 	<key>CFBundleSignature</key>
- 	<string>????</string>
- 	<key>CFBundleVersion</key>
- 	<string>1.1.1</string>
- 	<key>OSBundleLibraries</key>
- 	<dict>
- 		<key>com.apple.kernel.bsd</key>
- 		<string>1.0.0b1</string>
- 		<key>com.apple.kernel.mach</key>
- 		<string>1.0.0b1</string>
- 	</dict>
- </dict>
- </plist>
--- 0 ----
Index: openafs/src/afsd/afs.rc.linux
diff -c openafs/src/afsd/afs.rc.linux:1.2.8.1 openafs/src/afsd/afs.rc.linux:1.2.8.3
*** openafs/src/afsd/afs.rc.linux:1.2.8.1	Sat Oct 13 00:20:44 2001
--- openafs/src/afsd/afs.rc.linux	Wed Dec 26 15:48:16 2001
***************
*** 77,83 ****
  }
  
  on_network() {
!     ADDRS=`ifconfig -a | grep 'inet addr' | grep -v 127.0.0.1 | wc -l`
      if [ "$ADDRS" = "" ]; then
         echo afs: No interfaces with IP address 1>&2
         return 1
--- 77,83 ----
  }
  
  on_network() {
!     ADDRS=`LANG=C ifconfig -a | grep 'inet addr' | grep -v 127.0.0.1 | wc -l`
      if [ "$ADDRS" = "" ]; then
         echo afs: No interfaces with IP address 1>&2
         return 1
***************
*** 172,178 ****
  		choose_client
  	fi
      
! 	if [ ! -f $MODLOADDIR/$LIBAFS ] ; then
  		echo AFS module $MODLOADDIR/$LIBAFS does not exist. Not starting AFS.
  		exit 1
  	fi
--- 172,178 ----
  		choose_client
  	fi
      
! 	if [ ! -f "$MODLOADDIR/$LIBAFS" ] ; then
  		echo AFS module $MODLOADDIR/$LIBAFS does not exist. Not starting AFS.
  		exit 1
  	fi
Index: openafs/src/afsd/afsd.c
diff -c openafs/src/afsd/afsd.c:1.13.2.2 openafs/src/afsd/afsd.c:1.13.2.5
*** openafs/src/afsd/afsd.c:1.13.2.2	Sat Oct 13 00:20:44 2001
--- openafs/src/afsd/afsd.c	Sun Jan 20 03:20:58 2002
***************
*** 55,61 ****
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/afsd/afsd.c,v 1.13.2.2 2001/10/13 04:20:44 shadow Exp $");
  
  #define VFS 1
  
--- 55,61 ----
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/afsd/afsd.c,v 1.13.2.5 2002/01/20 08:20:58 shadow Exp $");
  
  #define VFS 1
  
***************
*** 807,812 ****
--- 807,816 ----
  		  (strcmp(currp->d_name,         "quota.user") == 0) ||
  		  (strcmp(currp->d_name,         "quota.group") == 0) ||
  #endif
+ #ifdef AFS_LINUX22_ENV
+ 		  /* this is the ext3 journal file */
+ 		  (strcmp(currp->d_name,         ".journal") == 0) ||
+ #endif
  		  (strcmp(currp->d_name, "lost+found") == 0)) {
  	    /*
  	     * Don't do anything - this file is legit, and is to be left alone.
***************
*** 1058,1063 ****
--- 1062,1077 ----
      return 0;
  }
  
+ static ConfigCellAlias(aca, arock, adir)
+     register struct afsconf_cellalias *aca;
+     char *arock;
+     struct afsconf_dir *adir;
+ {
+     /* push the alias into the kernel */
+     call_syscall(AFSOP_ADDCELLALIAS, aca->aliasName, aca->realName);
+     return 0;
+ }
+ 
  #ifdef AFS_AFSDB_ENV
  static AfsdbLookupHandler()
  {
***************
*** 1612,1617 ****
--- 1626,1632 ----
      lookingForHomeCell = 1;
  
      afsconf_CellApply(cdir, ConfigCell, (char *) 0);
+     afsconf_CellAliasApply(cdir, ConfigCellAlias, (char *) 0);
  
      /*
       * If we're still looking for the home cell after the whole cell configuration database
***************
*** 1996,2002 ****
  #endif
  
      error = syscall(AFS_SYSCALL, AFSCALL_CALL, param1, param2, param3, param4, param5, param6, param7);
!     if (afsd_verbose) printf("SScall(%d, %d)=%d ", AFS_SYSCALL, AFSCALL_CALL, error);
      return (error);
  }
  #else	/* AFS_AIX32_ENV */
--- 2011,2017 ----
  #endif
  
      error = syscall(AFS_SYSCALL, AFSCALL_CALL, param1, param2, param3, param4, param5, param6, param7);
!     if (afsd_verbose) printf("SScall(%d, %d, %d)=%d ", AFS_SYSCALL, AFSCALL_CALL, param1, error);
      return (error);
  }
  #else	/* AFS_AIX32_ENV */
Index: openafs/src/auth/Makefile.in
diff -c openafs/src/auth/Makefile.in:1.5 openafs/src/auth/Makefile.in:1.5.2.1
*** openafs/src/auth/Makefile.in:1.5	Mon Sep 10 16:21:01 2001
--- openafs/src/auth/Makefile.in	Sun Jan 20 03:27:57 2002
***************
*** 39,45 ****
  LIBS=libauth.a ${TOP_LIBDIR}/libsys.a \
        ${TOP_LIBDIR}/librxkad.a ${TOP_LIBDIR}/libdes.a \
        ${TOP_LIBDIR}/librx.a ${TOP_LIBDIR}/libsys.a \
!       ${TOP_LIBDIR}/liblwp.a ${TOP_LIBDIR}/util.a ${XLIBS}
  INCLS=cellconfig.h auth.h keys.h
  KSRCS=auth.h
  UKSRCS=${KSRCS} cellconfig.h acfg_errors.c keys.h cellconfig.c \
--- 39,45 ----
  LIBS=libauth.a ${TOP_LIBDIR}/libsys.a \
        ${TOP_LIBDIR}/librxkad.a ${TOP_LIBDIR}/libdes.a \
        ${TOP_LIBDIR}/librx.a ${TOP_LIBDIR}/libsys.a \
!       ${TOP_LIBDIR}/liblwp.a ${TOP_LIBDIR}/util.a
  INCLS=cellconfig.h auth.h keys.h
  KSRCS=auth.h
  UKSRCS=${KSRCS} cellconfig.h acfg_errors.c keys.h cellconfig.c \
***************
*** 69,79 ****
  	$(AR) crv $@ $(KOBJS) AFS_component_version_number.o
  	$(RANLIB) $@
  
! copyauth: copyauth.o
! 	$(CC) $(CFLAGS) -o copyauth copyauth.o ${LIBS}
  
! setkey: setkey.o
! 	${CC} $(CFLAGS) -o setkey setkey.o ${LIBS}
  
  acfg_errors.o: acfg_errors.c
  
--- 69,79 ----
  	$(AR) crv $@ $(KOBJS) AFS_component_version_number.o
  	$(RANLIB) $@
  
! copyauth: copyauth.o 
! 	$(CC) $(CFLAGS) -o copyauth copyauth.o ${LIBS} ${XLIBS}
  
! setkey: setkey.o 
! 	${CC} $(CFLAGS) -o setkey setkey.o ${LIBS} ${XLIBS}
  
  acfg_errors.o: acfg_errors.c
  
Index: openafs/src/auth/cellconfig.c
diff -c openafs/src/auth/cellconfig.c:1.14.2.2 openafs/src/auth/cellconfig.c:1.14.2.5
*** openafs/src/auth/cellconfig.c:1.14.2.2	Sat Oct 13 00:20:47 2001
--- openafs/src/auth/cellconfig.c	Sun Jan 20 03:33:45 2002
***************
*** 10,16 ****
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/auth/cellconfig.c,v 1.14.2.2 2001/10/13 04:20:47 shadow Exp $");
  
  #include <afs/stds.h>
  #include <afs/pthread_glock.h>
--- 10,16 ----
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/auth/cellconfig.c,v 1.14.2.5 2002/01/20 08:33:45 shadow Exp $");
  
  #include <afs/stds.h>
  #include <afs/pthread_glock.h>
***************
*** 33,44 ****
  #include <netdb.h>
  #include <sys/file.h>
  #include <sys/time.h>
- #include <afs/afsint.h>
  #ifdef AFS_AFSDB_ENV
  #include <arpa/nameser.h>
  #include <resolv.h>
  #endif /* AFS_AFSDB_ENV */
  #endif /* AFS_NT40_ENV */
  #include <errno.h>
  #include <ctype.h>
  #include <time.h>
--- 33,44 ----
  #include <netdb.h>
  #include <sys/file.h>
  #include <sys/time.h>
  #ifdef AFS_AFSDB_ENV
  #include <arpa/nameser.h>
  #include <resolv.h>
  #endif /* AFS_AFSDB_ENV */
  #endif /* AFS_NT40_ENV */
+ #include <afs/afsint.h>
  #include <errno.h>
  #include <ctype.h>
  #include <time.h>
***************
*** 357,362 ****
--- 357,363 ----
      FILE *tf;
      register char *tp, *bp;
      register struct afsconf_entry *curEntry;
+     struct afsconf_aliasentry *curAlias;
      register afs_int32 code;
      afs_int32 i;
      char tbuffer[256], tbuf1[256];
***************
*** 468,475 ****
      if (curEntry) {
  	curEntry->next = adir->entries;
  	adir->entries = curEntry;
      }
!     
      /* now read the fs keys, if possible */
      adir->keystr = (struct afsconf_keys *) 0;
      afsconf_IntGetKeys(adir);
--- 469,513 ----
      if (curEntry) {
  	curEntry->next = adir->entries;
  	adir->entries = curEntry;
+     }
+ 
+     /* Read in the alias list */
+     strcompose(tbuffer, 256, adir->name, "/", AFSDIR_CELLALIAS_FILE, NULL);
+ 
+     tf = fopen(tbuffer, "r");
+     while (tf) {
+ 	char *aliasPtr;
+ 
+ 	tp = fgets(tbuffer, sizeof(tbuffer), tf);
+ 	if (!tp) break;
+ 	TrimLine(tbuffer);  /* remove white space */
+ 
+ 	if (tbuffer[0] == '\0' ||
+ 	    tbuffer[0] == '\n' ||
+ 	    tbuffer[0] == '#') continue;	/* empty line */
+ 
+ 	tp = tbuffer;
+ 	while (tp[0] != '\0' && tp[0] != ' ' && tp[0] != '\t') tp++;
+ 	if (tp[0] == '\0') continue;		/* invalid line */
+ 
+ 	while (tp[0] != '\0' && (tp[0] == ' ' || tp[0] == '\t')) 0[tp++] = '\0';
+ 	if (tp[0] == '\0') continue;		/* invalid line */
+ 
+ 	aliasPtr = tp;
+ 	while (tp[0] != '\0' && tp[0] != ' ' && tp[0] != '\t' &&
+ 	       tp[0] != '\r' && tp[0] != '\n') tp++;
+ 	tp[0] = '\0';
+ 
+ 	curAlias = malloc(sizeof(*curAlias));
+ 	memset(curAlias, 0, sizeof(*curAlias));
+ 
+ 	strcpy(curAlias->aliasInfo.aliasName, aliasPtr);
+ 	strcpy(curAlias->aliasInfo.realName, tbuffer);
+ 
+ 	curAlias->next = adir->alias_entries;
+ 	adir->alias_entries = curAlias;
      }
! 
      /* now read the fs keys, if possible */
      adir->keystr = (struct afsconf_keys *) 0;
      afsconf_IntGetKeys(adir);
***************
*** 545,550 ****
--- 583,610 ----
      return 0;
  }
  
+ /* call aproc(entry, arock, adir) for all cell aliases.
+  * Proc must return 0, or we'll stop early and return the code it returns
+  */
+ afsconf_CellAliasApply(adir, aproc, arock)
+     struct afsconf_dir *adir;
+     int (*aproc)();
+     char *arock;
+ {
+     register struct afsconf_aliasentry *tde;
+     register afs_int32 code;
+     LOCK_GLOBAL_MUTEX
+     for(tde=adir->alias_entries; tde; tde=tde->next) {
+ 	code = (*aproc)(&tde->aliasInfo, arock, adir);
+ 	if (code) {
+ 	    UNLOCK_GLOBAL_MUTEX
+ 	    return code;
+ 	}
+     }
+     UNLOCK_GLOBAL_MUTEX
+     return 0;
+ }
+ 
  afs_int32 afsconf_SawCell = 0;
  
  afsconf_GetExtendedCellInfo(adir, acellName, aservice, acellInfo, clones)
***************
*** 658,663 ****
--- 718,728 ----
  
      if (server_num == 0)		/* No AFSDB records */
  	return AFSCONF_NOTFOUND;
+ 
+     /* Convert the real cell name to lowercase */
+     for (p = (unsigned char *) realCellName; *p; p++)
+ 	*p = tolower(*p);
+ 
      strncpy(acellInfo->name, realCellName, sizeof(acellInfo->name));
      acellInfo->numServers = server_num;
  
***************
*** 734,739 ****
--- 799,805 ----
  char *acellName;
  struct afsconf_cell *acellInfo; {
      register struct afsconf_entry *tce;
+     struct afsconf_aliasentry *tcae;
      struct afsconf_entry *bestce;
      register afs_int32 i;
      int tservice;
***************
*** 765,770 ****
--- 831,845 ----
  	UNLOCK_GLOBAL_MUTEX
  	return 0;
      }
+ 
+     /* Look through the list of aliases */
+     for (tcae = adir->alias_entries; tcae; tcae = tcae->next) {
+ 	if (strcasecmp(tcae->aliasInfo.aliasName, tcell) == 0) {
+ 	    tcell = tcae->aliasInfo.realName;
+ 	    break;
+ 	}
+     }
+ 
      for(tce=adir->entries;tce;tce=tce->next) {
  	if (strcasecmp(tce->cellInfo.name, tcell) == 0) {
  	    /* found our cell */
***************
*** 797,803 ****
      else {
  	UNLOCK_GLOBAL_MUTEX
  #ifdef AFS_AFSDB_ENV
! 	return afsconf_GetAfsdbInfo(acellName, aservice, acellInfo);
  #else
  	return AFSCONF_NOTFOUND;
  #endif /* AFS_AFSDB_ENV */
--- 872,878 ----
      else {
  	UNLOCK_GLOBAL_MUTEX
  #ifdef AFS_AFSDB_ENV
! 	return afsconf_GetAfsdbInfo(tcell, aservice, acellInfo);
  #else
  	return AFSCONF_NOTFOUND;
  #endif /* AFS_AFSDB_ENV */
Index: openafs/src/auth/cellconfig.p.h
diff -c openafs/src/auth/cellconfig.p.h:1.5 openafs/src/auth/cellconfig.p.h:1.5.4.1
*** openafs/src/auth/cellconfig.p.h:1.5	Thu Jul  5 11:39:03 2001
--- openafs/src/auth/cellconfig.p.h	Sun Jan 20 03:21:00 2002
***************
*** 69,85 ****
--- 69,96 ----
      int timeout;				/* Data timeout, if non-zero */
  };
  
+ struct afsconf_cellalias {
+     char aliasName[MAXCELLCHARS];
+     char realName[MAXCELLCHARS];
+ };
+ 
  struct afsconf_entry {
      struct afsconf_entry *next;	/* next guy in afsconf_dir */
      struct afsconf_cell	cellInfo;	/* info for this cell */
  };
  
+ struct afsconf_aliasentry {
+     struct afsconf_aliasentry *next;
+     struct afsconf_cellalias aliasInfo;
+ };
+ 
  struct afsconf_dir {
      char *name;	    /* pointer to dir prefix */
      char *cellName; /* cell name, if any, we're in */
      struct afsconf_entry *entries; /* list of cell entries */
      struct afsconf_keys	*keystr;    /* structure containing keys */
      afs_int32 timeRead;		    /* time stamp of file last read */
+     struct afsconf_aliasentry *alias_entries; /* cell aliases */
  };
  
  extern struct afsconf_dir *afsconf_Open();
Index: openafs/src/auth/ktc.c
diff -c openafs/src/auth/ktc.c:1.7.2.1 openafs/src/auth/ktc.c:1.7.2.2
*** openafs/src/auth/ktc.c:1.7.2.1	Sat Oct 13 00:20:47 2001
--- openafs/src/auth/ktc.c	Wed Dec 26 15:45:27 2001
***************
*** 16,22 ****
  #include <afs/param.h>
  #endif
  
! RCSID("$Header: /data/cvs/openafs/src/auth/ktc.c,v 1.7.2.1 2001/10/13 04:20:47 shadow Exp $");
  
  #if defined(UKERNEL)
  #include "../afs/sysincludes.h"
--- 16,22 ----
  #include <afs/param.h>
  #endif
  
! RCSID("$Header: /data/cvs/openafs/src/auth/ktc.c,v 1.7.2.2 2001/12/26 20:45:27 shadow Exp $");
  
  #if defined(UKERNEL)
  #include "../afs/sysincludes.h"
***************
*** 1274,1280 ****
      struct ktc_principal principal;
      struct ktc_token token;
      int     status;
!     off_t   start, lseek();
      int     lifetime, kvno;
      int     count;		/* count for write */
  
--- 1274,1280 ----
      struct ktc_principal principal;
      struct ktc_token token;
      int     status;
!     off_t   start;
      int     lifetime, kvno;
      int     count;		/* count for write */
  
Index: openafs/src/auth/ktc_nt.c
diff -c openafs/src/auth/ktc_nt.c:1.5 openafs/src/auth/ktc_nt.c:1.5.4.1
*** openafs/src/auth/ktc_nt.c:1.5	Thu Jul 12 15:58:26 2001
--- openafs/src/auth/ktc_nt.c	Wed Nov 21 01:45:48 2001
***************
*** 12,18 ****
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/auth/ktc_nt.c,v 1.5 2001/07/12 19:58:26 shadow Exp $");
  
  #include <afs/stds.h>
  #include <stdio.h>
--- 12,18 ----
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/auth/ktc_nt.c,v 1.5.4.1 2001/11/21 06:45:48 shadow Exp $");
  
  #include <afs/stds.h>
  #include <stdio.h>
***************
*** 333,338 ****
--- 333,351 ----
  	strcpy(tp, client->name);
  	tp += temp+1;
  
+     /* we need the SMB user name to associate the tokens with in the
+     integrated logon case. */
+     if (flags & AFS_SETTOK_LOGON) {
+     if (client->smbname == NULL)
+       temp = 0;
+     else
+ 	    temp = strlen(client->smbname);
+         if (temp == 0 || temp >= MAXKTCNAMELEN)
+           return KTC_INVAL;
+ 	    strcpy(tp, client->smbname);
+           tp += temp+1;
+     }
+            
  	/* uuid */
  	status = UuidCreate((UUID *)&uuid);
  	memcpy(tp, &uuid, sizeof(uuid));
Index: openafs/src/bozo/.cvsignore
diff -c openafs/src/bozo/.cvsignore:1.1 openafs/src/bozo/.cvsignore:1.1.2.1
*** openafs/src/bozo/.cvsignore:1.1	Mon Sep 10 16:14:07 2001
--- openafs/src/bozo/.cvsignore	Sun Jan 20 04:07:31 2002
***************
*** 2,7 ****
--- 2,8 ----
  Makefile
  bnode.h
  bos
+ bos_util
  boserr.c
  bosint.cs.c
  bosint.h
Index: openafs/src/bozo/Makefile.in
diff -c openafs/src/bozo/Makefile.in:1.4 openafs/src/bozo/Makefile.in:1.4.2.2
*** openafs/src/bozo/Makefile.in:1.4	Fri Sep  7 19:34:48 2001
--- openafs/src/bozo/Makefile.in	Sun Jan 20 04:07:31 2002
***************
*** 60,66 ****
  OBJS=bosserver.o bnode.o ezbnodeops.o fsbnodeops.o bosint.ss.o bosint.xdr.o \
  bosoprocs.o cronbnodeops.o
  
! all: bosserver ${TOP_INCDIR}/afs/bosint.h bos ${TOP_LIBDIR}/libbos.a ${TOP_INCDIR}/afs/bnode.h
  
  $(OBJS) bosint.xdr.o bosint.cs.o boserr.o: $(INCLS)
  
--- 60,66 ----
  OBJS=bosserver.o bnode.o ezbnodeops.o fsbnodeops.o bosint.ss.o bosint.xdr.o \
  bosoprocs.o cronbnodeops.o
  
! all: bosserver ${TOP_INCDIR}/afs/bosint.h bos ${TOP_LIBDIR}/libbos.a ${TOP_INCDIR}/afs/bnode.h bos_util
  
  $(OBJS) bosint.xdr.o bosint.cs.o boserr.o: $(INCLS)
  
***************
*** 87,92 ****
--- 87,97 ----
  bos: bos.o $(LIBS) libbos.a
  	${CC} ${CFLAGS} -o bos bos.o libbos.a $(LIBS)  ${XLIBS}
  
+ bos_util.o: bos_util.c ${INCLS} AFS_component_version_number.o
+ 
+ bos_util: bos_util.o $(LIBS) 
+ 	${CC} ${CFLAGS} -o bos_util bos_util.o $(LIBS)  ${XLIBS}
+ 
  ezbnodeops.o: ezbnodeops.c ${INCLS}
  
  fsbnodeops.o: fsbnodeops.c ${INCLS}
***************
*** 107,112 ****
--- 112,118 ----
  	${DESTDIR}${includedir}/afs/bosint.h \
  	${DESTDIR}${bindir}/bos \
  	${DESTDIR}${afssrvbindir}/bos \
+ 	${DESTDIR}${afssrvsbindir}/bos_util \
  	${DESTDIR}${libdir}/afs/libbos.a \
  	${DESTDIR}${includedir}/afs/bnode.h
  
***************
*** 122,127 ****
--- 128,136 ----
  ${DEST}/root.server/usr/afs/bin/bos: bos
  	${INSTALL} $? $@
  
+ ${DEST}/root.server/usr/afs/bin/bos_util: bos_util
+ 	${INSTALL} $? $@
+ 
  ${DEST}/lib/afs/libbos.a: libbos.a
  	${INSTALL} $? $@
  
***************
*** 132,139 ****
  # Misc. targets
  #
  clean:
! 	$(RM) -f  *.a *.o bos bosserver testproc bosint.cs.c bosint.ss.c bosint.xdr.c \
! 		bosint.h core boserr.c bnode.h AFS_component_version_number.c
  
  test: 
  	cd test; $(MAKE) 
--- 141,149 ----
  # Misc. targets
  #
  clean:
! 	$(RM) -f  *.a *.o bos bosserver testproc bos_util \
! 		bosint.cs.c bosint.ss.c bosint.xdr.c bosint.h \
! 		core boserr.c bnode.h AFS_component_version_number.c 
  
  test: 
  	cd test; $(MAKE) 
***************
*** 154,159 ****
--- 164,172 ----
  ${DESTDIR}${afssrvbindir}/bos: bos
  	${INSTALL} $? $@
  
+ ${DESTDIR}${afssrvsbindir}/bos_util: bos_util
+ 	${INSTALL} $? $@
+ 
  ${DESTDIR}${libdir}/afs/libbos.a: libbos.a
  	${INSTALL} $? $@
  
***************
*** 171,176 ****
  	${DEST}/include/afs/bosint.h \
  	${DEST}/bin/bos \
  	${DEST}/root.server/usr/afs/bin/bos \
  	${DEST}/lib/afs/libbos.a \
  	${DEST}/include/afs/bnode.h
- 
--- 184,189 ----
  	${DEST}/include/afs/bosint.h \
  	${DEST}/bin/bos \
  	${DEST}/root.server/usr/afs/bin/bos \
+ 	${DEST}/root.server/usr/afs/bin/bos_util \
  	${DEST}/lib/afs/libbos.a \
  	${DEST}/include/afs/bnode.h
Index: openafs/src/bozo/NTMakefile
diff -c openafs/src/bozo/NTMakefile:1.2.8.1 openafs/src/bozo/NTMakefile:1.2.8.2
*** openafs/src/bozo/NTMakefile:1.2.8.1	Wed Sep 19 18:32:47 2001
--- openafs/src/bozo/NTMakefile	Wed Nov 14 22:30:27 2001
***************
*** 66,72 ****
  	$(DESTDIR)\lib\afs\afsaudit.lib \
  	$(DESTDIR)\lib\afs\afsreg.lib \
  	$(DESTDIR)\lib\afs\afseventlog.lib \
! 	$(DESTDIR)\lib\afs\afsprocmgmt.lib
  
  $(BOSSERVER_EXEFILE): $(BOSSERVER_EXEOBJS) $(BOSSERVER_EXELIBS)
  	$(EXECONLINK)
--- 66,73 ----
  	$(DESTDIR)\lib\afs\afsaudit.lib \
  	$(DESTDIR)\lib\afs\afsreg.lib \
  	$(DESTDIR)\lib\afs\afseventlog.lib \
! 	$(DESTDIR)\lib\afs\afsprocmgmt.lib \
! 	$(DESTDIR)\lib\cm_dns.obj
  
  $(BOSSERVER_EXEFILE): $(BOSSERVER_EXEOBJS) $(BOSSERVER_EXELIBS)
  	$(EXECONLINK)
***************
*** 100,106 ****
  	$(DESTDIR)\lib\afs\afsbos.lib \
  	$(DESTDIR)\lib\afs\afsreg.lib \
  	$(DESTDIR)\lib\afs\afsprocmgmt.lib \
! 	$(DESTDIR)\lib\afs\afspioctl.lib
  
  
  $(RS_BOS_EXEFILE): $(BOS_EXEOBJS) $(BOS_EXELIBS)
--- 101,108 ----
  	$(DESTDIR)\lib\afs\afsbos.lib \
  	$(DESTDIR)\lib\afs\afsreg.lib \
  	$(DESTDIR)\lib\afs\afsprocmgmt.lib \
! 	$(DESTDIR)\lib\afs\afspioctl.lib \
! 	$(DESTDIR)\lib\cm_dns.obj
  
  
  $(RS_BOS_EXEFILE): $(BOS_EXEOBJS) $(BOS_EXELIBS)
Index: openafs/src/bozo/bnode.c
diff -c openafs/src/bozo/bnode.c:1.7.2.1 openafs/src/bozo/bnode.c:1.7.2.3
*** openafs/src/bozo/bnode.c:1.7.2.1	Sat Oct 13 00:21:04 2001
--- openafs/src/bozo/bnode.c	Wed Dec 26 15:47:02 2001
***************
*** 10,16 ****
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/bozo/bnode.c,v 1.7.2.1 2001/10/13 04:21:04 shadow Exp $");
  
  #include <stddef.h>
  #include <stdlib.h>
--- 10,16 ----
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/bozo/bnode.c,v 1.7.2.3 2001/12/26 20:47:02 shadow Exp $");
  
  #include <stddef.h>
  #include <stdlib.h>
***************
*** 534,543 ****
  			    tb->errorSignal = 0;
  			}
  			if (tp->coreName)
! 			    bozo_Log("%s:%s exited with code %d",
  				tb->name, tp->coreName, tp->lastExit);
  			else
! 			    bozo_Log("%s exited with code %d",
  				tb->name, tp->lastExit);
  		    }
  		    else {
--- 534,543 ----
  			    tb->errorSignal = 0;
  			}
  			if (tp->coreName)
! 			    bozo_Log("%s:%s exited with code %d\n",
  				tb->name, tp->coreName, tp->lastExit);
  			else
! 			    bozo_Log("%s exited with code %d\n",
  				tb->name, tp->lastExit);
  		    }
  		    else {
***************
*** 554,564 ****
  			    RememberProcName(tp);
  			}
  			if (tp->coreName)
! 			    bozo_Log("%s:%s exited on signal %d%s",
  				tb->name, tp->coreName, tp->lastSignal,
  				WCOREDUMP(status) ? " (core dumped)" : "");
  			else
! 			    bozo_Log("%s exited on signal %d%s",
  				tb->name, tp->lastSignal,
  				WCOREDUMP(status) ? " (core dumped)" : "");
  			SaveCore(tb, tp);
--- 554,564 ----
  			    RememberProcName(tp);
  			}
  			if (tp->coreName)
! 			    bozo_Log("%s:%s exited on signal %d%s\n",
  				tb->name, tp->coreName, tp->lastSignal,
  				WCOREDUMP(status) ? " (core dumped)" : "");
  			else
! 			    bozo_Log("%s exited on signal %d%s\n",
  				tb->name, tp->lastSignal,
  				WCOREDUMP(status) ? " (core dumped)" : "");
  			SaveCore(tb, tp);
Index: openafs/src/bozo/bos_util.c
diff -c /dev/null openafs/src/bozo/bos_util.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:38 2002
--- openafs/src/bozo/bos_util.c	Sun Jan 20 03:52:34 2002
***************
*** 0 ****
--- 1,201 ----
+ /* 
+  *  Copyright (C) 1989 by the Massachusetts Institute of Technology
+  * 
+  *    Export of software employing encryption from the United States of
+  *    America is assumed to require a specific license from the United
+  *    States Government.  It is the responsibility of any person or
+  *    organization contemplating export to obtain such a license before
+  *    exporting.
+  * 
+  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+  * distribute this software and its documentation for any purpose and
+  * without fee is hereby granted, provided that the above copyright
+  * notice appear in all copies and that both that copyright notice and
+  * this permission notice appear in supporting documentation, and that
+  * the name of M.I.T. not be used in advertising or publicity pertaining
+  * to distribution of the software without specific, written prior
+  * permission.  M.I.T. makes no representations about the suitability of
+  * this software for any purpose.  It is provided "as is" without express
+  * or implied warranty.
+  */
+ 
+ #include <afsconfig.h>
+ #include <afs/param.h>
+ 
+ RCSID("$Header: /data/cvs/openafs/src/bozo/bos_util.c,v 1.1.2.1 2002/01/20 08:52:34 shadow Exp $");
+ 
+ #include <sys/types.h>
+ #include <netinet/in.h>
+ #include <netdb.h>
+ 
+ #include <afs/stds.h>
+ #include <afs/afsutil.h>
+ #include <rx/rxkad.h>
+ #include <afs/keys.h>
+ #include <afs/cellconfig.h>
+ 
+ int 
+ main(int argc, char **argv)
+ {
+     struct afsconf_dir *tdir;
+     register afs_int32 code;
+ 
+     if (argc == 1) {
+ 	printf("bos_util: usage is 'bos_util <opcode> options, e.g.\n");
+ 	printf("    bos_util add <kvno>\n");
+ 	printf("    bos_util adddes <kvno>\n");
+ #ifdef KERBEROS
+ 	printf("    bos_util srvtab2keyfile <kvno> <keyfile> <princ>\n");
+ #endif
+ 	printf("    bos_util delete <kvno>\n");
+ 	printf("    bos_util list\n");
+ 	exit(1);
+     }
+ 
+     tdir = afsconf_Open(AFSDIR_SERVER_ETC_DIR);
+     if (!tdir) {
+ 	printf("bos_util: can't initialize conf dir '%s'\n", AFSDIR_SERVER_ETC_DIR);
+ 	exit(1);
+     }
+     if (strcmp(argv[1], "add")==0) {
+ 	struct ktc_encryptionKey tkey;
+ 	int kvno;
+ 	char buf[BUFSIZ], ver[BUFSIZ];
+ 	char *tcell = (char *) 0;
+ 
+ 	if (argc != 3) {
+ 	    printf("bos_util add: usage is 'bos_util add <kvno>\n");
+ 	    exit(1);
+ 	}
+ 	kvno = atoi(argv[2]);
+ 	memset(&tkey, 0, sizeof(struct ktc_encryptionKey));
+ 
+ 	/* prompt for key */
+ 	code=des_read_pw_string(buf,sizeof(buf),"input key: ",0);
+ 	if(code || strlen(buf)==0) {
+ 	    printf("Bad key: \n");
+ 	    exit(1);
+ 	}
+ 	code=des_read_pw_string(ver,sizeof(ver),"Retype input key: ",0);
+ 	if(code || strlen(ver)==0) {
+ 	    printf("Bad key: \n");
+ 	    exit(1);
+ 	}
+ 	if (strcmp (ver, buf) != 0) {
+ 	    printf ("\nInput key mismatch\n");
+ 	    exit(1);
+ 	}
+ 	ka_StringToKey(buf,tcell,&tkey);
+ 	code = afsconf_AddKey(tdir, kvno, &tkey);
+ 	if (code) {
+ 	    printf("bos_util: failed to set key, code %d.\n", code);
+ 	    exit(1);
+ 	}
+     }
+     else if (strcmp(argv[1], "adddes")==0) {
+ 	struct ktc_encryptionKey tkey;
+ 	int kvno;
+ 	register afs_int32 code;
+ 	char buf[BUFSIZ], ver[BUFSIZ];
+ 	char *tcell = (char *) 0;
+ 
+ 	if (argc != 3) {
+ 	    printf("bos_util adddes: usage is 'bos_util adddes <kvno>\n");
+ 	    exit(1);
+ 	}
+ 	kvno = atoi(argv[2]);
+ 	memset(&tkey, 0, sizeof(struct ktc_encryptionKey));
+ 
+ 	/* prompt for key */
+ 	code=des_read_pw_string(buf,sizeof(buf),"input key: ",0);
+ 	if(code || strlen(buf)==0) {
+ 	    printf("Bad key: \n");
+ 	    exit(1);
+ 	}
+ 	code=des_read_pw_string(ver,sizeof(ver),"Retype input key: ",0);
+ 	if(code || strlen(ver)==0) {
+ 	    printf("Bad key: \n");
+ 	    exit(1);
+ 	}
+ 	if (strcmp (ver, buf) != 0) {
+ 	    printf ("\nInput key mismatch\n");
+ 	    exit(1);
+ 	}
+ 	des_string_to_key(buf,&tkey);
+ 	code = afsconf_AddKey(tdir, kvno, &tkey);
+ 	if (code) {
+ 	    printf("bos_util: failed to set key, code %d.\n", code);
+ 	    exit(1);
+ 	}
+     }
+ #ifdef KERBEROS
+     else if (strcmp(argv[1], "srvtab2keyfile")==0) {
+ 	char tkey[8], name[255], inst[255], realm[255];
+ 	int kvno;
+ 	if (argc != 5) {
+ 	    printf("bos_util add: usage is 'bos_util srvtab2keyfile <kvno> <keyfile> <princ>\n");
+ 	    exit(1);
+ 	}
+ 	kvno = atoi(argv[2]);
+ 	bzero(tkey, sizeof(tkey));
+ 	code = kname_parse(name, inst, realm, argv[4]);
+ 	if (code != 0) {
+ 		printf("Invalid kerberos name\n");
+ 		exit(1);
+ 	}
+ 	code = read_service_key(name, inst, realm, kvno, argv[3], tkey);
+ 	if (code != 0) {
+ 		printf("Can't find key in %s\n", argv[3]);
+ 		exit(1);
+ 	}
+ 	code = afsconf_AddKey(tdir, kvno, tkey);
+ 	if (code) {
+ 	    printf("bos_util: failed to set key, code %d.\n", code);
+ 	    exit(1);
+ 	}
+     }
+ #endif
+     else if (strcmp(argv[1], "delete")==0) {
+ 	long kvno;
+ 	if (argc != 3) {
+ 	    printf("bos_util delete: usage is 'bos_util delete <kvno>\n");
+ 	    exit(1);
+ 	}
+ 	kvno = atoi(argv[2]);
+ 	code = afsconf_DeleteKey(tdir, kvno);
+ 	if (code) {
+ 	    printf("bos_util: failed to delete key %d, (code %d)\n", kvno, code);
+ 	    exit(1);
+ 	}
+     }
+     else if (strcmp(argv[1], "list") == 0) {
+ 	struct afsconf_keys tkeys;
+ 	register int i;
+ 	unsigned char tbuffer[9];
+ 	
+ 	code = afsconf_GetKeys(tdir, &tkeys);
+ 	if (code) {
+ 	    printf("bos_util: failed to get keys, code %d\n", code);
+ 	    exit(1);
+ 	}
+ 	for(i=0;i<tkeys.nkeys;i++) {
+ 	    if (tkeys.key[i].kvno != -1) {
+ 		int count;
+ 		unsigned char x[8];
+ 		memcpy(tbuffer, tkeys.key[i].key, 8);
+ 		tbuffer[8] = 0;
+ 		printf("kvno %4d: key is '%s' '", tkeys.key[i].kvno, tbuffer);
+ 		strcpy(x,(char *)tbuffer);
+ 		for(count=0;count<8;count++)
+ 		    printf("\\%03o",(unsigned char *)x[count]);
+ 		printf("'\n");
+ 	    }
+ 	}
+ 	printf("All done.\n");
+     }
+     else {
+ 	printf("bos_util: unknown operation '%s', type 'bos_util' for assistance\n");
+ 	exit(1);
+     }
+     exit(0);
+ }
Index: openafs/src/bozo/bosint.xg
diff -c openafs/src/bozo/bosint.xg:1.3 openafs/src/bozo/bosint.xg:1.3.6.1
*** openafs/src/bozo/bosint.xg:1.3	Mon Jan 29 12:38:31 2001
--- openafs/src/bozo/bosint.xg	Wed Dec 26 14:30:34 2001
***************
*** 135,141 ****
  ) = 94;
  
  GetCellHost(
!   IN afs_int32 awhich,
    OUT string name<BOZO_BSSIZE>
  ) = 95;
  
--- 135,141 ----
  ) = 94;
  
  GetCellHost(
!   IN afs_uint32 awhich,
    OUT string name<BOZO_BSSIZE>
  ) = 95;
  
Index: openafs/src/bozo/bosoprocs.c
diff -c openafs/src/bozo/bosoprocs.c:1.6.2.2 openafs/src/bozo/bosoprocs.c:1.6.2.5
*** openafs/src/bozo/bosoprocs.c:1.6.2.2	Sat Oct 13 00:21:04 2001
--- openafs/src/bozo/bosoprocs.c	Wed Dec 26 15:50:10 2001
***************
*** 10,16 ****
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/bozo/bosoprocs.c,v 1.6.2.2 2001/10/13 04:21:04 shadow Exp $");
  
  #include <afs/stds.h>
  #include <sys/types.h>
--- 10,16 ----
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/bozo/bosoprocs.c,v 1.6.2.5 2001/12/26 20:50:10 shadow Exp $");
  
  #include <afs/stds.h>
  #include <sys/types.h>
***************
*** 362,367 ****
--- 362,368 ----
      struct afsconf_cell tcell;
      register afs_int32 code;
      char caller[MAXKTCNAMELEN];
+     char clones[MAXHOSTSPERCELL];
      
      if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
        code = BZACCESS;
***************
*** 369,375 ****
      }
      if (DoLogging) bozo_Log("%s is executing SetCellName '%s'\n", caller, aname);
  
!     code = afsconf_GetCellInfo(bozo_confdir, (char *) 0, (char *) 0, &tcell);
      if (code) 
        goto fail;
  
--- 370,376 ----
      }
      if (DoLogging) bozo_Log("%s is executing SetCellName '%s'\n", caller, aname);
  
!     code = afsconf_GetExtendedCellInfo(bozo_confdir, (char *) 0, (char *) 0, &tcell, &clones);
      if (code) 
        goto fail;
  
***************
*** 382,388 ****
      }
  
      strcpy(tcell.name, aname);
!     code = afsconf_SetCellInfo(bozo_confdir, AFSDIR_SERVER_ETC_DIRPATH, &tcell);
  
    fail:
      osi_auditU (acall, BOS_SetCellEvent, code, AUD_STR, aname, AUD_END);
--- 383,389 ----
      }
  
      strcpy(tcell.name, aname);
!     code = afsconf_SetExtendedCellInfo(bozo_confdir, AFSDIR_SERVER_ETC_DIRPATH, &tcell, &clones);
  
    fail:
      osi_auditU (acall, BOS_SetCellEvent, code, AUD_STR, aname, AUD_END);
***************
*** 411,423 ****
  
  BOZO_GetCellHost(acall, awhich, aname)
  struct rx_call *acall;
! afs_int32 awhich;
  char **aname; {
      register afs_int32 code;
      struct afsconf_cell tcell;
      register char *tp;
  
!     code = afsconf_GetCellInfo(bozo_confdir, (char *) 0, (char *) 0, &tcell);
      if (code) goto fail;
  
      if (awhich >= tcell.numServers) {
--- 412,425 ----
  
  BOZO_GetCellHost(acall, awhich, aname)
  struct rx_call *acall;
! afs_uint32 awhich;
  char **aname; {
      register afs_int32 code;
      struct afsconf_cell tcell;
      register char *tp;
+     char clones[MAXHOSTSPERCELL];
  
!     code = afsconf_GetExtendedCellInfo(bozo_confdir, (char *) 0, (char *) 0, &tcell, &clones);
      if (code) goto fail;
  
      if (awhich >= tcell.numServers) {
***************
*** 426,433 ****
      }
      
      tp = tcell.hostName[awhich];
!     *aname = (char *) malloc(strlen(tp)+1);
!     strcpy(*aname, tp);
      goto done;
      
  fail:
--- 428,440 ----
      }
      
      tp = tcell.hostName[awhich];
!     *aname = (char *) malloc(strlen(tp)+3);
!     if (clones[awhich]) {
! 	strcpy(*aname, "[");
! 	strcat(*aname, tp);
! 	strcat(*aname, "]");
!     } else
!         strcpy(*aname, tp);
      goto done;
      
  fail:
***************
*** 446,451 ****
--- 453,459 ----
      afs_int32 which;
      register int i;
      char caller[MAXKTCNAMELEN];
+     char clones[MAXHOSTSPERCELL];
  
      if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
        code = BZACCESS;
***************
*** 454,460 ****
      if (DoLogging) 
        bozo_Log("%s is executing DeleteCellHost '%s'\n", caller, aname);
  
!     code = afsconf_GetCellInfo(bozo_confdir, (char *) 0, (char *) 0, &tcell);
      if (code) 
        goto fail;
  
--- 462,468 ----
      if (DoLogging) 
        bozo_Log("%s is executing DeleteCellHost '%s'\n", caller, aname);
  
!     code = afsconf_GetExtendedCellInfo(bozo_confdir, (char *) 0, (char *) 0, &tcell, &clones);
      if (code) 
        goto fail;
  
***************
*** 473,479 ****
  
      memset(&tcell.hostAddr[which], 0, sizeof(struct sockaddr_in));
      memset(tcell.hostName[which], 0, MAXHOSTCHARS);
!     code = afsconf_SetCellInfo(bozo_confdir, AFSDIR_SERVER_ETC_DIRPATH, &tcell);
  
    fail:
      osi_auditU( acall, BOS_DeleteHostEvent, code, AUD_STR, aname, AUD_END);
--- 481,487 ----
  
      memset(&tcell.hostAddr[which], 0, sizeof(struct sockaddr_in));
      memset(tcell.hostName[which], 0, MAXHOSTCHARS);
!     code = afsconf_SetExtendedCellInfo(bozo_confdir, AFSDIR_SERVER_ETC_DIRPATH, &tcell, &clones);
  
    fail:
      osi_auditU( acall, BOS_DeleteHostEvent, code, AUD_STR, aname, AUD_END);
***************
*** 488,493 ****
--- 496,504 ----
      afs_int32 which;
      register int i;
      char caller[MAXKTCNAMELEN];
+     char clones[MAXHOSTSPERCELL];
+     char *n;
+     char isClone = 0;
  
      if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
        code = BZACCESS;
***************
*** 496,508 ****
      if (DoLogging) 
        bozo_Log("%s is executing AddCellHost '%s'\n", caller, aname);
  
!     code = afsconf_GetCellInfo(bozo_confdir, (char *) 0, (char *) 0, &tcell);
      if (code) 
        goto fail;
  
      which = -1;
      for(i=0;i<tcell.numServers;i++) {
! 	if (strcmp(tcell.hostName[i], aname) == 0) {
  	    which = i;
  	    break;
  	}
--- 507,526 ----
      if (DoLogging) 
        bozo_Log("%s is executing AddCellHost '%s'\n", caller, aname);
  
!     code = afsconf_GetExtendedCellInfo(bozo_confdir, (char *) 0, (char *) 0, &tcell, &clones);
      if (code) 
        goto fail;
  
+     n = aname;
+     if (*n == '[') {
+         *(n + strlen(n) -1) = 0;
+         ++n;
+         isClone = 1;
+     }
+ 
      which = -1;
      for(i=0;i<tcell.numServers;i++) {
! 	if (strcmp(tcell.hostName[i], n) == 0) {
  	    which = i;
  	    break;
  	}
***************
*** 534,541 ****
      }
  
      memset(&tcell.hostAddr[which], 0, sizeof(struct sockaddr_in));
!     strcpy(tcell.hostName[which], aname);
!     code = afsconf_SetCellInfo(bozo_confdir, AFSDIR_SERVER_ETC_DIRPATH, &tcell);
  
    fail:
      osi_auditU(acall, BOS_AddHostEvent, code, AUD_STR, aname, AUD_END);
--- 552,560 ----
      }
  
      memset(&tcell.hostAddr[which], 0, sizeof(struct sockaddr_in));
!     strcpy(tcell.hostName[which], n);
!     clones[which] = isClone;
!     code = afsconf_SetExtendedCellInfo(bozo_confdir, AFSDIR_SERVER_ETC_DIRPATH, &tcell, &clones);
  
    fail:
      osi_auditU(acall, BOS_AddHostEvent, code, AUD_STR, aname, AUD_END);
***************
*** 1160,1166 ****
  
  struct bozo_bosEntryStats bozo_bosEntryStats[] = {
      {NULL, 1,1, 0755, 02}, /* AFSDIR_SERVER_AFS_DIRPATH    */
!     {NULL, 1,1, 0755, 02}, /* AFSDIR_SERVER_ETC_DIRPATH    */
      {NULL, 1,1, 0755, 02}, /* AFSDIR_SERVER_BIN_DIRPATH    */
      {NULL, 1,1, 0755, 02}, /* AFSDIR_SERVER_LOGS_DIRPATH   */
      {NULL, 1,0, 0700, 07}, /* AFSDIR_SERVER_BACKUP_DIRPATH */
--- 1179,1185 ----
  
  struct bozo_bosEntryStats bozo_bosEntryStats[] = {
      {NULL, 1,1, 0755, 02}, /* AFSDIR_SERVER_AFS_DIRPATH    */
!     {NULL, 1,1, 0700, 02}, /* AFSDIR_SERVER_ETC_DIRPATH    */
      {NULL, 1,1, 0755, 02}, /* AFSDIR_SERVER_BIN_DIRPATH    */
      {NULL, 1,1, 0755, 02}, /* AFSDIR_SERVER_LOGS_DIRPATH   */
      {NULL, 1,0, 0700, 07}, /* AFSDIR_SERVER_BACKUP_DIRPATH */
Index: openafs/src/bozo/bosserver.c
diff -c openafs/src/bozo/bosserver.c:1.12.2.2 openafs/src/bozo/bosserver.c:1.12.2.3
*** openafs/src/bozo/bosserver.c:1.12.2.2	Sat Oct 13 00:21:04 2001
--- openafs/src/bozo/bosserver.c	Sun Jan 20 04:06:15 2002
***************
*** 10,16 ****
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/bozo/bosserver.c,v 1.12.2.2 2001/10/13 04:21:04 shadow Exp $");
  
  #include <afs/stds.h>
  #include <sys/types.h>
--- 10,16 ----
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/bozo/bosserver.c,v 1.12.2.3 2002/01/20 09:06:15 shadow Exp $");
  
  #include <afs/stds.h>
  #include <sys/types.h>
***************
*** 670,676 ****
      struct ktc_encryptionKey tkey;
      int i;
      char namebuf[AFSDIR_PATH_MAX];
! 
  #ifdef	AFS_AIX32_ENV
      struct sigaction nsa;
  
--- 670,678 ----
      struct ktc_encryptionKey tkey;
      int i;
      char namebuf[AFSDIR_PATH_MAX];
! #ifndef AFS_NT40_ENV
!     int nofork = 0;
! #endif
  #ifdef	AFS_AIX32_ENV
      struct sigaction nsa;
  
***************
*** 748,753 ****
--- 750,758 ----
  	    DoSyslog = 1;
  	    DoSyslogFacility = atoi(argv[code]+8);
  	}
+ 	else if (strcmp(argv[code], "-nofork")==0) {
+ 	    nofork = 1;
+ 	}
  #endif
  	else if (strcmp(argv[code], "-enable_peer_stats")==0) {
  	    rx_enablePeerRPCStats();
***************
*** 768,773 ****
--- 773,779 ----
  	    printf("Usage: bosserver [-noauth] [-log] "
  		   "[-syslog[=FACILITY]] "
  		   "[-enable_peer_stats] [-enable_process_stats] "
+ 		   "[-nofork] "
  		   "[-help]\n");
  #else
  	    printf("Usage: bosserver [-noauth] [-log] "
***************
*** 811,816 ****
--- 817,823 ----
      /* go into the background and remove our controlling tty */
  
  #ifndef AFS_NT40_ENV
+     if (!nofork)
      background();
  #endif /* ! AFS_NT40_ENV */
  
Index: openafs/src/bucoord/NTMakefile
diff -c openafs/src/bucoord/NTMakefile:1.2.8.1 openafs/src/bucoord/NTMakefile:1.2.8.2
*** openafs/src/bucoord/NTMakefile:1.2.8.1	Wed Sep 19 18:32:48 2001
--- openafs/src/bucoord/NTMakefile	Wed Nov 14 22:30:27 2001
***************
*** 79,85 ****
          $(DESTDIR)\lib\afs\afsusd.lib \
  	$(DESTDIR)\lib\afs\afsprocmgmt.lib \
  	$(DESTDIR)\lib\afs\afspioctl.lib \
! 	$(DESTDIR)\lib\afs\afsreg.lib
  	
  
  $(EXEFILE): $(EXEOBJS) $(EXELIBS)
--- 79,86 ----
          $(DESTDIR)\lib\afs\afsusd.lib \
  	$(DESTDIR)\lib\afs\afsprocmgmt.lib \
  	$(DESTDIR)\lib\afs\afspioctl.lib \
! 	$(DESTDIR)\lib\afs\afsreg.lib \
!      $(DESTDIR)\lib\cm_dns.obj
  	
  
  $(EXEFILE): $(EXEOBJS) $(EXELIBS)
Index: openafs/src/budb/NTMakefile
diff -c openafs/src/budb/NTMakefile:1.2.8.1 openafs/src/budb/NTMakefile:1.2.8.2
*** openafs/src/budb/NTMakefile:1.2.8.1	Wed Sep 19 18:32:49 2001
--- openafs/src/budb/NTMakefile	Wed Nov 14 22:30:28 2001
***************
*** 75,81 ****
  	$(DESTDIR)\lib\afsubik.lib \
  	$(DESTDIR)\lib\afs\afseventlog.lib \
  	$(DESTDIR)\lib\afs\afsreg.lib \
! 	$(DESTDIR)\lib\afs\afsprocmgmt.lib
  
  
  $(EXEFILE): $(EXEOBJS)  $(EXELIBS)
--- 75,82 ----
  	$(DESTDIR)\lib\afsubik.lib \
  	$(DESTDIR)\lib\afs\afseventlog.lib \
  	$(DESTDIR)\lib\afs\afsreg.lib \
! 	$(DESTDIR)\lib\afs\afsprocmgmt.lib \
! 	$(DESTDIR)\lib\cm_dns.obj
  
  
  $(EXEFILE): $(EXEOBJS)  $(EXELIBS)
Index: openafs/src/butc/NTMakefile
diff -c openafs/src/butc/NTMakefile:1.2 openafs/src/butc/NTMakefile:1.2.8.1
*** openafs/src/butc/NTMakefile:1.2	Sat Nov  4 05:04:12 2000
--- openafs/src/butc/NTMakefile	Wed Nov 14 22:30:29 2001
***************
*** 49,55 ****
  	$(DESTDIR)\lib\afs\afsprocmgmt.lib \
  	$(DESTDIR)\lib\afs\afspioctl.lib \
  	$(DESTDIR)\lib\afs\afseventlog.lib \
! 	$(DESTDIR)\lib\afs\afsreg.lib
  
  $(EXEFILE): $(EXEOBJS) $(EXELIBS)
  	$(EXECONLINK)
--- 49,56 ----
  	$(DESTDIR)\lib\afs\afsprocmgmt.lib \
  	$(DESTDIR)\lib\afs\afspioctl.lib \
  	$(DESTDIR)\lib\afs\afseventlog.lib \
! 	$(DESTDIR)\lib\afs\afsreg.lib \
! 	$(DESTDIR)\lib\cm_dns.obj
  
  $(EXEFILE): $(EXEOBJS) $(EXELIBS)
  	$(EXECONLINK)
Index: openafs/src/butc/tcmain.c
diff -c openafs/src/butc/tcmain.c:1.5.2.2 openafs/src/butc/tcmain.c:1.5.2.3
*** openafs/src/butc/tcmain.c:1.5.2.2	Sat Oct 13 00:21:08 2001
--- openafs/src/butc/tcmain.c	Wed Dec 26 15:26:09 2001
***************
*** 10,16 ****
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/butc/tcmain.c,v 1.5.2.2 2001/10/13 04:21:08 shadow Exp $");
  
  #include <sys/types.h>
  #include <sys/stat.h>
--- 10,16 ----
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/butc/tcmain.c,v 1.5.2.3 2001/12/26 20:26:09 shadow Exp $");
  
  #include <sys/types.h>
  #include <sys/stat.h>
***************
*** 355,361 ****
          count = sscanf(line, "%s %s %s %u%s\n",
  		      tcapacity, tfmsize, devName, &aport, trest);
  
! 	if (count == 4) {
  	    if ( atocl(tcapacity, 'K', &capacity) ) {
  	       fprintf(stderr, "tapeconfig: Tape capacity parse error in: %s\n", line);
  	       ERROR_EXIT(-1);
--- 355,361 ----
          count = sscanf(line, "%s %s %s %u%s\n",
  		      tcapacity, tfmsize, devName, &aport, trest);
  
! 	if (count == 4 || count == 5) {
  	    if ( atocl(tcapacity, 'K', &capacity) ) {
  	       fprintf(stderr, "tapeconfig: Tape capacity parse error in: %s\n", line);
  	       ERROR_EXIT(-1);
***************
*** 366,372 ****
  	    }
  	} else {
  	    count = sscanf(line, "%s %u%s\n", devName, &aport, trest);
! 	    if (count == 2) {
  	        capacity = 0x7fffffff;
  		fmSize = 0;
  	    } else {
--- 366,372 ----
  	    }
  	} else {
  	    count = sscanf(line, "%s %u%s\n", devName, &aport, trest);
! 	    if (count == 2 || count == 3) {
  	        capacity = 0x7fffffff;
  		fmSize = 0;
  	    } else {
Index: openafs/src/cf/linux-test2.m4
diff -c openafs/src/cf/linux-test2.m4:1.2.4.1 openafs/src/cf/linux-test2.m4:1.2.4.2
*** openafs/src/cf/linux-test2.m4:1.2.4.1	Sat Oct 13 00:21:11 2001
--- openafs/src/cf/linux-test2.m4	Wed Dec 26 15:14:08 2001
***************
*** 13,18 ****
--- 13,33 ----
  AC_MSG_RESULT($ac_cv_linux_fs_struct_inode_has_i_bytes)
  CPPFLAGS="$save_CPPFLAGS"])
  
+ AC_DEFUN(LINUX_FS_STRUCT_INODE_HAS_I_TRUNCATE_SEM, [
+ AC_MSG_CHECKING(for i_truncate_sem in struct inode)
+ save_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -D__KERNEL__ $CPPFLAGS"
+ AC_CACHE_VAL(ac_cv_linux_fs_struct_inode_has_i_truncate_sem,
+ [
+ AC_TRY_COMPILE(
+ [#include <linux/fs.h>],
+ [struct inode _i;
+ printf("%x\n", _i.i_truncate_sem);], 
+ ac_cv_linux_fs_struct_inode_has_i_truncate_sem=yes,
+ ac_cv_linux_fs_struct_inode_has_i_truncate_sem=no)])
+ AC_MSG_RESULT($ac_cv_linux_fs_struct_inode_has_i_truncate_sem)
+ CPPFLAGS="$save_CPPFLAGS"])
+ 
  AC_DEFUN(LINUX_FS_STRUCT_ADDRESS_SPACE_HAS_PAGE_LOCK, [
  AC_MSG_CHECKING(for page_lock in struct address_space)
  save_CPPFLAGS="$CPPFLAGS"
Index: openafs/src/cf/linux-test4.m4
diff -c openafs/src/cf/linux-test4.m4:1.6.2.1 openafs/src/cf/linux-test4.m4:1.6.2.2
*** openafs/src/cf/linux-test4.m4:1.6.2.1	Sat Oct 13 00:21:11 2001
--- openafs/src/cf/linux-test4.m4	Wed Dec 26 15:15:05 2001
***************
*** 58,78 ****
  AC_MSG_RESULT($ac_cv_linux_fs_struct_inode_has_i_cdev)
  CPPFLAGS="$save_CPPFLAGS"])
  
- AC_DEFUN(LINUX_FS_STRUCT_INODE_HAS_I_TRUNCATE_SEM, [
- AC_MSG_CHECKING(for i_truncate_sem in struct inode)
- save_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -D__KERNEL__ $CPPFLAGS"
- AC_CACHE_VAL(ac_cv_linux_fs_struct_inode_has_i_truncate_sem, 
- [
- AC_TRY_COMPILE(
- [#include <linux/fs.h>],
- [struct inode _inode;
- printf("%d\n", _inode.i_truncate_sem);], 
- ac_cv_linux_fs_struct_inode_has_i_truncate_sem=yes,
- ac_cv_linux_fs_struct_inode_has_i_truncate_sem=no)])
- AC_MSG_RESULT($ac_cv_linux_fs_struct_inode_has_i_truncate_sem)
- CPPFLAGS="$save_CPPFLAGS"])
- 
  AC_DEFUN(LINUX_FS_STRUCT_INODE_HAS_I_DEVICES, [
  AC_MSG_CHECKING(for i_devices in struct inode)
  save_CPPFLAGS="$CPPFLAGS"
--- 58,63 ----
Index: openafs/src/config/Makefile.ppc_darwin_13.in
diff -c openafs/src/config/Makefile.ppc_darwin_13.in:1.4.2.1 openafs/src/config/Makefile.ppc_darwin_13.in:1.4.2.2
*** openafs/src/config/Makefile.ppc_darwin_13.in:1.4.2.1	Thu Sep 20 16:12:33 2001
--- openafs/src/config/Makefile.ppc_darwin_13.in	Sat Nov 10 18:22:55 2001
***************
*** 5,11 ****
  #
  #
  # compilation and link editor flags
! XCFLAGS=-no-precomp
  #MT_CFLAGS=-D_REENTRANT -DAFS_PTHREAD_ENV ${XCFLAGS}
  #MT_CC=cc
  KROOT=
--- 5,11 ----
  #
  #
  # compilation and link editor flags
! XCFLAGS=-no-cpp-precomp
  #MT_CFLAGS=-D_REENTRANT -DAFS_PTHREAD_ENV ${XCFLAGS}
  #MT_CC=cc
  KROOT=
Index: openafs/src/config/Makefile.ppc_darwin_14.in
diff -c /dev/null openafs/src/config/Makefile.ppc_darwin_14.in:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:41 2002
--- openafs/src/config/Makefile.ppc_darwin_14.in	Sat Nov 10 18:22:55 2001
***************
*** 0 ****
--- 1,43 ----
+ # Keep macros within each section in sorted order for clean diff displays.
+ #
+ # AFS_OSTYPE used to indicate suffixes and os specific subdirectories.
+ AFS_OSTYPE = DARWIN
+ #
+ #
+ # compilation and link editor flags
+ XCFLAGS=-no-cpp-precomp
+ #MT_CFLAGS=-D_REENTRANT -DAFS_PTHREAD_ENV ${XCFLAGS}
+ #MT_CC=cc
+ KROOT=
+ KINCLUDES=-I$(KROOT)/System/Library/Frameworks/Kernel.framework/Headers
+ #SHARE_LDFLAGS =
+ LWP_OPTMZ=-O2
+ OPTMZ=-O2
+ DBG=-g
+ REGEX_OBJ=regex.o
+ 
+ 
+ #
+ # libraries
+ XLIBS=@LIB_AFSDB@
+ TXLIBS=
+ #MTLIBS=
+ #XLIBELFA=
+ #XLIBKVM=
+ #
+ SHLIB_SUFFIX=
+ SHLIB_CFLAGS=
+ #
+ # programs
+ AR=ar
+ AS=as
+ CC=cc
+ CP=cp
+ INSTALL=${TOP_SRCDIR}/pinstall/pinstall
+ LEX=lex -l
+ LD= ld
+ LORDER = lorder
+ MV=mv
+ RANLIB=ranlib
+ RM=rm
+ STRIP= strip
Index: openafs/src/config/Makefile.sparc_linux24.in
diff -c /dev/null openafs/src/config/Makefile.sparc_linux24.in:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:41 2002
--- openafs/src/config/Makefile.sparc_linux24.in	Sun Jan 20 03:49:33 2002
***************
*** 0 ****
--- 1,47 ----
+ # Copyright 1998 Transarc Corporation 
+ #
+ # Keep macros within each section in sorted order for clean diff displays.
+ #
+ # AFS_OSTYPE used to indicate suffixes and os specific subdirectories.
+ AFS_OSTYPE = LINUX
+ 
+ # Base directory for linux kernel source. Actually a prefix which is complete
+ # when LINUX_VERS is appended to it.
+ LINUX_SRCDIR = /usr/src/linux-
+ # Default list of Linux kernels to build. Build will run only if all
+ # can be built. To build a different set, specify LINUX_VERS to make.
+ LINUX_VERS = 2.2.14
+ 
+ #
+ # compilation and link editor flags
+ DBG=-g
+ OPTMZ=-O2
+ PAM_CFLAGS = -O2 -Dlinux -DLINUX_PAM -fPIC
+ # Put -O2 here to _ensure_ all Makefiles pick it up.
+ XCFLAGS= -O2
+ MT_CFLAGS=-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}
+ XLDFLAGS=
+ SHARE_LDFLAGS = -shared -Xlinker -x
+ SHLIB_SUFFIX=so
+ SHLIB_CFLAGS=
+ #
+ # libraries
+ MTLIBS=-lpthread
+ TXLIBS= /usr/lib/libncurses.so
+ XLIBS=@LIB_AFSDB@
+ #
+ # programs
+ AR=ar
+ AS=as
+ CP=cp
+ LD=ld   
+ MT_CC=cc
+ MV=mv
+ RANLIB=ranlib
+ RM=rm
+ INSTALL=${TOP_SRCDIR}/pinstall/pinstall
+ #
+ # Other OS specific requirements
+ #
+ YACC = bison -y
+ LEX = flex -l
Index: openafs/src/config/NTDllmap.txt
diff -c openafs/src/config/NTDllmap.txt:1.1 openafs/src/config/NTDllmap.txt:1.1.12.1
*** openafs/src/config/NTDllmap.txt:1.1	Fri Nov  3 21:25:34 2000
--- openafs/src/config/NTDllmap.txt	Sun Jan 20 04:09:15 2002
***************
*** 1,4 ****
! pthread.dll                    0x61000000    0x00080000
  afsrpc.dll                     0x61080000    0x00080000
  afsauthent.dll                 0x61100000    0x00080000
  afspioctl.dll                  0x61200000    0x00080000
--- 1,4 ----
! afspthread.dll                 0x61000000    0x00080000
  afsrpc.dll                     0x61080000    0x00080000
  afsauthent.dll                 0x61100000    0x00080000
  afspioctl.dll                  0x61200000    0x00080000
Index: openafs/src/config/NTMakefile
diff -c openafs/src/config/NTMakefile:1.8 openafs/src/config/NTMakefile:1.8.2.1
*** openafs/src/config/NTMakefile:1.8	Thu Sep  6 23:38:22 2001
--- openafs/src/config/NTMakefile	Wed Nov 14 22:38:52 2001
***************
*** 72,77 ****
--- 72,80 ----
  !	IF (!EXIST($(DESTDIR)\WinInstall\Config))
  		$(MKDIR) $(DESTDIR)\WinInstall\Config
  !	ENDIF
+ !	IF (!EXIST($(DESTDIR)\WinInstall\Dll))
+ 		$(MKDIR) $(DESTDIR)\WinInstall\Dll
+ !	ENDIF
  !	IF (!EXIST($(DESTDIR)\root.server))
  		$(MKDIR) $(DESTDIR)\root.server
  !	ENDIF
***************
*** 114,120 ****
  	$(COPY) $? $@
  	util_cr + $@
  
! $(DESTDIR)\bin\NTLang.bat: NTLang.bat util_cr.exe
  	$(COPY) NTLang.bat $(DESTDIR)\bin
  	util_cr + $(DESTDIR)\bin\NTLang.bat
  
--- 117,123 ----
  	$(COPY) $? $@
  	util_cr + $@
  
! $(DESTDIR)\bin\NTLang.bat: NTLang.bat util_cr.exe 
  	$(COPY) NTLang.bat $(DESTDIR)\bin
  	util_cr + $(DESTDIR)\bin\NTLang.bat
  
***************
*** 131,137 ****
  	- symlink make $(DESTDIR)\doc doc-pathname
  
  
! version: $(DESTDIR)\bin\mkvers.exe NTMakefile.version
  
  NTMakefile.version: NTMakefile.version-CML NTMakefile.version-NOCML
  	$(DEL) NTMakefile.version
--- 134,140 ----
  	- symlink make $(DESTDIR)\doc doc-pathname
  
  
! version: $(DESTDIR)\bin\mkvers.exe NTMakefile.version 
  
  NTMakefile.version: NTMakefile.version-CML NTMakefile.version-NOCML
  	$(DEL) NTMakefile.version
***************
*** 163,169 ****
  
  langsetup: $(DESTDIR)\bin\NTLang.bat
  
! install: idirs $(INCTOOLS) $(INCCOPY) version $(INCFILES) $(DESTDIR)\NTDllmap.txt langsetup 
  
  install9x: install
  
--- 166,172 ----
  
  langsetup: $(DESTDIR)\bin\NTLang.bat
  
! install: idirs $(INCTOOLS) $(INCCOPY) version $(INCFILES) $(DESTDIR)\NTDllmap.txt langsetup
  
  install9x: install
  
Index: openafs/src/config/NTMakefile.i386_nt40
diff -c openafs/src/config/NTMakefile.i386_nt40:1.6.2.1 openafs/src/config/NTMakefile.i386_nt40:1.6.2.3
*** openafs/src/config/NTMakefile.i386_nt40:1.6.2.1	Sat Oct 13 00:21:18 2001
--- openafs/src/config/NTMakefile.i386_nt40	Sun Jan 20 04:09:15 2002
***************
*** 37,46 ****
  !ENDIF
  
  #define used in WinNT/2000 installation and program version display
! AFSPRODUCT_VERSION=1.1.1 a
  CELLNAME_DEFAULT=Your Cell Name
  CELLSERVDB_INSTALL=CellServDB.GrandCentral
  CELLSERVDB_WEB=http://grand.central.org/dl/cellservdb/CellServDB
  
  !IFNDEF TARGETOS
  TARGETOS = WINNT
--- 37,47 ----
  !ENDIF
  
  #define used in WinNT/2000 installation and program version display
! AFSPRODUCT_VERSION=1.2.2 b
  CELLNAME_DEFAULT=Your Cell Name
  CELLSERVDB_INSTALL=CellServDB.GrandCentral
  CELLSERVDB_WEB=http://grand.central.org/dl/cellservdb/CellServDB
+ #NMAKE_DEFINES=-DDEBUG_VERBOSE
  
  !IFNDEF TARGETOS
  TARGETOS = WINNT
***************
*** 156,162 ****
       -DAFS_AFSDB_ENV \
       -DAFS_FREELANCE_CLIENT
  
! afscdefs = $(afscdefs) $(AFSDEV_AUXCDEFINES)
  
  
  # Compiler switches (except include paths and preprocessor defines)
--- 157,163 ----
       -DAFS_AFSDB_ENV \
       -DAFS_FREELANCE_CLIENT
  
! afscdefs = $(afscdefs) $(AFSDEV_AUXCDEFINES) $(NMAKE_DEFINES)
  
  
  # Compiler switches (except include paths and preprocessor defines)
***************
*** 308,317 ****
  CPP2OBJ = $(cc) $(cflags) $(cdebug) $(cvarsdll) $(afscflags) $(afscdefs) /c
  
  # Resource compiler macro
! RC = $(rc) $(rcvars) $(rcflags) $(AFSDEV_AUXRCFLAGS)
  
  # Lex/Yacc macros
! LEX = flex -l
  YACC = bison
  
  # Inference rules for building and installing targets
--- 309,318 ----
  CPP2OBJ = $(cc) $(cflags) $(cdebug) $(cvarsdll) $(afscflags) $(afscdefs) /c
  
  # Resource compiler macro
! RC = $(rc) $(rcvars) $(rcflags) $(AFSDEV_AUXRCFLAGS) /d "AFSPRODUCT_VERSION=\"$(AFSPRODUCT_VERSION)\""
  
  # Lex/Yacc macros
! LEX =1.2.2 a
  YACC = bison
  
  # Inference rules for building and installing targets
Index: openafs/src/config/NTMakefile.i386_win95
diff -c openafs/src/config/NTMakefile.i386_win95:1.3.2.1 openafs/src/config/NTMakefile.i386_win95:1.3.2.3
*** openafs/src/config/NTMakefile.i386_win95:1.3.2.1	Sat Oct 13 00:21:18 2001
--- openafs/src/config/NTMakefile.i386_win95	Sun Jan 20 04:09:15 2002
***************
*** 37,43 ****
  !ENDIF
  
  #define used in Win9x installation and program version display
! AFSPRODUCT_VERSION=1.1.1 a
  CELLNAME_DEFAULT=Your Cell Name
  CELLSERVDB_INSTALL=CellServDB.GrandCentral
  CELLSERVDB_WEB=http://grand.central.org/dl/cellservdb/CellServDB
--- 37,43 ----
  !ENDIF
  
  #define used in Win9x installation and program version display
! AFSPRODUCT_VERSION=1.2.2 b
  CELLNAME_DEFAULT=Your Cell Name
  CELLSERVDB_INSTALL=CellServDB.GrandCentral
  CELLSERVDB_WEB=http://grand.central.org/dl/cellservdb/CellServDB
***************
*** 327,333 ****
  CPP2OBJ = $(cc) $(cflags) $(cdebug) $(cvarsdll) $(afscflags) $(afscdefs) $(afscppdefs) /c
  
  # Resource compiler macro
! RC = $(rc) $(rcvars) $(rcflags) $(AFSDEV_AUXRCFLAGS)
  
  # Lex/Yacc macros
  LEX = flex -l
--- 327,333 ----
  CPP2OBJ = $(cc) $(cflags) $(cdebug) $(cvarsdll) $(afscflags) $(afscdefs) $(afscppdefs) /c
  
  # Resource compiler macro
! RC = $(rc) $(rcvars) $(rcflags) $(AFSDEV_AUXRCFLAGS) /d "AFSPRODUCT_VERSION=\"$(AFSPRODUCT_VERSION)\""
  
  # Lex/Yacc macros
  LEX = flex -l
Index: openafs/src/config/afs_args.h
diff -c openafs/src/config/afs_args.h:1.3.4.1 openafs/src/config/afs_args.h:1.3.4.2
*** openafs/src/config/afs_args.h:1.3.4.1	Sat Oct 13 00:21:18 2001
--- openafs/src/config/afs_args.h	Sun Jan 20 03:21:02 2002
***************
*** 40,45 ****
--- 40,46 ----
  #define	AFSOP_ADDCELL2		 29	/* 2nd add cell protocol interface */
  #define	AFSOP_AFSDB_HANDLER	 30	/* userspace AFSDB lookup handler */
  #define	AFSOP_SET_DYNROOT	 31	/* enable/disable dynroot support */
+ #define	AFSOP_ADDCELLALIAS	 32	/* create alias for existing cell */
  
  /* The range 20-30 is reserved for AFS system offsets in the afs_syscall */
  #define	AFSCALL_PIOCTL		20
Index: openafs/src/config/afs_sysnames.h
diff -c openafs/src/config/afs_sysnames.h:1.14.2.1 openafs/src/config/afs_sysnames.h:1.14.2.3
*** openafs/src/config/afs_sysnames.h:1.14.2.1	Sat Oct 13 00:21:18 2001
--- openafs/src/config/afs_sysnames.h	Sun Jan 20 03:49:33 2002
***************
*** 49,54 ****
--- 49,55 ----
  #define SYS_NAME_ID_mac_mach51		 502
  #define SYS_NAME_ID_ppc_darwin_12        503
  #define SYS_NAME_ID_ppc_darwin_13        504
+ #define SYS_NAME_ID_ppc_darwin_14        505
  
  #define SYS_NAME_ID_next_mach20		 601
  #define SYS_NAME_ID_next_mach30		 602
***************
*** 125,130 ****
--- 126,132 ----
  
  #define SYS_NAME_ID_sparc_linux2	1700
  #define SYS_NAME_ID_sparc_linux22	1701
+ #define SYS_NAME_ID_sparc_linux24	1702
  
  #define SYS_NAME_ID_sparc64_linux2	1800
  #define SYS_NAME_ID_sparc64_linux22	1801
Index: openafs/src/config/param.alpha_dux40.h
diff -c openafs/src/config/param.alpha_dux40.h:1.4 openafs/src/config/param.alpha_dux40.h:1.4.4.1
*** openafs/src/config/param.alpha_dux40.h:1.4	Thu Jul  5 17:41:15 2001
--- openafs/src/config/param.alpha_dux40.h	Wed Nov 14 22:20:55 2001
***************
*** 102,107 ****
--- 102,111 ----
  #include <net/net_globals.h>
  
  #endif	/* ! ASSEMBLER & ! __LANGUAGE_ASSEMBLY__ */
+ 
+ #define memset(A, B, S) bzero(A, S)
+ #define memcpy(B, A, S) bcopy(A, B, S)
+ #define memcmp(A, B, S) bcmp(A, B, S)
  #endif /* _KERNEL */
  
  #endif	/* AFS_PARAM_H */
Index: openafs/src/config/param.alpha_dux50.h
diff -c openafs/src/config/param.alpha_dux50.h:1.2 openafs/src/config/param.alpha_dux50.h:1.2.4.1
*** openafs/src/config/param.alpha_dux50.h:1.2	Thu Jul  5 11:20:18 2001
--- openafs/src/config/param.alpha_dux50.h	Wed Nov 14 22:20:55 2001
***************
*** 103,108 ****
--- 103,112 ----
  #include <net/net_globals.h>
  
  #endif	/* ! ASSEMBLER & ! __LANGUAGE_ASSEMBLY__ */
+ 
+ #define memset(A, B, S) bzero(A, S)
+ #define memcpy(B, A, S) bcopy(A, B, S)
+ #define memcmp(A, B, S) bcmp(A, B, S)
  #endif /* _KERNEL */
  
  #endif	/* AFS_PARAM_H */
Index: openafs/src/config/param.ppc_darwin_14.h
diff -c /dev/null openafs/src/config/param.ppc_darwin_14.h:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:41 2002
--- openafs/src/config/param.ppc_darwin_14.h	Sat Nov 10 18:22:55 2001
***************
*** 0 ****
--- 1,62 ----
+ #ifndef AFS_PARAM_H
+ #define AFS_PARAM_H
+ 
+ #define AFS_ENV                 1
+ #define AFS_64BIT_ENV           1       /* Defines afs_int32 as int, not long. */
+ #define AFS_PPC_ENV 1
+ #define AFS_VFSINCL_ENV 1
+ 
+ #include <afs/afs_sysnames.h>
+ 
+ #define AFS_DARWIN_ENV
+ #define AFS_DARWIN13_ENV
+ #define AFS_DARWIN14_ENV
+ #define AFS_NONFSTRANS
+ #define AFS_SYSCALL             230
+ 
+ /* File system entry (used if mount.h doesn't define MOUNT_AFS */
+ #define AFS_MOUNT_AFS    "afs"
+ 
+ /* Machine / Operating system information */
+ #define sys_ppc_darwin_12   1
+ #define sys_ppc_darwin_13   1
+ #define sys_ppc_darwin_14   1
+ #define SYS_NAME        "ppc_darwin_14"
+ #define SYS_NAME_ID     SYS_NAME_ID_ppc_darwin_14
+ #define AFSBIG_ENDIAN   1
+ #define AFS_HAVE_FFS    1       /* Use system's ffs. */
+ 
+ #define AFS_GCPAGS                1       /* if nonzero, garbage collect PAGs */
+ #define RXK_LISTENER_ENV         1
+ 
+ #ifdef KERNEL
+ #undef MACRO_BEGIN
+ #undef MACRO_END
+ #include <kern/macro_help.h>
+ #define AFS_GLOBAL_SUNLOCK        1
+ #define AFS_VFS34       1       /* What is VFS34??? */
+ #define afsio_iov       uio_iov
+ #define afsio_iovcnt    uio_iovcnt
+ #define afsio_offset    uio_offset
+ #define afsio_seg       uio_segflg
+ #define afsio_resid     uio_resid
+ #define AFS_UIOSYS      UIO_SYSSPACE
+ #define AFS_UIOUSER     UIO_USERSPACE
+ #define AFS_CLBYTES     CLBYTES
+ #define osi_GetTime(x)  microtime(x)
+ #define AFS_KALLOC(x)   kalloc(x)
+ #define AFS_KFREE(x,y)  kfree(x,y)
+ #define v_count         v_usecount
+ #define v_vfsp          v_mount
+ #define vfs_bsize       mnt_stat.f_bsize
+ #define vfs_fsid        mnt_stat.f_fsid
+ #define va_nodeid       va_fileid
+ #define vfs_vnodecovered mnt_vnodecovered
+ #define direct          dirent
+ #define vnode_t         struct vnode
+ 
+ #define VN_RELE(vp)     vrele(((struct vnode *)(vp)))
+ #define VN_HOLD(vp)     VREF(((struct vnode *)(vp)))
+ 
+ #endif
+ #endif /* AFS_PARAM_H */
Index: openafs/src/config/param.ppc_darwin_14_usr.h
diff -c /dev/null openafs/src/config/param.ppc_darwin_14_usr.h:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:41 2002
--- openafs/src/config/param.ppc_darwin_14_usr.h	Sat Nov 10 18:22:55 2001
***************
*** 0 ****
--- 1,50 ----
+ #ifndef AFS_PARAM_H
+ #define AFS_PARAM_H
+ 
+ #define AFS_VFSINCL_ENV 1       /* NOBODY uses this.... */
+ #define AFS_ENV                 1
+ #define AFS_64BIT_ENV           1       /* Defines afs_int32 as int, not long. */
+ #define AFS_PPC_ENV 1
+ 
+ #include <afs/afs_sysnames.h>
+ #define AFS_USERSPACE_ENV
+ #define AFS_USR_DARWIN_ENV
+ #define AFS_USR_DARWIN13_ENV
+ #define AFS_USR_DARWIN14_ENV
+ #define AFS_NONFSTRANS 
+ #define AFS_SYSCALL             230
+ 
+ /* File system entry (used if mount.h doesn't define MOUNT_AFS */
+ #define AFS_MOUNT_AFS    "afs"
+ 
+ /* Machine / Operating system information */
+ #define sys_ppc_darwin_12   1
+ #define sys_ppc_darwin_13   1
+ #define sys_ppc_darwin_14   1
+ #define SYS_NAME        "ppc_darwin_14"
+ #define SYS_NAME_ID     SYS_NAME_ID_ppc_darwin_14
+ #define AFSBIG_ENDIAN   1
+ #define AFS_HAVE_FFS    1       /* Use system's ffs. */
+ 
+ #define AFS_UIOSYS      UIO_SYSSPACE
+ #define AFS_UIOUSER     UIO_USERSPACE
+ 
+ #define AFS_GCPAGS                0       /* if nonzero, garbage collect PAGs */
+ #define RXK_LISTENER_ENV          1
+ 
+ #define AFS_VFS34       1       /* What is VFS34??? */
+ #define afsio_iov       uio_iov
+ #define afsio_iovcnt    uio_iovcnt
+ #define afsio_offset    uio_offset
+ #define afsio_seg       uio_segflg
+ #define afsio_resid     uio_resid
+ #define AFS_UIOSYS      UIO_SYSSPACE
+ #define AFS_UIOUSER     UIO_USERSPACE
+ #define        VATTR_NULL      usr_vattr_null
+ 
+ #define AFS_DIRENT
+ #ifndef CMSERVERPREF
+ #define CMSERVERPREF
+ #endif
+ 
+ #endif /* AFS_PARAM_H */
Index: openafs/src/config/param.sparc_linux24.h
diff -c /dev/null openafs/src/config/param.sparc_linux24.h:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:41 2002
--- openafs/src/config/param.sparc_linux24.h	Sun Jan 20 03:49:33 2002
***************
*** 0 ****
--- 1,89 ----
+ /* Copyright (C) 1998 by Transarc Corporation */
+ 
+ 
+ #ifndef AFS_PARAM_H
+ #define AFS_PARAM_H
+ 
+ /* In user space the AFS_LINUX20_ENV should be sufficient. In the kernel,
+  * it's a judgment call. If something is obviously sparc specific, use that
+  * #define instead. Note that "20" refers to the linux 2.0 kernel. The "2"
+  * in the sysname is the current version of the client. This takes into
+  * account the perferred OS user space configuration as well as the kernel.
+  */
+ 
+ #define AFS_LINUX20_ENV	1
+ #define AFS_LINUX22_ENV	1
+ #define AFS_LINUX24_ENV	1
+ #define AFS_SPARC_LINUX20_ENV	1
+ #define AFS_SPARC_LINUX22_ENV	1
+ #define AFS_SPARC_LINUX24_ENV	1
+ #define AFS_NONFSTRANS 1
+ 
+ #define AFS_MOUNT_AFS "afs"	/* The name of the filesystem type. */
+ #define AFS_SYSCALL 227
+ #define AFS_64BIT_IOPS_ENV  1
+ #define AFS_NAMEI_ENV     1   /* User space interface to file system */
+ 
+ #if defined(__KERNEL__) && !defined(KDUMP_KERNEL)
+ #include <linux/config.h>
+ #ifdef CONFIG_SMP
+ #undef CONFIG_SMP
+ #endif
+ /* Using "AFS_SMP" to map to however many #define's are required to get
+  * MP to compile for Linux
+  */
+ #ifdef AFS_SMP
+ #define CONFIG_SMP
+ #ifndef __SMP__
+ #define __SMP__
+ #endif
+ #define AFS_GLOBAL_SUNLOCK
+ #endif
+ 
+ #if defined(MODULE) && defined(CONFIG_MODVERSIONS)
+ #define MODVERSIONS
+ #include <linux/modversions.h>
+ #endif
+ #endif /* __KERNEL__  && !DUMP_KERNEL*/
+ 
+ #include <afs/afs_sysnames.h>
+ 
+ #define AFS_USERSPACE_IP_ADDR 1
+ #define RXK_LISTENER_ENV 1
+ #define AFS_GCPAGS		0       /* if nonzero, garbage collect PAGs */
+ 
+ /* Machine / Operating system information */
+ #define SYS_NAME	"sparc_linux24"
+ #define SYS_NAME_ID	SYS_NAME_ID_sparc_linux24
+ #define AFSBIG_ENDIAN    1
+ #define AFS_HAVE_FFS        1       /* Use system's ffs. */
+ #define AFS_HAVE_STATVFS    0	/* System doesn't support statvfs */
+ #define AFS_VM_RDWR_ENV	    1	/* read/write implemented via VM */
+ 
+ #ifdef KERNEL
+ #ifndef MIN
+ #define MIN(A,B) ((A) < (B) ? (A) : (B))
+ #endif
+ #ifndef MAX
+ #define MAX(A,B) ((A) > (B) ? (A) : (B))
+ #endif
+ #endif /* KERNEL */
+ 
+ #if defined(AFS_SMP) && defined(CONFIG_MODVERSIONS)
+ /* hack, I don't know what else with theese symbols */
+ #define _do_spin_lock _do_spin_lock_R__ver__do_spin_lock
+ #define _do_spin_unlock _do_spin_unlock_R__ver__do_spin_unlock
+ #define kernel_flag kernel_flag_R__ver_kernel_flag
+ #endif
+ 
+ /* on sparclinux is O_LARGEFILE defined but there is not off64_t,
+    so small hack to get usd_file.c work */
+ #ifndef KERNEL
+ #define __USE_FILE_OFFSET64 1
+ #define __USE_LARGEFILE64 1
+ #if !defined off64_t
+ #define off64_t __off64_t
+ #endif
+ #endif
+ 
+ #endif /* AFS_PARAM_H */
Index: openafs/src/config/param.sparc_linux24_usr.h
diff -c /dev/null openafs/src/config/param.sparc_linux24_usr.h:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:41 2002
--- openafs/src/config/param.sparc_linux24_usr.h	Sun Jan 20 03:49:33 2002
***************
*** 0 ****
--- 1,57 ----
+ /* Copyright (C) 1998 by Transarc Corporation */
+ 
+ 
+ #ifndef AFS_PARAM_H
+ #define AFS_PARAM_H
+ 
+ /* In user space the AFS_LINUX20_ENV should be sufficient. In the kernel,
+  * it's a judgment call. If something is obviously sparc specific, use that
+  * #define instead. Note that "20" refers to the linux 2.0 kernel. The "2"
+  * in the sysname is the current version of the client. This takes into
+  * account the perferred OS user space configuration as well as the kernel.
+  */
+ 
+ #define UKERNEL			1	/* user space kernel */
+ #define AFS_ENV			1
+ #define AFS_USR_LINUX20_ENV	1
+ #define AFS_USR_LINUX22_ENV	1
+ #define AFS_USR_LINUX24_ENV	1
+ #define AFS_NONFSTRANS 1
+ 
+ #define AFS_MOUNT_AFS "afs"	/* The name of the filesystem type. */
+ #define AFS_SYSCALL 227
+ #define AFS_64BIT_IOPS_ENV  1
+ #define AFS_NAMEI_ENV     1   /* User space interface to file system */
+ #include <afs/afs_sysnames.h>
+ 
+ #define AFS_USERSPACE_IP_ADDR 1
+ #define RXK_LISTENER_ENV 1
+ #define AFS_GCPAGS		0       /* if nonzero, garbage collect PAGs */
+ 
+ 
+ /* Machine / Operating system information */
+ #define SYS_NAME	"sparc_linux24"
+ #define SYS_NAME_ID	SYS_NAME_ID_sparc_linux24
+ #define AFSBIG_ENDIAN    1
+ #define AFS_HAVE_FFS        1       /* Use system's ffs. */
+ #define AFS_HAVE_STATVFS    0	/* System doesn't support statvfs */
+ #define AFS_VM_RDWR_ENV	    1	/* read/write implemented via VM */
+ 
+ #define	afsio_iov	uio_iov
+ #define	afsio_iovcnt	uio_iovcnt
+ #define	afsio_offset	uio_offset
+ #define	afsio_seg	uio_segflg
+ #define	afsio_fmode	uio_fmode
+ #define	afsio_resid	uio_resid
+ #define	AFS_UIOSYS	1
+ #define	AFS_UIOUSER	UIO_USERSPACE
+ #define	AFS_CLBYTES	MCLBYTES
+ #define	AFS_MINCHANGE	2
+ #define	VATTR_NULL	usr_vattr_null
+ 
+ #define AFS_DIRENT
+ #ifndef CMSERVERPREF
+ #define CMSERVERPREF
+ #endif
+ 
+ #endif /* AFS_PARAM_H */
Index: openafs/src/config/venus.h
diff -c openafs/src/config/venus.h:1.6 openafs/src/config/venus.h:1.6.4.1
*** openafs/src/config/venus.h:1.6	Tue Jul 10 13:31:07 2001
--- openafs/src/config/venus.h	Sun Jan 20 03:21:02 2002
***************
*** 177,180 ****
--- 177,185 ----
  #define VIOC_PREFETCHTAPE       _VICEIOCTL(66)  /* MR-AFS prefetch from tape */
  #define VIOC_RESIDENCY_CMD      _VICEIOCTL(67)  /* generic MR-AFS cmds */
  #define VIOC_STATISTICS         _VICEIOCTL(68)  /* arla: fetch statistics */
+ 
+ /* Coordinated 'C' pioctl's */
+ #define VIOC_NEWALIAS		_VICEIOCTL2('C', 1) /* create new cell alias */
+ #define VIOC_GETALIAS		_VICEIOCTL2('C', 2) /* get alias info */
+ 
  #endif /* AFS_VENUS_H */
Index: openafs/src/des/Makefile.in
diff -c openafs/src/des/Makefile.in:1.4 openafs/src/des/Makefile.in:1.4.2.1
*** openafs/src/des/Makefile.in:1.4	Fri Sep  7 19:34:56 2001
--- openafs/src/des/Makefile.in	Wed Dec 26 15:11:22 2001
***************
*** 75,81 ****
  
  libdes.a: ${OBJS} AFS_component_version_number.o
  	$(RM) -f libdes.a
! 	ar r libdes.a ${OBJS} AFS_component_version_number.o
  	$(RANLIB) libdes.a
  
  make_ip: make_ip.o misc.o main.o
--- 75,81 ----
  
  libdes.a: ${OBJS} AFS_component_version_number.o
  	$(RM) -f libdes.a
! 	$(AR) crv libdes.a ${OBJS} AFS_component_version_number.o
  	$(RANLIB) libdes.a
  
  make_ip: make_ip.o misc.o main.o
***************
*** 189,195 ****
  	${UKERNELDIR}/des/libdes.a \
  	${UKERNELDIR}/des/des.h \
  	${UKERNELDIR}/des/mit-cpyright.h 
! 	
  ${UKERNELDIR}/des:
  	mkdir -p $?
  
--- 189,195 ----
  	${UKERNELDIR}/des/libdes.a \
  	${UKERNELDIR}/des/des.h \
  	${UKERNELDIR}/des/mit-cpyright.h 
! 
  ${UKERNELDIR}/des:
  	mkdir -p $?
  
Index: openafs/src/des/make_p_table.c
diff -c openafs/src/des/make_p_table.c:1.5 openafs/src/des/make_p_table.c:1.5.4.1
*** openafs/src/des/make_p_table.c:1.5	Thu Jul 12 15:58:34 2001
--- openafs/src/des/make_p_table.c	Sun Jan 20 04:03:14 2002
***************
*** 9,15 ****
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/des/make_p_table.c,v 1.5 2001/07/12 19:58:34 shadow Exp $");
  
  #include <mit-cpyright.h>
  #include <stdio.h>
--- 9,15 ----
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/des/make_p_table.c,v 1.5.4.1 2002/01/20 09:03:14 shadow Exp $");
  
  #include <mit-cpyright.h>
  #include <stdio.h>
***************
*** 58,64 ****
  	for (j = 0; j < 64; j++) {
  	    fprintf(stream,"\n");
  	    for (k = 0; k < 4; k++) {
! 		fprintf(stream,"0x%08lX",P_prime[i][j*4+k]);
  		if ((j == 63) && (k == 3))
  		    fprintf(stream, "}");
  		if ((i == 3) && (j == 63) && (k == 3))
--- 58,64 ----
  	for (j = 0; j < 64; j++) {
  	    fprintf(stream,"\n");
  	    for (k = 0; k < 4; k++) {
! 		fprintf(stream,"0x%08lX",(unsigned long)P_prime[i][j*4+k]);
  		if ((j == 63) && (k == 3))
  		    fprintf(stream, "}");
  		if ((i == 3) && (j == 63) && (k == 3))
Index: openafs/src/export/export.c
diff -c openafs/src/export/export.c:1.4 openafs/src/export/export.c:1.4.4.1
*** openafs/src/export/export.c:1.4	Fri Jul  6 00:19:54 2001
--- openafs/src/export/export.c	Wed Dec 26 15:17:52 2001
***************
*** 13,21 ****
  
  /* Unsafe: conflicts with _KERNEL inclusion of headers below */
  /* #include <afs/param.h> */
! #include <afsconfig.h>
! 
! RCSID("$Header: /data/cvs/openafs/src/export/export.c,v 1.4 2001/07/06 04:19:54 shadow Exp $");
  
  #define _KERNEL
  #include "sys/types.h"
--- 13,20 ----
  
  /* Unsafe: conflicts with _KERNEL inclusion of headers below */
  /* #include <afs/param.h> */
! /* #include <afsconfig.h> */
! /* RCSID("$Header: /data/cvs/openafs/src/export/export.c,v 1.4.4.1 2001/12/26 20:17:52 shadow Exp $"); */
  
  #define _KERNEL
  #include "sys/types.h"
Index: openafs/src/fsint/afsint.xg
diff -c openafs/src/fsint/afsint.xg:1.3.6.1 openafs/src/fsint/afsint.xg:1.3.6.2
*** openafs/src/fsint/afsint.xg:1.3.6.1	Sat Oct 13 00:21:31 2001
--- openafs/src/fsint/afsint.xg	Wed Dec 26 15:58:07 2001
***************
*** 348,356 ****
  StoreData(
    IN  AFSFid *Fid, 
    AFSStoreStatus *InStatus, 
!   afs_int32 Pos, 
!   afs_int32 Length, 
!   afs_int32 FileLength, 
    OUT AFSFetchStatus *OutStatus, 
    AFSVolSync *Sync
  ) split = 133;
--- 348,356 ----
  StoreData(
    IN  AFSFid *Fid, 
    AFSStoreStatus *InStatus, 
!   afs_uint32 Pos, 
!   afs_uint32 Length, 
!   afs_uint32 FileLength, 
    OUT AFSFetchStatus *OutStatus, 
    AFSVolSync *Sync
  ) split = 133;
Index: openafs/src/kauth/Makefile.in
diff -c openafs/src/kauth/Makefile.in:1.5 openafs/src/kauth/Makefile.in:1.5.2.1
*** openafs/src/kauth/Makefile.in:1.5	Mon Sep 10 16:21:06 2001
--- openafs/src/kauth/Makefile.in	Sun Jan 20 03:27:58 2002
***************
*** 200,206 ****
  user.o: user.c ${INCLS} ${TOP_INCDIR}/afs/vice.h
  	${CC} ${CFLAGS} -c user.c
  
! kdb: kdb.o ${INCLS}
  	${CC} ${LDFLAGS} -o kdb kdb.o libkauth.a ${LIBS} ${XLIBS}
  kdb.o: kdb.c AFS_component_version_number.o
  
--- 200,206 ----
  user.o: user.c ${INCLS} ${TOP_INCDIR}/afs/vice.h
  	${CC} ${CFLAGS} -c user.c
  
! kdb: kdb.o ${INCLS} ${LIBS} libkauth.a
  	${CC} ${LDFLAGS} -o kdb kdb.o libkauth.a ${LIBS} ${XLIBS}
  kdb.o: kdb.c AFS_component_version_number.o
  
Index: openafs/src/kauth/kautils.p.h
diff -c openafs/src/kauth/kautils.p.h:1.4.4.1 openafs/src/kauth/kautils.p.h:1.4.4.2
*** openafs/src/kauth/kautils.p.h:1.4.4.1	Wed Sep 19 18:40:34 2001
--- openafs/src/kauth/kautils.p.h	Sun Jan 20 04:09:16 2002
***************
*** 279,284 ****
--- 279,296 ----
    char **reasonP
  );
  
+ extern afs_int32 ka_UserAuthenticateGeneral2 (
+   afs_int32 flags,
+   char *name,
+   char *instance,
+   char *realm,
+   char *password,
+   char *smbname,
+   Date lifetime,
+   afs_int32 *password_expires,
+   afs_int32 spare2,
+   char **reasonP
+ );
  extern afs_int32 ka_UserAuthenticate (
    char *name,
    char *instance,
Index: openafs/src/kauth/user_nt.c
diff -c openafs/src/kauth/user_nt.c:1.6.2.1 openafs/src/kauth/user_nt.c:1.6.2.2
*** openafs/src/kauth/user_nt.c:1.6.2.1	Sat Oct 13 00:21:33 2001
--- openafs/src/kauth/user_nt.c	Wed Nov 21 01:45:49 2001
***************
*** 10,16 ****
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/kauth/user_nt.c,v 1.6.2.1 2001/10/13 04:21:33 shadow Exp $");
  
  #include <afs/stds.h>
  
--- 10,16 ----
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/kauth/user_nt.c,v 1.6.2.2 2001/11/21 06:45:49 shadow Exp $");
  
  #include <afs/stds.h>
  
***************
*** 86,91 ****
--- 86,107 ----
  	afs_int32 spare,
  	char **reasonP)
  {
+   return ka_UserAuthenticateGeneral2(flags, name, instance, realm, password, NULL,
+ 				     lifetime, password_expiresP, spare, reasonP);
+ }
+   
+ afs_int32 ka_UserAuthenticateGeneral2(
+ 	afs_int32 flags,
+ 	char *name,
+ 	char *instance,
+ 	char *realm,
+ 	char *password,
+ 	char *smbname,
+ 	Date lifetime,
+ 	afs_int32 *password_expiresP,
+ 	afs_int32 spare,
+ 	char **reasonP)
+ {
  	int code;
  	struct ktc_encryptionKey key1, key2;
  	char *ticket = NULL;
***************
*** 147,152 ****
--- 163,170 ----
  	strcpy(client.name, name);
  	strcpy(client.instance, instance);
  	strcpy(client.cell, upperRealm);
+ 	if (smbname)
+ 	  strcpy(client.smbname, smbname);
  
  	token.startTime = 0;		/* XXX */
  	token.endTime = expirationTime;
***************
*** 317,324 ****
  
      /* Check and extract server's name */
      if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length) {
! 	return(INTK_BADPW);
!     }
  
      (void) strncpy(s_service, ptr, sizeof(s_service)-1);
      s_service[sizeof(s_service)-1] = '\0';
--- 335,342 ----
  
      /* Check and extract server's name */
      if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length) {
! 		return(INTK_BADPW);
! 	}
  
      (void) strncpy(s_service, ptr, sizeof(s_service)-1);
      s_service[sizeof(s_service)-1] = '\0';
***************
*** 326,333 ****
  
      /* Check and extract server's instance */
      if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length) {
! 	return(INTK_BADPW);
!     }
  
      (void) strncpy(s_instance,ptr, sizeof(s_instance)-1);
      s_instance[sizeof(s_instance)-1] = '\0';
--- 344,351 ----
  
      /* Check and extract server's instance */
      if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length) {
! 		return(INTK_BADPW);
! 	}
  
      (void) strncpy(s_instance,ptr, sizeof(s_instance)-1);
      s_instance[sizeof(s_instance)-1] = '\0';
***************
*** 335,342 ****
  
      /* Check and extract server's realm */
      if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length) {
! 	return(INTK_BADPW);
!     }
  
      (void) strncpy(s_realm,ptr, sizeof(s_realm));
      s_realm[sizeof(s_realm)-1] = '\0';
--- 353,360 ----
  
      /* Check and extract server's realm */
      if ((strlen(ptr) + (ptr - (char *) cip->dat)) > cip->length) {
! 		return(INTK_BADPW);
! 	}
  
      (void) strncpy(s_realm,ptr, sizeof(s_realm));
      s_realm[sizeof(s_realm)-1] = '\0';
***************
*** 351,357 ****
      if ((ticket_len < 0) ||
  	((ticket_len + (ptr - (char *) cip->dat)) > (int) cip->length)) {
  	return(INTK_BADPW);
!     }
  
      /* Check returned server name, instance, and realm fields */
      /*
--- 369,375 ----
      if ((ticket_len < 0) ||
  	((ticket_len + (ptr - (char *) cip->dat)) > (int) cip->length)) {
  	return(INTK_BADPW);
! 	}
  
      /* Check returned server name, instance, and realm fields */
      /*
Index: openafs/src/libadmin/adminutil/NTMakefile
diff -c openafs/src/libadmin/adminutil/NTMakefile:1.2 openafs/src/libadmin/adminutil/NTMakefile:1.2.8.1
*** openafs/src/libadmin/adminutil/NTMakefile:1.2	Sat Nov  4 05:04:46 2000
--- openafs/src/libadmin/adminutil/NTMakefile	Sun Jan 20 04:09:16 2002
***************
*** 105,111 ****
  ILIBDIR = $(DESTDIR)\lib\afs
  
  DLLLIBS =\
! 	$(DESTDIR)\lib\pthread.lib \
  	$(DESTDIR)\lib\afsrpc.lib \
  	$(DESTDIR)\lib\afsauthent.lib
  
--- 105,111 ----
  ILIBDIR = $(DESTDIR)\lib\afs
  
  DLLLIBS =\
! 	$(DESTDIR)\lib\afspthread.lib \
  	$(DESTDIR)\lib\afsrpc.lib \
  	$(DESTDIR)\lib\afsauthent.lib
  
Index: openafs/src/libadmin/bos/NTMakefile
diff -c openafs/src/libadmin/bos/NTMakefile:1.2 openafs/src/libadmin/bos/NTMakefile:1.2.8.1
*** openafs/src/libadmin/bos/NTMakefile:1.2	Sat Nov  4 05:04:48 2000
--- openafs/src/libadmin/bos/NTMakefile	Sun Jan 20 04:09:17 2002
***************
*** 35,41 ****
  	$(DESTDIR)\lib\afs\afsvosadmin.lib \
  	$(DESTDIR)\lib\afsauthent.lib \
  	$(DESTDIR)\lib\afsrpc.lib \
! 	$(DESTDIR)\lib\pthread.lib
  
  $(DLLFILE): $(DLLOBJS) $(DLLLIBS)
  	$(DLLCONLINK) /DEF:bosadmin.def
--- 35,41 ----
  	$(DESTDIR)\lib\afs\afsvosadmin.lib \
  	$(DESTDIR)\lib\afsauthent.lib \
  	$(DESTDIR)\lib\afsrpc.lib \
! 	$(DESTDIR)\lib\afspthread.lib
  
  $(DLLFILE): $(DLLOBJS) $(DLLLIBS)
  	$(DLLCONLINK) /DEF:bosadmin.def
Index: openafs/src/libadmin/cfg/NTMakefile
diff -c openafs/src/libadmin/cfg/NTMakefile:1.2 openafs/src/libadmin/cfg/NTMakefile:1.2.8.1
*** openafs/src/libadmin/cfg/NTMakefile:1.2	Sat Nov  4 05:04:49 2000
--- openafs/src/libadmin/cfg/NTMakefile	Sun Jan 20 04:09:17 2002
***************
*** 40,46 ****
  	afscfgadmin.res
  
  DLLLIBS =\
! 	$(DESTDIR)\lib\pthread.lib \
  	$(DESTDIR)\lib\afs\afsadminutil.lib \
  	$(DESTDIR)\lib\afs\afsbosadmin.lib \
  	$(DESTDIR)\lib\afs\afskasadmin.lib \
--- 40,46 ----
  	afscfgadmin.res
  
  DLLLIBS =\
! 	$(DESTDIR)\lib\afspthread.lib \
  	$(DESTDIR)\lib\afs\afsadminutil.lib \
  	$(DESTDIR)\lib\afs\afsbosadmin.lib \
  	$(DESTDIR)\lib\afs\afskasadmin.lib \
Index: openafs/src/libadmin/cfg/test/NTMakefile
diff -c openafs/src/libadmin/cfg/test/NTMakefile:1.2 openafs/src/libadmin/cfg/test/NTMakefile:1.2.8.1
*** openafs/src/libadmin/cfg/test/NTMakefile:1.2	Sat Nov  4 05:04:51 2000
--- openafs/src/libadmin/cfg/test/NTMakefile	Sun Jan 20 04:09:18 2002
***************
*** 13,19 ****
  test tests: cfgtest.exe
  
  CFGTEST_EXELIBS =\
! 	$(DESTDIR)\lib\pthread.lib \
  	$(DESTDIR)\lib\afs\afsadminutil.lib \
  	$(DESTDIR)\lib\afs\afsclientadmin.lib \
  	$(DESTDIR)\lib\afs\afscfgadmin.lib \
--- 13,19 ----
  test tests: cfgtest.exe
  
  CFGTEST_EXELIBS =\
! 	$(DESTDIR)\lib\afspthread.lib \
  	$(DESTDIR)\lib\afs\afsadminutil.lib \
  	$(DESTDIR)\lib\afs\afsclientadmin.lib \
  	$(DESTDIR)\lib\afs\afscfgadmin.lib \
Index: openafs/src/libadmin/client/NTMakefile
diff -c openafs/src/libadmin/client/NTMakefile:1.2 openafs/src/libadmin/client/NTMakefile:1.2.8.1
*** openafs/src/libadmin/client/NTMakefile:1.2	Sat Nov  4 05:04:51 2000
--- openafs/src/libadmin/client/NTMakefile	Sun Jan 20 04:09:18 2002
***************
*** 26,32 ****
  	$(DESTDIR)\lib\afs\afsadminutil.lib \
  	$(DESTDIR)\lib\afsauthent.lib \
  	$(DESTDIR)\lib\afsrpc.lib \
! 	$(DESTDIR)\lib\pthread.lib
  
  $(DLLFILE): $(DLLOBJS) $(DLLLIBS)
  	$(DLLCONLINK) /DEF:clientadmin.def
--- 26,32 ----
  	$(DESTDIR)\lib\afs\afsadminutil.lib \
  	$(DESTDIR)\lib\afsauthent.lib \
  	$(DESTDIR)\lib\afsrpc.lib \
! 	$(DESTDIR)\lib\afspthread.lib
  
  $(DLLFILE): $(DLLOBJS) $(DLLLIBS)
  	$(DLLCONLINK) /DEF:clientadmin.def
Index: openafs/src/libadmin/kas/NTMakefile
diff -c openafs/src/libadmin/kas/NTMakefile:1.2 openafs/src/libadmin/kas/NTMakefile:1.2.8.1
*** openafs/src/libadmin/kas/NTMakefile:1.2	Sat Nov  4 05:04:52 2000
--- openafs/src/libadmin/kas/NTMakefile	Sun Jan 20 04:09:19 2002
***************
*** 31,37 ****
  	$(DESTDIR)\lib\afs\afsadminutil.lib \
  	$(DESTDIR)\lib\afsauthent.lib \
  	$(DESTDIR)\lib\afsrpc.lib \
! 	$(DESTDIR)\lib\pthread.lib
  
  $(DLLFILE): $(DLLOBJS) $(DLLLIBS)
  	$(DLLCONLINK) /DEF:kasadmin.def
--- 31,37 ----
  	$(DESTDIR)\lib\afs\afsadminutil.lib \
  	$(DESTDIR)\lib\afsauthent.lib \
  	$(DESTDIR)\lib\afsrpc.lib \
! 	$(DESTDIR)\lib\afspthread.lib
  
  $(DLLFILE): $(DLLOBJS) $(DLLLIBS)
  	$(DLLCONLINK) /DEF:kasadmin.def
Index: openafs/src/libadmin/pts/NTMakefile
diff -c openafs/src/libadmin/pts/NTMakefile:1.2 openafs/src/libadmin/pts/NTMakefile:1.2.8.1
*** openafs/src/libadmin/pts/NTMakefile:1.2	Sat Nov  4 05:04:53 2000
--- openafs/src/libadmin/pts/NTMakefile	Sun Jan 20 04:09:19 2002
***************
*** 33,39 ****
  	$(DESTDIR)\lib\afs\afsadminutil.lib \
  	$(DESTDIR)\lib\afsauthent.lib \
  	$(DESTDIR)\lib\afsrpc.lib \
! 	$(DESTDIR)\lib\pthread.lib
  
  $(DLLFILE): $(DLLOBJS) $(DLLLIBS)
  	$(DLLCONLINK) /DEF:ptsadmin.def
--- 33,39 ----
  	$(DESTDIR)\lib\afs\afsadminutil.lib \
  	$(DESTDIR)\lib\afsauthent.lib \
  	$(DESTDIR)\lib\afsrpc.lib \
! 	$(DESTDIR)\lib\afspthread.lib
  
  $(DLLFILE): $(DLLOBJS) $(DLLLIBS)
  	$(DLLCONLINK) /DEF:ptsadmin.def
Index: openafs/src/libadmin/test/NTMakefile
diff -c openafs/src/libadmin/test/NTMakefile:1.2 openafs/src/libadmin/test/NTMakefile:1.2.8.1
*** openafs/src/libadmin/test/NTMakefile:1.2	Sat Nov  4 05:04:58 2000
--- openafs/src/libadmin/test/NTMakefile	Sun Jan 20 04:09:22 2002
***************
*** 13,19 ****
  install test tests: afscp.exe
  
  AFSCP_EXELIBS =\
! 	$(DESTDIR)\lib\pthread.lib \
  	$(DESTDIR)\lib\afs\afsadminutil.lib \
  	$(DESTDIR)\lib\afs\afsclientadmin.lib \
  	$(DESTDIR)\lib\afs\afsbosadmin.lib \
--- 13,19 ----
  install test tests: afscp.exe
  
  AFSCP_EXELIBS =\
! 	$(DESTDIR)\lib\afspthread.lib \
  	$(DESTDIR)\lib\afs\afsadminutil.lib \
  	$(DESTDIR)\lib\afs\afsclientadmin.lib \
  	$(DESTDIR)\lib\afs\afsbosadmin.lib \
Index: openafs/src/libadmin/vos/NTMakefile
diff -c openafs/src/libadmin/vos/NTMakefile:1.2 openafs/src/libadmin/vos/NTMakefile:1.2.8.1
*** openafs/src/libadmin/vos/NTMakefile:1.2	Sat Nov  4 05:05:01 2000
--- openafs/src/libadmin/vos/NTMakefile	Sun Jan 20 04:09:22 2002
***************
*** 50,56 ****
  ILIBDIR = $(DESTDIR)\lib\afs
  
  DLLLIBS =\
! 	$(DESTDIR)\lib\pthread.lib \
  	$(DESTDIR)\lib\afs\afsadminutil.lib \
  	$(DESTDIR)\lib\afsauthent.lib \
  	$(DESTDIR)\lib\afsrpc.lib
--- 50,56 ----
  ILIBDIR = $(DESTDIR)\lib\afs
  
  DLLLIBS =\
! 	$(DESTDIR)\lib\afspthread.lib \
  	$(DESTDIR)\lib\afs\afsadminutil.lib \
  	$(DESTDIR)\lib\afsauthent.lib \
  	$(DESTDIR)\lib\afsrpc.lib
Index: openafs/src/libafs/MakefileProto.IRIX.in
diff -c openafs/src/libafs/MakefileProto.IRIX.in:1.11 openafs/src/libafs/MakefileProto.IRIX.in:1.11.2.4
*** openafs/src/libafs/MakefileProto.IRIX.in:1.11	Mon Sep 10 23:30:49 2001
--- openafs/src/libafs/MakefileProto.IRIX.in	Wed Dec 26 15:19:14 2001
***************
*** 182,188 ****
  IP19_KDEFS = -DIP19 -DEVEREST -DMP -DR4000 \
  	-mips3  -D_PAGESZ=16384 -D_MIPS3_ADDRSPACE -64
  IP20_KDEFS = -DIP20 -DR4000 -DJUMP_WAR -DBADVA_WAR -DTRITON -DUSE_PCI_PIO \
! 		$(KDEFS_32)
  IP21_KDEFS = -DIP21 -DEVEREST -DMP -DTFP -TARG:processor=r8000 $(KDEFS_64)
  IP25_KDEFS = -DIP25 -DEVEREST -DMP -DR10000 -TARG:processor=r10000 $(KDEFS_64)
  IP26_KDEFS = -DIP26 -DTFP -TARG:sync=off -TARG:processor=r8000 $(KDEFS_64)
--- 182,188 ----
  IP19_KDEFS = -DIP19 -DEVEREST -DMP -DR4000 \
  	-mips3  -D_PAGESZ=16384 -D_MIPS3_ADDRSPACE -64
  IP20_KDEFS = -DIP20 -DR4000 -DJUMP_WAR -DBADVA_WAR -DTRITON -DUSE_PCI_PIO \
! 		-D_R5000_CVT_WAR=1 -DCKPT -D_MTEXT_VFS $(KDEFS_32)
  IP21_KDEFS = -DIP21 -DEVEREST -DMP -DTFP -TARG:processor=r8000 $(KDEFS_64)
  IP25_KDEFS = -DIP25 -DEVEREST -DMP -DR10000 -TARG:processor=r10000 $(KDEFS_64)
  IP26_KDEFS = -DIP26 -DTFP -TARG:sync=off -TARG:processor=r8000 $(KDEFS_64)
***************
*** 197,202 ****
--- 197,208 ----
  	-TARG:t5_no_spec_stores $(KDEFS_64)
  IP30_KDEFS = -DIP30 -DR10000 -DMP -DCELL_PREPARE -DBHV_PREPARE \
  	-TARG:processor=r10000 $(KDEFS_64)
+ IP35_KDEFS =  -DIP35 -DR10000 -DMP -DSN -DSN1 -DMAPPED_KERNEL \
+ 	-DLARGE_CPU_COUNT \
+ 	-DPTE_64BIT -DULI -DCKPT -DMIPS4_ISA -DNUMA_BASE \
+ 	-DNUMA_PM  -DNUMA_TBORROW -DNUMA_MIGR_CONTROL -DNUMA_REPLICATION \
+ 	-DNUMA_REPL_CONTROL -DNUMA_SCHED -DCELL_PREPARE -DBHV_PREPARE \
+ 	-TARG:processor=r10000 $(KDEFS_64)
  # Loader flags
  LDFLAGS_64 = -64
  LDFLAGS_32 = -n32
***************
*** 225,231 ****
  <sgi_64>
  PROCESSORS = R10000
  <sgi_65>
! PROCESSORS = IP19 IP20 IP21 IP25 IP26 IP27 IP28 IP30
  <all>
  
  KOBJ = STATIC MODLOAD
--- 231,237 ----
  <sgi_64>
  PROCESSORS = R10000
  <sgi_65>
! PROCESSORS = IP19 IP20 IP21 IP25 IP26 IP27 IP28 IP30 @IRIX_BUILD_IP35@
  <all>
  
  KOBJ = STATIC MODLOAD
***************
*** 349,354 ****
--- 355,361 ----
  		IP27) 	CPU_KDEFS="${IP27_KDEFS}";; \
  		IP28)   CPU_KDEFS="${IP28_KDEFS}";; \
  		IP30)   CPU_KDEFS="${IP30_KDEFS}";; \
+ 		IP35)   CPU_KDEFS="${IP35_KDEFS}";; \
  		*) echo Unknown IP number $$p ; exit 1 ;; \
  		esac ;\
  		case $$t in \
Index: openafs/src/libafs/afs.ppc_darwin_14.plist.in
diff -c openafs/src/libafs/afs.ppc_darwin_14.plist.in:1.1.2.1 openafs/src/libafs/afs.ppc_darwin_14.plist.in:1.1.2.2
*** openafs/src/libafs/afs.ppc_darwin_14.plist.in:1.1.2.1	Wed Sep 12 01:03:53 2001
--- openafs/src/libafs/afs.ppc_darwin_14.plist.in	Sat Nov 10 18:22:57 2001
***************
*** 25,31 ****
  		<key>com.apple.kernel.bsd</key>
  		<string>1.1</string>
  		<key>com.apple.kernel.mach</key>
! 		<string>1.0.0b1</string>
  	</dict>
  </dict>
  </plist>
--- 25,31 ----
  		<key>com.apple.kernel.bsd</key>
  		<string>1.1</string>
  		<key>com.apple.kernel.mach</key>
! 		<string>1.1</string>
  	</dict>
  </dict>
  </plist>
Index: openafs/src/libafs/redhat.sh
diff -c openafs/src/libafs/redhat.sh:1.2 openafs/src/libafs/redhat.sh:removed
*** openafs/src/libafs/redhat.sh:1.2	Mon Apr 23 22:48:32 2001
--- openafs/src/libafs/redhat.sh	Wed Jan 30 16:23:48 2002
***************
*** 1,24 ****
- #!/bin/sh
- # This is a bridge script until we take care of tightly linking Linux inode 
- # internals to AFS vnode internals
- 
- IBYTES=""
- SETATTR=""
- 
- if [ -e $1/include/linux/fs.h ] ; then
- grep i_bytes $1/include/linux/fs.h > /dev/null
- if [ $? = 0 ]; then
- IBYTES="-DSTRUCT_INODE_HAS_I_BYTES=1"
- fi
- 
- grep "extern int inode_setattr" $1/include/linux/fs.h > /dev/null
- if [ $? = 0 ]; then
- SETATTR="-DINODE_SETATTR_NOT_VOID=1"
- fi
- 
- if [ -e $2 ] ; then
- /bin/rm $2
- fi
- echo "KDEFINES = ${IBYTES} ${SETATTR}" > $2
- fi
- exit 0
--- 0 ----
Index: openafs/src/libafsauthent/NTMakefile
diff -c openafs/src/libafsauthent/NTMakefile:1.3.4.1 openafs/src/libafsauthent/NTMakefile:1.3.4.2
*** openafs/src/libafsauthent/NTMakefile:1.3.4.1	Sat Oct 13 00:21:39 2001
--- openafs/src/libafsauthent/NTMakefile	Sun Jan 20 04:09:23 2002
***************
*** 209,217 ****
  
  DLLLIBS =\
  !IF (("$(SYS_NAME)"=="i386_win95" ) || ("$(SYS_NAME)"=="I386_WIN95" ))
! 	$(DESTDIR)\lib\win95\pthread.lib \
  !ELSE
! 	$(DESTDIR)\lib\pthread.lib \
  !ENDIF
  	$(DESTDIR)\lib\afsrpc.lib \
  	$(DESTDIR)\lib\afsdes.lib \
--- 209,217 ----
  
  DLLLIBS =\
  !IF (("$(SYS_NAME)"=="i386_win95" ) || ("$(SYS_NAME)"=="I386_WIN95" ))
! 	$(DESTDIR)\lib\win95\afspthread.lib \
  !ELSE
! 	$(DESTDIR)\lib\afspthread.lib \
  !ENDIF
  	$(DESTDIR)\lib\afsrpc.lib \
  	$(DESTDIR)\lib\afsdes.lib \
Index: openafs/src/libafsauthent/afsauthent.def
diff -c openafs/src/libafsauthent/afsauthent.def:1.1 openafs/src/libafsauthent/afsauthent.def:1.1.12.1
*** openafs/src/libafsauthent/afsauthent.def:1.1	Fri Nov  3 21:28:06 2000
--- openafs/src/libafsauthent/afsauthent.def	Wed Nov 21 01:45:51 2001
***************
*** 77,82 ****
--- 77,83 ----
  	ktc_OldPioctl					@76
  	pioctl						@77
  	rx_Init						@78
+ 	ka_UserAuthenticateGeneral2			@79
  
  
  
Index: openafs/src/libafsrpc/NTMakefile
diff -c openafs/src/libafsrpc/NTMakefile:1.4 openafs/src/libafsrpc/NTMakefile:1.4.4.1
*** openafs/src/libafsrpc/NTMakefile:1.4	Mon Apr 30 03:02:26 2001
--- openafs/src/libafsrpc/NTMakefile	Sun Jan 20 04:09:23 2002
***************
*** 257,265 ****
  
  DLLLIBS =\
  !IF (("$(SYS_NAME)"=="i386_win95" ) || ("$(SYS_NAME)"=="I386_WIN95" ))
! 	$(DESTDIR)\lib\win95\pthread.lib \
  !ELSE
! 	$(DESTDIR)\lib\pthread.lib \
  !ENDIF
  	$(DESTDIR)\lib\afs\afsutil.lib \
  	$(DESTDIR)\lib\afs\afsreg.lib
--- 257,265 ----
  
  DLLLIBS =\
  !IF (("$(SYS_NAME)"=="i386_win95" ) || ("$(SYS_NAME)"=="I386_WIN95" ))
! 	$(DESTDIR)\lib\win95\afspthread.lib \
  !ELSE
! 	$(DESTDIR)\lib\afspthread.lib \
  !ENDIF
  	$(DESTDIR)\lib\afs\afsutil.lib \
  	$(DESTDIR)\lib\afs\afsreg.lib
Index: openafs/src/pam/afs_auth.c
diff -c openafs/src/pam/afs_auth.c:1.7 openafs/src/pam/afs_auth.c:1.7.2.1
*** openafs/src/pam/afs_auth.c:1.7	Fri Sep  7 00:36:44 2001
--- openafs/src/pam/afs_auth.c	Wed Dec 26 15:23:03 2001
***************
*** 10,16 ****
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/pam/afs_auth.c,v 1.7 2001/09/07 04:36:44 shadow Exp $");
  
  #include <security/pam_appl.h>
  #include <security/pam_modules.h>
--- 10,16 ----
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/pam/afs_auth.c,v 1.7.2.1 2001/12/26 20:23:03 shadow Exp $");
  
  #include <security/pam_appl.h>
  #include <security/pam_modules.h>
***************
*** 256,261 ****
--- 256,264 ----
       */
      if (!refresh_token) {
         setpag();
+ #ifdef AFS_KERBEROS_ENV
+        ktc_newpag();
+ #endif
         if (logmask && LOG_MASK(LOG_DEBUG))
  	 syslog(LOG_DEBUG, "New PAG created in pam_authenticate()");
      }
Index: openafs/src/pam/afs_setcred.c
diff -c openafs/src/pam/afs_setcred.c:1.7 openafs/src/pam/afs_setcred.c:1.7.2.2
*** openafs/src/pam/afs_setcred.c:1.7	Fri Sep  7 00:36:44 2001
--- openafs/src/pam/afs_setcred.c	Wed Dec 26 15:23:03 2001
***************
*** 18,24 ****
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/pam/afs_setcred.c,v 1.7 2001/09/07 04:36:44 shadow Exp $");
  
  #include <sys/param.h>
  #include <afs/kautils.h>
--- 18,24 ----
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/pam/afs_setcred.c,v 1.7.2.2 2001/12/26 20:23:03 shadow Exp $");
  
  #include <sys/param.h>
  #include <afs/kautils.h>
***************
*** 45,51 ****
      int origmask;
      int logmask = LOG_UPTO(LOG_INFO);
      int nowarn = 0;
!     int use_first_pass = 0; /* use the password passed in by auth */
      int try_first_pass = 0;
      int got_authtok = 0;
      int ignore_uid  = 0;
--- 45,51 ----
      int origmask;
      int logmask = LOG_UPTO(LOG_INFO);
      int nowarn = 0;
!     int use_first_pass = 1; /* use the password passed in by auth */
      int try_first_pass = 0;
      int got_authtok = 0;
      int ignore_uid  = 0;
***************
*** 262,272 ****
  	  if (logmask && LOG_MASK(LOG_DEBUG))
  	    syslog(LOG_DEBUG, "New PAG created in pam_setcred()");
  	   setpag();
  	}
  
  	if ( flags & PAM_REFRESH_CRED ) {
  	    if (use_klog) {
!                auth_ok = do_klog(user, password, "00:00:01");
  	       ktc_ForgetAllTokens();
  	    } else {
              if ( ka_VerifyUserPassword(
--- 262,275 ----
  	  if (logmask && LOG_MASK(LOG_DEBUG))
  	    syslog(LOG_DEBUG, "New PAG created in pam_setcred()");
  	   setpag();
+ #ifdef AFS_KERBEROS_ENV
+ 	   ktc_newpag();
+ #endif
  	}
  
  	if ( flags & PAM_REFRESH_CRED ) {
  	    if (use_klog) {
!                auth_ok = ! do_klog(user, password, "00:00:01");
  	       ktc_ForgetAllTokens();
  	    } else {
              if ( ka_VerifyUserPassword(
***************
*** 286,292 ****
  	}
  	    
  	if (  flags & PAM_ESTABLISH_CRED ) {
! 	   if (use_klog) auth_ok = do_klog(user, password, NULL);
  	   else {
  	    if ( ka_UserAuthenticateGeneral(
                             KA_USERAUTH_VERSION,
--- 289,295 ----
  	}
  	    
  	if (  flags & PAM_ESTABLISH_CRED ) {
! 	   if (use_klog) auth_ok = ! do_klog(user, password, NULL);
  	   else {
  	    if ( ka_UserAuthenticateGeneral(
                             KA_USERAUTH_VERSION,
***************
*** 327,333 ****
  		    pam_afs_syslog(LOG_ERR, PAMAFS_PASSEXPFAIL, user);
  	    }
  #if defined(AFS_KERBEROS_ENV)
-     	    if (!use_klog) {
                 if (upwd) {
          	if ( chown(ktc_tkt_string(), upwd->pw_uid, upwd->pw_gid) < 0 )
  		    pam_afs_syslog(LOG_ERR, PAMAFS_CHOWNKRB, user);
--- 330,335 ----
***************
*** 336,342 ****
                  if ( errcode != PAM_SUCCESS )
                      pam_afs_syslog(LOG_ERR, PAMAFS_KRBFAIL, user);
  	       }
-     	    }
  #endif
  
  	    RET(PAM_SUCCESS);
--- 338,343 ----
Index: openafs/src/pam/afs_util.c
diff -c openafs/src/pam/afs_util.c:1.5.2.1 openafs/src/pam/afs_util.c:1.5.2.3
*** openafs/src/pam/afs_util.c:1.5.2.1	Sat Oct 13 00:21:44 2001
--- openafs/src/pam/afs_util.c	Sun Jan 20 03:34:44 2002
***************
*** 16,23 ****
  #include <afsconfig.h>
  #include <afs/param.h>
  #include <sys/wait.h>
  
! RCSID("$Header: /data/cvs/openafs/src/pam/afs_util.c,v 1.5.2.1 2001/10/13 04:21:44 shadow Exp $");
  
  #include "afs_util.h"
  
--- 16,24 ----
  #include <afsconfig.h>
  #include <afs/param.h>
  #include <sys/wait.h>
+ #include <limits.h>
  
! RCSID("$Header: /data/cvs/openafs/src/pam/afs_util.c,v 1.5.2.3 2002/01/20 08:34:44 shadow Exp $");
  
  #include "afs_util.h"
  
***************
*** 166,172 ****
  /* get the current AFS pag for the calling process */
  static afs_int32 curpag()
  {
!    gid_t groups[30];
     afs_uint32 g0, g1;
     afs_uint32 h, l, ret;
        
--- 167,173 ----
  /* get the current AFS pag for the calling process */
  static afs_int32 curpag()
  {
!    gid_t groups[NGROUPS_MAX];
     afs_uint32 g0, g1;
     afs_uint32 h, l, ret;
        
Index: openafs/src/procmgmt/NTMakefile
diff -c openafs/src/procmgmt/NTMakefile:1.3 openafs/src/procmgmt/NTMakefile:1.3.4.1
*** openafs/src/procmgmt/NTMakefile:1.3	Mon Apr 30 03:03:25 2001
--- openafs/src/procmgmt/NTMakefile	Sun Jan 20 04:09:24 2002
***************
*** 27,33 ****
  	afsprocmgmt.res
  
  DLLLIBS =\
! 	$(DESTDIR)\lib\pthread.lib \
  	$(DESTDIR)\lib\afs\afsutil.lib
  
  $(DLLFILE): $(DLLOBJS) $(DLLLIBS)
--- 27,33 ----
  	afsprocmgmt.res
  
  DLLLIBS =\
! 	$(DESTDIR)\lib\afspthread.lib \
  	$(DESTDIR)\lib\afs\afsutil.lib
  
  $(DLLFILE): $(DLLOBJS) $(DLLLIBS)
Index: openafs/src/procmgmt/test/NTMakefile
diff -c openafs/src/procmgmt/test/NTMakefile:1.2 openafs/src/procmgmt/test/NTMakefile:1.2.8.1
*** openafs/src/procmgmt/test/NTMakefile:1.2	Sat Nov  4 05:05:22 2000
--- openafs/src/procmgmt/test/NTMakefile	Sun Jan 20 04:09:24 2002
***************
*** 10,16 ****
  test tests: pmgttest.exe
  
  PMGTTEST_EXELIBS =\
! 	$(DESTDIR)\lib\pthread.lib \
  	$(DESTDIR)\lib\afs\afsprocmgmt.lib \
  	$(DESTDIR)\lib\afs\afsutil.lib
  
--- 10,16 ----
  test tests: pmgttest.exe
  
  PMGTTEST_EXELIBS =\
! 	$(DESTDIR)\lib\afspthread.lib \
  	$(DESTDIR)\lib\afs\afsprocmgmt.lib \
  	$(DESTDIR)\lib\afs\afsutil.lib
  
Index: openafs/src/ptserver/ptclient.c
diff -c openafs/src/ptserver/ptclient.c:1.5.2.2 openafs/src/ptserver/ptclient.c:1.5.2.3
*** openafs/src/ptserver/ptclient.c:1.5.2.2	Sat Oct 13 00:21:47 2001
--- openafs/src/ptserver/ptclient.c	Wed Nov 14 22:30:29 2001
***************
*** 10,16 ****
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/ptserver/ptclient.c,v 1.5.2.2 2001/10/13 04:21:47 shadow Exp $");
  
  #ifdef	AFS_AIX32_ENV
  #include <signal.h>
--- 10,16 ----
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/ptserver/ptclient.c,v 1.5.2.3 2001/11/15 03:30:29 shadow Exp $");
  
  #ifdef	AFS_AIX32_ENV
  #include <signal.h>
***************
*** 21,28 ****
  #include <WINNT/afsevent.h>
  #else
  #include <netinet/in.h>
- #endif
  #include <netdb.h>
  #include <stdio.h>
  #include <rx/xdr.h>
  #include <rx/rx.h>
--- 21,28 ----
  #include <WINNT/afsevent.h>
  #else
  #include <netinet/in.h>
  #include <netdb.h>
+ #endif
  #include <stdio.h>
  #include <rx/xdr.h>
  #include <rx/rx.h>
Index: openafs/src/rx/Makefile.in
diff -c openafs/src/rx/Makefile.in:1.4 openafs/src/rx/Makefile.in:1.4.2.1
*** openafs/src/rx/Makefile.in:1.4	Fri Sep  7 19:35:45 2001
--- openafs/src/rx/Makefile.in	Sun Jan 20 03:38:38 2002
***************
*** 85,90 ****
--- 85,92 ----
  
  ${XDROBJS}: xdr.h
  
+ rxperf.o: rx.h rx_null.h rx_globals.h
+ 
  rx_user.o: rx.h rx_user.h
  
  rx_packet.o: rx_packet.c rx_packet.h
***************
*** 104,109 ****
--- 106,114 ----
  xdr_rx.o: xdr.h rx.h
  
  xdr_refernce.o: xdr_refernce.c xdr.h
+ 
+ rxperf: rxperf.o librx.a
+ 	${CC} -o $@ rxperf.o ${LIBS}
  
  librx.a: ${LIBOBJS} RX_component_version_number.o
  	-$(RM) -f $@
Index: openafs/src/rx/rx.c
diff -c openafs/src/rx/rx.c:1.22.2.1 openafs/src/rx/rx.c:1.22.2.7
*** openafs/src/rx/rx.c:1.22.2.1	Sat Oct 13 00:21:49 2001
--- openafs/src/rx/rx.c	Tue Jan 29 14:52:14 2002
***************
*** 16,22 ****
  #include <afs/param.h>
  #endif
  
! RCSID("$Header: /data/cvs/openafs/src/rx/rx.c,v 1.22.2.1 2001/10/13 04:21:49 shadow Exp $");
  
  #ifdef KERNEL
  #include "../afs/sysincludes.h"
--- 16,22 ----
  #include <afs/param.h>
  #endif
  
! RCSID("$Header: /data/cvs/openafs/src/rx/rx.c,v 1.22.2.7 2002/01/29 19:52:14 shadow Exp $");
  
  #ifdef KERNEL
  #include "../afs/sysincludes.h"
***************
*** 897,903 ****
  		     * last reply packets */
  		    rxevent_Cancel(call->delayedAckEvent, call,
  				   RX_CALL_REFCOUNT_DELAY);
! 		    rxi_AckAll((struct rxevent *)0, call, 0);
  		}
  		MUTEX_EXIT(&call->lock);
  	    }
--- 897,908 ----
  		     * last reply packets */
  		    rxevent_Cancel(call->delayedAckEvent, call,
  				   RX_CALL_REFCOUNT_DELAY);
! 		    if (call->state == RX_STATE_PRECALL ||
! 			call->state == RX_STATE_ACTIVE) {
! 			rxi_SendAck(call, 0, 0, 0, 0, RX_ACK_DELAY, 0);
! 		    } else {
! 			rxi_AckAll((struct rxevent *)0, call, 0);
! 		    }
  		}
  		MUTEX_EXIT(&call->lock);
  	    }
***************
*** 1001,1006 ****
--- 1006,1026 ----
      clock_GetTime(&queueTime);
      AFS_RXGLOCK();
      MUTEX_ENTER(&conn->conn_call_lock);
+ 
+     /*
+      * Check if there are others waiting for a new call.
+      * If so, let them go first to avoid starving them.
+      * This is a fairly simple scheme, and might not be
+      * a complete solution for large numbers of waiters.
+      */
+     if (conn->makeCallWaiters) {
+ #ifdef	RX_ENABLE_LOCKS
+ 	CV_WAIT(&conn->conn_call_cv, &conn->conn_call_lock);
+ #else
+ 	osi_rxSleep(conn);
+ #endif
+     }
+ 
      for (;;) {
  	for (i=0; i<RX_MAXCALLS; i++) {
  	    call = conn->call[i];
***************
*** 1015,1021 ****
  	    }
  	    else {
  		call = rxi_NewCall(conn, i);
- 		MUTEX_ENTER(&call->lock);
  		break;
  	    }
  	}
--- 1035,1040 ----
***************
*** 1025,1036 ****
--- 1044,1067 ----
  	MUTEX_ENTER(&conn->conn_data_lock);
  	conn->flags |= RX_CONN_MAKECALL_WAITING;
  	MUTEX_EXIT(&conn->conn_data_lock);
+ 
+ 	conn->makeCallWaiters++;
  #ifdef	RX_ENABLE_LOCKS
  	CV_WAIT(&conn->conn_call_cv, &conn->conn_call_lock);
  #else
  	osi_rxSleep(conn);
  #endif
+ 	conn->makeCallWaiters--;
      }
+     /*
+      * Wake up anyone else who might be giving us a chance to
+      * run (see code above that avoids resource starvation).
+      */
+ #ifdef	RX_ENABLE_LOCKS
+     CV_BROADCAST(&conn->conn_call_cv);
+ #else
+     osi_rxWakeup(conn);
+ #endif
  
      CALL_HOLD(call, RX_CALL_REFCOUNT_BEGIN);
  
***************
*** 1918,1924 ****
  
  /* Allocate a call structure, for the indicated channel of the
   * supplied connection.  The mode and state of the call must be set by
!  * the caller. */
  struct rx_call *rxi_NewCall(conn, channel)
      register struct rx_connection *conn;
      register int channel;
--- 1949,1955 ----
  
  /* Allocate a call structure, for the indicated channel of the
   * supplied connection.  The mode and state of the call must be set by
!  * the caller. Returns the call with mutex locked. */
  struct rx_call *rxi_NewCall(conn, channel)
      register struct rx_connection *conn;
      register int channel;
***************
*** 2000,2006 ****
  	the call number is valid from the last time this channel was used */
      if (*call->callNumber == 0) *call->callNumber = 1;
  
-     MUTEX_EXIT(&call->lock);
      return call;
  }
  
--- 2031,2036 ----
***************
*** 2526,2532 ****
  	}
  	if (!call) {
  	    call = rxi_NewCall(conn, channel);
- 	    MUTEX_ENTER(&call->lock);
  	    *call->callNumber = np->header.callNumber;
  	    call->state = RX_STATE_PRECALL;
  	    clock_GetTime(&call->queueTime);
--- 2556,2561 ----
***************
*** 5263,5277 ****
   * seconds) to ask the client to authenticate itself.  The routine
   * issues a challenge to the client, which is obtained from the
   * security object associated with the connection */
! void rxi_ChallengeEvent(event, conn, dummy)
      struct rxevent *event;
      register struct rx_connection *conn;
!     char *dummy;
  {
      conn->challengeEvent = (struct rxevent *) 0;
      if (RXS_CheckAuthentication(conn->securityObject, conn) != 0) {
  	register struct rx_packet *packet;
  	struct clock when;
  	packet = rxi_AllocPacket(RX_PACKET_CLASS_SPECIAL);
  	if (packet) {
  	    /* If there's no packet available, do this later. */
--- 5292,5331 ----
   * seconds) to ask the client to authenticate itself.  The routine
   * issues a challenge to the client, which is obtained from the
   * security object associated with the connection */
! void rxi_ChallengeEvent(event, conn, atries)
      struct rxevent *event;
      register struct rx_connection *conn;
!     void *atries;
  {
+     int tries = (int) atries;
      conn->challengeEvent = (struct rxevent *) 0;
      if (RXS_CheckAuthentication(conn->securityObject, conn) != 0) {
  	register struct rx_packet *packet;
  	struct clock when;
+ 
+ 	if (tries <= 0) {
+ 	    /* We've failed to authenticate for too long.
+ 	     * Reset any calls waiting for authentication;
+ 	     * they are all in RX_STATE_PRECALL.
+ 	     */
+ 	    int i;
+ 
+ 	    MUTEX_ENTER(&conn->conn_call_lock);
+ 	    for (i=0; i<RX_MAXCALLS; i++) {
+ 		struct rx_call *call = conn->call[i];
+ 		if (call) {
+ 		    MUTEX_ENTER(&call->lock);
+ 		    if (call->state == RX_STATE_PRECALL) {
+ 			rxi_CallError(call, RX_CALL_DEAD);
+ 			rxi_SendCallAbort(call, NULL, 0, 0);
+ 		    }
+ 		    MUTEX_EXIT(&call->lock);
+ 		}
+ 	    }
+ 	    MUTEX_EXIT(&conn->conn_call_lock);
+ 	    return;
+ 	}
+ 
  	packet = rxi_AllocPacket(RX_PACKET_CLASS_SPECIAL);
  	if (packet) {
  	    /* If there's no packet available, do this later. */
***************
*** 5282,5288 ****
  	}
  	clock_GetTime(&when);
  	when.sec += RX_CHALLENGE_TIMEOUT;
! 	conn->challengeEvent = rxevent_Post(&when, rxi_ChallengeEvent, conn, 0);
      }
  }
  
--- 5336,5343 ----
  	}
  	clock_GetTime(&when);
  	when.sec += RX_CHALLENGE_TIMEOUT;
! 	conn->challengeEvent =
! 	    rxevent_Post(&when, rxi_ChallengeEvent, conn, (void *) (tries-1));
      }
  }
  
***************
*** 5297,5303 ****
  {
      if (!conn->challengeEvent) {
  	RXS_CreateChallenge(conn->securityObject, conn);
! 	rxi_ChallengeEvent((struct rxevent *)0, conn, NULL);
      };
  }
  
--- 5352,5358 ----
  {
      if (!conn->challengeEvent) {
  	RXS_CreateChallenge(conn->securityObject, conn);
! 	rxi_ChallengeEvent(NULL, conn, (void *) RX_CHALLENGE_MAXTRIES);
      };
  }
  
Index: openafs/src/rx/rx.h
diff -c openafs/src/rx/rx.h:1.7.2.1 openafs/src/rx/rx.h:1.7.2.5
*** openafs/src/rx/rx.h:1.7.2.1	Sat Oct 13 00:21:49 2001
--- openafs/src/rx/rx.h	Fri Jan 25 22:41:45 2002
***************
*** 506,511 ****
--- 506,512 ----
      u_short secondsUntilDead;	    /* Maximum silence from peer before RX_CALL_DEAD */
      u_short hardDeadTime;	    /* hard max for call execution */
      u_char ackRate;                 /* how many packets between ack requests */
+     u_char makeCallWaiters;         /* how many rx_NewCalls are waiting */
      int nSpecific;		    /* number entries in specific data */
      void **specific;		    /* pointer to connection specific data */
  };
***************
*** 735,743 ****
  #define	RX_ACK_TYPE_ACK		1   /* I have this packet, although I may discard it later */
  
  /* The packet size transmitted for an acknowledge is adjusted to reflect the actual size of the acks array.  This macro defines the size */
! #define rx_AckDataSize(nAcks) (sizeof(struct rx_ackPacket) - RX_MAXACKS + (nAcks))
  
  #define	RX_CHALLENGE_TIMEOUT	2   /* Number of seconds before another authentication request packet is generated */
  
  /* RX error codes.  RX uses error codes from -1 to -64.  Rxgen may use other error codes < -64; user programs are expected to return positive error codes */
  
--- 736,745 ----
  #define	RX_ACK_TYPE_ACK		1   /* I have this packet, although I may discard it later */
  
  /* The packet size transmitted for an acknowledge is adjusted to reflect the actual size of the acks array.  This macro defines the size */
! #define rx_AckDataSize(nAcks) (3 + nAcks + offsetof(struct rx_ackPacket, acks[0]))
  
  #define	RX_CHALLENGE_TIMEOUT	2   /* Number of seconds before another authentication request packet is generated */
+ #define RX_CHALLENGE_MAXTRIES	50  /* Max # of times we resend challenge */
  
  /* RX error codes.  RX uses error codes from -1 to -64.  Rxgen may use other error codes < -64; user programs are expected to return positive error codes */
  
Index: openafs/src/rx/rx_kcommon.c
diff -c openafs/src/rx/rx_kcommon.c:1.9.2.2 openafs/src/rx/rx_kcommon.c:1.9.2.3
*** openafs/src/rx/rx_kcommon.c:1.9.2.2	Sat Oct 13 00:21:49 2001
--- openafs/src/rx/rx_kcommon.c	Wed Jan 23 13:43:47 2002
***************
*** 14,20 ****
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/rx/rx_kcommon.c,v 1.9.2.2 2001/10/13 04:21:49 shadow Exp $");
  
  #include "../rx/rx_kcommon.h"
  
--- 14,20 ----
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/rx/rx_kcommon.c,v 1.9.2.3 2002/01/23 18:43:47 shadow Exp $");
  
  #include "../rx/rx_kcommon.h"
  
***************
*** 1059,1065 ****
  	afs_osi_Wakeup(&afs_termState);
      }
      rxk_ListenerPid = 0;
! #ifdef AFS_LINUX24_ENV
      afs_osi_Wakeup(&rxk_ListenerPid);
  #endif
  #ifdef AFS_SUN5_ENV
--- 1059,1065 ----
  	afs_osi_Wakeup(&afs_termState);
      }
      rxk_ListenerPid = 0;
! #if defined(AFS_LINUX22_ENV) || defined(AFS_SUN5_ENV)
      afs_osi_Wakeup(&rxk_ListenerPid);
  #endif
  #ifdef AFS_SUN5_ENV
Index: openafs/src/rx/rx_packet.c
diff -c openafs/src/rx/rx_packet.c:1.14.2.1 openafs/src/rx/rx_packet.c:1.14.2.3
*** openafs/src/rx/rx_packet.c:1.14.2.1	Sat Oct 13 00:21:49 2001
--- openafs/src/rx/rx_packet.c	Sun Jan 20 00:43:48 2002
***************
*** 14,20 ****
  #include <afs/param.h>
  #endif
  
! RCSID("$Header: /data/cvs/openafs/src/rx/rx_packet.c,v 1.14.2.1 2001/10/13 04:21:49 shadow Exp $");
  
  #ifdef KERNEL
  #if defined(UKERNEL)
--- 14,20 ----
  #include <afs/param.h>
  #endif
  
! RCSID("$Header: /data/cvs/openafs/src/rx/rx_packet.c,v 1.14.2.3 2002/01/20 05:43:48 shadow Exp $");
  
  #ifdef KERNEL
  #if defined(UKERNEL)
Index: openafs/src/rx/rxperf.c
diff -c /dev/null openafs/src/rx/rxperf.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:52 2002
--- openafs/src/rx/rxperf.c	Sun Jan 20 03:38:38 2002
***************
*** 0 ****
--- 1,931 ----
+ /*
+  * Copyright (c) 2000 - 2001 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution
+  *    at such time that OpenAFS documentation is written.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ /* 
+ nn * We are using getopt since we want it to be possible to link to
+  * transarc libs.
+  */
+ 
+ #ifdef RCSID
+ RCSID("$Id: rxperf.c,v 1.1.2.1 2002/01/20 08:38:38 shadow Exp $");
+ #endif
+ 
+ #include <stdarg.h>
+ #include <sys/types.h>
+ #include <sys/time.h>
+ #include <sys/socket.h>
+ #include <sys/file.h>
+ #include <sys/stat.h>
+ #include <netinet/in.h>
+ #include <arpa/inet.h>
+ #include <netdb.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <errno.h>
+ #include <strings.h>
+ #include <assert.h>
+ #include <unistd.h>
+ #include <signal.h>
+ #ifdef HAVE_ERRX
+ #include <err.h> /* not stricly right, but if we have a errx() there
+ 		  * is hopefully a err.h */
+ #endif
+ #include "rx.h"
+ #include "rx_null.h"
+ #include "rx_globals.h"
+ 
+ #if defined(u_int32)
+ #define u_int32_t u_int32
+ #elif defined(hget32)
+ #define u_int32_t afs_uint32
+ #endif
+ 
+ static const char *__progname;
+ 
+ #ifndef HAVE_WARNX
+ static void
+ warnx(const char *fmt, ...)
+ {
+     va_list args;
+ 
+     va_start(args, fmt);
+     fprintf(stderr, "%s: ", __progname);
+     vfprintf (stderr, fmt, args);
+     fprintf(stderr, "\n");
+     va_end(args);
+ }
+ #endif /* !HAVE_WARNX */
+      
+ #ifndef HAVE_ERRX
+ static void
+ errx(int eval, const char *fmt, ...)
+ {
+     va_list args;
+ 
+     va_start(args, fmt);
+     fprintf(stderr, "%s: ", __progname);
+     vfprintf (stderr, fmt, args);
+     fprintf(stderr, "\n");
+     va_end(args);
+ 
+     exit(eval);
+ }
+ #endif /* !HAVE_ERRX */
+ 
+ #ifndef HAVE_WARN
+ static void
+ warn(const char *fmt, ...)
+ {
+     va_list args;
+     char *errstr;
+ 
+     va_start(args, fmt);
+     fprintf(stderr, "%s: ", __progname);
+     vfprintf (stderr, fmt, args);
+ 
+     errstr = strerror(errno);
+     
+     fprintf(stderr, ": %s\n", errstr ? errstr : "unknown error");
+     va_end(args);
+ }
+ #endif /* !HAVE_WARN */
+      
+ #ifndef HAVE_ERR
+ static void
+ err(int eval, const char *fmt, ...)
+ {
+     va_list args;
+     char *errstr;
+ 
+     va_start(args, fmt);
+     fprintf(stderr, "%s: ", __progname);
+     vfprintf (stderr, fmt, args);
+ 
+     errstr = strerror(errno);
+     
+     fprintf(stderr, ": %s\n", errstr ? errstr : "unknown error");
+     va_end(args);
+ 
+     exit(eval);
+ }
+ #endif /* !HAVE_ERR */
+ 
+ #define DEFAULT_PORT 7009	/* To match tcpdump */
+ #define DEFAULT_HOST "127.0.0.1"
+ #define DEFAULT_BYTES 1000000
+ #define RXPERF_BUFSIZE 10000
+ 
+ enum { RX_PERF_VERSION = 3 };
+ enum { RX_SERVER_ID = 147 };
+ enum { RX_PERF_UNKNOWN = -1, RX_PERF_SEND = 0, RX_PERF_RECV = 1, 
+        RX_PERF_RPC=3, RX_PERF_FILE=4 };
+ 
+ enum { RXPERF_MAGIC_COOKIE = 0x4711 };
+ 
+ /*
+  *
+  */
+ 
+ #if DEBUG
+ #define DBFPRINT(x) do { printf x ; } while(0)
+ #else
+ #define DBFPRINT(x)
+ #endif
+ 
+ static void
+ sigusr1 (int foo)
+ {
+     exit (2); /* XXX profiler */
+ }
+ 
+ static void
+ sigint (int foo)
+ {
+     rx_Finalize();
+     exit (2); /* XXX profiler */
+ }
+ 
+ /*
+  *
+  */
+ 
+ static struct timeval timer_start;
+ static struct timeval timer_stop;
+ static int timer_check = 0;
+ 
+ static void
+ start_timer (void)
+ {
+     timer_check++;
+     gettimeofday (&timer_start, NULL);
+ }
+ 
+ /*
+  *
+  */
+ 
+ static void
+ end_and_print_timer (char *str)
+ {
+     long long start_l, stop_l;
+ 
+     timer_check--; 
+     assert (timer_check == 0);
+     gettimeofday(&timer_stop, NULL);
+     start_l = timer_start.tv_sec * 1000000 + timer_start.tv_usec;
+     stop_l = timer_stop.tv_sec * 1000000 + timer_stop.tv_usec;
+     printf("%s:\t%8llu msec\n", str, (stop_l-start_l)/1000);
+ }
+ 
+ /*
+  *
+  */
+ 
+ static u_long
+ str2addr (const char *s)
+ {
+     struct in_addr server;
+     struct hostent *h;
+ 
+ #ifndef INADDR_NONE
+ #define INADDR_NONE 0xffffffff
+ #endif
+     if (inet_addr(s) != INADDR_NONE)
+         return inet_addr(s);
+     h = gethostbyname (s);
+     if (h != NULL) {
+ 	memcpy (&server, h->h_addr_list[0], sizeof(server));
+ 	return server.s_addr;
+     }
+     return 0;
+ }
+ 
+ 
+ /*
+  *
+  */
+ 
+ static void
+ get_sec(int serverp, struct rx_securityClass** sec, int *secureindex)
+ {
+     if (serverp) {
+ 	*sec = rxnull_NewServerSecurityObject();
+ 	*secureindex = 1;
+     } else {
+ 	*sec = rxnull_NewClientSecurityObject();
+ 	*secureindex = 0;
+     }
+ }
+ 
+ /*
+  * process the "RPC" and return the results
+  */
+ 
+ char somebuf[RXPERF_BUFSIZE];
+ 
+ int32_t rxwrite_size = sizeof(somebuf);
+ int32_t rxread_size = sizeof(somebuf);
+ 
+ static int
+ readbytes(struct rx_call *call, int32_t bytes)
+ {
+     int32_t size;
+ 
+     while (bytes > 0) {
+ 	size = rxread_size;
+ 	if (size > bytes)
+ 	    size = bytes;
+ 	if (rx_Read (call, somebuf, size) != size)
+ 	    return 1;
+ 	bytes -= size;
+     }
+     return 0;
+ }
+ 
+ static int
+ sendbytes(struct rx_call *call, int32_t bytes)
+ {
+     int32_t size;
+ 
+     while (bytes > 0) {
+ 	size = rxwrite_size;
+ 	if (size > bytes)
+ 	    size = bytes;
+ 	if (rx_Write (call, somebuf, size) != size)
+ 	    return 1;
+ 	bytes -= size;
+     }
+     return 0;
+ }
+ 
+ 
+ static int32_t
+ rxperf_ExecuteRequest(struct rx_call *call)
+ {
+     int32_t version;
+     int32_t command;
+     u_int32_t bytes;
+     u_int32_t recvb;
+     u_int32_t sendb;
+     u_int32_t data;
+     u_int32_t num;
+     u_int32_t *readwrite;
+     int i;
+     int readp=TRUE;
+ 
+     DBFPRINT(("got a request\n"));
+ 
+     if (rx_Read (call, &version, 4) != 4) {
+ 	warn ("rx_Read failed to read version");
+ 	return -1;
+     }
+ 
+     if (htonl(RX_PERF_VERSION) != version) {
+ 	warnx ("client has wrong version");
+ 	return -1;
+     }
+ 	
+     if (rx_Read (call, &command, 4) != 4) {
+ 	warnx ("rx_Read failed to read command");
+ 	return -1;
+     }
+     command = ntohl(command);
+ 
+     if (rx_Read (call, &data, 4) != 4) {
+ 	warnx ("rx_Read failed to read size");
+ 	return -1;
+     }
+     rxread_size = ntohl(data);
+     if (rxread_size > sizeof(somebuf)) {
+ 	warnx("rxread_size too large %d", rxread_size);
+ 	return -1;
+     }
+ 
+     if (rx_Read (call, &data, 4) != 4) {
+ 	warnx ("rx_Read failed to write size");
+ 	return -1;
+     }
+     rxwrite_size = ntohl(data);
+     if (rxwrite_size > sizeof(somebuf)) {
+ 	warnx("rxwrite_size too large %d", rxwrite_size);
+ 	return -1;
+     }
+ 
+     switch (command) {
+     case RX_PERF_SEND:
+ 	DBFPRINT(("got a send request\n"));
+ 
+ 	if (rx_Read (call, &bytes, 4) != 4) {
+ 	    warnx ("rx_Read failed to read bytes");
+ 	    return -1;
+ 	}
+ 	bytes = ntohl(bytes);
+ 
+ 	DBFPRINT(("reading(%d) ", bytes));
+ 	readbytes(call, bytes);
+ 
+ 	data = htonl(RXPERF_MAGIC_COOKIE);
+ 	if (rx_Write (call, &data, 4) != 4) {
+ 	    warnx ("rx_Write failed when sending back result");
+ 	    return -1;
+ 	}
+ 	DBFPRINT(("done\n"));
+ 
+ 	break;
+     case RX_PERF_RPC:
+ 	DBFPRINT(("got a rpc request, reading commands\n"));
+ 	
+ 	if (rx_Read (call, &recvb, 4) != 4) {
+ 	    warnx ("rx_Read failed to read recvbytes");
+ 	    return -1;
+ 	}
+ 	recvb = ntohl(recvb);
+ 	if (rx_Read (call, &sendb, 4) != 4) {
+ 	    warnx ("rx_Read failed to read sendbytes");
+ 	    return -1;
+ 	}
+ 	sendb = ntohl(sendb);
+ 
+ 	DBFPRINT(("read(%d) ", recvb));
+ 	if (readbytes(call, recvb)) {
+ 	    warnx("readbytes failed");
+ 	    return -1;
+ 	}
+ 	DBFPRINT(("send(%d) ", sendb));
+ 	if (sendbytes(call, sendb)) {
+ 	    warnx("sendbytes failed");
+ 	    return -1;
+ 	}
+ 	
+ 	DBFPRINT(("done\n"));
+ 
+ 	data = htonl(RXPERF_MAGIC_COOKIE);
+ 	if (rx_Write (call, &data, 4) != 4) {
+ 	    warnx ( "rx_Write failed when sending back magic cookie");
+ 	    return -1;
+ 	}
+ 
+ 	break;
+     case RX_PERF_FILE:
+ 	if (rx_Read (call, &data, 4) != 4)
+ 	    errx (1, "failed to read num from client");
+ 	num = ntohl(data);
+ 
+ 	readwrite = malloc(num*sizeof(u_int32_t));
+ 	if(readwrite == NULL)
+ 	    err(1, "malloc");
+ 
+ 	if (rx_Read (call, readwrite, num*sizeof(u_int32_t)) !=
+ 	    num*sizeof(u_int32_t))
+ 	    errx (1, "failed to read recvlist from client");
+ 
+ 	    for(i=0; i < num; i++) {
+ 		if(readwrite[i] == 0) {
+ 		    DBFPRINT(("readp %d", readwrite[i] ));
+ 		    readp = !readp;
+ 		}
+ 
+ 		bytes = ntohl(readwrite[i])*sizeof(u_int32_t);
+ 
+ 		if(readp) {
+ 		    DBFPRINT(("read\n"));
+ 		    readbytes(call, bytes);
+ 		} else {
+ 		    sendbytes(call, bytes);
+ 		    DBFPRINT(("send\n"));
+ 		}
+ 	    }
+ 
+ 	break;
+     case RX_PERF_RECV:
+ 	DBFPRINT(("got a recv request\n"));
+ 
+ 	if (rx_Read (call, &bytes, 4) != 4) {
+ 	    warnx ("rx_Read failed to read bytes");
+ 	    return -1;
+ 	}
+ 	bytes = ntohl(bytes);
+ 
+ 	DBFPRINT(("sending(%d) ", bytes));
+ 	sendbytes(call, bytes);
+ 
+ 	data = htonl(RXPERF_MAGIC_COOKIE);
+ 	if (rx_Write (call, &data, 4) != 4) {
+ 	    warnx ("rx_Write failed when sending back result");
+ 	    return -1;
+ 	}
+ 	DBFPRINT(("done\n"));
+ 
+ 	break;
+     default:
+ 	warnx ("client sent a unsupported command");
+ 	return -1;
+     }
+     DBFPRINT(("done with command\n"));
+ 
+     return 0;
+ }
+ 
+ /*
+  *
+  */
+ 
+ static void
+ do_server (int port)
+ {
+     struct rx_service *service;
+     struct rx_securityClass *secureobj;
+     int secureindex;
+     int ret;
+ 
+     ret = rx_Init (port);
+     if (ret)
+ 	errx (1, "rx_Init failed");
+ 
+     get_sec(1, &secureobj, &secureindex);
+     
+     service = rx_NewService (0,
+ 			     RX_SERVER_ID,
+ 			     "rxperf", 
+ 			     &secureobj, 
+ 			     secureindex, 
+ 			     rxperf_ExecuteRequest);
+     if (service == NULL) 
+ 	errx(1, "Cant create server");
+ 
+     rx_StartServer(1) ;
+     abort();
+ }
+ 
+ /*
+  *
+  */
+ 
+ static void
+ readfile(const char *filename, u_int32_t **readwrite, u_int32_t *size)
+ {
+     FILE *f;
+     u_int32_t len=16;
+     u_int32_t num=0;
+     u_int32_t data;
+     char *ptr;
+     char buf[RXPERF_BUFSIZE];
+ 
+     *readwrite = malloc(sizeof(u_int32_t)*len);
+ 
+     if(*readwrite == NULL)
+ 	err(1, "malloc");
+ 
+     f=fopen(filename, "r");
+     if(f==NULL)
+ 	err(1, "fopen");
+ 
+     while(fgets(buf, sizeof(buf), f) != NULL) {
+ 	if(num >= len) {
+ 	    len=len*2;
+ 	    *readwrite = realloc(*readwrite, len*sizeof(u_int32_t));
+ 	    if(*readwrite == NULL)
+ 		err(1, "realloc");
+ 	}
+ 
+ 	if(*buf != '\n') {
+ 	    data = htonl(strtol (buf, &ptr, 0));
+ 	    if (ptr && ptr == buf)
+ 		errx (1, "can't resolve number of bytes to transfer");
+ 	} else {
+ 	    data = 0;
+ 	}
+ 	
+ 	(*readwrite)[num] =data;
+ 	num++;
+     }
+ 
+     *size = num;
+ 
+     
+     if(fclose(f) == -1)
+ 	err(1, "fclose");
+ }
+ 
+ 
+ /*
+  *
+  */
+ 
+ static void
+ do_client (const char *server, int port, char *filename,
+ 	   int32_t command, int32_t times, 
+ 	   int32_t bytes, int32_t sendtimes, int32_t recvtimes)
+ {
+     struct rx_connection *conn;
+     struct rx_call *call;
+     u_int32_t addr = str2addr(server);
+     struct rx_securityClass *secureobj;
+     int secureindex;
+     int32_t data;
+     int32_t num;
+     int ret;
+     int i;
+     int readp = FALSE;
+     char stamp[1024];
+     u_int32_t size;
+ 
+     u_int32_t *readwrite;
+ 
+     ret = rx_Init (0);
+     if (ret)
+ 	errx (1, "rx_Init failed");
+ 
+     get_sec(0, &secureobj, &secureindex);
+ 
+     conn = rx_NewConnection(addr, 
+ 			    port, 
+ 			    RX_SERVER_ID,
+ 			    secureobj,
+ 			    secureindex);
+     if (conn == NULL)
+ 	errx (1, "failed to contact server");
+ 
+     sprintf (stamp, "send\t%d times\t%d writes\t%d reads", times, sendtimes, recvtimes);
+     start_timer();
+ 
+     for(i=0; i < times ; i++) {
+ 
+ 	DBFPRINT(("starting command "));
+ 
+ 	call = rx_NewCall (conn);
+ 	if (call == NULL)
+ 	    errx (1, "rx_NewCall failed");
+ 	
+ 	data = htonl(RX_PERF_VERSION);
+ 	if (rx_Write (call, &data, 4) != 4)
+ 	    errx (1, "rx_Write failed to send version");
+ 	
+ 	data = htonl(command);
+ 	if (rx_Write (call, &data, 4) != 4)
+ 	    errx (1, "rx_Write failed to send command");
+ 
+ 	data = htonl(rxread_size);
+ 	if (rx_Write (call, &data, 4) != 4)
+ 	    errx (1, "rx_Write failed to send read size");
+ 	data = htonl(rxwrite_size);
+ 	if (rx_Write (call, &data, 4) != 4)
+ 	    errx (1, "rx_Write failed to send write read");
+ 
+ 
+ 	switch (command) {
+ 	case RX_PERF_RECV:
+ 	    DBFPRINT(("command "));
+ 
+ 	    data = htonl (bytes);
+ 	    if (rx_Write (call, &data, 4) != 4)
+ 		errx (1, "rx_Write failed to send size");	    
+ 	    
+ 	    DBFPRINT(("sending(%d) ", bytes));
+ 	    if (readbytes(call, bytes))
+ 		errx(1, "sendbytes");
+ 
+ 	    if (rx_Read (call, &data, 4) != 4)
+ 		errx (1, "failed to read result from server");
+ 	    
+ 	    if (data != htonl(RXPERF_MAGIC_COOKIE))
+ 		warn("server send wrong magic cookie in responce");
+ 
+ 	    DBFPRINT(("done\n"));
+ 
+ 	    break;
+ 	case RX_PERF_SEND:
+ 	    DBFPRINT(("command "));
+ 
+ 	    data = htonl (bytes);
+ 	    if (rx_Write (call, &data, 4) != 4)
+ 		errx (1, "rx_Write failed to send size");	    
+ 	    
+ 	    DBFPRINT(("sending(%d) ", bytes));
+ 	    if (sendbytes(call, bytes))
+ 		errx(1, "sendbytes");
+ 
+ 	    if (rx_Read (call, &data, 4) != 4)
+ 		errx (1, "failed to read result from server");
+ 	    
+ 	    if (data != htonl(RXPERF_MAGIC_COOKIE))
+ 		warn("server send wrong magic cookie in responce");
+ 
+ 	    DBFPRINT(("done\n"));
+ 
+ 	    break;
+ 	case RX_PERF_RPC:
+ 	    DBFPRINT(("commands "));
+ 
+ 	    data = htonl(sendtimes);
+ 	    if (rx_Write(call, &data, 4) != 4)
+ 		errx (1, "rx_Write failed to send command");
+ 	    
+ 	    data = htonl(recvtimes);
+ 	    if (rx_Write (call, &data, 4) != 4)
+ 		errx (1, "rx_Write failed to send command");
+ 	    
+ 	    DBFPRINT(("send(%d) ", sendtimes));
+ 	    sendbytes(call, sendtimes);
+ 	    
+ 	    DBFPRINT(("recv(%d) ", recvtimes));
+ 	    readbytes(call, recvtimes);
+ 	    
+ 	    if (rx_Read (call, &bytes, 4) != 4)
+ 		errx (1, "failed to read result from server");
+ 	    
+ 	    if (bytes != htonl(RXPERF_MAGIC_COOKIE))
+ 		warn("server send wrong magic cookie in responce");
+ 
+ 	    DBFPRINT(("done\n"));
+ 
+ 	    break;
+ 	case RX_PERF_FILE:
+ 	    readfile(filename, &readwrite, &num);
+ 
+ 	    data = htonl(num);
+ 	    if (rx_Write(call, &data, sizeof(data)) != 4)
+ 		errx (1, "rx_Write failed to send size");
+ 
+ 	    if (rx_Write(call, readwrite, num*sizeof(u_int32_t)) 
+ 		!= num*sizeof(u_int32_t))
+ 		errx (1, "rx_Write failed to send list");
+ 
+ 	    for(i=0; i < num; i++) {
+ 		if(readwrite[i] == 0)
+ 		    readp = !readp;
+ 
+ 		size = ntohl(readwrite[i])*sizeof(u_int32_t);
+ 
+ 		if(readp) {
+ 		    readbytes(call, size);
+ 		    DBFPRINT(("read\n"));
+ 		} else {
+ 		    sendbytes(call, size);
+ 		    DBFPRINT(("send\n"));
+ 		}
+ 	    }
+ 	    break;
+ 	default:
+ 	    abort();
+ 	}
+ 
+ 	rx_EndCall (call, 0);
+     }
+ 
+     end_and_print_timer (stamp);
+     DBFPRINT(("done for good\n"));
+ 
+     rx_Finalize();
+ }
+ 
+ static void
+ usage()
+ {
+ #define COMMON ""
+ 
+     fprintf(stderr, "usage: %s client -c send -b <bytes>\n",
+ 	    __progname);
+     fprintf(stderr, "usage: %s client -c recv -b <bytes>\n",
+ 	    __progname);
+     fprintf(stderr, "usage: %s client -c rpc  -S <sendbytes> -R <recvbytes>\n",
+ 	    __progname);
+     fprintf(stderr, "usage: %s client -c file -f filename\n", 
+ 	    __progname);
+     fprintf (stderr, "%s: usage:	common option to the client "
+ 	     "-w <write-bytes> -r <read-bytes> -T times -p port -s server\n",
+ 	     __progname);
+     fprintf(stderr, "usage: %s server -p port\n", __progname);
+ #undef COMMMON
+     exit(1);
+ }
+ 
+ /*
+  * do argument processing and call networking functions
+  */
+ 
+ static int
+ rxperf_server (int argc, char **argv)
+ {
+     int port	   = DEFAULT_PORT;
+     char *ptr;
+     int ch;
+ 
+     while ((ch = getopt(argc, argv, "r:d:p:w:")) != -1) {
+ 	switch (ch) {
+ 	case 'd':
+ #ifdef RXDEBUG
+ 	    rx_debugFile = fopen(optarg, "w");
+ 	    if (rx_debugFile == NULL)
+ 		err(1, "fopen %s", optarg);
+ #else
+ 	    errx(1, "compiled without RXDEBUG");
+ #endif
+ 	    break;
+ 	case 'r':
+ 	    rxread_size = strtol(optarg, &ptr, 0);
+ 	    if (ptr != 0 && ptr[0] != '\0')
+ 		errx (1, "can't resolve readsize");
+ 	    if (rxread_size > sizeof(somebuf))
+ 	      errx(1, "%d > sizeof(somebuf) (%d)",
+ 		   rxread_size, sizeof(somebuf));
+ 	    break;
+ 	case 'p':
+ 	    port = strtol(optarg, &ptr, 0);
+ 	    if (ptr != 0 && ptr[0] != '\0')
+ 		errx (1, "can't resolve portname");
+ 	    break;
+ 	case 'w':
+ 	    rxwrite_size = strtol(optarg, &ptr, 0);
+ 	    if (ptr != 0 && ptr[0] != '\0')
+ 		errx (1, "can't resolve writesize");
+ 	    if (rxwrite_size > sizeof(somebuf))
+ 		errx(1, "%d > sizeof(somebuf) (%d)",
+ 		     rxwrite_size, sizeof(somebuf));
+ 	    break;
+ 	default:
+ 	    usage();
+ 	}
+     }
+ 
+     if (optind != argc)
+ 	usage();
+     
+     do_server (htons(port));
+ 
+     return 0;
+ }
+ 
+ /*
+  * do argument processing and call networking functions
+  */
+ 
+ static int
+ rxperf_client (int argc, char **argv)
+ {
+     char *host	   = DEFAULT_HOST;
+     int bytes	   = DEFAULT_BYTES;
+     int port	   = DEFAULT_PORT;
+     char *filename = NULL;
+     int32_t cmd;
+     int sendtimes = 3;
+     int recvtimes = 30;
+     int times = 100;
+     char *ptr;
+     int ch;
+ 
+     cmd = RX_PERF_UNKNOWN;
+     
+     while ((ch  = getopt(argc, argv, "T:S:R:b:c:d:p:r:s:w:f:")) != -1) {
+ 	switch (ch) {
+ 	case 'b':
+ 	    bytes = strtol (optarg, &ptr, 0);
+ 	    if (ptr && *ptr != '\0')
+ 		errx (1, "can't resolve number of bytes to transfer");
+ 	    break;
+ 	case 'c':
+ 	    if (strcasecmp(optarg, "send") == 0)
+ 	      cmd = RX_PERF_SEND;
+ 	    else if (strcasecmp(optarg, "recv") == 0)
+ 		cmd = RX_PERF_RECV;
+ 	    else if (strcasecmp(optarg, "rpc") == 0)
+ 		cmd = RX_PERF_RPC;
+ 	    else if (strcasecmp(optarg, "file") == 0)
+ 		cmd = RX_PERF_FILE;
+ 	    else
+ 		errx(1, "unknown command %s", optarg);
+ 	    break;
+ 	case 'd':
+ #ifdef RXDEBUG
+ 	    rx_debugFile = fopen(optarg, "w");
+ 	    if (rx_debugFile == NULL)
+ 		err(1, "fopen %s", optarg);
+ #else
+ 	    errx(1, "compiled without RXDEBUG");
+ #endif
+ 	    break;
+ 	case 'p':
+ 	    port = strtol(optarg, &ptr, 0);
+ 	    if (ptr != 0 && ptr[0] != '\0')
+ 		errx (1, "can't resolve portname");
+ 	    break;
+ 	case 'r':
+ 	    rxread_size = strtol(optarg, &ptr, 0);
+ 	    if (ptr != 0 && ptr[0] != '\0')
+ 		errx (1, "can't resolve readsize");
+ 	    if (rxread_size > sizeof(somebuf))
+ 		errx(1, "%d > sizeof(somebuf) (%d)",
+ 		     rxread_size, sizeof(somebuf));
+ 	    break;
+ 	case 's':
+ 	    host = strdup(optarg);
+ 	    if (host == NULL)
+ 		err(1, "strdup");
+ 	    break;
+ 	case 'w':
+ 	    rxwrite_size = strtol(optarg, &ptr, 0);
+ 	    if (ptr != 0 && ptr[0] != '\0')
+ 		errx (1, "can't resolve writesize");
+ 	    if (rxwrite_size > sizeof(somebuf))
+ 		errx(1, "%d > sizeof(somebuf) (%d)",
+ 		     rxwrite_size, sizeof(somebuf));
+ 	    break;
+ 	case 'T':
+ 	    times = strtol (optarg, &ptr, 0);
+ 	    if (ptr && *ptr != '\0')
+ 		errx (1, "can't resolve number of bytes to transfer");
+ 	    break;
+ 	case 'S':
+ 	    sendtimes = strtol (optarg, &ptr, 0);
+ 	    if (ptr && *ptr != '\0')
+ 		errx (1, "can't resolve number of bytes to transfer");
+ 	    break;
+ 	case 'R':
+ 	    recvtimes = strtol (optarg, &ptr, 0);
+ 	    if (ptr && *ptr != '\0')
+ 		errx (1, "can't resolve number of bytes to transfer");
+ 	    break;
+ 	case 'f':
+ 	    filename = optarg;
+ 	    break;
+ 	default:
+ 	    usage();
+ 	}
+     }
+ 
+     if (optind != argc)
+ 	usage();
+     
+     if (cmd == RX_PERF_UNKNOWN)
+ 	errx(1, "no command given to the client");
+     
+     do_client(host, htons(port), filename, cmd, times, bytes, 
+ 	      sendtimes, recvtimes);
+     
+     return 0;
+ }
+ 
+ /*
+  * setup world and call cmd
+  */
+ 
+ int
+ main(int argc, char **argv)
+ {
+     PROCESS pid;
+ 
+     __progname = strrchr(argv[0], '/');
+     if (__progname == 0)
+       __progname = argv[0];
+ 
+     signal (SIGUSR1, sigusr1);
+     signal (SIGINT, sigint);
+ 
+     LWP_InitializeProcessSupport (LWP_NORMAL_PRIORITY, &pid);
+     
+     memset (somebuf, 0, sizeof(somebuf));
+ 
+     if (argc >= 2 && strcmp(argv[1], "server") == 0)
+ 	rxperf_server(argc - 1, argv + 1);
+     else if (argc >= 2 && strcmp(argv[1], "client") == 0)
+ 	rxperf_client(argc - 1, argv + 1);
+     else
+ 	usage();
+     return 0;
+ }
+ 
Index: openafs/src/rx/LINUX/rx_kmutex.h
diff -c openafs/src/rx/LINUX/rx_kmutex.h:1.4 openafs/src/rx/LINUX/rx_kmutex.h:1.4.4.1
*** openafs/src/rx/LINUX/rx_kmutex.h:1.4	Sat Jun 23 12:36:18 2001
--- openafs/src/rx/LINUX/rx_kmutex.h	Wed Jan 30 16:15:36 2002
***************
*** 106,121 ****
--- 106,133 ----
  static inline int CV_WAIT(afs_kcondvar_t *cv, afs_kmutex_t *l)
  {
      int isAFSGlocked = ISAFS_GLOCK(); 
+     sigset_t saved_set;
  
      if (isAFSGlocked) AFS_GUNLOCK();
      MUTEX_EXIT(l);
  
+     spin_lock_irq(&current->sigmask_lock);
+     saved_set = current->blocked;
+     sigfillset(&current->blocked);
+     recalc_sigpending(current);
+     spin_unlock_irq(&current->sigmask_lock);
+ 
  #if defined(AFS_LINUX24_ENV)
      interruptible_sleep_on((wait_queue_head_t *)cv);
  #else
      interruptible_sleep_on((struct wait_queue**)cv);
  #endif
  
+     spin_lock_irq(&current->sigmask_lock);
+     current->blocked = saved_set;
+     recalc_sigpending(current);
+     spin_unlock_irq(&current->sigmask_lock);
+ 
      MUTEX_ENTER(l);
      if (isAFSGlocked) AFS_GLOCK();
  
***************
*** 126,141 ****
--- 138,165 ----
  {
      int isAFSGlocked = ISAFS_GLOCK();
      long t = waittime * HZ / 1000;
+     sigset_t saved_set;
  
      if (isAFSGlocked) AFS_GUNLOCK();
      MUTEX_EXIT(l);
      
+     spin_lock_irq(&current->sigmask_lock);
+     saved_set = current->blocked;
+     sigfillset(&current->blocked);
+     recalc_sigpending(current);
+     spin_unlock_irq(&current->sigmask_lock);
+ 
  #if defined(AFS_LINUX24_ENV)
      t = interruptible_sleep_on_timeout((wait_queue_head_t *)cv, t);
  #else
      t = interruptible_sleep_on_timeout((struct wait_queue**)cv, t);
  #endif
      
+     spin_lock_irq(&current->sigmask_lock);
+     current->blocked = saved_set;
+     recalc_sigpending(current);
+     spin_unlock_irq(&current->sigmask_lock);
+ 
      MUTEX_ENTER(l);
      if (isAFSGlocked) AFS_GLOCK();
  
Index: openafs/src/rx/LINUX/rx_knet.c
diff -c openafs/src/rx/LINUX/rx_knet.c:1.6 openafs/src/rx/LINUX/rx_knet.c:1.6.4.2
*** openafs/src/rx/LINUX/rx_knet.c:1.6	Thu Jul 12 15:59:00 2001
--- openafs/src/rx/LINUX/rx_knet.c	Wed Jan 23 13:46:37 2002
***************
*** 15,21 ****
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/rx/LINUX/rx_knet.c,v 1.6 2001/07/12 19:59:00 shadow Exp $");
  
  #ifdef AFS_LINUX22_ENV
  #include "../rx/rx_kcommon.h"
--- 15,21 ----
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/rx/LINUX/rx_knet.c,v 1.6.4.2 2002/01/23 18:46:37 shadow Exp $");
  
  #ifdef AFS_LINUX22_ENV
  #include "../rx/rx_kcommon.h"
***************
*** 178,190 ****
      extern int (*sys_killp)();
      extern int rxk_ListenerPid;
  
!     if (rxk_ListenerPid) {
  	(void) (*sys_killp)(rxk_ListenerPid, 9);
! #ifdef AFS_LINUX24_ENV
! 	afs_osi_Sleep(&rxk_ListenerPid);
! #else
! 	rxk_ListenerPid = 0;
! #endif
      }
      sock_release(rx_socket);
      rx_socket = NULL;
--- 178,186 ----
      extern int (*sys_killp)();
      extern int rxk_ListenerPid;
  
!     while (rxk_ListenerPid) {
  	(void) (*sys_killp)(rxk_ListenerPid, 9);
! 	afs_osi_Sleep(&rxk_ListenerPid); 
      }
      sock_release(rx_socket);
      rx_socket = NULL;
Index: openafs/src/rx/SOLARIS/rx_knet.c
diff -c openafs/src/rx/SOLARIS/rx_knet.c:1.6.2.1 openafs/src/rx/SOLARIS/rx_knet.c:1.6.2.3
*** openafs/src/rx/SOLARIS/rx_knet.c:1.6.2.1	Sat Oct 13 00:21:51 2001
--- openafs/src/rx/SOLARIS/rx_knet.c	Thu Jan 24 05:47:24 2002
***************
*** 10,16 ****
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/rx/SOLARIS/rx_knet.c,v 1.6.2.1 2001/10/13 04:21:51 shadow Exp $");
  
  #ifdef AFS_SUN5_ENV
  #include "../rx/rx_kcommon.h"
--- 10,16 ----
  #include <afsconfig.h>
  #include "../afs/param.h"
  
! RCSID("$Header: /data/cvs/openafs/src/rx/SOLARIS/rx_knet.c,v 1.6.2.3 2002/01/24 10:47:24 shadow Exp $");
  
  #ifdef AFS_SUN5_ENV
  #include "../rx/rx_kcommon.h"
***************
*** 281,288 ****
      vnode_t *vp = SOTOV(so);
  
      AFS_STATCNT(osi_FreeSocket);
!     if (rxk_ListenerPid)
  	kill(rxk_ListenerPid, SIGUSR1);
      return 0;
  }
  
--- 281,290 ----
      vnode_t *vp = SOTOV(so);
  
      AFS_STATCNT(osi_FreeSocket);
!     while (rxk_ListenerPid) {
  	kill(rxk_ListenerPid, SIGUSR1);
+ 	afs_osi_Sleep(&rxk_ListenerPid);
+     }
      return 0;
  }
  
***************
*** 512,519 ****
      TIUSER *udp_tiptr = (TIUSER *) asocket;    
      AFS_STATCNT(osi_FreeSocket);
  
!     if (rxk_ListenerPid)
  	kill(rxk_ListenerPid, SIGUSR1);
      return 0;
  }
  
--- 514,523 ----
      TIUSER *udp_tiptr = (TIUSER *) asocket;    
      AFS_STATCNT(osi_FreeSocket);
  
!     if (rxk_ListenerPid) {
  	kill(rxk_ListenerPid, SIGUSR1);
+ 	afs_osi_Sleep(&rxk_ListenerPid);
+     }
      return 0;
  }
  
Index: openafs/src/rxkad/rxkad.p.h
diff -c openafs/src/rxkad/rxkad.p.h:1.2 openafs/src/rxkad/rxkad.p.h:1.2.8.1
*** openafs/src/rxkad/rxkad.p.h:1.2	Sat Nov  4 05:05:43 2000
--- openafs/src/rxkad/rxkad.p.h	Wed Nov 14 22:38:52 2001
***************
*** 21,26 ****
--- 21,32 ----
  #define MAXKTCREALMLEN	      64	/* should be 256 */
  #define KTC_TIME_UNCERTAINTY (15*60)	/* max skew bet. machines' clocks */
  
+ #define MAXRANDOMNAMELEN 16		/* length of random generated 
+ 					   usernames used by afslog for high 
+ 					   security must be < MAXKTCNAMELEN */
+ #define LOGON_OPTION_INTEGRATED 1
+ #define LOGON_OPTION_HIGHSECURITY 2
+ 
  /*
   * Define ticket types. For Kerberos V4 tickets, this is overloaded as
   * the server key version number, so class numbers 0 through 255 are reserved
***************
*** 46,51 ****
--- 52,60 ----
      char name[MAXKTCNAMELEN];
      char instance[MAXKTCNAMELEN];
      char cell[MAXKTCREALMLEN];
+ #ifdef AFS_NT40_ENV
+     char smbname[MAXRANDOMNAMELEN];
+ #endif
  };
  
  #ifndef NEVERDATE
Index: openafs/src/rxkad/test/.cvsignore
diff -c openafs/src/rxkad/test/.cvsignore:1.1 openafs/src/rxkad/test/.cvsignore:1.1.2.1
*** openafs/src/rxkad/test/.cvsignore:1.1	Mon Sep 10 16:14:39 2001
--- openafs/src/rxkad/test/.cvsignore	Sun Jan 20 04:03:51 2002
***************
*** 1 ****
--- 1,7 ----
  Makefile
+ stress.h
+ stress.xdr.c
+ stress.cs.c
+ stress.ss.c
+ stress_errs.h
+ stress_errs.c
Index: openafs/src/rxkad/test/Makefile.in
diff -c openafs/src/rxkad/test/Makefile.in:1.4 openafs/src/rxkad/test/Makefile.in:1.4.2.1
*** openafs/src/rxkad/test/Makefile.in:1.4	Mon Sep 10 16:21:12 2001
--- openafs/src/rxkad/test/Makefile.in	Sun Jan 20 04:03:51 2002
***************
*** 14,42 ****
  
  OPTIMIZE=-g
  
! INCDIRS= -I${DESTDIR}/include -I..
  
  HEADERS = ../rxkad.h stress.h stress_internal.h stress_errs.h
  
! LDIR= ${DESTDIR}/lib/
! ULIBS = ${LDIR}/afs/libcmd.a ${LDIR}/afs/libcom_err.a ${DESTDIR}/lib/afs/util.a
  
- LIBS = ../librxkad.a  ${LDIR}/librx.a ${LDIR}/libdes.a \
- 	${LDIR}/liblwp.a  ${ULIBS} ${XLIBS}
- 
  LIBRPC = ../../librpc/libafsrpc.so
  THLIBS= ${LDIR}/afs/libcmd.a  ${LDIR}/afs/libcom_err.a \
  	${ULIBS} ${XLIBS} ${LIBRPC} -lpthread
  
- CFLAGS = ${OPTIMIZE} ${INCDIRS} ${XCFLAGS}
- 
- 
  THFLAGS = -mt -DAFS_PTHREAD_ENV
  
  THRULE = ${CC} ${CFLAGS} ${THFLAGS} -c $?
  
- COMPILE_ET = ${SRCDIR}/bin/compile_et
- 
  noversion all test system: stress
  
  clean:
--- 14,40 ----
  
  OPTIMIZE=-g
  
! CFLAGS=-g -I. -I${srcdir} -I${TOP_OBJDIR}/src/config -I${TOP_INCDIR} ${XCFLAGS}
  
  HEADERS = ../rxkad.h stress.h stress_internal.h stress_errs.h
  
! LIBS=${TOP_LIBDIR}/librx.a \
! 	${TOP_LIBDIR}/liblwp.a \
! 	${TOP_LIBDIR}/libcmd.a \
! 	${TOP_LIBDIR}/librxkad.a \
! 	${TOP_LIBDIR}/libdes.a \
! 	${TOP_LIBDIR}/librx.a \
! 	${TOP_LIBDIR}/libcom_err.a \
! 	${TOP_LIBDIR}/util.a
  
  LIBRPC = ../../librpc/libafsrpc.so
  THLIBS= ${LDIR}/afs/libcmd.a  ${LDIR}/afs/libcom_err.a \
  	${ULIBS} ${XLIBS} ${LIBRPC} -lpthread
  
  THFLAGS = -mt -DAFS_PTHREAD_ENV
  
  THRULE = ${CC} ${CFLAGS} ${THFLAGS} -c $?
  
  noversion all test system: stress
  
  clean:
***************
*** 57,63 ****
  	${THRULE} -o th_stress.xdr.o
  
  stress.ss.c stress.cs.c stress.xdr.c stress.h: stress.rg
! 	${SRCDIR}/bin/rxgen stress.rg
  
  stress_errs.o: stress_errs.c
  
--- 55,61 ----
  	${THRULE} -o th_stress.xdr.o
  
  stress.ss.c stress.cs.c stress.xdr.c stress.h: stress.rg
! 	${RXGEN} stress.rg
  
  stress_errs.o: stress_errs.c
  
Index: openafs/src/sys/pagsh.c
diff -c openafs/src/sys/pagsh.c:1.5 openafs/src/sys/pagsh.c:1.5.4.2
*** openafs/src/sys/pagsh.c:1.5	Thu Jul 12 15:59:17 2001
--- openafs/src/sys/pagsh.c	Sun Jan 20 03:34:41 2002
***************
*** 10,22 ****
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/sys/pagsh.c,v 1.5 2001/07/12 19:59:17 shadow Exp $");
  
  #ifdef	AFS_AIX32_ENV
  #include <signal.h>
  #endif
  #include <stdio.h>
  #include <stdlib.h>
  #ifndef AFS_NT40_ENV
  #include <unistd.h>
  #endif
--- 10,23 ----
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/sys/pagsh.c,v 1.5.4.2 2002/01/20 08:34:41 shadow Exp $");
  
  #ifdef	AFS_AIX32_ENV
  #include <signal.h>
  #endif
  #include <stdio.h>
  #include <stdlib.h>
+ #include <limits.h>
  #ifndef AFS_NT40_ENV
  #include <unistd.h>
  #endif
***************
*** 84,94 ****
  
  static afs_uint32 curpag()
  {
!     afs_uint32 groups[30];
      afs_uint32 g0, g1;
      afs_uint32 h, l, ret;
  
!     if (getgroups(30, groups) < 2) return 0;
  
      g0 = groups[0] & 0xffff;
      g1 = groups[1] & 0xffff;
--- 85,95 ----
  
  static afs_uint32 curpag()
  {
!     afs_uint32 groups[NGROUPS_MAX];
      afs_uint32 g0, g1;
      afs_uint32 h, l, ret;
  
!     if (getgroups(sizeof groups/sizeof groups[0], groups) < 2) return 0;
  
      g0 = groups[0] & 0xffff;
      g1 = groups[1] & 0xffff;
Index: openafs/src/tbutc/NTMakefile
diff -c openafs/src/tbutc/NTMakefile:1.6.2.1 openafs/src/tbutc/NTMakefile:1.6.2.3
*** openafs/src/tbutc/NTMakefile:1.6.2.1	Wed Sep 19 18:32:54 2001
--- openafs/src/tbutc/NTMakefile	Sun Jan 20 04:09:25 2002
***************
*** 69,79 ****
  	     $(DESTDIR)\lib\afs\afsprocmgmt.lib \
               $(DESTDIR)\lib\afs\afseventlog.lib \
  !IF (("$(SYS_NAME)"=="i386_win95" ) || ("$(SYS_NAME)"=="I386_WIN95" ))
! 	$(DESTDIR)\lib\win95\pthread.lib \
  !ELSE
! 	$(DESTDIR)\lib\pthread.lib \
  !ENDIF
! 	     $(DESTDIR)\lib\afsdes.lib
  
  
  #	$(DESTDIR)\lib\afsauthent.lib \
--- 69,80 ----
  	     $(DESTDIR)\lib\afs\afsprocmgmt.lib \
               $(DESTDIR)\lib\afs\afseventlog.lib \
  !IF (("$(SYS_NAME)"=="i386_win95" ) || ("$(SYS_NAME)"=="I386_WIN95" ))
! 	$(DESTDIR)\lib\win95\afspthread.lib \
  !ELSE
! 	$(DESTDIR)\lib\afspthread.lib \
  !ENDIF
! 	     $(DESTDIR)\lib\afsdes.lib \
! 	     $(DESTDIR)\lib\cm_dns.obj
  
  
  #	$(DESTDIR)\lib\afsauthent.lib \
Index: openafs/src/tests/Makefile.in
diff -c /dev/null openafs/src/tests/Makefile.in:1.7.2.6
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/Makefile.in	Mon Jan 28 18:56:08 2002
***************
*** 0 ****
--- 1,386 ----
+ SYS_NAME=@AFS_SYSNAME@
+ MKAFS_OSTYPE=@MKAFS_OSTYPE@
+ TOP_SRCDIR=@TOP_SRCDIR@
+ TOP_INCDIR=@TOP_INCDIR@
+ TOP_LIBDIR=@TOP_LIBDIR@
+ COMPILE_ET=${TOP_SRCDIR}/comerr/compile_et
+ srcdir		= @srcdir@
+ include ../config/Makefile.${SYS_NAME}
+ 
+ SHELL		= /bin/sh
+ 
+ CFLAGS		= -I. -I${srcdir} ${DBG} ${OPTMZ} -I${TOP_SRCDIR}/config -I${TOP_INCDIR} ${XCFLAGS}
+ LDFLAGS=${DBG} ${OPTMZ} ${XLDFLAGS}
+ 
+ INCDIRS=-I${TOP_SRCDIR}/config -I${TOP_INCDIR}/afs -I${TOP_INCDIR}
+ INCLIBS=-L${SRCDIR}/lib/afs -L${TOP_LIBDIR}
+ 
+ LIBS=\
+ 	libdumpscan.a \
+ 	libxfiles.a \
+ 	${TOP_LIBDIR}/libauth.a \
+ 	${TOP_LIBDIR}/libaudit.a \
+ 	${TOP_LIBDIR}/libvolser.a \
+ 	${TOP_LIBDIR}/libvldb.a \
+ 	${TOP_LIBDIR}/libubik.a \
+ 	${TOP_LIBDIR}/librxkad.a \
+ 	${TOP_LIBDIR}/libsys.a \
+ 	${TOP_LIBDIR}/librx.a \
+ 	${TOP_LIBDIR}/liblwp.a \
+ 	${TOP_LIBDIR}/util.a \
+ 	${TOP_LIBDIR}/libcom_err.a \
+ 	${XLIBS}
+ 
+ OBJS_afsdump_scan    = afsdump_scan.o repair.o
+ OBJS_afsdump_xsed    = afsdump_xsed.o repair.o
+ OBJS_libxfiles.a     = xfiles.o xf_errs.o xf_printf.o int64.o \
+                        xf_files.o xf_rxcall.o xf_profile.o
+ OBJS_libdumpscan.a   = primitive.o util.o dumpscan_errs.o parsetag.o \
+                        parsedump.o parsevol.o parsevnode.o dump.o \
+                        directory.o pathname.o backuphdr.o stagehdr.o
+ 
+ TARGETS = libxfiles.a libdumpscan.a \
+           afsdump_scan afsdump_dirlist afsdump_extract dumptool
+ 
+ afsdump_scan: libxfiles.a libdumpscan.a $(OBJS_afsdump_scan)
+ 	$(CC) $(CFLAGS) $(LDFLAGS) -o afsdump_scan $(OBJS_afsdump_scan) $(LIBS)
+ 
+ afsdump_xsed: libxfiles.a libdumpscan.a $(OBJS_afsdump_xsed)
+ 	$(CC) $(CFLAGS) $(LDFLAGS) -o afsdump_xsed $(OBJS_afsdump_xsed) $(LIBS)
+ 
+ afsdump_dirlist: libxfiles.a libdumpscan.a afsdump_dirlist.o
+ 	$(CC) $(CFLAGS) $(LDFLAGS) -o afsdump_dirlist afsdump_dirlist.o $(LIBS)
+ 
+ afsdump_extract: libxfiles.a libdumpscan.a afsdump_extract.o
+ 	$(CC) $(CFLAGS) $(LDFLAGS) -o afsdump_extract afsdump_extract.o $(LIBS)
+ 
+ null-search: libxfiles.a libdumpscan.a null-search.c
+ 	$(CC) $(CFLAGS) $(LDFLAGS) -o null-search null-search.c $(LIBS)
+ 
+ dumptool: dumptool.c
+ 	$(CC) $(CFLAGS) $(LDFLAGS) -o dumptool dumptool.c
+ 
+ libxfiles.a: $(OBJS_libxfiles.a)
+ 	-rm -f libxfiles.a
+ 	$(AR) r libxfiles.a $(OBJS_libxfiles.a)
+ 	$(RANLIB) libxfiles.a
+ 
+ libdumpscan.a: $(OBJS_libdumpscan.a)
+ 	-rm -f libdumpscan.a
+ 	$(AR) r libdumpscan.a $(OBJS_libdumpscan.a)
+ 	$(RANLIB) libdumpscan.a
+ 
+ xf_errs.c xf_errs.h: xf_errs.et
+ 	$(COMPILE_ET) xf_errs.et
+ 
+ dumpscan_errs.c dumpscan_errs.h: dumpscan_errs.et
+ 	$(COMPILE_ET) dumpscan_errs.et
+ 
+ util.o xfiles.o xf_files.o: xf_errs.h
+ backuphdr.o directory.o parsedump.o parsetag.o: dumpscan_errs.h
+ parsevnode.o parsevol.o pathname.o repair.o:    dumpscan_errs.h
+ stagehdr.o util.o:                              dumpscan_errs.h
+ 
+ ${DEST}/etc/afsdump_scan: afsdump_scan
+ 	${INSTALL} $? $@
+ 
+ ${DEST}/etc/afsdump_dirlist: afsdump_dirlist
+ 	${INSTALL} $? $@
+ 
+ ${DEST}/etc/afsdump_extract: afsdump_extract
+ 	${INSTALL} $? $@
+ 
+ ${DEST}/etc/dumptool: dumptool
+ 	${INSTALL} $? $@
+ 
+ ${DESTDIR}${sbindir}/afsdump_scan: afsdump_scan
+ 	${INSTALL} $? $@
+ 
+ ${DESTDIR}${sbindir}/afsdump_dirlist: afsdump_dirlist
+ 	${INSTALL} $? $@
+ 
+ ${DESTDIR}${sbindir}/afsdump_extract: afsdump_extract
+ 	${INSTALL} $? $@
+ 
+ ${DESTDIR}${sbindir}/dumptool: dumptool
+ 	${INSTALL} $? $@
+ 
+ ${TOP_LIBDIR}/libxfiles.a: libxfiles.a
+ 	${INSTALL} $? $@
+ 
+ ${TOP_LIBDIR}/libdumpscan.a: libdumpscan.a
+ 	${INSTALL} $? $@
+ 
+ SYS_LIBS	= ${TOP_LIBDIR}/libsys.a ${TOP_LIBDIR}/librx.a ${TOP_LIBDIR}/liblwp.a ${TOP_LIBDIR}/util.a
+ 
+ AUTH_LIBS	= ${TOP_LIBDIR}/libauth.a ${SYS_LIBS}
+ 
+ INT_LIBS	= ${TOP_LIBDIR}/libafsint.a ${TOP_LIBDIR}/libsys.a ${TOP_LIBDIR}/librxkad.a ${TOP_LIBDIR}/librx.a ${TOP_LIBDIR}/liblwp.a ${TOP_LIBDIR}/libcom_err.a ${TOP_LIBDIR}/util.a 
+ 
+ TEST_PROGRAMS = write-ro-file hello-world read-vs-mmap read-vs-mmap2	 \
+ 		mmap-and-read large-dir large-dir2 large-dir3 mountpoint \
+ 		test-setgroups test-setpag hardlink1 hardlink2 mkdir2	 \
+ 		create-files create-symlinks create-dirs dup2-and-unlog	 \
+ 		readdir-vs-lstat read-write create-remove mkdir3         \
+ 		symlink echo-n test-parallel1 test-parallel2 create-stat \
+ 		kill-softly kill-softer rm-rf exit-wo-close	         \
+ 		mmap-vs-read mmap-vs-read2 strange-characters-c pine	 \
+ 		append-over-page write-ucc utime-dir mmap-shared-write	 \
+ 		rename5 rename-under-feet write-closed write-closed2	 \
+ 		truncate fchmod make-page utime-file rename6 	         \
+ 		write3 still-there-p write-large afscp hardlink4         \
+ 		intr-read asu truncate-files mmap-cat blocks-new-file 	 \
+ 		fsx write-rand
+ 
+ TEST_OBJS     = write-ro-file.o read-vs-mmap.o read-vs-mmap2.o		   \
+ 		mmap-and-read.o large-dir.o large-dir2.o large-dir3.o	   \
+ 		test-setgroups.o test-setpag.o hardlink1.o hardlink2.o	   \
+ 		mkdir2.o create-files.o create-symlinks.o create-dirs.o	   \
+ 		dup2-and-unlog.o readdir-vs-lstat.o read-write.o           \
+ 		create-remove.o symlink.o echo-n.o test-parallel1.o	   \
+ 		test-parallel1.o mkdir3.o rename6.o			   \
+ 		create-stat.o kill-softly.o kill-softer.o rm-rf.o          \
+ 		exit-wo-close.o mmap-vs-read.o mmap-vs-read2.o		   \
+ 		strange-characters-c.o pine.o append-over-page.o	   \
+ 		write-ucc.o utime-dir.o mmap-shared-write.o rename5.o	   \
+ 		rename-under-feet.o write-closed.o write-closed2.o	   \
+ 		truncate.o fchmod.o make-page.o utime-file.o	           \
+ 		write3.o still-there-p.o write-large.o hardlink4.o         \
+ 		intr-read.o asu.o truncate-files.o mmap-cat.o		   \
+ 		blocks-new-file.o fsx.o afscp.o afscp_callback.o	   \
+ 		write-rand.o
+ 
+ TEST_SRCS     = write-ro-file.c read-vs-mmap.c read-vs-mmap2.c		   \
+ 		mmap-and-read.c large-dir.c large-dir2.c large-dir3.c	   \
+ 		test-setgroups.c test-setpag.c hardlink1.c hardlink2.c	   \
+ 		mkdir2.c create-files.c create-symlinks.c create-dirs.c	   \
+ 		dup2-and-unlog.c readdir-vs-lstat.c read-write.c           \
+ 		create-remove.c symlink.c echo-n.c test-parallel1.c	   \
+ 		test-parallel2.c mkdir3.c rename6.c			   \
+ 		create-stat.c kill-softly.c kill-softer.c rm-rf.c          \
+ 		exit-wo-close.c mmap-vs-read.c mmap-vs-read2.c		   \
+ 		strange-characters-c.c pine.c append-over-page.c	   \
+ 		write-ucc.c utime-dir.c mmap-shared-write.c rename5.c	   \
+ 		rename-under-feet.c write-closed.c write-closed2.c	   \
+ 		truncate.c fchmod.c make-page.c utime-file.c	           \
+ 		write3.c still-there-p.c write-large.c hardlink4.c         \
+ 		intr-read.c asu.c truncate-files.c mmap-cat.c		   \
+ 		blocks-new-file.c fsx.c afscp.c afscp_callback.c	   \
+ 		write-rand.c
+ 
+ EXTRA_OBJS = err.o errx.o warn.o warnx.o
+ 
+ OpenAFS/OS.pm: OpenAFS/OS-$(MKAFS_OSTYPE).pm
+ 	$(CP) OpenAFS/OS-$(MKAFS_OSTYPE).pm OpenAFS/OS.pm
+ 
+ write-rand: write-rand.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ write-rand.o $(EXTRA_OBJS) $(LIBS)
+ 
+ write-ro-file: write-ro-file.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ write-ro-file.o $(EXTRA_OBJS) $(LIBS)
+ 
+ write-large: write-large.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ write-large.o $(EXTRA_OBJS) $(LIBS)
+ 
+ read-vs-mmap: read-vs-mmap.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ read-vs-mmap.o $(EXTRA_OBJS) $(LIBS)
+ 
+ read-vs-mmap2: read-vs-mmap2.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ read-vs-mmap2.o $(EXTRA_OBJS) $(LIBS)
+ 
+ mmap-vs-read: mmap-vs-read.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ mmap-vs-read.o $(EXTRA_OBJS) $(LIBS)
+ 
+ mmap-vs-read2: mmap-vs-read2.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ mmap-vs-read2.o $(EXTRA_OBJS) $(LIBS)
+ 
+ read-write: read-write.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ read-write.o $(EXTRA_OBJS) $(LIBS)
+ 
+ mmap-and-read: mmap-and-read.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ mmap-and-read.o $(EXTRA_OBJS) $(LIBS)
+ 
+ large-dir: large-dir.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ large-dir.o $(EXTRA_OBJS) $(LIBS)
+ 
+ large-dir2: large-dir2.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ large-dir2.o $(EXTRA_OBJS) $(LIBS)
+ 
+ large-dir3: large-dir3.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ large-dir3.o $(EXTRA_OBJS) $(LIBS)
+ 
+ fchmod: fchmod.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ fchmod.o $(EXTRA_OBJS) $(LIBS)
+ 
+ truncate: truncate.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ truncate.o $(EXTRA_OBJS) $(LIBS)
+ 
+ make-page: make-page.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ make-page.o $(EXTRA_OBJS) $(LIBS)
+ 
+ still-there-p: still-there-p.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ still-there-p.o $(EXTRA_OBJS) $(LIBS)
+ 
+ intr-read: intr-read.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ intr-read.o $(EXTRA_OBJS) $(LIBS)
+ 
+ blocks-new-file: blocks-new-file.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ blocks-new-file.o $(EXTRA_OBJS) $(LIBS)
+ 
+ asu: asu.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ asu.o $(EXTRA_OBJS) $(LIBS)
+ 
+ test-setgroups: test-setgroups.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ test-setgroups.o $(EXTRA_OBJS) $(SYS_LIBS) $(LIBS)
+ 
+ test-setpag: test-setpag.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ test-setpag.o $(EXTRA_OBJS) $(SYS_LIBS) $(LIBS)
+ 
+ hardlink1: hardlink1.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ hardlink1.o $(EXTRA_OBJS) $(LIBS)
+ 
+ hardlink2: hardlink2.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ hardlink2.o $(EXTRA_OBJS) $(LIBS)
+ 
+ hardlink4: hardlink4.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ hardlink4.o $(EXTRA_OBJS) $(LIBS)
+ 
+ mkdir2: mkdir2.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ mkdir2.o $(EXTRA_OBJS) $(LIBS)
+ 
+ mkdir3: mkdir3.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ mkdir3.o $(EXTRA_OBJS) $(LIBS)
+ 
+ create-files: create-files.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ create-files.o $(EXTRA_OBJS) $(LIBS)
+ 
+ create-symlinks: create-symlinks.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ create-symlinks.o $(EXTRA_OBJS) $(LIBS)
+ 
+ create-dirs: create-dirs.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ create-dirs.o $(EXTRA_OBJS) $(LIBS)
+ 
+ create-remove: create-remove.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ create-remove.o $(EXTRA_OBJS) $(LIBS)
+ 
+ dup2-and-unlog: dup2-and-unlog.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ dup2-and-unlog.o  $(EXTRA_OBJS) $(AUTH_LIBS) $(LIBS)
+ 
+ readdir-vs-lstat: readdir-vs-lstat.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ readdir-vs-lstat.o $(EXTRA_OBJS) $(LIBS)
+ 
+ symlink: symlink.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ symlink.o $(EXTRA_OBJS) $(LIBS)
+ 
+ echo-n: echo-n.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ echo-n.o $(EXTRA_OBJS)
+ 
+ test-parallel1: test-parallel1.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ test-parallel1.o $(EXTRA_OBJS) $(LIBS)
+ 
+ test-parallel2: test-parallel2.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ test-parallel2.o $(EXTRA_OBJS) $(LIBS)
+ 
+ create-stat: create-stat.o fs_lib.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ create-stat.o fs_lib.o $(EXTRA_OBJS) $(SYS_LIBS) $(LIBS)
+ 
+ kill-softly: kill-softly.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ kill-softly.o $(EXTRA_OBJS) $(LIBS)
+ 
+ kill-softer: kill-softer.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ kill-softer.o $(EXTRA_OBJS) $(LIBS)
+ 
+ rm-rf: rm-rf.o fs_lib.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ rm-rf.o fs_lib.o $(EXTRA_OBJS) $(SYS_LIBS) $(LIBS)
+ 
+ exit-wo-close: exit-wo-close.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ exit-wo-close.o $(EXTRA_OBJS) $(LIBS)
+ 
+ strange-characters-c: strange-characters-c.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ strange-characters-c.o $(EXTRA_OBJS) $(LIBS)
+ 
+ pine: pine.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ pine.o $(EXTRA_OBJS) $(LIBS)
+ 
+ append-over-page: append-over-page.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ append-over-page.o $(EXTRA_OBJS) $(LIBS)
+ 
+ write-ucc: write-ucc.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ write-ucc.o $(EXTRA_OBJS) $(LIBS)
+ 
+ utime-dir: utime-dir.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ utime-dir.o $(EXTRA_OBJS) $(LIBS)
+ 
+ utime-file: utime-file.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ utime-file.o $(EXTRA_OBJS) $(LIBS)
+ 
+ mmap-shared-write: mmap-shared-write.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ mmap-shared-write.o $(EXTRA_OBJS) $(LIBS)
+ 
+ rename5: rename5.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ rename5.o $(EXTRA_OBJS) $(LIBS)
+ 
+ rename6: rename6.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ rename6.o $(EXTRA_OBJS) $(LIBS)
+ 
+ write3: write3.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ write3.o $(EXTRA_OBJS) $(LIBS)
+ 
+ rename-under-feet: rename-under-feet.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ rename-under-feet.o $(EXTRA_OBJS) $(LIBS)
+ 
+ write-closed: write-closed.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ write-closed.o $(EXTRA_OBJS) $(LIBS)
+ 
+ write-closed2: write-closed2.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ write-closed2.o $(EXTRA_OBJS) $(SYS_LIBS) $(LIBS)
+ 
+ truncate-files: truncate-files.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ truncate-files.o $(EXTRA_OBJS) $(LIBS)
+ 
+ mmap-cat: mmap-cat.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ mmap-cat.o $(EXTRA_OBJS) $(LIBS)
+ 
+ run-tests: run-tests.in
+ 	(cd ../..; CONFIG_FILES=src/tests/run-tests CONFIG_HEADERS= $(SHELL) @TOP_SRCDIR@/../config.status)
+ 	@chmod +x run-tests
+ 
+ #.c.o:
+ #	$(CC) -c $(CPPFLAGS) $(DEFS) -I$(srcdir) -I. $(REALCFLAGS) $<
+ 
+ afscp: afscp.o afscp_callback.o $(EXTRA_OBJS)
+ 	$(CC) $(LDFLAGS) -o $@ afscp.o afscp_callback.o $(EXTRA_OBJS) $(INT_LIBS)
+ 
+ hello-world:   hello-world.in
+ 	sed -e "s!%CC%!$(CC)!" $(srcdir)/hello-world.in > $@
+ 	chmod +x hello-world
+ 
+ mountpoint:   mountpoint.in
+ 	sed -e "s!%bindir%!$(bindir)!" $(srcdir)/mountpoint.in > $@
+ 	chmod +x mountpoint
+ 
+ dest:
+ 
+ install:
+ 
+ uninstall:
+ 
+ all: run-tests OpenAFS/OS.pm libxfiles.a libdumpscan.a $(TEST_PROGRAMS)\
+ 	afsdump_scan afsdump_dirlist afsdump_extract dumptool
+ 
+ clean:
+ 	-rm -f xf_errs.c xf_errs.h dumpscan_errs.c dumpscan_errs.h *.o \
+ 	$(TARGETS) run-tests $(TEST_PROGRAMS) OS.pm
+ 
+ include ../config/Makefile.version
+ 
+ TAGS:	$(TEST_SRCS)
+ 	etags $(TEST_SRCS)
+ 
+ check: run-tests $(TEST_PROGRAMS)
+ 	./run-tests -all
+ 
+ check-fast: run-tests $(TEST_PROGRAMS)
+ 	./run-tests -all -fast
+ 
+ .PHONY:		all install clean realclean distclean mostlyclean install uninstall check
Index: openafs/src/tests/README
diff -c /dev/null openafs/src/tests/README:1.2.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/README	Sun Jan 20 04:18:06 2002
***************
*** 0 ****
--- 1,239 ----
+ AFS verification suite
+ 14 Jan 2002
+ 
+ Prerequisites
+ 
+ 1) A Kerberos KDC should already be configured 
+ 2) An afs key should be in the KeyFile the AFS binaries will use
+    (/usr/afs/etc/KeyFile in an IBM-style installation; bos_util can be used
+     to set it up)
+ 3) 2 srvtabs or keytabs with user keys, one for the user "admin"
+    and one for the user "user" that can be used for authenticated testing 
+    of the AFS installation
+ 4) The necessary tools for getting an AFS token from the installed Kerberos
+    (typically aklog) should be available.
+ 5) Ability to run as root on the "test" node.
+ 6) If the AFS to be tested is not OpenAFS, pt_util from OpenAFS should be
+    built and installed.
+ 7) Volume dump test tools included in new versions of OpenAFS.
+ 8) The "test" node should have partitions mounted as /vicepa and /vicepb
+ 9) perl5
+ 10) wget (should be configurable to use curl; what else?)
+ 
+ (*) This is not yet true but will be by the time the suite is delivered.
+ 
+ Setup
+ 1) Scripts provided bootstrap and populate a "test cell". (afs-newcell)
+ 
+ Tests
+ 
+ A) Simple tests
+ 10) Create a file. (creat1)
+ 20) Create a directory. (mkdir1/mkdir2)
+ 30) Create a symlink. (symlink)
+ 40) Create a in-same-directory hardlink. (hardlink1)
+ 50) Create a hardlink to a different-directory-same-volume file. (hardlink4)
+ 60) Create a hardlink to a directory. (hardlink2)
+ 70) Create a cross-volume hardlink. (hardlink5)
+ 80) Touch a file. (touch1)
+ 90) Write a simple file. (write1)
+ 100) Rewrite a file. (write3)
+ 110) Rename a file. (rename1)
+ 
+ B) Basic functionality
+ 10) Stat multiple hardlinked files. (hardlink3)
+ 20) Write, truncate, rewrite a file. (write2)
+ 30) Append to a file. (append1)
+ 40) Rename a file over another file. (rename2)
+ 50) Rename a file into a same-volume directory. (rename4)
+ 60) Rename a file into another-volume directory. (rename6)
+ 70) Rename an open directory. (rename-under-feet)
+ 80) Create a file with a large filename. (large-filename)
+ 90) Chmod a file by descriptor. (fchmod)
+ 100) Utimes a file. (utime-file)
+ 110) Utimes a directory. (utime-dir)
+ 120) Test directory "link count" increasing/decreasing appropriately. (mkdir3)
+ 
+ C) Mountpoint tests
+ 10) Create and remove a good mountpoint. (mkm-rmm)
+ 20) Create a mountpoint to a nonexistant volume. (mountpoint)
+ 
+ D) ACL tests
+ 10) Add a valid PTS user to an ACL. (acladduser)
+ 20) Add a valid PTS group to an ACL. (acladdgroup)
+ 30) Add ACL rights for a PTS user. (acladdrights)
+ 40) Add negative ACL rights for a PTS user. (acladdnegrights)
+ 50) Clear negative ACL rights for a PTS user. (aclclearnegrights)
+ 60) Remove a valid PTS user from an ACL. (aclremoveuser)
+ 70) Remove a valid PTS group from an ACL. (aclremovegroup)
+ 80) Copy an ACL. (aclcopy)
+ 
+ E) Executable tests
+ 10) Write and execute a script in a directory. (exec)
+ 20) Download and build http://www.openafs.org/dl/openafs/1.2.2/openafs-1.2.2-src.tar.gz, then run something from it. (build-openafs)
+ 
+ F) mmap tests
+ 10) Append over a mapped page. (append-over-page)
+ 20) Write via mmap to a shared-mapped file. (mmap-shared-write)
+ 30) Compare a file being read via mmap private and read (mmap-vs-read2)
+ 40) Compare a file being read via mmap shared and read (mmap-vs-read)
+ 50) Compare a file being read via read and mmap shared (read-vs-mmap2)
+ 60) Compare a file being read via read and mmap private (read-vs-mmap)
+ 
+ G) Filesystem Semantics tests
+ 10) Create a file with 8 bit characters in its name. (strange-characters)
+ 20) Test pine lockfile semantics. (pine)
+ 30) Create and remove a single file in parallel. (parallel1)
+ 40) Create a >2gb file (write-large)
+ 
+ H) AFS behavior tests
+ 10) Write a file in a readonly volume. (write-ro)
+ 20) Create 31707 entries in a directory. (too-many-files)
+ 30) Test setpag(). (setpag)
+ 40) Test setgroups(). (setgroups)
+ 
+ I) Remote operation tests
+ 10) Write a file locally and read it in a foreign cache manager. (extcopyin)
+ 20) Write a file in a foreign cache manager and read it locally. (extcopyout)
+ 
+ K) Client abuse tests
+ 10) Write a file, read, rewrite and reread a file with the same open descriptor. (read-write)
+ 20) Populate and clean up a directory tree. (create-remove-files)
+ 30) FSX file system stresser (fsx)
+ 
+ L) Fileserver tests
+ 
+ M) Ptserver tests
+ 10) Create a user (ptscreateuser)
+ 20) Create a group (ptscreategroup)
+ 30) Add a user to a group (ptsadduser)
+ 40) Chown a group (ptschown)
+ 50) Get user membership (ptsmembersuser)
+ 60) Get group membership (ptsmembersgroup)
+ 70) Examine a user (ptsexamineuser)
+ 80) Examine a group (ptsexaminegroup)
+ 90) Remove a user from a group (ptsremove)
+ 100) List groups a user owns (ptslistown)
+ 100) Set maxuser (ptssetmax)
+ 110) List maxuser (ptslistmax)
+ 130) Set fields on a user (ptssetf)
+ 140) Delete a group (ptsdeletegroup)
+ 150) Delete a user (ptsdeleteuser)
+ 160) pt_util exercising (?)
+ 
+ N) Volserver/vlserver tests
+ 10) Create a volume (voscreate)
+ 20) Move a volume (vosmove)
+ 30) Add a replication site (vosaddsite)
+ 40) Release a volume (vosrelease)
+ 50) Remove a replication site (vosremsite)
+ 70) Remove a volume (vosremove)
+ 80) Delete a VLDB entry (vosdelentry)
+ 90) Synchronize vldb to volumes (vossyncvldb)
+ 100) Zap a volume (voszap)
+ 110) Synchronize volumes to vldb (vossyncserv)
+ 120) Lock a VLDB entry (voslock)
+ 130) Unlock a VLDB entry (vosunlock)
+ 140) Unlock all VLDB entries after locking one or more (vosunlockall)
+ 150) Rename a volume. (vosrename)
+ 160) List all volumes on a partition. (voslistvol)
+ 170) List vldb (voslistvldb)
+ 180) Get partition info. (vospartinfo)
+ 190) List partitions (voslistpart)
+ 200) Backup a volume (vosbackup)
+ 210) Examine a volume (vosexamine)
+ 220) Dump a volume (vosdump)
+ 230) Restore a volume (vosrestore)
+ 240) Verify a volume dump (?)
+ 
+ O) Bosserver tests
+ 10) Add a bosserver host (bosaddhost)
+ 20) List server hosts (bostlisthosts)
+ 30) Remove a server host (bosremovehost)
+ 40) Add a superuser (bosadduser)
+ 50) List superusers (boslistusers)
+ 60) Remove a superuser (bosremoveuser)
+ 70) Install an executable shell script (bosinstall)
+ 80) Execute something via the bosserver (bosexec)
+ 80) Create a bos bnode (boscreate)
+ 90) Delete a running bnode (bosdeleterunning)
+ 100) Get a bnode status (bosstatus)
+ 110) Stop a bos bnode (bosstop)
+ 120) Restart a bos bnode (bosrestartstopped)
+ 130) Start a bos bnode (bosstart)
+ 140) Shutdown a bnode (bosshutdown)
+ 150) Delete a stopped bnode (bosdelete)
+ 160) Add a key (bosaddkey)
+ 170) List keys (boslistkeys)
+ 180) Remove a key (bosremovekey)
+ 180) Salvage a volume (bossalvagevolume)
+ 190) Salvage a partition (bossalvagepart)
+ 200) Salvage a server (bossalvageserver)
+ 
+ P) Regression
+ 10) Write a file larger than the cache. (fcachesize-write-file)
+ 20) Read a file larger than the cache. (fcachesize-read-file)
+ 30) Restore volume with a bad uniquifier in it, salvage, check. (baduniq)
+ 40) Check for bad dentry caching on Linux taking advantage of last test. (?)
+ 
+ ---
+ Copyright information
+ 
+ The AFStools perl modules are:
+ 
+ ## Copyright (c) 1996, 2001 Carnegie Mellon University
+ ## All Rights Reserved.
+ #
+ # Permission to use, copy, modify and distribute this software and its
+ # documentation is hereby granted, provided that both the copyright
+ # notice and this permission notice appear in all copies of the
+ # software, derivative works or modified versions, and any portions
+ # thereof, and that both notices appear in supporting documentation.
+ #
+ # CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ # CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ # ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ #
+ # Carnegie Mellon requests users of this software to return to
+ #
+ #  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
+ #  School of Computer Science
+ #  Carnegie Mellon University
+ #  Pittsburgh PA 15213-3890
+ #
+ # any improvements or extensions that they make and grant Carnegie Mellon
+ # the rights to redistribute these changes.
+ 
+ Some tests as noted are:
+ /*
+  * Copyright (c) 2001 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
Index: openafs/src/tests/README.afstools
diff -c /dev/null openafs/src/tests/README.afstools:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/README.afstools	Sun Jan 20 04:18:06 2002
***************
*** 0 ****
--- 1,2 ----
+ This is a (potentially) modified verion of the AFSTools perl suite. 
+ You should visit grand.central.org for the official version.
Index: openafs/src/tests/README.dumptool
diff -c /dev/null openafs/src/tests/README.dumptool:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/README.dumptool	Sun Jan 20 04:18:06 2002
***************
*** 0 ****
--- 1,152 ----
+ $Id: README.dumptool,v 1.1.2.1 2002/01/20 09:18:06 shadow Exp $
+ 
+ This is the README for dumptool, a program to interactively restore
+ AFS volume dump files.
+ 
+ 
+ INTRODUCTION
+ 
+ Dumptool arose out of a need here at NRL to perform maintenance of
+ MR-AFS (Multi-Resident AFS) volumes.  After it was written, we found
+ that it worked great on standard AFS volumes as well, and relatively
+ few changes were required to make it compile with a standard AFS
+ installation.
+ 
+ Dumptool provides an interface similar to the interactive Unix restore;
+ given a dump file, a user can navigate through the filesystem inside
+ the dump using familiar commands such as "cd" and "ls".  Also provided
+ is a "cp" command to copy individual files out of the dump into a
+ normal filesystem space.  This eliminates the need to restore an
+ entire volume just to retrieve a single file.
+ 
+ Dumptool was written at the Naval Research Laboratory by Ken Hornstein
+ <kenh@cmf.nrl.navy.mil>.  The latest and greatest version of dumptool
+ can always be found in the AFS contrib directory at:
+ 
+ /afs/transarc.com/public/afs-contrib/dumptool/
+ 
+ 
+ INSTALLATION & OPERATION
+ 
+ The standard Makefile target will build a dumptool for a vanilla AFS
+ installation.  The "mrafs" target will build a dumptool that can
+ operate on MR-AFS dumps.  In either case, you may need to change some
+ of the Makefile variables to reflect your site; see the Makefile for
+ more information.
+ 
+ Once dumptool is built successfully, you can run it on any AFS dump
+ file.  Without any additional arguments, dumptool will scan the dump file,
+ build indexes of all listed vnodes, and present a prompt (">") that
+ accepts the following commands:
+ 
+ 	ls	Lists files in the current directory.  Filename globbing
+ 		(e.g., wildcards such as * ?) are supported via the system
+ 		fnmatch() function.  Accepts the following flags:
+ 
+ 	    -l	Generates a "long" listing, similar to the -l switch for
+ 		the Unix ls.  Displays Unix mode mask, owner, group,
+ 		and file size.
+ 	    -i  Displays volume, vnode, and uniquifier for each matching
+ 		file in the format volume.vnode.uniquifier.  Note that
+ 		the volume displayed is that of the _parent_ volume,
+ 		which in the case of a backup volume is the _original_
+ 		volume from which it was generated.
+ 	    -F  Append / to filenames for directories, @ for symlinks,
+ 		and * for files which have the execute bits set.
+ 	    -R  Recurse through all subdirectories.
+ 	
+ 	cd	Change the current directory
+ 
+ 	cp	Copy a file from the dump.  Note that globbing is NOT
+ 		supported, and you must give a filename (the Unix
+ 		idiom of just giving a destination directory for the
+ 		second argument to cp will NOT work).
+ 	
+ 	vcp	Copy a file from the dump, by the vnode.  The first
+ 		argument is the vnode number, optionally followed by
+ 		the uniqifier.  E.g:
+ 
+ 		vcp 126278 /tmp/file1
+ 		vcp 126278.43289 /tmp/file2
+ 	
+ 	quit	Exits dumptool.
+ 	exit
+ 
+ 
+ ADDITIONAL OPTIONS TO DUMPTOOL
+ 
+ Dumptool supports a number of command-line options.  They are detailed
+ below:
+ 
+ 	-v	Verbose mode.  Output additional information during dump
+ 		processing.  Each -v will increate output.
+ 
+ 	-f	Force dump processing.  Attempt to continue processing
+ 		a dump even when some errors are detected.  Not completely
+ 		tested.
+ 	
+ 	-i	Inode dump.  Dump a list of all files in the volume,
+ 		with their volume/vnode/uniqifier information.
+ 
+ 
+ SUPPORT FOR MR-AFS
+ 
+ Dumptool also supports the extra information in MR-AFS dumps, and
+ provides some extra commands/options for dealing with MR-AFS dumps:
+ 
+ Additional command line options:
+ 
+ 	-d	Dump all residency filenames in the dump file to standard
+ 		output.
+ 	
+ 	-t 	Residency tag information.  Allows a user to specify the
+ 		tag of a residency if the rsserver is not available.
+ 		Format of option is Residency/Tag
+ 	
+ 	-r	Residency filesystem information.  Allows a user to specify
+ 		the residency filesystem information if dumptool is not
+ 		run on the same host as the residency in the dump.  Format
+ 		of option is Residency/Type/Size/Algorithm.
+ 
+ Additional commands:
+ 
+ 	file	Displays to standard output the residency filename of a
+ 		given dump filename.  All residencies available are shown.
+ 
+ 
+ CAVEATS
+ 
+ The user interface needs some work.  "ls" doesn't support nearly as many
+ options as the standard Unix one.  "cp" also doesn't have all of the features
+ found in common Unix variants.
+ 
+ Right now two passes are done through the dump file to scan all vnodes.
+ With some clever work this could be sped up somewhat and changed to only
+ do a single scan.
+ 
+ 
+ MODIFYING DUMPTOOL
+ 
+ I welcome changes to dumptool, but I have some guidelines.
+ 
+ First, I DEMAND that the changes be sent in context diff format.  I prefer
+ unidiff (diff -u), but standard context diffs are okay.  It's extremely
+ difficult to deal with new code in any other way.
+ 
+ If the changes you want to do require some significant
+ rearchitecturing, it might be a good idea to contact me first.  That
+ way we can coordinate the modifications in a meaningful way (I might
+ have made changes since the last released version).
+ 
+ If you're making MR-AFS specific changes, please follow the example
+ I've set and protect them with #ifdef RESIDENCY.
+ 
+ And please ... follow my code style, okay?  I always try to follow
+ whatever wacky code style I find in source code that I modify, and I
+ think it's only polite for you to do the same.
+ 
+ 
+ CONTACT INFORMATION
+ 
+ As always, please send comments, suggestions, or new features to me,
+ Ken Hornstein <kenh@cmf.nrl.navy.mil>.  Shar and enjoy.
Index: openafs/src/tests/TEMPLATE
diff -c /dev/null openafs/src/tests/TEMPLATE:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/TEMPLATE	Sun Jan 20 04:18:06 2002
***************
*** 0 ****
--- 1,27 ----
+ /*
+  * CMUCS AFStools
+  * dumpscan - routines for scanning and manipulating AFS volume dumps
+  *
+  * Copyright (c) 1998 Carnegie Mellon University
+  * All Rights Reserved.
+  * 
+  * Permission to use, copy, modify and distribute this software and its
+  * documentation is hereby granted, provided that both the copyright
+  * notice and this permission notice appear in all copies of the
+  * software, derivative works or modified versions, and any portions
+  * thereof, and that both notices appear in supporting documentation.
+  *
+  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+  *
+  * Carnegie Mellon requests users of this software to return to
+  *
+  *  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
+  *  School of Computer Science
+  *  Carnegie Mellon University
+  *  Pittsburgh PA 15213-3890
+  *
+  * any improvements or extensions that they make and grant Carnegie Mellon
+  * the rights to redistribute these changes.
+  */
Index: openafs/src/tests/acladdgroup.pl
diff -c /dev/null openafs/src/tests/acladdgroup.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/acladdgroup.pl	Sun Jan 20 04:18:06 2002
***************
*** 0 ****
--- 1,41 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($wscell, $path, @pos1, @pos2, @neg1, @neg2, $ret, @tmp, @tmp2, @tmp3, $found);
+ &AFS_Init();
+ $wscell = &AFS_fs_wscell();
+ $found = 0;
+ 
+ eval { &AFS_pts_creategroup(group1,,,); };
+ $path = "/afs/${wscell}/service/acltest";
+ mkdir $path, 0777;
+ ($pos1, $neg1) = &AFS_fs_getacl($path);
+ $ret = &AFS_fs_setacl([$path],[["group1", "rl"]],,);
+ ($pos2, $neg2) = &AFS_fs_getacl($path);
+ while ($ret = pop(@$pos2)) {
+     @tmp2=@$ret;
+     if ($tmp2[0] eq "group1") { 
+ 	$found++; 
+     } else { 
+ 	unshift @tmp, @$ret;
+     }
+ }
+ 
+ @tmp2=();
+ while ($ret = pop(@$pos1)) {
+     unshift @tmp2, @$ret;
+ }
+ 
+ if ($found != 1) {
+     exit(1);
+ }
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/acladdnegrights.pl
diff -c /dev/null openafs/src/tests/acladdnegrights.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/acladdnegrights.pl	Sun Jan 20 04:18:06 2002
***************
*** 0 ****
--- 1,42 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($wscell, $path, @pos1, @pos2, @neg1, @neg2, $ret, @tmp, @tmp2, @tmp3, $found);
+ &AFS_Init();
+ $wscell = &AFS_fs_wscell();
+ $found = 0;
+ 
+ eval { &AFS_pts_createuser(user1,,); };
+ $path = "/afs/${wscell}/service/acltest";
+ mkdir $path, 0777;
+ ($pos1, $neg1) = &AFS_fs_getacl($path);
+ $ret = &AFS_fs_setacl([$path],[],[["user1", "rl"]],);
+ ($pos2, $neg2) = &AFS_fs_getacl($path);
+ while ($ret = pop(@$neg2)) {
+     @tmp2=@$ret;
+     if ($tmp2[0] eq "user1") { 
+ 	$found++;
+     } else {
+ 	unshift @tmp, @$ret;
+     }
+ }
+ 
+ if ($found != 1) {
+     exit(1);
+ }
+ 
+ @tmp2=();
+ while ($ret = pop(@$neg1)) {
+     unshift @tmp2, @$ret;
+ }
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/acladdrights.pl
diff -c /dev/null openafs/src/tests/acladdrights.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/acladdrights.pl	Sun Jan 20 04:18:06 2002
***************
*** 0 ****
--- 1,42 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($wscell, $path, @pos1, @pos2, @neg1, @neg2, $ret, @tmp, @tmp2, @tmp3, $found);
+ &AFS_Init();
+ $wscell = &AFS_fs_wscell();
+ $found = 0;
+ 
+ eval { &AFS_pts_createuser(user1,,); };
+ $path = "/afs/${wscell}/service/acltest";
+ mkdir $path, 0777;
+ ($pos1, $neg1) = &AFS_fs_getacl($path);
+ $ret = &AFS_fs_setacl([$path],[["user1", "rlidw"]],,);
+ ($pos2, $neg2) = &AFS_fs_getacl($path);
+ while ($ret = pop(@$pos2)) {
+     @tmp2=@$ret;
+     if ($tmp2[0] eq "user1") { 
+ 	if ($tmp2[1] ne "rlidw") {
+ 	    exit (1);
+ 	}
+ 	$tmp2[1] = "rl";
+ 	unshift @tmp, @tmp2;
+     } else {
+ 	unshift @tmp, @$ret;
+     }
+ }
+ 
+ @tmp2=();
+ while ($ret = pop(@$pos1)) {
+     unshift @tmp2, @$ret;
+ }
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/acladduser.pl
diff -c /dev/null openafs/src/tests/acladduser.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/acladduser.pl	Sun Jan 20 04:18:06 2002
***************
*** 0 ****
--- 1,41 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($wscell, $path, @pos1, @pos2, @neg1, @neg2, $ret, @tmp, @tmp2, @tmp3, $found);
+ &AFS_Init();
+ $wscell = &AFS_fs_wscell();
+ $found = 0;
+ 
+ eval { &AFS_pts_createuser(user1,,); };
+ $path = "/afs/${wscell}/service/acltest";
+ mkdir $path, 0777;
+ ($pos1, $neg1) = &AFS_fs_getacl($path);
+ $ret = &AFS_fs_setacl([$path],[["user1", "rl"]],,);
+ ($pos2, $neg2) = &AFS_fs_getacl($path);
+ while ($ret = pop(@$pos2)) {
+     @tmp2=@$ret;
+     if ($tmp2[0] eq "user1") { 
+ 	$found++; 
+     } else { 
+ 	unshift @tmp, @$ret;
+     }
+ }
+ 
+ @tmp2=();
+ while ($ret = pop(@$pos1)) {
+     unshift @tmp2, @$ret;
+ }
+ 
+ if ($found != 1) {
+     exit(1);
+ }
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/aclclearnegrights.pl
diff -c /dev/null openafs/src/tests/aclclearnegrights.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/aclclearnegrights.pl	Sun Jan 20 04:18:06 2002
***************
*** 0 ****
--- 1,48 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($wscell, $path, @pos1, @pos2, @neg1, @neg2, $ret, @tmp, @tmp2, @tmp3, $found);
+ &AFS_Init();
+ $wscell = &AFS_fs_wscell();
+ $found = 0;
+ 
+ eval { &AFS_pts_createuser(user1,,); };
+ $path = "/afs/${wscell}/service/acltest";
+ mkdir $path, 0777;
+ ($pos1, $neg1) = &AFS_fs_getacl($path);
+ $ret = &AFS_fs_setacl([$path],[],[["user1", "r"]],);
+ ($pos2, $neg2) = &AFS_fs_getacl($path);
+ while ($ret = pop(@$neg2)) {
+     @tmp2=@$ret;
+     if ($tmp2[0] eq "user1") { 
+ 	if ($tmp2[1] ne "r") {
+ 	    exit 1;
+ 	}
+ 	$tmp2[1] = "rl";
+ 	unshift @tmp, @tmp2;
+     } else {
+ 	unshift @tmp, @$ret;
+     }
+ }
+ 
+ @tmp2=();
+ while ($ret = pop(@$neg1)) {
+     unshift @tmp2, @$ret;
+ }
+ 
+ if (@tmp != @tmp2) {
+     exit(1);
+ }
+ if (@pos1 != @pos2) {
+     exit(1);
+ }
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/aclcopy.pl
diff -c /dev/null openafs/src/tests/aclcopy.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/aclcopy.pl	Sun Jan 20 04:18:06 2002
***************
*** 0 ****
--- 1,32 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($wscell, $path, @pos1, @pos2, @neg1, @neg2, $ret, @tmp, @tmp2, @tmp3, $found, $path2);
+ &AFS_Init();
+ $wscell = &AFS_fs_wscell();
+ $found = 0;
+ 
+ eval { &AFS_pts_createuser(user1,,); };
+ $path = "/afs/${wscell}/service/acltest";
+ $path2 = "/afs/${wscell}/service/acltest2";
+ mkdir $path, 0777;
+ mkdir $path2, 0777;
+ ($pos1, $neg1) = &AFS_fs_getacl($path);
+ $ret = &AFS_fs_copyacl($path,[$path2],1);
+ ($pos2, $neg2) = &AFS_fs_getacl($path2);
+ if (@pos1 != @pos2) {
+     exit(1);
+ }
+ if (@neg1 != @neg2) {
+     exit(1);
+ }
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/aclremovegroup.pl
diff -c /dev/null openafs/src/tests/aclremovegroup.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/aclremovegroup.pl	Sun Jan 20 04:18:06 2002
***************
*** 0 ****
--- 1,52 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($wscell, $path, @pos1, @pos2, @neg1, @neg2, $ret, @tmp, @tmp2, @tmp3, $found, $listref, $first);
+ &AFS_Init();
+ $wscell = &AFS_fs_wscell();
+ $found = 0;
+ $first = 0;
+ 
+ $path = "/afs/${wscell}/service/acltest";
+ mkdir $path, 0777;
+ ($pos1, $neg1) = &AFS_fs_getacl($path);
+ $listref = "[ ";
+ while ($ret = pop(@$pos1)) {
+     $first++;
+     @tmp2=@$ret;
+     if ($tmp2[0] eq "group1") { 
+ 	$found++; 
+     } else { 
+ 	unshift @tmp, @$ret;
+ 	if ($first == 0 ) {
+ 	    $listref = $listref . "[ @tmp2 ]";
+ 	} else {
+ 	    $listref = $listref . ", [ @tmp2 ]";
+ 	}
+     }
+ }
+ $listref = $listref . " ]";
+ 
+ if ($found != 1) {
+     print "WARNING: Can't remove user not on ACL. This shouldn't happen.\n";
+     exit(1);
+ }
+ 
+ $ret = &AFS_fs_setacl([$path],$listref,,);
+ ($pos2, $neg2) = &AFS_fs_getacl($path);
+ 
+ @tmp2=();
+ while ($ret = pop(@$pos1)) {
+     unshift @tmp2, @$ret;
+ }
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/aclremoveuser.pl
diff -c /dev/null openafs/src/tests/aclremoveuser.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/aclremoveuser.pl	Sun Jan 20 04:18:06 2002
***************
*** 0 ****
--- 1,52 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($wscell, $path, @pos1, @pos2, @neg1, @neg2, $ret, @tmp, @tmp2, @tmp3, $found, $listref, $first);
+ &AFS_Init();
+ $wscell = &AFS_fs_wscell();
+ $found = 0;
+ $first = 0;
+ 
+ $path = "/afs/${wscell}/service/acltest";
+ mkdir $path, 0777;
+ ($pos1, $neg1) = &AFS_fs_getacl($path);
+ $listref = "[ ";
+ while ($ret = pop(@$pos1)) {
+     $first++;
+     @tmp2=@$ret;
+     if ($tmp2[0] eq "user1") { 
+ 	$found++; 
+     } else { 
+ 	unshift @tmp, @$ret;
+ 	if ($first == 0 ) {
+ 	    $listref = $listref . "[ @tmp2 ]";
+ 	} else {
+ 	    $listref = $listref . ", [ @tmp2 ]";
+ 	}
+     }
+ }
+ $listref = $listref . " ]";
+ 
+ if ($found != 1) {
+     print "WARNING: Can't remove user not on ACL. This shouldn't happen.\n";
+     exit(1);
+ }
+ 
+ $ret = &AFS_fs_setacl([$path],$listref,,);
+ ($pos2, $neg2) = &AFS_fs_getacl($path);
+ 
+ @tmp2=();
+ while ($ret = pop(@$pos1)) {
+     unshift @tmp2, @$ret;
+ }
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/afs-newcell.pl
diff -c /dev/null openafs/src/tests/afs-newcell.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/afs-newcell.pl	Sun Jan 20 04:18:06 2002
***************
*** 0 ****
--- 1,294 ----
+ #!/usr/bin/env perl -w
+ # Copyright (C) 2000 by Sam Hartman
+ # This file may be copied either under the terms of the GNU GPL or the IBM Public License
+ # either version 2 or later of the GPL or version 1.0 or later of the IPL.
+ 
+ use Term::ReadLine;
+ use strict;
+ use OpenAFS::ConfigUtils;
+ use OpenAFS::Dirpath;
+ use OpenAFS::OS;
+ use OpenAFS::Auth;
+ use Getopt::Long;
+ use vars qw($admin $server $cellname $cachesize $part
+           $requirements_met  $shutdown_needed $csdb);
+ my $rl = new Term::ReadLine('afs-newcell');
+ 
+ =head1  NAME
+ 
+    afs-newcell - Set up initial database server for AFS cell.
+ 
+ =head1 SYNOPSIS
+ 
+ B<afs-newcell> [B<--requirements-met>] [B<--admin> admin_user] [B<--cellname> cellname] [B<--cachesize> size] [B<--partition> partition-letter]
+ 
+ =head1 DESCRIPTION
+ 
+ 
+ This script sets up the initial AFS database and configures the first
+ database/file server. It also sets up an AFS cell's root volumes.  It 
+ assumes that you already have a fileserver and database servers.  The 
+ fileserver should have an empty root.afs. This script creates root.cell, 
+ user, service and populates root.afs.  
+ 
+ The B<requirements-met> option specifies that the initial requirements
+ have been met and that the script can proceed without displaying the
+ initial banner or asking for confirmation.
+ 
+ The B<admin> option specifies the name of the administrative user.
+ This user will be given system:administrators and susers permission in
+ the cell.
+ 
+ The B<cellname> option specifies the name of the cell.
+ 
+ The B<cachesize> option specifies the size of the AFS cache.
+ 
+ =head1 AUTHOR
+ 
+ Sam Hartman <hartmans@debian.org>
+ 
+ =cut
+ 
+ # main script
+ 
+ # mkvol(volume, mount)
+ sub mkvol($$) {
+     my ($vol, $mnt) = @_;
+     run("$openafsdirpath->{'afssrvsbindir'}/vos create $server $part $vol -localauth");
+     unwind("$openafsdirpath->{'afssrvsbindir'}/vos remove $server $part $vol -localauth");
+     run("$openafsdirpath->{'afssrvbindir'}/fs mkm $mnt $vol ");
+     run("$openafsdirpath->{'afssrvbindir'}/fs sa $mnt system:anyuser rl");
+ }
+ 
+ GetOptions (
+            "requirements-met" => \$requirements_met, 
+            "cellname=s" => \$cellname, 
+ 	   "cachesize=s" => \$cachesize,
+            "partition=s" => \$part,
+            "admin=s" => \$admin);
+ 
+ unless ($requirements_met) {
+   print <<eoreqs;
+                            Prerequisites
+ 
+ In order to set up a new AFS cell, you must meet the following:
+ 
+ 1) You need a working Kerberos realm with Kerberos4 support.  You
+    should install Heimdal with Kth-kerberos compatibility or MIT
+    Kerberos5.
+ 
+ 2) You need to create the single-DES AFS key and load it into
+    $openafsdirpath->{'afsconfdir'}/KeyFile.  If your cell's name is the same as
+    your Kerberos realm then create a principal called afs.  Otherwise,
+    create a principal called afs/cellname in your realm.  The cell
+    name should be all lower case, unlike Kerberos realms which are all
+    upper case.  You can use asetkey from the openafs-krb5 package, or
+    if you used AFS3 salt to create the key, the bos addkey command.
+ 
+ 3) This machine should have a filesystem mounted on /vicepa.  If you
+    do not have a free partition, on Linux you can create a large file by using
+    dd to extract bytes from /dev/zero.  Create a filesystem on this file
+    and mount it using -oloop.  
+ 
+ 4) You will need an administrative principal created in a Kerberos
+    realm.  This principal will be added to susers and
+    system:administrators and thus will be able to run administrative
+    commands.  Generally the user is a root instance of some administravie
+    user.  For example if jruser is an administrator then it would be
+    reasonable to create jruser/root and specify jruser/root as the user
+    to be added in this script.
+ 
+ 5) The AFS client must not be running on this workstation.  It will be
+    at the end of this script.
+ 
+ eoreqs
+ 
+   $_ = $rl->readline("Do you meet these requirements? [y/n] ");
+   unless (/^y/i ) {
+     print "Run this script again when you meet the requirements\n";
+     exit(1);
+   }
+        
+   if ($> != 0) {
+     die "This script should almost always be run as root.  Use the --requirements-met option to run as non-root.\n";
+   }
+ }
+ open(MOUNT, "mount |") or die "Failed to run mount: $!\n";
+ while(<MOUNT>) {
+   if(m:^AFS:) {
+     print "The AFS client is currently running on this workstation.\n";
+     print "Please restart this script after running $openafsinitcmd->{'client-stop'}\n";
+     exit(1);
+   }
+   if(m:^/afs on AFS:) {
+     print "The AFS client is currently running on this workstation.\n";
+     print "Please restart this script after running $openafsinitcmd->{'client-stop'}\n";
+     exit(1);
+   }
+ }
+ close MOUNT;
+ 
+ unless ( -f "$openafsdirpath->{'afsconfdir'}/KeyFile") {
+   print "You do not have an AFS keyfile.  Please create this using asetkey from openafs-krb5 or 
+ the bos addkey command";
+   exit(1);
+ }
+ 
+ print "If the fileserver is not running, this may hang for 30 seconds.\n";
+ run("$openafsinitcmd->{'filesrv-stop'}");
+ $server = `hostname`;
+ chomp $server;
+ $admin = $rl->readline("What administrative principal should be used? ") unless $admin;
+  die "Please specify an administrative user\n" unless $admin;
+ $admin =~ s:/:.:g;
+ if($admin =~ /@/) {
+ die "The administrative user must be in the same realm as the cell and no realm may be specified.\n";
+ }
+ 
+ $cellname = $rl->readline("What cellname should be used? ") unless $cellname;
+ die "Please specify a cellname\n" unless $cellname;
+ 
+ if (! -f "$openafsdirpath->{'afsconfdir'}/ThisCell") {
+     open(CELL, "> $openafsdirpath->{'afsconfdir'}/ThisCell");
+     print CELL "${cellname}";
+     close CELL;
+ }
+ 
+ open(CELL, "$openafsdirpath->{'afsconfdir'}/ThisCell") or
+     die "Cannot open $openafsdirpath->{'afsconfdir'}/ThisCell: $!\n";
+ 
+ my $lcell = <CELL>;
+ chomp $lcell;
+ close CELL;
+ 
+ run( "echo \\>$lcell >$openafsdirpath->{'afsconfdir'}/CellServDB");
+ $csdb = `host $server|awk '{print $4 " #" $1}'`;
+ run( "echo $csdb >>$openafsdirpath->{'afsconfdir'}/CellServDB");
+ run("$openafsinitcmd->{'filesrv-start'}");
+ unwind("$openafsinitcmd->{'filesrv-stop'}");
+ $shutdown_needed = 1;
+ run ("$openafsdirpath->{'afssrvbindir'}/bos addhost $server $server -localauth ||true");
+ run("$openafsdirpath->{'afssrvbindir'}/bos adduser $server $admin -localauth");
+ unwind("$openafsdirpath->{'afssrvbindir'}/bos removeuser $server $admin -localauth");
+ if ( -f "$openafsdirpath->{'afsdbdir'}/prdb.DB0" ) {
+   die "Protection database already exists; cell already partially created\n";
+  }
+ open(PRDB, "|$openafsdirpath->{'afssrvsbindir'}/pt_util -p $openafsdirpath->{'afsdbdir'}/prdb.DB0 -w ")
+ or die "Unable to start pt_util: $!\n";
+ print PRDB "$admin 128/20 1 -204 -204\n";
+ print PRDB "system:administrators 130/20 -204 -204 -204\n";
+ print PRDB" $admin 1\n";
+ close PRDB;
+ unwind( "rm $openafsdirpath->{'afsdbdir'}/prdb* ");
+ # Start up ptserver and vlserver
+ run("$openafsdirpath->{'afssrvbindir'}/bos create $server ptserver simple $openafsdirpath->{'afssrvlibexecdir'}/ptserver -localauth");
+ unwind("$openafsdirpath->{'afssrvbindir'}/bos delete $server ptserver -localauth");
+ 
+ run("$openafsdirpath->{'afssrvbindir'}/bos create $server vlserver simple $openafsdirpath->{'afssrvlibexecdir'}/vlserver -localauth");
+ unwind("$openafsdirpath->{'afssrvbindir'}/bos delete $server vlserver -localauth");
+ 
+ run( "$openafsdirpath->{'afssrvbindir'}/bos create $server fs fs ".
+      "-cmd $openafsdirpath->{'afssrvlibexecdir'}/fileserver ".
+      "-cmd $openafsdirpath->{'afssrvlibexecdir'}/volserver ".
+      "-cmd $openafsdirpath->{'afssrvlibexecdir'}/salvager -localauth");
+ unwind( "$openafsdirpath->{'afssrvbindir'}/bos delete $server fs -localauth ");
+ 
+ print "Waiting for database elections: ";
+ sleep(30);
+ print "done.\n";
+ # Past this point we want to control when bos shutdown happens
+ $shutdown_needed = 0;
+ unwind( "$openafsdirpath->{'afssrvbindir'}/bos shutdown $server -localauth ");
+ run("$openafsdirpath->{'afssrvsbindir'}/vos create $server a root.afs -localauth");
+ # bring up client
+ 
+ $cachesize = $rl->readline("What size cache (in 1k blocks)? ") unless $cachesize;
+ die "Please specify a cache size\n" unless $cachesize;
+ 
+ run("echo $lcell >$openafsdirpath->{'viceetcdir'}/ThisCell");
+ run("cp $openafsdirpath->{'afsconfdir'}/CellServDB $openafsdirpath->{'viceetcdir'}/CellServDB");
+ run("echo /afs:/usr/vice/cache:${cachesize} >$openafsdirpath->{'viceetcdir'}/cacheinfo");
+ run("$openafsinitcmd->{'client-forcestart'}");
+ my $afs_running = 0;
+ open(MOUNT, "mount |") or die "Failed to run mount: $!\n";
+ while(<MOUNT>) {
+ if(m:^AFS:) {
+        $afs_running = 1;
+ }
+        }
+ unless ($afs_running) {
+ print "*** The AFS client failed to start.\n";
+ print  "Please fix whatever problem kept it from running.\n";
+        exit(1);
+ }
+ unwind("$openafsinitcmd->{'client-stop'}");
+ 
+ unless ($part) {
+     $part = $rl    ->readline("What partition? [a] ");
+     $part = "a" unless $part;
+ }
+ 
+ &OpenAFS::Auth::authadmin();
+ 
+ run("$openafsdirpath->{'afssrvbindir'}/fs sa /afs system:anyuser rl");
+ 
+ run("$openafsdirpath->{'afssrvsbindir'}/vos create $server $part root.cell -localauth");
+ unwind("$openafsdirpath->{'afssrvsbindir'}/vos remove $server $part root.cell -localauth");
+ # We make root.cell s:anyuser readable after we mount in the next
+ # loop.
+ open(CELLSERVDB, "$openafsdirpath->{'viceetcdir'}/CellServDB")
+     or die "Unable to open $openafsdirpath->{'viceetcdir'}/CellServDB: $!\n";
+ while(<CELLSERVDB>) {
+     chomp;
+     if (/^>\s*([a-z0-9_\-.]+)/ ) {
+        run("$openafsdirpath->{'afssrvbindir'}/fs mkm /afs/$1 root.cell -cell $1 -fast");
+        unwind ("$openafsdirpath->{'afssrvbindir'}/fs rmm /afs/$1");
+    }
+ }
+ 
+ run("$openafsdirpath->{'afssrvbindir'}/fs sa /afs/$lcell system:anyuser rl");
+ run ("$openafsdirpath->{'afssrvbindir'}/fs mkm /afs/.$lcell root.cell -cell $lcell -rw");
+ unwind ("$openafsdirpath->{'afssrvbindir'}/fs rmm /afs/.$lcell");
+ run("$openafsdirpath->{'afssrvbindir'}/fs mkm /afs/.root.afs root.afs -rw");
+ unwind ("$openafsdirpath->{'afssrvbindir'}/fs rmm /afs/.root.afs");
+ 
+ mkvol( "user", "/afs/$lcell/user" );
+ unwind( "$openafsdirpath->{'afssrvsbindir'}/vos remove $server $part user -localauth ");
+ 
+ mkvol( "service", "/afs/$lcell/service" );
+ unwind( "$openafsdirpath->{'afssrvsbindir'}/vos remove $server $part service -localauth ");
+ 
+ mkvol( "rep", "/afs/$lcell/.replicated" );
+ unwind( "$openafsdirpath->{'afssrvsbindir'}/vos remove $server $part rep -localauth ");
+ run( "$openafsdirpath->{'afssrvbindir'}/fs mkm /afs/$lcell/replicated rep.readonly " );
+ 
+ run( "$openafsdirpath->{'afssrvsbindir'}/vos addsite $server $part rep -localauth" );
+ run( "$openafsdirpath->{'afssrvsbindir'}/vos release rep -localauth" );
+ unwind( "$openafsdirpath->{'afssrvsbindir'}/vos remove $server $part rep.readonly -localauth ");
+ 
+ mkvol( "unrep", "/afs/$lcell/unreplicated" );
+ unwind( "$openafsdirpath->{'afssrvsbindir'}/vos remove $server $part unrep -localauth ");
+ 
+ $lcell =~ /^([^.]*)/;
+ my $cellpart = $1;
+ run("ln -s /afs/$lcell /afs/$cellpart");
+ unwind ("rm /afs/$cellpart");
+ run( "ln -s /afs/.$lcell /afs/.$cellpart" );
+ unwind ("rm /afs/.$cellpart");
+ 
+ run( "$openafsdirpath->{'afssrvsbindir'}/vos addsite $server $part root.afs -localauth" );
+ run( "$openafsdirpath->{'afssrvsbindir'}/vos addsite $server $part root.cell -localauth" );
+ run( "$openafsdirpath->{'afssrvsbindir'}/vos release root.afs -localauth" );
+ run( "$openafsdirpath->{'afssrvsbindir'}/vos release root.cell -localauth" );
+ unwind( "$openafsdirpath->{'afssrvsbindir'}/vos remove $server $part root.cell.readonly -localauth ");
+ unwind( "$openafsdirpath->{'afssrvsbindir'}/vos remove $server $part root.afs.readonly -localauth ");
+ 
+ 
+ 
+ @unwinds = ();
+ END {
+ # If we fail before all the instances are created, we need to perform 
+ # our own bos shutdown
+     system("$openafsdirpath->{'afssrvbindir'}/bos shutdown $server -localauth") if $shutdown_needed;
+   run(pop @unwinds) while @unwinds;
+   }
Index: openafs/src/tests/afs-rmcell.sh
diff -c /dev/null openafs/src/tests/afs-rmcell.sh:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/afs-rmcell.sh	Sun Jan 20 04:18:06 2002
***************
*** 0 ****
--- 1,7 ----
+ #!/bin/sh
+ /bin/rm -rf /usr/afs/db/prdb.DB0 /usr/afs/db/prdb.DBSYS1 /usr/afs/db/vldb.DB0 /usr/afs/db/vldb.DBSYS1 /usr/afs/local/BosConfig /usr/afs/etc/UserList /usr/afs/etc/ThisCell /usr/afs/etc/CellServDB 
+ /bin/rm -rf /vicepa/AFSIDat 
+ /bin/rm -rf /vicepb/AFSIDat
+ /bin/rm -rf /vicepa/V*.vol
+ /bin/rm -rf /vicepb/V*.vol
+ exit 0
Index: openafs/src/tests/afscp.c
diff -c /dev/null openafs/src/tests/afscp.c:1.2.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/afscp.c	Sun Jan 20 04:18:06 2002
***************
*** 0 ****
--- 1,500 ----
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <errno.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #include <arpa/inet.h>
+ #include <unistd.h>
+ #include <fcntl.h>
+ #include <sys/select.h>
+ #include <sys/stat.h>
+ 
+ #include <afs/param.h>
+ #include <afs/afsint.h>
+ #include <sys/ioctl.h>
+ #include <afs/venus.h>
+ #include <afs/cellconfig.h>
+ #include <afs/afs.h>
+ 
+ /*#include <rx/rxkad.h>*/
+ #include <rx/rx_null.h>
+ 
+ /*#include <krb.h>*/
+ #include <afs/com_err.h>
+ 
+ struct VenusFid {
+     afs_int32 Cell;
+     struct AFSFid Fid;
+ };
+ 
+ int statfile(char *path, char *cellname, afs_uint32 *server, 
+              struct AFSFid *f)
+ {
+      
+      struct ViceIoctl v;
+      struct VenusFid vf;
+      afs_int32 srvbuf[MAXHOSTS];
+      int code;
+      
+      v.in=0;
+      v.in_size=0;
+      v.out=cellname;
+      v.out_size=MAXCELLCHARS;
+      if ((code=pioctl(path, VIOC_FILE_CELL_NAME, &v, 1)))
+           return code;
+      
+      v.out=(char *)&vf;
+      v.out_size=sizeof(struct VenusFid);
+      if ((code=pioctl(path, VIOCGETFID, &v, 1)))
+           return code;
+      memcpy(f,&vf.Fid, sizeof(struct AFSFid));
+      
+      v.out=(char *)srvbuf;
+      v.out_size=sizeof(srvbuf);
+      if ((code=pioctl(path, VIOCWHEREIS, &v, 1)))
+           return code;
+      if (v.out_size <= sizeof(afs_int32))
+           return EINVAL;
+      
+      memcpy(server, srvbuf, sizeof(afs_int32));
+      return 0;
+ }
+ 
+ 
+ extern int RXAFSCB_ExecuteRequest();
+ struct rx_securityClass *sc;
+ 
+ extern int start_cb_server() 
+ {
+      struct rx_service *s;
+ 
+      sc=rxnull_NewServerSecurityObject();
+      s=rx_NewService(0,1,"afs", &sc, 1, RXAFSCB_ExecuteRequest);
+      if (!s)
+           return 1;
+      rx_StartServer(0);
+      return 0;
+ }
+ 
+ 
+ /*extern int rx_socket;*/
+ extern unsigned short rx_port;
+ int do_rx_Init(void)
+ {
+      struct sockaddr_in s;
+      int len;
+ 
+      if (rx_Init(0)) {
+           fprintf(stderr, "Cannot initialize rx\n");
+           return 1;
+      }
+ 
+      len=sizeof(struct sockaddr_in);
+      if (getsockname(rx_socket, &s, &len)) {
+           perror("getsockname");
+           return 1;
+      }
+      rx_port=ntohs(s.sin_port);
+ 
+      return 0;
+ }
+ 
+ struct rx_securityClass *get_sc(char * cellname) 
+ {
+ #if 0
+      char realm[REALM_SZ];
+      CREDENTIALS c;
+ #endif
+      
+      return rxnull_NewClientSecurityObject();
+ #if 0     
+ 
+      ucstring(realm, cellname, REALM_SZ);
+      
+      if (krb_get_cred("afs", "", realm, &c)) {
+           if (get_ad_tkt("afs","",realm, DEFAULT_TKT_LIFE)) {
+                return NULL;
+           } else {
+                if (krb_get_cred("afs", "", realm, &c)) {
+                     return NULL;
+                }
+           }
+      }
+      
+      return rxkad_NewClientSecurityObject(rxkad_clear, c.session, c.kvno, 
+                                           c.ticket_st.length, c.ticket_st.dat);
+ #endif
+ }
+ 
+ #define scindex_NULL 0
+ #define scindex_RXKAD 2
+ 
+ #define scindex scindex_RXKAD
+ int main(int argc, char **argv) 
+ {
+      char scell[MAXCELLCHARS], dcell[MAXCELLCHARS];
+      afs_uint32 ssrv, dsrv;
+      char *databuffer,*srcf,*destd,*destf,*destpath;
+      struct stat statbuf;
+      
+      struct AFSStoreStatus sst;
+      struct AFSFetchStatus fst,dfst;
+      struct AFSVolSync vs;
+      struct AFSCallBack scb,dcb;
+      struct AFSFid sf, dd, df;
+     
+      int filesz;
+      int ch, blksize, bytesremaining, bytes;
+      struct timeval start, finish;
+      struct timezone tz;
+      struct rx_securityClass *ssc = 0, *dsc = 0;
+      int sscindex, dscindex;
+      struct rx_connection *sconn,*dconn;
+      struct rx_call *scall, *dcall;
+      int code,fetchcode,storecode,printcallerrs;
+      int slcl = 0, dlcl = 0;
+      int sfd, dfd, unauth = 0;
+ 
+      struct AFSCBFids theFids;
+      struct AFSCBs theCBs;
+ 
+ 
+      blksize=8*1024;
+      
+      while ((ch=getopt(argc, argv, "ioub:")) != -1) {
+           switch(ch)
+           {
+           case 'b':
+                blksize=atoi(optarg);
+                break;
+           case 'i':
+                slcl=1;
+                break;
+           case 'o':
+                dlcl=1;
+                break;
+           case 'a':
+                unauth=1;
+                break;
+           default:
+                exit(1);
+           }
+      }
+      
+ 
+      if (argc - optind < 2) {
+           fprintf(stderr, "Usage: afscp [-i|-o]] [-b xfersz] [-u] source dest\n");
+           fprintf(stderr, "  -b   Set block size\n");
+           fprintf(stderr, "  -i   Source is local (copy into AFS)\n");
+           fprintf(stderr, "  -o   Dest is local (copy out of AFS)\n");
+           fprintf(stderr, "  -u   Run unauthenticated\n");
+           exit(1);
+      }
+      srcf=argv[optind++];
+      destpath=argv[optind++];
+      destd=strdup(destpath);
+      if (!destd) {
+           perror("strdup");
+           exit(1);
+      }
+      if ((destf=strrchr(destd, '/'))) {
+           *destf++=0;
+      } else {
+           destf=destd;
+           destd=".";
+      }
+      
+      
+      if (!slcl && statfile(srcf, scell, &ssrv, &sf)) {
+           fprintf(stderr, "Cannot get attributes of %s\n", srcf);
+           exit(1);
+      }
+      if (!dlcl && statfile(destd, dcell, &dsrv, &dd)) {
+           fprintf(stderr, "Cannot get attributes of %s\n", destd);
+           exit(1);
+      }
+     
+      if ((databuffer=malloc(blksize)) == NULL) {
+           perror("malloc");
+           exit(1);
+      }
+      
+      if (do_rx_Init())
+           exit(1);
+ 
+      if (start_cb_server()) {
+           printf("Cannot start callback service\n");
+           goto Fail_rx;
+      }
+      
+      if (!slcl) {
+           sscindex=scindex_RXKAD;
+           if (unauth || (ssc=get_sc(scell)) == NULL) {
+                ssc=rxnull_NewClientSecurityObject();
+                sscindex=scindex_NULL;
+                /*printf("Cannot get authentication for cell %s; running unauthenticated\n", scell);*/
+           }
+                sscindex=scindex_NULL;
+ 
+           if ((sconn=rx_NewConnection(ssrv, htons(AFSCONF_FILEPORT), 1, ssc, 
+                                       sscindex))
+                 ==NULL) {
+                struct in_addr s;
+                s.s_addr=ssrv;
+                printf("Cannot initialize rx connection to source server (%s)\n",
+                       inet_ntoa(s));
+                goto Fail_sc;
+           }
+      }
+      
+      if (!dlcl) {
+           if (!slcl && ssrv == dsrv) {
+                dconn=sconn;
+                dsc=NULL;
+           } else {
+                if (slcl || strcmp(scell, dcell)){
+                     dscindex=scindex_RXKAD;
+                     if (unauth || (dsc=get_sc(dcell)) == NULL) {
+                          dsc=rxnull_NewClientSecurityObject();
+                          dscindex=scindex_NULL;
+                          /*printf("Cannot get authentication for cell %s; running unauthenticated\n", dcell);*/
+                     }
+                dscindex=scindex_NULL;
+                } else {
+                     dsc=ssc;
+                     dscindex=sscindex;
+                }
+           
+                if ((dconn=rx_NewConnection(dsrv, htons(AFSCONF_FILEPORT), 1, dsc,
+                                            dscindex))
+                    ==NULL) {
+                     struct in_addr s;
+                     s.s_addr=dsrv;
+                     printf("Cannot initialize rx connection to dest server (%s)\n",
+                            inet_ntoa(s));
+                     goto Fail_sconn;
+                }
+           }
+      }
+      
+      
+      memset(&sst, 0, sizeof(struct AFSStoreStatus));
+      
+      if (dlcl) {
+           dfd = open(destpath, O_RDWR|O_CREAT|O_EXCL, 0666);
+           if (dfd < 0 && errno == EEXIST) {
+                printf("%s already exists, overwriting\n", destpath);
+                dfd = open(destpath, O_RDWR|O_TRUNC, 0666);
+                if (dfd < 0) {
+                     fprintf(stderr, "Cannot open %s (%s)\n", destpath,
+                             error_message(errno));
+                     goto Fail_dconn;
+                }
+           } else if (dfd < 0) {
+                fprintf(stderr, "Cannot open %s (%s)\n", destpath,
+                        error_message(errno));
+                goto Fail_dconn;
+           }
+      } else {
+           if ((code=RXAFS_CreateFile(dconn, &dd, destf, &sst, &df, &fst,
+                                      &dfst, &dcb, &vs))) {
+                if (code == EEXIST) {
+                     printf("%s already exits, overwriting\n", destpath);
+                     if (statfile(destpath, dcell, &dsrv, &df))
+                          fprintf(stderr, "Cannot get attributes of %s\n",
+                                  destpath);
+                     else
+                          code=0;
+                } else {
+                     printf("Cannot create %s (%s)\n", destpath,
+                            error_message(code));
+                if (code)
+                     goto Fail_dconn;
+                }
+           }
+      }
+ 
+      if (slcl) {
+           sfd = open(srcf, O_RDONLY, 0);
+           if (sfd < 0) {
+                fprintf(stderr, "Cannot open %s (%s)\n", srcf,
+                        error_message(errno));
+                goto Fail_dconn;
+           }
+           if (fstat(sfd, &statbuf) < 0) {
+                fprintf(stderr, "Cannot stat %s (%s)\n", srcf,
+                        error_message(errno));
+                close(sfd);
+                goto Fail_dconn;
+           }
+      } else {
+           if ((code=RXAFS_FetchStatus(sconn, &sf, &fst, &scb, &vs))) {
+                printf("Cannot fetchstatus of %d.%d (%s)\n", sf.Volume, sf.Vnode, 
+                       error_message(code));
+                goto Fail_dconn;
+           }
+      }
+      
+      
+ 
+      if (slcl) {
+           filesz=statbuf.st_size;
+      } else {
+           filesz=fst.Length;
+      }
+      
+      printcallerrs=0;
+      fetchcode=0;
+      storecode=0;
+      if (!slcl) scall=rx_NewCall(sconn);
+      if (!dlcl) dcall=rx_NewCall(dconn);
+      gettimeofday(&start, &tz);
+      
+      if (!slcl) {
+           if ((code = StartRXAFS_FetchData(scall, &sf, 0, filesz))) {
+                printf("Unable to fetch data from %s (%s)\n", srcf, 
+                       error_message(code));
+                goto Fail_call;
+           }
+      }
+ 
+      if (!dlcl) {
+           if (slcl) {
+                sst.Mask=AFS_SETMODTIME|AFS_SETMODE;
+                sst.ClientModTime=statbuf.st_mtime;
+                sst.UnixModeBits=statbuf.st_mode & ~(S_IFMT|S_ISUID|S_ISGID);
+           } else {
+                sst.Mask=AFS_SETMODTIME|AFS_SETMODE;
+                sst.ClientModTime=fst.ClientModTime;
+                sst.UnixModeBits=fst.UnixModeBits & ~(S_IFMT|S_ISUID|S_ISGID);
+           }
+      
+           if ((code = StartRXAFS_StoreData(dcall, &df, &sst, 0, filesz, filesz))) {
+                printf("Unable to store data to %s (%s)\n", destpath, 
+                       error_message(code));
+                goto Fail_call;
+           }
+      }
+ 
+      if (slcl) {
+           bytesremaining=statbuf.st_size;
+      } else {
+           rx_Read(scall,&bytesremaining,sizeof(afs_int32));
+           bytesremaining=ntohl(bytesremaining);
+      }
+      
+      while (bytesremaining >0) {
+           /*printf("%d bytes remaining\n",bytesremaining);*/
+           if (slcl) {
+                if ((bytes=read(sfd, databuffer,
+                                   min(blksize,bytesremaining)))<= 0) {
+                     fetchcode=errno;
+                     break;
+                }
+           } else {
+                if ((bytes=rx_Read(scall, databuffer,
+                                   min(blksize,bytesremaining)))<= 0)
+                     break;
+           }
+           if (dlcl) {
+                if (write(dfd, databuffer, bytes) != bytes) {
+                     storecode=errno;
+                     break;
+                }
+           } else {
+                if (rx_Write(dcall, databuffer, bytes) != bytes)
+                     break;
+           }
+           bytesremaining -= bytes;
+           /*printf("%d bytes copied\n",bytes);*/
+      }
+           
+ 
+      if (bytesremaining > 0) {
+           printf("Some network error occured while copying data\n");
+           goto Fail_call;
+      }
+      
+      if (!slcl) fetchcode = EndRXAFS_FetchData(scall, &fst, &scb, &vs);
+      if (!dlcl) storecode = EndRXAFS_StoreData(dcall, &fst, &vs);
+      printcallerrs=1;
+  Fail_call:
+           
+      if (slcl) {
+           if (close(sfd) && !fetchcode) fetchcode = errno;
+      } else {
+           fetchcode = rx_EndCall(scall, fetchcode);
+      }
+      if (fetchcode && printcallerrs)
+           printf("Error returned from fetch: %s\n", error_message(fetchcode));
+ 
+      if (dlcl) {
+           if (close(dfd) && !storecode) storecode = errno;
+      } else {
+           storecode = rx_EndCall(dcall, storecode);
+      }
+      if (storecode && printcallerrs)
+           printf("Error returned from store: %s\n", error_message(storecode));
+      
+      gettimeofday(&finish, &tz);
+      
+      if (!slcl) {
+           theFids.AFSCBFids_len=1;
+           theFids.AFSCBFids_val=&sf;
+           theCBs.AFSCBs_len=1;
+           theCBs.AFSCBs_val=&scb;
+           scb.CallBackType = CB_DROPPED;
+           if ((code=RXAFS_GiveUpCallBacks(sconn, &theFids, &theCBs)))
+                printf("Could not give up source callback: %s\n",
+                       error_message(code));
+      }
+ 
+      if (!dlcl) {
+           theFids.AFSCBFids_len=1;
+           theFids.AFSCBFids_val=&df;
+           theCBs.AFSCBs_len=1;
+           theCBs.AFSCBs_val=&dcb;
+           dcb.CallBackType = CB_DROPPED;
+           if ((code=RXAFS_GiveUpCallBacks(dconn, &theFids, &theCBs)))
+                printf("Could not give up target callback: %s\n",
+                       error_message(code));
+      }
+ 
+      if (code==0)
+           code=storecode;
+      if (code==0)
+           code=fetchcode;
+      
+  Fail_dconn:
+      if (!dlcl && (slcl || dconn != sconn))
+           rx_DestroyConnection(dconn);
+  Fail_sconn:
+      if (!slcl) rx_DestroyConnection(sconn);
+  Fail_sc:
+      if (dsc && dsc != ssc)
+           RXS_Close(dsc);
+      if (ssc) RXS_Close(ssc);
+  Fail_rx:
+      rx_Finalize();
+      
+      free(databuffer);
+      if (printcallerrs) {
+           double rate,size,time;
+           if (finish.tv_sec == start.tv_sec) {
+                printf("Copied %d bytes in %d microseconds\n", filesz, finish.tv_usec
+                       -start.tv_usec);
+           } else {
+                printf("Copied %d bytes in %d seconds\n", filesz, finish.tv_sec
+                       -start.tv_sec);
+           }
+           
+           size=filesz/1024.0;
+           time=finish.tv_sec-start.tv_sec + (finish.tv_usec-start.tv_usec)/1e+06;
+           rate=size/time;
+           printf("Transfer rate %g Kbytes/sec\n", rate);
+      
+      }
+      
+      exit(code != 0);
+ }
Index: openafs/src/tests/afscp_callback.c
diff -c /dev/null openafs/src/tests/afscp_callback.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/afscp_callback.c	Sun Jan 20 04:18:06 2002
***************
*** 0 ****
--- 1,156 ----
+ #include <afs/param.h>
+ #include <afs/afscbint.h>               /*Callback interface defs*/
+ int afs_cb_inited = 0;
+ struct interfaceAddr afs_cb_interface;
+ static int init_afs_cb() {
+     int count;
+ 
+     afs_uuid_create(&afs_cb_interface.uuid);
+     count = rx_getAllAddr(&afs_cb_interface.addr_in, AFS_MAX_INTERFACE_ADDR);
+     if ( count <= 0 )
+         afs_cb_interface.numberOfInterfaces = 0;
+     else
+         afs_cb_interface.numberOfInterfaces = count;
+     afs_cb_inited = 1;
+     return 0;
+ }
+ afs_int32 SRXAFSCB_CallBack(rxcall, Fids_Array, CallBack_Array)
+     struct rx_call *rxcall;
+     AFSCBFids *Fids_Array;
+     AFSCBs *CallBack_Array;
+ 
+ { /*SRXAFSCB_CallBack*/
+     return(0);
+ 
+ } /*SRXAFSCB_CallBack*/
+ 
+ 
+ afs_int32 SRXAFSCB_InitCallBackState(rxcall)
+     struct rx_call *rxcall;
+ 
+ { /*SRXAFSCB_InitCallBackState*/
+    return(0);
+ 
+ } /*SRXAFSCB_InitCallBackState*/
+ 
+ afs_int32 SRXAFSCB_Probe(rxcall)
+         struct rx_call *rxcall;
+ 
+ { /*SRXAFSCB_Probe*/
+     return(0);
+ 
+ } /*SRXAFSCB_Probe*/
+ 
+ 
+ afs_int32 SRXAFSCB_GetCE(rxcall)
+     struct rx_call *rxcall;
+ 
+ { /*SRXAFSCB_GetCE*/
+      return(0);
+ } /*SRXAFSCB_GetCE*/
+ 
+ 
+ afs_int32 SRXAFSCB_GetCE64(rxcall)
+     struct rx_call *rxcall;
+ 
+ { /*SRXAFSCB_GetCE64*/
+      return(0);
+ } /*SRXAFSCB_GetCE64*/
+ 
+ 
+ afs_int32 SRXAFSCB_GetLock(rxcall)
+     struct rx_call *rxcall;
+ 
+ { /*SRXAFSCB_GetLock*/
+     return(0);
+ 
+ } /*SRXAFSCB_GetLock*/
+ afs_int32 SRXAFSCB_XStatsVersion(rxcall)
+     struct rx_call *rxcall;
+ 
+ { /*SRXAFSCB_XStatsVersion*/
+     return(0);
+ 
+ } /*SRXAFSCB_XStatsVersion*/
+ 
+ afs_int32 SRXAFSCB_GetXStats(rxcall)
+     struct rx_call *rxcall;
+ 
+ { /*SRXAFSCB_GetXStats*/
+      return(0);
+ } /*SRXAFSCB_GetXStats*/
+ 
+ int SRXAFSCB_InitCallBackState2(rxcall, addr)
+ struct rx_call *rxcall;
+ struct interfaceAddr * addr;
+ {
+     return RXGEN_OPCODE;
+ }
+ 
+ int SRXAFSCB_WhoAreYou(rxcall, addr)
+ struct rx_call *rxcall;
+ struct interfaceAddr *addr;
+ {
+     if ( rxcall && addr )
+     {
+         if (!afs_cb_inited) init_afs_cb();
+         *addr = afs_cb_interface;
+     }
+     return(0);
+ }
+ 
+ int SRXAFSCB_InitCallBackState3(rxcall, uuidp)
+ struct rx_call *rxcall;
+ afsUUID *uuidp;
+ {
+     return(0);
+ }
+ int SRXAFSCB_ProbeUuid(rxcall, uuidp)
+ struct rx_call *rxcall;
+ afsUUID *uuidp;
+ {
+     int code = 0;
+     if (!afs_cb_inited) init_afs_cb();
+     if (!afs_uuid_equal(uuidp, &afs_cb_interface.uuid))
+         code = 1; /* failure */
+     return code;
+ }
+ 
+ afs_int32 SRXAFSCB_GetServerPrefs(rxcall, serverIndex, srvrAddr, srvrRank)
+ struct rx_call *rxcall;
+ afs_int32 serverIndex;
+ afs_int32 *srvrAddr;
+ afs_int32 *srvrRank;
+ {
+     return RXGEN_OPCODE;
+ }
+ 
+ 
+ afs_int32 SRXAFSCB_GetCellServDB(rxcall, cellIndex, cellName, cellHosts)
+ struct rx_call *rxcall;
+ afs_int32 cellIndex;
+ char *cellName;
+ afs_int32 *cellHosts;
+ {
+     return RXGEN_OPCODE;
+ }
+ 
+ 
+ afs_int32 SRXAFSCB_GetLocalCell(rxcall, cellName)
+ struct rx_call *rxcall;
+ char *cellName;
+ {
+     return RXGEN_OPCODE;
+ }
+ 
+ 
+ afs_int32 SRXAFSCB_GetCacheConfig(rxcall, callerVersion, serverVersion,
+                                   configCount, config)
+ struct rx_call *rxcall;
+ afs_uint32 callerVersion;
+ afs_uint32 *serverVersion;
+ afs_uint32 *configCount;
+ cacheConfig *config;
+ {
+     return RXGEN_OPCODE;
+ }
Index: openafs/src/tests/afsdump_dirlist.c
diff -c /dev/null openafs/src/tests/afsdump_dirlist.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/afsdump_dirlist.c	Sun Jan 20 04:18:06 2002
***************
*** 0 ****
--- 1,140 ----
+ /*
+  * CMUCS AFStools
+  * dumpscan - routines for scanning and manipulating AFS volume dumps
+  *
+  * Copyright (c) 1998 Carnegie Mellon University
+  * All Rights Reserved.
+  * 
+  * Permission to use, copy, modify and distribute this software and its
+  * documentation is hereby granted, provided that both the copyright
+  * notice and this permission notice appear in all copies of the
+  * software, derivative works or modified versions, and any portions
+  * thereof, and that both notices appear in supporting documentation.
+  *
+  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+  *
+  * Carnegie Mellon requests users of this software to return to
+  *
+  *  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
+  *  School of Computer Science
+  *  Carnegie Mellon University
+  *  Pittsburgh PA 15213-3890
+  *
+  * any improvements or extensions that they make and grant Carnegie Mellon
+  * the rights to redistribute these changes.
+  */
+ 
+ /* afsdump_dirlist.c - List an AFS directory file */
+ 
+ #include <sys/fcntl.h>
+ #include <stdlib.h>
+ #include <stdarg.h>
+ #include <string.h>
+ 
+ #include "dumpscan.h"
+ 
+ extern int optind;
+ extern char *optarg;
+ 
+ char *argv0;
+ static char *input_path;
+ static int quiet, verbose, error_count;
+ 
+ static path_hashinfo phi;
+ static dump_parser dp;
+ 
+ 
+ /* Print a usage message and exit */
+ static void usage(int status, char *msg)
+ {
+   if (msg) fprintf(stderr, "%s: %s\n", argv0, msg);
+   fprintf(stderr, "Usage: %s [options] [file]\n", argv0);
+   fprintf(stderr, "  -h     Print this help message\n");
+   fprintf(stderr, "  -q     Quiet mode (don't print errors)\n");
+   fprintf(stderr, "  -v     Verbose mode\n");
+   exit(status);
+ }
+ 
+ 
+ /* Parse the command-line options */
+ static void parse_options(int argc, char **argv)
+ {
+   int c;
+ 
+   /* Set the program name */
+   if (argv0 = strrchr(argv[0], '/')) argv0++;
+   else argv0 = argv[0];
+ 
+   /* Initialize options */
+   input_path = 0;
+   quiet = verbose = 0;
+ 
+   /* Initialize other stuff */
+   error_count = 0;
+ 
+   /* Parse the options */
+   while ((c = getopt(argc, argv, "hqv")) != EOF) {
+     switch (c) {
+       case 'q': quiet        = 1;                         continue;
+       case 'v': verbose      = 1;                         continue;
+       case 'h': usage(0, 0);
+       default:  usage(1, "Invalid option!");
+     }
+   }
+ 
+   if (quiet && verbose) usage(1, "Can't specify both -q and -v");
+ 
+   /* Parse non-option arguments */
+   if (argc - optind > 1) usage(1, "Too many arguments!");
+   input_path = (argc == optind) ? "-" : argv[optind];
+ }
+ 
+ 
+ /* A callback to count and print errors */
+ static afs_uint32 my_error_cb(afs_uint32 code, int fatal, void *ref, char *msg, ...)
+ {
+   va_list alist;
+ 
+   error_count++;
+   if (!quiet) {
+     va_start(alist, msg);
+     com_err_va(argv0, code, msg, alist);
+     va_end(alist);
+   }
+ }
+ 
+ 
+ /* Main program */
+ void main(int argc, char **argv)
+ {
+   XFILE input_file;
+   afs_uint32 r;
+ 
+   parse_options(argc, argv);
+   initialize_acfg_error_table();
+   initialize_AVds_error_table();
+   initialize_rxk_error_table();
+   initialize_u_error_table();
+   initialize_vl_error_table();
+   initialize_vols_error_table();
+   initialize_xFil_error_table();
+   r = xfopen(&input_file, O_RDONLY, input_path);
+   if (r) {
+     com_err(argv0, r, "opening %s", input_path);
+     exit(2);
+   }
+ 
+   memset(&dp, 0, sizeof(dp));
+   dp.cb_error     = my_error_cb;
+   dp.print_flags  = DSPRINT_DIR;
+   if (input_file.is_seekable) dp.flags |= DSFLAG_SEEK;
+ 
+   r = ParseDirectory(&input_file, &dp, 0, 1);
+   xfclose(&input_file);
+ 
+   if (verbose && error_count) fprintf(stderr, "*** %d errors\n", error_count);
+   if (r && !quiet) fprintf(stderr, "*** FAILED: %s\n", error_message(r));
+   exit(0);
+ }
Index: openafs/src/tests/afsdump_extract.c
diff -c /dev/null openafs/src/tests/afsdump_extract.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/afsdump_extract.c	Sun Jan 20 04:18:06 2002
***************
*** 0 ****
--- 1,526 ----
+ /*
+  * CMUCS AFStools
+  * dumpscan - routines for scanning and manipulating AFS volume dumps
+  *
+  * Copyright (c) 1998 Carnegie Mellon University
+  * All Rights Reserved.
+  * 
+  * Permission to use, copy, modify and distribute this software and its
+  * documentation is hereby granted, provided that both the copyright
+  * notice and this permission notice appear in all copies of the
+  * software, derivative works or modified versions, and any portions
+  * thereof, and that both notices appear in supporting documentation.
+  *
+  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+  *
+  * Carnegie Mellon requests users of this software to return to
+  *
+  *  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
+  *  School of Computer Science
+  *  Carnegie Mellon University
+  *  Pittsburgh PA 15213-3890
+  *
+  * any improvements or extensions that they make and grant Carnegie Mellon
+  * the rights to redistribute these changes.
+  */
+ 
+ /* afsdump_extract.c - Extract files from an AFS dump */
+ 
+ #include <sys/fcntl.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <stdlib.h>
+ #include <stdarg.h>
+ #include <string.h>
+ 
+ #include "dumpscan.h"
+ #include "dumpscan_errs.h"
+ 
+ #define COPYBUFSIZE (256*1024)
+ 
+ extern int optind;
+ extern char *optarg;
+ 
+ char *argv0;
+ static char **file_names;
+ static int *file_vnums, name_count, vnum_count;
+ 
+ static char *input_path, *target;
+ static int quiet, verbose, error_count, dirs_done, extract_all;
+ static int nomode, use_realpath, use_vnum;
+ static int do_acls, do_headers;
+ 
+ static path_hashinfo phi;
+ static dump_parser dp;
+ 
+ /* Print a usage message and exit */
+ static void usage(int status, char *msg)
+ {
+   if (msg) fprintf(stderr, "%s: %s\n", argv0, msg);
+   fprintf(stderr, "Usage: %s [options] dumpfile [dest [files...]]\n", argv0);
+   fprintf(stderr, "  -A     Save ACL's\n");
+   fprintf(stderr, "  -H     Save headers\n");
+   fprintf(stderr, "  -h     Print this help message\n");
+   fprintf(stderr, "  -i     Use vnode numbers\n");
+   fprintf(stderr, "  -n     Don't actually create files\n");
+   fprintf(stderr, "  -p     Use real pathnames internally\n");
+   fprintf(stderr, "  -q     Quiet mode (don't print errors)\n");
+   fprintf(stderr, "  -v     Verbose mode\n");
+   fprintf(stderr, "The destination directory defaults to .\n");
+   fprintf(stderr, "Files may be vnode numbers or volume-relative paths;\n");
+   fprintf(stderr, "If vnode numbers are used, files will be extracted\n");
+   fprintf(stderr, "a name generated from the vnode number and uniqifier.\n");
+   fprintf(stderr, "If paths are used, -p is implied and files will be\n");
+   fprintf(stderr, "into correctly-named files.\n");
+   exit(status);
+ }
+ 
+ 
+ /* Parse the command-line options */
+ static void parse_options(int argc, char **argv)
+ {
+   int c, i, i_name, i_vnum;
+ 
+   /* Set the program name */
+   if (argv0 = strrchr(argv[0], '/')) argv0++;
+   else argv0 = argv[0];
+ 
+   /* Initialize options */
+   input_path = 0;
+   quiet = verbose = nomode = 0;
+   use_realpath = use_vnum = do_acls = do_headers = extract_all = 0;
+ 
+   /* Initialize other stuff */
+   error_count = 0;
+ 
+   /* Parse the options */
+   while ((c = getopt(argc, argv, "AHhinpqv")) != EOF) {
+     switch (c) {
+       case 'A': do_acls      = 1;                         continue;
+       case 'H': do_headers   = 1;                         continue;
+       case 'i': use_vnum     = 1;                         continue;
+       case 'n': nomode       = 1;                         continue;
+       case 'p': use_realpath = 1;                         continue;
+       case 'q': quiet        = 1;                         continue;
+       case 'v': verbose      = 1;                         continue;
+       case 'h': usage(0, 0);
+       default:  usage(1, "Invalid option!");
+     }
+   }
+ 
+   if (quiet && verbose) usage(1, "Can't specify both -q and -v");
+ 
+   /* Parse non-option arguments */
+   if (argc - optind < 1) usage(1, "Dumpfile name required!");
+   input_path = argv[optind];
+ 
+   if (argc - optind < 2) target = ".";
+   target = argv[optind + 1];
+ 
+   vnum_count = name_count = 0;
+   if (argc - optind < 3) extract_all = 1;
+   else {
+     argv += optind + 2;
+     argc -= optind + 2;
+     for (i = 0; i < argc; i++) {
+       if (argv[i][0] == '/') name_count++;
+       else                   vnum_count++;
+     }
+     file_names = (char **)malloc(name_count + sizeof(char *));
+     file_vnums = (afs_uint32 *)malloc(vnum_count + sizeof(afs_uint32));
+     if (name_count) use_realpath = 1;
+ 
+     i_name = i_vnum = 0;
+     for (i = 0; i < argc; i++) {
+       if (argv[i][0] == '/') file_names[i_name++] = argv[i];
+       else                   file_vnums[i_vnum++] = strtol(argv[i], 0, 0);
+     }
+   }
+ }
+ 
+ 
+ static int mkdirp(char *path)
+ {
+   char *x = path, slash;
+   struct stat statbuf;
+ 
+   for (;;) {
+     while (*x && *x != '/') x++;
+     slash = *x;
+     *x = 0;
+ 
+     if (stat(path, &statbuf)) {
+       if (errno == ENOENT) {
+         if (verbose) printf("> mkdir %s\n", path);
+         if (!mkdir(path, 0755)) errno = 0;
+       }
+     }
+     if (!slash) break;
+     *x++ = '/';
+     if (errno) return errno;
+   }
+ 
+   return 0;
+ }
+ 
+ 
+ static char *modestr(int mode)
+ {
+   static char str[10];
+   int i;
+ 
+   strcpy(str, "rwxrwxrwx");
+   for (i = 0; i < 9; i++) {
+     if (!(mode & (1 << i)))
+       str[8 - i] = '-';
+   }
+   if (mode & 01000) str[8] = (str[8] == '-') ? 'T' : 't';
+   if (mode & 02000) str[5] = (str[5] == '-') ? 'S' : 's';
+   if (mode & 04000) str[2] = (str[2] == '-') ? 'S' : 's';
+   return str;
+ }
+ 
+ 
+ static char *month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+                          "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+ static char *datestr(time_t date)
+ {
+   static char str[13];
+   time_t clock = time(0);
+   struct tm *now, *then;
+   int diff;
+ 
+   now = localtime(&clock);
+   then = localtime(&date);
+ 
+   diff = now->tm_mon - then->tm_mon;
+   if (then->tm_year == now->tm_year - 1) diff += 12;
+   if (then->tm_year == now->tm_year + 1) diff -= 12;
+ 
+   if (diff < 5 || diff > 5)
+     sprintf(str, "%3s %2d  %4d", month[then->tm_mon], then->tm_mday,
+             then->tm_year + 1900);
+   else
+     sprintf(str, "%3s %2d %2d:%2d", month[then->tm_mon], then->tm_mday,
+             then->tm_hour, then->tm_min);
+   return str;
+ }
+ 
+ 
+ /* Should we use this vnode?
+  * Return 0 if no, non-0 if yes
+  */
+ static int usevnode(XFILE *X, afs_uint32 vnum, char *vnodepath)
+ {
+   int vl, vpl, r, i;
+ 
+   /* Special case */
+   if (extract_all || !strcmp(vnodepath, "/"))
+     return 1;
+ 
+   for (i = 0; i < vnum_count; i++)
+     if (vnum == file_vnums[i]) return 2;
+ 
+   vl = strlen(vnodepath);
+ /*fprintf(stderr, "++ checking %s\n", vnodepath);*/
+   for (i = 0; i < name_count; i++) {
+     vpl = strlen(file_names[i]);
+ /*  fprintf(stderr, "   %s\n", file_names[i]);*/
+ 
+     if (vl > vpl) {
+       r = !strncmp(file_names[i], vnodepath, vpl) && vnodepath[vpl] == '/';
+     } else if (vl < vpl) {
+       r = !strncmp(file_names[i], vnodepath, vl) && file_names[i][vl] == '/';
+     } else {
+       r = !strcmp(file_names[i], vnodepath);
+     }
+     if (r) return 1;
+   }
+   return 0;
+ }
+ 
+ 
+ static int copyfile(XFILE *in, XFILE *out, int size)
+ {
+   static char buf[COPYBUFSIZE];
+   int nr, nw, r;
+ 
+   while (size) {
+     nr = (size > COPYBUFSIZE) ? COPYBUFSIZE : size;
+     if (r = xfread(in, buf, nr)) return r;
+     if (r = xfwrite(out, buf, nr)) return r;
+     size -= nr;
+   }
+   return 0;
+ }
+ 
+ 
+ /* A callback to count and print errors */
+ static afs_uint32 my_error_cb(afs_uint32 code, int fatal, void *ref, char *msg, ...)
+ {
+   va_list alist;
+ 
+   error_count++;
+   if (!quiet) {
+     va_start(alist, msg);
+     com_err_va(argv0, code, msg, alist);
+     va_end(alist);
+   }
+ }
+ 
+ 
+ static afs_uint32 dumphdr_cb(afs_dump_header *hdr, XFILE *X, void *refcon)
+ {
+   return 0;
+ }
+ 
+ 
+ static afs_uint32 volhdr_cb(afs_vol_header *hdr, XFILE *X, void *refcon)
+ {
+   return 0;
+ }
+ 
+ 
+ static afs_uint32 directory_cb(afs_vnode *v, XFILE *X, void *refcon)
+ {
+   char *vnodepath;
+   int r, use;
+ 
+   /* Should we even use this? */
+   if (!use_vnum) {
+     if (r = Path_Build(X, &phi, v->vnode, &vnodepath, !use_realpath))
+       return r;
+     if (!(use = usevnode(X, v->vnode, vnodepath))) {
+       free(vnodepath);
+       return 0;
+     }
+   }
+ 
+   /* Print it out */
+   if (verbose) {
+     if (use_vnum) 
+       printf("d%s %3d %-11d %11d %s #%d:%d\n",
+              modestr(v->mode), v->nlinks, v->owner, v->size,
+              datestr(v->server_date), v->vnode, v->vuniq);
+     else
+       printf("d%s %3d %-11d %11d %s %s\n",
+              modestr(v->mode), v->nlinks, v->owner, v->size,
+              datestr(v->server_date), vnodepath);
+   }
+   else if (!quiet && !use_vnum)
+     printf("%s\n", vnodepath);
+ 
+   /* Make the directory, if needed */
+   if (!nomode && !use_vnum && use != 2) {
+     if (strcmp(vnodepath, "/")
+       && (r = mkdirp(vnodepath + 1))) {
+       free(vnodepath);
+       return r;
+     }
+     if (do_acls) {
+       /* XXX do ACL's later */
+     }
+   }
+   if (!use_vnum) free(vnodepath);
+   return 0;
+ }
+ 
+ 
+ static afs_uint32 file_cb(afs_vnode *v, XFILE *X, void *refcon)
+ {
+   char *vnodepath, vnpx[30];
+   u_int64 where;
+   XFILE OX;
+   int r, use;
+ 
+   if (!dirs_done) {
+     dirs_done = 1;
+     if (verbose) printf("* Extracting files...\n");
+   }
+ 
+   /* Should we even use this? */
+   if (!use_vnum) {
+     if (r = Path_Build(X, &phi, v->vnode, &vnodepath, !use_realpath))
+       return r;
+     if (!(use = usevnode(X, v->vnode, vnodepath))) {
+       free(vnodepath);
+       return 0;
+     }
+     if (use == 2) {
+       free(vnodepath);
+       sprintf(vnpx, "#%d:%d", v->vnode, v->vuniq);
+       vnodepath = vnpx;
+     }
+   } else {
+     sprintf(vnpx, "#%d:%d", v->vnode, v->vuniq);
+     vnodepath = vnpx;
+   }
+ 
+   /* Print it out */
+   if (verbose) {
+     printf("-%s %3d %-11d %11d %s %s\n",
+            modestr(v->mode), v->nlinks, v->owner, v->size,
+            datestr(v->server_date), vnodepath);
+   } else if (!quiet) {
+     printf("%s\n", vnodepath);
+   }
+ 
+   if (!nomode) {
+     if ((r = xftell(X, &where))
+     ||  (r = xfseek(X, &v->d_offset))
+     ||  (r = xfopen_path(&OX, O_RDWR|O_CREAT|O_TRUNC, vnodepath + 1, 0644))) {
+       if (!use_vnum) free(vnodepath);
+       return r;
+     }
+     r = copyfile(X, &OX, v->size);
+     xfclose(&OX);
+     xfseek(X, &where);
+   } else r = 0;
+ 
+   if (!use_vnum && use != 2) free(vnodepath);
+   return r;
+ }
+ 
+ 
+ static afs_uint32 symlink_cb(afs_vnode *v, XFILE *X, void *refcon)
+ {
+   char *vnodepath, *linktarget, vnpx[30];
+   u_int64 where;
+   int r, use;
+ 
+   if (!dirs_done) {
+     dirs_done = 1;
+     if (verbose) printf("* Extracting files...\n");
+   }
+ 
+   /* Should we even use this? */
+   if (!use_vnum) {
+     if (r = Path_Build(X, &phi, v->vnode, &vnodepath, !use_realpath))
+       return r;
+     if (!(use = usevnode(X, v->vnode, vnodepath))) {
+       free(vnodepath);
+       return 0;
+     }
+     if (use == 2) {
+       free(vnodepath);
+       sprintf(vnpx, "#%d:%d", v->vnode, v->vuniq);
+       vnodepath = vnpx;
+     }
+   } else {
+     sprintf(vnpx, "#%d:%d", v->vnode, v->vuniq);
+     vnodepath = vnpx;
+   }
+ 
+   if (!(linktarget = (char *)malloc(v->size + 1))) {
+     if (!use_vnum && use != 2) free(vnodepath);
+     return DSERR_MEM;
+   }
+   if ((r = xftell(X, &where))
+   ||  (r = xfseek(X, &v->d_offset))
+   ||  (r = xfread(X, linktarget, v->size))) {
+     if (!use_vnum && use != 2) free(vnodepath);
+     free(linktarget);
+     return r;
+   }
+   xfseek(X, &where);
+   linktarget[v->size] = 0;
+ 
+   /* Print it out */
+   if (verbose)
+     printf("l%s %3d %-11d %11d %s %s -> %s\n",
+            modestr(v->mode), v->nlinks, v->owner, v->size,
+            datestr(v->server_date), vnodepath, linktarget);
+   else if (!quiet)
+     printf("%s\n", vnodepath);
+ 
+   r = 0;
+   if (!nomode) {
+     if (symlink(linktarget, vnodepath + 1))
+       r = errno;
+   }
+ 
+   free(linktarget);
+   if (!use_vnum && use != 2) free(vnodepath);
+   return r;
+ }
+ 
+ 
+ static afs_uint32 lose_cb(afs_vnode *v, XFILE *F, void *refcon)
+ {
+   int r;
+ 
+   if (!dirs_done) {
+     dirs_done = 1;
+     if (verbose) printf("* Extracting files...\n");
+   }
+ 
+   return 0;
+ }
+ 
+ 
+ /* Main program */
+ void main(int argc, char **argv)
+ {
+   XFILE input_file;
+   afs_uint32 r;
+ 
+   parse_options(argc, argv);
+   initialize_acfg_error_table();
+   initialize_AVds_error_table();
+   initialize_rxk_error_table();
+   initialize_u_error_table();
+   initialize_vl_error_table();
+   initialize_vols_error_table();
+   initialize_xFil_error_table();
+   r = xfopen(&input_file, O_RDONLY, input_path);
+   if (r) {
+     com_err(argv0, r, "opening %s", input_path);
+     exit(2);
+   }
+ 
+   memset(&dp, 0, sizeof(dp));
+   dp.cb_error       = my_error_cb;
+   if (input_file.is_seekable) dp.flags |= DSFLAG_SEEK;
+   dirs_done = 0;
+ 
+   if (!use_vnum) {
+     u_int64 where;
+ 
+     memset(&phi, 0, sizeof(phi));
+     phi.p = &dp;
+ 
+     if (verbose) printf("* Building pathname info...\n");
+     if ((r = xftell(&input_file, &where))
+     ||  (r = Path_PreScan(&input_file, &phi, 1))
+     ||  (r = xfseek(&input_file, &where))) {
+       com_err(argv0, r, "- path initialization failed");
+       xfclose(&input_file);
+       exit(1);
+     }
+   }
+ 
+   dp.cb_vnode_dir   = directory_cb;
+   dp.cb_vnode_file  = file_cb;
+   dp.cb_vnode_link  = symlink_cb;
+   dp.cb_vnode_empty = lose_cb;
+   dp.cb_vnode_wierd = lose_cb;
+   if (do_headers) {
+     dp.cb_dumphdr   = dumphdr_cb;
+     dp.cb_volhdr    = volhdr_cb;
+   }
+ 
+   if (!nomode) {
+     mkdir(target, 0755);
+     if (chdir(target)) {
+       fprintf(stderr, "chdir %s failed: %s\n", target, strerror(errno));
+       exit(1);
+     }
+   }
+   r = ParseDumpFile(&input_file, &dp);
+ 
+   if (verbose && error_count) fprintf(stderr, "*** %d errors\n", error_count);
+   if (r && !quiet) fprintf(stderr, "*** FAILED: %s\n", error_message(r));
+   exit(0);
+ }
Index: openafs/src/tests/afsdump_scan.c
diff -c /dev/null openafs/src/tests/afsdump_scan.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/afsdump_scan.c	Sun Jan 20 04:18:06 2002
***************
*** 0 ****
--- 1,293 ----
+ /*
+  * CMUCS AFStools
+  * dumpscan - routines for scanning and manipulating AFS volume dumps
+  *
+  * Copyright (c) 1998 Carnegie Mellon University
+  * All Rights Reserved.
+  * 
+  * Permission to use, copy, modify and distribute this software and its
+  * documentation is hereby granted, provided that both the copyright
+  * notice and this permission notice appear in all copies of the
+  * software, derivative works or modified versions, and any portions
+  * thereof, and that both notices appear in supporting documentation.
+  *
+  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+  *
+  * Carnegie Mellon requests users of this software to return to
+  *
+  *  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
+  *  School of Computer Science
+  *  Carnegie Mellon University
+  *  Pittsburgh PA 15213-3890
+  *
+  * any improvements or extensions that they make and grant Carnegie Mellon
+  * the rights to redistribute these changes.
+  */
+ 
+ /* afsdump_scan.c - General-purpose dump scanner */
+ 
+ #include <sys/fcntl.h>
+ #include <stdlib.h>
+ #include <stdarg.h>
+ #include <string.h>
+ 
+ #include "dumpscan.h"
+ 
+ extern int optind;
+ extern char *optarg;
+ 
+ extern XFILE repair_output;
+ extern afs_uint32 repair_dumphdr_cb(afs_dump_header *, XFILE *, void *);
+ extern afs_uint32 repair_volhdr_cb(afs_vol_header *, XFILE *, void *);
+ extern afs_uint32 repair_vnode_cb(afs_vnode *, XFILE *, void *);
+ 
+ char *argv0;
+ static char *input_path, *gendump_path;
+ static afs_uint32 printflags, repairflags;
+ static int quiet, verbose, error_count;
+ 
+ static path_hashinfo phi;
+ static dump_parser dp;
+ 
+ 
+ /* Print a usage message and exit */
+ static void usage(int status, char *msg)
+ {
+   if (msg) fprintf(stderr, "%s: %s\n", argv0, msg);
+   fprintf(stderr, "Usage: %s [options] [file]\n", argv0);
+   fprintf(stderr, "  -Pxxx  Set print options:\n");
+   fprintf(stderr, "          B = Print backup system header (if any)\n");
+   fprintf(stderr, "          H = Print AFS dump header\n");
+   fprintf(stderr, "          V = Print AFS volume header\n");
+   fprintf(stderr, "          v = List vnodes\n");
+   fprintf(stderr, "          p = Include path to each vnode\n");
+   fprintf(stderr, "          i = Include info for each vnode\n");
+   fprintf(stderr, "          d = List directory contents\n");
+   fprintf(stderr, "          a = List access control lists\n");
+   fprintf(stderr, "          g = Print debugging info\n");
+   fprintf(stderr, "  -Rxxx  Set repair options:\n");
+   fprintf(stderr, "          0 = Skip null tags\n");
+   fprintf(stderr, "          b = Seek backward to find skipped tags\n");
+   fprintf(stderr, "          d = Resync after vnode data\n");
+   fprintf(stderr, "          v = Resync after corrupted vnodes\n");
+   fprintf(stderr, "  -h     Print this help message\n");
+   fprintf(stderr, "  -gxxx  Generate a new dump in file xxx\n");
+   fprintf(stderr, "  -q     Quiet mode (don't print errors)\n");
+   fprintf(stderr, "  -v     Verbose mode\n");
+   exit(status);
+ }
+ 
+ 
+ /* Parse the argument given to the -P option.
+  * Returns the resulting * dumpscan print flags (DSPRINT_*).
+  * If an unrecognized flag is used, prints an error message and exits.
+  */
+ static afs_uint32 parse_printflags(char *flags)
+ {
+   afs_uint32 result = 0;
+   char *x;
+ 
+   for (x = flags; *x; x++) switch (*x) {
+     case 'B': result |= DSPRINT_BCKHDR;  continue;
+     case 'H': result |= DSPRINT_DUMPHDR; continue;
+     case 'V': result |= DSPRINT_VOLHDR;  continue;
+     case 'v': result |= DSPRINT_ITEM;    continue;
+     case 'p': result |= DSPRINT_PATH;    continue;
+     case 'i': result |= DSPRINT_VNODE;   continue;
+     case 'd': result |= DSPRINT_DIR;     continue;
+     case 'a': result |= DSPRINT_ACL;     continue;
+     case 'g': result |= DSPRINT_DEBUG;   continue;
+     default:  usage(1, "Invalid print options!");
+   }
+   return result;
+ }
+ 
+ 
+ /* Parse the argument given to the -R option.
+  * Returns the resulting * dumpscan repair flags (DSFIX_*).
+  * If an unrecognized flag is used, prints an error message and exits.
+  */
+ static afs_uint32 parse_repairflags(char *flags)
+ {
+   afs_uint32 result = 0;
+   char *x;
+ 
+   for (x = flags; *x; x++) switch (*x) {
+     case '0': result |= DSFIX_SKIP;   continue;
+     case 'b': result |= DSFIX_RSKIP;  continue;
+     case 'd': result |= DSFIX_VDSYNC; continue;
+     case 'v': result |= DSFIX_VFSYNC; continue;
+     default:  usage(1, "Invalid repair options!");
+   }
+   return result;
+ }
+ 
+ 
+ /* Parse the command-line options */
+ static void parse_options(int argc, char **argv)
+ {
+   int c;
+ 
+   /* Set the program name */
+   if (argv0 = strrchr(argv[0], '/')) argv0++;
+   else argv0 = argv[0];
+ 
+   /* Initialize options */
+   input_path = gendump_path = 0;
+   printflags = repairflags = 0;
+   quiet = verbose = 0;
+ 
+   /* Initialize other stuff */
+   error_count = 0;
+ 
+   /* Parse the options */
+   while ((c = getopt(argc, argv, "P:R:g:hqv")) != EOF) {
+     switch (c) {
+       case 'P': printflags   = parse_printflags(optarg);  continue;
+       case 'R': repairflags  = parse_repairflags(optarg); continue;
+       case 'g': gendump_path = optarg;                    continue;
+       case 'q': quiet        = 1;                         continue;
+       case 'v': verbose      = 1;                         continue;
+       case 'h': usage(0, 0);
+       default:  usage(1, "Invalid option!");
+     }
+   }
+ 
+   if (quiet && verbose) usage(1, "Can't specify both -q and -v");
+ 
+   /* Parse non-option arguments */
+   if (argc - optind > 1) usage(1, "Too many arguments!");
+   input_path = (argc == optind) ? "-" : argv[optind];
+ }
+ 
+ 
+ /* A callback to count and print errors */
+ static afs_uint32 my_error_cb(afs_uint32 code, int fatal, void *ref, char *msg, ...)
+ {
+   va_list alist;
+ 
+   error_count++;
+   if (!quiet) {
+     va_start(alist, msg);
+     com_err_va(argv0, code, msg, alist);
+     va_end(alist);
+   }
+ }
+ 
+ 
+ /* A callback to print the path of a vnode. */
+ static afs_uint32 print_vnode_path(afs_vnode *v, XFILE *X, void *refcon)
+ {
+   afs_uint32 r;
+   char *name = 0;
+ 
+   /* Do repair, but only for known vnode types */
+   if (gendump_path
+   &&  (!(v->field_mask & F_VNODE_TYPE)
+        || v->type != vFile
+        || v->type != vDirectory
+        || v->type != vSymlink)) {
+     r = repair_vnode_cb(v, X, refcon);
+     if (r) return r;
+   }
+   r = Path_Build(X, &phi, v->vnode, &name, 0);
+   if (!r && name) printf(" Path: %s\n", name);
+   if (name) free(name);
+   return r;
+ }
+ 
+ 
+ /* Setup for generating a repaired dump */
+ static afs_uint32 setup_repair(void)
+ {
+   afs_uint32 r;
+ 
+   r = xfopen(&repair_output, O_RDWR|O_CREAT|O_TRUNC, gendump_path);
+   if (r) return r;
+ 
+   dp.cb_dumphdr     = repair_dumphdr_cb;
+   dp.cb_volhdr      = repair_volhdr_cb;
+   dp.cb_vnode_dir   = repair_vnode_cb;
+   dp.cb_vnode_file  = repair_vnode_cb;
+   dp.cb_vnode_link  = repair_vnode_cb;
+   dp.cb_vnode_empty = repair_vnode_cb;
+   return 0;
+ }
+ 
+ 
+ /* Main program */
+ void main(int argc, char **argv)
+ {
+   XFILE input_file;
+   afs_uint32 r;
+ 
+   parse_options(argc, argv);
+   initialize_acfg_error_table();
+   initialize_AVds_error_table();
+   initialize_rxk_error_table();
+   initialize_u_error_table();
+   initialize_vl_error_table();
+   initialize_vols_error_table();
+   initialize_xFil_error_table();
+   r = xfopen(&input_file, O_RDONLY, input_path);
+   if (r) {
+     com_err(argv0, r, "opening %s", input_path);
+     exit(2);
+   }
+ 
+   memset(&dp, 0, sizeof(dp));
+   dp.cb_error     = my_error_cb;
+   dp.repair_flags = repairflags;
+   if (input_file.is_seekable) dp.flags |= DSFLAG_SEEK;
+   else {
+     if (repairflags)
+       fprintf(stderr, "Repair modes available only for seekable dumps\n");
+     if (printflags & DSPRINT_PATH)
+       fprintf(stderr, "Path-printing available only for seekable dumps\n");
+     if (repairflags || (printflags & DSPRINT_PATH))
+       exit(1);
+   }
+ 
+   if (gendump_path && (r = setup_repair())) {
+     com_err(argv0, r, "setting up repair output");
+     xfclose(&input_file);
+     exit(2);
+   }
+ 
+   if (printflags & DSPRINT_PATH) {
+     u_int64 where;
+ 
+     dp.print_flags = printflags & DSPRINT_DEBUG;
+     memset(&phi, 0, sizeof(phi));
+     phi.p = &dp;
+ 
+     if ((r = xftell(&input_file, &where))
+     ||  (r = Path_PreScan(&input_file, &phi, 0))
+     ||  (r = xfseek(&input_file, &where))) {
+       com_err(argv0, r, "- path initialization failed");
+       xfclose(&input_file);
+       exit(2);
+     }
+ 
+     dp.cb_vnode_dir   = print_vnode_path;
+     dp.cb_vnode_file  = print_vnode_path;
+     dp.cb_vnode_link  = print_vnode_path;
+     dp.cb_vnode_empty = print_vnode_path;
+     dp.cb_vnode_wierd = print_vnode_path;
+   }
+ 
+   dp.print_flags  = printflags;
+   r = ParseDumpFile(&input_file, &dp);
+   xfclose(&input_file);
+   if (gendump_path) {
+     if (!r) r = DumpDumpEnd(&repair_output);
+     if (!r) r = xfclose(&repair_output);
+     else xfclose(&repair_output);
+   }
+ 
+   if (verbose && error_count) fprintf(stderr, "*** %d errors\n", error_count);
+   if (r && !quiet) fprintf(stderr, "*** FAILED: %s\n", error_message(r));
+   exit(0);
+ }
Index: openafs/src/tests/afsdump_xsed.c
diff -c /dev/null openafs/src/tests/afsdump_xsed.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/afsdump_xsed.c	Sun Jan 20 04:18:06 2002
***************
*** 0 ****
--- 1,333 ----
+ /*
+  * COPYRIGHT NOTICE
+  * Copyright (c) 1997 Carnegie Mellon University
+  * All Rights Reserved.
+  * 
+  * Permission to use, copy, modify and distribute this software and its
+  * documentation is hereby granted, provided that both the copyright
+  * notice and this permission notice appear in all copies of the
+  * software, derivative works or modified versions, and any portions
+  * thereof, and that both notices appear in supporting documentation.
+  * 
+  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+  * 
+  * Carnegie Mellon requests users of this software to return to
+  * 
+  *  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
+  *  School of Computer Science
+  *  Carnegie Mellon University
+  *  Pittsburgh PA 15213-3890
+  * 
+  * any improvements or extensions that they make and grant Carnegie Mellon
+  * the rights to redistribute these changes.
+  */
+ 
+ /* UB - Unified Backups */
+ /* methods/afs/dumpscan/afsdump_scan.c - General-purpose dump scanner */
+ 
+ #include "dumpscan.h"
+ #include <sys/fcntl.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <stdarg.h>
+ #include <string.h>
+ 
+ extern int opterr, optind;
+ extern char *optarg;
+ 
+ extern XFILE repair_output;
+ extern afs_uint32 repair_dumphdr_cb(afs_dump_header *, XFILE *, void *);
+ extern afs_uint32 repair_volhdr_cb(afs_vol_header *, XFILE *, void *);
+ extern afs_uint32 repair_vnode_cb(afs_vnode *, XFILE *, void *);
+ 
+ char *argv0;
+ static char *input_path, *gendump_path;
+ static afs_uint32 printflags, repairflags, add_admin;
+ static int quiet, verbose, error_count;
+ 
+ static path_hashinfo phi;
+ static dump_parser dp;
+ 
+ 
+ /* Print a usage message and exit */
+ static void usage(int status, char *msg)
+ {
+   if (msg) fprintf(stderr, "%s: %s\n", argv0, msg);
+   fprintf(stderr, "Usage: %s [options] [file]\n", argv0);
+   fprintf(stderr, "  -Pxxx  Set print options:\n");
+   fprintf(stderr, "          B = Print backup system header (if any)\n");
+   fprintf(stderr, "          H = Print AFS dump header\n");
+   fprintf(stderr, "          V = Print AFS volume header\n");
+   fprintf(stderr, "          v = List vnodes\n");
+   fprintf(stderr, "          p = Include path to each vnode\n");
+   fprintf(stderr, "          i = Include info for each vnode\n");
+   fprintf(stderr, "          d = List directory contents\n");
+   fprintf(stderr, "          a = List access control lists\n");
+   fprintf(stderr, "          g = Print debugging info\n");
+   fprintf(stderr, "  -Rxxx  Set repair options:\n");
+   fprintf(stderr, "          0 = Skip null tags\n");
+   fprintf(stderr, "          b = Seek backward to find skipped tags\n");
+   fprintf(stderr, "          d = Resync after vnode data\n");
+   fprintf(stderr, "          v = Resync after corrupted vnodes\n");
+   fprintf(stderr, "  -Annn  Add all rights for ID nnn to every directory\n");
+   fprintf(stderr, "  -h     Print this help message\n");
+   fprintf(stderr, "  -gxxx  Generate a new dump in file xxx\n");
+   fprintf(stderr, "  -q     Quiet mode (don't print errors)\n");
+   fprintf(stderr, "  -v     Verbose mode\n");
+   exit(status);
+ }
+ 
+ 
+ /* Parse the argument given to the -P option.
+  * Returns the resulting * dumpscan print flags (DSPRINT_*).
+  * If an unrecognized flag is used, prints an error message and exits.
+  */
+ static afs_uint32 parse_printflags(char *flags)
+ {
+   afs_uint32 result = 0;
+   char *x;
+ 
+   for (x = flags; *x; x++) switch (*x) {
+     case 'B': result |= DSPRINT_BCKHDR;  continue;
+     case 'H': result |= DSPRINT_DUMPHDR; continue;
+     case 'V': result |= DSPRINT_VOLHDR;  continue;
+     case 'v': result |= DSPRINT_ITEM;    continue;
+     case 'p': result |= DSPRINT_PATH;    continue;
+     case 'i': result |= DSPRINT_VNODE;   continue;
+     case 'd': result |= DSPRINT_DIR;     continue;
+     case 'a': result |= DSPRINT_ACL;     continue;
+     case 'g': result |= DSPRINT_DEBUG;   continue;
+     default:  usage(1, "Invalid print options!");
+   }
+   return result;
+ }
+ 
+ 
+ /* Parse the argument given to the -R option.
+  * Returns the resulting * dumpscan repair flags (DSFIX_*).
+  * If an unrecognized flag is used, prints an error message and exits.
+  */
+ static afs_uint32 parse_repairflags(char *flags)
+ {
+   afs_uint32 result = 0;
+   char *x;
+ 
+   for (x = flags; *x; x++) switch (*x) {
+     case '0': result |= DSFIX_SKIP;    continue;
+     case 'b': result |= DSFIX_RSKIP;   continue;
+     case 'd': result |= DSFIX_VDSYNC;  continue;
+     case 'v': result |= DSFIX_VFSYNC;  continue;
+     default:  usage(1, "Invalid repair options!");
+   }
+   return result;
+ }
+ 
+ 
+ /* Parse the command-line options */
+ static void parse_options(int argc, char **argv)
+ {
+   int c;
+ 
+   /* Set the program name */
+   if (argv0 = strrchr(argv[0], '/')) argv0++;
+   else argv0 = argv[0];
+ 
+   /* Initialize options */
+   input_path = gendump_path = 0;
+   printflags = repairflags = add_admin = 0;
+   quiet = verbose = 0;
+ 
+   /* Initialize other stuff */
+   error_count = 0;
+ 
+   /* Parse the options */
+   while ((c = getopt(argc, argv, "A:P:R:g:hv")) != EOF) {
+     switch (c) {
+       case 'A': add_admin    = atoi(optarg);              continue;
+       case 'P': printflags   = parse_printflags(optarg);  continue;
+       case 'R': repairflags  = parse_repairflags(optarg); continue;
+       case 'g': gendump_path = optarg;                    continue;
+       case 'q': quiet        = 1;                         continue;
+       case 'v': verbose      = 1;                         continue;
+       case 'h': usage(0, 0);
+       default:  usage(1, "Invalid option!");
+     }
+   }
+ 
+   if (quiet && verbose) usage(1, "Can't specify both -q and -v");
+ 
+   /* Parse non-option arguments */
+   if (argc - optind > 1) usage(1, "Too many arguments!");
+   input_path = (argc == optind) ? "-" : argv[optind];
+   if (add_admin && !gendump_path) add_admin = 0;
+ }
+ 
+ 
+ /* A callback to count and print errors */
+ static afs_uint32 my_error_cb(afs_uint32 code, int fatal, void *ref, char *msg, ...)
+ {
+   va_list alist;
+ 
+   error_count++;
+   if (!quiet) {
+     va_start(alist, msg);
+     com_err_va(argv0, code, msg, alist);
+     va_end(alist);
+   }
+ }
+ 
+ 
+ /* A callback to print the path of a vnode. */
+ static afs_uint32 print_vnode_path(afs_vnode *v, XFILE *X, void *refcon)
+ {
+   afs_uint32 r;
+   char *name = 0;
+ 
+   /* Do repair, but only for known vnode types */
+   if (gendump_path
+   &&  (!(v->field_mask & F_VNODE_TYPE)
+        || v->type != vFile
+        || v->type != vDirectory
+        || v->type != vSymlink)) {
+     r = repair_vnode_cb(v, X, refcon);
+     if (r) return r;
+   }
+   r = Path_Build(X, &phi, v->vnode, &name, 0);
+   if (!r && name) printf(" Path: %s\n", name);
+   if (name) free(name);
+   return r;
+ }
+ 
+ 
+ static afs_uint32 munge_admin_acl(afs_vnode *v, XFILE *X, void *refcon)
+ {
+   struct acl_accessList *acl;
+   int add_entry = 1, remove_entry = -1;
+   int i, o, n;
+ 
+   acl = (struct acl_accessList *)(v->acl);
+   o = n = ntohl(acl->positive);
+   for (i = 0; i < n; i++)
+     if (ntohl(acl->entries[i].id) == add_admin) add_entry = 0;
+   n = ntohl(acl->negative);
+   for (i = o; i < n + o; i++)
+     if (ntohl(acl->entries[i].id) == add_admin) remove_entry = i;
+ 
+   if (add_entry) {
+     for (i = (remove_entry < 0) ? o + n : remove_entry; i > o; i--) {
+       acl->entries[i].id     = acl->entries[i-1].id;
+       acl->entries[i].rights = acl->entries[i-1].rights;
+     }
+     acl->entries[o].id = htonl(add_admin);
+     acl->entries[o].rights = htonl((PRSFS_READ   | PRSFS_LOOKUP
+                                   | PRSFS_INSERT | PRSFS_DELETE
+                                   | PRSFS_WRITE  | PRSFS_LOCK
+                                   | PRSFS_ADMINISTER));
+     acl->positive = htonl(o + 1);
+     if (remove_entry < 0) acl->total = htonl(o + n + 1);
+     else acl->negative = htonl(n - 1);
+   } else if (remove_entry >= 0) {
+     for (i = remove_entry; i < o + n - 1; i++) {
+       acl->entries[i].id     = acl->entries[i+1].id;
+       acl->entries[i].rights = acl->entries[i+1].rights;
+     }
+     acl->negative = htonl(n - 1);
+     acl->total    = htonl(o + n - 1);
+   }
+   return repair_vnode_cb(v, X, refcon);
+ }
+ 
+ 
+ /* Setup for generating a repaired dump */
+ static afs_uint32 setup_repair(void)
+ {
+   afs_uint32 r;
+ 
+   r = xfopen(&repair_output, gendump_path, O_RDWR, 0644);
+   if (r) return r;
+ 
+   dp.cb_dumphdr     = repair_dumphdr_cb;
+   dp.cb_volhdr      = repair_volhdr_cb;
+   dp.cb_vnode_dir   = repair_vnode_cb;
+   dp.cb_vnode_file  = repair_vnode_cb;
+   dp.cb_vnode_link  = repair_vnode_cb;
+   dp.cb_vnode_empty = repair_vnode_cb;
+   return 0;
+ }
+ 
+ 
+ /* Main program */
+ void main(int argc, char **argv)
+ {
+   XFILE *X;
+   afs_uint32 r;
+ 
+   parse_options(argc, argv);
+   initialize_UB_error_table();
+   initialize_UBsp_error_table();
+   initialize_AVds_error_table();
+   r = xfopen(&X, input_path, O_RDONLY, 0);
+   if (r) {
+     com_err(argv0, r, "opening %s", input_path);
+     exit(2);
+   }
+ 
+   bzero(&dp, sizeof(dp));
+   dp.cb_error     = my_error_cb;
+   dp.repair_flags = repairflags;
+   if (X->is_seekable) dp.flags |= DSFLAG_SEEK;
+   else {
+     if (repairflags)
+       fprintf(stderr, "Repair modes available only for seekable dumps\n");
+     if (printflags & DSPRINT_PATH)
+       fprintf(stderr, "Path-printing available only for seekable dumps\n");
+     if (repairflags || (printflags & DSPRINT_PATH))
+       exit(1);
+   }
+ 
+   if (gendump_path && (r = setup_repair())) {
+     com_err(argv0, r, "setting up repair output");
+     xfclose(X);
+     exit(2);
+   }
+ 
+   if (printflags & DSPRINT_PATH) {
+     u_int64 where;
+ 
+     dp.print_flags = printflags & DSPRINT_DEBUG;
+     bzero(&phi, sizeof(phi));
+     phi.p = &dp;
+ 
+     if ((r = xftell(X, &where))
+     ||  (r = Path_PreScan(X, &phi, 0))
+     ||  (r = xfseek(X, &where))) {
+       com_err(argv0, r, "- path initialization failed");
+       xfclose(X);
+       exit(2);
+     }
+ 
+     dp.cb_vnode_dir   = print_vnode_path;
+     dp.cb_vnode_file  = print_vnode_path;
+     dp.cb_vnode_link  = print_vnode_path;
+     dp.cb_vnode_empty = print_vnode_path;
+     dp.cb_vnode_wierd = print_vnode_path;
+   }
+ 
+   if (add_admin) {
+     dp.cb_vnode_dir = munge_admin_acl;
+   }
+ 
+   dp.print_flags  = printflags;
+   r = ParseDumpFile(X, &dp);
+   if (gendump_path) {
+     if (!r) r = DumpDumpEnd(&repair_output);
+     if (!r) r = xfclose(&repair_output);
+     else xfclose(&repair_output);
+   }
+ 
+   if (verbose && error_count) fprintf(stderr, "*** %d errors\n", error_count);
+   if (r && !quiet) fprintf(stderr, "*** FAILED: %s\n", error_message(r));
+   exit(0);
+ }
Index: openafs/src/tests/append-over-page.c
diff -c /dev/null openafs/src/tests/append-over-page.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/append-over-page.c	Sun Jan 20 04:18:06 2002
***************
*** 0 ****
--- 1,977 ----
+ /*
+  * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <errno.h>
+ 
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <sys/mman.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <dirent.h>
+ 
+ 
+ #include <err.h>
+ 
+ #ifndef MAP_FAILED
+ #define MAP_FAILED ((void *)-1)
+ #endif
+ 
+ static char long_buf[] =
+ "1000\n"
+ "1001\n"
+ "1002\n"
+ "1003\n"
+ "1004\n"
+ "1005\n"
+ "1006\n"
+ "1007\n"
+ "1008\n"
+ "1009\n"
+ "1010\n"
+ "1011\n"
+ "1012\n"
+ "1013\n"
+ "1014\n"
+ "1015\n"
+ "1016\n"
+ "1017\n"
+ "1018\n"
+ "1019\n"
+ "1020\n"
+ "1021\n"
+ "1022\n"
+ "1023\n"
+ "1024\n"
+ "1025\n"
+ "1026\n"
+ "1027\n"
+ "1028\n"
+ "1029\n"
+ "1030\n"
+ "1031\n"
+ "1032\n"
+ "1033\n"
+ "1034\n"
+ "1035\n"
+ "1036\n"
+ "1037\n"
+ "1038\n"
+ "1039\n"
+ "1040\n"
+ "1041\n"
+ "1042\n"
+ "1043\n"
+ "1044\n"
+ "1045\n"
+ "1046\n"
+ "1047\n"
+ "1048\n"
+ "1049\n"
+ "1050\n"
+ "1051\n"
+ "1052\n"
+ "1053\n"
+ "1054\n"
+ "1055\n"
+ "1056\n"
+ "1057\n"
+ "1058\n"
+ "1059\n"
+ "1060\n"
+ "1061\n"
+ "1062\n"
+ "1063\n"
+ "1064\n"
+ "1065\n"
+ "1066\n"
+ "1067\n"
+ "1068\n"
+ "1069\n"
+ "1070\n"
+ "1071\n"
+ "1072\n"
+ "1073\n"
+ "1074\n"
+ "1075\n"
+ "1076\n"
+ "1077\n"
+ "1078\n"
+ "1079\n"
+ "1080\n"
+ "1081\n"
+ "1082\n"
+ "1083\n"
+ "1084\n"
+ "1085\n"
+ "1086\n"
+ "1087\n"
+ "1088\n"
+ "1089\n"
+ "1090\n"
+ "1091\n"
+ "1092\n"
+ "1093\n"
+ "1094\n"
+ "1095\n"
+ "1096\n"
+ "1097\n"
+ "1098\n"
+ "1099\n"
+ "1100\n"
+ "1101\n"
+ "1102\n"
+ "1103\n"
+ "1104\n"
+ "1105\n"
+ "1106\n"
+ "1107\n"
+ "1108\n"
+ "1109\n"
+ "1110\n"
+ "1111\n"
+ "1112\n"
+ "1113\n"
+ "1114\n"
+ "1115\n"
+ "1116\n"
+ "1117\n"
+ "1118\n"
+ "1119\n"
+ "1120\n"
+ "1121\n"
+ "1122\n"
+ "1123\n"
+ "1124\n"
+ "1125\n"
+ "1126\n"
+ "1127\n"
+ "1128\n"
+ "1129\n"
+ "1130\n"
+ "1131\n"
+ "1132\n"
+ "1133\n"
+ "1134\n"
+ "1135\n"
+ "1136\n"
+ "1137\n"
+ "1138\n"
+ "1139\n"
+ "1140\n"
+ "1141\n"
+ "1142\n"
+ "1143\n"
+ "1144\n"
+ "1145\n"
+ "1146\n"
+ "1147\n"
+ "1148\n"
+ "1149\n"
+ "1150\n"
+ "1151\n"
+ "1152\n"
+ "1153\n"
+ "1154\n"
+ "1155\n"
+ "1156\n"
+ "1157\n"
+ "1158\n"
+ "1159\n"
+ "1160\n"
+ "1161\n"
+ "1162\n"
+ "1163\n"
+ "1164\n"
+ "1165\n"
+ "1166\n"
+ "1167\n"
+ "1168\n"
+ "1169\n"
+ "1170\n"
+ "1171\n"
+ "1172\n"
+ "1173\n"
+ "1174\n"
+ "1175\n"
+ "1176\n"
+ "1177\n"
+ "1178\n"
+ "1179\n"
+ "1180\n"
+ "1181\n"
+ "1182\n"
+ "1183\n"
+ "1184\n"
+ "1185\n"
+ "1186\n"
+ "1187\n"
+ "1188\n"
+ "1189\n"
+ "1190\n"
+ "1191\n"
+ "1192\n"
+ "1193\n"
+ "1194\n"
+ "1195\n"
+ "1196\n"
+ "1197\n"
+ "1198\n"
+ "1199\n"
+ "1200\n"
+ "1201\n"
+ "1202\n"
+ "1203\n"
+ "1204\n"
+ "1205\n"
+ "1206\n"
+ "1207\n"
+ "1208\n"
+ "1209\n"
+ "1210\n"
+ "1211\n"
+ "1212\n"
+ "1213\n"
+ "1214\n"
+ "1215\n"
+ "1216\n"
+ "1217\n"
+ "1218\n"
+ "1219\n"
+ "1220\n"
+ "1221\n"
+ "1222\n"
+ "1223\n"
+ "1224\n"
+ "1225\n"
+ "1226\n"
+ "1227\n"
+ "1228\n"
+ "1229\n"
+ "1230\n"
+ "1231\n"
+ "1232\n"
+ "1233\n"
+ "1234\n"
+ "1235\n"
+ "1236\n"
+ "1237\n"
+ "1238\n"
+ "1239\n"
+ "1240\n"
+ "1241\n"
+ "1242\n"
+ "1243\n"
+ "1244\n"
+ "1245\n"
+ "1246\n"
+ "1247\n"
+ "1248\n"
+ "1249\n"
+ "1250\n"
+ "1251\n"
+ "1252\n"
+ "1253\n"
+ "1254\n"
+ "1255\n"
+ "1256\n"
+ "1257\n"
+ "1258\n"
+ "1259\n"
+ "1260\n"
+ "1261\n"
+ "1262\n"
+ "1263\n"
+ "1264\n"
+ "1265\n"
+ "1266\n"
+ "1267\n"
+ "1268\n"
+ "1269\n"
+ "1270\n"
+ "1271\n"
+ "1272\n"
+ "1273\n"
+ "1274\n"
+ "1275\n"
+ "1276\n"
+ "1277\n"
+ "1278\n"
+ "1279\n"
+ "1280\n"
+ "1281\n"
+ "1282\n"
+ "1283\n"
+ "1284\n"
+ "1285\n"
+ "1286\n"
+ "1287\n"
+ "1288\n"
+ "1289\n"
+ "1290\n"
+ "1291\n"
+ "1292\n"
+ "1293\n"
+ "1294\n"
+ "1295\n"
+ "1296\n"
+ "1297\n"
+ "1298\n"
+ "1299\n"
+ "1300\n"
+ "1301\n"
+ "1302\n"
+ "1303\n"
+ "1304\n"
+ "1305\n"
+ "1306\n"
+ "1307\n"
+ "1308\n"
+ "1309\n"
+ "1310\n"
+ "1311\n"
+ "1312\n"
+ "1313\n"
+ "1314\n"
+ "1315\n"
+ "1316\n"
+ "1317\n"
+ "1318\n"
+ "1319\n"
+ "1320\n"
+ "1321\n"
+ "1322\n"
+ "1323\n"
+ "1324\n"
+ "1325\n"
+ "1326\n"
+ "1327\n"
+ "1328\n"
+ "1329\n"
+ "1330\n"
+ "1331\n"
+ "1332\n"
+ "1333\n"
+ "1334\n"
+ "1335\n"
+ "1336\n"
+ "1337\n"
+ "1338\n"
+ "1339\n"
+ "1340\n"
+ "1341\n"
+ "1342\n"
+ "1343\n"
+ "1344\n"
+ "1345\n"
+ "1346\n"
+ "1347\n"
+ "1348\n"
+ "1349\n"
+ "1350\n"
+ "1351\n"
+ "1352\n"
+ "1353\n"
+ "1354\n"
+ "1355\n"
+ "1356\n"
+ "1357\n"
+ "1358\n"
+ "1359\n"
+ "1360\n"
+ "1361\n"
+ "1362\n"
+ "1363\n"
+ "1364\n"
+ "1365\n"
+ "1366\n"
+ "1367\n"
+ "1368\n"
+ "1369\n"
+ "1370\n"
+ "1371\n"
+ "1372\n"
+ "1373\n"
+ "1374\n"
+ "1375\n"
+ "1376\n"
+ "1377\n"
+ "1378\n"
+ "1379\n"
+ "1380\n"
+ "1381\n"
+ "1382\n"
+ "1383\n"
+ "1384\n"
+ "1385\n"
+ "1386\n"
+ "1387\n"
+ "1388\n"
+ "1389\n"
+ "1390\n"
+ "1391\n"
+ "1392\n"
+ "1393\n"
+ "1394\n"
+ "1395\n"
+ "1396\n"
+ "1397\n"
+ "1398\n"
+ "1399\n"
+ "1400\n"
+ "1401\n"
+ "1402\n"
+ "1403\n"
+ "1404\n"
+ "1405\n"
+ "1406\n"
+ "1407\n"
+ "1408\n"
+ "1409\n"
+ "1410\n"
+ "1411\n"
+ "1412\n"
+ "1413\n"
+ "1414\n"
+ "1415\n"
+ "1416\n"
+ "1417\n"
+ "1418\n"
+ "1419\n"
+ "1420\n"
+ "1421\n"
+ "1422\n"
+ "1423\n"
+ "1424\n"
+ "1425\n"
+ "1426\n"
+ "1427\n"
+ "1428\n"
+ "1429\n"
+ "1430\n"
+ "1431\n"
+ "1432\n"
+ "1433\n"
+ "1434\n"
+ "1435\n"
+ "1436\n"
+ "1437\n"
+ "1438\n"
+ "1439\n"
+ "1440\n"
+ "1441\n"
+ "1442\n"
+ "1443\n"
+ "1444\n"
+ "1445\n"
+ "1446\n"
+ "1447\n"
+ "1448\n"
+ "1449\n"
+ "1450\n"
+ "1451\n"
+ "1452\n"
+ "1453\n"
+ "1454\n"
+ "1455\n"
+ "1456\n"
+ "1457\n"
+ "1458\n"
+ "1459\n"
+ "1460\n"
+ "1461\n"
+ "1462\n"
+ "1463\n"
+ "1464\n"
+ "1465\n"
+ "1466\n"
+ "1467\n"
+ "1468\n"
+ "1469\n"
+ "1470\n"
+ "1471\n"
+ "1472\n"
+ "1473\n"
+ "1474\n"
+ "1475\n"
+ "1476\n"
+ "1477\n"
+ "1478\n"
+ "1479\n"
+ "1480\n"
+ "1481\n"
+ "1482\n"
+ "1483\n"
+ "1484\n"
+ "1485\n"
+ "1486\n"
+ "1487\n"
+ "1488\n"
+ "1489\n"
+ "1490\n"
+ "1491\n"
+ "1492\n"
+ "1493\n"
+ "1494\n"
+ "1495\n"
+ "1496\n"
+ "1497\n"
+ "1498\n"
+ "1499\n"
+ "1500\n"
+ "1501\n"
+ "1502\n"
+ "1503\n"
+ "1504\n"
+ "1505\n"
+ "1506\n"
+ "1507\n"
+ "1508\n"
+ "1509\n"
+ "1510\n"
+ "1511\n"
+ "1512\n"
+ "1513\n"
+ "1514\n"
+ "1515\n"
+ "1516\n"
+ "1517\n"
+ "1518\n"
+ "1519\n"
+ "1520\n"
+ "1521\n"
+ "1522\n"
+ "1523\n"
+ "1524\n"
+ "1525\n"
+ "1526\n"
+ "1527\n"
+ "1528\n"
+ "1529\n"
+ "1530\n"
+ "1531\n"
+ "1532\n"
+ "1533\n"
+ "1534\n"
+ "1535\n"
+ "1536\n"
+ "1537\n"
+ "1538\n"
+ "1539\n"
+ "1540\n"
+ "1541\n"
+ "1542\n"
+ "1543\n"
+ "1544\n"
+ "1545\n"
+ "1546\n"
+ "1547\n"
+ "1548\n"
+ "1549\n"
+ "1550\n"
+ "1551\n"
+ "1552\n"
+ "1553\n"
+ "1554\n"
+ "1555\n"
+ "1556\n"
+ "1557\n"
+ "1558\n"
+ "1559\n"
+ "1560\n"
+ "1561\n"
+ "1562\n"
+ "1563\n"
+ "1564\n"
+ "1565\n"
+ "1566\n"
+ "1567\n"
+ "1568\n"
+ "1569\n"
+ "1570\n"
+ "1571\n"
+ "1572\n"
+ "1573\n"
+ "1574\n"
+ "1575\n"
+ "1576\n"
+ "1577\n"
+ "1578\n"
+ "1579\n"
+ "1580\n"
+ "1581\n"
+ "1582\n"
+ "1583\n"
+ "1584\n"
+ "1585\n"
+ "1586\n"
+ "1587\n"
+ "1588\n"
+ "1589\n"
+ "1590\n"
+ "1591\n"
+ "1592\n"
+ "1593\n"
+ "1594\n"
+ "1595\n"
+ "1596\n"
+ "1597\n"
+ "1598\n"
+ "1599\n"
+ "1600\n"
+ "1601\n"
+ "1602\n"
+ "1603\n"
+ "1604\n"
+ "1605\n"
+ "1606\n"
+ "1607\n"
+ "1608\n"
+ "1609\n"
+ "1610\n"
+ "1611\n"
+ "1612\n"
+ "1613\n"
+ "1614\n"
+ "1615\n"
+ "1616\n"
+ "1617\n"
+ "1618\n"
+ "1619\n"
+ "1620\n"
+ "1621\n"
+ "1622\n"
+ "1623\n"
+ "1624\n"
+ "1625\n"
+ "1626\n"
+ "1627\n"
+ "1628\n"
+ "1629\n"
+ "1630\n"
+ "1631\n"
+ "1632\n"
+ "1633\n"
+ "1634\n"
+ "1635\n"
+ "1636\n"
+ "1637\n"
+ "1638\n"
+ "1639\n"
+ "1640\n"
+ "1641\n"
+ "1642\n"
+ "1643\n"
+ "1644\n"
+ "1645\n"
+ "1646\n"
+ "1647\n"
+ "1648\n"
+ "1649\n"
+ "1650\n"
+ "1651\n"
+ "1652\n"
+ "1653\n"
+ "1654\n"
+ "1655\n"
+ "1656\n"
+ "1657\n"
+ "1658\n"
+ "1659\n"
+ "1660\n"
+ "1661\n"
+ "1662\n"
+ "1663\n"
+ "1664\n"
+ "1665\n"
+ "1666\n"
+ "1667\n"
+ "1668\n"
+ "1669\n"
+ "1670\n"
+ "1671\n"
+ "1672\n"
+ "1673\n"
+ "1674\n"
+ "1675\n"
+ "1676\n"
+ "1677\n"
+ "1678\n"
+ "1679\n"
+ "1680\n"
+ "1681\n"
+ "1682\n"
+ "1683\n"
+ "1684\n"
+ "1685\n"
+ "1686\n"
+ "1687\n"
+ "1688\n"
+ "1689\n"
+ "1690\n"
+ "1691\n"
+ "1692\n"
+ "1693\n"
+ "1694\n"
+ "1695\n"
+ "1696\n"
+ "1697\n"
+ "1698\n"
+ "1699\n"
+ "1700\n"
+ "1701\n"
+ "1702\n"
+ "1703\n"
+ "1704\n"
+ "1705\n"
+ "1706\n"
+ "1707\n"
+ "1708\n"
+ "1709\n"
+ "1710\n"
+ "1711\n"
+ "1712\n"
+ "1713\n"
+ "1714\n"
+ "1715\n"
+ "1716\n"
+ "1717\n"
+ "1718\n"
+ "1719\n"
+ "1720\n"
+ "1721\n"
+ "1722\n"
+ "1723\n"
+ "1724\n"
+ "1725\n"
+ "1726\n"
+ "1727\n"
+ "1728\n"
+ "1729\n"
+ "1730\n"
+ "1731\n"
+ "1732\n"
+ "1733\n"
+ "1734\n"
+ "1735\n"
+ "1736\n"
+ "1737\n"
+ "1738\n"
+ "1739\n"
+ "1740\n"
+ "1741\n"
+ "1742\n"
+ "1743\n"
+ "1744\n"
+ "1745\n"
+ "1746\n"
+ "1747\n"
+ "1748\n"
+ "1749\n"
+ "1750\n"
+ "1751\n"
+ "1752\n"
+ "1753\n"
+ "1754\n"
+ "1755\n"
+ "1756\n"
+ "1757\n"
+ "1758\n"
+ "1759\n"
+ "1760\n"
+ "1761\n"
+ "1762\n"
+ "1763\n"
+ "1764\n"
+ "1765\n"
+ "1766\n"
+ "1767\n"
+ "1768\n"
+ "1769\n"
+ "1770\n"
+ "1771\n"
+ "1772\n"
+ "1773\n"
+ "1774\n"
+ "1775\n"
+ "1776\n"
+ "1777\n"
+ "1778\n"
+ "1779\n"
+ "1780\n"
+ "1781\n"
+ "1782\n"
+ "1783\n"
+ "1784\n"
+ "1785\n"
+ "1786\n"
+ "1787\n"
+ "1788\n"
+ "1789\n"
+ "1790\n"
+ "1791\n"
+ "1792\n"
+ "1793\n"
+ "1794\n"
+ "1795\n"
+ "1796\n"
+ "1797\n"
+ "1798\n"
+ "1799\n"
+ "1800\n"
+ "1801\n"
+ "1802\n"
+ "1803\n"
+ "1804\n"
+ "1805\n"
+ "1806\n"
+ "1807\n"
+ "1808\n"
+ "1809\n"
+ "1810\n"
+ "1811\n"
+ "1812\n"
+ "1813\n"
+ "1814\n"
+ "1815\n"
+ "1816\n"
+ "1817\n"
+ "1818\n"
+ "1819\n"
+ "1820\n"
+ "1821\n"
+ "1822\n"
+ "1823\n"
+ "1824\n"
+ "1825\n"
+ "1826\n";
+ 
+ /*
+  * compare this file with read and mmap.
+  * return 0 iff identical.
+  */
+ 
+ static int
+ compare_file (const char *filename)
+ {
+     struct stat sb;
+     int fd;
+     int ret;
+     void *read_buf;
+     void *mmap_buf;
+ 
+     fd = open (filename, O_RDONLY);
+     if (fd < 0)
+ 	err(1, "open %s", filename);
+     ret = fstat (fd, &sb);
+     if (ret < 0)
+ 	err (1, "stat %s", filename);
+     read_buf = malloc (sb.st_size);
+     if (read_buf == NULL)
+ 	err (1, "malloc %u", (unsigned)sb.st_size);
+     ret = read (fd, read_buf, sb.st_size);
+     if (ret < 0)
+ 	err (1, "read %s", filename);
+     if (ret != sb.st_size)
+ 	errx (1, "short read from %s", filename);
+     mmap_buf = mmap (NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+     if (mmap_buf == (void *)MAP_FAILED)
+ 	err (1, "mmap %s", filename);
+     ret = memcmp (read_buf, mmap_buf, sb.st_size);
+     close (fd);
+     free (read_buf);
+     return ret;
+ }
+ 
+ static void
+ doit (const char *filename)
+ {
+     int fd;
+     int ret;
+ 
+     fd = open (filename, O_WRONLY | O_APPEND | O_CREAT | O_TRUNC, 0600);
+     if (fd < 0)
+ 	err (1, "open %s", filename);
+     ret = close (fd);
+     if (ret < 0)
+ 	err (1, "close %s", filename);
+     fd = open (filename, O_WRONLY | O_APPEND);
+     if (fd < 0)
+ 	err (1, "open %s", filename);
+     ret = write (fd, "foobar\n", 7);
+     if (ret < 0)
+ 	err (1, "write %s", filename);
+     if (ret != 7)
+ 	errx (1, "short write to %s", filename);
+     ret = close (fd);
+     if (ret < 0)
+ 	err(1, "close %s", filename);
+ 	
+     if(compare_file (filename))
+ 	errx (1, "compare 1 failed");
+ 
+     fd = open (filename, O_WRONLY | O_APPEND);
+     if (fd < 0)
+ 	err (1, "open %s", filename);
+     ret = write (fd, long_buf, strlen(long_buf));
+     if (ret < 0)
+ 	err (1, "write %s", filename);
+     if (ret != strlen(long_buf))
+ 	errx (1, "short write to %s", filename);
+     ret = close (fd);
+     if (ret < 0)
+ 	err(1, "close %s", filename);
+     
+     if(compare_file (filename))
+ 	errx (1, "compare 2 failed");
+ }
+ 
+ int
+ main(int argc, char **argv)
+ {
+     const char *file = "blaha";
+ 
+     if (argc != 1 && argc != 2)
+ 	errx (1, "usage: %s [file]", argv[0]);
+     if (argc == 2)
+ 	file = argv[1];
+     doit (file);
+     return 0;
+ }
Index: openafs/src/tests/append1
diff -c /dev/null openafs/src/tests/append1:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/append1	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,6 ----
+ #!/bin/sh
+ $objdir/echo-n hej > foo || exit 1
+ if test `cat foo` != "hej"; then exit 1; fi
+ $objdir/echo-n hopp >> foo || exit 1
+ if test `cat foo` != "hejhopp"; then exit 1; fi
+ rm foo || exit 1
Index: openafs/src/tests/apwd.c
diff -c /dev/null openafs/src/tests/apwd.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/apwd.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,472 ----
+ /*
+  * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <errno.h>
+ 
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <dirent.h>
+ 
+ #include <err.h>
+ 
+ #ifndef MAXPATHLEN
+ #ifdef PATH_MAX
+ #define MAXPATHLEN PATH_MAX
+ #else
+ #define MAXPATHLEN 4096
+ #endif
+ #endif
+ 
+ RCSID("$Id: apwd.c,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $");
+ 
+ static int verbose_flag;
+ static FILE *verbose_fp = NULL;
+ 
+ static int
+ initial_string (char **buf, size_t *size, size_t new_size)
+ {
+     char *tmp = malloc (new_size);
+ 
+     if (tmp == NULL)
+ 	return -1;
+     *buf  = tmp;
+     *size = new_size;
+     return 0;
+ }
+ 
+ static int
+ expand_string (char **buf, size_t *size, size_t new_size)
+ {
+     char *tmp = realloc (*buf, new_size);
+ 
+     if (tmp == NULL)
+ 	return -1;
+     *buf  = tmp;
+     *size = new_size;
+     return 0;
+ }
+ 
+ /*
+  * Verify that the dynamically allocated string `buf' of length
+  * `size', has room for `len' bytes.  Returns -1 if realloc fails.
+  */
+ 
+ static int
+ guarantee_room (char **buf, size_t *size, size_t len)
+ {
+     if (*size > len)
+ 	return 0;
+ 
+     return expand_string (buf, size, min(*size * 2, len));
+ }
+ 
+ static char *
+ getcwd_classic (char *buf, size_t size)
+ {
+     int dynamic_buf = 0;
+     struct stat root_sb, dot_sb, dotdot_sb;
+     char *work_string;
+     size_t work_length;
+     char slash_dot_dot[] = "/..";
+     char *curp;
+     char *endp;
+     DIR *dir = NULL;
+ 
+     if (initial_string (&work_string, &work_length, MAXPATHLEN) < 0)
+ 	return NULL;
+ 
+     if (buf == NULL) {
+ 	dynamic_buf = 1;
+ 	if (initial_string (&buf, &size, MAXPATHLEN) < 0) {
+ 	    free (work_string);
+ 	    return NULL;
+ 	}
+     }
+ 
+     endp = curp = buf + size - 1;
+ 
+     if (lstat (".", &dot_sb) < 0)
+ 	goto err_ret;
+     if (lstat ("/", &root_sb) < 0)
+ 	goto err_ret;
+     strcpy (work_string, "..");
+     fprintf (verbose_fp, "\".\" is (%u, %u), \"/\" is (%u, %u)\n",
+ 	     (unsigned)dot_sb.st_dev, (unsigned)dot_sb.st_ino,
+ 	     (unsigned)root_sb.st_dev, (unsigned)root_sb.st_ino);
+ 
+     while (dot_sb.st_dev != root_sb.st_dev
+ 	   || dot_sb.st_ino != root_sb.st_ino) {
+ 	struct dirent *dp;
+ 	int found = 0;
+ 	int change_dev = 0;
+ 	int pattern_len = strlen (work_string);
+ 
+ 	if (lstat (work_string, &dotdot_sb) < 0)
+ 	    goto err_ret;
+ 	fprintf (verbose_fp, "\"..\" is (%u, %u)\n",
+ 		 (unsigned)dotdot_sb.st_dev, (unsigned)dotdot_sb.st_ino);
+ 	if (dot_sb.st_dev != dotdot_sb.st_dev)
+ 	    change_dev = 1;
+ 	dir = opendir (work_string);
+ 	if (dir == NULL)
+ 	    goto err_ret;
+ 	while ((dp = readdir (dir)) != NULL) {
+ 	    size_t name_len = strlen (dp->d_name);
+ 
+ 	    if (change_dev) {
+ 		struct stat sb;
+ 
+ 		if (guarantee_room (&work_string, &work_length,
+ 				    pattern_len + name_len + 2) < 0) {
+ 		    goto err_ret;
+ 		}
+ 
+ 		strcat (work_string, "/");
+ 		strcat (work_string, dp->d_name);
+ 
+ 		if (lstat (work_string, &sb) < 0) {
+ 		    goto err_ret;
+ 		}
+ 		if (sb.st_dev == dot_sb.st_dev
+ 		    && sb.st_ino == dot_sb.st_ino) {
+ 		    fprintf (verbose_fp, "\"%s\" found\n", work_string);
+ 		    found = 1;
+ 		}
+ 		work_string[pattern_len] = '\0';
+ 	    } else if (dp->d_ino == dot_sb.st_ino) {
+ 		fprintf (verbose_fp, "\"%s\" found\n", dp->d_name);
+ 		found = 1;
+ 	    }
+ 
+ 	    if (found) {
+ 		while (buf + name_len >= curp) {
+ 		    size_t old_len;
+ 
+ 		    if (!dynamic_buf) {
+ 			errno = ERANGE;
+ 			goto err_ret;
+ 		    }
+ 		    old_len = endp - curp + 1;
+ 		    if (expand_string (&buf, &size, size * 2) < 0)
+ 			goto err_ret;
+ 		    memmove (buf + size - old_len,
+ 			     buf + size / 2 - old_len,
+ 			     old_len);
+ 		    endp = buf + size - 1;
+ 		    curp = endp - old_len + 1;
+ 		}
+ 		memcpy (curp - name_len, dp->d_name, name_len);
+ 		curp[-(name_len + 1)] = '/';
+ 		curp -= name_len + 1;
+ 		break;
+ 	    }
+ 	}
+ 	closedir (dir);
+ 	dir = NULL;
+ 
+ 	if (!found)
+ 	    goto err_ret;
+ 
+ 	dot_sb = dotdot_sb;
+ 	if (guarantee_room (&work_string, &work_length,
+ 			    pattern_len + strlen(slash_dot_dot) + 1) < 0)
+ 	    goto err_ret;
+ 	strcat (work_string, slash_dot_dot);
+     }
+     if (curp == endp) {
+ 	while (buf >= curp) {
+ 	    if (!dynamic_buf) {
+ 		errno = ERANGE;
+ 		goto err_ret;
+ 	    }
+ 	    if (expand_string (&buf, &size, size * 2) < 0)
+ 		goto err_ret;
+ 	}
+ 	*--curp = '/';
+     }
+     *endp = '\0';
+     memmove (buf, curp, endp - curp + 1);
+     free (work_string);
+     return buf;
+ 
+ err_ret:
+     if (dir)
+ 	closedir (dir);
+     if (dynamic_buf)
+ 	free (buf);
+     free (work_string);
+     return NULL;
+ }
+ 
+ #if linux
+ 
+ static char *
+ getcwd_proc (char *buf, size_t size)
+ {
+     int dynamic_buf = 0;
+ 
+     if (buf == NULL) {
+ 	dynamic_buf = 1;
+ 	if (initial_string (&buf, &size, MAXPATHLEN) < 0)
+ 	    return NULL;
+     } else if (size <= 1) {
+ 	errno = ERANGE;
+ 	return NULL;
+     }
+ 
+     for (;;) {
+ 	int ret;
+ 
+ 	ret = readlink ("/proc/self/cwd", buf, size);
+ 	if (ret == -1)
+ 	    goto err_ret;
+ 	if (buf[0] != '/') {
+ 	    errno = EINVAL;
+ 	    goto err_ret;
+ 	}
+ 	if (buf[ret-1] != '\0' && ret >= size) {
+ 	    if (!dynamic_buf) {
+ 		errno = ERANGE;
+ 		goto err_ret;
+ 	    }
+ 	    if (expand_string (&buf, &size, size * 2) < 0)
+ 		goto err_ret;
+ 	} else {
+ 	    if (buf[ret - 1] != '\0')
+ 		buf[ret] = '\0';
+ 	    return buf;
+ 	}
+     }
+ err_ret:
+     if (dynamic_buf)
+ 	free (buf);
+     return NULL;
+ }
+ 
+ #endif /* linux */
+ 
+ static int
+ test_1(char *(*func)(char *, size_t), const char *func_name, int init_size)
+ {
+     char real_buf[2048];
+     char buf[2048], *buf2, buf3[4711];
+     int i;
+     int ret = 0;
+     int three_done = 1;
+ 
+     if (getcwd (real_buf, sizeof(real_buf)) == NULL) {
+ 	fprintf (verbose_fp, "getcwd(buf, %u) failed\n",
+ 		 (unsigned)sizeof(real_buf));
+ 	ret = 1;
+     }
+     if (func (buf, sizeof(buf)) == NULL) {
+ 	fprintf (verbose_fp, "%s(buf, %u) failed\n", func_name, 
+ 		 (unsigned)sizeof(buf));
+ 	ret = 1;
+     } else {
+ 	fprintf (verbose_fp, "first *%s*\n", buf);
+ 	if (strcmp (real_buf, buf) != 0) {
+ 	    fprintf (verbose_fp, "first comparison failed: *%s* != *%s*\n",
+ 		     real_buf, buf);
+ 	    ret = 1;
+ 	}
+     }
+ 
+     buf2 = func (NULL, 0);
+     if (buf2 == NULL) {
+ 	fprintf (verbose_fp, "%s(NULL, 0) failed\n", func_name);
+ 	ret = 1;
+     } else {
+ 	fprintf (verbose_fp, "second *%s*\n", buf2);
+ 	if (strcmp (real_buf, buf2) != 0) {
+ 	    fprintf (verbose_fp, "second comparison failed: *%s* != *%s*\n",
+ 		     real_buf, buf2);
+ 	    ret = 1;
+ 	}
+ 	free (buf2);
+     }
+ 
+     for (i = init_size; i < sizeof(buf3); ++i) {
+ 	memset (buf3, '\x01', sizeof(buf3));
+ 	if (func (buf3, i) == NULL) {
+ 	    if (errno != ERANGE) {
+ 		fprintf (verbose_fp, "%s(buf,%u) call failed\n", func_name, i);
+ 		three_done = 0;
+ 		break;
+ 	    }
+ 	} else {
+ 	    int j;
+ 
+ 	    for (j = i; j < sizeof(buf3); ++j)
+ 		if (buf3[j] != '\x01') {
+ 		    fprintf (verbose_fp, "buffer was overwritten at %d\n", j);
+ 		    three_done = 0;
+ 		    break;
+ 		}
+ 	    break;
+ 	}
+     }
+ 
+     if (three_done) {
+ 	fprintf (verbose_fp, "third *%s*\n", buf3);
+ 	if (strcmp (real_buf, buf3) != 0) {
+ 	    fprintf (verbose_fp, "third comparison failed: *%s* != *%s*\n",
+ 		     real_buf, buf3);
+ 	    ret = 1;
+ 	} else if (strlen (buf3) + 1 != i
+ 		   && strlen (buf3) + 1 >= init_size) {
+ 	    fprintf (verbose_fp, "wrong len in third call: %d != %d\n",
+ 		     (unsigned)strlen(buf3) + 1, i);
+ 	    ret = 1;
+ 	}
+     } else {
+ 	ret = 1;
+     }
+ 
+     return ret;
+ }
+ 
+ static int
+ test_it(char *(*func)(char *, size_t), const char *name, int init_size)
+ {
+     int ret;
+ 
+     fprintf (verbose_fp, "testing %s (initial size %d)\n", name, init_size);
+     ret = test_1 (func, name, init_size);
+     if (ret)
+ 	fprintf (verbose_fp, "FAILED!\n");
+     else
+ 	fprintf (verbose_fp, "passed\n");
+     return ret;
+ }
+ 
+ #ifdef linux
+ #include <linux/unistd.h>
+ #endif
+ 
+ #ifdef __NR_getcwd
+ 
+ #define __NR_sys_getcwd __NR_getcwd
+ 
+ static
+ _syscall2(int, sys_getcwd, char *, buf, size_t, size)
+ 
+ static char *
+ getcwd_syscall (char *buf, size_t size)
+ {
+     int dynamic_buf = 0;
+ 
+     if (buf == NULL) {
+ 	dynamic_buf = 1;
+ 	if (initial_string (&buf, &size, MAXPATHLEN) < 0)
+ 	    return NULL;
+     }
+ 
+     for (;;) {
+ 	int ret;
+ 
+ 	ret = sys_getcwd (buf, size);
+ 	if (ret >= 0)
+ 	    return buf;
+ 	else if (errno == ERANGE) {
+ 	    if (!dynamic_buf)
+ 		return NULL;
+ 	    if (expand_string (&buf, &size, size * 2) < 0)
+ 		return NULL;
+ 	} else
+ 	    return NULL;
+     }
+ }
+ 
+ #endif
+ 
+ static int help_flag;
+ 
+ static struct agetargs args[] = {
+     {"verbose", 'v',	aarg_flag,	&verbose_flag,	"verbose",	NULL},
+     {"help",	0,	aarg_flag,	&help_flag,	NULL,		NULL},
+     {NULL,	0,	aarg_end,	NULL,		NULL,		NULL}
+ };
+ 
+ static void
+ usage (int exit_val)
+ {
+     aarg_printusage (args, NULL, "", AARG_GNUSTYLE);
+ }
+ 
+ int
+ main(int argc, char **argv)
+ {
+     int ret = 0;
+     int optind = 0;
+ 
+ 
+     verbose_flag = getenv ("VERBOSE") != NULL;
+ 
+     if (agetarg (args, argc, argv, &optind, AARG_GNUSTYLE))
+ 	usage (1);
+ 
+     argc -= optind;
+     argv += optind;
+ 
+     if (argc != 0)
+ 	usage (1);
+     if (help_flag)
+ 	usage (0);
+ 
+     verbose_fp = fdopen (4, "w");
+     if (verbose_fp == NULL) {
+ 	verbose_fp = fopen ("/dev/null", "w");
+ 	if (verbose_fp == NULL)
+ 	    err (1, "fopen");
+     }
+ 
+     ret += test_it (getcwd, "getcwd", 3);
+ #ifdef __NR_getcwd
+     ret += test_it (getcwd_syscall, "getcwd_syscall", 3);
+ #endif
+     ret += test_it (getcwd_classic, "getcwd_classic", 0);
+ #if linux
+     ret += test_it (getcwd_proc, "getcwd_proc", 0);
+ #endif
+     return ret;
+ }
Index: openafs/src/tests/asu.c
diff -c /dev/null openafs/src/tests/asu.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/asu.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,102 ----
+ /*
+  * Copyright (c) 2001 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ RCSID("$Id: asu.c,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $");
+ #endif
+ 
+ #include <sys/types.h>
+ #include <sys/param.h>
+ #include <sys/ioctl.h>
+ #include <stdio.h>
+ #include <pwd.h>
+ #include <unistd.h>
+ 
+ 
+ #include <err.h>
+ 
+ static void
+ usage(int exit_val)
+ {
+     fprintf(stderr, "asu user program [arguments ...]\n");
+     exit(exit_val);
+ }
+ 
+ int
+ main(int argc, char **argv)
+ {
+     const char *user, *prog;
+ 
+ 
+     if (argc < 3)
+ 	usage(1);
+ 
+     user = argv[1];
+     prog = argv[2];
+ 
+     if (getuid() == 0) {
+ 	struct passwd *pw;
+ 	gid_t groups[1];
+ 	uid_t uid;
+ 	gid_t gid;
+ 
+ 	pw = getpwnam(user);
+ 	if(pw == NULL)
+ 	    errx(1, "no such user %s", user);
+ 	
+ 	uid = pw->pw_uid;
+ 	gid = pw->pw_gid;
+ 	groups[0] = gid;
+ 	
+ 	if (setgroups(1, groups))
+ 	    errx(1, "setgroups failed");
+ 
+ 	setgid(gid);
+ 	setuid(uid);
+ 	setegid(gid);
+ 	seteuid(uid);
+     }
+ 
+ #if 0
+     if (k_hasafs()) {
+ 	int ret = k_setpag();
+ 	if (ret < 0)
+ 	    warn("k_setpag");
+     }
+ #endif
+     
+     execvp(prog, &argv[2]);
+ 
+     return 0;
+ }
Index: openafs/src/tests/backuphdr.c
diff -c /dev/null openafs/src/tests/backuphdr.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/backuphdr.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,87 ----
+ /*
+  * CMUCS AFStools
+  * dumpscan - routines for scanning and manipulating AFS volume dumps
+  *
+  * Copyright (c) 1998 Carnegie Mellon University
+  * All Rights Reserved.
+  * 
+  * Permission to use, copy, modify and distribute this software and its
+  * documentation is hereby granted, provided that both the copyright
+  * notice and this permission notice appear in all copies of the
+  * software, derivative works or modified versions, and any portions
+  * thereof, and that both notices appear in supporting documentation.
+  *
+  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+  *
+  * Carnegie Mellon requests users of this software to return to
+  *
+  *  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
+  *  School of Computer Science
+  *  Carnegie Mellon University
+  *  Pittsburgh PA 15213-3890
+  *
+  * any improvements or extensions that they make and grant Carnegie Mellon
+  * the rights to redistribute these changes.
+  */
+ 
+ /* backuphdr.c - Parse and print backup system headers */
+ 
+ #include <stdlib.h>
+ 
+ #include "dumpscan.h"
+ #include "dumpscan_errs.h"
+ #include "stagehdr.h"
+ 
+ afs_uint32 try_backuphdr(XFILE *X, char *tag, tagged_field *field,
+                       afs_uint32 value, tag_parse_info *pi,
+                       void *g_refcon, void *l_refcon)
+ {
+   dump_parser *p = (dump_parser *)g_refcon;
+   backup_system_header bh;
+   u_int64 where;
+   afs_uint32 r;
+ 
+   /* Which header should we try (if any)? */
+   switch (*tag) {
+     case STAGE_VERSMIN: r = ParseStageHdr(X, tag, &bh); break;
+     default: return DSERR_MAGIC;
+   }
+   if (r) return r;
+ 
+   /* Do something with it... */
+   if (p->print_flags & DSPRINT_BCKHDR) PrintBackupHdr(&bh);
+   if (p->cb_bckhdr) {
+     r = xftell(X, &where);
+     if (!r && p->cb_bckhdr)
+       r = (p->cb_bckhdr)(&bh, X, p->refcon);
+     if (p->flags & DSFLAG_SEEK) {
+       if (!r) r = xfseek(X, &where);
+       else xfseek(X, &where);
+     }
+   }
+   if (bh.server)  free(bh.server);
+   if (bh.part)    free(bh.part);
+   if (bh.volname) free(bh.volname);
+   return r;
+ }
+ 
+ 
+ void PrintBackupHdr(backup_system_header *hdr)
+ {
+   time_t from = hdr->from_date, to = hdr->to_date, dd = hdr->dump_date;
+ 
+   printf("* BACKUP SYSTEM HEADER\n");
+   printf(" Version:    %d\n", hdr->version);
+   printf(" Volume:     %s (%d)\n", hdr->volname, hdr->volid);
+   printf(" Location:   %s %s\n", hdr->server, hdr->part);
+   printf(" Level:      %d\n", hdr->level);
+   printf(" Range:      %d => %d\n", hdr->from_date, hdr->to_date);
+   printf("          == %s", ctime(&from));
+   printf("          => %s", ctime(&to));
+   printf(" Dump Time:  %d == %s", hdr->dump_date, ctime(&dd));
+   printf(" Dump Flags: 0x%08x\n", hdr->flags);
+   printf(" Length:     %d\n", hdr->dumplen);
+   printf(" File Num:   %d\n", hdr->filenum);
+ }
Index: openafs/src/tests/baduniq.pl
diff -c /dev/null openafs/src/tests/baduniq.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/baduniq.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,25 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, $ret);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ &AFS_vos_restore("badvol","localhost","a","/usr/tmp/t.uniq-bad","100","full",);
+ &AFS_bos_salvage("localhost","a","badvol",,,,,,);
+ &AFS_fs_mkmount("badvol", "badvol",,,);
+ if ( -f "badvol/test" ) {
+  &AFS_fs_rmmount("badvol");
+  exit(0);
+ }
+ &AFS_fs_rmmount("badvol");
+ exit(1);
+ 
+ 
+ 
Index: openafs/src/tests/baduniq.pl~
diff -c /dev/null openafs/src/tests/baduniq.pl~:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/baduniq.pl~	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,25 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, $ret);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ &AFS_vos_restore("badvol","localhost","a","/usr/tmp/service.dump","100","full",);
+ &AFS_bos_salvage("localhost","a","badvol",,,,,,);
+ &AFS_fs_mkmount("badvol", "badvol",,,);
+ if ( -f "badvol/test" ) {
+  &AFS_fs_rmmount("badvol");
+  exit(0);
+ }
+ &AFS_fs_rmmount("badvol");
+ exit(1);
+ 
+ 
+ 
Index: openafs/src/tests/blocks-new-file.c
diff -c /dev/null openafs/src/tests/blocks-new-file.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/blocks-new-file.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,81 ----
+ /*
+  * Copyright (c) 2001 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ 
+ #include <err.h>
+ 
+ static void
+ doit (const char *filename)
+ {
+     int fd;
+     struct stat sb;
+ 
+     fd = open (filename, O_RDWR | O_TRUNC | O_CREAT, 0666);
+     if (fd < 0)
+ 	err (1, "open %s", filename);
+     if (lseek (fd, (off_t)(1024*1024), SEEK_SET) != 1024*1024)
+ 	err (1, "lseek %s", filename);
+     if (write (fd, "hej", 3) != 3)
+ 	err (1, "write to %s", filename);
+     if (close (fd) < 0)
+ 	err (1, "close %s", filename);
+     if (stat (filename, &sb) < 0)
+ 	err (1, "stat %s", filename);
+     if (unlink (filename) < 0)
+ 	err (1, "unlink %s", filename);
+     if (sb.st_blocks == 0)
+ 	errx (1, "st_blocks == 0");
+ }
+ 
+ int
+ main(int argc, char **argv)
+ {
+ 
+     if (argc == 1)
+ 	doit ("foo");
+     else if (argc == 2)
+ 	doit (argv[1]);
+     else
+ 	errx (1, "usage: %s [filename]", argv[0]);
+     return 0;
+ }
Index: openafs/src/tests/boot-strap-arla
diff -c /dev/null openafs/src/tests/boot-strap-arla:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/boot-strap-arla	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,17 ----
+ #!/bin/sh
+ # $Id: boot-strap-arla,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ if test "X$FAST" != "X" ; then echo "Not running $0" ;exit 0; fi
+ 
+ ARLA_RELEASE=${AFSROOT}/stacken.kth.se/ftp/pub/arla/arla-0.34.tar.gz
+ 
+ mkdir src || exit 1
+ mkdir obj || exit 1
+ 
+ cd src || exit 1
+ gzip -dc $ARLA_RELEASE | tar xf -
+ cd ../obj || exit 1
+ ../src/*/configure || exit 1
+ make || exit 1
+ cd milko || exit 1
+ make || exit 1
+ exit 0
Index: openafs/src/tests/bosaddhost.pl
diff -c /dev/null openafs/src/tests/bosaddhost.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/bosaddhost.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,19 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ &AFS_bos_addhost(localhost,"128.2.1.2",,);
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/bosaddkey.pl
diff -c /dev/null openafs/src/tests/bosaddkey.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/bosaddkey.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,19 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ &AFS_bos_addkey(localhost,"\000\001\002\003\004\005\006\007",250,);
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/bosadduser.pl
diff -c /dev/null openafs/src/tests/bosadduser.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/bosadduser.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,19 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ &AFS_bos_adduser(localhost,[testuser1],);
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/boscreate.pl
diff -c /dev/null openafs/src/tests/boscreate.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/boscreate.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,27 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, $ret);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ open(FOO, ">sleeper.sh"); 
+ print FOO "#!/bin/sh\n";
+ print FOO "while true; do sleep 60; done\n";
+ print FOO "exit 0\n";
+ close FOO;
+ chmod 0755, "sleeper.sh";
+ 
+ &AFS_bos_install(localhost,["sleeper.sh"],,);
+ &AFS_bos_create(localhost,sleeper,simple,["/usr/afs/bin/sleeper.sh"],);
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/bosdelete.pl
diff -c /dev/null openafs/src/tests/bosdelete.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/bosdelete.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,19 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, $ret);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ &AFS_bos_delete(localhost,sleeper,);
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/bosdeleterunning.pl
diff -c /dev/null openafs/src/tests/bosdeleterunning.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/bosdeleterunning.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,22 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, $ret);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ eval { &AFS_bos_delete(localhost,sleeper,); };
+ 
+ if (! $@) {
+     exit (1);
+ }
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/bosexec.pl
diff -c /dev/null openafs/src/tests/bosexec.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/bosexec.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,26 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ use OpenAFS::ConfigUtils;
+ use OpenAFS::Dirpath;
+ use OpenAFS::OS;
+ 
+ my ($host);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ &AFS_bos_exec(localhost,"$openafsdirpath->{'afssrvbindir'}/foo.sh",);
+ if (-f "/usr/tmp/garbage") {
+ } else {
+     exit(1);
+ }
+ unlink "/usr/tmp/garbage";
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/bosinstall.pl
diff -c /dev/null openafs/src/tests/bosinstall.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/bosinstall.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,26 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ open(FOO, ">foo.sh"); 
+ print FOO "#!/bin/sh\n";
+ print FOO "touch /usr/tmp/garbage\n";
+ print FOO "exit 0\n";
+ close FOO;
+ chmod 0755, "foo.sh";
+ 
+ &AFS_bos_install(localhost,["foo.sh"],,);
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/boslisthosts.pl
diff -c /dev/null openafs/src/tests/boslisthosts.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/boslisthosts.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,31 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, @hosts, $this, $cell, $cnt);
+ $host = `hostname`;
+ chomp $host;
+ &AFS_Init();
+ $cell = &AFS_fs_wscell();
+ 
+ @hosts = &AFS_bos_listhosts(localhost,);
+ $this = shift(@hosts);
+ if ($this ne $cell) {
+     exit (1);
+ }
+ while ($this = shift(@hosts)) {
+     if ($this ne $host) {
+ 	if (($this ne "128.2.1.2")) {
+ 	    exit (1);
+ 	}
+     }
+ }
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/boslistkeys.pl
diff -c /dev/null openafs/src/tests/boslistkeys.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/boslistkeys.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,27 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, @hosts, $this, $cell, $cnt, %ret);
+ $host = `hostname`;
+ chomp $host;
+ &AFS_Init();
+ $cell = &AFS_fs_wscell();
+ 
+ %ret = &AFS_bos_listkeys(localhost,,);
+ foreach $this (keys %ret) {
+     if ($this == 250) {
+ 	if ($ret{250} ne 3288840443) {
+ 	    exit(1);
+ 	}
+     }
+ }
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/boslistusers.pl
diff -c /dev/null openafs/src/tests/boslistusers.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/boslistusers.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,26 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, @hosts, $this, $cell, $cnt);
+ $host = `hostname`;
+ chomp $host;
+ &AFS_Init();
+ 
+ @hosts = &AFS_bos_listusers(localhost,);
+ while ($this = shift(@hosts)) {
+     if ($this ne "admin") {
+ 	if (($this ne "testuser1")) {
+ 	    exit (1);
+ 	}
+     }
+ }
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/bosremovehost.pl
diff -c /dev/null openafs/src/tests/bosremovehost.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/bosremovehost.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,30 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, @hosts, $this, $cell, $cnt);
+ $host = `hostname`;
+ chomp $host;
+ &AFS_Init();
+ $cell = &AFS_fs_wscell();
+ 
+ &AFS_bos_removehost(localhost,"128.2.1.2",);
+ @hosts = &AFS_bos_listhosts(localhost,);
+ $this = shift(@hosts);
+ if ($this ne $cell) {
+     exit (1);
+ }
+ while ($this = shift(@hosts)) {
+     if ($this ne $host) {
+ 	exit (1);
+     }
+ }
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/bosremovekey.pl
diff -c /dev/null openafs/src/tests/bosremovekey.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/bosremovekey.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,25 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, @hosts, $this, $cell, $cnt, %ret);
+ $host = `hostname`;
+ chomp $host;
+ &AFS_Init();
+ $cell = &AFS_fs_wscell();
+ 
+ &AFS_bos_removekey(localhost,250,);
+ foreach $this (keys %ret) {
+     if ($this == 250) {
+ 	exit(1);
+     }
+ }
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/bosremoveuser.pl
diff -c /dev/null openafs/src/tests/bosremoveuser.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:54 2002
--- openafs/src/tests/bosremoveuser.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,26 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, @hosts, $this, $cell, $cnt);
+ $host = `hostname`;
+ chomp $host;
+ &AFS_Init();
+ $cell = &AFS_fs_wscell();
+ 
+ &AFS_bos_removeuser(localhost,[testuser1],);
+ @hosts = &AFS_bos_listusers(localhost,);
+ while ($this = shift(@hosts)) {
+     if ($this ne "admin") {
+ 	exit (1);
+     }
+ }
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/bosrestartstopped.pl
diff -c /dev/null openafs/src/tests/bosrestartstopped.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/bosrestartstopped.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,27 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, %info, %info2, $linfo);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ &AFS_bos_restart(localhost,[sleeper],,,);
+ %info = &AFS_bos_status("localhost",[sleeper],);
+ $linfo=$info{'sleeper'};
+ %info2 = %$linfo;
+ if ($info2{'num_starts'} != 2) {
+     exit 1;
+ }
+ if ($info2{'status'} ne "temporarily enabled, currently running normally.") {
+     exit 1;
+ }
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/bossalvagepart.pl
diff -c /dev/null openafs/src/tests/bossalvagepart.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/bossalvagepart.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,19 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, $ret);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ &AFS_bos_salvage("localhost","a",,,,,,,);
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/bossalvageserver.pl
diff -c /dev/null openafs/src/tests/bossalvageserver.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/bossalvageserver.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,19 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, $ret);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ &AFS_bos_salvage("localhost",,,,1,,,,);
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/bossalvagevolume.pl
diff -c /dev/null openafs/src/tests/bossalvagevolume.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/bossalvagevolume.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,19 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, $ret);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ &AFS_bos_salvage("localhost","a","unrep",,,,,,);
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/bosshutdown.pl
diff -c /dev/null openafs/src/tests/bosshutdown.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/bosshutdown.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,27 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, %info, %info2, $linfo);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ &AFS_bos_shutdown(localhost,[sleeper],1,);
+ %info = &AFS_bos_status("localhost",[sleeper],);
+ $linfo=$info{'sleeper'};
+ %info2 = %$linfo;
+ if ($info2{'num_starts'} != 2) {
+     exit 1;
+ }
+ if ($info2{'status'} ne "temporarily disabled, currently shutdown.") {
+     exit 1;
+ }
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/bosstart.pl
diff -c /dev/null openafs/src/tests/bosstart.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/bosstart.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,27 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, %info, %info2, $linfo);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ &AFS_bos_start(localhost,[sleeper],);
+ %info = &AFS_bos_status("localhost",[sleeper],);
+ $linfo=$info{'sleeper'};
+ %info2 = %$linfo;
+ if ($info2{'num_starts'} != 2) {
+     exit 1;
+ }
+ if ($info2{'status'} ne "currently running normally.") {
+     exit 1;
+ }
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/bosstatus.pl
diff -c /dev/null openafs/src/tests/bosstatus.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/bosstatus.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,26 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, %info, %info2, $linfo);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ %info = &AFS_bos_status("localhost",[sleeper],);
+ $linfo=$info{'sleeper'};
+ %info2 = %$linfo;
+ if ($info2{'num_starts'} != 1) {
+     exit 1;
+ }
+ if ($info2{'status'} ne "currently running normally.") {
+     exit 1;
+ }
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/bosstop.pl
diff -c /dev/null openafs/src/tests/bosstop.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/bosstop.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,27 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, %info, %info2, $linfo);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ &AFS_bos_stop(localhost,[sleeper],1,);
+ %info = &AFS_bos_status("localhost",[sleeper],);
+ $linfo=$info{'sleeper'};
+ %info2 = %$linfo;
+ if ($info2{'num_starts'} != 1) {
+     exit 1;
+ }
+ if ($info2{'status'} ne "disabled, currently shutdown.") {
+     exit 1;
+ }
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/build-and-run-rcs
diff -c /dev/null openafs/src/tests/build-and-run-rcs:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/build-and-run-rcs	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,29 ----
+ #!/bin/sh
+ set -x
+ # $Id: build-and-run-rcs,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ ##if test "X$FAST" != "X" ; then echo "Not running $0" ;  exit 0 ; fi
+ echo -n pwd before is ' '
+ pwd
+ #
+ # copied from generic-build because rcs wants to put (hard)links into tar balls.
+ #
+ filename=$AFSROOT/stacken.kth.se/ftp/pub/gnu/rcs/rcs-5.7.tar.gz
+ b=rcs-5.7
+ obj=$b-obj
+ gzip -dc $filename | tar xvf - >&4 2>&1
+ mkdir $obj || exit 1
+ cd $obj || exit 1
+ ../$b/configure >&4 || exit 1
+ make $MAKEFLAGS || exit 1
+ echo -n pwd after is ' '
+ pwd
+ echo row1 > testfile
+ echo log1 | ./src/ci -u testfile
+ ./src/co -l testfile
+ echo row2 >> testfile
+ echo log2 | ./src/ci -u testfile
+ ./src/co -l testfile
+ echo row3 >> testfile
+ echo log3 | ./src/ci -u testfile
+ wc -l testfile | grep '3 testfile' || exit 1
+ 
Index: openafs/src/tests/build-emacs
diff -c /dev/null openafs/src/tests/build-emacs:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/build-emacs	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,4 ----
+ #!/bin/sh
+ # $Id: build-emacs,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ if test "X$FAST" != "X" ; then echo "Not running $0" ;  exit 0 ; fi
+ $SHELL $SHELLVERBOSE $srcdir/generic-build $AFSROOT/stacken.kth.se/ftp/pub/gnu/emacs/emacs-20.7.tar.gz emacs-20.7
Index: openafs/src/tests/build-emacs-j
diff -c /dev/null openafs/src/tests/build-emacs-j:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/build-emacs-j	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,4 ----
+ #!/bin/sh
+ # $Id: build-emacs-j,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ if test "X$FAST" != "X" ; then echo "Not running $0" ;  exit 0 ; fi
+ env MAKEFLAGS="-j" $SHELL $SHELLVERBOSE $srcdir/generic-build $AFSROOT/stacken.kth.se/ftp/pub/gnu/emacs/emacs-20.7.tar.gz emacs-20.7
Index: openafs/src/tests/build-gdb
diff -c /dev/null openafs/src/tests/build-gdb:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/build-gdb	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,4 ----
+ #!/bin/sh
+ # $Id: build-gdb,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ if test "X$FAST" != "X" ; then echo "Not running $0" ;  exit 0 ; fi
+ $SHELL $SHELLVERBOSE $srcdir/generic-build $AFSROOT/stacken.kth.se/ftp/pub/gnu/gdb/gdb-5.0.tar.gz
Index: openafs/src/tests/build-openafs
diff -c /dev/null openafs/src/tests/build-openafs:1.2.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/build-openafs	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,10 ----
+ #!/bin/sh
+ # $Id: build-openafs,v 1.2.2.1 2002/01/20 09:18:07 shadow Exp $
+ FS=${FS:-${objdir}/../appl/fs/fs}
+ 
+ ${FS} sq . 0
+ if test "X$FAST" != "X" ; then echo "Not running $0" ;  exit 0 ; fi
+ test -f /usr/tmp/openafs-1.2.2-src.tar.gz && cp /usr/tmp/openafs-1.2.2-src.tar.gz openafs-1.2.2-src.tar.gz
+ test -f openafs-1.2.2-src.tar.gz || wget http://www.openafs.org/dl/1.2.2/openafs-1.2.2-src.tar.gz 2>&4
+ $SHELL $SHELLVERBOSE $srcdir/generic-build openafs-1.2.2-src.tar.gz openafs-1.2.2
+ openafs-1.2.2/src/finale/translate_et 180480 >& /dev/null
Index: openafs/src/tests/checkpwd
diff -c /dev/null openafs/src/tests/checkpwd:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/checkpwd	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,3 ----
+ #!/bin/sh
+ # $Id: checkpwd,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ $objdir/apwd
Index: openafs/src/tests/compare-inum-mp
diff -c /dev/null openafs/src/tests/compare-inum-mp:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/compare-inum-mp	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,8 ----
+ #!/bin/sh
+ # $Id: compare-inum-mp,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ FS=${FS:-${objdir}/../appl/fs/fs}
+ ${FS} sa . system:anyuser all || exit 1
+ ${FS} mkm root.cell root.cell || exit 1
+ $objdir/readdir-vs-lstat . || exit 1
+ $objdir/readdir-vs-lstat root.cell || exit 1
+ ${FS} rmm root.cell || exit 1
Index: openafs/src/tests/compare-inums
diff -c /dev/null openafs/src/tests/compare-inums:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/compare-inums	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,4 ----
+ #!/bin/sh
+ # $Id: compare-inums,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ $objdir/create-files 100 0 || exit 1
+ $objdir/readdir-vs-lstat . || exit 1
Index: openafs/src/tests/compare-with-local
diff -c /dev/null openafs/src/tests/compare-with-local:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/compare-with-local	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,77 ----
+ #!/bin/sh
+ # $Id: compare-with-local,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ #################################################################
+ #
+ # Copy file back and forth between $TMPDIR (defaults to /tmp)
+ # which is hopefully on local disk or any other well tested
+ # file system and the filesystem we want to test (in $PWD).
+ #
+ #################################################################
+ 
+ test $SHELLVERBOSE && set $SHELLVERBOSE
+ 
+ function compare () {
+     if cmp $1 $2; then
+ 	:
+     else
+ 	diff $1 $2
+ 	exit 1
+     fi
+ }
+ 
+ test $TMPDIR || TMPDIR=/tmp
+ TMPDIR=$TMPDIR/compare-with-local-$$
+ mkdir $TMPDIR || exit 1
+ 
+ # Generate test file
+ cat > $TMPDIR/bar << EOF
+ This is an arla temporary test file.
+ You may remove it any time.
+ Kontrollen blinkar blå.
+ EOF
+ 
+ cp $TMPDIR/bar bar
+ compare $TMPDIR/bar bar
+ mv bar $TMPDIR/bas
+ compare $TMPDIR/bar $TMPDIR/bas
+  # this is for later overwrite test
+  test -f bar && echo bar should not exist && exit 1
+  cp $TMPDIR/bar bar
+  compare $TMPDIR/bar bar
+ cat $TMPDIR/bas > bat
+ compare $TMPDIR/bar bat
+ cat bat > $TMPDIR/bau
+ compare $TMPDIR/bar $TMPDIR/bau
+ mv $TMPDIR/bau bav
+ compare $TMPDIR/bar bav
+  # this is for later overwrite test
+  test -f $TMPDIR/bau && echo $TMPDIR/bau should not exist && exit 1
+  cp $TMPDIR/bar $TMPDIR/bau 
+ cp bav $TMPDIR/baw
+ compare $TMPDIR/bar $TMPDIR/baw
+ 
+ # If we get so far we can write new files. 
+ # Now test overwrite.
+ 
+ # Generate test file slightly different
+ cat > $TMPDIR/bar << EOF
+ This is an arla temporary test file.
+ You may remove it any time.
+ Mera jul.
+ EOF
+ 
+ cp $TMPDIR/bar bar
+ compare $TMPDIR/bar bar
+ mv bar $TMPDIR/bas
+ compare $TMPDIR/bar $TMPDIR/bas
+ cat $TMPDIR/bas > bat
+ compare $TMPDIR/bar bat
+ cat bat > $TMPDIR/bau
+ compare $TMPDIR/bar $TMPDIR/bau
+ mv $TMPDIR/bau bav
+ compare $TMPDIR/bar bav
+ cp bav $TMPDIR/baw
+ compare $TMPDIR/bar $TMPDIR/baw
+ 
+ ${objdir}/rm-rf $TMPDIR
+ exit 0
Index: openafs/src/tests/copy-and-diff-gnu-mirror
diff -c /dev/null openafs/src/tests/copy-and-diff-gnu-mirror:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/copy-and-diff-gnu-mirror	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,7 ----
+ #!/bin/sh
+ # $Id: copy-and-diff-gnu-mirror,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ if test "X$FAST" != "X" ; then echo "Not running $0" ;  exit 0 ; fi
+ if test "X$LARGE" = "X" ; then echo "Not running large test $0" ;  exit 0 ; fi
+ original=${1-$AFSROOT/stacken.kth.se/ftp/pub}
+ (cd $original; tar cvf - gnu) 2>&4 | tar xvf - >&4
+ find gnu -type f -exec cmp '{}' $original/'{}' \;
Index: openafs/src/tests/copy-file
diff -c /dev/null openafs/src/tests/copy-file:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/copy-file	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,26 ----
+ #!/bin/sh
+ # $Id: copy-file,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ cat > foo <<EOF
+ hej love
+ 
+ ska vi g|ra r{tt nu.
+ EOF
+ 
+ cp foo foo2 || exit 1
+ cp foo foo2 || exit 1
+ cp foo foo2 || exit 1
+ cp foo foo2 || exit 1
+ cp foo foo2 || exit 1
+ cp foo foo2 || exit 1
+ cp foo foo2 || exit 1
+ cp foo foo2 || exit 1
+ cp foo foo2 || exit 1
+ cp foo foo2 || exit 1
+ cp foo foo2 || exit 1
+ cp foo foo2 || exit 1
+ cp foo foo2 || exit 1
+ cp foo foo2 || exit 1
+ cp foo foo2 || exit 1
+ cp foo foo2 || exit 1
+ cp foo foo2 || exit 1
+ exit 0
Index: openafs/src/tests/creat1
diff -c /dev/null openafs/src/tests/creat1:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/creat1	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,5 ----
+ #!/bin/sh
+ > foobar
+ test -f foobar || exit 1
+ test -s foobar && exit 1
+ rm foobar || exit 1
Index: openafs/src/tests/create-dirs.c
diff -c /dev/null openafs/src/tests/create-dirs.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/create-dirs.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,93 ----
+ /*
+  * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <dirent.h>
+ 
+ #include <err.h>
+ 
+ #ifdef RCSID
+ RCSID("$Id: create-dirs.c,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $");
+ #endif
+ 
+ static int
+ creat_dirs (int count)
+ {
+     int i;
+     
+     for (i = 0; i < count; ++i) {
+ 	char num[17];
+ 	int ret;
+ 
+ 	snprintf (num, sizeof(num), "%d", i);
+ 	
+ 	ret = mkdir (num, 0777);
+ 	if (ret < 0)
+ 	    err (1, "mkdir %s", num);
+     }
+     return 0;
+ }
+ 
+ static void
+ usage (int ret)
+ {
+     fprintf (stderr, "%s number-of-dirs\n", __progname);
+     exit (ret);
+ }
+ 
+ int
+ main(int argc, char **argv)
+ {
+     char *ptr;
+     int count;
+ 
+ 
+     if (argc != 2)
+ 	usage (1);
+ 
+     count = strtol (argv[1], &ptr, 0);
+     if (count == 0 && ptr == argv[1])
+ 	errx (1, "'%s' not a number", argv[1]);
+ 
+     return creat_dirs (count);
+ }
Index: openafs/src/tests/create-files.c
diff -c /dev/null openafs/src/tests/create-files.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/create-files.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,121 ----
+ /*
+  * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <dirent.h>
+ 
+ #include <err.h>
+ 
+ #undef max
+ #define max(a,b) ((a) > (b) ? (a) : (b))
+ #undef min
+ #define min(a,b) ((a) < (b) ? (a) : (b))
+ 
+ #ifdef RCSID
+ RCSID("$Id: create-files.c,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $");
+ #endif
+ 
+ static int
+ creat_files (int count, long startsize)
+ {
+     int i;
+     long size = 0;
+     
+     for (i = 0; i < count; ++i) {
+ 	char num[17];
+ 	int fd;
+ 
+ 	snprintf (num, sizeof(num), "%d", i);
+ 	
+ 	fd = open (num, O_WRONLY | O_CREAT | O_EXCL, 0777);
+ 	if (fd < 0)
+ 	    err (1, "open %s", num);
+ 	size = startsize;
+ 	while (size > 0) {
+ 	    char buf[8192];
+ 	    size_t len;
+ 	    ssize_t ret;
+ 
+ 	    len = min(sizeof(buf), size);
+ 
+ 	    ret = write (fd, buf, len);
+ 	    if (ret < 0)
+ 		err (1, "write to %s", num);
+ 	    if (ret != len)
+ 		errx (1, "short write to %s", num);
+ 	    size -= ret;
+ 	}
+ 	if (close (fd) < 0)
+ 	    err (1, "close %s", num);
+     }
+     return 0;
+ }
+ 
+ static void
+ usage (int ret)
+ {
+     fprintf (stderr, "%s number-of-files size-of-files\n", __progname);
+     exit (ret);
+ }
+ 
+ int
+ main(int argc, char **argv)
+ {
+     char *ptr;
+     int count;
+     long size;
+ 
+ 
+     if (argc != 3)
+ 	usage (1);
+ 
+     count = strtol (argv[1], &ptr, 0);
+     if (count == 0 && ptr == argv[1])
+ 	errx (1, "'%s' not a number", argv[1]);
+ 
+     size = strtol (argv[2], &ptr, 0);
+     if (size == 0 && ptr == argv[2])
+ 	errx (1, "`%s' not a number", argv[2]);
+ 
+     return creat_files (count, size);
+ }
Index: openafs/src/tests/create-remove-dirs
diff -c /dev/null openafs/src/tests/create-remove-dirs:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/create-remove-dirs	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,4 ----
+ #!/bin/sh
+ # $Id: create-remove-dirs,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ if test "X$FAST" != "X" ; then echo "Not running $0" ;  exit 0 ; fi
+ $objdir/create-remove dir 1000
Index: openafs/src/tests/create-remove-files
diff -c /dev/null openafs/src/tests/create-remove-files:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/create-remove-files	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,4 ----
+ #!/bin/sh
+ # $Id: create-remove-files,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ if test "X$FAST" != "X" ; then echo "Not running $0" ;  exit 0 ; fi
+ $objdir/create-remove file 1000
Index: openafs/src/tests/create-remove.c
diff -c /dev/null openafs/src/tests/create-remove.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/create-remove.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,143 ----
+ /*
+  * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <dirent.h>
+ 
+ #include <err.h>
+ 
+ #ifdef RCSID
+ RCSID("$Id: create-remove.c,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $");
+ #endif
+ 
+ static int
+ creat_dir (const char *name)
+ {
+     int ret = mkdir (name, 0777);
+     if (ret < 0) err (1, "mkdir %s", name);
+     return 0;
+ }
+ 
+ static int
+ remove_dir (const char *name)
+ {
+     int ret = rmdir (name);
+     if (ret < 0) err (1, "rmdir %s", name);
+     return 0;
+ }
+ 
+ static int
+ creat_file (const char *name)
+ {
+     int ret = open (name, O_CREAT|O_RDWR, 0777);
+     if (ret < 0) err (1, "mkdir %s", name);
+     close (ret);
+     return 0;
+ }
+ 
+ static int
+ unlink_file (const char *name)
+ {
+     int ret = unlink (name);
+     if (ret < 0) err (1, "unlink %s", name);
+     return 0;
+ }
+ 
+ 
+ static void
+ usage (int ret)
+ {
+     fprintf (stderr, "%s [file|dir] number-of-dirs\n", __progname);
+     exit (ret);
+ }
+ 
+ #ifndef MAXPATHLEN
+ #ifdef PATH_MAX
+ #define MAXPATHLEN PATH_MAX
+ #else
+ #define MAXPATHLEN 4096
+ #endif
+ #endif
+ 
+ static int
+ creat_many (int num,
+ 	    int (*c) (const char *name),
+ 	    int (*d) (const char *name))
+ {
+     char name[MAXPATHLEN];
+ 
+     if (num < 0)
+ 	errx (1, "not be negative");
+ 
+     snprintf (name, sizeof(name), "foo-%d-%d", num, getpid());
+ 
+     while (num-- > 0) {
+ 	(c) (name);
+ 	(d) (name);
+     }
+     return 0;
+ }
+ 
+ 
+ int
+ main(int argc, char **argv)
+ {
+     char *ptr;
+     int count;
+ 
+ 
+     if (argc != 3)
+ 	usage (1);
+ 
+     count = strtol (argv[2], &ptr, 0);
+     if (count == 0 && ptr == argv[2])
+ 	errx (1, "'%s' not a number", argv[2]);
+ 
+     if (strcmp ("file", argv[1]) == 0) 
+ 	return creat_many (count, creat_file, unlink_file);
+     else if (strcmp("dir", argv[1]) == 0)
+ 	return creat_many (count, creat_dir, remove_dir);
+     else
+ 	errx (1, "unknown type: %s", argv[1]);
+     return 0;
+ }
Index: openafs/src/tests/create-stat.c
diff -c /dev/null openafs/src/tests/create-stat.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/create-stat.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,151 ----
+ /*
+  * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <dirent.h>
+ #include <afs/afsint.h>
+ #include <afs/auth.h>
+ #include <afs/cellconfig.h>
+ #include <afs/cmd.h>
+ 
+ #include <err.h>
+ 
+ struct VenusFid {
+   afs_int32 Cell;
+   struct AFSFid Fid;
+ };
+ 
+ #ifdef RCSID
+ RCSID("$Id: create-stat.c,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $");
+ #endif
+ 
+ static void
+ usage (int ret)
+ {
+     fprintf (stderr, "%s file\n", __progname);
+     exit (ret);
+ }
+ 
+ int
+ main(int argc, char **argv)
+ {
+     char *file;
+     int ret;
+     struct stat sb;
+     struct stat sb_new;
+     struct stat sb_old;
+     struct VenusFid fid;
+     char *filename;
+     ino_t afsfileid;
+ 
+     if (argc != 2)
+ 	usage (1);
+ 
+     file = argv[1];
+ 
+     asprintf (&filename, "%s.new", file);
+ 
+     ret = open (file, O_RDWR, 0600);
+     if (ret < 0)
+ 	err (1, "open");
+     close (ret);
+ 
+     ret = open (filename, O_RDWR|O_CREAT|O_EXCL, 0600);
+     if (ret < 0) {
+ 	unlink(file);
+ 	err (1, "open");
+     }
+     close (ret);
+ 
+     ret = stat (file, &sb);
+     if (ret < 0) {
+ 	unlink(filename);
+ 	unlink(file);
+ 	err (1, "stat");
+     }
+ 
+     ret = lstat (filename, &sb_new);
+     if (ret < 0) {
+ 	unlink(filename);
+ 	unlink(file);
+ 	err (1, "stat");
+     }
+ 
+     if (sb.st_ino == sb_new.st_ino)
+ 	err (1, "sb.st_ino == sb_new.st_ino");
+ 
+     ret = lstat (file, &sb_old);
+     if (ret < 0) {
+ 	unlink(filename);
+ 	unlink(file);
+ 	err (1, "stat");
+     }
+ 
+     if (sb_old.st_ino == sb_new.st_ino)
+ 	err (1, "sb_old.st_ino == sb_new.st_ino");
+     if (sb.st_ino == sb_new.st_ino)
+ 	err (1, "sb.st_ino == sb_new.st_ino");
+     if (sb_old.st_ino != sb.st_ino)
+ 	err (1, "sb_old.st_ino != sb.st_ino");
+ 
+     ret = fs_getfid (file, &fid);
+     if (ret) {
+ 	unlink(file);
+ 	unlink(filename);
+ 	err (1, "fs_getfid: %d", ret);
+     }
+ 
+     afsfileid = ((fid.Fid.Volume & 0x7FFF) << 16 | (fid.Fid.Vnode & 0xFFFFFFFF));
+     if (sb.st_ino != afsfileid) {
+ 	unlink(file);
+ 	unlink(filename);
+ 	errx (1, "sb.st_ino(%ld) != afsfileid(%ld) (%d.%d.%d.%d)",
+ 	      (long)sb.st_ino, (long)afsfileid,
+ 	      fid.Cell, fid.Fid.Volume, fid.Fid.Vnode, fid.Fid.Unique);
+     }
+ 
+     unlink(filename);
+     unlink(file);
+ 
+     return 0;
+ }
Index: openafs/src/tests/create-symlinks.c
diff -c /dev/null openafs/src/tests/create-symlinks.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/create-symlinks.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,144 ----
+ /*
+  * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <dirent.h>
+ #include <limits.h>
+ 
+ #include <err.h>
+ 
+ #ifdef RCSID
+ RCSID("$Id: create-symlinks.c,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $");
+ #endif
+ 
+ #define CONTENT_STRING "kaka"
+ 
+ static FILE *verbose_fp = NULL;
+ 
+ static int
+ creat_symlinks (int count)
+ {
+     int ret;
+     int i;
+     
+     fprintf (verbose_fp, "creating:");
+ 
+     for (i = 0; i < count; ++i) {
+ 	char num[17];
+ 
+ 	fprintf (verbose_fp, " c%d", i);
+ 	fflush (verbose_fp);
+ 
+ 	snprintf (num, sizeof(num), "%d", i);
+ 	
+ 	ret = symlink (CONTENT_STRING, num);
+ 	if (ret < 0)
+ 	    err (1, "symlink %s", num);
+     }
+     fprintf (verbose_fp, "\n");
+     return 0;
+ }
+ 
+ #ifndef MAXPATHLEN
+ #ifdef PATH_MAX
+ #define MAXPATHLEN PATH_MAX
+ #else
+ #define MAXPATHLEN 4096
+ #endif
+ #endif
+ 
+ static int
+ verify_contents (int count)
+ {
+     int ret, i;
+     char file[MAXPATHLEN];
+     char content[MAXPATHLEN];
+     
+     fprintf (verbose_fp, "reading:");
+     for (i = 0; i < count; i++) {
+ 	fprintf (verbose_fp, " r%d", i); 
+ 	fflush (verbose_fp);
+ 
+ 	snprintf (file, sizeof(file), "%d", i);
+ 	ret = readlink (file, content, sizeof(content) - 1);
+ 	if (ret < 0)
+ 	    err (1, "readlink: %d", i);
+ 	content[ret] = '\0';
+ 	if (strcmp (CONTENT_STRING, content) != 0)
+ 	    errx (1, "%s != %s", content, CONTENT_STRING);
+     }
+     fprintf (verbose_fp, "\n");
+     return 0;
+ }
+ 
+ static void
+ usage (int ret)
+ {
+     fprintf (stderr, "%s number-of-symlinks\n", __progname);
+     exit (ret);
+ }
+ 
+ int
+ main(int argc, char **argv)
+ {
+     char *ptr;
+     int count;
+ 
+ 
+     if (argc != 2)
+ 	usage (1);
+ 
+     verbose_fp = fdopen (4, "w");
+     if (verbose_fp == NULL) {
+ 	verbose_fp = fopen ("/dev/null", "w");
+ 	if (verbose_fp == NULL)
+ 	    err (1, "fopen");
+     }
+ 
+     count = strtol (argv[1], &ptr, 0);
+     if (count == 0 && ptr == argv[1])
+ 	errx (1, "'%s' not a number", argv[1]);
+ 
+     return creat_symlinks (count) ||
+ 	verify_contents(count);
+ }
Index: openafs/src/tests/dd
diff -c /dev/null openafs/src/tests/dd:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/dd	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,8 ----
+ #!/bin/sh
+ # $Id: dd,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ if test -r /dev/zero; then
+   dd if=/dev/zero of=foo bs=1k count=20 >/dev/null 2>/dev/null || exit 1
+   rm foo || exit 1
+ else
+   echo "not running dd (you have no /dev/zero)"
+ fi
Index: openafs/src/tests/deep-tree
diff -c /dev/null openafs/src/tests/deep-tree:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/deep-tree	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,6 ----
+ #!/bin/sh
+ # $Id: deep-tree,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ if test "X$FAST" != "X" ; then echo "Not running $0" ;exit 0; fi
+ 
+ mkdir foo && ( cd foo && $SHELL $SHELLVERBOSE ${srcdir}/dir-tree 5 "0 1 2 3 4" )
+ ${objdir}/rm-rf foo
Index: openafs/src/tests/deep-tree2
diff -c /dev/null openafs/src/tests/deep-tree2:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/deep-tree2	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,12 ----
+ #!/bin/sh
+ # $Id: deep-tree2,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ 
+ mkdir foo
+ 
+ b=foo
+ for a in 0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v w x y z å ä ö; do
+     b=$b/$a
+     mkdir $b
+ done
+ 
+ rm -rf foo
\ No newline at end of file
Index: openafs/src/tests/dir-size-mismatch
diff -c /dev/null openafs/src/tests/dir-size-mismatch:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/dir-size-mismatch	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,10 ----
+ #!/bin/sh
+ # $Id: dir-size-mismatch,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ if test "X$FAST" != "X" ; then echo "Not running $0" ;exit 0; fi
+ 
+ for i in `awk 'BEGIN {for(i=0; i < 1000; ++i) printf "%d\n", i}' /dev/null`; do
+  ln -s hejsan qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq$i
+ done
+ find . -name 'qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq*' -print | xargs rm
+ ln -s foo bar
+ rm bar
Index: openafs/src/tests/dir-tree
diff -c /dev/null openafs/src/tests/dir-tree:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/dir-tree	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,22 ----
+ #!/bin/sh
+ # $Id: dir-tree,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ 
+ #######################################################
+ #
+ # Make a directory tree of directories 
+ # dir-tree <depth> <dirnames>+
+ #
+ #######################################################
+ 
+ DEPTH=$1; shift
+ DIRNUMS="$*"
+ export DIRNUMS DEPTH
+ 
+ # catch non numeric args and recurse cond
+ expr $DEPTH '>' 0 > /dev/null 2>&1 || exit 0
+ 
+ for a in $DIRNUMS; do
+     (mkdir $a && cd $a && \
+       $SHELL $SHELLVERBOSE ${srcdir}/dir-tree \
+ 	     `expr $DEPTH - 1` "$DIRNUMS") || exit 1
+ done
Index: openafs/src/tests/directory.c
diff -c /dev/null openafs/src/tests/directory.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/directory.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,254 ----
+ /*
+  * CMUCS AFStools
+  * dumpscan - routines for scanning and manipulating AFS volume dumps
+  *
+  * Copyright (c) 1998 Carnegie Mellon University
+  * All Rights Reserved.
+  * 
+  * Permission to use, copy, modify and distribute this software and its
+  * documentation is hereby granted, provided that both the copyright
+  * notice and this permission notice appear in all copies of the
+  * software, derivative works or modified versions, and any portions
+  * thereof, and that both notices appear in supporting documentation.
+  *
+  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+  *
+  * Carnegie Mellon requests users of this software to return to
+  *
+  *  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
+  *  School of Computer Science
+  *  Carnegie Mellon University
+  *  Pittsburgh PA 15213-3890
+  *
+  * any improvements or extensions that they make and grant Carnegie Mellon
+  * the rights to redistribute these changes.
+  */
+ 
+ /* directory.c - Parse an AFS directory */
+ /* See the end of this file for a description of the directory format */
+ 
+ #include <errno.h>
+ #include <sys/types.h>
+ #include <netinet/in.h>
+ 
+ #include "dumpscan.h"
+ #include "dumpscan_errs.h"
+ #include "xf_errs.h"
+ #include "dumpfmt.h"
+ #include "internal.h"
+ 
+ #include <afs/dir.h>
+ 
+ static afs_dir_page page;
+ 
+ #define allocbit(x) (page.header.freebitmap[(x)>>3] & (1 << ((x) & 7)))
+ #define DPHE (DHE + 1)
+ 
+ static void fixup(char *name, int l)
+ {
+   name += 16;
+   l -= 15;
+ 
+   while (l-- > 0) {
+     name[0] = name[4];
+     name++;
+   }
+ }
+ 
+ afs_uint32 parse_directory(XFILE *X, dump_parser *p, afs_vnode *v,
+                         afs_uint32 size, int toeof)
+ {
+   afs_dir_entry de;
+   int pgno, i, j, l, n;
+   afs_uint32 r;
+   u_int64 where;
+ 
+   if (p->print_flags & DSPRINT_DIR) {
+     printf("  VNode      Uniqifier   Name\n");
+     printf("  ========== ==========  ==============================\n");
+   }
+   if ((p->flags & DSFLAG_SEEK) && (r = xftell(X, &where))) return r;
+   for (pgno = 0; toeof || size; pgno++, size -= (toeof ? 0 : AFS_PAGESIZE)) {
+     if ((p->flags & DSFLAG_SEEK) && (r = xfseek(X, &where))) return r;
+     if (r = xfread(X, &page, AFS_PAGESIZE)) {
+       if (toeof && r == ERROR_XFILE_EOF) break;
+       return r;
+     }
+     if ((p->flags & DSFLAG_SEEK) && (r = xftell(X, &where))) return r;
+     if (page.header.tag != htons(1234)) {
+       if (p->cb_error)
+         (p->cb_error)(DSERR_MAGIC, 1, p->err_refcon,
+                       "Invalid page tag (%d) in page %d",
+                       ntohs(page.header.tag), pgno);
+       return DSERR_MAGIC;
+     }
+     for (i = (pgno ? 1 : DPHE); i < EPP; i++) {
+       if (!allocbit(i)) continue;
+       if (page.entry[i].flag != FFIRST) {
+         if (p->cb_error)
+           (p->cb_error)(DSERR_MAGIC, 0, p->err_refcon,
+                         "Invalid entry flag %d in entry %d/%d; skipping...",
+                         page.entry[i].flag, pgno, i);
+         continue;
+       }
+       n = (EPP - i - 1) * 32 + 16;
+       for (l = 0; n && page.entry[i].name[l]; l++, n--);
+       if (page.entry[i].name[l]) {
+         if (p->cb_error)
+           (p->cb_error)(DSERR_FMT, 0, p->err_refcon,
+                         "Filename too long in entry %d/%d; skipping page",
+                         pgno, i);
+         break;
+       }
+ /*    fixup(page.entry[i].name, l); */
+       if (pgno) de.slot = i - 1 + (pgno - 1) * (EPP - 1) + (EPP - DPHE);
+       else de.slot = i - DPHE;
+       de.name  = page.entry[i].name;
+       de.vnode = ntohl(page.entry[i].vnode);
+       de.uniq  = ntohl(page.entry[i].vunique);
+       if (p->print_flags & DSPRINT_DIR)
+         printf("  %10d %10d  %s\n", de.vnode, de.uniq, de.name);
+       if (p->cb_dirent) {
+         r = (p->cb_dirent)(v, &de, X, p->refcon);
+       }
+       if (p->cb_dirent && (r = (p->cb_dirent)(v, &de, X, p->refcon)))
+         return r;
+       i += ((l + 16) >> 5);
+     }
+   }
+   if ((p->flags & DSFLAG_SEEK) && (r = xfseek(X, &where))) return r;
+   return 0;
+ }
+ 
+ 
+ afs_uint32 ParseDirectory(XFILE *X, dump_parser *p, afs_uint32 size, int toeof)
+ {
+   afs_uint32 r;
+ 
+   r = parse_directory(X, p, 0, size, toeof);
+ }
+ 
+ 
+ typedef struct {
+   char **name;
+   afs_uint32 *vnode;
+   afs_uint32 *vuniq;
+ } dirlookup_stat;
+ 
+ 
+ static afs_uint32 dirlookup_cb(afs_vnode *v, afs_dir_entry *de,
+                             XFILE *X, void *refcon)
+ {
+   dirlookup_stat *s = (dirlookup_stat *)refcon;
+ 
+   if (s->name && s->name[0]) {                  /* Search by filename */
+     if (strcmp(de->name, s->name[0])) return 0; /* Not it! */
+     if (s->vnode) s->vnode[0] = de->vnode;
+     if (s->vuniq) s->vuniq[0] = de->uniq;
+   } else if (s->vnode) {                        /* Search by vnode */
+     if (de->vnode != s->vnode[0]) return 0;     /* Not it! */
+     if (s->name) {
+       s->name[0] = (char *)malloc(strlen(de->name) + 1);
+       if (!s->name[0]) return ENOMEM;
+       strcpy(s->name[0], de->name);
+     }
+     if (s->vuniq) s->vuniq[0] = de->uniq;
+   }
+   return DSERR_DONE;
+ }
+ 
+ 
+ /* Look up an entry in a directory, by name or vnode.
+  * If *name is NULL, we are looking up by vnode.
+  * Otherwise, we are looking for a filename.
+  * In any event, any of name, vnode, vuniq that are
+  * neither NULL nor the search key are filled in on
+  * success.
+  *
+  * Call this with X pointing to the start of the directory,
+  * and size set to the length of the directory.
+  * Returns 0 on success, whether or not the entry is found.
+  */
+ afs_uint32 DirectoryLookup(XFILE *X, dump_parser *p, afs_uint32 size,
+                     char **name, afs_uint32 *vnode, afs_uint32 *vuniq)
+ {
+   dump_parser my_p;
+   dirlookup_stat my_s;
+   afs_uint32 r;
+ 
+   memset(&my_s, 0, sizeof(my_s));
+   my_s.name  = name;
+   my_s.vnode = vnode;
+   my_s.vuniq = vuniq;
+ 
+   memset(&my_p, 0, sizeof(my_p));
+   my_p.refcon = (void *)&my_s;
+   my_p.err_refcon = p->err_refcon;
+   my_p.cb_error = p->cb_error;
+   my_p.cb_dirent  = dirlookup_cb;
+ 
+   r = parse_directory(X, &my_p, 0, size, 0);
+   if (!r) r = DSERR_DONE;
+   return handle_return(r, X, 0, p);
+ }
+ 
+ 
+ /* AFS directory format:
+  * AFS directories are stored in volume dumps in exactly the same format
+  * that is used on disk, which makes them relatively easy to dump and restore,
+  * but means we have to do some work to interpret them.
+  *
+  * The ACL for a directory is stored on disk in the last part of a "large"
+  * (directory) vnode.  This part of the vnode, which has fixed size
+  * SIZEOF_LARGEDISKVNODE - SIZEOF_SMALLDISKVNODE, is copied directly into
+  * the dump file with a tag of 'A' (VTAG_ACL).  The structure of this
+  * section is described in <afs/acl.h>.
+  *
+  * The name-to-vnode mappings are also stored exactly as they appear on
+  * disk, using the file data ('f') attribute.  As usual, this attribute
+  * consists of a 32-bit number containing the size, immediately followed
+  * by the data itself.  The interesting structures and constants are
+  * defined in <afs/dir.h>
+  * 
+  * A directory consists of one or more 'pages', each of which is 2K
+  * (AFS_PAGESIZE).  Each page contains EPP (currently 64) 'entries', each
+  * of which is 32 bytes.  The first page begins with a DirHeader, which
+  * is DHE entries long, and includes a PageHeader.  All other pages begin
+  * with just a PageHeader, which is 1 entry long.  Every other entry is
+  * a DirEntry, a DirXEntry (name extension), or unused.
+  *
+  * A Page Header contains the following elements:
+  * - pgcount    contains a count of the number of pages in the directory,
+  *              if the directory is new-style (>128 pages), or 0 if it is
+  *              old-style.  This field is meaningful only in the Dir Header.
+  * - tag        a magic number, which must be 1234
+  * - freecount  apparently unused
+  * - freebitmap A bitmap of free entries.  Each byte corresponds to 8
+  *              entries, with the least significant bit referring to the
+  *              first of those.  Each bit is set iff the corresponding
+  *              entry is allocated.  Entries used by the page and dir
+  *              headers are considered allocated.
+  *
+  * A Dir Header consists of a Page Header, followed by an allocation map
+  * and hash table.  The allocation map contains one byte for each of the
+  * first 128 pages; that byte contains the number of entries in that page
+  * that are allocated.  Every page that actually exists has at peast one
+  * entry allocated (the Page Header); if a byte in this map is 0, it means
+  * that the page does not yet exist.
+  *
+  * Each bucket in the hash table is a linked list, using 'blob numbers'
+  * as pointers.  A blob number is defined as (page# * EPP) + entry#.
+  * The head of each chain is kept in the hash table, and the next pointers
+  * are kept in the 'next' entry of each directory.
+  *
+  * Directory entries themselves contain the following elements:
+  * - flag    Set to FFIRST iff this is the first blob in an entry
+  *           (otherwise it will be a name continuation).  This is
+  *           probably not reliable.
+  * - length  Unused
+  * - next    Pointer to the next element in this hash chain
+  * - fid     FileID (vnode and uniquifier)
+  * - name    Filename (null-terminated)
+  */
Index: openafs/src/tests/dump.c
diff -c /dev/null openafs/src/tests/dump.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/dump.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,229 ----
+ /*
+  * CMUCS AFStools
+  * dumpscan - routines for scanning and manipulating AFS volume dumps
+  *
+  * Copyright (c) 1998 Carnegie Mellon University
+  * All Rights Reserved.
+  * 
+  * Permission to use, copy, modify and distribute this software and its
+  * documentation is hereby granted, provided that both the copyright
+  * notice and this permission notice appear in all copies of the
+  * software, derivative works or modified versions, and any portions
+  * thereof, and that both notices appear in supporting documentation.
+  *
+  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+  *
+  * Carnegie Mellon requests users of this software to return to
+  *
+  *  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
+  *  School of Computer Science
+  *  Carnegie Mellon University
+  *  Pittsburgh PA 15213-3890
+  *
+  * any improvements or extensions that they make and grant Carnegie Mellon
+  * the rights to redistribute these changes.
+  */
+ 
+ /* dump.c - Write out parts of a volume dump */
+ 
+ #include "dumpscan.h"
+ #include "dumpfmt.h"
+ 
+ #define COPYBUFSIZE 65536
+ 
+ afs_uint32 DumpDumpHeader(XFILE *OX, afs_dump_header *hdr)
+ {
+   afs_uint32 r;
+ 
+   if (r = WriteTagInt32Pair(OX, TAG_DUMPHEADER, hdr->magic, hdr->version))
+     return r;
+ 
+   if (hdr->field_mask & F_DUMPHDR_VOLID) {
+     if (r = WriteTagInt32(OX, DHTAG_VOLID, hdr->volid)) return r;
+   }
+   if (hdr->field_mask & F_DUMPHDR_VOLNAME) {
+     if (r = WriteByte(OX, DHTAG_VOLNAME)) return r;
+     if (r = WriteString(OX, hdr->volname)) return r;
+   }
+   if (hdr->field_mask & (F_DUMPHDR_FROM | F_DUMPHDR_TO)) {
+     if (r = WriteTagInt16(OX, DHTAG_DUMPTIMES, 2))
+       return r;
+     if (r = WriteInt32(OX, (hdr->field_mask & F_DUMPHDR_FROM)
+                        ? hdr->from_date : 0))
+       return r;
+     if (r = WriteInt32(OX, (hdr->field_mask & F_DUMPHDR_TO)
+                        ? hdr->to_date : time(0)))
+       return r;
+   }
+   return 0;
+ }
+ 
+ 
+ afs_uint32 DumpVolumeHeader(XFILE *OX, afs_vol_header *hdr)
+ {
+   afs_uint32 r;
+   int i;
+ 
+   if (r = WriteByte(OX, TAG_VOLHEADER)) return r;
+ 
+   if (hdr->field_mask & F_VOLHDR_VOLID) {
+     if (r = WriteTagInt32(OX, VHTAG_VOLID, hdr->volid)) return r;
+   }
+   if (hdr->field_mask & F_VOLHDR_VOLVERS) {
+     if (r = WriteTagInt32(OX, VHTAG_VERS, hdr->volvers)) return r;
+   }
+   if (hdr->field_mask & F_VOLHDR_VOLNAME) {
+     if (r = WriteByte(OX, VHTAG_VOLNAME)) return r;
+     if (r = WriteString(OX, hdr->volname)) return r;
+   }
+   if (hdr->field_mask & F_VOLHDR_INSERV) {
+     if (r = WriteTagByte(OX, VHTAG_INSERV, hdr->flag_inservice)) return r;
+   }
+   if (hdr->field_mask & F_VOLHDR_BLESSED) {
+     if (r = WriteTagByte(OX, VHTAG_BLESSED, hdr->flag_blessed)) return r;
+   }
+   if (hdr->field_mask & F_VOLHDR_VOLUNIQ) {
+     if (r = WriteTagInt32(OX, VHTAG_VUNIQ, hdr->voluniq)) return r;
+   }
+   if (hdr->field_mask & F_VOLHDR_VOLTYPE) {
+     if (r = WriteTagByte(OX, VHTAG_TYPE, hdr->voltype)) return r;
+   }
+   if (hdr->field_mask & F_VOLHDR_PARENT) {
+     if (r = WriteTagInt32(OX, VHTAG_PARENT, hdr->parent_volid)) return r;
+   }
+   if (hdr->field_mask & F_VOLHDR_CLONE) {
+     if (r = WriteTagInt32(OX, VHTAG_CLONE, hdr->clone_volid)) return r;
+   }
+   if (hdr->field_mask & F_VOLHDR_MAXQ) {
+     if (r = WriteTagInt32(OX, VHTAG_MAXQUOTA, hdr->maxquota)) return r;
+   }
+   if (hdr->field_mask & F_VOLHDR_MINQ) {
+     if (r = WriteTagInt32(OX, VHTAG_MINQUOTA, hdr->minquota)) return r;
+   }
+   if (hdr->field_mask & F_VOLHDR_DISKUSED) {
+     if (r = WriteTagInt32(OX, VHTAG_DISKUSED, hdr->diskused)) return r;
+   }
+   if (hdr->field_mask & F_VOLHDR_NFILES) {
+     if (r = WriteTagInt32(OX, VHTAG_FILECNT, hdr->nfiles)) return r;
+   }
+   if (hdr->field_mask & F_VOLHDR_ACCOUNT) {
+     if (r = WriteTagInt32(OX, VHTAG_ACCOUNT, hdr->account_no)) return r;
+   }
+   if (hdr->field_mask & F_VOLHDR_OWNER) {
+     if (r = WriteTagInt32(OX, VHTAG_OWNER, hdr->owner)) return r;
+   }
+   if (hdr->field_mask & F_VOLHDR_CREATE_DATE) {
+     if (r = WriteTagInt32(OX, VHTAG_CREAT, hdr->create_date)) return r;
+   }
+   if (hdr->field_mask & F_VOLHDR_ACCESS_DATE) {
+     if (r = WriteTagInt32(OX, VHTAG_ACCESS, hdr->access_date)) return r;
+   }
+   if (hdr->field_mask & F_VOLHDR_UPDATE_DATE) {
+     if (r = WriteTagInt32(OX, VHTAG_UPDATE, hdr->update_date)) return r;
+   }
+   if (hdr->field_mask & F_VOLHDR_EXPIRE_DATE) {
+     if (r = WriteTagInt32(OX, VHTAG_EXPIRE, hdr->expire_date)) return r;
+   }
+   if (hdr->field_mask & F_VOLHDR_BACKUP_DATE) {
+     if (r = WriteTagInt32(OX, VHTAG_BACKUP, hdr->backup_date)) return r;
+   }
+   if (hdr->field_mask & F_VOLHDR_OFFLINE_MSG) {
+     if (r = WriteTagInt32(OX, VHTAG_OFFLINE, hdr->offline_msg)) return r;
+   }
+   if (hdr->field_mask & F_VOLHDR_MOTD) {
+     if (r = WriteTagInt32(OX, VHTAG_MOTD, hdr->motd_msg)) return r;
+   }
+   if (hdr->field_mask & F_VOLHDR_WEEKUSE) {
+     if (r = WriteTagInt16(OX, VHTAG_WEEKUSE, 7)) return r;
+     for (i = 0; i < 7; i++)
+       if (r = WriteInt32(OX, hdr->weekuse[i])) return r;
+   }
+   if (hdr->field_mask & F_VOLHDR_DAYUSE_DATE) {
+     if (r = WriteTagInt32(OX, VHTAG_DUDATE, hdr->dayuse_date)) return r;
+   }
+   if (hdr->field_mask & F_VOLHDR_DAYUSE) {
+     if (r = WriteTagInt32(OX, VHTAG_DAYUSE, hdr->dayuse)) return r;
+   }
+   return 0;
+ }
+ 
+ 
+ afs_uint32 DumpVNode(XFILE *OX, afs_vnode *v)
+ {
+   afs_uint32 r;
+ 
+   if (r = WriteTagInt32Pair(OX, TAG_VNODE, v->vnode, v->vuniq)) return r;
+ 
+   if (v->field_mask & F_VNODE_TYPE) {
+     if (r = WriteTagByte(OX, VTAG_TYPE, v->type)) return r;
+   }
+   if (v->field_mask & F_VNODE_NLINKS) {
+     if (r = WriteTagInt16(OX, VTAG_NLINKS, v->nlinks)) return r;
+   }
+   if (v->field_mask & F_VNODE_DVERS) {
+     if (r = WriteTagInt32(OX, VTAG_DVERS, v->datavers)) return r;
+   }
+   if (v->field_mask & F_VNODE_SDATE) {
+     if (r = WriteTagInt32(OX, VTAG_SERVER_DATE, v->server_date)) return r;
+   }
+   if (v->field_mask & F_VNODE_AUTHOR) {
+     if (r = WriteTagInt32(OX, VTAG_AUTHOR, v->author)) return r;
+   }
+   if (v->field_mask & F_VNODE_OWNER) {
+     if (r = WriteTagInt32(OX, VTAG_OWNER, v->owner)) return r;
+   }
+   if (v->field_mask & F_VNODE_GROUP) {
+     if (r = WriteTagInt32(OX, VTAG_GROUP, v->group)) return r;
+   }
+   if (v->field_mask & F_VNODE_MODE) {
+     if (r = WriteTagInt16(OX, VTAG_MODE, v->mode)) return r;
+   }
+   if (v->field_mask & F_VNODE_PARENT) {
+     if (r = WriteTagInt32(OX, VTAG_PARENT, v->parent)) return r;
+   }
+   if (v->field_mask & F_VNODE_CDATE) {
+     if (r = WriteTagInt32(OX, VTAG_CLIENT_DATE, v->client_date)) return r;
+   }
+   if (v->field_mask & F_VNODE_ACL) {
+     if (r = WriteByte(OX, VTAG_ACL)) return r;
+     if (r = xfwrite(OX, v->acl, SIZEOF_LARGEDISKVNODE - SIZEOF_SMALLDISKVNODE))
+       return r;
+   }
+   return 0;
+ }
+ 
+ 
+ afs_uint32 DumpVNodeData(XFILE *OX, char *buf, afs_uint32 size)
+ {
+   afs_uint32 r;
+ 
+   if (r = WriteTagInt32(OX, VTAG_DATA, size)) return r;
+   if (r = xfwrite(OX, buf, size)) return r;
+   return 0;
+ }
+ 
+ 
+ afs_uint32 CopyVNodeData(XFILE *OX, XFILE *X, afs_uint32 size)
+ {
+   afs_uint32 r, n;
+   static char buf[COPYBUFSIZE];
+ 
+   if (r = WriteTagInt32(OX, VTAG_DATA, size)) return r;
+   while (size) {
+     n = (size > COPYBUFSIZE) ? COPYBUFSIZE : size;
+     if (r = xfread(X, buf, n)) return r;
+     if (r = xfwrite(OX, buf, n)) return r;
+     size -= n;
+   }
+   return 0;
+ }
+ 
+ 
+ afs_uint32 DumpDumpEnd(XFILE *OX) {
+   afs_uint32 r;
+ 
+   if (r = WriteTagInt32(OX, TAG_DUMPEND, DUMPENDMAGIC)) return r;
+   return 0;
+ }
Index: openafs/src/tests/dumpfmt.h
diff -c /dev/null openafs/src/tests/dumpfmt.h:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/dumpfmt.h	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,150 ----
+ /*
+  * CMUCS AFStools
+  * dumpscan - routines for scanning and manipulating AFS volume dumps
+  *
+  * Copyright (c) 1998 Carnegie Mellon University
+  * All Rights Reserved.
+  * 
+  * Permission to use, copy, modify and distribute this software and its
+  * documentation is hereby granted, provided that both the copyright
+  * notice and this permission notice appear in all copies of the
+  * software, derivative works or modified versions, and any portions
+  * thereof, and that both notices appear in supporting documentation.
+  *
+  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+  *
+  * Carnegie Mellon requests users of this software to return to
+  *
+  *  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
+  *  School of Computer Science
+  *  Carnegie Mellon University
+  *  Pittsburgh PA 15213-3890
+  *
+  * any improvements or extensions that they make and grant Carnegie Mellon
+  * the rights to redistribute these changes.
+  */
+ 
+ /* dumpfmt.h - Description of AFS dump format */
+ 
+ #ifndef _DUMPFMT_H_
+ #define _DUMPFMT_H_
+ 
+ #include "intNN.h"
+ 
+ /* AFS dump file format:
+  * All data in AFS dumps is tagged; that is, each data item is preceeded
+  * by a 1-byte tag which identifies what the data item is.  There is no
+  * explicit mention of what the data type is, but the type of each possible
+  * data item (and thus, each possible tag) is fixed.  Usually this is
+  * a relatively simple, fixed amount of data (byte, short, word), but
+  * sometimes it is more complex.
+  *
+  * There is some amount of structure to an AFS volume dump.  Basically,
+  * you get a dump header, followed by a volume header, followed by some
+  * vnodes, followed by a dump end.  Each of these items (header, vnode,
+  * dump end) consists of a tag, a fixed amount of required information,
+  * and 0 or more tagged attributes (except dump-end, which has no attributes).
+  *
+  * Vnodes, in turn, are usually listed in a particular order.  First, we
+  * list all the directory vnodes in the volume, in increasing order by
+  * vnode.  Then, we list all the file vnodes, again in increasing order.
+  * Directory vnodes must have a complete set of attributes and data, but
+  * in an incremental dump, file vnodes may have no attributes if the vnode
+  * has not changed since the reference date.
+  *
+  * The primary purpose of this file is to define the tags and some magic
+  * numbers.  There is also some information that is defined in the Transarc
+  * provided header files.
+  */
+ 
+ 
+ /** MAGIC NUMBERS **/
+ #define DUMPVERSION     1
+ #define DUMPBEGINMAGIC  0xb3a11322
+ #define DUMPENDMAGIC    0x3a214b6e
+ 
+ 
+ /** TOP-LEVEL TAGS **/
+ #define TAG_DUMPHEADER  1
+ #define TAG_VOLHEADER   2
+ #define TAG_VNODE       3
+ #define TAG_DUMPEND     4
+ 
+ 
+ /** DUMP HEADER TAGS **/
+ #define DHTAG_VOLNAME    'n'
+ #define DHTAG_VOLID      'v'
+ #define DHTAG_DUMPTIMES  't'
+ 
+ 
+ /** VOLUME HEADER TAGS **/
+ #define VHTAG_VOLID      'i'
+ #define VHTAG_VERS       'v'
+ #define VHTAG_VOLNAME    'n'
+ #define VHTAG_INSERV     's'
+ #define VHTAG_BLESSED    'b'
+ #define VHTAG_VUNIQ      'u'
+ #define VHTAG_TYPE       't'
+ #define VHTAG_PARENT     'p'
+ #define VHTAG_CLONE      'c'
+ #define VHTAG_MAXQUOTA   'q'
+ #define VHTAG_MINQUOTA   'm'
+ #define VHTAG_DISKUSED   'd'
+ #define VHTAG_FILECNT    'f'
+ #define VHTAG_ACCOUNT    'a'
+ #define VHTAG_OWNER      'o'
+ #define VHTAG_CREAT      'C'
+ #define VHTAG_ACCESS     'A'
+ #define VHTAG_UPDATE     'U'
+ #define VHTAG_EXPIRE     'E'
+ #define VHTAG_BACKUP     'B'
+ #define VHTAG_OFFLINE    'O'
+ #define VHTAG_MOTD       'M'
+ #define VHTAG_WEEKUSE    'W'
+ #define VHTAG_DUDATE     'D'
+ #define VHTAG_DAYUSE     'Z'
+ 
+ 
+ /** VNODE TAGS **/
+ #define VTAG_TYPE        't'
+ #define VTAG_NLINKS      'l'
+ #define VTAG_DVERS       'v'
+ #define VTAG_CLIENT_DATE 'm'
+ #define VTAG_AUTHOR      'a'
+ #define VTAG_OWNER       'o'
+ #define VTAG_GROUP       'g'
+ #define VTAG_MODE        'b'
+ #define VTAG_PARENT      'p'
+ #define VTAG_SERVER_DATE 's'
+ #define VTAG_ACL         'A'
+ #define VTAG_DATA        'f'
+ 
+ 
+ #define AFS_DIR_EPP 64
+ 
+ typedef struct {
+   afs_uint16 pgcount;
+   afs_uint16 tag;
+   char freecount;
+   char freebitmap[AFS_DIR_EPP/8];
+   char padding[32 - (5 + AFS_DIR_EPP/8)];
+ } afs_dir_pagehdr;
+ 
+ typedef struct {
+   char flag;
+   char length;
+   afs_uint16 next;
+   afs_uint32 vnode;
+   afs_uint32 vunique;
+   char name[16];
+   char padding[4];
+ } afs_dir_direntry;
+ 
+ typedef union {
+   afs_dir_pagehdr header;
+   afs_dir_direntry entry[AFS_DIR_EPP];
+ } afs_dir_page;
+ 
+ #endif /* _DUMPFMT_H_ */
Index: openafs/src/tests/dumpscan.h
diff -c /dev/null openafs/src/tests/dumpscan.h:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/dumpscan.h	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,379 ----
+ /*
+  * CMUCS AFStools
+  * dumpscan - routines for scanning and manipulating AFS volume dumps
+  *
+  * Copyright (c) 1998 Carnegie Mellon University
+  * All Rights Reserved.
+  * 
+  * Permission to use, copy, modify and distribute this software and its
+  * documentation is hereby granted, provided that both the copyright
+  * notice and this permission notice appear in all copies of the
+  * software, derivative works or modified versions, and any portions
+  * thereof, and that both notices appear in supporting documentation.
+  *
+  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+  *
+  * Carnegie Mellon requests users of this software to return to
+  *
+  *  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
+  *  School of Computer Science
+  *  Carnegie Mellon University
+  *  Pittsburgh PA 15213-3890
+  *
+  * any improvements or extensions that they make and grant Carnegie Mellon
+  * the rights to redistribute these changes.
+  */
+ 
+ /* dumpscan.h - Public interface */
+ 
+ #ifndef _DUMPSCAN_H_
+ #define _DUMPSCAN_H_
+ 
+ #include "intNN.h"
+ #include "xfiles.h"
+ 
+ #include <lock.h>
+ #include <afs/afsint.h>
+ #include <afs/nfs.h>
+ #include <afs/ihandle.h>
+ #include <afs/vnode.h>
+ #include <afs/cmd.h>
+ #include <afs/auth.h>
+ #include <afs/bnode.h>
+ #include <afs/cellconfig.h>
+ #include <afs/kautils.h>
+ #include <afs/pterror.h>
+ #include <afs/vlserver.h>
+ #include <afs/volser.h>
+ #include <ubik.h>
+ 
+ /* Random useful types */
+ typedef struct tagged_field tagged_field;
+ typedef struct tag_parse_info tag_parse_info;
+ typedef afs_uint32 (*tag_parser)(XFILE *, unsigned char *, tagged_field *,
+                               afs_uint32, tag_parse_info *, void *, void *);
+ 
+ /* Error codes used within dumpscan.
+  * Any of the routines declared below, or callbacks used by them,
+  * may signal a system error by returning the error number, or
+  * some other error by returning a com_err code.  Note that
+  * ParseTaggedData does _not_ return DSERR_TAG; instead, it returns
+  * 0, assuming the tag will be handled at a higher level.
+  *
+  * In addition, these errors may be reported to the caller of
+  * ParseDumpFile using the error callback.  Such reports will be
+  * issued whether or not error recovery is possible or attempted.
+  *
+  * NB: These errors are now in dumpscan_errs.h
+  */
+ 
+ 
+ /* Backup system dump header */
+ /* Right now, this looks a lot like an old stage header.  Eventually, it
+  * should contain enough fields to fully represent headers from old or
+  * new stage, Transarc, or other backup systems, and the appropriate read
+  * functions should extract as much data as possible from the actual file
+  * to fill this in. */
+ typedef struct {
+   afs_uint32 version;
+   afs_uint32 from_date;
+   afs_uint32 to_date;
+   afs_uint32 dump_date;
+   afs_uint32 filenum;
+   unsigned char *server;
+   unsigned char *part;
+   unsigned char *volname;
+   afs_uint32 volid;
+   afs_uint32 dumplen;
+   afs_uint32 level;
+   afs_uint32 magic;
+   afs_uint32 cksum;
+   afs_uint32 flags;
+ } backup_system_header;
+ 
+ 
+ /** AFS dump header **/
+ #define F_DUMPHDR_VOLID       0x00000001
+ #define F_DUMPHDR_VOLNAME     0x00000002
+ #define F_DUMPHDR_FROM        0x00000004
+ #define F_DUMPHDR_TO          0x00000008
+ typedef struct {
+   u_int64 offset;           /* Where in the file is it? */
+   afs_uint32 field_mask;       /* What fields are present? */
+   afs_uint32 magic;            /* Magic number */
+   afs_uint32 version;          /* Dump format version */
+   afs_uint32 volid;            /* VolID of volume in dump */
+   unsigned char *volname;   /* Name of volume in dump */
+   afs_uint32 from_date;        /* Reference date */
+   afs_uint32 to_date;          /* Date of dump */
+ } afs_dump_header;
+ 
+ 
+ /** AFS volume header **/
+ #define F_VOLHDR_VOLID        0x00000001
+ #define F_VOLHDR_VOLVERS      0x00000002
+ #define F_VOLHDR_VOLNAME      0x00000004
+ #define F_VOLHDR_INSERV       0x00000008
+ #define F_VOLHDR_BLESSED      0x00000010
+ #define F_VOLHDR_VOLUNIQ      0x00000020
+ #define F_VOLHDR_VOLTYPE      0x00000040
+ #define F_VOLHDR_PARENT       0x00000080
+ #define F_VOLHDR_CLONE        0x00000100
+ #define F_VOLHDR_MAXQ         0x00000200
+ #define F_VOLHDR_MINQ         0x00000400
+ #define F_VOLHDR_DISKUSED     0x00000800
+ #define F_VOLHDR_NFILES       0x00001000
+ #define F_VOLHDR_ACCOUNT      0x00002000
+ #define F_VOLHDR_OWNER        0x00004000
+ #define F_VOLHDR_CREATE_DATE  0x00008000
+ #define F_VOLHDR_ACCESS_DATE  0x00010000
+ #define F_VOLHDR_UPDATE_DATE  0x00020000
+ #define F_VOLHDR_EXPIRE_DATE  0x00040000
+ #define F_VOLHDR_BACKUP_DATE  0x00080000
+ #define F_VOLHDR_OFFLINE_MSG  0x00100000
+ #define F_VOLHDR_MOTD         0x00200000
+ #define F_VOLHDR_WEEKUSE      0x00400000
+ #define F_VOLHDR_DAYUSE       0x00800000
+ #define F_VOLHDR_DAYUSE_DATE  0x01000000
+ typedef struct {
+   u_int64 offset;           /* Where in the file is it? */
+   afs_uint32 field_mask;       /* What fields are present? */
+   afs_uint32 volid;            /* Volume ID */
+   afs_uint32 volvers;          /* ?? */
+   unsigned char *volname;   /* Volume Name */
+   int     flag_inservice;   /* Inservice flag (0 or not) */
+   int     flag_blessed;     /* Blessed to come online (0 or not) */
+   afs_uint32 voluniq;          /* Volume uniquifier */
+   int     voltype;          /* Volume type */
+   afs_uint32 parent_volid;     /* Parent volume ID */
+   afs_uint32 clone_volid;      /* Clone volume ID */
+   afs_uint32 maxquota;         /* Max quota */
+   afs_uint32 minquota;         /* Min quota (obsolete) */
+   afs_uint32 diskused;         /* Disk blocks used */
+   afs_uint32 nfiles;           /* Number of files in volume */
+   afs_uint32 account_no;       /* Account number (unused) */
+   afs_uint32 owner;            /* Volume owner */
+   afs_uint32 create_date;      /* Creation date of this copy */
+   afs_uint32 access_date;      /* Last access */
+   afs_uint32 update_date;      /* Last modification */
+   afs_uint32 expire_date;      /* Expiration (unused) */
+   afs_uint32 backup_date;      /* Last backup clone */
+   unsigned char *offline_msg; /* Offline message */
+   unsigned char *motd_msg;    /* Volume MOTD */
+   afs_uint32 weekuse[7];       /* Weekuse data */
+   afs_uint32 dayuse;           /* # accesses in last day */
+   afs_uint32 dayuse_date;      /* Date for which dayuse is valid */
+ } afs_vol_header;
+ 
+ 
+ /** AFS vnode **/
+ #define F_VNODE_TYPE          0x00000001
+ #define F_VNODE_NLINKS        0x00000002
+ #define F_VNODE_PARENT        0x00000004
+ #define F_VNODE_DVERS         0x00000008
+ #define F_VNODE_AUTHOR        0x00000010
+ #define F_VNODE_OWNER         0x00000020
+ #define F_VNODE_GROUP         0x00000040
+ #define F_VNODE_MODE          0x00000080
+ #define F_VNODE_CDATE         0x00000100
+ #define F_VNODE_SDATE         0x00000200
+ #define F_VNODE_SIZE          0x00000800
+ #define F_VNODE_DATA          0x00001000
+ #define F_VNODE_ACL           0x00000400
+ typedef struct {
+   u_int64 offset;           /* Where in the file is it? */
+   afs_uint32 field_mask;       /* What fields are present? */
+   afs_uint32 vnode;            /* Vnode number */
+   afs_uint32 vuniq;            /* Uniquifier */
+   int     type;             /* Vnode type */
+   afs_uint16 nlinks;           /* Number of links (should be in 1 dir!) */
+   afs_uint32 parent;           /* Parent vnode */
+   afs_uint32 datavers;         /* Data version */
+   afs_uint32 author;           /* Last writer */
+   afs_uint32 owner;            /* Owner UID */
+   afs_uint32 group;            /* Owning group */
+   afs_uint16 mode;             /* UNIX mode bits */
+   afs_uint32 client_date;      /* Last modified date from client */
+   afs_uint32 server_date;      /* Last modified date on server */
+   afs_uint32 size;             /* Size of data */
+   u_int64 d_offset;         /* Where in the file is the data? */
+   unsigned char acl[SIZEOF_LARGEDISKVNODE - SIZEOF_SMALLDISKVNODE];
+ } afs_vnode;
+ 
+ 
+ /** AFS directory entry **/
+ typedef struct {
+   int  slot;                /* Directory slot # (info only) */
+   char *name;               /* Name of entry */
+   afs_uint32 vnode;            /* Vnode number */
+   afs_uint32 uniq;             /* Uniquifier */
+ } afs_dir_entry;
+ 
+ 
+ /** Tagged field definitions **/
+ #define DKIND_NOOP      0x00  /* No data */
+ #define DKIND_BYTE      0x10  /* 1 byte  - decimal */
+ #define DKIND_HEX8      0x11  /* 1 byte  - hex */
+ #define DKIND_CHAR      0x12  /* 1 byte  - character */
+ #define DKIND_FLAG      0x13  /* 1 byte  - true/false */
+ #define DKIND_INT16     0x20  /* 2 bytes - decimal */
+ #define DKIND_HEX16     0x21  /* 2 bytes - hex */
+ #define DKIND_INT32     0x30  /* 4 bytes - decimal */
+ #define DKIND_HEX32     0x31  /* 4 bytes - hex */
+ #define DKIND_TIME      0x32  /* 4 bytes - time */
+ #define DKIND_STRING    0x40  /* ASCIIZ string */
+ #define DKIND_SPECIAL   0x50  /* Custom parser */
+ #define DKIND_MASK     (~0x0f)
+ struct tag_parse_info {
+   void *err_refcon;
+   afs_uint32 (*cb_error)(afs_uint32, int, void *, char *, ...);
+   afs_uint32 flags;
+ #define TPFLAG_SKIP   0x0001
+ #define TPFLAG_RSKIP  0x0002
+   int shift_offset;
+   u_int64 shift_start;
+ };
+ struct tagged_field {
+   char tag;        /* Tag character */
+   int  kind;       /* Kind of object */
+   char *label;     /* Label to use (for debugging) */
+   tag_parser func; /* Parser function (for DKIND_SPECIAL) */
+   void *refptr;    /* Reference pointer (for parser's use) */
+   int  refarg;     /* Reference argument (for parser's use) */
+ };
+ 
+ 
+ /** Control structure for parsing volume dumps **/
+ typedef struct {
+   /* Callback functions:
+    * Whenever a "complex" object is parsed, we call a callback function.
+    * The callback gets a pointer to the complex object, the file pointer
+    * for the dump we're parsing, and the value of refcon in this structure.
+    * Callbacks should return 0 if all is well, non-0 to abort the dump.
+    * By convention, positive numbers should be errno values, and negative
+    * numbers can be used for other things.  It is OK to _try_ to seek anywhere
+    * in the file.  Beware, though, that the input is not always seekable.
+    * Also, note that the structures passed to these callbacks are going to
+    * go away after the callback returns.  There is no way to prevent this;
+    * make a copy if you want one.
+    */
+   void *refcon;
+   afs_uint32 (*cb_bckhdr)(backup_system_header *, XFILE *, void *); /* Backup   */
+   afs_uint32 (*cb_dumphdr)(afs_dump_header *, XFILE *, void *); /* Dump hdr     */
+   afs_uint32 (*cb_volhdr)(afs_vol_header *, XFILE *, void *);   /* Volume hdr   */
+   afs_uint32 (*cb_vnode_dir)(afs_vnode *, XFILE *, void *);     /* Directory    */
+   afs_uint32 (*cb_vnode_file)(afs_vnode *, XFILE *, void *);    /* File         */
+   afs_uint32 (*cb_vnode_link)(afs_vnode *, XFILE *, void *);    /* Symlink      */
+   afs_uint32 (*cb_vnode_empty)(afs_vnode *, XFILE *, void *);   /* vnode+uniq   */
+   afs_uint32 (*cb_vnode_wierd)(afs_vnode *, XFILE *, void *);   /* Unknown type */
+ 
+   /* This function is called when there is an error in the dump. */
+   /* (cb_error)(errno, fatal, refcon, msg_fmt, msg_args...) */
+   void *err_refcon; /* If set, use instead of refcon for dir entries */
+   afs_uint32 (*cb_error)(afs_uint32, int, void *, char *, ...);
+ 
+   /* This function is called for each directory entry, if set */
+   afs_uint32 (*cb_dirent)(afs_vnode *, afs_dir_entry *, XFILE *, void *);
+ 
+   int flags;            /* Flags and options */
+ #define DSFLAG_SEEK     0x0001  /* Input file is seekable */
+ 
+   int print_flags;      /* Flags to control what is printed */
+ #define DSPRINT_BCKHDR  0x0001  /* Print backup system header */
+ #define DSPRINT_DUMPHDR 0x0002  /* Print AFS dump header */
+ #define DSPRINT_VOLHDR  0x0004  /* Print AFS volume header */
+ #define DSPRINT_ITEM    0x0010  /* Print top-level tags */
+ #define DSPRINT_VNODE   0x0020  /* Print vnode attributes */
+ #define DSPRINT_ACL     0x0040  /* Print directory ACL's */
+ #define DSPRINT_DIR     0x0080  /* Print directory contents */
+ #define DSPRINT_DEBUG   0x0100  /* Print debugging info */
+ #define DSPRINT_PATH    0x0200  /* Print vnode paths */
+ 
+   int repair_flags;     /* Flags to control what is repaired.
+                          * Most of these _require_ DSFLAG_SEEK */
+ #define DSFIX_SKIP      0x0001  /* Try to skip null tags */
+ #define DSFIX_RSKIP     0x0002  /* Seek back to fing skipped tags */
+ #define DSFIX_VDSYNC    0x0004  /* Resync location after vnode data */
+ #define DSFIX_VFSYNC    0x0008  /* Try to resync after bad vnode */
+ 
+   /** Things below this point for internal use only **/
+   afs_uint32 vol_uniquifier;
+ } dump_parser;
+ 
+ 
+ /** Hash table and control info for pathname manipulation **/
+ typedef struct vhash_ent {
+   struct vhash_ent *next;    /* Pointer to next entry */
+   afs_uint32 vnode;             /* VNode number */
+   afs_uint32 parent;            /* Parent VNode number */
+   u_int64 v_offset;          /* Offset to start of vnode */
+   u_int64 d_offset;          /* Offset to data (0 if none) */
+   afs_uint32 d_size;            /* Size of data */
+ } vhash_ent;
+ typedef struct {
+   afs_uint32 n_vnodes;          /* Number of vnodes in volume */
+   afs_uint32 n_dirs;            /* Number of file vnodes */
+   afs_uint32 n_files;           /* Number of directory vnodes */
+   int hash_size;             /* Hash table size (bits) */
+   vhash_ent **hash_table;    /* Hash table */
+   dump_parser *p;            /* Dump parser to use */
+ } path_hashinfo;
+ 
+ 
+ /** Function prototypes **/
+ /** Only the functions declared below are public interfaces **/
+ /** Maybe someday, I'll write man pages for these **/
+ 
+ /* primitive.c - I/O primitives */
+ extern afs_uint32 ReadByte(XFILE *, unsigned char *);
+ extern afs_uint32 ReadInt16(XFILE *, afs_uint16 *);
+ extern afs_uint32 ReadInt32(XFILE *, afs_uint32 *);
+ extern afs_uint32 ReadString(XFILE *, unsigned char **);
+ extern afs_uint32 WriteByte(XFILE *, unsigned char);
+ extern afs_uint32 WriteInt16(XFILE *, afs_uint16);
+ extern afs_uint32 WriteInt32(XFILE *, afs_uint32);
+ extern afs_uint32 WriteString(XFILE *, unsigned char *);
+ extern afs_uint32 WriteTagByte(XFILE *, unsigned char, unsigned char);
+ extern afs_uint32 WriteTagInt16(XFILE *, unsigned char, afs_uint16);
+ extern afs_uint32 WriteTagInt32(XFILE *, unsigned char, afs_uint32);
+ extern afs_uint32 WriteTagInt32Pair(XFILE *, unsigned char, afs_uint32, afs_uint32);
+ 
+ /* parsetag.c - Parse tagged data */
+ extern afs_uint32 ParseTaggedData(XFILE *, tagged_field *, unsigned char *,
+                            tag_parse_info *, void *, void *);
+ 
+ /* stagehdr.c - Parse and dump Stage dump headers */
+ extern afs_uint32 ParseStageHdr(XFILE *, unsigned char *, backup_system_header *);
+ extern afs_uint32 DumpStagehdr(XFILE *, backup_system_header *);
+ 
+ /* backuphdr.c - Parse and print backup system headers */
+ extern void PrintBackupHdr(backup_system_header *);
+ 
+ /* parsedump.c - Parse all or part of a volume dump */
+ extern afs_uint32 ParseDumpFile(XFILE *, dump_parser *);
+ extern afs_uint32 ParseDumpHeader(XFILE *, dump_parser *);
+ extern afs_uint32 ParseVolumeHeader(XFILE *, dump_parser *);
+ extern afs_uint32 ParseVNode(XFILE *, dump_parser *);
+ 
+ 
+ /* directory.c - Directory parsing and lookup */
+ extern afs_uint32 ParseDirectory(XFILE *, dump_parser *, afs_uint32, int);
+ extern afs_uint32 DirectoryLookup(XFILE *, dump_parser *, afs_uint32,
+                            char **, afs_uint32 *, afs_uint32 *);
+ 
+ /* dump.c - Dump parts of a volume dump */
+ extern afs_uint32 DumpDumpHeader(XFILE *, afs_dump_header *);
+ extern afs_uint32 DumpVolumeHeader(XFILE *, afs_vol_header *);
+ extern afs_uint32 DumpVNode(XFILE *, afs_vnode *);
+ extern afs_uint32 DumpVnodeData(XFILE *, char *, afs_uint32);
+ extern afs_uint32 CopyVnodeData(XFILE *, XFILE *, afs_uint32);
+ 
+ /* pathname.c - Follow and construct pathnames */
+ extern afs_uint32 Path_PreScan(XFILE *, path_hashinfo *, int);
+ extern void Path_FreeHashTable(path_hashinfo *);
+ extern afs_uint32 Path_Follow(XFILE *, path_hashinfo *, char *, vhash_ent *);
+ extern afs_uint32 Path_Build(XFILE *, path_hashinfo *, afs_uint32, char **, int);
+ 
+ #endif
Index: openafs/src/tests/dumpscan_errs.et
diff -c /dev/null openafs/src/tests/dumpscan_errs.et:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/dumpscan_errs.et	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,37 ----
+ # COPYRIGHT NOTICE
+ # Copyright (c) 1997 Carnegie Mellon University
+ # All Rights Reserved.
+ # 
+ # Permission to use, copy, modify and distribute this software and its
+ # documentation is hereby granted, provided that both the copyright
+ # notice and this permission notice appear in all copies of the
+ # software, derivative works or modified versions, and any portions
+ # thereof, and that both notices appear in supporting documentation.
+ # 
+ # CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ # CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ # ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ # 
+ # Carnegie Mellon requests users of this software to return to
+ # 
+ #  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
+ #  School of Computer Science
+ #  Carnegie Mellon University
+ #  Pittsburgh PA 15213-3890
+ # 
+ # any improvements or extensions that they make and grant Carnegie Mellon
+ # the rights to redistribute these changes.
+ 
+ # UB - Unified Backups
+ # methods/afs/dumpscan/afsdump_errs.et - AFS dump scanner errors
+ 
+ error_table AVds
+   ec DSERR_TAG,            "Unknown tag in AFS volume dump"
+   ec DSERR_MAGIC,          "Bad magic number in AFS volume dump"
+   ec DSERR_BOGUS,          "Bogus value in AFS volume dump"
+   ec DSERR_FMT,            "AFS volume dump format incorrect"
+   ec DSERR_KEEP,           "[AFS dumpscan internal: keep string]"
+   ec DSERR_PANIC,          "[AFS dumpscan internal: panic]"
+   ec DSERR_DONE,           "[AFS dumpscan internal: done]"
+   ec DSERR_MEM,            "[AFS dumpscan internal: out of memory]"
+ end
Index: openafs/src/tests/dumptool.c
diff -c /dev/null openafs/src/tests/dumptool.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/dumptool.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,2640 ----
+ /*
+  * $Id: dumptool.c,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+  *
+  * dumptool - A tool to manage MR-AFS dump files
+  *
+  * The dump file format ought to be documented _somewhere_, and
+  * this seems like a good as a place as any ...
+  *
+  * A AFS dump file is marked off into a series of sections.  Each
+  * section marked by a dump tag.  A tag is a single byte who's value
+  * corresponds with the next section.  The sections are (in order):
+  *
+  * DUMPHEADER (tag 0x01)
+  * VOLUMEHEADER (tag 0x02)
+  * VNODE (tag 0x03)
+  * DUMPEND (tag 0x04)
+  *
+  * Descriptions of the sections follow.  Note that in all cases, data is
+  * stored in the dump in network byte order.
+  *
+  * DUMPHEADER:
+  *
+  * DUMPHEADER contains two parts: the DUMPMAGIC magic number (32 bits)
+  * and the dump header itself.
+  *
+  * The dump header itself consists of a series of tagged values,
+  * each tag marking out members of the DumpHeader structure.  The
+  * routine ReadDumpHeader explains the specifics of these tags.
+  *
+  * VOLUMEHEADER:
+  *
+  * VOLUMEHEADER is a series of tagged values corresponding to the elements
+  * of the VolumeDiskData structure.  See ReadVolumeHeader for more
+  * information
+  *
+  * VNODE:
+  *
+  * The VNODE section is all vnodes contained in the volume (each vnode
+  * itself is marked with the VNODE tag, so it's really a sequence of
+  * VNODE tags, unlike other sections).
+  *
+  * Each vnode consists of three parts: the vnode number (32 bits), the
+  * uniqifier (32 bits), and a tagged list of elements corresponding to
+  * the elements of the VnodeDiskData structure.  See ScanVnodes for
+  * more information.  Note that if file data is associated with a vnode,
+  * it will be contained here.
+  *
+  * DUMPEND:
+  *
+  * The DUMPEND section consists of one part: the DUMPENDMAGIC magic
+  * number (32 bits).
+  * 
+  * Notes:
+  *
+  * The tagged elements are all ASCII letters, as opposed to the section
+  * headers (which are 0x01, 0x02, ...).  Thus, an easy way to tell when
+  * you've reached the end of an element sequence is to check to see if
+  * the next tag is a printable character (this code tests for < 20).
+  *
+  * "vos dump" dumps the large vnode index, then the small vnode index,
+  * so directories will appear first in the VNODE section.
+  */
+ 
+ #include <stdio.h>
+ #include <sys/types.h>
+ #include <sys/param.h>
+ #include <netinet/in.h>
+ #include <unistd.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <errno.h>
+ #include <termios.h>
+ #include <fnmatch.h>
+ 
+ #include <lock.h>
+ #include <afs/param.h>
+ #include <afs/afsint.h>
+ #include <afs/nfs.h>
+ #include <afs/acl.h>
+ #if !defined(PRE_AFS_36) && !defined(RESIDENCY)
+ #include <afs/ihandle.h>
+ #endif /* !defined(PRE_AFS_36) && !defined(RESIDENCY) */
+ #include <afs/vnode.h>
+ #include <afs/volume.h>
+ 
+ #ifdef RESIDENCY
+ #include <afs/rsdefs.h>
+ #include <afs/remioint.h>
+ #endif /* RESIDENCY */
+ 
+ #include <afs/dir.h>
+ 
+ /*
+  * Sigh.  Linux blows it again
+  */
+ 
+ #ifdef linux
+ #include <pty.h>
+ #endif
+ 
+ /*
+  * Stuff that is in private AFS header files, unfortunately
+  */
+ 
+ #define DUMPVERSION	1
+ #define DUMPENDMAGIC	0x3A214B6E
+ #define DUMPBEGINMAGIC	0xB3A11322
+ #define D_DUMPHEADER	1
+ #define D_VOLUMEHEADER	2
+ #define D_VNODE		3
+ #define D_DUMPEND	4
+ #define D_MAX		20
+ 
+ #define MAXDUMPTIMES	50
+ 
+ struct DumpHeader {
+ 	int32_t version;
+ 	VolumeId volumeId;
+ 	char volumeName[VNAMESIZE];
+ 	int nDumpTimes;             /* Number of pairs */
+ 	struct {
+ 		int32_t from, to;
+ 	} dumpTimes[MAXDUMPTIMES];
+ };
+ 
+ /*
+  * Our command-line arguments
+  */
+ 
+ #ifdef RESIDENCY
+ struct {
+ 	int Algorithm;		/* Conversion algorithm */
+ 	int Size;		/* Directory hierarchy size */
+ 	int FSType;		/* File system type */
+ 	int DeviceTag;		/* Device Tag */
+ } rscmdlineinfo[RS_MAXRESIDENCIES];
+ 
+ /*
+  * This stuff comes from ufsname.c (which itself takes it from
+  * ufs_interfaces.c)
+  */
+ 
+ /* There is an assumption that all of the prefixes will have exactly one '/' */
+ static char *Ufs_Prefixes[] = {"/ufs", "/slowufs", "/cdmf", "/sdmf"};
+ #define MAX_ITERATIONS 10
+ #define UFS_SUMMARYTREENAME "Summaries"
+ #define UFS_STAGINGTREENAME "Staging"
+ #define UFS_VOLUMEHEADERTREENAME "VolHeaders"
+ #define UFS_VOLUMETREENAME "Volumes"
+ #define UFS_ALGORITHMBASE 'A'
+ #define UFS_MOUNTPOINTBASE 'a'
+ #define UFS_ALGORITHMS 3
+ #define UFS_LINK_MAX 64 /* Arbitrary. */
+ #define HARD_LINKED_FILE -2
+ #define TAGSTONAME(FileName, MountPoint, Sections, Level1, RWVolume, Vnode, Uniquifier, Algorithm) \
+ { \
+     if (Level1) \
+         sprintf(FileName,"%s/%lu/%lu/%c%lu.%lu.%lu.%lu.%lu", MountPoint, \
+                 (Sections)[0], (Sections)[1], UFS_ALGORITHMBASE + Algorithm, \
+                 (Sections)[2], (Sections)[3], RWVolume, Vnode, Uniquifier); \
+     else \
+         sprintf(FileName,"%s/%lu/%c%lu.%lu.%lu.%lu.%lu", MountPoint, \
+                 (Sections)[0], UFS_ALGORITHMBASE + Algorithm, \
+                 (Sections)[1], (Sections)[2], RWVolume, Vnode, Uniquifier); \
+ }
+ #define TAGSTOSTAGINGNAME(FileName, MountPoint, RWVolume, Vnode, Uniquifier) \
+     sprintf(FileName,"%s/%s/%lu.%lu.%lu", MountPoint, \
+ 	    UFS_STAGINGTREENAME, RWVolume, Vnode, Uniquifier)
+ #define TAGSTOVOLUMEHEADERNAME(FileName, MountPoint, FileTag1, FileTag2) \
+     sprintf(FileName,"%s/%s/%lu", MountPoint, UFS_VOLUMEHEADERTREENAME, \
+ 	    FileTag1)
+ #define TAGSTOVOLUMEINFONAME(FileName, MountPoint, FileTag1, FileTag2) \
+     sprintf(FileName,"%s/%s/%lu/%lu", MountPoint, \
+ 	    UFS_VOLUMETREENAME, FileTag2, FileTag1)
+ #define TAGSTOVOLUMENAME(FileName, MountPoint, FileTag1, FileTag2, RWVolume) \
+     sprintf(FileName,"%s/%s/%lu/%lu.%lu", MountPoint, \
+ 	    UFS_VOLUMETREENAME, FileTag2, FileTag1, RWVolume)
+ #define TAGSTOSUMMARYNAME(FileName, MountPoint, FileTag1, FileTag2, SummaryRequestor, Residency) \
+     sprintf(FileName,"%s/%s/%lu.%lu.%lu.%lu", MountPoint, \
+ 	    UFS_SUMMARYTREENAME, FileTag1, FileTag2, SummaryRequestor, \
+ 	    Residency)
+ #define DEVICETAGNUMBERTOMOUNTPOINT(MountPoint, DeviceTagNumber, FSType) \
+     sprintf(MountPoint,"%s%c", Ufs_Prefixes[FSType], UFS_MOUNTPOINTBASE + \
+ 	    DeviceTagNumber)
+ #define MOUNTPOINTTODEVICETAGNUMBER(MountPoint) \
+     MountPoint[strlen(MountPoint) - 1] - UFS_MOUNTPOINTBASE
+ #define DEVICETAGNUMBERTOVOLUMEHEADERTREE(TreeName, MountPoint) \
+     sprintf(TreeName,"%s/%s", MountPoint, UFS_VOLUMEHEADERTREENAME)
+ #define UFS_RESIDENCIES_FILE "Residencies"
+ 
+ /* We don't ever want to map to uid/gid -1.  fchown() takes that as a
+    don't change flag.  We know however that volume number range from
+    0x2000000 to 0x20FFFFFF (see VAllocateVolumeId() in vol/vutil.c)
+    so we will use that to insure that -1 never appears. */
+ #define RWVolumeToUid(RWVolume) ((RWVolume >> 12) & 0xFFFF)
+ #define RWVolumeToGid(RWVolume) ((RWVolume & 0xFFF) | \
+ 				 (((RWVolume >> 28) & 0xF) << 12))
+ #define UidGidToRWVolume(Uid, Gid) ((Gid & 0xFFF) | ((Uid & 0xFFFF) << 12) | \
+ 				    ((Gid & 0xF000) << 16))
+ 
+ 
+ /* These routines generate a file name to correspond to the given tag
+    numbers. */
+ 
+ /* The following entropy array contains the order of bits from highest entropy
+    to lowest in the numbers FileTag1 and FileTag2.  Bit numbers 32 and above
+    correspond to FileTag2.  This ordering was determined by examining all read-
+    write volumes in the psc.edu cell. */
+ char UfsEntropy[1][64] = {
+   {1, 2, 3, 4, 33, 5, 6, 7, 44, 45, 46, 36, 8, 34, 42, 35, 
+      9, 40, 38, 32, 43, 10, 39, 37, 11, 41, 12, 13, 14, 0, 
+      15, 16, 61, 17, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 
+      50, 49, 48, 47, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 
+      21, 20, 19, 18, 62, 63},
+ };
+ 
+ uint32_t Directories[3][2] = { {256, 0}, {256, 16}, {256, 256}, };
+ #endif /* RESIDENCY */
+ 
+ static int verbose = 0;
+ static int numNoDirData = 0;
+ static int termsize = 0;
+ int Testing = 0;
+ #ifdef RESIDENCY
+ extern resid ServerRequestorId;
+ #endif /* RESIDENCY */
+ 
+ /*
+  * We use this structure to hold vnode data in our hash table.
+  * It's indexed by vnode number.
+  */
+ 
+ struct vnodeData {
+ 	struct VnodeDiskObject *vnode;	/* A pointer to the disk vnode */
+ 	int vnodeNumber;		/* The vnode number */
+ 	long dumpdata;			/* File offset of dump data (if
+ 					   available */
+ 	unsigned char *filedata;	/* A pointer to the actual file
+ 					   data itself (if available) */
+ 	unsigned int datalength;	/* The length of the data */
+ };
+ 
+ /*
+  * This contains the current location when we're doing a scan of a
+  * directory.
+  */
+ 
+ struct DirCursor {
+ 	int hashbucket;			/* Current hash bucket */
+ 	int entry;			/* Entry within hash bucket */
+ };
+ 
+ /*
+  * Arrays to hold vnode data
+  */
+ 
+ struct vnodeData **LargeVnodeIndex;
+ struct vnodeData **SmallVnodeIndex;
+ int numLargeVnodes = 0;
+ int numSmallVnodes = 0;
+ 
+ /*
+  * Crap for the libraries
+  */
+ 
+ int ShutdownInProgress = 0;
+ 
+ /*
+  * Our local function prototypes
+  */
+ 
+ static int ReadDumpHeader(FILE *, struct DumpHeader *);
+ static int ReadVolumeHeader(FILE *, VolumeDiskData *);
+ static int ScanVnodes(FILE *, VolumeDiskData *, int);
+ static int DumpVnodeFile(FILE *, struct VnodeDiskObject *, VolumeDiskData *);
+ static struct vnodeData *InsertVnode(unsigned int, struct VnodeDiskObject *);
+ static struct vnodeData *GetVnode(unsigned int);
+ static int CompareVnode(const void *, const void *);
+ static void InteractiveRestore(FILE *, VolumeDiskData *);
+ static void DirectoryList(int, char **, struct vnodeData *, VolumeDiskData *);
+ static void DirListInternal(struct vnodeData *, char *[], int, int, int, int,
+ 			    int, int, VolumeDiskData *, char *);
+ static int CompareDirEntry(const void *, const void *);
+ static struct vnodeData *ChangeDirectory(int, char **, struct vnodeData *);
+ static void CopyFile(int, char **, struct vnodeData *, FILE *);
+ static void CopyVnode(int, char **, FILE *);
+ static void DumpAllFiles(int, char **, struct vnodeData *, VolumeDiskData *);
+ static void DumpAllResidencies(FILE *, struct vnodeData *, VolumeDiskData *);
+ static struct vnodeData *FindFile(struct vnodeData *, char *);
+ static void ResetDirCursor(struct DirCursor *, struct vnodeData *);
+ static struct DirEntry *ReadNextDir(struct DirCursor *, struct vnodeData *);
+ static void MakeArgv(char *, int *, char ***);
+ static char *GetToken(char *, char **, char *, char *[]);
+ static int ReadInt16(FILE *, uint16_t *);
+ static int ReadInt32(FILE *, uint32_t *);
+ static int ReadString(FILE *, char *, int);
+ static int ReadByteString(FILE *, void *, int);
+ 
+ int
+ main(int argc, char *argv[])
+ {
+ 	int c, errflg = 0, dumpvnodes = 0, force = 0, inode = 0;
+ 	unsigned int magic;
+ 	struct DumpHeader dheader;
+ 	VolumeDiskData vol;
+ 	long offset;
+ 	int Res, Arg1, Arg2, Arg3, i;
+ 	char *p;
+ 	struct winsize win;
+ 	FILE *f;
+ 
+ #ifdef RESIDENCY
+ 	for (i = 0; i < RS_MAXRESIDENCIES; i++) {
+ 		rscmdlineinfo[i].Algorithm = -1;
+ 		rscmdlineinfo[i].Size = -1;
+ 		rscmdlineinfo[i].DeviceTag = -1;
+ 		rscmdlineinfo[i].FSType = - 1;
+ 	}
+ #endif /* RESIDENCY */
+ 
+ 	/*
+ 	 * Sigh, this is dumb, but we need the terminal window size
+ 	 * to do intelligent things with "ls" later on.
+ 	 */
+ 
+ 	if (isatty(STDOUT_FILENO)) {
+ 		if ((p = getenv("COLUMNS")) != NULL)
+ 			termsize = atoi(p);
+ 		else if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) == 0 &&
+ 			 win.ws_col > 0)
+ 			termsize = win.ws_col;
+ 	}
+ 
+ 	while ((c = getopt(argc, argv, "difr:t:v")) != EOF)
+ 		switch (c) {
+ 		case 't':
+ #ifdef RESIDENCY
+ 			if (sscanf(optarg, "%d/%d", &Res, &Arg1) != 2) {
+ 				errflg++;
+ 				break;
+ 			}
+ 
+ 			if (1 << (ffs(Res) - 1) != Res) {
+ 				fprintf(stderr, "Invalid residency %d\n", Res);
+ 				errflg++;
+ 				break;
+ 			}
+ 
+ 			if (Arg1 < 0 || Arg1 > 26) {
+ 				fprintf(stderr, "Invalid device tag: %d\n",
+ 					Arg1);
+ 				errflg++;
+ 				break;
+ 			}
+ 			rscmdlineinfo[ffs(Res) - 1].DeviceTag = Arg1;
+ #else /* RESIDENCY */
+ 			fprintf(stderr, "-t not supported in non-MRAFS "
+ 				"dumptool.\n");
+ 			errflg++;
+ #endif /* RESIDENCY */
+ 			break;
+ 
+ 		case 'r':
+ #ifdef RESIDENCY
+ 			if (sscanf(optarg, "%d/%d/%d/%d", &Res, &Arg1, &Arg2,
+ 				   &Arg3) != 4) {
+ 				errflg++;
+ 				break;
+ 			}
+ 
+ 			if (Arg1 < 0 || Arg1 > 3) {
+ 				fprintf(stderr, "Invalid fstype: %d\n", Arg1);
+ 				errflg++;
+ 				break;
+ 			}
+ 
+ 			if (Arg2 < 0 || Arg2 > 2) {
+ 				fprintf(stderr, "Invalid size: %d\n", Arg2);
+ 				errflg++;
+ 				break;
+ 			}
+ 
+ 			if (Arg3 <= 0 || Arg3 > UFS_ALGORITHMS) {
+ 				fprintf(stderr, "Invalid algorithm: %d\n",
+ 					Arg3);
+ 				errflg++;
+ 				break;
+ 			}
+ 			rscmdlineinfo[ffs(Res) - 1].FSType = Arg1;
+ 			rscmdlineinfo[ffs(Res) - 1].Size = Arg2;
+ 			rscmdlineinfo[ffs(Res) - 1].Algorithm = Arg3;
+ #else /* RESIDENCY */
+ 			fprintf(stderr, "-r not supported in non-MRAFS "
+ 				"dumptool.\n");
+ 			errflg++;
+ #endif /* RESIDENCY */
+ 			break;
+ 		case 'd':
+ #ifdef RESIDENCY
+ 			dumpvnodes++;
+ #else /* RESIDENCY */
+ 			fprintf(stderr, "-d not supported in non-MRAFS "
+ 				"dumptool.\n");
+ 			errflg++;
+ #endif /* RESIDENCY */
+ 			break;
+ 		case 'v':
+ 			verbose++;
+ 			break;
+ 		case 'f':
+ 			force++;
+ 			break;
+ 		case 'i':
+ 			inode++;
+ 			break;
+ 		case '?':
+ 		default:
+ 			errflg++;
+ 		}
+ 	
+ 	if (errflg || optind == argc) {
+ 		fprintf(stderr, "Usage: %s\n\t[-v] [-f]\n\t"
+ #ifdef RESIDENCY
+ 			"[-t Residency/Tag]\n\t"
+ 			"[-r Residency/Type/Size/Algorithm]\n\t"
+ 			"[-d] filename [file_in_dump [file in dump ...]]\n",
+ #else /* RESIDENCY */
+ 			"filename\n",
+ #endif /* RESIDENCY */
+ 			argv[0]);
+ 		exit(1);
+ 	}
+ 
+ 	/*
+ 	 * Try opening the dump file
+ 	 */
+ 
+ 	if ((f = fopen(argv[optind], "rb")) == NULL) {
+ 		fprintf(stderr, "open of dumpfile %s failed: %s\n", argv[optind],
+ 			strerror(errno));
+ 		exit(1);
+ 	}
+ 
+ 	if (ReadDumpHeader(f, &dheader)) {
+ 		fprintf(stderr, "Failed to read dump header!\n");
+ 		exit(1);
+ 	}
+ 
+ 	if (verbose)
+ 		printf("Dump is for volume %lu (%s)\n", dheader.volumeId,
+ 			dheader.volumeName);
+ 
+ 	if (getc(f) != D_VOLUMEHEADER) {
+ 		fprintf(stderr, "Volume header is missing from dump, aborting\n");
+ 		exit(1);
+ 	}
+ 
+ 	if (ReadVolumeHeader(f, &vol)) {
+ 		fprintf(stderr, "Unable to read volume header\n");
+ 		exit(1);
+ 	}
+ 
+ 	if (verbose) {
+ 		printf("Volume information:\n");
+ 		printf("\tid = %lu\n", vol.id);
+ 		printf("\tparent id = %lu\n", vol.parentId);
+ 		printf("\tname = %s\n", vol.name);
+ 		printf("\tflags =");
+ 		if (vol.inUse)
+ 			printf(" inUse");
+ 		if (vol.inService)
+ 			printf(" inService");
+ 		if (vol.blessed)
+ 			printf(" blessed");
+ 		if (vol.needsSalvaged)
+ 			printf(" needsSalvaged");
+ 		printf("\n");
+ 		printf("\tuniquifier = %lu\n", vol.uniquifier);
+ 		printf("\tCreation date = %s", ctime((time_t *) &vol.creationDate));
+ 		printf("\tLast access date = %s", ctime((time_t *) &vol.accessDate));
+ 		printf("\tLast update date = %s", ctime((time_t *) &vol.updateDate));
+ 		printf("\tVolume owner = %lu\n", vol.owner);
+ 	}
+ 
+ 	if (verbose)
+ 		printf("Scanning vnodes (this may take a while)\n");
+ 
+ 	/*
+ 	 * We need to do two vnode scans; one to get the number of
+ 	 * vnodes, the other to actually build the index.
+ 	 */
+ 
+ 	offset = ftell(f);
+ 
+ 	if (ScanVnodes(f, &vol, 1)) {
+ 		fprintf(stderr, "First vnode scan failed, aborting\n");
+ 		exit(1);
+ 	}
+ 
+ 	fseek(f, offset, SEEK_SET);
+ 
+ 	if (ScanVnodes(f, &vol, 0)) {
+ 		fprintf(stderr, "Second vnode scan failed, aborting\n");
+ 		exit(1);
+ 	}
+ 
+ 	if (getc(f) != D_DUMPEND || ReadInt32(f, &magic) ||
+ 	    magic != DUMPENDMAGIC) {
+ 		fprintf(stderr, "Couldn't find dump postamble, ");
+ 		if (! force) {
+ 			fprintf(stderr, "aborting (use -f to override)\n");
+ 			exit(1);
+ 		} else {
+ 			fprintf(stderr, "continuing anyway\n");
+ 			fprintf(stderr, "WARNING: Dump may not be complete!\n");
+ 		}
+ 	}
+ 
+ 	/*
+ 	 * If we wanted to simply dump all vnodes, do it now
+ 	 */
+ 
+ #ifdef RESIDENCY
+ 	if (dumpvnodes) {
+ 		struct vnodeData *vdata;
+ 
+ 		for (i = 0; i < numLargeVnodes; i++) {
+ 
+ 			vdata = LargeVnodeIndex[i];
+ 
+ 			if (vdata->vnode->type == vFidLookup)
+ 				if (DumpVnodeFile(stdout, vdata->vnode, &vol)) {
+ 					fprintf(stderr, "DumpVnodeFile failed, "
+ 						"aborting\n");
+ 					exit(1);
+ 				}
+ 		}
+ 
+ 		for (i = 0; i < numSmallVnodes; i++) {
+ 
+ 			vdata = SmallVnodeIndex[i];
+ 
+ 			if (vdata->vnode->type == vFidLookup)
+ 				if (DumpVnodeFile(stdout, vdata->vnode, &vol)) {
+ 					fprintf(stderr, "DumpVnodeFile failed, "
+ 						"aborting\n");
+ 					exit(1);
+ 				}
+ 		}
+ 
+ 	} else
+ #endif /* RESIDENCY */
+ 	if (inode) {
+ 		/*
+ 		 * Dump out all filenames with their corresponding FID
+ 		 */
+ 		
+ 		struct vnodeData *rootvdata;
+ 
+ 		if ((rootvdata = GetVnode(1)) == NULL) {
+ 			fprintf(stderr, "Can't get vnode data for root "
+ 				"vnode!  Aborting\n");
+ 			exit(1);
+ 		}
+ 
+ 		DirListInternal(rootvdata, NULL, 0, 0, 1, 0, 1, 0, &vol, "");
+ 		
+ 	} else if (argc > optind + 1) {
+ #ifdef RESIDENCY
+ 		/*
+ 		 * Dump out residencies of files given on the command line.
+ 		 */
+ 
+ 		struct vnodeData *vdata, *rootvdata;
+ 
+ 		if ((rootvdata = GetVnode(1)) == NULL) {
+ 			fprintf(stderr, "Can't get vnode data for root "
+ 				"vnode!  Aborting\n");
+ 			exit(1);
+ 		}
+ 
+ 		for (i = optind + 1; i < argc; i++) {
+ 
+ 			if ((vdata = FindFile(rootvdata, argv[i])) == NULL) {
+ 				fprintf(stderr, "Skipping file %s\n",
+ 					argv[i]);
+ 				continue;
+ 			}
+ 
+ 			if (verbose)
+ 				printf("Residency locations for %s:\n",
+ 				       argv[i]);
+ 
+ 			while (vdata->vnode->NextVnodeId != 0) {
+ 
+ 				vdata = GetVnode(vdata->vnode->NextVnodeId);
+ 
+ 				if (vdata == NULL) {
+ 					fprintf(stderr, "We had a vnode chain "
+ 						"pointer to a vnode that "
+ 						"doesn't exist, aborting!\n");
+ 					exit(1);
+ 				}
+ 				if (vdata->vnode->type == vFidLookup)
+ 					DumpVnodeFile(stdout, vdata->vnode,
+ 						      &vol);
+ 			}
+ 		}
+ #else /* RESIDENCY */
+ 		fprintf(stderr, "Extra arguments after dump filename: %s\n",
+ 			argv[optind]);
+ 		exit(1);
+ #endif /* RESIDENCY */
+ 	} else {
+ 		/*
+ 		 * Perform an interactive restore
+ 		 */
+ 	
+ 		InteractiveRestore(f, &vol);
+ 	}
+ 
+ 	exit(0);
+ }
+ 
+ /*
+  * Read the dump header, which is at the beginning of every dump
+  */
+ 
+ static int
+ ReadDumpHeader(FILE *f, struct DumpHeader *header)
+ {
+ 	unsigned int magic;
+ 	int tag, i;
+ 
+ 	if (getc(f) != D_DUMPHEADER ||
+ 	    ReadInt32(f, &magic) || ReadInt32(f, (unsigned int *)
+ 					      &header->version) ||
+ 	    magic != DUMPBEGINMAGIC) {
+ 		if (verbose)
+ 			fprintf(stderr, "Couldn't find dump magic numbers\n");
+ 		return -1;
+ 	}
+ 
+ 	header->volumeId = 0;
+ 	header->nDumpTimes = 0;
+ 
+ 	while ((tag = getc(f)) > D_MAX && tag != EOF) {
+ 		unsigned short length;
+ 		switch (tag) {
+ 		case 'v':
+ 			if (ReadInt32(f, &header->volumeId)) {
+ 				if (verbose)
+ 					fprintf(stderr, "Failed to read "
+ 						"volumeId\n");
+ 				return -1;
+ 			}
+ 			break;
+ 		case 'n':
+ 			if (ReadString(f, header->volumeName,
+ 				       sizeof(header->volumeName))) {
+ 				if (verbose)
+ 					fprintf(stderr, "Failed to read "
+ 						"volume name\n");
+ 				return -1;
+ 			}
+ 			break;
+ 		case 't':
+ 			if (ReadInt16(f, &length)) {
+ 				if (verbose)
+ 					fprintf(stderr, "Failed to read "
+ 						"dump time array length\n");
+ 				return -1;
+ 			}
+ 			header->nDumpTimes = (length >> 1);
+ 			for (i = 0; i < header->nDumpTimes; i++)
+ 				if (ReadInt32(f, (unsigned int *)
+ 					      &header->dumpTimes[i].from) ||
+ 				    ReadInt32(f, (unsigned int *)
+ 					      &header->dumpTimes[i].to)) {
+ 					if (verbose)
+ 						fprintf(stderr, "Failed to "
+ 							"read dump times\n");
+ 					return -1;
+ 				}
+ 			break;
+ 		default:
+ 			if (verbose)
+ 				fprintf(stderr, "Unknown dump tag \"%c\"\n",
+ 					tag);
+ 			return -1;
+ 		}
+ 	}
+ 
+ 	if (!header->volumeId || !header->nDumpTimes) {
+ 		if (verbose) 
+ 			fprintf(stderr, "We didn't get a volume Id or "
+ 				"dump times listing\n");
+ 		return 1;
+ 	}
+ 
+ 	ungetc(tag, f);
+ 	return 0;
+ }
+ 
+ /*
+  * Read the volume header; this is the information stored in VolumeDiskData.
+  *
+  * I'm not sure we need all of this, but read it in just in case.
+  */
+ 
+ static int
+ ReadVolumeHeader(FILE *f, VolumeDiskData *vol)
+ {
+ 	int tag;
+ 	unsigned int trash;
+ 	memset((void *) vol, 0, sizeof(*vol));
+ 
+ 	while ((tag = getc(f)) > D_MAX && tag != EOF) {
+ 		switch (tag) {
+ 		case 'i':
+ 			if (ReadInt32(f, &vol->id))
+ 				return -1;
+ 			break;
+ 		case 'v':
+ 			if (ReadInt32(f, &trash))
+ 				return -1;
+ 			break;
+ 		case 'n':
+ 			if (ReadString(f, vol->name, sizeof(vol->name)))
+ 				return -1;
+ 			break;
+ 		case 's':
+ 			vol->inService = getc(f);
+ 			break;
+ 		case 'b':
+ 			vol->blessed = getc(f);
+ 			break;
+ 		case 'u':
+ 			if (ReadInt32(f, &vol->uniquifier))
+ 				return -1;
+ 			break;
+ 		case 't':
+ 			vol->type = getc(f);
+ 			break;
+ 		case 'p':
+ 			if (ReadInt32(f, &vol->parentId))
+ 				return -1;
+ 			break;
+ 		case 'c':
+ 			if (ReadInt32(f, &vol->cloneId))
+ 				return -1;
+ 			break;
+ 		case 'q':
+ 			if (ReadInt32(f, (uint32_t *) &vol->maxquota))
+ 				return -1;
+ 			break;
+ 		case 'm':
+ 			if (ReadInt32(f, (uint32_t *) &vol->minquota))
+ 				return -1;
+ 			break;
+ 		case 'd':
+ 			if (ReadInt32(f, (uint32_t *) &vol->diskused))
+ 				return -1;
+ 			break;
+ 		case 'f':
+ 			if (ReadInt32(f, (uint32_t *) &vol->filecount))
+ 				return -1;
+ 			break;
+ 		case 'a':
+ 			if (ReadInt32(f, &vol->accountNumber))
+ 				return -1;
+ 			break;
+ 		case 'o':
+ 			if (ReadInt32(f, &vol->owner))
+ 				return -1;
+ 			break;
+ 		case 'C':
+ 			if (ReadInt32(f, &vol->creationDate))
+ 				return -1;
+ 			break;
+ 		case 'A':
+ 			if (ReadInt32(f, &vol->accessDate))
+ 				return -1;
+ 			break;
+ 		case 'U':
+ 			if (ReadInt32(f, &vol->updateDate))
+ 				return -1;
+ 			break;
+ 		case 'E':
+ 			if (ReadInt32(f, &vol->expirationDate))
+ 				return -1;
+ 			break;
+ 		case 'B':
+ 			if (ReadInt32(f, &vol->backupDate))
+ 				return -1;
+ 			break;
+ 		case 'O':
+ 			if (ReadString(f, vol->offlineMessage,
+ 				       sizeof(vol->offlineMessage)))
+ 				return -1;
+ 			break;
+ 		case 'M':
+ 			if (ReadString(f, (char *) vol->stat_reads, VMSGSIZE))
+ 				return -1;
+ 			break;
+ 		case 'W': {
+ 			unsigned short length;
+ 			int i;
+ 			unsigned int data;
+ 			if (ReadInt16(f, &length))
+ 				return -1;
+ 			for (i = 0; i < length; i++) {
+ 				if (ReadInt32(f, &data))
+ 					return -1;
+ 				if (i < sizeof(vol->weekUse) /
+ 					       sizeof(vol->weekUse[0]))
+ 					vol->weekUse[i] = data;
+ 			}
+ 			break;
+ 		}
+ 		case 'D':
+ 			if (ReadInt32(f, &vol->dayUseDate))
+ 				return -1;
+ 			break;
+ 		case 'Z':
+ 			if (ReadInt32(f, (uint32_t *) &vol->dayUse))
+ 				return -1;
+ 			break;
+ #ifdef RESIDENCY
+ 		case 'R': {
+ 			unsigned short length;
+ 			int i;
+ 			unsigned int data;
+ 
+ 			if (ReadInt16(f, &length))
+ 				return -1;
+ 			for (i = 0; i < length; i++) {
+ 				if (ReadInt32(f, &data))
+ 					return -1;
+ 				if (i < sizeof(vol->DesiredInfo.DesiredResidencyWords) /
+ 					sizeof(vol->DesiredInfo.DesiredResidencyWords[0]))
+ 					vol->DesiredInfo.DesiredResidencyWords[i] = data;
+ 			}
+ 			break;
+ 		}
+ 		case 'S': {
+ 			unsigned short length;
+ 			int i;
+ 			unsigned int data;
+ 
+ 			if (ReadInt16(f, &length))
+ 				return -1;
+ 			for (i = 0; i < length; i++) {
+ 				if (ReadInt32(f, &data))
+ 					return -1;
+ 				if (i < sizeof(vol->UnDesiredInfo.UnDesiredResidencyWords) /
+ 					sizeof(vol->UnDesiredInfo.UnDesiredResidencyWords[0]))
+ 					vol->UnDesiredInfo.UnDesiredResidencyWords[i] = data;
+ 			}
+ 			break;
+ 		}
+ #endif
+ 		default:
+ 			if (verbose)
+ 				fprintf(stderr, "Unknown dump tag \"%c\"\n",
+ 					tag);
+ 			return -1;
+ 		}
+ 	}
+ 
+ 	ungetc(tag, f);
+ 	return 0;
+ }
+ 
+ /*
+  * Scan all our vnode entries, and build indexing information.
+  */
+ 
+ static int
+ ScanVnodes(FILE *f, VolumeDiskData *vol, int sizescan)
+ {
+ 	int vnodeNumber;
+ 	int tag;
+ 	int numFileVnodes = 0;
+ 	int numDirVnodes = 0;
+ 	unsigned char buf[SIZEOF_LARGEDISKVNODE];
+ 	struct VnodeDiskObject *vnode = (struct VnodeDiskObject *) buf;
+ 	long offset, oldoffset;
+ 	struct vnodeData *vdata;
+ 	unsigned int length;
+ 
+ 	tag = getc(f);
+ 
+ 	while (tag == D_VNODE) {
+ 
+ 		offset = 0;
+ 		length = 0;
+ 		vnode->type = -1;
+ 		vnode->length = -1;
+ 
+ 		if (ReadInt32(f, (uint32_t *) &vnodeNumber))
+ 		{
+ 			fprintf(stderr, "failed int32 for 'vnodenum'\n");
+ 			return -1;
+ 		}
+ 
+ 		if (ReadInt32(f, &vnode->uniquifier))
+ 		{
+ 			fprintf(stderr, "failed int32 for 'uniquifier'\n");
+ 			return -1;
+ 		}
+ 		
+ 		if (verbose > 1 && !sizescan)
+ 			printf("Got vnode %d\n", vnodeNumber);
+ 		
+ 		while ((tag = getc(f)) > D_MAX && tag != EOF)
+ 			switch (tag) {
+ 			case 't':
+ 				vnode->type = (VnodeType) getc(f);
+ 				break;
+ 			case 'l':
+ 				{
+ 					unsigned short tmp;
+ 					if (ReadInt16(f, &tmp))
+ 					{
+ 						fprintf(stderr, "failed int16 for 'l'\n");
+ 						return -1;
+ 					}
+ 					vnode->linkCount = tmp;
+ 				}
+ 				break;
+ 			case 'v':
+ 				if (ReadInt32(f, &vnode->dataVersion))
+ 				{
+ 					fprintf(stderr, "failed int32 for 'v'\n");
+ 					return -1;
+ 				}
+ 				break;
+ 			case 'm':
+ 				if (ReadInt32(f, (uint32_t *) &vnode->unixModifyTime))
+ 				{
+ 					fprintf(stderr, "failed int32 for 'm'\n");
+ 					return -1;
+ 				}
+ 				break;
+ 			case 's':
+ 				if (ReadInt32(f, (uint32_t *) &vnode->serverModifyTime))
+ 				{
+ 					fprintf(stderr, "failed int32 for 's'\n");
+ 					return -1;
+ 				}
+ 				break;
+ 			case 'a':
+ 				if (ReadInt32(f, &vnode->author))
+ 				{
+ 					fprintf(stderr, "failed int32 for 'a'\n");
+ 					return -1;
+ 				}
+ 				break;
+ 			case 'o':
+ 				if (ReadInt32(f, &vnode->owner))
+ 				{
+ 					fprintf(stderr, "failed int32 for 'o'\n");
+ 					return -1;
+ 				}
+ 				break;
+ 			case 'g':
+ 				if (ReadInt32(f, (uint32_t *) &vnode->group))
+ 				{
+ 					fprintf(stderr, "failed int32 for 'g'\n");
+ 					return -1;
+ 				}
+ 				break;
+ 			case 'b': {
+ 				unsigned short modeBits;
+ 				if (ReadInt16(f, &modeBits))
+ 					return -1;
+ 				vnode->modeBits = modeBits;
+ 				break;
+ 			}
+ 			case 'p':
+ 				if (ReadInt32(f, &vnode->parent))
+ 				{
+ 					fprintf(stderr, "failed int32 for 'p'\n");
+ 					return -1;
+ 				}
+ 				break;
+ #ifdef RESIDENCY
+ 			case 'N':
+ 				if (ReadInt32(f, &vnode->NextVnodeId))
+ 				{
+ 					fprintf(stderr, "failed int32 for 'N'\n");
+ 					return -1;
+ 				}
+ 				break;
+ 			case 'R':
+ 				if (ReadInt32(f, &VLkp_Residencies(vnode)))
+ 				{
+ 					fprintf(stderr, "failed int32 for 'R'\n");
+ 					return -1;
+ 				}
+ 				break;
+ #endif
+ 			case 'S':
+ 				if (ReadInt32(f, &vnode->length))
+ 				{
+ 					fprintf(stderr, "failed int32 for 'S'\n");
+ 					return -1;
+ 				}
+ 				break;
+ 			case 'F':
+ 				if (ReadInt32(f, (uint32_t *) &vnode->vn_ino_lo))
+ 					return -1;
+ 				break;
+ 			case 'A':
+ 				if (ReadByteString(f,
+ 						(void *)VVnodeDiskACL(vnode),
+ 						VAclDiskSize(vnode)))
+ 				{
+ 					fprintf(stderr, "failed readbystring for 'A'\n");
+ 					return -1;
+ 				}
+ #if 0
+ 				acl_NtohACL(VVnodeDiskACL(vnode));
+ #endif
+ 				break;
+ #ifdef RESIDENCY 
+ 			case 'h':
+ 				if (ReadInt32(f, &vnode->length_hi))
+ 				{
+ 					fprintf(stderr, "failed int32 for 'h'\n");
+ 					return -1;
+ 				}
+ #endif
+ 			case 'f':
+ 				if (verbose > 1 && ! sizescan)
+ 					printf("We have file data!\n");
+ 				if (ReadInt32(f, &length))
+ 				{
+ 					fprintf(stderr, "failed int32 for 'f'\n");
+ 					return -1;
+ 				}
+ 				vnode->length = length;
+ 				offset = ftell(f);
+ 				fseek(f, length, SEEK_CUR);
+ 				break;
+ 			default:
+ 				if (verbose)
+ 				fprintf(stderr, "Unknown dump tag \"%c\"\n",
+ 					tag);
+ 			return -1;
+ 		}
+ 
+ 		/*
+ 		 * If we're doing an incremental restore, then vnodes
+ 		 * will be listed in the dump, but won't contain any
+ 		 * vnode information at all (I don't know why they're
+ 		 * included _at all_).  If we get one of these vnodes, then
+ 		 * just skip it (because we can't do anything with it.
+ 		 */
+ 
+ 		if (vnode->type == -1)
+ 			continue;
+ 
+ #ifdef RESIDENCY
+ 		if (verbose > 1 && vnode->type == vFidLookup && ! sizescan) {
+ 			printf("This is an auxiliary vnode (lookup) for vnode %d, residency %d\n",
+ 				VLkp_ParentVnodeId(vnode),
+ 				VLkp_Residencies(vnode));
+ 			if (DumpVnodeFile(stdout, vnode, vol))
+ 				return -1;
+ 		}
+ 
+ 		if (verbose > 1 && vnode->type == vAccessHistory && ! sizescan)
+ 			printf("This is an auxiliary vnode (history) for vnode %d\n",
+ 				VLkp_ParentVnodeId(vnode));
+ #endif
+ 
+ 		if (vnode->type == vDirectory)
+ 			numDirVnodes++;
+ 		else
+ 			numFileVnodes++;
+ 
+ 		/*
+ 		 * We know now all we would ever know about the vnode;
+ 		 * insert it into our hash table (but only if we're not
+ 		 * doing a vnode scan).
+ 		 */
+ 
+ 		if (!sizescan) {
+ 
+ 			vdata = InsertVnode(vnodeNumber, vnode);
+ 
+ 			if (vdata == NULL) {
+ 				if (verbose)
+ 					fprintf(stderr, "Failed to insert "
+ 						"vnode into hash table");
+ 				return -1;
+ 			}
+ 
+ 			vdata->dumpdata = offset;
+ 			vdata->datalength = length;
+ 
+ 			/*
+ 			 * Save directory data, since we'll need it later.
+ 			 */
+ 
+ 			if (vnode->type == vDirectory && length) {
+ 
+ 				vdata->filedata = malloc(length);
+ 
+ 				if (!vdata->filedata) {
+ 					if (verbose)
+ 						fprintf(stderr, "Unable to "
+ 							"allocate space for "
+ 							"file data (%d)\n",
+ 							length);
+ 					return -1;
+ 				}
+ 
+ 				oldoffset = ftell(f);
+ 				fseek(f, offset, SEEK_SET);
+ 
+ 				if (fread(vdata->filedata, length, 1, f) != 1) {
+ 					if (verbose)
+ 						fprintf(stderr, "Unable to "
+ 							"read in file data!\n");
+ 					return -1;
+ 				}
+ 
+ 				fseek(f, oldoffset, SEEK_SET);
+ 			} else if (vnode->type == vDirectory)
+ 				/*
+ 				 * Warn the user we may not have all directory
+ 				 * vnodes
+ 				 */
+ 				numNoDirData++;
+ 		}
+ 	}
+ 
+ 	ungetc(tag, f);
+ 
+ 	if (!sizescan) {
+ 
+ 		numLargeVnodes = numDirVnodes;
+ 		numSmallVnodes = numFileVnodes;
+ 
+ 	} else {
+ 		LargeVnodeIndex = (struct vnodeData **)
+ 					malloc(numDirVnodes *
+ 						sizeof(struct vnodeData));
+ 		SmallVnodeIndex = (struct vnodeData **)
+ 					malloc(numFileVnodes *
+ 						sizeof(struct vnodeData));
+ 		
+ 		if (LargeVnodeIndex == NULL || SmallVnodeIndex == NULL) {
+ 			if (verbose)
+ 				fprintf(stderr, "Unable to allocate space "
+ 					"for vnode tables\n");
+ 			return -1;
+ 		}
+ 	}
+ 
+ 	if (verbose)
+ 		fprintf(stderr,"%s vnode scan completed\n",
+ 			sizescan ? "Primary" : "Secondary");
+ 
+ 	return 0;
+ }
+ 
+ /*
+  * Perform an interactive restore
+  *
+  * Parsing the directory information is a pain, but other than that
+  * we just use the other tools we already have in here.
+  */
+ 
+ static void
+ InteractiveRestore(FILE *f, VolumeDiskData *vol)
+ {
+ 	struct vnodeData *vdatacwd;	/* Vnode data for our current dir */
+ 	char cmdbuf[256];
+ 	int argc;
+ 	char **argv;
+ 
+ 	/*
+ 	 * Let's see if we can at least get the data for our root directory.
+ 	 * If we can't, there's no way we can do an interactive restore.
+ 	 */
+ 
+ 	if ((vdatacwd = GetVnode(1)) == NULL) {
+ 		fprintf(stderr, "No entry for our root vnode!  Aborting\n");
+ 		return;
+ 	}
+ 
+ 	if (! vdatacwd->filedata) {
+ 		fprintf(stderr, "There is no directory data for the root "
+ 			"vnode (1.1).  An interactive\nrestore is not "
+ 			"possible.\n");
+ 		return;
+ 	}
+ 
+ 	/*
+ 	 * If you're doing a selective dump correctly, then you should get all
+ 	 * directory vnode data.  But just in case you didn't, let the user
+ 	 * know there may be a problem.
+ 	 */
+ 
+ 	if (numNoDirData)
+ 		fprintf(stderr, "WARNING: %d directory vnodes had no file "
+ 			"data.  An interactive restore\nmay not be possible\n",
+ 			numNoDirData);
+ 
+ 	printf("> ");
+ 	while (fgets(cmdbuf, 256, stdin)) {
+ 
+ 		cmdbuf[strlen(cmdbuf) - 1] = '\0';
+ 
+ 		if (strlen(cmdbuf) == 0) {
+ 			printf("> ");
+ 			continue;
+ 		}
+ 
+ 		MakeArgv(cmdbuf, &argc, &argv);
+ 
+ 		if (strcmp(argv[0], "ls") == 0) {
+ 			DirectoryList(argc, argv, vdatacwd, vol);
+ 		} else if (strcmp(argv[0], "cd") == 0) {
+ 			struct vnodeData *newvdata;
+ 
+ 			newvdata = ChangeDirectory(argc, argv, vdatacwd);
+ 
+ 			if (newvdata)
+ 				vdatacwd = newvdata;
+ 		} else if (strcmp(argv[0], "file") == 0) {
+ 			DumpAllFiles(argc, argv, vdatacwd, vol);
+ 		} else if (strcmp(argv[0], "cp") == 0) {
+ 			CopyFile(argc, argv, vdatacwd, f);
+ 		} else if (strcmp(argv[0], "vcp") == 0) {
+ 			CopyVnode(argc, argv, f);
+ 		} else if (strcmp(argv[0], "quit") == 0 ||
+ 			   strcmp(argv[0], "exit") == 0)
+ 			break;
+ 		else if (strcmp(argv[0], "?") == 0 ||
+ 			 strcmp(argv[0], "help") == 0) {
+ 			printf("Valid commands are:\n");
+ 			printf("\tls\t\tList current directory\n");
+ 			printf("\tcd\t\tChange current directory\n");
+ 			printf("\tcp\t\tCopy file from dump\n");
+ 			printf("\tvcp\t\tCopy file from dump (via vnode)\n");
+ #ifdef RESIDENCY
+ 			printf("\tfile\t\tList residency filenames\n");
+ #endif /* RESIDENCY */
+ 			printf("\tquit | exit\tExit program\n");
+ 			printf("\thelp | ?\tBrief help\n");
+ 		} else 
+ 			fprintf(stderr, "Unknown command, \"%s\", enter "
+ 				"\"help\" for a list of commands.\n",
+ 				argv[0]);
+ 		
+ 		printf("> ");
+ 	}
+ 
+ 	return;
+ }
+ 
+ /*
+  * Do a listing of all files in a directory.  Sigh, I wish this wasn't
+  * so complicated.
+  *
+  * With the reorganizing, this is just a front-end to DirListInternal()
+  */
+ 
+ static void
+ DirectoryList(int argc, char **argv, struct vnodeData *vdata,
+ 	      VolumeDiskData *vol)
+ {
+ 	int errflg = 0, lflag = 0, iflag = 0, Fflag = 0, sflag = 0, Rflag = 0;
+ 	int c;
+ 
+ 	optind = 1;
+ 
+ 	while ((c = getopt(argc, argv, "liFRs")) != EOF)
+ 		switch (c) {
+ 		case 'l':
+ 			lflag++;
+ 			break;
+ 		case 'i':
+ 			iflag++;
+ 			break;
+ 		case 'F':
+ 			Fflag++;
+ 			break;
+ 		case 'R':
+ 			Rflag++;
+ 		case 's':
+ 			sflag++;
+ 			break;
+ 		case '?':
+ 		default:
+ 			errflg++;
+ 		}
+ 
+ 	if (errflg) {
+ 		fprintf(stderr, "Usage: %s [-liFs] filename [filename ...]\n",
+ 			argv[0]);
+ 		return;
+ 	}
+ 
+ 	DirListInternal(vdata, &(argv[optind]), argc - optind, lflag, iflag,
+ 			Fflag, Rflag, 1, vol, NULL);
+ 
+ 	return;
+ }
+ 
+ /*
+  * Function that does the REAL work in terms of directory listing
+  */
+ 
+ static void
+ DirListInternal(struct vnodeData *vdata, char *pathnames[], int numpathnames,
+ 		int lflag, int iflag, int Fflag, int Rflag, int verbose,
+ 		VolumeDiskData *vol, char *path)
+ {
+ 	struct DirEntry *ep, **eplist = NULL, **eprecurse = NULL;
+ 	struct DirCursor cursor;
+ 	struct vnodeData *lvdata;
+ 
+ 	int i, j, numentries = 0, longestname = 0, numcols, col, numrows;
+ 	int numrecurse = 0;
+ 		
+ 	if (! vdata->filedata) {
+ 		fprintf(stderr, "There is no vnode data for this "
+ 			"directory!\n");
+ 		return;
+ 	}
+ 
+ 	ResetDirCursor(&cursor, vdata);
+ 
+ 	/*
+ 	 * Scan through the whole directory
+ 	 */
+ 
+ 	while ((ep = ReadNextDir(&cursor, vdata)) != NULL) {
+ 
+ 		/*
+ 		 * If we didn't get any filenames on the command line,
+ 		 * get them all.
+ 		 */
+ 
+ 		if (numpathnames == 0) {
+ 			eplist = realloc(eplist, sizeof(struct DirEntry *) *
+ 					 ++numentries);
+ 			eplist[numentries - 1] = ep;
+ 			if (strlen(ep->name) > longestname)
+ 				longestname = strlen(ep->name);
+ 			if (Rflag)
+ 				if ((lvdata = GetVnode(ntohl(ep->fid.vnode))) &&
+ 				    lvdata->vnode->type == vDirectory &&
+ 				    !(strcmp(ep->name, ".") == 0 ||
+ 				      strcmp(ep->name, "..") == 0)) {
+ 					eprecurse = realloc(eprecurse,
+ 						sizeof(struct DirEntry *) *
+ 						++numrecurse);
+ 					eprecurse[numrecurse - 1] = ep;
+ 				}
+ 
+ 		} else {
+ 			/*
+ 			 * Do glob matching via fnmatch()
+ 			 */
+ 
+ 			for (i = 0; i < numpathnames; i++)
+ 				if (fnmatch(pathnames[i], ep->name,
+ 						FNM_PATHNAME) == 0) {
+ 					eplist = realloc(eplist,
+ 						 sizeof(struct DirEntry *) *
+ 						 ++numentries);
+ 					eplist[numentries - 1] = ep;
+ 					if (strlen(ep->name) > longestname)
+ 						longestname = strlen(ep->name);
+ 					if (Rflag)
+ 						if ((lvdata =
+ 					     GetVnode(ntohl(ep->fid.vnode))) &&
+ 						    lvdata->vnode->type ==
+ 								vDirectory &&
+ 				               !(strcmp(ep->name, ".") == 0 ||
+ 				                 strcmp(ep->name, "..") == 0)) {
+ 							eprecurse =
+ 							     realloc(eprecurse,
+ 						sizeof(struct DirEntry *) *
+ 								++numrecurse);
+ 						 eprecurse[numrecurse - 1] = ep;
+ 						}
+ 					break;
+ 				}
+ 		}
+ 	}
+ 
+ 	qsort((void *) eplist, numentries, sizeof(struct DirEntry *),
+ 	      CompareDirEntry);
+ 
+ 	if (Rflag && eprecurse)
+ 		qsort((void *) eprecurse, numrecurse,
+ 		      sizeof(struct DirEntry *), CompareDirEntry);
+ 	/*
+ 	 * We don't have to do column printing if we have the -l or the -i
+ 	 * options.  Sigh, column printing is WAY TOO FUCKING COMPLICATED!
+ 	 */
+ 
+ 	if (!lflag && !iflag) {
+ 		char c;
+ 
+ 		if (Fflag)
+ 			longestname++;
+ 
+ 		longestname++;
+ 
+ 		numcols = termsize / longestname ? termsize / longestname : 1;
+ 		numrows = numentries / numcols +
+ 			(numentries % numcols ? 1 : 0);
+ 
+ 		for (i = 0; i < numrows; i++) {
+ 			col = 0;
+ 			while (col < numcols && (i + col * numrows) <
+ 								numentries) {
+ 				ep = eplist[i + col++ * numrows];
+ 				if (Fflag) {
+ 					if (!(lvdata =
+ 					       GetVnode(ntohl(ep->fid.vnode))))
+ 						c = ' ';
+ 					else if (lvdata->vnode->type ==
+ 						   vDirectory)
+ 						c = '/';
+ 					else if (lvdata->vnode->type ==
+ 						   vSymlink)
+ 						c = '@';
+ 					else if (lvdata->vnode->modeBits &
+ 						 0111 != 0)
+ 						c = '*';
+ 					else
+ 						c = ' ';
+ 				printf("%s%-*c", ep->name,
+ 				       longestname - strlen(ep->name), c);
+ 				} else
+ 					printf("%-*s", longestname, ep->name);
+ 			}
+ 
+ 			printf("\n");
+ 		}
+ 	} else if (iflag)
+ 		for (i = 0; i < numentries; i++)
+ 			if (!(lvdata = GetVnode(ntohl(eplist[i]->fid.vnode))))
+ 				printf("%d.0.0\t%s\n",
+ 				       vol->parentId ? vol->parentId : vol->id,
+ 				       eplist[i]->name);
+ 			else
+ 				if (path)
+ 					printf("%d.%d.%d\t%s/%s\n",
+ 					       vol->id,
+ 					       ntohl(eplist[i]->fid.vnode),
+ 					       ntohl(eplist[i]->fid.vunique),
+ 					       path, eplist[i]->name);
+ 				else
+ 					printf("%d.%d.%d\t%s\n",
+ 					       vol->id,
+ 					       ntohl(eplist[i]->fid.vnode),
+ 					       ntohl(eplist[i]->fid.vunique),
+ 					       eplist[i]->name);
+ 	else if (lflag) {
+ 		for (i = 0; i < numentries; i++)
+ 			if (!(lvdata = GetVnode(ntohl(eplist[i]->fid.vnode))))
+ 				printf("----------   0 0        "
+ 				       "0                 0 %s\n",
+ 					       eplist[i]->name);
+ 			else {
+ 				switch (lvdata->vnode->type) {
+ 				case vDirectory:
+ 					printf("d");
+ 					break;
+ 				case vSymlink:
+ 					printf("l");
+ 					break;
+ 				default:
+ 					printf("-");
+ 				}
+ 
+ 				for (j = 8; j >= 0; j--) {
+ 					if (lvdata->vnode->modeBits & (1 << j))
+ 						switch (j % 3) {
+ 							case 2: printf("r");
+ 								break;
+ 							case 1: printf("w");
+ 								break;
+ 							case 0: printf("x");
+ 						}
+ 					else
+ 						printf("-");
+ 				}
+ 
+ 				printf(" %-3d %-8d %-8d %10d %s\n",
+ 				       lvdata->vnode->linkCount,
+ 				       lvdata->vnode->owner,
+ 				       lvdata->vnode->group,
+ 				       lvdata->vnode->length,
+ 				       eplist[i]->name);
+ 			}
+ 	}
+ 
+ 	free(eplist);
+ 
+ 	if (Rflag && eprecurse) {
+ 		char *lpath;
+ 		lpath = NULL;
+ 		for (i = 0; i < numrecurse; i++) {
+ 			if (verbose)
+ 				printf("\n%s:\n", eprecurse[i]->name);
+ 			if (path) {
+ 				lpath = malloc(strlen(path) +
+ 					       strlen(eprecurse[i]->name) + 2);
+ 				if (lpath)
+ 					sprintf(lpath, "%s/%s", path,
+ 						eprecurse[i]->name);
+ 			}
+ 			DirListInternal(
+ 				      GetVnode(ntohl(eprecurse[i]->fid.vnode)),
+ 					NULL, 0, lflag, iflag, Fflag, Rflag,
+ 					verbose, vol, lpath);
+ 			if (lpath) {
+ 				free(lpath);
+ 				lpath = NULL;
+ 			}
+ 		}
+ 	}
+ 
+ 	if (eprecurse)
+ 		free(eprecurse);
+ 
+ 	return;
+ }
+ 
+ 
+ /*
+  * Directory name comparison function, used by qsort
+  */
+ 
+ static int
+ CompareDirEntry(const void *e1, const void *e2)
+ {
+ 	struct DirEntry **ep1 = (struct DirEntry **) e1;
+ 	struct DirEntry **ep2 = (struct DirEntry **) e2;
+ 
+ 	return strcmp((*ep1)->name, (*ep2)->name);
+ }
+ 
+ /*
+  * Change a directory.  Return a pointer to our new vdata structure for
+  * this directory.
+  */
+ 
+ static struct vnodeData *
+ ChangeDirectory(int argc, char **argv, struct vnodeData *vdatacwd)
+ {
+ 	struct vnodeData *newvdatacwd;
+ 
+ 	if (argc != 2) {
+ 		fprintf(stderr, "Usage: %s directory\n", argv[0]);
+ 		return NULL;
+ 	}
+ 
+ 	if ((newvdatacwd = FindFile(vdatacwd, argv[1])) == NULL)
+ 		return NULL;
+ 
+ 	if (newvdatacwd->vnode->type != vDirectory) {
+ 		fprintf(stderr, "%s: Not a directory\n", argv[1]);
+ 		return NULL;
+ 	}
+ 
+ 	if (newvdatacwd->filedata == NULL) {
+ 		fprintf(stderr, "%s: No directory data found.\n", argv[1]);
+ 		return NULL;
+ 	}
+ 
+ 	return newvdatacwd;
+ }
+ 
+ /*
+  * Copy a file from out of the dump file
+  */
+ 
+ #define COPYBUFSIZE 8192
+ 
+ static void
+ CopyFile(int argc, char **argv, struct vnodeData *vdatacwd, FILE *f)
+ {
+ 	struct vnodeData *vdata;
+ 	FILE *out;
+ 	long cur = 0;
+ 	int bytes, ret;
+ 	char buffer[COPYBUFSIZE];
+ 
+ 	if (argc != 3) {
+ 		fprintf(stderr, "Usage: %s dumpfile destfile\n", argv[0]);
+ 		return;
+ 	}
+ 
+ 	if ((vdata = FindFile(vdatacwd, argv[1])) == NULL)
+ 		return;
+ 
+ 	if (vdata->dumpdata == 0) {
+ 		fprintf(stderr, "File %s has no data in dump file\n",
+ 			argv[1]);
+ 		return;
+ 	}
+ 
+ 	if ((out = fopen(argv[2], "wb")) == NULL) {
+ 		fprintf(stderr, "Open of %s failed: %s\n", argv[2],
+ 			strerror(errno));
+ 		return;
+ 	}
+ 
+ 	if (fseek(f, vdata->dumpdata, SEEK_SET)) {
+ 		fprintf(stderr, "Seek failed: %s\n", strerror(errno));
+ 		fclose(out);
+ 		return;
+ 	}
+ 
+ 	while (cur < vdata->datalength) {
+ 
+ 		bytes = cur + COPYBUFSIZE < vdata->datalength ?
+ 			COPYBUFSIZE : vdata->datalength - cur;
+ 
+ 		ret = fread(buffer, sizeof(char), bytes, f);
+ 		if (ret != bytes) {
+ 			if (ret != 0)
+ 				fprintf(stderr, "Short read (expected %d, "
+ 					"got %d)\n", bytes, ret);
+ 			else
+ 				fprintf(stderr, "Error during read: %s\n",
+ 					strerror(errno));
+ 			fclose(out);
+ 			return;
+ 		}
+ 
+ 		ret = fwrite(buffer, sizeof(char), bytes, out);
+ 		if (ret != bytes) {
+ 			if (ret != 0)
+ 				fprintf(stderr, "Short write (expected %d, "
+ 					"got %d)\n", bytes, ret);
+ 			else
+ 				fprintf(stderr, "Error during write: %s\n",
+ 					strerror(errno));
+ 			fclose(out);
+ 			return;
+ 		}
+ 
+ 		cur += bytes;
+ 	}
+ 
+ 	fclose(out);
+ }
+ 
+ /*
+  * Copy a file from out of the dump file, by using the vnode
+  */
+ 
+ static void
+ CopyVnode(int argc, char *argv[], FILE *f)
+ {
+ 	struct vnodeData *vdata;
+ 	FILE *out;
+ 	long cur = 0;
+ 	int bytes, ret;
+ 	char buffer[COPYBUFSIZE];
+ 	unsigned int vnode, uniquifier = 0;
+ 
+ 	if (argc != 3) {
+ 		fprintf(stderr, "Usage: %s vnode[.uniqifier] destfile\n",
+ 			argv[0]);
+ 		return;
+ 	}
+ 
+ 	ret = sscanf(argv[1], "%d.%d", &vnode, &uniquifier);
+ 
+ 	if (ret < 1) {
+ 		fprintf(stderr, "Invalid file identifier: %s\n", argv[1]);
+ 		return;
+ 	}
+ 
+ 	if (!(vdata = GetVnode(vnode))) {
+ 		fprintf(stderr, "Vnode %d not in dump file\n", vnode);
+ 		return;
+ 	}
+ 
+ 	if (ret == 2 && vdata->vnode->uniquifier != uniquifier) {
+ 		fprintf(stderr, "Specified uniquifier %d did not match "
+ 			"uniquifier %d found in dump file!\n", uniquifier,
+ 			vdata->vnode->uniquifier);
+ 		return;
+ 	}
+ 
+ 	if (vdata->dumpdata == 0) {
+ 		fprintf(stderr, "File %s has no data in dump file\n",
+ 			argv[1]);
+ 		return;
+ 	}
+ 
+ 	if ((out = fopen(argv[2], "wb")) == NULL) {
+ 		fprintf(stderr, "Open of %s failed: %s\n", argv[2],
+ 			strerror(errno));
+ 		return;
+ 	}
+ 
+ 	if (fseek(f, vdata->dumpdata, SEEK_SET)) {
+ 		fprintf(stderr, "Seek failed: %s\n", strerror(errno));
+ 		fclose(out);
+ 		return;
+ 	}
+ 
+ 	while (cur < vdata->datalength) {
+ 
+ 		bytes = cur + COPYBUFSIZE < vdata->datalength ?
+ 			COPYBUFSIZE : vdata->datalength - cur;
+ 
+ 		ret = fread(buffer, sizeof(char), bytes, f);
+ 		if (ret != bytes) {
+ 			if (ret != 0)
+ 				fprintf(stderr, "Short read (expected %d, "
+ 					"got %d)\n", bytes, ret);
+ 			else
+ 				fprintf(stderr, "Error during read: %s\n",
+ 					strerror(errno));
+ 			fclose(out);
+ 			return;
+ 		}
+ 
+ 		ret = fwrite(buffer, sizeof(char), bytes, out);
+ 		if (ret != bytes) {
+ 			if (ret != 0)
+ 				fprintf(stderr, "Short write (expected %d, "
+ 					"got %d)\n", bytes, ret);
+ 			else
+ 				fprintf(stderr, "Error during write: %s\n",
+ 					strerror(errno));
+ 			fclose(out);
+ 			return;
+ 		}
+ 
+ 		cur += bytes;
+ 	}
+ 
+ 	fclose(out);
+ }
+ /*
+  * Dump all residency filenames associated with a file, or all files
+  * within a directory.
+  */
+ 
+ static void
+ DumpAllFiles(int argc, char **argv, struct vnodeData *vdatacwd,
+ 	     VolumeDiskData *vol)
+ {
+ #ifdef RESIDENCY
+ 	struct vnodeData *vdata, *nvdata;
+ 	struct DirCursor cursor;
+ 	struct DirEntry *ep;
+ 	FILE *f = stdout;
+ 	int c, i;
+ 	int dflag = 0, fflag = 0, errflg = 0;
+ 
+ 	optind = 1;
+ 
+ 	while ((c = getopt(argc, argv, "df:")) != EOF)
+ 		switch (c) {
+ 		case 'd':
+ 			dflag++;
+ 			break;
+ 		case 'f':
+ 			if ((f = fopen(optarg, "a")) == NULL) {
+ 				fprintf(stderr, "Cannot open \"%s\": %s\n",
+ 					optarg, strerror(errno));
+ 				return;
+ 			}
+ 			fflag++;
+ 			break;
+ 		case 'h':
+ 		case '?':
+ 		default:
+ 			errflg++;
+ 		}
+ 	
+ 	if (errflg || argc == optind) {
+ 		fprintf(stderr, "Usage: %s [-d] [-f filename] file "
+ 			"[file ...]\n", argv[0]);
+ 		if (fflag)
+ 			fclose(f);
+ 		return;
+ 	}
+ 
+ 	for (i = optind; i < argc; i++) {
+ 
+ 		if ((vdata = FindFile(vdatacwd, argv[i])) == NULL)
+ 			continue;
+ 
+ 		if (vdata->vnode->type == vDirectory && ! dflag) {
+ 			
+ 			ResetDirCursor(&cursor, vdata);
+ 
+ 			while ((ep = ReadNextDir(&cursor, vdata)) != NULL) {
+ 
+ 				if (!(nvdata =
+ 					     GetVnode(ntohl(ep->fid.vnode)))) {
+ 					fprintf(stderr, "Cannot find vnode "
+ 						"entry for %s (%d)\n",
+ 						ep->name, ntohl(ep->fid.vnode));
+ 					continue;
+ 				}
+ 
+ 
+ 				if (!fflag) {
+ 					printf("Residency locations for %s:\n",
+ 					ep->name);
+ 
+ 					if (nvdata->dumpdata)
+ 						printf("Local disk (in dump "
+ 						       "file)\n");
+ 				}
+ 
+ 				DumpAllResidencies(f, nvdata, vol);
+ 			
+ 			}
+ 
+ 		} else {
+ 			if (!fflag) {
+ 				printf("Residency locations for %s:\n",
+ 				       argv[i]);
+ 
+ 				if (vdata->dumpdata)
+ 					printf("Local disk (in dump file)\n");
+ 			}
+ 
+ 			DumpAllResidencies(f, vdata, vol);
+ 		}
+ 	}
+ 
+ 	if (fflag)
+ 		fclose(f);
+ #else /* RESIDENCY */
+ 	fprintf(stderr, "The \"file\" command is not available in the non-"
+ 		"MRAFS version of dumptool.\n");
+ #endif /* RESIDENCY */
+ 	return;
+ }
+ 
+ /*
+  * Take a vnode, traverse the vnode chain, and dump out all files on
+  * all residencies corresponding to that parent vnode.
+  */
+ 
+ #ifdef RESIDENCY
+ static void
+ DumpAllResidencies(FILE *f, struct vnodeData *vdata, struct VolumeDiskData *vol)
+ {
+ 	unsigned int nextVnodeNum;
+ 
+ 	while (nextVnodeNum = vdata->vnode->NextVnodeId) {
+ 		if ((vdata = GetVnode(nextVnodeNum)) == NULL) {
+ 			fprintf(stderr, "We had a pointer to %lu in it's "
+ 				"vnode chain, but there\nisn't a record of "
+ 				"it!  The dump might be corrupt.\n",
+ 				nextVnodeNum);
+ 			return;
+ 		}
+ 
+ 		if (vdata->vnode->type == vFidLookup)
+ 			DumpVnodeFile(f, vdata->vnode, vol);
+ 	}
+ 
+ 	return;
+ }
+ #endif
+ 
+ 
+ /*
+  * Given a directory vnode and a filename, return the vnode corresponding
+  * to the file in that directory.
+  * 
+  * We now handle pathnames with directories in them.
+  */
+ 
+ static struct vnodeData *
+ FindFile(struct vnodeData *vdatacwd, char *filename)
+ {
+ 	struct DirHeader *dhp;
+ 	struct DirEntry *ep;
+ 	int i, num;
+ 	struct vnodeData *vdata;
+ 	char *c, newstr[MAXPATHLEN];
+ 
+ 	if (! vdatacwd->filedata) {
+ 		fprintf(stderr, "There is no vnode data for this "
+ 			"directory!\n");
+ 		return NULL;
+ 	}
+ 
+ 	/*
+ 	 * If we have a "/" in here, look up the vnode data for the
+ 	 * directory (everything before the "/") and use that as our
+ 	 * current directory.  We automagically handle multiple directories
+ 	 * by using FindFile recursively.
+ 	 */
+ 
+ 	if ((c = strrchr(filename, '/')) != NULL) {
+ 
+ 		strncpy(newstr, filename, c - filename);
+ 		newstr[c - filename] = '\0';
+ 
+ 		if ((vdatacwd = FindFile(vdatacwd, newstr)) == NULL)
+ 			return NULL;
+ 
+ 		if (vdatacwd->vnode->type != vDirectory) {
+ 			fprintf(stderr, "%s: Not a directory\n", newstr);
+ 			return NULL;
+ 		}
+ 
+ 		filename = c + 1;
+ 	}
+ 
+ 	dhp = (struct DirHeader *) vdatacwd->filedata;
+ 
+ 	i = DirHash(filename);
+ 
+ 	num = ntohs(dhp->hashTable[i]);
+ 
+ 	while (num) {
+ 		ep = (struct DirEntry *) (vdatacwd->filedata + (num * 32));
+ 		if (strcmp(ep->name, filename) == 0)
+ 			break;
+ 		num = ntohs(ep->next);
+ 	}
+ 
+ 	if (! num) {
+ 		fprintf(stderr, "%s: No such file or directory\n", filename);
+ 		return NULL;
+ 	}
+ 
+ 	if ((vdata = GetVnode(ntohl(ep->fid.vnode))) == NULL) {
+ 		fprintf(stderr, "%s: No vnode information for %lu found\n",
+ 			filename, ntohl(ep->fid.vnode));
+ 		return NULL;
+ 	}
+ 
+ 	return vdata;
+ }
+ 
+ /*
+  * Reset a structure containing the current directory scan location
+  */
+ 
+ static void
+ ResetDirCursor(struct DirCursor *cursor, struct vnodeData *vdata)
+ {
+ 	struct DirHeader *dhp;
+ 
+ 	cursor->hashbucket = 0;
+ 
+ 	dhp = (struct DirHeader *) vdata->filedata;
+ 
+ 	cursor->entry = ntohs(dhp->hashTable[0]);
+ }
+ 
+ /*
+  * Given a cursor and a directory entry, return the next entry in the
+  * directory.
+  */
+ 
+ static struct DirEntry *
+ ReadNextDir(struct DirCursor *cursor, struct vnodeData *vdata)
+ {
+ 	struct DirHeader *dhp;
+ 	struct DirEntry *ep;
+ 
+ 	dhp = (struct DirHeader *) vdata->filedata;
+ 
+ 	if (cursor->entry) {
+ 		ep = (struct DirEntry *) (vdata->filedata +
+ 							(cursor->entry * 32));
+ 		cursor->entry = ntohs(ep->next);
+ 		return ep;
+ 	} else {
+ 		while (++(cursor->hashbucket) < NHASHENT) {
+ 			cursor->entry =
+ 				ntohs(dhp->hashTable[cursor->hashbucket]);
+ 			if (cursor->entry) {
+ 				ep = (struct DirEntry *) (vdata->filedata +
+ 							(cursor->entry * 32));
+ 				cursor->entry = ntohs(ep->next);
+ 				return ep;
+ 			}
+ 		}
+ 	}
+ 
+ 	return NULL;
+ }
+ 
+ /*
+  * Given a string, split it up into components a la Unix argc/argv.
+  *
+  * This code is most stolen from ftp.
+  */
+ 
+ static void
+ MakeArgv(char *string, int *argc, char ***argv)
+ {
+ 	static char *largv[64];
+ 	char **la = largv;
+ 	char *s = string;
+ 	static char argbuf[256];
+ 	char *ap = argbuf;
+ 
+ 	*argc = 0;
+ 	*argv = largv;
+ 
+ 	while (*la++ = GetToken(s, &s, ap, &ap))
+ 		(*argc)++;
+ }
+ 
+ /*
+  * Return a pointer to the next token, and update the current string
+  * position.
+  */
+ 
+ static char *
+ GetToken(char *string, char **nexttoken, char argbuf[], char *nextargbuf[])
+ {
+ 	char *sp = string;
+ 	char *ap = argbuf;
+ 	int got_one = 0;
+ 
+ S0:
+ 	switch (*sp) {
+ 
+ 	case '\0':
+ 		goto OUTTOKEN;
+ 	
+ 	case ' ':
+ 	case '\t':
+ 		sp++; goto S0;
+ 	
+ 	default:
+ 		goto S1;
+ 	}
+ 
+ S1:
+ 	switch (*sp) {
+ 
+ 	case ' ':
+ 	case '\t':
+ 	case '\0':
+ 		goto OUTTOKEN;	/* End of our token */
+ 
+ 	case '\\':
+ 		sp++; goto S2;	/* Get next character */
+ 
+ 	case '"':
+ 		sp++; goto S3;	/* Get quoted string */
+ 	
+ 	default:
+ 		*ap++ = *sp++;	/* Add a character to our token */
+ 		got_one = 1;
+ 		goto S1;
+ 	}
+ 
+ S2:
+ 	switch (*sp) {
+ 
+ 	case '\0':
+ 		goto OUTTOKEN;
+ 
+ 	default:
+ 		*ap++ = *sp++;
+ 		got_one = 1;
+ 		goto S1;
+ 	}
+ 
+ S3:
+ 	switch (*sp) {
+ 
+ 	case '\0':
+ 		goto OUTTOKEN;
+ 	
+ 	case '"':
+ 		sp++; goto S1;
+ 	
+ 	default:
+ 		*ap++ = *sp++;
+ 		got_one = 1;
+ 		goto S3;
+ 	}
+ 
+ OUTTOKEN:
+ 	if (got_one)
+ 		*ap++ = '\0';
+ 	*nextargbuf = ap;		/* Update storage pointer */
+ 	*nexttoken = sp;		/* Update token pointer */
+ 
+ 	return got_one ? argbuf : NULL;
+ }
+ 
+ /*
+  * Insert vnodes into our hash table.
+  */
+ 
+ static struct vnodeData *
+ InsertVnode(unsigned int vnodeNumber, struct VnodeDiskObject *vnode)
+ {
+ 	struct VnodeDiskObject *nvnode;
+ 	struct vnodeData *vdata;
+ 	static int curSmallVnodeIndex = 0;
+ 	static int curLargeVnodeIndex = 0;
+ 	struct vnodeData ***vnodeIndex;
+ 	int *curIndex;
+ 
+ 	nvnode = (struct VnodeDiskObject *) malloc(sizeof(struct VnodeDiskObject));
+ 
+ 	if (!nvnode) {
+ 		if (verbose)
+ 			fprintf(stderr, "Unable to allocate space for vnode\n");
+ 		return NULL;
+ 	}
+ 
+ 	memcpy((void *) nvnode, (void *) vnode, sizeof(struct VnodeDiskObject));
+ 
+ 	if (vnodeNumber & 1) {
+ 		vnodeIndex = &LargeVnodeIndex;
+ 		curIndex = &curLargeVnodeIndex;
+ 	} else {
+ 		vnodeIndex = &SmallVnodeIndex;
+ 		curIndex = &curSmallVnodeIndex;
+ 	}
+ 
+ 	vdata = (struct vnodeData *) malloc(sizeof(struct vnodeData));
+ 
+ 	vdata->vnode = nvnode;
+ 	vdata->vnodeNumber = vnodeNumber;
+ 	vdata->dumpdata = 0;
+ 	vdata->filedata = 0;
+ 	vdata->datalength = 0;
+ 
+ 	(*vnodeIndex)[(*curIndex)++] = vdata;
+ 
+ 	return vdata;
+ }
+ 
+ /*
+  * Routine to retrieve a vnode from the hash table.
+  */
+ 
+ static struct vnodeData *
+ GetVnode(unsigned int vnodeNumber)
+ {
+ 	struct vnodeData vnode, *vnodep, **tmp;
+ 
+ 	vnode.vnodeNumber = vnodeNumber;
+ 	vnodep = &vnode;
+ 
+ 	tmp = (struct vnodeData **)
+ 		bsearch((void *) &vnodep,
+ 		        vnodeNumber & 1 ? LargeVnodeIndex : SmallVnodeIndex,
+ 			vnodeNumber & 1 ? numLargeVnodes : numSmallVnodes,
+ 			sizeof(struct vnodeData *), CompareVnode);
+ 
+ 	return tmp ? *tmp : NULL;
+ }
+ 
+ /*
+  * Our comparator function for bsearch
+  */
+ 
+ static int
+ CompareVnode(const void *node1, const void *node2)
+ {
+ 	struct vnodeData **vnode1 = (struct vnodeData **) node1;
+ 	struct vnodeData **vnode2 = (struct vnodeData **) node2;
+ 
+ 	if ((*vnode1)->vnodeNumber == (*vnode2)->vnodeNumber)
+ 		return 0;
+ 	else if ((*vnode1)->vnodeNumber > (*vnode2)->vnodeNumber)
+ 		return 1;
+ 	else
+ 		return -1;
+ }
+ 
+ #ifdef RESIDENCY
+ /*
+  * Dump out the filename corresponding to a particular vnode.
+  *
+  * This routine has the following dependancies:
+  *
+  * - Only will work on UFS filesystems at this point
+  * - Has to talk to the rsserver.
+  * - Can only determine UFS algorithm type when run on the same machine
+  *   as the residency (unless you manually specify algorithm information)
+  */
+ 
+ static int
+ DumpVnodeFile(FILE *f, struct VnodeDiskObject *vnode, VolumeDiskData *vol)
+ {
+ 	static int rscache = 0;
+ 	static rsaccessinfoList rsnlist = {0, 0};
+ 	char MountPoint[MAXPATHLEN + 1];
+ 	char FileName[MAXPATHLEN + 1];
+ 	unsigned int Size, Level[4];
+ 	unsigned int DeviceTag, Algorithm;
+ 	FileSystems *FSInfo;
+ 	int i, found, FSType, rsindex;
+ 
+ 	/*
+ 	 * Maybe we found out something about this residency via the
+ 	 * command-line; check that first.
+ 	 */
+ 
+ 	rsindex = ffs(VLkp_Residencies(vnode)) - 1;
+ 
+ 	/*
+ 	 * We need to get information from the rsserver (so we can
+ 	 * find out the device tag for a given residency).  If we
+ 	 * haven't cached that, talk to the rsserver to get it.
+ 	 * If we have info about this already, then don't talk to
+ 	 * the rsserver (this lets us still do disaster recovery if
+ 	 * MR-AFS is completely hosed).
+ 	 */
+ 
+ 	if (! rscache && rscmdlineinfo[rsindex].DeviceTag == -1) {
+ 		int code;
+ 
+ 		code = ServerInitResidencyConnection();
+ 
+ 		if (code) {
+ 			fprintf(stderr, "ServerInitResidencyConnection failed "
+ 				"with code %d\n", code);
+ 			return -1;
+ 		}
+ 
+ 		code = rs_GetResidencySummary(ServerRequestorId, &rsnlist);
+ 
+ 		if (code) {
+ 			fprintf(stderr, "rs_GetResidencySummary failed "
+ 				"with code %d\n", code);
+ 			return -1;
+ 		}
+ 
+ 		rscache = 1;
+ 	}
+ 
+ 	/*
+ 	 * For a given residency (as specified in the vnode),
+ 	 * find out it's device tag number, either via the rsserver
+ 	 * or via the command line.
+ 	 */
+ 
+ 	if (rscmdlineinfo[rsindex].DeviceTag != -1) {
+ 		DeviceTag = rscmdlineinfo[rsindex].DeviceTag;
+ 		found = 1;
+ 	} else
+ 		for (i = 0, found = 0; (i < rsnlist.rsaccessinfoList_len) &&
+ 								(!found); i++) {
+ 			if (rsnlist.rsaccessinfoList_val[i].id.residency ==
+ 			    VLkp_Residencies(vnode)) {
+ 				found = 1;
+ 				DeviceTag =
+ 			     rsnlist.rsaccessinfoList_val[i].devicetagnumber;
+ 				break;
+ 			}
+ 		}
+ 
+ 	if (! found) {
+ 		if (verbose)
+ 			fprintf(stderr, "Unable to find residency %d in "
+ 				"rsserver database, aborting\n",
+ 				VLkp_Residencies(vnode));
+ 		return -1;
+ 	}
+ 
+ 	/*
+ 	 * Okay, now we've got the DeviceTag ... which we can use to
+ 	 * lookup the on-disk configuration information (which we
+ 	 * assume is locally stored).  We also need the DeviceTag to
+ 	 * print out which partition we're using (but that comes later).
+ 	 *
+ 	 * We lookup the on-disk configuration information by calling
+ 	 * Ufs_GetFSInfo() to get the configuration information on the
+ 	 * filesystems specified by the given DeviceTag.
+ 	 *
+ 	 * Before we call Ufs_GetFSInfo, check the command-line cache;
+ 	 * if we got something via the command-line, don't go to disk.
+ 	 */
+ 
+ 	if (rscmdlineinfo[rsindex].FSType == -1 &&
+ 	    Ufs_GetFSInfo(&FSInfo, DeviceTag)) {
+ 		if (verbose)
+ 			fprintf(stderr, "Ufs_GetFSInfo failed for DeviceTag "
+ 				"%d, Residency %d\n", DeviceTag,
+ 				VLkp_Residencies(vnode));
+ 		return -1;
+ 	}
+ 
+ 	/*
+ 	 * The FSInfo structure has the last two things we need: the
+ 	 * FSType (ufs, slowufs, etc etc), and the usage algorithm (which
+ 	 * ends up being how many directories are being used on the
+ 	 * residency filesystem).
+ 	 *
+ 	 * With these last two parameters, use routines stolen from
+ 	 * ufsname to generate the filename.
+ 	 *
+ 	 * (Actually, I lied - we also need the "Size" parameter, which
+ 	 * we can also get from FSInfo);
+ 	 */
+ 
+ 	if (rscmdlineinfo[rsindex].FSType != -1) {
+ 		FSType = rscmdlineinfo[rsindex].FSType;
+ 		Algorithm = rscmdlineinfo[rsindex].Algorithm;
+ 		Size = rscmdlineinfo[rsindex].Size;
+ 	} else {
+ 		FSType = FSInfo->FileSystems_u.UfsInterface.FSType;
+ 		Algorithm = FSInfo->FileSystems_u.UfsInterface.Algorithm;
+ 		if (FSInfo->FileSystems_u.UfsInterface.Directories[1] == 0)
+ 			Size = 0;
+ 		else if (FSInfo->FileSystems_u.UfsInterface.Directories[1] == 16)
+ 			Size = 1;
+ 		else if (FSInfo->FileSystems_u.UfsInterface.Directories[1] == 256)
+ 			Size = 2;
+ 		else {
+ 			if (verbose)
+ 				fprintf(stderr, "Unknown directory size %d, "
+ 					"aborting\n",
+ 					FSInfo->FileSystems_u.UfsInterface.Directories[1]);
+ 			return -1;
+ 		}
+ 	}
+ 
+ 	/*
+ 	 * First, generate our mount point from the DeviceTag and
+ 	 * FSType.
+ 	 */
+ 
+ 	DEVICETAGNUMBERTOMOUNTPOINT(MountPoint, DeviceTag, FSType);
+ 
+ 	/*
+ 	 * Then, generate the "level" (directory bitmasks) from the
+ 	 * file tags, size, and algorithm
+ 	 */
+ 
+ 	UfsTagsToLevel(VLkp_FileTag1(vnode), VLkp_FileTag2(vnode), Algorithm,
+ 		       Size, Level, VLkp_ParentVnodeId(vnode),
+ 		       VLkp_ParentUniquifierId(vnode));
+ 
+ 	/*
+ 	 * Finally, take the above information and generate the
+ 	 * corresponding filename (this macro ends up being a
+ 	 * sprintf() call)
+ 	 */
+ 
+ 	TAGSTONAME(FileName, MountPoint, Level, Directories[Size][1],
+ 		   vol->parentId, VLkp_ParentVnodeId(vnode),
+ 		   VLkp_ParentUniquifierId(vnode), Algorithm);
+ 
+ 	fprintf(f, "%s\n", FileName);
+ 
+ 	return 0;
+ }
+ #endif
+ 
+ /*
+  * Read a 16 bit integer in network order
+  */
+ 
+ static int
+ ReadInt16(FILE *f, unsigned short *s)
+ {
+ 	unsigned short in;
+ 
+ 	if (fread((void *)&in, sizeof(in), 1, f) != 1) {
+ 		if (verbose)
+ 			fprintf(stderr, "ReadInt16 failed!\n");
+ 		return -1;
+ 	}
+ 
+ 	*s = ntohs(in);
+ 
+ 	return 0;
+ }
+ 
+ 
+ /*
+  * Read a 32 bit integer in network order
+  */
+ 
+ static int
+ ReadInt32(FILE *f, unsigned int *i)
+ {
+ 	unsigned int in;
+ 
+ 	if (fread((void *)&in, sizeof(in), 1, f) != 1) {
+ 		if (verbose)
+ 			fprintf(stderr, "ReadInt32 failed!\n");
+ 		return -1;
+ 	}
+ 
+ 	*i = ntohl((unsigned long) in);
+ 
+ 	return 0;
+ }
+ 
+ /*
+  * Read a string from a dump file
+  */
+ 
+ static int
+ ReadString(FILE *f, char *string, int maxlen)
+ {
+ 	int c;
+ 
+ 	while (maxlen--) {
+ 		if ((*string++ = getc(f)) == 0)
+ 			break;
+ 	}
+ 
+ 	/*
+ 	 * I'm not sure what the _hell_ this is supposed to do ...
+ 	 * but it was in the original dump code
+ 	 */
+ 
+ 	if (string[-1]) {
+ 		while ((c = getc(f)) && c != EOF);
+ 		string[-1] = 0;
+ 	}
+ 
+ 	return 0;
+ }
+ 
+ static int
+ ReadByteString(FILE *f, void *s, int size)
+ {
+ 	unsigned char *c = (unsigned char *) s;
+ 
+ 	while (size--)
+ 		*c++ = getc(f);
+ 	
+ 	return 0;
+ }
+ 
+ /*
+  * The directory hashing algorithm used by AFS
+  */
+ 
+ DirHash (string)
+     register char *string; {
+     /* Hash a string to a number between 0 and NHASHENT. */
+     register unsigned char tc;
+     register int hval;
+     register int tval;
+     hval = 0;
+     while(tc=(*string++)) {
+         hval *= 173;
+         hval  += tc;
+     }
+     tval = hval & (NHASHENT-1);
+ #ifdef AFS_CRAY_ENV     /* actually, any > 32 bit environment */
+     if (tval == 0) return tval;
+     else if (hval & 0x80000000) tval = NHASHENT-tval;
+ #else /* AFS_CRAY_ENV */
+     if (tval == 0) return tval;
+     else if (hval < 0) tval = NHASHENT-tval;
+ #endif /* AFS_CRAY_ENV */
+     return tval;
+ }
+ 
+ #ifdef RESIDENCY
+ /*
+  * Sigh, we need this for the AFS libraries
+  */
+ 
+ int
+ LogErrors(int level, char *a, char *b, char *c, char *d, char *e, char *f,
+ 	  char *g, char *h, char *i, char *j, char *k)
+ {
+ 	if (level <= 0) {
+ 		fprintf(stderr, a, b, c, d, e, f, g, h, i, j, k);
+ 	}
+ 	return 0;
+ }
+ 
+ /*
+  * These are routines taken from AFS libraries and programs.  Most of
+  * them are from ufsname.c, but a few are from the dir library (the dir
+  * library has a bunch of hidden dependancies, so it's not suitable to
+  * include it outright).
+  */
+ 
+ UfsEntropiesToTags(HighEntropy,LowEntropy,Algorithm,FileTag1,FileTag2)
+     uint32_t HighEntropy;
+     uint32_t LowEntropy;
+     uint32_t Algorithm;
+     uint32_t *FileTag1;
+     uint32_t *FileTag2;
+ {
+     int i;
+ 
+     if ((Algorithm > UFS_ALGORITHMS) || (Algorithm <= 0))
+         return -1;
+     *FileTag1 = 0;
+     *FileTag2 = 0;
+     for (i=0;i<32;++i) {
+         if (UfsEntropy[Algorithm-1][i] < 32)
+ 	    *FileTag1 |= ((HighEntropy & (1 << i)) == 0) ?
+ 	        0 : 1 << UfsEntropy[Algorithm-1][i];
+ 	else
+ 	    *FileTag2 |= ((HighEntropy & (1 << i)) == 0) ?
+ 	        0 : 1 << (UfsEntropy[Algorithm-1][i] - 32);
+     }
+     for (i=32;i<64;++i) {
+         if (UfsEntropy[Algorithm-1][i] < 32)
+ 	    *FileTag1 |=((LowEntropy & (1 << (i - 32))) == 0) ?
+ 	        0 : 1 << UfsEntropy[Algorithm-1][i];
+ 	else
+ 	    *FileTag2 |=((LowEntropy & (1 << (i - 32))) == 0) ?
+ 	        0 : 1 << (UfsEntropy[Algorithm-1][i] - 32);
+     }
+     return 0;
+ }
+ 
+ uint32_t UfsTagsToHighEntropy(FileTag1,FileTag2,Algorithm)
+     uint32_t FileTag1;
+     uint32_t FileTag2;
+     uint32_t Algorithm;
+ {
+     int i;
+     uint32_t Value;
+ 
+     Value = 0;
+     for (i=0;i<32;++i) {
+         if (UfsEntropy[Algorithm-1][i] < 32)
+ 	    Value |= ((FileTag1 & (1 << UfsEntropy[Algorithm-1][i]))
+ 		      == 0) ? 0: 1 << i;
+ 	else
+ 	    Value |= ((FileTag2 & (1 << (UfsEntropy[Algorithm-1][i] - 
+ 					 32))) == 0) ? 0: 1 << i;
+     }
+     return Value;
+ }
+ 
+ uint32_t UfsTagsToLowEntropy(FileTag1,FileTag2,Algorithm)
+     uint32_t FileTag1;
+     uint32_t FileTag2;
+     uint32_t Algorithm;
+ {
+     int i;
+     uint32_t Value;
+ 
+     Value = 0;
+     for (i=32;i<64;++i) {
+         if (UfsEntropy[Algorithm-1][i] < 32)
+ 	    Value |= ((FileTag1 & (1 << UfsEntropy[Algorithm-1][i])) 
+ 		      == 0) ? 0: 1 << (i - 32);
+ 	else
+ 	    Value |= ((FileTag2 & (1 << (UfsEntropy[Algorithm-1][i] -
+ 					 32))) == 0) ? 0: 1 << (i - 32) ;
+     }
+     return Value;
+ }
+ 
+ UfsTagsToLevel(FileTag1, FileTag2, Algorithm, Size, Sections, vnode, Uniquifier)
+     uint32_t FileTag1;
+     uint32_t FileTag2;
+     uint32_t Algorithm;
+     uint32_t Size;
+     uint32_t Sections[4];
+     uint32_t vnode;
+     uint32_t Uniquifier;
+ {
+     uint32_t HighEntropy;
+     uint32_t LowEntropy;
+ 
+     switch (Algorithm) {
+         case 1:
+             LowEntropy = UfsTagsToLowEntropy(
+                                 FileTag1,
+                                 FileTag2,
+                                 Algorithm);
+             HighEntropy = UfsTagsToHighEntropy(
+                                 FileTag1,
+                                 FileTag2,
+                                 Algorithm);
+             Sections[0] = HighEntropy % Directories[Size][0];
+             HighEntropy /= Directories[Size][0];
+             if (Directories[Size][1]) {
+                 Sections[1] = HighEntropy % Directories[Size][1];
+                 HighEntropy /= Directories[Size][1];
+                 Sections[2] = HighEntropy;
+                 Sections[3] = LowEntropy;
+             } else {
+                 Sections[1] = HighEntropy;
+                 Sections[2] = LowEntropy;
+             }
+             break;
+         case 2:
+             Sections[0] = FileTag1 & 0xff;
+             if (Directories[Size][1]) {
+                 Sections[1] = Uniquifier & 0xff;
+                 if (Directories[Size][1] == 16) Sections[1] &= 0xf;
+                 Sections[2] = FileTag1;
+                 Sections[3] = FileTag2;
+             } else {
+                 Sections[1] = FileTag1;
+                 Sections[2] = FileTag2;
+             }
+             break;
+         case 3:
+             Sections[0] = FileTag1 & 0xff;
+             if (Directories[Size][1]) {
+                 Sections[1] = (vnode >> 1) & 0xff;
+                 if (Directories[Size][1] == 16) Sections[1] &= 0xf;
+                 Sections[2] = FileTag1;
+                 Sections[3] = FileTag2;
+             } else {
+                 Sections[1] = FileTag1;
+                 Sections[2] = FileTag2;
+             }
+             break;
+         default:
+             fprintf(stderr,"UfsTagsToLevel: bad algorithm %lu!\n", Algorithm);
+             return -1;
+     }
+     return 0;
+ }
+ 
+ #include <afs/afscbdummies.h>
+ #endif /* RESIDENCY */
Index: openafs/src/tests/dup2-and-unlog.c
diff -c /dev/null openafs/src/tests/dup2-and-unlog.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/dup2-and-unlog.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,32 ----
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <sys/types.h>
+ #include <stdio.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <err.h>
+ 
+ int
+ main(int argc, char **argv)
+ {
+     int fd;
+ 
+ 
+     fd = open ("foo", O_RDWR|O_CREAT, 0666);
+     if (fd < 0)
+ 	err (1, "open");
+ 
+     dup2 (fd + 1, fd);
+     
+     if (write (fd, "foo\n", 4) != 4)
+ 	errx (1, "write");
+ 
+     ktc_ForgetAllTokens();
+ 
+     close (fd);
+     close (fd + 1);
+ 
+     exit (0);
+ }
Index: openafs/src/tests/echo-n.c
diff -c /dev/null openafs/src/tests/echo-n.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/echo-n.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,18 ----
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ 
+ int
+ main (int argc, char **argv)
+ {
+     int i;
+     for (i = 1; i < argc ; i++) {
+ 	printf ("%s", argv[i]);
+ 	if (argc > i + 1)
+ 	    printf (" ");
+     }
+     fflush (stdout);
+     return 0;
+ }
Index: openafs/src/tests/err.c
diff -c /dev/null openafs/src/tests/err.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/err.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,48 ----
+ /*
+  * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan 
+  * (Royal Institute of Technology, Stockholm, Sweden).  
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ RCSID("$Id: err.c,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $");
+ #endif
+ 
+ #include "err.h"
+ 
+ void
+ err(int eval, const char *fmt, ...)
+ {
+   va_list ap;
+   va_start(ap, fmt);
+   verr(eval, fmt, ap);
+   va_end(ap);
+ }
Index: openafs/src/tests/err.h
diff -c /dev/null openafs/src/tests/err.h:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/err.h	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,71 ----
+ /*
+  * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan 
+  * (Royal Institute of Technology, Stockholm, Sweden).  
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ /* $Id: err.h,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $ */
+ 
+ #ifndef __ERR_H__
+ #define __ERR_H__
+ 
+ #include <errno.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <stdarg.h>
+ 
+ extern const char *__progname;
+ 
+ #if !defined(__GNUC__) && !defined(__attribute__)
+ #define __attribute__(x)
+ #endif
+ 
+ void warnerr(int doerrno, const char *fmt, va_list ap)
+      __attribute__ ((format (printf, 2, 0)));
+ 
+ void verr(int eval, const char *fmt, va_list ap)
+      __attribute__ ((noreturn, format (printf, 2, 0)));
+ void err(int eval, const char *fmt, ...)
+      __attribute__ ((noreturn, format (printf, 2, 3)));
+ void verrx(int eval, const char *fmt, va_list ap)
+      __attribute__ ((noreturn, format (printf, 2, 0)));
+ void errx(int eval, const char *fmt, ...)
+      __attribute__ ((noreturn, format (printf, 2, 3)));
+ void vwarn(const char *fmt, va_list ap)
+      __attribute__ ((format (printf, 1, 0)));
+ void warn(const char *fmt, ...)
+      __attribute__ ((format (printf, 1, 2)));
+ void vwarnx(const char *fmt, va_list ap)
+      __attribute__ ((format (printf, 1, 0)));
+ void warnx(const char *fmt, ...)
+      __attribute__ ((format (printf, 1, 2)));
+ 
+ #endif /* __ERR_H__ */
Index: openafs/src/tests/errx.c
diff -c /dev/null openafs/src/tests/errx.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/errx.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,48 ----
+ /*
+  * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan 
+  * (Royal Institute of Technology, Stockholm, Sweden).  
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ RCSID("$Id: errx.c,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $");
+ #endif
+ 
+ #include "err.h"
+ 
+ void
+ errx(int eval, const char *fmt, ...)
+ {
+   va_list ap;
+   va_start(ap, fmt);
+   verrx(eval, fmt, ap);
+   va_end(ap);
+ }
Index: openafs/src/tests/exec
diff -c /dev/null openafs/src/tests/exec:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/exec	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,9 ----
+ #!/bin/sh
+ echo '#!/bin/sh' > foo.sh
+ export objdir
+ echo '$objdir/echo-n "foo"' >> foo.sh
+ test -f foo.sh || exit 1
+ chmod +x foo.sh
+ test -x foo.sh || exit 1
+ FOO=`./foo.sh`
+ test "X"$FOO = "Xfoo" || exit 1
Index: openafs/src/tests/exit-wo-close.c
diff -c /dev/null openafs/src/tests/exit-wo-close.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/exit-wo-close.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,127 ----
+ /*
+  * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <sys/wait.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ 
+ #include <err.h>
+ 
+ #ifdef RCSID
+ RCSID("$Id: exit-wo-close.c,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $");
+ #endif
+ 
+ static int 
+ child (const char *filename)
+ {
+     int fd;
+     int ret;
+ 
+     fd = open (filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
+     if (fd < 0)
+ 	err (1, "open %s", filename);
+     ret = write (fd, "hej", 3);
+     if (ret != 3)
+ 	err (1, "write %s", filename);
+     return 0;
+ }
+ 
+ static int 
+ parent (const char *filename, pid_t child_pid)
+ {
+     int stat;
+     int ret;
+     int fd;
+     struct stat sb;
+     char buf[3];
+ 
+     ret = waitpid (child_pid, &stat, 0);
+     if (ret < 0)
+ 	err (1, "waitpid %u", (unsigned)child_pid);
+     if (!WIFEXITED(stat) || WEXITSTATUS(stat) != 0)
+ 	errx (1, "weird child %u", (unsigned)child_pid);
+     fd = open (filename, O_RDONLY, 0);
+     if (fd < 0)
+ 	err (1, "open %s", filename);
+     ret = fstat (fd, &sb);
+     if (ret < 0)
+ 	err (1, "fstat %s", filename);
+     if (sb.st_size != 3)
+ 	errx (1, "size of %s = %u != 3", filename, (unsigned)sb.st_size);
+     ret = read (fd, buf, sizeof(buf));
+     if (ret < 0)
+ 	err (1, "read %s", filename);
+     if (ret != 3)
+ 	errx (1, "short read from %s", filename);
+     if (memcmp (buf, "hej", 3) != 0)
+ 	errx (1, "bad contents of %s = `%.3s'\n", filename, buf);
+     close (fd);
+     return 0;
+ }
+ 
+ static int
+ doit (const char *filename)
+ {
+     pid_t pid;
+ 
+     pid = fork ();
+     if (pid < 0)
+ 	err (1, "fork");
+ 
+     if (pid == 0)
+ 	return child (filename);
+     else
+ 	return parent (filename, pid);
+ }
+ 
+ int
+ main(int argc, char **argv)
+ {
+     const char *file = "foo";
+ 
+ 
+     if (argc != 2 && argc != 1)
+ 	errx (1, "usage: %s [file]", argv[0]);
+     if (argc == 2)
+ 	file = argv[1];
+     return doit (file);
+ }
Index: openafs/src/tests/extcopyin
diff -c /dev/null openafs/src/tests/extcopyin:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/extcopyin	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,11 ----
+ #!/bin/sh
+ FS=${FS:-${objdir}/../appl/fs/fs}
+ ${FS} sa . system:anyuser all || exit 1
+ ${objdir}/write-rand /usr/tmp/$$ 262144 || exit 1
+ ${objdir}/afscp -i -b 56k /usr/tmp/$$ `pwd`/$$ || exit 1
+ diff /usr/tmp/$$ `pwd`/$$ || exit 1
+ ${objdir}/afscp -i -b 32k /usr/tmp/$$ `pwd`/$$ || exit 1
+ diff /usr/tmp/$$ `pwd`/$$ || exit 1
+ exit 0
+ 
+ 
Index: openafs/src/tests/extcopyout
diff -c /dev/null openafs/src/tests/extcopyout:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/extcopyout	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,11 ----
+ #!/bin/sh
+ FS=${FS:-${objdir}/../appl/fs/fs}
+ ${FS} sa . system:anyuser all || exit 1
+ ${objdir}/write-rand $$ 262144 || exit 1
+ ${objdir}/afscp -o -b 56k `pwd`/$$ /usr/tmp/$$ || exit 1
+ diff /usr/tmp/$$ `pwd`/$$ || exit 1
+ ${objdir}/afscp -o -b 32k `pwd`/$$ /usr/tmp/$$ || exit 1
+ diff /usr/tmp/$$ `pwd`/$$ || exit 1
+ exit 0
+ 
+ 
Index: openafs/src/tests/fcachesize-dir
diff -c /dev/null openafs/src/tests/fcachesize-dir:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/fcachesize-dir	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,13 ----
+ #!/bin/sh
+ # $Id: fcachesize-dir,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ 
+ FS=${FS:-${objdir}/../appl/fs/fs}
+ SIZE1=`$FS getcache -b | awk '{ print $4 ; exit }'`
+ mkdir foo
+ SIZE2=`$FS getcache -b | awk '{ print $4 ; exit }'`
+ test $SIZE2 = `expr $SIZE1 + 2048` || exit 1
+ rmdir foo
+ #SIZE3=`$FS getcache -b | awk '{ print $4 ; exit }'`
+ #test $SIZE3 = $SIZE1 || exit 1
+ 
+ exit 0
Index: openafs/src/tests/fcachesize-file-small
diff -c /dev/null openafs/src/tests/fcachesize-file-small:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/fcachesize-file-small	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,13 ----
+ #!/bin/sh
+ # $Id: fcachesize-file-small,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ 
+ FS=${FS:-${objdir}/../appl/fs/fs}
+ SIZE1=`$FS getcache -b | awk '{ print $4 ; exit }'`
+ echo foo > foo
+ SIZE2=`$FS getcache -b | awk '{ print $4 ; exit }'`
+ test $SIZE2 = `expr $SIZE1 + 4` || exit 1
+ rm foo
+ #SIZE3=`$FS getcache -b | awk '{ print $4 ; exit }'`
+ #test $SIZE3 = $SIZE1 || exit 1
+ 
+ exit 0
Index: openafs/src/tests/fcachesize-read-file
diff -c /dev/null openafs/src/tests/fcachesize-read-file:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/fcachesize-read-file	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,14 ----
+ #!/bin/sh
+ # $Id: fcachesize-read-file,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ 
+ FS=${FS:-${objdir}/../appl/fs/fs}
+ SIZE1=`$FS getcache | awk '{ print $8 ; exit }'`
+ SIZE2=`expr $SIZE1 + 4`
+ if test -w /dev/null; then
+   dd if=../foo of=/dev/null bs=1k count=$SIZE2 >/dev/null 2>/dev/null || exit 1
+   rm ../foo || exit 1
+ else
+   echo "not running dd (you have no /dev/null)"
+ fi
+ 
+ exit 0
Index: openafs/src/tests/fcachesize-write-file
diff -c /dev/null openafs/src/tests/fcachesize-write-file:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/fcachesize-write-file	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,13 ----
+ #!/bin/sh
+ # $Id: fcachesize-write-file,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ 
+ FS=${FS:-${objdir}/../appl/fs/fs}
+ SIZE1=`$FS getcache | awk '{ print $8 ; exit }'`
+ SIZE2=`expr $SIZE1 + 4`
+ if test -r /dev/zero; then
+   dd if=/dev/zero of=../foo bs=1k count=$SIZE2 >/dev/null 2>/dev/null || exit 1
+ else
+   echo "not running dd (you have no /dev/zero)"
+ fi
+ 
+ exit 0
Index: openafs/src/tests/fchmod.c
diff -c /dev/null openafs/src/tests/fchmod.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/fchmod.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,71 ----
+ /*
+  * Copyright (c) 2000 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <unistd.h>
+ #include <fcntl.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ 
+ #include <err.h>
+ 
+ int
+ main(int argc, char **argv)
+ {
+     int fd, ret;
+     struct stat sb;
+ 
+ 
+     fd = open ("deps", O_WRONLY|O_CREAT|O_TRUNC, 0666);
+     if (fd < 0)
+ 	err (1, "open");
+     ret = fstat (fd, &sb);
+     if (ret < 0)
+ 	err (1, "fstat");
+     ret = write (fd, "# DO NOT DELETE\n", 16);
+     if (ret != 16)
+ 	err (1, "write");
+     ret = fchmod (fd, 0100644);
+     if (ret < 0)
+ 	errx (1, "fchmod");
+     ret = close (fd);
+     if (ret < 0)
+ 	errx (1, "close");
+ 
+     unlink("deps");
+     return 0;
+ }
Index: openafs/src/tests/fhbench.c
diff -c /dev/null openafs/src/tests/fhbench.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/fhbench.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,337 ----
+ /*
+  * Copyright (c) 2000 - 2001 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <sys/types.h>
+ #include <sys/param.h>
+ #include <unistd.h>
+ #include <limits.h>
+ #include <sys/mount.h>
+ 
+ #ifdef HAVE_SYS_IOCCOM_H
+ #include <sys/ioccom.h>
+ #endif
+ 
+ #include <fcntl.h>
+ 
+ #include <err.h>
+ #include <agetarg.h>
+ 
+ #include <atypes.h>
+ #include <kafs.h>
+ 
+ RCSID("$Id: fhbench.c,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $");
+ 
+ struct fhb_handle {
+     char data[512];
+ };
+ 
+ static int help_flag;
+ static int num_files;
+ static int write_file = 0;
+ static int num_runs = 3;
+ 
+ static struct agetargs args[] = {
+     {"num",	'n',	aarg_integer,	&num_files,	"number of files"},
+     {"write",	'w',	aarg_integer,	&write_file,	"write num kb"},
+     {"runs",	'r',	aarg_integer,	&num_runs,	"number of runs"},
+     {"help",	0,	aarg_flag,	&help_flag,	NULL,		NULL},
+     {NULL,	0,	aarg_end,	NULL,		NULL,		NULL}
+ };
+ 
+ 
+ static void
+ fhb_fhget (char *filename, struct fhb_handle *handle)
+ {
+     int ret = 0;
+ #if defined(HAVE_GETFH) && defined(HAVE_FHOPEN)
+     {
+ 	fhandle_t fh;
+ 
+ 	ret = getfh (filename, &fh);
+ 	if (ret)
+ 	    err (1, "getfh");
+ 	memcpy (handle, &fh, sizeof(fh));
+     }
+ #endif
+     {
+ 	struct ViceIoctl vice_ioctl;
+ 	
+ 	vice_ioctl.in      = NULL;
+ 	vice_ioctl.in_size = 0;
+ 	
+ 	vice_ioctl.out      = (caddr_t)handle;
+ 	vice_ioctl.out_size = sizeof(*handle);
+ 	
+ 	ret = pioctl (filename, VIOC_FHGET, &vice_ioctl, 0);
+ 	if (ret)
+ 	    errx (1, "k_pioctl");
+     }
+ }
+ 
+ 
+ static int
+ fhb_fhopen (struct fhb_handle *handle, int flags)
+ {
+     int ret;
+ #if defined(HAVE_GETFH) && defined(HAVE_FHOPEN)
+     {
+ 	fhandle_t fh;
+ 
+ 	memcpy (&fh, handle, sizeof(fh));
+ 	ret = fhopen (&fh, flags);
+ 	if (ret >= 0)
+ 	    return ret;
+     }
+ #endif
+ 
+ #ifdef KERBEROS			/* really KAFS */
+     {
+ 	struct ViceIoctl vice_ioctl;
+ 	
+ 	vice_ioctl.in      = (caddr_t)handle;
+ 	vice_ioctl.in_size = sizeof(*handle);
+ 	
+ 	vice_ioctl.out      = NULL;
+ 	vice_ioctl.out_size = 0;
+ 	
+ 	ret = k_pioctl (NULL, VIOC_FHOPEN, &vice_ioctl, flags);
+ 	if (ret >= 0)
+ 	    return ret;
+     }
+ #endif
+     errx (1, "fhopen/k_pioctl");
+ }
+ 
+ static void
+ nop_call (void)
+ {
+ #ifdef KERBEROS			/* really KAFS */
+     {
+ 	struct ViceIoctl vice_ioctl;
+ 	char c[8];
+ 	int ret;
+ 	
+ 	vice_ioctl.in      = (caddr_t)&c;
+ 	vice_ioctl.in_size = sizeof(c);
+ 	
+ 	vice_ioctl.out      = NULL;
+ 	vice_ioctl.out_size = 0;
+ 	
+ 	ret = k_pioctl (NULL, VIOC_XFSDEBUG, &vice_ioctl, 0);
+ 	if (ret < 0)
+ 	    err (1, "k_pioctl");
+     }
+ #else
+     {
+ 	static first = 1;
+ 	if (first) {
+ 	    warnx ("can't test this");
+ 	    first = 0;
+ 	}
+     }
+ #endif
+ }
+ 
+ static void
+ create_file (int num, struct fhb_handle *handle)
+ {
+     int fd;
+     char filename[1024];
+ 
+     snprintf (filename, sizeof(filename), "file-%d", num);
+ 
+     fd = open (filename, O_CREAT|O_EXCL|O_RDWR, 0666);
+     if (fd < 0)
+ 	err (1, "open");
+ 
+     close (fd);
+     
+     fhb_fhget(filename, handle);
+ }
+ 
+ char databuf[1024];
+ 
+ static void
+ write_to_file (int fd, int num)
+ {
+     int ret;
+     while (num > 0) {
+ 	ret = write (fd, databuf, sizeof(databuf));
+ 	if (ret != sizeof(databuf))
+ 	    err (1, "write");
+ 	num--;
+     }
+ }
+ 
+ static void
+ fhopen_file (int num, struct fhb_handle *handle)
+ {
+     int fd;
+ 
+     fd = fhb_fhopen(handle, O_RDWR);
+     if (fd < 0)
+ 	err (1, "open");
+ 
+     if (write_file)
+ 	write_to_file(fd, write_file);
+     close(fd);
+ }
+ 
+ static void
+ open_file (int num)
+ {
+     int fd;
+     char filename[1024];
+ 
+     snprintf (filename, sizeof(filename), "file-%d", num);
+ 
+     fd = open (filename, O_RDWR, 0666);
+     if (fd < 0)
+ 	err (1, "open");
+ 
+     if (write_file)
+ 	write_to_file(fd, write_file);
+ 
+     close (fd);
+ }
+ 
+ static void
+ unlink_file (int num)
+ {
+     int ret;
+     char filename[1024];
+ 
+     snprintf (filename, sizeof(filename), "file-%d", num);
+ 
+     ret = unlink(filename);
+     if (ret < 0)
+ 	err (1, "unlink");
+ }
+ 
+ struct timeval time1, time2;
+ 
+ static void
+ starttesting(char *msg)
+ {
+     printf("testing %s...\n", msg);
+     fflush (stdout);
+     gettimeofday(&time1, NULL);
+ }    
+ 
+ static void
+ endtesting(void)
+ {
+     gettimeofday(&time2, NULL);
+     timevalsub(&time2, &time1);
+     printf("timing: %ld.%06ld\n", (long)time2.tv_sec, (long)time2.tv_usec);
+ }
+ 
+ static void
+ usage (int exit_val)
+ {
+     aarg_printusage (args, NULL, "number of files", AARG_GNUSTYLE);
+     exit (exit_val);
+ }
+ 
+ static void
+ open_bench (int i, struct fhb_handle *handles)
+ {
+     printf ("====== test run %d\n"
+ 	    "==================\n",
+ 	    i);
+ 
+     starttesting ("fhopening files");
+     for (i = 0; i < num_files; i++)
+ 	fhopen_file (i, &handles[i]);
+     endtesting ();
+    
+     starttesting ("opening files");
+     for (i = 0; i < num_files; i++)
+ 	open_file (i);
+     endtesting ();
+ }
+ 
+ int
+ main (int argc, char **argv)
+ {
+     int optind = 0;
+     int i;
+     struct fhb_handle *handles;
+ 
+ 
+     if (agetarg (args, argc, argv, &optind, AARG_GNUSTYLE))
+ 	usage (1);
+ 
+     if (help_flag)
+ 	usage (0);
+ 
+     if (num_files <= 0)
+ 	usage (1);
+ 
+     if (write_file < 0)
+ 	usage (1);
+ 
+ #ifdef KERBEROS
+     if (!k_hasafs())
+ #endif
+ 	errx (1, "no afs kernel module");
+ 
+     handles = emalloc (num_files * sizeof(*handles));
+ 
+     starttesting ("creating files");
+     for (i = 0; i < num_files; i++)
+ 	create_file (i, &handles[i]);
+     endtesting ();
+ 
+     for (i = 0 ; i < num_runs; i++)
+ 	open_bench (i, handles);
+    
+     printf ( "==================\n");
+     starttesting ("unlink files");
+     for (i = 0; i < num_files; i++)
+ 	unlink_file (i);
+     endtesting ();
+ 
+     printf ( "==================\n");
+     starttesting ("nop call");
+     for (i = 0; i < num_files; i++)
+ 	nop_call ();
+     endtesting ();
+ 
+     return 0;
+ }
Index: openafs/src/tests/find-and-cat-netbsd
diff -c /dev/null openafs/src/tests/find-and-cat-netbsd:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/find-and-cat-netbsd	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,5 ----
+ #!/bin/sh
+ # $Id: find-and-cat-netbsd,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ if test "X$FAST" != "X" ; then echo "Not running $0" ;  exit 0 ; fi
+ netbsd_ftp_mirror=${1-$AFSROOT/stacken.kth.se/ftp/pub/NetBSD/NetBSD-1.4/}
+ find ${netbsd_ftp_mirror} -type f -exec cat '{}' \; > /dev/null
Index: openafs/src/tests/find-linux
diff -c /dev/null openafs/src/tests/find-linux:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/find-linux	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,5 ----
+ #!/bin/sh
+ # $Id: find-linux,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ if test "X$FAST" != "X" ; then echo "Not running $0" ;  exit 0 ; fi
+ linux_src=${1-$AFSROOT/pdc.kth.se/src/OS/Linux/}
+ (cd ${linux_src} ; find . ) >&4
Index: openafs/src/tests/fs-flush
diff -c /dev/null openafs/src/tests/fs-flush:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/fs-flush	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,6 ----
+ #!/bin/sh
+ # $Id: fs-flush,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ FS=${FS:-${objdir}/../appl/fs/fs}
+ > foobar
+ ${FS} flush
+ test -f foobar || exit 1
\ No newline at end of file
Index: openafs/src/tests/fs-sa-la
diff -c /dev/null openafs/src/tests/fs-sa-la:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/fs-sa-la	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,6 ----
+ #!/bin/sh
+ # $Id: fs-sa-la,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ FS=${FS:-${objdir}/../appl/fs/fs}
+ ${FS} sa . kalle-anka-nu rl 2>&4
+ ${FS} la >&4 2>&4
+ exit 0
Index: openafs/src/tests/fs_lib.c
diff -c /dev/null openafs/src/tests/fs_lib.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/fs_lib.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,848 ----
+ /*
+  * Copyright (c) 1998 - 2001 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <dirent.h>
+ #include <errno.h>
+ #include <netinet/in.h>
+ #include <afs/stds.h>
+ #include <afs/vice.h>
+ #include <afs/venus.h>
+ #include <afs/afsint.h>
+ #include <afs/auth.h>
+ #include <afs/cellconfig.h>
+ #include <afs/cmd.h>
+ 
+ enum { PIOCTL_MAXSIZE = 2000 };
+ 
+ struct VenusFid {
+   afs_int32 Cell;
+   struct AFSFid Fid;
+ };
+ 
+ /*
+  * fs_getfid, the the `fid' that `path' points on. 
+  */
+ 
+ int
+ fs_getfid(char *path, struct VenusFid *fid)
+ {
+     struct ViceIoctl a_params;
+ 
+     if (path == NULL || fid == NULL)
+ 	return EINVAL;
+ 
+     a_params.in_size=0;
+     a_params.out_size=sizeof(struct VenusFid);
+     a_params.in=NULL;
+     a_params.out=(void*) fid;
+     
+     if(pioctl(path,VIOCGETFID,&a_params,1) == -1)
+ 	return errno;
+ 
+     return 0;
+ }
+ 
+ /*
+  * Do nothing
+  */
+ 
+ int
+ fs_nop(void)
+ {
+     struct ViceIoctl a_params;
+ 
+     a_params.in_size=0;
+     a_params.out_size=0;
+     a_params.in=NULL;
+     a_params.out=NULL;
+     
+     if (pioctl(NULL,VIOCNOP,&a_params,1) == -1) 
+ 	return errno;
+ 
+     return 0;
+ }
+ 
+ /*
+  * Get the `cell' that the `path' ends up in
+  */
+ 
+ int
+ fs_getfilecellname(char *path, char *cell, size_t len)
+ {
+     struct ViceIoctl a_params;
+ 
+     a_params.in_size=0;
+     a_params.out_size=len;
+     a_params.in=NULL;
+     a_params.out=cell;
+     
+     if (pioctl(path,VIOC_FILE_CELL_NAME,&a_params,1) == -1) 
+ 	return errno;
+ 
+     return 0;
+ }
+ 
+ /*
+  * set the level of crypt
+  */
+ 
+ #ifdef VIOC_SETRXKCRYPT
+ int
+ fs_setcrypt (u_int32_t n)
+ {
+     struct ViceIoctl	a_params;
+ 
+     a_params.in_size  = sizeof(n);
+     a_params.out_size = 0;
+     a_params.in	      = (char *)&n;
+     a_params.out      = NULL;
+ 
+     if (pioctl (NULL, VIOC_SETRXKCRYPT, &a_params, 0) == -1)
+ 	return errno;
+ 
+     return 0;
+ }
+ #endif
+ 
+ /*
+  * get currernt level of crypt
+  */
+ 
+ #ifdef VIOC_GETRXKCRYPT
+ int
+ fs_getcrypt (u_int32_t *level)
+ {
+     struct ViceIoctl	a_params;
+ 
+     a_params.in_size  = 0;
+     a_params.out_size = sizeof(*level);
+     a_params.in	      = NULL;
+     a_params.out      = (char *) level;
+ 
+     if (pioctl (NULL, VIOC_GETRXKCRYPT, &a_params, 0) == -1) 
+ 	return errno;
+     
+     return 0;
+ }
+ #endif
+ 
+ /*
+  * get and set the connect-mode
+  */
+ 
+ #ifdef VIOCCONNECTMODE
+ int
+ fs_connect(int32_t type, int32_t *flags)
+ {
+     struct ViceIoctl   a_params;
+ 
+     a_params.in_size = sizeof(type);
+     a_params.out_size = sizeof (int32_t);
+     a_params.in = (char *) &type;
+     a_params.out = (char *) flags;
+ 
+     if (pioctl (NULL, VIOCCONNECTMODE, &a_params, 0) == -1)
+ 	return errno;
+ 
+     return 0;
+ }
+ #endif
+ 
+ /*
+  *
+  */
+ 
+ #ifdef VIOC_FPRIOSTATUS
+ int
+ fs_setfprio(struct VenusFid fid, int16_t prio)
+ {
+     struct ViceIoctl   a_params;
+     struct vioc_fprio  fprio;
+ 
+     fprio.cmd = FPRIO_SET;
+     fprio.Cell = fid.Cell;
+     fprio.Volume = fid.fid.Volume;
+     fprio.Vnode = fid.fid.Vnode;
+     fprio.Unique = fid.fid.Unique;
+     fprio.prio = prio;
+ 
+     a_params.in_size = sizeof(fprio);
+     a_params.out_size = 0;
+     a_params.in = (char *) &fprio;
+     a_params.out = NULL;
+ 
+     if (pioctl (NULL, VIOC_FPRIOSTATUS , &a_params, 0) == -1)
+ 	return errno;
+ 
+     return 0;
+ }
+ #endif
+ 
+ #ifdef VIOC_FPRIOSTATUS
+ int
+ fs_getfprio(struct VenusFid fid, int16_t *prio)
+ {
+     struct ViceIoctl   a_params;
+     struct vioc_fprio  fprio;
+ 
+     fprio.cmd = FPRIO_GET;
+     fprio.Cell = fid.Cell;
+     fprio.Volume = fid.fid.Volume;
+     fprio.Vnode = fid.fid.Vnode;
+     fprio.Unique = fid.fid.Unique;
+ 
+     a_params.in_size = sizeof(fprio);
+     a_params.out_size = sizeof(*prio);
+     a_params.in = (char *) &fprio;
+     a_params.out = (char *) prio;
+ 
+     if (pioctl (NULL, VIOC_FPRIOSTATUS , &a_params, 0) == -1)
+ 	return errno;
+ 
+     return 0;
+ }
+ #endif
+ 
+ #ifdef VIOC_FPRIOSTATUS
+ int
+ fs_setmaxfprio(int16_t maxprio)
+ {
+     struct ViceIoctl   a_params;
+     struct vioc_fprio  fprio;
+ 
+     fprio.cmd = FPRIO_SETMAX;
+     fprio.prio = maxprio;
+ 
+     a_params.in_size = sizeof(fprio);
+     a_params.out_size = 0;
+     a_params.in = (char *) &fprio;
+     a_params.out = NULL;
+ 
+     if (pioctl (NULL, VIOC_FPRIOSTATUS , &a_params, 0) == -1)
+ 	return errno;
+ 
+     return 0;
+ }
+ #endif
+ 
+ #ifdef VIOC_FPRIOSTATUS
+ int
+ fs_getmaxfprio(int16_t *maxprio)
+ {
+     struct ViceIoctl   a_params;
+     struct vioc_fprio  fprio;
+ 
+     fprio.cmd = FPRIO_GETMAX;
+ 
+     a_params.in_size = sizeof(fprio);
+     a_params.out_size = sizeof(*maxprio);
+     a_params.in = (char *) &fprio;
+     a_params.out = (char *) maxprio;
+ 
+     if (pioctl (NULL, VIOC_FPRIOSTATUS , &a_params, 0) == -1)
+ 	return errno;
+ 
+     return 0;
+ }
+ #endif
+ 
+ /*
+  *
+  */
+ 
+ #ifdef VIOCGETCACHEPARAMS
+ int
+ fs_getfilecachestats(u_int32_t *max_bytes,
+ 		     u_int32_t *used_bytes,
+ 		     u_int32_t *max_vnodes,
+ 		     u_int32_t *used_vnodes)
+ {
+     u_int32_t parms[16];
+     struct ViceIoctl a_params;
+ 
+     a_params.in_size  = 0;
+     a_params.out_size = sizeof(parms);
+     a_params.in       = NULL;
+     a_params.out      = (char *) parms;
+ 
+     memset (parms, 0, sizeof(parms));
+ 
+     if (pioctl (NULL, VIOCGETCACHEPARAMS , &a_params, 0) == -1)
+ 	return errno;
+ 
+     /* param[0] and param[1] send maxbytes and usedbytes in kbytes */
+ 
+     if (max_vnodes)
+ 	*max_vnodes = parms[2];
+     if (used_vnodes)
+ 	*used_vnodes = parms[3];
+     if (max_bytes)
+ 	*max_bytes = parms[4];
+     if (used_bytes)
+ 	*used_bytes = parms[5];
+ 
+     return 0;
+ }
+ #endif
+ 
+ /*
+  *
+  */
+ 
+ #ifdef VIOC_AVIATOR
+ int
+ fs_getaviatorstats(u_int32_t *max_workers,
+ 		   u_int32_t *used_workers)
+ {
+     u_int32_t parms[16];
+     struct ViceIoctl a_params;
+ 
+     a_params.in_size = 0;
+     a_params.out_size = sizeof(parms);
+     a_params.in = NULL;
+     a_params.out = (char *) parms;
+ 
+     if (pioctl (NULL, VIOC_AVIATOR , &a_params, 0) == -1)
+ 	return errno;
+ 
+     if (max_workers)
+ 	*max_workers = parms[0];
+     if (used_workers)
+ 	*used_workers = parms[1];
+ 
+     return 0;
+ }
+ #endif
+ 
+ /*
+  *
+  */
+ 
+ #ifdef VIOC_GCPAGS
+ int
+ fs_gcpags(void)
+ {
+     struct ViceIoctl a_params;
+ 
+     a_params.in_size  = 0;
+     a_params.out_size = 0;
+     a_params.in       = NULL;
+     a_params.out      = NULL;
+ 
+ 
+     if (pioctl(NULL, VIOC_GCPAGS, &a_params, 0) != 0)
+ 	return errno;
+     
+     return 0;
+ }
+ #endif
+ 
+ /*
+  *
+  */
+ 
+ #ifdef VIOC_CALCULATE_CACHE
+ int
+ fs_calculate_cache(u_int32_t *calculated,
+ 		   u_int32_t *usedbytes)
+ {
+     u_int32_t parms[16];
+     struct ViceIoctl a_params;
+ 
+     a_params.in_size = 0;
+     a_params.out_size = sizeof(parms);
+     a_params.in = NULL;
+     a_params.out = (char *) parms;
+ 
+     if (pioctl (NULL, VIOC_CALCULATE_CACHE , &a_params, 0) == -1)
+ 	return errno;
+ 
+     if (calculated)
+ 	*calculated = parms[0];
+     if (usedbytes)
+ 	*usedbytes = parms[1];
+ 
+     return 0;
+ }
+ #endif
+ 
+ /*
+  *
+  */
+ 
+ #ifdef VIOC_BREAKCALLBACK
+ int
+ fs_invalidate (const char *path)
+ {
+     struct ViceIoctl   a_params;
+ 
+     a_params.in_size  = 0;
+     a_params.out_size = 0;
+     a_params.in       = NULL;
+     a_params.out      = NULL;
+     
+     if (pioctl ((char *)path, VIOC_BREAKCALLBACK, &a_params, 0) < 0)
+ 	return errno;
+     else
+ 	return 0;
+ }
+ #endif
+ 
+ /*
+  * Get/set debug levels with pioctl_cmd.
+  *
+  * inflags == -1 -> don't change
+  * outflags == NULL -> don't return
+  */
+ 
+ static int
+ debug (int pioctl_cmd, int inflags, int *outflags, char *pathname)
+ {
+     struct ViceIoctl   a_params;
+ 
+     int32_t rinflags = inflags;
+     int32_t routflags;
+ 
+     if (inflags != -1) {
+ 	a_params.in_size = sizeof(rinflags);
+ 	a_params.in = (char *) &rinflags;
+     } else {
+ 	a_params.in_size = 0;
+ 	a_params.in = NULL;
+     }
+ 	
+     if (outflags) {
+ 	a_params.out_size = sizeof(routflags);
+ 	a_params.out = (char *)  &routflags;
+     } else {
+ 	a_params.out_size = 0;
+ 	a_params.out = NULL;
+     }
+ 
+     if (pioctl (pathname, pioctl_cmd, &a_params, 0) == -1)
+ 	return errno;
+     
+     if (outflags)
+ 	*outflags = routflags;
+ 
+     return 0;
+ }
+ 
+ /*
+  * xfs_debug
+  */
+ 
+ #ifdef VIOC_XFSDEBUG
+ int
+ xfs_debug(int inflags, int *outflags)
+ {
+     return debug (VIOC_XFSDEBUG, inflags, outflags, NULL);
+ }
+ #endif
+ 
+ /*
+  * xfs_debug_print
+  */
+ 
+ #ifdef VIOC_XFSDEBUG_PRINT
+ int
+ xfs_debug_print(int inflags, char *pathname)
+ {
+     return debug (VIOC_XFSDEBUG_PRINT, inflags, NULL, pathname);
+ }
+ #endif
+ 
+ /*
+  * arla_debug
+  */
+ 
+ #ifdef VIOC_ARLADEBUG
+ int
+ arla_debug (int inflags, int *outflags)
+ {
+     return debug (VIOC_ARLADEBUG, inflags, outflags, NULL);
+ }
+ #endif
+ 
+ /*
+  * checkservers
+  *
+  *   flags is the same flags as in CKSERV flags
+  *
+  */
+ 
+ int
+ fs_checkservers(char *cell, int32_t flags, u_int32_t *hosts, int numhosts)
+ {
+     struct ViceIoctl a_params;
+     char *in = NULL;
+     int ret;
+     size_t insize;
+ 
+     if (cell != NULL) {
+ 	insize = strlen(cell) + sizeof(int32_t) + 1;
+ 	in = malloc (insize);
+ 	if (in == NULL)
+ 	    errx (1, "malloc");
+ 
+ 	memcpy (in, &flags, sizeof(flags));
+ 
+ 	memcpy (in + sizeof(int32_t), cell, strlen(cell));
+ 	in[sizeof(int32_t) + strlen(cell)] = '\0';
+ 	
+ 	a_params.in_size = insize;
+ 	a_params.in = in;
+     } else {
+ 	a_params.in_size = sizeof(flags);
+ 	a_params.in = (caddr_t )&flags;
+     }
+ 
+     a_params.out_size = numhosts * sizeof(u_int32_t);
+     a_params.out = (caddr_t)hosts;
+ 
+     ret = 0;
+ 
+     if (pioctl (NULL, VIOCCKSERV, &a_params, 0) == -1)
+ 	ret = errno;
+     
+     if (in)
+ 	free(in);
+ 
+     return ret;
+ }
+ 
+ /*
+  * check validity of cached volume information
+  */
+ 
+ int
+ fs_checkvolumes (void)
+ {
+     struct ViceIoctl a_params;
+ 
+     a_params.in       = NULL;
+     a_params.in_size  = 0;
+     a_params.out      = NULL;
+     a_params.out_size = 0;
+ 
+     if (pioctl (NULL, VIOCCKBACK, &a_params, 0) < 0)
+ 	return errno;
+     else
+ 	return 0;
+ }
+ 
+ /*
+  * set current sysname to `sys'
+  */
+ 
+ int
+ fs_set_sysname (const char *sys)
+ {
+     struct ViceIoctl a_params;
+     int32_t set = 1;
+ 
+     a_params.in_size  = sizeof(set) + strlen(sys) + 1;
+     a_params.in       = malloc(a_params.in_size);
+     if (a_params.in == NULL)
+ 	return ENOMEM;
+     a_params.out      = NULL;
+     a_params.out_size = 0;
+     memcpy (a_params.in, &set, sizeof(set));
+     strcpy (a_params.in + sizeof(set), sys);
+ 
+     if(pioctl (NULL, VIOC_AFS_SYSNAME, &a_params, 1) < 0)
+ 	return errno;
+     else
+ 	return 0;
+ }
+ 
+ /*
+  *
+  */
+ 
+ int
+ fs_setcache(int lv, int hv, int lb, int hb)
+ {
+     struct ViceIoctl a_params;
+     u_int32_t s[4];
+ 
+     s[0] = lv;
+     s[1] = hv;
+     s[2] = lb;
+     s[3] = hb;
+ 
+     a_params.in_size  = ((hv == 0) ? 1 : 4) * sizeof(u_int32_t);
+     a_params.out_size = 0;
+     a_params.in       = (void *)s;
+     a_params.out      = NULL;
+ 
+     if (pioctl(NULL, VIOCSETCACHESIZE, &a_params, 0) < 0)
+ 	return errno;
+     else
+ 	return 0;
+ }
+ 
+ /*
+  * return the local cell in `cell' (of size `cell_sz').
+  */
+ 
+ int
+ fs_wscell (char *cell, size_t cell_sz)
+ {
+     struct ViceIoctl a_params;
+ 
+     a_params.in_size  = 0;
+     a_params.in       = NULL;
+     a_params.out_size = cell_sz;
+     a_params.out      = cell;
+ 
+     if (pioctl (NULL, VIOC_GET_WS_CELL, &a_params, 0) < 0)
+ 	return errno;
+     return 0;
+ }
+ 
+ /*
+  * Flush the contents of the volume pointed to by `path'.
+  */
+ 
+ int
+ fs_flushvolume (const char *path)
+ {
+     struct ViceIoctl a_params;
+ 
+     a_params.in_size  = 0;
+     a_params.out_size = 0;
+     a_params.in       = NULL;
+     a_params.out      = NULL;
+ 
+     if (pioctl ((char *)path, VIOC_FLUSHVOLUME, &a_params, 0) < 0)
+ 	return errno;
+     else
+ 	return 0;
+ }
+ 
+ /*
+  * Flush the file `path' from the cache.
+  */
+ 
+ int
+ fs_flush (const char *path)
+ {
+     struct ViceIoctl a_params;
+ 
+     a_params.in_size  = 0;
+     a_params.out_size = 0;
+     a_params.in       = NULL;
+     a_params.out      = NULL;
+ 
+     if (pioctl ((char *)path, VIOCFLUSH, &a_params, 0) < 0)
+ 	return errno;
+     else
+ 	return 0;
+ }
+ 
+ /*
+  *
+  */
+ 
+ int
+ fs_venuslog (void)
+ {
+     struct ViceIoctl a_params;
+     int32_t status = 0;   /* XXX not really right, but anyway */
+ 
+     a_params.in_size  = sizeof(int32_t);
+     a_params.out_size = 0;
+     a_params.in       = (caddr_t) &status;
+     a_params.out      = NULL;
+ 
+     if (pioctl (NULL, VIOC_VENUSLOG, &a_params, 0) < 0)
+ 	return errno;
+     else
+ 	return 0;
+ }
+ 
+ /*
+  * Get status for `cell' and put the flags in `flags'.
+  */
+ 
+ int
+ fs_getcellstatus (char *cellname, u_int32_t *flags)
+ {
+     struct ViceIoctl a_params;
+ 
+     a_params.in_size  = strlen (cellname) + 1;
+     a_params.out_size = sizeof (u_int32_t);
+     a_params.in       = cellname;
+     a_params.out      = (caddr_t) flags;
+ 
+     if (pioctl (NULL, VIOC_GETCELLSTATUS, &a_params, 0) < 0)
+ 	return errno;
+     else
+ 	return 0;
+ }
+ 
+ /*
+  * Separate `path' into directory and last component and call
+  * pioctl with `pioctl_cmd'.
+  */
+ 
+ static int
+ internal_mp (const char *path, int pioctl_cmd, char **res)
+ {
+     struct ViceIoctl    a_params;
+     char               *last;
+     char               *path_bkp;
+     int			error;
+ 
+     path_bkp = strdup (path);
+     if (path_bkp == NULL) {
+ 	printf ("fs: Out of memory\n");
+ 	return ENOMEM;
+     }
+ 
+     a_params.out = malloc (PIOCTL_MAXSIZE);
+     if (a_params.out == NULL) {
+ 	printf ("fs: Out of memory\n");
+ 	free (path_bkp);
+ 	return ENOMEM;
+     }
+ 
+     /* If path contains more than the filename alone - split it */
+ 
+     last = strrchr (path_bkp, '/');
+     if (last != NULL) {
+ 	*last = '\0';
+ 	a_params.in = last + 1;
+     } else
+ 	a_params.in = (char *)path;
+ 
+     a_params.in_size = strlen (a_params.in) + 1;
+     a_params.out_size = PIOCTL_MAXSIZE;
+ 
+     error = pioctl (last ? path_bkp : "." ,
+ 		      pioctl_cmd, &a_params, 1);
+     if (error < 0) {
+ 	error = errno;
+ 	free (path_bkp);
+ 	free (a_params.out);
+ 	return error;
+     }
+ 
+     if (res != NULL)
+ 	*res = a_params.out;
+     else
+ 	free (a_params.out);
+     free (path_bkp);
+     return 0;
+ }
+ 
+ int
+ fs_lsmount (const char *path)
+ {
+     char *res;
+     int error = internal_mp (path, VIOC_AFS_STAT_MT_PT, &res);
+ 
+     if (error == 0) {
+ 	printf ("'%s' is a mount point for volume '%s'\n", path, res);
+ 	free (res);
+     }
+     return error;
+ }
+ 
+ int
+ fs_rmmount (const char *path)
+ {
+     return internal_mp (path, VIOC_AFS_DELETE_MT_PT, NULL);
+ }
+ 
+ int
+ fs_incompat_renumber (int *ret)
+ {
+     struct ViceIoctl a_params;
+     unsigned char buf[1024];
+ 
+     a_params.in_size  = 0;
+     a_params.out_size = sizeof(buf);
+     a_params.in       = 0;
+     a_params.out      = (caddr_t) buf;
+ 
+     /* getcrypt or getinitparams */
+     if (pioctl (NULL, _VICEIOCTL(49), &a_params, 0) < 0) {
+ 	if (errno == EINVAL) {
+ 
+ 	    /* not openafs or old openafs */
+ 
+ 	    a_params.in_size  = 0;
+ 	    a_params.out_size = 4;
+ 	    a_params.in       = 0;
+ 	    a_params.out      = (caddr_t) buf;
+ 	    
+ 	    if (pioctl (NULL, _VICEIOCTL(49), &a_params, 0) < 0) {
+ 		if (errno == EINVAL) {
+ 		    
+ 		    a_params.in_size  = 0;
+ 		    a_params.out_size = 4;
+ 		    a_params.in       = 0;
+ 		    a_params.out      = (caddr_t) buf;
+ 		    
+ 		    /* might be new interface */
+ 
+ 		    if (pioctl (NULL, _VICEIOCTL(55), &a_params, 0) < 0)
+ 			return errno; /* dunno */
+ 		    
+ 		    *ret = 1;
+ 		    return 0;
+ 		} else {
+ 		    return errno;
+ 		}
+ 	    }
+ 	    *ret = 0;
+ 	    return 0;
+ 	} else
+ 	    return errno;
+     }
+     *ret = 1;
+     return 0;
+ }
Index: openafs/src/tests/fsx.c
diff -c /dev/null openafs/src/tests/fsx.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/fsx.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,1054 ----
+ /*
+  *	Copyright (C) 1991, NeXT Computer, Inc.  All Rights Reserverd.
+  *
+  *	File:	fsx.c
+  *	Author:	Avadis Tevanian, Jr.
+  *
+  *	File system exerciser. 
+  *
+  *	Rewritten 8/98 by Conrad Minshall.
+  */
+ 
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #if defined(_UWIN) || defined(__linux)
+ # include <sys/param.h>
+ # include <limits.h>
+ # include <time.h>
+ # include <strings.h>
+ # define MAP_FILE 0
+ #else
+ # include <sys/dirent.h>
+ #endif
+ #include <sys/file.h>
+ #include <sys/mman.h>
+ #include <limits.h>
+ #include <err.h>
+ #include <signal.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <unistd.h>
+ #include <stdarg.h>
+ #include <errno.h>
+ 
+ #define NUMPRINTCOLUMNS 32	/* # columns of data to print on each line */
+ 
+ /*
+  *	A log entry is an operation and a bunch of arguments.
+  */
+ 
+ struct log_entry {
+ 	int	operation;
+ 	int	args[3];
+ };
+ 
+ #define	LOGSIZE	1000
+ 
+ struct log_entry	oplog[LOGSIZE];	/* the log */
+ int			logptr = 0;	/* current position in log */
+ int			logcount = 0;	/* total ops */
+ 
+ /*
+  *	Define operations
+  */
+ 
+ #define	OP_READ		1
+ #define OP_WRITE	2
+ #define OP_TRUNCATE	3
+ #define OP_CLOSEOPEN	4
+ #define OP_MAPREAD	5
+ #define OP_MAPWRITE	6
+ #define OP_SKIPPED	7
+ 
+ #ifndef PAGE_SIZE
+ #define PAGE_SIZE       4096
+ #endif
+ #define PAGE_MASK       (PAGE_SIZE - 1)
+ 
+ char	*original_buf;			/* a pointer to the original data */
+ char	*good_buf;			/* a pointer to the correct data */
+ char	*temp_buf;			/* a pointer to the current data */
+ char	*fname;				/* name of our test file */
+ int	fd;				/* fd for our test file */
+ 
+ off_t		file_size = 0;
+ off_t		biggest = 0;
+ char		state[256];
+ unsigned long	testcalls = 0;		/* calls to function "test" */
+ 
+ unsigned long	simulatedopcount = 0;	/* -b flag */
+ int	closeprob = 0;			/* -c flag */
+ int	debug = 0;			/* -d flag */
+ unsigned long	debugstart = 0;		/* -D flag */
+ unsigned long	maxfilelen = 256 * 1024;	/* -l flag */
+ int	sizechecks = 1;			/* -n flag disables them */
+ int	maxoplen = 64 * 1024;		/* -o flag */
+ int	quiet = 0;			/* -q flag */
+ unsigned long progressinterval = 0;	/* -p flag */
+ int	readbdy = 1;			/* -r flag */
+ int	style = 0;			/* -s flag */
+ int	truncbdy = 1;			/* -t flag */
+ int	writebdy = 1;			/* -w flag */
+ long	monitorstart = -1;		/* -m flag */
+ long	monitorend = -1;		/* -m flag */
+ int	lite = 0;			/* -L flag */
+ long	numops = -1;			/* -N flag */
+ int	randomoplen = 1;		/* -O flag disables it */
+ int	seed = 1;			/* -S flag */
+ int     mapped_writes = 1;              /* -W flag disables */
+ int 	mapped_reads = 1;		/* -R flag disables it */
+ int	fsxgoodfd = 0;
+ FILE *	fsxlogf = NULL;
+ int badoff = -1;
+ int closeopen = 0;
+ 
+ 
+ void
+ prt(char *fmt, ...)
+ {
+ 	va_list args;
+ 
+ 	va_start(args, fmt);
+ 	vfprintf(stdout, fmt, args);
+ 	if (fsxlogf)
+ 		vfprintf(fsxlogf, fmt, args);
+ 	va_end(args);
+ }
+ 
+ void
+ prterr(char *prefix)
+ {
+ 	prt("%s%s%s\n", prefix, prefix ? ": " : "", strerror(errno));
+ }
+ 
+ 
+ void
+ log4(int operation, int arg0, int arg1, int arg2)
+ {
+ 	struct log_entry *le;
+ 
+ 	le = &oplog[logptr];
+ 	le->operation = operation;
+ 	if (closeopen)
+ 		le->operation = ~ le->operation;
+ 	le->args[0] = arg0;
+ 	le->args[1] = arg1;
+ 	le->args[2] = arg2;
+ 	logptr++;
+ 	logcount++;
+ 	if (logptr >= LOGSIZE)
+ 		logptr = 0;
+ }
+ 
+ 
+ void
+ logdump(void)
+ {
+ 	int	i, count, down;
+ 	struct log_entry	*lp;
+ 
+ 	prt("LOG DUMP (%d total operations):\n", logcount);
+ 	if (logcount < LOGSIZE) {
+ 		i = 0;
+ 		count = logcount;
+ 	} else {
+ 		i = logptr;
+ 		count = LOGSIZE;
+ 	}
+ 	for ( ; count > 0; count--) {
+ 		int opnum;
+ 
+ 		opnum = i+1 + (logcount/LOGSIZE)*LOGSIZE;
+ 		prt("%d(%d mod 256): ", opnum, opnum%256);
+ 		lp = &oplog[i];
+ 		if ((closeopen = lp->operation < 0))
+ 			lp->operation = ~ lp->operation;
+ 			
+ 		switch (lp->operation) {
+ 		case OP_MAPREAD:
+ 			prt("MAPREAD\t0x%x thru 0x%x\t(0x%x bytes)",
+ 			    lp->args[0], lp->args[0] + lp->args[1] - 1,
+ 			    lp->args[1]);
+ 			if (badoff >= lp->args[0] && badoff <
+ 						     lp->args[0] + lp->args[1])
+ 				prt("\t***RRRR***");
+ 			break;
+ 		case OP_MAPWRITE:
+ 			prt("MAPWRITE 0x%x thru 0x%x\t(0x%x bytes)",
+ 			    lp->args[0], lp->args[0] + lp->args[1] - 1,
+ 			    lp->args[1]);
+ 			if (badoff >= lp->args[0] && badoff <
+ 						     lp->args[0] + lp->args[1])
+ 				prt("\t******WWWW");
+ 			break;
+ 		case OP_READ:
+ 			prt("READ\t0x%x thru 0x%x\t(0x%x bytes)",
+ 			    lp->args[0], lp->args[0] + lp->args[1] - 1,
+ 			    lp->args[1]);
+ 			if (badoff >= lp->args[0] &&
+ 			    badoff < lp->args[0] + lp->args[1])
+ 				prt("\t***RRRR***");
+ 			break;
+ 		case OP_WRITE:
+ 			prt("WRITE\t0x%x thru 0x%x\t(0x%x bytes)",
+ 			    lp->args[0], lp->args[0] + lp->args[1] - 1,
+ 			    lp->args[1]);
+ 			if (lp->args[0] > lp->args[2])
+ 				prt(" HOLE");
+ 			else if (lp->args[0] + lp->args[1] > lp->args[2])
+ 				prt(" EXTEND");
+ 			if ((badoff >= lp->args[0] || badoff >=lp->args[2]) &&
+ 			    badoff < lp->args[0] + lp->args[1])
+ 				prt("\t***WWWW");
+ 			break;
+ 		case OP_TRUNCATE:
+ 			down = lp->args[0] < lp->args[1];
+ 			prt("TRUNCATE %s\tfrom 0x%x to 0x%x",
+ 			    down ? "DOWN" : "UP", lp->args[1], lp->args[0]);
+ 			if (badoff >= lp->args[!down] &&
+ 			    badoff < lp->args[!!down])
+ 				prt("\t******WWWW");
+ 			break;
+ 		case OP_SKIPPED:
+ 			prt("SKIPPED (no operation)");
+ 			break;
+ 		default:
+ 			prt("BOGUS LOG ENTRY (operation code = %d)!",
+ 			    lp->operation);
+ 		}
+ 		if (closeopen)
+ 			prt("\n\t\tCLOSE/OPEN");
+ 		prt("\n");
+ 		i++;
+ 		if (i == LOGSIZE)
+ 			i = 0;
+ 	}
+ }
+ 
+ 
+ void
+ save_buffer(char *buffer, off_t bufferlength, int fd)
+ {
+ 	off_t ret;
+ 	ssize_t byteswritten;
+ 
+ 	if (fd <= 0 || bufferlength == 0)
+ 		return;
+ 
+ 	if (bufferlength > SSIZE_MAX) {
+ 		prt("fsx flaw: overflow in save_buffer\n");
+ 		exit(67);
+ 	}
+ 	if (lite) {
+ 		off_t size_by_seek = lseek(fd, (off_t)0, L_XTND);
+ 		if (size_by_seek == (off_t)-1)
+ 			prterr("save_buffer: lseek eof");
+ 		else if (bufferlength > size_by_seek) {
+ 			warn("save_buffer: .fsxgood file too short... will save 0x%qx bytes instead of 0x%qx\n", (unsigned long long)size_by_seek,
+ 			     (unsigned long long)bufferlength);
+ 			bufferlength = size_by_seek;
+ 		}
+ 	}
+ 
+ 	ret = lseek(fd, (off_t)0, SEEK_SET);
+ 	if (ret == (off_t)-1)
+ 		prterr("save_buffer: lseek 0");
+ 	
+ 	byteswritten = write(fd, buffer, (size_t)bufferlength);
+ 	if (byteswritten != bufferlength) {
+ 		if (byteswritten == -1)
+ 			prterr("save_buffer write");
+ 		else
+ 			warn("save_buffer: short write, 0x%x bytes instead of 0x%qx\n",
+ 			     (unsigned)byteswritten,
+ 			     (unsigned long long)bufferlength);
+ 	}
+ }
+ 
+ 
+ void
+ report_failure(int status)
+ {
+ 	logdump();
+ 	
+ 	if (fsxgoodfd) {
+ 		if (good_buf) {
+ 			save_buffer(good_buf, file_size, fsxgoodfd);
+ 			prt("Correct content saved for comparison\n");
+ 			prt("(maybe hexdump \"%s\" vs \"%s.fsxgood\")\n",
+ 			    fname, fname);
+ 		}
+ 		close(fsxgoodfd);
+ 	}
+ 	exit(status);
+ }
+ 
+ 
+ #define short_at(cp) ((unsigned short)((*((unsigned char *)(cp)) << 8) | \
+ 				        *(((unsigned char *)(cp)) + 1)))
+ 
+ void
+ check_buffers(unsigned offset, unsigned size)
+ {
+ 	unsigned char c, t;
+ 	unsigned i = 0;
+ 	unsigned n = 0;
+ 	unsigned op = 0;
+ 	unsigned bad = 0;
+ 
+ 	if (bcmp(good_buf + offset, temp_buf, size) != 0) {
+ 		prt("READ BAD DATA: offset = 0x%x, size = 0x%x\n",
+ 		    offset, size);
+ 		prt("OFFSET\tGOOD\tBAD\tRANGE\n");
+ 		while (size > 0) {
+ 			c = good_buf[offset];
+ 			t = temp_buf[i];
+ 			if (c != t) {
+ 			        if (n == 0) {
+ 					bad = short_at(&temp_buf[i]);
+ 				        prt("0x%5x\t0x%04x\t0x%04x", offset,
+ 				            short_at(&good_buf[offset]), bad);
+ 					op = temp_buf[offset & 1 ? i+1 : i];
+ 				}
+ 				n++;
+ 				badoff = offset;
+ 			}
+ 			offset++;
+ 			i++;
+ 			size--;
+ 		}
+ 		if (n) {
+ 		        prt("\t0x%5x\n", n);
+ 			if (bad)
+ 				prt("operation# (mod 256) for the bad data may be %u\n", ((unsigned)op & 0xff));
+ 			else
+ 				prt("operation# (mod 256) for the bad data unknown, check HOLE and EXTEND ops\n");
+ 		} else
+ 		        prt("????????????????\n");
+ 		report_failure(110);
+ 	}
+ }
+ 
+ 
+ void
+ check_size(void)
+ {
+ 	struct stat	statbuf;
+ 	off_t	size_by_seek;
+ 
+ 	if (fstat(fd, &statbuf)) {
+ 		prterr("check_size: fstat");
+ 		statbuf.st_size = -1;
+ 	}
+ 	size_by_seek = lseek(fd, (off_t)0, L_XTND);
+ 	if (file_size != statbuf.st_size || file_size != size_by_seek) {
+ 		prt("Size error: expected 0x%qx stat 0x%qx seek 0x%qx\n",
+ 		    (unsigned long long)file_size,
+ 		    (unsigned long long)statbuf.st_size,
+ 		    (unsigned long long)size_by_seek);
+ 		report_failure(120);
+ 	}
+ }
+ 
+ 
+ void
+ check_trunc_hack(void)
+ {
+ 	struct stat statbuf;
+ 
+ 	ftruncate(fd, (off_t)0);
+ 	ftruncate(fd, (off_t)100000);
+ 	fstat(fd, &statbuf);
+ 	if (statbuf.st_size != (off_t)100000) {
+ 		prt("no extend on truncate! not posix!\n");
+ 		exit(130);
+ 	}
+ 	ftruncate(fd, 0);
+ }
+ 
+ 
+ void
+ doread(unsigned offset, unsigned size)
+ {
+ 	off_t ret;
+ 	unsigned iret;
+ 
+ 	offset -= offset % readbdy;
+ 	if (size == 0) {
+ 		if (!quiet && testcalls > simulatedopcount)
+ 			prt("skipping zero size read\n");
+ 		log4(OP_SKIPPED, OP_READ, offset, size);
+ 		return;
+ 	}
+ 	if (size + offset > file_size) {
+ 		if (!quiet && testcalls > simulatedopcount)
+ 			prt("skipping seek/read past end of file\n");
+ 		log4(OP_SKIPPED, OP_READ, offset, size);
+ 		return;
+ 	}
+ 
+ 	log4(OP_READ, offset, size, 0);
+ 
+ 	if (testcalls <= simulatedopcount)
+ 		return;
+ 
+ 	if (!quiet && (progressinterval && testcalls % progressinterval == 0 ||
+ 		       debug &&
+ 		       (monitorstart == -1 ||
+ 			offset + size > monitorstart &&
+ 			(monitorend == -1 || offset <= monitorend))))
+ 		prt("%lu read\t0x%x thru\t0x%x\t(0x%x bytes)\n", testcalls,
+ 		    offset, offset + size - 1, size);
+ 	ret = lseek(fd, (off_t)offset, SEEK_SET);
+ 	if (ret == (off_t)-1) {
+ 		prterr("doread: lseek");
+ 		report_failure(140);
+ 	}
+ 	iret = read(fd, temp_buf, size);
+ 	if (iret != size) {
+ 		if (iret == -1)
+ 			prterr("doread: read");
+ 		else
+ 			prt("short read: 0x%x bytes instead of 0x%x\n",
+ 			    iret, size);
+ 		report_failure(141);
+ 	}
+ 	check_buffers(offset, size);
+ }
+ 
+ 
+ void
+ domapread(unsigned offset, unsigned size)
+ {
+ 	unsigned pg_offset;
+ 	unsigned map_size;
+ 	char    *p;
+ 
+ 	offset -= offset % readbdy;
+ 	if (size == 0) {
+ 		if (!quiet && testcalls > simulatedopcount)
+ 			prt("skipping zero size read\n");
+ 		log4(OP_SKIPPED, OP_MAPREAD, offset, size);
+ 		return;
+ 	}
+ 	if (size + offset > file_size) {
+ 		if (!quiet && testcalls > simulatedopcount)
+ 			prt("skipping seek/read past end of file\n");
+ 		log4(OP_SKIPPED, OP_MAPREAD, offset, size);
+ 		return;
+ 	}
+ 
+ 	log4(OP_MAPREAD, offset, size, 0);
+ 
+ 	if (testcalls <= simulatedopcount)
+ 		return;
+ 
+ 	if (!quiet && (progressinterval && testcalls % progressinterval == 0 ||
+ 		       debug &&
+ 		       (monitorstart == -1 ||
+ 			offset + size > monitorstart &&
+ 			(monitorend == -1 || offset <= monitorend))))
+ 		prt("%lu mapread\t0x%x thru\t0x%x\t(0x%x bytes)\n", testcalls,
+ 		    offset, offset + size - 1, size);
+ 
+ 	pg_offset = offset & PAGE_MASK;
+ 	map_size  = pg_offset + size;
+ 
+ 	if ((p = (char *)mmap(0, map_size, PROT_READ, MAP_FILE, fd,
+ 			      (off_t)(offset - pg_offset))) == (char *)-1) {
+ 	        prterr("domapread: mmap");
+ 		report_failure(190);
+ 	}
+ 	memcpy(temp_buf, p + pg_offset, size);
+ 	if (munmap(p, map_size) != 0) {
+ 		prterr("domapread: munmap");
+ 		report_failure(191);
+ 	}
+ 
+ 	check_buffers(offset, size);
+ }
+ 
+ 
+ void
+ gendata(char *original_buf, char *good_buf, unsigned offset, unsigned size)
+ {
+ 	while (size--) {
+ 		good_buf[offset] = testcalls % 256; 
+ 		if (offset % 2)
+ 			good_buf[offset] += original_buf[offset];
+ 		offset++;
+ 	}
+ }
+ 
+ 
+ void
+ dowrite(unsigned offset, unsigned size)
+ {
+ 	off_t ret;
+ 	unsigned iret;
+ 
+ 	offset -= offset % writebdy;
+ 	if (size == 0) {
+ 		if (!quiet && testcalls > simulatedopcount)
+ 			prt("skipping zero size write\n");
+ 		log4(OP_SKIPPED, OP_WRITE, offset, size);
+ 		return;
+ 	}
+ 
+ 	log4(OP_WRITE, offset, size, file_size);
+ 
+ 	gendata(original_buf, good_buf, offset, size);
+ 	if (file_size < offset + size) {
+ 		if (file_size < offset)
+ 			bzero(good_buf + file_size, offset - file_size);
+ 		file_size = offset + size;
+ 		if (lite) {
+ 			warn("Lite file size bug in fsx!");
+ 			report_failure(149);
+ 		}
+ 	}
+ 
+ 	if (testcalls <= simulatedopcount)
+ 		return;
+ 
+ 	if (!quiet && (progressinterval && testcalls % progressinterval == 0 ||
+ 		       debug &&
+ 		       (monitorstart == -1 ||
+ 			offset + size > monitorstart &&
+ 			(monitorend == -1 || offset <= monitorend))))
+ 		prt("%lu write\t0x%x thru\t0x%x\t(0x%x bytes)\n", testcalls,
+ 		    offset, offset + size - 1, size);
+ 	ret = lseek(fd, (off_t)offset, SEEK_SET);
+ 	if (ret == (off_t)-1) {
+ 		prterr("dowrite: lseek");
+ 		report_failure(150);
+ 	}
+ 	iret = write(fd, good_buf + offset, size);
+ 	if (iret != size) {
+ 		if (iret == -1)
+ 			prterr("dowrite: write");
+ 		else
+ 			prt("short write: 0x%x bytes instead of 0x%x\n",
+ 			    iret, size);
+ 		report_failure(151);
+ 	}
+ }
+ 
+ 
+ void
+ domapwrite(unsigned offset, unsigned size)
+ {
+ 	unsigned pg_offset;
+ 	unsigned map_size;
+ 	off_t    cur_filesize;
+ 	char    *p;
+ 
+ 	offset -= offset % writebdy;
+ 	if (size == 0) {
+ 		if (!quiet && testcalls > simulatedopcount)
+ 			prt("skipping zero size write\n");
+ 		log4(OP_SKIPPED, OP_MAPWRITE, offset, size);
+ 		return;
+ 	}
+ 	cur_filesize = file_size;
+ 
+ 	log4(OP_MAPWRITE, offset, size, 0);
+ 
+ 	gendata(original_buf, good_buf, offset, size);
+ 	if (file_size < offset + size) {
+ 		if (file_size < offset)
+ 			bzero(good_buf + file_size, offset - file_size);
+ 		file_size = offset + size;
+ 		if (lite) {
+ 			warn("Lite file size bug in fsx!");
+ 			report_failure(200);
+ 		}
+ 	}
+ 
+ 	if (testcalls <= simulatedopcount)
+ 		return;
+ 
+ 	if (!quiet && (progressinterval && testcalls % progressinterval == 0 ||
+ 		       debug &&
+ 		       (monitorstart == -1 ||
+ 			offset + size > monitorstart &&
+ 			(monitorend == -1 || offset <= monitorend))))
+ 		prt("%lu mapwrite\t0x%x thru\t0x%x\t(0x%x bytes)\n", testcalls,
+ 		    offset, offset + size - 1, size);
+ 
+ 	if (file_size > cur_filesize) {
+ 	        if (ftruncate(fd, file_size) == -1) {
+ 		        prterr("domapwrite: ftruncate");
+ 			exit(201);
+ 		}
+ 	}
+ 	pg_offset = offset & PAGE_MASK;
+ 	map_size  = pg_offset + size;
+ 
+ 	if ((p = (char *)mmap(0, map_size, PROT_READ | PROT_WRITE,
+ 			      MAP_FILE | MAP_SHARED, fd,
+ 			      (off_t)(offset - pg_offset))) == (char *)-1) {
+ 	        prterr("domapwrite: mmap");
+ 		report_failure(202);
+ 	}
+ 	memcpy(p + pg_offset, good_buf + offset, size);
+ 	if (msync(p, map_size, 0) != 0) {
+ 		prterr("domapwrite: msync");
+ 		report_failure(203);
+ 	}
+ 	if (munmap(p, map_size) != 0) {
+ 		prterr("domapwrite: munmap");
+ 		report_failure(204);
+ 	}
+ }
+ 
+ 
+ void
+ dotruncate(unsigned size)
+ {
+ 	int oldsize = file_size;
+ 
+ 	size -= size % truncbdy;
+ 	if (size > biggest) {
+ 		biggest = size;
+ 		if (!quiet && testcalls > simulatedopcount)
+ 			prt("truncating to largest ever: 0x%x\n", size);
+ 	}
+ 
+ 	log4(OP_TRUNCATE, size, (unsigned)file_size, 0);
+ 
+ 	if (size > file_size)
+ 		bzero(good_buf + file_size, size - file_size);
+ 	file_size = size;
+ 
+ 	if (testcalls <= simulatedopcount)
+ 		return;
+ 	
+ 	if (progressinterval && testcalls % progressinterval == 0 ||
+ 	    debug && (monitorstart == -1 || monitorend == -1 ||
+ 		      size <= monitorend))
+ 		prt("%lu trunc\tfrom 0x%x to 0x%x\n", testcalls, oldsize, size);
+ 	if (ftruncate(fd, (off_t)size) == -1) {
+ 	        prt("ftruncate1: %x\n", size);
+ 		prterr("dotruncate: ftruncate");
+ 		report_failure(160);
+ 	}
+ }
+ 
+ 
+ void
+ writefileimage()
+ {
+ 	ssize_t iret;
+ 
+ 	if (lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1) {
+ 		prterr("writefileimage: lseek");
+ 		report_failure(171);
+ 	}
+ 	iret = write(fd, good_buf, file_size);
+ 	if ((off_t)iret != file_size) {
+ 		if (iret == -1)
+ 			prterr("writefileimage: write");
+ 		else
+ 			prt("short write: 0x%x bytes instead of 0x%qx\n",
+ 			    iret, (unsigned long long)file_size);
+ 		report_failure(172);
+ 	}
+ 	if (lite ? 0 : ftruncate(fd, file_size) == -1) {
+ 	        prt("ftruncate2: %qx\n", (unsigned long long)file_size);
+ 		prterr("writefileimage: ftruncate");
+ 		report_failure(173);
+ 	}
+ }
+ 
+ 
+ void
+ docloseopen(void)
+ { 
+ 	if (testcalls <= simulatedopcount)
+ 		return;
+ 
+ 	if (debug)
+ 		prt("%lu close/open\n", testcalls);
+ 	if (close(fd)) {
+ 		prterr("docloseopen: close");
+ 		report_failure(180);
+ 	}
+ 	fd = open(fname, O_RDWR, 0);
+ 	if (fd < 0) {
+ 		prterr("docloseopen: open");
+ 		report_failure(181);
+ 	}
+ }
+ 
+ 
+ void
+ test(void)
+ {
+ 	unsigned long	offset;
+ 	unsigned long	size = maxoplen;
+ 	unsigned long	rv = random();
+ 	unsigned long	op = rv % (3 + !lite + mapped_writes);
+ 
+         /* turn off the map read if necessary */
+ 
+         if (op == 2 && !mapped_reads)
+             op = 0;
+ 
+ 	if (simulatedopcount > 0 && testcalls == simulatedopcount)
+ 		writefileimage();
+ 
+ 	testcalls++;
+ 
+ 	closeopen = (rv >> 3) < (1 << 28) / closeprob;
+ 
+ 	if (debugstart > 0 && testcalls >= debugstart)
+ 		debug = 1;
+ 
+ 	if (!quiet && testcalls < simulatedopcount && testcalls % 100000 == 0)
+ 		prt("%lu...\n", testcalls);
+ 
+ 	/*
+ 	 * READ:	op = 0
+ 	 * WRITE:	op = 1
+ 	 * MAPREAD:     op = 2
+ 	 * TRUNCATE:	op = 3
+ 	 * MAPWRITE:    op = 3 or 4
+ 	 */
+ 	if (lite ? 0 : op == 3 && (style & 1) == 0) /* vanilla truncate? */
+ 		dotruncate(random() % maxfilelen);
+ 	else {
+ 		if (randomoplen)
+ 			size = random() % (maxoplen+1);
+ 		if (lite ? 0 : op == 3)
+ 			dotruncate(size);
+ 		else {
+ 			offset = random();
+ 			if (op == 1 || op == (lite ? 3 : 4)) {
+ 				offset %= maxfilelen;
+ 				if (offset + size > maxfilelen)
+ 					size = maxfilelen - offset;
+ 				if (op != 1)
+ 					domapwrite(offset, size);
+ 				else
+ 					dowrite(offset, size);
+ 			} else {
+ 				if (file_size)
+ 					offset %= file_size;
+ 				else
+ 					offset = 0;
+ 				if (offset + size > file_size)
+ 					size = file_size - offset;
+ 				if (op != 0)
+ 					domapread(offset, size);
+ 				else
+ 					doread(offset, size);
+ 			}
+ 		}
+ 	}
+ 	if (sizechecks && testcalls > simulatedopcount)
+ 		check_size();
+ 	if (closeopen)
+ 		docloseopen();
+ }
+ 
+ 
+ void
+ cleanup(sig)
+ 	int	sig;
+ {
+ 	if (sig)
+ 		prt("signal %d\n", sig);
+ 	prt("testcalls = %lu\n", testcalls);
+ 	exit(sig);
+ }
+ 
+ 
+ void
+ usage(void)
+ {
+ 	fprintf(stdout, "usage: %s",
+ 		"fsx [-dnqLOW] [-b opnum] [-c Prob] [-l flen] [-m start:end] [-o oplen] [-p progressinterval] [-r readbdy] [-s style] [-t truncbdy] [-w writebdy] [-D startingop] [-N numops] [-P dirpath] [-S seed] fname\n\
+ 	-b opnum: beginning operation number (default 1)\n\
+ 	-c P: 1 in P chance of file close+open at each op (default infinity)\n\
+ 	-d: debug output for all operations\n\
+ 	-l flen: the upper bound on file size (default 262144)\n\
+ 	-m startop:endop: monitor (print debug output) specified byte range (default 0:infinity)\n\
+ 	-n: no verifications of file size\n\
+ 	-o oplen: the upper bound on operation size (default 65536)\n\
+ 	-p progressinterval: debug output at specified operation interval\n\
+ 	-q: quieter operation\n\
+ 	-r readbdy: 4096 would make reads page aligned (default 1)\n\
+ 	-s style: 1 gives smaller truncates (default 0)\n\
+ 	-t truncbdy: 4096 would make truncates page aligned (default 1)\n\
+ 	-w writebdy: 4096 would make writes page aligned (default 1)\n\
+ 	-D startingop: debug output starting at specified operation\n\
+ 	-L: fsxLite - no file creations & no file size changes\n\
+ 	-N numops: total # operations to do (default infinity)\n\
+ 	-O: use oplen (see -o flag) for every op (default random)\n\
+ 	-P: save .fsxlog and .fsxgood files in dirpath (default ./)\n\
+ 	-S seed: for random # generator (default 1) 0 gets timestamp\n\
+ 	-W: mapped write operations DISabled\n\
+         -R: read() system calls only (mapped reads disabled)\n\
+ 	fname: this filename is REQUIRED (no default)\n");
+ 	exit(90);
+ }
+ 
+ 
+ int
+ getnum(char *s, char **e)
+ {
+ 	int ret = -1;
+ 
+ 	*e = (char *) 0;
+ 	ret = strtol(s, e, 0);
+ 	if (*e)
+ 		switch (**e) {
+ 		case 'b':
+ 		case 'B':
+ 			ret *= 512;
+ 			*e = *e + 1;
+ 			break;
+ 		case 'k':
+ 		case 'K':
+ 			ret *= 1024;
+ 			*e = *e + 1;
+ 			break;
+ 		case 'm':
+ 		case 'M':
+ 			ret *= 1024*1024;
+ 			*e = *e + 1;
+ 			break;
+ 		case 'w':
+ 		case 'W':
+ 			ret *= 4;
+ 			*e = *e + 1;
+ 			break;
+ 		}
+ 	return (ret);
+ }
+ 
+ 
+ int
+ main(int argc, char **argv)
+ {
+ 	int	i, style, ch;
+ 	char	*endp;
+ 	char goodfile[1024];
+ 	char logfile[1024];
+ 
+ 	goodfile[0] = 0;
+ 	logfile[0] = 0;
+ 
+ 	setvbuf(stdout, (char *)0, _IOLBF, 0); /* line buffered stdout */
+ 
+ 	while ((ch = getopt(argc, argv, "b:c:dl:m:no:p:qr:s:t:w:D:LN:OP:RS:W"))
+ 	       != EOF)
+ 		switch (ch) {
+ 		case 'b':
+ 			simulatedopcount = getnum(optarg, &endp);
+ 			if (!quiet)
+ 				fprintf(stdout, "Will begin at operation %ld\n",
+ 					simulatedopcount);
+ 			if (simulatedopcount == 0)
+ 				usage();
+ 			simulatedopcount -= 1;
+ 			break;
+ 		case 'c':
+ 			closeprob = getnum(optarg, &endp);
+ 			if (!quiet)
+ 				fprintf(stdout,
+ 					"Chance of close/open is 1 in %d\n",
+ 					closeprob);
+ 			if (closeprob <= 0)
+ 				usage();
+ 			break;
+ 		case 'd':
+ 			debug = 1;
+ 			break;
+ 		case 'l':
+ 			maxfilelen = getnum(optarg, &endp);
+ 			if (maxfilelen <= 0)
+ 				usage();
+ 			break;
+ 		case 'm':
+ 			monitorstart = getnum(optarg, &endp);
+ 			if (monitorstart < 0)
+ 				usage();
+ 			if (!endp || *endp++ != ':')
+ 				usage();
+ 			monitorend = getnum(endp, &endp);
+ 			if (monitorend < 0)
+ 				usage();
+ 			if (monitorend == 0)
+ 				monitorend = -1; /* aka infinity */
+ 			debug = 1;
+ 		case 'n':
+ 			sizechecks = 0;
+ 			break;
+ 		case 'o':
+ 			maxoplen = getnum(optarg, &endp);
+ 			if (maxoplen <= 0)
+ 				usage();
+ 			break;
+ 		case 'p':
+ 			progressinterval = getnum(optarg, &endp);
+ 			if (progressinterval < 0)
+ 				usage();
+ 			break;
+ 		case 'q':
+ 			quiet = 1;
+ 			break;
+ 		case 'r':
+ 			readbdy = getnum(optarg, &endp);
+ 			if (readbdy <= 0)
+ 				usage();
+ 			break;
+ 		case 's':
+ 			style = getnum(optarg, &endp);
+ 			if (style < 0 || style > 1)
+ 				usage();
+ 			break;
+ 		case 't':
+ 			truncbdy = getnum(optarg, &endp);
+ 			if (truncbdy <= 0)
+ 				usage();
+ 			break;
+ 		case 'w':
+ 			writebdy = getnum(optarg, &endp);
+ 			if (writebdy <= 0)
+ 				usage();
+ 			break;
+ 		case 'D':
+ 			debugstart = getnum(optarg, &endp);
+ 			if (debugstart < 1)
+ 				usage();
+ 			break;
+ 		case 'L':
+ 		        lite = 1;
+ 			break;
+ 		case 'N':
+ 			numops = getnum(optarg, &endp);
+ 			if (numops < 0)
+ 				usage();
+ 			break;
+ 		case 'O':
+ 			randomoplen = 0;
+ 			break;
+ 		case 'P':
+ 			strncpy(goodfile, optarg, sizeof(goodfile));
+ 			strcat(goodfile, "/");
+ 			strncpy(logfile, optarg, sizeof(logfile));
+ 			strcat(logfile, "/");
+ 			break;
+                 case 'R':
+                         mapped_reads = 0;
+                         break;
+ 		case 'S':
+                         seed = getnum(optarg, &endp);
+ 			if (seed == 0)
+ 				seed = time(0) % 10000;
+ 			if (!quiet)
+ 				fprintf(stdout, "Seed set to %d\n", seed);
+ 			if (seed < 0)
+ 				usage();
+ 			break;
+ 		case 'W':
+ 		        mapped_writes = 0;
+ 			if (!quiet)
+ 				fprintf(stdout, "mapped writes DISABLED\n");
+ 			break;
+               
+ 		default:
+ 			usage();
+ 			/* NOTREACHED */
+ 		}
+ 	argc -= optind;
+ 	argv += optind;
+ 	if (argc != 1)
+ 		usage();
+ 	fname = argv[0];
+ 
+ 	signal(SIGHUP,	cleanup);
+ 	signal(SIGINT,	cleanup);
+ 	signal(SIGPIPE,	cleanup);
+ 	signal(SIGALRM,	cleanup);
+ 	signal(SIGTERM,	cleanup);
+ 	signal(SIGXCPU,	cleanup);
+ 	signal(SIGXFSZ,	cleanup);
+ 	signal(SIGVTALRM,	cleanup);
+ 	signal(SIGUSR1,	cleanup);
+ 	signal(SIGUSR2,	cleanup);
+ 
+ 	initstate(seed, state, 256);
+ 	setstate(state);
+ 	fd = open(fname, O_RDWR|(lite ? 0 : O_CREAT|O_TRUNC), 0666);
+ 	if (fd < 0) {
+ 		prterr(fname);
+ 		exit(91);
+ 	}
+ 	strncat(goodfile, fname, 256);
+ 	strcat (goodfile, ".fsxgood");
+ 	fsxgoodfd = open(goodfile, O_RDWR|O_CREAT|O_TRUNC, 0666);
+ 	if (fsxgoodfd < 0) {
+ 		prterr(goodfile);
+ 		exit(92);
+ 	}
+ 	strncat(logfile, fname, 256);
+ 	strcat (logfile, ".fsxlog");
+ 	fsxlogf = fopen(logfile, "w");
+ 	if (fsxlogf == NULL) {
+ 		prterr(logfile);
+ 		exit(93);
+ 	}
+ 	if (lite) {
+ 		off_t ret;
+ 		file_size = maxfilelen = lseek(fd, (off_t)0, L_XTND);
+ 		if (file_size == (off_t)-1) {
+ 			prterr(fname);
+ 			warn("main: lseek eof");
+ 			exit(94);
+ 		}
+ 		ret = lseek(fd, (off_t)0, SEEK_SET);
+ 		if (ret == (off_t)-1) {
+ 			prterr(fname);
+ 			warn("main: lseek 0");
+ 			exit(95);
+ 		}
+ 	}
+ 	original_buf = (char *) malloc(maxfilelen);
+ 	for (i = 0; i < maxfilelen; i++)
+ 		original_buf[i] = random() % 256;
+ 	good_buf = (char *) malloc(maxfilelen);
+ 	bzero(good_buf, maxfilelen);
+ 	temp_buf = (char *) malloc(maxoplen);
+ 	bzero(temp_buf, maxoplen);
+ 	if (lite) {	/* zero entire existing file */
+ 		ssize_t written;
+ 
+ 		written = write(fd, good_buf, (size_t)maxfilelen);
+ 		if (written != maxfilelen) {
+ 			if (written == -1) {
+ 				prterr(fname);
+ 				warn("main: error on write");
+ 			} else
+ 				warn("main: short write, 0x%x bytes instead of 0x%x\n",
+ 				     (unsigned)written, maxfilelen);
+ 			exit(98);
+ 		}
+ 	} else 
+ 		check_trunc_hack();
+ 
+ 	while (numops == -1 || numops--)
+ 		test();
+ 
+ 	if (close(fd)) {
+ 		prterr("close");
+ 		report_failure(99);
+ 	}
+ 	prt("All operations completed A-OK!\n");
+ 
+ 	exit(0);
+ 	return 0;
+ }
Index: openafs/src/tests/ga-test.c
diff -c /dev/null openafs/src/tests/ga-test.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/ga-test.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,329 ----
+ /*
+  * Copyright (c) 1999 - 2000 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ /*
+  * Test if agetarg works as expected
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ 
+ #include <err.h>
+ 
+ #include <agetarg.h>
+ 
+ RCSID("$Id: ga-test.c,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $");
+ 
+ typedef struct {
+     int style;
+     int argc;
+     char *argv[10];
+     enum { GA_SUCCESS = 0, GA_FAILURE } retval ;
+ } ga_tests;
+ 
+ 
+ /* XXX TODO: aarg_negative_flag, manualpage generation ? */
+ 
+ /*
+  *
+  */
+ 
+ static void
+ test_simple_string (void)
+ {
+     char *string;
+     int i, optind;
+     ga_tests tests[] = {
+ 	{ AARG_GNUSTYLE, 2, { "string", "--string=foo", NULL } },
+ 	{ AARG_GNUSTYLE, 3, { "string", "-s", "foo", NULL} },
+ 	{ AARG_AFSSTYLE, 3, { "string", "-string", "foo", NULL} },
+ 	{ AARG_AFSSTYLE, 3, { "string", "-strin", "foo", NULL} },
+ 	{ AARG_AFSSTYLE, 3, { "string", "-st", "foo", NULL}, GA_FAILURE },
+ 	{ AARG_AFSSTYLE, 2, { "string", "--flag"}, 		GA_FAILURE },
+ 	{ AARG_AFSSTYLE, 2, { "string", "foo", NULL} }
+     };
+ 
+     struct agetargs args[] = {
+ 	{ "string", 's', aarg_string, NULL,
+ 	  "string test", "stringfoo", aarg_mandatory},
+ 	{ "strip", 0, aarg_string, NULL,
+ 	  "strip test", "stripfoo", aarg_optional},
+ 	{ NULL, 0, aarg_end, NULL, NULL }
+     }, *a = args;
+ 
+     a->value = &string;
+ 
+     for (i = 0 ; i < sizeof(tests)/sizeof(*tests); i++) {
+ 	string = NULL;
+ 	optind = 0;
+ 
+ 	if (agetarg (args, tests[i].argc, tests[i].argv, &optind, 
+ 		    tests[i].style)) {
+ 	    if (tests[i].retval == GA_FAILURE)
+ 		continue;
+ 	    warnx ("test_string: %s failed for test %d",
+ 		   tests[i].argv[1], i);
+ 	    continue;
+ 	} else {
+ 	    if (tests[i].retval != GA_SUCCESS) {
+ 		warnx ("test_string: %s failed to fail for test %d",
+ 		       tests[i].argv[1], i);
+ 		continue;
+ 	    }
+ 	}
+ 	
+ 	if (optind != tests[i].argc) {
+ 	    warnx ("argc != optind for test %s, %d", tests[i].argv[1], i);
+ 	    continue;
+ 	}
+ 
+ 	if (string == NULL || strcmp (string, "foo") != 0) {
+ 	    warnx ("error parsing for test %d: string", i);
+ 	    continue;
+ 	}
+     }
+ }
+ 
+ /*
+  *
+  */
+ 
+ static void
+ test_simple_strings (void)
+ {
+     agetarg_strings strings;
+ 
+     int i, optind;
+     ga_tests tests[] = {
+ 	{ AARG_GNUSTYLE, 3, { "strings", 
+ 			     "--strings=foo", "--strings=bar", NULL } },
+ 	{ AARG_GNUSTYLE, 5, { "strings", "-s", "foo", "-s", "bar", NULL} },
+ 	{ AARG_AFSSTYLE, 4, { "strings", "-string", "foo", "bar", NULL} }
+ #if 0
+ 	{ AARG_AFSSTYLE, 3, { "strings", "foo", "bar", NULL} }
+ #endif
+     };
+ 
+     struct agetargs args[] = {
+ 	{ "strings", 's', aarg_strings, NULL,
+ 	  "strings test", "stringsfoo", aarg_optional},
+ 	{ NULL, 0, aarg_end, NULL, NULL }
+     }, *a = args;
+ 
+     a->value = &strings;
+ 
+     for (i = 0 ; i < sizeof(tests)/sizeof(*tests); i++) {
+ 	strings.num_strings = 0;
+ 	strings.strings = NULL;
+ 	optind = 0;
+ 
+ 	if (agetarg (args, tests[i].argc, tests[i].argv, &optind, 
+ 		    tests[i].style)) {
+ 	    if (tests[i].retval == GA_FAILURE)
+ 		continue;
+ 	    warnx ("test_strings: %s failed for test %d",
+ 		   tests[i].argv[1], i);
+ 	    continue;
+ 	} else {
+ 	    if (tests[i].retval != GA_SUCCESS) {
+ 		warnx ("test_strings: %s failed to fail for test %d",
+ 		       tests[i].argv[1], i);
+ 		continue;
+ 	    }
+ 	}
+ 	
+ 	if (optind != tests[i].argc) {
+ 	    warnx ("argc != optind for test %s, %d",
+ 		   tests[i].argv[1], i);
+ 	    continue;
+ 	}
+ 
+ 	if (strings.num_strings != 2 
+ 	    || strcmp(strings.strings[0], "foo") != 0
+ 	    || strcmp(strings.strings[1], "bar") != 0)
+ 	{
+ 	    warnx ("error parsing for test %d: strings", i);
+ 	    continue;
+ 	}
+     }
+ }
+ 
+ /*
+  *
+  */
+ 
+ static void
+ test_simple_integer (void)
+ {
+     int integer;
+     int i, optind;
+     ga_tests tests[] = {
+ 	{ AARG_GNUSTYLE, 2, { "integer", "--integer=4711", NULL } },
+ 	{ AARG_GNUSTYLE, 3, { "integer", "-i", "4711", NULL} },
+ 	{ AARG_AFSSTYLE, 3, { "integer", "-integer", "4711", NULL} },
+ 	{ AARG_AFSSTYLE, 2, { "integer", "4711", NULL} }
+     };
+ 
+     struct agetargs args[] = {
+ 	{ "integer", 'i', aarg_integer, NULL,
+ 	  "integer test", "integer", aarg_mandatory},
+ 	{ NULL, 0, aarg_end, NULL, NULL }
+     }, *a = args;
+ 
+     a->value = &integer;
+ 
+     for (i = 0 ; i < sizeof(tests)/sizeof(*tests); i++) {
+ 	integer = 0;
+ 	optind = 0;
+ 
+ 	if (agetarg (args, tests[i].argc, tests[i].argv, &optind, 
+ 		    tests[i].style)) {
+ 	    if (tests[i].retval == GA_FAILURE)
+ 		continue;
+ 	    warnx ("test_integer: %s failed for test %d",
+ 		   tests[i].argv[1], i);
+ 	    continue;
+ 	} else {
+ 	    if (tests[i].retval != GA_SUCCESS) {
+ 		warnx ("test_integer: %s failed to fail for test %d",
+ 		       tests[i].argv[1], i);
+ 		continue;
+ 	    }
+ 	}
+ 	
+ 	if (optind != tests[i].argc) {
+ 	    warnx ("argc != optind for test %s, %d",
+ 		   tests[i].argv[1], i);	
+ 	    continue;
+ 	}
+ 
+ 	if (integer != 4711) {
+ 	    warnx ("error parsing for test %d: integer 4711", i);
+ 	    continue;
+ 	}
+     }
+ }
+ 
+ /*
+  *
+  */
+ 
+ static void
+ test_simple_flag (void)
+ {
+     int flag;
+     int i, optind;
+     ga_tests tests[] = {
+ 	{ AARG_GNUSTYLE, 2, { "flag", "--flag=yes", NULL },	GA_SUCCESS },
+ 	{ AARG_GNUSTYLE, 2, { "flag", "-g", NULL},		GA_SUCCESS },
+ 	{ AARG_AFSSTYLE, 2, { "flag", "--flag"}, 		GA_FAILURE },
+ 	{ AARG_AFSSTYLE, 2, { "flag", "-flag", NULL},		GA_SUCCESS },
+ #if 0
+ 	/* XXX */
+ 	{ AARG_AFSSTYLE, 2, { "flag", "yes", NULL},		GA_SUCCESS },
+ #endif
+ 	{ AARG_GNUSTYLE, 2, { "flag", "--no-flag", NULL},	GA_SUCCESS }
+     };
+ 
+     struct agetargs args[] = {
+ 	{ "flag", 'g', aarg_flag, NULL,
+ 	  "flag", "flag bar", aarg_optional},
+ 	{ NULL, 0, aarg_end, NULL, NULL }
+     }, *a = args;
+ 
+     a->value = &flag;
+ 
+     for (i = 0 ; i < sizeof(tests)/sizeof(*tests); i++) {
+ 	if (i < 4)
+ 	    flag = 0;
+ 	else
+ 	    flag = 1;
+ 	optind = 0;
+ 
+ 	if (agetarg (args, tests[i].argc, tests[i].argv, &optind, 
+ 		    tests[i].style)) {
+ 	    if (tests[i].retval == GA_FAILURE)
+ 		continue;
+ 	    warnx ("test_flag: %s failed for test %d",
+ 		   tests[i].argv[1], i);
+ 	    continue;
+ 	} else {
+ 	    if (tests[i].retval != GA_SUCCESS) {
+ 		warnx ("test_flag: %s failed to fail for test %d",
+ 		       tests[i].argv[1], i);
+ 		continue;
+ 	    }
+ 	}
+ 	
+ 	if (optind != tests[i].argc) {
+ 	    warnx ("argc != optind for test %s, %d",
+ 		   tests[i].argv[1], i);
+ 	    continue;
+ 	}
+ 
+ 	if (i < 4) {
+ 	    if (flag == 0) {
+ 		warnx ("error parsing for test %d: flag %s",
+ 		       i,
+ 		       tests[i].argv[1]);
+ 		continue;
+ 	    }
+ 	} else {
+ 	    if (flag != 0) {
+ 		warnx ("error parsing test %d: flag %s",
+ 		       i,
+ 		       tests[i].argv[1]);
+ 		    continue;
+ 	    }
+ 	}
+     }
+ }
+ 
+ /*
+  *
+  */
+ 
+ int
+ main (int argc, char **argv)
+ {
+ 
+     test_simple_string();
+     test_simple_strings();
+     test_simple_integer();
+     test_simple_flag();
+     
+     return 0;
+ }
Index: openafs/src/tests/generic-build
diff -c /dev/null openafs/src/tests/generic-build:1.2.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/generic-build	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,18 ----
+ #!/bin/sh
+ # $Id: generic-build,v 1.2.2.1 2002/01/20 09:18:07 shadow Exp $
+ if test $# -ne 1 -a $# -ne 2; then
+   echo "Usage: $0 file [directory]"
+   exit 1
+ fi
+ filename=$1
+ if test $# -gt 1; then
+   b=$2
+ else
+   b=`basename $filename .tar.gz`
+ fi
+ obj=$b-obj
+ 
+ gzip -dc $filename | tar xvf - >&4 2>&1 || exit 1
+ cd $b || exit 1
+ ./configure >&4 || exit 1
+ make $MAKEFLAGS >&4 || exit 1
Index: openafs/src/tests/getdents-and-unlink1
diff -c /dev/null openafs/src/tests/getdents-and-unlink1:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/getdents-and-unlink1	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,9 ----
+ #!/bin/sh
+ # $Id: getdents-and-unlink1,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ if test "X$FAST" != "X" ; then echo "Not running $0" ;  exit 0 ; fi
+ gzip -dc ${AFSROOT}/stacken.kth.se/ftp/pub/gnu/emacs/emacs-20.7.tar.gz |
+ tar vxf - >&4 2>&1 || exit 1
+ cd emacs-20.7 || exit 1
+ $objdir/kill-softer lisp || exit 1
+ test -d lisp && exit 1
+ exit 0
Index: openafs/src/tests/getdents-and-unlink2
diff -c /dev/null openafs/src/tests/getdents-and-unlink2:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:55 2002
--- openafs/src/tests/getdents-and-unlink2	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,9 ----
+ #!/bin/sh
+ # $Id: getdents-and-unlink2,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ if test "X$FAST" != "X" ; then echo "Not running $0" ;  exit 0 ; fi
+ gzip -dc ${AFSROOT}/stacken.kth.se/ftp/pub/gnu/emacs/emacs-20.7.tar.gz |
+ tar vxf - >&4 2>&1 || exit 1
+ cd emacs-20.7 || exit 1
+ $objdir/rm-rf lisp || exit 1
+ test -d lisp && exit 1
+ exit 0
Index: openafs/src/tests/getdents-and-unlink3
diff -c /dev/null openafs/src/tests/getdents-and-unlink3:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/getdents-and-unlink3	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,9 ----
+ #!/bin/sh
+ # $Id: getdents-and-unlink3,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ if test "X$FAST" != "X" ; then echo "Not running $0" ;  exit 0 ; fi
+ gzip -dc ${AFSROOT}/stacken.kth.se/ftp/pub/gnu/emacs/emacs-20.7.tar.gz |
+ tar vxf - >&4 2>&1 || exit 1
+ cd emacs-20.7 || exit 1
+ $objdir/kill-softly lisp || exit 1
+ test -d lisp && exit 1
+ exit 0
Index: openafs/src/tests/grind-arla-with-cvs
diff -c /dev/null openafs/src/tests/grind-arla-with-cvs:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/grind-arla-with-cvs	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,52 ----
+ #!/bin/sh
+ 
+ if [ x`uname` != xLinux ] ; then
+     echo This test does not run on this architecture
+     exit 1
+ fi
+ 
+ echo '***********************************************************'
+ echo '*                                                         *'
+ echo '*               Infinite run until error                  *'
+ echo '*                                                         *'
+ echo '***********************************************************'
+ sleep 5
+ 
+ # First argument is our working dir
+ test $1 || exit 1
+ mkdir $1
+ cd $1 || exit 1
+ 
+ TOPDIR=$PWD
+ export TOPDIR
+ CVSROOT=/afs/stacken.kth.se/src/SourceRepository
+ export CVSROOT
+ 
+ # test if cvs takes -R
+ cvs -R help 2>&1 | grep Usage: > /dev/null && exit 1
+ 
+ cvs -R checkout arla
+ while true; do
+ 	echo Starting at $TOPDIR
+ 
+ 	cd $TOPDIR || exit 1
+ 	cd arla || exit 1
+ 	cvs -R update -A -d
+ 	sh HACKING
+ 	cd $TOPDIR || exit 1
+ 	mkdir arla-obj
+ 	cd arla-obj || exit 1
+ 	
+ 	../arla/configure && mv xfs/linux/Makefile xfs/linux/Makefile.old && sed 's/ -Werror//g' < xfs/linux/Makefile.old > xfs/linux/Makefile &&  make || exit 1
+ 
+ 	cd $TOPDIR || exit 1
+ 	cd arla || exit 1
+ 	cvs -R update -r arla-0-35-branch -d
+ 	sh HACKING
+ 	cd $TOPDIR || exit 1
+ 	mkdir arla-obj
+ 	cd arla-obj || exit 1
+ 	../arla/configure && mv xfs/linux/Makefile xfs/linux/Makefile.old && sed 's/ -Werror//g' < xfs/linux/Makefile.old > xfs/linux/Makefile &&  make || exit 1
+ done
+ 	
+ 	
Index: openafs/src/tests/hardlink1.c
diff -c /dev/null openafs/src/tests/hardlink1.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/hardlink1.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,149 ----
+ /*
+  * Copyright (c) 1999 - 2000 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <unistd.h>
+ #include <fcntl.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ 
+ #include <err.h>
+ 
+ #ifdef RCSID
+ RCSID("$Id: hardlink1.c,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $");
+ #endif
+ 
+ int
+ main(int argc, char *argv[])
+ {
+     int fd1, fd2;
+     int ret;
+     struct stat sb1, sb2;
+ 
+ 
+     fd1 = open("foo", O_RDWR|O_CREAT, 0666);
+     if (fd1 < 0)
+ 	err (1, "open foo");
+ 
+     ret = fstat (fd1, &sb1);
+     if (ret < 0)
+ 	err (1, "stat foo");
+ 
+     if (sb1.st_nlink != 1)
+ 	errx (1, "foo.st_nlink != 1");
+ 
+     ret = link ("foo", "bar");
+     if (ret < 0)
+ 	err (1, "link foo, bar");
+ 
+     ret = fstat (fd1, &sb1);
+     if (ret < 0)
+ 	err (1, "stat foo");
+ 
+     ret = lstat ("bar", &sb2);
+     if (ret < 0)
+ 	err (1, "stat bar");
+ 
+     if (sb1.st_nlink != 2)
+ 	errx (1, "foo.st_nlink != 2");
+ 
+     if (sb2.st_nlink != 2)
+ 	errx (1, "bar.st_nlink != 2");
+ 
+     if (sb1.st_dev    != sb2.st_dev
+ 	|| sb1.st_ino != sb2.st_ino)
+ 	errx (1, "dev and ino differ");
+ 
+     fd2 = open("bar", O_RDONLY, 0);
+     if (fd2 < 0)
+ 	err (1, "open bar");
+ 
+     ret = fstat (fd2, &sb2);
+     if (ret < 0)
+ 	err (1, "fstat bar");
+     
+     if (sb2.st_nlink != 2)
+ 	errx (1, "bar.st_nlink != 2");
+ 
+     if (write (fd1, "hej", 3) != 3)
+ 	errx (1, "write to foo");
+ 
+     ret = fstat (fd1, &sb1);
+     if (ret < 0)
+ 	err (1, "stat foo");
+ 
+     if (sb1.st_size != 3)
+ 	errx (1, "foo.st_size != 3");
+ 
+     ret = close (fd1);
+     if (ret < 0)
+ 	err (1, "close foo");
+ 
+     ret = fstat (fd2, &sb2);
+     if (ret < 0)
+ 	err (1, "fstat bar");
+ 
+     if (sb2.st_size != 3)
+ 	errx (1, "bar.st_size != 3");
+ 
+     ret = close (fd2);
+     if (ret < 0)
+ 	err (1, "close bar");
+ 
+     if (unlink ("foo") < 0)
+ 	err (1, "unlink foo");
+ 
+     fd2 = open("bar", O_RDONLY, 0);
+     if (fd2 < 0)
+ 	err (1, "open bar");
+ 
+     ret = fstat (fd2, &sb2);
+     if (ret < 0)
+ 	err (1, "fstat bar");
+     
+     if (sb2.st_nlink != 1)
+ 	errx (1, "bar.st_nlink != 1");
+ 
+     ret = close (fd2);
+     if (ret < 0)
+ 	err (1, "close bar");
+ 
+     if (unlink ("bar") < 0)
+ 	err (1, "unlink bar");
+ 
+     return 0;
+ }
Index: openafs/src/tests/hardlink2.c
diff -c /dev/null openafs/src/tests/hardlink2.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/hardlink2.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,71 ----
+ /*
+  * Copyright (c) 1999 - 2000 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <unistd.h>
+ #include <fcntl.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ 
+ #include <err.h>
+ 
+ #ifdef RCSID
+ RCSID("$Id: hardlink2.c,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $");
+ #endif
+ 
+ int
+ main(int argc, char *argv[])
+ {
+     int fd1;
+     int ret;
+     struct stat sb1;
+ 
+ 
+     ret = mkdir ("1", 0777);
+     if (ret < 0)
+ 	err (1, "mkdir 1");
+ 
+     ret = link ("1", "2");
+     if (ret == 0)
+ 	errx (1, "link 1 2 should have failed");
+ 
+     ret = rmdir ("1");
+     if (ret < 0)
+ 	err (1, "rmdir 1");
+ 
+     return 0;
+ }
Index: openafs/src/tests/hardlink3
diff -c /dev/null openafs/src/tests/hardlink3:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/hardlink3	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,28 ----
+ #!/bin/sh
+ # $Id: hardlink3,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ 
+ if test "X$FAST" != "X" ; then echo "Not running $0" ;  exit 0 ; fi
+ 
+ FS=${FS:-${objdir}/../appl/fs/fs}
+ 
+ touch file
+ for i in `awk 'BEGIN {for(i=0; i < 1000; ++i) printf "%d\n", i}' /dev/null`; do
+  ln file file$i
+ done
+ 
+ # now trigger bulkstatus
+ for i in `awk 'BEGIN {for(i=0; i < 1000; ++i) printf "%d\n", i}' /dev/null`; do
+  ls -l file > /dev/null 2>&1 || exit 1
+  ${FS} flush file 
+ done
+ 
+ # just stat them all
+ for i in `awk 'BEGIN {for(i=0; i < 1000; ++i) printf "%d\n", i}' /dev/null`; do
+  ls -l file$i > /dev/null 2>&1  || exit 1
+ done
+ 
+ #clean up
+ for i in `awk 'BEGIN {for(i=0; i < 1000; ++i) printf "%d\n", i}' /dev/null`; do
+  rm file$i > /dev/null 2>&1  || exit 1
+ done
+ rm file
\ No newline at end of file
Index: openafs/src/tests/hardlink4.c
diff -c /dev/null openafs/src/tests/hardlink4.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/hardlink4.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,99 ----
+ /*
+  * Copyright (c) 1999 - 2000 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <unistd.h>
+ #include <fcntl.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ 
+ #include <err.h>
+ 
+ #ifdef RCSID
+ RCSID("$Id: hardlink4.c,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $");
+ #endif
+ 
+ int
+ main(int argc, char *argv[])
+ {
+     int fd1;
+     int ret;
+     struct stat sb1;
+ 
+ 
+     ret = mkdir ("1", 0777);
+     if (ret < 0)
+ 	err (1, "mkdir 1");
+ 
+     ret = mkdir ("2", 0777);
+     if (ret < 0)
+ 	err (1, "mkdir 2");
+ 
+     fd1 = open("1/foo", O_RDWR|O_CREAT, 0666);
+     if (fd1 < 0)
+ 	err (1, "open 1/foo");
+ 
+     ret = fstat (fd1, &sb1);
+     if (ret < 0)
+ 	err (1, "stat foo");
+ 
+     if (sb1.st_nlink != 1)
+ 	errx (1, "foo.st_nlink != 1");
+ 
+     ret = close (fd1);
+     if (ret < 0)
+ 	err (1, "close 1/foo");
+ 
+     ret = link ("1/foo", "2/foo");
+     if (ret == 0)
+ 	unlink ("2/foo");
+     if (ret < 0 && errno != EXDEV)
+ 	err (1, "link 1/foo, 2/foo");
+ 
+     ret = unlink ("1/foo");
+     if (ret < 0)
+ 	err (1, "unlink 1/foo");
+ 
+     ret = rmdir ("1");
+     if (ret < 0)
+ 	err (1, "rmdir 1");
+ 
+     ret = rmdir ("2");
+     if (ret < 0)
+ 	err (1, "rmdir 2");
+     return 0;
+ }
Index: openafs/src/tests/hardlink5
diff -c /dev/null openafs/src/tests/hardlink5:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/hardlink5	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,11 ----
+ #!/bin/sh
+ # $Id: hardlink5,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ 
+ if test "X$FAST" != "X" ; then echo "Not running $0" ;  exit 0 ; fi
+ 
+ FS=${FS:-${objdir}/../appl/fs/fs}
+ 
+ touch file
+ ln file ../../service/file && exit 1
+ rm file
+ 
Index: openafs/src/tests/hello-world.in
diff -c /dev/null openafs/src/tests/hello-world.in:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/hello-world.in	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,8 ----
+ #!/bin/sh
+ # $Id: hello-world.in,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ cat <<FOO > foo.c
+ int main() { return 0; }
+ FOO
+ %CC% -o foo foo.c || exit 1
+ ./foo || exit 1
+ rm -f foo foo.c
Index: openafs/src/tests/int64.c
diff -c /dev/null openafs/src/tests/int64.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/int64.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,407 ----
+ /*
+  * CMUCS AFStools
+  * dumpscan - routines for scanning and manipulating AFS volume dumps
+  *
+  * Copyright (c) 1998 Carnegie Mellon University
+  * All Rights Reserved.
+  * 
+  * Permission to use, copy, modify and distribute this software and its
+  * documentation is hereby granted, provided that both the copyright
+  * notice and this permission notice appear in all copies of the
+  * software, derivative works or modified versions, and any portions
+  * thereof, and that both notices appear in supporting documentation.
+  *
+  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+  *
+  * Carnegie Mellon requests users of this software to return to
+  *
+  *  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
+  *  School of Computer Science
+  *  Carnegie Mellon University
+  *  Pittsburgh PA 15213-3890
+  *
+  * any improvements or extensions that they make and grant Carnegie Mellon
+  * the rights to redistribute these changes.
+  */
+ 
+ /* int64.c - Support for 64-bit integers */
+ 
+ #include <stdio.h>
+ #include <string.h>
+ #include "intNN.h"
+ 
+ char *hexify_int64(u_int64 *X, char *buf)
+ {
+   static char mybuf[17];
+ 
+ #ifdef NATIVE_INT64
+   char c, *p;
+   u_int64 x = *X;
+ 
+   if (!buf) buf = mybuf;
+   p = buf + 16;
+   *p-- = 0;
+   while (x && p >= buf) {
+     c = x & 0xf;
+     c += ((c < 10) ? '0' : 'a' - 10);
+     *p-- = c;
+     x >>= 4;
+   }
+   while (p >= buf) *p-- = '0';
+ 
+ #else
+   if (!buf) buf = mybuf;
+   sprintf(buf, "%08lx%08lx", X->hi, X->lo);
+ #endif
+ 
+   return buf;
+ }
+ 
+ 
+ #ifdef NATIVE_INT64
+ char *decimate_int64(u_int64 *X, char *buf)
+ {
+   static char mybuf[21];
+   char *p;
+   u_int64 x = *X;
+ 
+   if (!buf) buf = mybuf;
+   p = buf + 21;
+   *--p = 0;
+   while (x && p > buf) {
+     *--p = ((x % 10) + '0');
+     x /= 10;
+   }
+   if (!*p) *--p = '0';
+   return p;
+ }
+ 
+ #else
+ static char bitvals[64][21] = {
+ /*                1 */ "00000000000000000001",
+ /*                2 */ "00000000000000000002",
+ /*                4 */ "00000000000000000004",
+ /*                8 */ "00000000000000000008",
+ /*               10 */ "00000000000000000016",
+ /*               20 */ "00000000000000000032",
+ /*               40 */ "00000000000000000064",
+ /*               80 */ "00000000000000000128",
+ /*              100 */ "00000000000000000256",
+ /*              200 */ "00000000000000000512",
+ /*              400 */ "00000000000000001024",
+ /*              800 */ "00000000000000002048",
+ /*             1000 */ "00000000000000004096",
+ /*             2000 */ "00000000000000008192",
+ /*             4000 */ "00000000000000016384",
+ /*             8000 */ "00000000000000032768",
+ /*            10000 */ "00000000000000065536",
+ /*            20000 */ "00000000000000131072",
+ /*            40000 */ "00000000000000262144",
+ /*            80000 */ "00000000000000524288",
+ /*           100000 */ "00000000000001048576",
+ /*           200000 */ "00000000000002097152",
+ /*           400000 */ "00000000000004194304",
+ /*           800000 */ "00000000000008388608",
+ /*          1000000 */ "00000000000016777216",
+ /*          2000000 */ "00000000000033554432",
+ /*          4000000 */ "00000000000067108864",
+ /*          8000000 */ "00000000000134217728",
+ /*         10000000 */ "00000000000268435456",
+ /*         20000000 */ "00000000000536870912",
+ /*         40000000 */ "00000000001073741824",
+ /*         80000000 */ "00000000002147483648",
+ /*        100000000 */ "00000000004294967296",
+ /*        200000000 */ "00000000008589934592",
+ /*        400000000 */ "00000000017179869184",
+ /*        800000000 */ "00000000034359738368",
+ /*       1000000000 */ "00000000068719476736",
+ /*       2000000000 */ "00000000137438953472",
+ /*       4000000000 */ "00000000274877906944",
+ /*       8000000000 */ "00000000549755813888",
+ /*      10000000000 */ "00000001099511627776",
+ /*      20000000000 */ "00000002199023255552",
+ /*      40000000000 */ "00000004398046511104",
+ /*      80000000000 */ "00000008796093022208",
+ /*     100000000000 */ "00000017592186044416",
+ /*     200000000000 */ "00000035184372088832",
+ /*     400000000000 */ "00000070368744177664",
+ /*     800000000000 */ "00000140737488355328",
+ /*    1000000000000 */ "00000281474976710656",
+ /*    2000000000000 */ "00000562949953421312",
+ /*    4000000000000 */ "00001125899906842624",
+ /*    8000000000000 */ "00002251799813685248",
+ /*   10000000000000 */ "00004503599627370496",
+ /*   20000000000000 */ "00009007199254740992",
+ /*   40000000000000 */ "00018014398509481984",
+ /*   80000000000000 */ "00036028797018963968",
+ /*  100000000000000 */ "00072057594037927936",
+ /*  200000000000000 */ "00144115188075855872",
+ /*  400000000000000 */ "00288230376151711744",
+ /*  800000000000000 */ "00576460752303423488",
+ /* 1000000000000000 */ "01152921504606846976",
+ /* 2000000000000000 */ "02305843009213693952",
+ /* 4000000000000000 */ "04611686018427387904",
+ /* 8000000000000000 */ "09223372036854775808" };
+ 
+ 
+ static void prep_table(void)
+ {
+   int bit, digit;
+ 
+   if (bitvals[0][0] < '0') return;
+   for (bit = 0; bit < 64; bit++)
+     for (digit = 0; digit < 20; digit++)
+       bitvals[bit][digit] -= '0';
+ }
+ 
+ 
+ static void add_bit(int bit, char *answer)
+ {
+   int digit;
+ 
+   for (digit = 19; digit >= 0; digit--) {
+     answer[digit] += bitvals[bit][digit];
+     if (!digit) break;
+     while(answer[digit] > 9) {
+       answer[digit] -= 10;
+       answer[digit-1]++;
+     }
+   }
+ }
+ 
+ 
+ static void decimate(unsigned long hi, unsigned long lo, char *answer)
+ {
+   unsigned long mask;
+   int bit, digit;
+ 
+   memset(answer, 0, 21);
+   for (bit = 0, mask = 1; bit < 32; bit++, mask <<= 1)
+     if (lo&mask) add_bit(bit, answer);
+   for (bit = 0, mask = 1; bit < 32; bit++, mask <<= 1)
+     if (hi&mask) add_bit(bit + 32, answer);
+ 
+   for (digit = 0; digit < 20; digit++)
+     answer[digit] += '0';
+ }
+ 
+ char *decimate_int64(u_int64 *X, char *buf)
+ {
+   static char mybuf[21];
+   char *p;
+ 
+   prep_table();
+   if (!buf) buf = mybuf;
+   decimate(X->hi, X->lo, buf);
+   for (p = buf; *p == '0'; p++);
+   return (*p) ? p : p-1;
+ }
+ 
+ #endif /* NATIVE_INT64 */
+ 
+ 
+ void shift_int64(u_int64 *X, int bits)
+ {
+ #ifdef NATIVE_INT64
+   if (bits < 0) *X >>= (-bits);
+   else          *X <<= bits;
+ #else
+   if (bits < 0) {
+     bits = -bits;
+     if (bits >= 32) {
+       X->lo = ((X->hi & 0xffffffffL) >> (bits - 32));
+       X->hi = 0;
+     } else {
+       X->lo = ((X->lo & 0xffffffffL) >> bits)
+             | ((X->hi & ((1 << (32 - bits)) - 1)) << (32 - bits));
+       X->hi = ((X->hi & 0xffffffffL) >> bits);
+     }
+   } else {
+     if (bits >= 32) {
+       X->hi = ((X->lo & 0xffffffffL) << (bits - 32));
+       X->lo = 0;
+     } else {
+       X->hi = ((X->hi & 0xffffffffL) << bits)
+             | ((X->lo & (((1 << bits) - 1) << (32 - bits))) >> (32 - bits));
+       X->lo = ((X->lo & 0xffffffffL) << bits);
+     }
+   }
+ #endif
+ }
+ 
+ 
+ #ifdef TEST_INT64
+ 
+ /** the rest of this is for testing the int64 suite **/
+ 
+ #ifdef NATIVE_INT64
+ 
+ #define xize(x) #x
+ #define stringize(x) xize(x)
+ #define INT64_NAME stringize(unsigned NATIVE_INT64)
+ 
+ 
+ #endif /* NATIVE_INT64 */
+ 
+ 
+ void verify_int64_size () {
+ #ifdef NATIVE_INT64
+   signed char testchar = -1;
+   unsigned int testint = (unsigned char)testchar;
+ 
+   printf("We think '%s' is a native 64-bit type\n", INT64_NAME);
+ 
+   if (testint != 0xff) {
+     printf("testint = 0x%x; should be 0xff\n", testint);
+     fprintf(stderr, "Hmm...  char's are not 8 bits.  That sucks!\n");
+     exit(-1);
+   }
+   printf("Looks like a char is 8 bits...\n");
+ 
+   if (sizeof(unsigned NATIVE_INT64) != 8) {
+     printf("sizeof(%s) = %d; should be 8\n", INT64_NAME, sizeof(unsigned NATIVE_INT64));
+     fprintf(stderr, "Hey!  You said a %s was 64-bits wide!\n", INT64_NAME);
+     exit(-1);
+   }
+   printf("Yippee!  We have a native 64-bit type (%s)\n\n", INT64_NAME);
+ 
+ #else /* !NATIVE_INT64 */
+ 
+   printf("Using fake 64-bit integers...\n\n");
+ #endif /* NATIVE_INT64 */
+ }
+ 
+ 
+ void test_int64_constructs(void)
+ {
+   u_int64 x, y;
+   afs_uint32 hi, lo;
+   int failures = 0, pass;
+   char buf[17];
+ 
+   printf("Constructor/accessor tests:\n");
+   printf("Setting x := %s\n", INT64_TEST_STR);
+   mk64(x, INT64_TEST_HI, INT64_TEST_LO);
+ 
+ #ifdef NATIVE_INT64
+   pass = (x == INT64_TEST_CONST);
+   hexify_int64(&x, buf);
+   printf("NATIVE mk64: x       = 0x%16s                %s\n",
+          buf, pass ? "PASSED" : "FAILED");
+   if (!pass) failures++;
+ #else
+   pass = (x.hi == INT64_TEST_HI && x.lo == INT64_TEST_LO);
+   printf("FAKE mk64:   x.hi    = 0x%08lx  x.lo    = 0x%08lx  %s\n",
+          x.hi, x.lo, pass ? "PASSED" : "FAILED");
+   if (!pass) failures++;
+ #endif
+ 
+   pass = (hi64(x) == INT64_TEST_HI && lo64(x) == INT64_TEST_LO);
+   printf("hi64/lo64:   hi64(x) = 0x%08lx  lo64(x) = 0x%08lx  %s\n",
+          hi64(x), lo64(x), pass ? "PASSED" : "FAILED");
+   if (!pass) failures++;
+ 
+   ex64(x, hi, lo);
+   pass = (hi == INT64_TEST_HI && lo == INT64_TEST_LO);
+   printf("ex64:        hi      = 0x%08lx  lo      = 0x%08lx  %s\n",
+          hi, lo, pass ? "PASSED" : "FAILED");
+   if (!pass) failures++;
+ 
+   cp64(y, x);
+   pass = (hi64(y) == INT64_TEST_HI && lo64(y) == INT64_TEST_LO);
+   printf("cp64:        hi64(y) = 0x%08lx  lo64(y) = 0x%08lx  %s\n",
+          hi64(y), lo64(y), pass ? "PASSED" : "FAILED");
+   if (!pass) failures++;
+ 
+   if (failures) printf("%d/4 tests FAILED\n\n", failures);
+   else          printf("All 4 tests PASSED\n\n");
+ }
+ 
+ 
+ void test_int64_compares()
+ {
+ #define NCOMPARE 9
+   u_int64 control, test[NCOMPARE];
+   char cbuf[17], tbuf[17];
+   int i, r, result[NCOMPARE];
+   int pass, failures, FAILURES = 0;
+ 
+   printf("Comparison tests:\n");
+ 
+   mk64(control, 0x12345678, 0xabcdabcd);
+   mk64(test[0], 0x12340000, 0xabcd0000);  result[0] = +1;
+   mk64(test[1], 0x12340000, 0xabcdabcd);  result[1] = +1;
+   mk64(test[2], 0x12340000, 0xabcdffff);  result[2] = +1;
+   mk64(test[3], 0x12345678, 0xabcd0000);  result[3] = +1;
+   mk64(test[4], 0x12345678, 0xabcdabcd);  result[4] =  0;
+   mk64(test[5], 0x12345678, 0xabcdffff);  result[5] = -1;
+   mk64(test[6], 0x1234ffff, 0xabcd0000);  result[6] = -1;
+   mk64(test[7], 0x1234ffff, 0xabcdabcd);  result[7] = -1;
+   mk64(test[8], 0x1234ffff, 0xabcdffff);  result[8] = -1;
+ 
+   for (i = 0; i < NCOMPARE; i++) {
+     failures = 0;
+     hexify_int64(&control, cbuf);
+     hexify_int64(&test[i], tbuf);
+ 
+     r = eq64(control, test[i]);
+     pass = (r == (result[i] == 0));   if (!pass) failures++;
+     printf("0x%s == 0x%s %s\n", cbuf, tbuf, pass ? "PASSED" : "FAILED");
+ 
+     r = ne64(control, test[i]);
+     pass = (r == (result[i] != 0));   if (!pass) failures++;
+     printf("0x%s != 0x%s %s\n", cbuf, tbuf, pass ? "PASSED" : "FAILED");
+ 
+     r = lt64(control, test[i]);
+     pass = (r == (result[i] <  0));   if (!pass) failures++;
+     printf("0x%s <  0x%s %s\n", cbuf, tbuf, pass ? "PASSED" : "FAILED");
+ 
+     r = le64(control, test[i]);
+     pass = (r == (result[i] <= 0));   if (!pass) failures++;
+     printf("0x%s <= 0x%s %s\n", cbuf, tbuf, pass ? "PASSED" : "FAILED");
+ 
+     r = gt64(control, test[i]);
+     pass = (r == (result[i] >  0));   if (!pass) failures++;
+     printf("0x%s >  0x%s %s\n", cbuf, tbuf, pass ? "PASSED" : "FAILED");
+ 
+     r = ge64(control, test[i]);
+     pass = (r == (result[i] >= 0));   if (!pass) failures++;
+     printf("0x%s >= 0x%s %s\n", cbuf, tbuf, pass ? "PASSED" : "FAILED");
+ 
+     r = zero64(test[i]);
+     pass = !r;                        if (!pass) failures++;
+     printf("0x%s is nonzero            %s\n",
+            tbuf, pass ? "PASSED" : "FAILED");
+ 
+     if (failures) printf("%d/7 tests on this pair FAILED\n\n", failures);
+     else          printf("All 7 tests on this pair PASSED\n\n");
+   }
+ 
+   mk64(control, 0, 0);
+   pass = zero64(control);  if (!pass) FAILURES++;
+   printf("0x0000000000000000 is zero               %s\n",
+          pass ? "PASSED" : "FAILED");
+   
+   if (FAILURES)
+     printf("%d/%d comparison tests FAILED\n\n", FAILURES, 7 * NCOMPARE + 1);
+   else
+     printf("All %d comparison tests PASSED\n\n", 7 * NCOMPARE + 1);
+ }
+ 
+ 
+ void test_int64_arith()
+ {
+   printf("No arithmetic tests yet!!!\n");
+ }
+ 
+ 
+ void main() {
+   verify_int64_size();
+   test_int64_constructs();
+   test_int64_compares();
+   test_int64_arith();
+   exit(0);
+ }
+ #endif
Index: openafs/src/tests/intNN.h
diff -c /dev/null openafs/src/tests/intNN.h:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/intNN.h	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,155 ----
+ /*
+  * CMUCS AFStools
+  * dumpscan - routines for scanning and manipulating AFS volume dumps
+  *
+  * Copyright (c) 1998 Carnegie Mellon University
+  * All Rights Reserved.
+  * 
+  * Permission to use, copy, modify and distribute this software and its
+  * documentation is hereby granted, provided that both the copyright
+  * notice and this permission notice appear in all copies of the
+  * software, derivative works or modified versions, and any portions
+  * thereof, and that both notices appear in supporting documentation.
+  *
+  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+  *
+  * Carnegie Mellon requests users of this software to return to
+  *
+  *  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
+  *  School of Computer Science
+  *  Carnegie Mellon University
+  *  Pittsburgh PA 15213-3890
+  *
+  * any improvements or extensions that they make and grant Carnegie Mellon
+  * the rights to redistribute these changes.
+  */
+ 
+ #ifndef _INTNN_H_
+ #define _INTNN_H_
+ 
+ /* intNN.h - Sized integer types */
+ #include <afs/stds.h>
+ #if 0
+ typedef short afs_int16;
+ typedef unsigned short afs_uint16;
+ 
+ typedef long afs_int32;
+ typedef unsigned long afs_uint32;
+ #endif
+ 
+ 
+ /* Support for 64-bit integers.
+  * Presently, only unsigned 64-bit numbers are supported.
+  */
+ #define INT64_TEST_STR "0x12345678fedcba98"
+ #define INT64_TEST_HI  0x12345678
+ #define INT64_TEST_LO  0xfedcba98
+ 
+ 
+ #ifdef NATIVE_INT64
+ typedef unsigned NATIVE_INT64 u_int64;
+ 
+ /* construct/extract/assign */
+ #define mk64(X,H,L) ((X) = ( ((u_int64)(H) << 32) \
+                            | ((u_int64)(L) & 0xffffffff)))
+ #define hi64(Y)     ((afs_uint32)(((Y) >> 32) & 0xffffffff))
+ #define lo64(Y)     ((afs_uint32)((Y) & 0xffffffff))
+ #define ex64(Y,H,L) ((H) = hi64(Y), (L) = lo64(Y))
+ #define cp64(X,Y)   ((X) = (Y))
+ #define get64(X)    (X)
+ #define set64(X,V)  ((X) = (V))
+ 
+ /* Comparison */
+ #define eq64(X,Y)   ((X) == (Y))
+ #define ne64(X,Y)   ((X) != (Y))
+ #define lt64(X,Y)   ((X) <  (Y))
+ #define le64(X,Y)   ((X) <= (Y))
+ #define gt64(X,Y)   ((X) >  (Y))
+ #define ge64(X,Y)   ((X) >= (Y))
+ #define zero64(X)   (!(X))
+ 
+ /* Arithmetic */
+ #define add64_32(X,A,B) ((X) = (A) + (u_int64)(B))
+ #define add64_64(X,A,B) ((X) = (A) + (B))
+ #define sub64_32(X,A,B) ((X) = (A) - (u_int64)(B))
+ #define sub64_64(X,A,B) ((X) = (A) - (B))
+ 
+ /* Byte-order */
+ #ifdef WORDS_BIGENDIAN
+ #define hton64(X,Y) cp64(X,Y)
+ #define ntoh64(X,Y) cp64(X,Y)
+ #else
+ #define hton64(X,Y) mk64(X,htonl(lo64(Y)),htonl(hi64(Y)))
+ #define ntoh64(X,Y) mk64(X,ntohl(lo64(Y)),ntohl(hi64(Y)))
+ #endif
+ 
+ #else /* !NATIVE_INT64 */
+ /** We have to provide our own 64-bit integers **/
+ typedef struct { afs_uint32 hi, lo; } u_int64;
+ 
+ /* construct/extract/assign */
+ #define mk64(X,H,L) ((X).hi = (H), (X).lo = (L))
+ #define ex64(Y,H,L) ((H) = (Y).hi, (L) = (Y).lo)
+ #define hi64(Y)     ((Y).hi)
+ #define lo64(Y)     ((Y).lo)
+ #define cp64(X,Y)   ((X).hi = (Y).hi, (X).lo = (Y).lo)
+ #define get64(X)    ((X).lo)
+ #define set64(X,V)  ((X).hi = 0, (X).lo = (V))
+ 
+ /* Comparison */
+ #define eq64(A,B) ((A).hi == (B).hi && (A).lo == (B).lo)
+ #define ne64(A,B) ((A).hi != (B).hi || (A).lo != (B).lo)
+ #define lt64(A,B) ((A).hi <  (B).hi || ((A).hi == (B).hi && (A).lo <  (B).lo))
+ #define le64(A,B) ((A).hi <  (B).hi || ((A).hi == (B).hi && (A).lo <= (B).lo))
+ #define gt64(A,B) ((A).hi >  (B).hi || ((A).hi == (B).hi && (A).lo >  (B).lo))
+ #define ge64(A,B) ((A).hi >  (B).hi || ((A).hi == (B).hi && (A).lo >= (B).lo))
+ #define zero64(X) ((X).hi == 0 && (X).lo == 0)
+ 
+ /* Arithmetic */
+ #define add64_32(X,A,B) (                                              \
+   (X).lo = (A).lo + (B),                                               \
+   (X).hi = (A).hi +                                                    \
+    (((((A).lo & 0x80000000) ^  ((B) & 0x80000000)) && !((X).lo & 0x80000000)) \
+   || (((A).lo & 0x80000000) && ((B) & 0x80000000)))                     \
+   )
+ #define add64_64(X,A,B) (add64_32(X,A,(B).lo), (X).hi += (B).hi)
+ 
+ #define sub64_32(X,A,B) ((X).lo = (A).lo - (B), \
+                          (X).hi = (A).hi - ((A).lo < (B)))
+ #define sub64_64(X,A,B) (sub64_32(X,A,(B).lo), (X).hi -= (B).hi)
+ 
+ /* Byte-order */
+ #define hton64(X,Y) mk64(X,htonl(hi64(Y)),htonl(lo64(Y)))
+ #define ntoh64(X,Y) mk64(X,ntohl(hi64(Y)),ntohl(lo64(Y)))
+ 
+ #endif /* NATIVE_INT64 */
+ 
+ 
+ /* The following are too complex to be macros: */
+ 
+ /* char *hexify_int64(u_int64 a, char *buf)
+  * Produces an ASCII representation of a in hexadecimal, and returns
+  * a pointer to the resulting string.  If buf is non-NULL, it is taken
+  * to be a pointer to the buffer to be used, which must be at least 17
+  * bytes long.  This function is thread-safe iff buf is provided.
+  */
+ extern char *hexify_int64(u_int64 *, char *);
+ 
+ /* char *decimate_int64(u_int64 a, char *buf)
+  * Produces an ASCII representation of a in decimal, and returns
+  * a pointer to the resulting string.  If buf is non-NULL, it is taken
+  * to be a pointer to the buffer to be used, which must be at least 21
+  * bytes long.  This function is thread-safe iff buf is provided.
+  */
+ extern char *decimate_int64(u_int64 *, char *);
+ 
+ /* void shift_int64(u_int64 a, int bits)
+  * Shifts the 64-bit integer in a by the specified number of bits.
+  * If bits is positive, the shift is to the left; if negative, the
+  * shift is to the right.
+  */
+ extern void shift_int64(u_int64 *, int);
+ 
+ #endif /* _INTNN_H_ */
Index: openafs/src/tests/internal.h
diff -c /dev/null openafs/src/tests/internal.h:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/internal.h	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,55 ----
+ /*
+  * CMUCS AFStools
+  * dumpscan - routines for scanning and manipulating AFS volume dumps
+  *
+  * Copyright (c) 1998 Carnegie Mellon University
+  * All Rights Reserved.
+  * 
+  * Permission to use, copy, modify and distribute this software and its
+  * documentation is hereby granted, provided that both the copyright
+  * notice and this permission notice appear in all copies of the
+  * software, derivative works or modified versions, and any portions
+  * thereof, and that both notices appear in supporting documentation.
+  *
+  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+  *
+  * Carnegie Mellon requests users of this software to return to
+  *
+  *  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
+  *  School of Computer Science
+  *  Carnegie Mellon University
+  *  Pittsburgh PA 15213-3890
+  *
+  * any improvements or extensions that they make and grant Carnegie Mellon
+  * the rights to redistribute these changes.
+  */
+ 
+ /* internal.h - Routines for internal use only */
+ 
+ #include "xfiles.h"
+ #include "dumpscan.h"
+ 
+ 
+ /* parsevol.c - Routines to parse volume headers */
+ extern afs_uint32 parse_volhdr(XFILE *, unsigned char *, tagged_field *, afs_uint32,
+                             tag_parse_info *, void *, void *);
+ 
+ /* parsevnode.c - Routines to parse vnodes and their fields */
+ extern afs_uint32 parse_vnode(XFILE *, unsigned char *, tagged_field *, afs_uint32,
+                            tag_parse_info *, void *, void *);
+ 
+ /* directory.c - Routines for parsing AFS directories */
+ extern afs_uint32 parse_directory(XFILE *, dump_parser *, afs_vnode *,
+                                afs_uint32, int);
+ 
+ /* backuphdr.c - Generic support for backup system headers */
+ extern afs_uint32 try_backuphdr(XFILE *X, unsigned char *tag, tagged_field *field,
+                              afs_uint32 value, tag_parse_info *pi,
+                              void *g_refcon, void *l_refcon);
+ 
+ /* util.c - Random utilities */
+ extern afs_uint32 handle_return(int, XFILE *, unsigned char, dump_parser *);
+ extern void prep_pi(dump_parser *, tag_parse_info *);
+ extern afs_uint32 match_next_vnode(XFILE *, dump_parser *, u_int64 *, afs_uint32);
Index: openafs/src/tests/intr-read.c
diff -c /dev/null openafs/src/tests/intr-read.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/intr-read.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,128 ----
+ /*
+  * Copyright (c) 2001 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <signal.h>
+ #include <errno.h>
+ #include <dirent.h>
+ 
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ 
+ 
+ #include <err.h>
+ 
+ #define RETSIGTYPE void
+ #ifndef MAXPATHLEN
+ #ifdef PATH_MAX
+ #define MAXPATHLEN PATH_MAX
+ #else
+ #define MAXPATHLEN 4096
+ #endif
+ #endif
+ 
+ static sig_atomic_t set_alarm = 1;
+ 
+ static RETSIGTYPE
+ sigalrm(int foo)
+ {
+     signal(SIGALRM, sigalrm);
+     set_alarm = 1;
+ }
+ 
+ static void
+ try_read(const char *filename)
+ {
+     int fd;
+ 
+     fd = open(filename, O_RDONLY);
+     if (fd < 0) {
+ 	if (errno == EINTR)
+ 	    err(1, "open %s was interrupted", filename);
+     } else {
+ 	close(fd);
+     }
+ }
+ 
+ static void
+ find(const char *dirname)
+ {
+     DIR *dir;
+     struct dirent *dp;
+ 
+     dir = opendir(dirname);
+     if (dir == NULL)
+ 	err (1, "opendir %s", dirname);
+     while ((dp = readdir(dir)) != NULL) {
+ 	char fname[MAXPATHLEN];
+ 	struct stat sb;
+ 
+ 	if (set_alarm) {
+ 	    alarm(1);
+ 	    set_alarm = 0;
+ 	}
+ 	if (strcmp (dp->d_name, ".") == 0
+ 	    || strcmp (dp->d_name, "..") == 0)
+ 	    continue;
+ 	snprintf(fname, sizeof(fname), "%s/%s", dirname, dp->d_name);
+ 	if (lstat(fname, &sb) < 0)
+ 	    err(1, "stat %s", fname);
+ 	if (S_ISDIR(sb.st_mode))
+ 	  find(fname);
+ 	else
+ 	  try_read(fname);
+     }
+     closedir(dir);
+ }
+ 
+ int
+ main(int argc, char **argv)
+ {
+     struct sigaction sa;
+ 
+     sa.sa_handler = sigalrm;
+     sigfillset(&sa.sa_mask);
+     sa.sa_flags   = 0;
+     sigaction(SIGALRM, &sa, NULL);
+     while (--argc)
+ 	find(*++argv);
+     return 0;
+ }
Index: openafs/src/tests/intr-read1
diff -c /dev/null openafs/src/tests/intr-read1:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/intr-read1	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,4 ----
+ #!/bin/sh
+ # $Id: intr-read1,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ $objdir/intr-read ${AFSROOT}/stacken.kth.se/ftp/pub/gnu/gnu-0.2 || exit 1
+ exit 0
Index: openafs/src/tests/invalidate-file.c
diff -c /dev/null openafs/src/tests/invalidate-file.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/invalidate-file.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,202 ----
+ /*
+  * Copyright (c) 2000 - 2001 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <sys/types.h>
+ #include <sys/mman.h>
+ #include <sys/stat.h>
+ 
+ #include <unistd.h>
+ #include <fcntl.h>
+ 
+ #include <atypes.h>
+ 
+ #include <kafs.h>
+ 
+ #include <fs.h>
+ #include <arlalib.h>
+ 
+ #include <err.h>
+ 
+ RCSID("$Id: invalidate-file.c,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $");
+ 
+ #ifndef MAP_FAILED
+ #define MAP_FAILED ((void *)-1)
+ #endif
+ 
+ #ifdef KERBEROS
+ 
+ static void
+ create_write_file (char *filename)
+ {
+     int ret;
+     int fd;
+ 
+     fs_invalidate (filename);
+ 
+     fd = open(filename, O_RDWR|O_CREAT, 0666);
+     if (fd < 0)
+ 	err (1, "open(rw): %s", filename);
+ 
+     ret = write (fd, "foo", 3);
+     if (ret < 0)
+ 	err (1, "write");
+     
+     fs_invalidate (filename);
+     
+     ret = write (fd, "foo", 3);
+     if (ret < 0)
+ 	err (1, "write2");
+     
+     ret = close (fd);
+     if (ret < 0)
+ 	err (1, "close");
+ }
+ 
+ static void
+ read_file (char *filename)
+ {
+     int ret;
+     int fd;
+     char buf[3];
+ 
+     fs_invalidate (filename);
+ 
+     fd = open(filename, O_RDONLY, 0666);
+     if (fd < 0)
+ 	err (1, "open(ro)");
+ 
+     ret = read (fd, buf, sizeof(buf));
+     if (ret < 0)
+ 	err (1, "read");
+     
+     fs_invalidate (filename);
+     
+     ret = read (fd, buf, sizeof(buf));
+     if (ret < 0)
+ 	err (1, "read");
+     
+     ret = close (fd);
+     if (ret < 0)
+ 	err (1, "close");
+ }
+ 
+ static void
+ mmap_read_file (char *filename)
+ {
+     int fd;
+     void *v;
+     char buf[6];
+ 
+     fs_invalidate (filename);
+ 
+     fd = open(filename, O_RDONLY, 0666);
+     if (fd < 0)
+ 	err (1, "open(ro-mmap)");
+ 
+     v = mmap (NULL, 6, PROT_READ, MAP_SHARED, fd, 0);
+     if (v == (void *)MAP_FAILED)
+ 	err (1, "mmap(ro) %s", filename);
+ 
+     memcpy (buf, v, 3);
+     fs_invalidate (filename);
+     memcpy (buf, v, 3);
+ 
+     munmap (v, 6);
+ }
+ 
+ static void
+ mmap_write_file (char *filename)
+ {
+     int fd;
+     void *v;
+ 
+     fs_invalidate (filename);
+ 
+     fd = open (filename, O_RDWR, 0666);
+     if (fd < 0)
+ 	err (1, "open(rw-mmap)");
+ 
+     v = mmap (NULL, 6, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+     if (v == (void *)MAP_FAILED)
+ 	err (1, "mmap(rw) %s", filename);
+ 
+     memcpy (v, "foo", 3);
+     fs_invalidate (filename);
+     memcpy (v, "foo", 3);
+ 
+     munmap (v, 6);
+     close (fd);
+ }
+ 
+ int
+ main(int argc, char **argv)
+ {
+     char *filename = "foo";
+     
+ 
+ #ifdef KERBEROS
+     if (!k_hasafs())
+ #endif
+ 	exit (1);
+     
+     create_write_file (filename);
+     read_file (filename);
+     read_file (filename);
+     read_file (filename);
+     read_file (filename);
+     mmap_read_file (filename);
+     mmap_read_file (filename);
+     mmap_read_file (filename);
+     mmap_read_file (filename);
+     mmap_write_file (filename);
+     mmap_write_file (filename);
+     mmap_write_file (filename);
+     mmap_write_file (filename);
+     
+     return 0;
+ }
+ 
+ #else
+ 
+ int
+ main(int argc, char **argv)
+ {
+ 
+     errx (1, "no kafs support");
+ }
+ #endif
Index: openafs/src/tests/kill-softer.c
diff -c /dev/null openafs/src/tests/kill-softer.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/kill-softer.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,191 ----
+ /*
+  * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <dirent.h>
+ 
+ #include <err.h>
+ 
+ #ifdef RCSID
+ RCSID("$Id: kill-softer.c,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $");
+ #endif
+ 
+ static FILE *verbose;
+ 
+ struct entry {
+     char *name;
+     int status;
+ };
+ 
+ static void
+ kill_one (struct entry *ents, int ind, int curents);
+ 
+ static void
+ do_dir (const char *dirname);
+ 
+ static void
+ kill_dir (const char *dirname);
+ 
+ static void
+ kill_one (struct entry *ents, int ind, int curents)
+ {
+     int ret;
+     int i;
+ 
+     ret = unlink (ents[ind].name);
+     if (ret < 0) {
+ 	if (errno == EISDIR || errno == EPERM)
+ 	    do_dir (ents[ind].name);
+ 	else
+ 	    err (1, "unlink %s", ents[ind].name);
+     }
+     ents[ind].status = 0;
+     for (i = 0; i <= ind; ++i) {
+ 	struct stat sb;
+ 
+ 	ret = lstat (ents[i].name, &sb);
+ 	if (ret == 0 || errno != ENOENT)
+ 	    err (1, "%s still exists?", ents[i].name);
+     }
+ 
+     for (i = ind + 1; i < curents; ++i) {
+ 	struct stat sb;
+ 
+ 	ret = lstat (ents[i].name, &sb);
+ 	if (ret < 0)
+ 	    err (1, "stat %s", ents[i].name);
+     }
+ }
+ 
+ static void
+ do_dir (const char *dirname)
+ {
+     int ret;
+ 
+     ret = chdir (dirname);
+     if (ret < 0)
+ 	err (1, "chdir %s", dirname);
+     kill_dir (dirname);
+     ret = chdir ("..");
+     if (ret < 0)
+ 	err (1, "chdir ..");
+     ret = rmdir (dirname);
+     if (ret < 0)
+ 	err (1, "rmdir %s", dirname);
+ }
+ 
+ static void
+ kill_dir (const char *dirname)
+ {
+     struct entry *ents;
+     int maxents;
+     int curents = 0;
+     DIR *dir;
+     struct dirent *dp;
+     int i;
+ 
+     fprintf (verbose, "reading %s\n", dirname);
+ 
+     dir = opendir (".");
+     if (dir == NULL)
+ 	err (1, "opendir %s", dirname);
+     maxents = 10;
+     ents = malloc (sizeof (*ents) * maxents);
+     if (ents == NULL)
+ 	err (1, "malloc");
+     while ((dp = readdir (dir)) != NULL) {
+ 	if (strcmp (dp->d_name, ".") == 0
+ 	    || strcmp (dp->d_name, "..") == 0)
+ 	    continue;
+ 
+ 	if (curents >= maxents) {
+ 	    maxents *= 2;
+ 	    ents = realloc (ents, sizeof(*ents) * maxents);
+ 	    if (ents == NULL)
+ 		err (1, "realloc");
+ 	}
+ 	ents[curents].name   = strdup (dp->d_name);
+ 	ents[curents].status = 1;
+ 	++curents;
+ 	fprintf (verbose, "  adding %s\n", dp->d_name);
+     }
+     closedir (dir);
+     dir = opendir (".");
+     if (dir == NULL)
+ 	err (1, "opendir %s", dirname);
+     i = 0;
+     while((dp = readdir (dir)) != NULL) {
+ 	if (strcmp (dp->d_name, ".") == 0
+ 	    || strcmp (dp->d_name, "..") == 0)
+ 	    continue;
+ 
+ 	if (strcmp (ents[i].name, dp->d_name) != 0) {
+ 	    errx (1, "%s != %s", ents[i].name, dp->d_name);
+ 	}
+ 	fprintf (verbose, "  deleting %s\n", ents[i].name);
+ 	kill_one (ents, i, curents);
+ 	++i;
+     }
+     if (i != curents)
+ 	errx (1, "missing %d entries in %s", curents - i, dirname);
+     closedir (dir);
+     free (ents);
+     fprintf (verbose, "end of %s\n", dirname);
+ }
+ 
+ int
+ main(int argc, char **argv)
+ {
+ 
+     verbose = fdopen (4, "w");
+     if (verbose == NULL) {
+ 	verbose = fopen ("/dev/null", "w");
+ 	if (verbose == NULL)
+ 	    err (1, "fopen /dev/null");
+     }
+ 
+     if (argc != 2)
+ 	errx (1, "usage: %s directory", argv[0]);
+     do_dir (argv[1]);
+     return 0;
+ }
Index: openafs/src/tests/kill-softly.c
diff -c /dev/null openafs/src/tests/kill-softly.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/kill-softly.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,161 ----
+ /*
+  * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <dirent.h>
+ 
+ #include <err.h>
+ 
+ #ifdef RCSID
+ RCSID("$Id: kill-softly.c,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $");
+ #endif
+ 
+ struct entry {
+     char *name;
+     int status;
+ };
+ 
+ static void
+ kill_one (struct entry *ents, int ind, int curents);
+ 
+ static void
+ do_dir (const char *dirname);
+ 
+ static void
+ kill_dir (const char *dirname);
+ 
+ static void
+ kill_one (struct entry *ents, int ind, int curents)
+ {
+     int ret;
+     int i;
+ 
+     ret = unlink (ents[ind].name);
+     if (ret < 0) {
+ 	if (errno == EISDIR || errno == EPERM)
+ 	    do_dir (ents[ind].name);
+ 	else
+ 	    err (1, "unlink %s", ents[ind].name);
+     }
+     ents[ind].status = 0;
+     for (i = 0; i <= ind; ++i) {
+ 	struct stat sb;
+ 
+ 	ret = lstat (ents[i].name, &sb);
+ 	if (ret == 0 || errno != ENOENT)
+ 	    err (1, "%s still exists?", ents[i].name);
+     }
+ 
+     for (i = ind + 1; i < curents; ++i) {
+ 	struct stat sb;
+ 
+ 	ret = lstat (ents[i].name, &sb);
+ 	if (ret < 0)
+ 	    err (1, "stat %s", ents[i].name);
+     }
+ }
+ 
+ static void
+ do_dir (const char *dirname)
+ {
+     int ret;
+ 
+     ret = chdir (dirname);
+     if (ret < 0)
+ 	err (1, "chdir %s", dirname);
+     kill_dir (dirname);
+     ret = chdir ("..");
+     if (ret < 0)
+ 	err (1, "chdir ..");
+     ret = rmdir (dirname);
+     if (ret < 0)
+ 	err (1, "rmdir %s", dirname);
+ }
+ 
+ static void
+ kill_dir (const char *dirname)
+ {
+     struct entry *ents;
+     int maxents;
+     int curents = 0;
+     DIR *dir;
+     struct dirent *dp;
+     int i;
+ 
+     dir = opendir (".");
+     if (dir == NULL)
+ 	err (1, "opendir %s", dirname);
+     maxents = 10;
+     ents = malloc (sizeof (*ents) * maxents);
+     if (ents == NULL)
+ 	err (1, "malloc");
+     while ((dp = readdir (dir)) != NULL) {
+ 	if (strcmp (dp->d_name, ".") == 0
+ 	    || strcmp (dp->d_name, "..") == 0)
+ 	    continue;
+ 
+ 	if (curents >= maxents) {
+ 	    maxents *= 2;
+ 	    ents = realloc (ents, sizeof(*ents) * maxents);
+ 	    if (ents == NULL)
+ 		err (1, "realloc");
+ 	}
+ 	ents[curents].name   = strdup (dp->d_name);
+ 	ents[curents].status = 1;
+ 	++curents;
+     }
+     closedir (dir);
+     for (i = 0; i < curents; ++i)
+ 	kill_one (ents, i, curents);
+     free (ents);
+ }
+ 
+ int
+ main(int argc, char **argv)
+ {
+ 
+     if (argc != 2)
+ 	errx (1, "usage: %s directory", argv[0]);
+     do_dir (argv[1]);
+     return 0;
+ }
Index: openafs/src/tests/kotest
diff -c /dev/null openafs/src/tests/kotest:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/kotest	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,4 ----
+ #!/bin/sh
+ # $Id: kotest,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ 
+ exec ${objdir}/../lib/ko/kotest
Index: openafs/src/tests/large-dir-16384
diff -c /dev/null openafs/src/tests/large-dir-16384:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/large-dir-16384	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,4 ----
+ #!/bin/sh
+ # $Id: large-dir-16384,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ if test "X$FAST" != "X" ; then echo "Not running $0" ;  exit 0 ; fi
+ $objdir/large-dir large-dir-16384 16384
Index: openafs/src/tests/large-dir-extra
diff -c /dev/null openafs/src/tests/large-dir-extra:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/large-dir-extra	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,7 ----
+ #!/bin/sh
+ # $Id: large-dir-extra,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ if test "X$FAST" != "X" ; then echo "Not running $0" ;  exit 0 ; fi
+ for i in 10 20 30 31 40 50 60 70 80 90 100; do
+   $objdir/large-dir2 large-dir-$i $i || exit 1
+   $objdir/large-dir3 large-dir-$i $i || exit 1
+ done
Index: openafs/src/tests/large-dir.c
diff -c /dev/null openafs/src/tests/large-dir.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/large-dir.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,157 ----
+ /*
+  * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <dirent.h>
+ 
+ #include <err.h>
+ 
+ #ifdef RCSID
+ RCSID("$Id: large-dir.c,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $");
+ #endif
+ 
+ static int
+ creat_files (const char *dirname, int count)
+ {
+     struct stat sb;
+     int i;
+     DIR *d;
+     struct dirent *dp;
+     
+     if (mkdir (dirname, 0777) < 0)
+ 	err (1, "mkdir %s", dirname);
+ 
+     if (chdir (dirname) < 0)
+ 	err (1, "chdir %s", dirname);
+     if (stat (".", &sb) < 0)
+ 	err (1, "stat .");
+     if (sb.st_size != 2048)
+ 	errx (1, "size != 2048");
+     for (i = 0; i < count; ++i) {
+ 	char num[17];
+ 	int fd;
+ 
+ 	snprintf (num, sizeof(num), "%d", i);
+ 	
+ 	fd = open (num, O_CREAT | O_EXCL, 0777);
+ 	if (fd < 0)
+ 	    err (1, "open %s", num);
+ 	if (close (fd) < 0)
+ 	    err (1, "close %s", num);
+     }
+     if (stat (".", &sb) < 0)
+ 	err (1, "stat .");
+ 
+     d = opendir (".");
+     if (d == NULL)
+ 	err (1, "opendir .");
+     for (i = -2; i < count; ++i) {
+ 	char num[17];
+ 
+ 	dp = readdir (d);
+ 	if (dp == NULL)
+ 	    errx (1, "out of entries at %d?", i);
+ 	if (i == -2)
+ 	    strcpy (num, ".");
+ 	else if (i == -1)
+ 	    strcpy (num, "..");
+ 	else
+ 	    snprintf (num, sizeof(num), "%d", i);
+ 	if (strcmp (num, dp->d_name) != 0)
+ 	    errx (1, "'%s' != '%s'", num, dp->d_name);
+     }
+     if (readdir (d) != NULL)
+ 	errx (1, "more entries?");
+     closedir (d);
+     for (i = 0; i < count; ++i) {
+ 	char num[17];
+ 
+ 	snprintf (num, sizeof(num), "%d", i);
+ 	
+ 	if (unlink (num) < 0)
+ 	    err (1, "unlink %s", num);
+     }
+     d = opendir (".");
+     if (d == NULL)
+ 	err (1, "opendir .");
+     dp = readdir (d);
+     if (dp == NULL || strcmp (dp->d_name, ".") != 0)
+ 	errx (1, "where's .?");
+     dp = readdir (d);
+     if (dp == NULL || strcmp (dp->d_name, "..") != 0)
+ 	errx (1, "where's ..?");
+     if (readdir (d) != NULL)
+ 	errx (1, "even more entries?");
+     closedir (d);
+     if (stat (".", &sb) < 0)
+ 	err (1, "stat .");
+ #if 0
+     if (sb.st_size != 2048)
+ 	errx (1, "size != 2048");
+ #endif
+     return 0;
+ }
+ 
+ static void
+ usage (int ret)
+ {
+     fprintf (stderr, "%s directory number-of-files\n", __progname);
+     exit (ret);
+ }
+ 
+ int
+ main(int argc, char **argv)
+ {
+     char *ptr;
+     int count;
+ 
+ 
+     if (argc != 3)
+ 	usage (1);
+ 
+     count = strtol (argv[2], &ptr, 0);
+     if (count == 0 && ptr == argv[2])
+ 	errx (1, "'%s' not a number", argv[2]);
+ 
+     return creat_files (argv[1], count);
+ }
Index: openafs/src/tests/large-dir2.c
diff -c /dev/null openafs/src/tests/large-dir2.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/large-dir2.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,136 ----
+ /*
+  * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <dirent.h>
+ 
+ #include <err.h>
+ 
+ #ifdef RCSID
+ RCSID("$Id: large-dir2.c,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $");
+ #endif
+ 
+ static int
+ creat_files (const char *dirname, int count)
+ {
+     struct stat sb;
+     int i;
+     DIR *d;
+     struct dirent *dp;
+     
+     srand (time (NULL));
+ 
+     if (mkdir (dirname, 0777) < 0)
+ 	err (1, "mkdir %s", dirname);
+ 
+     if (chdir (dirname) < 0)
+ 	err (1, "chdir %s", dirname);
+     if (stat (".", &sb) < 0)
+ 	err (1, "stat .");
+ #if 0
+     if (sb.st_size != 2048)
+ 	errx (1, "size != 2048");
+ #endif
+     for (i = 0; i < count; ++i) {
+ 	char fname[256];
+ 	int len;
+ 	int j;
+ 	int fd;
+ 
+ 	len = 1 + rand () % (sizeof(fname) - 2);
+ 
+ 	for (j = 0; j < len; ++j)
+ 	    fname[j] = 'A' + rand() % ('z' - 'A');
+ 	fname[j] = '\0';
+ 
+ 	fd = open (fname, O_CREAT | O_EXCL, 0777);
+ 	if (fd < 0)
+ 	    err (1, "open %s", fname);
+ 	if (close (fd) < 0)
+ 	    err (1, "close %s", fname);
+     }
+     if (stat (".", &sb) < 0)
+ 	err (1, "stat .");
+ 
+     d = opendir (".");
+     if (d == NULL)
+ 	err (1, "opendir .");
+     while ((dp = readdir (d)) != NULL) {
+ 	if (strcmp (dp->d_name, ".") == 0
+ 	    || strcmp (dp->d_name, "..") == 0)
+ 	    continue;
+ 
+ 	if (unlink (dp->d_name) < 0)
+ 	    err (1, "unlink %s", dp->d_name);
+     }
+     closedir (d);
+     if (chdir ("..") < 0)
+ 	err (1, "chdir ..");
+     if (rmdir (dirname) < 0)
+ 	err (1, "rmdir");
+     return 0;
+ }
+ 
+ static void
+ usage (int ret)
+ {
+     fprintf (stderr, "%s directory number-of-files\n", __progname);
+     exit (ret);
+ }
+ 
+ int
+ main(int argc, char **argv)
+ {
+     char *ptr;
+     int count;
+ 
+ 
+     if (argc != 3)
+ 	usage (1);
+ 
+     count = strtol (argv[2], &ptr, 0);
+     if (count == 0 && ptr == argv[2])
+ 	errx (1, "'%s' not a number", argv[2]);
+ 
+     return creat_files (argv[1], count);
+ }
Index: openafs/src/tests/large-dir3.c
diff -c /dev/null openafs/src/tests/large-dir3.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/large-dir3.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,124 ----
+ /*
+  * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <dirent.h>
+ 
+ #include <err.h>
+ 
+ #ifdef RCSID
+ RCSID("$Id: large-dir3.c,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $");
+ #endif
+ 
+ static int
+ creat_files (const char *dirname, int count)
+ {
+     struct stat sb;
+     int i;
+     DIR *d;
+     struct dirent *dp;
+     
+     if (mkdir (dirname, 0777) < 0)
+ 	err (1, "mkdir %s", dirname);
+ 
+     if (chdir (dirname) < 0)
+ 	err (1, "chdir %s", dirname);
+     if (stat (".", &sb) < 0)
+ 	err (1, "stat .");
+     for (i = 0; i < count; ++i) {
+ 	char num[17];
+ 	int fd;
+ 
+ 	snprintf (num, sizeof(num), "%d", i);
+ 	
+ 	fd = open (num, O_CREAT | O_EXCL, 0777);
+ 	if (fd < 0)
+ 	    err (1, "open %s", num);
+ 	if (close (fd) < 0)
+ 	    err (1, "close %s", num);
+     }
+     if (stat (".", &sb) < 0)
+ 	err (1, "stat .");
+ 
+     d = opendir (".");
+     if (d == NULL)
+ 	err (1, "opendir .");
+     while ((dp = readdir (d)) != NULL) {
+ 	if (strcmp (dp->d_name, ".") == 0
+ 	    || strcmp (dp->d_name, "..") == 0)
+ 	    continue;
+ 
+ 	if (unlink (dp->d_name) < 0)
+ 	    err (1, "unlink %s", dp->d_name);
+     }
+     closedir (d);
+     if (chdir ("..") < 0)
+ 	err (1, "chdir ..");
+     if (rmdir (dirname) < 0)
+ 	err (1, "rmdir");
+     return 0;
+ }
+ 
+ static void
+ usage (int ret)
+ {
+     fprintf (stderr, "%s directory number-of-files\n", __progname);
+     exit (ret);
+ }
+ 
+ int
+ main(int argc, char **argv)
+ {
+     char *ptr;
+     int count;
+ 
+ 
+     if (argc != 3)
+ 	usage (1);
+ 
+     count = strtol (argv[2], &ptr, 0);
+     if (count == 0 && ptr == argv[2])
+ 	errx (1, "'%s' not a number", argv[2]);
+ 
+     return creat_files (argv[1], count);
+ }
Index: openafs/src/tests/large-filename
diff -c /dev/null openafs/src/tests/large-filename:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/large-filename	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,6 ----
+ #!/bin/sh
+ # $Id: large-filename,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ 
+ touch aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 2>/dev/null >/dev/null || exit 1
+ rm aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 2>/dev/null >/dev/null || exit 1
+ exit 0
Index: openafs/src/tests/ls-afs
diff -c /dev/null openafs/src/tests/ls-afs:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/ls-afs	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,5 ----
+ #!/bin/sh
+ # $Id: ls-afs,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ if test "X$FAST" != "X" ; then echo "Not running $0" ;  exit 0 ; fi
+ ls -l $AFSROOT >/dev/null
+ true
Index: openafs/src/tests/make-page.c
diff -c /dev/null openafs/src/tests/make-page.c:1.2.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/make-page.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,96 ----
+ /*
+  * Copyright (c) 2000 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <errno.h>
+ 
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <sys/mman.h>
+ #include <sys/time.h>
+ #include <unistd.h>
+ 
+ 
+ #include <err.h>
+ 
+ #ifndef MAP_FAILED
+ #define MAP_FAILED ((void *)-1)
+ #endif
+ 
+ int
+ main (int argc, char **argv)
+ {
+     int mb = 10;
+     int ret;
+     size_t sz;
+     void *mmap_buf;
+ 
+     srand(getpid() * time(NULL));
+ 
+     sz = mb * 1024 * 1024;
+ 
+ #ifdef MAP_ANON
+     mmap_buf = mmap (NULL, sz, PROT_READ|PROT_WRITE,
+ 		     MAP_ANON|MAP_PRIVATE, -1, 0);
+ #else
+     {
+ 	int fd;
+ 
+ 	fd = open ("/dev/zero", O_RDWR);
+ 	if (fd < 0)
+ 	    err (1, "open /dev/zero");
+ 	mmap_buf = mmap (NULL, sz, PROT_READ | PROT_WRITE,
+ 			 MAP_PRIVATE, fd, 0);
+ 	close (fd);
+     }
+ #endif
+     if (mmap_buf == (void *)MAP_FAILED)
+ 	err (1, "mmap");    
+ 
+     while (1) {
+ 	int *foo = (int *) ((unsigned char *) mmap_buf + (((rand() % (sz - 9)) + 7) & ~7));
+ 	struct timeval tv = { 0, 1000} ;
+ 	*foo = 10;
+ 	select (0, NULL, NULL, NULL, &tv);
+     }
+     
+     ret = munmap (mmap_buf, sz);
+     if (ret)
+ 	err (1, "munmap");
+ }
Index: openafs/src/tests/many-dirs
diff -c /dev/null openafs/src/tests/many-dirs:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/many-dirs	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,6 ----
+ #!/bin/sh
+ # $Id: many-dirs,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ 
+ mkdir foobar || exit 1
+ (cd foobar && $objdir/create-dirs 1000) || exit 1
+ $objdir/rm-rf foobar || exit 1
Index: openafs/src/tests/many-fetchs
diff -c /dev/null openafs/src/tests/many-fetchs:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/many-fetchs	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,15 ----
+ #!/bin/sh
+ # $Id: many-fetchs,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ 
+ FS=${FS:-${objdir}/../appl/fs/fs}
+ 
+ touch foo
+ 
+ echo "foobar" > foo
+ 
+ for i in `awk 'BEGIN {for(i=0; i < 1000; ++i) printf "%d\n", i}' /dev/null`; do
+     ${FS} flush foo
+     cat foo > /dev/null || exit 1
+ done
+ 
+ rm foo
\ No newline at end of file
Index: openafs/src/tests/many-files
diff -c /dev/null openafs/src/tests/many-files:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/many-files	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,4 ----
+ #!/bin/sh
+ # $Id: many-files,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ 
+ $objdir/create-files 1000 0
Index: openafs/src/tests/many-files-with-content
diff -c /dev/null openafs/src/tests/many-files-with-content:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/many-files-with-content	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,4 ----
+ #!/bin/sh
+ # $Id: many-files-with-content,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ 
+ $objdir/create-files 1000 10
Index: openafs/src/tests/many-stores
diff -c /dev/null openafs/src/tests/many-stores:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/many-stores	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,10 ----
+ #!/bin/sh
+ # $Id: many-stores,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ 
+ touch foo
+ 
+ for i in `awk 'BEGIN {for(i=0; i < 1000; ++i) printf "%d\n", i}' /dev/null`; do
+     echo "foo$i" >> foo || exit 1
+ done
+ 
+ rm foo
\ No newline at end of file
Index: openafs/src/tests/many-symlinks
diff -c /dev/null openafs/src/tests/many-symlinks:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/many-symlinks	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,4 ----
+ #!/bin/sh
+ # $Id: many-symlinks,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ 
+ $objdir/create-symlinks 1000
Index: openafs/src/tests/mkdir
diff -c /dev/null openafs/src/tests/mkdir:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/mkdir	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,10 ----
+ #!/bin/sh
+ # $Id: mkdir,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ mkdir foo || exit 1
+ echo hej > foo/1 || exit 1
+ rmdir foo >/dev/null 2>&1 
+ test -d foo || exit 1
+ rm -f foo/1 || exit 1
+ rmdir foo || exit 1
+ test -d foo && exit 1
+ exit 0
Index: openafs/src/tests/mkdir-lnk
diff -c /dev/null openafs/src/tests/mkdir-lnk:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/mkdir-lnk	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,12 ----
+ #!/bin/sh
+ mkdir foo || exit 1
+ ls -ld foo | awk '{if($2 != 2) { exit(1) }}'  || exit 1
+ mkdir foo/1 || exit 1
+ ls -ld foo | awk '{if($2 != 3) { exit(1) }}'  || exit 1
+ mkdir foo/2 || exit 1
+ ls -ld foo | awk '{if($2 != 4) { exit(1) }}'  || exit 1
+ rmdir foo/1 || exit 1
+ ls -ld foo | awk '{if($2 != 3) { exit(1) }}'  || exit 1
+ rmdir foo/2 || exit 1
+ ls -ld foo | awk '{if($2 != 2) { exit(1) }}'  || exit 1
+ rmdir foo || exit 1
Index: openafs/src/tests/mkdir1
diff -c /dev/null openafs/src/tests/mkdir1:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/mkdir1	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,7 ----
+ #!/bin/sh
+ # $Id: mkdir1,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ mkdir foobar || exit 1
+ test -d foobar || exit 1
+ test -d foobar/. || exit 1
+ test -d foobar/.. || exit 1
+ rmdir foobar || exit 1
Index: openafs/src/tests/mkdir2.c
diff -c /dev/null openafs/src/tests/mkdir2.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/mkdir2.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,82 ----
+ /*
+  * Copyright (c) 1999 - 2000 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <unistd.h>
+ #include <fcntl.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ 
+ #include <err.h>
+ 
+ #ifdef RCSID
+ RCSID("$Id: mkdir2.c,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $");
+ #endif
+ 
+ int
+ main(int argc, char *argv[])
+ {
+     int ret;
+     struct stat dot_sb, sb;
+ 
+ 
+     ret = mkdir ("foo", 0777);
+     if (ret < 0)
+ 	err (1, "mkdir foo");
+     ret = lstat (".", &dot_sb);
+     if (ret < 0)
+ 	err (1, "lstat .");
+     ret = lstat ("foo", &sb);
+     if (ret < 0)
+ 	err (1, "lstat foo");
+     if (sb.st_nlink != 2)
+ 	errx (1, "sb.st_link != 2");
+     ret = lstat ("foo/.", &sb);
+     if (ret < 0)
+ 	err (1, "lstat foo/.");
+     if (sb.st_nlink != 2)
+ 	errx (1, "sb.st_link != 2");
+     ret = lstat ("foo/..", &sb);
+     if (ret < 0)
+ 	err (1, "lstat foo");
+     if (sb.st_nlink != dot_sb.st_nlink)
+ 	errx (1, "sb.st_link != dot_sb.st_nlink");
+     ret = rmdir ("foo");
+     if (ret < 0)
+ 	err (1, "rmdir foo");
+     return 0;
+ }
Index: openafs/src/tests/mkdir3.c
diff -c /dev/null openafs/src/tests/mkdir3.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/mkdir3.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,100 ----
+ /*
+  * Copyright (c) 1999 - 2000 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <unistd.h>
+ #include <fcntl.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ 
+ #include <err.h>
+ 
+ #ifdef RCSID
+ RCSID("$Id: mkdir3.c,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $");
+ #endif
+ 
+ int
+ main(int argc, char *argv[])
+ {
+     int ret;
+     struct stat dot_sb, sb;
+     int fd;
+ 
+     ret = mkdir ("foo", 0777);
+     if (ret < 0)
+ 	err (1, "mkdir foo");
+     ret = lstat (".", &dot_sb);
+     if (ret < 0)
+ 	err (1, "lstat .");
+     ret = lstat ("foo", &sb);
+     if (ret < 0)
+ 	err (1, "lstat foo");
+     if (sb.st_nlink != 2)
+ 	errx (1, "sb.st_link != 2");
+     ret = lstat ("foo/.", &sb);
+     if (ret < 0)
+ 	err (1, "lstat foo/.");
+     if (sb.st_nlink != 2)
+ 	errx (1, "sb.st_link != 2");
+     ret = lstat ("foo/..", &sb);
+     if (ret < 0)
+ 	err (1, "lstat foo");
+     if (sb.st_nlink != dot_sb.st_nlink)
+ 	errx (1, "sb.st_link != dot_sb.st_nlink");
+     ret = mkdir ("foo/bar", 0777);
+     if (ret < 0)
+ 	err (1, "mkdir bar");
+     fd = open ("foo/baz", O_CREAT|O_RDWR, 0600);
+     if (fd < 0)
+ 	err (1, "creat baz");
+     close(fd);
+     ret = lstat ("foo", &sb);
+     if (ret < 0)
+ 	err (1, "lstat foo");
+     if (sb.st_nlink != 3)
+ 	errx (1, "sb.st_link != 3");
+     ret = unlink ("foo/baz");
+     if (ret < 0)
+ 	err (1, "unlink baz");
+     ret = rmdir ("foo/bar");
+     if (ret < 0)
+ 	err (1, "rmdir bar");
+     ret = rmdir ("foo");
+     if (ret < 0)
+ 	err (1, "rmdir foo");
+     return 0;
+ }
Index: openafs/src/tests/mkm-rmm
diff -c /dev/null openafs/src/tests/mkm-rmm:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/mkm-rmm	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,13 ----
+ #!/bin/sh
+ # $Id: mkm-rmm,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ FS=${FS:-${objdir}/../appl/fs/fs}
+ ${FS} sa . system:anyuser all || exit 1
+ ${FS} mkm root.cell root.cell || exit 1
+ test -d root.cell || exit 1 
+ ${FS} rmm root.cell || exit 1
+ test -d root.cell && exit 1 
+ ${FS} mkm root.cell root.cell || exit 1
+ test -d root.cell || exit 1 
+ ${FS} rmm root.cell || exit 1
+ test -d root.cell && exit 1 
+ exit 0
Index: openafs/src/tests/mmap-and-read.c
diff -c /dev/null openafs/src/tests/mmap-and-read.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/mmap-and-read.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,165 ----
+ /*
+  * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <sys/types.h>
+ #include <fcntl.h>
+ #include <time.h>
+ #include <unistd.h>
+ #include <string.h>
+ #include <sys/mman.h>
+ #include <sys/stat.h>
+ #include <err.h>
+ 
+ #ifdef RCSID
+ RCSID("$Id: mmap-and-read.c,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $");
+ #endif
+ 
+ #ifndef MAP_FAILED
+ #define MAP_FAILED ((void *)-1)
+ #endif
+ 
+ static char *
+ generate_random_file (const char *filename,
+ 		      unsigned npages,
+ 		      unsigned pagesize,
+ 		      int writep)
+ {
+     int fd;
+     char *buf, *fbuf;
+     int i;
+     int prot;
+     int flags;
+     size_t sz = npages * pagesize;
+ 
+     buf = malloc (sz);
+     if (buf == NULL)
+ 	err (1, "malloc %u", (unsigned)sz);
+ 
+     for (i = 0; i < npages; ++i)
+ 	memset (buf + pagesize * i, '0' + i, pagesize);
+ 
+     fd = open (filename, O_RDWR | O_CREAT | O_TRUNC, 0666);
+     if (fd < 0)
+ 	err (1, "open %s", filename);
+ 
+     if (ftruncate (fd, sz) < 0)
+ 	err (1, "ftruncate");
+ 
+     prot = PROT_READ | PROT_WRITE;
+     flags = MAP_SHARED;
+ 
+     fbuf = mmap (0, sz, prot, flags, fd, 0);
+     if (fbuf == (void *)MAP_FAILED)
+ 	err (1, "mmap");
+ 
+     if (writep) {
+ 	if(write(fd, "hej\n", 4) != 4)
+ 	    err(1, "write");
+     }
+ 
+     memcpy (fbuf, buf, sz);
+ 
+ #if 0
+     if (msync (fbuf, sz, MS_SYNC))
+ 	err(1, "msync");
+ #endif
+ 
+     if (munmap (fbuf, sz) != 0)
+ 	err (1, "munmap");
+ 
+     if (close (fd))
+ 	err (1, "close");
+     return buf;
+ }
+ 
+ static char *
+ read_file (int fd, size_t sz)
+ {
+     char *buf;
+     ssize_t ret;
+ 
+     buf = malloc (sz);
+     if (buf == NULL)
+ 	err (1, "malloc %u", (unsigned)sz);
+     ret = read (fd, buf, sz);
+     if (ret < 0)
+         err (1, "read");
+     if (ret != sz)
+         errx(1, "short read %d < %u", (int)ret, (unsigned)sz);
+     return buf;
+ }
+ 
+ static int
+ test (const char *file, int writep)
+ {
+     const size_t sz  = 4 * getpagesize();
+     char *buf;
+     char *malloc_buf;
+     int fd;
+     int ret;
+ 
+     buf = generate_random_file (file, 4, getpagesize(), writep);
+ 
+     fd = open (file, O_RDONLY, 0);
+     if (fd < 0)
+ 	err (1, "open %s", file);
+ 
+     malloc_buf = read_file (fd, sz);
+     close (fd);
+     ret = memcmp (buf, malloc_buf, sz);
+     free (buf);
+     
+     return ret;
+ }
+ 
+ 
+ int
+ main (int argc, char **argv)
+ {
+ 
+ 
+     srand (time(NULL));
+ 
+     if (test ("foo", 1) != 0)
+ 	errx (1, "test(1)");
+     if (test ("bar", 0) != 0)
+ 	errx (1, "test(2)");
+ 
+     return 0;
+ }
Index: openafs/src/tests/mmap-cat.c
diff -c /dev/null openafs/src/tests/mmap-cat.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/mmap-cat.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,145 ----
+ /*
+  * Copyright (c) 2001 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <errno.h>
+ 
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <sys/mman.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ 
+ #include <err.h>
+ 
+ #ifndef MAP_FAILED
+ #define MAP_FAILED ((void *)-1)
+ #endif
+ 
+ static void
+ doit_mmap(int fd, struct stat *sb)
+ {
+     void *mmap_buf;
+     int ret;
+ 
+     mmap_buf = mmap (NULL, sb->st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+     if (mmap_buf == (void *)MAP_FAILED)
+ 	err (1, "mmap");
+     ret = write (1, mmap_buf, sb->st_size);
+     if (ret != sb->st_size)
+ 	err(1, "write returned %d wanted to write %d",
+ 	    ret, (int)sb->st_size);
+     munmap(mmap_buf, sb->st_size);
+ }
+ 
+ 
+ static void
+ doit_read(int fd, struct stat *sb)
+ {
+     int ret;
+     void *read_buf;
+ 
+     read_buf = malloc(sb->st_size);
+     if (read_buf == NULL)
+ 	err(1, "malloc(%d)", (int)sb->st_size);
+     ret = read(fd, read_buf, sb->st_size);
+     if (ret != sb->st_size)
+ 	err(1, "read returned %d wanted to write %d",
+ 	    ret, (int)sb->st_size);
+     ret = write (1, read_buf, sb->st_size);
+     if (ret != sb->st_size)
+ 	err(1, "write returned %d wanted to write %d",
+ 	    ret, (int)sb->st_size);
+     free(read_buf);
+ }
+ 
+ static void
+ doit (const char *filename, void (*func)(int, struct stat *))
+ {
+     struct stat sb;
+     int fd;
+     int ret;
+ 
+     fd = open (filename, O_RDONLY);
+     if (fd < 0)
+ 	err(1, "open %s", filename);
+     ret = fstat (fd, &sb);
+     (*func)(fd, &sb);
+     if (ret < 0)
+ 	err (1, "stat %s", filename);
+     close (fd);
+ }
+ 
+ static int read_flag;
+ static int mmap_flag;
+ static int help_flag;
+ 
+ static void
+ usage (int exit_val)
+ {
+     fprintf(stderr, "mmap-cat [-m|-r] filename\n");
+     exit (exit_val);
+ }
+ 
+ int
+ main(int argc, char **argv)
+ {
+     int optind = 0;
+ 
+     if (argc != 2)
+ 	usage(1);
+ 
+     if (!strcmp(argv[1],"-m")) {
+       mmap_flag++;
+     } else
+     if (!strcmp(argv[1],"-r")) {
+       read_flag++;
+     } else
+       usage (1);
+ 
+     if (read_flag && mmap_flag)
+ 	errx(1, "can't do both mmap and read");
+ 
+     if (read_flag)
+ 	doit(argv[0], doit_read);
+     if (mmap_flag)
+ 	doit(argv[0], doit_mmap);
+ 
+     return 0;
+ }
Index: openafs/src/tests/mmap-shared-write.c
diff -c /dev/null openafs/src/tests/mmap-shared-write.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/mmap-shared-write.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,101 ----
+ /*
+  * Copyright (c) 2000 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <sys/types.h>
+ #include <fcntl.h>
+ #include <time.h>
+ #include <unistd.h>
+ #include <string.h>
+ #include <sys/mman.h>
+ #include <sys/stat.h>
+ #include <err.h>
+ 
+ #ifndef MAP_FAILED
+ #define MAP_FAILED ((void *)-1)
+ #endif
+ 
+ #ifdef RCSID
+ RCSID("$Id: mmap-shared-write.c,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $");
+ #endif
+ 
+ static int
+ doit (const char *filename)
+ {
+     int fd;
+     size_t sz = getpagesize ();
+     void *v;
+ 
+     fd = open (filename, O_RDWR | O_CREAT, 0600);
+     if (fd < 0)
+ 	err (1, "open %s", filename);
+     if (ftruncate (fd, sz) < 0)
+ 	err (1, "ftruncate %s", filename);
+     v = mmap (NULL, sz, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+     if (v == (void *)MAP_FAILED)
+ 	err (1, "mmap %s", filename);
+ 
+     memset (v, 'z', sz);
+ 
+     msync (v, sz, MS_SYNC);
+ 
+     if (close (fd) < 0)
+ 	err (1, "close %s", filename);
+     return 0;
+ }
+ 
+ static void
+ usage(void)
+ {
+     errx (1, "usage: [filename]");
+ }
+ 
+ int
+ main (int argc, char **argv)
+ {
+     const char *filename = "foo";
+ 
+ 
+     if (argc != 1 && argc != 2)
+ 	usage ();
+ 
+     if (argc == 2)
+ 	filename = argv[1];
+ 
+     return doit (filename);
+ }
Index: openafs/src/tests/mmap-vs-read.c
diff -c /dev/null openafs/src/tests/mmap-vs-read.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/mmap-vs-read.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,172 ----
+ /*
+  * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <sys/types.h>
+ #include <fcntl.h>
+ #include <time.h>
+ #include <unistd.h>
+ #include <string.h>
+ #include <sys/mman.h>
+ #include <sys/stat.h>
+ #include <err.h>
+ 
+ #ifdef RCSID
+ RCSID("$Id: mmap-vs-read.c,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $");
+ #endif
+ 
+ static int debug = 0;
+ 
+ static void
+ generate_file (const char *filename, int randomp, size_t sz)
+ {
+     int fd;
+     char *buf;
+     int i;
+ 
+     buf = malloc (sz);
+     if (buf == NULL)
+ 	err (1, "malloc %u", (unsigned)sz);
+ 
+     fd = open (filename, O_WRONLY | O_CREAT, 0666);
+     if (fd < 0)
+ 	err (1, "open %s", filename);
+ 
+     for (i = 0; i < sz; ++i)
+ 	if (randomp)
+ 	    buf[i] = rand();
+ 	else
+ 	    buf[0] = 0;
+ 
+     if (write (fd, buf, sz) != sz)
+ 	err (1, "write");
+     if (close (fd))
+ 	err (1, "close");
+     free (buf);
+ }
+ 
+ static char *
+ read_file (int fd, size_t sz)
+ {
+     char *buf;
+     ssize_t ret;
+ 
+     buf = malloc (sz);
+     if (buf == NULL)
+ 	err (1, "malloc %u", (unsigned)sz);
+     ret = read (fd, buf, sz);
+     if (ret < 0)
+         err(1, "read");
+     if (ret != sz)
+         errx(1, "short read %d < %u", (int)ret, (unsigned)sz);
+     return buf;
+ }
+ 
+ #ifndef MAP_FAILED
+ #define MAP_FAILED ((void *)-1)
+ #endif
+ 
+ static void *
+ mmap_file (int fd, size_t sz)
+ {
+     void *ret;
+ 
+     ret = mmap (0, sz, PROT_READ, MAP_SHARED, fd, 0);
+     if (ret == (void *)MAP_FAILED)
+ 	err (1, "mmap");
+     return ret;
+ }
+ 
+ static void __attribute__ ((__unused__))
+ print_area (unsigned char *ptr,  size_t len)
+ {
+     while (len--) {
+ 	printf ("%x", *ptr);
+ 	ptr++;
+     }
+ }
+ 
+ static int
+ do_test (int randomp)
+ {
+     unsigned char *malloc_buf;
+     void *mmap_buf;
+     int fd;
+     const char *file = "foo";
+     const size_t sz  = 4 * getpagesize();
+ 
+     generate_file (file, randomp, sz);
+ 
+     fd = open (file, O_RDONLY, 0);
+     if (fd < 0)
+ 	err (1, "open %s", file);
+ 
+     mmap_buf   = mmap_file (fd, sz);
+     malloc_buf = read_file (fd, sz);
+     close (fd);
+     unlink (file);
+     if (memcmp (malloc_buf, mmap_buf, sz) != 0) {
+ 	if (debug) {
+ 	    printf ("type: %s\n", randomp ? "random" : "allzero");
+ 	    printf ("read: ");
+ 	    print_area (malloc_buf, sz);
+ 	    printf ("\nmmap: ");
+ 	    print_area (mmap_buf, sz);
+ 	    printf ("\n");
+ 	}
+ 	return 1;
+     }
+     return 0;
+ }
+ 
+ int
+ main (int argc, char **argv)
+ {
+ 
+     if (argc != 1)
+ 	debug = 1;
+ 
+     srand (time(NULL));
+ 
+     if (do_test (0))
+ 	return 1;
+     if (do_test (1))
+ 	return 2;
+ 
+     return 0;
+ }
Index: openafs/src/tests/mmap-vs-read2.c
diff -c /dev/null openafs/src/tests/mmap-vs-read2.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/mmap-vs-read2.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,172 ----
+ /*
+  * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <sys/types.h>
+ #include <fcntl.h>
+ #include <time.h>
+ #include <unistd.h>
+ #include <string.h>
+ #include <sys/mman.h>
+ #include <sys/stat.h>
+ #include <err.h>
+ 
+ #ifdef RCSID
+ RCSID("$Id: mmap-vs-read2.c,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $");
+ #endif
+ 
+ static int debug = 0;
+ 
+ static void
+ generate_file (const char *filename, int randomp, size_t sz)
+ {
+     int fd;
+     char *buf;
+     int i;
+ 
+     buf = malloc (sz);
+     if (buf == NULL)
+ 	err (1, "malloc %u", (unsigned)sz);
+ 
+     fd = open (filename, O_WRONLY | O_CREAT, 0666);
+     if (fd < 0)
+ 	err (1, "open %s", filename);
+ 
+     for (i = 0; i < sz; ++i)
+ 	if (randomp)
+ 	    buf[i] = rand();
+ 	else
+ 	    buf[0] = 0;
+ 
+     if (write (fd, buf, sz) != sz)
+ 	err (1, "write");
+     if (close (fd))
+ 	err (1, "close");
+     free (buf);
+ }
+ 
+ static unsigned char *
+ read_file (int fd, size_t sz)
+ {
+     unsigned char *buf;
+     ssize_t ret;
+ 
+     buf = malloc (sz);
+     if (buf == NULL)
+ 	err (1, "malloc %u", (unsigned)sz);
+     ret = read(fd, buf, sz);
+     if(ret < 0)
+         err(1, "read");
+     if (ret != sz)
+         errx(1, "short read %d < %u", (int)ret, (unsigned)sz);
+     return buf;
+ }
+ 
+ #ifndef MAP_FAILED
+ #define MAP_FAILED ((void *)-1)
+ #endif
+ 
+ static void *
+ mmap_file (int fd, size_t sz)
+ {
+     void *ret;
+ 
+     ret = mmap (0, sz, PROT_READ, MAP_PRIVATE, fd, 0);
+     if (ret == (void *)MAP_FAILED)
+ 	err (1, "mmap");
+     return ret;
+ }
+ 
+ static void __attribute__ ((__unused__))
+ print_area (unsigned char *ptr,  size_t len)
+ {
+     while (len--) {
+ 	printf ("%x", *ptr);
+ 	ptr++;
+     }
+ }
+ 
+ static int
+ do_test (int randomp)
+ {
+     unsigned char *malloc_buf;
+     void *mmap_buf;
+     int fd;
+     const char *file = "foo";
+     const size_t sz  = 3 * getpagesize() / 2;
+ 
+     generate_file (file, randomp, sz);
+ 
+     fd = open (file, O_RDONLY, 0);
+     if (fd < 0)
+ 	err (1, "open %s", file);
+ 
+     mmap_buf   = mmap_file (fd, sz);
+     malloc_buf = read_file (fd, sz);
+     close (fd);
+     unlink (file);
+     if (memcmp (malloc_buf, mmap_buf, sz) != 0) {
+ 	if (debug) {
+ 	    printf ("type: %s\n", randomp ? "random" : "allzero");
+ 	    printf ("read: ");
+ 	    print_area (malloc_buf, sz);
+ 	    printf ("\nmmap: ");
+ 	    print_area (mmap_buf, sz);
+ 	    printf ("\n");
+ 	}
+ 	return 1;
+     }
+     return 0;
+ }
+ 
+ int
+ main (int argc, char **argv)
+ {
+ 
+     if (argc != 1)
+ 	debug = 1;
+ 
+     srand (time(NULL));
+ 
+     if (do_test (0))
+ 	return 1;
+     if (do_test (1))
+ 	return 2;
+ 
+     return 0;
+ }
Index: openafs/src/tests/mountpoint.in
diff -c /dev/null openafs/src/tests/mountpoint.in:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/mountpoint.in	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,9 ----
+ #!/bin/sh
+ # $Id: mountpoint.in,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ FS=${FS:-${objdir}/../appl/fs/fs}
+ ${FS} sa . system:anyuser all || exit 1
+ ${FS} mkm no-such-volume no-such-volume 2>/dev/null || exit 1
+ if ls no-such-volume 2>/dev/null && touch no-such-volume/foo 2>/dev/null; then
+   ${FS} rmm no-such-volume; exit 1
+ fi
+ ${FS} rmm no-such-volume || exit 1
Index: openafs/src/tests/null-search.c
diff -c /dev/null openafs/src/tests/null-search.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/null-search.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,150 ----
+ #include <sys/fcntl.h>
+ #include <stdlib.h>
+ #include <stdarg.h>
+ #include <string.h>
+ 
+ #include "dumpscan.h"
+ 
+ char *argv0;
+ static char *input_path = 0;
+ static int quiet = 0, showpaths = 0, searchcount = 1;
+ static int error_count = 0, bad_count = 0;
+ static path_hashinfo phi;
+ static dump_parser dp;
+ 
+ /* Print a usage message and exit */
+ static void usage(int status, char *msg)
+ {
+   if (msg) fprintf(stderr, "%s: %s\n", argv0, msg);
+   fprintf(stderr, "Usage: %s [options] [file]\n", argv0);
+   fprintf(stderr, "  -h     Print this help message\n");
+   fprintf(stderr, "  -p     Print paths of bad vnodes\n");
+   fprintf(stderr, "  -q     Quiet mode (don't print errors)\n");
+   exit(status);
+ }
+ 
+ 
+ /* Parse the command-line options */
+ static void parse_options(int argc, char **argv)
+ {
+   int c;
+ 
+   if (argv0 = strrchr(argv[0], '/')) argv0++;
+   else argv0 = argv[0];
+ 
+   /* Parse the options */
+   while ((c = getopt(argc, argv, "n:hpq")) != EOF) {
+     switch (c) {
+       case 'n': searchcount  = atoi(optarg); continue;
+       case 'p': showpaths    = 1;            continue;
+       case 'q': quiet        = 1;            continue;
+       case 'h': usage(0, 0);
+       default:  usage(1, "Invalid option!");
+     }
+   }
+ 
+   if (argc - optind > 1) usage(1, "Too many arguments!");
+   input_path = (argc == optind) ? "-" : argv[optind];
+ }
+ 
+ 
+ /* A callback to count and print errors */
+ static afs_uint32 my_error_cb(afs_uint32 code, int fatal, void *ref, char *msg, ...)
+ {
+   va_list alist;
+ 
+   error_count++;
+   if (!quiet) {
+     va_start(alist, msg);
+     com_err_va(argv0, code, msg, alist);
+     va_end(alist);
+   }
+ }
+ 
+ 
+ /* A callback to process file vnodes */
+ static afs_uint32 my_file_cb(afs_vnode *v, XFILE *X, void *refcon)
+ {
+   static char buf[1024];
+   afs_uint32 size, nulls, cnulls, maxcnulls, n, r;
+   char *name = 0;
+   int i;
+ 
+   nulls = cnulls = maxcnulls = 0;
+   size = v->size;
+   if ((r = xfseek(X, &v->d_offset))) return r;
+   while (size) {
+     n = (size > 1024) ? 1024 : size;
+     if (r = xfread(X, buf, n)) return r;
+     for (i = 0; i < n; i++) {
+       if (buf[i]) {
+         if (cnulls > maxcnulls) maxcnulls = cnulls;
+         cnulls = 0;
+       } else {
+         nulls++;
+         cnulls++;
+       }
+     }
+     size -= n;
+   }
+   if (maxcnulls >= searchcount) {
+     bad_count++;
+     if (showpaths) Path_Build(X, &phi, v->vnode, &name, 0);
+     if (name) {
+       printf("*** BAD %d (%s) - %d nulls, %d consecutive\n",
+              v->vnode, name, nulls, maxcnulls);
+       free(name);
+     } else {
+       printf("*** BAD %d - %d nulls, %d consecutive\n",
+              v->vnode, nulls, maxcnulls);
+     }
+   }
+   return r;
+ }
+ 
+ 
+ int main(int argc, char **argv)
+ {
+   XFILE input_file;
+   afs_uint32 r;
+ 
+   parse_options(argc, argv);
+   initialize_acfg_error_table();
+   initialize_AVds_error_table();
+   initialize_rxk_error_table();
+   initialize_u_error_table();
+   initialize_vl_error_table();
+   initialize_vols_error_table();
+   initialize_xFil_error_table();
+   r = xfopen(&input_file, O_RDONLY, input_path);
+   if (r) {
+     com_err(argv0, r, "opening %s", input_path);
+     exit(2);
+   }
+ 
+   memset(&dp, 0, sizeof(dp));
+   dp.cb_error      = my_error_cb;
+   if (input_file.is_seekable) dp.flags |= DSFLAG_SEEK;
+   if (showpaths) {
+     u_int64 where;
+ 
+     memset(&phi, 0, sizeof(phi));
+     phi.p = &dp;
+ 
+     if ((r = xftell(&input_file, &where))
+     ||  (r = Path_PreScan(&input_file, &phi, 0))
+     ||  (r = xfseek(&input_file, &where))) {
+       com_err(argv0, r, "- path initialization failed");
+       xfclose(&input_file);
+       exit(2);
+     }
+   }
+ 
+   dp.cb_vnode_file = my_file_cb;
+   r = ParseDumpFile(&input_file, &dp);
+   xfclose(&input_file);
+ 
+   if (error_count) printf("*** %d errors\n", error_count);
+   if (bad_count)   printf("*** %d bad files\n", bad_count);
+   if (r && !quiet) printf("*** FAILED: %s\n", error_message(r));
+ }
Index: openafs/src/tests/parallel1
diff -c /dev/null openafs/src/tests/parallel1:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/parallel1	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,5 ----
+ #!/bin/sh
+ # $Id: parallel1,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ if test "X$FAST" != "X" ; then echo "Not running $0" ;  exit 0 ; fi
+ $objdir/test-parallel1 1>&4
+ 
Index: openafs/src/tests/parsedump.c
diff -c /dev/null openafs/src/tests/parsedump.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/parsedump.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,258 ----
+ /*
+  * CMUCS AFStools
+  * dumpscan - routines for scanning and manipulating AFS volume dumps
+  *
+  * Copyright (c) 1998 Carnegie Mellon University
+  * All Rights Reserved.
+  * 
+  * Permission to use, copy, modify and distribute this software and its
+  * documentation is hereby granted, provided that both the copyright
+  * notice and this permission notice appear in all copies of the
+  * software, derivative works or modified versions, and any portions
+  * thereof, and that both notices appear in supporting documentation.
+  *
+  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+  *
+  * Carnegie Mellon requests users of this software to return to
+  *
+  *  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
+  *  School of Computer Science
+  *  Carnegie Mellon University
+  *  Pittsburgh PA 15213-3890
+  *
+  * any improvements or extensions that they make and grant Carnegie Mellon
+  * the rights to redistribute these changes.
+  */
+ 
+ /* parsedump.c - Parse a volume dump file */
+ 
+ #include "dumpscan.h"
+ #include "dumpscan_errs.h"
+ #include "dumpfmt.h"
+ #include "internal.h"
+ #include "stagehdr.h"
+ 
+ static afs_uint32 parse_dumphdr  (XFILE *, unsigned char *, tagged_field *,
+                                afs_uint32, tag_parse_info *, void *, void *);
+ static afs_uint32 parse_dumpend  (XFILE *, unsigned char *, tagged_field *,
+                                afs_uint32, tag_parse_info *, void *, void *);
+ static afs_uint32 store_dumphdr  (XFILE *, unsigned char *, tagged_field *,
+                                afs_uint32, tag_parse_info *, void *, void *);
+ static afs_uint32 parse_dumptimes(XFILE *, unsigned char *, tagged_field *,
+                                afs_uint32, tag_parse_info *, void *, void *);
+ 
+ /** Field list for top-level objects **/
+ static tagged_field top_fields[] = {
+   { TAG_DUMPHEADER,  DKIND_SPECIAL, "* DUMP HEADER",   parse_dumphdr, 0, 0 },
+   { TAG_VOLHEADER,   DKIND_SPECIAL, "* VOLUME HEADER", parse_volhdr,  0, 0 },
+   { TAG_VNODE,       DKIND_SPECIAL, "* VNODE ",        parse_vnode,   0, 0 },
+   { TAG_DUMPEND,     DKIND_INT32,   "* DUMP END",      parse_dumpend, 0, 0 },
+   { STAGE_VERSMIN,   DKIND_SPECIAL, "* STAGE HEADER",  try_backuphdr, 0, 0 },
+   { 0,0,0,0,0,0 }};
+ 
+ 
+ /** Field list for dump headers **/
+ static tagged_field dumphdr_fields[] = {
+   { DHTAG_VOLNAME,   DKIND_STRING,  " Volume name:  ", store_dumphdr,   0, 0 },
+   { DHTAG_VOLID,     DKIND_INT32,   " Volume ID:    ", store_dumphdr,   0, 0 },
+   { DHTAG_DUMPTIMES, DKIND_SPECIAL, " Dump Range:   ", parse_dumptimes, 0, 0 },
+   { 0,0,0,0,0,0 }};
+ 
+ 
+ /* Parse a dump header, including its tagged attributes, and call the
+  * dump-header callback, if one is defined.
+  */
+ static afs_uint32 parse_dumphdr(XFILE *X, unsigned char *tag, tagged_field *field,
+                              afs_uint32 value, tag_parse_info *pi,
+                              void *g_refcon, void *l_refcon)
+ {
+   dump_parser *p = (dump_parser *)g_refcon;
+   afs_dump_header hdr;
+   u_int64 where;
+   afs_uint32 r;
+ 
+   memset(&hdr, 0, sizeof(hdr));
+   if (r = xftell(X, &where)) return r;
+   sub64_32(hdr.offset, where, 1);
+ 
+   if (r = ReadInt32(X, &hdr.magic)) return r;
+   if (r = ReadInt32(X, &hdr.version)) return r;
+ 
+   if (hdr.magic != DUMPBEGINMAGIC) {
+     if (p->cb_error)
+       (p->cb_error)(DSERR_MAGIC, 1, p->err_refcon,
+                     "Invalid magic number (0x%08x) in dump header",
+                     hdr.magic);
+     return DSERR_MAGIC;
+   }
+   if (hdr.version != DUMPVERSION) {
+     if (p->cb_error)
+       (p->cb_error)(DSERR_MAGIC, 1, p->err_refcon,
+                     "Unknown dump format version (%d) in dump header",
+                     hdr.version);
+     return DSERR_MAGIC;
+   }
+ 
+   if (p->print_flags & DSPRINT_DUMPHDR)
+     printf("%s [%s = 0x%s]\n", field->label,
+       decimate_int64(&hdr.offset, 0), hexify_int64(&hdr.offset, 0));
+   if (p->print_flags & DSPRINT_DUMPHDR) {
+     printf(" Magic number: 0x%08x\n", hdr.magic);
+     printf(" Version:      %d\n", hdr.version);
+   }
+   r = ParseTaggedData(X, dumphdr_fields, tag, pi, g_refcon, (void *)&hdr);
+ 
+   if (!r && p->cb_dumphdr) {
+     r = xftell(X, &where);
+     if (!r) r = (p->cb_dumphdr)(&hdr, X, p->refcon);
+     if (p->flags & DSFLAG_SEEK) {
+       if (!r) r = xfseek(X, &where);
+       else xfseek(X, &where);
+     }
+   }
+   if (hdr.field_mask & F_DUMPHDR_VOLNAME)
+     free(hdr.volname);
+   return r;
+ }
+ 
+ 
+ /* Store tagged attributes into a dump header */
+ static afs_uint32 store_dumphdr(XFILE *X, unsigned char *tag, tagged_field *field,
+                              afs_uint32 value, tag_parse_info *pi,
+                              void *g_refcon, void *l_refcon)
+ {
+   dump_parser *p = (dump_parser *)g_refcon;
+   afs_dump_header *hdr = (afs_dump_header *)l_refcon;
+ 
+   switch (field->tag) {
+   case DHTAG_VOLID:
+     hdr->field_mask |= F_DUMPHDR_VOLID;
+     hdr->volid = value;
+     if (p->print_flags & DSPRINT_DUMPHDR)
+       printf("%s%d\n", field->label, hdr->volid);
+     return 0;
+ 
+   case DHTAG_VOLNAME:
+     if (tag && tag[0]) {
+       hdr->field_mask |= F_DUMPHDR_VOLNAME;
+       hdr->volname = tag;
+       if (p->print_flags & DSPRINT_DUMPHDR)
+         printf("%s%s\n", field->label, hdr->volname);
+       return DSERR_KEEP;
+     } else return 0;
+ 
+   default:
+     if (p->print_flags & DSPRINT_DUMPHDR)
+       printf("%s<<< UNKNOWN FIELD >>>\n", field->label);
+     return 0;
+   }
+ }
+ 
+ 
+ /* Parse and store the dump time range from a dump header */
+ static afs_uint32 parse_dumptimes(XFILE *X, unsigned char *tag,
+                                tagged_field *field, afs_uint32 value,
+                                tag_parse_info *pi,
+                                void *g_refcon, void *l_refcon)
+ {
+   dump_parser *p = (dump_parser *)g_refcon;
+   afs_dump_header *hdr = (afs_dump_header *)l_refcon;
+   afs_uint16 count;
+   afs_uint32 r;
+ 
+   if (r = ReadInt16(X, &count)) return r;
+   if (count != 2) {
+     if (p->cb_error)
+       (p->cb_error)(DSERR_FMT, 1, p->err_refcon,
+                     "Incorrect array count (%d) in dump times", count);
+     return DSERR_FMT;
+   }
+   if (r = ReadInt32(X, &hdr->from_date)) return r;
+   if (r = ReadInt32(X, &hdr->to_date)) return r;
+   hdr->field_mask |= (F_DUMPHDR_FROM | F_DUMPHDR_TO);
+   if (p->print_flags & DSPRINT_DUMPHDR)
+     printf("%s%d => %d\n", field->label, hdr->from_date, hdr->to_date);
+ 
+   return ReadByte(X, tag);
+ }
+ 
+ 
+ /* Parse a dump_end record */
+ static afs_uint32 parse_dumpend(XFILE *X, unsigned char *tag, tagged_field *field,
+                              afs_uint32 value, tag_parse_info *pi,
+                              void *g_refcon, void *l_refcon)
+ {
+   dump_parser *p = (dump_parser *)g_refcon;
+   afs_uint32 r;
+ 
+   if (value != DUMPENDMAGIC) {
+     if (p->cb_error)
+       (p->cb_error)(DSERR_MAGIC, 1, p->err_refcon,
+                     "Invalid magic number (0x%08x) in dump trailer",
+                     value);
+     return DSERR_MAGIC;
+   }
+   if (p->print_flags & (DSPRINT_DUMPHDR | DSPRINT_ITEM))
+     printf("%s\n", field->label);
+   return DSERR_DONE;
+ }
+ 
+ 
+ 
+ afs_uint32 ParseDumpFile(XFILE *X, dump_parser *p)
+ {
+   tag_parse_info pi;
+   unsigned char tag;
+   afs_uint32 r;
+ 
+   prep_pi(p, &pi);
+   r = ParseTaggedData(X, top_fields, &tag, &pi, (void *)p, 0);
+   return handle_return(r, X, tag, p);
+ }
+ 
+ 
+ afs_uint32 ParseDumpHeader(XFILE *X, dump_parser *p)
+ {
+   tag_parse_info pi;
+   unsigned char tag;
+   afs_uint32 r;
+ 
+   prep_pi(p, &pi);
+   if (r = ReadByte(X, &tag)) return handle_return(r, X, tag, p);
+   if (tag != TAG_DUMPHEADER) return handle_return(0, X, tag, p);
+   r = parse_dumphdr(X, &tag, &top_fields[0], 0, &pi, (void *)p, 0);
+   if (!r && tag >= 1 && tag <= 4) r = DSERR_DONE;
+   return handle_return(r, X, tag, p);
+ }
+ 
+ 
+ afs_uint32 ParseVolumeHeader(XFILE *X, dump_parser *p)
+ {
+   tag_parse_info pi;
+   unsigned char tag;
+   afs_uint32 r;
+ 
+   prep_pi(p, &pi);
+   if (r = ReadByte(X, &tag)) return handle_return(r, X, tag, p);
+   if (tag != TAG_VOLHEADER) return handle_return(0, X, tag, p);
+   r = parse_volhdr(X, &tag, &top_fields[1], 0, &pi, (void *)p, 0);
+   if (!r && tag >= 1 && tag <= 4) r = DSERR_DONE;
+   return handle_return(r, X, tag, p);
+ }
+ 
+ 
+ afs_uint32 ParseVNode(XFILE *X, dump_parser *p)
+ {
+   tag_parse_info pi;
+   unsigned char tag;
+   afs_uint32 r;
+ 
+   prep_pi(p, &pi);
+   if (r = ReadByte(X, &tag)) return handle_return(r, X, tag, p);
+   if (tag != TAG_VNODE) return handle_return(0, X, tag, p);
+   r = parse_vnode(X, &tag, &top_fields[2], 0, &pi, (void *)p, 0);
+   if (!r && tag >= 1 && tag <= 4) r = DSERR_DONE;
+   return handle_return(r, X, tag, p);
+ }
Index: openafs/src/tests/parsetag.c
diff -c /dev/null openafs/src/tests/parsetag.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/parsetag.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,174 ----
+ /*
+  * CMUCS AFStools
+  * dumpscan - routines for scanning and manipulating AFS volume dumps
+  *
+  * Copyright (c) 1998 Carnegie Mellon University
+  * All Rights Reserved.
+  * 
+  * Permission to use, copy, modify and distribute this software and its
+  * documentation is hereby granted, provided that both the copyright
+  * notice and this permission notice appear in all copies of the
+  * software, derivative works or modified versions, and any portions
+  * thereof, and that both notices appear in supporting documentation.
+  *
+  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+  *
+  * Carnegie Mellon requests users of this software to return to
+  *
+  *  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
+  *  School of Computer Science
+  *  Carnegie Mellon University
+  *  Pittsburgh PA 15213-3890
+  *
+  * any improvements or extensions that they make and grant Carnegie Mellon
+  * the rights to redistribute these changes.
+  */
+ 
+ /* parsetag.c - Parse a tagged data stream */
+ 
+ #include "dumpscan.h"
+ #include "dumpscan_errs.h"
+ 
+ /* If a parser function is defined, it will be called after the data value
+  * (if any) is read.  The parser is called as follows:
+  *
+  *   parser(input_file, &tag, &field_rec, value, g_refcon, l_refcon);
+  *
+  * - input_file is the FILE * for the input stream
+  * - field_rec is a pointer to the field record for the field just read
+  * - g_refcon and l_refcon are as passed in to ParseTaggedData
+  * - For integer types, value is the integer value
+  * - For DKIND_STRING, tag is a pointer to the string just read
+  * - For DKIND_SPEACH, tag is a pointer to the place to put the next tag.
+  *
+  * If the field type is DKIND_SPECIAL, the parser is expected to read its
+  * own data from the input stream, and return when ParseTaggedData is supposed
+  * to take over, with the next tag to process in *tag.  At no other time
+  * should the parser read, write, or reposition the input stream.
+  *
+  * The parser routine should return 0 on success, non-0 on failure.  If the
+  * data type is DKIND_STRING, the parser may return DSERR_KEEP to indicate
+  * that the memory allocated for the value should not be freed.
+  */
+ 
+ /* Parse a file containing tagged data and attributes **/
+ afs_uint32 ParseTaggedData(XFILE *X, tagged_field *fields, unsigned char *tag,
+                     tag_parse_info *pi, void *g_refcon, void *l_refcon)
+ {
+   int i = -1;
+   afs_uint32 r, val;
+   afs_uint16 val16;
+   unsigned char val8;
+   unsigned char *strval;
+ 
+   for (;;) {
+     if (i < 0 || (fields[i].kind & DKIND_MASK) != DKIND_SPECIAL) {
+       /* Need to read in a tag */
+       if (r = ReadByte(X, tag)) return r;
+     }
+ 
+     /* Simple error recovery - if we encounter a 0, it can never be
+      * a valid tag.  If TPFLAG_SKIP is set, we can skip over any
+      * such null bytes, and process whatever tag we find beyond.
+      * In addition, if TPFLAG_RSKIP is set, then the next time
+      * we encounter a 0, try skipping backwards.  That seems to
+      * work much of the time.
+      */
+     if (!*tag && pi->shift_offset && (pi->flags & TPFLAG_RSKIP)) {
+       u_int64 where, tmp64a, tmp64b;
+       char buf1[21], buf2[21], buf3[21];
+       char *p1, *p2, *p3;
+ 
+       if (r = xftell(X, &tmp64a)) return r;
+       sub64_32(where, tmp64a, pi->shift_offset + 1);
+       if (r = xfseek(X, &where)) return r;
+       if (pi->cb_error){
+         (pi->cb_error)(DSERR_FMT, 0, pi->err_refcon,
+                        "Inserted %d bytes before offset %d",
+                        pi->shift_offset, decimate_int64(&where, 0));
+         add64_32(tmp64a, pi->shift_start, pi->shift_offset);
+         p1 = decimate_int64(&tmp64a, buf1);
+         sub64_64(tmp64b, where, tmp64a);
+         p2 = decimate_int64(&tmp64b, buf2);
+         p3 = decimate_int64(&pi->shift_start, buf3);
+         (pi->cb_error)(DSERR_FMT, 0, pi->err_refcon,
+                        ">>> SHIFT start=%s length=%s target=%s",
+                        p1, p2, p3);
+       }
+       pi->shift_offset = 0;
+       if (r = ReadByte(X, tag)) return r;
+     }
+     if (!*tag && (pi->flags & TPFLAG_SKIP)) {
+       int count = 0;
+       u_int64 where, tmp64a;
+ 
+       if (r = xftell(X, &where)) return r;
+       
+       while (!*tag) {
+         if (r = ReadByte(X, tag)) return r;
+         count++;
+       }
+       pi->shift_offset += count;
+       cp64(pi->shift_start, where);
+       if (pi->cb_error) {
+         sub64_32(tmp64a, where, 1);
+         (pi->cb_error)(DSERR_FMT, 0, pi->err_refcon,
+                        "Skipped %d bytes at offset %s",
+                        count, decimate_int64(&tmp64a, 0));
+       }
+     }
+ 
+     for (i = 0; fields[i].tag && fields[i].tag != *tag; i++);
+     if (!fields[i].tag) return 0;
+ 
+     switch (fields[i].kind & DKIND_MASK) {
+     case DKIND_NOOP:
+       if (fields[i].func) {
+         r = (fields[i].func)(X, 0, fields+i, 0, pi, g_refcon, l_refcon);
+         if (r) return r;
+       }
+       break;
+ 
+     case DKIND_BYTE:
+       if (r = ReadByte(X, &val8)) return r;
+       if (fields[i].func) {
+         r = (fields[i].func)(X, 0, fields+i, val8, pi, g_refcon, l_refcon);
+         if (r) return r;
+       }
+       break;
+ 
+     case DKIND_INT16:
+       if (r = ReadInt16(X, &val16)) return r;
+       if (fields[i].func) {
+         r = (fields[i].func)(X, 0, fields+i, val16, pi, g_refcon, l_refcon);
+         if (r) return r;
+       }
+       break;
+ 
+     case DKIND_INT32:
+       if (r = ReadInt32(X, &val)) return r;
+       if (fields[i].func) {
+         r = (fields[i].func)(X, 0, fields+i, val, pi, g_refcon, l_refcon);
+         if (r) return r;
+       }
+       break;
+ 
+     case DKIND_STRING: 
+       if (r = ReadString(X, &strval)) return r;
+       if (fields[i].func) {
+         r = (fields[i].func)(X, strval, fields+i, 0, pi, g_refcon, l_refcon);
+         if (r != DSERR_KEEP) free(strval);
+         if (r && r != DSERR_KEEP) return r;
+       } else free(strval);
+       break;
+ 
+     case DKIND_SPECIAL:
+       if (fields[i].func) {
+         r = (fields[i].func)(X, tag, fields+i, 0, pi, g_refcon, l_refcon);
+         if (r) return r;
+       } else i = -1;
+     }
+   }
+ }
Index: openafs/src/tests/parsevnode.c
diff -c /dev/null openafs/src/tests/parsevnode.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/parsevnode.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,427 ----
+ /*
+  * CMUCS AFStools
+  * dumpscan - routines for scanning and manipulating AFS volume dumps
+  *
+  * Copyright (c) 1998 Carnegie Mellon University
+  * All Rights Reserved.
+  * 
+  * Permission to use, copy, modify and distribute this software and its
+  * documentation is hereby granted, provided that both the copyright
+  * notice and this permission notice appear in all copies of the
+  * software, derivative works or modified versions, and any portions
+  * thereof, and that both notices appear in supporting documentation.
+  *
+  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+  *
+  * Carnegie Mellon requests users of this software to return to
+  *
+  *  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
+  *  School of Computer Science
+  *  Carnegie Mellon University
+  *  Pittsburgh PA 15213-3890
+  *
+  * any improvements or extensions that they make and grant Carnegie Mellon
+  * the rights to redistribute these changes.
+  */
+ 
+ /* parsevnode.c - Parse a VNode */
+ 
+ #include <sys/types.h>
+ #include <netinet/in.h>
+ #include <errno.h>
+ 
+ #include "dumpscan.h"
+ #include "dumpscan_errs.h"
+ #include "dumpfmt.h"
+ #include "internal.h"
+ 
+ #include <afs/acl.h>
+ #include <afs/prs_fs.h>
+ 
+ static afs_uint32 LastGoodVNode = 0;
+ static afs_uint32 store_vnode(XFILE *, unsigned char *, tagged_field *, afs_uint32,
+                            tag_parse_info *, void *, void *);
+ static afs_uint32 parse_acl  (XFILE *, unsigned char *, tagged_field *, afs_uint32,
+                            tag_parse_info *, void *, void *);
+ static afs_uint32 parse_vdata(XFILE *, unsigned char *, tagged_field *, afs_uint32,
+                            tag_parse_info *, void *, void *);
+ 
+ /** Field list for vnodes **/
+ static tagged_field vnode_fields[] = {
+   { VTAG_TYPE,        DKIND_BYTE,    " VNode type:   ", store_vnode, 0, 0 },
+   { VTAG_NLINKS,      DKIND_INT16,   " Link count:   ", store_vnode, 0, 0 },
+   { VTAG_DVERS,       DKIND_INT32,   " Version:      ", store_vnode, 0, 0 },
+   { VTAG_CLIENT_DATE, DKIND_TIME,    " Server Date:  ", store_vnode, 0, 0 },
+   { VTAG_AUTHOR,      DKIND_INT32,   " Author:       ", store_vnode, 0, 0 },
+   { VTAG_OWNER,       DKIND_INT32,   " Owner:        ", store_vnode, 0, 0 },
+   { VTAG_GROUP,       DKIND_INT32,   " Group:        ", store_vnode, 0, 0 },
+   { VTAG_MODE,        DKIND_INT16,   " UNIX mode:    ", store_vnode, 0, 0 },
+   { VTAG_PARENT,      DKIND_INT32,   " Parent:       ", store_vnode, 0, 0 },
+   { VTAG_SERVER_DATE, DKIND_TIME,    " Client Date:  ", store_vnode, 0, 0 },
+   { VTAG_ACL,         DKIND_SPECIAL, " xxxxxxxx ACL: ", parse_acl,   0, 0 },
+   { VTAG_DATA,        DKIND_SPECIAL, " Contents:     ", parse_vdata, 0, 0 },
+   { 0,0,0,0,0,0 }};
+ 
+ 
+ static afs_uint32 resync_vnode(XFILE *X, dump_parser *p, afs_vnode *v,
+                             int start, int limit)
+ {
+   u_int64 where, expected_where;
+   afs_uint32 r;
+   int i;
+ 
+   if (r = xftell(X, &expected_where)) return r;
+   cp64(where, expected_where);
+ 
+   r = match_next_vnode(X, p, &where, v->vnode);
+   if (r && r != DSERR_FMT) return r;
+   if (r) for (i = -start; i < limit; i++) {
+     add64_32(where, expected_where, i);
+     r = match_next_vnode(X, p, &where, v->vnode);
+     if (!r) break;
+     if (r != DSERR_FMT) return r;
+   }
+   if (r) {
+     if (p->cb_error)
+       (p->cb_error)(r, 1, p->err_refcon,
+                     "Unable to resync after vnode %d [%s = 0x%s]",
+                     v->vnode, decimate_int64(&expected_where, 0),
+                     hexify_int64(&expected_where, 0));
+     return r;
+   }
+   if (ne64(where, expected_where) && p->cb_error) {
+     (p->cb_error)(DSERR_FMT, 0, p->err_refcon,
+                   "Vnode after %d not in expected location",
+                   v->vnode);
+     (p->cb_error)(DSERR_FMT, 0, p->err_refcon, "Expected location: %s = 0x%s",
+                   decimate_int64(&expected_where, 0),
+                   hexify_int64(&expected_where, 0));
+     (p->cb_error)(DSERR_FMT, 0, p->err_refcon, "Actual location: %s = 0x%s",
+                   decimate_int64(&where, 0), hexify_int64(&where, 0));
+   }
+   return xfseek(X, &where);
+ }
+ 
+ 
+ /* Parse a VNode, including any tagged attributes and data, and call the
+  * appropriate callback, if one is defined.
+  */
+ afs_uint32 parse_vnode(XFILE *X, unsigned char *tag, tagged_field *field,
+                     afs_uint32 value, tag_parse_info *pi,
+                     void *g_refcon, void *l_refcon)
+ {
+   dump_parser *p = (dump_parser *)g_refcon;
+   afs_uint32 (*cb)(afs_vnode *, XFILE *, void *);
+   u_int64 where, offset2k;
+   afs_vnode v;
+   afs_uint32 r;
+ 
+ 
+   if (r = xftell(X, &where)) return r;
+   memset(&v, 0, sizeof(v));
+   sub64_32(v.offset, where, 1);
+   if (r = ReadInt32(X, &v.vnode)) return r;
+   if (r = ReadInt32(X, &v.vuniq)) return r;
+ 
+   mk64(offset2k, 0, 2048);
+   if (!LastGoodVNode
+   || ((p->flags & DSFLAG_SEEK) && v.vnode == 1
+        && lt64(v.offset, offset2k)))
+     LastGoodVNode = -1;
+ 
+   if (p->print_flags & DSPRINT_ITEM) {
+     printf("%s %d/%d [%s = 0x%s]\n", field->label, v.vnode, v.vuniq,
+            decimate_int64(&where, 0), hexify_int64(&where, 0));
+   }
+ 
+   r = ParseTaggedData(X, vnode_fields, tag, pi, g_refcon, (void *)&v);
+ 
+   /* Try to resync, if requested */
+   if (!r && (p->repair_flags & DSFIX_VFSYNC)) {
+     afs_uint32 drop;
+     u_int64 xwhere;
+ 
+     if (r = xftell(X, &where)) return r;
+     sub64_32(xwhere, where, 1);
+ 
+     /* Are we at the start of a valid vnode (or dump end)? */
+     r = match_next_vnode(X, p, &xwhere, v.vnode);
+     if (r && r != DSERR_FMT) return r;
+     if (r) { /* Nope. */
+       /* Was _this_ a valid vnode?  If so, we can keep it and search for
+        * the next one.  Otherwise, we throw it out, and start the search
+        * at the starting point of this vnode.
+        */
+       drop = r = match_next_vnode(X, p, &v.offset, LastGoodVNode);
+       if (r && r != DSERR_FMT) return r;
+       if (!r) {
+         add64_32(where, v.offset, 1);
+         if (r = xfseek(X, &v.offset)) return r;
+       } else {
+         if (r = xfseek(X, &xwhere)) return r;
+       }
+       if (r = resync_vnode(X, p, &v, 0, 1024)) return r;
+       if (r = ReadByte(X, tag)) return r;
+       if (drop) {
+         if (p->cb_error)
+           (p->cb_error)(DSERR_FMT, 0, p->err_refcon,
+                         "Dropping vnode %d", v.vnode);
+         return 0;
+       }
+     } else {
+       if (r = xfseek(X, &where)) return r;
+     }
+   }
+   LastGoodVNode = v.vnode;
+ 
+   if (!r) {
+     if (v.field_mask & F_VNODE_TYPE)
+       switch (v.type) {
+       case vFile:      cb = p->cb_vnode_file;  break;
+       case vDirectory: cb = p->cb_vnode_dir;   break;
+       case vSymlink:   cb = p->cb_vnode_link;  break;
+       default:         cb = p->cb_vnode_wierd; break;
+       }
+     else               cb = p->cb_vnode_empty;
+     if (cb) {
+       u_int64 where;
+ 
+       if (r = xftell(X, &where)) return r;
+       r = (cb)(&v, X, p->refcon);
+       if (p->flags & DSFLAG_SEEK) {
+         if (!r) r = xfseek(X, &where);
+         else xfseek(X, &where);
+       }
+     }
+   }
+   return r;
+ }
+ 
+ 
+ /* Store data in a vnode */
+ static afs_uint32 store_vnode(XFILE *X, unsigned char *tag, tagged_field *field,
+                            afs_uint32 value, tag_parse_info *pi,
+                            void *g_refcon, void *l_refcon)
+ {
+   dump_parser *p = (dump_parser *)g_refcon;
+   afs_vnode *v = (afs_vnode *)l_refcon;
+   time_t when;
+   afs_uint32 r = 0;
+ 
+   switch (field->tag) {
+   case VTAG_TYPE:
+     v->field_mask |= F_VNODE_TYPE;
+     v->type = value;
+     if (p->print_flags & DSPRINT_VNODE) {
+       switch (value) {
+       case vFile:
+         printf("%sFile (%d)\n", field->label, value);
+         break;
+       case vDirectory:
+         printf("%sDirectory (%d)\n", field->label, value);
+         break;
+       case vSymlink:
+         printf("%sSymbolic Link (%d)\n", field->label, value);
+         break;
+       default:
+         printf("%s??? (%d)\n", field->label, value);
+       }
+       return r;
+     }
+     break;
+ 
+   case VTAG_NLINKS:
+     v->field_mask |= F_VNODE_NLINKS;
+     v->nlinks = value;
+     break;
+ 
+   case VTAG_DVERS:
+     v->field_mask |= F_VNODE_DVERS;
+     v->datavers = value;
+     break;
+ 
+   case VTAG_CLIENT_DATE:
+     v->field_mask |= F_VNODE_CDATE;
+     v->client_date = value;
+     break;
+ 
+   case VTAG_SERVER_DATE:
+     v->field_mask |= F_VNODE_SDATE;
+     v->server_date = value;
+     break;
+ 
+   case VTAG_AUTHOR:
+     v->field_mask |= F_VNODE_AUTHOR;
+     v->author = value;
+     break;
+ 
+   case VTAG_OWNER:
+     v->field_mask |= F_VNODE_OWNER;
+     v->owner = value;
+     break;
+ 
+   case VTAG_GROUP:
+     v->field_mask |= F_VNODE_GROUP;
+     v->group = value;
+     break;
+ 
+   case VTAG_MODE:
+     v->field_mask |= F_VNODE_MODE;
+     v->mode = value;
+     break;
+ 
+   case VTAG_PARENT:
+     v->field_mask |= F_VNODE_PARENT;
+     v->parent = value;
+     break;
+   }
+ 
+   if (p->print_flags & DSPRINT_VNODE)
+     switch (field->kind) {
+     case DKIND_BYTE:
+     case DKIND_INT16:
+     case DKIND_INT32:  printf("%s%d\n",     field->label, value); break;
+     case DKIND_HEX8:   printf("%s0x%02x\n", field->label, value); break;
+     case DKIND_HEX16:  printf("%s0x%04x\n", field->label, value); break;
+     case DKIND_HEX32:  printf("%s0x%08x\n", field->label, value); break;
+     case DKIND_CHAR:   printf("%s%c\n",     field->label, value); break;
+     case DKIND_STRING: printf("%s%s\n",     field->label, tag);   break;
+     case DKIND_FLAG:
+       printf("%s%s\n", field->label, value ? "true" : "false");
+       break;
+     case DKIND_TIME:
+       when = value;
+       printf("%s%s", field->label, ctime(&when));
+       break;
+   }
+   return r;
+ }
+ 
+ 
+ static char *rights2str(afs_uint32 rights)
+ {
+   static char str[16];
+   char *p = str;
+ 
+   if (rights & PRSFS_READ)       *p++ = 'r';
+   if (rights & PRSFS_LOOKUP)     *p++ = 'l';
+   if (rights & PRSFS_INSERT)     *p++ = 'i';
+   if (rights & PRSFS_DELETE)     *p++ = 'd';
+   if (rights & PRSFS_WRITE)      *p++ = 'w';
+   if (rights & PRSFS_LOCK)       *p++ = 'k';
+   if (rights & PRSFS_ADMINISTER) *p++ = 'a';
+   if (rights & PRSFS_USR0)       *p++ = 'A';
+   if (rights & PRSFS_USR1)       *p++ = 'B';
+   if (rights & PRSFS_USR2)       *p++ = 'C';
+   if (rights & PRSFS_USR3)       *p++ = 'D';
+   if (rights & PRSFS_USR4)       *p++ = 'E';
+   if (rights & PRSFS_USR5)       *p++ = 'F';
+   if (rights & PRSFS_USR6)       *p++ = 'G';
+   if (rights & PRSFS_USR7)       *p++ = 'H';
+ 
+   *p = 0;
+   if (!str[0]) strcpy(str, "none");
+   return str;
+ }
+ 
+ 
+ /* Parse and store the ACL data from a directory vnode */
+ static afs_uint32 parse_acl(XFILE *X, unsigned char *tag, tagged_field *field,
+                          afs_uint32 value, tag_parse_info *pi,
+                          void *g_refcon, void *l_refcon)
+ {
+   struct acl_accessList *acl;
+   dump_parser *p = (dump_parser *)g_refcon;
+   afs_vnode *v = (afs_vnode *)l_refcon;
+   afs_uint32 r, i, n;
+ 
+   if (r = xfread(X, v->acl, SIZEOF_LARGEDISKVNODE - SIZEOF_SMALLDISKVNODE))
+     return r;
+ 
+   v->field_mask |= F_VNODE_ACL;
+   if (p->print_flags & DSPRINT_ACL) {
+     acl = (struct acl_accessList *)(v->acl);
+     n = ntohl(acl->positive);
+     if (n) {
+       printf("Positive ACL: %d entries\n", n);
+       for (i = 0; i < n; i++)
+         printf("              %9d  %s\n",
+                ntohl(acl->entries[i].id),
+                rights2str(acl->entries[i].rights));
+     }
+     n = ntohl(acl->negative);
+     if (n) {
+       printf("Positive ACL: %d entries\n", n);
+       for (i = ntohl(acl->positive); i < ntohl(acl->total); i++)
+         printf("              %9d  %s\n",
+                ntohl(acl->entries[i].id),
+                rights2str(acl->entries[i].rights));
+     }
+   }
+   return ReadByte(X, tag);
+ }
+ 
+ 
+ /* Parse or skip over the vnode data */
+ static afs_uint32 parse_vdata(XFILE *X, unsigned char *tag, tagged_field *field,
+                            afs_uint32 value, tag_parse_info *pi,
+                            void *g_refcon, void *l_refcon)
+ {
+   dump_parser *p = (dump_parser *)g_refcon;
+   afs_vnode *v = (afs_vnode *)l_refcon;
+   static char *symlink_buf = 0;
+   static int symlink_size = 0;
+   afs_uint32 r;
+ 
+   if (r = ReadInt32(X, &v->size)) return r;
+   v->field_mask |= F_VNODE_SIZE;
+ 
+   if (v->size) {
+     v->field_mask |= F_VNODE_DATA;
+     if (r = xftell(X, &v->d_offset)) return r;
+     if (p->print_flags & DSPRINT_VNODE)
+       printf("%s%d (0x%08x) bytes at %s (0x%s)\n", field->label,
+              v->size, v->size, decimate_int64(&v->d_offset, 0),
+              hexify_int64(&v->d_offset, 0));
+     
+     switch (v->type) {
+     case vSymlink:
+       if (v->size > symlink_size) {
+         if (symlink_buf) symlink_buf = (char *)realloc(symlink_buf, v->size + 1);
+         else symlink_buf = (char *)malloc(v->size + 1);
+         symlink_size = symlink_buf ? v->size : 0;
+       }
+       if (symlink_buf) {
+         if (r = xfread(X, symlink_buf, v->size)) return r;
+         symlink_buf[v->size] = 0;
+         if (p->print_flags & DSPRINT_VNODE)
+           printf("Target:       %s\n", symlink_buf);
+       } else {
+         /* Call the callback here, because it's non-fatal */
+         if (p->cb_error)
+           (p->cb_error)(ENOMEM, 0, p->err_refcon,
+                         "Out of memory reading symlink");
+         if (r = xfskip(X, v->size)) return r;
+       }
+       break;
+ 
+     case vDirectory:
+       if (p->cb_dirent || (p->print_flags & DSPRINT_DIR)) {
+         if (r = parse_directory(X, p, v, v->size, 0)) return r;
+         break;
+       }
+ 
+     default:
+       if (r = xfskip(X, v->size)) return r;
+     }
+   } else if (p->print_flags & DSPRINT_VNODE) {
+     printf("%sEmpty\n", field->label);
+   }
+   if (p->repair_flags & DSFIX_VDSYNC) {
+     r = resync_vnode(X, p, v, 10, 15);
+     if (r) return r;
+   }
+   return ReadByte(X, tag);
+ }
Index: openafs/src/tests/parsevol.c
diff -c /dev/null openafs/src/tests/parsevol.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/parsevol.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,302 ----
+ /*
+  * CMUCS AFStools
+  * dumpscan - routines for scanning and manipulating AFS volume dumps
+  *
+  * Copyright (c) 1998 Carnegie Mellon University
+  * All Rights Reserved.
+  * 
+  * Permission to use, copy, modify and distribute this software and its
+  * documentation is hereby granted, provided that both the copyright
+  * notice and this permission notice appear in all copies of the
+  * software, derivative works or modified versions, and any portions
+  * thereof, and that both notices appear in supporting documentation.
+  *
+  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+  *
+  * Carnegie Mellon requests users of this software to return to
+  *
+  *  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
+  *  School of Computer Science
+  *  Carnegie Mellon University
+  *  Pittsburgh PA 15213-3890
+  *
+  * any improvements or extensions that they make and grant Carnegie Mellon
+  * the rights to redistribute these changes.
+  */
+ 
+ /* parsevol.c - Parse a volume header */
+ 
+ #include "dumpscan.h"
+ #include "dumpscan_errs.h"
+ #include "dumpfmt.h"
+ 
+ static afs_uint32 store_volhdr   (XFILE *, unsigned char *, tagged_field *,
+                                afs_uint32, tag_parse_info *, void *, void *);
+ static afs_uint32 parse_weekuse  (XFILE *, unsigned char *, tagged_field *,
+                                afs_uint32, tag_parse_info *, void *, void *);
+ 
+ /** Field list for volume headers **/
+ static tagged_field volhdr_fields[] = {
+   { VHTAG_VOLID,     DKIND_INT32,   " Volume ID:   ", store_volhdr,  0, 0 },
+   { VHTAG_VERS,      DKIND_INT32,   " Version:     ", store_volhdr,  0, 0 },
+   { VHTAG_VOLNAME,   DKIND_STRING,  " Volume name: ", store_volhdr,  0, 0 },
+   { VHTAG_INSERV,    DKIND_FLAG,    " In service?  ", store_volhdr,  0, 0 },
+   { VHTAG_BLESSED,   DKIND_FLAG,    " Blessed?     ", store_volhdr,  0, 0 },
+   { VHTAG_VUNIQ,     DKIND_INT32,   " Uniquifier:  ", store_volhdr,  0, 0 },
+   { VHTAG_TYPE,      DKIND_BYTE,    " Type:        ", store_volhdr,  0, 0 },
+   { VHTAG_PARENT,    DKIND_INT32,   " Parent ID:   ", store_volhdr,  0, 0 },
+   { VHTAG_CLONE,     DKIND_INT32,   " Clone ID:    ", store_volhdr,  0, 0 },
+   { VHTAG_MAXQUOTA,  DKIND_INT32,   " Max quota:   ", store_volhdr,  0, 0 },
+   { VHTAG_MINQUOTA,  DKIND_INT32,   " Min quota:   ", store_volhdr,  0, 0 },
+   { VHTAG_DISKUSED,  DKIND_INT32,   " Disk used:   ", store_volhdr,  0, 0 },
+   { VHTAG_FILECNT,   DKIND_INT32,   " File count:  ", store_volhdr,  0, 0 },
+   { VHTAG_ACCOUNT,   DKIND_INT32,   " Account:     ", store_volhdr,  0, 0 },
+   { VHTAG_OWNER,     DKIND_INT32,   " Owner:       ", store_volhdr,  0, 0 },
+   { VHTAG_CREAT,     DKIND_TIME,    " Created:     ", store_volhdr,  0, 0 },
+   { VHTAG_ACCESS,    DKIND_TIME,    " Accessed:    ", store_volhdr,  0, 0 },
+   { VHTAG_UPDATE,    DKIND_TIME,    " Updated:     ", store_volhdr,  0, 0 },
+   { VHTAG_EXPIRE,    DKIND_TIME,    " Expires:     ", store_volhdr,  0, 0 },
+   { VHTAG_BACKUP,    DKIND_TIME,    " Backed up:   ", store_volhdr,  0, 0 },
+   { VHTAG_OFFLINE,   DKIND_STRING,  " Offine Msg:  ", store_volhdr,  0, 0 },
+   { VHTAG_MOTD,      DKIND_STRING,  " MOTD:        ", store_volhdr,  0, 0 },
+   { VHTAG_WEEKUSE,   DKIND_SPECIAL, " Weekuse:     ", parse_weekuse, 0, 0 },
+   { VHTAG_DUDATE,    DKIND_TIME,    " Dayuse Date: ", store_volhdr,  0, 0 },
+   { VHTAG_DAYUSE,    DKIND_INT32,   " Daily usage: ", store_volhdr,  0, 0 },
+   { 0,0,0,0,0,0 }};
+ 
+ 
+ /* Parse a volume header, including any tagged attributes, and call the
+  * volume-header callback, if one is defined.
+  */
+ afs_uint32 parse_volhdr(XFILE *X, unsigned char *tag, tagged_field *field,
+                      afs_uint32 value, tag_parse_info *pi,
+                      void *g_refcon, void *l_refcon)
+ {
+   dump_parser *p = (dump_parser *)g_refcon;
+   afs_vol_header hdr;
+   u_int64 where;
+   afs_uint32 r;
+ 
+   memset(&hdr, 0, sizeof(hdr));
+   if (r = xftell(X, &where)) return r;
+   sub64_32(hdr.offset, where, 1);
+   if (p->print_flags & DSPRINT_VOLHDR)
+     printf("%s [%s = 0x%s]\n", field->label,
+            decimate_int64(&hdr.offset, 0), hexify_int64(&hdr.offset, 0));
+ 
+   r = ParseTaggedData(X, volhdr_fields, tag, pi, g_refcon, (void *)&hdr);
+ 
+   if (!r && p->cb_volhdr) {
+     if (r = xftell(X, &where)) return r;
+     r = (p->cb_volhdr)(&hdr, X, p->refcon);
+     if (p->flags & DSFLAG_SEEK) {
+       if (!r) r = xfseek(X, &where);
+       else xfseek(X, &where);
+     }
+   }
+   if (hdr.field_mask & F_VOLHDR_VOLUNIQ)
+     p->vol_uniquifier = hdr.voluniq;
+   if (hdr.field_mask & F_VOLHDR_VOLNAME)
+     free(hdr.volname);
+   if (hdr.field_mask & F_VOLHDR_OFFLINE_MSG)
+     free(hdr.offline_msg);
+   if (hdr.field_mask & F_VOLHDR_MOTD)
+     free(hdr.motd_msg);
+   return r;
+ }
+ 
+ 
+ /* Store data in a volume header */
+ static afs_uint32 store_volhdr(XFILE *X, unsigned char *tag, tagged_field *field,
+                             afs_uint32 value, tag_parse_info *pi,
+                             void *g_refcon, void *l_refcon)
+ {
+   dump_parser *p = (dump_parser *)g_refcon;
+   afs_vol_header *hdr = (afs_vol_header *)l_refcon;
+   time_t when;
+   afs_uint32 r = 0;
+ 
+   switch (field->tag) {
+   case VHTAG_VOLID:
+     hdr->field_mask |= F_VOLHDR_VOLID;
+     hdr->volid = value;
+     break;
+ 
+   case VHTAG_VERS:
+     hdr->field_mask |= F_VOLHDR_VOLVERS;
+     hdr->volvers = value;
+     break;
+ 
+   case VHTAG_VOLNAME:
+     if (tag && tag[0]) {
+       hdr->field_mask |= F_VOLHDR_VOLNAME;
+       hdr->volname = tag;
+       r = DSERR_KEEP;
+     }
+     break;
+ 
+   case VHTAG_INSERV:
+     hdr->field_mask |= F_VOLHDR_INSERV;
+     hdr->flag_inservice = value;
+     break;
+ 
+   case VHTAG_BLESSED:
+     hdr->field_mask |= F_VOLHDR_BLESSED;
+     hdr->flag_blessed = value;
+     break;
+ 
+   case VHTAG_VUNIQ:
+     hdr->field_mask |= F_VOLHDR_VOLUNIQ;
+     hdr->voluniq = value;
+     break;
+ 
+   case VHTAG_TYPE:
+     hdr->field_mask |= F_VOLHDR_VOLTYPE;
+     hdr->voltype = value;
+     break;
+ 
+   case VHTAG_PARENT:
+     hdr->field_mask |= F_VOLHDR_PARENT;
+     hdr->parent_volid = value;
+     break;
+ 
+   case VHTAG_CLONE:
+     hdr->field_mask |= F_VOLHDR_CLONE;
+     hdr->clone_volid = value;
+     break;
+ 
+   case VHTAG_MAXQUOTA:
+     hdr->field_mask |= F_VOLHDR_MAXQ;
+     hdr->maxquota = value;
+     break;
+ 
+   case VHTAG_MINQUOTA:
+     hdr->field_mask |= F_VOLHDR_MINQ;
+     hdr->minquota = value;
+     break;
+ 
+   case VHTAG_DISKUSED:
+     hdr->field_mask |= F_VOLHDR_DISKUSED;
+     hdr->diskused = value;
+     break;
+ 
+   case VHTAG_FILECNT:
+     hdr->field_mask |= F_VOLHDR_NFILES;
+     hdr->nfiles = value;
+     break;
+ 
+   case VHTAG_ACCOUNT:
+     hdr->field_mask |= F_VOLHDR_ACCOUNT;
+     hdr->account_no = value;
+     break;
+ 
+   case VHTAG_OWNER:
+     hdr->field_mask |= F_VOLHDR_OWNER;
+     hdr->owner = value;
+     break;
+ 
+   case VHTAG_CREAT:
+     hdr->field_mask |= F_VOLHDR_CREATE_DATE;
+     hdr->create_date = value;
+     break;
+ 
+   case VHTAG_ACCESS:
+     hdr->field_mask |= F_VOLHDR_ACCESS_DATE;
+     hdr->access_date = value;
+     break;
+ 
+   case VHTAG_UPDATE:
+     hdr->field_mask |= F_VOLHDR_UPDATE_DATE;
+     hdr->update_date = value;
+     break;
+ 
+   case VHTAG_EXPIRE:
+     hdr->field_mask |= F_VOLHDR_EXPIRE_DATE;
+     hdr->expire_date = value;
+     break;
+ 
+   case VHTAG_BACKUP:
+     hdr->field_mask |= F_VOLHDR_BACKUP_DATE;
+     hdr->backup_date = value;
+     break;
+ 
+   case VHTAG_OFFLINE:
+     if (tag && tag[0]) {
+       hdr->field_mask |= F_VOLHDR_OFFLINE_MSG;
+       hdr->offline_msg = tag;
+       r = DSERR_KEEP;
+     }
+     break;
+ 
+   case VHTAG_MOTD:
+     if (tag && tag[0]) {
+       hdr->field_mask |= F_VOLHDR_MOTD;
+       hdr->motd_msg = tag;
+       r = DSERR_KEEP;
+     }
+     break;
+ 
+   case VHTAG_DUDATE:
+     hdr->field_mask |= F_VOLHDR_DAYUSE_DATE;
+     hdr->dayuse_date = value;
+     break;
+ 
+   case VHTAG_DAYUSE:
+     hdr->field_mask |= F_VOLHDR_DAYUSE;
+     hdr->dayuse = value;
+     break;
+   }
+ 
+   if (p->print_flags & DSPRINT_VOLHDR)
+     switch (field->kind) {
+     case DKIND_BYTE:
+     case DKIND_INT16:
+     case DKIND_INT32:  printf("%s%d\n",     field->label, value); break;
+     case DKIND_HEX8:   printf("%s0x%02x\n", field->label, value); break;
+     case DKIND_HEX16:  printf("%s0x%04x\n", field->label, value); break;
+     case DKIND_HEX32:  printf("%s0x%08x\n", field->label, value); break;
+     case DKIND_CHAR:   printf("%s%c\n",     field->label, value); break;
+     case DKIND_STRING: printf("%s%s\n",     field->label, tag);   break;
+     case DKIND_FLAG:
+       printf("%s%s\n", field->label, value ? "true" : "false");
+       break;
+     case DKIND_TIME:
+       when = value;
+       printf("%s%s", field->label, ctime(&when));
+       break;
+   }
+   return r;
+ }
+ 
+ 
+ /* Parse and store the week use data from a volume header */
+ static afs_uint32 parse_weekuse(XFILE *X, unsigned char *tag, tagged_field *field,
+                              afs_uint32 value, tag_parse_info *pi,
+                              void *g_refcon, void *l_refcon)
+ {
+   dump_parser *p = (dump_parser *)g_refcon;
+   afs_vol_header *hdr = (afs_vol_header *)l_refcon;
+   afs_uint16 count;
+   afs_uint32 r;
+   unsigned int i;
+ 
+   if (r = ReadInt16(X, &count)) return r;
+   if (count != 7) {
+     if (p->cb_error)
+       (p->cb_error)(DSERR_FMT, 1, p->err_refcon,
+                     "Incorrect array count (%d) in weekuse data", count);
+     return DSERR_FMT;
+   }
+   for (i = 0; i < count; i++)
+     if (r = ReadInt32(X, hdr->weekuse + i)) return r;
+   hdr->field_mask |= F_VOLHDR_WEEKUSE;
+   if (p->print_flags & DSPRINT_VOLHDR) {
+     printf("%s%10d %10d %10d %10d\n", field->label,
+            hdr->weekuse[0], hdr->weekuse[1], hdr->weekuse[2], hdr->weekuse[3]);
+     printf("%s%10d %10d %10d\n", field->label,
+            hdr->weekuse[4], hdr->weekuse[5], hdr->weekuse[6]);
+   }
+   return ReadByte(X, tag);
+ }
Index: openafs/src/tests/pathname.c
diff -c /dev/null openafs/src/tests/pathname.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/pathname.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,376 ----
+ /*
+  * CMUCS AFStools
+  * dumpscan - routines for scanning and manipulating AFS volume dumps
+  *
+  * Copyright (c) 1998 Carnegie Mellon University
+  * All Rights Reserved.
+  * 
+  * Permission to use, copy, modify and distribute this software and its
+  * documentation is hereby granted, provided that both the copyright
+  * notice and this permission notice appear in all copies of the
+  * software, derivative works or modified versions, and any portions
+  * thereof, and that both notices appear in supporting documentation.
+  *
+  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+  *
+  * Carnegie Mellon requests users of this software to return to
+  *
+  *  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
+  *  School of Computer Science
+  *  Carnegie Mellon University
+  *  Pittsburgh PA 15213-3890
+  *
+  * any improvements or extensions that they make and grant Carnegie Mellon
+  * the rights to redistribute these changes.
+  */
+ 
+ /* pathname.c - Pathname lookup and traversal */
+ 
+ #include <errno.h>
+ #include <string.h>
+ 
+ #include "dumpscan.h"
+ #include "dumpscan_errs.h"
+ 
+ /* Hash function for a vnode */
+ #define BUCKET_SIZE 32
+ #define vnode_hash(phi,vnode) ((vnode) & ((1 << (phi)->hash_size) - 1))
+ 
+ 
+ static vhash_ent *get_vhash_ent(path_hashinfo *phi, afs_uint32 vnode, int make)
+ {
+   int key = vnode_hash(phi, vnode);
+   vhash_ent *vhe;
+ 
+   for (vhe = phi->hash_table[key];
+        vhe && vhe->vnode != vnode;
+        vhe = vhe->next);
+   if (make && !vhe) {
+     vhe = (vhash_ent *)malloc(sizeof(vhash_ent));
+     if (vhe) {
+       memset(vhe, 0, sizeof(vhash_ent));
+       vhe->vnode = vnode;
+       vhe->next = phi->hash_table[key];
+       phi->hash_table[key] = vhe;
+     }
+   }
+   return vhe;
+ }
+ 
+ 
+ static afs_uint32 volhdr_cb(afs_vol_header *hdr, XFILE *X, void *refcon)
+ {
+   path_hashinfo *phi = (path_hashinfo *)refcon;
+   int nfiles, hsize;
+ 
+   if (hdr->field_mask & F_VOLHDR_NFILES) {
+     nfiles = phi->n_vnodes = hdr->nfiles;
+     for (phi->hash_size = 1;
+          nfiles > BUCKET_SIZE;
+          phi->hash_size++, nfiles >>= 1);
+     hsize = (1 << phi->hash_size);
+     phi->hash_table = (vhash_ent **)malloc(hsize * sizeof(vhash_ent *));
+     if (!phi->hash_table) return ENOMEM;
+     memset(phi->hash_table, 0, hsize * sizeof(vhash_ent *));
+     return 0;
+   } else {
+     if (phi->p->cb_error)
+       (phi->p->cb_error)(DSERR_FMT, 1, phi->p->err_refcon,
+                          "File count missing from volume header");
+     return DSERR_FMT;
+   }
+ }
+ 
+ 
+ static afs_uint32 vnode_keep(afs_vnode *v, XFILE *X, void *refcon)
+ {
+   path_hashinfo *phi = (path_hashinfo *)refcon;
+   vhash_ent *vhe;
+ 
+   if (!phi->hash_table) {
+     if (phi->p->cb_error)
+       (phi->p->cb_error)(DSERR_FMT, 1, phi->p->refcon,
+                          "No volume header in dump???");
+     return DSERR_FMT;
+   }
+   vhe = get_vhash_ent(phi, v->vnode, 1);
+   if (!vhe) return ENOMEM;
+   cp64(vhe->v_offset, v->offset);
+   if (v->field_mask & F_VNODE_PARENT)
+     vhe->parent = v->parent;
+   if (v->field_mask & F_VNODE_DATA) {
+     cp64(vhe->d_offset, v->d_offset);
+     vhe->d_size   = v->size;
+   }
+   if ((v->field_mask & F_VNODE_TYPE) && v->type == vDirectory)
+     phi->n_dirs++;
+   else
+     phi->n_files++;
+   return 0;
+ }
+ 
+ 
+ static afs_uint32 vnode_stop(afs_vnode *v, XFILE *X, void *refcon)
+ {
+   path_hashinfo *phi = (path_hashinfo *)refcon;
+   int r;
+ 
+   /* If the file is seekable, try to position so we can pick up later... */
+   if (phi->p->flags && DSFLAG_SEEK)
+     if (r = xfseek(X, &v->offset)) return r;
+   return DSERR_DONE;
+ }
+ 
+ 
+ static afs_uint32 dirent_cb(afs_vnode *v, afs_dir_entry *de,
+                          XFILE *X, void *refcon)
+ {
+   path_hashinfo *phi = (path_hashinfo *)refcon;
+   vhash_ent *vhe;
+ 
+   if (!phi->hash_table) {
+     if (phi->p->cb_error)
+       (phi->p->cb_error)(DSERR_FMT, 1, phi->p->refcon,
+                          "No volume header in dump???");
+     return DSERR_FMT;
+   }
+   if (!strcmp(de->name, ".") || !strcmp(de->name, "..")) return 0;
+   vhe = get_vhash_ent(phi, de->vnode, 1);
+   if (!vhe) return ENOMEM;
+   vhe->parent = v->vnode;
+   return 0;
+ }
+ 
+ 
+ /* Prescan the vnodes in a dump file, collecting information that will
+  * be useful in generating and following pathnames.  
+  */
+ afs_uint32 Path_PreScan(XFILE *X, path_hashinfo *phi, int full)
+ {
+   dump_parser my_p, *p = phi->p;
+   int r;
+ 
+   memset(phi, 0, sizeof(path_hashinfo));
+   phi->p = p;
+   memset(&my_p, 0, sizeof(my_p));
+   my_p.refcon       = (void *)phi;
+   my_p.cb_volhdr    = volhdr_cb;
+   my_p.cb_vnode_dir = vnode_keep;
+   if (full) {
+     my_p.cb_vnode_file  = vnode_keep;
+     my_p.cb_vnode_link  = vnode_keep;
+     my_p.cb_vnode_empty = vnode_keep;
+     my_p.cb_vnode_wierd = vnode_keep;
+   } else {
+     my_p.cb_vnode_file  = vnode_stop;
+     my_p.cb_vnode_link  = vnode_stop;
+     my_p.cb_vnode_empty = vnode_stop;
+     my_p.cb_vnode_wierd = vnode_stop;
+   }
+   my_p.err_refcon   = p->err_refcon;
+   my_p.cb_error     = p->cb_error;
+   my_p.cb_dirent    = dirent_cb;
+   my_p.flags        = p->flags;
+   my_p.print_flags  = p->print_flags;
+   my_p.repair_flags = p->repair_flags;
+ 
+   return ParseDumpFile(X, &my_p);
+ }
+ 
+ 
+ /* Free the hash table in a path_hashinfo */
+ void Path_FreeHashTable(path_hashinfo *phi)
+ {
+   int i, size;
+   vhash_ent *vhe, *next_vhe;
+ 
+   if (phi->hash_table) {
+     size = (1 << phi->hash_size);
+     for (i = 0; i < size; i++)
+       for (vhe = phi->hash_table[i]; vhe; vhe = next_vhe) {
+         next_vhe = vhe->next;
+         free(vhe);
+       }
+     free(phi->hash_table);
+   }
+ }
+ 
+ 
+ /* Follow a pathname to the vnode it represents */
+ afs_uint32 Path_Follow(XFILE *X, path_hashinfo *phi,
+                     char *path, vhash_ent *his_vhe)
+ {
+   vhash_ent *vhe;
+   char *name;
+   afs_uint32 r, vnum = 1;
+ 
+   if (*path == '/') path++;
+   name = strtok(path, "/");
+ 
+   for (name = strtok(path, "/"); name; name = strtok(0, "/")) {
+     if (!(vnum & 1)) {
+       if (phi->p->cb_error)
+         (phi->p->cb_error)(ENOTDIR, 1, phi->p->err_refcon,
+                            "Not a directory vnode");
+       return ENOTDIR;
+     }
+     vhe = get_vhash_ent(phi, vnum, 0);
+     if (!vhe) {
+       if (phi->p->cb_error)
+         (phi->p->cb_error)(DSERR_FMT, 1, phi->p->err_refcon,
+                            "Vnode %d not found in hash table", vnum);
+       return DSERR_FMT;
+     }
+     if (zero64(vhe->d_offset)) {
+       if (phi->p->cb_error)
+         (phi->p->cb_error)(DSERR_FMT, 1, phi->p->err_refcon,
+                            "Directory vnode %d is incomplete", vnum);
+       return DSERR_FMT;
+     }
+     if (r = xfseek(X, &vhe->d_offset)) {
+       if (phi->p->cb_error)
+         (phi->p->cb_error)(r, 1, phi->p->err_refcon,
+                            "Unable to seek to directory %d", vnum);
+       return r;
+     }
+     vnum = 0;
+     r = DirectoryLookup(X, phi->p, vhe->d_size, &name, &vnum, 0);
+     if (r) return r;
+     if (!vnum) {
+       if (phi->p->cb_error)
+         (phi->p->cb_error)(ENOENT, 1, phi->p->err_refcon,
+                            "No such vnode");
+       return ENOENT;
+     }
+   }
+   vhe = get_vhash_ent(phi, vnum, 0);
+   if (!vhe) {
+     if (phi->p->cb_error)
+       (phi->p->cb_error)(DSERR_FMT, 1, phi->p->err_refcon,
+                          "Vnode %d not found in hash table", vnum);
+     return DSERR_FMT;
+   }
+   if (his_vhe) *his_vhe = *vhe;
+   return 0;
+ }
+ 
+ 
+ afs_uint32 Path_Build(XFILE *X, path_hashinfo *phi, afs_uint32 vnode,
+                    char **his_path, int fast)
+ {
+   vhash_ent *vhe;
+   char *name, *path = 0, fastbuf[12];
+   char *x, *y;
+   afs_uint32 parent, r;
+   int nl, pl = 0;
+ 
+   if (vnode == 1) {
+     *his_path = (char *)malloc(2);
+     if (!his_path) {
+       if (phi->p->cb_error)
+         (phi->p->cb_error)(ENOMEM, 1, phi->p->err_refcon,
+                            "No memory for pathname of vnode 1");
+       return ENOMEM;
+     }
+     strcpy(*his_path, "/");
+     return 0;
+   }
+ 
+   *his_path = 0;
+   vhe = get_vhash_ent(phi, vnode, 0);
+   if (!vhe) {
+     if (phi->p->cb_error)
+       (phi->p->cb_error)(DSERR_FMT, 1, phi->p->err_refcon,
+                          "Vnode %d not found in hash table", vnode);
+     return DSERR_FMT;
+   }
+   while (vnode != 1) {
+     /* Find the parent */
+     if (!vhe->parent) {
+       if (phi->p->cb_error)
+         (phi->p->cb_error)(DSERR_FMT, 1, phi->p->err_refcon,
+                            "Vnode %d has no parent?", vnode);
+       if (path) free(path);
+       return DSERR_FMT;
+     }
+     parent = vhe->parent;
+     vhe = get_vhash_ent(phi, parent, 0);
+     if (phi->p->print_flags & DSPRINT_DEBUG)
+       fprintf(stderr, "Searching for vnode %d in parent %d\n", vnode, parent);
+     if (!vhe) {
+       if (phi->p->cb_error)
+         (phi->p->cb_error)(DSERR_FMT, 1, phi->p->err_refcon,
+                            "Vnode %d not found in hash table", parent);
+       if (path) free(path);
+       return DSERR_FMT;
+     }
+ 
+     if (fast) {
+       /* Make up a path component from the vnode number */
+       sprintf(fastbuf, "%d", vnode);
+       name = fastbuf;
+     } else {
+       /* Do a reverse-lookup in the parent directory */
+       if (zero64(vhe->d_offset)) {
+         if (phi->p->cb_error)
+           (phi->p->cb_error)(DSERR_FMT, 1, phi->p->err_refcon,
+                              "Directory vnode %d is incomplete", parent);
+         if (path) free(path);
+         return DSERR_FMT;
+       }
+       if (r = xfseek(X, &vhe->d_offset)) {
+         if (phi->p->cb_error)
+           (phi->p->cb_error)(errno, 1, phi->p->err_refcon,
+                              "Unable to seek to directory %d", parent);
+         if (path) free(path);
+         return r;
+       }
+ 
+       name = 0;
+       r = DirectoryLookup(X, phi->p, vhe->d_size, &name, &vnode, 0);
+       if (r) return r;
+       if (!name) {
+         if (phi->p->cb_error)
+           (phi->p->cb_error)(DSERR_FMT, 1, phi->p->err_refcon,
+                              "No entry for vnode %d in directory %d",
+                              vnode, parent);
+         if (path) free(path);
+         return ENOENT;
+       }
+     }
+ 
+     nl = strlen(name);
+     if (path) {
+       path = (char *)realloc(path, nl + pl + 2);
+       if (!path) {
+         if (phi->p->cb_error)
+           (phi->p->cb_error)(ENOMEM, 1, phi->p->err_refcon,
+                              "No memory for pathname of vnode 1");
+         return ENOMEM;
+       }
+       x = path + pl;
+       y = x + nl + 1;
+       while (x >= path) *y-- = *x--;
+       path[0] = '/';
+       for (x = name, y = path + 1; *x;) *y++ = *x++;
+       pl += nl + 1;
+     } else {
+       path = (char *)malloc(nl + 2);
+       if (!path) {
+         if (phi->p->cb_error)
+           (phi->p->cb_error)(ENOMEM, 1, phi->p->err_refcon,
+                              "No memory for pathname of vnode 1");
+         return ENOMEM;
+       }
+       path[0] = '/';
+       strcpy(path + 1, name);
+       pl = nl + 1;
+     }
+     if (!fast) free(name);
+     vnode = parent;
+   }
+   *his_path = path;
+   return 0;
+ }
Index: openafs/src/tests/pine.c
diff -c /dev/null openafs/src/tests/pine.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/pine.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,99 ----
+ /*
+  * Copyright (c) 2000 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <unistd.h>
+ #include <fcntl.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <sys/stat.h>
+ 
+ #include <err.h>
+ 
+ #define LOCK 		"mailbox-name.lock"
+ 
+ int
+ main(int argc, char *argv[])
+ {
+     int ret;
+     struct stat sb;
+     char unique[1024];
+     int retrycount = 0;
+ 
+ 
+     snprintf (unique, sizeof(unique), LOCK ".%d.%d",
+ 	      getpid(), (int)time(NULL));
+ 
+     ret = umask(077);
+     if (ret < 0)
+ 	err (1, "umask");
+ 
+     ret = open(unique, O_WRONLY|O_CREAT|O_EXCL, 0666);
+     if (ret < 0)
+ 	errx (1, "open");
+ 
+     close (ret);
+     
+  retry:
+     retrycount++;
+     if (retrycount > 10000000)
+ 	errx (1, "failed getting the lock");
+     ret = link(unique, LOCK);
+     if (ret < 0)
+ 	goto retry;
+     
+     ret = stat(unique, &sb);
+     if (ret < 0)
+ 	errx (1, "stat");
+     
+     if (sb.st_nlink != 2)
+ 	goto retry;
+ 
+     ret = chmod (LOCK, 0666);
+     if (ret < 0)
+ 	errx (1, "chmod");
+ 
+     ret = unlink (LOCK);
+     if (ret < 0)
+ 	err (1, "unlink " LOCK);
+ 
+     ret = unlink (unique);
+     if (ret < 0)
+ 	err (1, "unlink: %s", unique);
+ 
+     return 0;
+ }
Index: openafs/src/tests/primitive.c
diff -c /dev/null openafs/src/tests/primitive.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/primitive.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,165 ----
+ /*
+  * CMUCS AFStools
+  * dumpscan - routines for scanning and manipulating AFS volume dumps
+  *
+  * Copyright (c) 1998 Carnegie Mellon University
+  * All Rights Reserved.
+  * 
+  * Permission to use, copy, modify and distribute this software and its
+  * documentation is hereby granted, provided that both the copyright
+  * notice and this permission notice appear in all copies of the
+  * software, derivative works or modified versions, and any portions
+  * thereof, and that both notices appear in supporting documentation.
+  *
+  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+  *
+  * Carnegie Mellon requests users of this software to return to
+  *
+  *  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
+  *  School of Computer Science
+  *  Carnegie Mellon University
+  *  Pittsburgh PA 15213-3890
+  *
+  * any improvements or extensions that they make and grant Carnegie Mellon
+  * the rights to redistribute these changes.
+  */
+ 
+ /* primitive.c - Routines for reading and writing low-level things */
+ 
+ #include <sys/types.h>
+ #include <netinet/in.h>
+ #include <errno.h>
+ #include <stdlib.h>
+ #include <string.h>
+ 
+ #include "dumpscan.h"
+ 
+ #define BUFSIZE 256
+ 
+ 
+ afs_uint32 ReadByte(XFILE *X, unsigned char *val)
+ {
+   return xfread(X, val, 1);
+ }
+ 
+ afs_uint32 ReadInt16(XFILE *X, afs_uint16 *val)
+ {
+   afs_uint32 r;
+ 
+   if (r = xfread(X, val, 2)) return r;
+   *val = ntohs(*val);
+   return 0;
+ }
+ 
+ afs_uint32 ReadInt32(XFILE *X, afs_uint32 *val)
+ {
+   afs_uint32 r;
+ 
+   if (r = xfread(X, val, 4)) return r;
+   *val = ntohl(*val);
+   return 0;
+ }
+ 
+ /* Read in a NUL-terminated string.  This method is kind of messy, but
+  * has the advantage that it reads the data stream only once, doesn't
+  * read anything extra, and never has to seek on the data stream.
+  */
+ afs_uint32 ReadString(XFILE *X, unsigned char **val)
+ {
+   static unsigned char buf[BUFSIZE];
+   unsigned char *result = 0;
+   afs_uint32 r;
+   int i, l = 0;
+ 
+   *val = 0;
+   for (;;) {
+     for (i = 0; i < BUFSIZE; i++) {
+       r = ReadByte(X, buf + i);
+       if (r) {
+         if (result) free(result);
+         return r;
+       }
+       if (!buf[i]) break;
+     }
+     /* iff we found a null, i < BUFSIZE and buf[i] holds the NUL */
+     if (result) result = (unsigned char *)realloc(result, l + i + 1);
+     else result = (unsigned char *)malloc(i + 1);
+     if (!result) return ENOMEM;
+     memcpy(result + l, buf, i);
+     result[l+i] = 0;
+     l += i;
+     if (i < BUFSIZE) break;
+   }
+   *val = result;
+   return 0;
+ }
+ 
+ 
+ afs_uint32 WriteByte(XFILE *X, unsigned char val)
+ {
+   return xfwrite(X, &val, 1);
+ }
+ 
+ afs_uint32 WriteInt16(XFILE *X, afs_uint16 val)
+ {
+   val = htons(val);
+   return xfwrite(X, &val, 2);
+ }
+ 
+ afs_uint32 WriteInt32(XFILE *X, afs_uint32 val)
+ {
+   val = htonl(val);
+   return xfwrite(X, &val, 4);
+ }
+ 
+ afs_uint32 WriteString(XFILE *X, unsigned char *str)
+ {
+   int len = strlen((char *)str) + 1;
+   return xfwrite(X, str, len);
+ }
+ 
+ afs_uint32 WriteTagByte(XFILE *X, unsigned char tag, unsigned char val)
+ {
+   char buffer[2];
+   buffer[0] = tag;
+   buffer[1] = val;
+   return xfwrite(X, buffer, 2);
+ }
+ 
+ afs_uint32 WriteTagInt16(XFILE *X, unsigned char tag, afs_uint16 val)
+ {
+   char buffer[3];
+   buffer[0] = tag;
+   buffer[1] = (val & 0xff00) >> 8;
+   buffer[2] = val & 0xff;
+   return xfwrite(X, buffer, 3);
+ }
+ 
+ afs_uint32 WriteTagInt32(XFILE *X, unsigned char tag, afs_uint32 val)
+ {
+   char buffer[5];
+   buffer[0] = tag;
+   buffer[1] = (val & 0xff000000) >> 24;
+   buffer[2] = (val & 0xff0000) >> 16;
+   buffer[3] = (val & 0xff00) >> 8;
+   buffer[4] = val & 0xff;
+   return xfwrite(X, buffer, 5);
+ }
+ 
+ afs_uint32 WriteTagInt32Pair(XFILE *X, unsigned char tag,
+                              afs_uint32 val1, afs_uint32 val2)
+ {
+   char buffer[9];
+   buffer[0] = tag;
+   buffer[1] = (val1 & 0xff000000) >> 24;
+   buffer[2] = (val1 & 0xff0000) >> 16;
+   buffer[3] = (val1 & 0xff00) >> 8;
+   buffer[4] = val1 & 0xff;
+   buffer[5] = (val2 & 0xff000000) >> 24;
+   buffer[6] = (val2 & 0xff0000) >> 16;
+   buffer[7] = (val2 & 0xff00) >> 8;
+   buffer[8] = val2 & 0xff;
+   return xfwrite(X, buffer, 9);
+ }
Index: openafs/src/tests/ptsadduser.pl
diff -c /dev/null openafs/src/tests/ptsadduser.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/ptsadduser.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,17 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ &AFS_Init();
+ 
+ &AFS_pts_add([testuser1],[testgroup1],);
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/ptschown.pl
diff -c /dev/null openafs/src/tests/ptschown.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/ptschown.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,17 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ &AFS_Init();
+ 
+ &AFS_pts_chown(testgroup1,testuser1,);
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/ptscreategroup.pl
diff -c /dev/null openafs/src/tests/ptscreategroup.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/ptscreategroup.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,17 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ &AFS_Init();
+ 
+ &AFS_pts_creategroup(testgroup1,,);
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/ptscreateuser.pl
diff -c /dev/null openafs/src/tests/ptscreateuser.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/ptscreateuser.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,17 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ &AFS_Init();
+ 
+ &AFS_pts_createuser(testuser1,,);
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/ptsdeletegroup.pl
diff -c /dev/null openafs/src/tests/ptsdeletegroup.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/ptsdeletegroup.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,17 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ &AFS_Init();
+ 
+ &AFS_pts_delete([testgroup1],);
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/ptsdeleteuser.pl
diff -c /dev/null openafs/src/tests/ptsdeleteuser.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/ptsdeleteuser.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,17 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ &AFS_Init();
+ 
+ &AFS_pts_delete([testuser1],);
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/ptsexaminegroup.pl
diff -c /dev/null openafs/src/tests/ptsexaminegroup.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/ptsexaminegroup.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,27 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my (%info);
+ &AFS_Init();
+ 
+ %info = &AFS_pts_examine(testgroup1,);
+ if ($info{'creator'} ne "admin") {
+     exit(1);
+ }
+ if ($info{'mem_count'} != 1) {
+     exit(1);
+ }
+ if ($info{'owner'} ne "testuser1") {
+     exit(1);
+ }
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/ptsexamineuser.pl
diff -c /dev/null openafs/src/tests/ptsexamineuser.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/ptsexamineuser.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,24 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my (%info);
+ &AFS_Init();
+ 
+ %info = &AFS_pts_examine(testuser1,);
+ if ($info{'creator'} ne "admin") {
+     exit(1);
+ }
+ if ($info{'mem_count'} != 1) {
+     exit(1);
+ }
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/ptslistmax.pl
diff -c /dev/null openafs/src/tests/ptslistmax.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/ptslistmax.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,24 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my (@info);
+ &AFS_Init();
+ 
+ @info = &AFS_pts_listmax();
+ if ($info[0] != 100) {
+     exit(1);
+ }
+ if ($info[1] != -300) {
+     exit(1);
+ }
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/ptslistown.pl
diff -c /dev/null openafs/src/tests/ptslistown.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/ptslistown.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,23 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my (@owned, $group);
+ &AFS_Init();
+ 
+ @owned = &AFS_pts_listown(testuser1,);
+ while ($group = pop(@owned)) {
+     if ($group ne "testgroup1") {
+ 	exit(1);
+     }
+ }
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/ptsmembersgroup.pl
diff -c /dev/null openafs/src/tests/ptsmembersgroup.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/ptsmembersgroup.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,35 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my (@membership, $group);
+ &AFS_Init();
+ 
+ @membership = &AFS_pts_members(testgroup1,);
+ while ($group = pop(@membership)) {
+     if ($group ne "testuser1") {
+ 	exit(1);
+     }
+ }
+ &AFS_pts_add([admin],[testgroup1],);
+ @membership = &AFS_pts_members(testgroup1,);
+ while ($group = pop(@membership)) {
+     if ($group eq "testuser1") {
+     } else {
+ 	if ($group eq "admin") {
+ 	} else {
+ 	    exit(1);
+ 	}
+     }
+ }
+ &AFS_pts_remove([admin],["testgroup1"],);
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/ptsmembersuser.pl
diff -c /dev/null openafs/src/tests/ptsmembersuser.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/ptsmembersuser.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,35 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my (@membership, $group);
+ &AFS_Init();
+ 
+ @membership = &AFS_pts_members(testuser1,);
+ while ($group = pop(@membership)) {
+     if ($group ne "testgroup1") {
+ 	exit(1);
+     }
+ }
+ &AFS_pts_add([testuser1],["system:administrators"],);
+ @membership = &AFS_pts_members(testuser1,);
+ while ($group = pop(@membership)) {
+     if ($group eq "testgroup1") {
+     } else {
+ 	if ($group eq "system:administrators") {
+ 	} else {
+ 	    exit(1);
+ 	}
+     }
+ }
+ &AFS_pts_remove([testuser1],["system:administrators"],);
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/ptsremove.pl
diff -c /dev/null openafs/src/tests/ptsremove.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/ptsremove.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,17 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ &AFS_Init();
+ 
+ &AFS_pts_remove([testuser1],[testgroup1],);
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/ptssetf.pl
diff -c /dev/null openafs/src/tests/ptssetf.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/ptssetf.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,28 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my (%info);
+ &AFS_Init();
+ 
+ &AFS_pts_setf(testuser1,"S-M--",30,);
+ %info = &AFS_pts_examine(testuser1,);
+ if ($info{'creator'} ne "admin") {
+     exit(1);
+ }
+ if ($info{'flags'} ne "S-M--") {
+     exit(1);
+ }
+ if ($info{'group_quota'} != 30) {
+     exit(1);
+ }
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/ptssetmax.pl
diff -c /dev/null openafs/src/tests/ptssetmax.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/ptssetmax.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,17 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ &AFS_Init();
+ 
+ &AFS_pts_setmax(100,-300,);
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/read-vs-mmap.c
diff -c /dev/null openafs/src/tests/read-vs-mmap.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/read-vs-mmap.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,171 ----
+ /*
+  * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <sys/types.h>
+ #include <fcntl.h>
+ #include <time.h>
+ #include <unistd.h>
+ #include <string.h>
+ #include <sys/mman.h>
+ #include <sys/stat.h>
+ #include <err.h>
+ 
+ #ifdef RCSID
+ RCSID("$Id: read-vs-mmap.c,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $");
+ #endif
+ 
+ static int debug = 0;
+ 
+ static void
+ generate_file (const char *filename, int randomp, size_t sz)
+ {
+     int fd;
+     char *buf;
+     int i;
+ 
+     buf = malloc (sz);
+     if (buf == NULL)
+ 	err (1, "malloc %u", (unsigned)sz);
+ 
+     fd = open (filename, O_WRONLY | O_CREAT, 0666);
+     if (fd < 0)
+ 	err (1, "open %s", filename);
+ 
+     for (i = 0; i < sz; ++i)
+ 	if (randomp)
+ 	    buf[i] = rand();
+ 	else
+ 	    buf[0] = 0;
+ 
+     if (write (fd, buf, sz) != sz)
+ 	err (1, "write");
+     if (close (fd))
+ 	err (1, "close");
+     free (buf);
+ }
+ 
+ static unsigned char *
+ read_file (int fd, size_t sz)
+ {
+     unsigned char *buf;
+     ssize_t ret;
+ 
+     buf = malloc (sz);
+     if (buf == NULL)
+ 	err (1, "malloc %u", (unsigned)sz);
+     ret = read(fd, buf, sz);
+     if(ret < 0)
+       err(1, "read");
+     if(ret != sz)
+       errx(1, "short read %d < %u", (int)ret, (unsigned)sz);
+     return buf;
+ }
+ 
+ #ifndef MAP_FAILED
+ #define MAP_FAILED ((void *)-1)
+ #endif
+ 
+ static void *
+ mmap_file (int fd, size_t sz)
+ {
+     void *ret;
+ 
+     ret = mmap (0, sz, PROT_READ, MAP_PRIVATE, fd, 0);
+     if (ret == (void *)MAP_FAILED)
+ 	err (1, "mmap");
+     return ret;
+ }
+ 
+ static void __attribute__ ((__unused__))
+ print_area (unsigned char *ptr,  size_t len)
+ {
+     while (len--) {
+ 	printf ("%x", *ptr);
+ 	ptr++;
+     }
+ }
+ 
+ static int
+ do_test (int randomp)
+ {
+     unsigned char *malloc_buf;
+     void *mmap_buf;
+     int fd;
+     const char *file = "foo";
+     const size_t sz  = 16384;
+ 
+     generate_file (file, randomp, sz);
+ 
+     fd = open (file, O_RDONLY, 0);
+     if (fd < 0)
+ 	err (1, "open %s", file);
+ 
+     malloc_buf = read_file (fd, sz);
+     mmap_buf   = mmap_file (fd, sz);
+     close (fd);
+     unlink (file);
+     if (memcmp (malloc_buf, mmap_buf, sz) != 0) {
+ 	if (debug) {
+ 	    printf ("type: %s\n", randomp ? "random" : "allzero");
+ 	    printf ("read: ");
+ 	    print_area (malloc_buf, sz);
+ 	    printf ("\nmmap: ");
+ 	    print_area (mmap_buf, sz);
+ 	    printf ("\n");
+ 	}
+ 	return 1;
+     }
+     return 0;
+ }
+ 
+ int
+ main (int argc, char **argv)
+ {
+     if (argc != 1)
+ 	debug = 1;
+ 
+     srand (time(NULL));
+ 
+     if (do_test (0))
+ 	return 1;
+     if (do_test (1))
+ 	return 2;
+ 
+     return 0;
+ }
Index: openafs/src/tests/read-vs-mmap2.c
diff -c /dev/null openafs/src/tests/read-vs-mmap2.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/read-vs-mmap2.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,134 ----
+ /*
+  * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <sys/types.h>
+ #include <fcntl.h>
+ #include <time.h>
+ #include <unistd.h>
+ #include <string.h>
+ #include <sys/mman.h>
+ #include <sys/stat.h>
+ #include <err.h>
+ 
+ #ifdef RCSID
+ RCSID("$Id: read-vs-mmap2.c,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $");
+ #endif
+ 
+ static void
+ generate_random_file (const char *filename, size_t sz)
+ {
+     int fd;
+     char *buf;
+     int i;
+ 
+     buf = malloc (sz);
+     if (buf == NULL)
+ 	err (1, "malloc %u", (unsigned)sz);
+ 
+     fd = open (filename, O_WRONLY | O_CREAT, 0666);
+     if (fd < 0)
+ 	err (1, "open %s", filename);
+ 
+     for (i = 0; i < sz; ++i)
+ 	buf[i] = rand();
+ 
+     if (write (fd, buf, sz) != sz)
+ 	err (1, "write");
+     if (close (fd))
+ 	err (1, "close");
+     free (buf);
+ }
+ 
+ static char *
+ read_file (int fd, size_t sz)
+ {
+     char *buf;
+     ssize_t ret;
+ 
+     buf = malloc (sz);
+     if (buf == NULL)
+ 	err (1, "malloc %u", (unsigned)sz);
+     ret = read(fd, buf, sz);
+     if(ret < 0)
+         err(1, "read");
+     if(ret != sz)
+         errx(1, "short read %d < %u", (int)ret, (unsigned)sz);
+     return buf;
+ }
+ 
+ #ifndef MAP_FAILED
+ #define MAP_FAILED ((void *)-1)
+ #endif
+ 
+ static void *
+ mmap_file (int fd, size_t sz)
+ {
+     void *ret;
+ 
+     ret = mmap (0, sz, PROT_READ, MAP_SHARED, fd, 0);
+     if (ret == (void *)MAP_FAILED)
+ 	err (1, "mmap");
+     return ret;
+ }
+ 
+ int
+ main (int argc, char **argv)
+ {
+     const char *file = "foo";
+     const size_t sz  = 16384;
+     char *malloc_buf;
+     void *mmap_buf;
+     int fd;
+ 
+     srand (time(NULL));
+ 
+     generate_random_file (file, sz);
+ 
+     fd = open (file, O_RDONLY, 0);
+     if (fd < 0)
+ 	err (1, "open %s", file);
+ 
+     malloc_buf = read_file (fd, sz);
+     mmap_buf   = mmap_file (fd, sz);
+     close (fd);
+     unlink (file);
+     if (memcmp (malloc_buf, mmap_buf, sz) != 0)
+ 	return 1;
+     return 0;
+ }
Index: openafs/src/tests/read-write.c
diff -c /dev/null openafs/src/tests/read-write.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/read-write.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,147 ----
+ /*
+  * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <sys/types.h>
+ #include <fcntl.h>
+ #include <time.h>
+ #include <unistd.h>
+ #include <string.h>
+ #include <sys/mman.h>
+ #include <sys/stat.h>
+ #include <err.h>
+ 
+ #ifdef RCSID
+ RCSID("$Id: read-write.c,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $");
+ #endif
+ 
+ static char *
+ write_random_file (int fd, size_t sz)
+ {
+     char *buf;
+     int i;
+ 
+     buf = malloc (sz);
+     if (buf == NULL)
+ 	err (1, "malloc %u", (unsigned)sz);
+ 
+     for (i = 0; i < sz; ++i)
+ 	buf[i] = rand();
+ 
+     if (write (fd, buf, sz) != sz)
+ 	err (1, "write");
+ 
+     return buf;
+ }
+ 
+ static void
+ write_null_file (int fd, size_t sz)
+ {
+     char *buf;
+     int i;
+ 
+     buf = malloc (sz);
+     if (buf == NULL)
+ 	err (1, "malloc %u", (unsigned)sz);
+ 
+     for (i = 0; i < sz; ++i)
+ 	buf[i] = 0;
+ 
+     if (write (fd, buf, sz) != sz)
+ 	err (1, "write");
+ 
+     free (buf);
+ }
+ 
+ static char *
+ read_file (int fd, size_t sz)
+ {
+     char *buf;
+     ssize_t ret;
+ 
+     buf = malloc (sz);
+     if (buf == NULL)
+ 	err (1, "malloc %u", (unsigned)sz);
+     ret = read(fd, buf, sz);
+     if(ret < 0)
+ 	err (1, "read");
+     else if(ret == 0)
+         errx(1, "EOF on read");
+     return buf;
+ }
+ 
+ #ifndef MAP_FAILED
+ #define MAP_FAILED ((void *)-1)
+ #endif
+ 
+ int
+ main (int argc, char **argv)
+ {
+     const char *file = "foo";
+     const size_t sz  = 16384;
+     char *random_buf;
+     char *read_buf1;
+     char *read_buf2;
+     int fd;
+ 
+ 
+     srand (time(NULL));
+ 
+     fd = open (file, O_RDWR | O_CREAT, 0);
+     if (fd < 0)
+ 	err (1, "open %s", file);
+ 
+     if (lseek(fd, 0, SEEK_SET) < 0)
+ 	err (1, "lseek");
+     write_null_file(fd, sz);
+     if (lseek(fd, 0, SEEK_SET) < 0)
+ 	err (1, "lseek");
+     read_buf1 = read_file (fd, sz);
+     if (lseek(fd, 0, SEEK_SET) < 0)
+ 	err (1, "lseek");
+     random_buf = write_random_file(fd, sz);
+     if (lseek(fd, 0, SEEK_SET) < 0)
+ 	err (1, "lseek");
+     read_buf2 = read_file (fd, sz);
+ 
+     close (fd);
+     unlink (file);
+     if (memcmp (random_buf, read_buf2, sz) != 0)
+ 	return 1;
+     return 0;
+ }
Index: openafs/src/tests/readdir-vs-lstat.c
diff -c /dev/null openafs/src/tests/readdir-vs-lstat.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/readdir-vs-lstat.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,102 ----
+ /*
+  * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <dirent.h>
+ #include <errno.h>
+ 
+ #include <err.h>
+ 
+ #ifdef RCSID
+ RCSID("$Id: readdir-vs-lstat.c,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $");
+ #endif
+ 
+ static int
+ verify_inodes (const char *dirname)
+ {
+     DIR *d;
+     struct dirent *dp;
+     
+     if (chdir (dirname) < 0)
+ 	err (1, "chdir %s", dirname);
+ 
+     d = opendir (".");
+     if (d == NULL)
+ 	err (1, "opendir %s", dirname);
+     while ((dp = readdir (d)) != NULL) {
+ 	struct stat sb;
+ 
+ 	if (lstat (dp->d_name, &sb) < 0) {
+ 	    if (errno == EACCES)
+ 		continue;
+ 	    err (1, "lstat %s", dp->d_name);
+ 	}
+ 	if (dp->d_ino != sb.st_ino)
+ 	    errx (1, "%s: inode %u != %u", dp->d_name,
+ 		  (unsigned)dp->d_ino, (unsigned)sb.st_ino);
+     }
+     closedir (d);
+     return 0;
+ }
+ 
+ static void
+ usage (int ret)
+ {
+     fprintf (stderr, "%s [directory]\n", __progname);
+     exit (ret);
+ }
+ 
+ int
+ main(int argc, char **argv)
+ {
+     char *name = ".";
+ 
+ 
+     if (argc > 2)
+ 	usage (1);
+ 
+     if (argc > 1)
+ 	name = argv[1];
+ 
+     return verify_inodes (name);
+ }
Index: openafs/src/tests/readfile-wo-create
diff -c /dev/null openafs/src/tests/readfile-wo-create:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/readfile-wo-create	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,3 ----
+ #!/bin/sh
+ FOO=`cat $AFSROOT/stacken.kth.se/ftp/pub/arla/tests/used-by-arla-check`
+ test "X"$FOO = "Xfoo" || exit 1
Index: openafs/src/tests/reauth.pl
diff -c /dev/null openafs/src/tests/reauth.pl:1.2.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/reauth.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,12 ----
+ #!/usr/bin/env perl
+ use Term::ReadLine;
+ use strict;
+ use OpenAFS::ConfigUtils;
+ use OpenAFS::Dirpath;
+ use OpenAFS::OS;
+ use OpenAFS::Auth;
+ use Getopt::Long;
+ use vars qw($admin $server $cellname $cachesize $part
+           $requirements_met  $shutdown_needed $csdb);
+ 
+ &OpenAFS::Auth::authadmin();
Index: openafs/src/tests/rename-under-feet.c
diff -c /dev/null openafs/src/tests/rename-under-feet.c:1.2.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/rename-under-feet.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,168 ----
+ /*
+  * Copyright (c) 2000 - 2001 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <errno.h>
+ #include <signal.h>
+ 
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <sys/wait.h>
+ #include <unistd.h>
+ #include <dirent.h>
+ 
+ #include <err.h>
+ 
+ #define RETSIGTYPE void
+ 
+ static void
+ emkdir (const char *path, mode_t mode)
+ {
+     int ret = mkdir (path, mode);
+     if (ret < 0)
+ 	err (1, "mkdir %s", path);
+ }
+ 
+ static pid_t child_pid;
+ 
+ static sig_atomic_t term_sig = 0;
+ 
+ static RETSIGTYPE
+ child_sigterm (int signo)
+ {
+     term_sig = 1;
+ }
+ 
+ static int
+ child_chdir (const char *path)
+ {
+     int ret;
+     int pfd[2];
+ 
+     ret = pipe (pfd);
+     if (ret < 0)
+ 	err (1, "pipe");
+ 
+     child_pid = fork ();
+     if (child_pid < 0)
+ 	err (1, "fork");
+     if (child_pid != 0) {
+ 	close (pfd[1]);
+ 	return pfd[0];
+     } else {
+ 	char buf[256];
+ 	struct sigaction sa;
+ 	FILE *fp;
+ 
+ 	sa.sa_handler = child_sigterm;
+ 	sigfillset(&sa.sa_mask);
+ 	sa.sa_flags = 0;
+ 	sigaction (SIGTERM, &sa, NULL);
+ 
+ 	close (pfd[0]);
+ 	ret = chdir (path);
+ 	if (ret < 0)
+ 	    err (1, "chdir %s", path);
+ 	ret = write (pfd[1], "", 1);
+ 	if (ret != 1)
+ 	    err (1, "write");
+ 	while (!term_sig)
+ 	    pause ();
+ #if 0
+ 	if(getcwd (buf, sizeof(buf)) == NULL)
+ 	    err (1, "getcwd");
+ #endif
+ 	fp = fdopen (4, "w");
+ 	if (fp != NULL)
+ 	    fprintf (fp, "child: cwd = %s\n", buf);
+ 	exit (0);
+     }
+ }
+ 
+ static void
+ kill_child (void)
+ {
+     kill (child_pid, SIGTERM);
+ }
+ 
+ int
+ main (int argc, char **argv)
+ {
+     struct stat sb;
+     int ret;
+     int fd;
+     char buf[1];
+     int status;
+ 
+ 
+     emkdir ("one", 0777);
+     emkdir ("two", 0777);
+     emkdir ("one/a", 0777);
+ 
+     fd = child_chdir ("one/a");
+     atexit (kill_child);
+     ret = read (fd, buf, 1);
+     if (ret < 0)
+         err(1, "read");
+     if (ret == 0)
+         errx(1, "EOF on read");
+ 
+     ret = rename ("one/a", "two/a");
+     if (ret < 0)
+ 	err (1, "rename one/a two");
+     ret = lstat ("two/a", &sb);
+     if (ret < 0)
+ 	err (1, "lstat two/a");
+     ret = lstat ("one/a", &sb);
+     if (ret != -1 || errno != ENOENT)
+ 	errx (1, "one/a still exists");
+     kill_child ();
+     waitpid (child_pid, &status, 0);
+     ret = lstat ("one/a", &sb);
+     if (ret != -1 || errno != ENOENT)
+ 	errx (1, "one/a still exists after child");
+     if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
+ 	rmdir ("one/a");
+ 	rmdir ("two/a");
+ 	rmdir ("one");
+ 	rmdir ("two");
+ 	return 0;
+     } else
+ 	return 1;
+ }
Index: openafs/src/tests/rename1
diff -c /dev/null openafs/src/tests/rename1:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/rename1	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,7 ----
+ #!/bin/sh
+ # $Id: rename1,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ touch foo || exit 1
+ mv foo bar || exit 1
+ test -f foo && exit 1
+ test -f bar || exit 1
+ rm bar || exit 1
Index: openafs/src/tests/rename2
diff -c /dev/null openafs/src/tests/rename2:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/rename2	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,7 ----
+ #!/bin/sh
+ # $Id: rename2,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ touch foo bar || exit 1
+ mv foo bar || exit 1
+ test -f foo && exit 1
+ test -f bar || exit 1
+ rm bar || exit 1
Index: openafs/src/tests/rename3
diff -c /dev/null openafs/src/tests/rename3:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/rename3	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,9 ----
+ #!/bin/sh
+ # $Id: rename3,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ echo foo > foo || exit 1
+ sed 's/foo/bar/' foo > bar || exit 1
+ rm foo || exit 1
+ test -f foo && exit 1
+ mv bar foo || exit 1
+ test -f bar && exit 1
+ test -f foo || exit 1
Index: openafs/src/tests/rename4
diff -c /dev/null openafs/src/tests/rename4:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/rename4	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,9 ----
+ #!/bin/sh
+ # $Id: rename4,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ mkdir old_parent new_parent old_parent/victim || exit 1
+ mv old_parent/victim new_parent || exit 1
+ test -d old_parent || exit 1
+ test -d new_parent || exit 1
+ test -d old_parent/victim && exit 1
+ test -d new_parent/victim || exit 1
+ rmdir new_parent/victim new_parent old_parent
Index: openafs/src/tests/rename5.c
diff -c /dev/null openafs/src/tests/rename5.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/rename5.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,105 ----
+ /*
+  * Copyright (c) 2000 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <errno.h>
+ 
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <sys/mman.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <dirent.h>
+ 
+ 
+ #include <err.h>
+ 
+ static void
+ emkdir (const char *path, mode_t mode)
+ {
+     int ret;
+ 
+     ret = mkdir (path, mode);
+     if (ret < 0)
+ 	err (1, "mkdir %s", path);
+ }
+ 
+ static void
+ elstat (const char *path, struct stat *sb)
+ {
+     int ret;
+ 
+     ret = lstat (path, sb);
+     if (ret < 0)
+ 	err (1, "lstat %s", path);
+ }
+ 
+ static void
+ check_inum (const struct stat *sb1, const struct stat *sb2)
+ {
+     if (sb1->st_ino != sb2->st_ino)
+ 	errx (1, "wrong inode-number %u != %u",
+ 	      (unsigned)sb1->st_ino, (unsigned)sb2->st_ino);
+ }
+ 
+ int
+ main(int argc, char **argv)
+ {
+     int ret;
+     struct stat old_sb, new_sb, dot_sb;
+ 
+     emkdir ("old_parent", 0777);
+     emkdir ("new_parent", 0777);
+     emkdir ("old_parent/victim", 0777);
+ 
+     elstat ("old_parent", &old_sb);
+     elstat ("new_parent", &new_sb);
+     elstat ("old_parent/victim/..", &dot_sb);
+     check_inum (&old_sb, &dot_sb);
+ 
+     ret = rename("old_parent/victim", "new_parent/victim");
+     if (ret < 0)
+ 	err (1, "rename old_parent/victim new_parent/victim");
+ 
+     elstat ("new_parent/victim/..", &dot_sb);
+ 
+     check_inum (&new_sb, &dot_sb);
+ 
+     return 0;
+ }
Index: openafs/src/tests/rename6.c
diff -c /dev/null openafs/src/tests/rename6.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/rename6.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,73 ----
+ /*
+  * Copyright (c) 2000 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <errno.h>
+ 
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <sys/mman.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <dirent.h>
+ 
+ 
+ #include <err.h>
+ 
+ int
+ main(int argc, char **argv)
+ {
+     int ret;
+     int fd;
+     struct stat old_sb, new_sb, dot_sb;
+ 
+     fd = open("foo", O_RDWR|O_CREAT|O_TRUNC, 0644);
+     if (fd < 0)
+ 	err (1, "open1");
+     ret = close (fd);
+     if (ret < 0)
+ 	err (1, "close1");
+ 
+     ret = rename("foo", "../../service/foo");
+     if (ret == 0)
+ 	err (1, "rename didn't fail");
+ 
+     unlink("foo");
+     return 0;
+ }
Index: openafs/src/tests/repair.c
diff -c /dev/null openafs/src/tests/repair.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/repair.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,366 ----
+ /*
+  * CMUCS AFStools
+  * dumpscan - routines for scanning and manipulating AFS volume dumps
+  *
+  * Copyright (c) 1998 Carnegie Mellon University
+  * All Rights Reserved.
+  * 
+  * Permission to use, copy, modify and distribute this software and its
+  * documentation is hereby granted, provided that both the copyright
+  * notice and this permission notice appear in all copies of the
+  * software, derivative works or modified versions, and any portions
+  * thereof, and that both notices appear in supporting documentation.
+  *
+  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+  *
+  * Carnegie Mellon requests users of this software to return to
+  *
+  *  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
+  *  School of Computer Science
+  *  Carnegie Mellon University
+  *  Pittsburgh PA 15213-3890
+  *
+  * any improvements or extensions that they make and grant Carnegie Mellon
+  * the rights to redistribute these changes.
+  */
+ 
+ /* repair.c - Routines to generate a repaired dump */
+ 
+ #include <sys/types.h>
+ #include <netinet/in.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <errno.h>
+ 
+ #include "dumpscan.h"
+ #include "dumpscan_errs.h"
+ #include "dumpfmt.h"
+ 
+ #include <afs/acl.h>
+ #include <afs/dir.h>
+ #include <afs/prs_fs.h>
+ 
+ XFILE repair_output;
+ int repair_verbose;
+ #define RV repair_verbose
+ 
+ 
+ /* Try to dump a dump header.  Generate missing fields, if neccessary */
+ afs_uint32 repair_dumphdr_cb(afs_dump_header *hdr, XFILE *X, void *refcon)
+ {
+   afs_uint32 r, field_mask = hdr->field_mask;
+   char volname[22];
+ 
+   if (!(field_mask & F_DUMPHDR_VOLID)) {
+     if (RV) fprintf(stderr, ">>> DUMP HEADER missing volume ID\n");
+     return DSERR_FMT;
+   }
+   if (!(field_mask & F_DUMPHDR_VOLNAME)) {
+     if (RV) {
+       fprintf(stderr, ">>> DUMP HEADER missing volume name\n");
+       fprintf(stderr, ">>> Will use RESTORED.%d\n", hdr->volid);
+     }
+     sprintf(volname, "RESTORED.%d", hdr->volid);
+     hdr->volname = (unsigned char *)malloc(strlen(volname) + 1);
+     if (!hdr->volname) return ENOMEM;
+     strcpy(hdr->volname, volname);
+     hdr->field_mask |= F_DUMPHDR_VOLNAME;
+   }
+   if (!(field_mask & F_DUMPHDR_FROM)) {
+     if (RV) fprintf(stderr, ">>> DUMP HEADER missing from time (using 0)\n");
+     hdr->from_date = 0;
+     hdr->field_mask |= F_DUMPHDR_FROM;
+   }
+   if (!(field_mask & F_DUMPHDR_TO)) {
+     hdr->to_date = time(0);
+     if (RV) fprintf(stderr, ">>> DUMP HEADER missing from time (using %d)\n",
+       hdr->to_date);
+     hdr->field_mask |= F_DUMPHDR_TO;
+   }
+ 
+   return DumpDumpHeader(&repair_output, hdr);
+ }
+ 
+ 
+ /* Try to dump a volume header.  Generate missing fields, if necessary */
+ afs_uint32 repair_volhdr_cb(afs_vol_header *hdr, XFILE *X, void *refcon)
+ {
+   afs_uint32 r, field_mask = hdr->field_mask;
+   char volname[22];
+ 
+   if (!(field_mask & F_VOLHDR_VOLID)) {
+     if (RV) fprintf(stderr, ">>> VOL HEADER missing volume ID\n");
+     return DSERR_FMT;
+   }
+   if (!(field_mask & F_VOLHDR_VOLVERS)) {
+     if (RV) fprintf(stderr, ">>> VOL HEADER missing version (using 1)\n");
+     hdr->volvers = 1;
+     hdr->field_mask |= F_VOLHDR_VOLVERS;
+   } else if (hdr->volvers != 1) {
+     if (RV) fprintf(stderr, ">>> VOL HEADER bogus version %d (using 1)\n",
+             hdr->volvers);
+     hdr->volvers = 1;
+   }
+   if (!(field_mask & F_VOLHDR_VOLNAME)) {
+     if (RV) {
+       fprintf(stderr, ">>> VOL HEADER missing volume name\n");
+       fprintf(stderr, ">>> Will use RESTORED.%d\n", hdr->volid);
+     }
+     sprintf(volname, "RESTORED.%d", hdr->volid);
+     hdr->volname = (unsigned char *)malloc(strlen(volname) + 1);
+     if (!hdr->volname) return ENOMEM;
+     strcpy(hdr->volname, volname);
+     hdr->field_mask |= F_VOLHDR_VOLNAME;
+   }
+   if (!(field_mask & F_VOLHDR_INSERV)) {
+     if (RV)
+       fprintf(stderr, ">>> VOL HEADER missing in-service flag (using 1)\n");
+     hdr->flag_inservice = 1;
+     hdr->field_mask |= F_VOLHDR_INSERV;
+   }
+   if (!(field_mask & F_VOLHDR_BLESSED)) {
+     if (RV) fprintf(stderr, ">>> VOL HEADER missing blessed flag (using 1)\n");
+     hdr->flag_blessed = 1;
+     hdr->field_mask |= F_VOLHDR_BLESSED;
+   }
+   if (!(field_mask & F_VOLHDR_VOLUNIQ)) {
+     if (RV) fprintf(stderr, ">>> VOL HEADER missing uniquifier (using 1)\n");
+     hdr->voluniq = 1;
+     hdr->field_mask |= F_VOLHDR_VOLUNIQ;
+   }
+   if (!(field_mask & F_VOLHDR_VOLTYPE)) {
+     if (RV) fprintf(stderr, ">>> VOL HEADER missing type (using 0: RW)\n");
+     hdr->voltype = 0;
+     hdr->field_mask |= F_VOLHDR_VOLTYPE;
+   } else if (hdr->voltype < 0 || hdr->voltype > 2) {
+     if (RV) fprintf(stderr, ">>> VOL HEADER bogus type %d (using 0: RW)\n",
+             hdr->voltype);
+     hdr->voltype = 0;
+   }
+   if (!(field_mask & F_VOLHDR_PARENT)) {
+     if (RV) fprintf(stderr, ">>> VOL HEADER parent (using %d)\n", hdr->volid);
+     hdr->parent_volid = hdr->volid;
+     hdr->field_mask |= F_VOLHDR_PARENT;
+   }
+   if (!(field_mask & F_VOLHDR_MAXQ)) {
+     if (field_mask & F_VOLHDR_DISKUSED) hdr->maxquota = hdr->diskused;
+     else hdr->maxquota = 1;
+     if (RV) fprintf(stderr, ">>> VOL HEADER missing max quota (using %d)\n",
+             hdr->maxquota);
+     hdr->field_mask |= F_VOLHDR_MAXQ;
+   }
+   if (!(field_mask & F_VOLHDR_DISKUSED)) {
+     if (RV) fprintf(stderr, ">>> VOL HEADER missing disk used (using 2048)\n");
+     hdr->diskused = 2048;
+     hdr->field_mask |= F_VOLHDR_DISKUSED;
+   }
+   if (!(field_mask & F_VOLHDR_NFILES)) {
+     if (RV) fprintf(stderr, ">>> VOL HEADER missing file count (using 1)\n");
+     hdr->nfiles = 1;
+     hdr->field_mask |= F_VOLHDR_NFILES;
+   }
+   if (!(field_mask & F_VOLHDR_CREATE_DATE)) {
+     hdr->create_date = 0;
+     if ((field_mask & F_VOLHDR_ACCESS_DATE)
+     &&  (!hdr->create_date || hdr->access_date < hdr->create_date))
+       hdr->create_date = hdr->access_date;
+     if ((field_mask & F_VOLHDR_UPDATE_DATE)
+     &&  (!hdr->create_date || hdr->update_date < hdr->create_date))
+       hdr->create_date = hdr->update_date;
+     if ((field_mask & F_VOLHDR_BACKUP_DATE)
+     &&  (!hdr->create_date || hdr->backup_date < hdr->create_date))
+       hdr->create_date = hdr->backup_date;
+ 
+     if (RV) fprintf(stderr, ">>> VOL HEADER missing create date (using %d)\n",
+             hdr->create_date);
+     hdr->field_mask |= F_VOLHDR_CREATE_DATE;
+   }
+   if (!(field_mask & F_VOLHDR_ACCESS_DATE)) {
+     hdr->access_date = 0;
+     if ((field_mask & F_VOLHDR_CREATE_DATE)
+     &&  (!hdr->access_date || hdr->create_date > hdr->access_date))
+       hdr->access_date = hdr->create_date;
+     if ((field_mask & F_VOLHDR_UPDATE_DATE)
+     &&  (!hdr->access_date || hdr->update_date > hdr->access_date))
+       hdr->access_date = hdr->update_date;
+     if ((field_mask & F_VOLHDR_BACKUP_DATE)
+     &&  (!hdr->access_date || hdr->backup_date > hdr->access_date))
+       hdr->access_date = hdr->backup_date;
+ 
+     if (RV) fprintf(stderr, ">>> VOL HEADER missing access date (using %d)\n",
+             hdr->access_date);
+     hdr->field_mask |= F_VOLHDR_ACCESS_DATE;
+   }
+   if (!(field_mask & F_VOLHDR_UPDATE_DATE)) {
+     hdr->update_date = 0;
+     if ((field_mask & F_VOLHDR_CREATE_DATE)
+     &&  (!hdr->update_date || hdr->create_date > hdr->update_date))
+       hdr->update_date = hdr->create_date;
+     if ((field_mask & F_VOLHDR_ACCESS_DATE) && !hdr->update_date)
+       hdr->update_date = hdr->access_date;
+     if ((field_mask & F_VOLHDR_BACKUP_DATE) && !hdr->update_date)
+       hdr->update_date = hdr->backup_date;
+ 
+     if (RV) fprintf(stderr, ">>> VOL HEADER missing update date (using %d)\n",
+             hdr->update_date);
+     hdr->field_mask |= F_VOLHDR_UPDATE_DATE;
+   }
+ 
+   return DumpVolumeHeader(&repair_output, hdr);
+ }
+ 
+ 
+ /* Try to dump a vnode.  Generate missing fields, if necessary */
+ afs_uint32 repair_vnode_cb(afs_vnode *v, XFILE *X, void *refcon)
+ {
+   afs_uint32 r, field_mask = v->field_mask;
+ 
+   if ((v->vnode & 1) && !field_mask) {
+     if (RV) fprintf(stderr, ">>> VNODE %d is directory but has no fields?\n");
+     v->type = vDirectory;
+     v->field_mask |= F_VNODE_TYPE;
+     field_mask = F_VNODE_TYPE; /* Messy! */
+   }
+   if (field_mask && !(field_mask & F_VNODE_TYPE)) {
+     v->type = (v->vnode & 1) ? vDirectory : vFile;
+     if (RV) fprintf(stderr, ">>> VNODE %d missing type (using %d)\n",
+             v->vnode, v->type);
+     v->field_mask |= F_VNODE_TYPE;
+   }
+   if (field_mask && !(field_mask & F_VNODE_NLINKS)) {
+     if (RV)
+       fprintf(stderr, ">>> VNODE %d missing link count (using 1)\n", v->vnode);
+     v->nlinks = 1;
+     v->field_mask |= F_VNODE_NLINKS;
+   }
+   if (field_mask && !(field_mask & F_VNODE_PARENT)) {
+     if (RV)
+       fprintf(stderr, ">>> VNODE %d missing parent (using 1)\n", v->vnode);
+     v->parent = 1;
+     v->field_mask |= F_VNODE_PARENT;
+   }
+   if (field_mask && !(field_mask & F_VNODE_DVERS)) {
+     if (RV) fprintf(stderr, ">>> VNODE %d missing data version (using 1)\n",
+               v->vnode);
+     v->datavers = 1;
+     v->field_mask |= F_VNODE_DVERS;
+   }
+   if (field_mask && !(field_mask & F_VNODE_AUTHOR)) {
+     if (field_mask & F_VNODE_OWNER) v->author = v->owner;
+     else v->author = 0;
+     if (RV) fprintf(stderr, ">>> VNODE %d missing author (using %d)\n",
+             v->vnode, v->author);
+     v->field_mask |= F_VNODE_AUTHOR;
+   }
+   if (field_mask && !(field_mask & F_VNODE_OWNER)) {
+     if (field_mask & F_VNODE_AUTHOR) v->owner = v->author;
+     else v->owner = 0;
+     if (RV) fprintf(stderr, ">>> VNODE %d missing owner (using %d)\n",
+             v->vnode, v->owner);
+     v->field_mask |= F_VNODE_OWNER;
+   }
+   if (field_mask && !(field_mask & F_VNODE_MODE)) {
+     v->mode = (v->vnode & 1) ? 0755 : 0644;
+     if (RV) fprintf(stderr, ">>> VNODE missing mode (using %d)\n", v->mode);
+     v->field_mask |= F_VNODE_MODE;
+   }
+   if (field_mask && !(field_mask & F_VNODE_CDATE)) {
+     if (field_mask & F_VNODE_SDATE) v->client_date = v->server_date;
+     else v->client_date = 0;
+ 
+     if (RV) fprintf(stderr, ">>> VNODE %d missing client date (using %d)\n",
+             v->vnode, v->client_date);
+     v->field_mask |= F_VNODE_CDATE;
+   }
+   if (field_mask && !(field_mask & F_VNODE_SDATE)) {
+     if (field_mask & F_VNODE_CDATE) v->server_date = v->client_date;
+     else v->server_date = 0;
+ 
+     if (RV) fprintf(stderr, ">>> VNODE %d missing server date (using %d)\n",
+             v->vnode, v->server_date);
+     v->field_mask |= F_VNODE_SDATE;
+   }
+   if (field_mask && !(field_mask & F_VNODE_SIZE)) {
+     if (RV) fprintf(stderr, ">>> VNODE %d has no data size (using 0)\n");
+     v->size = 0;
+     v->field_mask |= F_VNODE_SIZE;
+   }
+   if ((field_mask & F_VNODE_DATA) && !v->size) {
+     if (RV)
+       fprintf(stderr, ">>> VNODE %d has data, but size == 0 (ignoring)\n",
+             v->vnode);
+     v->field_mask &=~ F_VNODE_DATA;
+   }
+   if (field_mask && v->type == vDirectory && !(field_mask & F_VNODE_ACL)) {
+     struct acl_accessList *acl = (struct acl_accessList *)v->acl;
+     if (RV) {
+       fprintf(stderr, ">>> VNODE %d is directory but has no ACL\n");
+       fprintf(stderr, ">>> Will generate default ACL\n");
+     }
+     memset(v->acl, 0, SIZEOF_LARGEDISKVNODE - SIZEOF_SMALLDISKVNODE);
+     acl->size = htonl(SIZEOF_LARGEDISKVNODE - SIZEOF_SMALLDISKVNODE);
+     acl->version = htonl(ACL_ACLVERSION);
+     acl->total = htonl(v->owner ? 0 : 1);
+     acl->positive = acl->total;
+     acl->negative = 0;
+     if (v->owner) {
+       acl->entries[0].id = htonl(v->owner);
+       acl->entries[0].rights = htonl((PRSFS_READ   | PRSFS_WRITE
+                                     | PRSFS_INSERT | PRSFS_LOOKUP
+                                     | PRSFS_DELETE | PRSFS_LOCK
+                                     | PRSFS_ADMINISTER));
+     }
+     v->field_mask |= F_VNODE_ACL;
+   }
+ 
+   r = DumpVNode(&repair_output, v);
+   if (r) return r;
+ 
+   if (v->size) {
+     if (r = xfseek(X, &v->d_offset)) return r;
+     r = CopyVNodeData(&repair_output, X, v->size);
+   } else if (v->type == vDirectory) {
+     afs_dir_page page;
+     struct DirHeader *dhp = (struct DirHeader *)&page;
+     int i;
+ 
+     if (RV) {
+       fprintf(stderr, ">>> VNODE %d is directory but has no contents\n");
+       fprintf(stderr, ">>> Will generate deafult directory entries\n");
+     }
+     memset(&page, 0, sizeof(page));
+ 
+     /* Page and Directory Headers */
+     page.header.tag = htons(1234);
+     page.header.freecount = (EPP - DHE - 3);
+     page.header.freebitmap[0] = 0xff;
+     page.header.freebitmap[1] = 0x7f;
+     dhp->alloMap[0] = EPP - DHE - 3;
+     for (i = 1; i < MAXPAGES; i++) dhp->alloMap[i] = EPP;
+ 
+     /* Entry for . */
+     page.entry[DHE + 1].flag    = FFIRST;
+     page.entry[DHE + 1].length  = 1;
+     page.entry[DHE + 1].vnode   = v->vnode;
+     page.entry[DHE + 1].vunique = v->vuniq;
+     strcpy(page.entry[DHE + 1].name, ".");
+     dhp->hashTable[0x2e] = DHE + 1;
+ 
+     /* Entry for .. */
+     page.entry[DHE + 2].flag    = FFIRST;
+     page.entry[DHE + 2].length  = 1;
+     page.entry[DHE + 2].vnode   = v->parent;
+     page.entry[DHE + 2].vunique = 1;         /* Can't have everything! */
+     strcpy(page.entry[DHE + 2].name, "..");
+     dhp->hashTable[0x44] = DHE + 2;
+ 
+     r = DumpVNodeData(&repair_output, (char *)&page, 2048);
+   } else if (field_mask) {
+     /* We wrote out attributes, so we should also write the 0-length data */
+     r = DumpVNodeData(&repair_output, "", 0);
+   }
+ 
+   return r;
+ }
Index: openafs/src/tests/rewrite-emacs
diff -c /dev/null openafs/src/tests/rewrite-emacs:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/rewrite-emacs	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,10 ----
+ #!/bin/sh
+ # $Id: rewrite-emacs,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ if test "X$FAST" != "X" ; then echo "Not running $0" ;  exit 0 ; fi
+ emacsver=20.7
+ gzip -dc ${AFSROOT}/stacken.kth.se/ftp/pub/gnu/emacs/emacs-${emacsver}.tar.gz |
+ tar vxf - >&4 2>&1 || exit 1
+ find emacs-${emacsver} -size 0 -print | xargs rm || exit 1
+ find emacs-${emacsver} -print | xargs chmod u+w || exit 1
+ $objdir/truncate-files emacs-${emacsver} || exit 1
+ exit 0
Index: openafs/src/tests/rm-rf.c
diff -c /dev/null openafs/src/tests/rm-rf.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/rm-rf.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,128 ----
+ /*
+  * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <dirent.h>
+ 
+ #include <err.h>
+ 
+ #ifdef RCSID
+ RCSID("$Id: rm-rf.c,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $");
+ #endif
+ 
+ static void
+ kill_one (const char *filename);
+ 
+ static void
+ kill_dir (const char *dirname);
+ 
+ static void
+ do_dir (const char *dirname);
+ 
+ static void
+ kill_one (const char *filename)
+ {
+     int ret;
+ 
+     ret = unlink (filename);
+     if (ret < 0) {
+ 	if (errno == EISDIR || errno == EPERM)
+ 	    do_dir (filename);
+ 	else
+ 	    err (1, "unlink %s", filename);
+     }
+ }
+ 
+ static void
+ do_dir (const char *dirname)
+ {
+     int ret;
+ 
+     ret = fs_rmmount (dirname);
+     if (ret == 0)
+       return;
+ 
+     ret = chdir (dirname);
+     if (ret < 0)
+ 	err (1, "chdir %s", dirname);
+     kill_dir (dirname);
+     ret = chdir ("..");
+     if (ret < 0)
+ 	err (1, "chdir ..");
+     ret = rmdir (dirname);
+     if (ret < 0)
+ 	err (1, "rmdir %s", dirname);
+ }
+ 
+ static void
+ kill_dir (const char *dirname)
+ {
+     DIR *dir;
+     struct dirent *dp;
+ 
+     dir = opendir (".");
+     if (dir == NULL)
+ 	err (1, "opendir %s", dirname);
+     while ((dp = readdir (dir)) != NULL) {
+ 	if (strcmp (dp->d_name, ".") == 0
+ 	    || strcmp (dp->d_name, "..") == 0)
+ 	    continue;
+ 
+ 	kill_one (dp->d_name);
+     }
+     closedir(dir);
+ }
+ 
+ int
+ main(int argc, char **argv)
+ {
+ 
+     if (argc < 2)
+ 	errx (1, "usage: %s directory [...]", argv[0]);
+     while (argc >= 2) {
+ 	do_dir (argv[1]);
+ 	argc--;
+ 	argv++;
+     }
+     return 0;
+ }
Index: openafs/src/tests/run-fsx
diff -c /dev/null openafs/src/tests/run-fsx:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/run-fsx	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,7 ----
+ #!/bin/sh
+ # $Id: run-fsx,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ FS=${FS:-${objdir}/../appl/fs/fs}
+ 
+ if test "X$FAST" != "X" ; then echo "Not running $0" ;  exit 0 ; fi
+ ${objdir}/fsx -N 25000 -RW -c 1 fsxtmp
+ 
Index: openafs/src/tests/run-rcs
diff -c /dev/null openafs/src/tests/run-rcs:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/run-rcs	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,11 ----
+ #!/bin/sh
+ echo row1 > testfile
+ echo log1 | ci -u testfile
+ co -l testfile
+ echo row2 >> testfile
+ echo log2 | ci -u testfile
+ co -l testfile
+ echo row3 >> testfile
+ echo log3 | ci -u testfile
+ wc -l testfile | grep '3 testfile' || exit 1
+ 
Index: openafs/src/tests/run-suite.pl
diff -c /dev/null openafs/src/tests/run-suite.pl:1.8.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/run-suite.pl	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,233 ----
+ #!/usr/bin/env perl
+ # Copyright (C) 2000 by Sam Hartman
+ # This file may be copied either under the terms of the GNU GPL or the IBM Public License
+ # either version 2 or later of the GPL or version 1.0 or later of the IPL.
+ 
+ use Term::ReadLine;
+ use strict;
+ use OpenAFS::ConfigUtils;
+ use OpenAFS::Dirpath;
+ use OpenAFS::OS;
+ use OpenAFS::Auth;
+ use Getopt::Long;
+ use vars qw($admin $server $cellname $cachesize $part
+           $shutdown_needed $csdb);
+ my $rl = new Term::ReadLine('run-suite');
+ 
+ =head1  NAME
+ 
+    run-suite - Set up AFS cell and test.
+ 
+ =head1 SYNOPSIS
+ 
+ B<run-suite> [B<--cellname> cellname] [B<--cachesize> size]
+ 
+ =head1 DESCRIPTION
+ 
+ 
+ This script sets up an AFS cell, then runs a suite of tests against the 
+ cell to verify the build.
+ 
+ The B<cellname> option specifies the name of the cell.
+ 
+ The B<cachesize> option specifies the size of the AFS cache.
+ 
+ =cut
+ 
+ # main script
+ 
+ # mkvol(volume, mount)
+ sub mkvol($$) {
+     my ($vol, $mnt) = @_;
+     run("$openafsdirpath->{'afssrvsbindir'}/vos create $server $part $vol -localauth");
+     unwind("$openafsdirpath->{'afssrvsbindir'}/vos remove $server $part $vol -localauth");
+     run("$openafsdirpath->{'afssrvbindir'}/fs mkm $mnt $vol ");
+     run("$openafsdirpath->{'afssrvbindir'}/fs sa $mnt system:anyuser rl");
+ }
+ 
+ GetOptions (
+            "cellname=s" => \$cellname, 
+ 	   "cachesize=s" => \$cachesize,
+            "partition=s" => \$part,
+            "admin=s" => \$admin);
+ 
+ if ($> != 0) {
+   die "This script should almost always be run as root.\n";
+ }
+ 
+ open(MOUNT, "mount |") or die "Failed to run mount: $!\n";
+ while(<MOUNT>) {
+   if(m:^AFS:) {
+     print "The AFS client is currently running on this workstation.\n";
+     print "Please restart this script after running $openafsinitcmd->{'client-stop'}\n";
+     exit(1);
+   }
+   if(m:^/afs on AFS:) {
+     print "The AFS client is currently running on this workstation.\n";
+     print "Please restart this script after running $openafsinitcmd->{'client-stop'}\n";
+     exit(1);
+   }
+ }
+ close MOUNT;
+ 
+ unless ( -f "$openafsdirpath->{'afsconfdir'}/KeyFile") {
+   print "You do not have an AFS keyfile.  Please create this using asetkey from openafs-krb5 or 
+ the bos addkey command";
+   exit(1);
+ }
+ 
+ print "If the fileserver is not running, this may hang for 30 seconds.\n";
+ run("$openafsinitcmd->{'filesrv-stop'}");
+ $server = `hostname`;
+ chomp $server;
+ $admin = "admin" unless $admin;
+ $admin =~ s:/:.:g;
+ if($admin =~ /@/) {
+ die "The administrative user must be in the same realm as the cell and no realm may be specified.\n";
+ }
+ 
+ $cellname = $rl->readline("What cellname should be used? ") unless $cellname;
+ die "Please specify a cellname\n" unless $cellname;
+ 
+ unlink "$openafsdirpath->{'viceetcdir'}/CellServDB";
+ unlink "$openafsdirpath->{'viceetcdir'}/ThisCell";
+ 
+ my $lcell = "${cellname}";
+ 
+ #let bosserver create symlinks
+ run("$openafsinitcmd->{'filesrv-start'}");
+ unwind("$openafsinitcmd->{'filesrv-stop'}");
+ $shutdown_needed = 1;
+ run ("$openafsdirpath->{'afssrvbindir'}/bos setcellname $server $lcell -localauth ||true");
+ run ("$openafsdirpath->{'afssrvbindir'}/bos addhost $server $server -localauth ||true");
+ run("$openafsdirpath->{'afssrvbindir'}/bos adduser $server $admin -localauth");
+ unwind("$openafsdirpath->{'afssrvbindir'}/bos removeuser $server $admin -localauth");
+ if ( -f "$openafsdirpath->{'afsdbdir'}/prdb.DB0" ) {
+   die "Protection database already exists; cell already partially created\n";
+  }
+ open(PRDB, "|$openafsdirpath->{'afssrvsbindir'}/pt_util -p $openafsdirpath->{'afsdbdir'}/prdb.DB0 -w ")
+ or die "Unable to start pt_util: $!\n";
+ print PRDB "$admin 128/20 1 -204 -204\n";
+ print PRDB "system:administrators 130/20 -204 -204 -204\n";
+ print PRDB" $admin 1\n";
+ close PRDB;
+ unwind( "rm $openafsdirpath->{'afsdbdir'}/prdb* ");
+ # Start up ptserver and vlserver
+ run("$openafsdirpath->{'afssrvbindir'}/bos create $server ptserver simple $openafsdirpath->{'afssrvlibexecdir'}/ptserver -localauth");
+ unwind("$openafsdirpath->{'afssrvbindir'}/bos delete $server ptserver -localauth");
+ unwind("$openafsdirpath->{'afssrvbindir'}/bos stop $server ptserver -localauth -wait");
+ 
+ run("$openafsdirpath->{'afssrvbindir'}/bos create $server vlserver simple $openafsdirpath->{'afssrvlibexecdir'}/vlserver -localauth");
+ unwind("$openafsdirpath->{'afssrvbindir'}/bos delete $server vlserver -localauth");
+ unwind("$openafsdirpath->{'afssrvbindir'}/bos stop $server vlserver -localauth -wait");
+ 
+ run( "$openafsdirpath->{'afssrvbindir'}/bos create $server fs fs ".
+      "-cmd $openafsdirpath->{'afssrvlibexecdir'}/fileserver ".
+      "-cmd $openafsdirpath->{'afssrvlibexecdir'}/volserver ".
+      "-cmd $openafsdirpath->{'afssrvlibexecdir'}/salvager -localauth");
+ unwind( "$openafsdirpath->{'afssrvbindir'}/bos delete $server fs -localauth ");
+ unwind( "$openafsdirpath->{'afssrvbindir'}/bos stop $server fs -localauth -wait");
+ run("$openafsdirpath->{'afssrvbindir'}/bos restart $server -all -bosserver -localauth");
+ 
+ print "Waiting for database elections: ";
+ sleep(90);
+ print "done.\n";
+ # Past this point we want to control when bos shutdown happens
+ $shutdown_needed = 0;
+ unwind( "$openafsdirpath->{'afssrvbindir'}/bos shutdown $server -localauth ");
+ run("$openafsdirpath->{'afssrvsbindir'}/vos create $server a root.afs -localauth");
+ # bring up client
+ 
+ $cachesize = $rl->readline("What size cache (in 1k blocks)? ") unless $cachesize;
+ die "Please specify a cache size\n" unless $cachesize;
+ 
+ mkdir "/usr/vice/cache", 0700;
+ mkdir "/afs", 0777;
+ 
+ run("echo /afs:/usr/vice/cache:${cachesize} >$openafsdirpath->{'viceetcdir'}/cacheinfo");
+ run("$openafsinitcmd->{'client-forcestart'}");
+ my $afs_running = 0;
+ open(MOUNT, "mount |") or die "Failed to run mount: $!\n";
+ while(<MOUNT>) {
+ if(m:^AFS:) {
+        $afs_running = 1;
+ }
+        }
+ unless ($afs_running) {
+ print "*** The AFS client failed to start.\n";
+ print  "Please fix whatever problem kept it from running.\n";
+        exit(1);
+ }
+ unwind("$openafsinitcmd->{'client-stop'}");
+ 
+ $part = "a" unless $part;
+ 
+ &OpenAFS::Auth::authadmin();
+ 
+ run("$openafsdirpath->{'afssrvbindir'}/fs sa /afs system:anyuser rl");
+ 
+ run("$openafsdirpath->{'afssrvsbindir'}/vos create $server $part root.cell -localauth");
+ unwind("$openafsdirpath->{'afssrvsbindir'}/vos remove $server $part root.cell -localauth");
+ # We make root.cell s:anyuser readable after we mount in the next
+ # loop.
+ open(CELLSERVDB, "$openafsdirpath->{'viceetcdir'}/CellServDB")
+     or die "Unable to open $openafsdirpath->{'viceetcdir'}/CellServDB: $!\n";
+ while(<CELLSERVDB>) {
+     chomp;
+     if (/^>\s*([a-z0-9_\-.]+)/ ) {
+        run("$openafsdirpath->{'afssrvbindir'}/fs mkm /afs/$1 root.cell -cell $1 -fast");
+        unwind ("$openafsdirpath->{'afssrvbindir'}/fs rmm /afs/$1");
+    }
+ }
+ 
+ run("$openafsdirpath->{'afssrvbindir'}/fs sa /afs/$lcell system:anyuser rl");
+ run ("$openafsdirpath->{'afssrvbindir'}/fs mkm /afs/.$lcell root.cell -cell $lcell -rw");
+ unwind ("$openafsdirpath->{'afssrvbindir'}/fs rmm /afs/.$lcell");
+ run("$openafsdirpath->{'afssrvbindir'}/fs mkm /afs/.root.afs root.afs -rw");
+ unwind ("$openafsdirpath->{'afssrvbindir'}/fs rmm /afs/.root.afs");
+ 
+ mkvol( "user", "/afs/$lcell/user" );
+ unwind( "$openafsdirpath->{'afssrvsbindir'}/vos remove $server $part user -localauth ");
+ 
+ mkvol( "service", "/afs/$lcell/service" );
+ unwind( "$openafsdirpath->{'afssrvsbindir'}/vos remove $server $part service -localauth ");
+ 
+ mkvol( "rep", "/afs/$lcell/.replicated" );
+ unwind( "$openafsdirpath->{'afssrvsbindir'}/vos remove $server $part rep -localauth ");
+ run( "$openafsdirpath->{'afssrvbindir'}/fs mkm /afs/$lcell/replicated rep.readonly " );
+ 
+ run( "$openafsdirpath->{'afssrvsbindir'}/vos addsite $server $part rep -localauth" );
+ run( "$openafsdirpath->{'afssrvsbindir'}/vos release rep -localauth" );
+ unwind( "$openafsdirpath->{'afssrvsbindir'}/vos remove $server $part rep.readonly -localauth ");
+ 
+ mkvol( "unrep", "/afs/$lcell/unreplicated" );
+ unwind( "$openafsdirpath->{'afssrvsbindir'}/vos remove $server $part unrep -localauth ");
+ 
+ $lcell =~ /^([^.]*)/;
+ my $cellpart = $1;
+ run("ln -s /afs/$lcell /afs/$cellpart");
+ unwind ("rm /afs/$cellpart");
+ run( "ln -s /afs/.$lcell /afs/.$cellpart" );
+ unwind ("rm /afs/.$cellpart");
+ 
+ run( "$openafsdirpath->{'afssrvsbindir'}/vos addsite $server $part root.afs -localauth" );
+ run( "$openafsdirpath->{'afssrvsbindir'}/vos addsite $server $part root.cell -localauth" );
+ run( "$openafsdirpath->{'afssrvsbindir'}/vos release root.afs -localauth" );
+ run( "$openafsdirpath->{'afssrvsbindir'}/vos release root.cell -localauth" );
+ unwind( "$openafsdirpath->{'afssrvsbindir'}/vos remove $server $part root.cell.readonly -localauth ");
+ unwind( "$openafsdirpath->{'afssrvsbindir'}/vos remove $server $part root.afs.readonly -localauth ");
+ 
+ run("$openafsinitcmd->{'client-restart'}");
+ 
+ `cp ./t.uniq-bad /usr/tmp`;
+ 
+ system ("pagsh -c './test-front.sh $lcell'");
+ 
+ @unwinds = ();
+ END {
+ # If we fail before all the instances are created, we need to perform 
+ # our own bos shutdown
+     system("$openafsdirpath->{'afssrvbindir'}/bos shutdown $server -localauth") if $shutdown_needed;
+   run(pop @unwinds) while @unwinds;
+   }
+ 
Index: openafs/src/tests/run-tests.in
diff -c /dev/null openafs/src/tests/run-tests.in:1.3.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/run-tests.in	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,417 ----
+ #!/bin/sh
+ #
+ # $Id: run-tests.in,v 1.3.2.1 2002/01/20 09:18:07 shadow Exp $
+ #
+ srcdir=@srcdir@
+ objdir=`pwd`
+ SHELL=/bin/sh
+ VERSION=@VERSION@
+ PACKAGE=@PACKAGE@
+ host=@host@
+ RUNAS=nobody
+ FS=@afssrvbindir@/fs
+ export FS
+ 
+ AFSROOT=${AFSROOT-/afs}
+ export AFSROOT
+ 
+ BASIC_TESTS="creat1			\
+ 	    mkdir1			\
+ 	    mkdir2 			\
+ 	    symlink 			\
+ 	    hardlink1			\
+ 	    hardlink4			\
+ 	    hardlink2			\
+ 	    hardlink5			\
+ 	    touch1			\
+ 	    write1			\
+ 	    write3			\
+ 	    rename1			\
+ 	    hardlink3			\
+ 	    write2			\
+ 	    append1			\
+ 	    rename2			\
+ 	    rename4			\
+ 	    rename6			\
+ 	    rename-under-feet		\
+ 	    large-filename		\
+ 	    fchmod			\
+ 	    utime-file			\
+ 	    utime-dir			\
+ 	    mkdir3"
+ 
+ MTPT_TESTS="mkm-rmm			\
+ 	    mountpoint"
+ 
+ ACL_TESTS="acladduser.pl		\
+ 	    acladdgroup.pl		\
+ 	    acladdrights.pl		\
+ 	    acladdnegrights.pl		\
+ 	    aclclearnegrights.pl	\
+ 	    aclremoveuser.pl		\
+ 	    aclremovegroup.pl		\
+ 	    aclcopy.pl"
+ 
+ EXEC_TESTS="exec			\
+ 	    hello-world			\
+ 	    build-openafs"
+ 
+ MMAP_TESTS="append-over-page		\
+ 	    mmap-shared-write		\
+ 	    mmap-vs-read2		\
+ 	    mmap-vs-read		\
+ 	    read-vs-mmap2		\
+ 	    read-vs-mmap"
+ 
+ FS_TESTS="strange-characters		\
+ 	    pine			\
+ 	    parallel1			\
+ 	    write-large"
+ 
+ AFS_TESTS="write-ro			\
+ 	    too-many-files		\
+ 	    setpag			\
+ 	    setgroups"
+ 
+ RMT_TESTS="extcopyin			\
+ 	    extcopyout"
+ 
+ ABUSE_TESTS="read-write			\
+ 	    create-remove-files		\
+ 	    run-fsx"
+ 
+ PTS_TESTS="ptscreateuser.pl		\
+ 	    ptscreategroup.pl		\
+ 	    ptsadduser.pl		\
+ 	    ptschown.pl			\
+ 	    ptsmembersuser.pl		\
+ 	    ptsmembersgroup.pl		\
+ 	    ptsexamineuser.pl		\
+ 	    ptsexaminegroup.pl		\
+ 	    ptsremove.pl		\
+ 	    ptslistown.pl		\
+ 	    ptssetmax.pl		\
+ 	    ptslistmax.pl		\
+ 	    ptssetf.pl			\
+ 	    ptsdeletegroup.pl		\
+ 	    ptsdeleteuser.pl"
+ 
+ VOS_TESTS="voscreate.pl		\
+ 	    vosmove.pl			\
+ 	    vosaddsite.pl		\
+ 	    vosrelease.pl		\
+ 	    vosremsite.pl		\
+ 	    vosremove.pl		\
+ 	    vosdelentry.pl		\
+ 	    vossyncvldb.pl		\
+ 	    voszap.pl			\
+ 	    vossyncserv.pl		\
+ 	    voslock.pl			\
+ 	    vosunlock.pl		\
+ 	    vosunlockall.pl		\
+ 	    vosrename.pl		\
+ 	    voslistvol.pl		\
+ 	    voslistvldb.pl		\
+ 	    vospartinfo.pl		\
+ 	    voslistpart.pl		\
+ 	    vosbackup.pl		\
+ 	    vosexamine.pl		\
+ 	    vosdump.pl			\
+ 	    vosrestore.pl"
+ 
+ BOS_TESTS="bosaddhost.pl		\
+ 	    boslisthosts.pl		\
+ 	    bosremovehost.pl		\
+ 	    bosadduser.pl		\
+ 	    boslistusers.pl		\
+ 	    bosremoveuser.pl		\
+ 	    bosinstall.pl		\
+ 	    bosexec.pl			\
+ 	    boscreate.pl		\
+ 	    bosdeleterunning.pl		\
+ 	    bosstatus.pl		\
+ 	    bosstop.pl			\
+ 	    bosrestartstopped.pl	\
+ 	    bosstart.pl			\
+ 	    bosshutdown.pl		\
+ 	    bosdelete.pl		\
+ 	    bosaddkey.pl		\
+ 	    boslistkeys.pl		\
+ 	    bosremovekey.pl		\
+ 	    bossalvagevolume.pl		\
+ 	    bossalvagepart.pl		\
+ 	    bossalvageserver.pl"
+ 
+ REG_TESTS="fcachesize-write-file	\
+ 	    fcachesize-read-file	\
+ 	    baduniq.pl"
+ 
+ ALL_TESTS="creat1			\
+ 	    mkdir1			\
+ 	    mkdir2 			\
+ 	    symlink 			\
+ 	    hardlink1			\
+ 	    hardlink4			\
+ 	    hardlink2			\
+ 	    hardlink5			\
+ 	    touch1			\
+ 	    write1			\
+ 	    write3			\
+ 	    rename1			\
+ 	    hardlink3			\
+ 	    write2			\
+ 	    append1			\
+ 	    rename2			\
+ 	    rename4			\
+ 	    rename6			\
+ 	    rename-under-feet		\
+ 	    large-filename		\
+ 	    fchmod			\
+ 	    utime-file			\
+ 	    utime-dir			\
+ 	    mkdir3			\
+ 	    mkm-rmm			\
+ 	    mountpoint			\
+ 	    acladduser.pl		\
+ 	    acladdgroup.pl		\
+ 	    acladdrights.pl		\
+ 	    acladdnegrights.pl		\
+ 	    aclclearnegrights.pl	\
+ 	    aclremoveuser.pl		\
+ 	    aclremovegroup.pl		\
+ 	    aclcopy.pl			\
+ 	    exec			\
+ 	    hello-world			\
+ 	    build-openafs		\
+ 	    append-over-page		\
+ 	    mmap-shared-write		\
+ 	    mmap-vs-read2		\
+ 	    mmap-vs-read		\
+ 	    read-vs-mmap2		\
+ 	    read-vs-mmap		\
+ 	    strange-characters		\
+ 	    pine			\
+ 	    parallel1			\
+ 	    write-large			\
+ 	    write-ro			\
+ 	    too-many-files		\
+ 	    setpag			\
+ 	    setgroups			\
+ 	    extcopyin			\
+ 	    extcopyout			\
+ 	    read-write			\
+ 	    create-remove-files		\
+ 	    run-fsx			\
+ 	    ptscreateuser.pl		\
+ 	    ptscreategroup.pl		\
+ 	    ptsadduser.pl		\
+ 	    ptschown.pl			\
+ 	    ptsmembersuser.pl		\
+ 	    ptsmembersgroup.pl		\
+ 	    ptsexamineuser.pl		\
+ 	    ptsexaminegroup.pl		\
+ 	    ptsremove.pl		\
+ 	    ptslistown.pl		\
+ 	    ptssetmax.pl		\
+ 	    ptslistmax.pl		\
+ 	    ptssetf.pl			\
+ 	    ptsdeletegroup.pl		\
+ 	    ptsdeleteuser.pl		\
+ 	    voscreate.pl		\
+ 	    vosmove.pl			\
+ 	    vosaddsite.pl		\
+ 	    vosrelease.pl		\
+ 	    vosremsite.pl		\
+ 	    vosremove.pl		\
+ 	    vosdelentry.pl		\
+ 	    vossyncvldb.pl		\
+ 	    voszap.pl			\
+ 	    vossyncserv.pl		\
+ 	    voslock.pl			\
+ 	    vosunlock.pl		\
+ 	    vosunlockall.pl		\
+ 	    vosrename.pl		\
+ 	    voslistvol.pl		\
+ 	    voslistvldb.pl		\
+ 	    vospartinfo.pl		\
+ 	    voslistpart.pl		\
+ 	    vosbackup.pl		\
+ 	    vosexamine.pl		\
+ 	    vosdump.pl			\
+ 	    vosrestore.pl		\
+ 	    bosaddhost.pl		\
+ 	    boslisthosts.pl		\
+ 	    bosremovehost.pl		\
+ 	    bosadduser.pl		\
+ 	    boslistusers.pl		\
+ 	    bosremoveuser.pl		\
+ 	    bosinstall.pl		\
+ 	    bosexec.pl			\
+ 	    boscreate.pl		\
+ 	    bosdeleterunning.pl		\
+ 	    bosstatus.pl		\
+ 	    bosstop.pl			\
+ 	    bosrestartstopped.pl	\
+ 	    bosstart.pl			\
+ 	    bosshutdown.pl		\
+ 	    bosdelete.pl		\
+ 	    bosaddkey.pl		\
+ 	    boslistkeys.pl		\
+ 	    bosremovekey.pl		\
+ 	    bossalvagevolume.pl		\
+ 	    bossalvagepart.pl		\
+ 	    bossalvageserver.pl		\
+ 	    fcachesize-write-file	\
+ 	    fcachesize-read-file	\
+ 	    baduniq.pl"
+ 
+ TESTS="$ALL_TESTS"
+ TEST_MODE="all"
+ 
+ linebreak=":-------------------------------;"
+ 
+ PARALLELL=
+ FAST=
+ LARGE=
+ PRINT_CACHESIZE=
+ usage="Usage: $0 [-user user] [-all] [-fast] [-large] [-j] [-verbose] [-x] tests ..."
+ while true
+ do
+   case $1 in
+   -all) ALL=yes;;
+   -fast) FAST=yes;;
+   -large) LARGE=yes;;
+   -j) PARALLELL="&";;
+   -verbose) VERBOSE=yes;;
+   -user) RUNAS=$1; shift;;
+   -x) SHELLVERBOSE="-x";;
+   -p) PRINT_CACHESIZE="yes";;
+   -basic) TESTS="$BASIC_TESTS";TEST_MODE="basic";;
+   -mtpt) TESTS="$MTPT_TESTS";TEST_MODE="mtpt";;
+   -acl) TESTS="$ACL_TESTS";TEST_MODE="acl";;
+   -exec) TESTS="$EXEC_TESTS";TEST_MODE="exec";;
+   -mmap) TESTS="$MMAP_TESTS";TEST_MODE="mmap";;
+   -fs) TESTS="$FS_TESTS";TEST_MODE="fs";;
+   -afs) TESTS="$AFS_TESTS";TEST_MODE="afs";;
+   -rmt) TESTS="$RMT_TESTS";TEST_MODE="rmt";;
+   -abuse) TESTS="$ABUSE_TESTS";TEST_MODE="abuse";;
+   -pts) TESTS="$PTS_TESTS";TEST_MODE="pts";;
+   -vos) TESTS="$VOS_TESTS";TEST_MODE="vos";;
+   -bos) TESTS="$BOS_TESTS";TEST_MODE="bos";;
+   -reg) TESTS="$REG_TESTS";TEST_MODE="reg";;
+   -help|--help) echo $usage; 
+ 	echo "tests available: $linebreak"; for a in "$ALL_TESTS"; do echo $a ; done;
+ 	exit 0;;
+   -version|--version) echo "$0 $Id: run-tests.in,v 1.3.2.1 2002/01/20 09:18:07 shadow Exp $"; exit 0;;
+   -*) echo "$0: Bad option $1"; echo $usage; exit 1;;
+   *) break;;
+   esac
+   shift
+ done
+ 
+ if test "X$WORKDIR" = "X";then
+ 	echo "WORKDIR=workdir $0 $* or env WORKDIR=workdir $0 $*"; exit 1;
+ fi
+ 
+ RUNTESTS=
+ if test "X$ALL" != "X" ; then
+     RUNTESTS="$TESTS"
+ elif test $# -lt 1; then
+     echo $usage; exit
+ else
+     RUNTESTS=$*
+ fi
+ 
+ # these are variables exported to the scripts
+ 
+ export FAST
+ export LARGE
+ export VERBOSE
+ export SHELLVERBOSE
+ 
+ # and file descriptors
+ 
+ # 3 - progress
+ # 4 - details
+ 
+ if test "$VERBOSE" = "yes"; then
+   exec 3>/dev/null
+   exec 4>&1
+ else
+   exec 3>&1
+   exec 4>/dev/null
+ fi
+ 
+ # Find out where we really are
+ 
+ srcdir=`cd $srcdir; pwd`
+ objdir=`cd $objdir; pwd`
+ 
+ export srcdir
+ export objdir
+ 
+ echo "-------------------------------------------------"
+ echo "$PACKAGE-$VERSION"
+ echo "hosttype $host"
+ echo "${SHELL},${SHELLVERBOSE},${VERBOSE},${PARALLELL},${FAST}"
+ echo "testmode ${TEST_MODE}"
+ echo "runas ${RUNAS}"
+ echo "${srcdir}"
+ echo "${objdir}"
+ echo "${WORKDIR}"
+ date
+ echo "-------------------------------------------------"
+ 
+ test "X$VERBOSE" != "X" && echo "Running tests"
+ 
+ FAILEDTESTS=
+ exitval=0
+ 
+ for a in $RUNTESTS; do
+   #
+   # XXX Test if binary in $srcdir, shellscript in $srcdir else
+   # its a binary in objdir
+   #
+   if test -x ${srcdir}/$a ; then
+     b="${srcdir}/$a"
+   elif test -f ${srcdir}/$a ; then
+     b="${SHELL} ${SHELLVERBOSE} ${srcdir}/$a"
+   else
+     b="${objdir}/$a"
+   fi
+   echo "Running $a"
+   test "X$VERBOSE" != "X" && echo "Running test $a ($b)."
+   if test "$a" = "setgroups" ; then
+      b="${objdir}/asu root $b"
+   else
+      b="${objdir}/asu $RUNAS $b"
+   fi
+   tmpdir="`hostname`-$a-`date +%Y-%m-%d-%H-%M-%S`-$$"
+   cd $WORKDIR && mkdir $tmpdir && (cd $tmpdir && $b ${PARALLELL})
+   saved_res=$?
+   test "X$VERBOSE" != "X" && echo "Saved res = $saved_res"
+   if test "X${PARALLELL}" = "X" ;then
+      if test $saved_res != 0 ; then 
+ 	echo "Test $a FAILED"
+         FAILEDTESTS="${FAILEDTESTS} $a"; 
+         exitval=$savedres
+      else
+ 	test "X$VERBOSE" != "X" && echo "Test $a succeeded, tmpdir is removed"
+ 	${objdir}/rm-rf $tmpdir
+      fi
+      test "X$VERBOSE" != "X" && echo "Done test $a."
+   fi
+   test "X${PRINT_CACHESIZE}" = Xyes && $objdir/../appl/fs/fs calculate
+ done
+ 
+ wait
+ date
+ 
+ if test "$FAILEDTESTS"; then
+   echo "-----------------------------------------------------------"
+   echo "Failed test(s) were: $FAILEDTESTS"
+ else
+   echo "All test(s) were succesful!"
+ fi
+ 
+ exit $exitval
Index: openafs/src/tests/setgroups
diff -c /dev/null openafs/src/tests/setgroups:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/setgroups	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,4 ----
+ #!/bin/sh
+ # $Id: setgroups,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ 
+ $objdir/test-setgroups nobody 1>&4
Index: openafs/src/tests/setpag
diff -c /dev/null openafs/src/tests/setpag:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/setpag	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,4 ----
+ #!/bin/sh
+ # $Id: setpag,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ 
+ $objdir/test-setpag 1>&4
Index: openafs/src/tests/shallow-tree
diff -c /dev/null openafs/src/tests/shallow-tree:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/shallow-tree	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,5 ----
+ #!/bin/sh
+ # $Id: shallow-tree,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ 
+ mkdir foo && ( cd foo && $SHELL $SHELLVERBOSE ${srcdir}/dir-tree 3 "0 1 2 3 4" )
+ ${objdir}/rm-rf foo
\ No newline at end of file
Index: openafs/src/tests/stagehdr.c
diff -c /dev/null openafs/src/tests/stagehdr.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/stagehdr.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,150 ----
+ /*
+  * CMUCS AFStools
+  * dumpscan - routines for scanning and manipulating AFS volume dumps
+  *
+  * Copyright (c) 1998 Carnegie Mellon University
+  * All Rights Reserved.
+  * 
+  * Permission to use, copy, modify and distribute this software and its
+  * documentation is hereby granted, provided that both the copyright
+  * notice and this permission notice appear in all copies of the
+  * software, derivative works or modified versions, and any portions
+  * thereof, and that both notices appear in supporting documentation.
+  *
+  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+  *
+  * Carnegie Mellon requests users of this software to return to
+  *
+  *  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
+  *  School of Computer Science
+  *  Carnegie Mellon University
+  *  Pittsburgh PA 15213-3890
+  *
+  * any improvements or extensions that they make and grant Carnegie Mellon
+  * the rights to redistribute these changes.
+  */
+ 
+ /* stagehdr.c - Parse and dump stage backup headers */
+ 
+ #include <sys/types.h>
+ #include <netinet/in.h>
+ #include <stdlib.h>
+ #include <errno.h>
+ 
+ #include "dumpscan.h"
+ #include "dumpscan_errs.h"
+ #include "xf_errs.h"
+ #include "stagehdr.h"
+ 
+ static afs_uint32 hdr_checksum(char *buf, int size)
+ {
+   afs_uint32 sum = 0, n = size / sizeof(afs_uint32), *words = (afs_uint32 *)buf;
+ 
+   while (--n)
+     sum += ntohl(*words++);
+   return sum;
+ }
+ 
+ 
+ /* Parse a stage backup header.
+  * If tag is non-NULL, *tag should contain the first byte (already read),
+  * and will be filled in with the first byte after the header, if one exists.
+  * On success, returns 0 and leaves us positioned after the header
+  * On failure, returns an error and position is undefined
+  * Iff there is no header, returns DSERR_MAGIC and leaves us
+  * positioned where we started.
+  */
+ afs_uint32 ParseStageHdr(XFILE *X, unsigned char *tag, backup_system_header *hdr)
+ {
+   char buf[STAGE_HDRLEN];
+   struct stage_header *bckhdr = (struct stage_header *)buf;
+   u_int64 where;
+   afs_uint32 r;
+ 
+   if (r = xftell(X, &where)) return r;
+   if (hdr) memset(hdr, 0, sizeof(*hdr));
+   if (tag) {
+     if (*tag != STAGE_VERSMIN) return DSERR_MAGIC;
+     buf[0] = *tag;
+     r = xfread(X, buf + 1, STAGE_HDRLEN - 1);
+   } else {
+     r = xfread(X, buf, STAGE_HDRLEN);
+   }
+ 
+   if (r == ERROR_XFILE_EOF) {
+     r = xfseek(X, &where);
+     return r ? r : DSERR_MAGIC;
+   } else if (r) return r;
+ 
+   if (bckhdr->c_vers < STAGE_VERSMIN
+   ||  ntohl(bckhdr->c_magic) != STAGE_MAGIC
+   ||  hdr_checksum(buf, STAGE_HDRLEN) != STAGE_CHECKSUM) {
+     r = xfseek(X, &where);
+     return r ? r : DSERR_MAGIC;
+   }
+ 
+   if (hdr) {
+     hdr->version   = bckhdr->c_vers;
+     hdr->from_date = ntohl(bckhdr->c_fdate);
+     hdr->to_date   = ntohl(bckhdr->c_tdate);
+     hdr->dump_date = ntohl(bckhdr->c_time);
+     hdr->filenum   = ntohl(bckhdr->c_filenum);
+     hdr->volid     = ntohl(bckhdr->c_id);
+     hdr->dumplen   = ntohl(bckhdr->c_length);
+     hdr->level     = ntohl(bckhdr->c_level);
+     hdr->magic     = ntohl(bckhdr->c_magic);
+     hdr->cksum     = ntohl(bckhdr->c_checksum);
+     hdr->flags     = ntohl(bckhdr->c_flags);
+     hdr->server    = malloc(strlen(bckhdr->c_host) + 1);
+     hdr->part      = malloc(strlen(bckhdr->c_disk) + 1);
+     hdr->volname   = malloc(strlen(bckhdr->c_name) + 1);
+ 
+     if (!hdr->server || !hdr->part || !hdr->volname) {
+       if (hdr->server)  free(hdr->server);
+       if (hdr->part)    free(hdr->part);
+       if (hdr->volname) free(hdr->volname);
+       return ENOMEM;
+     }
+     strcpy(hdr->server,  bckhdr->c_host);
+     strcpy(hdr->part,    bckhdr->c_disk);
+     strcpy(hdr->volname, bckhdr->c_name);
+   }
+ 
+   if (tag) return ReadByte(X, tag);
+   else return 0;
+ }
+ 
+ 
+ /* Dump a stage backup header */
+ afs_uint32 DumpStageHdr(XFILE *OX, backup_system_header *hdr)
+ {
+   char buf[STAGE_HDRLEN];
+   struct stage_header *bckhdr = (struct stage_header *)buf;
+   afs_uint32 checksum;
+   afs_uint32 r;
+ 
+   memset(buf, 0, STAGE_HDRLEN);
+   bckhdr->c_vers     = hdr->version;
+   bckhdr->c_fdate    = htonl(hdr->from_date);
+   bckhdr->c_tdate    = htonl(hdr->to_date);
+   bckhdr->c_filenum  = htonl(hdr->filenum);
+   bckhdr->c_time     = htonl(hdr->dump_date);
+   bckhdr->c_id       = htonl(hdr->volid);
+   bckhdr->c_length   = htonl(hdr->dumplen);
+   bckhdr->c_level    = htonl(hdr->level);
+   bckhdr->c_magic    = htonl(STAGE_MAGIC);
+   bckhdr->c_flags    = htonl(hdr->flags);
+ 
+   strcpy(bckhdr->c_host, hdr->server);
+   strcpy(bckhdr->c_disk, hdr->part);
+   strcpy(bckhdr->c_name, hdr->volname);
+ 
+   /* Now, compute the checksum */
+   checksum = hdr_checksum(buf, STAGE_HDRLEN);
+   bckhdr->c_checksum = htonl(STAGE_CHECKSUM - checksum);
+ 
+   if (r = xfwrite(OX, buf, STAGE_HDRLEN)) return r;
+   return 0;
+ }
Index: openafs/src/tests/stagehdr.h
diff -c /dev/null openafs/src/tests/stagehdr.h:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/stagehdr.h	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,61 ----
+ /*
+  * CMUCS AFStools
+  * dumpscan - routines for scanning and manipulating AFS volume dumps
+  *
+  * Copyright (c) 1998 Carnegie Mellon University
+  * All Rights Reserved.
+  * 
+  * Permission to use, copy, modify and distribute this software and its
+  * documentation is hereby granted, provided that both the copyright
+  * notice and this permission notice appear in all copies of the
+  * software, derivative works or modified versions, and any portions
+  * thereof, and that both notices appear in supporting documentation.
+  *
+  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+  *
+  * Carnegie Mellon requests users of this software to return to
+  *
+  *  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
+  *  School of Computer Science
+  *  Carnegie Mellon University
+  *  Pittsburgh PA 15213-3890
+  *
+  * any improvements or extensions that they make and grant Carnegie Mellon
+  * the rights to redistribute these changes.
+  */
+ 
+ /* stagehdr.h - (old) Stage backup header format */
+ 
+ #ifndef _STAGEHDR_H_
+ #define _STAGEHDR_H_
+ 
+ #include "intNN.h"
+ 
+ /* Stage-related constants */
+ #define STAGE_MAGIC    0x00adf8bc       /* magic number for stage header */
+ #define STAGE_CHECKSUM 84446            /* checksum (same as 4.2bsd dump) */
+ #define STAGE_VERSMIN  20               /* minimum version */
+ #define STAGE_NAMLEN   64               /* length of host/part/vol names */
+ #define STAGE_HDRLEN   1024             /* size of the header */
+ 
+ struct stage_header {
+   unsigned char c_vers;               /* header version (starts at 20) */
+   unsigned char c_notused[3];
+   afs_uint32       c_fdate;              /* dump "from" date */
+   afs_uint32       c_tdate;              /* dump "to" date */
+   afs_uint32       c_filenum;            /* tape file number */
+   afs_uint32       c_time;               /* time dump was done */
+   char          c_host[STAGE_NAMLEN]; /* hostname volume came from */
+   char          c_disk[STAGE_NAMLEN]; /* partition volume came from */
+   char          c_name[STAGE_NAMLEN]; /* volume name */
+   afs_uint32       c_id;                 /* volume ID */
+   afs_uint32       c_length;             /* length of the dump */
+   afs_uint32       c_level;              /* dump level */
+   afs_uint32       c_magic;              /* magic number */
+   afs_uint32       c_checksum;           /* checksum of backup header */
+   afs_uint32       c_flags;              /* feature flags */
+ };
+ 
+ #endif /* _STAGEHDR_H_ */
Index: openafs/src/tests/still-there-p.c
diff -c /dev/null openafs/src/tests/still-there-p.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/still-there-p.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,89 ----
+ /*
+  * Copyright (c) 2001 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <errno.h>
+ 
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <dirent.h>
+ 
+ 
+ #include <err.h>
+ 
+ #define TEST_BUFFER_SZ		(1024*8)
+ 
+ int
+ main(int argc, char **argv)
+ {
+     const char *file = "foo";
+     char otherbuf[TEST_BUFFER_SZ];
+     char buf[TEST_BUFFER_SZ];
+     int fd;
+ 	
+ 
+     fd = open (file, O_RDWR|O_TRUNC|O_CREAT, 0644);
+     if (fd < 0)
+ 	err(1, "open(%s)", file);
+ 
+     if (write (fd, buf, sizeof(buf)) != sizeof(buf))
+ 	errx(1, "write");
+ 
+     while (1) {
+ 	if (lseek(fd, 0, SEEK_SET) < 0)
+ 	    err(1, "lseek");
+ 
+ 	if (read(fd, otherbuf, sizeof(otherbuf)) != sizeof(otherbuf)) {
+ 	    struct stat sb;
+ 
+ 	    if (fstat(fd, &sb) < 0)
+ 		err(1, "fstat");
+ 	    printf("size: %d\n", (int)sb.st_size);
+ 	    printf ("lseek(SEEK_CUR): %d\n", (int)lseek(fd, 0, SEEK_CUR));
+ 	    errx(1, "read");
+ 	}
+ 
+ 	if (memcmp(buf, otherbuf, sizeof(buf)) != 0)
+ 	    errx (1, "buf != otherbuf");
+     }
+     close(fd);
+ 
+     return 0;
+ }
Index: openafs/src/tests/strange-characters
diff -c /dev/null openafs/src/tests/strange-characters:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/strange-characters	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,7 ----
+ #!/bin/sh
+ # $Id: strange-characters,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ for i in å ä ö åäö; do
+   touch $i || exit 1
+   test -f $i || exit 1
+   rm $i || exit 1
+ done
Index: openafs/src/tests/strange-characters-c.c
diff -c /dev/null openafs/src/tests/strange-characters-c.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/strange-characters-c.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,93 ----
+ /*
+  * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <sys/types.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ 
+ #include <err.h>
+ 
+ #ifdef RCSID
+ RCSID("$Id: strange-characters-c.c,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $");
+ #endif
+ 
+ static void
+ creat_file (char *name)
+ {
+     int fd;
+ 
+     fd = open (name, O_WRONLY | O_CREAT | O_EXCL, 0777);
+     if (fd < 0)
+ 	err (1, "open %s", name);
+     if (close (fd) < 0)
+ 	err (1, "close %s", name);
+ }
+ 
+ static void
+ look_at_file (char *name)
+ {
+     int fd;
+ 
+     fd = open (name, O_RDONLY | O_EXCL, 0777);
+     if (fd < 0)
+ 	err (1, "open %s", name);
+     if (close (fd) < 0)
+ 	err (1, "close %s", name);
+ }
+ 
+ static void
+ usage (int ret)
+ {
+     fprintf (stderr, "%s\n", __progname);
+     exit (ret);
+ }
+ 
+ int
+ main(int argc, char **argv)
+ {
+     char *file = "åäö";
+ 
+ 
+     if (argc != 1)
+ 	usage (1);
+ 
+     creat_file (file);
+     look_at_file (file);
+     return 0;
+ }
Index: openafs/src/tests/strange-other-characters
diff -c /dev/null openafs/src/tests/strange-other-characters:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/strange-other-characters	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,5 ----
+ #!/bin/sh
+ # $Id: strange-other-characters,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $
+ dir=$AFSROOT/stacken.kth.se/ftp/pub/arla/tests
+ 
+ test -f $dir/åäö || exit 1
Index: openafs/src/tests/symlink.c
diff -c /dev/null openafs/src/tests/symlink.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/symlink.c	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,72 ----
+ /*
+  * Copyright (c) 1999 - 2000 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <dirent.h>
+ 
+ #include <err.h>
+ 
+ #ifdef RCSID
+ RCSID("$Id: symlink.c,v 1.1.2.1 2002/01/20 09:18:07 shadow Exp $");
+ #endif
+ 
+ int
+ main(int argc, char **argv)
+ {
+     int ret;
+     struct stat sb;
+ 
+ 
+     ret = symlink ("foo", "bar");
+     if (ret < 0)
+ 	err (1, "symlink foo,bar");
+     ret = lstat ("bar", &sb);
+     if (ret < 0)
+ 	err (1, "lstat bar");
+     if ((sb.st_mode & S_IFLNK) != S_IFLNK)
+ 	errx (1, "bar is not symlink");
+     ret = unlink ("bar");
+     if (ret < 0)
+ 	err (1, "unlink bar");
+     return 0;
+ }
Index: openafs/src/tests/t.uniq-bad
Index: openafs/src/tests/test-front.sh
diff -c /dev/null openafs/src/tests/test-front.sh:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/test-front.sh	Sun Jan 20 04:18:07 2002
***************
*** 0 ****
--- 1,10 ----
+ #!/bin/sh
+ pwd=`pwd`
+ cell=$1
+ ./reauth.pl
+ PERL5LIB=$pwd
+ export PERL5LIB
+ WORKDIR=/afs/${cell}/unreplicated
+ export WORKDIR
+ ./run-tests -all
+ 
Index: openafs/src/tests/test-gunzip-gnu-mirror
diff -c /dev/null openafs/src/tests/test-gunzip-gnu-mirror:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/test-gunzip-gnu-mirror	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,14 ----
+ #!/bin/sh
+ # $Id: test-gunzip-gnu-mirror,v 1.1.2.1 2002/01/20 09:18:08 shadow Exp $
+ if test "X$FAST" != "X" ; then echo "Not running $0" ;  exit 0 ; fi
+ original=${1-$AFSROOT/stacken.kth.se/ftp/pub/gnu}
+ cd $original || exit 1
+ find . -name '*.gz' -print | while read i; do
+   foo=`gunzip --verbose --test $i 2>&1`
+   echo $foo >& 4
+   case "$foo" in
+ *not*in*gzip*format*) ;;
+ *OK*) ;;
+ *) exit 1 ;;
+   esac
+ done
Index: openafs/src/tests/test-parallel1.c
diff -c /dev/null openafs/src/tests/test-parallel1.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/test-parallel1.c	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,100 ----
+ /*
+  * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <sys/types.h>
+ #include <sys/wait.h>
+ #include <sys/param.h>
+ #include <unistd.h>
+ 
+ #include <err.h>
+ 
+ #include <fcntl.h>
+ 
+ #ifdef RCSID
+ RCSID("$Id: test-parallel1.c,v 1.1.2.1 2002/01/20 09:18:08 shadow Exp $");
+ #endif
+ 
+ #define WORKER_TIMES 100
+ #define NUM_WORKER 10
+ 
+ static int
+ worker (int num)
+ {
+     int i, fd;
+ 
+     for (i = 0 ; i < WORKER_TIMES ; i++) {
+ 	fd = open ("foo", O_CREAT|O_RDWR, 0600);
+ 	if (fd >= 0) {
+ 	    fchmod (fd, 0700);
+ 	    close (fd);
+ 	}
+ 	unlink("foo");
+ 	if (i % 1000) {
+ 	    printf (" %d", num);
+ 	    fflush (stdout);
+ 	}
+     }
+     return 0;
+ }
+ 
+ 
+ int
+ main(int argc, char **argv)
+ {
+     int i, ret;
+     
+ 
+     for (i = 0; i < NUM_WORKER ; i++) {
+ 	int ret;
+ 	
+ 	ret = fork();
+ 	switch (ret) {
+ 	case 0:
+ 	    return worker(i);
+ 	case -1:
+ 	    err (1, "fork");
+ 	}
+     }
+     i = NUM_WORKER;
+     while (i && wait (&ret)) {
+ 	i--;
+ 	if (ret)
+ 	    err (1, "wait: %d", ret);
+     }
+     return 0;
+ }
Index: openafs/src/tests/test-parallel2.c
diff -c /dev/null openafs/src/tests/test-parallel2.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/test-parallel2.c	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,182 ----
+ /*
+  * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <sys/types.h>
+ #include <sys/wait.h>
+ #include <sys/param.h>
+ #include <sys/stat.h>
+ #include <unistd.h>
+ 
+ #include <err.h>
+ 
+ #include <fcntl.h>
+ 
+ #ifdef RCSID
+ RCSID("$Id: test-parallel2.c,v 1.1.2.1 2002/01/20 09:18:08 shadow Exp $");
+ #endif
+ 
+ #define WORKER_TIMES 1000
+ #define NUM_WORKER 100
+ 
+ static int
+ getcwd_worker (int num)
+ {
+     char name[17];
+     int i;
+ 
+     snprintf (name, sizeof(name), "%d", num);
+     if (mkdir (name, 0777) < 0)
+ 	err (1, "mkdir %s", name);
+     if (chdir (name) < 0)
+ 	err (1, "chdir %s", name);
+     for (i = 0; i < WORKER_TIMES; ++i) {
+ 	char buf[256];
+ 
+ 	getcwd (buf, sizeof(buf));
+     }
+     return 0;
+ }
+ 
+ static int
+ mkdir_worker (int num)
+ {
+     int i;
+ 
+     for (i = 0; i < WORKER_TIMES; ++i){
+ 	char name[256];
+ 
+ 	snprintf (name, sizeof(name), "m%d-%d", num, i);
+ 	mkdir (name, 0777);
+     }
+     return 0;
+ }
+ 
+ static int
+ mkdir_rmdir_worker (int num)
+ {
+     int i;
+ 
+     for (i = 0; i < WORKER_TIMES; ++i){
+ 	char name[256];
+ 
+ 	snprintf (name, sizeof(name), "rm%d-%d", num, i);
+ 	mkdir (name, 0777);
+     }
+     for (i = 0; i < WORKER_TIMES; ++i){
+ 	char name[256];
+ 
+ 	snprintf (name, sizeof(name), "rm%d-%d", num, i);
+ 	rmdir (name);
+     }
+     return 0;
+ }
+ 
+ static int
+ rename_worker (int num)
+ {
+     int i;
+ 
+     for (i = 0; i < WORKER_TIMES; ++i){
+ 	char name[256];
+ 	int fd;
+ 
+ 	snprintf (name, sizeof(name), "rm%d-%d", num, i);
+ 	fd = open (name, O_WRONLY | O_CREAT, 0777);
+ 	close (fd);
+     }
+     for (i = 0; i < WORKER_TIMES; ++i){
+ 	char name[256], name2[256];
+ 
+ 	snprintf (name, sizeof(name), "rm%d-%d", num, i);
+ 	snprintf (name2, sizeof(name2), "rn%d-%d", num, i);
+ 	rename (name, name2);
+     }
+     return 0;
+ }
+ 
+ static int
+ stat_worker (int num)
+ {
+     char name[17];
+     int i;
+     char buf[256];
+     struct stat sb;
+ 
+     snprintf (name, sizeof(name), "%d", num);
+     if (mkdir (name, 0777) < 0)
+ 	err (1, "mkdir %s", name);
+     if (chdir (name) < 0)
+ 	err (1, "chdir %s", name);
+     for (i = 0; i < WORKER_TIMES; ++i) {
+ 	getcwd (buf, sizeof(buf));
+ 	stat (buf, &sb);
+     }
+     return 0;
+ }
+ 
+ static int (*workers[])(int) = {getcwd_worker, mkdir_worker,
+ 				mkdir_rmdir_worker, rename_worker,
+ 				stat_worker};
+ 
+ static int nworkers = sizeof(workers)/sizeof(*workers);
+ 
+ int
+ main(int argc, char **argv)
+ {
+     int i, ret;
+     
+ 
+     for (i = 0; i < NUM_WORKER ; i++) {
+ 	int ret;
+ 	
+ 	ret = fork();
+ 	switch (ret) {
+ 	case 0:
+ 	    return (*workers[i % nworkers])(i);
+ 	case -1:
+ 	    err (1, "fork");
+ 	}
+     }
+     i = NUM_WORKER;
+     while (i && wait (&ret)) {
+ 	i--;
+ 	if (ret)
+ 	    err (1, "wait: %d", ret);
+     }
+     return 0;
+ }
Index: openafs/src/tests/test-setgroups.c
diff -c /dev/null openafs/src/tests/test-setgroups.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/test-setgroups.c	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,125 ----
+ /*
+  * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <sys/types.h>
+ #include <sys/param.h>
+ #include <unistd.h>
+ #include <pwd.h>
+ #include <limits.h>
+ 
+ #include <err.h>
+ 
+ #ifdef RCSID
+ RCSID("$Id: test-setgroups.c,v 1.1.2.1 2002/01/20 09:18:08 shadow Exp $");
+ #endif
+ 
+ #if !defined(NGROUPS) && defined(NGROUPS_MAX)
+ #define NGROUPS NGROUPS_MAX
+ #endif
+ 
+ static void
+ print_groups (int ngroups, gid_t groups[NGROUPS])
+ {
+     int i;
+ 
+     printf ("groups: ");
+     for (i = 0; i < ngroups; ++i)
+ 	printf ("%d%s", groups[i], (i < ngroups - 1) ? ", " : "");
+     printf ("\n");
+ }    
+ 
+ int
+ main(int argc, char **argv)
+ {
+     char *user;
+     char *this_user;
+     struct passwd *this_pwd, *pwd;
+     int ret;
+     gid_t groups[NGROUPS];
+     int ngroups;
+     gid_t pag0, pag1, pag2;
+ 
+ 
+     if (argc != 2)
+ 	errx (1, "Usage: %s user", argv[0]);
+     user = argv[1];
+ 
+     this_pwd = getpwuid (getuid ());
+     if (this_pwd == NULL)
+ 	errx (1, "Who are you?");
+     this_user = strdup (this_pwd->pw_name);
+ 
+     pwd = getpwnam (user);
+     if (pwd == NULL)
+ 	errx (1, "User %s not found", user);
+ 
+     ngroups = getgroups (NGROUPS, groups);
+     if (ngroups < 0)
+ 	err (1, "getgroups %d", NGROUPS);
+     printf ("user %s ", this_user);
+     print_groups (ngroups, groups);
+     printf ("doing setpag()\n");
+     ret = setpag ();
+     if (ret < 0)
+ 	err (1, "setpag");
+ 
+     ngroups = getgroups (NGROUPS, groups);
+     if (ngroups < 0)
+ 	err (1, "getgroups %d", NGROUPS);
+     pag0 = groups[0];
+     pag1 = groups[1];
+     pag2 = groups[2];
+     printf ("user %s ", this_user);
+     print_groups (ngroups, groups);
+ 
+     ret = initgroups (user, pwd->pw_gid);
+     if (ret < 0)
+ 	err (1, "initgroups");
+ 
+     ngroups = getgroups (NGROUPS, groups);
+     if (ngroups < 0)
+ 	err (1, "getgroups %d", NGROUPS);
+     printf ("user %s ", user);
+     print_groups (ngroups, groups);
+     if ((groups[0] == pag0 && groups[1] == pag1)
+ 	|| (groups[1] == pag1 && groups[2] == pag2))
+ 	return 0;
+     else
+ 	return 1;
+ }
+ 
Index: openafs/src/tests/test-setpag.c
diff -c /dev/null openafs/src/tests/test-setpag.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/test-setpag.c	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,116 ----
+ /*
+  * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <sys/types.h>
+ #include <sys/wait.h>
+ #include <sys/param.h>
+ #include <unistd.h>
+ #include <pwd.h>
+ #include <limits.h>
+ 
+ #include <err.h>
+ 
+ #ifdef RCSID
+ RCSID("$Id: test-setpag.c,v 1.1.2.1 2002/01/20 09:18:08 shadow Exp $");
+ #endif
+ 
+ #if !defined(NGROUPS) && defined(NGROUPS_MAX)
+ #define NGROUPS NGROUPS_MAX
+ #endif
+ 
+ static void
+ print_groups (int ngroups, gid_t groups[NGROUPS])
+ {
+     int i;
+ 
+     printf ("groups: ");
+     for (i = 0; i < ngroups; ++i)
+ 	printf ("%d%s", groups[i], (i < ngroups - 1) ? ", " : "");
+     printf ("\n");
+ }    
+ 
+ int
+ main(int argc, char **argv)
+ {
+     int ret;
+     gid_t groups[NGROUPS];
+     int ngroups;
+     gid_t pag1, pag2;
+     pid_t pid;
+ 
+     if (argc != 1)
+ 	errx (1, "Usage: %s", argv[0]);
+ 
+     ngroups = getgroups (NGROUPS, groups);
+     if (ngroups < 0)
+ 	err (1, "getgroups %d", NGROUPS);
+     pag1 = groups[1];
+     pag2 = groups[2];
+     printf ("in parent ");
+     print_groups (ngroups, groups);
+     pid = fork ();
+     if (pid < 0)
+ 	err (1, "fork");
+     if (pid == 0) {
+ 	ret = setpag ();
+ 	if (ret < 0)
+ 	    err (1, "setpag");
+ 	ngroups = getgroups (NGROUPS, groups);
+ 	if (ngroups < 0)
+ 	    err (1, "getgroups %d", NGROUPS);
+ 	printf ("in child ");
+ 	print_groups (ngroups, groups);
+ 	return 0;
+     } else {
+ 	int status;
+ 
+ 	while(waitpid (pid, &status, WNOHANG | WUNTRACED) != pid)
+ 	    ;
+ 	if (status)
+ 	    return 1;
+ 	ngroups = getgroups (NGROUPS, groups);
+ 	if (ngroups < 0)
+ 	    err (1, "getgroups %d", NGROUPS);
+ 	printf ("in parent ");
+ 	print_groups (ngroups, groups);
+ 	if (groups[1] == pag1 && groups[2] == pag2)
+ 	    return 0;
+ 	else
+ 	    return 1;
+     }
+ }
Index: openafs/src/tests/too-many-files
diff -c /dev/null openafs/src/tests/too-many-files:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/too-many-files	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,5 ----
+ #!/bin/sh
+ # $Id: too-many-files,v 1.1.2.1 2002/01/20 09:18:08 shadow Exp $
+ if test "X$FAST" != "X" ; then echo "Not running $0" ;  exit 0 ; fi
+ 
+ $objdir/create-files 31707 0
Index: openafs/src/tests/touch1
diff -c /dev/null openafs/src/tests/touch1:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/touch1	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,4 ----
+ #!/bin/sh
+ touch foobar || exit 1
+ test -f foobar || exit 1
+ rm foobar || exit 1
Index: openafs/src/tests/truncate-files.c
diff -c /dev/null openafs/src/tests/truncate-files.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/truncate-files.c	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,148 ----
+ /*
+  * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <dirent.h>
+ 
+ #include <err.h>
+ 
+ #ifdef RCSID
+ RCSID("$Id: truncate-files.c,v 1.1.2.1 2002/01/20 09:18:08 shadow Exp $");
+ #endif
+ 
+ static void do_dir(const char *);
+ static void repeat_dir(const char *);
+ 
+ static void
+ do_dir(const char *dirname)
+ {
+     int ret;
+ 
+     ret = chdir (dirname);
+     if (ret < 0)
+ 	err (1, "chdir %s", dirname);
+     repeat_dir (dirname);
+     ret = chdir ("..");
+     if (ret < 0)
+ 	err (1, "chdir ..");
+ }
+ 
+ static void
+ read_and_truncate (const char *filename, const struct stat *sb)
+ {
+     int fd;
+     char *buf;
+     int ret;
+     struct stat sb2;
+ 
+     buf = malloc (sb->st_size);
+     if (buf == NULL)
+ 	err (1, "malloc %lu", (unsigned long)sb->st_size);
+     fd = open (filename, O_RDONLY);
+     if (fd < 0)
+ 	err (1, "open readonly %s", filename);
+     ret = read (fd, buf, sb->st_size);
+     if (ret < 0)
+ 	err (1, "read %s", filename);
+     if (ret != sb->st_size)
+ 	errx (1, "short read from %s", filename);
+     if (close (fd))
+ 	err (1, "close reading %s", filename);
+     fd = open (filename, O_WRONLY | O_TRUNC, 0);
+     if (fd < 0)
+ 	err(1, "open wronly-trunc %s", filename);
+     ret = write (fd, buf, sb->st_size);
+     if (ret < 0)
+ 	err (1, "write %s", filename);
+     if (ret != sb->st_size)
+ 	errx (1, "short write %s", filename);
+     if (close (fd))
+ 	err (1, "close writing %s", filename);
+     ret = lstat (filename, &sb2);
+     if (ret < 0)
+ 	err (1, "stat %s", filename);
+     if (sb2.st_size != sb->st_size)
+ 	errx (1, "wrong size after re-writing %s: %lu != %lu",
+ 	      filename,
+ 	      (unsigned long)sb->st_size, (unsigned long)sb2.st_size);
+     free(buf);
+ }
+ 
+ static void
+ repeat_dir (const char *dirname)
+ {
+     DIR *dir;
+     struct dirent *dp;
+ 
+     dir = opendir (".");
+     if (dir == NULL)
+ 	err(1, "opendir %s", dirname);
+     while ((dp = readdir (dir)) != NULL) {
+ 	struct stat sb;
+ 	int ret;
+ 
+ 	if (strcmp (dp->d_name, ".") == 0
+ 	    || strcmp (dp->d_name, "..") == 0)
+ 	    continue;
+ 
+ 	ret = lstat (dp->d_name, &sb);
+ 	if (ret < 0)
+ 	    err (1, "lstat %s", dp->d_name);
+ 	if (S_ISDIR(sb.st_mode))
+ 	    do_dir (dp->d_name);
+ 	else if (S_ISREG(sb.st_mode))
+ 	    read_and_truncate (dp->d_name, &sb);
+     }
+     closedir (dir);
+ }
+ 
+ 
+ int
+ main(int argc, char **argv)
+ {
+ 
+     if (argc != 2)
+ 	errx (1, "usage: %s directory", argv[0]);
+     do_dir (argv[1]);
+     return 0;
+ }
Index: openafs/src/tests/truncate.c
diff -c /dev/null openafs/src/tests/truncate.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/truncate.c	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,108 ----
+ /*
+  * Copyright (c) 2000 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <unistd.h>
+ #include <fcntl.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ 
+ #include <err.h>
+ 
+ static void
+ create_and_write (char *name, const char *buf)
+ {
+     int fd, ret;
+     int len = strlen(buf);
+ 
+     fd = open (name, O_WRONLY|O_CREAT|O_TRUNC, 0666);
+     if (fd < 0)
+ 	err (1, "open");
+     ret = write (fd, buf, len);
+     if (ret != len)
+ 	err (1, "write");
+     ret = close (fd);
+     if (ret < 0)
+ 	err (1, "close");
+ }
+ 
+ static void
+ check_size (char *name, int len)
+ {
+     struct stat sb;
+     int ret;
+ 
+     ret = stat(name, &sb);
+     if (ret < 0)
+ 	err (1, "stat");
+ 
+     if (len != sb.st_size)
+ 	errx (1, "len != sb.st_size");
+ }
+ 
+ int
+ main(int argc, char **argv)
+ {
+     int ret;
+ 
+ 
+     create_and_write ("foo", "hej\n");
+ 
+     ret = truncate ("foo", 0);
+     if (ret < 0)
+ 	err (1, "truncate(0)");
+ 
+     check_size ("foo", 0);
+ 
+     ret = unlink("foo");
+     if (ret < 0)
+ 	errx (1, "unlink");
+ 
+     create_and_write ("bar", "hej\nhej\n");
+ 
+     ret = truncate ("bar", 16);
+     if (ret < 0)
+ 	err (1, "truncate(16)");
+ 
+     check_size ("bar", 16);
+ 
+     ret = unlink("bar");
+     if (ret < 0)
+ 	errx (1, "unlink");
+ 
+     return 0;
+ }
Index: openafs/src/tests/untar-emacs
diff -c /dev/null openafs/src/tests/untar-emacs:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/untar-emacs	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,9 ----
+ #!/bin/sh
+ # $Id: untar-emacs,v 1.1.2.1 2002/01/20 09:18:08 shadow Exp $
+ if test "X$FAST" != "X" ; then echo "Not running $0" ;  exit 0 ; fi
+ for i in 1 2 3 4 5 6 7 8 9 10; do
+   $objdir/echo-n '.' >&3
+   gzip -dc $AFSROOT/stacken.kth.se/ftp/pub/gnu/emacs/emacs-20.7.tar.gz | tar xvf - >&4 || exit 1
+   rm -rf emacs-20.7
+ done
+ echo >&3
Index: openafs/src/tests/untar-openafs
diff -c /dev/null openafs/src/tests/untar-openafs:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/untar-openafs	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,10 ----
+ #!/bin/sh
+ # $Id: untar-openafs,v 1.1.2.1 2002/01/20 09:18:08 shadow Exp $
+ if test "X$FAST" != "X" ; then echo "Not running $0" ;  exit 0 ; fi
+ wget http://www.openafs.org/dl/1.2.2/openafs-1.2.2-src.tar.gz
+ for i in 1 2 3 4 5 6 7 8 9 10; do
+   $objdir/echo-n '.' >&3
+   gzip -dc openafs-1.2.2-src.tar.gz | tar xvf - >&4 || exit 1
+   rm -rf openafs-1.2.2
+ done
+ echo >&3
Index: openafs/src/tests/util.c
diff -c /dev/null openafs/src/tests/util.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/util.c	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,164 ----
+ /*
+  * CMUCS AFStools
+  * dumpscan - routines for scanning and manipulating AFS volume dumps
+  *
+  * Copyright (c) 1998 Carnegie Mellon University
+  * All Rights Reserved.
+  * 
+  * Permission to use, copy, modify and distribute this software and its
+  * documentation is hereby granted, provided that both the copyright
+  * notice and this permission notice appear in all copies of the
+  * software, derivative works or modified versions, and any portions
+  * thereof, and that both notices appear in supporting documentation.
+  *
+  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+  *
+  * Carnegie Mellon requests users of this software to return to
+  *
+  *  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
+  *  School of Computer Science
+  *  Carnegie Mellon University
+  *  Pittsburgh PA 15213-3890
+  *
+  * any improvements or extensions that they make and grant Carnegie Mellon
+  * the rights to redistribute these changes.
+  */
+ 
+ /* util.c - Useful utilities */
+ 
+ #include <errno.h>
+ 
+ #include "xf_errs.h"
+ #include "dumpscan.h"
+ #include "dumpscan_errs.h"
+ #include "dumpfmt.h"
+ 
+ 
+ /* Take care of errno, ERROR_XFILE_EOF, and ENOMEM return codes.
+  * Call whatever callbacks are necessary, and return the code to
+  * actually use.  If you don't want '0' to result in a DSERR_TAG,
+  * then you must translate it to DSERR_DONE before calling this.
+  */
+ /*** THIS FUNCTION INTENDED FOR INTERNAL USE ONLY ***/
+ int handle_return(int r, XFILE *X, unsigned char tag, dump_parser *p)
+ {
+   u_int64 where, xwhere;
+ 
+   switch (r) {
+   case 0:
+     if (p->cb_error) {
+       xftell(X, &where);
+       sub64_32(xwhere, where, 1);
+       (p->cb_error)(DSERR_TAG, 1, p->err_refcon,
+                     (tag > 0x20 && tag < 0x7f)
+                     ? "Unexpected tag '%c' at %s = 0x%s"
+                     : "Unexpected tag 0x%02x at %s = 0x%s",
+                     tag, decimate_int64(&xwhere, 0), hexify_int64(&xwhere, 0));
+     }
+     return DSERR_TAG;
+     
+   case ERROR_XFILE_EOF:
+     if (p->cb_error) {
+       xftell(X, &where);
+       (p->cb_error)(ERROR_XFILE_EOF, 1, p->err_refcon,
+                     "Unexpected EOF at %s = 0x%s",
+                     decimate_int64(&where, 0), hexify_int64(&where, 0));
+     }
+     return ERROR_XFILE_EOF;
+     
+   case ENOMEM:
+     if (p->cb_error) {
+       xftell(X, &where);
+       (p->cb_error)(ENOMEM, 1, p->err_refcon,
+                     "Out of memory at %s = 0x%s",
+                     decimate_int64(&where, 0), hexify_int64(&where, 0));
+     }
+     return ENOMEM;
+     
+   case DSERR_DONE:
+     return 0;
+ 
+   default:
+     /* For other negative valuees, the callback was already done */
+     if (r > 0 && p->cb_error)
+       (p->cb_error)(r, 1, p->err_refcon,
+                     "System error %d reading dump file", r);
+     return r;
+   }
+ }
+ 
+ 
+ /* Prepare a tag_parse_info for use by the dump parser. *
+ /*** THIS FUNCTION INTENDED FOR INTERNAL USE ONLY ***/
+ void prep_pi(dump_parser *p, tag_parse_info *pi)
+ {
+   memset(pi, 0, sizeof(tag_parse_info));
+   pi->err_refcon = p->err_refcon;
+   pi->cb_error = p->cb_error;
+ 
+   if (p->repair_flags & DSFIX_SKIP)
+     pi->flags |= TPFLAG_SKIP;
+   if ((p->flags & DSFLAG_SEEK) && (p->repair_flags & DSFIX_RSKIP))
+     pi->flags |= TPFLAG_RSKIP;
+ }
+ 
+ 
+ /* Does the designated location match a vnode?
+  * Returns 0 if yes, DSERR_FMT if no, something else on error
+  */
+ /*** THIS FUNCTION INTENDED FOR INTERNAL USE ONLY ***/
+ int match_next_vnode(XFILE *X, dump_parser *p, u_int64 *where, afs_uint32 vnode)
+ {
+   afs_uint32 r, x, y, z;
+   unsigned char tag;
+ 
+   if (r = xfseek(X, where)) return r;
+   if (r = ReadByte(X, &tag)) return r;
+   switch (tag) {
+   case 3:  /* A vnode? */
+     if (r = ReadInt32(X, &x)) return r;
+     if (r = ReadInt32(X, &y)) return r;
+     if (r = ReadByte(X, &tag)) return r;
+     if ( !((vnode & 1) && !(x & 1) && x < vnode)
+     &&   !((vnode & 1) == (x & 1) && x > vnode))
+       return DSERR_FMT;
+     if (x > vnode && x - vnode > 10000) return DSERR_FMT;
+     if (y < 0 || y > p->vol_uniquifier)  return DSERR_FMT;
+ 
+     /* Now, what follows the vnode/uniquifier? */
+     switch (tag) {
+     case 3:   /* Another vnode? - Only if this is a non-directory */
+       if (x & 1) return DSERR_FMT;
+       if (r = ReadInt32(X, &z)) return r;
+       if ( !((x & 1) && !(z & 1) && z < x)
+       &&   !((x & 1) == (z & 1) && z > x))
+         return DSERR_FMT;
+       return 0;
+ 
+     case 4:   /* Dump end - Only if this is a non-directory */
+       if (x & 1) return DSERR_FMT;
+       if (r = ReadInt32(X, &z)) return r;
+       if (z != DUMPENDMAGIC) return DSERR_FMT;
+       return 0;
+ 
+     case 't': /* Vnode type byte */
+       if (r = ReadByte(X, &tag)) return r;
+       if ((tag == vFile || tag == vSymlink) && !(x & 1)) return 0;
+       if (tag == vDirectory && (x & 1)) return 0;
+       return DSERR_FMT;
+ 
+     default:
+       return DSERR_FMT;
+     }
+ 
+   case 4:  /* A dump end? */
+     if (r = ReadInt32(X, &x)) return r;
+     if (x != DUMPENDMAGIC) return DSERR_FMT;
+     return 0;
+ 
+   default:
+     return DSERR_FMT;
+   }
+ }
Index: openafs/src/tests/utime-dir.c
diff -c /dev/null openafs/src/tests/utime-dir.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/utime-dir.c	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,77 ----
+ /*
+  * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <errno.h>
+ 
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <sys/time.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <err.h>
+ 
+ static void
+ doit (const char *filename)
+ {
+     int ret;
+     struct timeval tv[2];
+ 
+     ret = mkdir (filename, 0700);
+     if (ret < 0)
+ 	err (1, "mkdir %s", filename);
+     gettimeofday (&tv[0], NULL);
+     tv[1] = tv[0];
+     ret = utimes (filename, tv);
+     if (ret < 0)
+ 	err(1, "utimes %s", filename);
+ }
+ 
+ int
+ main(int argc, char **argv)
+ {
+     const char *file = "blaha";
+ 
+     if (argc != 1 && argc != 2)
+ 	errx (1, "usage: %s [file]", argv[0]);
+     if (argc == 2)
+ 	file = argv[1];
+     doit (file);
+     return 0;
+ }
Index: openafs/src/tests/utime-file.c
diff -c /dev/null openafs/src/tests/utime-file.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/utime-file.c	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,97 ----
+ /*
+  * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #ifdef RCSID
+ RCSID("$Id: utime-file.c,v 1.1.2.1 2002/01/20 09:18:08 shadow Exp $");
+ #endif
+ 
+ #include <fcntl.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <utime.h>
+ #include <sys/stat.h>
+ #include <sys/time.h>
+ 
+ #include <err.h>
+ 
+ int
+ main (int argc, char ** argv)
+ {
+     int len;
+     int ret;
+     int fd;
+     char *filename = "foo";
+     char *buf;
+     struct stat sb;
+     struct utimbuf t;
+ 
+     switch (argc) {
+     case 1:
+ 	len = 8 * 1024; break;
+     case 2:
+ 	len = atoi(argv[1]);
+ 	if (len == 0)
+ 	    errx (1, "invalid len");
+     default:
+ 	errx (1, "argv != [12]");
+     }
+ 
+     buf = malloc (len);
+     memset (buf, 'a', len);
+ 
+     fd = open (filename, O_RDWR|O_CREAT|O_EXCL, 0744);
+     if (fd < 0)
+ 	errx (1, "open");
+     ret = fstat (fd, &sb);
+     if (ret < 0)
+ 	errx (1, "open");
+ 
+     ret = ftruncate (fd, len);
+     fstat (fd, &sb);
+     lseek (fd, 0, SEEK_SET);
+     write (fd, buf, len);
+     fstat (fd, &sb);
+ 
+     t.modtime = t.actime = time (NULL); 
+     utime (filename, &t);
+ 
+     close (fd);
+     free (buf);
+ 
+     return 0;
+ }
Index: openafs/src/tests/visit-volumes
diff -c /dev/null openafs/src/tests/visit-volumes:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/visit-volumes	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,6 ----
+ #!/bin/sh
+ # $Id: visit-volumes,v 1.1.2.1 2002/01/20 09:18:08 shadow Exp $
+ ls ${AFSROOT}/nada.kth.se/* >&4 2>&4 || exit 1
+ ls -l ${AFSROOT}/nada.kth.se/* >&4 2>&4 || exit 1
+ ls ${AFSROOT}/nada.kth.se/*/* >&4 2>&4 || exit 1
+ ls -l ${AFSROOT}/nada.kth.se/*/* >&4 2>&4 || exit 1
Index: openafs/src/tests/vosaddsite.pl
diff -c /dev/null openafs/src/tests/vosaddsite.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/vosaddsite.pl	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,19 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, $ret);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ &AFS_vos_addsite("testvol","localhost","b",);
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/vosbackup.pl
diff -c /dev/null openafs/src/tests/vosbackup.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/vosbackup.pl	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,19 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, $ret);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ &AFS_vos_backup("rep",);
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/voscreate.pl
diff -c /dev/null openafs/src/tests/voscreate.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/voscreate.pl	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,20 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, $ret);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ $ret = &AFS_vos_create("testvol","localhost","a",,);
+ $ret = &AFS_vos_create("testvol2","localhost","a",,);
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/vosdelentry.pl
diff -c /dev/null openafs/src/tests/vosdelentry.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/vosdelentry.pl	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,19 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, $ret);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ &AFS_vos_delentry("testvol",);
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/vosdump.pl
diff -c /dev/null openafs/src/tests/vosdump.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/vosdump.pl	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,19 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, $ret);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ &AFS_vos_dump("service",0,"/usr/tmp/service.dump",);
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/vosexamine.pl
diff -c /dev/null openafs/src/tests/vosexamine.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/vosexamine.pl	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,32 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, %info, %info2, @rosites, $tmp, @rosite);
+ $host = `hostname`;
+ chomp $host;
+ &AFS_Init();
+ 
+ %info = &AFS_vos_examine("rep",);
+ if ($info{'rwpart'} ne "a") {
+     exit 1;
+ }
+ 
+ $ret = $info{'rosites'};
+ @rosites = @$ret;
+ while ($ret = pop(@rosites)) {
+     @rosite = @$ret;
+     if ($rosite[1] ne "a") {
+ 	exit 1;
+     }
+ }
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/voslistpart.pl
diff -c /dev/null openafs/src/tests/voslistpart.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/voslistpart.pl	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,26 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, $ret, @parts, $count);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ @parts = &AFS_vos_listpart("localhost",);
+ $ret = shift(@parts);
+ if ($ret ne "a") {
+     exit (1);
+ }
+ $ret = shift(@parts);
+ if ($ret ne "b") {
+     exit (1);
+ }
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/voslistvldb.pl
diff -c /dev/null openafs/src/tests/voslistvldb.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/voslistvldb.pl	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,24 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, $ret, %vols, $lvol, %vol);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ %vols = &AFS_vos_listvldb(undef,"localhost","b",,);
+ $lvol=$vols{'testvol3'};
+ %vol=%$lvol;
+ # if it worked it worked...
+ if ($vol{'rwpart'} ne "b") {
+     exit(1);
+ }
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/voslistvol.pl
diff -c /dev/null openafs/src/tests/voslistvol.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/voslistvol.pl	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,24 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, $ret, %vols, $lvol, %vol);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ %vols = &AFS_vos_listvol("localhost","b",);
+ $lvol=$vols{'testvol3'};
+ %vol=%$lvol;
+ # if it worked it worked...
+ if ($vol{'part'} ne "b") {
+     exit(1);
+ }
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/voslock.pl
diff -c /dev/null openafs/src/tests/voslock.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/voslock.pl	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,19 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, $ret);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ &AFS_vos_lock("testvol",);
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/vosmove.pl
diff -c /dev/null openafs/src/tests/vosmove.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/vosmove.pl	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,19 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, $ret);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ &AFS_vos_move("testvol","localhost","a","localhost","b",);
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/vospartinfo.pl
diff -c /dev/null openafs/src/tests/vospartinfo.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/vospartinfo.pl	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,19 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, $ret, %info);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ %info = &AFS_vos_partinfo("localhost",,);
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/vosrelease.pl
diff -c /dev/null openafs/src/tests/vosrelease.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/vosrelease.pl	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,19 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, $ret);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ &AFS_vos_release("testvol",,);
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/vosremove.pl
diff -c /dev/null openafs/src/tests/vosremove.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/vosremove.pl	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,19 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, $ret);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ &AFS_vos_remove("testvol.readonly","localhost","b",);
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/vosremsite.pl
diff -c /dev/null openafs/src/tests/vosremsite.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/vosremsite.pl	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,19 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, $ret);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ &AFS_vos_remsite("testvol","localhost","b",);
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/vosrename.pl
diff -c /dev/null openafs/src/tests/vosrename.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/vosrename.pl	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,19 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, $ret);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ &AFS_vos_rename("testvol","testvol3",);
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/vosrestore.pl
diff -c /dev/null openafs/src/tests/vosrestore.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/vosrestore.pl	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,19 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, $ret);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ &AFS_vos_restore("service2","localhost","a","/usr/tmp/service.dump",,"full",);
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/vossyncserv.pl
diff -c /dev/null openafs/src/tests/vossyncserv.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/vossyncserv.pl	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,19 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, $ret);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ &AFS_vos_syncserv("localhost","a",,);
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/vossyncvldb.pl
diff -c /dev/null openafs/src/tests/vossyncvldb.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/vossyncvldb.pl	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,19 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, $ret);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ &AFS_vos_syncvldb("localhost","b",,);
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/vosunlock.pl
diff -c /dev/null openafs/src/tests/vosunlock.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/vosunlock.pl	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,19 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, $ret);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ &AFS_vos_unlock("testvol",);
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/vosunlockall.pl
diff -c /dev/null openafs/src/tests/vosunlockall.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/vosunlockall.pl	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,21 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, $ret);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ &AFS_vos_lock("testvol",);
+ &AFS_vos_lock("service",);
+ &AFS_vos_unlockvldb("localhost",,);
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/voszap.pl
diff -c /dev/null openafs/src/tests/voszap.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/voszap.pl	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,19 ----
+ #!/usr/bin/env perl
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT %AFS_Help);
+ use OpenAFS::afsconf;
+ use OpenAFS::fs;
+ use OpenAFS::pts;
+ use OpenAFS::vos;
+ use OpenAFS::bos;
+ 
+ my ($host, $ret);
+ $host = `hostname`;
+ &AFS_Init();
+ 
+ &AFS_vos_zap("testvol2","localhost","a",,);
+ 
+ exit(0);
+ 
+ 
+ 
Index: openafs/src/tests/warn.c
diff -c /dev/null openafs/src/tests/warn.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:56 2002
--- openafs/src/tests/warn.c	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,48 ----
+ /*
+  * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan 
+  * (Royal Institute of Technology, Stockholm, Sweden).  
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ RCSID("$Id: warn.c,v 1.1.2.1 2002/01/20 09:18:08 shadow Exp $");
+ #endif
+ 
+ #include "err.h"
+ 
+ void
+ warn(const char *fmt, ...)
+ {
+   va_list ap;
+   va_start(ap, fmt);
+   vwarn(fmt, ap);
+   va_end(ap);
+ }
Index: openafs/src/tests/warnx.c
diff -c /dev/null openafs/src/tests/warnx.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:57 2002
--- openafs/src/tests/warnx.c	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,48 ----
+ /*
+  * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan 
+  * (Royal Institute of Technology, Stockholm, Sweden).  
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ RCSID("$Id: warnx.c,v 1.1.2.1 2002/01/20 09:18:08 shadow Exp $");
+ #endif
+ 
+ #include "err.h"
+ 
+ void
+ warnx(const char *fmt, ...)
+ {
+   va_list ap;
+   va_start(ap, fmt);
+   vwarnx(fmt, ap);
+   va_end(ap);
+ }
Index: openafs/src/tests/write-closed.c
diff -c /dev/null openafs/src/tests/write-closed.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:57 2002
--- openafs/src/tests/write-closed.c	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,95 ----
+ /*
+  * Copyright (c) 2000 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <errno.h>
+ 
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <sys/mman.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <dirent.h>
+ 
+ 
+ #include <err.h>
+ 
+ #ifndef MAP_FAILED
+ #define MAP_FAILED ((void *)-1)
+ #endif
+ 
+ static void
+ doit (const char *filename)
+ {
+     int fd;
+     int ret;
+     void *buf;
+ 
+     fd = open (filename, O_RDWR | O_CREAT | O_TRUNC, 0600);
+     if (fd < 0)
+ 	err (1, "open %s", filename);
+     ret = ftruncate (fd, 1);
+     if (ret < 0)
+ 	err (1, "ftruncate %s", filename);
+     buf = mmap (NULL, 1, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+     if (buf == (void *) MAP_FAILED)
+ 	err (1, "mmap");
+     if (fchmod (fd, 0) < 0)
+ 	err (1, "fchmod %s, 0", filename);
+     ret = close (fd);
+     if (ret < 0)
+ 	err (1, "close %s", filename);
+     *((char *)buf) = 0x17;
+     ret = munmap (buf, 1);
+     if (ret < 0)
+ 	err (1, "munmap");
+ }
+ 
+ int
+ main(int argc, char **argv)
+ {
+     const char *file = "foo";
+ 
+     if (argc != 1 && argc != 2)
+ 	errx (1, "usage: %s [file]", argv[0]);
+     if (argc == 2)
+ 	file = argv[1];
+     doit (file);
+     return 0;
+ }
Index: openafs/src/tests/write-closed2.c
diff -c /dev/null openafs/src/tests/write-closed2.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:57 2002
--- openafs/src/tests/write-closed2.c	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,128 ----
+ /*
+  * Copyright (c) 2000 - 2001 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <errno.h>
+ 
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <sys/mman.h>
+ #ifdef HAVE_SYS_IOCCOM_H
+ #include <sys/ioccom.h>
+ #endif
+ #include <sys/ioctl.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <dirent.h>
+ 
+ #include <err.h>
+ #include <netinet/in.h>
+ #include <afs/param.h>
+ #include <afs/stds.h>
+ #include <afs/vice.h>
+ #include <afs/venus.h>
+ 
+ #ifndef MAP_FAILED
+ #define MAP_FAILED ((void *)-1)
+ #endif
+ 
+ static int
+ set_acl (char *dir)
+ {
+     struct ViceIoctl a_params;
+     char *foo = "1\n0\nsystem:anyuser 0\n";
+ 
+     a_params.in_size  = strlen(foo);
+     a_params.out_size = 0;
+     a_params.in       = foo;
+     a_params.out      = NULL;
+ 
+     return pioctl (dir, VIOCSETAL, &a_params, 1);
+ }
+ 
+ static void
+ doit (const char *filename)
+ {
+     int fd;
+     int ret;
+     void *buf;
+ 
+     ret = mkdir ("bad", 0777);
+     if (ret < 0)
+ 	err (1, "mkdir bad");
+ 
+     ret = chdir ("bad");
+     if (ret < 0)
+ 	err (1, "chdir bad");
+ 
+     fd = open (filename, O_RDWR | O_CREAT | O_TRUNC, 0600);
+     if (fd < 0)
+ 	err (1, "open %s", filename);
+     ret = ftruncate (fd, 1);
+     if (ret < 0)
+ 	err (1, "ftruncate %s", filename);
+     buf = mmap (NULL, 1, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+     if (buf == (void *) MAP_FAILED)
+ 	err (1, "mmap");
+     ret = set_acl (".");
+     if (ret < 0)
+ 	err (1, "setacl failed");
+ 
+     ret = close (fd);
+     if (ret < 0)
+ 	err (1, "close %s", filename);
+     *((char *)buf) = 0x17;
+     ret = munmap (buf, 1);
+     if (ret < 0)
+ 	err (1, "munmap");
+ }
+ 
+ int
+ main(int argc, char **argv)
+ {
+     const char *file = "foo";
+ 
+ 
+     if (argc != 1 && argc != 2)
+ 	errx (1, "usage: %s [file]", argv[0]);
+     if (argc == 2)
+ 	file = argv[1];
+     doit (file);
+     return 0;
+ }
Index: openafs/src/tests/write-large.c
diff -c /dev/null openafs/src/tests/write-large.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:57 2002
--- openafs/src/tests/write-large.c	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,96 ----
+ /*
+  * Copyright (c) 2001 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #define _LARGEFILE64_SOURCE
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <sys/types.h>
+ 
+ #include <stdio.h>
+ 
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ 
+ 
+ #include <err.h>
+ 
+ const char *fn = "foobar";
+ 
+ static void
+ check_size(const char *fn, size_t sz, int paranoia)
+ {
+     struct stat sb;
+ 
+     if (paranoia)
+ 	return;
+ 
+     if (stat(fn, &sb) < 0)
+ 	err(1, "stat");
+     if (sb.st_size != sz)
+ 	errx(1, "st_size mismatch %d != %d", (int)sb.st_size, (int)sz);
+ }
+ 
+ int
+ main(int argc, char **argv)
+ {
+     int fd, cnt, ret;
+     int buf[1024];
+ 
+ #ifdef O_LARGEFILE
+     fd = open(fn, O_RDWR|O_CREAT|O_TRUNC|O_LARGEFILE, 0644);
+ #else
+     fd = open(fn, O_RDWR|O_CREAT|O_TRUNC, 0644);
+ #endif
+     if (fd < 0)
+ 	err(1, "open1");
+     cnt=0;
+     while (cnt < 2097151) {
+       ret = write(fd,buf,1024);
+       if (ret != 1024)
+ 	errx(1, "write1 %d %d", cnt, ret);
+       cnt++;
+     }
+     ret = write(fd,buf,1024);
+     if (ret != 1023)
+       errx(1, "write1 last %d", ret);
+     if (close(fd) < 0)
+ 	err(1, "close1");
+     
+     check_size(fn, 2147483647, 0);
+     
+     return 0;
+ }
Index: openafs/src/tests/write-rand.c
diff -c /dev/null openafs/src/tests/write-rand.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:57 2002
--- openafs/src/tests/write-rand.c	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,111 ----
+ /*
+  * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <sys/types.h>
+ #include <fcntl.h>
+ #include <time.h>
+ #include <unistd.h>
+ #include <string.h>
+ #include <sys/mman.h>
+ #include <sys/stat.h>
+ #include <err.h>
+ 
+ #ifdef RCSID
+ RCSID("$Id: write-rand.c,v 1.1.2.1 2002/01/20 09:18:08 shadow Exp $");
+ #endif
+ 
+ static char *
+ write_random_file (int fd, size_t sz)
+ {
+     char *buf;
+     int i, j;
+ 
+     j = sz;
+     if (j > 2048) {
+       j = 2048;
+     }
+     buf = malloc (j);
+     if (buf == NULL)
+ 	err (1, "malloc %u", (unsigned)sz);
+ 
+     for (i = 0; i < j; ++i) {
+       buf[i] = rand();
+     }      
+     while (sz > 0) {
+       if (write (fd, buf, j) != j)
+ 	err (1, "write");
+       
+       sz -= j;
+       j = sz;
+       if (j > 2048)
+ 	j = 2048;
+     }
+ 
+     return 0;
+ }
+ 
+ int
+ main (int argc, char **argv)
+ {
+     const char *file;
+     const size_t sz;
+     char *random_buf;
+     char *read_buf1;
+     char *read_buf2;
+     int fd;
+ 
+     if (argc != 3) 
+       errx (1, "usage: %s file size", argv[0]);
+ 
+     file = argv[1];
+     sz = atoi(argv[2]);
+ 
+     srand (time(NULL));
+ 
+     fd = open (file, O_RDWR | O_CREAT, 0755);
+     if (fd < 0)
+ 	err (1, "open %s", file);
+ 
+     if (lseek(fd, 0, SEEK_SET) < 0)
+ 	err (1, "lseek");
+     write_random_file(fd, sz);
+ 
+     close (fd);
+     return 0;
+ }
Index: openafs/src/tests/write-ro
diff -c /dev/null openafs/src/tests/write-ro:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:57 2002
--- openafs/src/tests/write-ro	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,3 ----
+ #!/bin/sh
+ touch ../../replicated/foo || exit 0
+ exit 1
Index: openafs/src/tests/write-ro-file.c
diff -c /dev/null openafs/src/tests/write-ro-file.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:57 2002
--- openafs/src/tests/write-ro-file.c	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,69 ----
+ /*
+  * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <unistd.h>
+ #include <fcntl.h>
+ 
+ #include <err.h>
+ 
+ #ifdef RCSID
+ RCSID("$Id: write-ro-file.c,v 1.1.2.1 2002/01/20 09:18:08 shadow Exp $");
+ #endif
+ 
+ int
+ main(int argc, char *argv[])
+ {
+   int fd;
+   int ret;
+ 
+   fd = open("foo", O_RDWR|O_CREAT, 0);
+   if (fd < 0)
+       err (1, "open foo");
+   ret = write (fd, "foo", 3);
+   if (ret < 0) {
+       unlink("foo");
+       err (1, "write foo");
+   }
+   ret = close (fd);
+   if (ret < 0) {
+       unlink("foo");
+       err (1, "close foo");
+   }
+   unlink("foo");
+   return 0;
+ }
Index: openafs/src/tests/write-ucc.c
diff -c /dev/null openafs/src/tests/write-ucc.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:57 2002
--- openafs/src/tests/write-ucc.c	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,101 ----
+ /*
+  * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <errno.h>
+ 
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <sys/time.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <err.h>
+ 
+ static void
+ doit (const char *filename)
+ {
+     int fd;
+     int ret;
+     struct timeval tv[2];
+     struct stat sb;
+ 
+     fd = open (filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+     if (fd < 0)
+ 	err (1, "open %s", filename);
+     ret = write (fd, "hej\n", 4);
+     if(ret < 0)
+ 	err (1, "write %s", filename);
+     if (ret != 4)
+ 	errx (1, "short write to %s", filename);
+     gettimeofday (&tv[0], NULL);
+     tv[1] = tv[0];
+     ret = utimes (filename, tv);
+     if(ret < 0)
+ 	err (1, "utimes %s", filename);
+     ret = chmod (filename, 0644);
+     if (ret < 0)
+ 	err (1, "chmod %s", filename);
+     ret = chown (filename, 0, 0);
+     ret = fstat (fd, &sb);
+     if (ret < 0)
+ 	err (1, "fstat %s", filename);
+     if (sb.st_size != 4)
+ 	errx (1, "stat 1: size = %lu != 4", (unsigned long)sb.st_size);
+     ret = close (fd);
+     if (ret < 0)
+ 	err (1, "close %s", filename);
+     ret = stat (filename, &sb);
+     if (ret < 0)
+ 	err (1, "stat %s", filename);
+     if (sb.st_size != 4)
+ 	errx (1, "stat 1: size = %lu != 4", (unsigned long)sb.st_size);
+ }
+ 
+ int
+ main(int argc, char **argv)
+ {
+     const char *file = "blaha";
+ 
+     if (argc != 1 && argc != 2)
+ 	errx (1, "usage: %s [file]", argv[0]);
+     if (argc == 2)
+ 	file = argv[1];
+     doit (file);
+     return 0;
+ }
Index: openafs/src/tests/write1
diff -c /dev/null openafs/src/tests/write1:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:57 2002
--- openafs/src/tests/write1	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,4 ----
+ #!/bin/sh
+ echo hej > foo || exit 1
+ if test X`cat foo` != X"hej"; then exit 1; fi
+ rm foo || exit 1
Index: openafs/src/tests/write2
diff -c /dev/null openafs/src/tests/write2:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:57 2002
--- openafs/src/tests/write2	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,6 ----
+ #!/bin/sh
+ echo hopp > foo || exit 1
+ if test X`cat foo` != "Xhopp"; then exit 1; fi
+ echo hej > foo || exit 1
+ if test X`cat foo` != "Xhej"; then exit 1; fi
+ rm foo || exit 1
Index: openafs/src/tests/write3.c
diff -c /dev/null openafs/src/tests/write3.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:57 2002
--- openafs/src/tests/write3.c	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,125 ----
+ /*
+  * Copyright (c) 2001 Kungliga Tekniska Högskolan
+  * (Royal Institute of Technology, Stockholm, Sweden).
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 
+  * 3. Neither the name of the Institute nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ 
+ #include <sys/types.h>
+ 
+ #include <stdio.h>
+ 
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ 
+ 
+ #include <err.h>
+ 
+ const char *fn = "foobar";
+ 
+ static void
+ check_size(const char *fn, size_t sz, int paranoia)
+ {
+     struct stat sb;
+ 
+     if (paranoia)
+ 	return;
+ 
+     if (stat(fn, &sb) < 0)
+ 	err(1, "stat");
+     if (sb.st_size != sz)
+ 	errx(1, "st_size mismatch %d != %d", (int)sb.st_size, (int)sz);
+ }
+ 
+ static void
+ check_size_read(int fd, size_t sz)
+ {
+     off_t old_off;
+     size_t sz2;
+     void *buf;
+ 
+     if ((old_off = lseek(fd, 0, SEEK_CUR)) < 0)
+ 	err(1, "lseek");
+ 
+     if (lseek(fd, 0, SEEK_SET) < 0)
+ 	err(1, "lseek");
+     buf = malloc(sz);
+     if (buf == NULL)
+ 	errx(1, "malloc");
+     if ((sz2 = read(fd, buf, sz)) < 0)
+ 	errx(1, "read");
+     if (sz2 != sz)
+ 	errx(1, "end before end: sz2 (%u) != sz (%u)", (unsigned)sz2,
+ 	     (unsigned)sz);
+     if ((sz2 = lseek(fd, 0, SEEK_END)) < 0)
+ 	errx(1, "lseek");
+     if (sz2 != sz)
+ 	errx(1, "end past end: sz2 (%u) != sz (%u)", (unsigned)sz2,
+ 	     (unsigned)sz);
+     free(buf);
+ }
+ 
+ 
+ int
+ main(int argc, char **argv)
+ {
+     int fd;
+ 
+     fd = open(fn, O_RDWR|O_CREAT|O_TRUNC, 0644);
+     if (fd < 0)
+ 	err(1, "open1");
+     if (write(fd,"kaka", 4) != 4)
+ 	errx(1, "write1");
+     check_size(fn, 4, 1);
+     if (close(fd) < 0)
+ 	err(1, "close1");
+     
+     check_size(fn, 4, 0);
+     
+     fd = open(fn,O_RDWR|O_CREAT|O_TRUNC,644);
+     if (fd < 0)
+ 	err(1, "open2");
+     check_size(fn, 0, 1);
+     if (write(fd,"kaka", 4) != 4)
+ 	errx(1, "write2");
+     check_size(fn, 4, 1);
+     check_size_read(fd, 4);
+     if (close(fd) < 0)
+         err(1, "close2");
+     check_size(fn, 4, 1);
+ 
+     unlink(fn);
+ 
+     return 0;
+ }
Index: openafs/src/tests/xf_errs.et
diff -c /dev/null openafs/src/tests/xf_errs.et:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:57 2002
--- openafs/src/tests/xf_errs.et	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,37 ----
+ # CMUCS AFStools
+ # dumpscan - routines for scanning and manipulating AFS volume dumps
+ #
+ # Copyright (c) 1998 Carnegie Mellon University
+ # All Rights Reserved.
+ # 
+ # Permission to use, copy, modify and distribute this software and its
+ # documentation is hereby granted, provided that both the copyright
+ # notice and this permission notice appear in all copies of the
+ # software, derivative works or modified versions, and any portions
+ # thereof, and that both notices appear in supporting documentation.
+ #
+ # CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ # CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ # ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ #
+ # Carnegie Mellon requests users of this software to return to
+ #
+ #  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
+ #  School of Computer Science
+ #  Carnegie Mellon University
+ #  Pittsburgh PA 15213-3890
+ #
+ # any improvements or extensions that they make and grant Carnegie Mellon
+ # the rights to redistribute these changes.
+ 
+ # xf_errs.et - Error table for xfiles
+ 
+ error_table xFil
+   ec ERROR_XFILE_EOF,            "EOF while reading XFILE"
+   ec ERROR_XFILE_WRONLY,         "XFILE may not be opened write-only"
+   ec ERROR_XFILE_RDONLY,         "XFILE is read-only"
+   ec ERROR_XFILE_NOSEEK,         "XFILE is not seekable"
+   ec ERROR_XFILE_ISPASS,         "XFILE passthru already set"
+   ec ERROR_XFILE_NOPASS,         "XFILE passthru not set"
+   ec ERROR_XFILE_TYPE,           "unknown XFILE type"
+ end
Index: openafs/src/tests/xf_files.c
diff -c /dev/null openafs/src/tests/xf_files.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:57 2002
--- openafs/src/tests/xf_files.c	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,200 ----
+ /*
+  * CMUCS AFStools
+  * dumpscan - routines for scanning and manipulating AFS volume dumps
+  *
+  * Copyright (c) 1998 Carnegie Mellon University
+  * All Rights Reserved.
+  * 
+  * Permission to use, copy, modify and distribute this software and its
+  * documentation is hereby granted, provided that both the copyright
+  * notice and this permission notice appear in all copies of the
+  * software, derivative works or modified versions, and any portions
+  * thereof, and that both notices appear in supporting documentation.
+  *
+  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+  *
+  * Carnegie Mellon requests users of this software to return to
+  *
+  *  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
+  *  School of Computer Science
+  *  Carnegie Mellon University
+  *  Pittsburgh PA 15213-3890
+  *
+  * any improvements or extensions that they make and grant Carnegie Mellon
+  * the rights to redistribute these changes.
+  */
+ 
+ /* xf_files.c - XFILE routines for accessing UNIX files */
+ 
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <errno.h>
+ 
+ #include "xfiles.h"
+ #include "xf_errs.h"
+ 
+ #define O_MODE_MASK (O_RDONLY | O_WRONLY | O_RDWR)
+ 
+ 
+ /* do_read for stdio xfiles */
+ static afs_uint32 xf_FILE_do_read(XFILE *X, void *buf, afs_uint32 count)
+ {
+   FILE *F = X->refcon;
+ 
+   /* XXX: handle short and interrupted reads */
+   if (fread(buf, count, 1, F) != 1)
+     return ferror(F) ? errno : ERROR_XFILE_EOF;
+   return 0;
+ }
+ 
+ 
+ /* do_write for stdio xfiles */
+ static afs_uint32 xf_FILE_do_write(XFILE *X, void *buf, afs_uint32 count)
+ {
+   FILE *F = X->refcon;
+ 
+   /* XXX: handle interrupted writes */
+   if (fwrite(buf, count, 1, F) != 1)
+     return errno;
+   return 0;
+ }
+ 
+ 
+ /* do_tell for stdio xfiles */
+ static afs_uint32 xf_FILE_do_tell(XFILE *X, u_int64 *offset)
+ {
+   FILE *F = X->refcon;
+   off_t where;
+ 
+   where = ftell(F);
+   if (where == -1) return errno;
+   set64(*offset, where);
+   return 0;
+ }
+ 
+ 
+ /* do_seek for stdio xfiles */
+ static afs_uint32 xf_FILE_do_seek(XFILE *X, u_int64 *offset)
+ {
+   FILE *F = X->refcon;
+   off_t where = get64(*offset);
+ 
+   if (fseek(F, where, SEEK_SET) == -1) return errno;
+   return 0;
+ }
+ 
+ 
+ /* do_skip for stdio xfiles */
+ static afs_uint32 xf_FILE_do_skip(XFILE *X, afs_uint32 count)
+ {
+   FILE *F = X->refcon;
+ 
+   if (fseek(F, count, SEEK_CUR) == -1) return errno;
+   return 0;
+ }
+ 
+ 
+ /* do_close for stdio xfiles */
+ static afs_uint32 xf_FILE_do_close(XFILE *X)
+ {
+   FILE *F = X->refcon;
+ 
+   X->refcon = 0;
+   if (fclose(F)) return errno;
+   return 0;
+ }
+ 
+ 
+ /* Prepare a stdio XFILE */
+ static void prepare(XFILE *X, FILE *F, int xflag)
+ {
+   struct stat st;
+ 
+   memset(X, 0, sizeof(*X));
+   X->do_read  = xf_FILE_do_read;
+   X->do_write = xf_FILE_do_write;
+   X->do_tell  = xf_FILE_do_tell;
+   X->do_close = xf_FILE_do_close;
+   X->refcon = F;
+   if (xflag == O_RDWR) X->is_writable = 1;
+ 
+   if (!fstat(fileno(F), &st)
+   && ((st.st_mode & S_IFMT) == S_IFREG
+   ||  (st.st_mode & S_IFMT) == S_IFBLK)) {
+     X->is_seekable = 1;
+     X->do_seek = xf_FILE_do_seek;
+     X->do_skip = xf_FILE_do_skip;
+   }
+ }
+ 
+ 
+ /* Open an XFILE by path */
+ afs_uint32 xfopen_path(XFILE *X, int flag, char *path, int mode)
+ {
+   FILE *F = 0;
+   int fd = -1, xflag;
+   afs_uint32 code;
+ 
+   xflag = flag & O_MODE_MASK;
+   if (xflag == O_WRONLY) return ERROR_XFILE_WRONLY;
+ 
+   if ((fd = open(path, flag, mode)) < 0) return errno;
+   if (!(F = fdopen(fd, (xflag == O_RDONLY) ? "r" : "r+"))) {
+     code = errno;
+     close(fd);
+     return code;
+   }
+ 
+   prepare(X, F, xflag);
+   return 0;
+ }
+ 
+ 
+ /* Open an XFILE by FILE * */
+ afs_uint32 xfopen_FILE(XFILE *X, int flag, FILE *F)
+ {
+   flag &= O_MODE_MASK;
+   if (flag == O_WRONLY) return ERROR_XFILE_WRONLY;
+   prepare(X, F, flag);
+   return 0;
+ }
+ 
+ 
+ /* Open an XFILE by file descriptor */
+ afs_uint32 xfopen_fd(XFILE *X, int flag, int fd)
+ {
+   FILE *F;
+ 
+   flag &= O_MODE_MASK;
+   if (flag == O_WRONLY) return ERROR_XFILE_WRONLY;
+   if (!(F = fdopen(fd, (flag == O_RDONLY) ? "r" : "r+"))) return errno;
+   prepare(X, F, flag);
+   return 0;
+ }
+ 
+ 
+ /* open-by-name support for filenames */
+ afs_uint32 xfon_path(XFILE *X, int flag, char *name)
+ {
+   return xfopen_path(X, flag, name, 0644);
+ }
+ 
+ 
+ /* open-by-name support for file descriptors */
+ afs_uint32 xfon_fd(XFILE *X, int flag, char *name)
+ {
+   int fd = atoi(name);
+   return xfopen_fd(X, flag, fd);
+ }
+ 
+ 
+ /* open-by-name support for standard I/O */
+ afs_uint32 xfon_stdio(XFILE *X, int flag)
+ {
+   flag &= O_MODE_MASK;
+   if (flag == O_WRONLY) flag = O_RDWR;
+   return xfopen_FILE(X, flag, (flag == O_RDONLY) ? stdin : stdout);
+ }
Index: openafs/src/tests/xf_printf.c
diff -c /dev/null openafs/src/tests/xf_printf.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:57 2002
--- openafs/src/tests/xf_printf.c	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,444 ----
+ /*
+  * CMUCS AFStools
+  * dumpscan - routines for scanning and manipulating AFS volume dumps
+  *
+  * Copyright (c) 1998 Carnegie Mellon University
+  * All Rights Reserved.
+  * 
+  * Permission to use, copy, modify and distribute this software and its
+  * documentation is hereby granted, provided that both the copyright
+  * notice and this permission notice appear in all copies of the
+  * software, derivative works or modified versions, and any portions
+  * thereof, and that both notices appear in supporting documentation.
+  *
+  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+  *
+  * Carnegie Mellon requests users of this software to return to
+  *
+  *  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
+  *  School of Computer Science
+  *  Carnegie Mellon University
+  *  Pittsburgh PA 15213-3890
+  *
+  * any improvements or extensions that they make and grant Carnegie Mellon
+  * the rights to redistribute these changes.
+  */
+ 
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <stdio.h>
+ #include <ctype.h>
+ #include <netinet/in.h>
+ #include <netdb.h>
+ #include <stdarg.h>
+ 
+ #include "xfiles.h"
+ #include "xf_errs.h"
+ 
+ #define SPBUFLEN 40
+ static char spbuf[SPBUFLEN + 1] = "";
+ 
+ 
+ #define MAXPREC 100
+ 
+ /* Generate an ASCII representation of an integer <val>, as follows:
+  * <base> indicates the base to be used (2-36)
+  * <uc> is nonzero if letter digits should be uppercase
+  * <prec> is the minimum number of digits
+  * The resulting number is stored in <buf>, which must be long enough
+  * to receive it.  The minimum length is <prec> or ceil(log{base}(val)),
+  * whichever is larger, plus room for a trailing NUL.
+  */
+ static void mkint(char *buf, unsigned long val, int base, int uc, int prec)
+ {
+   int len = 0, dig, i;
+ 
+   while (val) {
+     dig = val % base;
+     val = (val - dig) / base;
+     if (dig < 10)  dig = dig + '0';
+     else if (uc) dig = dig + 'A' - 10;
+     else         dig = dig + 'a' - 10;
+     buf[len++] = dig;
+   }
+   while (len < prec) buf[len++] = '0';
+   for (i = 0; i < (len + 1) / 2; i++) {
+     dig = buf[i];
+     buf[i] = buf[len - i - 1];
+     buf[len - i - 1] = dig;
+   }
+   buf[len] = 0;
+ }
+ 
+ 
+ /* Write spaces faster than one at a time */
+ static afs_uint32 wsp(XFILE *X, int count)
+ {
+   char *x;
+   afs_uint32 err;
+   int i;
+ 
+   if (!spbuf[0]) {
+     for (x = spbuf, i = SPBUFLEN; i; x++, i--) *x = ' ';
+   }
+ 
+   while (count > SPBUFLEN) {
+     err = xfwrite(X, spbuf, SPBUFLEN);
+     if (err) return err;
+     count -= SPBUFLEN;
+   }
+   if (count > 0) return xfwrite(X, spbuf, count);
+   return 0;
+ }
+ 
+ 
+ /* This function is a mostly-complete implementation of snprintf,
+  * with the following features:
+  *
+  *   - Actually obeys the length limit, which (unfortunately) many
+  *     implementations of snprintf do not.
+  *  
+  *   - Supports all the standard format specifiers for integers
+  *     (d, i, o, u, x, X), floating-point values (f, e, E, g, G),
+  *     and strings and characters (c, s, %), plus a few unusual
+  *     but useful ones described below.
+  *  
+  *   - Supports all the standard flags (-, 0, +, space, #).  These
+  *     flags are ignored if used when they are not appropriate.
+  *  
+  *   - Supports the standard size modifiers for short (h), long (h),
+  *     and double (L) arguments.  These modifiers are ignored if used
+  *     when they are not appropriate.
+  *  
+  *   - Supports minimum field width and precision, where appropriate,
+  *     including the use of '*' to specify a value given as an argument
+  *     instead of in the format string.  There is a maximum precision
+  *     of 100 digits.
+  *  
+  *   - At present, the 'p' specifier for printing pointers is not
+  *     implemented, because it is inherently non-portable and thus
+  *     can be implemented correctly only by the compiler's run-time
+  *     library.
+  *
+  *   - Floating-point specifier (%e, %f, %g) are implemented by
+  *     calling the standard sprintf, and thus may be unsafe.
+  *  
+  *   - The '%...$' notation is used primarily when the format string
+  *     is specified by the user, who knows but cannot change the order
+  *     of the arguments.  Such usage is inherently dangerous and
+  *     insecure; thus, it is not supported.
+  *  
+  * The custom format specifier '%I' is supported.  This specifier
+  * takes as its argument an unsigned long integer containing an
+  * IPv4 address in network byte order.  The address is rendered
+  * either as a hostname or as a dotted quad, as follows:
+  *  
+  *   - If precision is nonzero or unspecified, a hostname lookup
+  *     is attempted; if it is successful, the hostname is printed.
+  *     If the hostname lookup fails, the address is printed in
+  *     dotted-quad notation.
+  *  
+  *   - If precision is explicitly specified as 0, then the hostname
+  *     lookup is skipped, and dotted-quad notation is always used.
+  *  
+  *   - If a hostname is to be printed:
+  *     + The precision controls the maximum number of characters
+  *       printed, as with %s.
+  *     + If the '#' flag is specified, any letters in the hostname
+  *       will be forced to lower case before printing.
+  *     + If the '+' flag is specified, any letters in the hostname
+  *       will be forced to upper case before printing.  If both
+  *       '#' and '+' are given, the '+' flag will be ignored.
+  *     + The '0' and ' ' flags have no effect.
+  *  
+  *   - If a dotted quad is to be printed:
+  *     + The precision has no effect; dotted quads are always
+  *       7 to 12 characters in length, depending on the value
+  *       to be printed and the format flags used.
+  *     + If the '0' flag is given, each field (byte) of the address
+  *       will be padded with '0' on the left to three digits.
+  *     + If the ' ' flag is given, each field (byte) of the address
+  *       will be padded with spaces on the left to three digits.  If
+  *       both '0' and ' ' are given, the ' ' flag will be ignored.
+  *     + The '#' and '+' flags have no effect.
+  */
+ 
+ afs_uint32 vxfprintf(XFILE *X, char *fmt, va_list ap)
+ {
+   unsigned int width, precision, haveprec, len;
+   int ljust, plsign, spsign, altform, zfill;
+   int hflag, lflag, count, *countp, j;
+   char *x, *y, *lit = 0, xbuf[MAXPREC + 21], fbuf[20];
+   struct hostent *he;
+   struct in_addr ia;
+   unsigned long UVAL;
+   long SVAL, *lcountp;
+   double FVAL;
+   short *hcountp;
+   afs_uint32 err;
+ 
+   count = 0;
+   while (*fmt) {
+     if (*fmt != '%') {
+       if (!lit) lit = fmt;
+       fmt++;
+       count++;
+       continue;
+     }
+     if (lit) {
+       if ((err = xfwrite(X, lit, fmt - lit))) return err;
+       lit = 0;
+     }
+ 
+     /** Found a format specifier **/
+     ljust = plsign = spsign = altform = zfill = 0;
+     width = precision = haveprec = 0;
+     hflag = lflag = 0;
+     fmt++;
+ 
+     /* parse format flags */
+     while (*fmt) {
+       switch (*fmt) {
+         case '-': ljust   = 1; fmt++; continue;      /* left justify */
+         case '+': plsign  = 1; fmt++; continue;      /* use + or - */
+         case ' ': spsign  = 1; fmt++; continue;      /* use space or - */
+         case '#': altform = 1; fmt++; continue;      /* alternate form */
+         case '0': zfill   = 1; fmt++; continue;      /* pad with 0 */
+         default: break;
+       }
+       break;
+     }
+ 
+     /* parse minimum width */
+     if (*fmt == '*') {
+       width = va_arg(ap, int);
+       fmt++;
+     } else while (isdigit(*fmt)) {
+       width = (width * 10) + (*fmt - '0');
+       fmt++;
+     }
+ 
+     /* parse precision */
+     if (*fmt == '.') {
+       fmt++;
+       haveprec = 1;
+       if (*fmt == '*') {
+         precision = va_arg(ap, int);
+         fmt++;
+       } else while (isdigit(*fmt)) {
+         precision = (precision * 10) + (*fmt - '0');
+         fmt++;
+       }
+     }
+ 
+     /* parse size flags */
+     while (*fmt) {
+       switch (*fmt) {
+         case 'h': hflag   = 1; fmt++; continue;      /* short argument */
+         case 'l': lflag   = 1; fmt++; continue;      /* long argument */
+         default: break;
+       }
+       break;
+     }
+ 
+     /* parse format specifier */
+     if (!*fmt) break;
+     switch (*fmt++) {
+       case 'e':
+       case 'E':
+       case 'f':
+       case 'g':
+       case 'G':
+         FVAL = va_arg(ap, double);
+         sprintf(fbuf, "%%%s%s.*L%c", plsign ? "+" : (spsign ? " " : ""),
+                 altform ? "#" : "", fmt[-1]);
+         if (!haveprec) precision = 6;
+         if (precision > MAXPREC) precision = MAXPREC;
+         sprintf(xbuf, fbuf, precision, FVAL);
+         x = xbuf;
+         len = strlen(x);
+         break;
+ 
+       case 'i': 
+       case 'd': /* signed decimal integer */
+         if      (lflag) SVAL = va_arg(ap, long);
+         else if (hflag) SVAL = va_arg(ap, int);
+         else            SVAL = va_arg(ap, int);
+         UVAL = (SVAL < 0) ? -SVAL : SVAL;
+ 
+         if (SVAL < 0)    xbuf[0] = '-';
+         else if (plsign) xbuf[0] = '+';
+         else if (spsign) xbuf[0] = ' ';
+         else             xbuf[0] = 0;
+ 
+         if (!haveprec) {
+           if (zfill && !ljust) precision = width - !!xbuf[0];
+           else precision = 1;
+           if (precision < 1 + !!xbuf[0]) precision = 1 + !!xbuf[0];
+         }
+         if (precision > MAXPREC) precision = MAXPREC;
+ 
+         mkint(xbuf + 1, UVAL, 10, 0, precision);
+         x = xbuf + !xbuf[0];
+         len = strlen(x);
+         break;
+ 
+ 
+       case 'o': /* unsigned octal integer */
+         if      (lflag) UVAL = va_arg(ap, unsigned long);
+         else if (hflag) UVAL = va_arg(ap, unsigned int);
+         else            UVAL = va_arg(ap, unsigned int);
+ 
+         xbuf[0] = '0';
+ 
+         if (!haveprec) {
+           if (zfill && !ljust) precision = width;
+           else precision = 1;
+         }
+         if (precision > MAXPREC) precision = MAXPREC;
+ 
+         mkint(xbuf + 1, UVAL, 8, 0, precision);
+         x = xbuf + (xbuf[1] == '0' || !altform);
+         len = strlen(x);
+         break;
+ 
+       case 'u': /* unsigned decimal integer */
+         if      (lflag) UVAL = va_arg(ap, unsigned long);
+         else if (hflag) UVAL = va_arg(ap, unsigned int);
+         else            UVAL = va_arg(ap, unsigned int);
+ 
+         if (!haveprec) {
+           if (zfill && !ljust) precision = width;
+           else precision = 1;
+         }
+         if (precision > MAXPREC) precision = MAXPREC;
+ 
+         mkint(xbuf, UVAL, 10, 0, precision);
+         x = xbuf;
+         len = strlen(x);
+         break;
+ 
+       case 'x': 
+       case 'X': /* unsigned hexadecimal integer */
+         if      (lflag) UVAL = va_arg(ap, unsigned long);
+         else if (hflag) UVAL = va_arg(ap, unsigned int);
+         else            UVAL = va_arg(ap, unsigned int);
+ 
+         xbuf[0] = '0';
+         xbuf[1] = 'x';
+ 
+         if (!haveprec) {
+           if (zfill && !ljust) precision = width;
+           else precision = 1;
+         }
+         if (precision > MAXPREC) precision = MAXPREC;
+ 
+         mkint(xbuf + 2, UVAL, 16, 0, precision);
+         x = xbuf + ((altform && UVAL) ? 0 : 2);
+         len = strlen(x);
+         break;
+ 
+       case '%': /* literal % */
+         xbuf[0] = '%';
+         xbuf[1] = 0;
+         x = xbuf;
+         len = 1;
+         break;
+ 
+       case 'c': /* character */
+         xbuf[0] = va_arg(ap, int);
+         xbuf[1] = 0;
+         x = xbuf;
+         len = 1;
+         break;
+ 
+       case 's': /* string */
+         x = va_arg(ap, char *);
+         if (!x) x = "<null>";
+         len = strlen(x);
+         if (haveprec && precision < len) len = precision;
+         break;
+ 
+       case 'I': /* IP address:
+          * value is provided as a network-order unsigned long integer
+          * precision specifies max hostname length, as for %s
+          * if precision is explicitly 0, no hostname lookup is done
+          * if 0fill specified, IPaddr fields are 0-filled to 3 digits
+          * if spsign specified, IPaddr fields are space-filled to 3 digits
+          */
+         UVAL = va_arg(ap, unsigned long);
+         ia.s_addr = UVAL;
+         /* XXX: add support for an application-provided function
+          * for doing hostname lookups.  We don't do it automatically
+          * because on some platforms that would prevent us from
+          * being fully statically linked.
+          */
+         if (haveprec && !precision) he = 0;
+         else he = gethostbyaddr((char *)&ia, 4, AF_INET);
+         if (he) {
+           x = he->h_name;
+           len = strlen(x);
+           if (haveprec && precision < len) len = precision;
+           if (altform)
+             for (y = x; *y; y++) if (isupper(*y)) *y = tolower(*y);
+           else if (plsign)
+             for (y = x; *y; y++) if (islower(*y)) *y = toupper(*y);
+         } else {
+           UVAL = ntohl(UVAL);
+           if      (zfill)  x = "%03u.%03u.%03u.%03u";
+           else if (spsign) x = "%3u.%3u.%3u.%3u";
+           else             x = "%u.%u.%u.%u";
+           sprintf(xbuf, x,
+                   (UVAL & 0xff000000) >> 24, (UVAL & 0x00ff0000) >> 16,
+                   (UVAL & 0x0000ff00) >> 8,  (UVAL & 0x000000ff));
+           x = xbuf;
+           len = strlen(xbuf);
+         }
+         break;
+ 
+       case 'n': /* report count so far */
+         if (lflag) {
+           lcountp = va_arg(ap, long *);
+           *lcountp = count;
+         } else if (hflag) {
+           hcountp = va_arg(ap, short *);
+           *hcountp = count;
+         } else {
+           countp = va_arg(ap, int *);
+           *countp = count;
+         }
+         continue;
+ 
+       default: /* unknown specifier */
+         continue;
+     }
+ 
+     /* render the results */
+     if (!width)        width = len;
+     j = width - len;
+     if (j > 0) count += j;
+     count += len;
+ 
+     if (!ljust && (err = wsp(X, j))) return err;
+     if ((err = xfwrite(X, x, len))) return err;
+     if (ljust && (err = wsp(X, j))) return err;
+   }
+   if (lit && (err = xfwrite(X, lit, fmt - lit))) return err;
+   return 0;
+ lose:
+   return err;
+ }
+ 
+ 
+ afs_uint32 xfprintf(XFILE *X, char *fmt, ...)
+ {
+   va_list ap;
+   afs_uint32 err;
+ 
+   va_start(ap, fmt);
+   err = vxfprintf(X, fmt, ap);
+   va_end(ap);
+   return err;
+ }
Index: openafs/src/tests/xf_profile.c
diff -c /dev/null openafs/src/tests/xf_profile.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:57 2002
--- openafs/src/tests/xf_profile.c	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,184 ----
+ /*
+  * CMUCS AFStools
+  * dumpscan - routines for scanning and manipulating AFS volume dumps
+  *
+  * Copyright (c) 1998 Carnegie Mellon University
+  * All Rights Reserved.
+  * 
+  * Permission to use, copy, modify and distribute this software and its
+  * documentation is hereby granted, provided that both the copyright
+  * notice and this permission notice appear in all copies of the
+  * software, derivative works or modified versions, and any portions
+  * thereof, and that both notices appear in supporting documentation.
+  *
+  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+  *
+  * Carnegie Mellon requests users of this software to return to
+  *
+  *  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
+  *  School of Computer Science
+  *  Carnegie Mellon University
+  *  Pittsburgh PA 15213-3890
+  *
+  * any improvements or extensions that they make and grant Carnegie Mellon
+  * the rights to redistribute these changes.
+  */
+ 
+ /* xf_profile.c - XFILE routines for read/write profiling */
+ 
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <string.h>
+ #include <stdlib.h>
+ #include <fcntl.h>
+ #include <errno.h>
+ 
+ #include "xfiles.h"
+ #include "xf_errs.h"
+ 
+ #define O_MODE_MASK (O_RDONLY | O_WRONLY | O_RDWR)
+ 
+ typedef struct {
+   XFILE content;
+   XFILE profile;
+ } PFILE;
+ 
+ 
+ /* do_read for profiled xfiles */
+ static afs_uint32 xf_PROFILE_do_read(XFILE *X, void *buf, afs_uint32 count)
+ {
+   PFILE *PF = X->refcon;
+   afs_uint32 err;
+ 
+   err = xfread(&PF->content, buf, count);
+   xfprintf(&PF->profile, "R %ld =%ld\n", (long)count, (long)err);
+   return err;
+ }
+ 
+ 
+ /* do_write for profiled xfiles */
+ static afs_uint32 xf_PROFILE_do_write(XFILE *X, void *buf, afs_uint32 count)
+ {
+   PFILE *PF = X->refcon;
+   afs_uint32 err;
+ 
+   err = xfwrite(&PF->content, buf, count);
+   xfprintf(&PF->profile, "W %ld =%ld\n", (long)count, (long)err);
+   return err;
+ }
+ 
+ 
+ /* do_tell for profiled xfiles */
+ static afs_uint32 xf_PROFILE_do_tell(XFILE *X, u_int64 *offset)
+ {
+   PFILE *PF = X->refcon;
+   afs_uint32 err;
+ 
+   err = xftell(&PF->content, offset);
+   if (err) xfprintf(&PF->profile, "TELL ERR =%ld\n", (long)err);
+   else     xfprintf(&PF->profile, "TELL %s =0\n", hexify_int64(offset, 0));
+   return err;
+ }
+ 
+ 
+ /* do_seek for profiled xfiles */
+ static afs_uint32 xf_PROFILE_do_seek(XFILE *X, u_int64 *offset)
+ {
+   PFILE *PF = X->refcon;
+   afs_uint32 err;
+ 
+   err = xfseek(&PF->content, offset);
+   xfprintf(&PF->profile, "SEEK %s =%ld\n", hexify_int64(offset, 0), (long)err);
+   return err;
+ }
+ 
+ 
+ /* do_skip for profiled xfiles */
+ static afs_uint32 xf_PROFILE_do_skip(XFILE *X, afs_uint32 count)
+ {
+   PFILE *PF = X->refcon;
+   afs_uint32 err;
+ 
+   err = xfskip(&PF->content, count);
+   xfprintf(&PF->profile, "SKIP %ld =%ld\n", (long)count, (long)err);
+   return err;
+ }
+ 
+ 
+ /* do_close for profiled xfiles */
+ static afs_uint32 xf_PROFILE_do_close(XFILE *X)
+ {
+   PFILE *PF = X->refcon;
+   afs_uint32 err, err2;
+ 
+   err = xfclose(&PF->content);
+   err2 = xfclose(&PF->profile);
+   free(PF);
+   return err ? err : err2;
+ }
+ 
+ 
+ /* Open a profiled XFILE */
+ afs_uint32 xfopen_profile(XFILE *X, int flag, char *xname, char *profile)
+ {
+   PFILE *PF;
+   afs_uint32 err;
+ 
+   PF = malloc(sizeof(*PF));
+   if (!PF) return ENOMEM;
+   memset(PF, 0, sizeof(*PF));
+ 
+   err = xfopen(&PF->profile, O_RDWR|O_CREAT|O_TRUNC, profile);
+   if (err) {
+     free(PF);
+     return err;
+   }
+ 
+   err = xfopen(&PF->content, flag, xname);
+   if (err) {
+     xfclose(&PF->profile);
+     free(PF);
+     return err;
+   }
+ 
+   memset(X, 0, sizeof(*X));
+   X->refcon = PF;
+   X->do_read  = xf_PROFILE_do_read;
+   X->do_write = xf_PROFILE_do_write;
+   X->do_tell  = xf_PROFILE_do_tell;
+   X->do_close = xf_PROFILE_do_close;
+   X->is_writable = PF->content.is_writable;
+   if (PF->content.is_seekable) {
+     X->is_seekable;
+     X->do_seek  = xf_PROFILE_do_seek;
+     X->do_skip  = xf_PROFILE_do_skip;
+   }
+   xfprintf(&PF->profile, "OPEN %s\n", xname);
+   return 0;
+ }
+ 
+ 
+ afs_uint32 xfon_profile(XFILE *X, int flag, char *name)
+ {
+   char *x, *profile, *xname;
+   afs_uint32 err;
+ 
+   if (!(name = strdup(name))) return ENOMEM;
+ 
+   profile = "-";
+   xname = name;
+   for (x = name; *x; x++) {
+     if (x[0] == ':' && x[1] == ':') {
+       *x = 0;
+       profile = name;
+       xname = x + 2;
+       break;
+     }
+   }
+   if (!*name) profile = "-";
+   err = xfopen_profile(X, flag, xname, profile);
+   free(name);
+   return err;
+ }
Index: openafs/src/tests/xf_rxcall.c
diff -c /dev/null openafs/src/tests/xf_rxcall.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:57 2002
--- openafs/src/tests/xf_rxcall.c	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,260 ----
+ /*
+  * CMUCS AFStools
+  * dumpscan - routines for scanning and manipulating AFS volume dumps
+  *
+  * Copyright (c) 1998 Carnegie Mellon University
+  * All Rights Reserved.
+  * 
+  * Permission to use, copy, modify and distribute this software and its
+  * documentation is hereby granted, provided that both the copyright
+  * notice and this permission notice appear in all copies of the
+  * software, derivative works or modified versions, and any portions
+  * thereof, and that both notices appear in supporting documentation.
+  *
+  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+  *
+  * Carnegie Mellon requests users of this software to return to
+  *
+  *  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
+  *  School of Computer Science
+  *  Carnegie Mellon University
+  *  Pittsburgh PA 15213-3890
+  *
+  * any improvements or extensions that they make and grant Carnegie Mellon
+  * the rights to redistribute these changes.
+  */
+ 
+ /* xf_rxcall.c - XFILE routines for Rx bulk data transfers */
+ 
+ #include <sys/types.h>
+ #include <netinet/in.h>
+ #include <errno.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <fcntl.h>
+ #include <netdb.h>
+ 
+ #include "xfiles.h"
+ #include "xf_errs.h"
+ 
+ #include <rx/xdr.h>
+ #include <rx/rx.h>
+ #include <rx/rx_null.h>
+ #include <rx/rxkad.h>
+ #include <afs/auth.h>
+ #include <afs/cellconfig.h>
+ #include <afs/vlserver.h>
+ #include <afs/volser.h>
+ 
+ #ifndef AFSCONF_CLIENTNAME
+ #include <afs/dirpath.h>
+ #define AFSCONF_CLIENTNAME AFSDIR_CLIENT_ETC_DIRPATH
+ #endif
+ 
+ #define O_MODE_MASK (O_RDONLY | O_WRONLY | O_RDWR)
+ 
+ struct rxinfo {
+   struct rx_connection *conn;  /* connection */
+   struct rx_call *call;        /* call */
+   afs_int32 tid;                   /* volser transaction ID */
+   afs_uint32 code;                /* result code */
+ };
+ 
+ static afs_uint32 xf_rxcall_do_read(XFILE *X, void *buf, afs_uint32 count)
+ {
+   struct rxinfo *i = X->refcon;
+   afs_uint32 xcount;
+ 
+   xcount = rx_Read(i->call, buf, count);
+   if (xcount == count) return 0;
+   i->code = rx_EndCall(i->call, 0);
+   i->call = 0;
+   return i->code ? i->code : ERROR_XFILE_RDONLY;
+ }
+ 
+ 
+ static afs_uint32 xf_rxcall_do_write(XFILE *X, void *buf, afs_uint32 count)
+ {
+   struct rxinfo *i = X->refcon;
+   afs_uint32 xcount;
+ 
+   xcount = rx_Write(i->call, buf, count);
+   if (xcount == count) return 0;
+   i->code = rx_EndCall(i->call, 0);
+   i->call = 0;
+   return i->code;
+ }
+ 
+ 
+ static afs_uint32 xf_rxcall_do_close(XFILE *X)
+ {
+   struct rxinfo *i = X->refcon;
+   afs_uint32 code;
+ 
+   if (i->call) {
+     code = rx_EndCall(i->call, i->code);
+     i->call = 0;
+   } else {
+     code = i->code;
+   }
+   free(i);
+   return code;
+ }
+ 
+ 
+ static afs_uint32 xf_voldump_do_close(XFILE *X)
+ {
+   struct rxinfo *i = X->refcon;
+   struct rx_connection *conn = i->conn;
+   afs_uint32 code, rcode, xcode;
+   afs_int32 tid = i->tid;
+ 
+   code = xf_rxcall_do_close(X);
+   xcode = AFSVolEndTrans(conn, tid, &rcode);
+   if (!code) code = xcode ? xcode : rcode;
+   return code;
+ }
+ 
+ 
+ afs_uint32 xfopen_rxcall(XFILE *X, int flag, struct rx_call *call)
+ {
+   struct rxinfo *i;
+ 
+   flag &= O_MODE_MASK;
+   if (flag == O_WRONLY) return ERROR_XFILE_WRONLY;
+   memset(X, 0, sizeof(*X));
+   if (!(i = (struct rxinfo *)malloc(sizeof(struct rxinfo)))) return ENOMEM;
+   i->call = call;
+   i->code = 0;
+   X->do_read  = xf_rxcall_do_read;
+   X->do_write = xf_rxcall_do_write;
+   X->do_close = xf_rxcall_do_close;
+   X->is_writable = (flag == O_RDWR);
+   X->refcon = i;
+   return 0;
+ }
+ 
+ 
+ afs_uint32 xfopen_voldump(XFILE *X, struct rx_connection *conn,
+                        afs_int32 part, afs_int32 volid, afs_int32 date)
+ {
+   struct rx_call *call;
+   struct rxinfo *i;
+   afs_uint32 code, rcode;
+   afs_int32 tid;
+ 
+   if (code = AFSVolTransCreate(conn, volid, part, ITBusy, &tid)) return code;
+   call = rx_NewCall(conn);
+   if ((code = StartAFSVolDump(call, tid, date))
+   ||  (code = xfopen_rxcall(X, O_RDONLY, call))) {
+     rx_EndCall(call, 0);
+     AFSVolEndTrans(conn, tid, &rcode);
+     return code;
+   }
+ 
+   i = X->refcon;
+   i->conn = conn;
+   i->tid = tid;
+   X->do_close = xf_voldump_do_close;
+   return 0;
+ }
+ 
+ 
+ afs_uint32 xfon_voldump(XFILE *X, int flag, char *name)
+ {
+   struct hostent *he;
+   struct rx_securityClass *class;
+   struct rx_connection *conn;
+   struct ktc_principal sname;
+   struct ktc_token token;
+   struct afsconf_dir *confdir;
+   afs_uint32 code, server_addr;
+   afs_int32 volid, partid, date;
+   int isnum, index;
+   char *x, *y;
+ 
+   /* Parse out the optional date and server location */
+   if (code = rx_Init(0)) return code;
+   if (!(name = strdup(name))) return ENOMEM;
+   if (x = strrchr(name, ',')) {
+     *x++ = 0;
+     date = atoi(x);
+   } else {
+     date = 0;
+   }
+   if (x = strrchr(name, '@')) {
+     int a, b, c, d;
+ 
+     *x++ = 0;
+     if (!(y = strchr(x, '/'))) {
+       free(name);
+       return VL_BADPARTITION;
+     }
+     *y++ = 0;
+     if (sscanf(x, "%d.%d.%d.%d", &a, &b, &c, &d) == 4
+     &&  a >= 0 && a <= 255 && b >= 0 && b <= 255
+     &&  c >= 0 && c <= 255 && d >= 0 && d <= 255) {
+       server_addr = (a << 24) | (b << 16) | (c << 8) | d;
+       server_addr = htonl(server_addr);
+     } else {
+       he = gethostbyname(x);
+       if (!he) {
+         free(name);
+         return VL_BADSERVER;
+       }
+       memcpy(&server_addr, he->h_addr, sizeof(server_addr));
+     }
+     partid = volutil_GetPartitionID(y);
+     if (partid < 0) {
+       free(name);
+       return VL_BADPARTITION;
+     }
+   }
+ 
+   /* Get tokens and set up a security object */
+   confdir = afsconf_Open(AFSCONF_CLIENTNAME);
+   if (!confdir) {
+     free(name);
+     return AFSCONF_NODB;
+   }
+   if (code = afsconf_GetLocalCell(confdir, sname.cell, MAXKTCNAMELEN)) {
+     free(name);
+     return code;
+   }
+   afsconf_Close(confdir);
+   strcpy(sname.name, "afs");
+   sname.instance[0] = 0;
+   code = ktc_GetToken(&sname, &token, sizeof(token), 0);
+   if (code) {
+     class = rxnull_NewClientSecurityObject();
+     index = 0;
+   } else {
+     class = rxkad_NewClientSecurityObject(rxkad_clear, &token.sessionKey,
+             token.kvno, token.ticketLen, token.ticket);
+     index = 2;
+   }
+ 
+   /* Figure out the volume ID, looking it up in the VLDB if neccessary.
+    * Also look up the server and partition, if they were not specified.
+    */
+   for (isnum = 1, y = name; *y; y++)
+     if (*y < '0' || *y > '9') isnum = 0;
+   if (isnum) {
+     volid = atoi(name);
+     if (!x) {
+       fprintf(stderr, "XXX: need to lookup volume by ID!\n");
+       exit(-1);
+     }
+   } else {
+     fprintf(stderr, "XXX: need to lookup volume by name!\n");
+     exit(-1);
+   }
+   free(name);
+ 
+   /* Establish a connection and start the call */
+   conn = rx_NewConnection(server_addr, htons(AFSCONF_VOLUMEPORT),
+                           VOLSERVICE_ID, class, index);
+   return xfopen_voldump(X, conn, partid, volid, date);
+ }
Index: openafs/src/tests/xfiles.c
diff -c /dev/null openafs/src/tests/xfiles.c:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:57 2002
--- openafs/src/tests/xfiles.c	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,219 ----
+ /*
+  * CMUCS AFStools
+  * dumpscan - routines for scanning and manipulating AFS volume dumps
+  *
+  * Copyright (c) 1998 Carnegie Mellon University
+  * All Rights Reserved.
+  * 
+  * Permission to use, copy, modify and distribute this software and its
+  * documentation is hereby granted, provided that both the copyright
+  * notice and this permission notice appear in all copies of the
+  * software, derivative works or modified versions, and any portions
+  * thereof, and that both notices appear in supporting documentation.
+  *
+  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+  *
+  * Carnegie Mellon requests users of this software to return to
+  *
+  *  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
+  *  School of Computer Science
+  *  Carnegie Mellon University
+  *  Pittsburgh PA 15213-3890
+  *
+  * any improvements or extensions that they make and grant Carnegie Mellon
+  * the rights to redistribute these changes.
+  */
+ 
+ /* xfiles.c - General support routines for xfiles */
+ #include <sys/types.h>
+ #include <string.h>
+ #include <errno.h>
+ 
+ #include "xfiles.h"
+ #include "xf_errs.h"
+ 
+ #define SKIP_SIZE 65536
+ 
+ extern afs_uint32 xfon_path(XFILE *, int, char *);
+ extern afs_uint32 xfon_fd(XFILE *, int, char *);
+ extern afs_uint32 xfon_voldump(XFILE *, int, char *);
+ extern afs_uint32 xfon_profile(XFILE *, int, char *);
+ extern afs_uint32 xfon_stdio(XFILE *, int);
+ 
+ struct xftype {
+   struct xftype *next;
+   char *name;
+   afs_uint32 (*do_on)(XFILE *, int, char *);
+ };
+ 
+ 
+ static struct xftype *xftypes = 0;
+ static int did_register_defaults = 0;
+ 
+ 
+ afs_uint32 xfread(XFILE *X, void *buf, afs_uint32 count)
+ {
+   afs_uint32 code;
+   u_int64 tmp64;
+ 
+   code = (X->do_read)(X, buf, count);
+   if (code) return code;
+ 
+   add64_32(tmp64, X->filepos, count);
+   cp64(X->filepos, tmp64);
+   if (X->passthru) return xfwrite(X->passthru, buf, count);
+   return 0;
+ }
+ 
+ 
+ afs_uint32 xfwrite(XFILE *X, void *buf, afs_uint32 count)
+ {
+   afs_uint32 code;
+   u_int64 tmp64;
+ 
+   if (!X->is_writable) return ERROR_XFILE_RDONLY;
+   code = (X->do_write)(X, buf, count);
+   if (code) return code;
+ 
+   add64_32(tmp64, X->filepos, count);
+   cp64(X->filepos, tmp64);
+   return 0;
+ }
+ 
+ 
+ afs_uint32 xftell(XFILE *X, u_int64 *offset)
+ {
+   if (X->do_tell) return (X->do_tell)(X, offset);
+   cp64(*offset, X->filepos);
+   return 0;
+ }
+ 
+ 
+ afs_uint32 xfseek(XFILE *X, u_int64 *offset)
+ {
+   afs_uint32 code;
+ 
+   if (!X->do_seek) return ERROR_XFILE_NOSEEK;
+   code = (X->do_seek)(X, offset);
+   if (code) return code;
+   cp64(X->filepos, *offset);
+   return 0;
+ }
+ 
+ 
+ afs_uint32 xfskip(XFILE *X, afs_uint32 count)
+ {
+   afs_uint32 code;
+   u_int64 tmp64;
+ 
+   /* Use the skip method, if there is one */
+   if (X->do_skip && !X->passthru) {
+     code = (X->do_skip)(X, count);
+     if (code) return code;
+     add64_32(tmp64, X->filepos, count);
+     cp64(X->filepos, tmp64);
+     return 0;
+   }
+ 
+   /* Simulate using absolute seek, if available */
+   if (X->do_seek && !X->passthru) {
+     if (code = xftell(X, &tmp64)) return code;
+     add64_32(X->filepos, tmp64, count);
+     cp64(tmp64, X->filepos);
+     return xfseek(X, &tmp64);
+   }
+ 
+   /* Do it the hard/slow way - read all the data to be skipped.
+    * This is done if no other method is available, or if we are
+    * supposed to be copying all the data to another XFILE
+    */
+   {
+     char buf[SKIP_SIZE];
+     afs_uint32 n;
+ 
+     while (count) {
+       n = (count > SKIP_SIZE) ? SKIP_SIZE : count;
+       if (code = xfread(X, buf, n)) return code;
+       count -= n;
+     }
+     return 0;
+   }
+ }
+ 
+ 
+ afs_uint32 xfpass(XFILE *X, XFILE *Y)
+ {
+   if (X->passthru) return ERROR_XFILE_ISPASS;
+   if (!Y->is_writable) return ERROR_XFILE_RDONLY;
+   X->passthru = Y;
+   return 0;
+ }
+ 
+ 
+ afs_uint32 xfunpass(XFILE *X)
+ {
+   if (!X->passthru) return ERROR_XFILE_NOPASS;
+   X->passthru = 0;
+   return 0;
+ }
+ 
+ 
+ afs_uint32 xfclose(XFILE *X)
+ {
+   int code = 0;
+ 
+   if (X->do_close) code = (X->do_close)(X);
+   memset(X, 0, sizeof(*X));
+   return 0;
+ }
+ 
+ 
+ afs_uint32 xfregister(char *name, afs_uint32 (*do_on)(XFILE *, int, char *))
+ {
+   struct xftype *x;
+ 
+   if (!(x = (struct xftype *)malloc(sizeof(struct xftype)))) return ENOMEM;
+   memset(x, 0, sizeof(*x));
+   x->next = xftypes;
+   x->name = name;
+   x->do_on = do_on;
+   xftypes = x;
+ }
+ 
+ 
+ static void register_default_types(void)
+ {
+   xfregister("FILE",    xfon_path);
+   xfregister("FD",      xfon_fd);
+   xfregister("AFSDUMP", xfon_voldump);
+   xfregister("PROFILE", xfon_profile);
+   did_register_defaults = 1;
+ }
+ 
+ 
+ afs_uint32 xfopen(XFILE *X, int flag, char *name)
+ {
+   struct xftype *x;
+   char *type, *sep;
+ 
+   if (!did_register_defaults) register_default_types();
+   if (!strcmp(name, "-")) return xfon_stdio(X, flag);
+ 
+   for (type = name; *name && *name != ':'; name++);
+   if (*name) {
+     sep = name;
+     *name++ = 0;
+   } else {
+     sep = 0;
+     name = type;
+     type = "FILE";
+   }
+ 
+   for (x = xftypes; x; x = x->next)
+     if (!strcmp(type, x->name)) break;
+   if (sep) *sep = ':';
+   if (x) return (x->do_on)(X, flag, name);
+   return ERROR_XFILE_TYPE;
+ }
Index: openafs/src/tests/xfiles.h
diff -c /dev/null openafs/src/tests/xfiles.h:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:58 2002
--- openafs/src/tests/xfiles.h	Sun Jan 20 04:18:08 2002
***************
*** 0 ****
--- 1,88 ----
+ /*
+  * CMUCS AFStools
+  * dumpscan - routines for scanning and manipulating AFS volume dumps
+  *
+  * Copyright (c) 1998 Carnegie Mellon University
+  * All Rights Reserved.
+  * 
+  * Permission to use, copy, modify and distribute this software and its
+  * documentation is hereby granted, provided that both the copyright
+  * notice and this permission notice appear in all copies of the
+  * software, derivative works or modified versions, and any portions
+  * thereof, and that both notices appear in supporting documentation.
+  *
+  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+  *
+  * Carnegie Mellon requests users of this software to return to
+  *
+  *  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
+  *  School of Computer Science
+  *  Carnegie Mellon University
+  *  Pittsburgh PA 15213-3890
+  *
+  * any improvements or extensions that they make and grant Carnegie Mellon
+  * the rights to redistribute these changes.
+  */
+ 
+ /* xfiles.h - Type, constant, and function declarations for
+  * extensible file-like things */
+ 
+ #ifndef _XFILES_H_
+ #define _XFILES_H_
+ 
+ #include <stdio.h>
+ #include <stdarg.h>
+ #include "intNN.h"
+ 
+ struct rx_call;
+ struct rx_connection;
+ 
+ /* The XFILE structure */
+ typedef struct XFILE XFILE;
+ struct XFILE {
+   afs_uint32 (*do_read)(XFILE *, void *, afs_uint32);   /* read data */
+   afs_uint32 (*do_write)(XFILE *, void *, afs_uint32);  /* write data */
+   afs_uint32 (*do_tell)(XFILE *, u_int64 *);         /* find position */
+   afs_uint32 (*do_seek)(XFILE *, u_int64 *);         /* set position */
+   afs_uint32 (*do_skip)(XFILE *, afs_uint32);           /* skip forward */
+   afs_uint32 (*do_close)(XFILE *);                   /* close */
+   u_int64 filepos;                                /* position (counted) */
+   int is_seekable;                                /* 1 if seek works */
+   int is_writable;                                /* 1 if write works */
+   XFILE *passthru;                                /* XFILE to pass thru to */
+   void *refcon;                                   /* type-specific data */
+ };
+ 
+ 
+ /* Functions for opening XFILEs.  For these, the first two arguments are
+  * always a pointer to an XFILE to fill in, and the mode in which to
+  * open the file.  O_RDONLY and O_RDWR are permitted; O_WRONLY is not.
+  * Other open modes may or may not be used, depending on the object type.
+  * Remaining arguments are a function of the object type
+  */
+ extern afs_uint32 xfopen     (XFILE *, int, char *);      /* open by TYPE:name */
+ extern afs_uint32 xfopen_path(XFILE *, int, char *, int); /* open by path   */
+ extern afs_uint32 xfopen_FILE(XFILE *, int, FILE *);      /* open by FILE * */
+ extern afs_uint32 xfopen_fd  (XFILE *, int, int);         /* open by fd     */
+ extern afs_uint32 xfopen_rxcall (XFILE *, int, struct rx_call *);
+ extern afs_uint32 xfopen_voldump(XFILE *, struct rx_connection *,
+                               afs_int32, afs_int32, afs_int32);
+ extern afs_uint32 xfopen_profile(XFILE *, int, char *, char *);
+ 
+ extern afs_uint32 xfregister(char *, afs_uint32 (*)(XFILE *, int, char *));
+ 
+ /* Standard operations on XFILEs */
+ extern afs_uint32 xfread(XFILE *, void *, afs_uint32);     /* read data */
+ extern afs_uint32 xfwrite(XFILE *, void *, afs_uint32);    /* write data */
+ extern afs_uint32 xfprintf(XFILE *, char *, ...);          /* formatted */
+ extern afs_uint32 vxfprintf(XFILE *, char *, va_list);     /* formatted VA */
+ extern afs_uint32 xftell(XFILE *, u_int64 *);              /* get position */
+ extern afs_uint32 xfseek(XFILE *, u_int64 *);              /* set position */
+ extern afs_uint32 xfskip(XFILE *, afs_uint32);             /* skip forward */
+ extern afs_uint32 xfpass(XFILE *, XFILE *);                /* set passthru */
+ extern afs_uint32 xfunpass(XFILE *);                       /* unset passthru */
+ extern afs_uint32 xfclose(XFILE *);                        /* close */
+ 
+ #endif /* _XFILES_H_ */
Index: openafs/src/tests/OpenAFS/Auth-Heimdal.pm
diff -c /dev/null openafs/src/tests/OpenAFS/Auth-Heimdal.pm:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:58 2002
--- openafs/src/tests/OpenAFS/Auth-Heimdal.pm	Sun Jan 20 04:18:10 2002
***************
*** 0 ****
--- 1,44 ----
+ # This is -*- perl -*-
+ 
+ package OpenAFS::Auth;
+ use OpenAFS::Dirpath;
+ 
+ use strict;
+ #use vars qw( @ISA @EXPORT );
+ #@ISA = qw(Exporter);
+ #require Exporter;
+ #@EXPORT = qw($openafs-authadmin $openafs-authuser);
+ 
+ sub getcell {
+     my($cell);
+     open(CELL, "$openafsdirpath->{'afsconfdir'}/ThisCell") 
+ 	or die "Cannot open $openafsdirpath->{'afsconfdir'}/ThisCell: $!\n";
+     $cell = <CELL>;
+     chomp $cell;
+     close CELL;
+     return $cell;
+ }
+ 
+ sub getrealm {
+     my($cell);
+     open(CELL, "$openafsdirpath->{'afsconfdir'}/ThisCell") 
+ 	or die "Cannot open $openafsdirpath->{'afsconfdir'}/ThisCell: $!\n";
+     $cell = <CELL>;
+     chomp $cell;
+     close CELL;
+     $cell =~ tr/a-z/A-Z/;
+     return $cell;
+ }
+ 
+ sub authadmin {
+     my $cell = &getrealm;
+     my $cmd = "kinit -k -t /usr/afs/etc/krb5.keytab admin\@${cell} ; afslog";
+     system($cmd);
+ }
+ sub authuser {
+     my $cell = &getrealm;
+     my $cmd = "kinit -k -t /usr/afs/etc/krb5.keytab user\@${cell} ; afslog";
+     system($cmd);
+ }
+ 
+ 1;
Index: openafs/src/tests/OpenAFS/CMU_copyright.pm
diff -c /dev/null openafs/src/tests/OpenAFS/CMU_copyright.pm:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:58 2002
--- openafs/src/tests/OpenAFS/CMU_copyright.pm	Sun Jan 20 04:18:10 2002
***************
*** 0 ****
--- 1,33 ----
+ ## CMUCS AFStools
+ ## Copyright (c) 1996, 2001 Carnegie Mellon University
+ ## All Rights Reserved.
+ #
+ # Permission to use, copy, modify and distribute this software and its
+ # documentation is hereby granted, provided that both the copyright
+ # notice and this permission notice appear in all copies of the
+ # software, derivative works or modified versions, and any portions
+ # thereof, and that both notices appear in supporting documentation.
+ #
+ # CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ # CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ # ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ #
+ # Carnegie Mellon requests users of this software to return to
+ #
+ #  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
+ #  School of Computer Science
+ #  Carnegie Mellon University
+ #  Pittsburgh PA 15213-3890
+ #
+ # any improvements or extensions that they make and grant Carnegie Mellon
+ # the rights to redistribute these changes.
+ #
+ # CMU_copyright.pm - CMU copyright
+ # This isn't a real package; it merely provides a central location to keep
+ # information regarding redistribution of this set of modules, and to make
+ # sure that no one can use the modules (at least, as shipped) without also
+ # having a copy of these terms.
+ 
+ package AFS::CMU_copyright;
+ 
+ 1;
Index: openafs/src/tests/OpenAFS/ConfigUtils.pm
diff -c /dev/null openafs/src/tests/OpenAFS/ConfigUtils.pm:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:58 2002
--- openafs/src/tests/OpenAFS/ConfigUtils.pm	Sun Jan 20 04:18:10 2002
***************
*** 0 ****
--- 1,26 ----
+ # This is -*- perl -*-
+ 
+ package OpenAFS::ConfigUtils;
+ 
+ use strict;
+ use vars qw( @ISA @EXPORT @unwinds);
+ @ISA = qw(Exporter);
+ require Exporter;
+ @EXPORT = qw(@unwinds run unwind);
+ 
+ sub run ($) {
+   print join(' ', @_);
+   print "\n";
+   system (@_)  == 0
+     or die "Failed: $?\n";
+ }
+ 
+ # This subroutine takes a command to run in case of failure.  After
+ # each succesful step, this routine should be run with a command to
+ # undo the successful step.
+ 
+ 	 sub unwind($) {
+ 	   push @unwinds, $_[0];
+ 	 }
+ 
+ 1;
Index: openafs/src/tests/OpenAFS/Dirpath.pm.in
diff -c /dev/null openafs/src/tests/OpenAFS/Dirpath.pm.in:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:58 2002
--- openafs/src/tests/OpenAFS/Dirpath.pm.in	Sun Jan 20 04:18:10 2002
***************
*** 0 ****
--- 1,25 ----
+ # This is -*- perl -*-
+ 
+ package OpenAFS::Dirpath;
+ 
+ use strict;
+ use vars qw( @ISA @EXPORT $openafsdirpath);
+ @ISA = qw(Exporter);
+ require Exporter;
+ @EXPORT = qw($openafsdirpath);
+ 
+ # Dirpath configuration
+ $openafsdirpath = {
+         'afsconfdir'       => '@afsconfdir@',
+         'viceetcdir'       => '@viceetcdir@',
+ 	'afssrvbindir'     => '@afssrvbindir@',
+ 	'afssrvsbindir'    => '@afssrvsbindir@',
+ 	'afssrvlibexecdir' => '@afssrvlibexecdir@',
+ 	'afsdbdir'         => '@afsdbdir@',
+ 	'afslogsdir'       => '@afslogsdir@',
+ 	'afslocaldir'      => '@afslocaldir@',
+ 	'afsbackupdir'     => '@afsbackupdir@',
+ 	'afsbosconfigdir'  => '@afsbosconfigdir@'
+ };
+ 
+ 1;
Index: openafs/src/tests/OpenAFS/OS-LINUX.pm
diff -c /dev/null openafs/src/tests/OpenAFS/OS-LINUX.pm:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:58 2002
--- openafs/src/tests/OpenAFS/OS-LINUX.pm	Sun Jan 20 04:18:10 2002
***************
*** 0 ****
--- 1,23 ----
+ # This is -*- perl -*-
+ 
+ package OpenAFS::OS;
+ 
+ use strict;
+ use vars qw( @ISA @EXPORT $openafsinitcmd);
+ @ISA = qw(Exporter);
+ require Exporter;
+ @EXPORT = qw($openafsinitcmd);
+ 
+ # OS-specific configuration
+ $openafsinitcmd = {
+         'client-start'      => '/etc/init.d/openafs-client start',
+         'client-stop'       => '/etc/init.d/openafs-client stop',
+ 	'client-forcestart' => '/etc/init.d/openafs-client force-start',
+         'client-restart'    => '/etc/init.d/openafs-client restart',
+ 	'filesrv-start'     => '/etc/init.d/openafs-fileserver start',
+ 	'filesrv-stop'      => '/etc/init.d/openafs-fileserver stop',
+ 	'filesrv-forcestart'=> '/etc/init.d/openafs-fileserver force-start',
+ 	'filesrv-restart'   => '/etc/init.d/openafs-fileserver restart',
+ };
+ 
+ 1;
Index: openafs/src/tests/OpenAFS/OS-SOLARIS.pm
diff -c /dev/null openafs/src/tests/OpenAFS/OS-SOLARIS.pm:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:58 2002
--- openafs/src/tests/OpenAFS/OS-SOLARIS.pm	Sun Jan 20 04:18:10 2002
***************
*** 0 ****
--- 1,23 ----
+ # This is -*- perl -*-
+ 
+ package OpenAFS::OS;
+ 
+ use strict;
+ use vars qw( @ISA @EXPORT $openafsinitcmd);
+ @ISA = qw(Exporter);
+ require Exporter;
+ @EXPORT = qw($openafsinitcmd);
+ 
+ # OS-specific configuration
+ $openafsinitcmd = {
+         'client-start'      => 'modload /usr/vice/etc/modload/libafs.nonfs.o; /usr/vice/etc/afsd -nosettime',
+         'client-stop'       => 'echo Solaris client cannot be stopped',
+ 	'client-forcestart' => 'modload /usr/vice/etc/modload/libafs.nonfs.o; /usr/vice/etc/afsd -nosettime',
+         'client-restart'    => 'echo Solaris client cannot be restarted',
+ 	'filesrv-start'     => '/usr/afs/bin/bosserver',
+ 	'filesrv-stop'      => '/usr/afs/bin/bos shutdown localhost -local -wait; pkill /usr/afs/bin/bosserver',
+ 	'filesrv-forcestart'=> '/usr/afs/bin/bosserver',
+ 	'filesrv-restart'   => '/usr/afs/bin/bos shutdown localhost -local -wait; pkill /usr/afs/bin/bosserver; sleep 1; /usr/afs/bin/bosserver',
+ };
+ 
+ 1;
Index: openafs/src/tests/OpenAFS/afsconf.pm
diff -c /dev/null openafs/src/tests/OpenAFS/afsconf.pm:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:58 2002
--- openafs/src/tests/OpenAFS/afsconf.pm	Sun Jan 20 04:18:10 2002
***************
*** 0 ****
--- 1,234 ----
+ # CMUCS AFStools
+ # Copyright (c) 1996, Carnegie Mellon University
+ # All rights reserved.
+ #
+ # See CMUCS/CMU_copyright.pm for use and distribution information
+ 
+ package OpenAFS::afsconf;
+ 
+ =head1 NAME
+ 
+ OpenAFS::afsconf - Access to AFS config info
+ 
+ =head1 SYNOPSIS
+ 
+   use OpenAFS::afsconf;
+ 
+   $cell = AFS_conf_localcell();
+   $cell = AFS_conf_canoncell($cellname);
+   @servers = AFS_conf_cellservers($cellname);
+   @cells = AFS_conf_listcells();
+   %info = AFS_conf_cacheinfo();
+ 
+ =head1 DESCRIPTION
+ 
+ This module provides access to information about the local workstation's
+ AFS configuration.  This includes information like the name of the
+ local cell, where AFS is mounted, and access to information in the
+ F<CellServDB>.  All information returned by this module is based on the
+ configuration files, and does not necessarily reflect changes made
+ on the afsd command line or using B<fs> commands.
+ 
+ =cut
+ 
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::config;
+ use OpenAFS::util qw(:DEFAULT :afs_internal);
+ use Exporter;
+ 
+ $VERSION   = '';
+ $VERSION   = '1.00';
+ @ISA       = qw(Exporter);
+ @EXPORT    = qw(&AFS_conf_localcell
+                 &AFS_conf_canoncell
+ 		&AFS_conf_listcells
+ 		&AFS_conf_cellservers
+ 		&AFS_conf_cacheinfo);
+ 
+ 
+ # _confpath($file) - Return path to a configuration file
+ sub _confpath {
+   my($file) = @_;
+ 
+   if ($conf_paths{$file}) {
+     $conf_paths{$file};
+   } elsif ($AFS_Parms{confdir} && -r "$AFS_Parms{confdir}/$file") {
+     $conf_paths{$file} = "$AFS_Parms{confdir}/$file";
+   } elsif (-r "$def_ConfDir/$file") {
+     $conf_paths{$file} = "$def_ConfDir/$file";
+   } else {
+     die "Unable to locate $file\n";
+   }
+ }
+ 
+ =head2 AFS_conf_localcell()
+ 
+ Return the canonical name of the local cell.  This depends on the contents
+ of the F<ThisCell> file in the AFS configuration directory.
+ 
+ =cut
+ 
+ $AFS_Help{conf_localcell} = '=> $lclcell';
+ sub AFS_conf_localcell {
+   my($path) = _confpath(ThisCell);
+   my($result);
+ 
+   return '' if (!$path);
+   if (open(THISCELL, $path)) {
+     chomp($result = <THISCELL>);
+     close(THISCELL);
+     $result;
+   } else {
+     die "Unable to open $path: $!\n";
+   }
+ }
+ 
+ =head2 AFS_conf_canoncell($cellname)
+ 
+ Return the canonical name of the specified cell, as found in F<CellServDB>.
+ I<$cellname> may be any unique prefix of a cell name, as with various AFS
+ commands that take cell names as arguments.
+ 
+ =head2 AFS_conf_cellservers($cellname)
+ 
+ Return a list of servers in the specified cell.  As with B<AFS_conf_canoncell>,
+ I<$cellname> may be any unique prefix of a cell name.  The resulting list
+ contains server hostnames, as found in F<CellServDB>.
+ 
+ =cut
+ 
+ $AFS_Help{conf_canoncell} = '$cellname => $canon';
+ $AFS_Help{conf_cellservers} = '$cellname => @servers';
+ 
+ sub AFS_conf_canoncell   { &_findcell($_[0], 0); }
+ sub AFS_conf_cellservers { &_findcell($_[0], 1); }
+ 
+ sub _findcell {
+   my($cellname, $doservers) = @_;
+   my($path, $found, @servers, $looking);
+ 
+   return $canon_name{$cellname} if (!$doservers && $canon_name{$cellname});
+   $path = _confpath(CellServDB) || die "Unable to locate CellServDB\n";
+ 
+   if (open(CELLSERVDB, $path)) {
+     my($cellpat) = $cellname;
+     $cellpat =~ s/(\W)/\\$1/g;
+     while (<CELLSERVDB>) {
+       $looking = 0 if (/^\>/);
+       if (/^\>$cellpat/) {
+ 	if ($found) {
+ 	  close(CELLSERVDB);
+ 	  die "Cell name $cellname is not unique\n";
+ 	} else {
+ 	  chop($found = $_);
+ 	  $found =~ s/^\>(\S+).*/$1/;
+ 	  $looking = 1 if ($doservers);
+ 	}
+       } elsif ($looking && (/^[\.\d]+\s*\#\s*(.*\S+)/ || /^([\.\d]+)/)) {
+ 	push(@servers, $1);
+       }
+     }
+     close(CELLSERVDB);
+     if ($found) {
+       $canon_name{$cellname} = $found;
+       $doservers ? @servers : ($found);
+     } else {
+       die "Cell $cellname not in CellServDB\n";
+     }
+   } else {
+     die "Unable to open $path: $!\n";
+   }
+ }
+ 
+ =head2 AFS_conf_listcells()
+ 
+ Return a list of canonical names (as found in F<CellServDB>) of all
+ known AFS cells.
+ 
+ =cut
+ 
+ $AFS_Help{conf_listcells} = '=> @cells';
+ sub AFS_conf_listcells {
+   my($path, @cells);
+ 
+   $path = _confpath(CellServDB) || die "Unable to locate CellServDB!\n";
+ 
+   if (open(CELLSERVDB, $path)) {
+     while (<CELLSERVDB>) {
+       if (/^\>(\S+)/) {
+ 	push(@cells, $1);
+       }
+     }
+     close(CELLSERVDB);
+     @cells;
+   } else {
+     die "Unable to open $path: $!\n";
+   }
+ }
+ 
+ =head2 AFS_conf_cacheinfo()
+ 
+ Return a table of information about the local workstation's cache
+ configuration.  This table may contain any or all of the following elements:
+ 
+ =over 14
+ 
+ =item afsroot
+ 
+ Mount point for the AFS root volume
+ 
+ =item cachedir
+ 
+ Location of the AFS cache directory
+ 
+ =item cachesize
+ 
+ AFS cache size
+ 
+ =item hardcachesize
+ 
+ Hard limit on AFS cache size (if specified; probably Mach-specific)
+ 
+ =item translator
+ 
+ Name of AFS/NFS translator server (if set)
+ 
+ =back
+ 
+ =cut
+ 
+ $AFS_Help{conf_cacheinfo} = '=> %info';
+ sub AFS_conf_cacheinfo {
+   my($path) = _confpath('cacheinfo');
+   my(%result, $line, $hcs);
+ 
+   if ($path) {
+     if (open(CACHEINFO, $path)) {
+       chop($line = <CACHEINFO>);
+       close(CACHEINFO);
+       (@result{'afsroot', 'cachedir', 'cachesize'} , $hcs) = split(/:/, $line);
+       $result{'hardcachesize'} = $hcs if ($hcs);
+     } else {
+       die "Unable to open $path: $!\n";
+     }
+   }
+   if ($ENV{'AFSSERVER'}) {
+     $result{'translator'} = $ENV{'AFSSERVER'};
+   } elsif (open(SRVFILE, "$ENV{HOME}/.AFSSERVER")
+ 	   || open(SRVFILE, "/.AFSSERVER")) {
+     $result{'translator'} = <SRVFILE>;
+     close(SRVFILE);
+   }
+   %result;
+ }
+ 
+ 
+ 1;
+ 
+ =head1 COPYRIGHT
+ 
+ The CMUCS AFStools, including this module are
+ Copyright (c) 1996, Carnegie Mellon University.  All rights reserved.
+ For use and redistribution information, see CMUCS/CMU_copyright.pm
+ 
+ =cut
Index: openafs/src/tests/OpenAFS/bos.pm
diff -c /dev/null openafs/src/tests/OpenAFS/bos.pm:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:58 2002
--- openafs/src/tests/OpenAFS/bos.pm	Sun Jan 20 04:18:10 2002
***************
*** 0 ****
--- 1,679 ----
+ # CMUCS AFStools
+ # Copyright (c) 1996, Carnegie Mellon University
+ # All rights reserved.
+ #
+ # See CMU_copyright.ph for use and distribution information
+ #
+ #: * bos.pm - Wrappers around BOS commands (basic overseer server)
+ #: * This module provides wrappers around the various bosserver 
+ #: * commands, giving them a nice perl-based interface.  Someday, they might
+ #: * talk to the servers directly instead of using 'bos', but not anytime
+ #: * soon.
+ #:
+ 
+ package OpenAFS::bos;
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT :afs_internal);
+ use OpenAFS::wrapper;
+ use Exporter;
+ 
+ $VERSION   = '';
+ $VERSION   = '1.00';
+ @ISA       = qw(Exporter);
+ @EXPORT    = qw(&AFS_bos_create        &AFS_bos_addhost
+ 		&AFS_bos_addkey        &AFS_bos_adduser
+ 		&AFS_bos_delete        &AFS_bos_exec
+ 		&AFS_bos_getdate       &AFS_bos_getlog
+ 		&AFS_bos_getrestart    &AFS_bos_install
+ 		&AFS_bos_listhosts     &AFS_bos_listkeys
+ 		&AFS_bos_listusers     &AFS_bos_prune
+ 		&AFS_bos_removehost    &AFS_bos_removekey
+ 		&AFS_bos_removeuser    &AFS_bos_restart
+ 		&AFS_bos_salvage       &AFS_bos_setauth
+ 		&AFS_bos_setcellname   &AFS_bos_setrestart
+ 		&AFS_bos_shutdown      &AFS_bos_start
+ 		&AFS_bos_startup       &AFS_bos_status
+ 		&AFS_bos_stop          &AFS_bos_uninstall);
+ 
+ #: AFS_bos_addhost($server, $host, [$clone], [$cell])
+ #: Add a new database server host named $host to the database
+ #: on $server.
+ #: If $clone is specified, create an entry for a clone server.
+ #: On success, return 1.
+ #:
+ $AFS_Help{bos_addhost} = '$server, $host, [$clone], [$cell] => Success?';
+ sub AFS_bos_addhost {
+   my($server, $host, $clone, $cell) = @_;
+   my(@args);
+ 
+   @args = ('addhost', '-server', $server, '-host', $host);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-clone') if ($clone);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('bos', \@args);
+   1;
+ }
+ 
+ #: AFS_bos_addkey($server, $key, $kvno, [$cell])
+ #: Add a key $key with key version number $kvno on server $server
+ #: On success, return 1.
+ #:
+ $AFS_Help{bos_addkey} = '$server, $key, $kvno, [$cell] => Success?';
+ sub AFS_bos_addkey {
+   my($server, $key, $kvno, $cell) = @_;
+   my(@args);
+ 
+   @args = ('addkey', '-server', $server, '-key', $key, '-kvno', $kvno);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('bos', \@args);
+   1;
+ }
+ 
+ #: AFS_bos_adduser($server, \@user, [$cell])
+ #: Add users specified in @users to bosserver superuser list on $server.
+ #: On success, return 1.
+ #:
+ $AFS_Help{bos_adduser} = '$server, \@user, [$cell] => Success?';
+ sub AFS_bos_adduser {
+   my($server, $user, $cell) = @_;
+   my(@args);
+ 
+   @args = ('adduser', '-server', $server, '-user', @$user);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('bos', \@args);
+   1;
+ }
+ 
+ #: AFS_bos_create($server, $instance, $type, \@cmd, [$cell])
+ #: Create a bnode with name $instance
+ #: The server name ($server) may be a hostname or IP address
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, return 1.
+ #:
+ $AFS_Help{bos_create} = '$server, $instance, $type, \@cmd, [$cell] => Success?';
+ sub AFS_bos_create {
+   my($server, $instance, $type, $cmd, $cell) = @_;
+   my(@args);
+ 
+   @args = ('create', '-server', $server, '-instance', $instance, '-type', 
+ 	   $type, '-cmd', @$cmd);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('bos', \@args);
+   1;
+ }
+ 
+ #: AFS_bos_delete($server, $instance, [$cell])
+ #: Delete a bnode with name $instance
+ #: The server name ($server) may be a hostname or IP address
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, return 1.
+ #:
+ $AFS_Help{bos_delete} = '$server, $instance, [$cell] => Success?';
+ sub AFS_bos_delete {
+   my($server, $instance, $cell) = @_;
+   my(@args);
+ 
+   @args = ('delete', '-server', $server, '-instance', $instance);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('bos', \@args);
+   1;
+ }
+ 
+ #: AFS_bos_exec($server, $cmd, [$cell])
+ #: Exec a process on server $server
+ #: The server name ($server) may be a hostname or IP address
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, return 1.
+ #:
+ $AFS_Help{bos_exec} = '$server, $cmd, [$cell] => Success?';
+ sub AFS_bos_exec {
+   my($server, $cmd, $cell) = @_;
+   my(@args);
+ 
+   @args = ('exec', '-server', $server, '-cmd', $cmd);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('bos', \@args);
+   1;
+ }
+ 
+ #: AFS_bos_getdate($server, $file, [$cell])
+ #: Get the date for file $file from server $server 
+ #: On success, return ($exedate, $bakdate, $olddate).
+ #:
+ $AFS_Help{bos_getdate} = '$server, $file, [$cell] => ($exedate, $bakdate, $olddate)';
+ sub AFS_bos_getdate {
+   my($server, $file, $cell) = @_;
+   my(@args, $exedate, $bakdate, $olddate);
+ 
+   @args = ('getdate', '-server', $server, '-file', $file);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('bos', \@args,
+ 	   [[ 'dated (.*), (no )?\.BAK', \$exedate],
+ 	    [ '\.BAK file dated (.*), (no )?\.OLD', \$bakdate],
+ 	    [ '\.OLD file dated (.*)\.', \$olddate]]);
+   ($exedate, $bakdate, $olddate);
+ }
+ 
+ #: AFS_bos_getlog($server, $file, [$cell])
+ #: Get log named $file from server $server 
+ #: On success, return 1.
+ #:
+ $AFS_Help{bos_getlog} = '$server, $file, [$cell] => Success?';
+ sub AFS_bos_getlog {
+   my($server, $file, $cell) = @_;
+   my(@args);
+ 
+   @args = ('getlog', '-server', $server, '-file', $file);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('bos', \@args, 
+ 	   [[ '^Fetching log file .*', '.']], { pass_stdout });
+   1;
+ }
+ 
+ #: AFS_bos_getrestart($server, [$cell])
+ #: Get the restart time for server $server 
+ #: On success, return ($genrestart, $binrestart).
+ #:
+ $AFS_Help{bos_getrestart} = '$server, [$cell] => ($genrestart, $binrestart)';
+ sub AFS_bos_getrestart {
+   my($server, $cell) = @_;
+   my(@args, $genrestart, $binrestart);
+ 
+   @args = ('getrestart', '-server', $server);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('bos', \@args,
+ 	   [[ '^Server .* restarts at\s*(.*\S+)', \$genrestart],
+ 	    [ '^Server .* restarts for new binaries at\s*(.*\S+)', \$binrestart]]);
+   ($genrestart, $binrestart);
+ }
+ 
+ #: AFS_bos_install($server, \@files, [$dir], [$cell])
+ #: Install files in \@files on server $server in directory $dir
+ #: or the default directory.
+ #: The server name ($server) may be a hostname or IP address
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, return 1.
+ #:
+ $AFS_Help{bos_install} = '$server, \@files, [$dir], [$cell] => Success?';
+ sub AFS_bos_install {
+   my($server, $files, $dir, $cell) = @_;
+   my(@args, $file);
+ 
+   @args = ('install', '-server', $server, '-file', @$files);
+   push(@args, '-dir', $dir)        if ($dir);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('bos', \@args, [[ 'bos: installed file .*', '.' ]],
+ 	   { 'errors_last' => 1 });
+   1;
+ }
+ 
+ #: AFS_bos_listhosts($server, [$cell])
+ #: Get host list on server $server.
+ #: The server name ($server) may be a hostname or IP address
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, an array of hosts with the first entry being the cellname.
+ #:
+ $AFS_Help{bos_listhosts} = '$server, [$cell] => @ret';
+ sub AFS_bos_listhosts {
+   my($server, $cell) = @_;
+   my(@args, @ret);
+ 
+   @args = ('listhosts', '-server', $server);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('bos', \@args, 
+ 	   [[ '^Cell name is (.*)', sub { 
+ 	       push(@ret, $_[0]);
+ 	   } ],
+ 	    [ 'Host \S+ is (\S+)', sub {
+ 		push(@ret, $_[0]);
+ 	    } ]
+ 	    ]);
+   @ret;
+ }
+ 
+ #: AFS_bos_listkeys($server, [$showkey], [$cell])
+ #: Get key list on server $server.
+ #: The server name ($server) may be a hostname or IP address
+ #: If specified, $showkey indicates keys and not checksums should be shown.
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, an array of hosts with the first entry being the cellname.
+ #:
+ $AFS_Help{bos_listkeys} = '$server, [$showkey], [$cell] => %ret';
+ sub AFS_bos_listkeys {
+   my($server, $showkey, $cell) = @_;
+   my(@args, %ret);
+ 
+   @args = ('listkeys', '-server', $server);
+   push(@args, '-showkey')          if ($showkey);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   %ret = &wrapper('bos', \@args, 
+ 		  [[ '^key (\d+) has cksum (\d+)', sub {
+ 		      my(%ret) = %OpenAFS::wrapper::result;
+ 		      $ret{$_[0]} = $_[1];
+ 		      %OpenAFS::wrapper::result = %ret;
+ 		      } ],
+ 		   [ '^key (\d+) is \'(\S+)\'', sub {
+ 		      my(%ret) = %OpenAFS::wrapper::result;
+                       $ret{$_[0]} = $_[1];
+ 		      %OpenAFS::wrapper::result = %ret;
+                       } ],
+ 		   [ '^Keys last changed on\s*(.*\S+)', sub {
+ 		      my(%ret) = %OpenAFS::wrapper::result;
+ 		       $ret{'date'} = $_[0];
+ 		      %OpenAFS::wrapper::result = %ret;
+ 		      } ],
+ 		   [ 'All done.', '.']]);
+   %ret;
+ }
+ 
+ #: AFS_bos_listusers($server, [$cell])
+ #: Get superuser list on server $server.
+ #: The server name ($server) may be a hostname or IP address
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, an array of users.
+ #:
+ $AFS_Help{bos_listusers} = '$server, [$cell] => @ret';
+ sub AFS_bos_listusers {
+   my($server, $cell) = @_;
+   my(@args, @ret);
+ 
+   @args = ('listusers', '-server', $server);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('bos', \@args, [[ '^SUsers are: (\S+)', sub { 
+       push(@ret, split(' ',$_[0]));
+   } ]]);
+   @ret;
+ }
+ 
+ #: AFS_bos_prune($server, [$bak], [$old], [$core], [$all], [$cell])
+ #: Prune files on server $server
+ #: If $bak is specified, remove .BAK files
+ #: If $old is specified, remove .OLD files
+ #: If $core is specified, remove core files
+ #: If $all is specified, remove all junk files
+ #: On success, return 1.
+ #:
+ $AFS_Help{bos_prune} = '$server, [$bak], [$old], [$core], [$all], [$cell] => Success?';
+ sub AFS_bos_prune {
+   my($server, $bak, $old, $core, $all, $cell) = @_;
+   my(@args);
+ 
+   @args = ('prune', '-server', $server, '-bak', $bak, '-old', $old, '-core', $core, '-all', $all);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-bak') if ($bak);
+   push(@args, '-old') if ($old);
+   push(@args, '-core') if ($core);
+   push(@args, '-all') if ($all);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('bos', \@args);
+   1;
+ }
+ 
+ #: AFS_bos_removehost($server, $host, [$cell])
+ #: Remove a new database server host named $host from the database
+ #: on $server.
+ #: On success, return 1.
+ #:
+ $AFS_Help{bos_removehost} = '$server, $host, [$cell] => Success?';
+ sub AFS_bos_removehost {
+   my($server, $host, $cell) = @_;
+   my(@args);
+ 
+   @args = ('removehost', '-server', $server, '-host', $host);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('bos', \@args);
+   1;
+ }
+ 
+ #: AFS_bos_removekey($server, $kvno, [$cell])
+ #: Remove a key with key version number $kvno on server $server
+ #: On success, return 1.
+ #:
+ $AFS_Help{bos_removekey} = '$server, $kvno, [$cell] => Success?';
+ sub AFS_bos_removekey {
+   my($server, $kvno, $cell) = @_;
+   my(@args);
+ 
+   @args = ('removekey', '-server', $server, '-kvno', $kvno);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('bos', \@args);
+   1;
+ }
+ 
+ #: AFS_bos_removeuser($server, \@user, [$cell])
+ #: Remove users specified in @users to bosserver superuser list on $server.
+ #: On success, return 1.
+ #:
+ $AFS_Help{bos_removeuser} = '$server, \@user, [$cell] => Success?';
+ sub AFS_bos_removeuser {
+   my($server, $user, $cell) = @_;
+   my(@args);
+ 
+   @args = ('removeuser', '-server', $server, '-user', @$user);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('bos', \@args);
+   1;
+ }
+ 
+ #: AFS_bos_restart($server, [\@inst], [$bosserver], [$all], [$cell])
+ #: Restart bosserver instances specified in \@inst, or if $all is
+ #: specified, all instances.
+ #: If $bosserver is specified, restart the bosserver.
+ #: The server name ($server) may be a hostname or IP address
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, return 1.
+ #:
+ $AFS_Help{bos_restart} = '$server, [\@inst], [$bosserver], [$all], [$cell] => Success?';
+ sub AFS_bos_restart {
+   my($server, $inst, $bosserver, $all, $cell) = @_;
+   my(@args);
+ 
+   @args = ('restart', '-server', $server);
+   push(@args, '-instance', @$inst) if ($inst);
+   push(@args, '-bosserver')        if ($bosserver);
+   push(@args, '-all')              if ($all);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('bos', \@args);
+   1;
+ }
+ 
+ #: AFS_bos_salvage($server, [$partition], [$volume], [$file], [$all], [$showlog], [$parallel], [$tmpdir], [$orphans], [$cell])
+ #: Invoke the salvager, providing a partition $partition if specified, and 
+ #: further a volume id $volume if specified. 
+ #: If specified, $file is a file to write the salvager output into.
+ #: If specified, $all indicates all partitions should be salvaged.
+ #: If specified, $showlog indicates the log should be displayed on completion.
+ #: If specified, $parallel indicates the number salvagers that should be run
+ #: in parallel.
+ #: If specified, $tmpdir indicates a directory in which to store temporary 
+ #: files.
+ #: If specified, $orphans indicates how to handle orphans in a volume
+ #: (valid options are ignore, remove and attach).
+ #: The server name ($server) may be a hostname or IP address
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, return 1.
+ #:
+ $AFS_Help{bos_salvage} = '$server, [$partition], [$volume], [$file], [$all], [$showlog], [$parallel], [$tmpdir], [$orphans], [$cell] => Success?';
+ sub AFS_bos_salvage {
+   my($server, $partition, $volume, $file, $all, $showlog, $parallel, $tmpdir, $orphans, $cell) = @_;
+   my(@args);
+ 
+   @args = ('salvage', '-server', $server);
+   push(@args, '-partition', $partition)if ($partition);
+   push(@args, '-volume', $volume)      if ($volume);
+   push(@args, '-file', $file)      if ($file);
+   push(@args, '-all')              if ($all);
+   push(@args, '-showlog')          if ($showlog);
+   push(@args, '-parallel', $parallel)  if ($parallel);
+   push(@args, '-tmpdir', $tmpdir)  if ($tmpdir);
+   push(@args, '-orphans', $orphans)if ($orphans);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('bos', \@args, [['bos: shutting down fs.', '.'],
+ 			   ['Starting salvage.', '.'],
+ 			   ['bos: waiting for salvage to complete.', '.'],
+ 			   ['bos: salvage completed', '.'],
+ 			   ['bos: restarting fs.', '.']],
+ 	   { 'errors_last' => 1 });
+   1;
+ }
+ 
+ #: AFS_bos_setauth($server, $authrequired, [$cell])
+ #: Set the authentication required flag for server $server to 
+ #: $authrequired.
+ #: On success, return 1.
+ #:
+ $AFS_Help{bos_setauth} = '$server, $authrequired, [$cell] => Success?';
+ sub AFS_bos_setauth {
+   my($server, $authrequired, $cell) = @_;
+   my(@args);
+ 
+   @args = ('setauth', '-server', $server, '-authrequired', $authrequired);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('bos', \@args);
+   1;
+ }
+ 
+ #: AFS_bos_setcellname($server, $name, [$cell])
+ #: Set the cellname for server $server to $name
+ #: On success, return 1.
+ #:
+ $AFS_Help{bos_setcellname} = '$server, $name, [$cell] => Success?';
+ sub AFS_bos_setcellname {
+   my($server, $name, $cell) = @_;
+   my(@args);
+ 
+   @args = ('setcellname', '-server', $server, '-name', $name);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('bos', \@args);
+   1;
+ }
+ 
+ #: AFS_bos_setrestart($server, $time, [$general], [$newbinary], [$cell])
+ #: Set the restart time for server $server to $time
+ #: If specified, $general indicates only the general restart time should be 
+ #: set.
+ #: If specified, $newbinary indicates only the binary restart time should be 
+ #: set.
+ #: On success, return 1.
+ #:
+ $AFS_Help{bos_setrestart} = '$server, $time, [$general], [$newbinary], [$cell] => Success?';
+ sub AFS_bos_setrestart {
+   my($server, $time, $general, $newbinary, $cell) = @_;
+   my(@args);
+ 
+   @args = ('setrestart', '-server', $server, '-time', $time);
+   push(@args, '-general')          if ($general);
+   push(@args, '-newbinary')        if ($newbinary);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('bos', \@args);
+   1;
+ }
+ 
+ #: AFS_bos_shutdown($server, [\@inst], [$wait], [$cell])
+ #: Stop all bosserver instances or if \@inst is specified,
+ #: only those in \@inst on server $server 
+ #: waiting for them to stop if $wait is specified.
+ #: The server name ($server) may be a hostname or IP address
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, return 1.
+ #:
+ $AFS_Help{bos_shutdown} = '$server, [\@inst], [$wait], [$cell] => Success?';
+ sub AFS_bos_shutdown {
+   my($server, $inst, $wait, $cell) = @_;
+   my(@args);
+ 
+   @args = ('shutdown', '-server', $server);
+   push(@args, '-instance', @$inst) if ($inst);
+   push(@args, '-wait')             if ($wait);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('bos', \@args);
+   1;
+ }
+ 
+ #: AFS_bos_start($server, \@inst, [$cell])
+ #: Start bosserver instances in \@inst on server $server .
+ #: The server name ($server) may be a hostname or IP address
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, return 1.
+ #:
+ $AFS_Help{bos_start} = '$server, \@inst, [$cell] => Success?';
+ sub AFS_bos_start {
+   my($server, $inst, $cell) = @_;
+   my(@args);
+ 
+   @args = ('start', '-server', $server, '-instance', @$inst);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('bos', \@args);
+   1;
+ }
+ 
+ #: AFS_bos_startup($server, [\@inst], [$cell])
+ #: Start all bosserver instances or if \@inst is specified, only
+ #: those in \@inst on server $server .
+ #: The server name ($server) may be a hostname or IP address
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, return 1.
+ #:
+ $AFS_Help{bos_startup} = '$server, [\@inst], [$cell] => Success?';
+ sub AFS_bos_startup {
+   my($server, $inst, $cell) = @_;
+   my(@args);
+ 
+   @args = ('startup', '-server', $server);
+   push(@args, '-instance', @$inst) if ($inst);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('bos', \@args);
+   1;
+ }
+ 
+ #: AFS_bos_status($server, [\@bnodes], [$cell])
+ #: Get status for the specified bnodes on $server, or for all bnodes
+ #: if none are given.
+ #: The server name ($server) may be a hostname or IP address
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, return an associative array whose keys are the names
+ #: of bnodes on the specified server, and each of whose values is
+ #: an associative array describing the status of the corresponding
+ #: bnode, containing some or all of the following elements:
+ #: - name         Name of this bnode (same as key)
+ #: - type         Type of bnode (simple, cron, fs)
+ #: - status       Basic status
+ #: - aux_status   Auxillary status string, for bnode types that provide it
+ #: - num_starts   Number of process starts
+ #: - last_start   Time of last process start
+ #: - last_exit    Time of last exit
+ #: - last_error   Time of last error exit
+ #: - error_code   Exit code from last error exit
+ #: - error_signal Signal from last error exit
+ #: - commands     Ref to list of commands
+ #:
+ $AFS_Help{bos_status} = '$server, [\@bnodes], [$cell] => %bnodes';
+ sub AFS_bos_status {
+   my($server, $bnodes, $cell) = @_;
+   my(@args, %finres, %blist, @cmds);
+ 
+   @args = ('status', '-server', $server, '-long');
+   push(@args, '-instance', @$bnodes) if ($bnodes);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   %finres = &wrapper('bos', \@args,
+            [['^(Instance)', sub {
+               my(%binfo) = %OpenAFS::wrapper::result;
+ 
+               if ($binfo{name}) {
+                 $binfo{commands} = [@cmds] if (@cmds);
+                 $blist{$binfo{name}} = \%binfo;
+ 
+                 @cmds = ();
+                 %OpenAFS::wrapper::result = ();
+               }
+             }],
+             ['^Instance (.*), \(type is (\S+)\)\s*(.*)',            'name', 'type', 'status'   ],
+             ['Auxilliary status is: (.*)\.',                        'aux_status'               ],
+             ['Process last started at (.*) \((\d+) proc starts\)',  'last_start', 'num_starts' ],
+             ['Last exit at (.*\S+)',                                'last_exit'                ],
+             ['Last error exit at (.*),',                            'last_error'               ],
+             ['by exiting with code (\d+)',                          'error_code'               ],
+             ['due to signal (\d+)',                                 'error_signal'             ],
+             [q/Command \d+ is '(.*)'/, sub { push(@cmds, $_[0]) }],
+            ]);
+   if ($finres{name}) {
+     $finres{commands} = [@cmds] if (@cmds);
+     $blist{$finres{name}} = \%finres;
+   }
+   %blist;
+ }
+ 
+ #: AFS_bos_stop($server, \@inst, [$wait], [$cell])
+ #: Stop bosserver instances in \@inst on server $server 
+ #: waiting for them to stop if $wait is specified.
+ #: The server name ($server) may be a hostname or IP address
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, return 1.
+ #:
+ $AFS_Help{bos_stop} = '$server, \@inst, [$wait], [$cell] => Success?';
+ sub AFS_bos_stop {
+   my($server, $inst, $wait, $cell) = @_;
+   my(@args);
+ 
+   @args = ('stop', '-server', $server, '-instance', @$inst);
+   push(@args, '-wait')             if ($wait);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('bos', \@args);
+   1;
+ }
+ 
+ #: AFS_bos_uninstall($server, \@files, [$dir], [$cell])
+ #: Uninstall files in \@files on server $server in directory $dir
+ #: or the default directory.
+ #: The server name ($server) may be a hostname or IP address
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, return 1.
+ #:
+ $AFS_Help{bos_uninstall} = '$server, \@files, [$dir], [$cell] => Success?';
+ sub AFS_bos_uninstall {
+   my($server, $files, $dir, $cell) = @_;
+   my(@args);
+ 
+   @args = ('uninstall', '-server', $server, '-file', @$files);
+   push(@args, '-dir', $dir) if ($dir);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('bos', \@args, [[ '^bos: uninstalled file .*', '.' ]],
+ 	   { 'errors_last' => 1 });
+   1;
+ }
+ 
+ 1;
Index: openafs/src/tests/OpenAFS/config.pm
diff -c /dev/null openafs/src/tests/OpenAFS/config.pm:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:58 2002
--- openafs/src/tests/OpenAFS/config.pm	Sun Jan 20 04:18:10 2002
***************
*** 0 ****
--- 1,125 ----
+ # CMUCS AFStools
+ # Copyright (c) 1996, Carnegie Mellon University
+ # All rights reserved.
+ #
+ # See CMU_copyright.pm for use and distribution information
+ 
+ package OpenAFS::config;
+ 
+ =head1 NAME
+ 
+ OpenAFS::config - AFStools configuration
+ 
+ =head1 SYNOPSIS
+ 
+   use OpenAFS::config;
+ 
+ =head1 DESCRIPTION
+ 
+ This module contains various AFStools configuration variables which are used
+ by the other AFStools modules.  These describe how AFStools should act in a
+ particular installation, and are mostly pretty mundane.  All of the defaults
+ here are pretty reasonable, so you shouldn't have to change anything unless
+ your site is particularly exotic.
+ 
+ Note that this file only describes how a particular B<installation> of AFStools
+ should act, not how it should act upon a particular B<cell>.  Since the cell
+ AFStools is running in is not necessarily the same as the cell on which it
+ is acting, most configuration that is really per-cell should be located in a
+ cell-specific module.
+ 
+ This module should only be used by other parts of AFStools.  As such, the
+ variables described here are not normally visible to user programs, and this
+ file is mostly of interest to administrators who are installing AFStools.
+ 
+ =over 4
+ 
+ =cut
+ 
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::Dirpath;
+ use Exporter;
+ 
+ $VERSION   = '';
+ $VERSION   = '1.00';
+ @ISA       = qw(Exporter);
+ @EXPORT    = qw($def_ConfDir
+                 @CmdList
+                 @CmdPath
+                 $err_table_dir
+                );
+ 
+ # The following configuration variables are defined here.  Mention them
+ # all an extra time, to suppress annoying warnings.  Doesn't perl have
+ # a way of doing this???
+ @x = ();
+ @x = ($def_ConfDir, @CmdList, @CmdPath);
+ 
+ =item $def_ConfDir - Default configuration directory
+ 
+ This is the default AFS configuration directory, where files like ThisCell,
+ CellServDB, and so on are found.  If the AFStools parameter I<confdir> is
+ set, it will generally be searched before this directory.  Normally, this
+ should be set to F</usr/vice/etc> and not changed, as that path is hardwired
+ into AFS.  However, it might be necessary to modify this if your site uses
+ an exotic locally-compiled version of AFS.
+ 
+ =cut
+ 
+ $def_ConfDir = "$openafsdirpath->{'viceetcdir'}";
+ #$def_ConfDir = "/usr/vice/etc";
+ 
+ 
+ =item @CmdList - List of AFS commands
+ 
+ This is a list of AFS commands that the AFStools package might want to invoke
+ using B<OpenAFS::wrapper::wrapper>.  Don't remove anything from this list if you
+ know what's good for you.  It's OK to add things, though, if you think you
+ might use the wrapper features for something.
+ 
+ =cut
+ 
+ @CmdList = ('fs', 'pts', 'vos', 'bos', 'kas', 'krbkas', 'sys');
+ 
+ 
+ =item @CmdPath - Path to search for AFS commands
+ 
+ This is the list of directories where B<OpenAFS::wrapper::wrapper> will look for
+ AFS commands.  For AFStools to work properly, every command listed in
+ I<@OpenAFS::config::CmdList> must appear in one of these directories.  The default
+ should be sufficient for most sites; we deal with Transarc's reccommendations
+ as well as common practice.  Note that on machines for which /usr/afs/bin
+ exists (typically, AFS fileservers), that directory is first.  This is probably
+ what you want...
+ 
+ =cut
+ 
+ @CmdPath = (split(/:/, $ENV{PATH}),
+             "$openafsdirpath->{'afssrvbindir'}",        # For servers
+ 	    '/usr/local/bin',      # Many sites put AFS in /usr/local
+ 	    '/usr/local/etc',
+ 	    '/usr/afsws/bin',      # For people who use Transarc's
+ 	    '/usr/afsws/etc');     # silly reccommendations
+ 
+ =item $err_table_dir - Error table directory
+ 
+ This is the location of error tables used by the errcode and errstr
+ routines in OpenAFS::errtrans.  Each file in this directory should be a
+ com_err error table (in source form), and should be named the same
+ as the com_err error package contained within.
+ 
+ =cut
+ 
+ $err_table_dir = '/usr/local/lib/errtbl';
+ 
+ 1;
+ 
+ =back
+ 
+ =head1 COPYRIGHT
+ 
+ The CMUCS AFStools, including this module are
+ Copyright (c) 1996, Carnegie Mellon University.  All rights reserved.
+ For use and redistribution information, see CMUCS/CMU_copyright.pm
+ 
+ =cut
Index: openafs/src/tests/OpenAFS/errtrans.pm
diff -c /dev/null openafs/src/tests/OpenAFS/errtrans.pm:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:58 2002
--- openafs/src/tests/OpenAFS/errtrans.pm	Sun Jan 20 04:18:10 2002
***************
*** 0 ****
--- 1,310 ----
+ # CMUCS AFStools
+ # Copyright (c) 1996, Carnegie Mellon University
+ # All rights reserved.
+ #
+ # See CMUCS/CMU_copyright.pm for use and distribution information
+ 
+ package OpenAFS::errtrans;
+ 
+ =head1 NAME
+ 
+ OpenAFS::errtrans - com_err error translation
+ 
+ =head1 SYNOPSIS
+ 
+   use OpenAFS::errtrans
+   $code = errcode($name);
+   $code = errcode($pkg, $err);
+   $string = errstr($code, [$volerrs]);
+ 
+ =head1 DESCRIPTION
+ 
+ This module translates "common" error codes such as those produced
+ by MIT's com_err package, and used extensively in AFS.  It also knows
+ how to translate system error codes, negative error codes used by Rx,
+ and a few "special" error codes used by AFS's volume package.
+ 
+ In order to work, these routines depend on the existence of error
+ table files in $err_table_dir, which is usually /usr/local/lib/errtbl.
+ Each file should be named after a com_err error package, and contain
+ the definition for that package.
+ 
+ Note that the AFS version of com_err translates package names to uppercase
+ before generating error codes, so a table which claims to define the 'pt'
+ package actually defines the 'PT' package when compiled by AFS's compile_et.
+ Tables that are normally fed to AFS's compile_et should be installed using
+ the _uppercase_ version of the package name.
+ 
+ The error tables used in AFS are part of copyrighted AFS source code, and
+ are not included with this package.  However, I have included a utility
+ (gen_et) which can generate error tables from the .h files normally
+ produced by compile_et, and Transarc provides many of these header files
+ with binary AFS distributions (in .../include/afs).  See the gen_et
+ program for more details.
+ 
+ =cut
+ 
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT :afs_internal);
+ use OpenAFS::config qw($err_table_dir);
+ use Symbol;
+ use Exporter;
+ use POSIX;
+ 
+ $VERSION   = '';
+ $VERSION   = '1.00';
+ @ISA       = qw(Exporter);
+ @EXPORT    = qw(&errcode &errstr);
+ 
+ 
+ @NumToChar = ('', 'A'..'Z', 'a'..'z', '0'..'9', '_');
+ %CharToNum = map(($NumToChar[$_], $_), (1 .. $#NumToChar));
+ 
+ %Vol_Codes = ( VSALVAGE    => 101,
+                VNOVNODE    => 102,
+                VNOVOL      => 103,
+                VVOLEXISTS  => 104,
+                VNOSERVICE  => 105,
+                VOFFLINE    => 106,
+                VONLINE     => 107,
+                VDISKFULL   => 108,
+                VOVERQUOTA  => 109,
+                VBUSY       => 110,
+                VMOVED      => 111
+              );
+ %Vol_Desc  = ( 101 => "volume needs to be salvaged",
+                102 => "no such entry (vnode)",
+                103 => "volume does not exist / did not salvage",
+                104 => "volume already exists",
+                105 => "volume out of service",
+                106 => "volume offline (utility running)",
+                107 => "volume already online",
+                108 => "unknown volume error 108",
+                109 => "unknown volume error 109",
+                110 => "volume temporarily busy",
+                111 => "volume moved"
+              );
+ %Rx_Codes  = ( RX_CALL_DEAD           => -1,
+                RX_INVALID_OPERATION   => -2,
+                RX_CALL_TIMEOUT        => -3,
+                RX_EOF                 => -4,
+                RX_PROTOCOL_ERROR      => -5,
+                RX_USER_ABORT          => -6,
+                RX_ADDRINUSE           => -7,
+                RX_MSGSIZE             => -8,
+                RXGEN_CC_MARSHAL       => -450,
+                RXGEN_CC_UNMARSHAL     => -451,
+                RXGEN_SS_MARSHAL       => -452,
+                RXGEN_SS_UNMARSHAL     => -453,
+                RXGEN_DECODE           => -454,
+                RXGEN_OPCODE           => -455,
+                RXGEN_SS_XDRFREE       => -456,
+                RXGEN_CC_XDRFREE       => -457
+              );
+ %Rx_Desc   = (   -1 => "server or network not responding",
+                  -2 => "invalid RPC (Rx) operation",
+                  -3 => "server not responding promptly",
+                  -4 => "Rx unexpected EOF",
+                  -5 => "Rx protocol error",
+                  -6 => "Rx user abort",
+                  -7 => "port address already in use",
+                  -8 => "Rx message size incorrect",
+                -450 => "Rx client: XDR marshall failed",
+                -451 => "Rx client: XDR unmarshall failed",
+                -452 => "Rx server: XDR marshall failed",
+                -453 => "Rx server: XDR unmarshall failed",
+                -454 => "Rx: Decode failed",
+                -455 => "Rx: Invalid RPC opcode",
+                -456 => "Rx server: XDR free failed",
+                -457 => "Rx client: XDR free failed",
+                map(($_ => "RPC interface mismatch ($_)"), (-499 .. -458)),
+                -999 => "Unknown error"
+              );
+ 
+ 
+ sub _tbl_to_num {
+   my(@tbl) = split(//, $_[0]);
+   my($n);
+ 
+   @tbl = @tbl[0..3] if (@tbl > 4);
+   foreach (@tbl) { $n = ($n << 6) + $CharToNum{$_} }
+   $n << 8;
+ }
+ 
+ 
+ sub _num_to_tbl {
+   my($n) = $_[0] >> 8;
+   my($tbl);
+ 
+   while ($n) {
+     $tbl = @NumToChar[$n & 0x3f] . $tbl;
+     $n >>= 6;
+   }
+   $tbl;
+ }
+ 
+ 
+ sub _load_system_errors {
+   my($file) = @_;
+   my($fh) = &gensym();
+ 
+   return if ($did_include{$file});
+ # print "Loading $file...\n";
+   $did_include{$file} = 'yes';
+   if (open($fh, "/usr/include/$file")) {
+     while (<$fh>) {
+       if (/^\#define\s*(E\w+)\s*(\d+)/) {
+         $Codes{$1} = $2;
+       } elsif (/^\#include\s*\"([^"]+)\"/
+            ||  /^\#include\s*\<([^>]+)\>/) {
+         &_load_system_errors($1);
+       }
+     }
+     close($fh);
+   }
+ }
+ 
+ 
+ # Load an error table into memory
+ sub _load_error_table {
+   my($pkg) = @_;
+   my($fh, @words, $curval, $tval, $nval);
+   my($tid, $tfn, $code, $val, $desc);
+ 
+   return if ($Have_Table{$pkg});
+   # Read in the input file, and split it into words
+   $fh = &gensym();
+   return unless open($fh, "$err_table_dir/$pkg");
+ # print "Loading $pkg...\n";
+   line: while (<$fh>) {
+     s/^\s*//;  # Strip leading whitespace
+     while ($_) {
+       next line if (/^#/);
+       if    (/^(error_table|et)\s*/) { push(@words, 'et');  $_ = $' }
+       elsif (/^(error_code|ec)\s*/)  { push(@words, 'ec');  $_ = $' }
+       elsif (/^end\s*/)              { push(@words, 'end'); $_ = $' }
+       elsif (/^(\w+)\s*/)            { push(@words, $1);    $_ = $' }
+       elsif (/^\"([^"]*)\"\s*/)      { push(@words, $1);    $_ = $' }
+       elsif (/^([,=])\s*/)           { push(@words, $1);    $_ = $' }
+       else { close($fh); return }
+     }
+   }
+   close($fh);
+ 
+   # Parse the table header
+   $_ = shift(@words); return unless ($_ eq 'et');
+   if ($words[1] eq 'ec')    { $tid = shift(@words) }
+   elsif ($words[2] eq 'ec') { ($tfn, $tid) = splice(@words, 0, 2) }
+   else { return; }
+   if ($tid ne $pkg) {
+     $Have_Table{$tid} = 'yes';
+     $_ = $tid;
+     $_ =~ tr/a-z/A-Z/;
+     $tid = $_ if ($_ eq $pkg);
+   }
+   $tval = &_tbl_to_num($tid);
+   $Have_Table{$pkg} = 'yes';
+ # print "Package $pkg: table-id = $tid, table-fun = $tfn, base = $tval\n";
+ 
+   while (@words) {
+     $_ = shift(@words); return unless ($_ eq 'ec');
+     $code = shift(@words);
+     $_ = shift(@words);
+     if ($_ eq '=') {
+       $val = shift(@words);
+       $_ = shift(@words);
+     } else {
+       $val = $curval;
+     }
+     return unless ($_ eq ',');
+     $desc = shift(@words);
+     $nval = $tval + $val;
+     $curval = $val + 1;
+     $Desc{$nval} = $desc;
+     $Codes{$code} = $nval;
+ #   print "  code $code: value = $nval ($tval + $val), desc = \"$desc\"\n";
+   }
+ }
+ 
+ =head2 errcode($name)
+ 
+ Returns the numeric error code corresponding to the specified error
+ name.  This routine knows about names of system errors, a few special
+ Rx and volume-package errors, and any errors defined in installed
+ error tables.  If the specified error code is not found, returns -999.
+ 
+ =head2 errcode($pkg, $code)
+ 
+ Shifts $code into the specified error package, and returns the
+ resulting com_err code.  This can be used to generate error codes
+ for _any_ valid com_err package.
+ 
+ =cut
+ 
+ sub errcode {
+   if (@_ > 1) {
+     my($pkg, $code) = @_;
+     &_tbl_to_num($pkg) + $code;
+   } else {
+     my($name) = @_;
+     my($dir, @tbls, $code);
+ 
+     &_load_system_errors("errno.h");
+     if ($Vol_Codes{$name})   { $Vol_Codes{$name} }
+     elsif ($Rx_Codes{$name}) { $Rx_Codes{$name} }
+     elsif ($Codes{$name})    { $Codes{$name} }
+     else {
+       if ($name =~ /^E/) {  # Might be a POSIX error constant
+         $! = 0;
+         $code = &POSIX::constant($name, 0);
+         if (!$!) { return $code; }
+       }
+       $dir = &gensym();
+       if (opendir($dir, $err_table_dir)) {
+         @tbls = grep(!/^\.?\.$/, readdir($dir));
+         close($dir);
+         foreach (@tbls) { &_load_error_table($_) }
+       }
+       $Codes{$name} ? $Codes{$name} : -999;
+     }
+   }
+ }
+ 
+ 
+ =head2 errstr($code, [$volerrs])
+ 
+ Returns the error string corresponding to a specified com_err, Rx,
+ or system error code.  If $volerrs is specified and non-zero, then
+ volume-package errors are considered before system errors with the
+ same values.
+ 
+ =cut
+ 
+ sub errstr {
+   my($code, $volerrs) = @_;
+   my($pkg, $sub);
+ 
+   if ($Rx_Desc{$code}) { return $Rx_Desc{$code} }
+   if ($volerrs && $Vol_Desc{$code}) { return $Vol_Desc{$code} }
+   $sub = $code & 0xff;
+   $pkg = &_num_to_tbl($code);
+   if ($pkg eq '') {
+     $! = $sub + 0;
+     $_ = $! . '';
+     if (/^(Error )?\d+$/) { $Vol_Desc{$sub} ? $Vol_Desc{$sub} : "Error $sub" }
+     else { $_ }
+   } else {
+     &_load_error_table($pkg);
+     $Desc{$code} ? $Desc{$code} : "Unknown code $pkg $sub ($code)";
+   }
+ }
+ 
+ 1;
+ 
+ =head1 COPYRIGHT
+ 
+ The CMUCS AFStools, including this module are
+ Copyright (c) 1996, Carnegie Mellon University.  All rights reserved.
+ For use and redistribution information, see CMUCS/CMU_copyright.pm
+ 
+ =cut
Index: openafs/src/tests/OpenAFS/fs.pm
diff -c /dev/null openafs/src/tests/OpenAFS/fs.pm:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:58 2002
--- openafs/src/tests/OpenAFS/fs.pm	Sun Jan 20 04:18:10 2002
***************
*** 0 ****
--- 1,817 ----
+ # CMUCS AFStools
+ # Copyright (c) 1996, 2001 Carnegie Mellon University
+ # All rights reserved.
+ #
+ # See CMU_copyright.ph for use and distribution information
+ #
+ #: * fs.pm - Wrappers around the FS commands (fileserver/cache manager)
+ #: * This module provides wrappers around the various FS commands, which
+ #: * perform fileserver and cache manager control operations.  Right now,
+ #: * these are nothing more than wrappers around 'fs'; someday, we might
+ #: * talk to the cache manager directly, but not anytime soon.
+ #:
+ 
+ package OpenAFS::fs;
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT :afs_internal);
+ use OpenAFS::wrapper;
+ use Exporter;
+ 
+ $VERSION   = '';
+ $VERSION   = '1.00';
+ @ISA       = qw(Exporter);
+ @EXPORT    = qw(&AFS_fs_getacl          &AFS_fs_setacl
+                 &AFS_fs_cleanacl        &AFS_fs_getquota
+                 &AFS_fs_setquota        &AFS_fs_whereis
+ 		&AFS_fs_examine         &AFS_fs_setvol
+                 &AFS_fs_getmount        &AFS_fs_mkmount
+                 &AFS_fs_rmmount         &AFS_fs_checkvolumes
+                 &AFS_fs_flush           &AFS_fs_flushmount
+                 &AFS_fs_flushvolume     &AFS_fs_messages
+                 &AFS_fs_newcell         &AFS_fs_rxstatpeer
+                 &AFS_fs_rxstatproc      &AFS_fs_setcachesize
+                 &AFS_fs_setcell         &AFS_fs_setcrypt
+                 &AFS_fs_setclientaddrs  &AFS_fs_copyacl
+                 &AFS_fs_storebehind     &AFS_fs_setserverprefs
+                 &AFS_fs_checkservers    &AFS_fs_checkservers_interval
+                 &AFS_fs_exportafs       &AFS_fs_getcacheparms
+                 &AFS_fs_getcellstatus   &AFS_fs_getclientaddrs
+                 &AFS_fs_getcrypt        &AFS_fs_getserverprefs
+                 &AFS_fs_listcells       &AFS_fs_setmonitor
+                 &AFS_fs_getmonitor      &AFS_fs_getsysname
+                 &AFS_fs_setsysname      &AFS_fs_whichcell
+                 &AFS_fs_wscell);
+ 
+ #: ACL-management functions:
+ #: AFS access control lists are represented as a Perl list (or usually, a
+ #: reference to such a list).  Each element in such a list corresponds to
+ #: a single access control entry, and is a reference to a 2-element list
+ #: consisting of a PTS entity (name or ID), and a set of rights.  The
+ #: rights are expressed in the usual publically-visible AFS notation, as
+ #: a string of characters drawn from the class [rlidwkaABCDEFGH].  No
+ #: rights are denoted by the empty string; such an ACE will never returned
+ #: by this library, but may be used as an argument to remove a particular
+ #: ACE from a directory's ACL.
+ #:
+ #: One might be inclined to ask why we chose this representation, instead of
+ #: using an associative array, as might seem obvious.  The answer is that
+ #: doing so would have implied a nonambiguity that isn't there.  Suppose you
+ #: have an ACL %x, and want to know if there is an entry for user $U on that
+ #: list.  You might think you could do this by looking at $x{$U}.  The
+ #: problem here is that two values for $U (one numeric and one not) refer to
+ #: the same PTS entity, even though they would reference different elements
+ #: in such an ACL.  So, we instead chose a representation that wasn't a hash,
+ #: so people wouldn't try to do hash-like things to it.  If you really want
+ #: to be able to do hash-like operations, you should turn the list-form ACL
+ #: into a hash table, and be sure to do name-to-number translation on all the
+ #: keys as you go.
+ #:
+ #: AFS_fs_getacl($path)
+ #: Get the ACL on a specified path.
+ #: On success, return a list of two references to ACLs; the first is the
+ #: positive ACL for the specified path, and the second is the negative ACL.
+ #:
+ $AFS_Help{fs_getacl} = '$path => (\@posacl, \@negacl)';
+ sub AFS_fs_getacl {
+   my($path) = @_;
+   my(@args, @posacl, @negacl, $neg);
+ 
+   @args = ('listacl', '-path', $path);
+   &wrapper('fs', \@args,
+ 	   [
+ 	    [ '^(Normal|Negative) rights\:', sub {
+ 	      $neg = ($_[0] eq 'Negative');
+ 	    }],
+ 	    [ '^  (.*) (\S+)$', sub { #',{
+ 	      if ($neg) {
+ 		push(@negacl, [@_]);
+ 	      } else {
+ 		push(@posacl, [@_]);
+ 	      }
+ 	    }]]);
+   (\@posacl, \@negacl);
+ }
+ 
+ #: AFS_fs_setacl(\@paths, \@posacl, \@negacl, [$clear])
+ #: Set the ACL on a specified path.  Like the 'fs setacl' command, this
+ #: function normally only changes ACEs that are mentioned in one of the two
+ #: argument lists.  If a given ACE already exists, it is changed; if not, it
+ #: is added.  To delete a single ACE, specify the word 'none' or the empty
+ #: string in the rights field.  ACEs that already exist but are not mentioned
+ #: are left untouched, unless $clear is specified.  In that case, all
+ #: existing ACE's (both positive and negative) are deleted.
+ $AFS_Help{fs_setacl} = '\@paths, \@posacl, \@negacl, [$clear] => Success?';
+ sub AFS_fs_setacl {
+   my($paths, $posacl, $negacl, $clear) = @_;
+   my($ace, $U, $access);
+ 
+   if (@$posacl) {
+     @args = ('setacl', '-dir', @$paths);
+     push(@args, '-clear') if ($clear);
+     push(@args, '-acl');
+     foreach $e (@$posacl) {
+       ($U, $access) = @$e;
+       $access = 'none' if ($access eq '');
+       push(@args, $U, $access);
+     }
+     &wrapper('fs', \@args);
+   }
+   if (@$negacl) {
+     @args = ('setacl', '-dir', @$paths, '-negative');
+     push(@args, '-clear') if ($clear && !@$posacl);
+     push(@args, '-acl');
+     foreach $e (@$negacl) {
+       ($U, $access) = @$e;
+       $access = 'none' if ($access eq '');
+       push(@args, $U, $access);
+     }
+     &wrapper('fs', \@args);
+   }
+   if ($clear && !@$posacl && !@$negacl) {
+     @args = ('setacl', '-dir', @$paths,
+ 	     '-acl', 'system:anyuser', 'none', '-clear');
+     &wrapper('fs', \@args);
+   }
+   1;
+ }
+ 
+ #: AFS_fs_cleanacl(\@paths)
+ #: Clean the ACL on the specified path, removing any ACEs which refer to PTS
+ #: entities that no longer exist.  All the work is done by 'fs'.
+ #:
+ $AFS_Help{'fs_cleanacl'} = '\@paths => Success?';
+ sub AFS_fs_cleanacl {
+   my($paths) = @_;
+   my(@args);
+ 
+   @args = ('cleanacl', '-path', @$paths);
+   &wrapper('fs', \@args);
+   1;
+ }
+ 
+ #: AFS_fs_getquota($path) [listquota]
+ #: Get the quota on the specified path.
+ #: On success, returns the quota.
+ #:
+ $AFS_Help{'fs_getquota'} = '$path => $quota';
+ sub AFS_fs_getquota {
+   my($path) = @_;
+   my(@args, $quota);
+ 
+   @args = ('listquota', '-path', $path);
+   &wrapper('fs', \@args,
+ 	   [[ '^\S+\s+(\d+)\s+\d+\s+\d+\%', \$quota ]]);
+   $quota;
+ }
+ 
+ #: AFS_fs_setquota($path, $quota) [setquota]
+ #: Set the quota on the specified path to $quota.  If $quota is
+ #: given as 0, there will be no limit to the volume's size.
+ #: On success, return 1
+ #:
+ $AFS_Help{'fs_setquota'} = '$path, $quota => Success?';
+ sub AFS_fs_setquota {
+   my($path, $quota) = @_;
+   my(@args);
+ 
+   @args = ('setquota', '-path', $path, '-max', $quota);
+   &wrapper('fs', \@args);
+   1;
+ }
+ 
+ #: AFS_fs_whereis($path)  [whereis, whichcell]
+ #: Locate the fileserver housing the specified path, and the cell in which it
+ #: is located.
+ #: On success, returns a list of 2 or more elements.  The first element is the
+ #: name of the cell in which the volume is located.  The remaining elements
+ #: the names of servers housing the volume; for a replicated volume, there may
+ #: (should) be more than one such server.
+ #:
+ $AFS_Help{'fs_whereis'} = '$path => ($cell, @servers)';
+ sub AFS_fs_whereis {
+   my($path) = @_;
+   my(@args, $cell, @servers);
+ 
+   @args = ('whichcell', '-path', $path);
+   &wrapper('fs', \@args,
+ 	   [[ "lives in cell \'(.*)\'", \$cell ]]);
+ 
+   @args = ('whereis', '-path', $path);
+   &wrapper('fs', \@args,
+ 	   [[ 'is on host(s?)\s*(.*)', sub {
+ 	     @servers = split(' ', $_[1]);
+ 	   }]]);
+   ($cell, @servers);
+ }
+ 
+ #: AFS_fs_examine($path)
+ #: Get information about the volume containing the specified path.
+ #: On success, return an associative array containing some or all
+ #: of the following elements:
+ #: - vol_name
+ #: - vol_id
+ #: - quota_max
+ #: - quota_used
+ #: - quota_pctused
+ #: - part_size
+ #: - part_avail
+ #: - part_used
+ #: - part_pctused
+ #:
+ $AFS_Help{'fs_examine'} = '$path => %info';
+ sub AFS_fs_examine {
+   my($path) = @_;
+   my(@args, %info);
+ 
+   @args = ('examine', '-path', $path);
+   %info = &wrapper('fs', \@args,
+ 		   [[ 'vid = (\d+) named (\S+)',       'vol_id', 'vol_name' ],
+ 		    [ 'disk quota is (\d+|unlimited)', 'quota_max' ],
+ 		    [ 'blocks used are (\d+)',         'quota_used' ],
+ 		    [ '(\d+) blocks available out of (\d+)',
+ 		     'part_avail', 'part_size']]);
+   if ($info{'quota_max'} eq 'unlimited') {
+     $info{'quota_max'} = 0;
+     $info{'quota_pctused'} = 0;
+   } else {
+     $info{'quota_pctused'} = ($info{'quota_used'} / $info{'quota_max'}) * 100;
+     $info{'quota_pctused'} =~ s/\..*//;
+   }
+   $info{'part_used'} = $info{'part_size'} - $info{'part_avail'};
+   $info{'part_pctused'} = ($info{'part_used'} / $info{'part_size'}) * 100;
+   $info{'part_pctused'} =~ s/\..*//;
+   %info;
+ }
+ 
+ #: AFS_fs_setvol($path, [$maxquota], [$motd])
+ #: Set information about the volume containing the specified path.
+ #: On success, return 1.
+ $AFS_Help{'fs_setvol'} = '$path, [$maxquota], [$motd] => Success?';
+ sub AFS_fs_setvol {
+   my($path, $maxquota, $motd) = @_;
+   my(@args);
+ 
+   @args = ('setvol', '-path', $path);
+   push(@args, '-max', $maxquota) if ($maxquota || $maxquota eq '0');
+   push(@args, '-motd', $motd) if ($motd);
+   &wrapper('fs', \@args);
+   1;
+ }
+ 
+ 
+ #: AFS_fs_getmount($path)
+ #: Get the contents of the specified AFS mount point.
+ #: On success, return the contents of the specified mount point.
+ #: If the specified path is not a mount point, return the empty string.
+ $AFS_Help{'fs_getmount'} = '$path => $vol';
+ sub AFS_fs_getmount {
+   my($path) = @_;
+   my(@args, $vol);
+ 
+   @args = ('lsmount', '-dir', $path);
+   &wrapper('fs', \@args,
+ 	   [[ "mount point for volume '(.+)'", \$vol ]]);
+   $vol;
+ }
+ 
+ 
+ #: AFS_fs_mkmount($path, $vol, [$cell], [$rwmount], [$fast])
+ #: Create an AFS mount point at $path, leading to the volume $vol.
+ #: If $cell is specified, create a cellular mount point to that cell.
+ #: If $rwmount is specified and nonzero, create a read-write mount point.
+ #: If $fast is specified and nonzero, don't check to see if the volume exists.
+ #: On success, return 1.
+ $AFS_Help{'fs_mkmount'} = '$path, $vol, [$cell], [$rwmount], [$fast] => Success?';
+ sub AFS_fs_mkmount {
+   my($path, $vol, $cell, $rwmount, $fast) = @_;
+   my(@args);
+ 
+   @args = ('mkmount', '-dir', $path, '-vol', $vol);
+   push(@args, '-cell', $cell) if ($cell);
+   push(@args, '-rw') if ($rwmount);
+   push(@args, '-fast') if ($fast);
+   &wrapper('fs', \@args);
+   1;
+ }
+ 
+ #: AFS_fs_rmmount($path) [rmmount]
+ #: Remove an AFS mount point at $path
+ #: On success, return 1
+ $AFS_Help{'fs_rmmount'} = '$path => Success?';
+ sub AFS_fs_rmmount {
+   my($path) = @_;
+   my(@args);
+ 
+   @args = ('rmmount', '-dir', $path);
+   &wrapper('fs', \@args);
+   1;
+ }
+ 
+ #: AFS_fs_checkvolumes()
+ #: Check/update volume ID cache
+ #: On success, return 1
+ $AFS_Help{'fs_checkvolumes'} = '=> Success?';
+ sub AFS_fs_checkvolumes {
+   my(@args);
+ 
+   @args = ('checkvolumes');
+   &wrapper('fs', \@args);
+   1;
+ }
+ 
+ #: AFS_fs_flush(\@paths)
+ #: Flush files named by @paths from the cache
+ #: On success, return 1
+ $AFS_Help{'fs_flush'} = '\@paths => Success?';
+ sub AFS_fs_flush {
+   my($paths) = @_;
+   my(@args);
+ 
+   @args = ('flush');
+   push(@args, '-path', @$paths) if $paths;
+   &wrapper('fs', \@args);
+   1;
+ }
+ 
+ #: AFS_fs_flushmount(\@paths)
+ #: Flush mount points named by @paths from the cache
+ #: On success, return 1
+ $AFS_Help{'fs_flushmount'} = '\@paths => Success?';
+ sub AFS_fs_flushmount {
+   my($paths) = @_;
+   my(@args);
+ 
+   @args = ('flushmount');
+   push(@args, '-path', @$paths) if $paths;
+   &wrapper('fs', \@args);
+   1;
+ }
+ 
+ #: AFS_fs_flushvolume(\@paths)
+ #: Flush volumes containing @paths from the cache
+ #: On success, return 1
+ $AFS_Help{'fs_flushvolume'} = '\@paths => Success?';
+ sub AFS_fs_flushvolume {
+   my($paths) = @_;
+   my(@args);
+ 
+   @args = ('flushvolume');
+   push(@args, '-path', @$paths) if $paths;
+   &wrapper('fs', \@args);
+   1;
+ }
+ 
+ #: AFS_fs_messages($mode)
+ #: Set cache manager message mode
+ #: Valid modes are 'user', 'console', 'all', 'none'
+ #: On success, return 1
+ $AFS_Help{'fs_messages'} = '$mode => Success?';
+ sub AFS_fs_messages {
+   my($mode) = @_;
+   my(@args);
+ 
+   @args = ('messages', '-show', $mode);
+   &wrapper('fs', \@args);
+   1;
+ }
+ 
+ #: AFS_fs_newcell($cell, \@dbservers, [$linkedcell])
+ #: Add a new cell to the cache manager's list, or updating an existing cell
+ #: On success, return 1
+ $AFS_Help{'fs_newcell'} = '$cell, \@dbservers, [$linkedcell] => Success?';
+ sub AFS_fs_newcell {
+   my($cell, $dbservers, $linkedcell) = @_;
+   my(@args);
+ 
+   @args = ('newcell', '-name', $cell, '-servers', @$dbservers);
+   push(@args, '-linkedcell', $linkedcell) if $linkedcell;
+   &wrapper('fs', \@args);
+   1;
+ }
+ 
+ #: AFS_fs_rxstatpeer($enable, [$clear])
+ #: Control per-peer Rx statistics:
+ #: - if $enable is 1, enable stats
+ #: - if $enable is 0, disable stats
+ #: - if $clear  is 1, clear stats
+ #: On success, return 1
+ $AFS_Help{'fs_rxstatpeer'} = '$enable, [$clear] => Success?';
+ sub AFS_fs_rxstatpeer {
+   my($enable, $clear) = @_;
+   my(@args);
+ 
+   @args = ('rxstatpeer');
+   push(@args, '-enable')  if $enable;
+   push(@args, '-disable') if defined($enable) && !$enable;
+   push(@args, '-clear')   if $clear;
+   &wrapper('fs', \@args);
+   1;
+ }
+ 
+ #: AFS_fs_rxstatproc($enable, [$clear])
+ #: Control per-process Rx statistics:
+ #: - if $enable is 1, enable stats
+ #: - if $enable is 0, disable stats
+ #: - if $clear  is 1, clear stats
+ #: On success, return 1
+ $AFS_Help{'fs_rxstatproc'} = '$enable, [$clear] => Success?';
+ sub AFS_fs_rxstatproc {
+   my($enable, $clear) = @_;
+   my(@args);
+ 
+   @args = ('rxstatproc');
+   push(@args, '-enable')  if $enable;
+   push(@args, '-disable') if defined($enable) && !$enable;
+   push(@args, '-clear')   if $clear;
+   &wrapper('fs', \@args);
+   1;
+ }
+ 
+ #: AFS_fs_setcachesize($size)
+ #: Set the cache size to $size K
+ #: On success, return 1
+ $AFS_Help{'fs_setcachesize'} = '$size => Success?';
+ sub AFS_fs_setcachesize {
+   my($size) = @_;
+   my(@args);
+ 
+   @args = ('setcachesize', '-blocks', $size);
+   &wrapper('fs', \@args);
+   1;
+ }
+ 
+ #: AFS_fs_setcell(\@cells, $suid)
+ #: Set cell control bits for @cells
+ #: - if $suid is 1, enable suid programs
+ #: - if $suid is 0, disable suid programs
+ #: On success, return 1
+ $AFS_Help{'fs_setcell'} = '\@cells, [$suid] => Success?';
+ sub AFS_fs_setcell {
+   my($cells, $suid) = @_;
+   my(@args);
+ 
+   @args = ('setcell', '-cell', @$cells);
+   push(@args, '-suid')   if $suid;
+   push(@args, '-nosuid') if defined($suid) && !$suid;
+   &wrapper('fs', \@args);
+   1;
+ }
+ 
+ #: AFS_fs_setcrypt($enable)
+ #: Control cache manager encryption
+ #: - if $enable is 1, enable encrypted connections
+ #: - if $enable is 0, disable encrypted connections
+ #: On success, return 1
+ $AFS_Help{'fs_setcrypt'} = '$enable => Success?';
+ sub AFS_fs_setcrypt {
+   my($enable) = @_;
+   my(@args);
+ 
+   @args = ('setcrypt', '-crypt', $enable ? 'on' : 'off');
+   &wrapper('fs', \@args);
+   1;
+ }
+ 
+ #: AFS_fs_setclientaddrs(\@addrs)
+ #: Set client network interface addresses
+ #: On success, return 1
+ $AFS_Help{'fs_setclientaddrs'} = '\@addrs => Success?';
+ sub AFS_fs_setclientaddrs {
+   my($addrs) = @_;
+   my(@args);
+ 
+   @args = ('setclientaddrs');
+   push(@args, '-address', @$addrs) if $addrs;
+   &wrapper('fs', \@args);
+   1;
+ }
+ 
+ #: AFS_fs_copyacl($from, \@to, [$clear])
+ #: Copy the access control list on $from to each directory named in @to.
+ #: If $clear is specified and nonzero, the target ACL's are cleared first
+ #: On success, return 1
+ $AFS_Help{'fs_copyacl'} = '$from, \@to, [$clear] => Success?';
+ sub AFS_fs_copyacl {
+   my($from, $to, $clear) = @_;
+   my(@args);
+ 
+   @args = ('copyacl', '-fromdir', $from, '-todir', @$to);
+   push(@args, '-clear') if $clear;
+   &wrapper('fs', \@args);
+   1;
+ }
+ 
+ #: AFS_fs_storebehind(\@paths, [$size], [$def])
+ #: Set amount of date to store after file close
+ #: If $size is specified, the size for each file in @paths is set to $size.
+ #: If $default is specified, the default size is set to $default.
+ #: Returns the new or current default value, and a hash mapping filenames
+ #: to their storebehind sizes.  A hash entry whose value is undef indicates
+ #: that the corresponding file will use the default size.
+ $AFS_Help{'fs_storebehind'} = '\@paths, [$size], [$def] => ($def, \%sizes)';
+ sub AFS_fs_storebehind {
+   my($paths, $size, $def) = @_;
+   my(@args, %sizes, $ndef);
+ 
+   @args = ('storebehind', '-verbose');
+   push(@args, '-kbytes', $size) if defined($size);
+   push(@args, '-files', @$paths) if $paths && @$paths;
+   push(@args, '-allfiles', $def) if defined($def);
+   &wrapper('fs', \@args, [
+     ['^Will store up to (\d+) kbytes of (.*) asynchronously',
+      sub { $sizes{$_[1]} = $_[0] }],
+     ['^Will store (.*) according to default',
+      sub { $sizes{$_[0]} = undef }],
+     ['^Default store asynchrony is (\d+) kbytes', \$ndef],
+   ]);
+   ($ndef, \%sizes);
+ }
+ 
+ #: AFS_fs_setserverprefs(\%fsprefs, \%vlprefs)
+ #: Set fileserver and/or VLDB server preference ranks
+ #: Each of %fsprefs and %vlprefs maps server names to the rank to be
+ #: assigned to the specified servers.
+ #: On success, return 1.
+ $AFS_Help{'fs_setserverprefs'} = '\%fsprefs, \%vlprefs => Success?';
+ sub AFS_fs_setserverprefs {
+   my($fsprefs, $vlprefs) = @_;
+   my(@args, $srv);
+ 
+   @args = ('setserverprefs');
+   if ($fsprefs && %$fsprefs) {
+     push(@args, '-servers');
+     foreach $srv (keys %$fsprefs) {
+       push(@args, $srv, $$fsprefs{$srv});
+     }
+   }
+   if ($vlprefs && %$vlprefs) {
+     push(@args, '-vlservers');
+     foreach $srv (keys %$vlprefs) {
+       push(@args, $srv, $$vlprefs{$srv});
+     }
+   }
+   &wrapper('fs', \@args);
+   1;
+ }
+ 
+ #: AFS_fs_checkservers([$fast], [$allcells], [$cell])
+ #: Check to see what fileservers are down
+ #: If $cell is specified, fileservers in the specified cell are checked
+ #: If $allcells is specified and nonzero, fileservers in all cells are checked
+ #: If $fast is specified and nonzero, don't probe servers
+ $AFS_Help{'fs_checkservers'} = '[$fast], [$allcells], [$cell] => @down';
+ sub AFS_fs_checkservers {
+   my($fast, $allcells, $cell) = @_;
+   my(@args, @down);
+ 
+   @args = ('checkservers');
+   push(@args, '-all')         if $allcells;
+   push(@args, '-fast')        if $fast;
+   push(@args, '-cell', $cell) if $cell;
+   &wrapper('fs', \@args, [
+     ['^These servers unavailable due to network or server problems: (.*)\.',
+      sub { push(@down, split(' ', $_[0])) }],
+   ]);
+   @down;
+ }
+ 
+ #: AFS_fs_checkservers_interval([$interval])
+ #: Get and/or set the down server check interval
+ #: If $interval is specified and nonzero, it is set as the new interval
+ #: On success, returns the old interval in seconds
+ $AFS_Help{'fs_checkservers_interval'} = '$interval => $oldinterval';
+ sub AFS_fs_checkservers_interval {
+   my($interval) = @_;
+   my(@args, $oldinterval);
+ 
+   @args = ('checkservers', '-interval', $interval);
+   &wrapper('fs', \@args, [
+     ['^The new down server probe interval \((\d+) secs\)',    \$oldinterval],
+     ['^The current down server probe interval is (\d+) secs', \$oldinterval],
+   ]);
+   $oldinterval;
+ }
+ 
+ #: AFS_fs_exportafs($type, \%options);
+ #: Get and/or modify protocol translator settings
+ #: $type is the translator type, which must be 'nfs'
+ #: %options specifies the options to be set.  Each key is the name of an
+ #: option, which is enabled if the value is 1, and disabled if the value
+ #: is 0.  The following options are supported:
+ #:   start       Enable exporting of AFS
+ #:   convert     Copy AFS owner mode bits to UNIX group/other mode bits
+ #:   uidcheck    Strict UID checking
+ #:   submounts   Permit mounts of /afs subdirectories
+ #: On success, returns an associative array %modes, which is of the same
+ #: form, indicating which options are enabled.
+ $AFS_Help{'fs_exportafs'} = '$type, \%options => %modes';
+ sub AFS_fs_exportafs {
+   my($type, $options) = @_;
+   my(@args, %modes);
+ 
+   @args = ('exportafs', '-type', $type);
+   foreach (qw(start convert uidcheck submounts)) {
+     push(@args, "-$_", $$options{$_} ? 'on' : 'off') if exists($$options{$_});
+   }
+ 
+   &wrapper('fs', \@args, [
+     ['translator is disabled',  sub { $modes{'start'}     = 0 }],
+     ['translator is enabled',   sub { $modes{'start'}     = 1 }],
+     ['strict unix',             sub { $modes{'convert'}   = 0 }],
+     ['convert owner',           sub { $modes{'convert'}   = 1 }],
+     [q/no 'passwd sync'/,       sub { $modes{'uidcheck'}  = 0 }],
+     [q/strict 'passwd sync'/,   sub { $modes{'uidcheck'}  = 1 }],
+     ['Only mounts',             sub { $modes{'submounts'} = 0 }],
+     ['Allow mounts',            sub { $modes{'submounts'} = 1 }],
+   ]);
+   %modes;
+ }
+ 
+ 
+ #: AFS_fs_getcacheparms()
+ #: Returns the size of the cache, and the amount of cache space used.
+ #: Sizes are returned in 1K blocks.
+ $AFS_Help{'fs_getcacheparms'} = 'void => ($size, $used)';
+ sub AFS_fs_getcacheparms {
+   my(@args, $size, $used);
+ 
+   @args = ('getcacheparms');
+   &wrapper('fs', \@args, [
+     [q/AFS using (\d+) of the cache's available (\d+) 1K byte blocks/,
+      \$used, \$size],
+   ]);
+   ($size, $used);
+ }
+ 
+ #: AFS_fs_getcellstatus(\@cells)
+ #: Get cell control bits for cells listed in @cells.
+ #: On success, returns a hash mapping cells to their status; keys are
+ #: cell names, and values are 1 if SUID programs are permitted for that
+ #: cell, and 0 if not.
+ $AFS_Help{'fs_getcellstatus'} = '\@cells => %status';
+ sub AFS_fs_getcellstatus {
+   my($cells) = @_;
+   my(@args, %status);
+ 
+   @args = ('getcellstatus', '-cell', @$cells);
+   &wrapper('fs', \@args, [
+     ['Cell (.*) status: setuid allowed',    sub { $status{$_[0]} = 1 }],
+     ['Cell (.*) status: no setuid allowed', sub { $status{$_[0]} = 0 }],
+   ]);
+   %status;
+ }
+ 
+ #: AFS_fs_getclientaddrs
+ #: Returns a list of the client interface addresses
+ $AFS_Help{'fs_getclientaddrs'} = 'void => @addrs';
+ sub AFS_fs_getclientaddrs {
+   my(@args, @addrs);
+ 
+   @args = ('getclientaddrs');
+   &wrapper('fs', \@args, [
+     ['^(\d+\.\d+\.\d+\.\d+)', \@addrs ]
+   ]);
+   @addrs;
+ }
+ 
+ #: AFS_fs_getcrypt
+ #: Returns the cache manager encryption flag
+ $AFS_Help{'fs_getcrypt'} = 'void => $crypt';
+ sub AFS_fs_getcrypt {
+   my(@args, $crypt);
+ 
+   @args = ('getcrypt');
+   &wrapper('fs', \@args, [
+     ['^Security level is currently clear', sub { $crypt = 0 }],
+     ['^Security level is currently crypt', sub { $crypt = 1 }],
+   ]);
+   $crypt;
+ }
+ 
+ #: AFS_fs_getserverprefs([$vlservers], [$numeric])
+ #: Get fileserver or vlserver preference ranks
+ #: If $vlservers is specified and nonzero, VLDB server ranks
+ #: are retrieved; otherwise fileserver ranks are retrieved.
+ #: If $numeric is specified and nonzero, servers are identified
+ #: by IP address instead of by hostname.
+ #: Returns a hash whose keys are server names or IP addresses, and
+ #: whose values are the ranks of those servers.
+ $AFS_Help{'fs_getserverprefs'} = '[$vlservers], [$numeric] => %prefs';
+ sub AFS_fs_getserverprefs {
+   my($vlservers, $numeric) = @_;
+   my(@args, %prefs);
+ 
+   @args = ('getserverprefs');
+   push(@args, '-numeric')   if $numeric;
+   push(@args, '-vlservers') if $vlservers;
+   &wrapper('fs', \@args, [
+     ['^(\S+)\s*(\d+)', \%prefs],
+   ]);
+   %prefs;
+ }
+ 
+ #: AFS_fs_listcells([$numeric')
+ #: Get a list of cells known to the cache manager, and the VLDB
+ #: servers for each cell.
+ #: If $numeric is specified and nonzero, VLDB servers are identified
+ #: by IP address instead of by hostname.
+ #: Returns a hash where each key is a cell name, and each value is
+ #: a list of VLDB servers for the corresponding cell.
+ $AFS_Help{'fs_listcells'} = '[$numeric] => %cells';
+ sub AFS_fs_listcells {
+   my($numeric) = @_;
+   my(@args, %cells);
+ 
+   @args = ('listcells');
+   push(@args, '-numeric') if $numeric;
+   &wrapper('fs', \@args, [
+     ['^Cell (\S+) on hosts (.*)\.',
+       sub { $cells{$_[0]} = [ split(' ', $_[1]) ] }],
+   ]);
+   %cells;
+ }
+ 
+ #: AFS_fs_setmonitor($server)
+ #: Set the cache manager monitor host to $server.
+ #: If $server is 'off' or undefined, monitoring is disabled.
+ #: On success, return 1.
+ $AFS_Help{'fs_setmonitor'} = '$server => Success?';
+ sub AFS_fs_setmonitor {
+   my($server) = @_;
+   my(@args);
+ 
+   @args = ('monitor', '-server', defined($server) ? $server : 'off');
+   &wrapper('fs', \@args);
+   1;
+ }
+ 
+ #: AFS_fs_getmonitor
+ #: Return the cache manager monitor host, or undef if monitoring is disabled.
+ $AFS_Help{'fs_getmonitor'} = 'void => $server';
+ sub AFS_fs_getmonitor {
+   my(@args, $server);
+ 
+   @args = ('monitor');
+   &wrapper('fs', \@args, [
+     ['Using host (.*) for monitor services\.', \$server],
+   ]);
+   $server;
+ }
+ 
+ #: AFS_fs_getsysname
+ #: Returns the current list of system type names
+ $AFS_Help{'fs_getsysname'} = 'void => @sys';
+ sub AFS_fs_getsysname {
+   my(@args, @sys);
+ 
+   @args = ('sysname');
+   &wrapper('fs', \@args, [
+     [q/Current sysname is '(.*)'/, \@sys],
+     [q/Current sysname list is '(.*)'/,
+       sub { push(@sys, split(q/' '/, $_[0])) }],
+   ]);
+   @sys;
+ }
+ 
+ #: AFS_fs_setsysname(\@sys)
+ #: Sets the system type list to @sys
+ #: On success, return 1.
+ $AFS_Help{'fs_setsysname'} = '$server => Success?';
+ sub AFS_fs_setsysname {
+   my($sys) = @_;
+   my(@args);
+ 
+   @args = ('sysname', '-newsys', @$sys);
+   &wrapper('fs', \@args);
+   1;
+ }
+ 
+ #: AFS_fs_whichcell(\@paths)
+ #: Get the cells containing the specified paths
+ #: Returns a hash in which each key is a pathname, and each value
+ #: is the name of the cell which contains the corresponding file.
+ $AFS_Help{'fs_whichcell'} = '\@paths => %where';
+ sub AFS_fs_whichcell {
+   my($paths) = @_;
+   my(@args, %where);
+ 
+   @args = ('whichcell', '-path', @$paths);
+   &wrapper('fs', \@args, [
+     [q/^File (.*) lives in cell '(.*)'/, \%where],
+   ]);
+   %where;
+ }
+ 
+ #: AFS_fs_wscell
+ #: Returns the name of the workstation's home cell
+ $AFS_Help{'fs_wscell'} = 'void => $cell';
+ sub AFS_fs_wscell {
+   my(@args, $cell);
+ 
+   @args = ('wscell');
+   &wrapper('fs', \@args, [
+     [q/^This workstation belongs to cell '(.*)'/, \$cell],
+   ]);
+   $cell;
+ }
+ 
Index: openafs/src/tests/OpenAFS/kas.pm
diff -c /dev/null openafs/src/tests/OpenAFS/kas.pm:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:58 2002
--- openafs/src/tests/OpenAFS/kas.pm	Sun Jan 20 04:18:10 2002
***************
*** 0 ****
--- 1,325 ----
+ # CMUCS AFStools
+ # Copyright (c) 1996, Carnegie Mellon University
+ # All rights reserved.
+ #
+ # See CMU_copyright.ph for use and distribution information
+ #
+ #: * kas.pm - Wrappers around KAS commands (authentication maintenance)
+ #: * This module provides wrappers around the various kaserver commands
+ #: * giving them a nice perl-based interface.  At present, this module
+ #: * requires a special 'krbkas' which uses existing Kerberos tickets
+ #: * which the caller must have already required (using 'kaslog').
+ #:
+ 
+ package OpenAFS::kas;
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT :afs_internal);
+ use OpenAFS::wrapper;
+ use POSIX ();
+ use Exporter;
+ 
+ $VERSION   = '';
+ $VERSION   = '1.00';
+ @ISA       = qw(Exporter);
+ @EXPORT    = qw(&AFS_kas_create        &AFS_kas_setf
+                 &AFS_kas_delete        &AFS_kas_setkey
+                 &AFS_kas_examine       &AFS_kas_setpw
+                 &AFS_kas_randomkey     &AFS_kas_stringtokey
+                 &AFS_kas_list);
+ 
+ # Instructions to parse kas error messages
+ @kas_err_parse = ( [ ' : \[.*\] (.*), wait one second$', '.' ],
+                    [ ' : \[.*\] (.*) \(retrying\)$',     '.' ],
+                    [ ' : \[.*\] (.*)',                   '-' ]);
+ 
+ # Instructions to parse attributes of an entry
+ @kas_entry_parse = (
+     [ '^User data for (.*) \((.*)\)$',      'princ', 'flags', '.'        ],
+     [ '^User data for (.*)',                'princ'                      ],
+     [ 'key \((\d+)\) cksum is (\d+),',      'kvno', 'cksum'              ],
+     [ 'last cpw: (.*)',                     \&parsestamp, 'stamp_cpw'    ],
+     [ 'password will (never) expire',       'stamp_pwexp'                ],
+     [ 'password will expire: ([^\.]*)',     \&parsestamp, 'stamp_pwexp'  ],
+     [ 'An (unlimited) number of',           'max_badauth'                ],
+     [ '(\d+) consecutive unsuccessful',     'max_badauth'                ],
+     [ 'for this user is ([\d\.]+) minutes', 'locktime'                   ],
+     [ 'for this user is (not limited)',     'locktime'                   ],
+     [ 'User is locked (forever)',           'locked'                     ],
+     [ 'User is locked until (.*)',          \&parsestamp, 'locked'       ],
+     [ 'entry (never) expires',              'stamp_expire'               ],
+     [ 'entry expires on ([^\.]*)\.',        \&parsestamp, 'stamp_expire' ],
+     [ 'Max ticket lifetime (.*) hours',     'maxlife'                    ],
+     [ 'Last mod on (.*) by',                \&parsestamp, 'stamp_update' ],
+     [ 'Last mod on .* by (.*)',             'last_writer'                ]);
+ 
+ 
+ @Months = ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
+            'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
+ %Months = map(($Months[$_] => $_), 0..11);
+ 
+ # Parse a timestamp
+ sub parsestamp {
+   my($stamp) = @_;
+   my($MM, $DD, $YYYY, $hh, $mm, $ss);
+ 
+   if ($stamp =~ /^\S+ (\S+) (\d+) (\d+):(\d+):(\d+) (\d+)/) {
+     ($MM, $DD, $hh, $mm, $ss, $YYYY) = ($1, $2, $3, $4, $5, $6);
+     $YYYY -= 1900;
+     $MM = $Months{$MM};
+     if (defined($MM)) {
+       $stamp = POSIX::mktime($ss, $mm, $hh, $DD, $MM, $YYYY);
+     }
+   }
+   $stamp;
+ }
+ 
+ 
+ # Turn an 8-byte key into a string we can give to kas
+ sub stringize_key {
+   my($key) = @_;
+   my(@chars) = unpack('CCCCCCCC', $key);
+ 
+   sprintf("\\%03o" x 8, @chars);
+ }
+ 
+ 
+ # Turn a string into an 8-byte DES key
+ sub unstringize_key {
+   my($string) = @_;
+   my($char, $key);
+ 
+   while ($string ne '') {
+     if ($string =~ /^\\(\d\d\d)/) {
+       $char = $1;
+       $string = $';
+       $key .= chr(oct($char));
+     } else {
+       $key .= substr($string, 0, 1);
+       $string =~ s/^.//;
+     }
+   }
+   $key;
+ }
+ 
+ 
+ #: AFS_kas_create($princ, $initpass, [$cell])
+ #: Create a principal with name $princ, and initial password $initpass
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, return 1.
+ #:
+ $AFS_Help{kas_create} = '$princ, $initpass, [$cell] => Success?';
+ sub AFS_kas_create {
+   my($print, $initpass, $cell) = @_;
+   my(@args, $id);
+ 
+   @args = ('create', '-name', $princ, '-initial_password', $initpass);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('krbkas', \@args, [ @kas_err_parse ]);
+   1;
+ }
+ 
+ 
+ #: AFS_kas_delete($princ, [$cell])
+ #: Delete the principal $princ.
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, return 1.
+ #:
+ $AFS_Help{kas_delete} = '$princ, [$cell] => Success?';
+ sub AFS_kas_delete {
+   my($princ, $cell) = @_;
+   my(@args);
+ 
+   @args = ('delete', '-name', $princ);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('krbkas', \@args, [ @kas_err_parse ]);
+   1;
+ }
+ 
+ 
+ #: AFS_kas_examine($princ, [$cell])
+ #: Examine the prinicpal $princ, and return information about it.
+ #: If specified, operate in cell $cell instead of the default cell.
+ #: On success, return an associative array with some or all of the following:
+ #: - princ        Name of this principal
+ #: - kvno         Key version number
+ #: - cksum        Key checksum
+ #: - maxlife      Maximum ticket lifetime (in hours)
+ #: - stamp_expire Time this principal expires, or 'never'
+ #: - stamp_pwexp  Time this principal's password expires, or 'never'
+ #: - stamp_cpw    Time this principal's password was last changed
+ #: - stamp_update Time this princiapl was last modified
+ #: - last_writer  Administrator who last modified this principal
+ #: - max_badauth  Maximum number of bad auth attempts, or 'unlimited'
+ #: - locktime     Penalty time for bad auth (in minutes), or 'not limited'
+ #: - locked       Set and non-empty if account is locked
+ #: - expired      Set and non-empty if account is expired
+ #: - flags        Reference to a list of flags
+ #:
+ $AFS_Help{kas_examine} = '$princ, [$cell] => %info';
+ sub AFS_kas_examine {
+   my($vol, $cell) = @_;
+   my(%result, @args, $flags);
+ 
+   @args = ('examine', '-name', $princ);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   %result = &wrapper('krbkas', \@args, [ @kas_err_parse, @kas_entry_parse ]);
+ 
+   if ($result{flags}) {
+     $result{expired} = 1 if ($result{flags} =~ /expired/);
+     $result{flags} = [ split(/\+/, $result{flags}) ];
+   }
+   %result;
+ }
+ 
+ 
+ #: AFS_kas_list([$cell])
+ #: Get a list of principals in the kaserver database
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, return an associative array whose keys are names of kaserver
+ #: principals, and each of whose values is an associative array describing
+ #: the corresponding principal, containing some or all of the same elements
+ #: that may be returned by AFS_kas_examine
+ #:
+ $AFS_Help{kas_list} = '[$cell] => %princs';
+ sub AFS_kas_list {
+   my($cell) = @_;
+   my(@args, %finres, %plist);
+ 
+   @args = ('list', '-long');
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   %finres = &wrapper('krbkas', \@args,
+     [ @kas_err_parse,
+     [ '^User data for (.*)', sub {
+       my(%pinfo) = %OpenAFS::wrapper::result;
+ 
+       if ($pinfo{name}) {
+         $plist{$pinfo{name}} = \%pinfo;
+         %OpenAFS::wrapper::result = ();
+       }
+     }],
+       @kas_entry_parse ]);
+ 
+   if ($finres{name}) {
+     $plist{$finres{name}} = \%finres;
+   }
+   %plist;
+ }
+ 
+ 
+ #: AFS_kas_setf($princ, \%attrs, [$cell])
+ #: Change the attributes of the principal $princ.
+ #: If specified, operate in cell $cell instead of the default cell.
+ #: The associative array %attrs specifies the attributes to change and
+ #: their new values.  Any of the following attributes may be changed:
+ #: - flags        Entry flags
+ #: - expire       Expiration time (mm/dd/yy)
+ #: - lifetime     Maximum ticket lifetime (seconds)
+ #: - pwexpires    Maximum password lifetime (days)
+ #: - reuse        Permit password reuse (yes/no)
+ #: - attempts     Maximum failed authentication attempts
+ #: - locktime     Authentication failure penalty (minutes or hh:mm)
+ #: 
+ #: On success, return 1.
+ #:
+ $AFS_Help{kas_setf} = '$princ, \%attrs, [$cell] => Success?';
+ sub AFS_kas_setf {
+   my($princ, $attrs, $cell) = @_;
+   my(%result, @args);
+ 
+   @args = ('setfields', '-name', $princ);
+   push(@args, '-flags',      $$attrs{flags})     if ($$attrs{flags});
+   push(@args, '-expiration', $$attrs{expire})    if ($$attrs{expire});
+   push(@args, '-lifetime',   $$attrs{lifetime})  if ($$attrs{lifetime});
+   push(@args, '-pwexpires',  $$attrs{pwexpires}) if ($$attrs{pwexpires});
+   push(@args, '-reuse',      $$attrs{reuse})     if ($$attrs{reuse});
+   push(@args, '-attempts',   $$attrs{attempts})  if ($$attrs{attempts});
+   push(@args, '-locktime',   $$attrs{locktime})  if ($$attrs{locktime});
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('krbkas', \@args, [ @kas_err_parse ]);
+   1;
+ }
+ 
+ 
+ #: AFS_kas_setkey($princ, $key, [$kvno], [$cell])
+ #: Change the key of principal $princ to the specified value.
+ #: $key is the 8-byte DES key to use for this principal.
+ #: If specified, set the key version number to $kvno.
+ #: If specified, operate in cell $cell instead of the default cell.
+ #: On success, return 1.
+ #:
+ $AFS_Help{kas_setkey} = '$princ, $key, [$kvno], [$cell] => Success?';
+ sub AFS_kas_setkey {
+   my($princ, $key, $kvno, $cell) = @_;
+   my(@args);
+ 
+   @args = ('setkey', '-name', $princ, '-new_key', &stringize_key($key));
+   push(@args, '-kvno', $kvno) if (defined($kvno));
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('krbkas', \@args, [ @kas_err_parse ]);
+   1;
+ }
+ 
+ 
+ #: AFS_kas_setpw($princ, $password, [$kvno], [$cell])
+ #: Change the key of principal $princ to the specified value.
+ #: $password is the new password to use.
+ #: If specified, set the key version number to $kvno.
+ #: If specified, operate in cell $cell instead of the default cell.
+ #: On success, return 1.
+ #:
+ $AFS_Help{kas_setpw} = '$princ, $password, [$kvno], [$cell] => Success?';
+ sub AFS_kas_setpw {
+   my($princ, $password, $kvno, $cell) = @_;
+   my(@args);
+ 
+   @args = ('setpasswd', '-name', $princ, '-new_password', $password);
+   push(@args, '-kvno', $kvno) if (defined($kvno));
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('krbkas', \@args, [ @kas_err_parse ]);
+   1;
+ }
+ 
+ 
+ #: AFS_kas_stringtokey($string, [$cell])
+ #: Convert the specified string to a DES key
+ #: If specified, operate in cell $cell instead of the default cell.
+ #: On success, return the resulting key
+ $AFS_Help{kas_stringtokey} = '$string, [$cell] => $key';
+ sub AFS_kas_stringtokey {
+   my($string, $cell) = @_;
+   my(@args, $key);
+ 
+   @args = ('stringtokey', '-string', $string);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('krbkas', \@args,
+     [ @kas_err_parse,
+       [ q/^Converting .* in realm .* yields key='(.*)'.$/, \$key ]]);
+   &unstringize_key($key);
+ }
+ 
+ 
+ #: AFS_kas_randomkey([$cell])
+ #: Ask the kaserver to generate a random DES key
+ #: If specified, operate in cell $cell instead of the default cell.
+ #: On success, return the resulting key
+ $AFS_Help{kas_randomkey} = '[$cell] => $key';
+ sub AFS_kas_randomkey {
+   my($cell) = @_;
+   my(@args, $key);
+ 
+   @args = ('getrandomkey');
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('krbkas', \@args,
+     [ @kas_err_parse,
+       [ '^Key: (\S+)', \$key ]]);
+   &unstringize_key($key);
+ }
+ 
+ 1;
Index: openafs/src/tests/OpenAFS/pts.pm
diff -c /dev/null openafs/src/tests/OpenAFS/pts.pm:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:58 2002
--- openafs/src/tests/OpenAFS/pts.pm	Sun Jan 20 04:18:10 2002
***************
*** 0 ****
--- 1,306 ----
+ # CMUCS AFStools
+ # Copyright (c) 1996, Carnegie Mellon University
+ # All rights reserved.
+ #
+ # See CMU_copyright.ph for use and distribution information
+ #
+ #: * pts.pm - Wrappers around PTS commands (user/group maintenance)
+ #: * This module provides wrappers around the various PTS commands, giving
+ #: * them a nice perl-based interface.  Someday, they might talk to the
+ #: * ptserver directly instead of using 'pts', but not anytime soon.
+ #:
+ 
+ package OpenAFS::pts;
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT :afs_internal);
+ use OpenAFS::wrapper;
+ use Exporter;
+ 
+ $VERSION   = '';
+ $VERSION   = '1.00';
+ @ISA       = qw(Exporter);
+ @EXPORT    = qw(&AFS_pts_createuser    &AFS_pts_listmax
+ 		&AFS_pts_creategroup   &AFS_pts_setmax
+ 		&AFS_pts_delete        &AFS_pts_add
+ 		&AFS_pts_rename        &AFS_pts_remove
+ 		&AFS_pts_examine       &AFS_pts_members
+ 		&AFS_pts_chown         &AFS_pts_listown
+ 		&AFS_pts_setf);
+ 
+ 
+ #: AFS_pts_createuser($user, [$id], [$cell])
+ #: Create a PTS user with $user as its name.
+ #: If specified, use $id as the PTS id; otherwise, AFS picks one.
+ #: If specified, operate in cell $cell instead of the default cell.
+ #: On success, return the PTS id of the newly-created user.
+ #:
+ $AFS_Help{pts_createuser} = '$user, [$id], [$cell] => $uid';
+ sub AFS_pts_createuser {
+   my($user, $id, $cell) = @_;
+   my(@args, $uid);
+ 
+   @args = ('createuser', '-name', $user);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   push(@args, '-id', $id) if ($id);
+   &wrapper('pts', \@args, [[ '^User .* has id (\d+)', \$uid ]]);
+   $uid;
+ }
+ 
+ 
+ #: AFS_pts_creategroup($group, [$id], [$owner], [$cell])
+ #: Create a PTS group with $group as its name.
+ #: If specified, use $id as the PTS id; otherwise, AFS picks one.
+ #: If specified, use $owner as the owner, instead of the current user.
+ #: If specified, operate in cell $cell instead of the default cell.
+ #: On success, return the PTS id of the newly-created group.
+ #:
+ $AFS_Help{pts_creategroup} = '$group, [$id], [$owner], [$cell] => $gid';
+ sub AFS_pts_creategroup {
+   my($group, $id, $owner, $cell) = @_;
+   my(@args, $uid);
+ 
+   @args = ('creategroup', '-name', $group);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   push(@args, '-id', $id) if ($id);
+   push(@args, '-owner', $owner) if ($owner);
+   &wrapper('pts', \@args, [[ '^group .* has id (\-\d+)', \$uid ]]);
+   $uid;
+ }
+ 
+ 
+ #: AFS_pts_delete(\@objs, [$cell])
+ #: Attempt to destroy PTS objects listed in @objs.
+ #: If specified, operate in cell $cell instead of the default cell.
+ #: On success, return 1.
+ #: If multiple objects are specified and only some are destroyed, some
+ #: operations may be left untried.
+ #:
+ $AFS_Help{pts_delete} = '\@objs, [$cell] => Success?';
+ sub AFS_pts_delete {
+   my($objs, $cell) = @_;
+   my(@args);
+ 
+   @args = ('delete', '-nameorid', @$objs);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('pts', \@args);
+   1;
+ }
+ 
+ 
+ #: AFS_pts_rename($old, $new, [$cell])
+ #: Rename the PTS object $old to have the name $new.
+ #: If specified, operate in cell $cell instead of the default cell.
+ #: On success, return 1.
+ #:
+ $AFS_Help{pts_rename} = '$old, $new, [$cell] => Success?';
+ sub AFS_pts_rename {
+   my($old, $new, $cell) = @_;
+   my(@args);
+ 
+   @args = ('rename', '-oldname', $old, '-newname', $new);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('pts', \@args);
+   1;
+ }
+ 
+ 
+ #: AFS_pts_examine($obj, [$cell])
+ #: Examine the PTS object $obj, and return information about it.
+ #: If specified, operate in cell $cell instead of the default cell.
+ #: On success, return an associative array with some or all of the following:
+ #: - name         Name of this object
+ #: - id           ID of this object
+ #: - owner        Name or ID of owner
+ #: - creator      Name or ID of creator
+ #: - mem_count    Number of members (group) or memberships (user)
+ #: - flags        Privacy/access flags (as a string)
+ #: - group_quota  Remaining group quota
+ #:
+ $AFS_Help{pts_examine} = '$obj, [$cell] => %info';
+ sub AFS_pts_examine {
+   my($obj, $cell) = @_;
+   my(@args);
+ 
+   @args = ('examine', '-nameorid', $obj);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('pts', \@args,
+ 	   [[ '^Name\: (.*)\, id\: ([\-0-9]+)\, owner\: (.*)\, creator\: (.*)\,$', #',
+ 	      'name', 'id', 'owner', 'creator' ],
+ 	    [ '^  membership\: (\d+)\, flags\: (.....)\, group quota\: (\d+)\.$',  #',
+ 	      'mem_count', 'flags', 'group_quota' ]
+ 	    ]);
+ }
+ 
+ 
+ #: AFS_pts_chown($obj, $owner, [$cell])
+ #: Change the owner of the PTS object $obj to be $owner.
+ #: If specified, operate in cell $cell instead of the default cell.
+ #: On success, return 1.
+ #:
+ $AFS_Help{pts_chown} = '$obj, $owner, [$cell] => Success?';
+ sub AFS_pts_chown {
+   my($obj, $owner, $cell) = @_;
+   my(@args);
+ 
+   @args = ('chown', '-name', $obj, '-owner', $owner);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('pts', \@args);
+   1;
+ }
+ 
+ 
+ #: AFS_pts_setf($obj, [$access], [$gquota], [$cell])
+ #: Change the access flags and/or group quota for the PTS object $obj.
+ #: If specified, $access specifies the new access flags in the standard 'SOMAR'
+ #: format; individual flags may be specified as '.' to keep the current value.
+ #: If specified, $gquota specifies the new group quota.
+ #: If specified, operate in cell $cell instead of the default cell.
+ #: On success, return 1.
+ #:
+ $AFS_Help{pts_setf} = '$obj, [$access], [$gquota], [$cell] => Success?';
+ sub AFS_pts_setf {
+   my($obj, $access, $gquota, $cell) = @_;
+   my(%result, @args);
+ 
+   @args = ('setfields', '-nameorid', $obj);
+   push(@args, '-groupquota', $gquota) if ($gquota ne '');
+   if ($access) {
+     my(@old, @new, $i);
+     # Ensure access is 5 characters
+     if (length($access) < 5) {
+       $access .= ('.' x (5 - length($access)));
+     } elsif (length($access) > 5) {
+       substr($access, 5) = '';
+     }
+ 
+     %result = &AFS_pts_examine($obj, $cell);
+ 
+     @old = split(//, $result{'flags'});
+     @new = split(//, $access);
+     foreach $i (0 .. 4) {
+       $new[$i] = $old[$i] if ($new[$i] eq '.');
+     }
+     $access = join('', @new);
+     if ($access ne $result{'flags'}) {
+       push(@args, '-access', $access);
+     }
+   }
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('pts', \@args);
+   1;
+ }
+ 
+ 
+ #: AFS_pts_listmax([$cell])
+ #: Fetch the maximum assigned group and user ID.
+ #: If specified, operate in cell $cell instead of the default cell.
+ #: On success, returns (maxuid, maxgid)
+ #:
+ $AFS_Help{pts_listmax} = '[$cell] => ($maxuid, $maxgid)';
+ sub AFS_pts_listmax {
+   my($cell) = @_;
+   my(@args, $uid, $gid);
+ 
+   @args = ('listmax');
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('pts', \@args,
+ 	   [[ '^Max user id is (\d+) and max group id is (\-\d+).',
+ 	      \$uid, \$gid ]]);
+   ($uid, $gid);
+ }
+ 
+ 
+ #: AFS_pts_setmax([$maxuser], [$maxgroup], [$cell])
+ #: Set the maximum assigned group and/or user ID.
+ #: If specified, $maxuser is the new maximum user ID
+ #: If specified, $maxgroup is the new maximum group ID
+ #: If specified, operate in cell $cell instead of the default cell.
+ #: On success, return 1.
+ #:
+ $AFS_Help{pts_setmax} = '[$maxuser], [$maxgroup], [$cell] => Success?';
+ sub AFS_pts_setmax {
+   my($maxuser, $maxgroup, $cell) = @_;
+   my(@args);
+ 
+   @args = ('setmax');
+   push(@args, '-group', $maxgroup) if ($maxgroup);
+   push(@args, '-user',  $maxuser)  if ($maxuser);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('pts', \@args);
+   1;
+ }
+ 
+ #: AFS_pts_add(\@users, \@groups, [$cell])
+ #: Add users specified in @users to groups specified in @groups.
+ #: If specified, operate in cell $cell instead of the default cell.
+ #: On success, return 1.
+ #: If multiple users and/or groups are specified and only some memberships
+ #: are added, some operations may be left untried.
+ #:
+ $AFS_Help{pts_add} = '\@users, \@groups, [$cell] => Success?';
+ sub AFS_pts_add {
+   my($users, $groups, $cell) = @_;
+   my(@args);
+ 
+   @args = ('adduser', '-user', @$users, '-group', @$groups);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('pts', \@args);
+   1;
+ }
+ 
+ 
+ #: AFS_pts_remove(\@users, \@groups, [$cell])
+ #: Remove users specified in @users from groups specified in @groups.
+ #: If specified, operate in cell $cell instead of the default cell.
+ #: On success, return 1.
+ #: If multiple users and/or groups are specified and only some memberships
+ #: are removed, some operations may be left untried.
+ #:
+ $AFS_Help{pts_remove} = '\@users, \@groups, [$cell] => Success?';
+ sub AFS_pts_remove {
+   my($users, $groups, $cell) = @_;
+   my(@args);
+ 
+   @args = ('removeuser', '-user', @$users, '-group', @$groups);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('pts', \@args);
+   1;
+ }
+ 
+ 
+ #: AFS_pts_members($obj, [$cell])
+ #: If $obj specifies a group, retrieve a list of its members.
+ #: If $obj specifies a user, retrieve a list of groups to which it belongs.
+ #: If specified, operate in cell $cell instead of the default cell.
+ #: On success, return the resulting list.
+ #:
+ $AFS_Help{pts_members} = '$obj, [$cell] => @members';
+ sub AFS_pts_members {
+   my($obj, $cell) = @_;
+   my(@args, @grouplist);
+ 
+   @args = ('membership', '-nameorid', $obj);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('pts', \@args, [[ '^  (.*)', \@grouplist ]]);
+   @grouplist;
+ }  
+ 
+ 
+ #: AFS_pts_listown($owner, [$cell])
+ #: Retrieve a list of PTS groups owned by the PTS object $obj.
+ #: If specified, operate in cell $cell instead of the default cell.
+ #: On success, return the resulting list.
+ #:
+ $AFS_Help{pts_listown} = '$owner, [$cell] => @owned';
+ sub AFS_pts_listown {
+   my($owner, $cell) = @_;
+   my(@args, @grouplist);
+ 
+   @args = ('listowned', '-nameorid', $owner);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('pts', \@args, [[ '^  (.*)', \@grouplist ]]);
+   @grouplist;
+ }  
+ 
+ 
+ 1;
Index: openafs/src/tests/OpenAFS/util.pm
diff -c /dev/null openafs/src/tests/OpenAFS/util.pm:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:58 2002
--- openafs/src/tests/OpenAFS/util.pm	Sun Jan 20 04:18:10 2002
***************
*** 0 ****
--- 1,356 ----
+ # CMUCS AFStools
+ # Copyright (c) 1996, Carnegie Mellon University
+ # All rights reserved.
+ #
+ # See CMUCS/CMU_copyright.ph for use and distribution information
+ 
+ package OpenAFS::util;
+ 
+ =head1 NAME
+ 
+ OpenAFS::util - General AFS utilities
+ 
+ =head1 SYNOPSIS
+ 
+   use OpenAFS::util;
+ 
+   AFS_Init();
+   AFS_Trace($subject, $level);
+   AFS_SetParm($parm, $value);
+ 
+   use OpenAFS::util qw(GetOpts_AFS);
+   %options = GetOpts_AFS(\@argv, \@optlist);
+ 
+ =head1 DESCRIPTION
+ 
+ This module defines a variety of AFS-related utility functions.  Virtually
+ every application that uses AFStools will need to use some of the utilities
+ defined in this module.  In addition, a variety of global variables are
+ defined here for use by all the AFStools modules.  Most of these are
+ private, but a few are semi-public.
+ 
+ =cut
+ 
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::config;
+ require OpenAFS::afsconf;   ## Avoid circular 'use' dependencies
+ use Exporter;
+ 
+ $VERSION   = '';
+ $VERSION   = '1.00';
+ @ISA       = qw(Exporter);
+ @EXPORT    = qw(&AFS_Init
+ 		&AFS_Trace
+ 		&AFS_SetParm);
+ @EXPORT_OK = qw(%AFS_Parms
+                 %AFS_Trace
+ 		%AFS_Help
+                 %AFScmd
+ 		&GetOpts_AFS
+ 		&GetOpts_AFS_Help);
+ %EXPORT_TAGS = (afs_internal => [qw(%AFS_Parms %AFS_Trace %AFScmd %AFS_Help)],
+                 afs_getopts  => [qw(&GetOpts_AFS &GetOpts_AFS_Help)] );
+ 
+ 
+ =head2 AFS_Init()
+ 
+ This function does basic initialization of AFStools.  It must be called before
+ any other AFStools function.
+ 
+ =cut
+ 
+ sub AFS_Init
+ {
+   my(@dirs, $c, $i, $x);
+ 
+   $AFS_Parms{'authlvl'}  = 1;
+   $AFS_Parms{'confdir'}  = $def_ConfDir;
+   $AFS_Parms{'cell'}     = OpenAFS::afsconf::AFS_conf_localcell();
+ 
+   # Search for AFS commands
+   @dirs = @CmdPath;
+   foreach $c (@CmdList)
+     {
+       $AFScmd{$c} = '';
+       foreach $i ($[ .. $#dirs)
+ 	{
+           $x = $dirs[$i];
+ 	  if (-x "$x/$c" && ! -d "$x/$c")
+ 	    {
+ 	      $AFScmd{$c} = "$x/$c";
+               splice(@dirs, $i, 1);   # Move this item to the start of the array
+ 	      unshift(@dirs, $x);
+ 	      last;
+ 	    }
+ 	}
+       return "Unable to locate $c!" if (!$AFScmd{$c});
+     }
+   0;
+ }
+ 
+ 
+ =head2 AFS_Trace($subject, $level)
+ 
+ Sets the tracing level for a particular "subject" to the specified level.
+ All tracing levels start at 0, and can be set to higher values to get debugging
+ information from different parts of AFStools.  This function is generally
+ only of use to people debugging or extending AFStools.
+ 
+ =cut
+ 
+ $AFS_Help{Trace} = '$subject, $level => void';
+ sub AFS_Trace {
+   my($subject, $level) = @_;
+ 
+   $AFS_Trace{$subject} = $level;
+ }
+ 
+ 
+ =head2 AFS_SetParm($parm, $value)
+ 
+ Sets the AFStools parameter I<$parm> to I<$value>.  AFStools parameters are
+ used to alter the behaviour of various parts of the system.  The following
+ parameters are currently defined:
+ 
+ =over 10
+ 
+ =item authlvl
+ 
+ The authentication level to use for commands that talk directly to AFS
+ servers (bos, vos, pts, etc.).  Set to 0 for unauthenticated access (-noauth),
+ 1 to use the user's existing tokens, or 2 to use the AFS service key
+ (-localauth).
+ 
+ =item cell
+ 
+ The default AFS cell in which to work.  This is initially the workstation's
+ local cell.
+ 
+ =item confdir
+ 
+ The AFS configuration directory to use.  If none is specified, the default
+ (as defined in OpenAFS::config) will be used.
+ 
+ =item vostrace
+ 
+ Set the tracing level used by various B<vos> utilities.  The default is 0,
+ which disables any tracing of activity of B<vos> commands.  A setting of 1
+ copies output from all commands except those which are invoked solely to
+ get information; a setting of 2 additionally uses the "-verbose" command
+ on any command whose output is copied.  If a setting of 3 is used, all
+ B<vos> commands will be invoked with "-verbose", and have their output
+ copied to stdout.
+ 
+ =back
+ 
+ =cut
+ 
+ $AFS_Help{SetParm} = '$parm, $value => void';
+ sub AFS_SetParm {
+   my($parm, $value) = @_;
+ 
+   $AFS_Parms{$parm} = $value;
+ }
+ 
+ 
+ #: GetOpts_AFS(\@argv, \@optlist)
+ #: Parse AFS-style options.
+ #: \@argv is a hard reference to the list of arguments to be parsed.
+ #: \@optlist is a hard reference to the list of option specifications for valid
+ #: options; in their default order.  Each option specification, in turn, is a
+ #: hard reference to an associative array containing some of the following
+ #: elements:
+ #:     name       => The name of the argument
+ #:     numargs    => Number of arguments (0, 1, or -1 for multiple)
+ #:     required   => If nonzero, this argument is required
+ #:     default    => Value to give this option if not specified
+ #:     noauto     => Don't use this option for unadorned arguments
+ #:
+ #: Results are returned in the form of an associative array of options and
+ #: their values:
+ #: - Boolean (0-argument) options have a value of 1 if specified.  This type
+ #:   of option may not be marked 'required'.
+ #: - Simple (1-argument) options have a value which is the string given by the
+ #:   user.
+ #: - Multiple-argument options have a value which is a hard reference to an
+ #:   array of values given by the user.
+ #:
+ #: Argument parsing is done in a similar manner to the argument parser used by
+ #: various AFS utilities.  Options have multi-character names, and may not be
+ #: combined with their arguments or other options.  Those options which take
+ #: arguments use up at least the next argument, regardless of whether it begins
+ #: with a dash.  Options which can take multiple arguments will eat at least
+ #: one argument, as well as any following argument up to the next option (i.e.,
+ #: the next argument beginning with a dash).  An "unadorned" argument will be
+ #: used by the next argument-taking option.  If there are multiple unadorned
+ #: arguments, they will be used up by successive arguments much in the same
+ #: way Perl handles list assignment - each one-argument (scalar) option will
+ #: use one argument; the first multi-argument (list) option will use up any
+ #: remaining unadorned arguments.
+ #:
+ #: On completion, @argv will be left with any unparsed arguments (this can
+ #: happen if the last option specified is _not_ a multi-argument option, and
+ #: there are no "defaulted" options).  This is considered to be an error
+ #: condition.
+ #:
+ sub GetOpts_AFS_Help {
+   my($cmd, $optlist) = @_;
+   my($option, $optname, $desc);
+ 
+   foreach $option (@$optlist) {
+     $optname = '-' . $$option{name};
+     if ($$option{numargs}) {
+       $desc = $$option{desc} ? $$option{desc} : $$option{name};
+       $desc = " <$desc>";
+       $desc .= '+' if ($$option{numargs} < 0);
+       $optname .= $desc;
+     }
+     $optname = "[$optname]" if (!$$option{required});
+     $cmd .= " $optname";
+   }
+   $cmd;
+ }
+ 
+ sub _which_opt {
+   my($optname, @options) = @_;
+   my($o, $which, $n);
+ 
+   foreach $o (@options) {
+     next unless ($o =~ /^$optname/);
+     $n++;
+     $which = $o;
+   }
+   ($n == 1) ? $which : $optname;
+ }
+ 
+ sub GetOpts_AFS {
+   my($argv, $optlist) = @_;
+   my(@autolist, %opttbl, %result);
+   my($stop, $key, $value, $diemsg);
+ 
+   # Initialization:
+   @autolist = map {
+     if ($_->{numargs} && !$_->{noauto} && !$stop) {
+       $stop = 1 if ($_->{numargs} < 0);
+       ($_->{name});
+     } else {
+       ();
+     }
+   } (@$optlist, { name=>'-help', numargs=>0, required=>0 } );
+   %opttbl = map { $_->{name} => $_ } @$optlist;
+ 
+   while (@$argv) {
+     my($optname, $optkind);
+ 
+     # Parse the next argument.  It can either be an option, or an
+     # unadorned argument.  If the former, shift it off and process it.
+     # Otherwise, grab the next "automatic" option.  If there are no
+     # more automatic options, we have extra arguments and should return.
+     if ($argv->[0] =~ /^-(.+)/) {  # Got an option!
+       $optname = $1;
+       shift(@$argv);
+     } else {                       # An unadorned argument
+       if (@autolist) {
+ 	$optname = shift(@autolist);
+       } else {
+ 	$diemsg = join(' ', "Extra arguments:", @$argv) unless ($diemsg);
+         shift @$argv;
+         next;
+       }
+     }
+     $optname = &_which_opt($optname, keys %opttbl);
+ 
+     # Find out how many arguments this thing wants, then remove it from
+     # the option table and automatic option list.
+     $optkind = $opttbl{$optname}->{numargs};
+     delete $opttbl{$optname};
+     @autolist = grep($_ ne $optname, @autolist);
+ 
+     # Parse arguments (if any), and set the result value
+     if (!$optkind) {               # Boolean!
+       $result{$optname} = 1;
+     } elsif ($optkind == 1) {      # Single argument
+       # Shift off a single argument, or signal an error
+       if (!@$argv) {
+         $diemsg = "No argument for -$optname" unless ($diemsg);
+         next;
+       }
+       $result{$optname} = shift(@$argv);
+     } elsif ($optkind < 0) {       # Multiple arguments
+       # Shift off at least one argument, and any additional
+       # ones that are present.  EXCEPT, if there are no more
+       # explicitly-specified options but there ARE automatic
+       # options left in our list, then only eat up one.
+       my($val, @val);
+       if (!@$argv) {
+ 	$diemsg = "No argument for -$optname" unless ($diemsg);
+         next;
+       }
+       $val = shift(@$argv);
+       push(@val, shift @$argv) while (@$argv && $argv->[0] !~ /^-/);
+       if (@autolist && !@$argv) {
+ 	unshift(@$argv, @val);
+ 	@val = ($val);
+       } else {
+ 	unshift(@val, $val);
+       }
+       $result{$optname} = [@val];
+     } else {
+       die "Invalid argument spec for -$optname ($optkind)\n";
+     }
+   }
+ 
+   # Now for a little clean-up
+   # Set default values for any unspecified option that has them.
+   # Set an error condition if there are any required options that
+   # were not specified.
+   while (($key, $value) = each %opttbl) {
+     if ($value->{required}) {
+       $diemsg = "Required option -$key not specified" unless($diemsg);
+     }
+     $result{$key} = $value->{default};
+   }
+   if ($diemsg && !$result{help}) { die $diemsg . "\n" }
+   %result;
+ }
+ 
+ 
+ 1;
+ 
+ =head1 VARIABLES
+ 
+ The following global variables are defined by B<OpenAFS::util>.  None of these
+ are exported by default.  Those marked "Private" should not be used outside
+ AFStools; their names, meaning, and even existence may change at any time.
+ 
+ =over 12
+ 
+ =item %AFS_Help - Help info
+ 
+ This array contains argument lists for all publicly-exported AFStools
+ functions with names of the form AFS_*.  It is intended for programs like
+ B<testbed>, which provide a direct interactive interface to AFStools.
+ 
+ =item %AFS_Parms - Parameter settings  [Private]
+ 
+ This array contains the settings of AFStools parameters set with
+ B<OpenAFS::util::AFS_SetParm>.
+ 
+ =item %AFS_Trace - Tracing levels  [Private]
+ 
+ This array contains the tracing levels set with B<OpenAFS::util::AFS_Trace>.
+ 
+ =item %AFScmd - AFS command locations  [Private]
+ 
+ This array contains paths to the various AFS command binaries, for use
+ by B<OpenAFS::wrapper::wrapper> and possibly other AFStools functions.
+ 
+ =back
+ 
+ =head1 COPYRIGHT
+ 
+ The CMUCS AFStools, including this module are
+ Copyright (c) 1996, Carnegie Mellon University.  All rights reserved.
+ For use and redistribution information, see CMUCS/CMU_copyright.pm
+ 
+ =cut
Index: openafs/src/tests/OpenAFS/vos.pm
diff -c /dev/null openafs/src/tests/OpenAFS/vos.pm:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:58 2002
--- openafs/src/tests/OpenAFS/vos.pm	Sun Jan 20 04:18:10 2002
***************
*** 0 ****
--- 1,803 ----
+ # CMUCS AFStools
+ # Copyright (c) 1996, Carnegie Mellon University
+ # All rights reserved.
+ #
+ # See CMU_copyright.ph for use and distribution information
+ #
+ #: * vos.pm - Wrappers around VOS commands (volume maintenance)
+ #: * This module provides wrappers around the various volserver and VLDB
+ #: * commands, giving them a nice perl-based interface.  Someday, they might
+ #: * talk to the servers directly instead of using 'vos', but not anytime
+ #: * soon.
+ #:
+ 
+ package OpenAFS::vos;
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT :afs_internal);
+ use OpenAFS::wrapper;
+ use Exporter;
+ 
+ $VERSION   = '';
+ $VERSION   = '1.00';
+ @ISA       = qw(Exporter);
+ @EXPORT    = qw(&AFS_vos_create        &AFS_vos_listvldb
+                 &AFS_vos_remove        &AFS_vos_delentry
+                 &AFS_vos_rename        &AFS_vos_syncserv
+                 &AFS_vos_move          &AFS_vos_syncvldb
+                 &AFS_vos_examine       &AFS_vos_lock
+                 &AFS_vos_addsite       &AFS_vos_unlock
+                 &AFS_vos_remsite       &AFS_vos_unlockvldb
+                 &AFS_vos_release       &AFS_vos_changeaddr
+                 &AFS_vos_backup        &AFS_vos_listpart
+                 &AFS_vos_backupsys     &AFS_vos_partinfo
+                 &AFS_vos_dump          &AFS_vos_listvol
+                 &AFS_vos_restore       &AFS_vos_zap
+                 &AFS_vos_status);
+ 
+ $vos_err_parse = [ 'Error in vos (.*) command', '-(.*)' ];
+ 
+ 
+ #: AFS_vos_create($vol, $server, $part, [$quota], [$cell])
+ #: Create a volume with name $vol
+ #: The server name ($server) may be a hostname or IP address
+ #: The partition may be a partition name (/vicepx), letter (x), or number (24)
+ #: If specified, use $quota for the initial quota instead of 5000 blocks.
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, return the volume ID.
+ #:
+ $AFS_Help{vos_create} = '$vol, $server, $part, [$quota], [$cell] => $volid';
+ sub AFS_vos_create {
+   my($vol, $server, $part, $quota, $cell) = @_;
+   my(@args, $id);
+ 
+   @args = ('create', '-name', $vol, '-server', $server, '-part', $part);
+   push(@args, '-maxquota', $quota) if ($quota ne '');
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-verbose')          if ($AFS_Parms{'vostrace'} > 1);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('vos', \@args, 
+ 	   [$vos_err_parse,
+ 	    ['^Volume (\d+) created on partition \/vicep\S+ of \S+', \$id ],
+ 	    $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ]);
+   $id;
+ }
+ 
+ 
+ #: AFS_vos_remove($vol, $server, $part, [$cell])
+ #: Remove the volume $vol from the server and partition specified by $server and
+ #: $part.  If appropriate, also remove the corresponding VLDB entry.
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, return 1.
+ #:
+ $AFS_Help{vos_remove} = '$vol, $server, $part, [$cell] => Success?';
+ sub AFS_vos_remove {
+   my($vol, $server, $part, $cell) = @_;
+   my(@args);
+ 
+   @args = ('remove', '-id', $vol, '-server', $server, '-part', $part);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-verbose')          if ($AFS_Parms{'vostrace'} > 1);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('vos', \@args,
+ 	   [$vos_err_parse,
+ 	    $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ]);
+   1;
+ }
+ 
+ 
+ #: AFS_vos_rename($old, $new, [$cell])
+ #: Rename the volume $old to have the name $new.
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, return 1.
+ #:
+ $AFS_Help{vos_rename} = '$old, $new, [$cell] => Success?';
+ sub AFS_vos_rename {
+   my($old, $new, $cell) = @_;
+   my(@args);
+ 
+   @args = ('rename', '-oldname', $old, '-newname', $new);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-verbose')          if ($AFS_Parms{'vostrace'} > 1);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('vos', \@args,
+ 	   [$vos_err_parse,
+ 	    $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ]);
+   1;
+ }
+ 
+ 
+ #: AFS_vos_move($vol, $fromsrv, $frompart, $tosrv, $topart, [$cell])
+ #: Move the volume specified by $vol.
+ #: The source location is specified by $fromsrv and $frompart.
+ #: The destination location is specified by $tosrv and $topart.
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, return 1.
+ 
+ #:
+ $AFS_Help{vos_move} = '$vol, $fromsrv, $frompart, $tosrv, $topart, [$cell] => Success?';
+ sub AFS_vos_move {
+   my($vol, $fromsrv, $frompart, $tosrv, $topart, $cell) = @_;
+   my(@args);
+ 
+   @args = ('move', '-id', $vol,
+ 	   '-fromserver', $fromsrv, '-frompartition', $frompart,
+ 	   '-toserver', $tosrv, '-topartition', $topart);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-verbose')          if ($AFS_Parms{'vostrace'} > 1);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('vos', \@args,
+ 	   [$vos_err_parse,
+ 	    $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ]);
+   1;
+ }
+ 
+ 
+ #: AFS_vos_examine($vol, [$cell])
+ #: Examine the volume $vol, and return information about it.
+ #: If specified, operate in cell $cell instead of the default cell.
+ #: On success, return an associative array with some or all of the following:
+ #: - name         Name of this volume
+ #: - id           ID of this volume
+ #: - kind         Kind of volume (RW, RO, or BK)
+ #: - inuse        Disk space in use
+ #: - maxquota     Maximum disk usage quota
+ #: - minquota     Minimum disk usage quota (optional)
+ #: - stamp_create Time when volume was originally created
+ #: - stamp_update Time volume was last modified
+ #: - stamp_backup Time backup volume was cloned, or 'Never'
+ #: - stamp_copy   Time this copy of volume was made
+ #: - backup_flag  State of automatic backups: empty or 'disabled'
+ #: - dayuse       Number of accesses in the past day
+ #: - rwid         ID of read-write volume (even if this is RO or BK)
+ #: - roid         ID of read-only volume (even if this is RW or BK)
+ #: - bkid         ID of backup volume (even if this is RW or RO)
+ #: - rwserv       Name of server where read/write volume is
+ #: - rwpart       Name of partition where read/write volume is
+ #: - rosites      Reference to a list of read-only sites.  Each site, in turn,
+ #:                is a reference to a two-element list (server, part).
+ #:
+ $AFS_Help{vos_examine} = '$vol, [$cell] => %info';
+ sub AFS_vos_examine {
+   my($vol, $cell) = @_;
+   my(%result, @args, @rosites);
+ 
+   @args = ('examine', '-id', $vol);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-verbose')          if ($AFS_Parms{'vostrace'} > 2);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   %result = &wrapper('vos', \@args,
+ 		     [$vos_err_parse,
+ 		      ['^(\S+)\s*(\d+)\s*(RW|RO|BK)\s*(\d+)\s*K',          'name', 'id', 'kind', 'inuse'],
+ 		      ['MaxQuota\s*(\d+)\s*K',                             'maxquota'     ],
+ 		      ['MinQuota\s*(\d+)\s*K',                             'minquota'     ],
+ 		      ['Creation\s*(.*\S+)',                               'stamp_create' ],
+ 		      ['Last Update\s*(.*\S+)',                            'stamp_update' ],
+ 		      ['Backup\s+([^\d\s].*\S+)',                          'stamp_backup' ],
+ 		      ['Copy\s*(.*\S+)',                                   'stamp_copy'   ],
+ 		      ['Automatic backups are (disabled) for this volume', 'backup_flag'  ],
+ 		      ['(\d+) accesses in the past day',                   'dayuse'       ],
+ 		      ['RWrite\:\s*(\d+)',                                 'rwid'         ],
+ 		      ['ROnly\:\s*(\d+)',                                  'roid'         ],
+ 		      ['Backup\:\s*(\d+)',                                 'bkid'         ],
+ 		      ['server (\S+) partition /vicep(\S+) RW Site',       'rwserv', 'rwpart'],
+ 		      ['server (\S+) partition /vicep(\S+) RO Site',       sub {
+ 			push(@rosites, [$_[0], $_[1]]);
+ 		      }],
+ 		      ($AFS_Parms{'vostrace'} > 2) ? ([ '', '?']) : () ]);
+ 
+   $result{'rosites'} = \@rosites if (@rosites);
+   %result;
+ }
+ 
+ 
+ 
+ #: AFS_vos_addsite($vol, $server, $part, [$cell])
+ #: Add a replication site for volume $vol
+ #: The server name ($server) may be a hostname or IP address
+ #: The partition may be a partition name (/vicepx), letter (x), or number (24)
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, return 1.
+ #:
+ $AFS_Help{vos_addsite} = '$vol, $server, $part, [$cell] => Success?';
+ sub AFS_vos_addsite {
+   my($vol, $server, $part, $cell) = @_;
+   my(@args);
+ 
+   @args = ('addsite', '-id', $vol, '-server', $server, '-part', $part);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-verbose')          if ($AFS_Parms{'vostrace'} > 1);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('vos', \@args,
+ 	   [$vos_err_parse,
+ 	    $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ]);
+   1;
+ }
+ 
+ 
+ #: AFS_vos_remsite($vol, $server, $part, [$cell])
+ #: Remove a replication site for volume $vol
+ #: The server name ($server) may be a hostname or IP address
+ #: The partition may be a partition name (/vicepx), letter (x), or number (24)
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, return 1.
+ #:
+ $AFS_Help{vos_remsite} = '$vol, $server, $part, [$cell] => Success?';
+ sub AFS_vos_remsite {
+   my($vol, $server, $part, $cell) = @_;
+   my(@args);
+ 
+   @args = ('remsite', '-id', $vol, '-server', $server, '-part', $part);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-verbose')          if ($AFS_Parms{'vostrace'} > 1);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('vos', \@args,
+ 	   [$vos_err_parse,
+ 	    $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ]);
+   1;
+ }
+ 
+ 
+ #: AFS_vos_release($vol, [$cell], [$force])
+ #: Release the volume $vol.
+ #: If $force is specified and non-zero, use the "-f" switch.
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, return 1.
+ #:
+ $AFS_Help{vos_release} = '$vol, [$cell], [$force] => Success?';
+ sub AFS_vos_release {
+   my($vol, $cell, $force) = @_;
+   my(@args);
+ 
+   @args = ('release', '-id', $vol);
+   push(@args, '-f')                if ($force);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-verbose')          if ($AFS_Parms{'vostrace'} > 1);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('vos', \@args,
+ 	   [$vos_err_parse,
+ 	    $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ]);
+   1;
+ }
+ 
+ 
+ #: AFS_vos_backup($vol, [$cell])
+ #: Make a backup of the volume $vol.
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, return 1.
+ #:
+ $AFS_Help{vos_backup} = '$vol, [$cell] => Success?';
+ sub AFS_vos_backup {
+   my($vol, $cell) = @_;
+   my(@args);
+ 
+   @args = ('backup', '-id', $vol);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-verbose')          if ($AFS_Parms{'vostrace'} > 1);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('vos', \@args,
+ 	   [$vos_err_parse,
+ 	    $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ]);
+   1;
+ }
+ 
+ 
+ #: AFS_vos_backupsys([$prefix], [$server, [$part]], [$exclude], [$cell])
+ #: Do en masse backups of AFS volumes.
+ #: If specified, match only volumes whose names begin with $prefix
+ #: If specified, limit work to the $server and, if given, $part.
+ #: If $exclude is specified and non-zero, backup only volumes NOT matched.
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, return 1.
+ #:
+ $AFS_Help{vos_backupsys} = '[$prefix], [$server, [$part]], [$exclude], [$cell] => Success?';
+ sub AFS_vos_backupsys {
+   my($prefix, $server, $part, $exclude, $cell) = @_;
+   my(@args);
+ 
+   @args = ('backupsys');
+   push(@args, '-prefix', $prefix)  if ($prefix);
+   push(@args, '-server', $server)  if ($server);
+   push(@args, '-partition', $part) if ($server && $part);
+   push(@args, '-exclude')          if ($exclude);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-verbose')          if ($AFS_Parms{'vostrace'} > 1);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('vos', \@args,
+ 	   [$vos_err_parse,
+ 	    $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ]);
+   1;
+ }
+ 
+ 
+ #: AFS_vos_dump($vol, [$time], [$file], [$cell])
+ #: Dump the volume $vol
+ #: If specified, do an incremental dump since $time instead of a full dump.
+ #: If specified, dump to $file instead of STDOUT
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, return 1.
+ #:
+ $AFS_Help{vos_dump} = '$vol, [$time], [$file], [$cell] => Success?';
+ sub AFS_vos_dump {
+   my($vol, $time, $file, $cell) = @_;
+   my(@args);
+ 
+   @args = ('dump', '-id', $vol);
+   push(@args, '-time', ($time ? $time : 0));
+   push(@args, '-file', $file)      if ($file);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-verbose')          if ($AFS_Parms{'vostrace'} > 1);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('vos', \@args,
+ 	   [$vos_err_parse,
+ 	    $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ],
+ 	   { pass_stdout => !$file });
+   1;
+ }
+ 
+ 
+ #: AFS_vos_restore($vol, $server, $part, [$file], [$id], [$owmode], [$cell])
+ #: Restore the volume $vol to partition $part on server $server.
+ #: If specified, restore from $file instead of STDIN
+ #: If specified, use the volume ID $id
+ #: If specified, $owmode must be 'abort', 'full', or 'incremental', and
+ #: indicates what to do if the volume exists.
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, return 1.
+ #:
+ $AFS_Help{vos_restore} = '$vol, $server, $part, [$file], [$id], [$owmode], [$cell] => Success?';
+ sub AFS_vos_restore {
+   my($vol, $server, $part, $file, $id, $owmode, $cell) = @_;
+   my(@args);
+ 
+   @args = ('restore', '-name', $vol, '-server', $server, '-partition', $part);
+   push(@args, '-file', $file)      if ($file);
+   push(@args, '-id', $id)          if ($id);
+   push(@args, '-overwrite', $owmode) if ($owmode);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-verbose')          if ($AFS_Parms{'vostrace'} > 1);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('vos', \@args,
+ 	   [$vos_err_parse,
+ 	    $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ]);
+   1;
+ }
+ 
+ 
+ #: AFS_vos_listvldb([$vol], [$server, [$part]], [$locked], [$cell])
+ #: Get a list of volumes in the VLDB.
+ #: If specified, list only the volume $vol
+ #: If specified, list only volumes on the server $server.
+ #: If specified with $server, list only volumes on the partition $part.
+ #: If $locked is specified and nonzero, list only locked VLDB entries
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, return an associative array whose keys are names of volumes
+ #: on the specified server, and each of whose values is an associative
+ #: array describing the corresponding volume, containing some or all of
+ #: these elements:
+ #: - name         Name of this volume (same as key)
+ #: - rwid         ID of read-write volume (even if this is RO or BK)
+ #: - roid         ID of read-only volume (even if this is RW or BK)
+ #: - bkid         ID of backup volume (even if this is RW or RO)
+ #: - locked       Empty or LOCKED to indicate VLDB entry is locked
+ #: - rwserv       Name of server where read/write volume is
+ #: - rwpart       Name of partition where read/write volume is
+ #: - rosites      Reference to a list of read-only sites.  Each site, in turn,
+ #:                is a reference to a two-element list (server, part).
+ #:
+ $AFS_Help{vos_listvldb} = '[$vol], [$server, [$part]], [$locked], [$cell] => %vols';
+ sub AFS_vos_listvldb {
+   my($vol, $server, $part, $locked, $cell) = @_;
+   my(%finres, %vlist, @rosites);
+ 
+   @args = ('listvldb');
+   push(@args, '-name', $vol)       if ($vol);
+   push(@args, '-server', $server)  if ($server);
+   push(@args, '-partition', $part) if ($part && $server);
+   push(@args, '-locked')           if ($locked);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-verbose')          if ($AFS_Parms{'vostrace'} > 2);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   %finres = &wrapper('vos', \@args,
+ 		     [$vos_err_parse,
+ 		      ['^(VLDB|Total) entries', '.'],
+ 		      ['^(\S+)', sub {
+ 			my(%vinfo) = %OpenAFS::wrapper::result;
+ 
+ 			if ($vinfo{name}) {
+ 			  $vinfo{rosites} = [@rosites] if (@rosites);
+ 			  $vlist{$vinfo{name}} = \%vinfo;
+ 
+ 			  @rosites = ();
+ 			  %OpenAFS::wrapper::result = ();
+ 			}
+ 		      }],
+ 		      ['^(\S+)',                                           'name'         ],
+ 		      ['RWrite\:\s*(\d+)',                                 'rwid'         ],
+ 		      ['ROnly\:\s*(\d+)',                                  'roid'         ],
+ 		      ['Backup\:\s*(\d+)',                                 'bkid'         ],
+ 		      ['Volume is currently (LOCKED)',                     'locked'       ],
+ 		      ['server (\S+) partition /vicep(\S+) RW Site',       'rwserv', 'rwpart'],
+ 		      ['server (\S+) partition /vicep(\S+) RO Site',       sub {
+ 			push(@rosites, [$_[0], $_[1]]);
+ 		      }],
+ 		      ($AFS_Parms{'vostrace'} > 2) ? ([ '', '?']) : () ]);
+ 
+   if ($finres{name}) {
+     $finres{rosites} = [@rosites] if (@rosites);
+     $vlist{$finres{name}} = \%finres;
+   }
+   %vlist;
+ }
+ 
+ 
+ 
+ #: AFS_vos_delentry($vol, [$cell])
+ #: Delete the VLDB entry for the volume $vol
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, return 1.
+ #:
+ $AFS_Help{vos_delentry} = '$vol, [$cell] => Success?';
+ sub AFS_vos_delentry {
+   my($vol, $cell) = @_;
+   my(@args);
+ 
+   @args = ('delentry', '-id', $vol);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-verbose')          if ($AFS_Parms{'vostrace'} > 1);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('vos', \@args,
+ 	   [$vos_err_parse,
+ 	    $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ]);
+   1;
+ }
+ 
+ 
+ #: AFS_vos_syncserv($server, [$part], [$cell], [$force])
+ #: Synchronize the server $server with the VLDB
+ #: If specified, synchronize only partition $part
+ #: If specified, work in $cell instead of the default cell
+ #: If $force is specified, force updates to occur
+ #: On success, return 1.
+ #:
+ $AFS_Help{vos_syncserv} = '$server, [$part], [$cell], [$force] => Success?';
+ sub AFS_vos_syncserv {
+   my($server, $part, $cell, $force) = @_;
+   my(@args);
+ 
+   @args = ('syncserv', '-server', $server);
+   push(@args, '-partition', $part) if ($part);
+   push(@args, '-force')            if ($force);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-verbose')          if ($AFS_Parms{'vostrace'} > 1);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('vos', \@args,
+ 	   [$vos_err_parse,
+ 	    $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ]);
+   1;
+ }
+ 
+ 
+ #: AFS_vos_syncvldb($server, [$part], [$cell], [$force])
+ #: Synchronize the VLDB with server $server
+ #: If specified, synchronize only partition $part
+ #: If specified, work in $cell instead of the default cell
+ #: If $force is specified, force updates to occur
+ #: On success, return 1.
+ #:
+ $AFS_Help{vos_syncvldb} = '$server, [$part], [$cell], [$force] => Success?';
+ sub AFS_vos_syncvldb {
+   my($server, $part, $cell, $force) = @_;
+   my(@args);
+ 
+   @args = ('syncvldb', '-server', $server);
+   push(@args, '-partition', $part) if ($part);
+   push(@args, '-force')            if ($force);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-verbose')          if ($AFS_Parms{'vostrace'} > 1);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('vos', \@args,
+ 	   [$vos_err_parse,
+ 	    $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ]);
+   1;
+ }
+ 
+ 
+ #: AFS_vos_lock($vol, [$cell])
+ #: Lock the VLDB entry for volume $vol.
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, return 1.
+ #:
+ $AFS_Help{vos_lock} = '$vol, [$cell] => Success?';
+ sub AFS_vos_lock {
+   my($vol, $cell) = @_;
+   my(@args);
+ 
+   @args = ('lock', '-id', $vol);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-verbose')          if ($AFS_Parms{'vostrace'} > 1);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('vos', \@args,
+ 	   [$vos_err_parse,
+ 	    $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ]);
+   1;
+ }
+ 
+ 
+ #: AFS_vos_unlock($vol, [$cell])
+ #: Unlock the VLDB entry for volume $vol.
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, return 1.
+ #:
+ $AFS_Help{vos_unlock} = '$vol, [$cell] => Success?';
+ sub AFS_vos_unlock {
+   my($vol, $cell) = @_;
+   my(@args);
+ 
+   @args = ('unlock', '-id', $vol);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-verbose')          if ($AFS_Parms{'vostrace'} > 1);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('vos', \@args,
+ 	   [$vos_err_parse,
+ 	    $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ]);
+   1;
+ }
+ 
+ 
+ #: AFS_vos_unlockvldb([$server, [$part]], [$cell])
+ #: Unlock some or all VLDB entries
+ #: If specified, unlock only entries for volumes on server $server
+ #: If specified with $server, unlock only entries for volumes on
+ #: partition $part, instead of entries for volumes on all partitions
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, return 1.
+ #:
+ $AFS_Help{vos_unlockvldb} = '[$server, [$part]], [$cell] => Success?';
+ sub AFS_vos_unlockvldb {
+   my($server, $part, $cell) = @_;
+   my(@args);
+ 
+   @args = ('unlockvldb');
+   push(@args, '-server', $server)  if ($server);
+   push(@args, '-partition', $part) if ($server && $part);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-verbose')          if ($AFS_Parms{'vostrace'} > 1);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('vos', \@args,
+ 	   [$vos_err_parse,
+ 	    $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ]);
+   1;
+ }
+ 
+ 
+ #: AFS_vos_changeaddr($old, $new, [$cell])
+ #: Change the IP address of server $old to $new.
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, return 1.
+ #:
+ $AFS_Help{vos_changeaddr} = '$old, $new, [$cell] => Success?';
+ sub AFS_vos_changeaddr {
+   my($old, $new, $cell) = @_;
+   my(@args);
+ 
+   @args = ('changeaddr', '-oldaddr', $old, '-newaddr', $new);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-verbose')          if ($AFS_Parms{'vostrace'} > 1);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('vos', \@args,
+ 	   [$vos_err_parse,
+ 	    $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ]);
+   1;
+ }
+ 
+ 
+ #: AFS_vos_listpart($server, [$cell])
+ #: Retrieve a list of partitions on server $server
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, return a list of partition letters
+ #:
+ $AFS_Help{vos_listpart} = '$server, [$cell] => @parts';
+ sub AFS_vos_listpart {
+   my($server, $cell) = @_;
+   my(@args, @parts);
+ 
+   @args = ('listpart', '-server', $server);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-verbose')          if ($AFS_Parms{'vostrace'} > 2);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('vos', \@args,
+ 	   [$vos_err_parse,
+ 	    [ '^(.*\/vicep.*)$', #',
+ 	     sub {
+ 	       push(@parts, map {
+ 		 my($x) = $_;
+ 		 $x =~ s/^\/vicep//;
+ 		 $x;
+ 	       } split(' ', $_[0]));
+ 	     }],
+ 	    ($AFS_Parms{'vostrace'} > 2) ? ([ '', '?']) : () ]);
+   @parts;
+ }
+ 
+ 
+ #: AFS_vos_partinfo($server, [$part], [$cell])
+ #: Get information about partitions on server $server.
+ #: If specified, only get info about partition $part.
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, return an associative array whose keys are partition letters,
+ #: and each of whose values is a reference to a 2-element list, consisting
+ #: of the total size of the partition and the amount of space used.
+ #:
+ $AFS_Help{vos_partinfo} = '$server, [$part], [$cell] => %info';
+ sub AFS_vos_partinfo {
+   my($server, $part, $cell) = @_;
+   my(@args, %parts);
+ 
+   @args = ('partinfo', '-server', $server);
+   push(@args, '-partition', $part) if ($part);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-verbose')          if ($AFS_Parms{'vostrace'} > 2);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('vos', \@args,
+ 	   [$vos_err_parse,
+ 	    [ '^Free space on partition /vicep(.+)\: (\d+) K blocks out of total (\d+)',
+ 	     sub {
+ 	       $parts{$_[0]} = [ $_[1], $_[2] ];
+ 	     }],
+ 	    ($AFS_Parms{'vostrace'} > 2) ? ([ '', '?']) : () ]);
+   %parts;
+ }
+ 
+ 
+ #: AFS_vos_listvol($server, [$part], [$cell])
+ #: Get a list of volumes on the server $server.
+ #: If specified, list only volumes on the partition $part.
+ #: If specified, work in $cell instead of the default cell.
+ #: On success, return an associative array whose keys are names of volumes
+ #: on the specified server, and each of whose values is an associative
+ #: array describing the corresponding volume, containing some or all of
+ #: these elements:
+ #: - name         Name of this volume (same as key)
+ #: - id           ID of this volume
+ #: - kind         Kind of volume (RW, RO, or BK)
+ #: - inuse        Disk space in use
+ #: - maxquota     Maximum disk usage quota
+ #: - minquota     Minimum disk usage quota (optional)
+ #: - stamp_create Time when volume was originally created
+ #: - stamp_update Time volume was last modified
+ #: - stamp_backup Time backup volume was cloned, or 'Never'
+ #: - stamp_copy   Time this copy of volume was made
+ #: - backup_flag  State of automatic backups: empty or 'disabled'
+ #: - dayuse       Number of accesses in the past day
+ #: - serv         Server where this volume is located
+ #: - part         Partition where this volume is located
+ #:
+ $AFS_Help{vos_listvol} = '$server, [$part], [$cell] => %vols';
+ sub AFS_vos_listvol {
+   my($server, $part, $cell) = @_;
+   my(%finres, %vlist);
+ 
+   @args = ('listvol', '-server', $server, '-long');
+   push(@args, '-partition', $part) if ($part);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-verbose')          if ($AFS_Parms{'vostrace'} > 2);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   %finres = &wrapper('vos', \@args,
+ 		     [$vos_err_parse,
+ 		      ['^\S+\s*\d+\s*(RW|RO|BK)', sub {
+ 			my(%vinfo) = %OpenAFS::wrapper::result;
+ 
+ 			if ($vinfo{name}) {
+ 			  $vlist{$vinfo{name}} = \%vinfo;
+ 			  %OpenAFS::wrapper::result = ();
+ 			}
+ 		      }],
+ 		      ['^(\S+)\s*(\d+)\s*(RW|RO|BK)\s*(\d+)\s*K',          'name', 'id', 'kind', 'inuse'],
+ 		      ['(\S+)\s*\/vicep(\S+)\:',                           'serv', 'part' ],
+ 		      ['MaxQuota\s*(\d+)\s*K',                             'maxquota'     ],
+ 		      ['MinQuota\s*(\d+)\s*K',                             'minquota'     ],
+ 		      ['Creation\s*(.*\S+)',                               'stamp_create' ],
+ 		      ['Last Update\s*(.*\S+)',                            'stamp_update' ],
+ 		      ['Backup\s+([^\d\s].*\S+)',                          'stamp_backup' ],
+ 		      ['Copy\s*(.*\S+)',                                   'stamp_copy'   ],
+ 		      ['Automatic backups are (disabled) for this volume', 'backup_flag'  ],
+ 		      ['(\d+) accesses in the past day',                   'dayuse'       ],
+ 		      ($AFS_Parms{'vostrace'} > 2) ? ([ '', '?']) : () ]);
+ 
+   if ($finres{name}) {
+     $vlist{$finres{name}} = \%finres;
+   }
+   %vlist;
+ }
+ 
+ #: AFS_vos_zap($vol, $server, $part, [$cell], [$force])
+ #: Remove the volume $vol from the server and partition specified by $server and
+ #: $part.  Don't bother messing with the VLDB.
+ #: If specified, work in $cell instead of the default cell.
+ #: If $force is specified, force the zap to happen
+ #: On success, return 1.
+ #:
+ $AFS_Help{vos_zap} = '$vol, $server, $part, [$cell], [$force] => Success?';
+ sub AFS_vos_zap {
+   my($vol, $server, $part, $cell, $force) = @_;
+   my(@args);
+ 
+   @args = ('zap', '-id', $vol, '-server', $server, '-part', $part);
+   push(@args, '-force')            if ($force);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-verbose')          if ($AFS_Parms{'vostrace'} > 1);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('vos', \@args,
+ 	   [$vos_err_parse,
+ 	    $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ]);
+   1;
+ }
+ 
+ 
+ #: AFS_vos_status($server, [$cell])
+ #: Get information about outstanding transactions on $server
+ #: If specified, work in $cell instead of the default cell
+ #: On success, return a list of transactions, each of which is a reference
+ #: to an associative array containing some or all of these elements:
+ #: - transid      Transaction ID
+ #: - stamp_create Time the transaction was created
+ #: - volid        Volume ID
+ #: - part         Partition letter
+ #: - action       Action or procedure
+ #: - flags        Volume attach flags
+ #: If there are no transactions, the list will be empty.
+ #:
+ $AFS_Help{vos_status} = '$server, [$cell] => @trans';
+ sub AFS_vos_status {
+   my($server, $cell) = @_;
+   my(@trlist);
+ 
+   @args = ('status', '-server', $server);
+   push(@args, '-noauth')           if ($AFS_Parms{'authlvl'} == 0);
+   push(@args, '-localauth')        if ($AFS_Parms{'authlvl'} == 2);
+   push(@args, '-verbose')          if ($AFS_Parms{'vostrace'} > 2);
+   push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+   &wrapper('vos', \@args,
+ 	   [$vos_err_parse,
+ 	    ['^(\-)', sub {
+ 	      my(%trinfo) = %OpenAFS::wrapper::result;
+ 	      
+ 	      if ($trinfo{transid}) {
+ 		push(@trlist, \%trinfo);
+ 		%OpenAFS::wrapper::result = ();
+ 	      }
+ 	    }],
+ 	    ['^transaction\:\s*(\d+)\s*created: (.*\S+)',        'transid', 'stamp_create'],
+ 	    ['^attachFlags:\s*(.*\S+)',                          'flags'],
+ 	    ['^volume:\s*(\d+)\s*partition\: \/vicep(\S+)\s*procedure\:\s*(\S+)',
+ 	     'volid', 'part', 'action'],
+ 	    ($AFS_Parms{'vostrace'} > 2) ? ([ '', '?']) : () ]);
+ 
+   @trlist;
+ }
+ 
+ 1;
Index: openafs/src/tests/OpenAFS/wrapper.pm
diff -c /dev/null openafs/src/tests/OpenAFS/wrapper.pm:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:58 2002
--- openafs/src/tests/OpenAFS/wrapper.pm	Sun Jan 20 04:18:10 2002
***************
*** 0 ****
--- 1,729 ----
+ # CMUCS AFStools
+ # Copyright (c) 1996, 2001 Carnegie Mellon University
+ # All rights reserved.
+ #
+ # See CMU_copyright.ph for use and distribution information
+ 
+ package OpenAFS::wrapper;
+ 
+ =head1 NAME
+ 
+ OpenAFS::wrapper - AFS command wrapper
+ 
+ =head1 SYNOPSIS
+ 
+   use OpenAFS::wrapper;
+   %result = &wrapper($cmd, \@args, \@pspec, \%options);
+ 
+ =head1 DESCRIPTION
+ 
+ This module provides a generic wrapper for calling an external program and
+ parsing its output.  It is primarily intended for use by AFStools for calling
+ AFS commands, but is general enough to be used for running just about any
+ utility program.  The wrapper is implemented by a single function,
+ B<OpenAFS::wrapper::wrapper>, which takes several arguments:
+ 
+ =over 4
+ 
+ =item $cmd
+ 
+ The command to run.  This can be a full path, or it can be a simple command
+ name, in which case B<wrapper()> will find the binary on its internal path.
+ 
+ =item \@args
+ 
+ A reference to the list of arguments to be passed to the command.  Each
+ element of the list is passed as a single argument, as in B<exec()>.
+ 
+ =item \@pspec
+ 
+ A reference to the list describing how to parse the command's output.
+ See below for details.
+ 
+ =item \%options
+ 
+ A reference to a table of command execution and parsing options.
+ 
+ =back
+ 
+ On success, B<wrapper()> returns an associative array of data gathered
+ from the command's output.  The exact contents of this array are
+ caller-defined, and depend on the parsing instructions given.  On failure,
+ an exception will be thrown (using B<die>), describing the reason for the
+ failure.
+ 
+ The I<%options> table may be used to pass any or all of the following
+ options into B<wrapper()>, describing how the command should be executed
+ and its output parsed:
+ 
+ =over 4
+ 
+ =item pass_stderr
+ 
+ If specified and nonzero, the command's stderr will be passed directly
+ to the calling program's, instead of being parsed.  This is useful when
+ we want to process the command's output, but let the user see any
+ diagnostic output or error messages.
+ 
+ =item pass_stdout
+ 
+ If specified and nonzero, the command's stdout will be passed directly
+ to the calling program's, instead of being parsed.  This is useful when
+ the command being run produces diagnostic or error messages on stderr
+ that we want to parse, but provides bulk data on stdout that we don't
+ want to touch (e.g. B<vos dump> when the output file is stdout).
+ 
+ =item path
+ 
+ If specified, the path to be used for the program to execute, instead of
+ deriving it from the command name.  This is useful when we want the
+ command's argv[0] (which is always I<$cmd}) to be different from the
+ path to the program.
+ 
+ =item errors_last
+ 
+ If specified and nonzero, the built-in instructions for catching errors
+ from the command will be added to the end of the instructions in @pspec
+ instead of to the beginning.
+ 
+ =back
+ 
+ =head1 PARSING COMMAND OUTPUT
+ 
+ The I<@pspec> list describes how to parse command output.  Each element
+ of the list acts like an "instruction" describing how to parse the command's
+ output.  As each line of output is received from the program, the parsing
+ instructions are run over that line in order.  This process continues for
+ every line of output until the program terminates, or the process is
+ aborted early by flow-control operators.
+ 
+ Each parsing instruction is a reference to a list, which consists of a
+ regular expression and a list of "actions".  As a line of output is
+ processed, it is compared to each instruction's regexp in turn.  Whenever
+ a match is found, the actions associated with that instruction are taken,
+ in order.  Each instruction's regexp may contain one or more parenthesized
+ subexpressions; generally, each "action" uses up one subexpression, but there
+ are some exceptions.  Due to the current design of B<wrapper()>, each regexp
+ must have at least one subexpression, even if it is not used.
+ 
+ The acceptable actions are listed below, each followed by a number in brackets
+ indicating how many subexpressions are "used" by this action.  It is an error
+ if there are not enough subexpressions left to satisfy an action.  In the
+ following descriptions, I<$action> is the action itself (typically a string or
+ reference), I<$value> is the value of the subexpression that will be used, and
+ I<%result> is the result table that will be returned by B<wrapper> when the
+ command completes.
+ 
+ =over 4
+ 
+ =item string  [1]
+ 
+ Sets $result{$action} to $value.  Note that several specific strings have
+ special meaning, and more may be added in the future.  To ensure compatibility
+ with future versions of B<wrapper>, use only valid Perl identifiers as
+ "string" actions.
+ 
+ =item scalar ref  [1]
+ 
+ Sets $$action to $value.
+ 
+ =item list ref  [*]
+ 
+ Pushes the remaining subexpression values onto @$action.  This action uses
+ all remaining subexpression values.
+ 
+ =item hash ref  [2]
+ 
+ Sets $$action{$value0} to $value1.
+ 
+ =item code ref  [*]
+ 
+ Calls the referenced function, with all remaining subexpression values as
+ its arguments.  Any values returned by the function will be used to refill
+ the (now empty) subexpression value list, and thus may be used as arguments
+ by subsequent actions.  If only a few values are required, use a function
+ like this:
+ 
+   sub usetwo {  # uses two values and preserves the rest
+     my($val1, $val2, @rest) = @_;
+ 
+     print STDOUT "Got $val1, $val2\n";
+     @rest;
+   }
+ 
+ =item '.'  [0]
+ 
+ End processing for this line of output, ignoring any remaining instructions.
+ Remaining actions in this instruction will be processed.
+ 
+ =item '+n'  [0]
+ 
+ Skip the next I<n> instructions.  This, along with the '.' action, can be
+ used to build simple flow-control constructs based on the contents of
+ lines of output.
+ 
+ =item '-x'  [0..1]
+ 
+ Signal an error after this instruction.  Remaining actions in this instruction
+ will be processed, but no further instructions will be processed for this
+ line, and no further lines of output will be processed.  If I<x> is given,
+ it will be used as a regexp to match against the B<previous> line of output,
+ and the first parenthesized subexpression resulting from that match will be
+ used as the error string.  Otherwise, one subexpression from the current
+ line will be used up as the error string.
+ 
+ =item '?'  [1]
+ 
+ Prints $value to STDOUT.
+ 
+ =back
+ 
+ =cut
+ 
+ use OpenAFS::CMU_copyright;
+ use OpenAFS::util qw(:DEFAULT :afs_internal);
+ use Exporter;
+ use Symbol;
+ 
+ $VERSION   = '';
+ $VERSION   = '1.00';
+ @ISA       = qw(Exporter);
+ @EXPORT    = qw(&wrapper);
+ @EXPORT_OK = qw(&wrapper &fast_wrapper);
+ 
+ sub wrapper {
+   my($cmd, $args, $instrs, $options) = @_;
+   my($prevline, $pid, $exception);
+   my(@instrs, $instr, $action, @values, $path);
+   local(%result);
+   my(@werrinstrs) = ([ '^(wrapper\:.*)',       '-' ]);
+   my(@cerrinstrs) = ([ '^(' . $cmd  . '\:.*)', '-' ],
+                      [ '^(' . $path . '\:.*)', '-' ]);
+ 
+   if ($options->{errors_last}) {
+     @instrs = (@werrinstrs, @$instrs, @cerrinstrs);
+   } else {
+     @instrs = (@werrinstrs, @cerrinstrs, @$instrs);
+   }
+ 
+   if ($options->{path}) {
+     $path = $options->{path};
+   } elsif ($cmd =~ /^\//) {
+     $path = $cmd;
+   } else {
+     $path = $AFScmd{$cmd};
+   }
+ 
+   if ($AFS_Trace{wrapper}) {
+     print STDERR "Instructions:\n";
+     foreach $instr (@$instrs) {
+       print STDERR "  /", $instr->[0], "/\n";
+       if ($AFS_Trace{wrapper} > 2) {
+ 	my(@actions) = @$instr;
+ 	shift(@actions);
+ 	print "  => ",
+ 	join(', ', map { ref($_) ? "<" . ref($_) . " reference>"
+ 			   : $_ } @actions),
+ 	  "\n";
+       }
+     }
+   }
+ 
+   ## Start the child
+   if ($options->{pass_stdout}) {
+     open(REALSTDOUT, ">&STDOUT");
+   }
+   $pid = open(AFSCMD, "-|");
+   if (!defined($pid)) {
+     die "wrapper: Fork failed for $cmd: $!\n";
+   }
+ 
+   ## Run the appropriate program
+   if (!$pid) {
+ 
+     if ($AFS_Trace{wrapper} > 1) {
+       print STDERR "Command: $path ", join(' ', @$args), "\n";
+     }
+ 
+     open(STDERR, ">&STDOUT") if (!$options{pass_stderr});
+     if ($options{pass_stdout}) {
+       open(STDOUT, ">&REALSTDOUT");
+       close(REALSTDOUT);
+     }
+ 
+     { exec($path $cmd, @$args); }
+     # Need to be careful here - we might be doing "vos dump" to STDOUT
+     if ($options{pass_stdout}) {
+       print STDERR "wrapper: Exec failed for $cmd: $!\n";
+     } else {
+       print STDOUT "wrapper: Exec failed for $cmd: $!\n";
+     }
+     exit(127);
+   }
+   if ($options{pass_stdout}) {
+     close(REALSTDOUT);
+   }
+ 
+   ## Now, parse the output
+  line:
+   while (<AFSCMD>) {
+     my($skip) = 0;
+ 
+     print STDERR $_ if ($AFS_Trace{wrapper} > 3);
+     chop;
+ 
+   instr:
+     foreach $instr (@instrs) {
+       my($dot, $action, @actions);
+ 
+       if ($skip) {
+ 	$skip--;
+ 	next instr;
+       }
+       $dot = 0;
+       if ($instr->[0]) {
+ 	@values = ($_ =~ $instr->[0]);
+ 	next instr if (!@values);
+       } else {
+ 	@values = ();
+       }
+       
+     act:
+       @actions = @$instr;
+       shift(@actions);
+       foreach $action (@actions) {
+ 	if      (ref($action) eq 'SCALAR') {
+ 	  if (@values) {
+ 	    $$action = shift(@values);
+ 	  } else {
+ 	    last act;
+ 	  }
+ 	} elsif (ref($action) eq 'ARRAY') {
+ 	  push(@$action, @values);
+ 	  @values = ();
+ 	} elsif (ref($action) eq 'HASH') {
+ 	  if (@values > 1) {
+ 	    $$action{$values[0]} = $values[1];
+ 	    shift(@values); shift(@values);
+ 	  } elsif (@values) {
+ 	    $$action{shift @values} = '';
+ 	    last act;
+ 	  } else {
+ 	    last act;
+ 	  }
+ 	} elsif (ref($action) eq 'CODE') {
+ 	  @values = &$action(@values);
+ 	} elsif (ref($action)) {
+ 	  $exception = "Unknown reference to " . ref($action)
+                      . "in parse instructions";
+ 	  last line;
+ 	} else {                  ## Must be a string!
+ 	  if ($action eq '.') {
+ 	    $dot = 1;
+ 	  } elsif ($action =~ /\+(\d+)/) {
+ 	    $skip = $1;
+ 	  } elsif ($action =~ /-(.*)/) {
+ 	    my($pat) = $1;
+ 
+ 	    if ($pat && $prevline) {
+ 	      ($exception) = ($prevline =~ $pat);
+ 	    } elsif (@values) {
+ 	      $exception = shift(@values);
+ 	    } else {
+ 	      $exception = $_;
+ 	    }
+ 	  } elsif ($action eq '?') {
+ 	    print STDOUT (@values ? shift(@values) : $_), "\n";
+ 	  } elsif (@values) {
+ 	    $result{$action} = shift(@values);
+ 	  } else {
+ 	    last act;
+ 	  }
+ 	}
+       }
+       
+       last line if ($exception);
+       last instr if ($dot);
+     }
+     $prevline = $_;
+   }
+   close(AFSCMD);
+   $exception .= "\n" if ($exception && $exception !~ /\n$/);
+   die $exception if ($exception);
+   %result;
+ }
+ 
+ 
+ ## Generate code for a fast wrapper (see example below)
+ sub _fastwrap_gen {
+   my($instrs, $refs) = @_;
+   my($SRC, $N, $N1, $X, $instr, $pattern, @actions, $action);
+ 
+   $N = $X = 0;
+   $N1 = 1;
+ 
+   $SRC = <<'#####';
+ sub {
+   my($FD, $refs) = @_;
+   my($prevline, @values, $skip, $exception);
+ 
+   line: while (<$FD>) {
+ #####
+ 
+   $SRC .= "    print STDERR \$_;\n" if ($AFS_Trace{'wrapper'} > 3);
+   $SRC .= "    chop;\n";
+ 
+   foreach $instr (@$instrs) {
+     ($pattern, @actions) = (@$instr);
+     $SRC .= ($pattern ? <<"#####" : <<"#####");
+ 
+     instr_$N:
+     die \$exception if \$exception;
+     if (\$skip) { \$skip-- } else {
+       \@values = (\$_ =~ /$pattern/);
+       if (\@values) {
+ #####
+ 
+     instr_$N:
+     die \$exception if \$exception;
+     if (\$skip) { \$skip-- } else {
+       \@values = ();
+       if (1) {
+ #####
+ 
+     foreach $action (@actions) {
+       if      (ref($action) eq 'SCALAR') {
+         $refs[++$X] = $action;
+         $SRC .= <<"#####";
+ 
+         if (\@values) { \${\$refs[$X]} = shift (\@values) }
+         else { goto instr_$N1 }
+ #####
+ 
+       } elsif (ref($action) eq 'ARRAY') {
+         $refs[++$X] = $action;
+         $SRC .= <<"#####";
+ 
+         push(\@{\$refs[$X]}, \@values);
+         \@values = ();
+ #####
+ 
+       } elsif (ref($action) eq 'HASH') {
+         $refs[++$X] = $action;
+         $SRC .= <<"#####";
+ 
+         if (\@values > 1) {
+           \$refs[$X]{\$values[0]} = shift(\$values[1]);
+           shift(\@values); shift(\@values);
+         } elsif (\@values) {
+           \$refs[$X]{shift(\@values)} = '';
+           goto instr_$N1;
+         } else {
+           goto instr_$N1;
+         }
+ #####
+ 
+       } elsif (ref($action) eq 'CODE') {
+         $refs[++$X] = $action;
+         $SRC .= "\n        \@values = \$refs[$X]->(\@values);\n";
+ 
+       } elsif (ref($action)) {
+         die "Unknown reference to " . ref($action) . "in parse instructions\n";
+ 
+       } elsif ($action eq '.') {
+         $SRC .= "\n        next line;\n";
+ 
+       } elsif ($action eq '?') {
+         $SRC .= <<"#####";
+ 
+         if (\@values) { print STDOUT shift(\@values), "\\n" }
+         else         { print STDOUT \$_, "\\n" }
+ #####
+ 
+       } elsif ($action =~ /\+(\d+)/) {
+         $SRC .= "\n        \$skip = $1;\n";
+ 
+       } elsif ($action =~ /-(.*)/) {
+         $SRC .= $1 ? <<"#####" : <<"#####";
+ 
+         if (\$prevline)  { (\$exception) = (\$prevline =~ /$1/) }
+         elsif (\@values) { \$exception = shift(\@values) }
+         else            { \$exception = \$_ }
+ #####
+ 
+         if (\@values)    { \$exception = shift(\@values) }
+         else            { \$exception = \$_ }
+ #####
+ 
+       } else {
+         $SRC .= <<"#####";
+ 
+         if (\@values) { \$result{"\Q$action\E"} = shift(\@values) }
+         else { goto instr_$N1 }
+ #####
+       }
+     }
+ 
+     $N++; $N1++;
+     $SRC .= <<'#####';
+       }
+     }
+ #####
+   }
+ 
+   $SRC .= <<'#####';
+   } continue {
+     die $exception if $exception;
+     $prevline = $_;
+   }
+ }
+ #####
+ 
+   $SRC;
+ }
+ 
+ ####################### Example code #######################
+ # sub {
+ #   my($FD, $refs) = @_;
+ #   my($prevline, @values, $skip, $exception);
+ # 
+ #   line: while (<$FD>) {
+ #     print STDERR $_;     ## if ($AFS_Trace{'wrapper'} > 3);
+ #     chop;
+ # 
+ #     ## Following block repeated for each instruction
+ #     instr_N:
+ #     die $exception if $exception;
+ #     if ($skip) { $skip-- } else {
+ #       @values = ($_ =~ /## pattern ##/);    ## () if no pattern
+ #       if (@values) {                        ## 1 if no pattern
+ #         ## For each action, include one of the following blocks:
+ # 
+ #         ## SCALAR ref
+ #         if (@values) { ${$refs[X]} = shift (@values) }
+ #         else { goto instr_N+1 }
+ # 
+ #         ## ARRAY ref
+ #         push(@{$refs[X]}, @values);
+ #         @values = ();
+ # 
+ #         ## HASH ref
+ #         if (@values > 1) {
+ #           $refs[X]{shift(@values)} = shift(@values);
+ #         } elsif (@values) {
+ #           $refs[X]{shift(@values)} = '';
+ #           goto instr_N+1;
+ #         } else {
+ #           goto instr_N+1;
+ #         }
+ # 
+ #         ## CODE ref
+ #         @values = $refs[X]->(@values);
+ # 
+ #         ## string '.'
+ #         next line;
+ # 
+ #         ## string '?'
+ #         if (@values) { print STDOUT shift(@values), "\n" }
+ #         else         { print STDOUT $_, "\n" }
+ # 
+ #         ## string '+DDD'
+ #         $skip = DDD;
+ # 
+ #         ## string '-XXX'
+ #         if ($prevline)  { ($exception) = ($prefline =~ /XXX/) }
+ #         elsif (@values) { $exception = shift(@values) }
+ #         else            { $exception = $_ }
+ #         
+ #         ## string '-'
+ #         if (@values)    { $exception = shift(@values) }
+ #         else            { $exception = $_ }
+ # 
+ #         ## anything else
+ #         if (@values) { $result{XXX} = shift(@values) }
+ #         else { goto instr_N+1 }
+ #       }
+ #     }
+ # 
+ #   } continue {
+ #     die $exception if $exception;
+ #     $prevline = $_;
+ #   }
+ # }
+ ############################################################
+ 
+ 
+ ## The following does exactly the same thing as wrapper(),
+ ## but should be considerably faster.  Instead of interpreting
+ ## parsing instructions, it translates them into perl code,
+ ## which is then compiled into the interpreter.  The chief
+ ## benefit to this approach is that we no longer compile
+ ## one RE per instruction per line of input.
+ 
+ sub fast_wrapper {
+   my($cmd, $args, $instrs, $options) = @_;
+   my(@instrs, $SRC, $CODE, $path, $pid, $refs, $FD, $exception);
+   local(%result);
+   my(@werrinstrs) = ([ '^(wrapper\:.*)',       '-' ]);
+   my(@cerrinstrs) = ([ '^(' . $cmd  . '\:.*)', '-' ],
+                      [ '^(' . $path . '\:.*)', '-' ]);
+ 
+   $FD = gensym;
+   $refs = [];
+   if ($options->{errors_last}) {
+     @instrs = (@werrinstrs, @$instrs, @cerrinstrs);
+   } else {
+     @instrs = (@werrinstrs, @cerrinstrs, @$instrs);
+   }
+   $SRC = _fastwrap_gen(\@instrs, $refs);
+   $CODE = eval $SRC;
+ 
+   if ($options->{path}) {
+     $path = $options->{path};
+   } elsif ($cmd =~ /^\//) {
+     $path = $cmd;
+   } else {
+     $path = $AFScmd{$cmd};
+   }
+ 
+   if ($AFS_Trace{'wrapper'}) {
+     print STDERR "Instructions:\n";
+     foreach $instr (@$instrs) {
+       print STDERR "  /", $instr->[0], "/\n";
+       if ($AFS_Trace{'wrapper'} > 2) {
+ 	my(@actions) = @$instr;
+ 	shift(@actions);
+ 	print "  => ",
+ 	join(', ', map { ref($_) ? "<" . ref($_) . " reference>"
+ 			   : $_ } @actions),
+ 	  "\n";
+       }
+     }
+   }
+ 
+   if ($AFS_Trace{'wrapper'} > 2) { print STDERR "Input parse code:\n$SRC\n" }
+ 
+   ## Start the child
+   if ($options->{pass_stdout}) {
+     open(REALSTDOUT, ">&STDOUT");
+   }
+   $pid = open($FD, "-|");
+   if (!defined($pid)) {
+     die "wrapper: Fork failed for $cmd: $!\n";
+   }
+ 
+   ## Run the appropriate program
+   if (!$pid) {
+     if ($AFS_Trace{'wrapper'} > 1) {
+       print STDERR "Command: $path ", join(' ', @$args), "\n";
+     }
+ 
+     open(STDERR, ">&STDOUT") if (!$options{pass_stderr});
+     if ($options{pass_stdout}) {
+       open(STDOUT, ">&REALSTDOUT");
+       close(REALSTDOUT);
+     }
+ 
+     { exec($path $cmd, @$args) }
+     # Need to be careful here - we might be doing "vos dump" to STDOUT
+     if ($options{pass_stdout}) {
+       print STDERR "wrapper: Exec failed for $cmd: $!\n";
+     } else {
+       print STDOUT "wrapper: Exec failed for $cmd: $!\n";
+     }
+     exit(127);
+   }
+   if ($options{pass_stdout}) {
+     close(REALSTDOUT);
+   }
+ 
+   ## Now, parse the output
+   eval { $CODE->($FD, $refs) };
+   $exception = $@;
+ 
+   close($FD);
+ 
+   $exception .= "\n" if ($exception && $exception !~ /\n$/);
+   die $exception if ($exception);
+   %result;
+ }
+ 
+ 
+ 1;
+ 
+ =head1 EXAMPLES
+ 
+ The following set of instructions is used by B<wrapper> to detect errors
+ issued by the command, or by the child process spawned to invoke the command.
+ I<$cmd> is the name of the command to run, and I<$path> is the path to the
+ binary actually invoked.
+ 
+   [ '^(wrapper\:.*)',       '-' ]
+   [ '^(' . $cmd  . '\:.*)', '-' ]
+   [ '^(' . $path . '\:.*)', '-' ]
+ 
+ The following instruction is added by the B<OpenAFS::vos> module to catch errors
+ generated by B<vos> commands, which often take the form of a generic error
+ message (Error in vos XXX command), with a description of the specific problem
+ on the preceeding line:
+ 
+   [ 'Error in vos (.*) command', '-(.*)' ]
+ 
+ If the AFStools parameter I<vostrace> is nonzero, the following instruction
+ is added to force all lines of output to be copied to STDOUT.  Note that this
+ is different from specifying the I<pass_stdout> option, which would pass the
+ command's STDOUT directly to ours without parsing it.
+ 
+   [ '', '?' ]
+ 
+ B<OpenAFS::vos::AFS_vos_listvldb> uses the following instructions to parse the
+ output of "vos listvldb".  This is a fairly complex example, which illustrates
+ many of the features of B<wrapper>.
+ 
+   1  ['^(VLDB|Total) entries', '.']
+   2  ['^(\S+)', sub {
+        my(%vinfo) = %OpenAFS::wrapper::result;
+        if ($vinfo{name}) {
+          $vinfo{rosites} = [@rosites] if (@rosites);
+          $vlist{$vinfo{name}} = \%vinfo;
+          @rosites = ();
+          %OpenAFS::wrapper::result = ();
+        }
+      }],
+   3  ['^(\S+)',                       'name'   ],
+   4  ['RWrite\:\s*(\d+)',             'rwid'   ],
+   5  ['ROnly\:\s*(\d+)',              'roid'   ],
+   6  ['Backup\:\s*(\d+)',             'bkid'   ],
+   7  ['Volume is currently (LOCKED)', 'locked' ],
+   8  ['server (\S+) partition /vicep(\S+) RW Site',       'rwserv', 'rwpart'],
+   9  ['server (\S+) partition /vicep(\S+) RO Site',       sub {
+        push(@rosites, [$_[0], $_[1]]);
+      }],
+ 
+ Instruction 1 matchees the header and trailer lines printed out by B<vos>, and
+ terminates processing of those lines before instructions 2 and 3 have a chance
+ to match it.  This is a simple example of a conditional - the next two
+ instructions are used only if this one doesn't match.  If we wanted to consider
+ additional instructions even on lines that do match this one, we could place
+ them above this one, or use '+2' instead of '.', which would skip only the next
+ two instructions and allow remaining ones to be processed.
+ 
+ Instruction 2 matches the first line printed for each volume, stores away any
+ information that has been collected about the previous volume, and prepares for
+ the new one.  Besides being a good example of use of a code reference as an
+ action, this instruction also takes advantage of the fact that B<wrapper>'s
+ %result array is a dynamically-scoped variable, and so can be modified by code
+ referenced in parsing instructions.
+ 
+ The remaining instructions are fairly simple.  Instructions 3 through 8 use
+ simple strings to add information about the volume to %result.  Instruction 9
+ is a bit more complicated; it uses a function to add a server/partition pair
+ to the current volume's list of RO sites.
+ 
+ =head1 COPYRIGHT
+ 
+ The CMUCS AFStools, including this module are
+ Copyright (c) 1996, 2001 Carnegie Mellon University.  All rights reserved.
+ For use and redistribution information, see CMUCS/CMU_copyright.pm
+ 
+ =cut
Index: openafs/src/tools/openafs-tools-cmd.README
diff -c /dev/null openafs/src/tools/openafs-tools-cmd.README:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:58 2002
--- openafs/src/tools/openafs-tools-cmd.README	Sun Jan 20 04:05:08 2002
***************
*** 0 ****
--- 1,232 ----
+ ## OpenAFS Tools Documentation ##
+ ## A collection of open source programs and interfaces designed ##
+ ## to ease the configuration and maintenance of OpenAFS. ##
+ ##
+ ## Copyright 2001, 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
+ ##
+ ## openafs-tools, Version 1.2.2 ##
+ 
+ ####################### TABLE OF CONTENTS ###########################
+ 
+ 1) Overview
+ 2) System configuration requirements
+  a) OS
+  b) OpenAFS
+  c) OpenAFS Tools
+ 3) Usage
+  a) OpenAFS Installation
+  b) OpenAFS Uninstallation 
+ 4) Implementation
+  a) OpenAFS Installation
+  b) OpenAFS Uninstallation
+ 5) Known Problems
+ 6) Future Expansion
+ 
+ ######################## 1) OVERVIEW ################################
+ 
+     The Tools use shell and Perl scripts.  So far, they has been tested 
+ only on Red Hat Linux 6.2 and 7.1 machines, running kernels 2.2 or 2.4. 
+     As of this version, OpenAFS Tools has two functions: 
+ installing OpenAFS, and uninstalling OpenAFS.  
+     We hope that you enjoy using and developing these tools, and
+ that they enhance the popularity and use of OpenAFS.  If you have
+ any questions, comments or suggestions, please send them to the
+ OpenAFS mailing lists.  
+ 
+ ############# 2) SYSTEM CONFIGURATION REQUIREMENTS ##################
+ 
+ a) OS
+     OpenAFS Tools has been developed and tested on machines running 
+ Red Hat Linux 6.2 and 7.1, with kernel version 2.2 or 2.4.  It may 
+ or may not run well on other versions of Linux or other kernel 
+ versions -- use caution when using them with other setups.  
+ 
+ b) OpenAFS
+     Finally, you need to download and install the OpenAFS 1.2.2 RPMs 
+ for Red Hat Linux from http://www.openafs.org.  The files you need 
+ are:
+     Red Hat 6.2:
+       openafs-kernel-1.2.2-rh6.2.1.i386.rpm
+       openafs-1.2.2-rh6.2.1.i386.rpm 
+       openafs-client-1.2.2-rh6.2.1.i386.rpm 
+       openafs-server-1.2.2-rh6.2.1.i386.rpm
+     Red Hat 7.1:
+       openafs-kernel-1.2.2-rh7.1.1.i386.rpm
+       openafs-1.2.2-rh7.11..i386.rpm 
+       openafs-client-1.2.2-rh7.1.1.i386.rpm 
+       openafs-server-1.2.2-rh7.1.1.i386.rpm
+ Once these are downloaded, install them (using an rpm -i or rpm -U
+ command).
+ 
+ c) OpenAFS Tools
+     Now all that's left to do is install the OpenAFS Tools rpm.  The
+ file you need is openafs-tools-1.1.1-1.i386.rpm.  Install it using 
+ an rpm -i or rpm -U command.  This will create several directories
+ and populate your system with necessary files.  The main directories
+ created and populated is:
+     /usr/afs/tools/install/
+ Now you should be ready to get started.
+ 
+ ########################## 3) USAGE #################################
+ 
+ a) OpenAFS Installation
+ 
+     Execute the /usr/afs/tools/install/install_afs command.
+ It can take a variety of arguments to specify how you would like
+ to set the machine up.  If you do not specify needed arguments
+ on the command line, you will be prompted for them interactively.
+ To get a rundown on how to use install_afs, execute:
+   /usr/afs/tools/install/install_afs help
+ Once configured correctly, this machine will run the installation 
+ program (the same one run by the web interface), and restart your
+ computer.
+ 
+ b) OpenAFS Uninstallation 
+ 
+     The uninstallation program is very simple.  Just run
+   /usr/afs/tools/install/afs_uninstall
+ It does not accept any arguments and will not prompt you for
+ anything.  Be forewarned, however: this will uninstall OpenAFS from
+ your system and delete any information served from that machine in
+ OpenAFS filespace.  You should also restart your machine after
+ running the command, to avoid potential problems with future OpenAFS
+ installations.
+ 
+ ##################### 4) IMPLEMENTATION #############################
+ 
+     This section will focus on the details of the implementation of
+ OpenAFS tools.  It will outline the code and file structure of the
+ package, and will document the choices made during implementation, so
+ that someone working on the code can have a better understanding for
+ what's there already.
+ 
+ a) OpenAFS Installation
+ 
+     The files involved in OpenAFS installation are:
+ 
+   - Possible AFS configuration files (/etc/sysconfig/afs):
+     /usr/afs/tools/install/afsinit_both
+     /usr/afs/tools/install/afsinit_server
+     /usr/afs/tools/install/afsinit_client
+   - Checking the state of OpenAFS on the system:
+     /usr/afs/tools/install/.afs_state
+   - Command line installation:
+     /usr/afs/tools/install/install_afs
+   - Perl scripts:
+     /usr/afs/tools/install/check_udebug.pl
+     /usr/afs/tools/install/write_fstab.pl
+     /usr/afs/tools/install/write_pam.pl
+ 
+ What follows is a brief summary of the installation process.
+   - Installation starts with the script install_afs.  The first thing
+ it does is ensure that the files needed for setting up additional 
+ servers and/or clients exist in the appropriate places (see section 
+ 3.a.i for a description of these files).  Then, after indicating to 
+ the state file that installation has begun, it begins installing 
+ OpenAFS.
+   - For clients, it then enables Pam Login Authentication using
+ the write_pam.pl program to change the /etc/pam.d/login file.
+   - For servers, it will alter the /etc/fstab file via the 
+ write_fstab.pl program, mounting the user-specified hard drive to
+ the /vicepa directory.
+   - For additional servers, it now copies the required
+ files from the /usr/afs/tools/install/afs directory to the
+ /usr/afs/etc directory, and defines the upclient processes,
+ which will periodically update the server's /usr/afs/bin and
+ /usr/afs/etc directories based on those directories on the first
+ server in the cell.
+   - A first server must then briefly start up a bosserver with
+ the noauth flag in order to create the keyfile and set the cell 
+ name.  It immediately shuts down the bosserver when this is down.
+ Next, it uses a kaserver with noauth to initialize cell security.
+ This involves creating two user accounts: afs and admin.  afs is an
+ account for the server processes and will not be needed by the user.
+ Currently we use the administrative password for the afs account
+ password.  The admin account is now added to the bos server database
+ and a pts entry is created as well.  Also, the afs account password
+ is added as a key for the server. The kaserver proces is terminated.  
+ The pts database is then bootstrapped to add the administrator to it.  
+   - For first servers, a normal bosserver is started.  It then 
+ creates the database server processes (kaserver, buserver, ptserver, 
+ and vlserver).  
+   - The file server, volume server, and salvager processes are now 
+ started for servers.  
+   - Next the root.afs volume is created for first servers, and on
+ additional servers the vldb is synced up.
+   - On a first server, the upserver process is then defined.
+   - Next the /usr/vice/etc/ThisCell file is created on a non-server
+ machine, and for non-first-servers the /usr/vice/etc/CellServDB file
+ is copied from its location at /usr/afs/tools/install/vice.
+   - The correct AFS setup file is copied to /etc/sysconfig/.
+   - Now the bosserver process is killed for server machines.  
+   - The next thing it does is initialize afs (/etc/rc.d/init.d/afs), 
+ and for servers it klogs in as admin.
+   - Then it activates the OpenAFS initialization script by running
+ /sbin/chkconfig --add afs.  
+   - Next a first server will configure the OpenAFS file space. 
+ Before doing this, however, it must first wait until a quorum has 
+ been elected.  After the check, the root.cell volume is created, 
+ it is mounted at /afs/<cell_name>, and the permissions are set 
+ on both it and /afs as read and lookup for any user.  A read-write 
+ version of root.cell is mounted at /afs/.<cell_name>.  Replication 
+ sites for both root.afs and root.cell are added.
+   - If necessary, client functionality is removed.
+   - Lastly, a done.txt file is written explaining what has been done
+ and what comes next, for use by the web interface.  The state file
+ is notified that installation is complete, and then the script ends.
+ 
+ b) OpenAFS Uninstallation
+ 
+     Uninstallation has only two files: the main script and the 
+ redirection script.
+   /usr/afs/tools/install/afs_uninstall
+ Here is a brief summary of what it does to uninstall OpenAFS:
+   - First it indicates to the state file that uninstallation has 
+ begun.
+   - Then it kills whatever bos server processes may be running.  
+   - Next, it deletes everything stored in an AFS partition directory
+ ( i.e. vicep*).
+   - It deletes the links to any initialization scripts in the startup 
+ directories (/etc/rc.d/rc*.d/*afs*)
+   - It removes the PAM afs file, and reconfigures the PAM login file
+ to not have integrated AFS logon.  
+   - It deletes the db, etc, local, and logs directories from
+ /usr/afs.
+   - Next it removes unnecessary files from /usr/vice/etc. 
+   - Then it deletes everything from the cache (/usr/vice/cache).
+   - Finally, it informs the state file that uninstallation is 
+ complete.
+ 
+ ##################### 5) KNOWN PROBLEMS #############################
+ 
+     We have encountered a few problems along the way, and wanted to 
+ document them as such.
+   - Be careful when installing something without client 
+ functionality.  This seems to require an extra reboot of the 
+ machine.  After installing OpenAFS, restart your machine again,
+ and that should get it working properly.
+     There very well be some other problems that we haven't 
+ yet encountered.  If you encounted such a problem, please send a
+ description to openafs-devel@openafs.org
+ 
+ #################### 6) FUTURE EXPANSION ############################
+ 
+     There is a lot of room for developing this package into something
+ very useful, and we would like to make a few suggestions for future
+ additions/fixes to the code.
+   - Allow ways to authenticate other than the kaserver, such as krb5.
+   - Find a secure, automatic way to transfer files from a server 
+ machine to a machine that is to be set up as an additional server or 
+ a client, rather then require the manual tranferral of those files. 
+   - Agree on a standard way to set up the filespace of a cell, as in
+ where to put the user volumes, etc., so that this can all be done
+ automatically by the scripts.
+   - Port this code to other operating systems to make it more
+ widely useful.
+   - Resolve all "Known Problems" (see section 5).
+   - Test, test, test.
Index: openafs/src/tools/install/RPM.README
diff -c /dev/null openafs/src/tools/install/RPM.README:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:58 2002
--- openafs/src/tools/install/RPM.README	Sun Jan 20 04:05:09 2002
***************
*** 0 ****
--- 1,33 ----
+ ## RPM creation documentation ##
+ ## Steps to creating an openafs-tools-cmd binary distribution RPM ##
+ ##
+ ## Copyright 2001, 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
+ ##
+ ## openafs-tools, Version 1.2.2 ##
+ 
+ Follow these steps to create a binary distribution RPM for the 
+ openafs-tools-cmd package no Red Hat Linux:
+ 
+ 1) Copy the spec file to your SPECS directory.
+ 
+   cp openafs-tools-cmd-1.2.2-1.spec /usr/src/redhat/SPECS/
+ 
+ 2) Create the source package by running:
+ 
+   ./make_rpm_source
+ 
+   This creates the source tar and moves it to the 
+ /usr/src/redhat/SOURCES directory
+ 
+ 3) Now you can create the RPM:
+ 
+   cd /usr/src/redhat/SPECS
+   rpm -ba --clean openafs-tools-cmd-1.2.2-1.i386.rpm
+ 
+   The RPM is now ready for use in the 
+ /usr/src/redhat/RPMS directory.
Index: openafs/src/tools/install/afs_uninstall
diff -c /dev/null openafs/src/tools/install/afs_uninstall:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:58 2002
--- openafs/src/tools/install/afs_uninstall	Sun Jan 20 04:05:09 2002
***************
*** 0 ****
--- 1,37 ----
+ #!/bin/sh
+ # OpenAFS uninstallation script for Linux
+ # openafs-tools, Version 1.2.2
+ #
+ # Copyright 2001, 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
+ #
+ # the directory with the openafs-tools files:
+ afscodeFileDir=/usr/afs/tools/install/
+ #
+ echo "Uninstall" > $afscodeFileDir/.afs_state
+ echo "begin" >> $afscodeFileDir/.afs_state
+ bosserver_process=$(ps -Ao pid,cmd | grep boss)
+ kill ${bosserver_process%% /*}
+ rm -rf /vicep*/*
+ rm -rf /etc/rc.d/rc*.d/*afs*
+ perl $afscodeFileDir/write_pam.pl disable
+ rm -f /lib/security/pam_afs.so
+ rm -rf /usr/afs/db
+ rm -rf /usr/afs/etc
+ rm -rf /usr/afs/local
+ rm -rf /usr/afs/logs
+ rm -f /usr/vice/etc/CellServDB
+ rm -f /usr/vice/etc/ThisCell
+ rm -f /usr/vice/etc/AFSLog
+ rm -rf /usr/vice/cache
+ mkdir /usr/vice/cache
+ echo "Uninstall" > $afscodeFileDir/.afs_state
+ echo "complete" >> $afscodeFileDir/.afs_state
+ 
+ 
+ 
+ 
Index: openafs/src/tools/install/afsinit_both
diff -c /dev/null openafs/src/tools/install/afsinit_both:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:58 2002
--- openafs/src/tools/install/afsinit_both	Sun Jan 20 04:05:09 2002
***************
*** 0 ****
--- 1,37 ----
+ #! /bin/sh
+ # 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
+ 
+ # Configuration information for AFS client
+ 
+ # AFS_CLIENT and AFS_SERVER determine if we should start the client and or
+ # the bosserver. Possible values are on and off.
+ AFS_CLIENT=on
+ AFS_SERVER=on
+ 
+ # AFS client configuration options:
+ LARGE="-stat 2800 -dcache 2400 -daemons 5 -volumes 128"
+ MEDIUM="-stat 2000 -dcache 800 -daemons 3 -volumes 70"
+ SMALL="-stat 300 -dcache 100 -daemons 2 -volumes 50"
+ OPTIONS=$MEDIUM
+ 
+ # Set to "-verbose" for a lot of debugging information from afsd. Only
+ # useful for debugging as it prints _a lot_ of information.
+ VERBOSE=
+ 
+ # AFSD_OPTIONS are the options passed to afsd.
+ AFSD_OPTIONS="$OPTIONS $VERBOSE"
+ 
+ 
+ # Sample server preferences function. Set server preferences using this.
+ # afs_serverprefs() {
+ #    /usr/afsws/etc/fs setserverprefs <host> <rank>
+ #}
+ 
+ # Either the name of an executable script or a set of commands go here.
+ # AFS_POST_INIT=afs_serverprefs
+ AFS_POST_INIT=
Index: openafs/src/tools/install/afsinit_client
diff -c /dev/null openafs/src/tools/install/afsinit_client:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:58 2002
--- openafs/src/tools/install/afsinit_client	Sun Jan 20 04:05:09 2002
***************
*** 0 ****
--- 1,37 ----
+ #! /bin/sh
+ # 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
+ 
+ # Configuration information for AFS client
+ 
+ # AFS_CLIENT and AFS_SERVER determine if we should start the client and or
+ # the bosserver. Possible values are on and off.
+ AFS_CLIENT=on
+ AFS_SERVER=off
+ 
+ # AFS client configuration options:
+ LARGE="-stat 2800 -dcache 2400 -daemons 5 -volumes 128"
+ MEDIUM="-stat 2000 -dcache 800 -daemons 3 -volumes 70"
+ SMALL="-stat 300 -dcache 100 -daemons 2 -volumes 50"
+ OPTIONS=$MEDIUM
+ 
+ # Set to "-verbose" for a lot of debugging information from afsd. Only
+ # useful for debugging as it prints _a lot_ of information.
+ VERBOSE=
+ 
+ # AFSD_OPTIONS are the options passed to afsd.
+ AFSD_OPTIONS="$OPTIONS $VERBOSE"
+ 
+ 
+ # Sample server preferences function. Set server preferences using this.
+ # afs_serverprefs() {
+ #    /usr/afsws/etc/fs setserverprefs <host> <rank>
+ #}
+ 
+ # Either the name of an executable script or a set of commands go here.
+ # AFS_POST_INIT=afs_serverprefs
+ AFS_POST_INIT=
Index: openafs/src/tools/install/afsinit_server
diff -c /dev/null openafs/src/tools/install/afsinit_server:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:58 2002
--- openafs/src/tools/install/afsinit_server	Sun Jan 20 04:05:09 2002
***************
*** 0 ****
--- 1,37 ----
+ #! /bin/sh
+ # 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
+ 
+ # Configuration information for AFS client
+ 
+ # AFS_CLIENT and AFS_SERVER determine if we should start the client and or
+ # the bosserver. Possible values are on and off.
+ AFS_CLIENT=off
+ AFS_SERVER=on
+ 
+ # AFS client configuration options:
+ LARGE="-stat 2800 -dcache 2400 -daemons 5 -volumes 128"
+ MEDIUM="-stat 2000 -dcache 800 -daemons 3 -volumes 70"
+ SMALL="-stat 300 -dcache 100 -daemons 2 -volumes 50"
+ OPTIONS=$MEDIUM
+ 
+ # Set to "-verbose" for a lot of debugging information from afsd. Only
+ # useful for debugging as it prints _a lot_ of information.
+ VERBOSE=
+ 
+ # AFSD_OPTIONS are the options passed to afsd.
+ AFSD_OPTIONS="$OPTIONS $VERBOSE"
+ 
+ 
+ # Sample server preferences function. Set server preferences using this.
+ # afs_serverprefs() {
+ #    /usr/afsws/etc/fs setserverprefs <host> <rank>
+ #}
+ 
+ # Either the name of an executable script or a set of commands go here.
+ # AFS_POST_INIT=afs_serverprefs
+ AFS_POST_INIT=
Index: openafs/src/tools/install/check_udebug.pl
diff -c /dev/null openafs/src/tools/install/check_udebug.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:58 2002
--- openafs/src/tools/install/check_udebug.pl	Sun Jan 20 04:05:09 2002
***************
*** 0 ****
--- 1,64 ----
+ #!/usr/bin/perl
+ #
+ # A perl script that checks to ensure the udebug output for a vlserver
+ # claims that a quorum has been elected.
+ #
+ # openafs-tools, Version 1.2.2
+ 
+ # Copyright 2002, 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
+ #
+ 
+ $serverName = $ARGV[0];
+ 
+ $afscodeFileDir = "/usr/afs/tools/install/";
+ $udebugOutput = $afscodeFileDir . "udebug.out.$$";
+ 
+ $foundQuorum = 0;
+ $recovery = 0;
+ 
+ while( !($foundQuorum and $recovery) ) {
+ 
+     system( "/usr/afs/bin/udebug $serverName vlserver &> $udebugOutput" ) == 0
+ 	or (system( "rm -f $udebugOutput" ) == 0 
+ 	    and die "check_udebug: the call to udebug (for server $serverName) failed or was killed\n");
+ 
+     open( UDEBUG, "<$udebugOutput");
+     @udebug = <UDEBUG>;
+     close(UDEBUG);
+ 
+     $newServerName = $serverName;
+ 
+     foreach $line (@udebug) {
+ 
+ 	# check the udebug output.  if this is the sync site, we've 
+ 	# found our quorum.  otherwise, if a last yes has been cast
+ 	# we'll check if that site is the sync site.  otherwise, if
+ 	# the last yes vote has not been cast, we'll keep on 
+ 	# checking this site until it is.
+ 	if( $line =~ m/^I am sync site(.*)/ ) {
+ 	    $foundQuorum = 1;
+ 	} elsif( $line =~ m/^Last yes vote for ([^\s]*) .*/ ) {
+ 	    $newServerName = $1;
+         } elsif( $line =~ m/^Recovery state (.*)\n$/ ) {
+ 	    if( $1 != 0 ) {
+ 		$recovery = 1;
+ 	    }
+ 	}
+ 	
+     }
+ 
+     # if this isn't the sync site, try somewhere else.
+     if( !$foundQuorum ) {
+ 	$serverName = $newServerName;
+     }
+ 
+ }
+ 
+ system( "rm -f $udebugOutput" );
+ 
+ #return once we've found the sync site.
Index: openafs/src/tools/install/install_afs
diff -c /dev/null openafs/src/tools/install/install_afs:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:58 2002
--- openafs/src/tools/install/install_afs	Sun Jan 20 04:05:09 2002
***************
*** 0 ****
--- 1,686 ----
+ #!/bin/sh
+ #
+ # A command line interface to execute the installation of OpenAFS.
+ #
+ # openafs-tools, Version 1.2.2
+ 
+ # Copyright 2001, 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
+ #
+ 
+ afscodeDir=/usr/afs/tools/install/
+ 
+ firstServer=1
+ addServer=2
+ notServer=3
+ 
+ isClient=1
+ notClient=2
+ 
+ if [ $# -gt 0 ]; then 
+ if [ $1 = "help" ]; then 
+ 
+   echo -e "OpenAFS Installation for Linux: Help Mode\n"
+   echo -e "The command install_afs takes the following optional arguments.  If any\nneeded information is not provided on the command line, it will be\nprompted for the user to input.\n"
+   echo -e "\t-machineName (or -m) name: where name specifies\n\t  the name of the machine the command is being run on"
+   echo -e "\t-cellName (or -c) cell: where cell specifies the\n\t  name of the home cell of this machine"
+   echo -e "\t-shortCell (or -s) scell: where scell is the shortcut\n\t   name desired for the home cell.  Ignored if this\n\t   is not the first server"
+   echo -e "\t-hardDrive (or -h) hd: where hd is the device name on\n\t   which to mount the first AFS partition.  Ignored if this\n\t   is not a server"
+   echo -e "\t-serverType (or -st) type: where type can be \"first\",\n\t   \"additional\", or \"not\", specifying whether this is\n\t   to be the first server in a cell, an additional server\n\t   for the cell, or not a server at all"
+   echo -e "\t-clientType (or -ct) type: where type can be \"client\"\n\t   or \"not\", specifying whether this machine is to be an\n\t   AFS client or not"
+   echo -e "\t-adminPassword (or -p) password: the administrative\n\t    password of the cell.  Ignored if this is not a server"
+   echo -e "\t-existingServer (or -e) name: the name of an\n\t   existing server already in the cell.  Ignored if\n\t   this is not an additional server"
+   echo -e "\t-scriptDirectory (or -d) name: the name of the\n\t   directory containing these OpenAFS installation\n\t   scripts"
+   echo -e "\t-noConf (or -n): Do not ask for confirmation before\n\t    performing the installation."
+   echo -e "\thelp: Display this help dialogue"
+   echo
+   exit 0
+ 
+ fi fi
+ 
+ # Check the state file to ensure AFS is not installed already
+ if [ -r $afscodeDir/.afs_state ]; then
+   read state < $afscodeDir/.afs_state
+   if [ $state = "Install" ]; then
+     echo -e "You have already run the OpenAFS installation program.  You must uninstall OpenAFS before you install it again."
+     exit 0
+   fi
+ fi
+ 
+ while [ $# -gt 0 ]; do
+ 
+   flag=$1
+   if [ $# -ne 0 ]; then 
+     shift
+   fi
+   if [ $flag != "-noConf" -a $flag != "-n" ]; then
+     val=$1
+     if [ $# -ne 0 ]; then 
+       shift
+     fi
+   else 
+     val=1
+   fi
+ 
+   # if the value is empty
+   if [ -z $val ]; then
+     echo -e No value given to $flag flag.  Use \"install_afs help\" for syntax.
+     exit 0
+   fi
+   # if the value is a flag
+   if [ -z ${val##-*} ]; then
+     echo -e No value given to $flag flag.  Use \"install_afs help\" for syntax.
+     exit 0
+   fi
+ 
+   if [ $flag = "-machineName" -o $flag = "-m" ]; then
+      machineName=$val
+   else
+   if [ $flag = "-cellName" -o $flag = "-c" ]; then
+      cellName=$val
+   else
+   if [ $flag = "-shortCell" -o $flag = "-s" ]; then
+      shortCell=$val
+   else
+   if [ $flag = "-hardDrive" -o $flag = "-h" ]; then
+      hardDrive=$val
+   else
+   if [ $flag = "-scriptDirectory" -o $flag = "-d" ]; then
+      scriptDir=$val
+   else
+   if [ $flag = "-serverType" -o $flag = "-st" ]; then
+      server=$val
+      if [ $val = "first" ]; then
+        serverType=$firstServer
+      else if [ $val = "additional" ]; then
+        serverType=$addServer
+      else if [ $val = "not" ]; then
+        serverType=$notServer
+      else 
+        echo -e Invalid value for -serverType flag.  Use \"install_afs help\" for syntax.
+        exit 0;
+      fi fi fi
+       
+   else
+   if [ $flag = "-clientType" -o $flag = "-ct" ]; then
+      client=$val
+      if [ $val = "client" ]; then
+        clientType=$isClient
+      else if [ $val = "not" ]; then
+        clientType=$notClient
+      else 
+        echo -e Invalid value for $flag flag.  Use \"install_afs help\" for syntax.
+        exit 0;
+      fi fi
+       
+   else
+   if [ $flag = "-adminPassword" -o $flag = "-p" ]; then
+      adminPassword=$val
+   else 
+   if [ $flag = "-existingServer" -o $flag = "-e" ]; then
+      existingServer=$val
+   else
+   if [ $flag = "-noConf"  -o $flag = "-n" ]; then
+      noConf=$val
+   else
+     echo Invalid flag $flag.  Use \"install_afs help\" for syntax.
+     exit 0;
+   fi fi fi fi fi fi fi fi fi fi
+ done
+ 
+ # Collect variables not given:
+ 
+ echo
+ while [ -z $server ]; do
+   echo -ne "Provide the server type for this machine (\"first\", \"additional\", or \"not\"),\n   or hit enter to accept the default (\"first\"): "
+   read server
+ 
+   if [ -z $server ]; then
+     server="first"
+   fi
+ 
+   if [ $server = "first" ]; then
+     serverType=$firstServer
+   else if [ $server = "additional" ]; then
+     serverType=$addServer
+   else if [ $server = "not" ]; then
+     serverType=$notServer
+   else 
+     echo -e Invalid value for server type.  Please choose \"first\", \"additional\", or \"not\".
+     server=""
+   fi fi fi
+ 
+ done
+ 
+ while [ -z $client ]; do
+   echo -ne "Provide the client type for this machine (\"client\" or \"not\"), or hit enter to\n   accept the default (\"client\"): "
+   read client
+ 
+   if [ -z $client ]; then
+     client="client"
+   fi
+ 
+   if [ $client = "client" ]; then
+     clientType=$isClient
+   else if [ $client = "not" ]; then
+     clientType=$notClient
+   else 
+     echo -e Invalid value for client type.  Please choose \"client\" or \"not\".
+     client=""
+   fi fi
+ 
+ done
+ 
+ if [ $serverType -eq $notServer ]; then
+   if [ $clientType -eq $notClient ]; then
+      echo -e "This machine must be either a server or a client."
+      exit 0
+   fi
+ fi
+ 
+ while [ -z $cellName ]; do
+   echo -ne "Provide the name of the cell (in the form of cellname.domainname):\n   "
+   read cellName
+ done
+ 
+ while [ -z $machineName ]; do
+   read default < /etc/HOSTNAME
+   echo -ne "Provide the name of this machine, or hit enter to accept the\n   default ($default): "
+   read machineName
+ 
+   if [ -z $machineName ]; then
+     machineName=$default
+   fi
+ 
+ done
+ 
+ if [ $serverType -ne $notServer ]; then 
+     
+   while [ -z $hardDrive ]; do
+     echo -ne "Provide the name of the device on which to mount the AFS partition,\n   i.e. hda5: "
+     read hardDrive
+   done
+ 
+ fi
+ 
+ if [ $serverType -eq $firstServer ]; then 
+     
+   while [ -z $shortCell  ]; do
+     default=${cellName%%.*}
+     echo -ne "Provide a shortcut name for your cell, or press Enter to accept the\n   default ($default): "
+     read shortCell
+  
+     if [ -z $shortCell ]; then
+       shortCell=$default
+     fi
+ 
+   done
+ 
+ fi
+ 
+ if [ $serverType -eq $addServer ]; then 
+     
+   while [ -z $existingServer ]; do
+     echo -ne "Provide the name of the first server in this cell:\n   "
+     read existingServer
+   done
+ 
+ fi
+ 
+ while [ -z $scriptDir ]; do
+   default=$afscodeDir
+   echo -ne "Provide the directory of this installation script, or press Enter to accept\n   the default ($default): "
+   read scriptDir
+ 
+   if [ -z $scriptDir ]; then
+     scriptDir=$default
+   fi
+ 
+ done
+ 
+ if [ $serverType -ne $notServer ]; then 
+   while [ -z $adminPassword ]; do
+     echo -ne "Provide the administrative password of this cell: "
+     stty -echo echonl
+     read adminPassword
+     stty echo
+     echo -ne "Please confirm the password: "
+     stty -echo echonl
+     read adminPassword2
+     stty echo
+ 
+     if [ -z $adminPassword ]; then
+       echo -e "You must give a password"
+     else 
+     if [ -z $adminPassword2 ]; then
+       echo -e "You must confirm the password"
+       adminPassword=""
+     else
+     if [ $adminPassword != $adminPassword2 ]; then
+       echo -e "Passwords do not match"
+       adminPassword=""
+     fi fi fi
+   done
+ fi
+ 
+ # Make sure the needed files exist:
+ if [ $serverType -eq $addServer ]; then
+   while [ ! -e $scriptDir/afs/ -o ! -e $scriptDir/afs/ThisCell -o ! -e $scriptDir/afs/CellServDB -o ! -e $scriptDir/afs/KeyFile -o  ! -e $scriptDir/afs/UserList ]; do
+     echo -e "Needed files in $scriptDir/afs do not exist."
+     echo -e "Copy the following files from $existingServer to the specified locations:"
+     echo -e "- $existingServer:/usr/afs/etc/ThisCell to $machineName:$scriptDir/afs/ThisCell"
+     echo -e "- $existingServer:/usr/afs/etc/CellServDB to $machineName:$scriptDir/afs/CellServDB"
+     echo -e "- $existingServer:/usr/afs/etc/KeyFile to $machineName:$scriptDir/afs/KeyFile"
+     echo -e "- $existingServer:/usr/afs/etc/UserList to $machineName:$scriptDir/afs/UserList"
+     echo -e "- $existingServer:/usr/vice/etc/CellServDB to $machineName:$scriptDir/vice/CellServDB"
+     echo -e "Press Enter when ready"
+     read anykey
+   done
+ fi
+ if [ $serverType -ne $firstServer ]; then
+   while [ ! -e $scriptDir/vice/ -o  ! -e $scriptDir/vice/CellServDB ]; do
+     echo "Needed file in $scriptDir/vice does not exist."
+     echo -e "Copy the following file from an existing server to the specified location:"
+     echo -e "- CellServDB from $cellName to $machineName:$scriptDir/vice/CellServDB"
+     echo -e "Press Enter when ready"
+     read anykey
+   done
+ fi
+ echo
+ echo -e "You're about to install OpenAFS with the following configuration:"
+ echo -e "Machine name: $machineName"
+ echo -e "Cell name: $cellName"
+ if [ $serverType -eq $firstServer ]; then
+   echo -e "Shortcut cell name: $shortCell"
+ fi
+ if [ $serverType -ne $notServer ]; then
+   echo -e "Hard drive: $hardDrive"
+   echo -ne "adminPassword: "
+   i=0;
+   while [ $i -lt ${#adminPassword} ]; do
+     echo -ne "*"
+     i=$[i+1]
+   done
+   echo
+ fi
+ echo -e "Server: $server"
+ echo -e "Client: $client"
+ if [ $serverType -eq $addServer ]; then
+   echo -e "Existing server: $existingServer"
+ fi
+ echo -e "Script directory: $scriptDir"
+ echo
+ if [ -z $noConf ]; then
+   echo -ne "Would you like to continue with the installation? "
+   while [ -z $goAhead ]; do
+     echo -ne "(y/n): "
+     read goAhead
+ 
+     if [ -z $goAhead ]; then
+       :
+     else 
+     if [ $goAhead = "n" ]; then
+       echo -e "Aborting installation"
+       exit 0
+     else
+     if [ $goAhead != "y" ]; then
+       goAhead=""
+     fi fi fi
+ 
+   done
+ fi
+ 
+ #Start the installation
+ 
+ # the directory on which the hard drive partition will be mounted:
+ partition=/vicepa
+ #
+ #
+ # the password for the afs account:
+ afsPassword=$adminPassword
+ #
+ # Make sure the needed files exist:
+ if [ $serverType -eq $addServer ]; then
+   if [ ! -e $scriptDir/afs/ ]; then
+     echo "Needed directory $scriptDir/afs does not exist.  Aborting."
+     exit 1
+   fi
+   if [ ! -e $scriptDir/afs/ThisCell ]; then
+     echo "Needed file $scriptDir/afs/ThisCell does not exist.  Aborting."
+     exit 1
+   fi
+   if [ ! -e $scriptDir/afs/CellServDB ]; then
+     echo "Needed file $scriptDir/afs/CellServDB does not exist.  Aborting."
+     exit 1
+   fi
+   if [ ! -e $scriptDir/afs/KeyFile ]; then
+     echo "Needed file $scriptDir/afs/KeyFile does not exist.  Aborting."
+     exit 1
+   fi
+   if [ ! -e $scriptDir/afs/UserList ]; then
+     echo "Needed file $scriptDir/afs/UserList does not exist.  Aborting."
+     exit 1
+   fi
+ fi
+ if [ $serverType -ne $firstServer ]; then
+   if [ ! -e $scriptDir/vice/ ]; then
+     echo "Needed directory $scriptDir/vice does not exist.  Aborting."
+     exit 1
+   fi
+   if [ ! -e $scriptDir/vice/CellServDB ]; then
+     echo "Needed file $scriptDir/vice/CellServDB does not exist.  Aborting."
+     exit 1
+   fi
+ fi
+ # Write to the state file
+ echo "Install" > $scriptDir/.afs_state
+ echo "begin" >> $scriptDir/.afs_state
+ #
+ #
+ #
+ if [ $clientType -eq $isClient ]; then
+   echo Configuring /etc/pam.d/login
+   perl $scriptDir/write_pam.pl enable
+   cd /lib/security 
+   echo ln -s pam_afs.so.1 pam_afs.so
+   ln -s pam_afs.so.1 pam_afs.so
+ fi
+ #
+ # Remove files installed by OpenAFS rpms that are intrusive
+ echo "Removing troublesome files"
+ rm -f /usr/vice/etc/ThisCell
+ rm -f /usr/vice/etc/CellServDB
+ #
+ if [ $serverType -ne $notServer ]; then 
+   mkdir $partition
+   echo Configuring /etc/fstab 
+   perl $scriptDir/write_fstab.pl $hardDrive $partition
+   mount -a
+ #
+ #
+   echo Starting the BOS server
+   mkdir -p /usr/afs/etc
+   if [ $serverType -eq $addServer ]; then
+     # Move the needed file to /usr/afs/etc
+     echo Copying /usr/afs/etc/ files for additional server
+     cp -f $scriptDir/afs/ThisCell /usr/afs/etc/
+     cp -f $scriptDir/afs/CellServDB /usr/afs/etc/
+     cp -f $scriptDir/afs/KeyFile /usr/afs/etc/
+     cp -f $scriptDir/afs/UserList /usr/afs/etc/
+   fi     
+ #
+   if [ $serverType -eq $firstServer ]; then
+ 
+     echo /usr/afs/bin/bosserver -noauth
+     /usr/afs/bin/bosserver -noauth
+     echo bos setcellname $machineName $cellName -noauth
+     bos setcellname $machineName $cellName -noauth
+     echo bos listhosts $machineName -noauth
+     bos listhosts $machineName -noauth
+     echo bos addkey $machineName -key $afsPassword -kvno 0 -cell $cellName -noauth
+     bos addkey $machineName -key $afsPassword -kvno 0 -cell $cellName -noauth
+     
+     echo bos shutdown $machineName -noauth
+     bos shutdown $machineName -noauth
+     bosserver_process=$(ps -Ao pid,cmd | grep boss)
+     echo kill ${bosserver_process%% /*}
+     kill ${bosserver_process%% /*}
+ 
+     /usr/afs/bin/kaserver -noauth &
+  
+     echo Configuring kaserver
+     kas create afs -initial_password $afsPassword -cell $cellName -noauth
+     kas examine -name afs -cell $cellName -noauth
+     kas create admin -initial_password $adminPassword -cell $cellName -noauth
+     kas setfields admin -flags admin -cell $cellName -noauth
+     kas examine -name admin -cell $cellName -noauth
+     
+     kaserver_process=$(ps -Ao pid,cmd | grep kaserver)
+     echo kill ${kaserver_process%% /*}
+     kill ${kaserver_process%% /*}
+ 
+     echo Bootstrapping ptserver
+     echo -e "admin 128/20 1 -204 -204\nsystem:administrators 130/20 -204 -204 -204\n   admin   1\n" | pt_util -p /usr/afs/db/prdb.DB0 -w
+ 
+   fi
+ 
+   /usr/afs/bin/bosserver
+ 
+   if [ $serverType -ne $firstServer ]; then
+     # Define the upclients
+     echo bos create $machineName upclientetc simple "/usr/afs/bin/upclient $existingServer /usr/afs/etc" -cell $cellName -localauth
+     bos create $machineName upclientetc simple "/usr/afs/bin/upclient $existingServer /usr/afs/etc" -cell $cellName -localauth
+     echo bos create $machineName upclientbin simple "/usr/afs/bin/upclient $existingServer -clear /usr/afs/bin" -cell $cellName -localauth
+     bos create $machineName upclientbin simple "/usr/afs/bin/upclient $existingServer -clear /usr/afs/bin" -cell $cellName -localauth
+   fi
+ fi
+ #
+ #
+ if [ $serverType -eq $firstServer ]; then
+ #
+   echo Starting the Database Server Processes
+ #
+   echo bos create -server $machineName -instance kaserver -type simple -cmd /usr/afs/bin/kaserver -cell $cellName -localauth
+   bos create -server $machineName -instance kaserver -type simple -cmd /usr/afs/bin/kaserver -cell $cellName -localauth
+   echo bos create -server $machineName -instance buserver -type simple -cmd /usr/afs/bin/buserver -cell $cellName -localauth
+   bos create -server $machineName -instance buserver -type simple -cmd /usr/afs/bin/buserver -cell $cellName -localauth
+   echo bos create -server $machineName -instance ptserver -type simple -cmd /usr/afs/bin/ptserver -cell $cellName -localauth
+   bos create -server $machineName -instance ptserver -type simple -cmd /usr/afs/bin/ptserver -cell $cellName -localauth
+   echo bos create -server $machineName -instance vlserver -type simple -cmd /usr/afs/bin/vlserver -cell $cellName -localauth
+   bos create -server $machineName -instance vlserver -type simple -cmd /usr/afs/bin/vlserver -cell $cellName -localauth
+ #
+   echo bos adduser $machineName admin -cell $cellName -localauth
+   bos adduser $machineName admin -cell $cellName -localauth
+   echo bos restart $machineName -all -cell $cellName -localauth
+   bos restart $machineName -all -cell $cellName -localauth
+ #
+ fi
+ #
+ if [ $serverType -ne $notServer ]; then
+   echo Starting the File Server, Volume Server, and Salvager
+ #
+   echo bos create $machineName fs fs /usr/afs/bin/fileserver /usr/afs/bin/volserver /usr/afs/bin/salvager -cell $cellName -localauth
+   bos create $machineName fs fs /usr/afs/bin/fileserver /usr/afs/bin/volserver /usr/afs/bin/salvager -cell $cellName -localauth
+ # Verify success of fs:
+   echo bos status $machineName fs -long -localauth
+   bos status $machineName fs -long -localauth
+ #
+   if [ $serverType -eq $firstServer ]; then
+     # Wait for Ubik to elect a quorum
+     echo Waiting for a quorum election . . .
+     perl $scriptDir/check_udebug.pl $machineName
+     echo vos create $machineName $partition root.afs -cell $cellName -localauth 
+     vos create $machineName $partition root.afs -cell $cellName -localauth
+ #
+   else 
+     vos syncvldb $machineName -cell $cellName -verbose -localauth
+     vos syncserv $machineName -cell $cellName -verbose -localauth
+   fi
+ fi
+ #
+ if [ $serverType -eq $firstServer ]; then
+   echo Starting the Server Portion of the Update Server
+ #
+   echo bos create $machineName upserver simple "/usr/afs/bin/upserver -crypt /usr/afs/etc -clear /usr/afs/bin" -cell $cellName -localauth
+   bos create $machineName upserver simple "/usr/afs/bin/upserver -crypt /usr/afs/etc -clear /usr/afs/bin" -cell $cellName -localauth
+ #
+ #
+ fi
+ #
+ # Installing Client Functionality
+ #
+ echo Defining Cell Membership for Client Processes
+ #
+ if [ $serverType -eq $notServer ]; then
+   echo $cellName > /usr/vice/etc/ThisCell
+ fi
+ #
+ echo Creating the Client CellServDB File
+ 
+ cd /usr/vice/etc
+ if [ $serverType -ne $firstServer ]; then
+     # Move the CellServDB file to /usr/vice/etc
+     cp -f $scriptDir/vice/CellServDB /usr/vice/etc
+ fi
+ #
+ # copy correct afs setup file to etc/sysconfig
+ if [ $serverType -eq $notServer ]; then
+   cp -f $scriptDir/afsinit_client /etc/sysconfig/afs
+ else
+   cp -f $scriptDir/afsinit_both /etc/sysconfig/afs
+ fi
+ #
+ # Overview: Completing the Installation of the First AFS Machine
+ #
+ echo Verifying the AFS Initialization Script
+ #
+ if [ $serverType -ne $notServer ]; then
+   echo bos shutdown $machineName -localauth
+   bos shutdown $machineName -localauth
+   bosserver_process=$(ps -Ao pid,cmd | grep boss)
+   echo kill ${bosserver_process%% /*}
+   kill ${bosserver_process%% /*}
+ fi
+ 
+ #
+ echo Continuing with Verifying ths AFS Initialization Script
+ #
+ echo /etc/rc.d/init.d/afs start
+ /etc/rc.d/init.d/afs start
+ if [ $serverType -ne $notServer ]; then
+   # klog in as admin
+   echo klog admin -password 
+   klog admin -password $adminPassword
+   # verify klog worked correctly:
+   echo tokens
+   tokens
+   # verify each process is running normally:
+   echo bos status $machineName
+   bos status $machineName
+   cd /
+   echo fs checkvolumes
+   fs checkvolumes
+ fi
+ #
+ echo Activating the AFS Initialization Script
+ #
+ echo /sbin/chkconfig --add afs
+ /sbin/chkconfig --add afs
+ cd /usr/vice/etc
+ rm afs.rc afs.conf
+ ln -s /etc/rc.d/init.d/afs afs.rc
+ ln -s /etc/sysconfig/afs afs.conf
+ #
+ if [ $serverType -eq $firstServer ]; then
+   echo Configuring the Top Levels of the AFS Filespace
+ #
+   # Wait for Ubik to elect a quorum
+   echo Waiting for a quorum election . . .
+   perl $scriptDir/check_udebug.pl $machineName
+   
+   echo fs setacl /afs system:anyuser rl
+   fs setacl /afs -acl system:anyuser rl
+   echo vos create $machineName $partition root.cell
+   vos create $machineName $partition root.cell
+   echo fs mkmount /afs/$cellName root.cell
+   fs mkmount /afs/$cellName root.cell
+   echo fs setacl /afs/$cellName system:anyuser rl
+   fs setacl /afs/$cellName -acl system:anyuser rl
+   cd /afs
+   ln -s $cellName $shortCell
+   echo fs mkmount /afs/.$cellName root.cell -rw
+   fs mkmount /afs/.$cellName root.cell -rw
+ 
+ # stop the client
+   echo Stopping the client to replicate
+   cd /
+   umount /afs
+   /usr/vice/etc/afsd -shutdown
+   
+   echo vos addsite $machineName $partition root.afs -localauth
+   vos addsite $machineName $partition root.afs -localauth
+   echo vos addsite $machineName $partition root.cell -localauth
+   vos addsite $machineName $partition root.cell -localauth
+   echo vos release root.afs -localauth
+   vos release root.afs -localauth
+   echo vos release root.cell -localauth
+   vos release root.cell -localauth
+ 
+   /etc/rc.d/init.d/afs stop
+   # start the client again
+   echo Starting client again
+   /etc/rc.d/init.d/afs start
+   cd /afs
+ 
+   # klog in as admin
+   echo klog admin -password 
+   klog admin -password $adminPassword
+ 
+   # Wait for Ubik to elect a quorum
+   echo Waiting for a quorum election . . .
+   perl $scriptDir/check_udebug.pl $machineName
+   
+   echo fs examine /afs
+   fs examine /afs
+   echo fs examine /afs/$cellName
+   fs examine /afs/$cellName
+ 
+ #
+ #
+ fi
+ fs checkvolumes
+ #
+ if [ $clientType -ne $isClient ]; then
+ #
+   echo Removing Client Functionality
+ #
+   # Install correct config file  
+   cp -f $scriptDir/afsinit_server /etc/sysconfig/afs
+ #
+   cd /usr/vice/etc
+   ln -fs /usr/afs/etc/ThisCell ThisCell
+   ln -fs /usr/afs/etc/CellServDB CellServDB
+ #
+   /etc/rc.d/init.d/afs stop
+   /etc/rc.d/init.d/afs start
+ #
+ fi
+ # remove the tokens
+ unlog
+ #
+ # Write the done file
+ echo "Here is a summary of what was done:<br><ul>" > $scriptDir/done.txt
+ if [ $serverType -eq $firstServer ]; then 
+   echo "<li>Configured $machineName as the first server to the cell $cellName</li>" >> $scriptDir/done.txt
+   echo "<li>Created the server processes (vlserver, buserver, kaserver, and ptserver)</li>" >> $scriptDir/done.txt
+   echo "<li>Created /vicepa as a server partition</li>" >> $scriptDir/done.txt
+   echo "<li>Created an admin account</li>" >> $scriptDir/done.txt
+   echo "<li>Mounted a read-write version of root.cell at /afs/.$cellName</li>" >> $scriptDir/done.txt
+ fi
+ if [ $serverType -eq $addServer ]; then 
+   echo "<li>Configured $machineName as an additional server to the cell $cellName</li>" >> $scriptDir/done.txt
+   echo "<li>Created the update processes, using $existingServer as the first server</li>" >> $scriptDir/done.txt
+   echo "<li>Created /vicepa as a server partition</li>" >> $scriptDir/done.txt
+ fi
+ if [ $clientType -eq $isClient ]; then 
+   echo "<li>Configured $machineName as a client to the cell $cellName</li>" >> $scriptDir/done.txt
+ fi
+   echo "</ul><br>" >> $scriptDir/done.txt
+ if [ $serverType -eq $firstServer ]; then 
+   echo "<br>Here are some suggestions about how to get started using your cell:<br><ul>" >> $scriptDir/done.txt
+   echo "<li>Read the <a href=\"http://oss.software.ibm.com/developerworks/opensource/afs/docs.html\">OpenAFS documentation</a></li>" >> $scriptDir/done.txt
+   echo "<li>Create users for your cell</li>" >> $scriptDir/done.txt
+   echo "<li>Create volumes</li>" >> $scriptDir/done.txt
+   echo "<li>Configure other machines to be additional servers for this cell</li>" >> $scriptDir/done.txt
+   echo "<li>Make another partition (i.e. /vicepb) on which to store volumes</li>" >> $scriptDir/done.txt
+   echo "<li>Mount other cells in root.afs</li>" >> $scriptDir/done.txt
+   echo "</ul>" >> $scriptDir/done.txt
+ fi
+ # Write the state file
+ echo "Install" > $scriptDir/.afs_state
+ echo "complete" >> $scriptDir/.afs_state
+ #
Index: openafs/src/tools/install/make_rpm_source
diff -c /dev/null openafs/src/tools/install/make_rpm_source:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:58 2002
--- openafs/src/tools/install/make_rpm_source	Sun Jan 20 04:05:09 2002
***************
*** 0 ****
--- 1,47 ----
+ #!/bin/sh
+ #
+ # Copyright 2001, 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
+ #
+ # packup
+ # creates rpm source file containing all the necessary files
+ # for the OpenAFS command line tools.  Moves to RPM source dir.
+ # 
+ # openafs-tools, Version 1.2.2
+ #
+ # Directory containing installation scripts, etc.
+ rootDir=../..
+ mainFileDir=..
+ rpmSource=/usr/src/redhat/SOURCES/
+ #
+ mkdir .tmpTarDir
+ cd .tmpTarDir
+ #
+ cp $rootDir/openafs-tools-cmd.README .
+ cp $mainFileDir/.afs_state afs_state
+ cp $mainFileDir/afsinit_both .
+ cp $mainFileDir/afsinit_client .
+ cp $mainFileDir/afsinit_server .
+ cp $mainFileDir/afs_uninstall .
+ cp $mainFileDir/install_afs .
+ cp $mainFileDir/write_fstab.pl .
+ cp $mainFileDir/write_pam.pl .
+ #
+ cp $mainFileDir/unpack_cmd .
+ #
+ tar -cf afs_linux.tar *
+ gzip -f afs_linux.tar
+ cd ..
+ cp .tmpTarDir/afs_linux.tar.gz .
+ rm -rf .tmpTarDir
+ #
+ tar -cf openafs-tools-cmd.tar afs_linux.tar.gz
+ rm -f afs_linux.tar.gz
+ mv openafs-tools-cmd.tar $rpmSource
+ chown nobody $rpmSource/openafs-tools-cmd.tar
+ #
+ 
Index: openafs/src/tools/install/openafs-tools-cmd-1.2.2-1.spec
diff -c /dev/null openafs/src/tools/install/openafs-tools-cmd-1.2.2-1.spec:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:58 2002
--- openafs/src/tools/install/openafs-tools-cmd-1.2.2-1.spec	Sun Jan 20 04:05:09 2002
***************
*** 0 ****
--- 1,71 ----
+ Summary: A program that can install and uninstall OpenAFS for Linux (command line only).
+ Name: openafs-tools-cmd
+ Version: 1.2.2
+ Release: 1
+ Copyright: IPL
+ Packager: OpenAFS
+ Group: Applications/File
+ Source: openafs-tools-cmd.tar
+ Conflicts: openafs-tools
+ Requires: openafs, openafs-kernel, openafs-client, openafs-server
+ BuildRoot: /var/tmp/%{name}-buildroot
+ 
+ %description
+ This rpm will extract and install the files needed to install and uninstall
+ OpenAFS on a Linux system. 
+ 
+ %prep
+ %setup -c
+ gunzip afs_linux.tar.gz
+ tar -xf afs_linux.tar
+ 
+ %build
+ chmod 744 unpack_cmd
+ 
+ %install
+ rm -rf $RPM_BUILD_ROOT
+ ./unpack_cmd
+ 
+ %post
+ %ifnos Linux
+   echo -e "WARNING: Operating system is not Linux.\n  openafs-tools has only been tested on Red Hat Linux, so proceed with caution."
+ %endif
+ if [ ! -e /usr/src/redhat ]; then
+   echo -e "WARNING: This operating system may not be Red Hat Linux.\nopenafs-tools has only been tested on Red Hat, so proceed with caution."
+ fi
+ %ifos Linux
+   ver=$(uname -r) 
+   verdash=${ver%%-*}
+   vermaj=${verdash%.*}
+   vermin=${verdash##*.}
+   if [ $vermaj != "2.2" -a $vermaj != "2.4" ]; then 
+     echo -e "WARNING: Kernel version is not 2.2 or 2.4.\n openafs-tools-client has only been tested on kernel versions 2.2 and 2.4, so proceed with caution."
+   fi
+ %endif
+ 
+ %preun
+ rm -f /usr/afs/tools/install/*install_output*
+ rm -rf /usr/afs/tools/install/afs
+ rm -rf /usr/afs/tools/install/vice
+ rm -rf /usr/afs/tools/install/done.txt
+ 
+ %clean
+ rm -rf $RPM_BUILD_ROOT
+ 
+ %files
+ %doc openafs-tools-cmd.README
+ /usr/afs/tools/openafs-tools-cmd.README
+ /usr/afs/tools/install/.afs_state
+ /usr/afs/tools/install/afsinit_both
+ /usr/afs/tools/install/afsinit_client
+ /usr/afs/tools/install/afsinit_server
+ /usr/afs/tools/install/afs_uninstall
+ /usr/afs/tools/install/install_afs
+ /usr/afs/tools/install/check_udebug.pl
+ /usr/afs/tools/install/write_fstab.pl
+ /usr/afs/tools/install/write_pam.pl
+ %dir /usr/afs/tools/install/
+ 
+ 
+ 
+ 
Index: openafs/src/tools/install/unpack_cmd
diff -c /dev/null openafs/src/tools/install/unpack_cmd:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:58 2002
--- openafs/src/tools/install/unpack_cmd	Sun Jan 20 04:05:09 2002
***************
*** 0 ****
--- 1,41 ----
+ #!/bin/sh
+ #
+ # unpack
+ # unpacks some of the necessary files for the OpenAFS command line tools.
+ # 
+ # openafs-tools, Version 1.2.2
+ #
+ # Copyright 2001, 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
+ #
+ # Directory to put all installation scripts, etc.
+ buildRoot=/var/tmp/openafs-tools-cmd-buildroot
+ rootDir=$buildRoot/usr/afs/tools
+ mainFileDir=$rootDir/install
+ #
+ mkdir -p $mainFileDir/
+ #
+ cp openafs-tools-cmd.README $rootDir/ 
+ cp -f afs_state $mainFileDir/.afs_state
+ cp -f afsinit_both $mainFileDir/
+ cp -f afsinit_client $mainFileDir/
+ cp -f afsinit_server $mainFileDir/
+ cp -f afs_uninstall $mainFileDir/
+ cp -f install_afs $mainFileDir/
+ cp -f check_udebug.pl $mainFileDir/
+ cp -f write_fstab.pl $mainFileDir/
+ cp -f write_pam.pl $mainFileDir/
+ #
+ chmod 600 $mainFileDir/.afs_state
+ chmod 744 $mainFileDir/afs_uninstall
+ chmod 744 $mainFileDir/install_afs
+ chmod a+w $mainFileDir
+ #
+ 
+ 
+ 
+ 
Index: openafs/src/tools/install/write_fstab.pl
diff -c /dev/null openafs/src/tools/install/write_fstab.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:58 2002
--- openafs/src/tools/install/write_fstab.pl	Sun Jan 20 04:05:09 2002
***************
*** 0 ****
--- 1,38 ----
+ #!/usr/bin/perl
+ #
+ # A perl script that will replace the line in /etc/fstab
+ # corresponding to the device given by the first argument,
+ # with a new line mounting that device to the second
+ # argument, or add it if necessary.
+ #
+ # openafs-tools, Version 1.2.2
+ 
+ # Copyright 2001, 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
+ #
+ 
+ open( FSTAB, "</etc/fstab");
+ @fstab = <FSTAB>;
+ close(FSTAB);
+ 
+ open( FSTAB, ">/etc/fstab");
+ 
+ $replaced = 0;
+ 
+ foreach $line (@fstab) {
+   @splitline = split(/\s+/, $line);
+   if( $splitline[0] eq "/dev/$ARGV[0]" ) {
+       print FSTAB "/dev/$ARGV[0]\t\t$ARGV[1]\t\t\text2\tdefaults     0  2\n";
+       $replaced = 1;
+   } else {
+       print FSTAB $line;
+   }
+ }
+ 
+ if( $replaced == 0 ) {
+     print FSTAB "/dev/$ARGV[0]\t\t$ARGV[1]\t\t\text2\tdefaults     0  2\n";
+ }
Index: openafs/src/tools/install/write_pam.pl
diff -c /dev/null openafs/src/tools/install/write_pam.pl:1.1.2.1
*** /dev/null	Wed Jan 30 16:23:58 2002
--- openafs/src/tools/install/write_pam.pl	Sun Jan 20 04:05:09 2002
***************
*** 0 ****
--- 1,54 ----
+ #!/usr/bin/perl
+ #
+ # A perl script that will enable or disable
+ # AFS login on a machine, depending on the
+ # first argument to the script.
+ #
+ # openafs-tools, Version 1.2.2
+ 
+ # Copyright 2001, 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
+ #
+ 
+ open( LOGIN, "</etc/pam.d/login");
+ @login = <LOGIN>;
+ close(LOGIN);
+ 
+ open( LOGIN, ">/etc/pam.d/login");
+ 
+ if( $ARGV[0] eq "enable" ) {
+ 
+     $enabled == 0;
+     
+     foreach $line (@login) {
+ 	@splitline = split( /\s+/, $line);
+ 	# only enable if: it's directly before the pwdb line (without the "shadow nullock",
+         #                 it hasn't been enabled yet in this script
+ 	if( $splitline[2] eq "/lib/security/pam_pwdb.so" && $splitline[3] eq ""  && $enabled == 0 ) {
+ 	    print LOGIN "auth\t   sufficient\t/lib/security/pam_afs.so try_first_pass ignore_root\n";
+ 	    $enabled = 1;
+ 	} 
+ 	# If you encounter the line, turn enabled on
+         if( $splitline[2] eq "/lib/scurity/pam_afs.so" ) {
+ 	    $enabled = 1;
+         }    
+ 	print LOGIN $line;
+     }
+ 
+ } else {
+ 
+     foreach $line (@login) {
+ 	@splitline = split( /\s+/, $line);
+ 	if( $splitline[2] ne "/lib/security/pam_afs.so" ) {
+ 	    print LOGIN $line;
+ 	}
+ 	
+     }
+ 
+ }
+ 
+ 
Index: openafs/src/tviced/NTMakefile
diff -c openafs/src/tviced/NTMakefile:1.4 openafs/src/tviced/NTMakefile:1.4.2.1
*** openafs/src/tviced/NTMakefile:1.4	Sun Aug 19 10:44:47 2001
--- openafs/src/tviced/NTMakefile	Sun Jan 20 04:09:25 2002
***************
*** 191,197 ****
  	$(DESTDIR)\lib\afs\afsprocmgmt.lib \
  	$(DESTDIR)\lib\afs\afseventlog.lib \
  	$(DESTDIR)\lib\afs\afsutil.lib \
! 	$(DESTDIR)\lib\pthread.lib
  
  $(EXEFILE): $(EXEOBJS) $(EXELIBS)
  	$(EXECONLINK)
--- 191,197 ----
  	$(DESTDIR)\lib\afs\afsprocmgmt.lib \
  	$(DESTDIR)\lib\afs\afseventlog.lib \
  	$(DESTDIR)\lib\afs\afsutil.lib \
! 	$(DESTDIR)\lib\afspthread.lib
  
  $(EXEFILE): $(EXEOBJS) $(EXELIBS)
  	$(EXECONLINK)
Index: openafs/src/update/NTMakefile
diff -c openafs/src/update/NTMakefile:1.2.8.1 openafs/src/update/NTMakefile:1.2.8.2
*** openafs/src/update/NTMakefile:1.2.8.1	Wed Sep 19 18:32:56 2001
--- openafs/src/update/NTMakefile	Wed Nov 14 22:30:30 2001
***************
*** 21,27 ****
  	$(DESTDIR)\lib\afsubik.lib \
  	$(DESTDIR)\lib\afs\afseventlog.lib \
  	$(DESTDIR)\lib\afsrxkad.lib \
! 	$(DESTDIR)\lib\afs\afsprocmgmt.lib
  
  ############################################################################
  # Definitions for generating files via RXGEN
--- 21,28 ----
  	$(DESTDIR)\lib\afsubik.lib \
  	$(DESTDIR)\lib\afs\afseventlog.lib \
  	$(DESTDIR)\lib\afsrxkad.lib \
! 	$(DESTDIR)\lib\afs\afsprocmgmt.lib \
! 	$(DESTDIR)\lib\cm_dns.obj
  
  ############################################################################
  # Definitions for generating files via RXGEN
Index: openafs/src/util/dirpath.c
diff -c openafs/src/util/dirpath.c:1.10.2.2 openafs/src/util/dirpath.c:1.10.2.3
*** openafs/src/util/dirpath.c:1.10.2.2	Sat Oct 13 00:22:10 2001
--- openafs/src/util/dirpath.c	Sun Jan 20 03:21:04 2002
***************
*** 10,16 ****
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/util/dirpath.c,v 1.10.2.2 2001/10/13 04:22:10 shadow Exp $");
  
  #include <stddef.h>
  #include <stdlib.h>
--- 10,16 ----
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/util/dirpath.c,v 1.10.2.3 2002/01/20 08:21:04 shadow Exp $");
  
  #include <stddef.h>
  #include <stdlib.h>
***************
*** 357,368 ****
--- 357,373 ----
  	 "/NoUsrViceEtcThisCellFileOnWindows");
    sprintf(dirPathArray[AFSDIR_CLIENT_CELLSERVDB_FILEPATH_ID], "%s/%s",
  	  ntClientConfigDirShort, AFSDIR_CELLSERVDB_FILE_NTCLIENT);
+   strcpy(dirPathArray[AFSDIR_CLIENT_CELLALIAS_FILEPATH_ID],
+ 	 "/NoCellAliasOnWindows");
  #else
    pathp = dirPathArray[AFSDIR_CLIENT_THISCELL_FILEPATH_ID];
    AFSDIR_CLIENT_FILEPATH(pathp, AFSDIR_CLIENT_ETC_DIR, AFSDIR_THISCELL_FILE);
  
    pathp = dirPathArray[AFSDIR_CLIENT_CELLSERVDB_FILEPATH_ID]; 
    AFSDIR_CLIENT_FILEPATH(pathp, AFSDIR_CLIENT_ETC_DIR, AFSDIR_CELLSERVDB_FILE);
+ 
+   pathp = dirPathArray[AFSDIR_CLIENT_CELLALIAS_FILEPATH_ID]; 
+   AFSDIR_CLIENT_FILEPATH(pathp, AFSDIR_CLIENT_ETC_DIR, AFSDIR_CELLALIAS_FILE);
  #endif /* AFS_NT40_ENV */
  
    pathp = dirPathArray[AFSDIR_CLIENT_NETINFO_FILEPATH_ID];
Index: openafs/src/util/dirpath.hin
diff -c openafs/src/util/dirpath.hin:1.2.2.1 openafs/src/util/dirpath.hin:1.2.2.2
*** openafs/src/util/dirpath.hin:1.2.2.1	Thu Sep 20 16:12:36 2001
--- openafs/src/util/dirpath.hin	Sun Jan 20 03:21:04 2002
***************
*** 118,123 ****
--- 118,124 ----
  /* file names */ 
  #define AFSDIR_THISCELL_FILE    "ThisCell"
  #define AFSDIR_CELLSERVDB_FILE  "CellServDB"
+ #define AFSDIR_CELLALIAS_FILE   "CellAlias"
  #define AFSDIR_KEY_FILE         "KeyFile"
  #define AFSDIR_ULIST_FILE       "UserList"
  #define AFSDIR_NOAUTH_FILE      "NoAuth"
***************
*** 260,265 ****
--- 261,267 ----
        AFSDIR_SERVER_MIGRATE_DIRPATH_ID,
        AFSDIR_SERVER_MIGRATELOG_FILEPATH_ID,
        AFSDIR_SERVER_BIN_FILE_DIRPATH_ID,
+       AFSDIR_CLIENT_CELLALIAS_FILEPATH_ID,
        AFSDIR_PATHSTRING_MAX } afsdir_id_t;
  
  /* getDirPath() returns a pointer to a string from an internal array of path strings 
***************
*** 331,336 ****
--- 333,339 ----
  /* client file paths */
  #define AFSDIR_CLIENT_THISCELL_FILEPATH getDirPath(AFSDIR_CLIENT_THISCELL_FILEPATH_ID)
  #define AFSDIR_CLIENT_CELLSERVDB_FILEPATH getDirPath(AFSDIR_CLIENT_CELLSERVDB_FILEPATH_ID)  
+ #define AFSDIR_CLIENT_CELLALIAS_FILEPATH getDirPath(AFSDIR_CLIENT_CELLALIAS_FILEPATH_ID)  
  #define AFSDIR_CLIENT_NETINFO_FILEPATH getDirPath(AFSDIR_CLIENT_NETINFO_FILEPATH_ID)
  #define AFSDIR_CLIENT_NETRESTRICT_FILEPATH getDirPath(AFSDIR_CLIENT_NETRESTRICT_FILEPATH_ID)
  
Index: openafs/src/util/vice.h
diff -c openafs/src/util/vice.h:1.4 openafs/src/util/vice.h:1.4.4.1
*** openafs/src/util/vice.h:1.4	Thu Jul  5 11:21:06 2001
--- openafs/src/util/vice.h	Sun Jan 20 03:21:04 2002
***************
*** 62,69 ****
--- 62,71 ----
   */
  #if defined(KERNEL) && !defined(AFS_OSF_ENV) && !defined(AFS_ALPHA_LINUX20_ENV)
  #define _VICEIOCTL(id)  ((unsigned int ) _IOW('V', id, struct ViceIoctl32))
+ #define _VICEIOCTL2(dev, id) ((unsigned int ) _IOW(dev, id, struct ViceIoctl32))
  #else
  #define _VICEIOCTL(id)  ((unsigned int ) _IOW('V', id, struct ViceIoctl))
+ #define _VICEIOCTL2(dev, id) ((unsigned int ) _IOW(dev, id, struct ViceIoctl))
  #endif
  
  /* Use this macro to define up to 256 vice ioctl's.  These ioctl's
***************
*** 72,75 ****
     into the kernel by the normal ioctl parameter passing mechanism.
   */
  
- #define _VALIDVICEIOCTL(com) (com >= _VICEIOCTL(0) && com <= _VICEIOCTL(255))
--- 74,76 ----
Index: openafs/src/venus/Makefile.in
diff -c openafs/src/venus/Makefile.in:1.6.2.1 openafs/src/venus/Makefile.in:1.6.2.3
*** openafs/src/venus/Makefile.in:1.6.2.1	Sat Oct 13 00:22:10 2001
--- openafs/src/venus/Makefile.in	Sun Jan 20 03:27:58 2002
***************
*** 105,111 ****
  		for f in kdump.IP??; \
  			do ${INSTALL} -s $$f ${DEST}/etc/$$f || exit $$? ; \
  		done ;; \
! 	sun4x_5[78] ) \
  		${INSTALLex} -f kdump.sh.solaris7 $@; \
  		${INSTALL} -s -f $? ${DEST}/etc/kdump32;; \
  	*linux* ) \
--- 105,111 ----
  		for f in kdump.IP??; \
  			do ${INSTALL} -s $$f ${DEST}/etc/$$f || exit $$? ; \
  		done ;; \
! 	sun4x_5[789] ) \
  		${INSTALLex} -f kdump.sh.solaris7 $@; \
  		${INSTALL} -s -f $? ${DEST}/etc/kdump32;; \
  	*linux* ) \
***************
*** 121,127 ****
  ${DEST}/etc/kdump64: kdump64
  	-set -x; \
  	case ${SYS_NAME} in \
! 	sun4x_5[78] | hp_ux11* ) \
  		${INSTALL} -s $? $@ ;;\
  	* ) \
  		echo skipping kdump64 for ${SYS_NAME} ;; \
--- 121,127 ----
  ${DEST}/etc/kdump64: kdump64
  	-set -x; \
  	case ${SYS_NAME} in \
! 	sun4x_5[789] | hp_ux11* ) \
  		${INSTALL} -s $? $@ ;;\
  	* ) \
  		echo skipping kdump64 for ${SYS_NAME} ;; \
***************
*** 183,191 ****
  	-set -x; \
  	case ${SYS_NAME} in \
  		alpha_linux* ) \
! 			${CC} -g -I${LINUX_KERNEL_PATH}/include -I${TOP_INCDIR} -I${TOP_SRCDIR}/config -I${TOP_INCDIR} ${XCFLAGS} -mno-fp-regs -ffixed-8 -o kdump-${LINUX_VERSION}.o -c kdump.c ;; \
  		*linux* ) \
! 			${CC} -g -I${LINUX_KERNEL_PATH}/include -I${TOP_INCDIR} -I${TOP_SRCDIR}/config -I${TOP_INCDIR} ${XCFLAGS} -o kdump-${LINUX_VERSION}.o -c kdump.c ;; \
  		alpha_osf1 | alpha_osf20 |  alpha_osf30 | alpha_osf32 | alpha_osf32c| alpha_dux?? ) \
  			${CC} -g ${CFLAGS} -I/usr/sys/include -I/usr/sys/BINARY -I/usr/sys/AFS -DDEBUGGER -c kdump.c ;;\
  		sgi_6? ) \
--- 183,191 ----
  	-set -x; \
  	case ${SYS_NAME} in \
  		alpha_linux* ) \
! 			${CC} -g -I${LINUX_KERNEL_PATH}/include -I${TOP_INCDIR} -I${TOP_SRCDIR}/config -I${TOP_SRCDIR}/libafs/afs -I${TOP_INCDIR} ${XCFLAGS} -mno-fp-regs -ffixed-8 -o kdump-${LINUX_VERSION}.o -c kdump.c ;; \
  		*linux* ) \
! 			${CC} -g -I${LINUX_KERNEL_PATH}/include -I${TOP_INCDIR} -I${TOP_SRCDIR}/config -I${TOP_SRCDIR}/libafs/afs -I${TOP_INCDIR} ${XCFLAGS} -o kdump-${LINUX_VERSION}.o -c kdump.c ;; \
  		alpha_osf1 | alpha_osf20 |  alpha_osf30 | alpha_osf32 | alpha_osf32c| alpha_dux?? ) \
  			${CC} -g ${CFLAGS} -I/usr/sys/include -I/usr/sys/BINARY -I/usr/sys/AFS -DDEBUGGER -c kdump.c ;;\
  		sgi_6? ) \
***************
*** 219,225 ****
  kdump64.o : kdump.c ${INCLS} AFS_component_version_number.c
  	-set -x; \
  	case ${SYS_NAME} in \
! 	sun4x_5[78] | hp_ux11* ) \
  		${CC} -g -I${TOP_INCDIR} -I${TOP_SRCDIR}/config -I${TOP_INCDIR} ${XCFLAGS64} -o kdump64.o -c kdump.c ;; \
  	esac
  
--- 219,225 ----
  kdump64.o : kdump.c ${INCLS} AFS_component_version_number.c
  	-set -x; \
  	case ${SYS_NAME} in \
! 	sun4x_5[789] | hp_ux11* ) \
  		${CC} -g -I${TOP_INCDIR} -I${TOP_SRCDIR}/config -I${TOP_INCDIR} ${XCFLAGS64} -o kdump64.o -c kdump.c ;; \
  	esac
  
***************
*** 262,268 ****
  kdump64 : kdump64.o
  	-set -x; \
  	case ${SYS_NAME} in \
! 	sun4x_5[78] | hp_ux11* )  \
  		${CC} -g ${XCFLAGS64} -o kdump64 kdump64.o ${TOP_LIBDIR}/libcmd64.a ${XLIBELFA} ${XLIBKVM} ${XLIBS} ;; \
  	esac
  
--- 262,268 ----
  kdump64 : kdump64.o
  	-set -x; \
  	case ${SYS_NAME} in \
! 	sun4x_5[789] | hp_ux11* )  \
  		${CC} -g ${XCFLAGS64} -o kdump64 kdump64.o ${TOP_LIBDIR}/libcmd64.a ${XLIBELFA} ${XLIBKVM} ${XLIBS} ;; \
  	esac
  
***************
*** 320,326 ****
  		for f in kdump.IP??; \
  			do ${INSTALL} -s $$f ${DESTDIR}${sbindir}/$$f || exit $$? ; \
  		done ;; \
! 	sun4x_5[78] ) \
  		${INSTALLex} -f kdump.sh.solaris7 $@; \
  		${INSTALL} -s -f $? ${DESTDIR}${sbindir}/kdump32;; \
  	*linux* ) \
--- 320,326 ----
  		for f in kdump.IP??; \
  			do ${INSTALL} -s $$f ${DESTDIR}${sbindir}/$$f || exit $$? ; \
  		done ;; \
! 	sun4x_5[789] ) \
  		${INSTALLex} -f kdump.sh.solaris7 $@; \
  		${INSTALL} -s -f $? ${DESTDIR}${sbindir}/kdump32;; \
  	*linux* ) \
***************
*** 335,341 ****
  ${DESTDIR}${sbindir}/kdump64: kdump64
  	-set -x; \
  	case ${SYS_NAME} in \
! 	sun4x_5[78] | hp_ux11* ) \
  		${INSTALL} -s $? $@ ;;\
  	* ) \
  		echo skipping kdump64 for ${SYS_NAME} ;; \
--- 335,341 ----
  ${DESTDIR}${sbindir}/kdump64: kdump64
  	-set -x; \
  	case ${SYS_NAME} in \
! 	sun4x_5[789] | hp_ux11* ) \
  		${INSTALL} -s $? $@ ;;\
  	* ) \
  		echo skipping kdump64 for ${SYS_NAME} ;; \
Index: openafs/src/venus/fs.c
diff -c openafs/src/venus/fs.c:1.12 openafs/src/venus/fs.c:1.12.2.1
*** openafs/src/venus/fs.c:1.12	Tue Aug  7 20:04:18 2001
--- openafs/src/venus/fs.c	Sun Jan 20 03:21:06 2002
***************
*** 10,16 ****
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/venus/fs.c,v 1.12 2001/08/08 00:04:18 shadow Exp $");
  
  #include <afs/afs_args.h>
  #include <rx/xdr.h>
--- 10,16 ----
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/venus/fs.c,v 1.12.2.1 2002/01/20 08:21:06 shadow Exp $");
  
  #include <afs/afs_args.h>
  #include <rx/xdr.h>
***************
*** 1863,1868 ****
--- 1863,1897 ----
      return 0;
  }
  
+ static ListAliasesCmd(as)
+     struct cmd_syndesc *as;
+ {
+     afs_int32 code, i;
+     char *tp, *aliasName, *realName;
+     struct ViceIoctl blob;
+ 
+     for(i=0;;i++) {
+ 	tp = space;
+ 	memcpy(tp, &i, sizeof(afs_int32));
+ 	blob.out_size = MAXSIZE;
+ 	blob.in_size = sizeof(afs_int32);
+ 	blob.in = space;
+ 	blob.out = space;
+ 	code = pioctl(0, VIOC_GETALIAS, &blob, 1);
+ 	if (code < 0) {
+ 	    if (errno == EDOM) break;	/* done with the list */
+ 	    Die(errno, 0);
+ 	    return 1;
+ 	}
+ 	tp = space;
+ 	aliasName = tp;
+ 	tp += strlen(aliasName) + 1;
+ 	realName = tp;
+ 	printf("Alias %s for cell %s\n", aliasName, realName);
+     }
+     return 0;
+ }
+ 
  static NewCellCmd(as)
      struct cmd_syndesc *as;
  {
***************
*** 1964,1969 ****
--- 1993,2032 ----
      return 0;
  }
  
+ static NewAliasCmd(as)
+     struct cmd_syndesc *as;
+ {
+     afs_int32 code;
+     struct ViceIoctl blob;
+     char *tp;
+     char *aliasName, *realName;
+ 
+     /* Now setup and do the NEWCELL pioctl call */
+     aliasName = as->parms[0].items->data;
+     realName = as->parms[1].items->data;
+     tp = space;
+     strcpy(tp, aliasName);
+     tp += strlen(aliasName) + 1;
+     strcpy(tp, realName);
+     tp += strlen(realName) + 1;
+ 
+     blob.in_size = tp - space;
+     blob.in = space;
+     blob.out_size = 0;
+     blob.out = space;
+     code = pioctl(0, VIOC_NEWALIAS, &blob, 1);
+     if (code < 0) {
+ 	if (errno == EEXIST) {
+ 	    fprintf(stderr, "%s: cell name `%s' in use by an existing cell.\n",
+ 		    pn, aliasName);
+ 	} else {
+ 	    Die(errno, 0);
+ 	}
+ 	return 1;
+     }
+     return 0;
+ }
+ 
  static WhichCellCmd(as)
    struct cmd_syndesc *as;
  {
***************
*** 2984,2989 ****
--- 3047,3054 ----
      ts = cmd_CreateSyntax("listcells", ListCellsCmd, 0, "list configured cells");
      cmd_AddParm(ts, "-numeric", CMD_FLAG, CMD_OPTIONAL, "addresses only");
  
+     ts = cmd_CreateSyntax("listaliases", ListAliasesCmd, 0, "list configured cell aliases");
+ 
      ts = cmd_CreateSyntax("setquota", SetQuotaCmd, 0, "set volume quota");
      cmd_AddParm(ts, "-path", CMD_SINGLE, CMD_OPTIONAL, "dir/file path");
      cmd_AddParm(ts, "-max", CMD_SINGLE, 0, "max quota in kbytes");
***************
*** 2996,3001 ****
--- 3061,3070 ----
      cmd_AddParm(ts, "-name", CMD_SINGLE, 0, "cell name");
      cmd_AddParm(ts, "-servers", CMD_LIST, CMD_REQUIRED, "primary servers");
      cmd_AddParm(ts, "-linkedcell", CMD_SINGLE, CMD_OPTIONAL, "linked cell name");
+ 
+     ts = cmd_CreateSyntax("newalias", NewAliasCmd, 0, "configure new cell alias");
+     cmd_AddParm(ts, "-alias", CMD_SINGLE, 0, "alias name");
+     cmd_AddParm(ts, "-name", CMD_SINGLE, 0, "real name of cell");
  
  #ifdef FS_ENABLE_SERVER_DEBUG_PORTS
  /*
Index: openafs/src/venus/kdump.c
diff -c openafs/src/venus/kdump.c:1.14 openafs/src/venus/kdump.c:1.14.2.4
*** openafs/src/venus/kdump.c:1.14	Wed Aug 29 13:36:27 2001
--- openafs/src/venus/kdump.c	Wed Dec 26 15:27:56 2001
***************
*** 10,16 ****
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/venus/kdump.c,v 1.14 2001/08/29 17:36:27 shadow Exp $");
  
  #include <stdio.h>
  #include <stdlib.h>	/* for malloc() */
--- 10,16 ----
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/venus/kdump.c,v 1.14.2.4 2001/12/26 20:27:56 shadow Exp $");
  
  #include <stdio.h>
  #include <stdlib.h>	/* for malloc() */
***************
*** 248,254 ****
  struct timezone {
      int a,b;
  };
! #ifndef AFS_ALPHA_LINUX20_ENV
  #ifndef AFS_LINUX24_ENV
  typedef struct timeval {
      int tv_sec;
--- 248,254 ----
  struct timezone {
      int a,b;
  };
! #if 0/*ndef AFS_ALPHA_LINUX20_ENV*/
  #ifndef AFS_LINUX24_ENV
  typedef struct timeval {
      int tv_sec;
***************
*** 261,269 ****
  #else
  #define _LINUX_BYTEORDER_LITTLE_ENDIAN_H
  #endif
  #include <linux/version.h>
  #include <linux/fs.h>
! #include <afs/osi_vfs.h>
  #else /* AFS_LINUX20_ENV */
  #ifdef AFS_HPUX110_ENV
  #define	KERNEL
--- 261,278 ----
  #else
  #define _LINUX_BYTEORDER_LITTLE_ENDIAN_H
  #endif
+ /* Avoid problems with timer_t redefinition */
+ #ifndef timer_t
+ #define timer_t ktimer_t
+ #define timer_t_redefined
+ #endif
  #include <linux/version.h>
  #include <linux/fs.h>
! #include <osi_vfs.h>
! #ifdef timer_t_redefined
! #undef timer_t
! #undef timer_t_redefined
! #endif
  #else /* AFS_LINUX20_ENV */
  #ifdef AFS_HPUX110_ENV
  #define	KERNEL
Index: openafs/src/vfsck/main.c
diff -c openafs/src/vfsck/main.c:1.5 openafs/src/vfsck/main.c:1.5.2.1
*** openafs/src/vfsck/main.c:1.5	Tue Aug  7 20:04:20 2001
--- openafs/src/vfsck/main.c	Wed Dec 26 15:26:57 2001
***************
*** 18,24 ****
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/vfsck/main.c,v 1.5 2001/08/08 00:04:20 shadow Exp $");
  
  #define VICE	/* allow us to put our changes in at will */
  #include <stdio.h>
--- 18,24 ----
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/vfsck/main.c,v 1.5.2.1 2001/12/26 20:26:57 shadow Exp $");
  
  #define VICE	/* allow us to put our changes in at will */
  #include <stdio.h>
***************
*** 1074,1080 ****
--- 1074,1084 ----
                          exit(-1);
                  else
  #endif
+ #ifdef  AFS_SUN5_ENV
+ 		    exit(exitstat);
+ #else
  		exit(4);
+ #endif
  	}
  #endif
  #ifdef VICE
Index: openafs/src/viced/afsfileprocs.c
diff -c openafs/src/viced/afsfileprocs.c:1.10.2.2 openafs/src/viced/afsfileprocs.c:1.10.2.3
*** openafs/src/viced/afsfileprocs.c:1.10.2.2	Sat Oct 13 00:22:10 2001
--- openafs/src/viced/afsfileprocs.c	Wed Dec 26 15:58:09 2001
***************
*** 28,34 ****
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/viced/afsfileprocs.c,v 1.10.2.2 2001/10/13 04:22:10 shadow Exp $");
  
  #include <stdio.h>
  #include <stdlib.h>
--- 28,34 ----
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/viced/afsfileprocs.c,v 1.10.2.3 2001/12/26 20:58:09 shadow Exp $");
  
  #include <stdio.h>
  #include <stdlib.h>
***************
*** 1205,1213 ****
      struct rx_connection *tcon;		/* Rx connection Handle */
      struct AFSFid *Fid;			/* Fid of taret file */
      struct AFSStoreStatus *InStatus;	/* Input Status for Fid */
!     afs_int32 Pos;				/* Not implemented yet */
!     afs_int32 Length;			/* Length of data to store */
!     afs_int32 FileLength;			/* Length of file after store */
      struct AFSFetchStatus *OutStatus;	/* Returned status for target fid */
  
  {
--- 1205,1213 ----
      struct rx_connection *tcon;		/* Rx connection Handle */
      struct AFSFid *Fid;			/* Fid of taret file */
      struct AFSStoreStatus *InStatus;	/* Input Status for Fid */
!     afs_uint32 Pos;                    /* Not implemented yet */
!     afs_uint32 Length;                 /* Length of data to store */
!     afs_uint32 FileLength;             /* Length of file after store */
      struct AFSFetchStatus *OutStatus;	/* Returned status for target fid */
  
  {
***************
*** 5160,5168 ****
      struct AFSFid *Fid;
      struct client *client;
      register struct rx_call *Call;
!     afs_int32 Pos;
!     afs_int32 Length;
!     afs_int32 FileLength;
      int sync;
  #if FS_STATS_DETAILED
      afs_int32 *a_bytesToStoreP;
--- 5160,5168 ----
      struct AFSFid *Fid;
      struct client *client;
      register struct rx_call *Call;
!     afs_uint32 Pos;
!     afs_uint32 Length;
!     afs_uint32 FileLength;
      int sync;
  #if FS_STATS_DETAILED
      afs_int32 *a_bytesToStoreP;
Index: openafs/src/viced/host.c
diff -c openafs/src/viced/host.c:1.7.2.1 openafs/src/viced/host.c:1.7.2.2
*** openafs/src/viced/host.c:1.7.2.1	Sat Oct 13 00:22:10 2001
--- openafs/src/viced/host.c	Wed Dec 26 15:21:39 2001
***************
*** 10,16 ****
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/viced/host.c,v 1.7.2.1 2001/10/13 04:22:10 shadow Exp $");
  
  #include <stdio.h>
  #include <errno.h>
--- 10,16 ----
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/viced/host.c,v 1.7.2.2 2001/12/26 20:21:39 shadow Exp $");
  
  #include <stdio.h>
  #include <errno.h>
***************
*** 748,753 ****
--- 748,757 ----
  	    FreeCE(client);
  	} else cp = &client->next;
      }
+ 
+     /* We've just cleaned out all the deleted clients; clear the flag */
+     host->hostFlags &= ~CLIENTDELETED;
+ 
      if (host->hostFlags & HOSTDELETED) {
  	register struct h_hashChain **hp, *th;
  	register struct rx_connection *rxconn;
Index: openafs/src/vlserver/NTMakefile
diff -c openafs/src/vlserver/NTMakefile:1.3 openafs/src/vlserver/NTMakefile:1.3.4.1
*** openafs/src/vlserver/NTMakefile:1.3	Mon Apr 30 03:05:47 2001
--- openafs/src/vlserver/NTMakefile	Wed Nov 14 22:30:31 2001
***************
*** 85,91 ****
  	$(DESTDIR)\lib\afs\afsaudit.lib \
  	$(DESTDIR)\lib\afs\afseventlog.lib \
  	$(DESTDIR)\lib\afs\afsreg.lib \
! 	$(DESTDIR)\lib\afs\afsprocmgmt.lib
  
  	
  $(VLSERVER): $(VLSERVER_EXEOBJS) $(LIBFILE) $(VLSERVER_EXECLIBS)
--- 85,92 ----
  	$(DESTDIR)\lib\afs\afsaudit.lib \
  	$(DESTDIR)\lib\afs\afseventlog.lib \
  	$(DESTDIR)\lib\afs\afsreg.lib \
! 	$(DESTDIR)\lib\afs\afsprocmgmt.lib \
! 	$(DESTDIR)\lib\cm_dns.obj
  
  	
  $(VLSERVER): $(VLSERVER_EXEOBJS) $(LIBFILE) $(VLSERVER_EXECLIBS)
Index: openafs/src/vol/Makefile.in
diff -c openafs/src/vol/Makefile.in:1.5.2.1 openafs/src/vol/Makefile.in:1.5.2.2
*** openafs/src/vol/Makefile.in:1.5.2.1	Sat Oct 13 00:22:11 2001
--- openafs/src/vol/Makefile.in	Sun Jan 20 03:27:59 2002
***************
*** 33,39 ****
  
  LIBS=${TOP_LIBDIR}/libcmd.a vlib.a ${TOP_LIBDIR}/util.a \
  	${TOP_LIBDIR}/libsys.a ${TOP_LIBDIR}/libdir.a \
! 	${TOP_LIBDIR}/liblwp.a  ${TOP_LIBDIR}/libacl.a ${XLIBS}
  
  CFLAGS = -D${SYS_NAME} ${OPTMZ} ${INCDIRS} ${XCFLAGS} ${DBG}
  
--- 33,39 ----
  
  LIBS=${TOP_LIBDIR}/libcmd.a vlib.a ${TOP_LIBDIR}/util.a \
  	${TOP_LIBDIR}/libsys.a ${TOP_LIBDIR}/libdir.a \
! 	${TOP_LIBDIR}/liblwp.a  ${TOP_LIBDIR}/libacl.a
  
  CFLAGS = -D${SYS_NAME} ${OPTMZ} ${INCDIRS} ${XCFLAGS} ${DBG}
  
***************
*** 156,162 ****
  
  # new salvager:  remove references to /vice by linking with novice.o
  salvager: vol-salvage.o physio.o vlib.a
! 	${CC} ${LDFLAGS} -o salvager vol-salvage.o physio.o ${LIBS}
  
  vol-salvage: vol-salvage.o
  vol-info: vol-info.o physio.o ihandle.o
--- 156,162 ----
  
  # new salvager:  remove references to /vice by linking with novice.o
  salvager: vol-salvage.o physio.o vlib.a
! 	${CC} ${LDFLAGS} -o salvager vol-salvage.o physio.o ${LIBS} ${XLIBS}
  
  vol-salvage: vol-salvage.o
  vol-info: vol-info.o physio.o ihandle.o
***************
*** 183,200 ****
  	case ${SYS_NAME} in \
  		*linux* | *fbsd*) \
  			${CC} ${CFLAGS} ${DBG} -o volinfo vol-info.o physio.o \
! 				ihandle.o ${LIBS} ;; \
  		*) \
  			${CC} ${CFLAGS} ${DBG} -o volinfo vol-info.o physio.o \
! 				 ihandle.o ${LIBS} ;; \
  	esac
  
  
  fs_conv_dux40D: fs_conv_411.o
! 	${CC} ${CFLAGS} ${TOP_LIBDIR}/libcmd.a -o fs_conv_dux40D fs_conv_411.o  ${LIBS} 
  
  fs_conv_sol26: fs_conv_411.o vlib.a 
! 	${CC} ${CFLAGS} ${TOP_LIBDIR}/libcmd.a -o fs_conv_sol26 fs_conv_411.o  ${LIBS} 
  
  fs_conv_411.o: fs_conv_411.c AFS_component_version_number.c
  	${CC} ${CFLAGS} -c fs_conv_411.c
--- 183,200 ----
  	case ${SYS_NAME} in \
  		*linux* | *fbsd*) \
  			${CC} ${CFLAGS} ${DBG} -o volinfo vol-info.o physio.o \
! 				ihandle.o ${LIBS} ${XLIBS} ;; \
  		*) \
  			${CC} ${CFLAGS} ${DBG} -o volinfo vol-info.o physio.o \
! 				 ihandle.o ${LIBS} ${XLIBS} ;; \
  	esac
  
  
  fs_conv_dux40D: fs_conv_411.o
! 	${CC} ${CFLAGS} ${TOP_LIBDIR}/libcmd.a -o fs_conv_dux40D fs_conv_411.o  ${LIBS} ${XLIBS}
  
  fs_conv_sol26: fs_conv_411.o vlib.a 
! 	${CC} ${CFLAGS} ${TOP_LIBDIR}/libcmd.a -o fs_conv_sol26 fs_conv_411.o  ${LIBS} ${XLIBS}
  
  fs_conv_411.o: fs_conv_411.c AFS_component_version_number.c
  	${CC} ${CFLAGS} -c fs_conv_411.c
Index: openafs/src/vol/NTMakefile
diff -c openafs/src/vol/NTMakefile:1.2 openafs/src/vol/NTMakefile:1.2.8.1
*** openafs/src/vol/NTMakefile:1.2	Sat Nov  4 05:06:21 2000
--- openafs/src/vol/NTMakefile	Sun Jan 20 04:09:26 2002
***************
*** 63,69 ****
  	$(DESTDIR)\lib\afs\afsreg.lib \
  	$(DESTDIR)\lib\afs\afsprocmgmt.lib \
  	$(DESTDIR)\lib\afs\afseventlog.lib \
! 	$(DESTDIR)\lib\pthread.lib
  
  ############################################################################
  # build salvager
--- 63,69 ----
  	$(DESTDIR)\lib\afs\afsreg.lib \
  	$(DESTDIR)\lib\afs\afsprocmgmt.lib \
  	$(DESTDIR)\lib\afs\afseventlog.lib \
! 	$(DESTDIR)\lib\afspthread.lib
  
  ############################################################################
  # build salvager
Index: openafs/src/volser/NTMakefile
diff -c openafs/src/volser/NTMakefile:1.2.8.1 openafs/src/volser/NTMakefile:1.2.8.2
*** openafs/src/volser/NTMakefile:1.2.8.1	Wed Sep 19 18:32:57 2001
--- openafs/src/volser/NTMakefile	Wed Nov 14 22:30:31 2001
***************
*** 64,70 ****
  	$(DESTDIR)\lib\afslwp.lib \
  	$(DESTDIR)\lib\afs\afsacl.lib \
  	$(DESTDIR)\lib\afs\afsreg.lib \
! 	$(DESTDIR)\lib\afs\afseventlog.lib
  
  
  ############################################################################
--- 64,71 ----
  	$(DESTDIR)\lib\afslwp.lib \
  	$(DESTDIR)\lib\afs\afsacl.lib \
  	$(DESTDIR)\lib\afs\afsreg.lib \
! 	$(DESTDIR)\lib\afs\afseventlog.lib \
!      $(DESTDIR)\lib\cm_dns.obj
  
  
  ############################################################################
Index: openafs/src/volser/vos.c
diff -c openafs/src/volser/vos.c:1.8.2.2 openafs/src/volser/vos.c:1.8.2.3
*** openafs/src/volser/vos.c:1.8.2.2	Sat Oct 13 00:22:11 2001
--- openafs/src/volser/vos.c	Wed Dec 26 15:12:17 2001
***************
*** 10,16 ****
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/volser/vos.c,v 1.8.2.2 2001/10/13 04:22:11 shadow Exp $");
  
  #include <sys/types.h>
  #ifdef AFS_NT40_ENV
--- 10,16 ----
  #include <afsconfig.h>
  #include <afs/param.h>
  
! RCSID("$Header: /data/cvs/openafs/src/volser/vos.c,v 1.8.2.3 2001/12/26 20:12:17 shadow Exp $");
  
  #include <sys/types.h>
  #ifdef AFS_NT40_ENV
***************
*** 67,73 ****
  cmd_AddParm(ts, "-noauth", CMD_FLAG, CMD_OPTIONAL, "don't authenticate");\
  cmd_AddParm(ts, "-localauth",CMD_FLAG,CMD_OPTIONAL,"use server tickets");\
  cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, "verbose");\
! cmd_AddParm(ts, "-crypt", CMD_FLAG, CMD_OPTIONAL, "encrypt commands");\
  
  #define ERROR_EXIT(code) {error=(code); goto error_exit;}
  
--- 67,73 ----
  cmd_AddParm(ts, "-noauth", CMD_FLAG, CMD_OPTIONAL, "don't authenticate");\
  cmd_AddParm(ts, "-localauth",CMD_FLAG,CMD_OPTIONAL,"use server tickets");\
  cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, "verbose");\
! cmd_AddParm(ts, "-encrypt", CMD_FLAG, CMD_OPTIONAL, "encrypt commands");\
  
  #define ERROR_EXIT(code) {error=(code); goto error_exit;}
  
