📄 sfldir.c
字号:
/* ---------------------------------------------------------------------[<]-
Function: get_curdir
Synopsis: Returns a buffer containing the current working directory.
This buffer is allocated using the mem_alloc() function and should be
freed using mem_free() when no longer needed. Returns NULL if there
was insufficient memory to allocate the buffer, or if the system does
not provide the current working directory information. Under Windows,
replaces backslash characters by the UNIX-like slash. Under OpenVMS,
returns directory name in POSIX format. Note that the directory name
always ends in a slash (e.g. 'C:/' or 'C:/subdir/').
---------------------------------------------------------------------[>]-*/
char *
get_curdir (void)
{
char
*curdir; /* String we get from the OS */
curdir = mem_alloc (PATH_MAX + 1);
#if (defined (__UNIX__) || defined (__OS2__))
getcwd (curdir, PATH_MAX);
#elif (defined (__VMS__))
getcwd (curdir, PATH_MAX, 0);
#elif (defined (WIN32))
GetCurrentDirectory (PATH_MAX, curdir);
strconvch (curdir, '\\', '/');
#elif (defined (MSDOS_FILESYSTEM))
getcwd (curdir, PATH_MAX);
strconvch (curdir, '\\', '/');
#else
strclr (curdir);
#endif
/* The directory must always end in a slash */
if (strlast (curdir) != '/')
strcat (curdir, "/");
return (curdir);
}
/* ---------------------------------------------------------------------[<]-
Function: set_curdir
Synopsis: Sets the current working directory as specified. Returns 0
if the directory path was found; -1 if there was an error. Under
Windows, replaces '/' by '\' before changing directory, and switches
to the specified disk if the path starts with a letter and ':'. Does
nothing if the path is NULL or empty.
---------------------------------------------------------------------[>]-*/
int
set_curdir (
const char *path)
{
int
feedback = 0;
#if (defined (__UNIX__) || defined (__VMS_XOPEN) || defined (__OS2__))
if (path && *path)
feedback = chdir (path);
#elif (defined (MSDOS_FILESYSTEM))
char
*copy_path = mem_strdup (path);
if (path == NULL || *path == '\0')
return (0); /* Do nothing if path is empty */
/* MS-DOS compilers generally require a two-step process */
strconvch (copy_path, '/', '\\');
# if (defined (WIN32))
/* The drive letter does not need to be changed separately in Win32. */
feedback = !SetCurrentDirectory (copy_path);
# elif (defined (__TURBOC__))
feedback = chdir (copy_path);
if (feedback == 0 && isalpha (path [0]) && path [1] == ':')
setdisk (toupper (path [0]) - 'A');
# elif (defined (__LCC__))
feedback = chdir (copy_path);
if (feedback == 0 && isalpha (path [0]) && path [1] == ':')
chdrive (toupper (path [0]) - 'A' + 1);
# elif (defined (_MSC_VER))
feedback = _chdir (copy_path);
if (feedback == 0 && isalpha (path [0]) && path [1] == ':')
_chdrive (toupper (path [0]) - 'A' + 1);
# endif
mem_strfree (©_path);
#else
feedback = -1;
#endif
return (feedback);
}
/* ---------------------------------------------------------------------[<]-
Function: file_matches
Synopsis: Returns TRUE if the filename matches the pattern. The pattern
is a character string that can contain these 'wildcard' characters:
---------------------------------------------------------------------[>]-*/
Bool
file_matches (
const char *filename,
const char *pattern)
{
char
*pattern_ptr, /* Points to pattern */
*filename_ptr; /* Points to filename */
filename_ptr = (char *) filename; /* Start comparing file name */
pattern_ptr = (char *) pattern; /* Start comparing file name */
FOREVER
{
/* If we came to the end of the pattern and the filename, we have */
/* successful match. */
if (*pattern_ptr == '\0' && *filename_ptr == '\0')
return (TRUE); /* Have a match */
/* Otherwise, end of either is a failed match */
if (*pattern_ptr == '\0' || *filename_ptr == '\0')
return (FALSE); /* Match failed */
/* If the pattern character is '?', then we matched a char */
if (*pattern_ptr == '?'
#if (defined (NAMEFOLD))
|| toupper (*pattern_ptr) == toupper (*filename_ptr))
#else
|| *pattern_ptr == *filename_ptr)
#endif
{
pattern_ptr++;
filename_ptr++;
}
else
/* If we have a '*', match as much of the filename as we can */
if (*pattern_ptr == '*')
{
pattern_ptr++; /* Try to match following char */
while (*filename_ptr && *filename_ptr != *pattern_ptr)
filename_ptr++;
}
else
return (FALSE); /* Match failed */
}
}
/* ---------------------------------------------------------------------[<]-
Function: make_dir
Synopsis: Create a new directory. Returns 0 if the directory was created;
-1 if there was an error. Under Windows and OpenVMS, accepts directory
names with '/'. Will create multiple levels of directory if required.
---------------------------------------------------------------------[>]-*/
int
make_dir (
const char *path_to_create)
{
char
*path,
*slash;
int
rc = 0;
path = mem_strdup (path_to_create); /* Working copy */
#if (defined (MSDOS_FILESYSTEM))
strconvch (path, '/', '\\');
/* Handle \\system\drive specially */
if (strprefixed (path, "\\\\")) /* Network drive name? */
{
slash = strchr (path + 2, '\\');
if (slash)
slash = strchr (slash + 1, '\\');
}
else
#endif
slash = strchr (path + 1, PATHEND);
/* Create each component of directory as required */
FOREVER /* Create any parent directories */
{
if (slash)
*slash = '\0'; /* Cut at slash */
if (!file_is_directory (path))
{
#if (defined (__UNIX__) || defined (__VMS_XOPEN) || defined (__OS2__))
rc = mkdir (path, 0775); /* User RWE Group RWE World RE */
#elif (defined (WIN32))
if (CreateDirectory (path, NULL))
rc = 0;
else
rc = -1;
#elif (defined (MSDOS_FILESYSTEM))
# if (defined (__DJGPP__))
rc = mkdir (path, 0775); /* User RWE Group RWE World RE */
# else
rc = mkdir (path); /* Protection? What's that? */
# endif
#else
rc = -1; /* Not a known system */
#endif
if (rc) /* End if error */
break;
}
if (slash == NULL) /* End if last directory */
break;
*slash = PATHEND; /* Restore path name */
slash = strchr (slash + 1, PATHEND);
}
mem_strfree (&path);
return (rc);
}
/* ---------------------------------------------------------------------[<]-
Function: remove_dir
Synopsis: remove a directory. Returns 0 if the directory could be
removed; -1 if there was an error. Under MS-DOS and OpenVMS accepts
a directory name in UNIX format, i.e. containing '/' delimiters. The
directory must be empty to be removed.
---------------------------------------------------------------------[>]-*/
int
remove_dir (
const char *path)
{
#if (defined (__UNIX__) || defined (__VMS_XOPEN) || defined (__OS2__))
/* Check that directory exists */
if (!file_is_directory (path))
return (-1);
return (rmdir (path));
#elif (defined (MSDOS_FILESYSTEM))
int
rc = 0;
char
*copy_path;
/* Check that directory exists */
if (!file_is_directory (path))
return (-1);
copy_path = mem_strdup (path);
if (copy_path)
{
strconvch (copy_path, '/', '\\');
# if (defined (WIN32))
if (RemoveDirectory (copy_path))
rc = 0;
else
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
coprintf (lpMsgBuf);
rc = -1;
}
# else
rc = rmdir (copy_path);
# endif
mem_strfree (©_path);
}
return (rc);
#else
return (-1);
#endif
}
/* ---------------------------------------------------------------------[<]-
Function: dir_usage
Synopsis: Calculates the amount of disk space used by a directory, and
optionally all directories below that. If the total size is greater
than 4Gb, returns an unspecified value. Returns 0 if there was an error.
---------------------------------------------------------------------[>]-*/
qbyte
dir_usage (const char *path, Bool recurse)
{
DIRST
dir;
qbyte
usage = 0;
char
*full_dir;
if (open_dir (&dir, path))
do
{
if ((dir.file_attrs & ATTR_HIDDEN) != 0)
; /* Do nothing */
else
if (recurse
&& (dir.file_attrs & ATTR_SUBDIR) != 0)
{
full_dir = locate_path (path, dir.file_name);
usage += dir_usage (full_dir, TRUE);
mem_free (full_dir);
}
else
usage += dir.file_size;
}
while (read_dir (&dir));
close_dir (&dir);
return (usage);
}
/* ---------------------------------------------------------------------[<]-
Function: dir_files
Synopsis: Calculates the number of files in a directory and optionally
all directories below that. Excludes directories from the count (thus,
a directory containing only '.' and '..' contains 0 files. Returns 0
if there was an error. Excludes hidden files.
---------------------------------------------------------------------[>]-*/
qbyte
dir_files (const char *path, Bool recurse)
{
DIRST
dir;
qbyte
files = 0;
char
*full_dir;
if (open_dir (&dir, path))
do
{
if ((dir.file_attrs & ATTR_HIDDEN) != 0)
; /* Do nothing */
else
if (recurse
&& (dir.file_attrs & ATTR_SUBDIR) != 0)
{
full_dir = locate_path (path, dir.file_name);
files += dir_files (full_dir, TRUE);
mem_free (full_dir);
}
else
files++;
}
while (read_dir (&dir));
close_dir (&dir);
return (files);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -