summaryrefslogtreecommitdiffstats
path: root/source3/client
diff options
context:
space:
mode:
authorAurélien Aptel <aurelien.aptel@gmail.com>2013-07-05 18:14:50 +0200
committerAndreas Schneider <asn@samba.org>2014-02-19 18:22:26 +0100
commit342d38eb4b872c341cf25884f795ae38b04fca0f (patch)
tree5c627f8e725e226368f328b8ed77fa1b0c1a57a4 /source3/client
parentb9b5bc433d07376ae0bd96de3704162c67684734 (diff)
downloadsamba-342d38eb4b872c341cf25884f795ae38b04fca0f.tar.gz
samba-342d38eb4b872c341cf25884f795ae38b04fca0f.tar.xz
samba-342d38eb4b872c341cf25884f795ae38b04fca0f.zip
clitar.c: start of argument parsing
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/clitar.c209
1 files changed, 187 insertions, 22 deletions
diff --git a/source3/client/clitar.c b/source3/client/clitar.c
index 78a6e3ed7eb..0750e324aae 100644
--- a/source3/client/clitar.c
+++ b/source3/client/clitar.c
@@ -24,14 +24,24 @@
#include <archive.h>
#define LEN(x) (sizeof(x)/sizeof((x)[0]))
-
-/* XXX: used in client.c, we have to export it for now */
+#define TAR_MAX_BLOCK_SIZE 65535
+/*
+ * XXX: used in client.c, we have to export it for now.
+ * corresponds to the transfer operation. Can be '\0', 'c' or 'x'
+ */
char tar_type = 0;
-enum tar_type {
+enum tar_operation {
+ TAR_NO_OPERATION,
+ TAR_CREATE, /* c flag */
+ TAR_EXTRACT, /* x flag */
+};
+
+enum tar_selection {
+ TAR_NO_SELECTION,
TAR_INCLUDE, /* I flag, default */
- TAR_INCLUDE_FILE, /* F flag */
- TAR_EXLUDE, /* X flag */
+ TAR_INCLUDE_LIST, /* F flag */
+ TAR_EXCLUDE, /* X flag */
};
enum {
@@ -40,19 +50,17 @@ enum {
};
struct tar {
- /* include, include from file, exclude */
- enum tar_type type;
-
- /* size in bytes of a block in the tar file */
- int blocksize;
-
/* flags */
- struct {
+ struct tar_mode {
+ enum tar_operation operation; /* create, extract */
+ enum tar_selection selection; /* inc, inc from file, exclude */
+ int blocksize; /* size in bytes of a block in the tar file */
bool hidden; /* backup hidden file? */
bool system; /* backup system file? */
bool incremental; /* backup _only_ archived file? */
bool reset; /* unset archive bit? */
bool dry; /* don't write tar file? */
+ bool regex; /* XXX: never actually using regex... */
bool verbose;
} mode;
@@ -67,14 +75,39 @@ struct tar {
};
static struct tar tar_ctx = {
- .type = TAR_INCLUDE,
- .blocksize = 20,
+ .mode.selection = TAR_INCLUDE,
+ .mode.blocksize = 20,
.mode.hidden = True,
.mode.system = True,
.mode.incremental = False,
.mode.dry = False,
};
+static int tar_set_blocksize(struct tar *t, int size)
+{
+ if (size <= 0 || size > TAR_MAX_BLOCK_SIZE) {
+ return 0;
+ }
+
+ t->mode.blocksize = size;
+
+ return 1;
+}
+
+static bool tar_set_newer_than(struct tar *t, char *filename)
+{
+ extern time_t newer_than;
+ SMB_STRUCT_STAT stbuf;
+
+ if (sys_stat(filename, &stbuf, false) != 0) {
+ DEBUG(0, ("Error setting newer-than time\n"));
+ return 0;
+ }
+
+ newer_than = convert_timespec_to_time_t(stbuf.st_ex_mtime);
+ DEBUG(1, ("Getting files newer than %s\n", time_to_asc(newer_than)));
+ return 1;
+}
/**
* cmd_block - interactive command to change tar blocksize
@@ -87,7 +120,6 @@ int cmd_block(void)
/* XXX: from client.c */
const extern char *cmd_ptr;
char *buf;
- int size;
TALLOC_CTX *ctx = talloc_tos();
if (!next_token_talloc(ctx, &cmd_ptr, &buf, NULL)) {
@@ -95,14 +127,11 @@ int cmd_block(void)
return 1;
}
- size = atoi(buf);
- if (size < 0 || size > 65535) {
- DEBUG(0, ("blocksize out of range"));
- return 1;
+ if(!tar_set_blocksize(&tar_ctx, atoi(buf))) {
+ DEBUG(0, ("invalid blocksize\n"));
}
- tar_ctx.blocksize = size;
- DEBUG(2,("blocksize is now %d\n", size));
+ DEBUG(2, ("blocksize is now %d\n", tar_ctx.mode.blocksize));
return 0;
}
@@ -288,5 +317,141 @@ Parse tar arguments. Sets tar_type, tar_excl, etc.
int tar_parseargs(int argc, char *argv[], const char *Optarg, int Optind)
{
- return 0;
+ int newOptind = Optind;
+
+ /*
+ * 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;
+
+ while (*Optarg) {
+ switch(*Optarg++) {
+ /* operation */
+ case 'c':
+ if (tar_ctx.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;
+ break;
+ case 'x':
+ if (tar_ctx.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;
+ break;
+
+ /* selection */
+ case 'I':
+ if (tar_ctx.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;
+ break;
+ case 'X':
+ if (tar_ctx.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;
+ break;
+ case 'F':
+ if (tar_ctx.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;
+ break;
+
+ /* blocksize */
+ case 'b':
+ if (Optind >= argc) {
+ DEBUG(0, ("Option b must be followed by a blocksize\n"));
+ return 0;
+ }
+
+ if (!tar_set_blocksize(&tar_ctx, atoi(argv[Optind]))) {
+ DEBUG(0, ("Option b must be followed by a valid blocksize\n"));
+ return 0;
+ }
+
+ Optind++;
+ newOptind++;
+ break;
+
+ /* incremental mode */
+ case 'g':
+ tar_ctx.mode.incremental = True;
+ break;
+
+ /* newer than */
+ case 'N':
+ if (Optind >= argc) {
+ DEBUG(0, ("Option N must be followed by valid file name\n"));
+ return 0;
+ }
+
+ if (!tar_set_newer_than(&tar_ctx, argv[Optind])) {
+ DEBUG(0,("Error setting newer-than time\n"));
+ return 0;
+ }
+
+ newOptind++;
+ Optind++;
+ break;
+
+ /* reset mode */
+ case 'a':
+ tar_ctx.mode.reset = True;
+ break;
+
+ /* verbose */
+ case 'q':
+ tar_ctx.mode.verbose = True;
+ break;
+
+ /* regex match */
+ case 'r':
+ tar_ctx.mode.regex = True;
+ break;
+
+ /* dry run mode */
+ case 'n':
+ if (tar_ctx.mode.operation != TAR_CREATE) {
+ DEBUG(0, ("n is only meaningful when creating a tar-file\n"));
+ return 0;
+ }
+
+ tar_ctx.mode.dry = True;
+ DEBUG(0, ("dry_run set\n"));
+ break;
+
+ default:
+ DEBUG(0,("Unknown tar option\n"));
+ return 0;
+ }
+ }
+
+ /* default operation is include */
+ if (tar_ctx.mode.operation == TAR_NO_OPERATION) {
+ tar_ctx.mode.operation = TAR_INCLUDE;
+ }
+
+ if (tar_ctx.mode.selection == TAR_INCLUDE_LIST) {
+ if (argc - Optind - 1 != 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]);
+ }
+
+ return newOptind;
+
}