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 | ||