feat(p6-iconv): --iconv charset conversion + PROTOCOL 2.16.0
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
#include "receiver.h"
|
||||
|
||||
#include "charset.h"
|
||||
#include "chunk.h"
|
||||
#include "config.h"
|
||||
#include "delay_updates.h"
|
||||
@@ -79,7 +80,7 @@ static bool receiver_process_batch(Config* config, int file_descriptor) {
|
||||
count > MAX_MANIFEST_ENTRIES)
|
||||
return false;
|
||||
for (int i = 0; i < count; i++) {
|
||||
char* check_path = receive_str(file_descriptor);
|
||||
char* check_path = receive_wire_str(file_descriptor);
|
||||
if (!check_path)
|
||||
return false;
|
||||
unsigned long long check_size;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "config.h"
|
||||
#include "charset.h"
|
||||
#include "credentials.h"
|
||||
#include "daemon_conf.h"
|
||||
#include "delay_updates.h"
|
||||
@@ -31,6 +32,10 @@ static bool allow_delete;
|
||||
static bool trust_sender;
|
||||
static bool allow_unauthenticated;
|
||||
static const char* required_client_cn;
|
||||
/* --iconv CONVERT_SPEC the server was itself started with (borrowed argv
|
||||
* pointer). Its LOCAL half may override the local charset the client assumed;
|
||||
* see charset_wire_init_receiver. */
|
||||
static const char* server_iconv_spec;
|
||||
|
||||
/* Non-NULL exactly when the listener runs in --daemon mode. Loaded once in
|
||||
* main before any accept-loop fork, then shared read-only by every forked
|
||||
@@ -318,6 +323,20 @@ void handler(int file_descriptor) {
|
||||
return;
|
||||
}
|
||||
config->use_delete = config->use_delete && allow_delete;
|
||||
/* --iconv (protocol 2.16.0): install the receiver-side wire->local conversion
|
||||
now that the client's full CONVERT_SPEC has been received and validated,
|
||||
before any received file name is decoded. The server's own --iconv (if
|
||||
any) may override the local charset; a spec the client is known to have
|
||||
validated cannot fail here unless the server's override names an
|
||||
unsupported charset. */
|
||||
if (config->iconv_spec && !charset_wire_init_receiver(config->iconv_spec, server_iconv_spec)) {
|
||||
log_message(LOG_LEVEL_ERROR,
|
||||
"--iconv: unsupported charset conversion requested (LOCAL[,REMOTE])");
|
||||
config_delete(config);
|
||||
close(file_descriptor);
|
||||
protocol_session_unbind();
|
||||
return;
|
||||
}
|
||||
/* --delete-missing-args deletes destination mirrors receiver-side, so it is
|
||||
deletion and stays gated by the same --allow-delete server policy. When
|
||||
the server policy is off the flag is inert (the missing entries are still
|
||||
@@ -485,6 +504,7 @@ void handler(int file_descriptor) {
|
||||
}
|
||||
protocol_session_unbind();
|
||||
identity_clear_active();
|
||||
charset_wire_free();
|
||||
close(file_descriptor);
|
||||
}
|
||||
|
||||
@@ -535,6 +555,11 @@ static void print_server_usage(void) {
|
||||
printf(" -6, --ipv6 Bind an IPv6 socket\n");
|
||||
printf(" --allow-delete Permit manifest deletion\n");
|
||||
printf(" --trust-sender Trust the remote sender's file list\n");
|
||||
printf(" --iconv=LOCAL[,REMOTE] Declare this server's LOCAL charset for file-name\n");
|
||||
printf(" conversion: received names are translated to this\n");
|
||||
printf(" charset (the wire charset still comes from the\n");
|
||||
printf(" client's CONVERT_SPEC). A name that cannot be\n");
|
||||
printf(" represented fails the run cleanly\n");
|
||||
printf(" --allow-unauthenticated Allow plaintext/anonymous network clients\n");
|
||||
printf(" -v, --verbose Enable debug logging\n");
|
||||
printf(" --help Show this help\n");
|
||||
@@ -621,6 +646,7 @@ int main(int argc, char* argv[]) {
|
||||
allow_delete = opts.allow_delete;
|
||||
trust_sender = opts.trust_sender;
|
||||
allow_unauthenticated = opts.allow_unauthenticated;
|
||||
server_iconv_spec = opts.iconv_spec;
|
||||
signal(SIGINT, cleanup);
|
||||
signal(SIGTERM, cleanup);
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "server_cli.h"
|
||||
#include "charset.h"
|
||||
#include "utils.h"
|
||||
#include <limits.h>
|
||||
#include <stdarg.h>
|
||||
@@ -143,6 +144,12 @@ int server_cli_parse(int argc, char* argv[], ServerCliOptions* opts, char* err,
|
||||
opts->trust_sender = true;
|
||||
} else if (arg_is(argv[i], "--allow-unauthenticated")) {
|
||||
opts->allow_unauthenticated = true;
|
||||
} else if (arg_is(argv[i], "--iconv")) {
|
||||
if (i + 1 >= argc) {
|
||||
set_error(err, err_size, "missing argument for --iconv");
|
||||
return -1;
|
||||
}
|
||||
opts->iconv_spec = argv[++i];
|
||||
} else if (arg_is(argv[i], "-p")) {
|
||||
if (i + 1 >= argc) {
|
||||
set_error(err, err_size, "missing argument for -p");
|
||||
@@ -180,6 +187,15 @@ int server_cli_parse(int argc, char* argv[], ServerCliOptions* opts, char* err,
|
||||
inline_value = argv[++i];
|
||||
}
|
||||
opts->early_input_file = inline_value;
|
||||
} else if (arg_has_value(argv[i], "--iconv", &inline_value)) {
|
||||
if (!inline_value) {
|
||||
if (i + 1 >= argc) {
|
||||
set_error(err, err_size, "missing argument for --iconv");
|
||||
return -1;
|
||||
}
|
||||
inline_value = argv[++i];
|
||||
}
|
||||
opts->iconv_spec = inline_value;
|
||||
} else if (arg_has_value(argv[i], "--dparam", &inline_value)) {
|
||||
if (!inline_value) {
|
||||
if (i + 1 >= argc) {
|
||||
@@ -227,6 +243,12 @@ int server_cli_parse(int argc, char* argv[], ServerCliOptions* opts, char* err,
|
||||
"--daemon");
|
||||
return -1;
|
||||
}
|
||||
/* --iconv: reject a malformed CONVERT_SPEC or an unsupported charset name at
|
||||
startup (a probe iconv_open is attempted). */
|
||||
if (opts->iconv_spec != NULL && !charset_spec_valid(opts->iconv_spec)) {
|
||||
set_error(err, err_size, "--iconv requires LOCAL[,REMOTE] charset names supported by iconv");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,12 @@ typedef struct ServerCliOptions {
|
||||
bool allow_delete; /* --allow-delete */
|
||||
bool trust_sender; /* --trust-sender */
|
||||
bool allow_unauthenticated; /* --allow-unauthenticated */
|
||||
/* --iconv=CONVERT_SPEC: the server's own LOCAL charset declaration. The
|
||||
* client's full spec rides the wire config frame anyway; when the server is
|
||||
* started with its own --iconv, its LOCAL half overrides the local charset
|
||||
* the client assumed so the server converts received names to ITS charset.
|
||||
* Borrowed pointer into argv (never owns heap). */
|
||||
const char* iconv_spec; /* --iconv value, or NULL */
|
||||
} ServerCliOptions;
|
||||
|
||||
/* Parse argc/argv into *opts. Zero-initialize *opts before calling (or use
|
||||
|
||||
Reference in New Issue
Block a user