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

📄 install.c

📁 Linux.Programming.by example 的源代码绝对经典
💻 C
📖 第 1 页 / 共 2 页
字号:
/* install - copy files and set attributes   Copyright (C) 89, 90, 91, 1995-2002 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 2, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  *//* Written by David MacKenzie <djm@gnu.ai.mit.edu> */#ifdef _AIX #pragma alloca#endif#include <config.h>#include <stdio.h>#include <getopt.h>#include <sys/types.h>#include <pwd.h>#include <grp.h>#include "system.h"#include "backupfile.h"#include "error.h"#include "cp-hash.h"#include "copy.h"#include "dirname.h"#include "makepath.h"#include "modechange.h"#include "path-concat.h"#include "quote.h"#include "xstrtol.h"/* The official name of this program (e.g., no `g' prefix).  */#define PROGRAM_NAME "install"#define AUTHORS "David MacKenzie"#if HAVE_SYS_WAIT_H# include <sys/wait.h>#endifstruct passwd *getpwnam ();struct group *getgrnam ();#ifndef _POSIX_VERSIONuid_t getuid ();gid_t getgid ();#endif#if ! HAVE_ENDGRENT# define endgrent() ((void) 0)#endif#if ! HAVE_ENDPWENT# define endpwent() ((void) 0)#endif/* Initial number of entries in each hash table entry's table of inodes.  */#define INITIAL_HASH_MODULE 100/* Initial number of entries in the inode hash table.  */#define INITIAL_ENTRY_TAB_SIZE 70/* Number of bytes of a file to copy at a time. */#define READ_SIZE (32 * 1024)int isdir ();int stat ();static int change_timestamps (const char *from, const char *to);static int change_attributes (const char *path);static int copy_file (const char *from, const char *to,		      const struct cp_options *x);static int install_file_to_path (const char *from, const char *to,				 const struct cp_options *x);static int install_file_in_dir (const char *from, const char *to_dir,				const struct cp_options *x);static int install_file_in_file (const char *from, const char *to,				 const struct cp_options *x);static void get_ids (void);static void strip (const char *path);void usage (int status);/* The name this program was run with, for error messages. */char *program_name;/* The user name that will own the files, or NULL to make the owner   the current user ID. */static char *owner_name;/* The user ID corresponding to `owner_name'. */static uid_t owner_id;/* The group name that will own the files, or NULL to make the group   the current group ID. */static char *group_name;/* The group ID corresponding to `group_name'. */static gid_t group_id;/* The permissions to which the files will be set.  The umask has   no effect. */static mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;/* If nonzero, strip executable files after copying them. */static int strip_files;/* If nonzero, install a directory instead of a regular file. */static int dir_arg;static struct option const long_options[] ={  {"backup", optional_argument, NULL, 'b'},  {"directory", no_argument, NULL, 'd'},  {"group", required_argument, NULL, 'g'},  {"mode", required_argument, NULL, 'm'},  {"owner", required_argument, NULL, 'o'},  {"preserve-timestamps", no_argument, NULL, 'p'},  {"strip", no_argument, NULL, 's'},  {"suffix", required_argument, NULL, 'S'},  {"version-control", required_argument, NULL, 'V'}, /* Deprecated. FIXME. */  {"verbose", no_argument, NULL, 'v'},  {GETOPT_HELP_OPTION_DECL},  {GETOPT_VERSION_OPTION_DECL},  {NULL, 0, NULL, 0}};static voidcp_option_init (struct cp_options *x){  x->copy_as_regular = 1;  x->dereference = DEREF_ALWAYS;  x->unlink_dest_before_opening = 1;  x->unlink_dest_after_failed_open = 0;  x->hard_link = 0;  x->interactive = I_UNSPECIFIED;  x->move_mode = 0;  x->myeuid = geteuid ();  x->one_file_system = 0;  x->preserve_ownership = 0;  x->preserve_links = 0;  x->preserve_mode = 0;  x->preserve_timestamps = 0;  x->require_preserve = 0;  x->recursive = 0;  x->sparse_mode = SPARSE_AUTO;  x->symbolic_link = 0;  x->backup_type = none;  /* Create destination files initially writable so we can run strip on them.     Although GNU strip works fine on read-only files, some others     would fail.  */  x->set_mode = 1;  x->mode = S_IRUSR | S_IWUSR;  x->stdin_tty = 0;  x->umask_kill = 0;  x->update = 0;  x->verbose = 0;  x->xstat = stat;  x->dest_info = NULL;  x->src_info = NULL;}intmain (int argc, char **argv){  int optc;  int errors = 0;  const char *specified_mode = NULL;  int make_backups = 0;  char *backup_suffix_string;  char *version_control_string = NULL;  int mkdir_and_install = 0;  struct cp_options x;  int n_files;  char **file;  program_name = argv[0];  setlocale (LC_ALL, "");  bindtextdomain (PACKAGE, LOCALEDIR);  textdomain (PACKAGE);  atexit (close_stdout);  cp_option_init (&x);  owner_name = NULL;  group_name = NULL;  strip_files = 0;  dir_arg = 0;  umask (0);  /* FIXME: consider not calling getenv for SIMPLE_BACKUP_SUFFIX unless     we'll actually use backup_suffix_string.  */  backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");  while ((optc = getopt_long (argc, argv, "bcsDdg:m:o:pvV:S:", long_options,			      NULL)) != -1)    {      switch (optc)	{	case 0:	  break;	case 'V':  /* FIXME: this is deprecated.  Remove it in 2001.  */	  error (0, 0,		 _("warning: --version-control (-V) is obsolete;  support for\ it\nwill be removed in some future release.  Use --backup=%s instead."		   ), optarg);	  /* Fall through.  */	case 'b':	  make_backups = 1;	  if (optarg)	    version_control_string = optarg;	  break;	case 'c':	  break;	case 's':	  strip_files = 1;	  break;	case 'd':	  dir_arg = 1;	  break;	case 'D':	  mkdir_and_install = 1;	  break;	case 'v':	  x.verbose = 1;	  break;	case 'g':	  group_name = optarg;	  break;	case 'm':	  specified_mode = optarg;	  break;	case 'o':	  owner_name = optarg;	  break;	case 'p':	  x.preserve_timestamps = 1;	  break;	case 'S':	  make_backups = 1;	  backup_suffix_string = optarg;	  break;	case_GETOPT_HELP_CHAR;	case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);	default:	  usage (EXIT_FAILURE);	}    }  /* Check for invalid combinations of arguments. */  if (dir_arg && strip_files)    error (EXIT_FAILURE, 0,	   _("the strip option may not be used when installing a directory"));  if (backup_suffix_string)    simple_backup_suffix = xstrdup (backup_suffix_string);  x.backup_type = (make_backups		   ? xget_version (_("backup type"),				   version_control_string)		   : none);  n_files = argc - optind;  file = argv + optind;  if (n_files == 0 || (n_files == 1 && !dir_arg))    {      error (0, 0, _("too few arguments"));      usage (EXIT_FAILURE);    }  if (specified_mode)    {      struct mode_change *change = mode_compile (specified_mode, 0);      if (change == MODE_INVALID)	error (EXIT_FAILURE, 0, _("invalid mode %s"), quote (specified_mode));      else if (change == MODE_MEMORY_EXHAUSTED)	xalloc_die ();      mode = mode_adjust (0, change);    }  get_ids ();  if (dir_arg)    {      int i;      for (i = 0; i < n_files; i++)	{	  errors |=	    make_path (file[i], mode, mode, owner_id, group_id, 0,		       (x.verbose ? _("creating directory %s") : NULL));	}    }  else    {      /* FIXME: it's a little gross that this initialization is	 required by copy.c::copy. */      hash_init ();      if (n_files == 2)        {          if (mkdir_and_install)	    errors = install_file_to_path (file[0], file[1], &x);	  else if (!isdir (file[1]))	    errors = install_file_in_file (file[0], file[1], &x);	  else	    errors = install_file_in_dir (file[0], file[1], &x);	}      else	{

⌨️ 快捷键说明

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