/*
* Copyright 2000, International Business Machines Corporation and others.
* All Rights Reserved.
- *
+ *
* This software has been released under the terms of the IBM Public
* License. For details, see the LICENSE file in the top-level source
* directory or online at http://www.openafs.org/dl/license10.html
#include <afsconfig.h>
#include <afs/param.h>
-RCSID
- ("$Header$");
+#include <roken.h>
-/* missing type from C language */
-
-#include <errno.h>
-#ifdef AFS_AIX32_ENV
-#include <signal.h>
-#undef _NONSTD_TYPES
-#endif
-#include <stdio.h>
#include <afs/afs_args.h>
-#include <sys/param.h>
-#ifdef AFS_SUN5_ENV
-#include <fcntl.h>
-#endif
-#include <sys/file.h>
-#include <sys/stat.h>
-#include <dirent.h>
-#include <sys/time.h>
#define VIRTUE
#define VICE
-#include <sys/ioctl.h>
#include <afs/vice.h>
#undef VIRTUE
#undef VICE
-#include <sys/ioctl.h>
-#include <netdb.h>
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
-
#include <afs/venus.h>
+#include <afs/sys_prototypes.h>
+#include <afs/afsutil.h>
+#include <afs/afs_consts.h>
/* ************************************************************* */
-#define MAXACL 400
-
-#if !defined(AFS_LINUX20_ENV) && !defined(AFS_DARWIN_ENV) && !defined(AFS_XBSD_ENV)
-extern sys_nerr;
-extern char *sys_errlist[];
-#endif
+#define MAXACL AFS_PIOCTL_MAXSIZE
short verbose = 0;
short renameTargets = 0;
short preserveMountPoints = 0;
short forceOverwrite = 0;
-int pageSize;
short setacl = 1;
short oldAcl = 0;
char file1[MAXPATHLEN], file2[MAXPATHLEN];
-#define MAXSIZE 2048
-static char space[MAXSIZE];
+static char space[AFS_PIOCTL_MAXSIZE];
struct OldAcl {
int nplus;
char data[1];
};
+static void ScanArgs(int argc, char *argv[]);
+static short MakeParent(char *file, afs_int32 owner);
+static int Copy(char *file1, char *file2, short recursive, int level);
+static int isMountPoint(char *name, struct ViceIoctl *blob);
+
+
/* ************************************************************ */
/* */
/* main program */
{
#ifdef AFS_AIX32_ENV
/*
- * The following signal action for AIX is necessary so that in case of a
- * crash (i.e. core is generated) we can include the user's data section
+ * The following signal action for AIX is necessary so that in case of a
+ * crash (i.e. core is generated) we can include the user's data section
* in the core dump. Unfortunately, by default, only a partial core is
* generated which, in many cases, isn't too useful.
*/
nsa.sa_flags = SA_FULLDUMP;
sigaction(SIGSEGV, &nsa, NULL);
#endif
-#if !defined (AFS_AIX_ENV) && !defined (AFS_HPUX_ENV)
- pageSize = getpagesize();
-#endif
ScanArgs(argc, argv);
/* now read each line of the CopyList */
if (Copy(file1, file2, !oneLevel, 0))
- exit(1); /* some type of failure */
+ return(1); /* some type of failure */
- exit(0);
+ return(0);
}
#define USAGE "usage: up [-v1frxm] from to\n"
-void
+static void
ScanArgs(int argc, char *argv[])
{
/* skip program name */
while (argc > 0 && *argv[0] == '-') {
char *cp = *argv;
+ if (strlen(cp) > 2) {
+ goto badoption;
+ }
+
switch (*++cp) {
case 'v':
verbose = 1;
break;
default:
- fprintf(stderr, "Unknown option: '%c'\n", *cp);
+ cp--;
+
+ badoption:
+ fprintf(stderr, "Unknown option: '%s'\n", cp);
fprintf(stderr, USAGE);
exit(1);
}
* 1 if it exists, 0 otherwise. Note: the owner argument
* is a hack. All directories made will have this owner.
*/
-short
+static short
MakeParent(char *file, afs_int32 owner)
{
char parent[MAXPATHLEN];
char *p;
struct stat s;
- strcpy(parent, file);
+ strlcpy(parent, file, sizeof parent);
p = strrchr(parent, '/');
if (!p) {
- strcpy(parent, ".");
+ strlcpy(parent, ".", sizeof parent);
} else if (p > parent) {
*p = '\0';
} else {
* This does the bulk of the work of the program. Handle one file,
* possibly copying subfiles if this is a directory
*/
-int
+static int
Copy(char *file1, char *file2, short recursive, int level)
{
struct stat s1, s2; /*Stat blocks */
if (verbose) {
printf(" Copy file %s to %s (%u Bytes)\n", file1, file2,
- s1.st_size);
+ (unsigned int) s1.st_size);
fflush(stdout);
}
- strcpy(tmpfile, file2); /* Name of temporary file */
- strcat(tmpfile, ".UPD");
+ strlcpy(tmpfile, file2, sizeof tmpfile); /* Name of temporary file */
+ strlcat(tmpfile, ".UPD", sizeof tmpfile);
/* open file1 for input */
f1 = open(file1, O_RDONLY);
if (f1 < 0) {
- fprintf(stderr, "Unable to open input file %s, ", file1);
- if (errno >= sys_nerr)
- fprintf(stderr, "error code = %d\n", errno);
- else
- fprintf(stderr, "%s\n", sys_errlist[errno]);
+ fprintf(stderr, "Unable to open input file %s: %s\n",
+ file1, strerror(errno));
return 1;
}
/* open temporary output file */
f2 = open(tmpfile, (O_WRONLY | O_CREAT | O_TRUNC), s1.st_mode);
if (f2 < 0) {
- fprintf(stderr, "Unable to open output file %s, ", tmpfile);
- if (errno >= sys_nerr)
- fprintf(stderr, "error code = %d\n", errno);
- else
- fprintf(stderr, "%s\n", sys_errlist[errno]);
+ fprintf(stderr, "Unable to open output file %s: %s\n",
+ tmpfile, strerror(errno));
fflush(stdout);
close(f1);
return 1;
/* Close the files */
code = close(f1);
+ if (code < 0) {
+ perror("close ");
+ rcode = 1;
+ }
code = close(f2);
if (code < 0) {
perror("close ");
/* Rename file2 to file2.old. [-r] */
if (renameTargets && goods2) {
- strcpy(newName, file2);
- strcat(newName, ".old");
+ strlcpy(newName, file2, sizeof newName);
+ strlcat(newName, ".old", sizeof newName);
if (verbose) {
printf(" Renaming %s to %s\n", file2, newName);
fflush(stdout);
if (s1.st_size != s2.st_size) {
fprintf(stderr,
"WARNING: New file %s is %u bytes long; should be %u\n",
- file2, s2.st_size, s1.st_size);
+ file2, (unsigned int) s2.st_size,
+ (unsigned int) s1.st_size);
}
}
fflush(stdout);
}
- n = readlink(file1, linkvalue, sizeof(linkvalue));
+ n = readlink(file1, linkvalue, sizeof(linkvalue)-1);
if (n == -1) {
fprintf(stderr, "Could not read symbolic link %s\n", file1);
perror("read link ");
char f1[MAXPATHLEN], f2[MAXPATHLEN];
char *p1, *p2;
struct dirent *d;
+ struct timeval tv[2];
if (verbose) {
printf("Level %d: Directory %s to %s\n", level, file1, file2);
return 1;
}
- strcpy(f1, file1);
- strcpy(f2, file2);
+ strlcpy(f1, file1, sizeof f1);
+ strlcpy(f2, file2, sizeof f2);
p1 = f1 + strlen(f1);
p2 = f2 + strlen(f2);
if (p1 == f1 || p1[-1] != '/')
while ((d = readdir(dir)) != NULL) {
if (strcmp(d->d_name, ".") == 0 || strcmp(d->d_name, "..") == 0)
continue;
- strcpy(p1, d->d_name);
- strcpy(p2, d->d_name);
+ strlcpy(p1, d->d_name, sizeof f1 - (p1 - f1));
+ strlcpy(p2, d->d_name, sizeof f2 - (p2 - f2));
code = Copy(f1, f2, recursive, level + 1);
if (code && !rcode)
rcode = 1; /* remember errors */
for (i = 1; i < strlen(file1); i++)
if (file1[i] == '/')
break;
- strcpy(aclspace, &file1[i]);
+ strlcpy(aclspace, &file1[i], sizeof aclspace);
blob.in_size = 1 + strlen(aclspace);
tfd = open(file1, O_RDONLY, 0);
/* Now convert the thing. */
oacl = (struct OldAcl *)(aclspace + 4);
sprintf(tacl, "%d\n%d\n", oacl->nplus, oacl->nminus);
- strcat(tacl, oacl->data);
- strcpy(aclspace, tacl);
+ strlcat(tacl, oacl->data, sizeof tacl);
+ strlcpy(aclspace, tacl, sizeof aclspace);
} /*Grab and convert old-style ACL */
else {
/* Get a new-style ACL */
printf("Not setting acls\n");
}
}
+
+ /* preserve access and modification times: ("-x" disables) */
+ if (preserveDate) {
+ tv[0].tv_sec = s1.st_atime;
+ tv[0].tv_usec = 0;
+ tv[1].tv_sec = s1.st_mtime;
+ tv[1].tv_usec = 0;
+ utimes(file2, tv);
+ }
}
return rcode;
} /*Copy */
-int
+static int
isMountPoint(char *name, struct ViceIoctl *blob)
{
afs_int32 code;
* 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, ".");
+ strlcpy(parent_dir, ".", sizeof parent_dir);
last_component = true_name;
}
blob->in = last_component;
blob->in_size = strlen(last_component) + 1;
- blob->out_size = MAXSIZE;
+ blob->out_size = AFS_PIOCTL_MAXSIZE;
blob->out = space;
- memset(space, 0, MAXSIZE);
+ memset(space, 0, AFS_PIOCTL_MAXSIZE);
code = pioctl(parent_dir, VIOC_AFS_STAT_MT_PT, blob, 0);
*/
}
}
- return 4;
}