~cfuhrman/+junk/netbsd-othersrc-trunk

« back to all changes in this revision

Viewing changes to bin/fsu_mv/fsu_mv.c

  • Committer: stacktic
  • Date: 2009-03-23 21:04:00 UTC
  • Revision ID: svn-v4:288d5a72-fed7-e111-8680-000c29dcf8fe:trunk:1946
ImportedĀ fs-utilsĀ binaries

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $NetBSD$ */
 
2
 
 
3
/*
 
4
 * Copyright (c) 2008 Arnaud Ysmal.  All Rights Reserved.
 
5
 *
 
6
 * Redistribution and use in source and binary forms, with or without
 
7
 * modification, are permitted provided that the following conditions
 
8
 * are met:
 
9
 * 1. Redistributions of source code must retain the above copyright
 
10
 *    notice, this list of conditions and the following disclaimer.
 
11
 * 2. Redistributions in binary form must reproduce the above copyright
 
12
 *    notice, this list of conditions and the following disclaimer in the
 
13
 *    documentation and/or other materials provided with the distribution.
 
14
 *
 
15
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
 
16
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 
17
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 
18
 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 
19
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
20
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 
21
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
22
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 
23
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 
24
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 
25
 * SUCH DAMAGE.
 
26
 */
 
27
 
 
28
#include <sys/stat.h>
 
29
#include <sys/syslimits.h>
 
30
 
 
31
#include <err.h>
 
32
#include <getopt.h>
 
33
#include <stdio.h>
 
34
#include <stdlib.h>
 
35
#include <string.h>
 
36
 
 
37
#include <rump/ukfs.h>
 
38
 
 
39
#include <fsu_mount.h>
 
40
 
 
41
#define FSU_MV_INTERACTIVE (0x01)
 
42
#define FSU_MV_VERBOSE (FSU_MV_INTERACTIVE<<1)
 
43
 
 
44
DECLARE_UKFS(ukfs)
 
45
 
 
46
static int fsu_mv_parse_arg(int *, char ***);
 
47
static int fsu_mv(struct ukfs *, const char *, const char *, int);
 
48
static int is_user_ok(const char *);
 
49
static int move_to_dir(struct ukfs *, const char *, const char *, int);
 
50
static int move_to_file(struct ukfs *, const char *, const char *, int);
 
51
static void usage(void);
 
52
 
 
53
int main(int, char *[]);
 
54
 
 
55
int
 
56
main(int argc, char *argv[])
 
57
{
 
58
        int cur_arg, flags = 0, rv;
 
59
 
 
60
        setprogname(argv[0]);
 
61
 
 
62
        FSU_MOUNT(argc, argv, ukfs);
 
63
 
 
64
        flags = fsu_mv_parse_arg(&argc, &argv);
 
65
        if (flags == -1 || argc < 2) {
 
66
                usage();
 
67
                return -1;
 
68
        }
 
69
 
 
70
        for (rv = 0, cur_arg = 0; cur_arg < argc-1; cur_arg++)
 
71
                rv |= fsu_mv(ukfs, argv[cur_arg], argv[argc-1], flags);
 
72
 
 
73
        return rv;
 
74
}
 
75
 
 
76
static int
 
77
fsu_mv_parse_arg(int *argc, char ***argv)
 
78
{
 
79
        int flags, rv;
 
80
 
 
81
        flags = 0;
 
82
        while ((rv = getopt(*argc, *argv, "iv")) != -1) {
 
83
                switch (rv) {
 
84
                case 'i':
 
85
                        flags |= FSU_MV_INTERACTIVE;
 
86
                        break;
 
87
                case 'v':
 
88
                        flags |= FSU_MV_VERBOSE;
 
89
                        break;
 
90
                case '?':
 
91
                default:
 
92
                        return -1;
 
93
                }
 
94
        }
 
95
        *argc -= optind;
 
96
        *argv += optind;
 
97
 
 
98
        return flags;
 
99
}
 
100
 
 
101
 
 
102
static int
 
103
fsu_mv(struct ukfs *fs, const char *from, const char *to, int flags)
 
104
{
 
105
        int rv;
 
106
        struct stat file_stat;
 
107
        
 
108
        rv = ukfs_stat(fs, to, &file_stat);
 
109
        if (rv == -1 || !S_ISDIR(file_stat.st_mode))
 
110
                return move_to_file(fs, from, to, flags);
 
111
 
 
112
        return move_to_dir(fs, from, to, flags);
 
113
}
 
114
 
 
115
static int
 
116
is_user_ok(const char *to)
 
117
{
 
118
        int ch, ch2;
 
119
 
 
120
        printf("Overwrite %s? ", to);
 
121
        if ((ch = getchar()) != EOF && ch != '\n')
 
122
                while ((ch2 = getchar()) != EOF && ch2 != '\n')
 
123
                        continue;
 
124
        
 
125
        if (ch != 'y' && ch != 'Y')
 
126
                return 0;
 
127
        return 1;
 
128
}
 
129
 
 
130
static int
 
131
move_to_dir(struct ukfs *fs, const char *from, const char *to, int flags)
 
132
{
 
133
        const char *p;
 
134
        int rv;
 
135
        char path[PATH_MAX + 1];
 
136
        struct stat file_stat;
 
137
        size_t len;
 
138
 
 
139
        len = strlen(to);
 
140
        rv = strlcpy(path, to, PATH_MAX + 1);
 
141
        if (rv != (int)len) {
 
142
                warn("%s", to);
 
143
                return -1;
 
144
        }
 
145
 
 
146
        rv = ukfs_stat(fs, from, &file_stat);
 
147
        if (rv == -1) {
 
148
                warn("%s", from);
 
149
                return -1;
 
150
        }
 
151
        
 
152
        p = strrchr(from, '/');
 
153
        if (p == NULL)
 
154
                p = from;
 
155
        else
 
156
                ++p;
 
157
        
 
158
        rv = strlcat(path, p, PATH_MAX + 1);
 
159
        if (rv == -1) {
 
160
                warn("%s/%s", path, p);
 
161
                return -1;
 
162
        }
 
163
 
 
164
        if (flags & FSU_MV_VERBOSE)
 
165
                printf("%s -> %s\n", from, path);
 
166
 
 
167
        if (flags & FSU_MV_INTERACTIVE) {
 
168
                rv = ukfs_stat(fs, path, &file_stat);
 
169
                if (rv != -1 && !is_user_ok(to))
 
170
                        return 0;
 
171
        }
 
172
 
 
173
        rv = ukfs_rename(fs, from, path);
 
174
        if (rv == -1) {
 
175
                warn("%s", from);
 
176
                return -1;
 
177
        }
 
178
        return 0;
 
179
}
 
180
 
 
181
static int
 
182
move_to_file(struct ukfs *fs, const char *from, const char *to, int flags)
 
183
{
 
184
        int rv;
 
185
        struct stat file_stat;
 
186
 
 
187
        if (flags & FSU_MV_VERBOSE)
 
188
                printf("%s -> %s\n", from, to);
 
189
        
 
190
        if (flags & FSU_MV_INTERACTIVE) {
 
191
                rv = ukfs_stat(fs, to, &file_stat);
 
192
                if (rv != -1 && !is_user_ok(to))
 
193
                        return 0;
 
194
        }
 
195
        rv = ukfs_rename(fs, from, to);
 
196
        if (rv == -1) {
 
197
                warn("%s or %s", from, to);
 
198
                return -1;
 
199
        }
 
200
        return 0;
 
201
}
 
202
 
 
203
static void
 
204
usage(void)
 
205
{
 
206
 
 
207
        fprintf(stderr, "usage: \t%s %s [-iv] source target\n"
 
208
                "       \t%s %s [-iv] source ... directory\n",
 
209
                getprogname(), fsu_mount_usage(),
 
210
                getprogname(), fsu_mount_usage());
 
211
 
 
212
        exit(EXIT_FAILURE);
 
213
}