Project

General

Profile

Statistics
| Branch: | Revision:

root / prex-0.9.0 / usr / bin / cp / cp.c @ 03e9c04a

History | View | Annotate | Download (3.99 KB)

1 03e9c04a Brad Neuman
/*
2
 * Copyright (c) 1988, 1993, 1994
3
 *        The Regents of the University of California.  All rights reserved.
4
 *
5
 * This code is derived from software contributed to Berkeley by
6
 * David Hitz of Auspex Systems Inc.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer.
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 * 3. Neither the name of the University nor the names of its contributors
17
 *    may be used to endorse or promote products derived from this software
18
 *    without specific prior written permission.
19
 *
20
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30
 * SUCH DAMAGE.
31
 */
32
33
/* modified by Kohsuke Ohtani for Prex. */
34
35
#include <sys/stat.h>
36
#include <sys/fcntl.h>
37
38
#include <unistd.h>
39
#include <err.h>
40
#include <string.h>
41
#include <stdlib.h>
42
#include <errno.h>
43
#include <limits.h>
44
#include <stdio.h>
45
46
#ifdef CMDBOX
47
#define main(argc, argv)        cp_main(argc, argv)
48
#endif
49
50
static void usage(void);
51
static int copy(char *from, char *to, int dirflag);
52
53
54
static char *iobuf;
55
56
int
57
main(int argc, char *argv[])
58
{
59
        int r, ch, checkch, i, iflag = 0;
60
        char *target;
61
        struct stat to_stat, tmp_stat;
62
63
        while ((ch = getopt(argc, argv, "")) != -1)
64
                switch(ch) {
65
                case '?':
66
                default:
67
                        usage();
68
                }
69
        argc -= optind;
70
        argv += optind;
71
72
        if (argc < 2)
73
                usage();
74
75
        if ((iobuf = malloc(BUFSIZ)) == NULL)
76
                err(1, NULL);
77
78
        target = argv[--argc];
79
80
        r = stat(target, &to_stat);
81
        if (r == -1 && errno != ENOENT)
82
                err(1, "%s", target);
83
        if (r == -1 || !S_ISDIR(to_stat.st_mode)) {
84
                /*
85
                 * File to file
86
                 */
87
                if (argc > 1)
88
                        usage();
89
90
                if (stat(argv[0], &tmp_stat) == -1) {
91
                        warn("%s", argv[0]);
92
                        exit(1);
93
                }
94
                if (!S_ISREG(tmp_stat.st_mode))
95
                        usage();
96
97
                /* interactive mode */
98
                if (r != -1 && iflag) {
99
                        (void)fprintf(stderr, "overwrite %s? ", target);
100
                        checkch = ch = getchar();
101
                        while (ch != '\n' && ch != EOF)
102
                                ch = getchar();
103
                        if (checkch != 'y')
104
                                exit(0);
105
                }
106
                r = copy(argv[0], target, 0);
107
        } else {
108
                /*
109
                 * File(s) to directory
110
                 */
111
                r = 0;
112
                for (i = 0; i < argc; i++)
113
                        r = copy(argv[i], target, 1);
114
        }
115
        free(iobuf);
116
        exit(r);
117
}
118
119
static void
120
usage(void)
121
{
122
        fprintf(stderr, "usage: cp src target\n"
123
                "       cp src1 ... srcN directory\n");
124
        exit(1);
125
        /* NOTREACHED */
126
}
127
128
static int
129
copy(char *from, char *to, int dirflag)
130
{
131
        char path[PATH_MAX];
132
        int fold, fnew, n;
133
        struct stat stbuf;
134
        mode_t mode;
135
        char *p;
136
137
        if (dirflag) {
138
                p = strrchr(from, '/');
139
                p = p ? p + 1 : from;
140
                strlcpy(path, to, sizeof(path));
141
                if (strcmp(to, "/"))
142
                        strlcat(path, "/", sizeof(path));
143
                strlcat(path, p, sizeof(path));
144
                to = path;
145
        }
146
147
        if ((fold = open(from, O_RDONLY)) == -1) {
148
                warn("%s", from);
149
                return 1;
150
        }
151
        fstat(fold, &stbuf);
152
        mode = stbuf.st_mode;
153
154
        if ((fnew = creat(to, mode)) == -1) {
155
                warn("%s", to);
156
                close(fold);
157
                return 1;
158
        }
159
        while ((n = read(fold, iobuf, BUFSIZ)) > 0) {
160
                if (write(fnew, iobuf, (size_t)n) != n) {
161
                        warn("%s", to);
162
                        close(fold);
163
                        close(fnew);
164
                        return 1;
165
                }
166
        }
167
        close(fold);
168
        close(fnew);
169
        return 0;
170
}