#include "util.h"
#include "holding.h"
#include "timestamp.h"
+#include "sockaddr-util.h"
#ifndef SEEK_SET
#define SEEK_SET 0
static void databuf_init(struct databuf *, int, char *, off_t, off_t);
static int databuf_flush(struct databuf *);
-static int startup_chunker(char *, off_t, off_t, struct databuf *, int *);
-static int do_chunk(int, struct databuf *, int);
+static int startup_chunker(char *, off_t, off_t, struct databuf *, int *, int *);
+static int do_chunk(int, struct databuf *, int, int);
/* we use a function pointer for full_write, so that we can "shim" in
* full_write_with_fake_enospc for testing */
config_overrides_t *cfg_ovr = NULL;
char *cfg_opt = NULL;
char *m;
+ int header_socket;
int data_socket;
/*
}
if ((header_fd = startup_chunker(filename, use, chunksize, &db,
- &data_socket)) < 0) {
+ &header_socket, &data_socket)) < 0) {
q = quote_string(vstrallocf(_("[chunker startup failed: %s]"), errstr));
putresult(TRYAGAIN, "%s %s\n", handle, q);
error("startup_chunker failed: %s", errstr);
}
command_in_transit = NULL;
- if (header_fd >= 0 && do_chunk(header_fd, &db, data_socket)) {
+ if (header_fd >= 0 && do_chunk(header_fd, &db, header_socket, data_socket)) {
char kb_str[NUM_STR_SIZE];
char kps_str[NUM_STR_SIZE];
double rt;
off_t use,
off_t chunksize,
struct databuf * db,
+ int *headersocket,
int *datasocket)
{
int header_fd, outfd;
int header_socket, data_socket;
int result;
struct addrinfo *res;
+ struct addrinfo *res_addr;
+ sockaddr_union *addr = NULL;
+ sockaddr_union data_addr;
header_port = 0;
data_port = 0;
gai_strerror(result));
return -1;
}
- header_socket = stream_server(res->ai_family, &header_port, 0,
+ for (res_addr = res; res_addr != NULL; res_addr = res_addr->ai_next) {
+ g_debug("ra: %s\n", str_sockaddr((sockaddr_union*)res_addr->ai_addr));
+ if (res_addr->ai_family == AF_INET) {
+ addr = (sockaddr_union *)res_addr->ai_addr;
+ break;
+ }
+ }
+ if (!addr) {
+ addr = (sockaddr_union *)res->ai_addr;
+ g_debug("addr: %s\n", str_sockaddr(addr));
+ }
+
+ header_socket = stream_server(SU_GET_FAMILY(addr), &header_port, 0,
STREAM_BUFSIZE, 0);
- data_socket = stream_server(res->ai_family, &data_port, 0,
+ data_socket = stream_server(SU_GET_FAMILY(addr), &data_port, 0,
STREAM_BUFSIZE, 0);
+ copy_sockaddr(&data_addr, addr);
+
+ SU_SET_PORT(&data_addr, data_port);
+
if (res) freeaddrinfo(res);
if (header_socket < 0) {
return -1;
}
- putresult(PORT, "%d 127.0.0.1:%d\n", header_port, data_port);
+ putresult(PORT, "%d %s\n", header_port, str_sockaddr(&data_addr));
header_fd = stream_accept(header_socket, CONNECT_TIMEOUT, 0,
STREAM_BUFSIZE);
aclose(data_socket);
return -1;
}
- aclose(header_socket);
tmp_filename = vstralloc(filename, ".tmp", NULL);
pc = strrchr(tmp_filename, '/');
amfree(tmp_filename);
databuf_init(db, outfd, filename, use, chunksize);
db->filename_seq++;
+ *headersocket = header_socket;
*datasocket = data_socket;
return header_fd;
}
do_chunk(
int header_fd,
struct databuf * db,
+ int header_socket,
int data_socket)
{
size_t nread;
* chunk code will rewrite it.
*/
nread = full_read(header_fd, header_buf, SIZEOF(header_buf));
+ aclose(header_fd);
+ aclose(header_socket);
if (nread != sizeof(header_buf)) {
if(errno != 0) {
errstr = vstrallocf(_("cannot read header: %s"), strerror(errno));
aclose(data_socket);
return 0;
}
- aclose(data_socket);
/*
* We've written the file header. Now, just write data until the
db->datain += nread;
while(db->dataout < db->datain) {
if(!databuf_flush(db)) {
+ aclose(data_fd);
+ aclose(data_socket);
return 0;
}
}
}
while(db->dataout < db->datain) {
if(!databuf_flush(db)) {
+ aclose(data_fd);
+ aclose(data_socket);
return 0;
}
}
dumpsize += (off_t)1; /* count partial final KByte */
filesize += (off_t)1;
}
+ aclose(data_fd);
+ aclose(data_socket);
return 1;
}