ln.c

来自「Linux下文件工具。」· C语言 代码 · 共 575 行 · 第 1/2 页

C
575
字号
      if (unlink (dest) && errno != ENOENT)	{	  error (0, errno, _("cannot remove %s"), quote (dest));	  return 1;	}    }  else if (errno != ENOENT)    {      error (0, errno, _("accessing %s"), quote (dest));      return 1;    }  if (verbose)    {      printf ((symbolic_link	       ? _("create symbolic link %s to %s")	       : _("create hard link %s to %s")),	      quote_n (0, dest), quote_n (1, source));      if (backup_succeeded)	printf (_(" (backup: %s)"), quote (dest_backup));      putchar ('\n');    }  if ((*linkfunc) (source, dest) == 0)    {      return 0;    }  error (0, errno,	 (symbolic_link	  ? _("creating symbolic link %s to %s")	  : _("creating hard link %s to %s")),	 quote_n (0, dest), quote_n (1, source));  if (dest_backup)    {      if (rename (dest_backup, dest))	error (0, errno, _("cannot un-backup %s"), quote (dest));    }  return 1;}voidusage (int status){  if (status != 0)    fprintf (stderr, _("Try `%s --help' for more information.\n"),	     program_name);  else    {      printf (_("\Usage: %s [OPTION]... TARGET [LINK_NAME]\n\  or:  %s [OPTION]... TARGET... DIRECTORY\n\  or:  %s [OPTION]... --target-directory=DIRECTORY TARGET...\n\"),	      program_name, program_name, program_name);      fputs (_("\Create a link to the specified TARGET with optional LINK_NAME.\n\If LINK_NAME is omitted, a link with the same basename as the TARGET is\n\created in the current directory.  When using the second form with more\n\than one TARGET, the last argument must be a directory;  create links\n\in DIRECTORY to each TARGET.  Create hard links by default, symbolic\n\links with --symbolic.  When creating hard links, each TARGET must exist.\n\\n\"), stdout);      fputs (_("\Mandatory arguments to long options are mandatory for short options too.\n\"), stdout);      fputs (_("\      --backup[=CONTROL]      make a backup of each existing destination file\n\  -b                          like --backup but does not accept an argument\n\  -d, -F, --directory         hard link directories (super-user only)\n\  -f, --force                 remove existing destination files\n\"), stdout);      fputs (_("\  -n, --no-dereference        treat destination that is a symlink to a\n\                                directory as if it were a normal file\n\  -i, --interactive           prompt whether to remove destinations\n\  -s, --symbolic              make symbolic links instead of hard links\n\"), stdout);      fputs (_("\  -S, --suffix=SUFFIX         override the usual backup suffix\n\      --target-directory=DIRECTORY  specify the DIRECTORY in which to create\n\                                the links\n\  -v, --verbose               print name of each file before linking\n\"), stdout);      fputs (HELP_OPTION_DESCRIPTION, stdout);      fputs (VERSION_OPTION_DESCRIPTION, stdout);      fputs (_("\\n\The backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\The version control method may be selected via the --backup option or through\n\the VERSION_CONTROL environment variable.  Here are the values:\n\\n\"), stdout);      fputs (_("\  none, off       never make backups (even if --backup is given)\n\  numbered, t     make numbered backups\n\  existing, nil   numbered if numbered backups exist, simple otherwise\n\  simple, never   always make simple backups\n\"), stdout);      printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);    }  exit (status);}intmain (int argc, char **argv){  int c;  int errors;  int make_backups = 0;  char *backup_suffix_string;  char *version_control_string = NULL;  char *target_directory = NULL;  int target_directory_specified;  unsigned int n_files;  char **file;  int dest_is_dir;  program_name = argv[0];  setlocale (LC_ALL, "");  bindtextdomain (PACKAGE, LOCALEDIR);  textdomain (PACKAGE);  atexit (close_stdout);  /* FIXME: consider not calling getenv for SIMPLE_BACKUP_SUFFIX unless     we'll actually use backup_suffix_string.  */  backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");  symbolic_link = remove_existing_files = interactive = verbose    = hard_dir_link = 0;  errors = 0;  while ((c = getopt_long (argc, argv, "bdfinsvFS:V:", long_options, NULL))	 != -1)    {      switch (c)	{	case 0:			/* Long-named option. */ 	  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 'd':	case 'F':	  hard_dir_link = 1;	  break;	case 'f':	  remove_existing_files = 1;	  interactive = 0;	  break;	case 'i':	  remove_existing_files = 0;	  interactive = 1;	  break;	case 'n':	  dereference_dest_dir_symlinks = 0;	  break;	case 's':#ifdef S_ISLNK	  symbolic_link = 1;#else	  error (1, 0, _("symbolic links are not supported on this system"));#endif	  break;	case TARGET_DIRECTORY_OPTION:	  target_directory = optarg;	  break;	case 'v':	  verbose = 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 (1);	  break;	}    }  n_files = argc - optind;  file = argv + optind;  if (n_files == 0)    {      error (0, 0, _("missing file argument"));      usage (1);    }  target_directory_specified = (target_directory != NULL);  if (!target_directory)    target_directory = file[n_files - 1];  /* If there's only one file argument, then pretend `.' was given     as the second argument.  */  if (n_files == 1)    {      static char *dummy[2];      dummy[0] = file[0];      dummy[1] = ".";      file = dummy;      n_files = 2;      dest_is_dir = 1;    }  else    {      dest_is_dir = isdir (target_directory);    }  if (symbolic_link)    linkfunc = symlink;  else    linkfunc = link;  if (target_directory_specified && !dest_is_dir)    {      error (0, 0, _("%s: specified target directory is not a directory"),	     quote (target_directory));      usage (1);    }  if (backup_suffix_string)    simple_backup_suffix = xstrdup (backup_suffix_string);  backup_type = (make_backups		 ? xget_version (_("backup type"), version_control_string)		 : none);  if (target_directory_specified || n_files > 2)    {      unsigned int i;      unsigned int last_file_idx = (target_directory_specified				    ? n_files - 1				    : n_files - 2);      if (!target_directory_specified && !dest_is_dir)	error (1, 0,	   _("when making multiple links, last argument must be a directory"));      for (i = 0; i <= last_file_idx; ++i)	errors += do_link (file[i], target_directory);    }  else    {      struct stat source_stats;      const char *source;      char *dest;      char *new_dest;      source = file[0];      dest = file[1];      /* When the destination is specified with a trailing slash and the	 source exists but is not a directory, convert the user's command	 `ln source dest/' to `ln source dest/basename(source)'.  */      if (dest[strlen (dest) - 1] == '/'	  && lstat (source, &source_stats) == 0	  && !S_ISDIR (source_stats.st_mode))	{	  PATH_BASENAME_CONCAT (new_dest, dest, source);	}      else	{	  new_dest = dest;	}      errors = do_link (source, new_dest);    }  exit (errors != 0);}

⌨️ 快捷键说明

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