[OpenAFS-devel] 'up' patch for preserving mountpoints
Todd M. Lewis
Todd_Lewis@unc.edu
Mon, 18 Jun 2001 08:45:06 -0400
This is a multi-part message in MIME format.
--------------4C36B612CAAD4FA2EE8C9FED
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
The 'up' command (venus/up.c) is like a recursive copy that knows about
and copies ACLs as well as files. Unfortunately, it doesn't know about
mount points. That may account for its unusual name -- up has the side
effect of copying the files in and below its source volume(s) "up" into
its target's volume.
The attached patch adds a "-m" option to up which makes it recognize and
copy mount points rather than traversing them during its recursive copy
operation. Without the -m option, up's default (questionable) behavior
remains unchanged.
--
+------------------------------------------------------------+
/ Todd_Lewis@unc.edu http://www.unc.edu/~utoddl /
/(919) 962-5273 Official Signature of the New Millennium /
+------------------------------------------------------------+
--------------4C36B612CAAD4FA2EE8C9FED
Content-Type: text/plain; charset=us-ascii;
name="up.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="up.patch"
--- venus/up.c-orig Wed May 23 13:13:59 2001
+++ venus/up.c Mon Jun 18 08:22:55 2001
@@ -21,6 +21,7 @@
#undef _NONSTD_TYPES
#endif
#include <stdio.h>
+#include <afs/afs_args.h>
#include <sys/param.h>
#ifdef AFS_SUN5_ENV
#include <fcntl.h>
@@ -35,6 +36,9 @@
#include <afs/vice.h>
#undef VIRTUE
#undef VICE
+#include <sys/ioctl.h>
+#include <netdb.h>
+#include <afs/venus.h>
/* ************************************************************* */
@@ -51,6 +55,7 @@
Boolean renameTargets = false;
Boolean oneLevel = false;
Boolean preserveDate = true;
+Boolean preserveMountPoints = false;
Boolean forceOverwrite = false;
int pageSize;
@@ -58,6 +63,9 @@
Boolean oldAcl = false;
char file1[MAXPATHLEN], file2[MAXPATHLEN];
+#define MAXSIZE 2048
+static char space[MAXSIZE];
+
struct OldAcl {
int nplus;
int nminus;
@@ -138,9 +146,13 @@
preserveDate = false;
break;
+ case 'm':
+ preserveMountPoints = true;
+ break;
+
default:
fprintf(stderr, "Unknown option: '%c'\n", *cp);
- fprintf(stderr, "usage: up [-v1frx] from to\n");
+ fprintf(stderr, "usage: up [-v1frxm] from to\n");
exit(1);
}
argc--, argv++;
@@ -151,8 +163,8 @@
exit(1);
}
- strcpy(file1, argv[0]);
- strcpy(file2, argv[1]);
+ strncpy(file1, argv[0], MAXPATHLEN);
+ strncpy(file2, argv[1], MAXPATHLEN);
} /*ScanArgs*/
@@ -437,6 +449,45 @@
return 1;
}
} /*Dealing with symlink*/
+
+ else if ( preserveMountPoints && (code=isMountPoint( file1, &blob )) ) {
+ /*
+ * --------------------- Copy mount point --------------------
+ */
+
+ if ( code > 1 ) {
+ perror("checking for mount point ");
+ return 1;
+ }
+ if (verbose) {
+ printf("Level %d: Mount point %s to %s\n", level, file1, file2);
+ fflush(stdout);
+ }
+
+ /* Don't ovewrite a write protected directory (unless force: -f) */
+ if (!forceOverwrite && goods2 && (s2.st_mode & 0200) == 0) {
+ fprintf(stderr,
+ "Target %s is write protected against its owner; not changed\n",
+ file2);
+ return 1;
+ }
+
+ if (verbose) {
+ printf(" Copy mount point %s for vol %s to %s\n", file1, blob.out, file2);
+ fflush(stdout);
+ }
+
+ unlink(file2); /* Always make the new link (it was easier) */
+
+ strcat(blob.out, "."); /* stupid convention; these end with a period */
+ code = symlink(blob.out, file2);
+ if (code == -1) {
+ fprintf(stderr, "Could not create mount point %s for vol %s\n", file2, blob.out);
+ perror("create mount point ");
+ return 1;
+ }
+
+ } /*Dealing with mount point*/
else if (((s1.st_mode & S_IFMT) == S_IFDIR) && (recursive || (level == 0))) {
/*
@@ -610,3 +661,75 @@
return rcode;
} /*Copy*/
+
+
+int isMountPoint( name, blob )
+ char *name;
+ struct ViceIoctl *blob;
+{
+ afs_int32 code;
+ char true_name[1024]; /*dirname*/
+ char parent_dir[1024]; /*Parent directory of true name*/
+ char *last_component; /*Last component of true name*/
+
+ sprintf(true_name, "%s%s",
+ (name[0] == '/') ? "" : "./",
+ name);
+
+ /*
+ * Find rightmost slash, if any.
+ */
+ last_component = (char *) rindex(true_name, '/');
+ if (last_component) {
+ /*
+ * Found it. Designate everything before it as the parent directory,
+ * everything after it as the final component.
+ */
+ strncpy(parent_dir, true_name, last_component - true_name);
+ parent_dir[last_component - true_name] = 0;
+ last_component++; /*Skip the slash*/
+ }
+ else {
+ /*
+ * No slash appears in the given file name. Set parent_dir to the current
+ * directory, and the last component as the given name.
+ */
+ strcpy(parent_dir, ".");
+ last_component = true_name;
+ }
+
+ if (strcmp(last_component, ".") == 0 || strcmp(last_component, "..") == 0) {
+ fprintf(stderr, "up: you may not use '.' or '..' as the last component\n");
+ fprintf(stderr, "up: of a name in the 'up' command.\n");
+ return 3;
+ }
+
+ blob->in = last_component;
+ blob->in_size = strlen(last_component)+1;
+ blob->out_size = MAXSIZE;
+ blob->out = space;
+ bzero(space, MAXSIZE);
+
+ code = pioctl(parent_dir, VIOC_AFS_STAT_MT_PT, blob, 0);
+
+ if (code == 0) {
+ printf("'%s' is a mount point for volume '%s'\n", name, space);
+ fflush(stdout);
+ return 1;
+ }
+ else {
+ if (errno == EINVAL) {
+ /* printf( "'%s' is not a mount point.\n", name);
+ * fflush(stdout);
+ */
+ return 0;
+ }
+ else {
+ fprintf( stderr, "problem examining '%s' in '%s'.\n", last_component, parent_dir );
+ return 2;
+ /* Die(errno, (ti->data ? ti->data : parent_dir));
+ */
+ }
+ }
+ return 4;
+}
--------------4C36B612CAAD4FA2EE8C9FED--