#include "c.h"
#include "closestream.h"
+#define RENAME_EXIT_SOMEOK 2
+#define RENAME_EXIT_NOTHING 4
+#define RENAME_EXIT_UNEXPLAINED 64
+
static int do_rename(char *from, char *to, char *s, int verbose, int symtarget)
{
- char *newname, *where, *p, *q, *target = NULL;
- int flen, tlen, slen;
+ char *newname = NULL, *where, *p, *q, *target = NULL;
+ int flen, tlen, slen, ret = 1;
struct stat sb;
if (symtarget) {
- if (lstat(s, &sb) == -1)
- err(EXIT_FAILURE, _("%s: lstat failed"), s);
-
- if (!S_ISLNK(sb.st_mode))
- errx(EXIT_FAILURE, _("%s: not a symbolic link"), s);
+ if (lstat(s, &sb) == -1) {
+ warn(_("%s: lstat failed"), s);
+ return 2;
+ }
+ if (!S_ISLNK(sb.st_mode)) {
+ warnx(_("%s: not a symbolic link"), s);
+ return 2;
+ }
target = xmalloc(sb.st_size + 1);
- if (readlink(s, target, sb.st_size + 1) < 0)
- err(EXIT_FAILURE, _("%s: readlink failed"), s);
+ if (readlink(s, target, sb.st_size + 1) < 0) {
+ warn(_("%s: readlink failed"), s);
+ ret = 2;
+ goto out;
+ }
target[sb.st_size] = '\0';
where = strstr(target, from);
*q = 0;
if (symtarget) {
- if (0 > unlink(s))
- err(EXIT_FAILURE, _("%s: unlink failed"), s);
- if (symlink(newname, s) != 0)
- err(EXIT_FAILURE, _("%s: symlinking to %s failed"), s, newname);
+ if (0 > unlink(s)) {
+ warn(_("%s: unlink failed"), s);
+ ret = 2;
+ goto out;
+ }
+ if (symlink(newname, s) != 0) {
+ warn(_("%s: symlinking to %s failed"), s, newname);
+ ret = 2;
+ goto out;
+ }
if (verbose)
printf("%s: `%s' -> `%s'\n", s, target, newname);
} else {
- if (rename(s, newname) != 0)
- err(EXIT_FAILURE, _("%s: rename to %s failed"), s, newname);
+ if (rename(s, newname) != 0) {
+ warn(_("%s: rename to %s failed"), s, newname);
+ ret = 2;
+ goto out;
+ }
if (verbose)
printf("`%s' -> `%s'\n", s, newname);
}
-
+ out:
free(newname);
free(target);
- return 1;
+ return ret;
}
static void __attribute__ ((__noreturn__)) usage(FILE * out)
int main(int argc, char **argv)
{
char *from, *to;
- int i, c, symtarget=0, verbose = 0;
+ int i, c, ret = 0, symtarget = 0, verbose = 0;
static const struct option longopts[] = {
{"verbose", no_argument, NULL, 'v'},
to = argv[1];
for (i = 2; i < argc; i++)
- do_rename(from, to, argv[i], verbose, symtarget);
-
- return EXIT_SUCCESS;
+ ret |= do_rename(from, to, argv[i], verbose, symtarget);
+
+ switch (ret) {
+ case 0:
+ return RENAME_EXIT_NOTHING;
+ case 1:
+ return EXIT_SUCCESS;
+ case 2:
+ return EXIT_FAILURE;
+ case 3:
+ return RENAME_EXIT_SOMEOK;
+ default:
+ return RENAME_EXIT_UNEXPLAINED;
+ }
}