1
/* Copyright (c) 1993,1994, Joseph Arceneaux. All rights reserved.
3
* This file is subject to the terms of the GNU General Public License as
4
* published by the Free Software Foundation. A copy of this license is
5
* included with this software distribution in the file COPYING. If you
6
* do not have a copy, you may obtain a copy by writing to the Free
7
* Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9
* This software is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details. */
14
/* GNU/Emacs style backups --
15
* This behaviour is controlled by two environment variables,
16
* VERSION_CONTROL and SIMPLE_BACKUP_SUFFIX.
18
* VERSION_CONTROL determines what kinds of backups are made. If it's
19
* value is "numbered", then the first modification of some file
20
* "eraserhead.c" will yield a backup file "eraserhead.c.~1~", the
21
* second modification will yield "eraserhead.c.~2~", and so on. It
22
* does not matter if the version numbers are not a sequence; the next
23
* version will be one greater than the highest in that directory.
25
* If the value of VERSION_CONTROL is "numbered_existing", then such
26
* numbered backups will be made if there are already numbered backup
27
* versions of the file. Otherwise, the backup name will be that of
28
* the original file with "~" (tilde) appended. E.g., "eraserhead.c~".
30
* If the value of VERSION_CONTROL is "simple", then the backup name
31
* will be that of the original file with "~" appended, regardless of
32
* whether or not there exist numbered versions in the directory.
34
* For simple backups, the value of SIMPLE_BACKUP_SUFFIX will be used
35
* rather than "~" if it is set.
37
* If VERSION_CONTROL is unset, "numbered_existing" is assumed. For
38
* Emacs lovers, "nil" is equivalent to "numbered_existing" and "t" is
39
* equivalent to "numbered".
41
* Finally, if VERSION_CONTROL is "none" or "never", backups are not
42
* made. I suggest you avoid this behaviour.
44
* Added, october 1999 (by Chris F.A. Johnson):
46
* If VERSION_WIDTH is set, then it controls zero padding of a numbered
49
/* Written by jla, based on code from djm (see `patch') */
54
#if defined (HAVE_UNISTD_H)
61
#elif defined(HAVE_SYS_UTIME_H)
62
#include <sys/utime.h>
66
#if defined (_WIN32) && !defined (__CYGWIN__)
73
#define ISDIGIT(c) (isdigit ((unsigned char) (c)))
75
#define ISDIGIT(c) (isascii (c) && isdigit (c))
77
#include <sys/types.h>
80
# define NAMLEN(dirent) strlen((dirent)->d_name)
82
# define dirent direct
83
# define NAMLEN(dirent) (dirent)->d_namlen
85
# include <sys/ndir.h>
93
# if !defined(HAVE_SYS_NDIR_H) && !defined(HAVE_SYS_DIR_H) && !defined(HAVE_NDIR_H)
102
RCSTAG_CC ("$Id: backup.c,v 1.17 2001/10/16 18:23:48 david Exp $");
105
#if defined (_POSIX_VERSION) /* Might be defined in unistd.h. */
106
/* POSIX does not require that the d_ino field be present, and some
107
systems do not provide it. */
108
#define REAL_DIR_ENTRY(dp) 1
110
#define REAL_DIR_ENTRY(dp) ((dp)->d_ino != 0)
113
#define generate_backup_filename(v,f) simple_backup_name((f))
116
#ifndef BACKUP_SUFFIX_STR
117
#define BACKUP_SUFFIX_STR "~"
120
#ifndef BACKUP_SUFFIX_CHAR
121
#define BACKUP_SUFFIX_CHAR '~'
124
#ifndef BACKUP_SUFFIX_FORMAT
125
#define BACKUP_SUFFIX_FORMAT "%s.~%0*d~"
128
/* Default backup file suffix to use */
129
static char *simple_backup_suffix = BACKUP_SUFFIX_STR;
131
/* What kinds of backup files to make -- see
132
table `version_control_values' below. */
133
enum backup_mode version_control = unknown;
134
int version_width = 1;
136
/* Construct a simple backup name for PATHNAME by appending
137
the value of `simple_backup_suffix'. */
145
backup_name = xmalloc (strlen (pathname) + strlen (simple_backup_suffix) + 2);
146
sprintf (backup_name, "%s%s", pathname, simple_backup_suffix);
151
/* If DIRENTRY is a numbered backup version of file BASE, return
152
that number. BASE_LENGTH is the string length of BASE. */
164
if (!strncmp (base, direntry, base_length) && ISDIGIT (direntry[base_length + 2]))
166
for (p = &direntry[base_length + 2]; ISDIGIT (*p); ++p)
168
version = version * 10 + *p - '0';
171
if (p[0] != BACKUP_SUFFIX_CHAR || p[1])
181
/* Return the highest version of file FILENAME in directory
182
DIRNAME. Return 0 if there are no numbered versions. */
193
int file_name_length;
195
dirp = opendir (dirname);
202
file_name_length = strlen (filename);
204
while ((dp = readdir (dirp)) != 0)
206
if (!REAL_DIR_ENTRY (dp) || NAMLEN (dp) <= file_name_length + 2)
212
this_version = version_number (filename, dp->d_name, file_name_length);
213
if (this_version > highest_version)
215
highest_version = this_version;
220
return highest_version;
224
/* Return the highest version number for file PATHNAME. If there
225
are no backups, or only a simple backup, return 0. */
233
int pathlen = strlen (pathname);
236
p = pathname + pathlen - 1;
237
while (p > pathname && *p != '/')
244
int dirlen = p - pathname;
248
dirname = xmalloc (dirlen + 1);
249
strncpy (dirname, pathname, (dirlen));
250
dirname[dirlen] = '\0';
251
version = highest_version (filename, dirname);
257
version = highest_version (filename, ".");
262
/* Generate a backup filename for PATHNAME, dependent on the
263
value of VERSION_CONTROL. */
266
generate_backup_filename (
267
enum backup_mode version_control,
270
int last_numbered_version;
273
if (version_control == none)
278
if (version_control == simple)
280
return simple_backup_name (pathname);
283
last_numbered_version = max_version (pathname);
284
if (version_control == numbered_existing && last_numbered_version == 0)
286
return simple_backup_name (pathname);
289
last_numbered_version++;
290
backup_name = xmalloc (strlen (pathname) + 16);
297
sprintf (backup_name, BACKUP_SUFFIX_FORMAT, pathname, version_width, (int) last_numbered_version);
304
static struct version_control_values values[] = {
305
{none, "never"}, /* Don't make backups. */
306
{none, "none"}, /* Ditto */
307
{simple, "simple"}, /* Only simple backups */
308
{numbered_existing, "existing"}, /* Numbered if they already exist */
309
{numbered_existing, "nil"}, /* Ditto */
310
{numbered, "numbered"}, /* Numbered backups */
311
{numbered, "t"}, /* Ditto */
312
{unknown, 0} /* Initial, undefined value. */
316
/* Determine the value of `version_control' by looking in the
317
environment variable "VERSION_CONTROL". Defaults to
318
numbered_existing. */
321
version_control_value (void)
324
struct version_control_values *v;
326
version = getenv ("VERSION_CONTROL");
327
if (version == 0 || *version == 0)
329
return numbered_existing;
335
if (strcmp (version, v->name) == 0)
347
/* Initialize information used in determining backup filenames. */
350
set_version_width (void)
352
char *v = getenv ("VERSION_WIDTH");
354
if (v && ISDIGIT (*v))
355
version_width = atoi (v);
356
if (version_width > 16)
361
initialize_backups (void)
363
char *v = getenv ("SIMPLE_BACKUP_SUFFIX");
367
simple_backup_suffix = v;
371
version_control = simple;
373
version_control = version_control_value ();
374
if (version_control == unknown)
376
fprintf (stderr, _("indent: Strange version-control value\n"));
377
fprintf (stderr, _("indent: Using numbered-existing\n"));
378
version_control = numbered_existing;
381
set_version_width ();
385
/* Make a backup copy of FILE, taking into account version-control.
386
See the description at the beginning of the file for details. */
390
struct file_buffer *file,
391
const struct stat *file_stats)
394
char *backup_filename;
397
if (version_control == none)
402
backup_filename = generate_backup_filename (version_control, file->name);
403
if (!backup_filename)
405
fprintf (stderr, _("indent: Can't make backup filename of %s\n"), file->name);
409
bf = fopen (backup_filename, "w");
412
fatal (_("Can't open backup file %s"), backup_filename);
415
size = fwrite (file->data, file->size, 1, bf);
418
fatal (_("Can't write to backup file %s"), backup_filename);
423
#ifdef PRESERVE_MTIME
427
buf.actime = time (NULL);
428
buf.modtime = file_stats->st_mtime;
429
if (utime (backup_filename, &buf) != 0)
431
WARNING (_("Can't preserve modification time on backup file %s"), backup_filename, 0);
436
free (backup_filename);