diff options
author | Aurélien Aptel <aurelien.aptel@gmail.com> | 2013-07-23 16:55:50 +0200 |
---|---|---|
committer | Andreas Schneider <asn@samba.org> | 2014-02-19 18:22:28 +0100 |
commit | 5cd72b39b35efc5129596ed258187def57f2f209 (patch) | |
tree | f536c5d1ab11c0f627a7ee383a7bda455c19af3b /source3/client | |
parent | 82dce8f7a8d340a39e08dcc12fb38b8ed254dc64 (diff) | |
download | samba-5cd72b39b35efc5129596ed258187def57f2f209.tar.gz samba-5cd72b39b35efc5129596ed258187def57f2f209.tar.xz samba-5cd72b39b35efc5129596ed258187def57f2f209.zip |
clitar.c: documentation
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.c | 192 |
1 files changed, 183 insertions, 9 deletions
diff --git a/source3/client/clitar.c b/source3/client/clitar.c index adb0ab4bfa..063a83b432 100644 --- a/source3/client/clitar.c +++ b/source3/client/clitar.c @@ -17,6 +17,55 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ +/** + * # General overview of the tar extension + * + * All tar_xxx() functions work on a `struct tar` which store most of + * the context of the backup process. + * + * The current tar context can be accessed via the global variable + * `tar_ctx`. It's not static but you should avoid accessing it + * directly. + * + * A tar context is first configured through tar_parse_args() which + * can be called from either the CLI (in client.c) or the interactive + * session (via the cmd_tar() callback). + * + * Once the configuration is done (successfully), the context is ready + * for processing and tar_to_process() returns true. + * + * The next step is to call tar_process() which dispatch the + * processing to either tar_create() or tar_extract(), depending on + * the context. + * + * ## Archive creation + * + * tar_create() creates an archive using the libarchive API then + * + * - iterates on the requested paths if the context is in inclusion + * mode with tar_create_from_list() + * + * - or iterates on the whole share (starting from the current dir) if + * in exclusion mode or if no specific path were requested + * + * The do_list() function from client.c is used to list recursively + * the share. In particular it takes a DOS path mask (eg. \mydir\*) + * and a callback function which will be called with each file name + * and attributes. The tar callback function is get_file_callback(). + * + * The callback function checks whether the file should be skipped + * according the the configuration via tar_create_skip_path(). If it's + * not skipped it's downloaded and written to the archive in + * tar_get_file(). + * + * ## Archive extraction + * + * tar_extract() opens the archive and iterates on each file in + * it. For each file tar_extract_skip_path() checks whether it should + * be skipped according to the config. If it's not skipped it's + * uploaded on the server in tar_send_file(). + */ + #include "includes.h" #include "system/filesys.h" #include "client/client_proto.h" @@ -77,15 +126,15 @@ struct tar { /* flags */ 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 */ + enum tar_selection selection; /* include, exclude */ + int blocksize; /* size in TAR_BLOCK_UNIT of a tar file block */ 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; + bool verbose; /* XXX: ignored */ } mode; /* nb of bytes received */ @@ -102,15 +151,29 @@ struct tar { struct archive *archive; }; +/** + * Global context imported in client.c when needed. + * + * Default options. + */ struct tar tar_ctx = { .mode.selection = TAR_INCLUDE, .mode.blocksize = TAR_DEFAULT_BLOCK_SIZE, .mode.hidden = true, .mode.system = true, .mode.incremental = false, + .mode.reset = false, .mode.dry = false, + .mode.regex = false, + .mode.verbose = false, }; + +/** + * fix_unix_path - convert @path to a DOS path + * @path: path to convert + * @removeprefix: if true, remove leading ./ or /. + */ static char *fix_unix_path (char *path, bool removeprefix) { char *from = path, *to = path; @@ -148,6 +211,11 @@ static char *fix_unix_path (char *path, bool removeprefix) return path; } +/** + * path_base_name - return @path basename + * + * If @path doesn't contain any directory separator return NULL. + */ static char *path_base_name (const char *path) { TALLOC_CTX *ctx = talloc_tos(); @@ -175,6 +243,10 @@ static char *path_base_name (const char *path) #define XSTR(v) DBG(2, ("DUMP:%-20.20s = %s\n", #v, v ? v : "NULL")) #define XINT(v) DBG(2, ("DUMP:%-20.20s = %d\n", #v, v)) #define XUINT64(v) DBG(2, ("DUMP:%-20.20s = %" PRIu64 "\n", #v, v)) + +/** + * tar_dump - dump tar structure on stdout + */ static void tar_dump(struct tar *t) { int i; @@ -216,6 +288,10 @@ static void tar_dump(struct tar *t) #undef XSTR #undef XINT +/** + * tar_add_selection_path - add a path to the path list + * @path: path to add + */ static void tar_add_selection_path(struct tar *t, const char *path) { TALLOC_CTX *ctx = talloc_tos(); @@ -229,6 +305,9 @@ static void tar_add_selection_path(struct tar *t, const char *path) fix_unix_path(t->path_list[t->path_list_size - 1], true); } +/** + * tar_set_blocksize - set block size in TAR_BLOCK_UNIT + */ static int tar_set_blocksize(struct tar *t, int size) { if (size <= 0 || size > TAR_MAX_BLOCK_SIZE) { @@ -240,6 +319,17 @@ static int tar_set_blocksize(struct tar *t, int size) return 0; } +/** + * tar_set_newer_than - set date threshold of saved files + * @filename: local path to a file + * + * Only files newer than the modification time of @filename will be + * saved. + * + * Note: this function set the global variable newer_than from + * client.c. Thus the time is not a field of the tar structure. See + * cmd_newer() to change its value from an interactive session. + */ static int tar_set_newer_than(struct tar *t, const char *filename) { extern time_t newer_than; @@ -255,6 +345,12 @@ static int tar_set_newer_than(struct tar *t, const char *filename) return 0; } +/** + * tar_read_inclusion_file - set path list from file + * @filename: path to the list file + * + * Read and add each line of @filename to the path list. + */ static int tar_read_inclusion_file (struct tar *t, const char* filename) { char *line; @@ -274,7 +370,11 @@ static int tar_read_inclusion_file (struct tar *t, const char* filename) return 0; } -/* skip leading slashes or dots */ +/** + * skip_useless_char_in_path - skip leading slashes/dots + * + * Skip leading slashes, backslashes and dot-slashes. + */ static const char* skip_useless_char_in_path(const char *p) { while (p) { @@ -290,11 +390,14 @@ static const char* skip_useless_char_in_path(const char *p) return p; } - /** - * return true if the path @sub is a subpath of @full. + * is_subpath - return true if the path @sub is a subpath of @full. + * @sub: path to test + * @full: container path * - * case-insensitive, true if @sub = @full + * String comparaison is case-insensitive. + * + * Return true if @sub = @full */ static bool is_subpath(const char *sub, const char *full) { @@ -323,6 +426,17 @@ static bool is_subpath(const char *sub, const char *full) return *full == *sub; } +/** + * tar_path_in_list - return true if @path is in the path list + * @path: path to find + * @reverse: when true also try to find path list element in @path + * + * Look at each path of the path list and return true if @path is a + * subpath of one of them. + * + * If you want /path to be in the path list (path/a/, path/b/) set + * @reverse to true to try to match the other way around. + */ static bool tar_path_in_list(struct tar *t, const char *path, bool reverse) { int i; @@ -349,6 +463,12 @@ static bool tar_path_in_list(struct tar *t, const char *path, bool reverse) return false; } +/** + * tar_extract_skip_path - return true if @entry should be skipped + * @entry: current tar entry + * + * Skip predicate for tar extraction (archive to server) only. + */ static bool tar_extract_skip_path(struct tar *t, struct archive_entry *entry) { @@ -373,6 +493,13 @@ static bool tar_extract_skip_path(struct tar *t, return in ? !skip : skip; } +/** + * tar_create_skip_path - return true if @fullpath shoud be skipped + * @fullpath: full remote path of the current file + * @finfo: remote file attributes + * + * Skip predicate for tar creation (server to archive) only. + */ static bool tar_create_skip_path(struct tar *t, const char *fullpath, const struct file_info *finfo) @@ -428,6 +555,11 @@ static bool tar_create_skip_path(struct tar *t, return in ? skip : !skip; } +/** + * tar_to_process - return true if @t is ready to be processed + * + * @t is ready if it properly parsed command line arguments. + */ bool tar_to_process (struct tar *t) { return t->to_process; @@ -622,6 +754,12 @@ int cmd_setmode(void) return 0; } +/** + * make_remote_path - recursively make remote dirs + * @full_path: full hierarchy to create + * + * Create @full_path and each parent directories as needed. + */ static int make_remote_path(const char *full_path) { extern struct cli_state *cli; @@ -672,6 +810,13 @@ static int make_remote_path(const char *full_path) return err; } +/** + * tar_send_file - send @entry to the remote server + * @entry: current archive entry + * + * Handle the creation of the parent directories and transfer the + * entry to a new remote file. + */ static int tar_send_file(struct tar *t, struct archive_entry *entry) { extern struct cli_state *cli; @@ -752,6 +897,11 @@ static int tar_send_file(struct tar *t, struct archive_entry *entry) return err; } +/** + * tar_get_file - fetch a remote file to the local archive + * @full_dos_path: path to the file to fetch + * @finfo: attributes of the file to fetch + */ static int tar_get_file(struct tar *t, const char *full_dos_path, struct file_info *finfo) { @@ -855,6 +1005,13 @@ static int tar_get_file(struct tar *t, const char *full_dos_path, return err; } +/** + * get_file_callback - do_list callback + * + * Callback for client.c do_list(). Called for each file found on the + * share matching do_list mask. Recursively call do_list() with itself + * as callback when the current file is a directory. + */ static NTSTATUS get_file_callback(struct cli_state *cli, struct file_info *finfo, const char *dir) @@ -905,6 +1062,9 @@ static NTSTATUS get_file_callback(struct cli_state *cli, return err; } +/** + * tar_create_from_list - fetch from path list in include mode + */ static int tar_create_from_list(struct tar *t) { TALLOC_CTX *ctx = talloc_tos(); @@ -944,6 +1104,9 @@ static int tar_create_from_list(struct tar *t) return err; } +/** + * tar_create - create archive and fetch files + */ static int tar_create(struct tar* t) { TALLOC_CTX *ctx = talloc_tos(); @@ -963,6 +1126,11 @@ static int tar_create(struct tar* t) goto out; } + /* + * Use PAX restricted format which is not the most + * conservative choice but has useful extensions and is widely + * supported + */ r = archive_write_set_format_pax_restricted(t->archive); if (r != ARCHIVE_OK) { DBG(0, ("Can't use pax restricted format: %s\n", @@ -1021,7 +1189,7 @@ static int tar_create(struct tar* t) } /** - * Return upper limit for the number of token in @str. + * max_token - return upper limit for the number of token in @str * * The result is not exact, the actual number of token might be less * than what is returned. @@ -1091,6 +1259,9 @@ int cmd_tar(void) return err; } +/** + * tar_extract - open archive and send files. + */ static int tar_extract(struct tar *t) { int err = 0; @@ -1152,6 +1323,9 @@ static int tar_extract(struct tar *t) return err; } +/** + * tar_process - start processing archive + */ int tar_process(struct tar *t) { int rc = 0; @@ -1187,7 +1361,7 @@ int tar_process(struct tar *t) * in the interactive session: * tar f1f2f3 v1 v2 v3 TARFILE PATHS... * - * opt has only flags (eg. "f1f2f3") and val has the arguments + * @flag has only flags (eg. "f1f2f3") and @val has the arguments * (values) following them (eg. ["v1", "v2", "v3", "TARFILE", "PATH1", * "PATH2"]). * |