📄 sflfile.c
字号:
pathptr++; /* of the path */
if ((length)
&& (dest [length - 1] != PATHEND))
dest [length++] = PATHEND; /* Add path-to-filename delimiter */
dest [length] = '\0';
strcat (dest, name);
add_extension (dest, dest, ext);
}
else
{
if (ext)
add_extension (dest, name, ext);
else
strcpy (dest, name);
}
return (pathptr);
}
/* ---------------------------------------------------------------------[<]-
Function: file_cycle
Synopsis: Cycles the file: if the file already exists, renames the
existing file. This function tries to rename the file using the date
of creation of the file; if this fails because an existing file had the
same name, generates a guaranteed unique file name. Returns TRUE if
the cycle operation succeeded, or FALSE if it failed (e.g. due to a
protection problem). The how argument must be one of:
<TABLE>
CYCLE_ALWAYS Cycle file unconditionally
CYCLE_HOURLY Cycle file if hour has changed
CYCLE_DAILY Cycle file if day has changed
CYCLE_WEEKLY Cycle file if week has changed
CYCLE_MONTHLY Cycle file if month has changed
CYCLE_NEVER Don't cycle the file
</TABLE>
---------------------------------------------------------------------[>]-*/
Bool
file_cycle (
const char *filename,
int how)
{
long
file_date; /* Datestamp of file */
char
*point,
*insert_at; /* Where we start messing name */
int
unique_nbr; /* To generate a unique name */
ASSERT (filename);
/* If no cycling needed, do nothing */
if (!file_cycle_needed (filename, how))
return (TRUE); /* No errors, nothing in fact */
file_date = timer_to_date (get_file_time (filename));
strcpy (full_name, filename);
point = strrchr (full_name, '.');
if (point)
{
strcpy (work_name, point); /* Save extension, if any */
*point = '\0'; /* and truncate original name */
}
else
strclr (work_name);
/* We leave up to 2 original letters of the filename, then stick-in */
/* the 6-digit timestamp. */
insert_at = strrchr (full_name, '/');
#if (defined (MSDOS_FILESYSTEM))
if (!insert_at)
insert_at = strrchr (full_name, '\\');
#endif
if (insert_at)
insert_at++; /* Bump past slash, if found */
else
insert_at = full_name;
if (*insert_at) /* Bump insert_at twice, to leave */
insert_at++; /* up to 2 letters before we */
if (*insert_at) /* stick-in the date stamp */
insert_at++;
/* Format new name for file and make sure it does not already exist */
sprintf (insert_at, "%06d", (int) (file_date % 1000000L));
strcat (insert_at, work_name);
if (file_exists (full_name))
{
point = strrchr (full_name, '.') + 1;
for (unique_nbr = 0; unique_nbr < 1000; unique_nbr++)
{
sprintf (point, "%03d", unique_nbr);
if (!file_exists (full_name))
break;
}
}
if (file_exists (full_name))
return (FALSE); /* We give up! */
if (file_rename (filename, full_name))
return (FALSE); /* No permission */
else
return (TRUE); /* Okay, it worked */
}
/* ---------------------------------------------------------------------[<]-
Function: file_cycle_needed
Synopsis: Checks whether the file should be cycled or not. Returns
TRUE if the file needs to be cycled, FALSE if not. The how argument
must be one of:
<TABLE>
CYCLE_ALWAYS Cycle file unconditionally
CYCLE_HOURLY Cycle file if hour has changed
CYCLE_DAILY Cycle file if day has changed
CYCLE_WEEKLY Cycle file if week has changed
CYCLE_MONTHLY Cycle file if month has changed
CYCLE_NEVER Don't cycle the file
</TABLE>
If the specified file does not exist or is not accessible, returns
FALSE.
---------------------------------------------------------------------[>]-*/
Bool
file_cycle_needed (
const char *filename,
int how)
{
long
curr_time, /* Current time */
curr_date, /* Current date */
file_date, /* Timestamp of file */
file_time; /* Datestamp of file */
Bool
cycle; /* Do we want to cycle the file? */
ASSERT (filename);
if (!file_exists (filename)) /* Not found - nothing more to do */
return (FALSE);
file_time = timer_to_time (get_file_time (filename));
file_date = timer_to_date (get_file_time (filename));
curr_time = time_now ();
curr_date = date_now ();
switch (how)
{
case CYCLE_ALWAYS:
cycle = TRUE;
break;
case CYCLE_HOURLY:
cycle = GET_HOUR (file_time) != GET_HOUR (curr_time);
break;
case CYCLE_DAILY:
cycle = GET_DAY (file_date) != GET_DAY (curr_date);
break;
case CYCLE_WEEKLY:
cycle = week_of_year (file_date) != week_of_year (curr_date);
break;
case CYCLE_MONTHLY:
cycle = GET_MONTH (file_date) != GET_MONTH (curr_date);
break;
case CYCLE_NEVER:
cycle = FALSE;
break;
default:
cycle = FALSE;
}
return (cycle);
}
/* ---------------------------------------------------------------------[<]-
Function: file_has_changed
Synopsis: Returns TRUE if the file has changed since it was last read.
The calling program must supply the date and time of the file as it
was read. If the file is not present or accessible, returns FALSE.
---------------------------------------------------------------------[>]-*/
Bool
file_has_changed (
const char *filename,
long old_date,
long old_time)
{
long
file_date, /* Timestamp of file */
file_time; /* Datestamp of file */
ASSERT (filename);
if (!file_exists (filename)) /* Not found - nothing more to do */
return (FALSE);
file_time = timer_to_time (get_file_time (filename));
file_date = timer_to_date (get_file_time (filename));
if (file_date > old_date
|| (file_date == old_date && file_time > old_time))
return (TRUE);
else
return (FALSE);
}
/* ---------------------------------------------------------------------[<]-
Function: safe_to_extend
Synopsis: Handles system-specific case of extending a file that may not
be in a valid state for such an operation. Returns TRUE if the extend
can go ahead; returns FALSE if the extend cannot be permitted.
Under MS-DOS and Windows, if the last byte in the file is Ctrl-Z (26)
the file is truncated by 1 position to remove this character.
---------------------------------------------------------------------[>]-*/
Bool
safe_to_extend (
const char *filename)
{
#if (defined (MSDOS_FILESYSTEM))
int handle; /* Opened file handle */
char endoffile; /* Last character in file */
ASSERT (filename);
if (system_devicename (filename))
return (FALSE); /* Not allowed on device names */
handle = open (filename, O_RDWR + O_BINARY, S_IREAD | S_IWRITE);
if (handle) /* If not found, ignore */
{
lseek (handle, -1, SEEK_END);
read (handle, &endoffile, 1);
if (endoffile == 26)
chsize (handle, filelength (handle) - 1);
close (handle);
}
#endif
return (TRUE);
}
/* ---------------------------------------------------------------------[<]-
Function: default_extension
Synopsis: Copies src to dest and adds ext if necessary. Returns dest.
Dest must be large enough for a fully-formatted filename; define it as
char [FILE_NAME_MAX + 1]. The ext argument can start with or without
a dot. If ext is null or empty, does nothing.
---------------------------------------------------------------------[>]-*/
char *
default_extension (
char *dest,
const char *src,
const char *ext)
{
int len, i;
char *ptr;
ASSERT (dest);
ASSERT (src);
if (dest != src) /* Copy src to dest if not same */
strcpy (dest, src);
if (ext != NULL && *ext != 0)
{
len = strlen (dest);
for (i = len - 1, ptr = dest + i; i >= 0; i--, ptr--)
if (*ptr == '\\' || *ptr == '/' || *ptr == '.')
break;
if (i < 0 || *ptr != '.')
{
if (*ext != '.')
{
dest [len++] = '.';
dest [len] = '\0';
}
strcat (dest + len, ext);
}
}
return (dest);
}
/* ---------------------------------------------------------------------[<]-
Function: fixed_extension
Synopsis: Copies src to dest and enforces ext extension. Returns dest.
Dest must be large enough for a fully-formatted filename; define it as
char [FILE_NAME_MAX + 1]. The ext argument can start with or without
a dot. If ext is null or empty, does nothing.
---------------------------------------------------------------------[>]-*/
char *
fixed_extension (
char *dest,
const char *src,
const char *ext)
{
ASSERT (dest);
ASSERT (src);
if (dest != src) /* Copy src to dest if not same */
strcpy (dest, src);
strip_extension (dest);
return (default_extension (dest, dest, ext));
}
/* ---------------------------------------------------------------------[<]-
Function: strip_extension
Synopsis: Removes dot and extension from the name, if any was present.
If the name contained multiple extensions, removes the last one only.
Returns name.
---------------------------------------------------------------------[>]-*/
char *
strip_extension (
char *name)
{
char *dot, *slash;
ASSERT (name);
dot = strrchr (name, '.'); /* Find dot in name, if any */
slash = strrchr (name, '\\'); /* Find last slash (DOS or Unix) */
if (slash == NULL)
slash = strrchr (name, '/');
if (dot > slash)
*dot = 0; /* If we had a dot, truncate name */
return (name);
}
/* ---------------------------------------------------------------------[<]-
Function: add_extension
Synopsis: Copies src to dest and adds ext if necessary. If extension
starts with "." then it will be added, in place of any existing extension.
If extension does not start with "." it will be added only if there is
no existing extension. If ext is null or empty, just copies src into
dest if required.
Dest must be large enough for a fully-formatted filename; define it as
char [FILE_NAME_MAX + 1].
---------------------------------------------------------------------[>]-*/
char *
add_extension (
char *dest,
const char *src,
const char *ext)
{
char
*result;
ASSERT (dest);
ASSERT (src);
if (!src || !dest)
return (NULL);
if (!ext || *ext == '\0')
{
if (dest != src) /* Copy src to dest if not same */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -