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

📄 rm.c

📁 HLPDK V10.0+ System Extension Library
💻 C
📖 第 1 页 / 共 2 页
字号:
/* `rm' file deletion utility for GNU.
   Copyright (C) 1988, 1989, 1990 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 1, or (at your option)
   any later version.

   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.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */

/* Written by Paul Rubin, David MacKenzie, and Richard Stallman. */

/* MS-DOS port (c) 1990 by Thorsten Ohl, ohl@gnu.ai.mit.edu
   This port is also distributed under the terms of the
   GNU General Public License as published by the
   Free Software Foundation.

   Please note that this file is not identical to the
   original GNU release, you should have received this
   code as patch to the official release.  */

#ifdef MSDOS
static char RCS_Id[] =
  "$Header: e:/gnu/fileutil/RCS/rm.c 1.4.0.3 90/09/20 08:46:14 tho Exp $";

static char Program_Id[] = "rm";
static char RCS_Revision[] = "$Revision: 1.4.0.3 $";

#define VERSION \
  "GNU %s, Version %.*s (compiled %s %s for MS-DOS)\n", Program_Id, \
  (sizeof RCS_Revision - 14), (RCS_Revision + 11), __DATE__, __TIME__

#define COPYING \
  "This is free software, distributed under the terms of the\n" \
  "GNU General Public License.  For details, see the file COPYING.\n"
#endif /* MSDOS */

#include <stdio.h>
#include <getopt.h>
#include <sys/types.h>
#include <errno.h>
#include "system.h"

#ifdef STDC_HEADERS
#include <stdlib.h>
#else
char *malloc ();
char *realloc ();

extern int errno;
#endif

#ifdef MSDOS
#include <string.h>
#include <malloc.h>
#include <io.h>
#include <direct.h>

#include <gnulib.h>

extern  void main (int argc, char **argv);
static  int rm (void);
static  int remove_file (struct stat *statp);
static  int remove_dir (struct stat *statp);
static  int clear_directory (struct stat *statp);
static  int yesno (void);
static  char *basename (char *name);
static  char *stpcpy (char *dest, char *source);
static  void usage (void);

extern  int eaccess (char *path, int mode);
extern  int eaccess_stat (struct stat *statp, int mode);

static  void strip_trailing_slashes (char **path);
#define strip_trailing_slashes(path)	strip_trailing_slashes (&path)
#define check_stack(stck, ino)		0
#define unlink(name)			force_unlink (name)
static int force_unlink (char *filename);

#else /* not MSDOS */

char *basename ();
char *stpcpy ();
char *xmalloc ();
char *xrealloc ();
int check_stack ();
int clear_directory ();
int eaccess_stat ();
int remove_dir ();
int remove_file ();
int rm ();
int yesno ();
void error ();
void strip_trailing_slashes ();
void usage ();

#endif /* not MSDOS */


/* Path of file now being processed; extended as necessary. */
char *pathname;

/* Number of bytes currently allocated for `pathname';
   made larger when necessary, but never smaller.  */
int pnsize;

/* Name this program was run with.  */
char *program_name;

/* If nonzero, display the name of each file removed. */
int verbose;

/* If nonzero, ignore nonexistant files. */
int ignore_missing_files;

/* If nonzero, recursively remove directories. */
int recursive;

/* If nonzero, query the user about whether to remove each file. */
int interactive;

/* If nonzero, remove directories with unlink instead of rmdir, and don't
   require a directory to be empty before trying to unlink it.
   Only works for the super-user. */
int unlink_dirs;

/* Information for detecting attempted removal of `.' and `..'. */
dev_t dot_dev, dotdot_dev;
ino_t dot_ino, dotdot_ino;

struct option long_opts[] =
{
#ifdef MSDOS
  {"copying", 0, NULL, 30},
  {"version", 0, NULL, 31},
#endif
  {"directory", 0, &unlink_dirs, 1},
  {"force", 0, NULL, 'f'},
  {"interactive", 0, NULL, 'i'},
  {"recursive", 0, &recursive, 1},
  {"verbose", 0, &verbose, 1},
  {NULL, 0, NULL, 0}
};

void
main (argc, argv)
     int argc;
     char **argv;
{
  int err = 0;
  int c;
  int ind;
  struct stat stats;

  verbose = ignore_missing_files = recursive = interactive
    = unlink_dirs = 0;
  pnsize = 256;
  program_name = argv[0];
  pathname = xmalloc (pnsize);

  while ((c = getopt_long (argc, argv, "dfirvR", long_opts, &ind)) != EOF)
    {
      switch (c)
	{
	case 0:			/* Long option. */
	  break;
	case 'd':
	  unlink_dirs = 1;
	  break;
	case 'f':
	  ignore_missing_files = 1;
	  interactive = 0;
	  break;
	case 'i':
	  ignore_missing_files = 0;
	  interactive = 1;
	  break;
	case 'r':
	case 'R':
	  recursive = 1;
	  break;
	case 'v':
	  verbose = 1;
	  break;
#ifdef MSDOS
	case 30:
	  fprintf (stderr, COPYING);
	  exit (0);
	  break;
	case 31:
	  fprintf (stderr, VERSION);
	  exit (0);
	  break;
#endif
	default:
	  usage ();
	}
    }

  if (optind == argc)
    usage ();

#ifndef MSDOS			/* this fails at the root ... */
  if (lstat (".", &stats))
    error (1, errno, ".");
  dot_dev = stats.st_dev;
  dot_ino = stats.st_ino;
  if (lstat ("..", &stats))
    error (1, errno, "..");
  dotdot_dev = stats.st_dev;
  dotdot_ino = stats.st_ino;
#endif /* not MSDOS */

  for (; optind < argc; optind++)
    {
      int len;

      strip_trailing_slashes (argv[optind]);
      len = strlen (argv[optind]);
      if (len + 1 > pnsize)
	{
	  free (pathname);
	  pnsize = 2 * (len + 1);
	  pathname = xmalloc (pnsize);
	}
      strcpy (pathname, argv[optind]);
      err += rm ();
    }

  exit (err > 0);
}

/* Remove file or directory `pathname' after checking appropriate things.
   Return 0 if `pathname' is removed, 1 if not. */

int
rm ()
{
  struct stat path_stats;

  if (lstat (pathname, &path_stats))
    {
      if (errno == ENOENT && ignore_missing_files)
	return 0;
      error (0, errno, "%s", pathname);
      return 1;
    }

#ifndef MSDOS
  if ((path_stats.st_dev == dot_dev && path_stats.st_ino == dot_ino)
      || (path_stats.st_dev == dotdot_dev && path_stats.st_ino == dotdot_ino))
    {
      error (0, 0, "%s: cannot remove current directory or parent", pathname);
      return 1;
    }
#endif /* not MSDOS */

  if ((path_stats.st_mode & S_IFMT) == S_IFDIR && !unlink_dirs)
    return remove_dir (&path_stats);
  else
    return remove_file (&path_stats);
}

/* Query the user if appropriate, and if ok try to remove the
   non-directory `pathname', which STATP contains info about.
   Return 0 if `pathname' is removed, 1 if not. */

int
remove_file (statp)
     struct stat *statp;
{
  if (interactive)
    {
      fprintf (stderr, "%s: remove %s`%s'? ", program_name,
	       (statp->st_mode & S_IFMT) == S_IFDIR ? "directory " : "",
	       pathname);
      if (!yesno ())
	return 1;
    }

  if (verbose)
    printf ("  %s\n", pathname);

  if (unlink (pathname))
    {
      error (0, errno, "%s", pathname);
      return 1;
    }
  return 0;
}

/* If not in recursive mode, print an error message and return 1.
   Otherwise, query the user if appropriate, then try to recursively
   remove directory `pathname', which STATP contains info about.
   Return 0 if `pathname' is removed, 1 if not. */

int
remove_dir (statp)
     struct stat *statp;
{
  int err;
  int writable;

  if (!recursive)
    {
      error (0, 0, "%s: is a directory", pathname);
      return 1;
    }

#ifdef S_IFLNK
  if ((statp->st_mode & S_IFMT) == S_IFLNK)
    writable = 1;
  else
#endif
    writable = eaccess_stat (statp, W_OK) == 0;

  if (!writable)
    {
      error (0, 0, "%s: no write permission for directory", pathname);
      return 1;
    }

  if (interactive)
    {
      fprintf (stderr, "%s: recursively descend directory `%s'? ",
	       program_name, pathname);
      if (!yesno ())
	return 1;
    }

⌨️ 快捷键说明

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