/*------------ Telecommunications & Signal Processing Lab ------------- McGill University Routine: void FLbackup (const char Fname[]) Purpose: Rename an existing file Description: This subroutine backs up a file. If a file with the given name exists, say xxx, that file is renamed to xxx~. Any previous file with the name xxx~ is removed. For MS-DOS, the ~ character is the last character in the file extension. In MS-DOS xxx is renamed to xxx.~. Only regular files are backed up. If a backup file is created, a warning message indicating the new name is issued. One use of this routine is to a copy of an existing file before opening a new file. This routine will terminate execution if the file cannot be backed up. Parameters: -> const char Fname[] File name Author / revision: P. Kabal Copyright (C) 1996 $Revision: 1.21 $ $Date: 1996/05/06 18:05:14 $ ----------------------------------------------------------------------*/ static char rcsid[] = "$Id: FLbackup.c 1.21 1996/05/06 AFsp-V2R1 $"; #include #include #include #include #ifndef sun # ifdef __STDC__ # define USE_REMOVE /* Use ANSI remove function */ # endif #endif #ifdef USE_REMOVE # define REMOVE remove #else /* Sun non-ANSI library does not have remove */ # include /* unlink (and rename) */ # define REMOVE unlink #endif #ifdef _MSDOS # ifndef MSDOS # define MSDOS 1 /* For MSVC with /Za option */ # endif #endif #ifdef MSDOS # define MAX_EXT_NAME 3 /* Extension (not counting dot) */ #endif #define MINV(a, b) (((a) < (b)) ? (a) : (b)) void FLbackup (Fname) const char Fname[]; { char Fback[FILENAME_MAX+1]; #ifdef MSDOS char Fdir[FILENAME_MAX+1]; char Fbase[FILENAME_MAX+1]; char Fext[FILENAME_MAX+1]; int i; #endif int n; /* Rename only if the file is a regular file */ if (FLexist (Fname)) { /* There are conditions under which this routine may clobber existing files. For instance if the input file name is too long, the truncated name used for the backup file could coincide with an existing file. Such problems will not occur if the input file name is such that the backup file name formed from it by adding one or two extra characters does not exceed exceed the maximum file name length. */ #ifdef MSDOS /* For MS-DOS, add ~ as the last character of the file extension */ FLdirName (Fname, Fdir); FLpreName (Fname, Fbase); n = FLextName (Fname, Fext); if (n == 0) { Fext[0] = '.'; Fext[1] = '~'; Fext[2] = '\0'; } else { i = MINV (n, MAX_EXT_NAME); Fext[i] = '~'; Fext[i+1] = '\0'; } STcatMax (Fext, Fbase, FILENAME_MAX); n = FLjoinNames (Fdir, Fbase, Fback); if (n == FILENAME_MAX) Fback[n-1] = '~'; /* File name may be too long, try to keep a ~ */ #else /* Add a ~ to the overall file name */ n = STcopyMax (Fname, Fback, FILENAME_MAX-1); Fback[n] = '~'; Fback[n+1] = '\0'; #endif /* Rename the file; rename is not guaranteed to delete a previous backup */ if (FLexist (Fback)) { if (REMOVE (Fback) != 0) UTerror ("FLbackup: Error deleting previous backup file \"%s\"", Fback); } if (rename (Fname, Fback) == 0) UTwarn ("FLbackup - Renamed existing file to \"%s\"", Fback); else UTerror ("FLbackup: Error backing up file \"%s\"", Fname); } return; }