annotate toys/cp.c @ 282:a08f1affe016

Add -v to cp.
author Rob Landley <rob@landley.net>
date Wed, 09 Apr 2008 22:01:20 -0500
parents a5652aa22f38
children 2134fa02ec00
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
262
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
1 /* vi: set sw=4 ts=4:
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
2 *
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
3 * cp.c - Copy files.
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
4 *
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
5 * Copyright 2008 Rob Landley <rob@landley.net>
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
6 *
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
7 * See http://www.opengroup.org/onlinepubs/009695399/utilities/cp.html
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
8 *
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
9 * "R+ra+d+p+r"
282
a08f1affe016 Add -v to cp.
Rob Landley <rob@landley.net>
parents: 272
diff changeset
10 USE_CP(NEWTOY(cp, "<2vslrR+rdpa+d+p+rHLPif", TOYFLAG_BIN))
262
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
11
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
12 config CP
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
13 bool "cp"
269
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
14 default y
262
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
15 help
269
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
16 usage: cp -fiprdal SOURCE... DEST
262
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
17
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
18 Copy files from SOURCE to DEST. If more than one SOURCE, DEST must
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
19 be a directory.
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
20
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
21 -f force copy by deleting destination file
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
22 -i interactive, prompt before overwriting existing DEST
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
23 -p preserve timestamps, ownership, and permissions
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
24 -r recurse into subdirectories (DEST must be a directory)
269
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
25 -d don't dereference symlinks
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
26 -a same as -dpr
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
27 -l hard link instead of copying
282
a08f1affe016 Add -v to cp.
Rob Landley <rob@landley.net>
parents: 272
diff changeset
28 -v verbose
262
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
29 */
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
30
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
31 #include "toys.h"
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
32
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
33 #define FLAG_f 1
267
784bc9b0d6df Make cp pass the rest of its test suite. Needs a bigger test suite (-lsHPLi
Rob Landley <rob@landley.net>
parents: 263
diff changeset
34 #define FLAG_i 2 // todo
784bc9b0d6df Make cp pass the rest of its test suite. Needs a bigger test suite (-lsHPLi
Rob Landley <rob@landley.net>
parents: 263
diff changeset
35 #define FLAG_P 4 // todo
784bc9b0d6df Make cp pass the rest of its test suite. Needs a bigger test suite (-lsHPLi
Rob Landley <rob@landley.net>
parents: 263
diff changeset
36 #define FLAG_L 8 // todo
784bc9b0d6df Make cp pass the rest of its test suite. Needs a bigger test suite (-lsHPLi
Rob Landley <rob@landley.net>
parents: 263
diff changeset
37 #define FLAG_H 16 // todo
262
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
38 #define FLAG_a 32
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
39 #define FLAG_p 64
267
784bc9b0d6df Make cp pass the rest of its test suite. Needs a bigger test suite (-lsHPLi
Rob Landley <rob@landley.net>
parents: 263
diff changeset
40 #define FLAG_d 128 // todo
262
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
41 #define FLAG_R 256
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
42 #define FLAG_r 512
269
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
43 #define FLAG_l 1024 // todo
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
44 #define FLAG_s 2048 // todo
282
a08f1affe016 Add -v to cp.
Rob Landley <rob@landley.net>
parents: 272
diff changeset
45 #define FLAG_v 4098
262
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
46
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
47 DEFINE_GLOBALS(
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
48 char *destname;
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
49 int destisdir;
263
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
50 int destisnew;
269
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
51 int keep_symlinks;
262
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
52 )
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
53
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
54 #define TT this.cp
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
55
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
56 // Copy an individual file or directory to target.
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
57
269
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
58 void cp_file(char *src, char *dst, struct stat *srcst)
262
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
59 {
267
784bc9b0d6df Make cp pass the rest of its test suite. Needs a bigger test suite (-lsHPLi
Rob Landley <rob@landley.net>
parents: 263
diff changeset
60 int fdout = -1;
262
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
61
282
a08f1affe016 Add -v to cp.
Rob Landley <rob@landley.net>
parents: 272
diff changeset
62 if (toys.optflags & FLAG_v)
a08f1affe016 Add -v to cp.
Rob Landley <rob@landley.net>
parents: 272
diff changeset
63 printf("'%s' -> '%s'\n", src, dst);
a08f1affe016 Add -v to cp.
Rob Landley <rob@landley.net>
parents: 272
diff changeset
64
262
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
65 // Copy directory or file to destination.
263
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
66
262
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
67 if (S_ISDIR(srcst->st_mode)) {
263
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
68 struct stat st2;
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
69
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
70 // Always make directory writeable to us, so we can create files in it.
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
71 //
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
72 // Yes, there's a race window between mkdir() and open() so it's
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
73 // possible that -p can be made to chown a directory other than the one
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
74 // we created. The closest we can do to closing this is make sure
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
75 // that what we open _is_ a directory rather than something else.
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
76
272
a5652aa22f38 Another cp -r fix, another test case...
Rob Landley <rob@landley.net>
parents: 271
diff changeset
77 if ((mkdir(dst, srcst->st_mode | 0200) && errno != EEXIST)
a5652aa22f38 Another cp -r fix, another test case...
Rob Landley <rob@landley.net>
parents: 271
diff changeset
78 || 0>(fdout=open(dst, 0)) || fstat(fdout, &st2)
a5652aa22f38 Another cp -r fix, another test case...
Rob Landley <rob@landley.net>
parents: 271
diff changeset
79 || !S_ISDIR(st2.st_mode))
263
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
80 {
269
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
81 perror_exit("mkdir '%s'", dst);
263
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
82 }
269
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
83 } else if (TT.keep_symlinks && S_ISLNK(srcst->st_mode)) {
267
784bc9b0d6df Make cp pass the rest of its test suite. Needs a bigger test suite (-lsHPLi
Rob Landley <rob@landley.net>
parents: 263
diff changeset
84 char *link = xreadlink(src);
784bc9b0d6df Make cp pass the rest of its test suite. Needs a bigger test suite (-lsHPLi
Rob Landley <rob@landley.net>
parents: 263
diff changeset
85
784bc9b0d6df Make cp pass the rest of its test suite. Needs a bigger test suite (-lsHPLi
Rob Landley <rob@landley.net>
parents: 263
diff changeset
86 // Note: -p currently has no effect on symlinks. How do you get a
784bc9b0d6df Make cp pass the rest of its test suite. Needs a bigger test suite (-lsHPLi
Rob Landley <rob@landley.net>
parents: 263
diff changeset
87 // filehandle to them? O_NOFOLLOW causes the open to fail.
269
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
88 if (!link || symlink(link, dst)) perror_msg("link '%s'", dst);
267
784bc9b0d6df Make cp pass the rest of its test suite. Needs a bigger test suite (-lsHPLi
Rob Landley <rob@landley.net>
parents: 263
diff changeset
89 free(link);
784bc9b0d6df Make cp pass the rest of its test suite. Needs a bigger test suite (-lsHPLi
Rob Landley <rob@landley.net>
parents: 263
diff changeset
90 } else if (toys.optflags & FLAG_l) {
269
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
91 if (link(src, dst)) perror_msg("link '%s'");
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
92 return;
262
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
93 } else {
263
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
94 int fdin, i;
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
95
262
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
96 fdin = xopen(src, O_RDONLY);
263
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
97 for (i=2 ; i; i--) {
269
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
98 fdout = open(dst, O_RDWR|O_CREAT|O_TRUNC, srcst->st_mode);
263
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
99 if (fdout>=0 || !(toys.optflags & FLAG_f)) break;
269
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
100 unlink(dst);
263
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
101 }
269
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
102 if (fdout<0) perror_exit("%s", dst);
262
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
103 xsendfile(fdin, fdout);
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
104 close(fdin);
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
105 }
263
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
106
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
107 // Inability to set these isn't fatal, some require root access.
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
108 // Can't do fchmod() etc here because -p works on mkdir, too.
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
109
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
110 if (toys.optflags & FLAG_p) {
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
111 int mask = umask(0);
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
112 struct utimbuf ut;
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
113
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
114 fchown(fdout,srcst->st_uid, srcst->st_gid);
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
115 ut.actime = srcst->st_atime;
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
116 ut.modtime = srcst->st_mtime;
269
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
117 utime(dst, &ut);
263
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
118 umask(mask);
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
119 }
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
120 xclose(fdout);
262
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
121 }
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
122
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
123 // Callback from dirtree_read() for each file/directory under a source dir.
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
124
263
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
125 int cp_node(char *path, struct dirtree *node)
262
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
126 {
263
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
127 char *s = path+strlen(path);
269
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
128 struct dirtree *n;
263
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
129
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
130 // Find appropriate chunk of path for destination.
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
131
271
7d625cbdde25 Update cp -r to work better, add relevant tests to test suite.
Rob Landley <rob@landley.net>
parents: 269
diff changeset
132 n = node;
7d625cbdde25 Update cp -r to work better, add relevant tests to test suite.
Rob Landley <rob@landley.net>
parents: 269
diff changeset
133 if (!TT.destisdir) n = n->parent;
7d625cbdde25 Update cp -r to work better, add relevant tests to test suite.
Rob Landley <rob@landley.net>
parents: 269
diff changeset
134 for (;;n = n->parent) {
269
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
135 while (s!=path) {
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
136 if (*(--s)=='/') break;
263
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
137 }
269
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
138 if (!n) break;
263
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
139 }
269
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
140 if (s != path) s++;
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
141
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
142 s = xmsprintf("%s/%s", TT.destname, s);
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
143 cp_file(path, s, &(node->st));
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
144 free(s);
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
145
262
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
146 return 0;
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
147 }
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
148
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
149 void cp_main(void)
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
150 {
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
151 struct stat st;
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
152 int i;
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
153
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
154 // Grab target argument. (Guaranteed to be there due to "<2" above.)
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
155
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
156 TT.destname = toys.optargs[--toys.optc];
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
157
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
158 // If destination doesn't exist, are we ok with that?
263
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
159
262
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
160 if (stat(TT.destname, &st)) {
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
161 if (toys.optc>1) goto error_notdir;
263
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
162 TT.destisnew++;
262
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
163
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
164 // If destination exists...
263
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
165
262
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
166 } else {
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
167 if (S_ISDIR(st.st_mode)) TT.destisdir++;
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
168 else if (toys.optc > 1) goto error_notdir;
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
169 }
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
170
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
171 // Handle sources
263
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
172
262
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
173 for (i=0; i<toys.optc; i++) {
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
174 char *src = toys.optargs[i];
269
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
175 char *dst;
262
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
176
269
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
177 // Skip src==dest (should check inodes to catch "cp blah ./blah").
263
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
178
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
179 if (!strcmp(src, TT.destname)) continue;
269
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
180
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
181 // Skip nonexistent sources.
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
182
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
183 TT.keep_symlinks = toys.optflags & FLAG_d;
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
184 if (TT.keep_symlinks ? lstat(src, &st) : stat(src, &st))
263
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
185 {
262
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
186 perror_msg("'%s'", src);
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
187 toys.exitval = 1;
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
188 continue;
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
189 }
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
190
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
191 // Copy directory or file.
263
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
192
271
7d625cbdde25 Update cp -r to work better, add relevant tests to test suite.
Rob Landley <rob@landley.net>
parents: 269
diff changeset
193 if (TT.destisdir) {
7d625cbdde25 Update cp -r to work better, add relevant tests to test suite.
Rob Landley <rob@landley.net>
parents: 269
diff changeset
194 dst = strrchr(src, '/');
7d625cbdde25 Update cp -r to work better, add relevant tests to test suite.
Rob Landley <rob@landley.net>
parents: 269
diff changeset
195 if (dst) dst++;
7d625cbdde25 Update cp -r to work better, add relevant tests to test suite.
Rob Landley <rob@landley.net>
parents: 269
diff changeset
196 else dst=src;
7d625cbdde25 Update cp -r to work better, add relevant tests to test suite.
Rob Landley <rob@landley.net>
parents: 269
diff changeset
197 dst = xmsprintf("%s/%s", TT.destname, dst);
7d625cbdde25 Update cp -r to work better, add relevant tests to test suite.
Rob Landley <rob@landley.net>
parents: 269
diff changeset
198 } else dst = TT.destname;
262
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
199 if (S_ISDIR(st.st_mode)) {
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
200 if (toys.optflags & FLAG_r) {
269
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
201 cp_file(src, dst, &st);
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
202
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
203 TT.keep_symlinks++;
263
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
204 strncpy(toybuf, src, sizeof(toybuf)-1);
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
205 toybuf[sizeof(toybuf)-1]=0;
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
206 dirtree_read(toybuf, NULL, cp_node);
262
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
207 } else error_msg("Skipped dir '%s'", src);
269
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
208 } else cp_file(src, dst, &st);
7b3d9594bf9c Fix -r logic, it needs both source and dest paths explicitly stated.
Rob Landley <rob@landley.net>
parents: 267
diff changeset
209 if (TT.destisdir) free(dst);
262
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
210 }
263
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
211
262
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
212 return;
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
213
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
214 error_notdir:
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
215 error_exit("'%s' isn't a directory", TT.destname);
70f36d9c5387 Add first pass at cp, totally untested, unlikely to work yet. :)
Rob Landley <rob@landley.net>
parents:
diff changeset
216 }