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