[PVFS2-CVS]
commit by robl in pvfs2-1/src/apps/admin: pvfs2-ln.c module.mk.in
CVS commit program
cvs at parl.clemson.edu
Mon Jul 11 17:26:08 EDT 2005
Update of /projects/cvsroot/pvfs2-1/src/apps/admin
In directory parlweb:/tmp/cvs-serv19004
Modified Files:
module.mk.in
Added Files:
pvfs2-ln.c
Log Message:
david metheny contributed a pvfs2-ln utility
--- /dev/null 2003-01-30 05:24:37.000000000 -0500
+++ pvfs2-ln.c 2005-07-11 16:26:08.000000000 -0400
@@ -0,0 +1,334 @@
+/*
+ * Copyright Acxiom Corporation, 2005
+ *
+ * See COPYING in top-level directory.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/time.h>
+#include <time.h>
+#include <getopt.h>
+
+#include "pvfs2.h"
+#include "str-utils.h"
+#include "pint-sysint-utils.h"
+
+#ifndef PVFS2_VERSION
+#define PVFS2_VERSION "Unknown"
+#endif
+
+/* optional parameters, filled in by parse_args() */
+struct options
+{
+ char * pszLinkTarget; /* Link Target */
+ char * pszLinkName; /* Link Name */
+ int nVerbose;
+};
+
+/* Function Prototypes */
+static void usage(int argc, char** argv);
+static int parse_args(int argc, char** argv, struct options * opts);
+static void enable_verbose(struct options * opts);
+static int make_link(PVFS_credentials * pCredentials,
+ const PVFS_fs_id fs_id,
+ const char * pszLinkTarget,
+ const char * pszPvfsPath,
+ const int nVerbose);
+
+int main(int argc, char **argv)
+{
+ int ret = -1;
+ char szPvfsPath[PVFS_NAME_MAX] = "";
+ PVFS_fs_id fs_id = 0;
+ struct options user_opts;
+ PVFS_credentials credentials;
+
+ /* Initialize any memory */
+ memset(&user_opts, 0, sizeof(user_opts));
+ memset(&credentials, 0, sizeof(credentials));
+
+ /* look at command line arguments */
+ ret = parse_args(argc, argv, &user_opts);
+ if(ret < 0)
+ {
+ fprintf(stderr, "Error: failed to parse command line arguments.\n");
+ return (-1);
+ }
+
+ ret = PVFS_util_init_defaults();
+ if (ret < 0)
+ {
+ PVFS_perror("PVFS_util_init_defaults", ret);
+ return (-1);
+ }
+
+ /* Let's verify that all the given files reside on a PVFS2 filesytem */
+ ret = PVFS_util_resolve(user_opts.pszLinkName,
+ &fs_id,
+ szPvfsPath,
+ PVFS_NAME_MAX);
+
+ if (ret < 0)
+ {
+ fprintf(stderr, "Error: could not find file system for %s\n",
+ user_opts.pszLinkTarget);
+ PVFS_sys_finalize();
+ return(-1);
+ }
+
+ /* We will re-use the same credentials for each call */
+ PVFS_util_gen_credentials(&credentials);
+
+ ret = make_link(&credentials,
+ fs_id,
+ user_opts.pszLinkTarget,
+ szPvfsPath,
+ user_opts.nVerbose);
+ if(ret != 0)
+ {
+ fprintf(stderr, "cannot create softlink [%s] to [%s]\n",
+ user_opts.pszLinkName,
+ user_opts.pszLinkTarget);
+ return(-1);
+ }
+
+ /* TODO: need to free the request descriptions */
+ PVFS_sys_finalize();
+
+ return(0);
+}
+
+static int make_link(PVFS_credentials * pCredentials,
+ const PVFS_fs_id fs_id,
+ const char * pszLinkTarget,
+ const char * pszPvfsPath,
+ const int nVerbose)
+{
+ int ret = 0;
+ char szBaseName[PVFS_NAME_MAX] = "";
+ PVFS_sys_attr attr;
+ PVFS_sysresp_lookup resp_lookup;
+ PVFS_object_ref parent_ref;
+ PVFS_sysresp_symlink resp_sym;
+
+ /* Initialize any variables */
+ memset(&attr, 0, sizeof(attr));
+ memset(&resp_lookup, 0, sizeof(resp_lookup));
+ memset(&parent_ref, 0, sizeof(parent_ref));
+ memset(&resp_sym, 0, sizeof(resp_sym));
+
+ /* Set the attributes for the new directory */
+ attr.owner = pCredentials->uid;
+ attr.group = pCredentials->gid;
+ attr.perms = 0777;
+ attr.atime = time(NULL);
+ attr.mtime = attr.atime;
+ attr.ctime = attr.atime;
+ attr.mask = (PVFS_ATTR_SYS_ALL_SETABLE);
+
+ /* We need to change the PINT_remove_base_dir to an API call (pvfs_util),
+ * and we need to change this to use it
+ */
+ ret = PINT_remove_base_dir( (char *) pszPvfsPath,
+ szBaseName,
+ sizeof(szBaseName));
+
+ if(ret != 0)
+ {
+ fprintf(stderr, "Cannot retrieve link name for creation on %s\n", pszPvfsPath);
+ return(-1);
+ }
+
+ /* Make sure we don't try and create the root directory */
+ if( strcmp(szBaseName, "/") == 0 )
+ {
+ fprintf(stderr, "directory exists\n");
+ return(-1);
+ }
+
+ /* TODO: We need to change the PINT_lookup_parent to an API call (pvfs_util),
+ * and we need to change this to use it. Maybe send entire parent_refn so
+ * that the fs_id is filled in also
+ */
+ ret = PINT_lookup_parent( (char *) pszPvfsPath,
+ fs_id,
+ pCredentials,
+ &parent_ref.handle);
+
+ if(ret < 0)
+ {
+ PVFS_perror("PVFS_util_lookup_parent", ret);
+ return(-1);
+ }
+
+ parent_ref.fs_id = fs_id;
+
+ if(nVerbose)
+ {
+ fprintf(stderr, "Creating Symlink\n");
+ fprintf(stderr, "\t szBaseName = [%s]\n", szBaseName);
+ fprintf(stderr, "\t fs_id = [%d]\n", fs_id);
+ fprintf(stderr, "\t Target = [%s]\n", pszLinkTarget);
+ fprintf(stderr, "\t pvfs path = [%s]\n", pszPvfsPath);
+
+ fprintf(stdout, "Directory Attributes\n");
+ fprintf(stdout, "\t owner [%d]\n", attr.owner);
+ fprintf(stdout, "\t group [%d]\n", attr.group);
+ fprintf(stdout, "\t perms [%o]\n", attr.perms);
+ fprintf(stdout, "\t atime [%Lu]\n", Lu(attr.atime));
+ fprintf(stdout, "\t mtime [%Lu]\n", Lu(attr.mtime));
+ fprintf(stdout, "\t ctime [%Lu]\n", Lu(attr.ctime));
+ }
+
+ ret = PVFS_sys_symlink(szBaseName,
+ parent_ref,
+ (char *) pszLinkTarget,
+ attr,
+ pCredentials,
+ &resp_sym);
+
+ if (ret < 0)
+ {
+ PVFS_perror("PVFS_sys_symlink", ret);
+ return(ret);
+ }
+
+ return(0);
+}
+
+/* parse_args()
+ *
+ * parses command line arguments
+ *
+ * returns pointer to options structure on success, NULL on failure
+ */
+static int parse_args(int argc, char** argv, struct options * opts)
+{
+ int ret = 0,
+ option_index = 0,
+ create_softlink = 0;
+ char * cur_option = NULL;
+ char flags[] = "hvVs"; /* Options available on command line */
+
+ static struct option long_opts[] =
+ {
+ {"help",0,0,0},
+ {"version",0,0,0},
+ {"verbose",0,0,0},
+ {0,0,0,0}
+ };
+
+ while((ret = getopt_long_only(argc, argv, flags, long_opts, &option_index)) != -1)
+ {
+ switch (ret)
+ {
+ case 0:
+ cur_option = (char*)long_opts[option_index].name;
+
+ if(strcmp("help", cur_option) == 0)
+ {
+ usage(argc, argv);
+ exit(0);
+ }
+ else if(strcmp("verbose", cur_option) == 0)
+ {
+ enable_verbose(opts);
+ }
+ else if (strcmp("version", cur_option) == 0)
+ {
+ printf("%s\n", PVFS2_VERSION);
+ exit(0);
+ }
+ else
+ {
+ usage(argc, argv);
+ return -1;
+ }
+ break;
+
+ case 'h': /* --help */
+ usage(argc, argv);
+ exit(0);
+ break;
+
+ case 's': /* --help */
+ create_softlink = 1;
+ break;
+
+ case 'V': /* --verbose */
+ enable_verbose(opts);
+ break;
+
+ case 'v': /* --version */
+ printf("%s\n", PVFS2_VERSION);
+ exit(0);
+ break;
+
+ case '?':
+ usage(argc, argv);
+ return -1;
+
+ default:
+ usage(argc, argv);
+ return -1;
+ }
+ }
+
+ if(!create_softlink)
+ {
+ fprintf(stderr, "Hard links not supported. Use -s option for softlinks\n");
+ usage(argc, argv);
+ exit(1);
+ }
+
+ /* Validation to make sure we have at least one directory to check */
+ if(argc - optind != 2)
+ {
+ usage(argc, argv);
+ return(-1);
+ }
+
+ /* We processed all options arguments, so let's get the link target & name */
+ opts->pszLinkTarget = argv[optind];
+ opts->pszLinkName = argv[optind+1];
+
+ if(opts->nVerbose)
+ {
+ fprintf(stdout, "Options Specified\n");
+ fprintf(stdout, "\t Verbose [%d]\n", opts->nVerbose);
+ fprintf(stdout, "\t Link Target [%s]\n", opts->pszLinkTarget);
+ fprintf(stdout, "\t Link Name [%s]\n", opts->pszLinkName);
+ }
+
+ return(0);
+}
+
+static void usage(int argc, char **argv)
+{
+ fprintf(stderr, "Usage: %s [OPTION] TARGET LINK_NAME\n", argv[0]);
+ fprintf(stderr, "Create a link to the specified TARGET with LINK_NAME.\n\n");
+
+ fprintf(stderr," -s, create softlink\n");
+ fprintf(stderr," -V, --verbose turns on verbose messages\n");
+ fprintf(stderr," -v, --version output version information and exit\n");
+ fprintf(stderr," -h, --help print help\n");
+ return;
+}
+
+static void enable_verbose(struct options * opts)
+{
+ opts->nVerbose = 1;
+}
+
+/*
+ * Local variables:
+ * c-indent-level: 4
+ * c-basic-offset: 4
+ * End:
+ *
+ * vim: ts=8 sts=4 sw=4 expandtab
+ */
Index: module.mk.in
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/apps/admin/module.mk.in,v
diff -u -w -p -u -r1.34 -r1.35
--- module.mk.in 11 Jul 2005 20:22:39 -0000 1.34
+++ module.mk.in 11 Jul 2005 20:26:08 -0000 1.35
@@ -19,7 +19,8 @@ ADMINSRC := \
$(DIR)/pvfs2-fsck.c\
$(DIR)/pvfs2-cp.c \
$(DIR)/pvfs2-touch.c \
- $(DIR)/pvfs2-remove-object.c
+ $(DIR)/pvfs2-remove-object.c \
+ $(DIR)/pvfs2-ln.c
ADMINSRC_SERVER := \
$(DIR)/pvfs2-mkspace.c \
More information about the PVFS2-CVS
mailing list