KI_DIR
Argument | Enumeration | Purpose |
---|---|---|
path$ | Pathname | |
depth | Number of subdirs to search | |
field$ | Fields to retrieve | |
filelen | Number of bytes of filename for 'N' field | |
SYM(buf$) | Buffer to hold requested data | |
count | Number of files found | |
status | KDB_ERROR_ENUM | Optional return status |
KI_DIR
This routine gives full access to all the information in a directory and in a files inode. It can be used for individual files and also for directories and sub directories. The function walks directories starting from a given path counting the files found and copying specified information about the files and directories into a buffer.
The starting path as a directory or file name. If a directory then all the files in the directory will be searched. If a filename then only the file will be examined.
The depth determines how many levels down the directory listing will be retrieved. The depth is measured from the first pattern matching character, so for a pattern of
"/mydir/??/reps/*.rd"the depth should be 3 or more. For backward compatibility only, if the depth specified is greater than one, but less than the pattern length (in this case 3), a depth equal to the pattern length will be used. If the depth is greater than the pattern, the last element in the path is used recursively, so a pattern of
"/mydir/*"would recurse to the depth specified.
Directories and files for which permissions are not suitable will be ignored. However the optional return status will be set to KE_FILENOTFOUND.
A number of bytes coding the required fields to be copied to the buffer for each file found. The string may be empty in which case nothing will be added to the buffer but the file will be counted.
The field$ parameter may have the following values
N | filename |
---|---|
S | size in bytes (low order 32 bits) |
O | owner id (0 in Windows) |
G | group id (0 in Windows) |
I | inode number (0 in Windows) |
M | time of last modification |
A | time of last access (deprecated). Modification time will be returned instead on file systems that do not maintain access times. |
C | time of creation |
T | type |
KCML 6.00 and later supports a new field parameter of L. This will add the filesize as a 6-byte binary for KCML's that are compiled with large file support. For KCML's that are not compiled with large file support, the filesize will be limited to 32-bits and is directly equivalent to the S flag.
File types are coded with letters
F | regular file |
---|---|
D | directory |
C | character special device |
B | block special device |
L | symbolic link |
P | FIFO pipe |
The order of the field codes determines the order in which the data is copied to the buffer. All the fields are 4 byte binary except for type which is 1 byte and filename whose length is determined by the filelen parameter.
Timestamps are 4 byte binary counts of seconds since 1970-01-01 0000 GMT (see $TIME). The accuracy of the timestamps depends on the operating system and filesystem.
If targetting Windows it is probably prudent to only use the 'M' code for last modified time.
Determines the number of characters of filename copied to the buffer for type 'N' fields.
The symbol of a buffer big enough to hold the requested information. The rest of the buffer is left unchanged. If zero then only counting is performed. If symbol is negative then the buffer will be re-dimensioned to the correct size to accomodate the requested information.
Returns the number of files found.
If negative then the absolute value gives the number actually processed before the search was terminated due to the output buffer filling. If zero then no files were processed probably because the path in ki_key$ did not exist or was not accessible due to permissions. Zero will also be returned under other error conditions, such as permissions problems in sub-directories, or files being deleted from the directory that KI_DIR is processing. In such circumstances error text is recorded that can be retrieved by a subsequent KI_ERROR_TEXT call on the connection handle.
When processing a directory the directory itself is copied as the first entry in the buffer and is included in the count.
The original path in path$ can contain pattern matching metacharacters '*', '?' and '[]'. The routine will find the longest base directory name that does not include metacharacters and start the search from there. The current directory is used if there are no directory separators in path$. The pattern matching rules are those used by the shell.
To determine the type and owner of a particular file the following would be used:
'KI_DIR("/dev/rmt0",1,"TO",0,SYM(buf$)) PRINT STR(buf$,,1),VAL(STR(buf$,2),4)
To find the names and size of all the files in the current directory and to sort by name
DIM name$(32)14+4 name$()=ALL(FF) 'KI_DIR(".",1,"NS",14,SYM(name$())) SORT name$()
To count the files in a directory and its subdirectories
count = 'KI_DIR("/usr/bc30",9," ",0,0) PRINT count
Platform independent code to cater for large (> 2Gb) files.
DIM a$(1)1,count,i,offset_size,bigflag$,fsize,errbuf$256,status CALL KI_DIR ".",1,"NL",32,-SYM(a$()) TO count,status IF (status == _KE_SUCCESS) REM Check if this KCML has been compiled with large file support bigflag$ = STR($MACHINE,54,1) AND HEX(01) IF (bigflag$ <> HEX(00)) REM This KCML has been compiled with large file support offset_size = 6 ELSE REM This is a standard KCML with a 2Gb filesize limit REM Size will be trucated to 32-bits, ie 2Gb offset_size = 4 END IF REM Print the file's name and size FOR i = 1 TO count fsize = VAL(STR(a$(i),33,offset_size),offset_size) PRINT STR(a$(i),,32),fsize NEXT i ELSE REM Get the error string from KI_DIR CALL KI_ERROR_TEXT -_KDB_DEFAULT_CONNECTION TO errbuf$,status PRINT errbuf$ END IF END IF
Compatibility
This routine recurses internally and can use a lot of heap memory, particularly on IBM AIX systems. For new code consider using KI_DIR_LIST and KI_STAT.