Fix: Remove compiler warnings (signedness, unused functions, snprintf truncation)
- Cast st_size to uint64_t to match file_size type in server.c - Remove unused functions: send_one_file, send_file_udp, verify_and_resend - Reduce rel buffer size to 1024 to prevent snprintf truncation in collect_files Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
Binary file not shown.
+1
-148
@@ -71,153 +71,6 @@ typedef struct {
|
|||||||
static atomic_uint_fast64_t g_bytes_sent = 0;
|
static atomic_uint_fast64_t g_bytes_sent = 0;
|
||||||
static atomic_uint_fast32_t g_files_sent = 0;
|
static atomic_uint_fast32_t g_files_sent = 0;
|
||||||
|
|
||||||
// ─── UDP helpers ──────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
static int verify_and_resend(sync_ctx_t *ctx, int file_fd,
|
|
||||||
uint32_t file_id, uint64_t file_size) {
|
|
||||||
uint32_t total_blocks = (file_size + UDP_PAYLOAD_MAX - 1) / UDP_PAYLOAD_MAX;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
uint32_t req = MAGIC_VERIFY;
|
|
||||||
if (writen(ctx->tcp_fd, &req, sizeof(req)) != sizeof(req)) return -1;
|
|
||||||
if (writen(ctx->tcp_fd, &file_id, sizeof(file_id)) != sizeof(file_id)) return -1;
|
|
||||||
|
|
||||||
uint32_t missing = 0;
|
|
||||||
if (readn(ctx->tcp_fd, &missing, sizeof(missing)) != sizeof(missing)) return -1;
|
|
||||||
if (missing == 0) break;
|
|
||||||
|
|
||||||
uint32_t *ids = malloc(missing * sizeof(uint32_t));
|
|
||||||
if (!ids) { perror("malloc"); return -1; }
|
|
||||||
if (readn(ctx->tcp_fd, ids, missing * sizeof(uint32_t))
|
|
||||||
!= (ssize_t)(missing * sizeof(uint32_t))) { free(ids); return -1; }
|
|
||||||
|
|
||||||
printf("[thread] Resending %u missing blocks...\n", missing);
|
|
||||||
for (uint32_t i = 0; i < missing; i++) {
|
|
||||||
uint32_t bid = ids[i];
|
|
||||||
if (bid >= total_blocks) continue;
|
|
||||||
uint64_t off = (uint64_t)bid * UDP_PAYLOAD_MAX;
|
|
||||||
if (lseek(file_fd, off, SEEK_SET) == (off_t)-1) { perror("lseek"); continue; }
|
|
||||||
|
|
||||||
char payload[UDP_PAYLOAD_MAX];
|
|
||||||
ssize_t nr = read(file_fd, payload, UDP_PAYLOAD_MAX);
|
|
||||||
if (nr <= 0) continue;
|
|
||||||
|
|
||||||
udp_packet_header_t hdr;
|
|
||||||
hdr.magic = MAGIC_UDP_DATA;
|
|
||||||
hdr.session_id = ctx->udp_session_id;
|
|
||||||
hdr.file_id = file_id;
|
|
||||||
hdr.block_id = bid;
|
|
||||||
hdr.block_offset = off;
|
|
||||||
hdr.payload_len = nr;
|
|
||||||
|
|
||||||
char pkt[sizeof(hdr) + UDP_PAYLOAD_MAX];
|
|
||||||
memcpy(pkt, &hdr, sizeof(hdr));
|
|
||||||
memcpy(pkt + sizeof(hdr), payload, nr);
|
|
||||||
sendto(ctx->udp_fd, pkt, sizeof(hdr) + nr, 0,
|
|
||||||
(struct sockaddr *)&ctx->udp_server_addr,
|
|
||||||
sizeof(ctx->udp_server_addr));
|
|
||||||
}
|
|
||||||
free(ids);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int send_file_udp(sync_ctx_t *ctx, const char *full_path,
|
|
||||||
uint32_t file_id, uint64_t file_size) {
|
|
||||||
int fd = open(full_path, O_RDONLY);
|
|
||||||
if (fd < 0) { perror("open"); return -1; }
|
|
||||||
|
|
||||||
uint32_t total = (file_size + UDP_PAYLOAD_MAX - 1) / UDP_PAYLOAD_MAX;
|
|
||||||
printf("[thread] UDP send: %s (%u blocks)\n", full_path, total);
|
|
||||||
|
|
||||||
for (uint32_t bid = 0; bid < total; bid++) {
|
|
||||||
char payload[UDP_PAYLOAD_MAX];
|
|
||||||
ssize_t nr = read(fd, payload, UDP_PAYLOAD_MAX);
|
|
||||||
if (nr <= 0) break;
|
|
||||||
|
|
||||||
udp_packet_header_t hdr;
|
|
||||||
hdr.magic = MAGIC_UDP_DATA;
|
|
||||||
hdr.session_id = ctx->udp_session_id;
|
|
||||||
hdr.file_id = file_id;
|
|
||||||
hdr.block_id = bid;
|
|
||||||
hdr.block_offset = (uint64_t)bid * UDP_PAYLOAD_MAX;
|
|
||||||
hdr.payload_len = nr;
|
|
||||||
|
|
||||||
char pkt[sizeof(hdr) + UDP_PAYLOAD_MAX];
|
|
||||||
memcpy(pkt, &hdr, sizeof(hdr));
|
|
||||||
memcpy(pkt + sizeof(hdr), payload, nr);
|
|
||||||
sendto(ctx->udp_fd, pkt, sizeof(hdr) + nr, 0,
|
|
||||||
(struct sockaddr *)&ctx->udp_server_addr,
|
|
||||||
sizeof(ctx->udp_server_addr));
|
|
||||||
}
|
|
||||||
|
|
||||||
int ret = verify_and_resend(ctx, fd, file_id, file_size);
|
|
||||||
close(fd);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ─── Send a single file over one connection (TCP or UDP data) ─────────────
|
|
||||||
|
|
||||||
static int send_one_file(sync_ctx_t *ctx, const char *full_path,
|
|
||||||
const char *rel_path) {
|
|
||||||
struct stat st;
|
|
||||||
if (stat(full_path, &st) < 0) { perror("stat"); return -1; }
|
|
||||||
|
|
||||||
file_meta_t meta;
|
|
||||||
meta.magic = MAGIC_META;
|
|
||||||
meta.name_len = strlen(rel_path);
|
|
||||||
meta.file_size = st.st_size;
|
|
||||||
meta.mode = st.st_mode;
|
|
||||||
|
|
||||||
if (writen(ctx->tcp_fd, &meta, sizeof(meta)) != sizeof(meta)) return -1;
|
|
||||||
if (writen(ctx->tcp_fd, rel_path, meta.name_len) != (ssize_t)meta.name_len) return -1;
|
|
||||||
|
|
||||||
file_response_t resp;
|
|
||||||
if (readn(ctx->tcp_fd, &resp, sizeof(resp)) != sizeof(resp)) return -1;
|
|
||||||
|
|
||||||
if (resp.response == RESP_SKIP) {
|
|
||||||
printf("[thread] Skip: %s\n", rel_path);
|
|
||||||
return 0;
|
|
||||||
} else if (resp.response == RESP_USE_UDP) {
|
|
||||||
if (send_file_udp(ctx, full_path, resp.file_id, meta.file_size) < 0)
|
|
||||||
return -1;
|
|
||||||
uint32_t ack = 0;
|
|
||||||
if (readn(ctx->tcp_fd, &ack, sizeof(ack)) != sizeof(ack)
|
|
||||||
|| ack != RESP_OK) {
|
|
||||||
fprintf(stderr, "[thread] UDP finalize failed: %s\n", rel_path);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
} else if (resp.response == RESP_SEND_DATA) {
|
|
||||||
int fd = open(full_path, O_RDONLY);
|
|
||||||
if (fd < 0) { perror("open"); return -1; }
|
|
||||||
off_t off = 0;
|
|
||||||
while (off < (off_t)meta.file_size) {
|
|
||||||
ssize_t r = sendfile(ctx->tcp_fd, fd, &off, meta.file_size - off);
|
|
||||||
if (r < 0) {
|
|
||||||
if (errno == EINTR) continue;
|
|
||||||
perror("sendfile"); close(fd); return -1;
|
|
||||||
}
|
|
||||||
if (r == 0) break;
|
|
||||||
}
|
|
||||||
close(fd);
|
|
||||||
uint32_t ack = 0;
|
|
||||||
if (readn(ctx->tcp_fd, &ack, sizeof(ack)) != sizeof(ack)
|
|
||||||
|| ack != RESP_OK) {
|
|
||||||
fprintf(stderr, "[thread] TCP finalize failed: %s\n", rel_path);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "[thread] Server rejected %s (code %u)\n",
|
|
||||||
rel_path, resp.response);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
atomic_fetch_add(&g_bytes_sent, meta.file_size);
|
|
||||||
atomic_fetch_add(&g_files_sent, 1);
|
|
||||||
printf("[thread] Sent: %s\n", rel_path);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ─── UDP session setup (called once per worker if -u) ─────────────────────
|
// ─── UDP session setup (called once per worker if -u) ─────────────────────
|
||||||
|
|
||||||
static int setup_udp(sync_ctx_t *ctx, const char *host) {
|
static int setup_udp(sync_ctx_t *ctx, const char *host) {
|
||||||
@@ -473,7 +326,7 @@ static int collect_files(const char *base, const char *sub, file_task_t **list,
|
|||||||
while ((e = readdir(dir)) != NULL) {
|
while ((e = readdir(dir)) != NULL) {
|
||||||
if (!strcmp(e->d_name, ".") || !strcmp(e->d_name, "..")) continue;
|
if (!strcmp(e->d_name, ".") || !strcmp(e->d_name, "..")) continue;
|
||||||
|
|
||||||
char rel[2048], full[2048];
|
char rel[1024], full[2048];
|
||||||
if (sub && sub[0]) {
|
if (sub && sub[0]) {
|
||||||
snprintf(rel, sizeof(rel), "%s/%s", sub, e->d_name);
|
snprintf(rel, sizeof(rel), "%s/%s", sub, e->d_name);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Binary file not shown.
+1
-1
@@ -353,7 +353,7 @@ void handle_client(int sock_fd, const char *dest_dir) {
|
|||||||
// Check if file already exists with same size and checksum (skip if so)
|
// Check if file already exists with same size and checksum (skip if so)
|
||||||
struct stat existing_st;
|
struct stat existing_st;
|
||||||
if (stat(target_path, &existing_st) == 0 &&
|
if (stat(target_path, &existing_st) == 0 &&
|
||||||
existing_st.st_size == meta.file_size &&
|
(uint64_t)existing_st.st_size == meta.file_size &&
|
||||||
S_ISREG(existing_st.st_mode)) {
|
S_ISREG(existing_st.st_mode)) {
|
||||||
// File exists with same size - check checksum
|
// File exists with same size - check checksum
|
||||||
uint64_t existing_checksum = fast_hash_file(target_path, meta.file_size);
|
uint64_t existing_checksum = fast_hash_file(target_path, meta.file_size);
|
||||||
|
|||||||
Reference in New Issue
Block a user