(FILECREATED "31-Aug-86 17:00:57" {ERIS}<LISPCORE>LIBRARY>WHEREIS.;4 21680 changes to: (FNS HASHFILE-WHEREIS WHEREISNOTICE WHEREISNOTICE1) (VARS WHEREISCOMS) previous date: "28-Apr-86 14:00:59" {ERIS}<LISPCORE>LIBRARY>WHEREIS.;3) (* Copyright (c) 1983, 1984, 1986 by Xerox Corporation. All rights reserved.) (PRETTYCOMPRINT WHEREISCOMS) (RPAQQ WHEREISCOMS ((* "WHEREIS from a hashfile") (FILES HASH) (COMS (* "This probably should go into the system somewhere") (FNS \REMOVEOLDVERSIONS)) (FNS HASHFILE-WHEREIS CLOSEWHEREIS WHEREISNOTICE WHEREISNOTICE1) (ADDVARS (WHEREIS.HASH)) (GLOBALVARS WHEREIS.HASH) (DECLARE: DONTEVAL@LOAD DOCOPY (P (MOVD (QUOTE HASHFILE-WHEREIS) (QUOTE WHEREIS))) (ADDVARS (AROUNDEXITFNS CLOSEWHEREIS))) (LOCALVARS . T))) (* "WHEREIS from a hashfile") (FILESLOAD HASH) (* "This probably should go into the system somewhere") (DEFINEQ (\REMOVEOLDVERSIONS [LAMBDA (FULLFILELST) (* rrb "22-Feb-84 18:12") (* removes all but the newest version of any file on FULLFILELST. Slow version as temporary until DIRECTORY has a way of asking for only the most recent version.) (PROG ((EXPANDEDFILELST (for FILE in FULLFILELST collect (UNPACKFILENAME FILE))) UNIQUELST FILE) [for EXPTAIL on EXPANDEDFILELST do (* skip deleted files.) (AND (SETQ FILE (CAR EXPTAIL)) (PROG [(XDIRECTORY (LISTGET FILE (QUOTE DIRECTORY))) (XNAME (LISTGET FILE (QUOTE NAME))) (XEXTENSION (LISTGET FILE (QUOTE EXTENSION))) (XVERSION (LISTGET FILE (QUOTE VERSION] (* go thru the list of expanded files and see if there are any other files on the list with the same name. If so and it is older, delete it. If so and it is newer, don't copy this guy onto the result list.) (for EFLTAIL on (CDR EXPTAIL) do (SETQ FILE (CAR EFLTAIL)) [COND ((AND (EQ (LISTGET FILE (QUOTE NAME)) XNAME) (EQ (LISTGET FILE (QUOTE EXTENSION)) XEXTENSION) (EQ (LISTGET FILE (QUOTE DIRECTORY)) XDIRECTORY)) (COND ((IGREATERP (LISTGET FILE (QUOTE VERSION)) XVERSION) (* XFILE should be deleted) (RETURN NIL)) (T (* mark it deleted. Don't want to play around with the pointers because the enclosing FOR is using the same list.) (RPLACA EFLTAIL NIL] finally (SETQ UNIQUELST (CONS (CAR EXPTAIL) UNIQUELST] (RETURN (for UFILE in UNIQUELST collect (PACKFILENAME UFILE]) ) (DEFINEQ (HASHFILE-WHEREIS [LAMBDA (NAME TYPE FILES FN) (* bvm: "28-Apr-86 12:24") (PROG (VAL) (* if FN given, APPLY* to each element and return NIL) (COND ((EQ NAME T) (* T as a NAME has a special meaning to INFILECOMS? so don't pass through.) (RETURN NIL))) (SETQ TYPE (GETFILEPKGTYPE TYPE)) [for FILE in (OR (LISTP FILES) FILELST) do (COND ((INFILECOMS? NAME TYPE (FILECOMS FILE)) (COND (FN (APPLY* FN NAME FILE))) (SETQ VAL (CONS FILE VAL] [AND (EQ FILES T) (EQ TYPE (QUOTE FNS)) (LITATOM NAME) (PROGN [COND ((AND WHEREIS.HASH (NLISTP WHEREIS.HASH)) (* make sure WHEREIS.HASH is a list.) (SETQ WHEREIS.HASH (LIST WHEREIS.HASH] (for WHISHSFILE HNAME HSFILE DELP on WHEREIS.HASH do (* WHEREIS.HASH is a list of hash file names off of which the hash file structure is linked into the system hash array. The full file name is hashed.) (COND ((LISTP (SETQ HNAME (CAR WHISHSFILE))) (* file already has an associated hashfile datatype) (SETQ HSFILE (CDR HNAME))) [(SETQ HSFILE (FINDFILE HNAME T)) (COND ([find X in WHEREIS.HASH suchthat (AND (LISTP X) (EQ HSFILE (HASHFILEPROP (CDR X) (QUOTE NAME] (* Looks like a duplicate entry) (RPLACA WHISHSFILE (SETQ HSFILE NIL)) (SETQ DELP T)) (T (SETQ HSFILE (OPENHASHFILE HSFILE)) (* if the data file is ever closed, break the link to the hash file structure.) (WHENCLOSE (HASHFILEPROP HSFILE (QUOTE STREAM)) (QUOTE BEFORE) [FUNCTION (LAMBDA (STRM) (for TAIL on WHEREIS.HASH when [AND (LISTP (CAR TAIL)) (EQ STRM (HASHFILEPROP (CDAR TAIL) (QUOTE STREAM] do (* remove the hashfile structure for this file's entry on WHEREIS.HASH.) (RPLACA TAIL (CAAR TAIL] (QUOTE CLOSEALL) (QUOTE NO)) (RPLACA WHISHSFILE (CONS HNAME HSFILE] (T (OR [EQ (QUOTE Y) (ASKUSER 120 (QUOTE Y) (CONCAT HNAME ", a file on WHEREIS.HASH, not found -- do you want to delete and continue?" ) (QUOTE ((Y "es") (N "o"] (ERRORX (LIST 23 HNAME))) (RPLACA WHISHSFILE (SETQ HSFILE NIL)) (SETQ DELP T))) [COND (HSFILE (for FILE inside (GETHASHFILE NAME HSFILE) when (NOT (FMEMB FILE VAL)) do (AND FN (APPLY* FN NAME FILE)) (push VAL FILE] finally (COND (DELP (SETQ WHEREIS.HASH (DREMOVE NIL WHEREIS.HASH] (RETURN (AND (NULL FN) (DREVERSE VAL]) (CLOSEWHEREIS [LAMBDA (FLG) (* bvm: "28-Apr-86 12:33") (* * Close the whereis file over logout, since there's no point in paying to keep it open) (AND WHEREIS.HASH (SELECTQ FLG ((NIL BEFORELOGOUT BEFORESYSOUT BEFOREMAKESYS) (for HF in (for WH in WHEREIS.HASH when (LISTP WH) collect (* Gather the hashfile handles) (CDR WH)) do (NLSETQ (CLOSEHASHFILE HF)))) NIL]) (WHEREISNOTICE [LAMBDA (FILEGROUP NEWFLG DATABASEFILE) (* bvm: "30-Aug-86 18:05") (* Copies the current whereis hash-file into a scratch file, then notices the files in FILEGROUP The copy is so that this function will execute even though someone else is reading the current database. The database is copied to a scratch file, then renamed to be a newer version of the previous database, which is deleted. This allows others to use the old database while the copying is going on. If an earlier version of the scratch file exists, it means that someone else is currently updating (their version disappears when they complete successfully or logout), so we wait for them to finish.) (RESETLST (PROG ([DATABASEFILENAME (OR DATABASEFILE (if WHEREIS.HASH then (* if there is a list of files, use the top one.) (if (NLISTP WHEREIS.HASH) then WHEREIS.HASH elseif (NLISTP (CAR WHEREIS.HASH)) then (CAR WHEREIS.HASH) else (CAAR WHEREIS.HASH)) else (QUOTE WHEREIS.HASH] (SCRATCHVAL (LIST NIL)) HF SCRATCH OLDWH) (SETQ OLDWH (INFILEP DATABASEFILENAME)) (RESETSAVE NIL (LIST [FUNCTION (LAMBDA (X) (if (CAR X) then (CLOSEF? (CAR X)) (AND RESETSTATE (DELFILE (CAR X] SCRATCHVAL)) (* creates a scratch file) (if (AND OLDWH (NOT NEWFLG)) then (* copy old one) [RPLACA SCRATCHVAL (SETQ HF (CLOSEF (OPENFILE (SETQ SCRATCH (PACKFILENAME (QUOTE DIRECTORY) (FILENAMEFIELD DATABASEFILENAME (QUOTE DIRECTORY)) (QUOTE NAME) (QUOTE NEWWHEREISDATABASE) (QUOTE EXTENSION) (QUOTE SCRATCH) (QUOTE TEMPORARY) (QUOTE S))) (QUOTE OUTPUT) (QUOTE NEW] (* Compensate for the fact that PACKFILENAME produces version -1 for temporary ;S) (AND (EQ (SYSTEMTYPE) (QUOTE TOPS20)) (SETQ SCRATCH (PACKFILENAME (QUOTE VERSION) NIL (QUOTE BODY) SCRATCH))) (* If there is a version earlier than the one we got, someone else must have it, and we must wait until he gets rid of it (by deleting it)) [bind OLDV (RPT ← 1) until [EQ HF (SETQ OLDV (FULLNAME SCRATCH (QUOTE OLDEST] do (DISMISS 2000) (OR (NULL RPT) (if (EQ RPT 5) then (printout T T (GETFILEINFO OLDV (QUOTE AUTHOR)) " seems to be updating the database right now." T "I'm waiting for him to finish." T T) (SETQ RPT NIL) else (add RPT 1] (SETQ HF (COPYHASHFILE OLDWH HF NIL NIL T)) (CLOSEF? OLDWH) elseif (AND OLDWH (EQ NEWFLG (QUOTE NOCOPY))) then (SETQ HF (OPENHASHFILE OLDWH (QUOTE BOTH) NIL)) else (SETQ HF (CREATEHASHFILE DATABASEFILENAME (QUOTE SMALLEXPR) NIL (OR (NUMBERP NEWFLG) 20000))) (SETQ NEWFLG T)) (* Must leave the new file open--otherwise, the user might lose access to it before he starts to do the noticing.) (for X in [\REMOVEOLDVERSIONS (for FILESPEC TEM inside FILEGROUP join (if (SETQ TEM (INFILEP FILESPEC)) then (* an individual file) (LIST TEM) else (* a specification for a group of files, expand it.) (DIRECTORY (PROG ((FGFIELDS (UNPACKFILENAME FILESPEC)) DIRPATTERN) [SETQ DIRPATTERN (PACKFILENAME (APPEND (UNPACKFILENAME FILESPEC) (QUOTE (NAME *] (if [AND (FMEMB (QUOTE EXTENSION) FGFIELDS) (NULL (LISTGET FGFIELDS (QUOTE EXTENSION] then (* no extension, must put a dot on since <lisp>* gets all files not just those with no extension so <lisp>*. is what we want.) (SETQ DIRPATTERN (PACK* DIRPATTERN "."))) (RETURN (if (NULL (FMEMB (QUOTE VERSION) FGFIELDS)) then (* pass in a pattern that only gets the most recent version unless one is specified.) (PACK* DIRPATTERN ";") else DIRPATTERN] do (ERSETQ (printout T (WHEREISNOTICE1 X HF) -2))) (SETQ HF (CLOSEHASHFILE HF)) (* This closes the file, but other updaters are still locked out cause they go for a new version and then trip over our old one.) (OR NEWFLG (if (SETQ HF (RENAMEFILE HF (PACKFILENAME (QUOTE VERSION) NIL (QUOTE BODY) DATABASEFILENAME))) then (DELFILE OLDWH))) (* Now others can get in to read or update.) (RETURN HF]) (WHEREISNOTICE1 [LAMBDA (FILE HF TRYHARD) (* bvm: "30-Aug-86 15:54") (RESETLST (PROG (NAME MAP DATE VAL ENV STREAM) [RESETSAVE NIL (LIST (QUOTE CLOSEF) (SETQ STREAM (OPENSTREAM FILE (QUOTE INPUT) (QUOTE OLD) NIL (QUOTE (DON'T.CHANGE.READ.DATE DON'T.CHANGE.DATE] (SETQ FILE (FULLNAME STREAM)) (SETFILEPTR STREAM 0) (MULTPLE-VALUE-SETQ (ENV MAP) (GET-ENVIRONMENT-AND-FILEMAP STREAM T)) (OR MAP (RETURN (LIST FILE "--can't find filemap"))) (if (AND (NOT TRYHARD) (EQUAL (SETQ DATE (FILEDATE STREAM)) (GETHASHFILE FILE HF)) DATE) then (* ; " already analyzed") (RETURN (LIST FILE DATE))) (SETQ NAME (NAMEFIELD FILE T)) (for X in (CDR MAP) do (for Y in (CDDR X) unless (OR [NULL (SETQ VAL (LOOKUPHASHFILE (CAR Y) NAME HF (QUOTE (INSERT RETRIEVE] (EQ NAME VAL) (AND (LISTP VAL) (FMEMB NAME VAL))) do (* ;; "the first LOOKUPHASHFILE stores NAME as value if there was no previous value, else returns previous value. If that value was non-null and did not contain NAME, now have to store union of NAME and what was there.") (PUTHASHFILE (CAR Y) (NCONC1 (OR (LISTP VAL) (LIST VAL)) NAME) HF))) (PUTHASHFILE FILE DATE HF) (RETURN FILE]) ) (ADDTOVAR WHEREIS.HASH ) (DECLARE: DOEVAL@COMPILE DONTCOPY (GLOBALVARS WHEREIS.HASH) ) (DECLARE: DONTEVAL@LOAD DOCOPY (MOVD (QUOTE HASHFILE-WHEREIS) (QUOTE WHEREIS)) (ADDTOVAR AROUNDEXITFNS CLOSEWHEREIS) ) (DECLARE: DOEVAL@COMPILE DONTCOPY (LOCALVARS . T) ) (PUTPROPS WHEREIS COPYRIGHT ("Xerox Corporation" 1983 1984 1986)) (DECLARE: DONTCOPY (FILEMAP (NIL (1167 3885 (\REMOVEOLDVERSIONS 1177 . 3883)) (3886 21314 (HASHFILE-WHEREIS 3896 . 9093) (CLOSEWHEREIS 9095 . 9782) (WHEREISNOTICE 9784 . 18690) (WHEREISNOTICE1 18692 . 21312))))) STOP