Rev 3420 | Rev 3641 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3420 | Rev 3640 | ||
---|---|---|---|
Line 28... | Line 28... | ||
28 | * POSSIBILITY OF SUCH DAMAGE. |
28 | * POSSIBILITY OF SUCH DAMAGE. |
29 | */ |
29 | */ |
30 | 30 | ||
31 | #include <stdio.h> |
31 | #include <stdio.h> |
32 | #include <stdlib.h> |
32 | #include <stdlib.h> |
- | 33 | #include <unistd.h> |
|
- | 34 | #include <getopt.h> |
|
- | 35 | #include <string.h> |
|
- | 36 | #include <fcntl.h> |
|
33 | #include "config.h" |
37 | #include "config.h" |
34 | #include "util.h" |
38 | #include "util.h" |
35 | #include "errors.h" |
39 | #include "errors.h" |
36 | #include "entry.h" |
40 | #include "entry.h" |
37 | #include "cp.h" |
41 | #include "cp.h" |
38 | #include "cmds.h" |
42 | #include "cmds.h" |
39 | 43 | ||
- | 44 | #define CP_VERSION "0.0.1" |
|
- | 45 | #define CP_DEFAULT_BUFLEN 1024 |
|
- | 46 | ||
40 | static char *cmdname = "cp"; |
47 | static const char *cmdname = "cp"; |
- | 48 | ||
- | 49 | static struct option const long_options[] = { |
|
- | 50 | { "buffer", required_argument, 0, 'b' }, |
|
- | 51 | { "force", no_argument, 0, 'f' }, |
|
- | 52 | { "recursive", no_argument, 0, 'r' }, |
|
- | 53 | { "help", no_argument, 0, 'h' }, |
|
- | 54 | { "version", no_argument, 0, 'v' }, |
|
- | 55 | { "verbose", no_argument, 0, 'V' }, |
|
- | 56 | { 0, 0, 0, 0 } |
|
- | 57 | }; |
|
- | 58 | ||
- | 59 | static int strtoint(const char *s1) |
|
- | 60 | { |
|
- | 61 | long t1; |
|
- | 62 | ||
- | 63 | if (-1 == (t1 = strtol(s1, (char **) NULL, 10))) |
|
- | 64 | return -1; |
|
- | 65 | ||
- | 66 | if (t1 <= 0) |
|
- | 67 | return -1; |
|
- | 68 | ||
- | 69 | return (int) t1; |
|
- | 70 | } |
|
- | 71 | ||
- | 72 | static size_t copy_file(const char *src, const char *dest, size_t blen, int vb) |
|
- | 73 | { |
|
- | 74 | int fd1, fd2, bytes = 0; |
|
- | 75 | off_t total = 0; |
|
- | 76 | size_t copied = 0; |
|
- | 77 | char *buff = NULL; |
|
- | 78 | ||
- | 79 | if (vb) |
|
- | 80 | printf("Copying %s to %s\n", src, dest); |
|
- | 81 | ||
- | 82 | if (-1 == (fd1 = open(src, O_RDONLY))) { |
|
- | 83 | printf("Unable to open source file %s\n", src); |
|
- | 84 | return 0; |
|
- | 85 | } |
|
- | 86 | ||
- | 87 | if (-1 == (fd2 = open(dest, O_CREAT))) { |
|
- | 88 | printf("Unable to open destination file %s\n", dest); |
|
- | 89 | return 0; |
|
- | 90 | } |
|
- | 91 | ||
- | 92 | total = lseek(fd1, 0, SEEK_END); |
|
- | 93 | ||
- | 94 | if (vb) |
|
- | 95 | printf("%d bytes to copy\n", total); |
|
- | 96 | ||
- | 97 | lseek(fd1, 0, SEEK_SET); |
|
- | 98 | ||
- | 99 | if (NULL == (buff = (char *) malloc(blen + 1))) { |
|
- | 100 | printf("Unable to allocate enough memory to read %s\n", |
|
- | 101 | src); |
|
- | 102 | goto out; |
|
- | 103 | } |
|
- | 104 | ||
- | 105 | do { |
|
- | 106 | if (-1 == (bytes = read(fd1, buff, blen))) |
|
- | 107 | break; |
|
- | 108 | copied += bytes; |
|
- | 109 | write(fd2, buff, blen); |
|
- | 110 | } while (bytes > 0); |
|
- | 111 | ||
- | 112 | if (bytes == -1) { |
|
- | 113 | printf("Error copying %s\n", src); |
|
- | 114 | copied = 0; |
|
- | 115 | goto out; |
|
- | 116 | } |
|
- | 117 | ||
- | 118 | out: |
|
- | 119 | close(fd1); |
|
- | 120 | close(fd2); |
|
- | 121 | if (buff) |
|
- | 122 | free(buff); |
|
- | 123 | return copied; |
|
- | 124 | } |
|
41 | 125 | ||
42 | /* Dispays help for cp in various levels */ |
- | |
43 | void help_cmd_cp(unsigned int level) |
126 | void help_cmd_cp(unsigned int level) |
44 | { |
127 | { |
- | 128 | if (level == HELP_SHORT) { |
|
45 | printf("This is the %s help for '%s'.\n", |
129 | printf("`%s' copies files and directories\n", cmdname); |
- | 130 | } else { |
|
46 | level ? EXT_HELP : SHORT_HELP, cmdname); |
131 | help_cmd_cp(HELP_SHORT); |
- | 132 | printf( |
|
- | 133 | "Usage: %s [options] <source> <dest>\n" |
|
- | 134 | "Options: (* indicates not yet implemented)\n" |
|
- | 135 | " -h, --help A short option summary\n" |
|
- | 136 | " -v, --version Print version information and exit\n" |
|
- | 137 | "* -V, --verbose Be annoyingly noisy about what's being done\n" |
|
- | 138 | "* -f, --force Do not complain when <dest> exists\n" |
|
- | 139 | "* -r, --recursive Copy entire directories\n" |
|
- | 140 | " -b, --buffer ## Set the read buffer size to ##\n" |
|
- | 141 | "Currently, %s is under development, some options might not work.\n", |
|
- | 142 | cmdname, cmdname); |
|
- | 143 | } |
|
- | 144 | ||
47 | return; |
145 | return; |
48 | } |
146 | } |
49 | 147 | ||
50 | /* Main entry point for cp, accepts an array of arguments */ |
- | |
51 | int cmd_cp(char **argv) |
148 | int cmd_cp(char **argv) |
52 | { |
149 | { |
53 | unsigned int argc; |
150 | unsigned int argc, buffer = CP_DEFAULT_BUFLEN, verbose = 0; |
54 | unsigned int i; |
151 | int c, opt_ind, ret = 0; |
55 | 152 | ||
56 | /* Count the arguments */ |
- | |
57 | for (argc = 0; argv[argc] != NULL; argc ++); |
153 | argc = cli_count_args(argv); |
58 | 154 | ||
- | 155 | for (c = 0, optind = 0, opt_ind = 0; c != -1;) { |
|
- | 156 | c = getopt_long(argc, argv, "hvVfrb:", long_options, &opt_ind); |
|
- | 157 | switch (c) { |
|
- | 158 | case 'h': |
|
- | 159 | help_cmd_cp(1); |
|
- | 160 | return CMD_SUCCESS; |
|
- | 161 | case 'v': |
|
59 | printf("%s %s\n", TEST_ANNOUNCE, cmdname); |
162 | printf("%d\n", CP_VERSION); |
- | 163 | return CMD_SUCCESS; |
|
- | 164 | case 'V': |
|
- | 165 | verbose = 1; |
|
- | 166 | break; |
|
- | 167 | case 'f': |
|
- | 168 | break; |
|
- | 169 | case 'r': |
|
- | 170 | break; |
|
- | 171 | case 'b': |
|
- | 172 | if (-1 == (buffer = strtoint(optarg))) { |
|
60 | printf("%d arguments passed to %s", argc - 1, cmdname); |
173 | printf("%s: Invalid buffer specification, " |
- | 174 | "(should be a number greater than zero)\n", |
|
- | 175 | cmdname); |
|
- | 176 | return CMD_FAILURE; |
|
- | 177 | } |
|
- | 178 | break; |
|
- | 179 | } |
|
- | 180 | } |
|
61 | 181 | ||
- | 182 | argc -= optind; |
|
- | 183 | ||
62 | if (argc < 2) { |
184 | if (argc != 2) { |
- | 185 | printf("%s: invalid number of arguments. Try %s --help\n", |
|
63 | printf("\n"); |
186 | cmdname, cmdname); |
64 | return CMD_SUCCESS; |
187 | return CMD_FAILURE; |
65 | } |
188 | } |
66 | 189 | ||
67 | printf(":\n"); |
190 | ret = copy_file(argv[optind], argv[optind + 1], buffer, verbose); |
- | 191 | ||
68 | for (i = 1; i < argc; i++) |
192 | if (verbose) |
69 | printf("[%d] -> %s\n", i, argv[i]); |
193 | printf("%d bytes copied (buffer = %d)\n", ret, buffer); |
70 | 194 | ||
- | 195 | if (ret) |
|
71 | return CMD_SUCCESS; |
196 | return CMD_SUCCESS; |
- | 197 | else |
|
- | 198 | return CMD_FAILURE; |
|
72 | } |
199 | } |
73 | 200 |