📄 sflfile.c
字号:
if no problems occurred, -1 if an error occurred, 1 if the destination
file already exists.
---------------------------------------------------------------------[>]-*/
int
file_copy (
const char *dest,
const char *src,
char mode)
{
FILE *inf, *outf;
char *buffer,
openmode [3] = "??";
size_t chars_read; /* Amount read from stream */
int feedback = 0;
ASSERT (dest);
ASSERT (src);
if (file_exists (dest))
return (1); /* Cancel: dest already exists */
# if (defined (MSDOS_FILESYSTEM))
if (system_devicename (dest) || system_devicename (src))
return (-1); /* Not allowed on device names */
# endif
# if (defined (MSDOS_FILESYSTEM))
openmode [1] = mode;
# else
openmode [1] = 0;
# endif
openmode [0] = 'r';
if ((inf = fopen (src, openmode)) == NULL)
return (-1); /* Input file not found */
if ((buffer = mem_alloc (SHRT_MAX)) == NULL)
feedback = -1; /* Insufficient memory for buffer */
else
{
openmode [0] = 'w';
if ((outf = fopen (dest, openmode)) == NULL)
{
mem_free (buffer);
return (-1); /* Could not create output file */
}
while ((chars_read = fread (buffer, 1, SHRT_MAX, inf)) != 0)
if (fwrite (buffer, 1, chars_read, outf) != chars_read)
{
feedback = -1;
break;
}
fclose (outf);
mem_free (buffer);
}
fclose (inf);
return (feedback);
}
/* ---------------------------------------------------------------------[<]-
Function: file_concat
Synopsis: Copies the contents of src onto dest. If dest does not exist,
it is created. Returns 0 if the concatenation operation succeeded, or
-1 if some error occurred.
---------------------------------------------------------------------[>]-*/
int
file_concat (
const char *src,
const char *dest)
{
FILE *inf, *outf;
char *buffer;
size_t chars_read; /* Amount read from stream */
int feedback = 0;
ASSERT (src);
ASSERT (dest);
# if (defined (MSDOS_FILESYSTEM))
if (system_devicename (dest) || system_devicename (src))
return (-1); /* Not allowed on device names */
# endif
if ((inf = fopen (src, FOPEN_READ_BINARY)) == NULL)
return (-1); /* Input file not found */
if ((buffer = mem_alloc (SHRT_MAX)) == NULL)
feedback = -1; /* Insufficient memory for buffer */
else
{
if ((outf = fopen (dest, FOPEN_APPEND_BINARY)) == NULL)
{
mem_free (buffer);
return (-1); /* Could not create output file */
}
while ((chars_read = fread (buffer, 1, SHRT_MAX, inf)) != 0)
if (fwrite (buffer, 1, chars_read, outf) != chars_read)
{
feedback = -1;
break;
}
fclose (outf);
mem_free (buffer);
}
fclose (inf);
return (feedback);
}
/* ---------------------------------------------------------------------[<]-
Function: file_rename
Synopsis: Renames a file from oldname to newname. Returns 0 if okay,
or -1 if there was an error. Does not overwrite existing files.
---------------------------------------------------------------------[>]-*/
int
file_rename (
const char *oldname,
const char *newname)
{
# if (defined (MSDOS_FILESYSTEM))
char *dos_newname;
int feedback;
ASSERT (oldname);
ASSERT (newname);
if (system_devicename (oldname) || system_devicename (newname))
return (-1); /* Not allowed on device names */
dos_newname = mem_strdup (newname);
strconvch (dos_newname, '/', '\\');
feedback = rename (oldname, dos_newname);
mem_free (dos_newname);
return (feedback);
# else
ASSERT (oldname);
ASSERT (newname);
return (rename (oldname, newname));
# endif
}
/* ---------------------------------------------------------------------[<]-
Function: file_delete
Synopsis: Deletes the specified file. Returns 0 if okay, -1 in case of
an error.
---------------------------------------------------------------------[>]-*/
int
file_delete (
const char *filename)
{
#if (defined (__VMS__))
ASSERT (filename);
return (remove (filename));
#elif (defined (WIN32))
int
rc;
ASSERT (filename);
if (system_devicename (filename))
return (-1); /* Not allowed on device names */
rc = !DeleteFile (filename);
if (rc && errno == EACCES)
{
/* Under WinNT and Win95, a delete of a freshly-created file can
* sometimes fail with a permission error which passes after a
* short delay. Ugly but it seems to work.
*/
Sleep (200);
rc = !DeleteFile (filename);
}
return (rc);
#else
ASSERT (filename);
return (unlink (filename));
#endif
}
/* ---------------------------------------------------------------------[<]-
Function: file_exists
Synopsis: Returns TRUE if the file exists, or FALSE if it does not.
---------------------------------------------------------------------[>]-*/
Bool
file_exists (
const char *filename)
{
ASSERT (filename);
return (file_mode (filename) > 0);
}
/* -------------------------------------------------------------------------
* file_mode -- internal
*
* Returns the file mode for the specified file or directory name; returns
* 0 if the specified file does not exist.
*/
static dbyte
file_mode (const char *filename)
{
#if (defined (WIN32))
DWORD dwfa;
dbyte mode;
ASSERT (filename);
if (system_devicename (filename))
return (0); /* Not allowed on device names */
dwfa = GetFileAttributes (filename);
if (dwfa == 0xffffffff)
return (0);
mode = 0;
if (dwfa & FILE_ATTRIBUTE_DIRECTORY)
mode |= S_IFDIR;
else
mode |= S_IFREG;
if (!(dwfa & FILE_ATTRIBUTE_HIDDEN))
mode |= S_IREAD;
if (!(dwfa & FILE_ATTRIBUTE_READONLY))
mode |= S_IWRITE;
if (is_exe_file (filename))
mode |= S_IEXEC;
return (mode);
#else
static struct stat
stat_buf;
ASSERT (filename);
# if (defined (MSDOS_FILESYSTEM))
/* Handle simple disk specifiers ourselves, since some compilers cannot
* do a 'stat' on these.
*/
if ( filename [1] == ':'
&& ((filename [2] == '\\' && filename [3] == '\0')
|| (filename [2] == '/' && filename [3] == '\0')
|| (filename [2] == '\0')))
return (S_IFDIR | S_IREAD | S_IWRITE);
# endif
if (strnull (filename))
return (0);
else
if (stat ((char *) filename, &stat_buf) == 0)
return ((dbyte) stat_buf.st_mode);
else
return (0);
#endif
}
/* ---------------------------------------------------------------------[<]-
Function: file_where
Synopsis: Scans a user-specified path symbol for a specific file, and
returns the fully-specified filename. Also adds an extension if this
is required.
The mode argument can be one of: r, w, a, or s for read, write, append,
or static. The function tries to locate existing files somewhere on the
path. New files are always created in the current directory. Static
files are created in the first directory on the path.
The path argument is only used when more is r, a, or s. If the path is
NULL or empty, it is ignored. Otherwise, the path is translated as an
environment variable, and cut into a list of directory names. The path
is cut up as follows:
<TABLE>
MS-DOS directory names separated by ';'. ;; means current.
OS/2 directory names separated by ';'. ;; means current.
Unix directory names separated by ':'. :: means current.
VMS directory names separated by ','. " ", means current.
Other single directory name.
</TABLE>
When the mode is 'r' or 'a', searches the current directory before
considering the path value. When the path cannot be translated, and is
not null or empty, it is used as a literal value.
The name argument is the filename with or without extension. It will
be prefixed by the path and suffixed by the extension, if required.
The ext argument is a default or mandatory extension. If ext starts
with a dot, it is mandatory and always used. Otherwise it is used only
if the name does not already have an extension. If ext is NULL or empty,
it is ignored.
The total length of a name including path, name, extension, and any
delimiters is FILE_NAME_MAX. Names are truncated if too long. The
maximum size of one directory component is FILE_DIR_MAX chars.
All parameters are case-sensitive; the precise effect of this depends on
the system. On MS-DOS, filenames are always folded to uppercase, but the
path must be supplied in uppercase correctly. On UNIX, all parameters are
case sensitive. On VMS, path and filenames are folded into uppercase.
Returns a pointer to a static character array containing the filename; if
mode is 'r' and the file does not exist, returns NULL. If the mode is
'w', 'a', or 's', always returns a valid filename.
Under VMS, all filenames are handled in POSIX mode, i.e. /disk/path/file
instead of $disk:[path]file.
---------------------------------------------------------------------[>]-*/
char *
file_where (
char mode,
const char *path,
const char *name,
const char *ext)
{
const char
*pathptr; /* End of directory in path */
char
*curdir;
Bool
search_curdir = TRUE; /* Look in current directory? */
ASSERT (name);
if (ext != NULL && *ext) /* Append extension if not null */
{ /* to get name + ext into */
if (ext [0] == '.') /* work_name. */
fixed_extension (work_name, name, ext);
else
default_extension (work_name, name, ext);
}
else
strcpy (work_name, name);
#if (NAMEFOLD == TRUE)
strupc (work_name); /* Fold to uppercase if needed */
#endif
if (path != NULL && *path) /* Get value of path, or NULL */
{
pathptr = getenv (path); /* Translate path symbol */
if (pathptr == NULL)
{
pathptr = path; /* If not found, use literally */
search_curdir = FALSE; /* Path now takes priority */
}
#if (PATHFOLD == TRUE) /* Fold to uppercase if necessary */
if (pathptr)
{
ASSERT (strlen (pathptr) < PATH_MAX);
strcpy (path_name, pathptr);
strupc (path_name);
pathptr = path_name; /* Redirect to uppercase version */
}
#endif
}
else
pathptr = NULL;
#if (defined (MSDOS_FILESYSTEM))
/* Normalise the path value by changing any slashes to backslashes */
if (pathptr)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -