;;; -*- Mode:gate; Fonts:(HL12 HL12I HL12B CPTFONTB HL12BI HL12B HL12I ) -*- =Node: 4Accessing Directories* =Text: 3ACCESSING DIRECTORIES* To understand the functions in this section, it is vital to have read the chapter on 1pathnames*. The 1filespec* argument in many of these functions may be a pathname or a namestring; its name, type and version default to 2:wild*. 3listf* 1filespec* Prints on 2*standard-output** the names of the files that match 1filespec*, and their sizes, creation dates, and other information that comes in the directory listing. 3fs:directory-list* 1filespec* &rest 1options* Finds all the files that match 1filespec* and returns a list with one element for each file. Each element is a list whose car is the pathname of the file and whose cdr is a list of the properties of the file; thus the element is a disembodied property list and 2get* may be used to access the file's properties. The car of one element is 2nil*; the properties in this element are properties of the file system as a whole rather than of a specific file. 1filespec* normally contains wildcards, and the data returned describe all existing files that match it. If it contains no wildcards, it specifies a single file and only that file is described in the data that are returned. The 1options* are keywords which modify the operation. The following options are currently defined: 2:noerror* If a file-system error (such as no such directory) occurs during the operation, normally an error is signaled and the user is asked to supply a new pathname. However, if 2:noerror* is specified then, in the event of an error, a condition object describing the error is returned as the result of 2fs:directory-list*. This is identical to the 2:noerror* option to 2open*. 2:deleted* This is for file servers on which deletion is not permanent. It specifies that deleted (but not yet expunged) files are to be included in the directory listing. 2:sorted* This requests that the directory list be sorted by filenames before it is returned. The properties that may appear in the list of property lists returned by 2fs:directory-list* are host-dependent to some extent. The following properties are those that are defined for both ITS and TOPS-20 file servers. This set of properties is likely to be extended or changed in the future. 2:length-in-bytes* The length of the file expressed in terms of the basic units in which it is written (characters in the case of a text file). 2:byte-size* The number of bits in one of those units. 2:length-in-blocks* The length of the file in terms of the file system's unit of storage allocation. 2:block-size* The number of bits in one of those units. 2:creation-date* The date the file was created, as a universal time. See 4(DATETIME-0)Dates and Times*. 2:reference-date* The most recent date on which the file was used, as a universal time or 2nil*, meaning the file was never referenced. 2:modification-date* The most recent date on which the file's contents were changed, as a universal time. 2:author* The name of the person who created the file, as a string. 2:reader* The name of the person who last read the file, as a string. 2:not-backed-up* 2t* if the file exists only on disk, 2nil* if it has been backed up on magnetic tape. 2:directory* 2t* if this file is actually a directory. 2:temporary* 2t* if this file is temporary. 2:deleted* 2t* if this file is deleted. Deleted files are included in the directory list only if you specify the 2:deleted* option. 2:dont-delete* 2t* indicates that the file is not allowed to be deleted. 2:dont-supersede* 2t* indicates that the file may not be superseded; that is, a file with the same name and higher version may not be created. 2:dont-reap* 2t* indicates that this file is not supposed to be deleted automatically for lack of use. 2:dont-dump* 2t* indicates that this file is not supposed to be dumped onto magnetic tape for backup purposes. 2:characters* 2t* indicates that this file contains characters (that is, text). 2nil* indicates that the file contains binary data. This property, rather than the file's byte size, should be used to decide whether it is a text file. 2:link-to* If the file is a link, this property is a string containing the name that the link points to. 2:offline* 2T* if the file's contents are not online. 2:incremental-dump-date* The last time this file was dumped during an incremental dump (a universal time). 2:incremental-dump-tape* The tape on which the last was saved in that incremental dump (a string). 2:complete-dump-date* The last time this file was dumped during an full dump (a universal time). 2:complete-dump-tape* The tape on which the last was saved in that full dump (a string). 2:generation-retention-count* The number of files differing in version that are kept around. 2:default-generation-retention-count* The generation-retention-count that a file ordinarily gets when it is created in this directory. 2:auto-expunge-interval* The interval at which files are expunged from this directory, in seconds. 2:date-last-expunged* The last (universal) time this directory was expunged, or 2nil*. 2:account* The account to which the file belongs, a string. 2:protection* A system-dependent description of the protection of this file as a string. 2:physical-volume* A string naming the physical volume on which the file is found. 2:volume-name* A string naming the logical volume on which the file is found. 2:pack-number* A string describing the pack on which this file is found. 2:disk-space-description* A system-dependent description of the space usage on the file system. This usually appears in the plist that applies to the entire directory list. The element in the directory list that has 2nil* instead of a file's pathname describes the directory as a whole. 2:physical-volume-free-blocks* This property is an alist in which each element maps a physical volume name (a string) into a number, that is the number of free blocks on that volume. 2:settable-properties* This property is a list of file property names that may be set. This information is provided in the directory list because it is different for different file systems. 2:pathname* This property is the pathname from which this directory list was made. 2:block-size* This is the number of words in a block in this directory. It can be used to interpret the numbers of free blocks. 3fs:directory-list-stream* 1filespec* &rest 1options* This is like 2fs:directory-list* but returns the information in a different form. Instead of returning the directory list all at once, it returns a special kind of stream which gives out one element of the directory list at a time. The directory list stream supports two operations: 2:entry* and 2:close*. 2:entry* asks for the next element of the directory stream. 2:close* closes any connection to a remote file server. The purpose of using 2fs:directory-list-stream* instead of 2fs:directory-list* is that, when communicating with a remote file server, the directory list stream can give you some of the information without waiting for it to all be transmitted and parsed. This is desirable if the directory is being printed on the console. 3directory* 1filespec* Returns a list of pathnames (truenames) of the files in the directory specified by 1filespec*. Wildcards are allowed. This is the Common Lisp way to find the contents of a directory. 3fs:expunge-directory* 1filespec* &key 1(error* 3t1)** Expunges the directory specified in 1filespec*; that is, permanently eliminates any deleted files in that directory. If 1error* is 2nil*, there is no error if the directory does not exist. Note that not all file systems support this function. To find out whether a particular one does, send the 2:undeletable-p* operation to a pathname. If it returns 2t*, the file system of that pathname supports undeletion (and therefore expunging). 3fs:create-directory* 1filespec* &key 1(error* 3t1)** Creates the directory specified in 1filespec*. If 1error* is 2nil*, there is no error if the directory cannot be created; instead an error string is returned. Not all file servers support creation of directories. 3fs:remote-connect* 1filespec* &key 1(error* 3t1)** 1access* Performs the TOPS-20 ``connect'' or ``access'' function, or their equivalents, in a remote file server. Access is done if 1access* is non-2nil*; otherwise, connect is done. The connect operation grants you full access to the specified directory. The access operation grants you whatever access to all files and directories you would have if logged in on the specified directory. Both operations affect access only, since the connected directory of the remote server is never used by the Lisp Machine in choosing which file to operate on. This function may ask you for a password if one is required for the directory you specify. If the operation cannot be performed, then if 1error* is 2nil*, an error object is returned. File Properties: 3fs:change-file-properties* 1file* 1error-p* &rest 1properties* Changes one or more properties of the file 1file*. The 1properties* arguments are alternating keywords and values. If an error occurs accessing the file or changing the properties, the 1error-p* argument controls what is done; if it is 2nil*, a condition object describing the error is returned; if it is 2t* a Lisp error is signaled. If no error occurs, 2fs:change-file-properties* returns 2t*. Only some of the properties of a file may be changed; for instance, its creation date or its author. Exactly which properties may be changed depends on the host file system; a list of the changeable property names is the 2:settable-properties* property of the file system as a whole, returned by 2fs:directory-list* as explained above. 3fs:file-properties* 1file* &optional 1(error-p* 3t1)** Returns a disembodied property list for a single file (compare this to 2fs:directory-list*). The car of the returned list is the truename of the file and the cdr is an alternating list of indicators and values. The 1error-p* argument is the same as in 2fs:change-file-properties*. Filename Completion: 3fs:complete-pathname* 1defaults* 1string* 1type* 1version* &rest 1options* 1string* is a partially-specified file name. (Presumably it was typed in by a user and terminated with the 2Altmode* key or the 2End* key to request completion.) 2fs:complete-pathname* looks in the file system on the appropriate host and returns a new, possibly more specific string. Any unambiguous abbreviations are expanded out in a host-dependent fashion. 1defaults*, 1type*, and 1version* are the arguments to be given to 2fs:merge-pathname-defaults* (see 4(FILENAMES-2)Pathname Functions*) when the user's input is eventually parsed and defaulted. 1options* are keywords (without following values) that control how the completion is performed. The following option keywords are allowed: 2:deleted* Looks for files which have been deleted but not yet expunged. 2:read or :in* The file is going to be read. This is the default. 2:print or :write or :out* The file is going to be written (i.e. a new version is going to be created). 2:old* Looks only for files that already exist. This is the default. 2:new-ok* Allows either a file that already exists or a file that does not yet exist. An example of the use of this is the 2C-X* 2C-F* (Find File) command in the editor. The first value returned is always a string containing a file name, either the original string or a new, more specific string. The second value returned indicates the success or failure of the completion. It is 2nil* if an error occurred. One possible error is that the file is on a file system that does not support completion, in which case the original string is returned unchanged. Other possible second values are 2:old*, which means that the string completed to the name of a file that exists, 2:new*, which means that the string completed to the name of a file that could be created, and 2nil* again, which means that there is no possible completion. Balance Directories: 3fs:balance-directories* 1filespec1* 1filespec2* &rest 1options* 2fs:balance-directories* is a function for maintaining multiple copies of a directory. Often it is useful to maintain copies of your files on more than one machine; this function provides a simple way of keeping those copies up to date. The function first parses 1filespec1*, filling in missing components with wildcards (except for the version, which is 2:newest*). Then 1filespec2* is parsed with 1filespec1* as the default. The resulting pathnames are used to generate directory lists using 2fs:directory-list*. Note that the resulting directory lists need not be entire directories; any subset of a directory that 2fs:directory-list* can produce will do. First the directory lists are matched up on the basis of file name and type. All of the files in either directory list which have both the same name and the same type are grouped together. The directory lists are next analyzed to determine if the directories are consistent, meaning that two files with the same name and type have equal creation-dates when their versions match, and greater versions have later creation-dates. If any inconsistencies are found, a warning message is printed on the console. If the version specified for both 1filespec1* and 1filespec2* was 2:newest* (the default), then the newest version of each file in each directory is copied to the other directory if it is not already there. The result is that each directory has the newest copy of every file in either of the two directories. If one or both of the specified versions is not 2:newest*, then 1every* version that appears in one directory list and not in the other is copied. This has the result that the two directories are completely the same. (Note that this is probably not the right thing to use to 1copy* an entire directory. Use 2copy-file* with a wildcard argument instead.) The 1options* are keywords arguments which modify the operation. The following options are currently defined: 2:ignore* This option takes one argument, which is a list of file names to ignore when making the directory lists. The default value is 2nil*. 2:error* This option is identical to the 2:error* option to 2open*. 2:query-mode* This option takes one argument, which indicates whether or not the user should be asked before files are transferred. If the argument is 2nil*, no querying is done. If it is 2:1->2*, then only files being transferred from 1filespec2* to 1filespec1* are queried, while if it is 2:2->1*, then files transferred from 1filespec1* to 1filespec2* are queried. If the argument is 2:always*, then the user is asked about all files. 2:copy-mode* This option is identical to the 2:copy-mode* option of 2copy-file*, and is used to control whether files are treated as binary or textual data. 2:direction* This option specifies transfer of files in one direction only. If the value is 2:1->2* then files are transfered only from 1filespec1* to 1filespec2*, never in the other direction. If the value is 2:2->1* then files are transferred only from 1filespec2* to 1filespec1*. 2nil*, the default, means transfer in either direction as appropriate. =Node: 4Errors in Accessing Files* =Text: 3ERRORS IN ACCESSING FILES fs:file-error* (3error*) 1Condition Flavor* This flavor is the basis for all errors signaled by the file system. It defines two special operations, 2:pathname* and 2:operation*. Usually, these return the pathname of the file being operated on, and the operation used. This operation was performed either on the pathname object itself, or on a stream. It defines prompting for the proceed types 2:retry-file-operation* and 2:new-pathname*, both of which are provided for many file errors. 2:retry-file-operation* tries the operation again exactly as it was requested by the program; 2:new-pathname* expects on argument, a pathname, and tries the same operation on this pathname instead of the original one. 3fs:file-operation-failure* (3fs:file-error*) 1Condition* This condition name signifies a problem with the file operation requested. It is an alternative to 2fs:file-request-failure* (4(FILEACCESS-4)Errors in Communication with File Servers*), which means that the file system was unable to consider the operation properly. All the following conditions in this section are always accompanied by 2fs:file-operation-failure*, 2fs:file-error*, and 2error*, so they will not be mentioned. 3fs:file-open-for-output* 1Condition* The request cannot be performed because the file is open for output. 3fs:file-locked* 1Condition* The file cannot be accessed because it is already being accessed. Just which kinds of simultaneous access are allowed depends on the file system. 3fs:circular-link* 1Condition* A link could not be opened because it pointed, directly or indirectly through other links, to itself. In fact, some systems report this condition whenever a chain of links exceeds a fixed length. 3fs:invalid-byte-size* 1Condition* In 2open*, the specified byte size was not valid for the particular file server or file. 3fs:no-more-room* 1Condition* Processing a request requires resources not available, such as space in a directory, or free disk blocks. 3fs:filepos-out-of-range* 1Condition* The 2:set-pointer* operation was used with a pointer value outside the bounds of the file. 3fs:not-available* 1Condition* A requested pack, file, etc. exists but is currently off line or not available to users. 3fs:file-lookup-error* 1Condition* This condition name categorizes all sorts of failure to find a specified file, for any operation. 3fs:device-not-found* (3fs:file-lookup-error*) 1Condition* The specified device does not exist. 3fs:directory-not-found* (3fs:file-lookup-error*) 1Condition* The specified directory does not exist. 3fs:file-not-found* (3fs:file-lookup-error*) 1Condition* There is no file with the specified name, type and version. This implies that the device and directory do exist, or one of the errors described above would have been signaled. 3fs:multiple-file-not-found* (3fs:file-lookup-error*) 1Condition* There is no file with the specified name and any of the specified types, in 2with-open-file-search*. Three special operations are defined: 2:operation* Returns the function which used 2with-open-file-search*, such as 2load*. 2:pathname* The base pathname used. 2:pathnames* A list of all the pathnames that were looked for. 3fs:link-target-not-found* (3fs:file-lookup-error*) 1Condition* The file specified was a link, but the link's target filename fails to be found. 3fs:access-error* 1Condition* The operation is possible, but the file server is insubordinate and refuses to obey you. 3fs:incorrect-access-to-file* (3access-error*). 1Condition* 3fs:incorrect-access-to-directory* (3access-error*). 1Condition* The file server refuses to obey you because of protection attached to the file (or, the directory). 3fs:invalid-wildcard* 1Condition* A pathname had a wildcard in a place where the particular file server does not support them. Such pathnames are not created by pathname parsing, but they can be created with the 2:new-pathname* operation. 3fs:wildcard-not-allowed* 1Condition* A pathname with a wildcard was used in an operation that does not support it. For example, opening a file with a wildcard in its name. 3fs:wrong-kind-of-file* 1Condition* An operation was done on the wrong kind of file. If files and directories share one name space and it is an error to open a directory, the error possesses this condition name. 3fs:creation-failure* 1Condition* An attempt to create a file or directory failed for a reason specifically connected with creation. 3fs:file-already-exists* (3fs:creation-failure*) 1Condition* The file or directory to be created already exists. 3fs:superior-not-directory* (3fs:creation-failure* 3fs:wrong-kind-of-file*) 1Condition* In file systems where directories and files share one name space, this error results from an attempt to create a file using a filename specifying a directory whose name exists in the file system but is not a directory. 3fs:delete-failure* 1Condition* A file to be deleted exists, but for some reason cannot be deleted. 3fs:directory-not-empty* (3fs:delete-failure*) 1Condition* A file could not be deleted because it is a directory and has files in it. 3fs:dont-delete-flag-set* (3fs:delete-failure*) 1Condition* A file could not be deleted because its ``don't delete'' flag is set. 3fs:rename-failure* 1Condition* A file to be renamed exists, but the renaming could not be done. The 2:new-pathname* operation on the condition instance returns the specified new pathname, which may be a pathname or a string. 3fs:rename-to-existing-file* (3fs:rename-failure*) 1Condition* Renaming cannot be done because there is already a file with the specified new name. 3fs:rename-across-directories* (3fs:rename-failure*) 1Condition* Renaming cannot be done because the new pathname contains a different device or directory from the one the file is on. This may not always be an error--some file systems support it in certain cases--but when it is an error, it has this condition name. 3fs:unknown-property* (3fs:change-property-failure*) 1Condition* A property name specified in a 2:change-properties* operation is not supported by the file server. (Some file servers support only a fixed set of property names.) The 2:property* operation on the condition instance returns the problematical property name. 3fs:invalid-property-value* (3fs:change-property-failure*) 1Condition* In a 2:change-properties* operation, some property was given a value that is not valid for it. The 2:property* operation on the condition instance returns the property name, and the 2:value* operation returns the specified value. 3fs:invalid-property-name* (3fs:change-property-failure*) 1Condition* In a 2:change-properties* operation, a syntactically invalid property name was specified. This may be because it is too long to be stored. The 2:property* operation on the condition instance returns the property name.