(FILECREATED " 1-Nov-86 19:17:18" {QV}<NOTECARDS>1.3K>NEXT>RHTPATCH127.;7 63566  

      changes to:  (FNS NC.ProcessInspectAndRepairRequest NC.ScavengerPhase1 NC.OpenNoteFile 
			NC.ProcessNoteFileNeedsTruncationError NC.ProcessNoteFileNeedsConversionError 
			NC.ProcessNoteFileNotFoundError)
		   (VARS RHTPATCH127COMS)

      previous date: "31-Oct-86 23:56:25" {QV}<NOTECARDS>1.3K>NEXT>RHTPATCH127.;6)


(* Copyright (c) 1986 by Xerox Corporation. All rights reserved.)

(PRETTYCOMPRINT RHTPATCH127COMS)

(RPAQQ RHTPATCH127COMS ((* * Fixes bugs on using inspector if in need of truncation. Also fixes 
			     some messages when asking user whether to truncate.)
			  (* * Changes to NCDATABASE)
			  (FNS NC.AskUserAboutTruncation NC.OpenNoteFile 
			       NC.ProcessNoteFileNeedsTruncationError 
			       NC.ProcessInspectAndRepairRequest 
			       NC.ProcessNoteFileNeedsConversionError NC.ProcessNoteFileNotFoundError 
			       NC.InspectAndRepairNoteFile)
			  (* * Changes to NCREPAIR)
			  (FNS NC.ScavengeDatabaseFile NC.ScavengerPhase1)
			  (* * Changes to NCLOCALDEVICE)
			  (FNS NCLocalDevice.InspectAndRepairNoteFile NCLocalDevice.OpenNoteFile)))
(* * Fixes bugs on using inspector if in need of truncation. Also fixes some messages when 
asking user whether to truncate.)

(* * Changes to NCDATABASE)

(DEFINEQ

(NC.AskUserAboutTruncation
  (LAMBDA (NoteFile PromptWindow)                            (* rht: "29-Oct-86 14:46")

          (* * Ask the user what to do since NoteFile truncation is needed.)



          (* * fgh 5/25/86 First created.)



          (* * rht 10/29/86: Change name from Abort to Cancel.)


    (LET (Items Menu PromptWinPos)

          (* * List user's options. Include Inspect&Repair only if this NoteFIle device has a RepairFn.)


         (SETQ Items (BQUOTE ((Cancel (QUOTE Cancel)
					  "Cancel the Open.")
				  (Truncate% File (QUOTE Truncate% File)
						  
				 "Truncate the file throwing away changes since last checkpoint.")
				  ,@(if (fetch (NoteFile RepairNoteFileFn) of NoteFile)
					then (LIST (QUOTE (Inspect% &% Repair (QUOTE 
									       Inspect% &% Repair)
										    
							   "Run Inspect&Repair on this NoteFile.")))))
				 ))

          (* * Bring up the menu with the options.)


         (MENU (SETQ Menu (create MENU
					ITEMS ← Items
					MENUOUTLINESIZE ← 2
					MENUFONT ←(FONTCREATE (QUOTE HELVETICA)
								12
								(QUOTE BOLD))))
		 (if (WINDOWP PromptWindow)
		     then (create POSITION
				      XCOORD ←(fetch (POSITION XCOORD) of (SETQ PromptWinPos
										  (WINDOWPOSITION
										    PromptWindow)))
				      YCOORD ←(DIFFERENCE (fetch (POSITION YCOORD)
							       of PromptWinPos)
							    (fetch (MENU IMAGEHEIGHT)
							       of Menu)))
		   else NIL)))))

(NC.OpenNoteFile
  (LAMBDA (NoteFileOrFileName NoteFilesHashArray Don'tCacheTypesAndTitlesFlg Don'tCreateFlg 
			      Convertw/oConfirmFlg Don'tCreateArrayFlg Can'tTruncateFlg 
			      Don'tCreateInterfaceFlg Don'tGetSpecialCardsFlg InterestedWindow 
			      PublicOrPrivate Don'tCheckOperationsInProgressFlg MenuPosition QuietFlg 
			      ReadOnlyFlg Don'tCheckForTruncationFlg)
                                                             (* rht: "31-Oct-86 23:17")

          (* * fgh 5/23/86 Renamed to NC.OpenNoteFile from NC.OpenDatabaseFile. Total revamp to implement device vector.)



          (* * kef 7/18/86: Inserted a call to stuff the UID into the NoteFile because BuildHashArray needed it.)



          (* * kef 7/21/86: Moved up the install of the NoteFile into the NoteFileHashArray to before the building of the 
	  NoteFile's hash array. The reason is that the remote multi client build hash array function needs to get a list of 
	  UIDs, and in order to do this, it needs to grab a Courier stream for the NoteFile given only the UID.
	  It can only do this if the UID is registered in the NoteFilesHashArray.)



          (* * fgh 8/31/86 Updated to account for changes made to system since 5/23/86 revamp. Changes reimplemented include:
	  (fgh 6/8/86 Added code to insure that two files with SameUIDP would never be open at once.) 
	  (fgh 6/25/86 Added contention locks -- NC.ProtectedNoteFileOperation, Don'tCheckOperationInProgressFlg etc.) 
	  (fgh 6/27/86 Added MenuPsotion arg to pass to SetUpNoteFileInterface) (kirk 15Jul86 Added call to 
	  NC.SetUpNoteFileInterface if already open))



          (* * fgh 9/1/86 Reimplemented ReadOnly NoteFile open.)



          (* * fgh 9/4/86 Put in default for NoteFilesHashArray which is NC.NoteFilesHashArray)



          (* * kirk/rht 8/29/86: Now resets Name after conversion from version 2 to version3.)



          (* * rht 10/29/86: Changed "aborted" to "canceled" in message.)



          (* * rht 10/31/86: Added Don'tCheckForTruncationFlg arg.)


    (DECLARE (GLOBALVARS NC.OpenNoteFileFns NC.LastNoteFileOpened))

          (* * If the value returned is not a NoteFile, let the user know there's been some problem.)


    (PROG (NoteFile FileName ReturnValue CriticalUIDs)

          (* * Figure out the name of the file containing the NoteFile)


	    (if (NULL (SETQ FileName (COND
			      ((type? NoteFile NoteFileOrFileName)
				(fetch (NoteFile FullFileName) of NoteFileOrFileName))
			      (NoteFileOrFileName)
			      (T (NC.DatabaseFileName "Name of NoteFile to open:" " -- " T NIL NIL 
							InterestedWindow)))))
		then (RETURN))                           (* SETQ FileName (OR (FULLNAME FileName) FileName))

          (* * Create a NoteFile object or use existing notefile object if there is one for this file name.)


	    (SETQ NoteFile (if (type? NoteFile NoteFileOrFileName)
				 then NoteFileOrFileName
			       else (OR (NC.NoteFileFromFileName FileName)
					    (create NoteFile))))
	    (replace (NoteFile FullFileName) of NoteFile with FileName)
	    (replace (NoteFile ReadOnlyFlg) of NoteFile with ReadOnlyFlg)

          (* * If there is no interested window, see if the menu window can be used.)


	    (if (AND (NULL InterestedWindow)
			 (fetch (NoteFile Menu) of NoteFile))
		then (SETQ InterestedWindow (WFROMMENU (fetch (NoteFile Menu) of NoteFile)))
		  )

          (* * Figure out the appropriate device vector from the file name.)


	    (NC.InstallDeviceVectorInNoteFile NoteFile PublicOrPrivate)

          (* * If this is an open NoteFIle, just bring up its menu.)


	    (if (NC.NoteFileOpenP NoteFile)
		then (OR Don'tCreateInterfaceFlg (NC.SetUpNoteFileInterface NoteFile 
										  MenuPosition))
                                                             (* bring up or create notefile icon if needed)
		       (RETURN NIL))

          (* * Notify user.)


	    (OR QuietFlg (NC.PrintMsg InterestedWindow T "Opening NoteFile: " FileName " ..."
					  (CHARACTER 13)))

          (* * Check to see if this NoteFile is busy doing something else)


	    (if (AND (NULL Don'tCheckOperationsInProgressFlg)
			 (PROCESSP (NC.NoteFileProp NoteFile (QUOTE ProcessInProgress))))
		then (NC.PrintOperationInProgressMsg InterestedWindow (QUOTE Open% NoteFile)
							 (NC.NoteFileProp NoteFile (QUOTE 
									      OperationInProgress)))
		       (RETURN NIL))

          (* * Run rest of function with contention lock.)


	    (RETURN
	      (NC.ProtectedNoteFileOperation
		NoteFile Open% NoteFile
		(PROG NIL

          (* * Run through OpenNoteFileFns with param of BEFORE. Exit if any returns DON'T)


		        (if (for Function in NC.OpenNoteFileFns
				 thereis (OR (EQ Function (QUOTE DON'T))
						 (EQ (QUOTE DON'T)
						       (APPLY* Function FileName NoteFile
								 (QUOTE BEFORE)))))
			    then (if (WINDOWP InterestedWindow)
				       then (NC.PrintMsg InterestedWindow NIL 
							     "Open canceled for NoteFile "
							     FileName "." (CHARACTER 13))
					      (NC.ClearMsg InterestedWindow T))
				   (RETURN))

          (* * Call the device specific OpenNoteFileFn, which returns a list of special UIDs)


		        (if (NULL (ERSETQ (SETQ ReturnValue (APPLY* (fetch (NoteFile
											 
										   OpenNoteFileFn)
										 of NoteFile)
									      NoteFile 
									      InterestedWindow 
								       Don'tCheckForTruncationFlg))))
			    then (SETQ ReturnValue (QUOTE NoteFileOpenFailed)))

          (* * Process error returns from the OpenNoteFileFn)


		        (if (NOT (LITATOM ReturnValue))
			    then 

          (* * OpenNoteFileFn returned correctly)


				   (SETQ CriticalUIDs ReturnValue)
			  else 

          (* * Error, process it.)


				 (SETQ ReturnValue
				   (OR (SELECTQ ReturnValue
						    (NoteFileNotFound (
								  NC.ProcessNoteFileNotFoundError
									NoteFile NoteFilesHashArray 
								      Don'tCacheTypesAndTitlesFlg 
									Don'tCreateFlg 
									Convertw/oConfirmFlg 
									Don'tCreateArrayFlg 
									Can'tTruncateFlg 
									Don'tCreateInterfaceFlg 
									Don'tGetSpecialCardsFlg 
									InterestedWindow 
									PublicOrPrivate 
								Don'tCheckOperationsInProgressFlg 
									MenuPosition QuietFlg 
									ReadOnlyFlg 
								       Don'tCheckForTruncationFlg))
						    (NoteFileNeedsConversion (
							   NC.ProcessNoteFileNeedsConversionError
									       NoteFile 
									       NoteFilesHashArray 
								      Don'tCacheTypesAndTitlesFlg 
									       Don'tCreateFlg 
									     Convertw/oConfirmFlg 
									      Don'tCreateArrayFlg 
									       Can'tTruncateFlg 
									  Don'tCreateInterfaceFlg 
									  Don'tGetSpecialCardsFlg 
									       InterestedWindow 
									       PublicOrPrivate 
								Don'tCheckOperationsInProgressFlg 
									       MenuPosition QuietFlg 
									       ReadOnlyFlg 
								       Don'tCheckForTruncationFlg))
						    (NoteFileNeedsTruncation (
							   NC.ProcessNoteFileNeedsTruncationError
									       NoteFile 
									       NoteFilesHashArray 
								      Don'tCacheTypesAndTitlesFlg 
									       Don'tCreateFlg 
									     Convertw/oConfirmFlg 
									      Don'tCreateArrayFlg 
									       Can'tTruncateFlg 
									  Don'tCreateInterfaceFlg 
									  Don'tGetSpecialCardsFlg 
									       InterestedWindow 
									       PublicOrPrivate 
								Don'tCheckOperationsInProgressFlg 
									       MenuPosition QuietFlg 
									       ReadOnlyFlg 
								       Don'tCheckForTruncationFlg))
						    (NoteFileAlreadyOpen
						      (ERSETQ (NC.ReportError
								  NIL
								  (CONCAT (fetch (NoteFile 
										     FullFileName)
									       of NoteFile)
									    
					    " is already open for exclusive access. Open failed."))))
						    (NoteFileOpenFailed
						      (ERSETQ (NC.ReportError
								  NIL
								  (CONCAT "Open of "
									    (fetch (NoteFile 
										     FullFileName)
									       of NoteFile)
									    
								    " failed for unknown reason."))))
						    (NoteFileHeaderBad
						      (ERSETQ (NC.ReportError
								  NIL
								  (CONCAT "Header of NoteFile "
									    (fetch (NoteFile 
										     FullFileName)
									       of NoteFile)
									    
							  " is bad.  Contact a NoteCards wizard."))))
						    (PROGN (ERSETQ (NC.ReportError
									 NIL
									 (CONCAT 
									   "Unknown error code ("
										   ReturnValue 
						     ") returned by OpenNoteFileFn for NoteFile "
										   FileName)))))
					 ReturnValue))

          (* * notify the user. if there's been a problem)


				 (if (AND (NOT (type? NoteFile ReturnValue))
					      (WINDOWP InterestedWindow))
				     then (NC.PrintMsg InterestedWindow NIL 
							   "Open canceled for NoteFile "
							   FileName "." (CHARACTER 13))
					    (NC.ClearMsg InterestedWindow T))

          (* * return whatever the error processing returned.)


				 (RETURN ReturnValue))
		        (SETQ ReturnValue)

          (* * Make sure there is no other open NF with this UID.)


		        (LET (NF)
			     (if (AND (SETQ NF (GETHASH (fetch (NoteFileCriticalUIDs 
											 NoteFile)
								   of CriticalUIDs)
								NC.NoteFilesHashArray))
					  (NEQ (fetch (NoteFile FullFileName) of NoteFile)
						 (fetch (NoteFile FullFileName) of NF))
					  (NC.NoteFileOpenP NF))
				 then (FLASHW PROMPTWINDOW)
					(NC.PrintMsg PROMPTWINDOW T "Couldn't open " FileName
						       (CHARACTER 13)
						       "because "
						       (fetch (NoteFile FullFileName) of NF)
						       " is already open "
						       (CHARACTER 13)
						       "and has the same UID.")
					(NC.CloseNoteFile NoteFile InterestedWindow T T)
					(RETURN NIL)))

          (* * If needed, build a hash array by calling the device specific BuilHashArrayFn.)


		        (replace (NoteFile UID) of NoteFile with (fetch (NoteFileCriticalUIDs
										  NoteFile)
									  of CriticalUIDs))

          (* * Store this NoteFile object in the appropriate NoteFile hash array)


		        (NC.StoreNoteFileInHashArray NoteFile (OR NoteFilesHashArray 
								      NC.NoteFilesHashArray))
		        (if (NOT Don'tCreateArrayFlg)
			    then (OR QuietFlg (NC.PrintMsg InterestedWindow T 
								 "Opening NoteFile: "
								 FileName
								 (CHARACTER 13)
								 "Building index array ..."
								 (CHARACTER 13)))
				   (if (OR (NULL (ERSETQ (SETQ ReturnValue
								   (APPLY*
								     (fetch (NoteFile 
										 BuildHashArrayFn)
									of NoteFile)
								     NoteFile QuietFlg 
								     InterestedWindow
								     (CONCAT "Opening NoteFile "
									       (fetch (NoteFile
											  
										     FullFileName)
										  of NoteFile)
									       (CHARACTER 13))))))
					       (NOT (type? NoteFile ReturnValue)))
				       then 

          (* * Error during building of hash array)


					      (ERSETQ (NC.ReportError NIL
									  (CONCAT
									    
							  "Build Hash Array failed for NoteFile "
									    (fetch (NoteFile 
										     FullFileName)
									       of NoteFile)
									    " because " ReturnValue)))
					      (RETURN)))

          (* * Set up critical UIDs in NoteFile object using the values returned from OpenNoteFileFn.)


		        (NC.InstallCriticalUIDsInNoteFile NoteFile CriticalUIDs)

          (* * if needed, cache the special cards)


		        (if (NOT Don'tGetSpecialCardsFlg)
			    then (NC.GetSpecialCards NoteFile QuietFlg InterestedWindow
							 (CONCAT "Opening NoteFile: "
								   (fetch (NoteFile FullFileName)
								      of NoteFile)
								   (CHARACTER 13))))

          (* * If needed, start the titles and types caching process)


		        (if (NOT Don'tCacheTypesAndTitlesFlg)
			    then (replace (NoteFile CachingProcess) of NoteFile
				      with (ADD.PROCESS (LIST (FUNCTION 
								      NC.CacheTypesAndTitles)
								    NoteFile))))

          (* * If needed, open up a NoteFile interface.)


		        (if (NOT Don'tCreateInterfaceFlg)
			    then (NC.SetUpNoteFileInterface NoteFile MenuPosition))

          (* * Record this as the last NF opened.)


		        (SETQ NC.LastNoteFileOpened NoteFile)

          (* * Run through OpenNoteFIleFns with param of AFTER. Stop if any returns DON'T)


		        (for Function in NC.OpenNoteFileFns thereis (EQ (QUOTE DON'T)
										(APPLY*
										  Function FileName 
										  NoteFile
										  (QUOTE AFTER))))

          (* * Go home, returning NoteFile)


		        (if (NULL QuietFlg)
			    then (NC.PrintMsg InterestedWindow T "Opening NoteFile: " FileName
						  (CHARACTER 13)
						  "Done."
						  (CHARACTER 13))
				   (NC.ClearMsg InterestedWindow T))
		        (RETURN NoteFile)))))))

(NC.ProcessNoteFileNeedsTruncationError
  (LAMBDA (NoteFile NoteFilesHashArray Don'tCacheTypesAndTitlesFlg Don'tCreateFlg 
		    Convertw/oConfirmFlg Don'tCreateArrayFlg Can'tTruncateFlg Don'tCreateInterfaceFlg 
		    Don'tGetSpecialCardsFlg PromptWindow PublicOrPrivate 
		    Don'tCheckOperationsInProgressFlg MenuPosition QuietFlg ReadOnlyFlg 
		    Don'tCheckForTruncationFlg)              (* rht: "31-Oct-86 23:01")

          (* * Discovered NoteFile needs version truncation when attempted to open it. Process that error.)



          (* * fgh 5/23/86 First created.)



          (* * fgh 9/1/86 Updated args to match NC.OpenNoteFile.)



          (* * rht 10/29/86: Changed name from Abort to Cancel.)



          (* * rht 10/31/86: Added Don'tCheckForTruncationFlg arg.)


    (PROG (TruncationFn)

          (* * If appropriate, notify the user.)


	    (if (WINDOWP PromptWindow)
		then (NC.PrintMsg PromptWindow T "NoteFile " (fetch (NoteFile FullFileName)
								    of NoteFile)
				      
			    " has information written since last successful close or checkpoint."
				      (CHARACTER 13)))

          (* * If the device has a TruncationFn then apply it and try to Open the NoteFile.)


	    (if (AND (NULL Can'tTruncateFlg)
			 (SETQ TruncationFn (fetch (NoteFile TruncateNoteFileFn) of NoteFile)))
		then 

          (* * ASk the user if they want to truncate, or abort, or repair the notefile.)


		       (SELECTQ (NC.AskUserAboutTruncation NoteFile PromptWindow)
				  (Cancel (RETURN (QUOTE CancelOpen)))
				  (Inspect% &% Repair (RETURN (NC.ProcessInspectAndRepairRequest
								  NoteFile NoteFilesHashArray 
								  Don'tCacheTypesAndTitlesFlg 
								  Don'tCreateFlg Convertw/oConfirmFlg 
								  Don'tCreateArrayFlg 
								  Can'tTruncateFlg 
								  Don'tCreateInterfaceFlg 
								  Don'tGetSpecialCardsFlg 
								  PromptWindow PublicOrPrivate 
								Don'tCheckOperationsInProgressFlg 
								  MenuPosition QuietFlg ReadOnlyFlg 
								  Don'tCheckForTruncationFlg)))
				  (Truncate% File (RETURN (NC.ProcessTruncationRequest NoteFile 
									       NoteFilesHashArray 
								      Don'tCacheTypesAndTitlesFlg 
										   Don'tCreateFlg 
									     Convertw/oConfirmFlg 
									      Don'tCreateArrayFlg 
										 Can'tTruncateFlg 
									  Don'tCreateInterfaceFlg 
									  Don'tGetSpecialCardsFlg 
										     PromptWindow 
										  PublicOrPrivate 
								Don'tCheckOperationsInProgressFlg 
										     MenuPosition 
											 QuietFlg 
										      ReadOnlyFlg 
								       Don'tCheckForTruncationFlg)))
				  (SHOULDNT 
				     "Illegal menu option selected in NC.AskUserAboutTruncation."))
	      else 

          (* * No TruncationFn. Tell the user if appropriate and return an error msg.)


		     (if (WINDOWP PromptWindow)
			 then (NC.PrintMsg PromptWindow NIL 
					       "No file truncation possible for this NoteFile."
					       (CHARACTER 13)
					       "See a NoteCards wizard."
					       (CHARACTER 13)))
		     (RETURN (QUOTE NoteFileNeedsTruncation))))))

(NC.ProcessInspectAndRepairRequest
  (LAMBDA (NoteFile NoteFilesHashArray Don'tCacheTypesAndTitlesFlg Don'tCreateFlg 
		    Convertw/oConfirmFlg Don'tCreateArrayFlg Can'tTruncateFlg Don'tCreateInterfaceFlg 
		    Don'tGetSpecialCardsFlg PromptWindow PublicOrPrivate 
		    Don'tCheckOperationsInProgressFlg MenuPosition QuietFlg ReadOnlyFlg 
		    Don'tCheckForTruncationFlg)              (* rht: " 1-Nov-86 19:15")

          (* * Do an an InspectAndRepair on a file then try to reopen. Used when checkpoint pinter out of sorts during an 
	  Open.)



          (* * fgh 5/25/86 First created.)



          (* * fgh 9/1/86 Updated args to match NC.OpenNoteFile.)



          (* * rht 10/31/86: Changed outdated call to NC.RepairNoteFile to NC.InspectAndRepairNoteFile.
	  Added Don'tCheckForTruncationFlg arg. No longer tries to open after NC.InspectAndRepairNoteFile returns.)


    (if (CAR (ERSETQ (NC.InspectAndRepairNoteFile NoteFile NIL PromptWindow)))
	then 

          (* * For now, can't open after NC.InspectAndRepairNoteFile returns because returns before repair has completed.)



          (* * (* * Repair NoteFile succeeded, try to Open the NF now.) (NC.OpenNoteFile NoteFile NoteFilesHashArray 
	  Don'tCacheTypesAndTitlesFlg Don'tCreateFlg Convertw/oConfirmFlg Don'tCreateArrayFlg Can'tTruncateFlg 
	  Don'tCreateInterfaceFlg Don'tGetSpecialCardsFlg PromptWindow PublicOrPrivate T MenuPosition QuietFlg ReadOnlyFlg 
	  Don'tCheckForTruncationFlg))


	       NIL
      else 

          (* * REapir NoteFile failed for some reason. Report and return.)


	     (ERSETQ (NC.ReportError NIL (CONCAT "NoteFile Inspect&RepairFailed for NoteFile "
						       (fetch (NoteFile FullFileName) of NoteFile)
						       )))
	     (QUOTE InspectAndRepairFailed))))

(NC.ProcessNoteFileNeedsConversionError
  (LAMBDA (NoteFile NoteFilesHashArray Don'tCacheTypesAndTitlesFlg Don'tCreateFlg 
		    Convertw/oConfirmFlg Don'tCreateArrayFlg Can'tTruncateFlg Don'tCreateInterfaceFlg 
		    Don'tGetSpecialCardsFlg PromptWindow PublicOrPrivate 
		    Don'tCheckOperationsInProgressFlg MenuPosition QuietFlg ReadOnlyFlg 
		    Don'tCheckForTruncationFlg)              (* rht: "31-Oct-86 23:00")

          (* * Discovered NoteFile needs version conversion when attempted to open it. Process that error.)



          (* * fgh 5/23/86 First created.)



          (* * fgh 9/1/86 Updated args to match NC.OpenNoteFile.)



          (* * rht 10/31/86: Added Don'tCheckForTruncationFlg arg.)


    (LET (ConversionFn ReturnValue)

          (* * If appropriate, notify the user.)


         (if (WINDOWP PromptWindow)
	     then (NC.PrintMsg PromptWindow T "NoteFile " (fetch (NoteFile FullFileName)
								 of NoteFile)
				   "is an old format file."
				   (CHARACTER 13)))

          (* * If the device has a ConversionFn, then apply it and try to Open the NoteFile.)


         (if (SETQ ConversionFn (fetch (NoteFile ConvertNoteFileFormatFn) of NoteFile))
	     then 

          (* * ask the user if conversion should be done. If so, do it, else return an error msg,)


		    (if (OR Convertw/oConfirmFlg (NC.AskYesOrNo 
						  "Do you want to convert it to the new format? "
								      " -- " "Y" NIL PromptWindow))
			then 

          (* * go ahead and convert.)


			       (if (type? NoteFile (CAR (ERSETQ (SETQ ReturnValue
									  (APPLY* ConversionFn 
										    NoteFile)))))
				   then 

          (* * Conversion successful, Open the note file.)


					  (NC.OpenNoteFile NoteFile NoteFilesHashArray 
							     Don'tCacheTypesAndTitlesFlg 
							     Don'tCreateFlg Convertw/oConfirmFlg 
							     Don'tCreateArrayFlg Can'tTruncateFlg 
							     Don'tCreateInterfaceFlg 
							     Don'tGetSpecialCardsFlg PromptWindow 
							     PublicOrPrivate T MenuPosition QuietFlg 
							     ReadOnlyFlg Don'tCheckForTruncationFlg)
				 else 

          (* * Error during conversion fn. report and get out of here.)


					(SELECTQ ReturnValue
						   (PROGN (ERSETQ
							      (NC.ReportError
								NIL
								(CONCAT 
						"NoteFile format conversion failed for NoteFile "
									  (fetch (NoteFile 
										     FullFileName)
									     of NoteFile))))
							    (QUOTE NoteFileConversionFailed))))
		      else 

          (* * User said don't convert. Just return)


			     (QUOTE NoteFileNeedsConversion))
	   else 

          (* * No conversion fn. Tell the user if appropriate and return an error msg.)


		  (if (WINDOWP PromptWindow)
		      then (NC.PrintMsg PromptWindow NIL "No format conversion possible."
					    (CHARACTER 13)
					    "See a NoteCards wizard."
					    (CHARACTER 13)))
		  (QUOTE NoteFileNeedsConversion)))))

(NC.ProcessNoteFileNotFoundError
  (LAMBDA (NoteFile NoteFilesHashArray Don'tCacheTypesAndTitlesFlg Don'tCreateFlg 
		    Convertw/oConfirmFlg Don'tCreateArrayFlg Can'tTruncateFlg Don'tCreateInterfaceFlg 
		    Don'tGetSpecialCardsFlg InterestedWindow PublicOrPrivate 
		    Don'tCheckOperationsInProgressFlg MenuPosition QuietFlg ReadOnlyFlg 
		    Don'tCheckForTruncationFlg)              (* rht: "31-Oct-86 22:59")

          (* * NoteFile couldnot be found when an attempt was made to open it. Find out if the user wants to create it.)



          (* * fgh 5/23/86 First created.)



          (* * fgh 9/1/86 Updated args to match NC.OpenNoteFIle.)



          (* * rht 10/31/86: Added Don'tCheckForTruncationFlg arg.)


    (if QuietFlg
	then 

          (* * If QuietFlg is set, then we'll just have to send back a error notification.)


	       (QUOTE NoteFileNotFound)
      else 

          (* * Otherwise, we can interact with the user.)


	     (LET (NewFileName)

          (* * Notify user of the error)


	          (NC.PrintMsg InterestedWindow T "Could not find NoteFile " (fetch (NoteFile
											  
										     FullFileName)
										  of NoteFile)
				 (CHARACTER 13))

          (* * If the user wants to create the file, then create it and try the open again.)


	          (if (AND (NULL Don'tCreateFlg)
			       (NC.AskYesOrNo (CONCAT "Do you want to create "
							  (fetch (NoteFile FullFileName)
							     of NoteFile))
						" -- " "Y" NIL InterestedWindow T NIL))
		      then (if (CAR (ERSETQ (SETQ NewFileName (NC.CreateNoteFile
							NoteFile NIL NIL InterestedWindow
							(CONCAT "Opening NoteFile" (CHARACTER
								    13))))))
				 then (NC.OpenNoteFile NoteFile NoteFilesHashArray 
							   Don'tCacheTypesAndTitlesFlg Don'tCreateFlg 
							   Convertw/oConfirmFlg Don'tCreateArrayFlg 
							   Can'tTruncateFlg Don'tCreateInterfaceFlg 
							   Don'tGetSpecialCardsFlg InterestedWindow 
							   PublicOrPrivate T MenuPosition QuietFlg 
							   ReadOnlyFlg Don'tCheckForTruncationFlg))
		    else (QUOTE NoteFileNotFound))))))

(NC.InspectAndRepairNoteFile
  (LAMBDA (NoteFileOrFileName ReadSubstancesFlg InterestedWindow)
                                                             (* fgh: " 1-Sep-86 19:36")

          (* * Check to be sure file is closed before calling real inspect and repair.)



          (* * rht 7/16/86: Added InterestedWindow arg. Removed call to NC.OpenDatabaseFile.)



          (* * rht 7/17/86: Now works with file name args as well as notefile args. Took out reopen'ing of notefile, because 
	  you don't know how it was originally opened.)



          (* * fgh 9/1/86 Now just a wrapper for the device specific inspect & repair fn. Old functionality is in 
	  NCLocalDevice.InspectAndRepairNoteFile.)


    (LET (NoteFileName)

          (* * Get the name of the file to be compacted)


         (SETQ NoteFileName (COND
	     ((NULL NoteFileOrFileName)
	       (PROG1 (NC.DatabaseFileName "Name of NoteFile to be compacted:" " -- " T NIL NIL 
					       InterestedWindow)
			(NC.ClearMsg InterestedWindow)))
	     ((type? NoteFile NoteFileOrFileName)
	       (fetch (NoteFile FullFileName) of NoteFileOrFileName))
	     (T NoteFileOrFileName)))

          (* * Apply the device specific repair notefile fn for the file's host.)


         (APPLY* (fetch (NoteFileDevice RepairNoteFileFn) of (NC.DeviceVectorForHost
								     (FILENAMEFIELD NoteFileName
										      (QUOTE HOST))
								     (QUOTE PRIVATE)))
		   NoteFileOrFileName ReadSubstancesFlg InterestedWindow))))
)
(* * Changes to NCREPAIR)

(DEFINEQ

(NC.ScavengeDatabaseFile
  (LAMBDA (NoteFileOrFileName BadLinkLabelsFlg ListOfBoxesToReconstruct 
			      ListOfCardsNeedingGlobalLinksReconstructed InterestedWindow)
                                                             (* rht: "29-Oct-86 16:22")

          (* Scavenge the database FileName. Essentially throw away all of the information about From and ToLinks and 
	  recreate them by retrieving the link information from the substance of each card and from the list of global links 
	  from the card.)



          (* * rht 8/9/84: Now calls NC.OpenDatabaseFile to do the file open.)



          (* * rht 7/17/85: Changed so can take a stream argument. Also handles link labels. If BadLinkLabelsFlg is non-nil, 
	  then don't try to read current link labels. Just rebuild them from what's out there. Otherwise, only rebuild if 
	  find new any new ones.)



          (* * fgh 22-Jul-85 Takes a list of bad file box cards and reconstructs the file boxes from the From pointer lists 
	  of all the cards in the NoteFile.)



          (* * fgh 30-Jul-85 Takes a list of cards with bad global links and reconstructs the global links list from the From
	  pointer lists of all the cards in the NoteFile.)



          (* * rht 11/23/85: Updated to handle new notefile and card object formats.)



          (* * rht 12/1/85: Now calls NC.GetMainCardData and NC.GetLinks instead of NC.GetNoteCard.)



          (* * rht 12/19/85: Massive overhaul for sake of speed. Should be wizzier now.)



          (* * fgh 2/4/86 Now works on open NFs. No need to error check since this function should always be called from 
	  earlier phases of the inspect & repaier.)



          (* * fgh 5/21/86 Fixed bug in handling of global links.)



          (* * rht 7/16/86: Added InterestedWindow arg.)



          (* * rht 7/16/86: Now calls NC.PutLinks passing UseOldDatesFlg.)



          (* * rht 9/5/86: Now checks that link is valid before passing it to NC.DelReferencesToCard.)



          (* * rht 10/29/86: Now closes prompt win at end if no filing info to tell.)


    (PROG (NoteFile FileName CardTotal NoteCardNumber OldLinkLabels DiscoveredLinkLabels 
		      ReconstructLinks ReconstructGlobalLinks ToBeFiledCards)

          (* * First, take care of checking stream's validity, etc.)


	    (SETQ FileName (if (type? NoteFile NoteFileOrFileName)
				 then (SETQ NoteFile NoteFileOrFileName)
					(fetch (NoteFile FullFileName) of NoteFileOrFileName)
			       else NoteFileOrFileName))   (* Try to open notefile.)
	    (if (NULL (OPENP FileName))
		then (if (NULL (SETQ NoteFile
				       (NC.OpenDatabaseFile FileName NIL T NIL NIL NIL NIL T T NIL 
							      InterestedWindow)))
			   then (NC.PrintMsg InterestedWindow NIL "Couldn't open " FileName "."
						 (CHARACTER 13)
						 "Repair aborted.")
				  (RETURN NIL)))

          (* * If link labels aren't screwed up, then read them in.)


	    (OR BadLinkLabelsFlg (SETQ OldLinkLabels (NC.RetrieveLinkLabels NoteFile T)))

          (* * Mark every card that needs its global links or substance reconstructed so we don't have to search the lists so
	  much.)


	    (for Card in ListOfCardsNeedingGlobalLinksReconstructed do (NC.SetUserDataProp
									       Card
									       (QUOTE 
								 NeedsGlobalLinksReconstructedFlg)
									       T))
	    (for Box in ListOfBoxesToReconstruct do (NC.SetUserDataProp Box (QUOTE 
									   NeedsReconstructingFlg)
										T))

          (* Read through all NoteCard substances to find actual pointers. Use this to create the To Links list.
	  The list collection function checks to make sure each link is valid.)


	    (SETQ CardTotal (SUB1 (fetch (NoteFile NextIndexNum)
					       NoteFile)))
	    (NC.PrintMsg InterestedWindow T "Rebuilding notefile links." (CHARACTER 13)
			   "Collecting Links for item " 1 " out of " CardTotal ".")
	    (SETQ NoteCardNumber 0)
	    (NC.MapCards
	      NoteFile
	      (FUNCTION (LAMBDA (Card)
		  (BLOCK)
		  (SETQ NoteCardNumber (ADD1 NoteCardNumber))
		  (AND (ZEROP (REMAINDER NoteCardNumber 10))
			 (NC.PrintMsg InterestedWindow T "Rebuilding notefile links." (CHARACTER
					  13)
					"Collecting Links for item " NoteCardNumber " out of " 
					CardTotal "."))
		  (if (NC.FetchUserDataProp Card (QUOTE NeedsReconstructingFlg))
		      then                                 (* Card substance and links will be reconstructed so 
							     no need to try to read substance.)
			     (NC.GetLinks Card)
			     (if (NOT (NC.FetchUserDataProp Card (QUOTE 
								 NeedsGlobalLinksReconstructedFlg)))
				 then (NC.SetUserDataProp Card (QUOTE ScavengerToLinks)
							      (NC.FetchGlobalLinks Card))
					(NC.SetUserDataProp Card (QUOTE ScavengerGlobalLinks)
							      (NC.FetchGlobalLinks Card)))
			     (NC.DeactivateCard Card T)
		    else (NC.GetMainCardData Card)
			   (NC.GetLinks Card)
			   (NC.ActivateCard Card)
			   (if (EQ (NC.FetchStatus Card)
				       (QUOTE ACTIVE))
			       then                        (* Collect links having active destinations.
							     Delete the others.)
				      (NC.SetUserDataProp
					Card
					(QUOTE ScavengerToLinks)
					(NCONC (for Link in (CAR (NC.CollectReferences
									   Card))
						    eachtime (BLOCK)
						    when (if (EQ (NC.FetchStatus
									 (fetch (Link 
										  DestinationCard)
									    of Link))
								       (QUOTE ACTIVE))
							     else (AND (type? Link Link)
									   (NC.DelReferencesToCard
									     Card Link))
								    NIL)
						    collect Link)
						 (if (NC.FetchUserDataProp Card (QUOTE 
								 NeedsGlobalLinksReconstructedFlg))
						   else (NC.SetUserDataProp Card (QUOTE 
									     ScavengerGlobalLinks)
										(NC.FetchGlobalLinks
										  Card))
							  (NC.FetchGlobalLinks Card))))
				      (if (NC.FetchUserDataProp Card (QUOTE 
								 NeedsGlobalLinksReconstructedFlg))
					else (NC.SetUserDataProp Card (QUOTE 
									     ScavengerGlobalLinks)
								     (NC.FetchGlobalLinks Card)))

          (* If there are file boxes to be reconstructed, then look thru the From links to see if this card was filed in one 
	  of the to-be-reconstructed boxes)


				      (AND ListOfBoxesToReconstruct
					     (for Link in (NC.FetchFromLinks Card)
						eachtime (BLOCK)
						when (AND (NC.ChildLinkP Link)
							      (NC.FetchUserDataProp
								(fetch (Link SourceCard)
								   of Link)
								(QUOTE NeedsReconstructingFlg)))
						do (push ReconstructLinks Link)))

          (* If there are global links to be reconstructed, then look thru the From links to see if this card had a global 
	  link from a card whose global links need reconstructing.)


				      (AND ListOfCardsNeedingGlobalLinksReconstructed
					     (for Link in (NC.FetchFromLinks Card)
						eachtime (BLOCK)
						when (AND (NC.GlobalLinkP Link)
							      (NC.FetchUserDataProp
								(fetch (Link SourceCard)
								   of Link)
								(QUOTE 
								 NeedsGlobalLinksReconstructedFlg)))
						do (push ReconstructGlobalLinks Link)))
				      (NC.DeactivateCard Card T))))))

          (* * Reconstruct any cards as requested)


	    (for BoxToReconstruct in ListOfBoxesToReconstruct eachtime (BLOCK)
	       do                                          (* Make a new file box using the given card.)
		    (NC.MakeNoteCard (QUOTE FileBox)
				       NoteFile "Untitled: Reconstructed during repair" T NIL 
				       BoxToReconstruct)

          (* File cards whose from links indicate that they used to be filed in this file box. Also add these new links to 
	  collected ToLinks.)


		    (NC.SetUserDataProp BoxToReconstruct (QUOTE ScavengerToLinks)
					  (APPEND (NC.FetchUserDataProp BoxToReconstruct
									    (QUOTE ScavengerToLinks)
									    )
						    (for Link in ReconstructLinks
						       eachtime (BLOCK)
						       when (NC.SameCardP BoxToReconstruct
									      (fetch (Link 
										       SourceCard)
										 of Link))
						       collect (NC.MakeChildLink
								   (fetch (Link DestinationCard)
								      of Link)
								   BoxToReconstruct NIL))))
                                                             (* Put the card away)
		    (NC.PutMainCardData BoxToReconstruct)
		    (NC.DeactivateCard BoxToReconstruct T))

          (* * Reconstruct any global link lists as required)


	    (for Link in ReconstructGlobalLinks bind ThisCardsToLinks ThisCardsGlobalLinks 
							   SourceCard
	       eachtime (BLOCK)
	       do (SETQ SourceCard (fetch (Link SourceCard) of Link)) 
                                                             (* Add it to the GlobalLinks list for its source card 
							     unless it's already there.)
		    (if (for GlobalLink in (SETQ ThisCardsGlobalLinks (NC.FetchUserDataProp
						     SourceCard
						     (QUOTE ScavengerGlobalLinks)))
			     eachtime (BLOCK) never (NC.SameLinkP Link GlobalLink))
			then (NC.SetUserDataProp SourceCard (QUOTE ScavengerGlobalLinks)
						     (CONS Link ThisCardsGlobalLinks)))
                                                             (* Add it to the source card's ToLinks list unless 
							     it's already there)
		    (if (for ToLink in (SETQ ThisCardsToLinks (NC.FetchUserDataProp
						 SourceCard
						 (QUOTE ScavengerToLinks)))
			     eachtime (BLOCK) never (NC.SameLinkP Link ToLink))
			then (NC.SetUserDataProp SourceCard (QUOTE ScavengerToLinks)
						     (CONS Link ThisCardsToLinks))))

          (* * Compute the From Links list by "inverting" the To Links list)


	    (NC.PrintMsg InterestedWindow T "Repairing NoteFile." (CHARACTER 13)
			   "Inverting links for item " 1 " out of " CardTotal ".")
	    (SETQ NoteCardNumber 0)
	    (NC.MapCards NoteFile (FUNCTION (LAMBDA (Card)
			     (SETQ NoteCardNumber (ADD1 NoteCardNumber))
			     (AND (ZEROP (REMAINDER NoteCardNumber 100))
				    (NC.PrintMsg InterestedWindow T "Repairing NoteFile."
						   (CHARACTER 13)
						   "Inverting links for item " NoteCardNumber 
						   " out of "
						   CardTotal "."))
			     (if (EQ (NC.FetchStatus Card)
					 (QUOTE ACTIVE))
				 then (for Link in (NC.FetchUserDataProp Card (QUOTE 
										 ScavengerToLinks))
					   bind DestinationCard LinkLabel eachtime (BLOCK)
					   do              (* Add this ToLink as a FromLink for the link's 
							     destination card.)
						(NC.SetUserDataProp (SETQ DestinationCard
									(fetch (Link 
										  DestinationCard)
									   of Link))
								      (QUOTE ScavengerFromLinks)
								      (CONS Link
									      (NC.FetchUserDataProp
										DestinationCard
										(QUOTE 
									       ScavengerFromLinks))))
                                                             (* Accumulate the link labels into a list.)
						(if (NOT (FMEMB (SETQ LinkLabel
									(fetch (Link Label)
									   of Link))
								      DiscoveredLinkLabels))
						    then (push DiscoveredLinkLabels LinkLabel)))))
			   ))

          (* * Reset all of the To and From Links lists in the database)


	    (NC.PrintMsg InterestedWindow T "Repairing NoteFile." (CHARACTER 13)
			   "Rewriting links for item " 1 " out of " CardTotal ".")
	    (SETQ NoteCardNumber 0)
	    (NC.MapCards NoteFile (FUNCTION (LAMBDA (Card)
			     (SETQ NoteCardNumber (ADD1 NoteCardNumber))
			     (AND (ZEROP (REMAINDER NoteCardNumber 10))
				    (NC.PrintMsg InterestedWindow T "Repairing NoteFile."
						   (CHARACTER 13)
						   "Rewriting links for item " NoteCardNumber 
						   " out of "
						   CardTotal "."))
			     (if (EQ (NC.FetchStatus Card)
					 (QUOTE ACTIVE))
				 then (NC.SetGlobalLinks Card (NC.FetchUserDataProp
							       Card
							       (QUOTE ScavengerGlobalLinks)))
					(NC.SetToLinks Card (NC.FetchUserDataProp Card
										      (QUOTE 
										 ScavengerToLinks)))
					(NC.SetFromLinks Card (NC.FetchUserDataProp Card
											(QUOTE
											  
									       ScavengerFromLinks)))
                                                             (* Check whether this card isn't filed anywhere.)
					(if (AND (NOT (NC.UndeletableCardP Card))
						     (for Link in (NC.FetchFromLinks Card)
							eachtime (BLOCK) never (NC.ChildLinkP
										       Link)))
					    then (push ToBeFiledCards Card))
					(NC.PutLinks Card T))
                                                             (* Clean any junk off the card.)
			     (NC.DeactivateCard Card T)
			     (NC.SetUserDataPropList Card NIL))))

          (* * File any unfiled cards in the ToBeFiled box.)


	    (if ToBeFiledCards
		then (NC.PrintMsg InterestedWindow T "Filing " (LENGTH ToBeFiledCards)
				      " cards in ToBeFiled box ...")
		       (NCP.FileCards ToBeFiledCards (fetch (NoteFile ToBeFiledCard)
							  of NoteFile)))
                                                             (* Rewrite link labels if we've found any new ones.)
	    (if (LDIFFERENCE DiscoveredLinkLabels OldLinkLabels)
		then (NC.StoreLinkLabels NoteFile (UNION DiscoveredLinkLabels OldLinkLabels)))
                                                             (* Clean up and get out.)
	    (NC.CheckpointDatabase NoteFile T)
	    (NC.ForceDatabaseClose NoteFile)
	    (NC.PrintMsg InterestedWindow T "Repair Completed for " (FULLNAME FileName)
			   ".")
	    (if ToBeFiledCards
		then (NC.PrintMsg InterestedWindow NIL "Filed " (LENGTH ToBeFiledCards)
				      " cards in ToBeFiled box.")
	      else (NC.ClearMsg InterestedWindow T)))))

(NC.ScavengerPhase1
  (LAMBDA (FileNameOrNoteFile ReadSubstancesFlg ScavengerInteractionWin RecheckBadCardsFlg 
			      InterestedWindow)              (* rht: "31-Oct-86 23:56")

          (* * This is the first phase of the scavenger. Runs over entire data portion of the notefile, accumulating pointers
	  to healthy parts of cards. Then runs over index array asking user what to do with bad or outdated pointers.
	  If ReadSubstancesFlg is non-nil then it'll do robust gets of the substances. This slows things down, but makes 
	  checking more comprehensive.)



          (* * rht 12/7/85: Updated to handle new notefile and card object formats.)



          (* * rht 3/22/86: No longer hangs bad cards off proplist of Reason atoms. Uses local var ReasonsHashArray instead.
	  NC.ScavengerPhase1 no longer hanging on completion of phase 3)



          (* * rht 7/7/86: Now passes non-nil Don'tCheckOperationInProgress flg to NC.OpenDatabaseFile.)



          (* * rht 7/16/86: Added InterestedWindow arg.)



          (* * rht 9/16/86: Changed call to NC.OpenDatabaseFile so that it won't try to get special cards.)



          (* * rht 10/31/86: Changed call from NC.OpenDatabaseFile to NC.OpenNoteFile. Now returns non-nil if successful.)


    (DECLARE (GLOBALVARS NC.ScavengerAttachedMenuFont NC.ScavengerInteractionWinRegion))
    (PROG (FileName NoteFile UnknownCardTypesList ReasonsList ReasonsHashArray CardsToDelete Menu 
		      MenuItems LinkLabelsNews CardTotal BadNewsList BadBoxes ExtraBadNews 
		      FirstTimeFlg InspectorPendingEvent NoteFileMenu NoteFileOpsMenuItem 
		      CanDoPhase3Flg NoteFileStream)

          (* * First, take care of opening notefile if needed.)


	    (if (AND (type? NoteFile FileNameOrNoteFile)
			 (SETQ NoteFileStream (fetch (NoteFile Stream) of FileNameOrNoteFile))
			 (OPENP NoteFileStream))
		then                                       (* This notefile is already open For when we do 
							     recursive call.)
		       (SETQ NoteFile FileNameOrNoteFile)
	      else                                         (* Get file name and open the file if conditions are 
							     okay.)
		     (SETQ FileName FileNameOrNoteFile)
		     (AND (NULL FileName)
			    (NULL (SETQ FileName (NC.DatabaseFileName 
					   "What is the name of the NoteFile to Inspect&Repair? "
									    NIL T NIL NIL 
									    InterestedWindow)))
			    (RETURN NIL))
		     (AND (NULL (SETQ NoteFile
				      (NC.OpenNoteFile FileName NIL T NIL NIL NIL NIL T T 
							 InterestedWindow NIL T NIL NIL NIL T)))
			    (NC.PrintMsg InterestedWindow NIL "Couldn't open " FileName "."
					   (CHARACTER 13)
					   "Repair aborted.")
			    (RETURN NIL))
		     (NC.ClearMsg InterestedWindow T))
	    (SETQ CardTotal (SUB1 (fetch (NoteFile NextIndexNum) of NoteFile)))
                                                             (* Build a window for talking to the user if one 
							     wasn't passed in.)
	    (if (WINDOWP ScavengerInteractionWin)
		then (CLEARW ScavengerInteractionWin)
	      else (SETQ ScavengerInteractionWin (CREATEW NC.ScavengerInteractionWinRegion 
							      "Inspect&Repair Interaction Window"
								NIL T))
                                                             (* This flg indicates that we're in the first call to 
							     the scavenger.)
		     (SETQ FirstTimeFlg T)
		     (WINDOWADDPROP ScavengerInteractionWin (QUOTE CLOSEFN)
				      (FUNCTION NC.MessageWinCloseFn)
				      T))                    (* Stash InterestedWindow for calls to phase 3 under 
							     menu whenselected fn.)
	    (OR (WINDOWPROP ScavengerInteractionWin (QUOTE INTERESTEDWINDOW))
		  (WINDOWPROP ScavengerInteractionWin (QUOTE INTERESTEDWINDOW)
				InterestedWindow))           (* Get all relevant info about the data area of the 
							     notefile onto the cards' prop lists.)
	    (if (OR (NOT FirstTimeFlg)
			(EQ (NC.GetScavengerInfo NoteFile ReadSubstancesFlg 
						     ScavengerInteractionWin InterestedWindow)
			      (QUOTE SUCCESS)))
		then (WINDOWPROP ScavengerInteractionWin (QUOTE NOTEFILE)
				     NoteFile)
		       (WINDOWPROP ScavengerInteractionWin (QUOTE CARDTOTAL)
				     CardTotal)
	      else                                         (* Something's wrong. Couldn't get scavenger info.
							     Bail out.)
		     (NC.ScavengerCleanup ScavengerInteractionWin InterestedWindow)
		     (CLOSEW ScavengerInteractionWin)
		     (RETURN NIL))

          (* * Check the list of card types that are undefined to see if user has loaded a definition since the last time we 
	  checked. If he has, then go try to read the substance card parts for those newly defined card types.)


	    (NC.CheckUnknownCardTypes NoteFile ReadSubstancesFlg ScavengerInteractionWin)

          (* * Next step is to run down the in-core index and find those cards having pointers to bad items in the data area.
	  We also need to look for undefined card types and for pointers past the checkpoint pointer.
	  However, we can reuse old bad news list if nothing has changed.)


	    (if (OR FirstTimeFlg RecheckBadCardsFlg (WINDOWPROP ScavengerInteractionWin
								      (QUOTE NEEDCHECKPOINT)))
		then (WINDOWPROP ScavengerInteractionWin (QUOTE ORIGINALBADNEWSLIST)
				     (SETQ BadNewsList (NC.BuildBadCardsList NoteFile 
									  ScavengerInteractionWin 
										 FirstTimeFlg 
										 InterestedWindow)))
	      else (SETQ BadNewsList (WINDOWPROP ScavengerInteractionWin (QUOTE 
									      ORIGINALBADNEWSLIST))))

          (* * Okay, now all the troublesome IDs and the reasons for their troubles are recorded in BadNewsList.
	  We next need to get directives from the user as to what to do for each problem card.)


	    (NC.RepositionWindowIfNeeded ScavengerInteractionWin)
                                                             (* If there's bad news for link labels then take off 
							     list and store in a local var.)
	    (if (SETQ LinkLabelsNews (for BadCardEntry in BadNewsList
					    bind (LinkLabelsCard ←(fetch (NoteFile LinkLabelsCard)
								       of NoteFile))
					    eachtime (BLOCK) when (NC.SameCardP 
										   LinkLabelsCard
											(CAR 
										     BadCardEntry))
					    do (RETURN BadCardEntry)))
		then (SETQ BadNewsList (DREMOVE LinkLabelsNews BadNewsList)))
                                                             (* Accumulate general statistics on the problems.)
	    (SETQ ReasonsHashArray (HASHARRAY 100))
	    (for BadNews in BadNewsList bind Card Type eachtime (BLOCK)
	       unless (FMEMB (CADR BadNews)
				 (QUOTE (DELETED FREE)))
	       do (SETQ Card (CAR BadNews))
		    (for Reason in (CDDDR BadNews) eachtime (BLOCK)
		       do (PUTHASH Reason (CONS Card (GETHASH Reason ReasonsHashArray))
				       ReasonsHashArray)
			    (if (NOT (FMEMB Reason ReasonsList))
				then (SETQ ReasonsList (CONS Reason ReasonsList)))
			    (if (EQ Reason (QUOTE UNKNOWNCARDTYPE))
				then                       (* Accumulate the list of unknown card types for 
							     nondeleted cards.)
				       (if (NOT (FMEMB (SETQ Type (
								 NC.FetchTypeFromScavengerInfo
								 Card))
							     UnknownCardTypesList))
					   then (push UnknownCardTypesList Type)))))
                                                             (* Build the menu entries that we know will be present
							     regardless of which cards are bad.)
	    (SETQ MenuItems (QUOTE ((Abort (QUOTE Abort)
					       "Quit this Inspect&Repair operation.")
					 (Recheck% Bad% Cards (QUOTE Recheck% Bad% Cards)
							      
	    "Recompute bad cards list.  Useful if you've just loaded some card type definitions.")
					 (Inspect% Cards (QUOTE Inspect% Cards)
							 "Bring up the cards inspector menu."
							 (SUBITEMS (Include% Deleted% Cards
								     (QUOTE Include% Deleted% Cards)
								     
								"Throw in deleted cards as well.")))))
	      )                                              (* Print a message if news on link labels is worse 
							     than just past checkpoint.)
	    (if (AND LinkLabelsNews (NOT (EQUAL (CDDDR LinkLabelsNews)
							(QUOTE (MAINDATAPASTCHKPT)))))
		then (push ExtraBadNews LinkLabelsNews)
		       (NC.PrintMsg ScavengerInteractionWin NIL "The link types are bad."
				      (CHARACTER 13)
				      
"If you don't back them up to a previous version, then phase 3 of Inspect&Repair will rebuild them."
				      (CHARACTER 13))
		       (WINDOWPROP ScavengerInteractionWin (QUOTE NEEDLINKSCAVENGE)
				     T))                     (* Collect any fileboxes that have bad substances.)
	    (if (SETQ BadBoxes (LET (Boxes)
				        (SETQ BadNewsList
					  (for News in BadNewsList bind Box eachtime
										   (BLOCK)
					     unless (if (AND (EQ (
								    NC.FetchTypeFromScavengerInfo
									   (SETQ Box (CAR News)))
									 (QUOTE FileBox))
								   (FMEMB (QUOTE BADMAINDATA)
									    (CDDDR News)))
							  then (push Boxes Box) 
                                                             (* If nothing else is wrong with those boxes, then 
							     take off bad news list.)
								 (EQ (LENGTH (CDDDR News))
								       1)
							else NIL)
					     collect News))
				    Boxes))
		then (NC.PrintMsg ScavengerInteractionWin NIL "Fileboxes "
				      (for Box in BadBoxes collect (
								   NC.FetchTitleFromScavengerInfo
									   Box))
				      " have bad substance(s)."
				      (CHARACTER 13)
				      
"If you don't delete them or back up to a previous version, then phase 3 of Inspect&Repair will rebuild their contents."
				      (CHARACTER 13))
		       (WINDOWPROP ScavengerInteractionWin (QUOTE NEEDLINKSCAVENGE)
				     T))                     (* Print out totals of active and deleted cards.)
	    (LET ((ActivesTotal 0)
		  (DeletedsTotal 0))
	         (NC.MapCards NoteFile (FUNCTION (LAMBDA (Card)
				  (SELECTQ (NC.FetchStatus Card)
					     (ACTIVE (SETQ ActivesTotal (ADD1 ActivesTotal)))
					     (DELETED (SETQ DeletedsTotal (ADD1 DeletedsTotal)))
					     NIL))))
	         (NC.PrintMsg ScavengerInteractionWin NIL "Out of " CardTotal " cards:"
				(CHARACTER 13)
				"there are " ActivesTotal " active cards and " DeletedsTotal 
				" deleted cards."
				(CHARACTER 13)))
	    (if ReasonsList
		then                                       (* Print out messages for bad cards.)
		       (NC.PrintMsg ScavengerInteractionWin NIL "Of the non-deleted ones,"
				      (CHARACTER 13))
		       (for Reason in ReasonsList eachtime (BLOCK)
			  do (NC.PrintMsg ScavengerInteractionWin NIL (LENGTH (GETHASH Reason 
										 ReasonsHashArray))
					      " have "
					      (GETPROP Reason (QUOTE ReasonString))
					      (CHARACTER 13))
			       (if (EQ Reason (QUOTE UNKNOWNCARDTYPE))
				   then (NC.PrintMsg ScavengerInteractionWin NIL 
							 "The unknown types are: "
							 UnknownCardTypesList "." (CHARACTER 13))))
	      else (NC.PrintMsg ScavengerInteractionWin NIL "All non-deleted cards look okay."
				    (CHARACTER 13)))

          (* Only allow continuation to phase 3 of repair, links rebuilding, if there's no bad news that can't be fixed.
	  We can fix bad proplist, titles or links. We can also fix even bad substances if they're for fileboxes.)


	    (if (for News in BadNewsList eachtime (BLOCK)
		     unless (FMEMB (CADR News)
				       (QUOTE (DELETED FREE)))
		     unless (EQ (NC.FetchTypeFromScavengerInfo (CAR News))
				    (QUOTE FileBox))
		     never (INTERSECTION (CDDDR News)
					     (QUOTE (BADMAINDATA UNKNOWNCARDTYPE))))
		then                                       (* Add the appropriate menu items.)
		       (if (NOT (WINDOWPROP ScavengerInteractionWin (QUOTE NEEDLINKSCAVENGE)))
			   then (SETQ MenuItems (CONS (QUOTE (End% Inspect&Repair
								       (QUOTE End% Inspect&Repair)
								       
				      "This exits Inspect&Repair normally, closing the notefile."))
							    MenuItems)))
		       (SETQ CanDoPhase3Flg T)
		       (SETQ MenuItems (CONS (QUOTE (Continue% Repair (QUOTE Continue% Repair)
									    
					       "Complete Inspect&Repair by rebuilding the links."))
						 MenuItems)))
                                                             (* Make sure a checkpoint will happen before 
							     continuing to phase 3 if there are any card parts 
							     beyond the checkpt pointer.)
	    (if (INTERSECTION ReasonsList (QUOTE (MAINDATAPASTCHKPT LINKSPASTCHKPT 
									  TITLEPASTCHKPT 
									  PROPLISTPASTCHKPT)))
		then (AND CanDoPhase3Flg (NC.PrintMsg ScavengerInteractionWin NIL 
		  "'Continue Repair' will integrate any card part versions beyond chkpt pointer."
							    (CHARACTER 13)))
		       (WINDOWPROP ScavengerInteractionWin (QUOTE NEEDCHECKPOINT)
				     T))                     (* Ugliness! Have to cache all these vars on window so
							     that attached menu's whenselectedfn will be able to 
							     grab them.)
	    (WINDOWPROP ScavengerInteractionWin (QUOTE BADNEWSLIST)
			  BadNewsList)
	    (WINDOWPROP ScavengerInteractionWin (QUOTE EXTRABADNEWS)
			  ExtraBadNews)
	    (WINDOWPROP ScavengerInteractionWin (QUOTE LINKSLABELSNEWS)
			  LinkLabelsNews)
	    (WINDOWPROP ScavengerInteractionWin (QUOTE BADBOXES)
			  BadBoxes)
	    (ATTACHMENU (create MENU
				    ITEMS ← MenuItems
				    WHENSELECTEDFN ←(FUNCTION 
				      NC.MessageWinAttachedMenuWhenSelectedFn)
				    MENUFONT ← NC.ScavengerAttachedMenuFont)
			  ScavengerInteractionWin
			  (QUOTE RIGHT)
			  (QUOTE TOP))
	    (RETURN NoteFile))))
)
(* * Changes to NCLOCALDEVICE)

(DEFINEQ

(NCLocalDevice.InspectAndRepairNoteFile
  (LAMBDA (NoteFileOrFileName ReadSubstancesFlg InterestedWindow)
                                                             (* rht: "20-Oct-86 14:55")

          (* * Check to be sure file is closed before calling real inspect and repair.)



          (* * rht 7/16/86: Added InterestedWindow arg. Removed call to NC.OpenDatabaseFile.)



          (* * rht 7/17/86: Now works with file name args as well as notefile args. Took out reopen'ing of notefile, because 
	  you don't know how it was originally opened.)



          (* * rht 10/15/86: Now only calls NC.NoteFileOpenP on real notefile objects.)



          (* * rht 10/16/86: Now autoloads NCREPAIR.)


    (LET ((NoteFile (if (type? NoteFile NoteFileOrFileName)
			then NoteFileOrFileName
		      else (NC.NoteFileFromFileName NoteFileOrFileName))))
         (if (AND NoteFile (NC.NoteFileOpenP NoteFile))
	     then (NC.CloseNoteFile NoteFile InterestedWindow))
         (NC.AutoloadApply* (FUNCTION NC.ScavengerPhase1)
			    NoteFileOrFileName ReadSubstancesFlg NIL NIL InterestedWindow))))

(NCLocalDevice.OpenNoteFile
  (LAMBDA (NoteFile PromptWindow Don'tCheckForTruncationFlg)
                                                             (* rht: "31-Oct-86 23:16")

          (* * OpenNoteFileFn for the local, single user device.)



          (* * fgh 5/22/86 First created.)



          (* * fgh 9/1/86 Reimplemented ReadOnly notefile.)



          (* * rht 10/31/86: Added Don'tCheckForTruncationFlg arg.)


    (OR (CAR (ERSETQ (PROG ((FullName (INFILEP (fetch (NoteFile FullFileName)
							    of NoteFile)))
				    EofPtr CriticalUIDs Stream)

          (* * First check for possible errors.)


			           (if (NULL FullName)
				       then 

          (* * Error: NoteFileNotFound, Return)


					      (RETURN (QUOTE NoteFileNotFound))
				     elseif (OPENP FullName)
				       then 

          (* * Error: NoteFile already open, Return)


					      (RETURN (QUOTE NoteFileAlreadyOpen))
				     elseif (NULL (ERSETQ (SETQ Stream
								  (OPENSTREAM
								    FullName
								    (if (fetch (NoteFile 
										      ReadOnlyFlg)
									     of NoteFile)
									then (QUOTE INPUT)
								      else (QUOTE BOTH))
								    (QUOTE OLD)
								    (QUOTE ((TYPE BINARY)))))))
				       then 

          (* * Error: File won't open)


					      (RETURN (QUOTE NoteFileOpenFailed)))

          (* * All is okay for now, create fill in the NoteFile object a bit.)


			           (replace (NoteFile Stream) of NoteFile with Stream)
			           (replace (NoteFile FullFileName) of NoteFile with FullName)
			           (NC.SetMonitor NoteFile (CREATE.MONITORLOCK FullName))

          (* * Make sure stream is not closed by CLOSEALLs)


			           (WHENCLOSE Stream (QUOTE CLOSEALL)
						(QUOTE NO))

          (* * Get the header and check for correct version, correct checkpoint, & plausibility.)


			           (NCLocalDevice.GetNoteFileHeader NoteFile)
			           (SETQ EofPtr (GETEOFPTR (fetch (NoteFile Stream)
								  of NoteFile)))
			           (COND
				     ((NOT (NCLocalDevice.NoteFileVersionOkayP NoteFile))
				       (RETURN (NCLocalDevice.OpenFailed NoteFile (QUOTE 
									  NoteFileNeedsConversion))))
				     ((NOT (NCLocalDevice.PlausibleNoteFileHeaderP NoteFile 
										       EofPtr))
				       (RETURN (NCLocalDevice.OpenFailed NoteFile (QUOTE 
										NoteFileHeaderBad))))
				     ((AND (NULL Don'tCheckForTruncationFlg)
					     (NCLocalDevice.NoteFileNeedsTruncationP NoteFile 
										       EofPtr))
				       (RETURN (NCLocalDevice.OpenFailed NoteFile (QUOTE 
									  NoteFileNeedsTruncation)))))

          (* * Go get the first six card UIDs on the file.)


			           (SETQ CriticalUIDs (NCLocalDevice.GetSpecialCardUIDs NoteFile))
			           (replace (NoteFileCriticalUIDs NoteFile) of CriticalUIDs
				      with (fetch (NoteFile UID) of NoteFile))

          (* * Return with list of special uids and NF-UID.)


			           (RETURN CriticalUIDs))))
	  (PROGN 

          (* * Open must have failed. Return a message to that effect.)


		   (NCLocalDevice.OpenFailed NoteFile)))))
)
(PUTPROPS RHTPATCH127 COPYRIGHT ("Xerox Corporation" 1986))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (1346 28968 (NC.AskUserAboutTruncation 1356 . 2966) (NC.OpenNoteFile 2968 . 16862) (
NC.ProcessNoteFileNeedsTruncationError 16864 . 20112) (NC.ProcessInspectAndRepairRequest 20114 . 21991
) (NC.ProcessNoteFileNeedsConversionError 21993 . 25133) (NC.ProcessNoteFileNotFoundError 25135 . 
27371) (NC.InspectAndRepairNoteFile 27373 . 28966)) (29001 58790 (NC.ScavengeDatabaseFile 29011 . 
43930) (NC.ScavengerPhase1 43932 . 58788)) (58828 63484 (NCLocalDevice.InspectAndRepairNoteFile 58838
 . 60013) (NCLocalDevice.OpenNoteFile 60015 . 63482)))))
STOP