📄 dirlist.c
字号:
#include "tdestr.h"
#include "common.h"
#include "define.h"
#include "tdefunc.h"
/*
* Name: dir_help
* Purpose: To prompt the user and list the directory contents
* Date: February 13, 1992
* Passed: window: pointer to current window
*/
int dir_help( WINDOW *window )
{
char dname[MAX_COLS+2]; /* directory search pattern */
char stem[MAX_COLS+2]; /* directory stem */
char drive[_MAX_DRIVE]; /* splitpath drive buff */
char dir[_MAX_DIR]; /* splitpath dir buff */
char fname[_MAX_FNAME]; /* splitpath fname buff */
char ext[_MAX_EXT]; /* splitpath ext buff */
int rc;
int file_mode;
int bin_length;
int prompt_line;
if (window != NULL) {
entab_linebuff( );
if (un_copy_line( window->ll, window, TRUE ) == ERROR)
return( ERROR );
prompt_line = window->bottom_line;
} else
prompt_line = g_display.nlines;
/*
* search path or pattern
*/
dname[0] = '\0';
rc = get_name( dir1, prompt_line, dname, g_display.message_color );
if (rc == OK) {
if (validate_path( dname, stem ) == OK) {
rc = list_and_pick( dname, stem, window );
/*
* if everything is everything, load in the file selected by user.
*/
if (rc == OK) {
file_mode = TEXT;
bin_length = 0;
_splitpath( dname, drive, dir, fname, ext );
if (stricmp( ext, ".exe" ) == 0 || stricmp( ext, ".com" ) == 0) {
file_mode = BINARY;
bin_length = g_status.file_chunk;
}
if (window != NULL)
attempt_edit_display( dname, LOCAL, file_mode, bin_length );
else
attempt_edit_display( dname, GLOBAL, file_mode, bin_length );
}
} else
/*
* invalid path or file name
*/
error( WARNING,
window != NULL ? window->bottom_line : g_display.nlines, dir2 );
}
return( rc );
}
/*
* Name: validate_path
* Purpose: make sure we got a valid search pattern or subdirectory
* Date: February 13, 1992
* Passed: dname: search path entered by user
* stem: directory stem is returned
* Returns: successful or not
* Notes: we need to validate the search path or pattern. if the search
* pattern is valid, then we need to get the search stem.
* the user may enter a subdirectory or some kind of search pattern.
* if the user enters a subdirectory, then there are a few things
* we need to take care of 1) find out if the subdirectory is
* the root, 2) append a '\' to the subdirectory so we can create
* a search pattern for the subdirectory, 3) don't append '\' to
* the root, it already has a '\'.
* if the user enters a search pattern, then we need to dissect the
* search path. we must create a stem from the search pattern.
*/
int validate_path( char *dname, char *stem )
{
int rc;
DTA dta; /* temp disk transfer struct for findfirst, etc. */
int fattr;
int i;
int len;
char *p;
char temp[MAX_COLS+2]; /* directory stem */
/*
* if path name is void then the current working directory is implied.
*/
if (dname[0] == '\0') {
assert( strlen( stardotstar ) < MAX_COLS );
strcpy( dname, stardotstar );
stem[0] = '\0';
rc = OK;
} else {
/*
* get the attributes of the search pattern, so we can determine if
* this is a pattern or subdirectory.
*/
rc = get_fattr( dname, &fattr );
if (rc == OK && (fattr & SUBDIRECTORY)) {
assert( strlen( dname ) < MAX_COLS );
strcpy( stem, dname );
/*
* if this is the root directory ( \ ), don't append '\' to it.
* user entered a subdirectory - append *.* to get contents of
* subdirectory.
*/
len = strlen( stem );
if (stem[len-1] != '\\') {
strcat( stem, "\\" );
strcat( dname, "\\" );
}
strcat( dname, stardotstar );
/*
* not a subdirectory. let's see if any files match the search
* pattern.
*/
} else if (rc != ERROR) {
if ((rc = my_findfirst( &dta, dname, NORMAL | READ_ONLY | HIDDEN |
SYSTEM | SUBDIRECTORY | ARCHIVE )) == OK) {
/*
* copy dname to "temp" so we can use "temp" to find the stem.
* we need to search the pattern backwards to figure the stem.
*/
assert( strlen( dname ) < MAX_COLS );
strcpy( temp, dname );
len = strlen( dname );
for (i=len,p=temp+len; i>=0; i--) {
/*
* if we run into the '\' or the ':', then we got a stem.
*/
if (*p == '\\' || *p == ':') {
p = temp + i;
*(p+1) = '\0';
break;
/*
* if we're at the beginning of the string, stem == '\0'
*/
} else if (i == 0) {
*p = '\0';
break;
}
--p;
}
assert( strlen( temp ) < MAX_COLS );
strcpy( stem, temp );
} else
rc = ERROR;
/*
* user did not enter a valid subdirectory name or search pattern.
*/
} else
rc = ERROR;
}
return( rc );
}
/*
* Name: list_and_pick
* Purpose: To show matching file names and let user pick a file
* Date: February 13, 1992
* Passed: dname: directory search pattern
* stem: stem of directory search pattern
* window: pointer to current window
* Returns: return code from pick. rc = OK, then edit a new file.
* Notes: real work routine of this function. save the cwd and let the
* user search upwards or downwards thru the directory structure.
* since we are doing DOS directory functions, we need to check the
* return code after each DOS call for critical errors.
*/
int list_and_pick( char *dname, char *stem, WINDOW *window )
{
int rc;
DTA dta; /* disk transfer address for findfirst */
DIRECTORY dir; /* contains all info for dir display */
unsigned int cnt; /* number of matching files */
FTYPE *flist, *p; /* pointer to list of matching files */
char cwd[MAX_COLS]; /* save the current working directory in this buff */
char dbuff[MAX_COLS]; /* temporary directory buff */
char prefix[MAX_COLS]; /* directory prefix */
int change_directory = FALSE;
int stop;
int len;
int drive;
/*
* Some algorithms alloc the maximum possible number of files in
* a directory, eg. 256 or 512. Let's count the number of matching
* files so we know egxactly how much memory to request from calloc.
* Depending on the op system, disk media, disk format, or version of DOS,
* the max number of files may vary, anyway, also, additionally.
*/
rc = my_findfirst( &dta, dname, NORMAL | READ_ONLY | HIDDEN | SYSTEM |
SUBDIRECTORY | ARCHIVE );
if (rc != ERROR) {
for (cnt=1; (rc = my_findnext( &dta )) == OK;)
++cnt;
flist = (FTYPE *)calloc( cnt, sizeof(FTYPE) );
} else
flist = NULL;
if (rc != ERROR && flist != NULL) {
stop = FALSE;
/*
* If user entered drive name in search pattern, find out the drive and
* directory stem.
*/
if (stem[1] == ':') {
/*
* If the second character of the search pattern is a ':', the
* the first character of the pattern should be the drive.
* Convert drive to lower case and get a numerical representation.
* CAVEAT: In DOS v 2.x, there may be up to 63 logical drives.
* my algorithm may blow up if the number of logical drives
* is greater than 'Z'.
* For DOS >= 3, the number of drives is limited to 26, I think.
*/
drive = stem[0];
if (drive < 'a')
drive += 32;
drive = drive - 'a' + 1;
rc = get_current_directory( dbuff, drive );
if (rc == ERROR)
stop = TRUE;
else {
/*
* Put drive letter, ':', and '\' in front of current directory.
*/
prefix[0] = (char)(drive - 1 + 'a');
prefix[1] = ':';
prefix[2] = '\\';
prefix[3] = '\0';
assert( strlen( prefix ) + strlen( dbuff ) < MAX_COLS );
strcpy( cwd, prefix );
strcat( cwd, dbuff );
}
/*
* else get current directory from default drive
*/
} else {
/*
* 0 = default drive.
*/
drive = 0;
rc = get_current_directory( dbuff, drive );
if (rc == ERROR)
stop = TRUE;
else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -