(main): Standardize on the diagnostics given when someone gives
[platform/upstream/coreutils.git] / src / mv.c
1 /* mv -- move or rename files
2    Copyright (C) 86, 89, 90, 91, 1995-2004 Free Software Foundation, Inc.
3
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2, or (at your option)
7    any later version.
8
9    This program 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.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software Foundation,
16    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
17
18 /* Written by Mike Parker, David MacKenzie, and Jim Meyering */
19
20 #include <config.h>
21 #include <stdio.h>
22 #include <getopt.h>
23 #include <sys/types.h>
24 #include <assert.h>
25
26 #include "system.h"
27 #include "argmatch.h"
28 #include "backupfile.h"
29 #include "copy.h"
30 #include "cp-hash.h"
31 #include "dirname.h"
32 #include "error.h"
33 #include "path-concat.h"
34 #include "quote.h"
35 #include "remove.h"
36
37 /* The official name of this program (e.g., no `g' prefix).  */
38 #define PROGRAM_NAME "mv"
39
40 #define AUTHORS "Mike Parker", "David MacKenzie", "Jim Meyering"
41
42 /* Initial number of entries in each hash table entry's table of inodes.  */
43 #define INITIAL_HASH_MODULE 100
44
45 /* Initial number of entries in the inode hash table.  */
46 #define INITIAL_ENTRY_TAB_SIZE 70
47
48 /* For long options that have no equivalent short option, use a
49    non-character as a pseudo short option, starting with CHAR_MAX + 1.  */
50 enum
51 {
52   TARGET_DIRECTORY_OPTION = CHAR_MAX + 1,
53   STRIP_TRAILING_SLASHES_OPTION,
54   REPLY_OPTION
55 };
56
57 int isdir ();
58 int lstat ();
59
60 /* The name this program was run with. */
61 char *program_name;
62
63 /* Remove any trailing slashes from each SOURCE argument.  */
64 static int remove_trailing_slashes;
65
66 /* Valid arguments to the `--reply' option. */
67 static char const* const reply_args[] =
68 {
69   "yes", "no", "query", 0
70 };
71
72 /* The values that correspond to the above strings. */
73 static int const reply_vals[] =
74 {
75   I_ALWAYS_YES, I_ALWAYS_NO, I_ASK_USER
76 };
77
78 static struct option const long_options[] =
79 {
80   {"backup", optional_argument, NULL, 'b'},
81   {"force", no_argument, NULL, 'f'},
82   {"interactive", no_argument, NULL, 'i'},
83   {"reply", required_argument, NULL, REPLY_OPTION},
84   {"strip-trailing-slashes", no_argument, NULL, STRIP_TRAILING_SLASHES_OPTION},
85   {"suffix", required_argument, NULL, 'S'},
86   {"target-directory", required_argument, NULL, TARGET_DIRECTORY_OPTION},
87   {"update", no_argument, NULL, 'u'},
88   {"verbose", no_argument, NULL, 'v'},
89   {"version-control", required_argument, NULL, 'V'},
90   {GETOPT_HELP_OPTION_DECL},
91   {GETOPT_VERSION_OPTION_DECL},
92   {NULL, 0, NULL, 0}
93 };
94
95 static void
96 rm_option_init (struct rm_options *x)
97 {
98   x->unlink_dirs = 0;
99   x->ignore_missing_files = 0;
100   x->root_dev_ino = NULL;
101   x->recursive = 1;
102
103   /* Should we prompt for removal, too?  No.  Prompting for the `move'
104      part is enough.  It implies removal.  */
105   x->interactive = 0;
106   x->stdin_tty = 0;
107
108   x->verbose = 0;
109
110   /* Since this program may well have to process additional command
111      line arguments after any call to `rm', that function must preserve
112      the initial working directory, in case one of those is a
113      `.'-relative name.  */
114   x->require_restore_cwd = true;
115 }
116
117 static void
118 cp_option_init (struct cp_options *x)
119 {
120   x->copy_as_regular = 0;  /* FIXME: maybe make this an option */
121   x->dereference = DEREF_NEVER;
122   x->unlink_dest_before_opening = 0;
123   x->unlink_dest_after_failed_open = 0;
124   x->hard_link = 0;
125   x->interactive = I_UNSPECIFIED;
126   x->move_mode = 1;
127   x->myeuid = geteuid ();
128   x->one_file_system = 0;
129   x->preserve_ownership = 1;
130   x->preserve_links = 1;
131   x->preserve_mode = 1;
132   x->preserve_timestamps = 1;
133   x->require_preserve = 0;  /* FIXME: maybe make this an option */
134   x->recursive = 1;
135   x->sparse_mode = SPARSE_AUTO;  /* FIXME: maybe make this an option */
136   x->symbolic_link = 0;
137   x->set_mode = 0;
138   x->mode = 0;
139   x->stdin_tty = isatty (STDIN_FILENO);
140
141   /* Find out the current file creation mask, to knock the right bits
142      when using chmod.  The creation mask is set to be liberal, so
143      that created directories can be written, even if it would not
144      have been allowed with the mask this process was started with.  */
145   x->umask_kill = ~ umask (0);
146
147   x->update = 0;
148   x->verbose = 0;
149   x->dest_info = NULL;
150   x->src_info = NULL;
151 }
152
153 /* If PATH is an existing directory, return nonzero, else 0.  */
154
155 static int
156 is_real_dir (const char *path)
157 {
158   struct stat stats;
159
160   return lstat (path, &stats) == 0 && S_ISDIR (stats.st_mode);
161 }
162
163 /* Move SOURCE onto DEST.  Handles cross-filesystem moves.
164    If SOURCE is a directory, DEST must not exist.
165    Return 0 if successful, non-zero if an error occurred.  */
166
167 static int
168 do_move (const char *source, const char *dest, const struct cp_options *x)
169 {
170   static int first = 1;
171   int copy_into_self;
172   int rename_succeeded;
173   int fail;
174
175   if (first)
176     {
177       first = 0;
178
179       /* Allocate space for remembering copied and created files.  */
180       hash_init ();
181     }
182
183   fail = copy (source, dest, 0, x, &copy_into_self, &rename_succeeded);
184
185   if (!fail)
186     {
187       char const *dir_to_remove;
188       if (copy_into_self)
189         {
190           /* In general, when copy returns with copy_into_self set, SOURCE is
191              the same as, or a parent of DEST.  In this case we know it's a
192              parent.  It doesn't make sense to move a directory into itself, and
193              besides in some situations doing so would give highly nonintuitive
194              results.  Run this `mkdir b; touch a c; mv * b' in an empty
195              directory.  Here's the result of running echo `find b -print`:
196              b b/a b/b b/b/a b/c.  Notice that only file `a' was copied
197              into b/b.  Handle this by giving a diagnostic, removing the
198              copied-into-self directory, DEST (`b/b' in the example),
199              and failing.  */
200
201           dir_to_remove = NULL;
202           fail = 1;
203         }
204       else if (rename_succeeded)
205         {
206           /* No need to remove anything.  SOURCE was successfully
207              renamed to DEST.  Or the user declined to rename a file.  */
208           dir_to_remove = NULL;
209         }
210       else
211         {
212           /* This may mean SOURCE and DEST referred to different devices.
213              It may also conceivably mean that even though they referred
214              to the same device, rename wasn't implemented for that device.
215
216              E.g., (from Joel N. Weber),
217              [...] there might someday be cases where you can't rename
218              but you can copy where the device name is the same, especially
219              on Hurd.  Consider an ftpfs with a primitive ftp server that
220              supports uploading, downloading and deleting, but not renaming.
221
222              Also, note that comparing device numbers is not a reliable
223              check for `can-rename'.  Some systems can be set up so that
224              files from many different physical devices all have the same
225              st_dev field.  This is a feature of some NFS mounting
226              configurations.
227
228              We reach this point if SOURCE has been successfully copied
229              to DEST.  Now we have to remove SOURCE.
230
231              This function used to resort to copying only when rename
232              failed and set errno to EXDEV.  */
233
234           dir_to_remove = source;
235         }
236
237       if (dir_to_remove != NULL)
238         {
239           struct rm_options rm_options;
240           enum RM_status status;
241
242           rm_option_init (&rm_options);
243           rm_options.verbose = x->verbose;
244
245           status = rm (1, &dir_to_remove, &rm_options);
246           assert (VALID_STATUS (status));
247           if (status == RM_ERROR)
248             fail = 1;
249         }
250     }
251
252   return fail;
253 }
254
255 /* Move file SOURCE onto DEST.  Handles the case when DEST is a directory.
256    DEST_IS_DIR must be nonzero when DEST is a directory or a symlink to a
257    directory and zero otherwise.
258    Return 0 if successful, non-zero if an error occurred.  */
259
260 static int
261 movefile (char *source, char *dest, int dest_is_dir,
262           const struct cp_options *x)
263 {
264   int dest_had_trailing_slash = strip_trailing_slashes (dest);
265   int fail;
266
267   /* This code was introduced to handle the ambiguity in the semantics
268      of mv that is induced by the varying semantics of the rename function.
269      Some systems (e.g., Linux) have a rename function that honors a
270      trailing slash, while others (like Solaris 5,6,7) have a rename
271      function that ignores a trailing slash.  I believe the Linux
272      rename semantics are POSIX and susv2 compliant.  */
273
274   if (remove_trailing_slashes)
275     strip_trailing_slashes (source);
276
277   /* In addition to when DEST is a directory, if DEST has a trailing
278      slash and neither SOURCE nor DEST is a directory, presume the target
279      is DEST/`basename source`.  This converts `mv x y/' to `mv x y/x'.
280      This change means that the command `mv any file/' will now fail
281      rather than performing the move.  The case when SOURCE is a
282      directory and DEST is not is properly diagnosed by do_move.  */
283
284   if (dest_is_dir || (dest_had_trailing_slash && !is_real_dir (source)))
285     {
286       /* DEST is a directory; build full target filename. */
287       char const *src_basename = base_name (source);
288       char *new_dest = path_concat (dest, src_basename, NULL);
289       if (new_dest == NULL)
290         xalloc_die ();
291       strip_trailing_slashes (new_dest);
292       fail = do_move (source, new_dest, x);
293       free (new_dest);
294     }
295   else
296     {
297       fail = do_move (source, dest, x);
298     }
299
300   return fail;
301 }
302
303 void
304 usage (int status)
305 {
306   if (status != EXIT_SUCCESS)
307     fprintf (stderr, _("Try `%s --help' for more information.\n"),
308              program_name);
309   else
310     {
311       printf (_("\
312 Usage: %s [OPTION]... SOURCE DEST\n\
313   or:  %s [OPTION]... SOURCE... DIRECTORY\n\
314   or:  %s [OPTION]... --target-directory=DIRECTORY SOURCE...\n\
315 "),
316               program_name, program_name, program_name);
317       fputs (_("\
318 Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.\n\
319 \n\
320 "), stdout);
321       fputs (_("\
322 Mandatory arguments to long options are mandatory for short options too.\n\
323 "), stdout);
324       fputs (_("\
325       --backup[=CONTROL]       make a backup of each existing destination file\n\
326   -b                           like --backup but does not accept an argument\n\
327   -f, --force                  do not prompt before overwriting\n\
328                                  (equivalent to --reply=yes)\n\
329   -i, --interactive            prompt before overwrite\n\
330                                  (equivalent to --reply=query)\n\
331 "), stdout);
332       fputs (_("\
333       --reply={yes,no,query}   specify how to handle the prompt about an\n\
334                                  existing destination file\n\
335       --strip-trailing-slashes remove any trailing slashes from each SOURCE\n\
336                                  argument\n\
337   -S, --suffix=SUFFIX          override the usual backup suffix\n\
338 "), stdout);
339       fputs (_("\
340       --target-directory=DIRECTORY  move all SOURCE arguments into DIRECTORY\n\
341   -u, --update                 move only when the SOURCE file is newer\n\
342                                  than the destination file or when the\n\
343                                  destination file is missing\n\
344   -v, --verbose                explain what is being done\n\
345 "), stdout);
346       fputs (HELP_OPTION_DESCRIPTION, stdout);
347       fputs (VERSION_OPTION_DESCRIPTION, stdout);
348       fputs (_("\
349 \n\
350 The backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\
351 The version control method may be selected via the --backup option or through\n\
352 the VERSION_CONTROL environment variable.  Here are the values:\n\
353 \n\
354 "), stdout);
355       fputs (_("\
356   none, off       never make backups (even if --backup is given)\n\
357   numbered, t     make numbered backups\n\
358   existing, nil   numbered if numbered backups exist, simple otherwise\n\
359   simple, never   always make simple backups\n\
360 "), stdout);
361       printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
362     }
363   exit (status);
364 }
365
366 int
367 main (int argc, char **argv)
368 {
369   int c;
370   int errors;
371   int make_backups = 0;
372   int dest_is_dir;
373   char *backup_suffix_string;
374   char *version_control_string = NULL;
375   struct cp_options x;
376   char *target_directory = NULL;
377   int target_directory_specified;
378   unsigned int n_files;
379   char **file;
380
381   initialize_main (&argc, &argv);
382   program_name = argv[0];
383   setlocale (LC_ALL, "");
384   bindtextdomain (PACKAGE, LOCALEDIR);
385   textdomain (PACKAGE);
386
387   atexit (close_stdout);
388
389   cp_option_init (&x);
390
391   /* FIXME: consider not calling getenv for SIMPLE_BACKUP_SUFFIX unless
392      we'll actually use backup_suffix_string.  */
393   backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
394
395   errors = 0;
396
397   while ((c = getopt_long (argc, argv, "bfiuvS:V:", long_options, NULL)) != -1)
398     {
399       switch (c)
400         {
401         case 0:
402           break;
403
404         case 'V':  /* FIXME: this is deprecated.  Remove it in 2001.  */
405           error (0, 0,
406                  _("warning: --version-control (-V) is obsolete;  support for\
407  it\nwill be removed in some future release.  Use --backup=%s instead."
408                    ), optarg);
409           /* Fall through.  */
410
411         case 'b':
412           make_backups = 1;
413           if (optarg)
414             version_control_string = optarg;
415           break;
416         case 'f':
417           x.interactive = I_ALWAYS_YES;
418           break;
419         case 'i':
420           x.interactive = I_ASK_USER;
421           break;
422         case REPLY_OPTION:
423           x.interactive = XARGMATCH ("--reply", optarg,
424                                      reply_args, reply_vals);
425           break;
426         case STRIP_TRAILING_SLASHES_OPTION:
427           remove_trailing_slashes = 1;
428           break;
429         case TARGET_DIRECTORY_OPTION:
430           target_directory = optarg;
431           break;
432         case 'u':
433           x.update = 1;
434           break;
435         case 'v':
436           x.verbose = 1;
437           break;
438         case 'S':
439           make_backups = 1;
440           backup_suffix_string = optarg;
441           break;
442         case_GETOPT_HELP_CHAR;
443         case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
444         default:
445           usage (EXIT_FAILURE);
446         }
447     }
448
449   n_files = (optind < argc ? argc - optind : 0);
450   file = argv + optind;
451
452   target_directory_specified = (target_directory != NULL);
453   if (target_directory == NULL && n_files != 0)
454     target_directory = file[n_files - 1];
455
456   dest_is_dir = (n_files > 0 && isdir (target_directory));
457
458   if (n_files == 0 || (n_files == 1 && !target_directory_specified))
459     {
460       if (n_files == 0)
461         error (0, 0, _("missing file operand"));
462       else
463         error (0, 0, _("missing file operand after %s"),
464                quote (argv[argc - 1]));
465       usage (EXIT_FAILURE);
466     }
467
468   if (target_directory_specified)
469     {
470       if (!dest_is_dir)
471         {
472           error (0, 0, _("specified target, %s is not a directory"),
473                  quote (target_directory));
474           usage (EXIT_FAILURE);
475         }
476     }
477   else if (n_files > 2 && !dest_is_dir)
478     {
479       error (0, 0,
480             _("when moving multiple files, last argument must be a directory"));
481       usage (EXIT_FAILURE);
482     }
483
484   if (backup_suffix_string)
485     simple_backup_suffix = xstrdup (backup_suffix_string);
486
487   x.backup_type = (make_backups
488                    ? xget_version (_("backup type"),
489                                    version_control_string)
490                    : none);
491
492   /* Move each arg but the last into the target_directory.  */
493   {
494     unsigned int last_file_idx = (target_directory_specified
495                                   ? n_files - 1
496                                   : n_files - 2);
497     unsigned int i;
498
499     /* Initialize the hash table only if we'll need it.
500        The problem it is used to detect can arise only if there are
501        two or more files to move.  */
502     if (last_file_idx)
503       dest_info_init (&x);
504
505     for (i = 0; i <= last_file_idx; ++i)
506       errors |= movefile (file[i], target_directory, dest_is_dir, &x);
507   }
508
509   exit (errors == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
510 }