summaryrefslogtreecommitdiffstats
path: root/source3/client
diff options
context:
space:
mode:
authorAurélien Aptel <aurelien.aptel@gmail.com>2013-07-08 18:09:47 +0200
committerAndreas Schneider <asn@samba.org>2014-02-19 18:22:26 +0100
commit45a45c8edac20469e5b9e7b30a55e3a591b62f79 (patch)
treeae8a31183f5d267e9552690dfb768b3b8499b397 /source3/client
parenteebd378b6cbc4b19c35b670cd5e493ef575c19cb (diff)
downloadsamba-45a45c8edac20469e5b9e7b30a55e3a591b62f79.tar.gz
samba-45a45c8edac20469e5b9e7b30a55e3a591b62f79.tar.xz
samba-45a45c8edac20469e5b9e7b30a55e3a591b62f79.zip
implement argument parsing, split client_proto.h
Signed-off-by: Aurélien Aptel <aurelien.aptel@gmail.com> Reviewed-by: David Disseldorp <ddiss@samba.org> Reviewed-by: Andreas Schneider <asn@samba.org>
Diffstat (limited to 'source3/client')
-rw-r--r--source3/client/client.c5
-rw-r--r--source3/client/client_proto.h9
-rw-r--r--source3/client/clitar.c175
-rw-r--r--source3/client/clitar_proto.h32
4 files changed, 160 insertions, 61 deletions
diff --git a/source3/client/client.c b/source3/client/client.c
index e039a470cb6..4fc285f08cf 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -26,6 +26,7 @@
#include "popt_common.h"
#include "rpc_client/cli_pipe.h"
#include "client/client_proto.h"
+#include "client/clitar_proto.h"
#include "../librpc/gen_ndr/ndr_srvsvc_c.h"
#include "../lib/util/select.h"
#include "system/readline.h"
@@ -5513,12 +5514,14 @@ static int do_message_op(struct user_auth_info *a_info)
* position of the -T option in the raw argv[]. */
{
int i;
+ extern struct tar tar_ctx;
+
for (i = 1; i < argc; i++) {
if (strncmp("-T", argv[i],2)==0)
break;
}
i++;
- if (!tar_parseargs(argc, argv, poptGetOptArg(pc), i)) {
+ if (!tar_parse_args(&tar_ctx, poptGetOptArg(pc), argv + i, argc - i)) {
poptPrintUsage(pc, stderr, 0);
exit(1);
}
diff --git a/source3/client/client_proto.h b/source3/client/client_proto.h
index d119014abdc..3e91ff0fb35 100644
--- a/source3/client/client_proto.h
+++ b/source3/client/client_proto.h
@@ -38,15 +38,6 @@ NTSTATUS do_list(const char *mask,
bool dirs);
int cmd_iosize(void);
-/* The following definitions come from client/clitar.c */
-
-int cmd_block(void);
-int cmd_tarmode(void);
-int cmd_setmode(void);
-int cmd_tar(void);
-int process_tar(void);
-int tar_parseargs(int argc, char *argv[], const char *Optarg, int Optind);
-
/* The following definitions come from client/dnsbrowse.c */
int do_smb_browse(void);
diff --git a/source3/client/clitar.c b/source3/client/clitar.c
index 0750e324aae..c2a80d2ed92 100644
--- a/source3/client/clitar.c
+++ b/source3/client/clitar.c
@@ -20,6 +20,7 @@
#include "includes.h"
#include "system/filesys.h"
#include "client/client_proto.h"
+#include "client/clitar_proto.h"
#include "libsmb/libsmb.h"
#include <archive.h>
@@ -67,14 +68,17 @@ struct tar {
/* path to tar archive name */
char *tar_path;
- /* path to file list (F flag) */
- char *list_path;
+ /* file descriptor of tar file */
+ int tar_fd;
+
+ /* list of path to include or exclude */
+ char **path_list;
/* archive handle */
struct archive *archive;
};
-static struct tar tar_ctx = {
+struct tar tar_ctx = {
.mode.selection = TAR_INCLUDE,
.mode.blocksize = 20,
.mode.hidden = True,
@@ -109,6 +113,29 @@ static bool tar_set_newer_than(struct tar *t, char *filename)
return 1;
}
+static bool tar_read_inclusion_file (struct tar *t, const char* filename)
+{
+ char *line;
+ const char **list;
+ TALLOC_CTX *ctx = talloc_tos();
+ int fd = open(filename, O_RDONLY);
+
+ if (fd < 0) {
+ DEBUG(0, ("Can't open inclusion file '%s': %s\n", filename, strerror(errno)));
+ return 0;
+ }
+
+ list = str_list_make_empty(ctx);
+
+ while ((line = afdgets(fd, ctx, 0))) {
+ list = str_list_add(list, line);
+ }
+
+ close(fd);
+ t->path_list = list;
+ return 1;
+}
+
/**
* cmd_block - interactive command to change tar blocksize
*
@@ -293,10 +320,11 @@ int cmd_setmode(void)
}
-/****************************************************************************
-Principal command for creating / extracting
-***************************************************************************/
-
+/**
+ * cmd_tar - interactive command to start a tar backup/restoration
+ *
+ * Check presence of argument, parse them and handle the request.
+ */
int cmd_tar(void)
{
return 0;
@@ -311,123 +339,146 @@ int process_tar(void)
return 0;
}
-/****************************************************************************
-Parse tar arguments. Sets tar_type, tar_excl, etc.
-***************************************************************************/
-
-int tar_parseargs(int argc, char *argv[], const char *Optarg, int Optind)
+/**
+ * tar_parse_args - parse and set tar command line arguments
+ * @flag: string pointing to tar options
+ * @val: number of tar arguments
+ * @valsize: table of arguments after the flags (number of element in val)
+ *
+ * tar arguments work in a weird way. For each flag f that takes a
+ * value v, the user is supposed to type:
+ *
+ * on the CLI:
+ * -Tf1f2f3 v1 v2 v3 TARFILE PATHS...
+ *
+ * in the interactive session:
+ * tar f1f2f3 v1 v2 v3 TARFILE PATHS...
+ *
+ * opt has only flags (eg. "f1f2f3") and val has the arguments
+ * (values) following them (eg. ["v1", "v2", "v3", "TARFILE", "PATH1",
+ * "PATH2"]).
+ *
+ * There are only 2 flags that take an arg: b and N. The other flags
+ * just change the semantic of PATH or TARFILE.
+ *
+ * PATH can be a list of included/excluded paths, the path to a file
+ * containing a list of included/excluded paths to use (F flag). If no
+ * PATH is provided, the whole share is used (/).
+ */
+int tar_parse_args(struct tar* t, const char *flag, const char **val, int valsize)
{
- int newOptind = Optind;
+ TALLOC_CTX *ctx = talloc_tos();
+
+ /* index of next value to use */
+ int ival = 0;
/*
* Reset back some options - could be from interactive version
* all other modes are left as they are
*/
- tar_ctx.mode.operation = TAR_NO_OPERATION;
- tar_ctx.mode.selection = TAR_NO_SELECTION;
- tar_ctx.mode.dry = False;
+ t->mode.operation = TAR_NO_OPERATION;
+ t->mode.selection = TAR_NO_SELECTION;
+ t->mode.dry = False;
- while (*Optarg) {
- switch(*Optarg++) {
+ while (*flag) {
+ switch(*flag++) {
/* operation */
case 'c':
- if (tar_ctx.mode.operation != TAR_NO_OPERATION) {
+ if (t->mode.operation != TAR_NO_OPERATION) {
printf("Tar must be followed by only one of c or x.\n");
return 0;
}
- tar_ctx.mode.operation = TAR_CREATE;
+ t->mode.operation = TAR_CREATE;
break;
case 'x':
- if (tar_ctx.mode.operation != TAR_NO_OPERATION) {
+ if (t->mode.operation != TAR_NO_OPERATION) {
printf("Tar must be followed by only one of c or x.\n");
return 0;
}
- tar_ctx.mode.operation = TAR_CREATE;
+ t->mode.operation = TAR_CREATE;
break;
/* selection */
case 'I':
- if (tar_ctx.mode.selection != TAR_NO_SELECTION) {
+ if (t->mode.selection != TAR_NO_SELECTION) {
DEBUG(0,("Only one of I,X,F must be specified\n"));
return 0;
}
- tar_ctx.mode.selection = TAR_INCLUDE;
+ t->mode.selection = TAR_INCLUDE;
break;
case 'X':
- if (tar_ctx.mode.selection != TAR_NO_SELECTION) {
+ if (t->mode.selection != TAR_NO_SELECTION) {
DEBUG(0,("Only one of I,X,F must be specified\n"));
return 0;
}
- tar_ctx.mode.selection = TAR_EXCLUDE;
+ t->mode.selection = TAR_EXCLUDE;
break;
case 'F':
- if (tar_ctx.mode.selection != TAR_NO_SELECTION) {
+ if (t->mode.selection != TAR_NO_SELECTION) {
DEBUG(0,("Only one of I,X,F must be specified\n"));
return 0;
}
- tar_ctx.mode.selection = TAR_INCLUDE_LIST;
+ t->mode.selection = TAR_INCLUDE_LIST;
break;
/* blocksize */
case 'b':
- if (Optind >= argc) {
+ if (ival >= valsize) {
DEBUG(0, ("Option b must be followed by a blocksize\n"));
return 0;
}
- if (!tar_set_blocksize(&tar_ctx, atoi(argv[Optind]))) {
+ if (!tar_set_blocksize(t, atoi(val[ival]))) {
DEBUG(0, ("Option b must be followed by a valid blocksize\n"));
return 0;
}
- Optind++;
- newOptind++;
+ ival++;
break;
/* incremental mode */
case 'g':
- tar_ctx.mode.incremental = True;
+ t->mode.incremental = True;
break;
/* newer than */
case 'N':
- if (Optind >= argc) {
+ if (ival >= valsize) {
DEBUG(0, ("Option N must be followed by valid file name\n"));
return 0;
}
- if (!tar_set_newer_than(&tar_ctx, argv[Optind])) {
+ if (!tar_set_newer_than(t, val[ival])) {
DEBUG(0,("Error setting newer-than time\n"));
return 0;
}
- newOptind++;
- Optind++;
+ ival++;
break;
/* reset mode */
case 'a':
- tar_ctx.mode.reset = True;
+ t->mode.reset = True;
break;
/* verbose */
case 'q':
- tar_ctx.mode.verbose = True;
+ t->mode.verbose = True;
break;
/* regex match */
case 'r':
- tar_ctx.mode.regex = True;
+ t->mode.regex = True;
break;
/* dry run mode */
case 'n':
- if (tar_ctx.mode.operation != TAR_CREATE) {
+ if (t->mode.operation != TAR_CREATE) {
DEBUG(0, ("n is only meaningful when creating a tar-file\n"));
return 0;
}
- tar_ctx.mode.dry = True;
+ t->mode.dry = True;
DEBUG(0, ("dry_run set\n"));
break;
@@ -437,21 +488,43 @@ int tar_parseargs(int argc, char *argv[], const char *Optarg, int Optind)
}
}
- /* default operation is include */
- if (tar_ctx.mode.operation == TAR_NO_OPERATION) {
- tar_ctx.mode.operation = TAR_INCLUDE;
+ /* no operation given? default operation is include */
+ if (t->mode.operation == TAR_NO_OPERATION) {
+ t->mode.operation = TAR_INCLUDE;
}
- if (tar_ctx.mode.selection == TAR_INCLUDE_LIST) {
- if (argc - Optind - 1 != 1) {
+ if (valsize - ival < 1) {
+ DEBUG(0, ("No tar file given.\n"));
+ return 0;
+ }
+
+ /* handle TARFILE */
+ t->tar_path = talloc_strdup(ctx, val[ival]);
+ ival++;
+
+ /* handle PATHs... */
+ tar_ctx.path_list = str_list_make_empty(ctx);
+
+ /* flag F -> read file list */
+ if (t->mode.selection == TAR_INCLUDE_LIST) {
+ if (valsize - ival != 1) {
DEBUG(0,("Option F must be followed by exactly one filename.\n"));
return 0;
}
- newOptind++;
- /* Optind points at the tar output file, Optind+1 at the inclusion file. */
- printf("tar: %s list: %s\n", argv[Optind], argv[Optind+1]);
+
+ if(!tar_read_inclusion_file(t, val[ival])) {
+ return 0;
+ }
+ ival++;
}
- return newOptind;
+ /* otherwise store all the PATHs on the command line */
+ else {
+ int i;
+ for (i = ival; i < valsize; i++) {
+ t->path_list = str_list_add(t->path_list, val[i]);
+ }
+ }
+ return 1;
}
diff --git a/source3/client/clitar_proto.h b/source3/client/clitar_proto.h
new file mode 100644
index 00000000000..e66c9f9ad89
--- /dev/null
+++ b/source3/client/clitar_proto.h
@@ -0,0 +1,32 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Tar backup command extension
+ * Copyright (C) Aurélien Aptel 2013
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _CLITAR_PROTO_H_
+#define _CLITAR_PROTO_H_
+
+struct tar;
+
+int cmd_block(void);
+int cmd_tarmode(void);
+int cmd_setmode(void);
+int cmd_tar(void);
+int process_tar(void);
+int tar_parse_args(struct tar *tar, const char *flag, const char **val, int valsize);
+
+#endif /* _CLITAR_PROTO_H_ */