X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=server-src%2Fchunker.c;h=5e6c1ef45c7619ec9bb761fe871494d8714a5e5f;hb=fb2bd066c2f8b34addafe48d62550e3033a59431;hp=fc783ba23acb5390b6f96da809c41e37037cabd5;hpb=1194fb66aa28d9929c3f2bef3cc6c1c3f40a60a4;p=debian%2Famanda diff --git a/server-src/chunker.c b/server-src/chunker.c index fc783ba..5e6c1ef 100644 --- a/server-src/chunker.c +++ b/server-src/chunker.c @@ -23,7 +23,7 @@ * Authors: the Amanda Development Team. Its members are listed in a * file named AUTHORS, in the root directory of this distribution. */ -/* $Id: chunker.c,v 1.25 2006/03/21 13:23:35 martinea Exp $ +/* $Id: chunker.c,v 1.36 2006/08/24 11:23:32 martinea Exp $ * * requests remote amandad processes to dump filesystems */ @@ -44,6 +44,13 @@ #include "server_util.h" #include "util.h" #include "holding.h" +#include "timestamp.h" + +#define chunker_debug(i, ...) do { \ + if ((i) <= debug_chunker) { \ + dbprintf(__VA_ARGS__); \ + } \ +} while (0) #ifndef SEEK_SET #define SEEK_SET 0 @@ -61,9 +68,9 @@ struct databuf { int fd; /* file to flush to */ char *filename; /* name of what fd points to */ int filename_seq; /* for chunking */ - long split_size; /* when to chunk */ - long chunk_size; /* size of each chunk */ - long use; /* size to use on this disk */ + off_t split_size; /* when to chunk */ + off_t chunk_size; /* size of each chunk */ + off_t use; /* size to use on this disk */ char buf[DISK_BLOCK_BYTES]; char *datain; /* data buffer markers */ char *dataout; @@ -74,100 +81,108 @@ static char *handle = NULL; static char *errstr = NULL; static int abort_pending; -static long dumpsize, headersize; -static long dumpbytes; -static long filesize; +static off_t dumpsize; +static unsigned long headersize; +static off_t dumpbytes; +static off_t filesize; static char *hostname = NULL; static char *diskname = NULL; +static char *qdiskname = NULL; static char *options = NULL; static char *progname = NULL; static int level; static char *dumpdate = NULL; -static char *datestamp; static int command_in_transit; +static char *chunker_timestamp = NULL; static dumpfile_t file; /* local functions */ -int main P((int, char **)); -static int write_tapeheader P((int, dumpfile_t *)); -static void databuf_init P((struct databuf *, int, char *, long, long)); -static int databuf_flush P((struct databuf *)); +int main(int, char **); +static ssize_t write_tapeheader(int, dumpfile_t *); +static void databuf_init(struct databuf *, int, char *, off_t, off_t); +static int databuf_flush(struct databuf *); -static int startup_chunker P((char *, long, long, struct databuf *)); -static int do_chunk P((int, struct databuf *)); +static int startup_chunker(char *, off_t, off_t, struct databuf *); +static int do_chunk(int, struct databuf *); int -main(main_argc, main_argv) - int main_argc; - char **main_argv; +main( + int argc, + char ** argv) { static struct databuf db; struct cmdargs cmdargs; cmd_t cmd; int infd; - unsigned long malloc_hist_1, malloc_size_1; - unsigned long malloc_hist_2, malloc_size_2; - char *conffile; char *q = NULL; - char *filename; - long chunksize, use; + char *filename = NULL; + char *qfilename = NULL; + off_t chunksize, use; times_t runtime; am_feature_t *their_features = NULL; int a; + config_overwrites_t *cfg_ovr = NULL; + char *cfg_opt = NULL; + + /* + * Configure program for internationalization: + * 1) Only set the message locale for now. + * 2) Set textdomain for all amanda related programs to "amanda" + * We don't want to be forced to support dozens of message catalogs. + */ + setlocale(LC_MESSAGES, "C"); + textdomain("amanda"); safe_fd(-1, 0); set_pname("chunker"); + dbopen(DBG_SUBDIR_SERVER); + /* Don't die when child closes pipe */ signal(SIGPIPE, SIG_IGN); - malloc_size_1 = malloc_inuse(&malloc_hist_1); - erroutput_type = (ERR_AMANDALOG|ERR_INTERACTIVE); set_logerror(logerror); - if (main_argc > 1) { - config_name = stralloc(main_argv[1]); - config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL); - } else { - char my_cwd[STR_SIZE]; + cfg_ovr = extract_commandline_config_overwrites(&argc, &argv); - if (getcwd(my_cwd, sizeof(my_cwd)) == NULL) { - error("cannot determine current working directory"); - } - config_dir = stralloc2(my_cwd, "/"); - if ((config_name = strrchr(my_cwd, '/')) != NULL) { - config_name = stralloc(config_name + 1); - } - } + if (argc > 1) + cfg_opt = argv[1]; - safe_cd(); + config_init(CONFIG_INIT_EXPLICIT_NAME | CONFIG_INIT_USE_CWD | CONFIG_INIT_FATAL, + cfg_opt); + apply_config_overwrites(cfg_ovr); - conffile = stralloc2(config_dir, CONFFILE_NAME); - if(read_conffile(conffile)) { - error("errors processing config file \"%s\"", conffile); - } - amfree(conffile); + safe_cd(); /* do this *after* config_init() */ + + check_running_as(RUNNING_AS_DUMPUSER); + + dbrename(config_name, DBG_SUBDIR_SERVER); - fprintf(stderr, - "%s: pid %ld executable %s version %s\n", + g_fprintf(stderr, + _("%s: pid %ld executable %s version %s\n"), get_pname(), (long) getpid(), - main_argv[0], version()); + argv[0], version()); fflush(stderr); /* now, make sure we are a valid user */ - if (getpwuid(getuid()) == NULL) - error("can't get login name for my uid %ld", (long)getuid()); - signal(SIGPIPE, SIG_IGN); signal(SIGCHLD, SIG_IGN); - datestamp = construct_datestamp(NULL); + cmd = getcmd(&cmdargs); + if(cmd == START) { + if(cmdargs.argc <= 1) + error(_("error [dumper START: not enough args: timestamp]")); + chunker_timestamp = newstralloc(chunker_timestamp, cmdargs.argv[2]); + } + else { + error(_("Didn't get START command")); + } /* do {*/ cmd = getcmd(&cmdargs); @@ -195,69 +210,88 @@ main(main_argc, main_argv) a = 2; if(a >= cmdargs.argc) { - error("error [chunker PORT-WRITE: not enough args: handle]"); + error(_("error [chunker PORT-WRITE: not enough args: handle]")); + /*NOTREACHED*/ } handle = newstralloc(handle, cmdargs.argv[a++]); if(a >= cmdargs.argc) { - error("error [chunker PORT-WRITE: not enough args: filename]"); + error(_("error [chunker PORT-WRITE: not enough args: filename]")); + /*NOTREACHED*/ } - filename = cmdargs.argv[a++]; + qfilename = newstralloc(qfilename, cmdargs.argv[a++]); + if (filename != NULL) + amfree(filename); + filename = unquote_string(qfilename); + amfree(qfilename); if(a >= cmdargs.argc) { - error("error [chunker PORT-WRITE: not enough args: hostname]"); + error(_("error [chunker PORT-WRITE: not enough args: hostname]")); + /*NOTREACHED*/ } hostname = newstralloc(hostname, cmdargs.argv[a++]); if(a >= cmdargs.argc) { - error("error [chunker PORT-WRITE: not enough args: features]"); + error(_("error [chunker PORT-WRITE: not enough args: features]")); + /*NOTREACHED*/ } am_release_feature_set(their_features); their_features = am_string_to_feature(cmdargs.argv[a++]); if(a >= cmdargs.argc) { - error("error [chunker PORT-WRITE: not enough args: diskname]"); + error(_("error [chunker PORT-WRITE: not enough args: diskname]")); + /*NOTREACHED*/ } - diskname = newstralloc(diskname, cmdargs.argv[a++]); + qdiskname = newstralloc(qdiskname, cmdargs.argv[a++]); + if (diskname != NULL) + amfree(diskname); + diskname = unquote_string(qdiskname); if(a >= cmdargs.argc) { - error("error [chunker PORT-WRITE: not enough args: level]"); + error(_("error [chunker PORT-WRITE: not enough args: level]")); + /*NOTREACHED*/ } level = atoi(cmdargs.argv[a++]); if(a >= cmdargs.argc) { - error("error [chunker PORT-WRITE: not enough args: dumpdate]"); + error(_("error [chunker PORT-WRITE: not enough args: dumpdate]")); + /*NOTREACHED*/ } dumpdate = newstralloc(dumpdate, cmdargs.argv[a++]); if(a >= cmdargs.argc) { - error("error [chunker PORT-WRITE: not enough args: chunksize]"); + error(_("error [chunker PORT-WRITE: not enough args: chunksize]")); + /*NOTREACHED*/ } - chunksize = atoi(cmdargs.argv[a++]); - chunksize = am_floor(chunksize, DISK_BLOCK_KB); + chunksize = OFF_T_ATOI(cmdargs.argv[a++]); + chunksize = am_floor(chunksize, (off_t)DISK_BLOCK_KB); if(a >= cmdargs.argc) { - error("error [chunker PORT-WRITE: not enough args: progname]"); + error(_("error [chunker PORT-WRITE: not enough args: progname]")); + /*NOTREACHED*/ } progname = newstralloc(progname, cmdargs.argv[a++]); if(a >= cmdargs.argc) { - error("error [chunker PORT-WRITE: not enough args: use]"); + error(_("error [chunker PORT-WRITE: not enough args: use]")); + /*NOTREACHED*/ } - use = am_floor(atoi(cmdargs.argv[a++]), DISK_BLOCK_KB); + use = am_floor(OFF_T_ATOI(cmdargs.argv[a++]), DISK_BLOCK_KB); if(a >= cmdargs.argc) { - error("error [chunker PORT-WRITE: not enough args: options]"); + error(_("error [chunker PORT-WRITE: not enough args: options]")); + /*NOTREACHED*/ } options = newstralloc(options, cmdargs.argv[a++]); if(a != cmdargs.argc) { - error("error [chunker PORT-WRITE: too many args: %d != %d]", + error(_("error [chunker PORT-WRITE: too many args: %d != %d]"), cmdargs.argc, a); + /*NOTREACHED*/ } if((infd = startup_chunker(filename, use, chunksize, &db)) < 0) { - q = squotef("[chunker startup failed: %s]", errstr); + q = squotef(_("[chunker startup failed: %s]"), errstr); putresult(TRYAGAIN, "%s %s\n", handle, q); error("startup_chunker failed"); } @@ -268,15 +302,13 @@ main(main_argc, main_argv) double rt; runtime = stopclock(); - rt = runtime.r.tv_sec+runtime.r.tv_usec/1000000.0; - snprintf(kb_str, sizeof(kb_str), "%ld", dumpsize - headersize); - snprintf(kps_str, sizeof(kps_str), "%3.1f", - rt ? dumpsize / rt : 0.0); - errstr = newvstralloc(errstr, - "sec ", walltime_str(runtime), - " kb ", kb_str, - " kps ", kps_str, - NULL); + rt = g_timeval_to_double(runtime); + g_snprintf(kb_str, SIZEOF(kb_str), "%lld", + (long long)(dumpsize - (off_t)headersize)); + g_snprintf(kps_str, SIZEOF(kps_str), "%3.1lf", + isnormal(rt) ? (double)dumpsize / rt : 0.0); + errstr = newvstrallocf(errstr, "sec %s kb %s kps %s", + walltime_str(runtime), kb_str, kps_str); q = squotef("[%s]", errstr); if(command_in_transit != -1) cmd = command_in_transit; @@ -284,31 +316,30 @@ main(main_argc, main_argv) cmd = getcmd(&cmdargs); switch(cmd) { case DONE: - putresult(DONE, "%s %ld %s\n", - handle, dumpsize - headersize, q); + putresult(DONE, "%s %lld %s\n", handle, + (long long)(dumpsize - (off_t)headersize), q); log_add(L_SUCCESS, "%s %s %s %d [%s]", - hostname, diskname, datestamp, level, errstr); + hostname, qdiskname, chunker_timestamp, level, errstr); break; case BOGUS: case TRYAGAIN: case FAILED: case ABORT_FINISHED: - if(dumpsize > DISK_BLOCK_KB) { - putresult(PARTIAL, "%s %ld %s\n", - handle, dumpsize - headersize, q); + if(dumpsize > (off_t)DISK_BLOCK_KB) { + putresult(PARTIAL, "%s %lld %s\n", handle, + (long long)(dumpsize - (off_t)headersize), + q); log_add(L_PARTIAL, "%s %s %s %d [%s]", - hostname, diskname, datestamp, level, errstr); + hostname, qdiskname, chunker_timestamp, level, errstr); } else { - errstr = newvstralloc(errstr, - "dumper returned ", - cmdstr[cmd], - NULL); + errstr = newvstrallocf(errstr, + _("dumper returned %s"), cmdstr[cmd]); amfree(q); q = squotef("[%s]",errstr); putresult(FAILED, "%s %s\n", handle, q); log_add(L_FAIL, "%s %s %s %d [%s]", - hostname, diskname, datestamp, level, errstr); + hostname, qdiskname, chunker_timestamp, level, errstr); } default: break; } @@ -320,10 +351,12 @@ main(main_argc, main_argv) } putresult(FAILED, "%s %s\n", handle, q); log_add(L_FAIL, "%s %s %s %d [%s]", - hostname, diskname, datestamp, level, errstr); + hostname, qdiskname, chunker_timestamp, level, errstr); amfree(q); } } + amfree(filename); + amfree(db.filename); break; default: @@ -332,7 +365,7 @@ main(main_argc, main_argv) } else if(cmdargs.argc >= 0) { q = squote(cmdargs.argv[0]); } else { - q = stralloc("(no input?)"); + q = stralloc(_("(no input?)")); } putresult(BAD_COMMAND, "%s\n", q); amfree(q); @@ -342,24 +375,20 @@ main(main_argc, main_argv) /* } while(cmd != QUIT); */ amfree(errstr); - amfree(datestamp); + amfree(chunker_timestamp); amfree(handle); amfree(hostname); amfree(diskname); + amfree(qdiskname); amfree(dumpdate); amfree(progname); amfree(options); - amfree(config_dir); - amfree(config_name); am_release_feature_set(their_features); their_features = NULL; - malloc_size_2 = malloc_inuse(&malloc_hist_2); + dbclose(); - if (malloc_size_1 != malloc_size_2) - malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2); - - exit(0); + return (0); /* exit */ } /* @@ -367,29 +396,38 @@ main(main_argc, main_argv) * on success, or -1 on error. */ static int -startup_chunker(filename, use, chunksize, db) - char *filename; - long use; - long chunksize; - struct databuf *db; +startup_chunker( + char * filename, + off_t use, + off_t chunksize, + struct databuf * db) { int infd, outfd; char *tmp_filename, *pc; - int data_port, data_socket; + in_port_t data_port; + int data_socket; + int result; + struct addrinfo *res; data_port = 0; - data_socket = stream_server(&data_port, -1, STREAM_BUFSIZE); + if ((result = resolve_hostname("localhost", 0, &res, NULL) != 0)) { + errstr = newvstrallocf(errstr, _("could not resolve localhost: %s"), + gai_strerror(result)); + return -1; + } + data_socket = stream_server(res->ai_family, &data_port, 0, + STREAM_BUFSIZE, 0); if(data_socket < 0) { - errstr = stralloc2("error creating stream server: ", strerror(errno)); + errstr = vstrallocf(_("error creating stream server: %s"), strerror(errno)); return -1; } putresult(PORT, "%d\n", data_port); - infd = stream_accept(data_socket, CONNECT_TIMEOUT, -1, NETWORK_BLOCK_BYTES); + infd = stream_accept(data_socket, CONNECT_TIMEOUT, 0, STREAM_BUFSIZE); if(infd == -1) { - errstr = stralloc2("error accepting stream: ", strerror(errno)); + errstr = vstrallocf(_("error accepting stream: %s"), strerror(errno)); return -1; } @@ -401,13 +439,14 @@ startup_chunker(filename, use, chunksize, db) if ((outfd = open(tmp_filename, O_RDWR|O_CREAT|O_TRUNC, 0600)) < 0) { int save_errno = errno; - errstr = squotef("holding file \"%s\": %s", + errstr = squotef(_("holding file \"%s\": %s"), tmp_filename, strerror(errno)); amfree(tmp_filename); aclose(infd); if(save_errno == ENOSPC) { - putresult(NO_ROOM, "%s %lu", handle, use); + putresult(NO_ROOM, "%s %lld\n", + handle, (long long)use); return -2; } else { return -1; @@ -420,61 +459,57 @@ startup_chunker(filename, use, chunksize, db) } static int -do_chunk(infd, db) - int infd; - struct databuf *db; +do_chunk( + int infd, + struct databuf * db) { - int nread; + ssize_t nread; char header_buf[DISK_BLOCK_BYTES]; startclock(); - dumpsize = headersize = dumpbytes = filesize = 0; + dumpsize = dumpbytes = filesize = (off_t)0; + headersize = 0; + memset(header_buf, 0, sizeof(header_buf)); /* * The first thing we should receive is the file header, which we * need to save into "file", as well as write out. Later, the * chunk code will rewrite it. */ - nread = fullread(infd, header_buf, sizeof(header_buf)); + nread = fullread(infd, header_buf, SIZEOF(header_buf)); if (nread != DISK_BLOCK_BYTES) { - char number1[NUM_STR_SIZE]; - char number2[NUM_STR_SIZE]; - if(nread < 0) { - errstr = stralloc2("cannot read header: ", strerror(errno)); + errstr = vstrallocf(_("cannot read header: %s"), strerror(errno)); } else { - snprintf(number1, sizeof(number1), "%d", nread); - snprintf(number2, sizeof(number2), "%d", DISK_BLOCK_BYTES); - errstr = vstralloc("cannot read header: got ", - number1, - " instead of ", - number2, - NULL); + errstr = vstrallocf(_("cannot read header: got %zd bytes instead of %d"), + nread, + DISK_BLOCK_BYTES); } return 0; } - parse_file_header(header_buf, &file, nread); + parse_file_header(header_buf, &file, (size_t)nread); if(write_tapeheader(db->fd, &file)) { int save_errno = errno; - errstr = squotef("write_tapeheader file \"%s\": %s", + errstr = squotef(_("write_tapeheader file %s: %s"), db->filename, strerror(errno)); if(save_errno == ENOSPC) { - putresult(NO_ROOM, "%s %lu\n", handle, - db->use+db->split_size-dumpsize); + putresult(NO_ROOM, "%s %lld\n", handle, + (long long)(db->use+db->split_size-dumpsize)); } return 0; } - dumpsize += DISK_BLOCK_KB; - filesize = DISK_BLOCK_KB; + dumpsize += (off_t)DISK_BLOCK_KB; + filesize = (off_t)DISK_BLOCK_KB; headersize += DISK_BLOCK_KB; /* * We've written the file header. Now, just write data until the * end. */ - while ((nread = fullread(infd, db->buf, db->datalimit - db->datain)) > 0) { + while ((nread = fullread(infd, db->buf, + (size_t)(db->datalimit - db->datain))) > 0) { db->datain += nread; while(db->dataout < db->datain) { if(!databuf_flush(db)) { @@ -487,9 +522,9 @@ do_chunk(infd, db) return 0; } } - if(dumpbytes > 0) { - dumpsize++; /* count partial final KByte */ - filesize++; + if(dumpbytes > (off_t)0) { + dumpsize += (off_t)1; /* count partial final KByte */ + filesize += (off_t)1; } return 1; } @@ -498,21 +533,21 @@ do_chunk(infd, db) * Initialize a databuf. Takes a writeable file descriptor. */ static void -databuf_init(db, fd, filename, use, chunk_size) - struct databuf *db; - int fd; - char *filename; - long use; - long chunk_size; +databuf_init( + struct databuf * db, + int fd, + char * filename, + off_t use, + off_t chunk_size) { db->fd = fd; db->filename = stralloc(filename); - db->filename_seq = 0; + db->filename_seq = (off_t)0; db->chunk_size = chunk_size; db->split_size = (db->chunk_size > use) ? use : db->chunk_size; - db->use = (use>db->split_size) ? use - db->split_size : 0; + db->use = (use > db->split_size) ? use - db->split_size : (off_t)0; db->datain = db->dataout = db->buf; - db->datalimit = db->buf + sizeof(db->buf); + db->datalimit = db->buf + SIZEOF(db->buf); } @@ -520,14 +555,15 @@ databuf_init(db, fd, filename, use, chunk_size) * Write out the buffer to the backing file */ static int -databuf_flush(db) - struct databuf *db; +databuf_flush( + struct databuf * db) { struct cmdargs cmdargs; int rc = 1; - int written; - long left_in_chunk; + ssize_t written; + off_t left_in_chunk; char *arg_filename = NULL; + char *qarg_filename = NULL; char *new_filename = NULL; char *tmp_filename = NULL; char sequence[NUM_STR_SIZE]; @@ -547,8 +583,8 @@ databuf_flush(db) /* * See if we need to split this file. */ - while (db->split_size > 0 && dumpsize >= db->split_size) { - if( db->use == 0 ) { + while (db->split_size > (off_t)0 && dumpsize >= db->split_size) { + if( db->use == (off_t)0 ) { /* * Probably no more space on this disk. Request some more. */ @@ -573,24 +609,31 @@ databuf_flush(db) a = 3; if(a >= cmdargs.argc) { - error("error [chunker CONTINUE: not enough args: filename]"); + error(_("error [chunker CONTINUE: not enough args: filename]")); + /*NOTREACHED*/ } - arg_filename = newstralloc(arg_filename, cmdargs.argv[a++]); + qarg_filename = newstralloc(qarg_filename, cmdargs.argv[a++]); + if (arg_filename != NULL) + amfree(arg_filename); + arg_filename = unquote_string(qarg_filename); if(a >= cmdargs.argc) { - error("error [chunker CONTINUE: not enough args: chunksize]"); + error(_("error [chunker CONTINUE: not enough args: chunksize]")); + /*NOTREACHED*/ } - db->chunk_size = atoi(cmdargs.argv[a++]); - db->chunk_size = am_floor(db->chunk_size, DISK_BLOCK_KB); + db->chunk_size = OFF_T_ATOI(cmdargs.argv[a++]); + db->chunk_size = am_floor(db->chunk_size, (off_t)DISK_BLOCK_KB); if(a >= cmdargs.argc) { - error("error [chunker CONTINUE: not enough args: use]"); + error(_("error [chunker CONTINUE: not enough args: use]")); + /*NOTREACHED*/ } - db->use = atoi(cmdargs.argv[a++]); + db->use = OFF_T_ATOI(cmdargs.argv[a++]); if(a != cmdargs.argc) { - error("error [chunker CONTINUE: too many args: %d != %d]", + error(_("error [chunker CONTINUE: too many args: %d != %d]"), cmdargs.argc, a); + /*NOTREACHED*/ } if(strcmp(db->filename, arg_filename) == 0) { @@ -602,12 +645,12 @@ databuf_flush(db) left_in_chunk = db->chunk_size - filesize; if(left_in_chunk > db->use) { db->split_size += db->use; - db->use = 0; + db->use = (off_t)0; } else { db->split_size += left_in_chunk; db->use -= left_in_chunk; } - if(left_in_chunk > 0) { + if(left_in_chunk > (off_t)0) { /* * We still have space in this chunk. */ @@ -631,9 +674,10 @@ databuf_flush(db) } else if(cmdargs.argc >= 0) { q = squote(cmdargs.argv[0]); } else { - q = stralloc("(no input?)"); + q = stralloc(_("(no input?)")); } - error("error [bad command after RQ-MORE-DISK: \"%s\"]", q); + error(_("error [bad command after RQ-MORE-DISK: \"%s\"]"), q); + /*NOTREACHED*/ } } @@ -645,7 +689,7 @@ databuf_flush(db) * First, open the new chunk file, and give it a new header * that has no cont_filename pointer. */ - snprintf(sequence, sizeof(sequence), "%d", db->filename_seq); + g_snprintf(sequence, SIZEOF(sequence), "%d", db->filename_seq); new_filename = newvstralloc(new_filename, db->filename, ".", @@ -664,14 +708,13 @@ databuf_flush(db) int save_errno = errno; if(save_errno == ENOSPC) { - putresult(NO_ROOM, "%s %lu\n", - handle, - db->use+db->split_size-dumpsize); - db->use = 0; /* force RQ_MORE_DISK */ + putresult(NO_ROOM, "%s %lld\n", handle, + (long long)(db->use+db->split_size-dumpsize)); + db->use = (off_t)0; /* force RQ_MORE_DISK */ db->split_size = dumpsize; continue; } - errstr = squotef("creating chunk holding file \"%s\": %s", + errstr = squotef(_("creating chunk holding file \"%s\": %s"), tmp_filename, strerror(errno)); aclose(db->fd); @@ -686,14 +729,13 @@ databuf_flush(db) aclose(newfd); if(save_errno == ENOSPC) { - putresult(NO_ROOM, "%s %lu\n", - handle, - db->use+db->split_size-dumpsize); - db->use = 0; /* force RQ_MORE DISK */ + putresult(NO_ROOM, "%s %lld\n", handle, + (long long)(db->use+db->split_size-dumpsize)); + db->use = (off_t)0; /* force RQ_MORE DISK */ db->split_size = dumpsize; continue; } - errstr = squotef("write_tapeheader file \"%s\": %s", + errstr = squotef(_("write_tapeheader file %s: %s"), tmp_filename, strerror(errno)); rc = 0; @@ -704,8 +746,8 @@ databuf_flush(db) * Now, update the header of the current file to point * to the next chunk, and then close it. */ - if (lseek(db->fd, (off_t)0, SEEK_SET) < 0) { - errstr = squotef("lseek holding file \"%s\": %s", + if (lseek(db->fd, (off_t)0, SEEK_SET) < (off_t)0) { + errstr = squotef(_("lseek holding file %s: %s"), db->filename, strerror(errno)); aclose(newfd); @@ -714,10 +756,10 @@ databuf_flush(db) } file.type = save_type; - strncpy(file.cont_filename, new_filename, sizeof(file.cont_filename)); - file.cont_filename[sizeof(file.cont_filename)] = '\0'; + strncpy(file.cont_filename, new_filename, SIZEOF(file.cont_filename)); + file.cont_filename[SIZEOF(file.cont_filename)-1] = '\0'; if(write_tapeheader(db->fd, &file)) { - errstr = squotef("write_tapeheader file \"%s\": %s", + errstr = squotef(_("write_tapeheader file \"%s\": %s"), db->filename, strerror(errno)); aclose(newfd); @@ -737,16 +779,16 @@ databuf_flush(db) /* * Update when we need to chunk again */ - if(db->use <= DISK_BLOCK_KB) { + if(db->use <= (off_t)DISK_BLOCK_KB) { /* * Cheat and use one more block than allowed so we can make * some progress. */ - db->split_size += 2 * DISK_BLOCK_KB; - db->use = 0; + db->split_size += (off_t)(2 * DISK_BLOCK_KB); + db->use = (off_t)0; } else if(db->chunk_size > db->use) { db->split_size += db->use; - db->use = 0; + db->use = (off_t)0; } else { db->split_size += db->chunk_size; db->use -= db->chunk_size; @@ -755,8 +797,8 @@ databuf_flush(db) amfree(tmp_filename); amfree(new_filename); - dumpsize += DISK_BLOCK_KB; - filesize = DISK_BLOCK_KB; + dumpsize += (off_t)DISK_BLOCK_KB; + filesize = (off_t)DISK_BLOCK_KB; headersize += DISK_BLOCK_KB; db->filename_seq++; } @@ -764,17 +806,18 @@ databuf_flush(db) /* * Write out the buffer */ - written = fullwrite(db->fd, db->dataout, db->datain - db->dataout); + written = fullwrite(db->fd, db->dataout, + (size_t)(db->datain - db->dataout)); if (written > 0) { db->dataout += written; - dumpbytes += written; + dumpbytes += (off_t)written; } - dumpsize += (dumpbytes / 1024); - filesize += (dumpbytes / 1024); + dumpsize += (dumpbytes / (off_t)1024); + filesize += (dumpbytes / (off_t)1024); dumpbytes %= 1024; if (written < 0) { if (errno != ENOSPC) { - errstr = squotef("data write: %s", strerror(errno)); + errstr = squotef(_("data write: %s"), strerror(errno)); rc = 0; goto common_exit; } @@ -783,8 +826,9 @@ databuf_flush(db) * NO-ROOM is informational only. Later, RQ_MORE_DISK will be * issued to use another holding disk. */ - putresult(NO_ROOM, "%s %lu\n", handle, db->use+db->split_size-dumpsize); - db->use = 0; /* force RQ_MORE_DISK */ + putresult(NO_ROOM, "%s %lld\n", handle, + (long long)(db->use+db->split_size-dumpsize)); + db->use = (off_t)0; /* force RQ_MORE_DISK */ db->split_size = dumpsize; goto common_exit; } @@ -798,29 +842,31 @@ databuf_flush(db) common_exit: amfree(new_filename); - amfree(tmp_filename); + /*@i@*/ amfree(tmp_filename); amfree(arg_filename); + amfree(qarg_filename); return rc; } /* - * Send an Amanda dump header to the output file. + * Send an Amanda dump header to the output file and set file->blocksize */ -static int -write_tapeheader(outfd, file) - int outfd; - dumpfile_t *file; +static ssize_t +write_tapeheader( + int outfd, + dumpfile_t *file) { - char buffer[DISK_BLOCK_BYTES]; - int written; + char *buffer; + ssize_t written; file->blocksize = DISK_BLOCK_BYTES; - build_header(buffer, file, sizeof(buffer)); + buffer = build_header(file, DISK_BLOCK_BYTES); - written = fullwrite(outfd, buffer, sizeof(buffer)); - if(written == sizeof(buffer)) return 0; + written = fullwrite(outfd, buffer, DISK_BLOCK_BYTES); + amfree(buffer); + if(written == DISK_BLOCK_BYTES) return 0; if(written < 0) return written; errno = ENOSPC; - return -1; + return (ssize_t)-1; }