2 $Id: ad_cp.c,v 1.1 2009-09-01 14:28:07 franklahm Exp $
4 Copyright (c) 2009 Frank Lahm <franklahm@gmail.com>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
19 #endif /* HAVE_CONFIG_H */
22 #include <sys/types.h>
37 #include <atalk/adouble.h>
38 #include <atalk/cnid.h>
39 #include <atalk/volinfo.h>
40 #include <atalk/util.h>
43 #define ADv2_DIRNAME ".AppleDouble"
53 static char *netatalk_dirs[] = {
61 Check for netatalk special folders e.g. ".AppleDB" or ".AppleDesktop"
62 Returns pointer to name or NULL.
64 static const char *check_netatalk_dirs(const char *name)
68 for (c=0; netatalk_dirs[c]; c++) {
69 if ((strcmp(name, netatalk_dirs[c])) == 0)
70 return netatalk_dirs[c];
76 static void usage_cp()
79 "Usage: ad cp [-R [-L | -P]] [-pv] <source_file> <target_file>\n"
80 "Usage: ad cp [-R [-L | -P]] [-pv] <source_file [source_file ...]> <target_directory>\n"
84 static int ad_cp_copy(const afpvol_t *srcvol, const afpvol_t *dstvol,
85 char *srcfile, char *dstfile, struct stat *st)
87 printf("copy: '%s' -> '%s'\n", srcfile, dstfile);
91 static int ad_cp_r(const afpvol_t *srcvol, const afpvol_t *dstvol, char *srcdir, char *dstdir)
93 int ret = 0, cwd, dirprinted = 0, dirempty;
94 static char srcpath[MAXPATHLEN+1];
95 static char dstpath[MAXPATHLEN+1];
99 static struct stat st; /* Save some stack space */
101 strlcat(srcpath, srcdir, sizeof(srcpath));
102 strlcat(dstpath, dstdir, sizeof(dstpath));
104 if ((dp = opendir (srcdir)) == NULL) {
105 perror("Couldn't opendir .");
109 /* First run: copy files */
110 while ((ep = readdir (dp))) {
111 /* Check if its "." or ".." */
112 if (DIR_DOT_OR_DOTDOT(ep->d_name))
115 /* Check for netatalk special folders e.g. ".AppleDB" or ".AppleDesktop" */
116 if ((check_netatalk_dirs(ep->d_name)) != NULL)
119 if (lstat(ep->d_name, &st) < 0) {
120 perror("Can't stat");
124 /* Build paths, copy, strip name */
125 strlcat(srcpath, "/", sizeof(srcpath));
126 strlcat(dstpath, "/", sizeof(dstpath));
127 strlcat(srcpath, ep->d_name, sizeof(srcpath));
128 strlcat(dstpath, ep->d_name, sizeof(dstpath));
130 ret = ad_cp_copy(srcvol, dstvol, srcpath, dstpath, &st);
132 if ((tmp = strrchr(srcpath, '/')))
134 if ((tmp = strrchr(dstpath, '/')))
141 /* Second run: recurse to dirs */
143 while ((ep = readdir (dp))) {
144 /* Check if its "." or ".." */
145 if (DIR_DOT_OR_DOTDOT(ep->d_name))
148 /* Check for netatalk special folders e.g. ".AppleDB" or ".AppleDesktop" */
149 if (check_netatalk_dirs(ep->d_name) != NULL)
152 if (lstat(ep->d_name, &st) < 0) {
153 perror("Can't stat");
158 if (S_ISDIR(st.st_mode)) {
159 strlcat(srcpath, "/", sizeof(srcpath));
160 strlcat(dstpath, "/", sizeof(dstpath));
161 ret = ad_cp_r(srcvol, dstvol, ep->d_name, ep->d_name);
172 if ((tmp = strrchr(srcpath, '/')))
174 if ((tmp = strrchr(dstpath, '/')))
180 int ad_cp(int argc, char **argv)
188 char *srcfile = NULL;
190 char *dstfile = NULL;
192 char path[MAXPATHLEN+1];
195 while ((c = getopt(argc, argv, ":npvLPR")) != -1) {
223 /* How many pathnames do we have */
224 numpaths = argc - optind;
225 printf("Number of paths: %u\n", numpaths);
231 while ( argv[argc-1][(strlen(argv[argc-1]) - 1)] == '/')
232 argv[argc-1][(strlen(argv[argc-1]) - 1)] = 0;
233 printf("Destination is: %s\n", argv[argc-1]);
235 /* Create vol for destination */
236 newvol(argv[argc-1], &dstvol);
239 /* Case 1: 2 paths */
240 if (stat(argv[optind], &sst) != 0)
242 if (S_ISREG(sst.st_mode)) {
243 /* Either file to file or file to dir copy */
244 newvol(argv[optind], &srcvol);
245 ad_cp_copy(&srcvol, &dstvol, srcfile, path, &sst);
249 } else if (S_ISDIR(sst.st_mode)) {
250 /* dir to dir copy. Check if -R is requested */
258 /* Case 2: >2 paths */
259 while (optind < (argc-1)) {
260 printf("Source is: %s\n", argv[optind]);
261 newvol(argv[optind], &srcvol);
262 if (stat(argv[optind], &sst) != 0)
264 if (S_ISDIR(sst.st_mode)) {
265 /* Source is a directory */
267 printf("Source %s is a directory\n", argv[optind]);
270 srcdir = argv[optind];
271 dstdir = argv[argc-1];
273 ad_cp_r(&srcvol, &dstvol, srcdir, dstdir);
276 /* Source is a file */
277 srcfile = argv[optind];
278 if (numpaths != 2 && !dstdir) {
283 strlcat(path, dstdir, sizeof(path));
284 basenametmp = strdup(srcfile);
285 strlcat(path, basename(basenametmp), sizeof(path));
287 printf("%s %s\n", srcfile, path);
288 if (ad_cp_copy(&srcvol, &dstvol, srcfile, path, &sst) != 0) {
297 } /* else (numpath>2) */