⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 backup.c

📁 GNU 系统开发优化 C 语言程序的应用程序
💻 C
字号:
/* backup.c -- make Emacs style backup file names   Copyright (C) 1992 Free Software Foundation, Inc.   This program is free software; you can redistribute it and/or modify   it without restriction.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.   GNU/Emacs style backups --   This behaviour is controlled by two environment variables,   VERSION_CONTROL and SIMPLE_BACKUP_SUFFIX.   VERSION_CONTROL determines what kinds of backups are made.  If it's   value is "numbered", then the first modification of some file   "eraserhead.c" will yield a backup file "eraserhead.c.~1~", the   second modification will yield "eraserhead.c.~2~", and so on.  It   does not matter if the version numbers are not a sequence;  the next   version will be one greater than the highest in that directory.   If the value of VERSION_CONTROL is "numbered_existing", then such   numbered backups will be made if there are already numbered backup   versions of the file.  Otherwise, the backup name will be that of   the original file with "~" (tilde) appended.  E.g., "eraserhead.c~".   If the value of VERSION_CONTROL is "simple", then the backup name   will be that of the original file with "~" appended, regardless of   whether or not there exist numbered versions in the directory.   For simple backups, the value of SIMPLE_BACKUP_SUFFIX will be used   rather than "~" if it is set.   If VERSION_CONTROL is unset, "numbered_existing" is assumed.  For   Emacs lovers, "nil" is equivalent to "numbered_existing" and "t" is   equivalent to "numbered".   Finally, if VERSION_CONTROL is "none" or "never", backups are not   made.  I suggest you avoid this behaviour. *//* Written by jla, based on code from djm (see `patch') */#include "sys.h"#include "backup.h"#include <ctype.h>#ifndef isascii#define ISDIGIT(c) (isdigit ((unsigned char) (c)))#else#define ISDIGIT(c) (isascii (c) && isdigit (c))#endif#ifndef NODIR#include <sys/types.h>#ifdef DIRENT#include <dirent.h>#ifdef direct#undef direct#endif#define direct dirent#define NLENGTH(direct) (strlen((direct)->d_name))#else /* !DIRENT */#define NLENGTH(direct) ((direct)->d_namlen)#ifdef USG#ifdef SYSNDIR#include <sys/ndir.h>#else /* !SYSNDIR */#include <ndir.h>#endif /* !SYSNDIR */#else /* !USG */#include <sys/dir.h>#endif /* !USG */#endif /* !DIRENT */#if defined (HAVE_UNISTD_H)#include <unistd.h>#endif#if defined (_POSIX_VERSION)	/* Might be defined in unistd.h.  *//* POSIX does not require that the d_ino field be present, and some   systems do not provide it. */#define REAL_DIR_ENTRY(dp) 1#else#define REAL_DIR_ENTRY(dp) ((dp)->d_ino != 0)#endif#else /* NODIR */#define generate_backup_filename(v,f) simple_backup_name((f))#endif /* NODIR */#ifndef SYS_BACKUP_SUFFIX#define SYS_BACKUP_SUFFIX "~"#endif#ifndef BACKUP_SUFFIX_STR#define BACKUP_SUFFIX_STR    "~"#endif#ifndef BACKUP_SUFFIX_CHAR#define BACKUP_SUFFIX_CHAR   '~'#endif#ifndef BACKUP_SUFFIX_FORMAT#define BACKUP_SUFFIX_FORMAT "%s.~%d~"#endif/* Default backup file suffix to use */static char *simple_backup_suffix = SYS_BACKUP_SUFFIX;/* What kinds of backup files to make -- see   table `version_control_values' below. */enum backup_mode version_control = unknown;/* Construct a simple backup name for PATHNAME by appending   the value of `simple_backup_suffix'. */static char *simple_backup_name (pathname)     char *pathname;{  char *backup_name;  backup_name = xmalloc (strlen (pathname)			 + strlen (simple_backup_suffix) + 2);  sprintf (backup_name, "%s%s", pathname, simple_backup_suffix);  return backup_name;}#ifndef NODIR/* If DIRENTRY is a numbered backup version of file BASE, return   that number.  BASE_LENGTH is the string length of BASE. */static intversion_number (base, direntry, base_length)     char *base;     char *direntry;     int base_length;{  int version;  char *p;  version = 0;  if (!strncmp (base, direntry, base_length)      && ISDIGIT (direntry[base_length + 2]))    {      for (p = &direntry[base_length + 2]; ISDIGIT (*p); ++p)	version = version * 10 + *p - '0';      if (p[0] != BACKUP_SUFFIX_CHAR || p[1])	version = 0;    }  return version;}/* Return the highest version of file FILENAME in directory   DIRNAME.  Return 0 if there are no numbered versions. */static inthighest_version (filename, dirname)     char *filename, *dirname;{  DIR *dirp;  struct direct *dp;  int highest_version;  int this_version;  int file_name_length;  dirp = opendir (dirname);  if (!dirp)    return 0;  highest_version = 0;  file_name_length = strlen (filename);  while ((dp = readdir (dirp)) != 0)    {      if (!REAL_DIR_ENTRY (dp) || NLENGTH (dp) <= file_name_length + 2)	continue;      this_version = version_number (filename, dp->d_name, file_name_length);      if (this_version > highest_version)	highest_version = this_version;    }  closedir (dirp);  return highest_version;}/* Return the highest version number for file PATHNAME.  If there   are no backups, or only a simple backup, return 0. */static intmax_version (pathname)     char *pathname;{  register char *p;  register char *filename;  int pathlen = strlen (pathname);  int version;  p = pathname + pathlen - 1;  while (p > pathname && *p != '/')    p--;  if (*p == '/')    {      int dirlen = p - pathname;      register char *dirname;      filename = p + 1;      dirname = xmalloc (dirlen + 1);      strncpy (dirname, pathname, (dirlen));      dirname[dirlen] = '\0';      version = highest_version (filename, dirname);      free (dirname);      return version;    }  filename = pathname;  version = highest_version (filename, ".");  return version;}/* Generate a backup filename for PATHNAME, dependent on the   value of VERSION_CONTROL. */static char *generate_backup_filename (version_control, pathname)     enum backup_mode version_control;     char *pathname;{  int last_numbered_version;  char *backup_name;  if (version_control == none)    return 0;  if (version_control == simple)    return simple_backup_name (pathname);  last_numbered_version = max_version (pathname);  if (version_control == numbered_existing      && last_numbered_version == 0)    return simple_backup_name (pathname);  last_numbered_version++;  backup_name = xmalloc (strlen (pathname) + 16);  if (!backup_name)    return 0;  sprintf (backup_name, BACKUP_SUFFIX_STR, pathname,	   (int) last_numbered_version);  return backup_name;}#endif /* !NODIR */static struct version_control_values values[] ={  {none, "never"},		/* Don't make backups. */  {simple, "simple"},		/* Only simple backups */  {numbered_existing, "existing"},	/* Numbered if they already exist */  {numbered_existing, "nil"},	/* Ditto */  {numbered, "numbered"},	/* Numbered backups */  {numbered, "t"},		/* Ditto */  {unknown, 0}			/* Initial, undefined value. */};extern char *getenv ();/* Determine the value of `version_control' by looking in the   environment variable "VERSION_CONTROL".  Defaults to   numbered_existing. */enum backup_modeversion_control_value (){  char *version;  struct version_control_values *v;  version = getenv ("VERSION_CONTROL");  if (version == 0 || *version == 0)    return numbered_existing;  v = &values[0];  while (v->name)    {      if (strcmp (version, v->name) == 0)	return v->value;      v++;    }  return unknown;}/* Initialize information used in determining backup filenames. */voidinitialize_backups (){  char *v = getenv ("SIMPLE_BACKUP_SUFFIX");  if (v && *v)    simple_backup_suffix = v;#ifdef NODIR  version_control = simple;#else /* !NODIR */  version_control = version_control_value ();  if (version_control == unknown)    {      fprintf (stderr, "indent:  Strange version-control value\n");      fprintf (stderr, "indent:  Using numbered-existing\n");      version_control = numbered_existing;    }#endif /* !NODIR */}/* Prints an error message using `perror' */extern void sys_error ();/* Make a backup copy of FILE, taking into account version-control.   See the description at the beginning of the file for details. */voidmake_backup (file)     struct file_buffer *file;{  int fd;  register char *p = file->name + strlen (file->name) - 1;  char *backup_filename;  char *new_backup_name;  backup_filename = generate_backup_filename (version_control, file->name);  if (!backup_filename)    {      fprintf (stderr, "indent: Can't make backup filename of %s", file->name);      exit (1);    }  fd = creat (backup_filename, 0666);  if (fd < 0)    sys_error (backup_filename);  if (write (fd, file->data, file->size) != file->size)    sys_error (backup_filename);  close (fd);  free (backup_filename);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -