source: mainline/uspace/app/bdsh/cmds/modules/cp/cp.c@ 713ea96a

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 713ea96a was 6348376, checked in by Jakub Jermar <jakub@…>, 14 years ago

Make use of read_all() and write_all() in bdsh's cp.

  • Property mode set to 100644
File size: 5.0 KB
Line 
1/*
2 * Copyright (c) 2008 Tim Post
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - 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 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <stdio.h>
30#include <stdlib.h>
31#include <unistd.h>
32#include <getopt.h>
33#include <str.h>
34#include <fcntl.h>
35#include "config.h"
36#include "util.h"
37#include "errors.h"
38#include "entry.h"
39#include "cp.h"
40#include "cmds.h"
41
42#define CP_VERSION "0.0.1"
43#define CP_DEFAULT_BUFLEN 1024
44
45static const char *cmdname = "cp";
46
47static struct option const long_options[] = {
48 { "buffer", required_argument, 0, 'b' },
49 { "force", no_argument, 0, 'f' },
50 { "recursive", no_argument, 0, 'r' },
51 { "help", no_argument, 0, 'h' },
52 { "version", no_argument, 0, 'v' },
53 { "verbose", no_argument, 0, 'V' },
54 { 0, 0, 0, 0 }
55};
56
57static int strtoint(const char *s1)
58{
59 long t1;
60
61 if (-1 == (t1 = strtol(s1, (char **) NULL, 10)))
62 return -1;
63
64 if (t1 <= 0)
65 return -1;
66
67 return (int) t1;
68}
69
70static int64_t copy_file(const char *src, const char *dest,
71 size_t blen, int vb)
72{
73 int fd1, fd2, bytes;
74 off64_t total;
75 int64_t copied = 0;
76 char *buff = NULL;
77
78 if (vb)
79 printf("Copying %s to %s\n", src, dest);
80
81 if (-1 == (fd1 = open(src, O_RDONLY))) {
82 printf("Unable to open source file %s\n", src);
83 return -1;
84 }
85
86 if (-1 == (fd2 = open(dest, O_CREAT))) {
87 printf("Unable to open destination file %s\n", dest);
88 close(fd1);
89 return -1;
90 }
91
92 total = lseek(fd1, 0, SEEK_END);
93
94 if (vb)
95 printf("%" PRIu64 " bytes to copy\n", total);
96
97 lseek(fd1, 0, SEEK_SET);
98
99 if (NULL == (buff = (char *) malloc(blen))) {
100 printf("Unable to allocate enough memory to read %s\n",
101 src);
102 copied = -1;
103 goto out;
104 }
105
106 while ((bytes = read_all(fd1, buff, blen)) > 0) {
107 if ((bytes = write_all(fd2, buff, bytes)) < 0)
108 break;
109 copied += bytes;
110 }
111
112 if (bytes < 0) {
113 printf("\nError copying %s, (%d)\n", src, bytes);
114 copied = bytes;
115 }
116
117out:
118 close(fd1);
119 close(fd2);
120 if (buff)
121 free(buff);
122 return copied;
123}
124
125void help_cmd_cp(unsigned int level)
126{
127 static char helpfmt[] =
128 "Usage: %s [options] <source> <dest>\n"
129 "Options: (* indicates not yet implemented)\n"
130 " -h, --help A short option summary\n"
131 " -v, --version Print version information and exit\n"
132 "* -V, --verbose Be annoyingly noisy about what's being done\n"
133 "* -f, --force Do not complain when <dest> exists\n"
134 "* -r, --recursive Copy entire directories\n"
135 " -b, --buffer ## Set the read buffer size to ##\n"
136 "Currently, %s is under development, some options may not work.\n";
137 if (level == HELP_SHORT) {
138 printf("`%s' copies files and directories\n", cmdname);
139 } else {
140 help_cmd_cp(HELP_SHORT);
141 printf(helpfmt, cmdname, cmdname);
142 }
143
144 return;
145}
146
147int cmd_cp(char **argv)
148{
149 unsigned int argc, verbose = 0;
150 int buffer = 0;
151 int c, opt_ind;
152 int64_t ret;
153
154 argc = cli_count_args(argv);
155
156 for (c = 0, optind = 0, opt_ind = 0; c != -1;) {
157 c = getopt_long(argc, argv, "hvVfrb:", long_options, &opt_ind);
158 switch (c) {
159 case 'h':
160 help_cmd_cp(1);
161 return CMD_SUCCESS;
162 case 'v':
163 printf("%s\n", CP_VERSION);
164 return CMD_SUCCESS;
165 case 'V':
166 verbose = 1;
167 break;
168 case 'f':
169 break;
170 case 'r':
171 break;
172 case 'b':
173 if (-1 == (buffer = strtoint(optarg))) {
174 printf("%s: Invalid buffer specification, "
175 "(should be a number greater than zero)\n",
176 cmdname);
177 return CMD_FAILURE;
178 }
179 if (verbose)
180 printf("Buffer = %d\n", buffer);
181 break;
182 }
183 }
184
185 if (buffer == 0)
186 buffer = CP_DEFAULT_BUFLEN;
187
188 argc -= optind;
189
190 if (argc != 2) {
191 printf("%s: invalid number of arguments. Try %s --help\n",
192 cmdname, cmdname);
193 return CMD_FAILURE;
194 }
195
196 ret = copy_file(argv[optind], argv[optind + 1], buffer, verbose);
197
198 if (verbose)
199 printf("%" PRId64 " bytes copied\n", ret);
200
201 if (ret >= 0)
202 return CMD_SUCCESS;
203 else
204 return CMD_FAILURE;
205}
206
Note: See TracBrowser for help on using the repository browser.