Imported Upstream version 2.5.1
[debian/amanda] / server-src / taper.c
index f403171f2d2867d208ef6bfba0e9400286b799cd..37d17ee51054e0b5017ca32c155a7dcfeebf3d74 100644 (file)
@@ -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: taper.c,v 1.118.2.1 2006/05/04 21:31:15 martinea Exp $
+/* $Id: taper.c,v 1.144 2006/08/24 11:23:32 martinea Exp $
  *
  * moves files from holding disk to tape, or from a socket to tape
  */
@@ -61,10 +61,10 @@ static int len       =  0;
 static int offset    =  0;
 static char *datestr = NULL;
 static char start_datestr[20];
-time_t raw_time;
-struct tm tape_time;
-struct tm backup_time;
-struct tm *tape_timep = &tape_time;
+static time_t raw_time;
+static struct tm tape_time;
+static struct tm backup_time;
+static struct tm *tape_timep = &tape_time;
 typedef struct vtbl_lbls {
     u_int8_t  label[45];
     u_int8_t  date[20];
@@ -76,46 +76,46 @@ static vtbl_lbls vtbl_entry[MAX_VOLUMES];
  * XXX advance to next tape first in next_tape
  * XXX label is being read twice?
  */
-long splitsize = 0; /* max size of dumpfile before split (Kb) */
-char *splitbuf = NULL;
-char *splitbuf_wr_ptr = NULL; /* the number of Kb we've written into splitbuf */
+static off_t splitsize = (off_t)0; /* max size of dumpfile before split (Kb) */
+static off_t mmap_splitsize = (off_t)0;
+static char *mmap_filename = NULL;
+static char *mmap_splitbuf = NULL;
+static char *mem_splitbuf = NULL;
+static char *splitbuf = NULL;
+static off_t mem_splitsize = (off_t)0;
+static char *splitbuf_wr_ptr = NULL; /* the number of Kb we've written into splitbuf */
 int orig_holdfile = -1;
 
 /* NBUFS replaced by conf_tapebufs */
 /* #define NBUFS               20 */
-int conf_tapebufs;
+static int conf_tapebufs;
 
-off_t maxseek = (off_t)1 << ((sizeof(off_t) * 8) - 11);
+static off_t maxseek = (off_t)1 << ((SIZEOF(off_t) * 8) - 11);
 
-char *holdfile_path = NULL;
-char *holdfile_path_thischunk = NULL;
-int num_holdfile_chunks = 0;
-dumpfile_t holdfile_hdr;
-dumpfile_t holdfile_hdr_thischunk;
-off_t holdfile_offset_thischunk = (off_t)0;
-int splitbuffer_fd = -1;
-char *splitbuffer_path = NULL;
+static char *holdfile_path = NULL;
+static char *holdfile_path_thischunk = NULL;
+static int num_holdfile_chunks = 0;
+static off_t holdfile_offset_thischunk = (off_t)0;
+static int mmap_splitbuffer_fd = -1;
 
 #define MODE_NONE 0
 #define MODE_FILE_WRITE 1
 #define MODE_PORT_WRITE 2
 
-int mode = MODE_NONE;
+static mode_t mode = MODE_NONE;
 
 /* This is now the number of empties, not full bufs */
 #define THRESHOLD      1
 
 #define CONNECT_TIMEOUT 2*60
 
-
-
 #define EMPTY 1
 #define FILLING 2
 #define FULL 3
 
 typedef struct buffer_s {
     long status;
-    unsigned int size;
+    ssize_t size;
     char *buffer;
 } buffer_t;
 
@@ -123,14 +123,15 @@ typedef struct buffer_s {
 #define prevbuf(p)    ((p) == buftable? buftable+conf_tapebufs-1 : (p)-1)
 
 /* major modules */
-int main P((int main_argc, char **main_argv));
-void file_reader_side P((int rdpipe, int wrpipe));
-void tape_writer_side P((int rdpipe, int wrpipe));
+int main(int main_argc, char **main_argv);
+void file_reader_side(int rdpipe, int wrpipe);
+void tape_writer_side(int rdpipe, int wrpipe);
+void put_syncpipe_fault_result(char *handle);
 
 /* shared-memory routines */
-char *attach_buffers P((unsigned int size));
-void detach_buffers P((char *bufp));
-void destroy_buffers P((void));
+char *attach_buffers(size_t size);
+void detach_buffers(char *bufp);
+void destroy_buffers(void);
 #define REMOVE_SHARED_MEMORY() \
     detach_buffers(buffers); \
     if (strcmp(procname, "reader") == 0) { \
@@ -138,29 +139,31 @@ void destroy_buffers P((void));
     }
 
 /* synchronization pipe routines */
-void syncpipe_init P((int rd, int wr));
-char syncpipe_get P((int *intp));
-int  syncpipe_getint P((void));
-char *syncpipe_getstr P((void));
-void syncpipe_put P((int ch, int intval));
-void syncpipe_putint P((int i));
-void syncpipe_putstr P((const char *str));
+void syncpipe_init(int rd, int wr);
+void syncpipe_read_error(ssize_t rc, ssize_t expected);
+void syncpipe_write_error(ssize_t rc, ssize_t expected);
+int syncpipe_get(int *intp);
+int syncpipe_getint(void);
+char *syncpipe_getstr(void);
+int syncpipe_put(int ch, int intval);
+int syncpipe_putint(int i);
+int syncpipe_putstr(const char *str);
 
 /* tape manipulation subsystem */
-int first_tape P((char *new_datestamp));
-int next_tape P((int writerr));
-int end_tape P((int writerr));
-int write_filemark P((void));
+int first_tape(char *new_datestamp);
+int next_tape(int writerr);
+int end_tape(int writerr);
+int write_filemark(void);
 
 /* support crap */
-int seek_holdfile P((int fd, buffer_t *bp, long kbytes));
+int seek_holdfile(int fd, buffer_t *bp, off_t kbytes);
 
 /* signal handling */
-static void install_signal_handlers P((void));
-static void signal_handler P((int));
+static void install_signal_handlers(void);
+static void signal_handler(int);
 
 /* exit routine */
-static void cleanup P((void));
+static void cleanup(void);
 
 /*
  * ========================================================================
@@ -168,7 +171,7 @@ static void cleanup P((void));
  *
  */
 int interactive;
-int writerpid;
+pid_t writerpid;
 times_t total_wait;
 #ifdef TAPER_DEBUG
 int bufdebug = 1;
@@ -182,7 +185,7 @@ int err;
 
 char *procname = "parent";
 
-char *taper_datestamp = NULL;
+char *taper_timestamp = NULL;
 char *label = NULL;
 int filenum;
 char *errstr = NULL;
@@ -190,15 +193,15 @@ int tape_fd = -1;
 char *tapedev = NULL;
 char *tapetype = NULL;
 tapetype_t *tt = NULL;
-long tt_blocksize;
-long tt_blocksize_kb;
-long buffer_size;
+size_t tt_blocksize;
+size_t tt_blocksize_kb;
+size_t buffer_size;
 int tt_file_pad;
 static unsigned long malloc_hist_1, malloc_size_1;
 static unsigned long malloc_hist_2, malloc_size_2;
 dumpfile_t file;
 dumpfile_t *save_holdfile = NULL;
-long cur_span_chunkstart = 0; /* start of current split dump chunk (Kb) */
+off_t cur_span_chunkstart = (off_t)0; /* start of current split dump chunk (Kb) */
 char *holdfile_name;
 int num_splits = 0;
 int expected_splits = 0;
@@ -219,41 +222,53 @@ int first_seg, last_seg;
  * MAIN PROGRAM
  *
  */
-int main(main_argc, main_argv)
-int main_argc;
-char **main_argv;
+int
+main(
+    int main_argc,
+    char **main_argv)
 {
     int p2c[2], c2p[2];                /* parent-to-child, child-to-parent pipes */
     char *conffile;
-    unsigned int size;
+    size_t size;
     int i;
-    int j;
-    int page_size;
+    size_t j;
+    size_t page_size;
     char *first_buffer;
+    int    new_argc,   my_argc;
+    char **new_argv, **my_argv;
 
     safe_fd(-1, 0);
 
     set_pname("taper");
 
+    dbopen("server");
+
     /* Don't die when child closes pipe */
     signal(SIGPIPE, SIG_IGN);
 
     malloc_size_1 = malloc_inuse(&malloc_hist_1);
 
+    parse_server_conf(main_argc, main_argv, &new_argc, &new_argv);
+    my_argc = new_argc;
+    my_argv = new_argv;
+
     fprintf(stderr, "%s: pid %ld executable %s version %s\n",
-           get_pname(), (long) getpid(), main_argv[0], version());
+           get_pname(), (long) getpid(), my_argv[0], version());
+    dbprintf(("%s: pid %ld executable %s version %s\n",
+           get_pname(), (long) getpid(), my_argv[0], version()));
     fflush(stderr);
 
-    if (main_argc > 1 && main_argv[1][0] != '-') {
-       config_name = stralloc(main_argv[1]);
-       config_dir = vstralloc(CONFIG_DIR, "/", main_argv[1], "/", NULL);
-       main_argc--;
-       main_argv++;
+    if (my_argc > 1 && my_argv[1][0] != '-') {
+       config_name = stralloc(my_argv[1]);
+       config_dir = vstralloc(CONFIG_DIR, "/", my_argv[1], "/", NULL);
+       my_argc--;
+       my_argv++;
     } else {
        char my_cwd[STR_SIZE];
 
-       if (getcwd(my_cwd, sizeof(my_cwd)) == NULL) {
+       if (getcwd(my_cwd, SIZEOF(my_cwd)) == NULL) {
            error("cannot determine current working directory");
+           /*NOTREACHED*/
        }
        config_dir = stralloc2(my_cwd, "/");
        if ((config_name = strrchr(my_cwd, '/')) != NULL) {
@@ -268,35 +283,43 @@ char **main_argv;
 
     /* print prompts and debug messages if running interactive */
 
-    interactive = (main_argc > 1 && strcmp(main_argv[1],"-t") == 0);
-    if(interactive) {
+    interactive = (my_argc > 1 && strcmp(my_argv[1],"-t") == 0);
+    if (interactive) {
        erroutput_type = ERR_INTERACTIVE;
     } else {
        erroutput_type = ERR_AMANDALOG;
        set_logerror(logerror);
     }
 
+    free_new_argv(new_argc, new_argv);
+
     conffile = stralloc2(config_dir, CONFFILE_NAME);
-    if(read_conffile(conffile)) {
+    if (read_conffile(conffile)) {
        error("errors processing config file \"%s\"", conffile);
+       /*NOTREACHED*/
     }
     amfree(conffile);
 
+    dbrename(config_name, DBG_SUBDIR_SERVER);
+
+    report_bad_conf_arg();
+
     conf_tapelist = getconf_str(CNF_TAPELIST);
     if (*conf_tapelist == '/') {
        conf_tapelist = stralloc(conf_tapelist);
     } else {
        conf_tapelist = stralloc2(config_dir, conf_tapelist);
     }
-    if(read_tapelist(conf_tapelist)) {
+    if (read_tapelist(conf_tapelist)) {
        error("could not load tapelist \"%s\"", conf_tapelist);
+       /*NOTREACHED*/
     }
 
-    tapedev    = getconf_str(CNF_TAPEDEV);
+    tapedev    = stralloc(getconf_str(CNF_TAPEDEV));
     tapetype    = getconf_str(CNF_TAPETYPE);
     tt         = lookup_tapetype(tapetype);
 #ifdef HAVE_LIBVTBLC
-    rawtapedev = getconf_str(CNF_RAWTAPEDEV);
+    rawtapedev = stralloc(getconf_str(CNF_RAWTAPEDEV));
 #endif /* HAVE_LIBVTBLC */
     tapedays   = getconf_int(CNF_TAPECYCLE);
     labelstr   = getconf_str(CNF_LABELSTR);
@@ -306,38 +329,52 @@ char **main_argv;
 
     conf_tapebufs = getconf_int(CNF_TAPEBUFS);
 
-    tt_blocksize_kb = tt->blocksize;
+    tt_blocksize_kb = (size_t)tapetype_get_blocksize(tt);
     tt_blocksize = tt_blocksize_kb * 1024;
-    tt_file_pad = tt->file_pad;
+    tt_file_pad = tapetype_get_file_pad(tt);
 
-    if(interactive) {
+    if (interactive) {
        fprintf(stderr,"taper: running in interactive test mode\n");
+       dbprintf(("taper: running in interactive test mode\n"));
        fflush(stderr);
     }
 
     /* create read/write syncronization pipes */
 
-    if(pipe(p2c) || pipe(c2p))
+    if (pipe(p2c)) {
+       error("creating sync pipes: %s", strerror(errno));
+       /*NOTREACHED*/
+    }
+    if (pipe(c2p)) {
        error("creating sync pipes: %s", strerror(errno));
+       /*NOTREACHED*/
+    }
 
     /* create shared memory segment */
 
 #if defined(HAVE_GETPAGESIZE)
-    page_size = getpagesize();
-    fprintf(stderr, "%s: page size is %d\n", get_pname(), page_size);
+    page_size = (size_t)getpagesize();
+    fprintf(stderr, "%s: page size = " SIZE_T_FMT "\n",
+               get_pname(), (SIZE_T_FMT_TYPE)page_size);
+    dbprintf(("%s: page size = " SIZE_T_FMT "\n", get_pname(),
+               (SIZE_T_FMT_TYPE)page_size));
 #else
     page_size = 1024;
-    fprintf(stderr, "%s: getpagesize() not available, using %d\n",
-           get_pname(),
-           page_size);
+    fprintf(stderr, "%s: getpagesize() not available, using " SIZE_T_FMT "\n",
+           get_pname(), page_size);
+    dbprintf((stderr, "%s: getpagesize() not available, using " SIZE_T_FMT "\n",
+           get_pname(), page_size));
 #endif
     buffer_size = am_round(tt_blocksize, page_size);
-    fprintf(stderr, "%s: buffer size is %ld\n", get_pname(), buffer_size);
-    while(conf_tapebufs > 0) {
+    fprintf(stderr, "%s: buffer size is " SIZE_T_FMT "\n",
+           get_pname(), (SIZE_T_FMT_TYPE)buffer_size);
+    dbprintf(("%s: buffer size is " SIZE_T_FMT "\n",
+           get_pname(), (SIZE_T_FMT_TYPE)buffer_size));
+    while (conf_tapebufs > 0) {
        size  = page_size;
        size += conf_tapebufs * buffer_size;
-       size += conf_tapebufs * sizeof(buffer_t);
-       if((buffers = attach_buffers(size)) != NULL) {
+       size += conf_tapebufs * SIZEOF(buffer_t);
+       if ((buffers = attach_buffers(size)) != NULL) {
            break;
        }
        log_add(L_INFO, "attach_buffers: (%d tapebuf%s: %d bytes) %s",
@@ -347,45 +384,50 @@ char **main_argv;
                        strerror(errno));
        conf_tapebufs--;
     }
-    if(buffers == NULL) {
+    if (buffers == NULL) {
        error("cannot allocate shared memory");
+       /*NOTREACHED*/
     }
-    i = (buffers - (char *)0) & (page_size - 1);  /* page boundary offset */
-    if(i != 0) {
+
+    /* page boundary offset */
+    i = (int)((buffers - (char *)0) & (page_size - 1));
+    if (i != 0) {
        first_buffer = buffers + page_size - i;
-       fprintf(stderr, "%s: shared memory at %p, first buffer at %p\n",
+       dbprintf(("%s: shared memory at %p, first buffer at %p\n",
                get_pname(),
-               buffers,
-               first_buffer);
+               (void *)buffers,
+               (void *)first_buffer));
     } else {
        first_buffer = buffers;
     }
-    buftable = (buffer_t *)(first_buffer + conf_tapebufs * buffer_size);
-    memset(buftable, 0, conf_tapebufs * sizeof(buffer_t));
-    if(conf_tapebufs < 10) {
+
+    /*LINTED  first_buffer, conf_tapebufs and buffer size are all * pagesize */
+    buftable = (buffer_t *)(first_buffer + (conf_tapebufs * buffer_size));
+    memset(buftable, 0, conf_tapebufs * SIZEOF(buffer_t));
+    if (conf_tapebufs < 10) {
        j = 1;
-    } else if(conf_tapebufs < 100) {
+    } else if (conf_tapebufs < 100) {
        j = 2;
     } else {
        j = 3;
     }
-    for(i = 0; i < conf_tapebufs; i++) {
+    for (i = 0; i < conf_tapebufs; i++) {
        buftable[i].buffer = first_buffer + i * buffer_size;
-       fprintf(stderr, "%s: buffer[%0*d] at %p\n",
+       dbprintf(("%s: buffer[%0*d] at %p\n",
                get_pname(),
-               j, i,
-               buftable[i].buffer);
+               (int)j, i,
+               (void *)buftable[i].buffer));
     }
-    fprintf(stderr, "%s: buffer structures at %p for %d bytes\n",
+    dbprintf(("%s: buffer structures at %p for %d bytes\n",
            get_pname(),
-           buftable,
-           (int)(conf_tapebufs * sizeof(buffer_t)));
+           (void *)buftable,
+           (int)(conf_tapebufs * SIZEOF(buffer_t))));
 
     /* fork off child writer process, parent becomes reader process */
-
     switch(writerpid = fork()) {
     case -1:
        error("fork: %s", strerror(errno));
+       /*NOTREACHED*/
 
     case 0:    /* child */
        aclose(p2c[1]);
@@ -393,6 +435,7 @@ char **main_argv;
 
        tape_writer_side(p2c[0], c2p[1]);
        error("tape writer terminated unexpectedly");
+       /*NOTREACHED*/
 
     default:   /* parent */
        aclose(p2c[0]);
@@ -400,9 +443,10 @@ char **main_argv;
 
        file_reader_side(c2p[0], p2c[1]);
        error("file reader terminated unexpectedly");
+       /*NOTREACHED*/
     }
 
-    /* NOTREACHED */
+    /*NOTREACHED*/
     return 0;
 }
 
@@ -412,33 +456,34 @@ char **main_argv;
  * FILE READER SIDE
  *
  */
-int read_file P((int fd, char *handle,
+int read_file(int fd, char *handle,
                  char *host, char *disk, char *datestamp, 
-                 int level));
-int taper_fill_buffer P((int fd, buffer_t *bp, int buflen));
-void dumpbufs P((char *str1));
-void dumpstatus P((buffer_t *bp));
-int get_next_holding_file P((int fd, buffer_t *bp, char *strclosing, int rc));
-int predict_splits P((char *filename));
-void create_split_buffer P((char *split_diskbuffer, long fallback_splitsize, char *id_string));
-void free_split_buffer P(());
+                 int level);
+ssize_t taper_fill_buffer(int fd, buffer_t *bp, size_t buflen);
+void dumpbufs(char *str1);
+void dumpstatus(buffer_t *bp);
+ssize_t get_next_holding_file(int fd, buffer_t *bp, char **strclosing, size_t rc);
+int predict_splits(char *filename);
+void create_split_buffer(char *split_diskbuffer, size_t fallback_splitsize, char *id_string);
+void free_split_buffer(void);
 
 
 /*
  * Create a buffer, either in an mmapped file or in memory, where PORT-WRITE
  * dumps can buffer the current split chunk in case of retry.
  */
-void create_split_buffer(split_diskbuffer, fallback_splitsize, id_string)
-char *split_diskbuffer;
-long fallback_splitsize;
-char *id_string;
+void
+create_split_buffer(
+    char *split_diskbuffer,
+    size_t fallback_splitsize,
+    char *id_string)
 {
     char *buff_err = NULL;
-    void *nulls = NULL;
-    int c;
+    off_t offset;
+    char *splitbuffer_path = NULL;
     
     /* don't bother if we're not actually splitting */
-    if(splitsize <= 0){
+    if (splitsize <= (off_t)0) {
        splitbuf = NULL;
        splitbuf_wr_ptr = NULL;
        return;
@@ -446,56 +491,107 @@ char *id_string;
 
 #ifdef HAVE_MMAP
 #ifdef HAVE_SYS_MMAN_H
-    if(strcmp(split_diskbuffer, "NULL")){
+    if (strcmp(split_diskbuffer, "NULL")) {
+       void *nulls = NULL;
+       char *quoted;
+       off_t c;
+
        splitbuffer_path = vstralloc(split_diskbuffer,
-                                    "/splitdump_buffer_XXXXXX",
+                                    "/splitdump_buffer",
                                     NULL);
-#ifdef HAVE_MKSTEMP
-       splitbuffer_fd = mkstemp(splitbuffer_path);
-#else
-       log_add(L_INFO, "mkstemp not available, using plain open() for split buffer- make sure %s has safe permissions", split_diskbuffer);
-       splitbuffer_fd = open(splitbuffer_path, O_RDWR|O_CREAT, 0600);
-#endif
-       if(splitbuffer_fd == -1){
-           buff_err = newvstralloc(buff_err, "mkstemp/open of ", 
-                                   splitbuffer_path, "failed (",
-                                   strerror(errno), ")", NULL);
-           goto fallback;
+       /* different file, munmap the previous */
+       if (mmap_filename && strcmp(mmap_filename, splitbuffer_path) != 0) {
+           dbprintf(("create_split_buffer: new file %s\n", splitbuffer_path));
+           munmap(splitbuf, (size_t)mmap_splitsize);
+           aclose(mmap_splitbuffer_fd);
+           mmap_splitbuf = NULL;
+           amfree(mmap_filename);
+           mmap_splitsize = 0;
        }
-       nulls = alloc(1024); /* lame */
-       memset(nulls, 0, 1024);
-       for(c = 0; c < splitsize ; c++) {
-           if(fullwrite(splitbuffer_fd, nulls, 1024) < 1024){
-               buff_err = newvstralloc(buff_err, "write to ", splitbuffer_path,
-                                       "failed (", strerror(errno), ")", NULL);
-               free_split_buffer();
+       if (!mmap_filename) {
+           dbprintf(("create_split_buffer: open file %s\n",
+                     splitbuffer_path));
+           mmap_splitbuffer_fd = open(splitbuffer_path, O_RDWR|O_CREAT, 0600);
+           if (mmap_splitbuffer_fd == -1) {
+               buff_err = newvstralloc(buff_err, "open of ", 
+                                       splitbuffer_path, "failed (",
+                                       strerror(errno), ")", NULL);
                goto fallback;
            }
        }
+       offset = lseek(mmap_splitbuffer_fd, (off_t)0, SEEK_END) / 1024;
+       if (offset < splitsize) { /* Increase file size */
+           dbprintf(("create_split_buffer: increase file size of %s to "
+                     OFF_T_FMT "kb\n",
+                     splitbuffer_path, (OFF_T_FMT_TYPE)splitsize));
+           if (mmap_filename) {
+               dbprintf(("create_split_buffer: munmap old file %s\n",
+                         mmap_filename));
+               munmap(splitbuf, (size_t)mmap_splitsize);
+               mmap_splitsize = 0;
+               mmap_splitbuf = NULL;
+           }
+           nulls = alloc(1024); /* lame */
+           memset(nulls, 0, 1024);
+           for (c = offset; c < splitsize ; c += (off_t)1) {
+               if (fullwrite(mmap_splitbuffer_fd, nulls, 1024) < 1024) {
+                   buff_err = newvstralloc(buff_err, "write to ",
+                                           splitbuffer_path,
+                                           "failed (", strerror(errno),
+                                           ")", NULL);
+                   c -= 1;
+                   if (c <= (off_t)fallback_splitsize) {
+                       goto fallback;
+                   }
+                   splitsize = c;
+                   break;
+               }
+           }
+       }
        amfree(nulls);
 
-        splitbuf = mmap(NULL, (size_t)splitsize*1024, PROT_READ|PROT_WRITE,
-                       MAP_SHARED, splitbuffer_fd, (off_t)0);
-       if(splitbuf == (char*)-1){
-           buff_err = newvstralloc(buff_err, "mmap failed (", strerror(errno),
-                                   ")", NULL);
-           free_split_buffer();
-           goto fallback;
+       if (mmap_splitsize < splitsize*1024) {
+           mmap_splitsize = splitsize*1024;
+           mmap_filename = stralloc(splitbuffer_path);
+           dbprintf(("create_split_buffer: mmap file %s for " OFF_T_FMT "kb\n",
+                         mmap_filename,(OFF_T_FMT_TYPE)splitsize));
+            mmap_splitbuf = mmap(NULL, (size_t)mmap_splitsize,
+                                PROT_READ|PROT_WRITE,
+                                MAP_SHARED, mmap_splitbuffer_fd, (off_t)0);
+           if (mmap_splitbuf == (char*)-1) {
+               buff_err = newvstralloc(buff_err, "mmap failed (",
+                                       strerror(errno), ")", NULL);
+               aclose(mmap_splitbuffer_fd);
+               amfree(mmap_filename);
+               mmap_splitsize = 0;
+               mmap_splitbuf = NULL;
+               goto fallback;
+           }
        }
+       quoted = quote_string(splitbuffer_path);
        fprintf(stderr,
-               "taper: r: buffering %ldkb split chunks in mmapped file %s\n",
-               splitsize, splitbuffer_path);
+               "taper: r: buffering " OFF_T_FMT
+               "kb split chunks in mmapped file %s\n",
+               (OFF_T_FMT_TYPE)splitsize, quoted);
+       dbprintf(("taper: r: buffering " OFF_T_FMT
+               "kb split chunks in mmapped file %s\n",
+               (OFF_T_FMT_TYPE)splitsize, quoted));
+       amfree(splitbuffer_path);
+       amfree(quoted);
+       amfree(buff_err);
+       splitbuf = mmap_splitbuf;
        splitbuf_wr_ptr = splitbuf;
        return;
-    }
-    else{
+    } else {
        buff_err = stralloc("no split_diskbuffer specified");
     }
 #else
+    (void)split_diskbuffer;    /* Quite unused parameter warning */
     buff_err = stralloc("mman.h not available");
     goto fallback;
 #endif
 #else
+    (void)split_diskbuffer;    /* Quite unused parameter warning */
     buff_err = stralloc("mmap not available");
     goto fallback;
 #endif
@@ -504,64 +600,93 @@ char *id_string;
       Buffer split dumps in memory, if we can't use a file.
     */
     fallback:
-        splitsize = fallback_splitsize;
+       amfree(splitbuffer_path);
+        splitsize = (off_t)fallback_splitsize;
+       dbprintf(("create_split_buffer: fallback size " OFF_T_FMT "\n",
+                 (OFF_T_FMT_TYPE)splitsize));
        log_add(L_INFO,
                "%s: using fallback split size of %dkb to buffer %s in-memory",
                buff_err, splitsize, id_string);
-       splitbuf = alloc(splitsize * 1024);
+       amfree(buff_err);
+       if (splitsize > mem_splitsize) {
+           amfree(mem_splitbuf);
+           mem_splitbuf = alloc(fallback_splitsize * 1024);
+           mem_splitsize = fallback_splitsize;
+           dbprintf(("create_split_buffer: alloc buffer size " OFF_T_FMT "\n",
+                         (OFF_T_FMT_TYPE)splitsize *1024));
+       }
+       splitbuf = mem_splitbuf;
        splitbuf_wr_ptr = splitbuf;
 }
 
 /*
  * Free up resources that create_split_buffer eats.
  */
-void free_split_buffer()
+void
+free_split_buffer(void)
 {
-    if(splitbuffer_fd != -1){
+    if (mmap_splitbuffer_fd != -1) {
 #ifdef HAVE_MMAP
 #ifdef HAVE_SYS_MMAN_H
-       if(splitbuf != NULL) munmap(splitbuf, splitsize);
+       if (splitbuf != NULL)
+           munmap(splitbuf, (size_t)mmap_splitsize);
 #endif
 #endif
-       aclose(splitbuffer_fd);
-       splitbuffer_fd = -1;
-
-       if(unlink(splitbuffer_path) == -1){
-           log_add(L_WARNING, "Failed to unlink %s: %s",
-                   splitbuffer_path, strerror(errno));
-       }
-       amfree(splitbuffer_path);
-       splitbuffer_path = NULL;
+       aclose(mmap_splitbuffer_fd);
+       amfree(mmap_filename);
+       mmap_splitsize = 0;
     }
-    else if(splitbuf){
+    if (mem_splitbuf) {
        amfree(splitbuf);
-       splitbuf = NULL;
+       mem_splitsize = 0;
     }
 }
 
+void
+put_syncpipe_fault_result(
+    char *     handle)
+{
+    char *q;
+
+    if (handle == NULL)
+       handle = "<nohandle>";
+
+    q = squotef("[Taper syncpipe fault]");
+    putresult(TAPE_ERROR, "%s %s\n", handle, q);
+    log_add(L_ERROR, "tape-error %s %s", handle, q);
+    amfree(q);
+}
 
-void file_reader_side(rdpipe, wrpipe)
-int rdpipe, wrpipe;
+void
+file_reader_side(
+    int rdpipe,
+    int wrpipe)
 {
     cmd_t cmd;
     struct cmdargs cmdargs;
     char *handle = NULL;
     char *filename = NULL;
+    char *qfilename = NULL;
     char *hostname = NULL;
     char *diskname = NULL;
+    char *qdiskname = NULL;
     char *result = NULL;
     char *datestamp = NULL;
     char *split_diskbuffer = NULL;
     char *id_string = NULL;
-    char tok;
+    int tok;
     char *q = NULL;
-    int level, fd, data_port, data_socket, wpid;
+    int level, fd;
+    in_port_t data_port;
+    int data_socket;
+    pid_t wpid;
     char level_str[64];
     struct stat stat_file;
     int tape_started;
     int a;
-    long fallback_splitsize = 0;
+    size_t fallback_splitsize = 0;
     int tmpint;
+    char *c, *c1;
 
     procname = "reader";
     syncpipe_init(rdpipe, wrpipe);
@@ -572,48 +697,92 @@ int rdpipe, wrpipe;
     cmd = getcmd(&cmdargs);
     total_wait = stopclock();
 
-    if(cmd != START_TAPER || cmdargs.argc != 2) {
+    if (cmd != START_TAPER || cmdargs.argc != 2) {
        error("error [file_reader_side cmd %d argc %d]", cmd, cmdargs.argc);
+       /*NOTREACHED*/
     }
 
     /* pass start command on to tape writer */
 
-    taper_datestamp = newstralloc(taper_datestamp, cmdargs.argv[2]);
+    taper_timestamp = newstralloc(taper_timestamp, cmdargs.argv[2]);
 
     tape_started = 0;
-    syncpipe_put('S', 0);
-    syncpipe_putstr(taper_datestamp);
+    if (syncpipe_put('S', 0) == -1) {
+       put_syncpipe_fault_result(NULL);
+    }
+
+    if (syncpipe_putstr(taper_timestamp) == -1) {
+       put_syncpipe_fault_result(NULL);
+    }
 
     /* get result of start command */
 
     tok = syncpipe_get(&tmpint);
     switch(tok) {
+    case -1:
+       put_syncpipe_fault_result(NULL);
+       break;
+
     case 'S':
        putresult(TAPER_OK, "\n");
        tape_started = 1;
        /* start is logged in writer */
        break;
+
     case 'E':
        /* no tape, bail out */
-       result = syncpipe_getstr();
-       q = squotef("[%s]", result ? result : "(null)");
-       putresult(TAPE_ERROR, "%s\n", q);
-       amfree(q);
-       log_add(L_ERROR,"no-tape [%s]", "No writable valid tape found");
-       amfree(result);
-       syncpipe_put('e', 0);                   /* ACK error */
+       if ((result = syncpipe_getstr()) == NULL) {
+           put_syncpipe_fault_result(NULL);
+       } else {
+           q = squotef("[%s]", result);
+           putresult(TAPE_ERROR, "<nohandle> %s\n", q);
+           amfree(q);
+           log_add(L_ERROR,"no-tape [%s]", "No writable valid tape found");
+           c = c1 = result;
+           while (*c != '\0') {
+               if (*c == '\n') {
+                   *c = '\0';
+                   log_add(L_WARNING,"%s", c1);
+                   c1 = c+1;
+               }
+               c++;
+           }
+           if (strlen(c1) > 1 )
+               log_add(L_WARNING,"%s", c1);
+           amfree(result);
+           (void)syncpipe_put('e', 0);                 /* ACK error */
+       }
+       break;
+
+    case 'H': /* Syncpipe I/O error */
+       /* No ACK syncpipe is down just exit */
+        put_syncpipe_fault_result(handle);
        break;
+
+    case 'X':
+       /*
+        * Pipe read error: Communications is severed at least
+        * back to us.  We send a blind 'Q' (quit) and we don't
+        * wait for a response...
+        */
+       syncpipe_put('Q', 0);                   /* ACK error */
+       error("error [communications pipe from writer severed]");
+       /*NOTREACHED*/
+
     default:
-       error("expected 'S' or 'E' for START-TAPER, got '%c'", tok);
+       q = squotef("[syncpipe sequence fault: Expected 'S' or 'E']");
+       putresult(TAPE_ERROR, "<nohandle> %s\n", q);
+       log_add(L_ERROR, "no-tape %s]", q);
+       amfree(q);
     }
 
-    /* process further commands */
-
-    while(1) {
+    /* process further driver commands */
+    while (1) {
        startclock();
        cmd = getcmd(&cmdargs);
-       if(cmd != QUIT && !tape_started) {
+       if (cmd != QUIT && !tape_started) {
            error("error [file_reader_side cmd %d without tape ready]", cmd);
+           /*NOTREACHED*/
        }
        total_wait = timesadd(total_wait, stopclock());
 
@@ -634,67 +803,86 @@ int rdpipe, wrpipe;
            cmdargs.argc++;                     /* true count of args */
            a = 2;
 
-           if(a >= cmdargs.argc) {
+           if (a >= cmdargs.argc) {
                error("error [taper PORT-WRITE: not enough args: handle]");
+               /*NOTREACHED*/
            }
            handle = newstralloc(handle, cmdargs.argv[a++]);
 
-           if(a >= cmdargs.argc) {
+           if (a >= cmdargs.argc) {
                error("error [taper PORT-WRITE: not enough args: hostname]");
+               /*NOTREACHED*/
            }
            hostname = newstralloc(hostname, cmdargs.argv[a++]);
 
-           if(a >= cmdargs.argc) {
+           if (a >= cmdargs.argc) {
                error("error [taper 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) {
+           if (a >= cmdargs.argc) {
                error("error [taper 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) {
+           if (a >= cmdargs.argc) {
                error("error [taper PORT-WRITE: not enough args: level]");
+               /*NOTREACHED*/
            }
            level = atoi(cmdargs.argv[a++]);
 
-           if(a >= cmdargs.argc) {
+           if (a >= cmdargs.argc) {
                error("error [taper PORT-WRITE: not enough args: datestamp]");
+               /*NOTREACHED*/
            }
            datestamp = newstralloc(datestamp, cmdargs.argv[a++]);
 
-           if(a >= cmdargs.argc) {
+           if (a >= cmdargs.argc) {
                error("error [taper PORT-WRITE: not enough args: splitsize]");
+               /*NOTREACHED*/
            }
-           splitsize = atoi(cmdargs.argv[a++]);
+           splitsize = OFF_T_ATOI(cmdargs.argv[a++]);
 
-           if(a >= cmdargs.argc) {
+           if (a >= cmdargs.argc) {
                error("error [taper PORT-WRITE: not enough args: split_diskbuffer]");
+               /*NOTREACHED*/
            }
            split_diskbuffer = newstralloc(split_diskbuffer, cmdargs.argv[a++]);
 
-           if(a >= cmdargs.argc) {
+           if (a >= cmdargs.argc) {
                error("error [taper PORT-WRITE: not enough args: fallback_splitsize]");
+               /*NOTREACHED*/
            }
-           fallback_splitsize = atoi(cmdargs.argv[a++]);
+           /* Must fit in memory... */
+           fallback_splitsize = (size_t)atoi(cmdargs.argv[a++]);
 
-           if(a != cmdargs.argc) {
+           if (a != cmdargs.argc) {
                error("error [taper file_reader_side PORT-WRITE: too many args: %d != %d]",
                      cmdargs.argc, a);
+               /*NOTREACHED*/
            }
 
-           snprintf(level_str, sizeof(level_str), "%d", level);
-           id_string = newvstralloc(id_string, hostname, ":", diskname, ".",
+           if (fallback_splitsize < 128 ||
+               fallback_splitsize > 64 * 1024 * 1024) {
+               error("error [bad value for fallback_splitsize]");
+               /*NOTREACHED*/
+           }
+           snprintf(level_str, SIZEOF(level_str), "%d", level);
+           id_string = newvstralloc(id_string, hostname, ":", qdiskname, ".",
                                     level_str, NULL);
 
            create_split_buffer(split_diskbuffer, fallback_splitsize, id_string);
            amfree(id_string);
 
            data_port = 0;
-           data_socket = stream_server(&data_port, -1, STREAM_BUFSIZE);        
-           if(data_socket < 0) {
+           data_socket = stream_server(&data_port, 0, STREAM_BUFSIZE, 0);      
+           if (data_socket < 0) {
                char *m;
 
                m = vstralloc("[port create failure: ",
@@ -709,8 +897,8 @@ int rdpipe, wrpipe;
            }
            putresult(PORT, "%d\n", data_port);
 
-           if((fd = stream_accept(data_socket, CONNECT_TIMEOUT,
-                                  -1, NETWORK_BLOCK_BYTES)) == -1) {
+           if ((fd = stream_accept(data_socket, CONNECT_TIMEOUT,
+                                  0, STREAM_BUFSIZE)) == -1) {
                q = squote("[port connect timeout]");
                putresult(TAPE_ERROR, "%s %s\n", handle, q);
                aclose(data_socket);
@@ -719,10 +907,10 @@ int rdpipe, wrpipe;
            }
            expected_splits = -1;
 
-           while(read_file(fd,handle,hostname,diskname,datestamp,level));
+           while(read_file(fd, handle, hostname, qdiskname, datestamp, level))
+               (void)fd;  /* Quiet lint */
 
            aclose(data_socket);
-           free_split_buffer();
            break;
 
        case FILE_WRITE:
@@ -741,65 +929,80 @@ int rdpipe, wrpipe;
            cmdargs.argc++;                     /* true count of args */
            a = 2;
 
-           if(a >= cmdargs.argc) {
+           if (a >= cmdargs.argc) {
                error("error [taper FILE-WRITE: not enough args: handle]");
+               /*NOTREACHED*/
            }
            handle = newstralloc(handle, cmdargs.argv[a++]);
 
-           if(a >= cmdargs.argc) {
+           if (a >= cmdargs.argc) {
                error("error [taper FILE-WRITE: not enough args: filename]");
+               /*NOTREACHED*/
            }
-           filename = newstralloc(filename, cmdargs.argv[a++]);
+           qfilename = newstralloc(qfilename, cmdargs.argv[a++]);
+           if (filename != NULL)
+               amfree(filename);
+           filename = unquote_string(qfilename);
 
-           if(a >= cmdargs.argc) {
+           if (a >= cmdargs.argc) {
                error("error [taper FILE-WRITE: not enough args: hostname]");
+               /*NOTREACHED*/
            }
            hostname = newstralloc(hostname, cmdargs.argv[a++]);
 
-           if(a >= cmdargs.argc) {
+           if (a >= cmdargs.argc) {
                error("error [taper FILE-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) {
+           if (a >= cmdargs.argc) {
                error("error [taper FILE-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) {
+           if (a >= cmdargs.argc) {
                error("error [taper FILE-WRITE: not enough args: level]");
+               /*NOTREACHED*/
            }
            level = atoi(cmdargs.argv[a++]);
 
-           if(a >= cmdargs.argc) {
+           if (a >= cmdargs.argc) {
                error("error [taper FILE-WRITE: not enough args: datestamp]");
+               /*NOTREACHED*/
            }
            datestamp = newstralloc(datestamp, cmdargs.argv[a++]);
 
-           if(a >= cmdargs.argc) {
+           if (a >= cmdargs.argc) {
                error("error [taper FILE-WRITE: not enough args: splitsize]");
+               /*NOTREACHED*/
            }
-           splitsize = atoi(cmdargs.argv[a++]);
+           splitsize = OFF_T_ATOI(cmdargs.argv[a++]);
 
-           if(a != cmdargs.argc) {
+           if (a != cmdargs.argc) {
                error("error [taper file_reader_side FILE-WRITE: too many args: %d != %d]",
                      cmdargs.argc, a);
+               /*NOTREACHED*/
            }
-           if(holdfile_name != NULL) {
+           if (holdfile_name != NULL) {
                filename = newstralloc(filename, holdfile_name);
            }
 
-           if((expected_splits = predict_splits(filename)) < 0) {
+           if ((expected_splits = predict_splits(filename)) < 0) {
                break;
            }
-           if(stat(filename, &stat_file)!=0) {
+           if (stat(filename, &stat_file)!=0) {
                q = squotef("[%s]", strerror(errno));
                putresult(TAPE_ERROR, "%s %s\n", handle, q);
                amfree(q);
                break;
            }
-           if((fd = open(filename, O_RDONLY)) == -1) {
+           if ((fd = open(filename, O_RDONLY)) == -1) {
                q = squotef("[%s]", strerror(errno));
                putresult(TAPE_ERROR, "%s %s\n", handle, q);
                amfree(q);
@@ -809,17 +1012,16 @@ int rdpipe, wrpipe;
            holdfile_path_thischunk = stralloc(filename);
            holdfile_offset_thischunk = (off_t)0;
 
-           while(read_file(fd,handle,hostname,diskname,datestamp,level)){
-               if(splitsize > 0 && holdfile_path_thischunk)
+           while (read_file(fd,handle,hostname,qdiskname,datestamp,level)) {
+               if (splitsize > (off_t)0 && holdfile_path_thischunk)
                    filename = newstralloc(filename, holdfile_path_thischunk);
-               if((fd = open(filename, O_RDONLY)) == -1) {
+               if ((fd = open(filename, O_RDONLY)) == -1) {
                    q = squotef("[%s]", strerror(errno));
                    putresult(TAPE_ERROR, "%s %s\n", handle, q);
                    amfree(q);
                    break;
                }
            }
-
            break;
 
        case QUIT:
@@ -827,40 +1029,45 @@ int rdpipe, wrpipe;
            fprintf(stderr,"taper: DONE [idle wait: %s secs]\n",
                    walltime_str(total_wait));
            fflush(stderr);
-           syncpipe_put('Q', 0);       /* tell writer we're exiting gracefully */
+           (void)syncpipe_put('Q', 0); /* tell writer we're exiting gracefully */
            aclose(wrpipe);
 
-           if((wpid = wait(NULL)) != writerpid) {
+           if ((wpid = wait(NULL)) != writerpid) {
+               dbprintf(("taper: writer wait returned %u instead of %u: %s\n",
+                       (unsigned)wpid, (unsigned)writerpid, strerror(errno)));
                fprintf(stderr,
-                       "taper: writer wait returned %d instead of %d: %s\n",
-                       wpid, writerpid, strerror(errno));
+                       "taper: writer wait returned %u instead of %u: %s\n",
+                       (unsigned)wpid, (unsigned)writerpid, strerror(errno));
                fflush(stderr);
            }
 
-           if (datestamp != NULL)
-               amfree(datestamp);
+           free_split_buffer();
+           amfree(datestamp);
+           clear_tapelist();
+           free_server_config();
+           amfree(taper_timestamp);
            amfree(label);
            amfree(errstr);
            amfree(changer_resultstr);
            amfree(tapedev);
-           amfree(conf_tapelist);
            amfree(filename);
+           amfree(conf_tapelist);
            amfree(config_dir);
            amfree(config_name);
-           if(holdfile_name != NULL) amfree(holdfile_name);
+           amfree(holdfile_name);
 
            malloc_size_2 = malloc_inuse(&malloc_hist_2);
 
-           if(malloc_size_1 != malloc_size_2) {
+           if (malloc_size_1 != malloc_size_2) {
                malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2);
            }
-
            exit(0);
+           /*NOTREACHED*/
 
        default:
-           if(cmdargs.argc >= 1) {
+           if (cmdargs.argc >= 1) {
                q = squote(cmdargs.argv[1]);
-           } else if(cmdargs.argc >= 0) {
+           } else if (cmdargs.argc >= 0) {
                q = squote(cmdargs.argv[0]);
            } else {
                q = stralloc("(no input?)");
@@ -870,42 +1077,52 @@ int rdpipe, wrpipe;
            break;
        }
     }
-    amfree(handle);
-    am_release_feature_set(their_features);
-    amfree(hostname);
-    amfree(diskname);
-    fprintf(stderr, "TAPER AT END OF READER SIDE\n");
+    /* NOTREACHED */
 }
 
-void dumpbufs(str1)
-char *str1;
+void
+dumpbufs(
+    char *str1)
 {
     int i,j;
     long v;
 
     fprintf(stderr, "%s: state", str1);
-    for(i = j = 0; i < conf_tapebufs; i = j+1) {
+    for (i = j = 0; i < conf_tapebufs; i = j+1) {
        v = buftable[i].status;
-       for(j = i; j < conf_tapebufs && buftable[j].status == v; j++);
+       for(j = i; j < conf_tapebufs && buftable[j].status == v; j++)
+           (void)j; /* Quiet lint */
        j--;
-       if(i == j) fprintf(stderr, " %d:", i);
-       else fprintf(stderr, " %d-%d:", i, j);
+       if (i == j) {
+           fprintf(stderr, " %d:", i);
+       } else {
+           fprintf(stderr, " %d-%d:", i, j);
+       }
        switch(v) {
-       case FULL:      fputc('F', stderr); break;
-       case FILLING:   fputc('f', stderr); break;
-       case EMPTY:     fputc('E', stderr); break;
+       case FULL:
+           fputc('F', stderr);
+           break;
+
+       case FILLING:
+           fputc('f', stderr);
+           break;
+
+       case EMPTY:
+           fputc('E', stderr);
+           break;
+
        default:
            fprintf(stderr, "%ld", v);
            break;
        }
-
     }
     fputc('\n', stderr);
     fflush(stderr);
 }
 
-void dumpstatus(bp)
-buffer_t *bp;
+void
+dumpstatus(
+    buffer_t *bp)
 {
     char pn[2];
     char bt[NUM_STR_SIZE];
@@ -914,15 +1131,24 @@ buffer_t *bp;
 
     pn[0] = procname[0];
     pn[1] = '\0';
-    snprintf(bt, sizeof(bt), "%d", (int)(bp-buftable));
+    snprintf(bt, SIZEOF(bt), "%d", (int)(bp-buftable));
 
     switch(bp->status) {
-    case FULL:         snprintf(status, sizeof(status), "F%d", bp->size);
-                       break;
-    case FILLING:      status[0] = 'f'; status[1] = '\0'; break;
-    case EMPTY:                status[0] = 'E'; status[1] = '\0'; break;
+    case FULL:
+       snprintf(status, SIZEOF(status), "F" SIZE_T_FMT,
+               (SIZE_T_FMT_TYPE)bp->size);
+       break;
+
+    case FILLING:
+       snprintf(status, SIZEOF(status), "f");
+       break;
+
+    case EMPTY:
+       snprintf(status, SIZEOF(status), "E");
+       break;
+
     default:
-       snprintf(status, sizeof(status), "%ld", bp->status);
+       snprintf(status, SIZEOF(status), "%ld", bp->status);
        break;
     }
 
@@ -938,109 +1164,126 @@ buffer_t *bp;
   be another global.  What is rc anyway, 'read count?' I keep thinking it
   should be 'return code')
 */
-int get_next_holding_file(fd, bp, strclosing, rc)
-     int fd;
-     buffer_t *bp;
-     char *strclosing;
+ssize_t
+get_next_holding_file(
+    int fd,
+    buffer_t *bp,
+    char **strclosing,
+    size_t rc)
 {
-    int save_fd, rc1;
+    int save_fd;
+    ssize_t rc1;
     struct stat stat_file;
-    int ret = -1;
+    ssize_t ret = -1;
     
     save_fd = fd;
     close(fd);
     
     /* see if we're fresh out of file */
-    if(file.cont_filename[0] == '\0') {
+    if (file.cont_filename[0] == '\0') {
        err = 0;
        ret = 0;
-    } else if(stat(file.cont_filename, &stat_file) != 0) {
+    } else if (stat(file.cont_filename, &stat_file) != 0) {
        err = errno;
        ret = -1;
-       strclosing = newvstralloc(strclosing,"can't stat: ",file.cont_filename,NULL);
-    } else if((fd = open(file.cont_filename,O_RDONLY)) == -1) {
+       *strclosing = newvstralloc(*strclosing, "can't stat: ",
+                                  file.cont_filename, NULL);
+    } else if ((fd = open(file.cont_filename,O_RDONLY)) == -1) {
        err = errno;
        ret = -1;
-       strclosing = newvstralloc(strclosing,"can't open: ",file.cont_filename,NULL);
-    } else if((fd != save_fd) && dup2(fd, save_fd) == -1) {
+       *strclosing = newvstralloc(*strclosing, "can't open: ",
+                                  file.cont_filename, NULL);
+    } else if ((fd != save_fd) && dup2(fd, save_fd) == -1) {
        err = errno;
        ret = -1;
-       strclosing = newvstralloc(strclosing,"can't dup2: ",file.cont_filename,NULL);
+       *strclosing = newvstralloc(*strclosing, "can't dup2: ",
+                                  file.cont_filename, NULL);
     } else {
        buffer_t bp1;
+       char *quoted;
+
        holdfile_path = stralloc(file.cont_filename);
-       
-       fprintf(stderr, "taper: r: switching to next holding chunk '%s'\n", file.cont_filename); 
+       quoted = quote_string(holdfile_path);
+       fprintf(stderr, "taper: r: switching to next holding chunk '%s'\n",
+               quoted); 
+       amfree(quoted);
        num_holdfile_chunks++;
        
        bp1.status = EMPTY;
        bp1.size = DISK_BLOCK_BYTES;
-       bp1.buffer = malloc(DISK_BLOCK_BYTES);
+       bp1.buffer = alloc(DISK_BLOCK_BYTES);
        
-       if(fd != save_fd) {
+       if (fd != save_fd) {
            close(fd);
            fd = save_fd;
        }
        
        rc1 = taper_fill_buffer(fd, &bp1, DISK_BLOCK_BYTES);
-       if(rc1 <= 0) {
+       if (rc1 <= 0) {
            amfree(bp1.buffer);
            err = (rc1 < 0) ? errno : 0;
            ret = -1;
-           strclosing = newvstralloc(strclosing,
-                                     "Can't read header: ",
-                                     file.cont_filename,
-                                     NULL);
+           *strclosing = newvstralloc(*strclosing,
+                                      "Can't read header: ",
+                                      file.cont_filename,
+                                      NULL);
        } else {
-           parse_file_header(bp1.buffer, &file, rc1);
+           parse_file_header(bp1.buffer, &file, (size_t)rc1);
            
            amfree(bp1.buffer);
            bp1.buffer = bp->buffer + rc;
            
-           rc1 = taper_fill_buffer(fd, &bp1, tt_blocksize - rc);
-           if(rc1 <= 0) {
+           rc1 = taper_fill_buffer(fd, &bp1, (size_t)tt_blocksize - rc);
+           if (rc1 <= 0) {
                err = (rc1 < 0) ? errno : 0;
                ret = -1;
-               if(rc1 < 0) {
-                   strclosing = newvstralloc(strclosing,
-                                             "Can't read data: ",
-                                             file.cont_filename,
-                                             NULL);
+               if (rc1 < 0) {
+                   *strclosing = newvstralloc(*strclosing,
+                                              "Can't read data: ",
+                                              file.cont_filename,
+                                              NULL);
                }
-           }
-           else {
+           } else {
                ret = rc1;
                num_holdfiles++;
            }
        }
     }
-    
+
     return(ret);
 }
 
 
-int read_file(fd, handle, hostname, diskname, datestamp, level)
-    int fd, level;
-    char *handle, *hostname, *diskname, *datestamp;
+int
+read_file(
+    int                fd,
+    char *     handle,
+    char *     hostname,
+    char *     qdiskname,
+    char *     datestamp,
+    int                level)
 {
     buffer_t *bp;
-    char tok;
-    int rc, opening, closing, bufnum, need_closing, nexting;
-    long filesize;
+    int tok;
+    ssize_t rc;
+#ifdef ASSERTIONS
+    int opening;
+#endif
+    int closing, bufnum, need_closing, nexting;
+    off_t filesize;
     times_t runtime;
     char *strclosing = NULL;
     char seekerrstr[STR_SIZE];
     char *str;
     int header_written = 0;
-    int buflen;
+    size_t buflen;
     dumpfile_t first_file;
     dumpfile_t cur_holdfile;
-    long kbytesread = 0;
+    off_t kbytesread = (off_t)0;
     int header_read = 0;
     char *cur_filename = NULL;
     int retry_from_splitbuf = 0;
     char *splitbuf_rd_ptr = NULL;
-
     char *q = NULL;
 
 #ifdef HAVE_LIBVTBLC
@@ -1051,117 +1294,168 @@ int read_file(fd, handle, hostname, diskname, datestamp, level)
 
 
     /* initialize */
+    memset(&first_file, 0, SIZEOF(first_file));
+    memset(&cur_holdfile, 0, SIZEOF(cur_holdfile));
 
-    filesize = 0;
+    filesize = (off_t)0;
     closing = 0;
     need_closing = 0;
     nexting = 0;
     err = 0;
 
     /* don't break this if we're still on the same file as a previous init */
-    if(cur_span_chunkstart <= 0){
-    fh_init(&file);
-      header_read = 0;
-    }
-    else if(mode == MODE_FILE_WRITE){
-      memcpy(&file, save_holdfile, sizeof(dumpfile_t));
-      memcpy(&cur_holdfile, save_holdfile, sizeof(dumpfile_t));
+    if (cur_span_chunkstart <= (off_t)0) {
+       fh_init(&file);
+       header_read = 0;
+    } else if(mode == MODE_FILE_WRITE){
+       memcpy(&file, save_holdfile, SIZEOF(dumpfile_t));
+       memcpy(&cur_holdfile, save_holdfile, SIZEOF(dumpfile_t));
     }
 
-    if(bufdebug) {
+    if (bufdebug) {
        fprintf(stderr, "taper: r: start file\n");
        fflush(stderr);
     }
 
-    for(bp = buftable; bp < buftable + conf_tapebufs; bp++) {
+    for (bp = buftable; bp < buftable + conf_tapebufs; bp++) {
        bp->status = EMPTY;
     }
 
     bp = buftable;
-    if(interactive || bufdebug) dumpstatus(bp);
+    if (interactive || bufdebug)
+       dumpstatus(bp);
 
-    if(cur_span_chunkstart >= 0 && splitsize > 0){
+    if ((cur_span_chunkstart >= (off_t)0) && (splitsize > (off_t)0)) {
         /* We're supposed to start at some later part of the file, not read the
           whole thing. "Seek" forward to where we want to be. */
-       if(label) putresult(SPLIT_CONTINUE, "%s %s\n", handle, label);
-        if(mode == MODE_FILE_WRITE && cur_span_chunkstart > 0){
+       if (label)
+           putresult(SPLIT_CONTINUE, "%s %s\n", handle, label);
+        if ((mode == MODE_FILE_WRITE) && (cur_span_chunkstart > (off_t)0)) {
+           char *quoted = quote_string(holdfile_path_thischunk);
            fprintf(stderr, "taper: r: seeking %s to " OFF_T_FMT " kb\n",
-                           holdfile_path_thischunk, holdfile_offset_thischunk);
+                           quoted,
+                           (OFF_T_FMT_TYPE)holdfile_offset_thischunk);
            fflush(stderr);
 
-           if(holdfile_offset_thischunk > maxseek){
-             snprintf(seekerrstr, sizeof(seekerrstr), "Can't seek by " OFF_T_FMT " kb (compiled for %d-bit file offsets), recompile with large file support or set holdingdisk chunksize to <%ld Mb", holdfile_offset_thischunk, (int)(sizeof(off_t) * 8), (long)(maxseek/1024));
-             log_add(L_ERROR, "%s", seekerrstr);
-             fprintf(stderr, "taper: r: FATAL: %s\n", seekerrstr);
-             fflush(stderr);
-             syncpipe_put('X', 0);
-             return -1;
+           if (holdfile_offset_thischunk > maxseek) {
+               snprintf(seekerrstr, SIZEOF(seekerrstr), "Can't seek by "
+                       OFF_T_FMT " kb (compiled for %d-bit file offsets), "
+                       "recompile with large file support or "
+                       "set holdingdisk chunksize to <" OFF_T_FMT " Mb",
+                       (OFF_T_FMT_TYPE)holdfile_offset_thischunk,
+                       (int)(sizeof(off_t) * 8),
+                       (OFF_T_FMT_TYPE)(maxseek/(off_t)1024));
+               log_add(L_ERROR, "%s", seekerrstr);
+               fprintf(stderr, "taper: r: FATAL: %s\n", seekerrstr);
+               fflush(stderr);
+               if (syncpipe_put('X', 0) == -1) {
+                       put_syncpipe_fault_result(handle);
+               }
+               amfree(quoted);
+               return -1;
            }
-           if(lseek(fd, holdfile_offset_thischunk*1024, SEEK_SET) == (off_t)-1){
-             fprintf(stderr, "taper: r: FATAL: seek_holdfile lseek error while seeking into %s by " OFF_T_FMT "kb: %s\n", holdfile_path_thischunk, holdfile_offset_thischunk, strerror(errno));
-             fflush(stderr);
-             syncpipe_put('X', 0);
-             return -1;
+           if (lseek(fd, holdfile_offset_thischunk*(off_t)1024, SEEK_SET) == (off_t)-1) {
+               fprintf(stderr, "taper: r: FATAL: seek_holdfile lseek error "
+                       "while seeking into %s by "
+                       OFF_T_FMT "kb: %s\n", quoted,
+                       (OFF_T_FMT_TYPE)holdfile_offset_thischunk,
+                       strerror(errno));
+               fflush(stderr);
+               if (syncpipe_put('X', 0) == -1) {
+                       put_syncpipe_fault_result(handle);
+               }
+               amfree(quoted);
+               return -1;
            }
-        }
-        else if(mode == MODE_PORT_WRITE){
+           amfree(quoted);
+        } else if (mode == MODE_PORT_WRITE) {
            fprintf(stderr, "taper: r: re-reading split dump piece from buffer\n");
            fflush(stderr);
            retry_from_splitbuf = 1;
            splitbuf_rd_ptr = splitbuf;
-           if(splitbuf_rd_ptr >= splitbuf_wr_ptr) retry_from_splitbuf = 0;
+           if (splitbuf_rd_ptr >= splitbuf_wr_ptr)
+               retry_from_splitbuf = 0;
         }
-        if(cur_span_chunkstart > 0) header_read = 1; /* really initialized in prior run */
+        if (cur_span_chunkstart > (off_t)0)
+           header_read = 1; /* really initialized in prior run */
     }
 
     /* tell writer to open tape */
 
+#ifdef ASSERTIONS
     opening = 1;
-    syncpipe_put('O', 0);
-    syncpipe_putstr(datestamp);
-    syncpipe_putstr(hostname);
-    syncpipe_putstr(diskname);
-    syncpipe_putint(level);
+#endif
+
+    if (syncpipe_put('O', 0) == -1) {
+       put_syncpipe_fault_result(handle);
+       return -1;
+    }
+    if (syncpipe_putstr(datestamp) == -1) {
+       put_syncpipe_fault_result(handle);
+       return -1;
+    }
+    if (syncpipe_putstr(hostname) == -1) {
+       put_syncpipe_fault_result(handle);
+       return -1;
+    }
+    if (syncpipe_putstr(qdiskname) == -1) {
+       put_syncpipe_fault_result(handle);
+       return -1;
+    }
+    if (syncpipe_putint(level) == -1) {
+       put_syncpipe_fault_result(handle);
+       return -1;
+    }
 
     startclock();
     
     /* read file in loop */
     
-    while(1) {
-       tok = syncpipe_get(&bufnum);
+    while (1) {
+       if ((tok = syncpipe_get(&bufnum)) == -1) {
+           put_syncpipe_fault_result(handle);
+           return -1;
+       }
+
        switch(tok) {
-           
        case 'O':
+#ifdef ASSERTIONS
            assert(opening);
            opening = 0;
+#endif
            err = 0;
            break;
            
        case 'R':
-           if(bufdebug) {
+           if (bufdebug) {
                fprintf(stderr, "taper: r: got R%d\n", bufnum);
                fflush(stderr);
            }
            
-           if(need_closing) {
-               syncpipe_put('C', 0);
+           if (need_closing) {
+               if (syncpipe_put('C', 0) == -1) {
+                   put_syncpipe_fault_result(handle);
+                   return (-1);
+               }
                closing = 1;
                need_closing = 0;
                break;
            }
            
-           if(closing) break;  /* ignore extra read tokens */
+           if (closing)
+               break;  /* ignore extra read tokens */
            
+#ifdef ASSERTIONS
            assert(!opening);
-           if(bp->status != EMPTY || bufnum != bp-buftable) {
+#endif
+           if(bp->status != EMPTY || bufnum != (int)(bp - buftable)) {
                /* XXX this SHOULD NOT HAPPEN.  Famous last words. */
-               fprintf(stderr,"taper: panic: buffer mismatch at ofs %ld:\n",
-                       filesize);
-               if(bufnum != bp-buftable) {
+               fprintf(stderr,"taper: panic: buffer mismatch at ofs "
+                       OFF_T_FMT ":\n", (OFF_T_FMT_TYPE)filesize);
+               if(bufnum != (int)(bp - buftable)) {
                    fprintf(stderr, "    my buf %d but writer buf %d\n",
                            (int)(bp-buftable), bufnum);
-               }
-               else {
+               } else {
                    fprintf(stderr,"buf %d state %s (%ld) instead of EMPTY\n",
                            (int)(bp-buftable),
                            bp->status == FILLING? "FILLING" :
@@ -1171,7 +1465,7 @@ int read_file(fd, handle, hostname, diskname, datestamp, level)
                dumpbufs("taper");
                sleep(1);
                dumpbufs("taper: after 1 sec");
-               if(bp->status == EMPTY)
+               if (bp->status == EMPTY)
                    fprintf(stderr, "taper: result now correct!\n");
                fflush(stderr);
                
@@ -1179,23 +1473,31 @@ int read_file(fd, handle, hostname, diskname, datestamp, level)
                                     "[fatal buffer mismanagement bug]");
                q = squote(errstr);
                putresult(TRYAGAIN, "%s %s\n", handle, q);
-               cur_span_chunkstart = 0;
+               cur_span_chunkstart = (off_t)0;
                amfree(q);
                log_add(L_INFO, "retrying %s:%s.%d on new tape due to: %s",
-                       hostname, diskname, level, errstr);
+                       hostname, qdiskname, level, errstr);
                closing = 1;
-               syncpipe_put('X', 0);   /* X == buffer snafu, bail */
+               if (syncpipe_put('X', 0) == -1) {/* X == buffer snafu, bail */
+                   put_syncpipe_fault_result(handle);
+                   return (-1);
+               }
                do {
-                   tok = syncpipe_get(&bufnum);
-               } while(tok != 'x');
+                   if ((tok = syncpipe_get(&bufnum)) == -1) {
+                       put_syncpipe_fault_result(handle);
+                       return (-1);
+                   }
+               } while (tok != 'x');
                aclose(fd);
                return -1;
-           } /* end 'if (bf->status != EMPTY || bufnum != bp-buftable)' */
+           } /* end 'if (bf->status != EMPTY || bufnum != (int)(bp-buftable))' */
 
            bp->status = FILLING;
-           buflen = header_read ? tt_blocksize : DISK_BLOCK_BYTES;
-           if(interactive || bufdebug) dumpstatus(bp);
-           if(header_written == 0 && (header_read == 1 || cur_span_chunkstart > 0)){
+           buflen = header_read ? (size_t)tt_blocksize : DISK_BLOCK_BYTES;
+           if (interactive || bufdebug)
+               dumpstatus(bp);
+           if (header_written == 0 &&
+                       (header_read == 1 || cur_span_chunkstart > (off_t)0)) {
                /* for split dumpfiles, modify headers for the second - nth
                   pieces that signify that they're continuations of the last
                   normal one */
@@ -1203,182 +1505,224 @@ int read_file(fd, handle, hostname, diskname, datestamp, level)
                file.type = F_SPLIT_DUMPFILE;
                file.partnum = num_splits + 1;
                file.totalparts = expected_splits;
-                 cont_filename = stralloc(file.cont_filename);
+                cont_filename = stralloc(file.cont_filename);
                file.cont_filename[0] = '\0';
                build_header(bp->buffer, &file, tt_blocksize);
   
-               if(cont_filename[0] != '\0') {
+               if (cont_filename[0] != '\0') {
                  file.type = F_CONT_DUMPFILE;
                    strncpy(file.cont_filename, cont_filename,
-                           sizeof(file.cont_filename));
+                           SIZEOF(file.cont_filename));
                        }
-               memcpy(&cur_holdfile, &file, sizeof(dumpfile_t));
+               memcpy(&cur_holdfile, &file, SIZEOF(dumpfile_t));
   
-               if(interactive || bufdebug) dumpstatus(bp);
-               bp->size = tt_blocksize;
-               rc = tt_blocksize;
+               if (interactive || bufdebug)
+                   dumpstatus(bp);
+               bp->size = (ssize_t)tt_blocksize;
+               rc = (ssize_t)tt_blocksize;
                header_written = 1;
                amfree(cont_filename);
-                       }
-           else if(retry_from_splitbuf){
+           } else if (retry_from_splitbuf) {
                /* quietly pull dump data from our in-memory cache, and the
                   writer side need never know the wiser */
                memcpy(bp->buffer, splitbuf_rd_ptr, tt_blocksize);
-               bp->size = tt_blocksize;
-               rc = tt_blocksize;
+               bp->size = (ssize_t)tt_blocksize;
+               rc = (ssize_t)tt_blocksize;
  
                splitbuf_rd_ptr += tt_blocksize;
-               if(splitbuf_rd_ptr >= splitbuf_wr_ptr) retry_from_splitbuf = 0;
-           }
-           else if((rc = taper_fill_buffer(fd, bp, buflen)) < 0) {
+               if (splitbuf_rd_ptr >= splitbuf_wr_ptr)
+                   retry_from_splitbuf = 0;
+           } else if ((rc = taper_fill_buffer(fd, bp, buflen)) < 0) {
                err = errno;
                closing = 1;
-               strclosing = newvstralloc(strclosing,"Can't read data: ",NULL);
-               syncpipe_put('C', 0);
+               strclosing = newvstralloc(strclosing,"Can't read data: ",
+                                         NULL);
+               if (syncpipe_put('C', 0) == -1) {
+                   put_syncpipe_fault_result(handle);
+                   return (-1);
+               }
            }
   
-           if(!closing) {
-               if(rc < buflen) { /* switch to next holding file */
-                   int ret;
-                   if(file.cont_filename[0] != '\0'){
-                      cur_filename = newvstralloc(cur_filename, file.cont_filename, NULL);
-                               }
-                   ret = get_next_holding_file(fd, bp, strclosing, rc);
-                   if(ret <= 0){
+           if (!closing) {
+               if (rc < (ssize_t)buflen) { /* switch to next holding file */
+                   ssize_t ret;
+
+                   if (file.cont_filename[0] != '\0') {
+                       cur_filename = newvstralloc(cur_filename, file.cont_filename, NULL);
+                   }
+                   ret = get_next_holding_file(fd, bp, &strclosing, (size_t)rc);
+                   if (ret <= 0) {
                        need_closing = 1;
-                           }
-                           else {
-                       memcpy(&cur_holdfile, &file, sizeof(dumpfile_t));
+                   } else {
+                       memcpy(&cur_holdfile, &file, SIZEOF(dumpfile_t));
                        rc += ret;
-                               bp->size = rc;
-                           }
-                       }
-               if(rc > 0) {
+                       bp->size = rc;
+                   }
+               }
+               if (rc > 0) {
                    bp->status = FULL;
                    /* rebuild the header block, which might have CONT junk */
-                   if(header_read == 0) {
+                   if (header_read == 0) {
                        char *cont_filename;
                        /* write the "real" filename if the holding-file
                           is a partial one */
-                       parse_file_header(bp->buffer, &file, rc);
-                       parse_file_header(bp->buffer, &first_file, rc);
+                       parse_file_header(bp->buffer, &file, (size_t)rc);
+                       parse_file_header(bp->buffer, &first_file, (size_t)rc);
                        cont_filename = stralloc(file.cont_filename);
                        file.cont_filename[0] = '\0';
-                       if(splitsize > 0){
+                       if (splitsize > (off_t)0) {
                            file.type = F_SPLIT_DUMPFILE;
                            file.partnum = 1;
                            file.totalparts = expected_splits;
                        }
                        file.blocksize = tt_blocksize;
                        build_header(bp->buffer, &file, tt_blocksize);
-                       kbytesread += tt_blocksize/1024; /* XXX shady */
+                       kbytesread += (off_t)(tt_blocksize/1024); /* XXX shady */
  
                        file.type = F_CONT_DUMPFILE;
  
                        /* add CONT_FILENAME back to in-memory header */
                        strncpy(file.cont_filename, cont_filename, 
-                               sizeof(file.cont_filename));
-                       if(interactive || bufdebug) dumpstatus(bp);
-                       bp->size = tt_blocksize; /* output a full tape block */
+                               SIZEOF(file.cont_filename));
+                       if (interactive || bufdebug)
+                           dumpstatus(bp);
+                       bp->size = (ssize_t)tt_blocksize; /* output a full tape block */
                        /* save the header, we'll need it if we jump tapes */
-                       memcpy(&cur_holdfile, &file, sizeof(dumpfile_t));
+                       memcpy(&cur_holdfile, &file, SIZEOF(dumpfile_t));
                        header_read = 1;
                        header_written = 1;
                        amfree(cont_filename);
-                   }
-                   else {
+                   } else {
                        filesize = kbytesread;
                    }
 
-                   if(bufdebug) {
+                   if (bufdebug) {
                        fprintf(stderr,"taper: r: put W%d\n",(int)(bp-buftable));
                        fflush(stderr);
                    }
-                   syncpipe_put('W', bp-buftable);
+                   if (syncpipe_put('W', (int)(bp-buftable)) == -1) {
+                       put_syncpipe_fault_result(handle);
+                       return (-1);
+                   }
                    bp = nextbuf(bp);
                }
 
-               if(kbytesread + DISK_BLOCK_BYTES/1024 >= splitsize && splitsize > 0 && !need_closing){
+               if (((kbytesread + (off_t)(DISK_BLOCK_BYTES/1024)) >= splitsize)
+                       && (splitsize > (off_t)0) && !need_closing) {
 
-                   if(mode == MODE_PORT_WRITE){
+                   if (mode == MODE_PORT_WRITE) {
                        splitbuf_wr_ptr = splitbuf;
                        splitbuf_rd_ptr = splitbuf;
-                       memset(splitbuf, 0, sizeof(splitbuf));
+                       memset(splitbuf, 0, SIZEOF(splitbuf));
                        retry_from_splitbuf = 0;
                    }
 
-                   fprintf(stderr,"taper: r: end %s.%s.%s.%d part %d, splitting chunk that started at %ldkb after %ldkb (next chunk will start at %ldkb)\n", hostname, diskname, datestamp, level, num_splits+1, cur_span_chunkstart, kbytesread, cur_span_chunkstart+kbytesread);
+                   fprintf(stderr,"taper: r: end %s.%s.%s.%d part %d, "
+                               "splitting chunk that started at "
+                               OFF_T_FMT "kb after " OFF_T_FMT
+                               "kb (next chunk will start at "
+                               OFF_T_FMT "kb)\n",
+                               hostname, qdiskname, datestamp, level,
+                               num_splits+1,
+                               (OFF_T_FMT_TYPE)cur_span_chunkstart,
+                               (OFF_T_FMT_TYPE)kbytesread,
+                               (OFF_T_FMT_TYPE)(cur_span_chunkstart+kbytesread));
                    fflush(stderr);
 
                    nexting = 1;
                    need_closing = 1;
                } /* end '(kbytesread >= splitsize && splitsize > 0)' */
-               if(need_closing && rc <= 0) {
-                   syncpipe_put('C', 0);
+               if (need_closing && rc <= 0) {
+                   if (syncpipe_put('C', 0) == -1) {
+                       put_syncpipe_fault_result(handle);
+                       return (-1);
+                   }
                    need_closing = 0;
                    closing = 1;
                }
-                kbytesread += rc/1024;
-           } /* end the 'if(!closing)' (successful buffer fill) */
+                kbytesread += (off_t)(rc / 1024);
+           } /* end the 'if (!closing)' (successful buffer fill) */
            break;
 
        case 'T':
        case 'E':
-           syncpipe_put('e', 0);       /* ACK error */
+       case 'H':
+           if (syncpipe_put('e', 0) == -1) {   /* ACK error */
+               put_syncpipe_fault_result(handle);
+               return (-1);
+           }
 
-           str = syncpipe_getstr();
-           errstr = newvstralloc(errstr, "[", str ? str : "(null)", "]", NULL);
+           if ((str = syncpipe_getstr()) == NULL) {
+               put_syncpipe_fault_result(handle);
+               return (-1);
+           }
+           
+           errstr = newvstralloc(errstr, "[", str, "]", NULL);
            amfree(str);
 
            q = squote(errstr);
-           if(tok == 'T') {
-               if(splitsize > 0){
+           if (tok == 'T') {
+               if (splitsize > (off_t)0) {
                    /* we'll be restarting this chunk on the next tape */
-                   if(mode == MODE_FILE_WRITE){
+                   if (mode == MODE_FILE_WRITE) {
                      aclose(fd);
                    }
 
-                   putresult(SPLIT_NEEDNEXT, "%s %ld\n", handle, cur_span_chunkstart);
-                   log_add(L_INFO, "continuing %s:%s.%d on new tape from %ldkb mark: %s",
-                           hostname, diskname, level, cur_span_chunkstart, errstr);
+                   putresult(SPLIT_NEEDNEXT, "%s " OFF_T_FMT "\n", handle,
+                               (OFF_T_FMT_TYPE)cur_span_chunkstart);
+                   log_add(L_INFO, "continuing %s:%s.%d on new tape from "
+                               OFF_T_FMT "kb mark: %s",
+                               hostname, qdiskname, level,
+                               (OFF_T_FMT_TYPE)cur_span_chunkstart, errstr);
                    return 1;
-               }
-               else{
+               } else {
                    /* restart the entire dump (failure propagates to driver) */
                    aclose(fd);
                    putresult(TRYAGAIN, "%s %s\n", handle, q);
-                   cur_span_chunkstart = 0;
+                   cur_span_chunkstart = (off_t)0;
                    log_add(L_INFO, "retrying %s:%s.%d on new tape due to: %s",
-                           hostname, diskname, level, errstr);
+                           hostname, qdiskname, level, errstr);
                }
            } else {
                aclose(fd);
                putresult(TAPE_ERROR, "%s %s\n", handle, q);
                log_add(L_FAIL, "%s %s %s %d [out of tape]",
-                       hostname, diskname, datestamp, level);
+                       hostname, qdiskname, datestamp, level);
                log_add(L_ERROR,"no-tape [%s]", "No more writable valid tape found");
            }
            amfree(q);
-
            return 0;
 
        case 'C':
+#ifdef ASSERTIONS
            assert(!opening);
+#endif
            assert(closing);
 
-           if(nexting){
+           if (nexting) {
              cur_span_chunkstart += kbytesread; /* XXX possibly wrong */
-             holdfile_name = newvstralloc(holdfile_name, cur_filename, NULL);
-
-             kbytesread = 0;
-             if(cur_filename != NULL) amfree(cur_filename);
+             if (cur_filename)
+               holdfile_name = newvstralloc(holdfile_name, cur_filename,
+                                            NULL);
+             else
+               amfree(holdfile_name);
+
+             kbytesread = (off_t)0;
+             amfree(cur_filename);
            }
 
+           if ((str = syncpipe_getstr()) == NULL) {
+               put_syncpipe_fault_result(handle);
+               return (-1);
+           }
 
-           str = syncpipe_getstr();
            label = newstralloc(label, str ? str : "(null)");
            amfree(str);
-           str = syncpipe_getstr();
+           if ((str = syncpipe_getstr()) == NULL) {
+               put_syncpipe_fault_result(handle);
+               return (-1);
+           }
+
            filenum = atoi(str ? str : "-9876");        /* ??? */
            amfree(str);
            fprintf(stderr, "taper: reader-side: got label %s filenum %d\n",
@@ -1386,20 +1730,20 @@ int read_file(fd, handle, hostname, diskname, datestamp, level)
            fflush(stderr);
 
            /* we'll need that file descriptor if we're gonna write more */
-           if(!nexting){
-           aclose(fd);
+           if (!nexting) {
+               aclose(fd);
            }
 
            runtime = stopclock();
-           if(nexting) startclock();
-           if(err) {
-               if(strclosing) {
+           if (nexting)
+               startclock();
+           if (err) {
+               if (strclosing) {
                    errstr = newvstralloc(errstr,
                                          "[input: ", strclosing, ": ",
                                          strerror(err), "]", NULL);
                    amfree(strclosing);
-               }
-               else
+               } else
                    errstr = newvstralloc(errstr,
                                          "[input: ", strerror(err), "]",
                                          NULL);
@@ -1407,15 +1751,17 @@ int read_file(fd, handle, hostname, diskname, datestamp, level)
                putresult(TAPE_ERROR, "%s %s\n", handle, q);
 
                amfree(q);
-               if(splitsize){
-                 log_add(L_FAIL, "%s %s %s.%d %d %s", hostname, diskname,
-                         datestamp, num_splits, level, errstr);
+               if (splitsize != (off_t)0) {
+                   log_add(L_FAIL, "%s %s %s.%d %d %s", hostname, qdiskname,
+                               datestamp, num_splits, level, errstr);
+               } else {
+                   log_add(L_FAIL, "%s %s %s %d %s",
+                               hostname, qdiskname, datestamp, level, errstr);
                }
-               else{
-               log_add(L_FAIL, "%s %s %s %d %s",
-                       hostname, diskname, datestamp, level, errstr);
+               if ((str = syncpipe_getstr()) == NULL) {        /* reap stats */
+                   put_syncpipe_fault_result(handle);
+                   return (-1);
                }
-               str = syncpipe_getstr();        /* reap stats */
                amfree(str);
                 amfree(errstr);
            } else {
@@ -1423,12 +1769,17 @@ int read_file(fd, handle, hostname, diskname, datestamp, level)
                char kps_str[NUM_STR_SIZE];
                double rt;
 
-               rt = runtime.r.tv_sec+runtime.r.tv_usec/1000000.0;
+               rt = (double)(runtime.r.tv_sec) +
+                    ((double)(runtime.r.tv_usec) / 1000000.0);
                curdump_rt = timesadd(runtime, curdump_rt);
-               snprintf(kb_str, sizeof(kb_str), "%ld", filesize);
-               snprintf(kps_str, sizeof(kps_str), "%3.1f",
-                                    rt ? filesize / rt : 0.0);
-               str = syncpipe_getstr();
+               snprintf(kb_str, SIZEOF(kb_str), OFF_T_FMT,
+                       (OFF_T_FMT_TYPE)filesize);
+               snprintf(kps_str, SIZEOF(kps_str), "%3.1lf",
+                                 (isnormal(rt) ? (double)filesize / rt : 0.0));
+               if ((str = syncpipe_getstr()) == NULL) {
+                   put_syncpipe_fault_result(handle);
+                   return (-1);
+               }
                errstr = newvstralloc(errstr,
                                      "[sec ", walltime_str(runtime),
                                      " kb ", kb_str,
@@ -1436,38 +1787,41 @@ int read_file(fd, handle, hostname, diskname, datestamp, level)
                                      " ", str,
                                      "]",
                                      NULL);
-               q = squote(errstr);
-               if (splitsize == 0) { /* Ordinary dump */
-                   if(first_file.is_partial) {
+               if (splitsize == (off_t)0) { /* Ordinary dump */
+                   q = squote(errstr);
+/*@i@*/                    if (first_file.is_partial) {
                        putresult(PARTIAL, "%s %s %d %s\n",
                                  handle, label, filenum, q);
                        log_add(L_PARTIAL, "%s %s %s %d %s",
-                               hostname, diskname, datestamp, level, errstr);
-                   }
-                   else {
+                               hostname, qdiskname, datestamp, level, errstr);
+                   } else {
                        putresult(DONE, "%s %s %d %s\n",
                                  handle, label, filenum, q);
                        log_add(L_SUCCESS, "%s %s %s %d %s",
-                               hostname, diskname, datestamp, level, errstr);
+                               hostname, qdiskname, datestamp, level, errstr);
                    }
+                   amfree(q);
                } else { /* Chunked dump */
                    num_splits++;
-                   if(mode == MODE_FILE_WRITE){
+                   if (mode == MODE_FILE_WRITE) {
                        holdfile_path_thischunk = stralloc(holdfile_path);
-                       holdfile_offset_thischunk = (lseek(fd, (off_t)0, SEEK_CUR))/1024;
+                       holdfile_offset_thischunk = (lseek(fd, (off_t)0, SEEK_CUR))/(off_t)1024;
                        if(!save_holdfile){
-                           save_holdfile = alloc(sizeof(dumpfile_t));
+                           save_holdfile = alloc(SIZEOF(dumpfile_t));
                        }
-                       memcpy(save_holdfile, &cur_holdfile,sizeof(dumpfile_t));
+                       memcpy(save_holdfile, &cur_holdfile,SIZEOF(dumpfile_t));
                    }
-                   log_add(L_CHUNK, "%s %s %s %d %d %s", hostname, diskname,
+                   log_add(L_CHUNK, "%s %s %s %d %d %s", hostname, qdiskname,
                            datestamp, num_splits, level, errstr);
-                   if(!nexting){ /* split dump complete */
-                       rt =curdump_rt.r.tv_sec+curdump_rt.r.tv_usec/1000000.0;
-                       snprintf(kb_str, sizeof(kb_str), "%ld",
-                                   filesize+cur_span_chunkstart);
-                       snprintf(kps_str, sizeof(kps_str), "%3.1f",
-                                   rt ? (filesize+cur_span_chunkstart) / rt : 0.0);
+                   if (!nexting) { /* split dump complete */
+                       rt = (double)(curdump_rt.r.tv_sec) +
+                            ((double)(curdump_rt.r.tv_usec) / 1000000.0);
+                       snprintf(kb_str, SIZEOF(kb_str), OFF_T_FMT,
+                               (OFF_T_FMT_TYPE)(filesize + cur_span_chunkstart));
+                       snprintf(kps_str, SIZEOF(kps_str), "%3.1lf",
+                           isnormal(rt) ?
+                           ((double)(filesize+cur_span_chunkstart)) / rt :
+                           0.0);
                         amfree(errstr);
                        errstr = newvstralloc(errstr,
                                              "[sec ", walltime_str(curdump_rt),
@@ -1480,23 +1834,22 @@ int read_file(fd, handle, hostname, diskname, datestamp, level)
                        putresult(DONE, "%s %s %d %s\n", handle, label,
                                  filenum, q);
                        log_add(L_CHUNKSUCCESS, "%s %s %s %d %s",
-                               hostname, diskname, datestamp, level, errstr);
+                               hostname, qdiskname, datestamp, level, errstr);
                        amfree(save_holdfile);
                        amfree(holdfile_path_thischunk);
                         amfree(q);
-                    }
+                   }
                }
                amfree(str);
 
-               if(!nexting){
+               if (!nexting) {
                    num_splits = 0;
                    expected_splits = 0;
                    amfree(holdfile_name);
                    num_holdfiles = 0;
-                   cur_span_chunkstart = 0;
+                   cur_span_chunkstart = (off_t)0;
                    curdump_rt = times_zero;
                }
-               
                amfree(errstr);
                
 #ifdef HAVE_LIBVTBLC
@@ -1514,19 +1867,17 @@ int read_file(fd, handle, hostname, diskname, datestamp, level)
                if ((len = strlen(hostname)) <= 20) {
                    memset(desc + len, ' ', 1);
                    offset = len + 1;
-               }
-               else{
+               } else {
                    memset(desc + 20, ' ', 1);
                    offset = 21;
                }
 
-               strncpy(desc + offset, diskname, 20);
+               strncpy(desc + offset, qdiskname, 20);
 
-               if ((len = strlen(diskname)) <= 20) {
+               if ((len = strlen(qdiskname)) <= 20) {
                    memset(desc + offset + len, ' ', 1);
                    offset = offset + len + 1;
-               }
-               else{
+               } else {
                    memset(desc + offset + 20, ' ', 1);
                    offset = offset + 21;
                }
@@ -1539,8 +1890,14 @@ int read_file(fd, handle, hostname, diskname, datestamp, level)
                fflush(stderr);
 
                /* pass label string on to tape writer */
-               syncpipe_put('L', filenum);
-               syncpipe_putstr(vol_label);             
+               if (syncpipe_put('L', filenum) == -1) {
+                   put_syncpipe_fault_result(handle);
+                   return (-1);
+               }
+               if (syncpipe_putstr(vol_label) == -1) {
+                   put_syncpipe_fault_result(handle);
+                   return (-1);
+               }
 
                /* 
                 * reformat datestamp for later use with set_date from vtblc 
@@ -1553,106 +1910,160 @@ int read_file(fd, handle, hostname, diskname, datestamp, level)
                        vol_date);
 
                /* pass date string on to tape writer */                
-               syncpipe_put('D', filenum);
-               syncpipe_putstr(vol_date);
+               if (syncpipe_put('D', filenum) == -1) {
+                   put_syncpipe_fault_result(handle);
+                   return (-1);
+               }
+               if (syncpipe_putstr(vol_date) == -1) {
+                   put_syncpipe_fault_result(handle);
+                   return (-1);
+               }
 
 #endif /* HAVE_LIBVTBLC */
            }
            /* reset stuff that assumes we're on a new file */
 
-           if(nexting){
-               opening = 1;
-               nexting = 0;
-               closing = 0;
-               filesize = 0;
-               syncpipe_put('O', 0);
-               syncpipe_putstr(datestamp);
-               syncpipe_putstr(hostname);
-               syncpipe_putstr(diskname);
-               syncpipe_putint(level);
-               for(bp = buftable; bp < buftable + conf_tapebufs; bp++) {
-                   bp->status = EMPTY;
-               }
-               bp = buftable;
-               header_written = 0;
-               break;
+           if (!nexting)
+               return 0;
+
+#ifdef ASSERTIONS
+           opening = 1;
+#endif
+           nexting = 0;
+           closing = 0;
+           filesize = (off_t)0;
+           if (syncpipe_put('O', 0) == -1) {
+               put_syncpipe_fault_result(handle);
+               return -1;
+           }
+           if (syncpipe_putstr(datestamp) == -1) {
+               put_syncpipe_fault_result(handle);
+               return -1;
+           }
+           if (syncpipe_putstr(hostname) == -1) {
+               put_syncpipe_fault_result(handle);
+               return -1;
+           }
+           if (syncpipe_putstr(qdiskname) == -1) {
+               put_syncpipe_fault_result(handle);
+               return -1;
            }
-           else return 0;
+           if (syncpipe_putint(level) == -1) {
+               put_syncpipe_fault_result(handle);
+               return -1;
+           }
+           for (bp = buftable; bp < buftable + conf_tapebufs; bp++) {
+               bp->status = EMPTY;
+           }
+           bp = buftable;
+           header_written = 0;
+           break;
+
+       case 'X':
+           /*
+            * Pipe read error: Communications is severed at least
+            * back to us.  We send a blind 'Q' (quit) and we don't
+            * wait for a response...
+            */
+           syncpipe_put('Q', 0);                       /* ACK error */
+           fprintf(stderr, "taper: communications pipe from reader severed\n");
+           return -1;
 
        default:
-           assert(0);
+           q = squotef("[Taper syncpipe protocol error]");
+           putresult(TAPE_ERROR, "%s %s\n", handle, q);
+           log_add(L_ERROR, "tape-error %s %s", handle, q);
+           amfree(q);
+           return -1;
        }
     }
-
     return 0;
 }
 
-int taper_fill_buffer(fd, bp, buflen)
-int fd;
-buffer_t *bp;
-int buflen;
+ssize_t
+taper_fill_buffer(
+    int fd,
+    buffer_t *bp,
+    size_t buflen)
 {
     char *curptr;
-    int spaceleft, cnt;
+    ssize_t cnt;
 
     curptr = bp->buffer;
-    bp->size = 0;
-    spaceleft = buflen;
 
-    cnt = fullread(fd, curptr, spaceleft);
+    cnt = fullread(fd, curptr, buflen);
     switch(cnt) {
     case 0:    /* eof */
-       if(interactive) fputs("r0", stderr);
-       return bp->size;
+       if (interactive)
+           fputs("r0", stderr);
+       bp->size = 0;
+       return (ssize_t)0;
+       /*NOTREACHED*/
+
     case -1:   /* error on read, punt */
-       if(interactive) fputs("rE", stderr);
+       if (interactive)
+           fputs("rE", stderr);
+       bp->size = 0;
        return -1;
+       /*NOTREACHED*/
+
     default:
-       if(mode == MODE_PORT_WRITE && splitsize > 0){
+       if ((mode == MODE_PORT_WRITE) && (splitsize > (off_t)0)) {
            memcpy(splitbuf_wr_ptr, curptr, (size_t)cnt);
            splitbuf_wr_ptr += cnt;
        }
-       spaceleft -= cnt;
-       curptr += cnt;
-       bp->size += cnt;
+       bp->size = cnt;
+       break;
     }
 
-    if(interactive) fputs("R", stderr);
-    return bp->size;
+    if (interactive)
+       fputs("R", stderr);
+    return ((ssize_t)bp->size);
 }
 
 /* Given a dumpfile in holding, determine its size and figure out how many
  * times we'd have to split it.
  */
-int predict_splits(filename)
-char *filename;
+int
+predict_splits(
+    char *filename)
 {
     int splits = 0;
-    long total_kb = 0;
-    long adj_splitsize = splitsize - DISK_BLOCK_BYTES/1024;
+    off_t total_kb = (off_t)0;
+    off_t adj_splitsize = splitsize - (off_t)(DISK_BLOCK_BYTES / 1024);
 
-    if(splitsize <= 0) return(0);
+    if (splitsize <= (off_t)0)
+       return(0);
 
-    if(adj_splitsize <= 0){
-      error("Split size must be > %ldk", DISK_BLOCK_BYTES/1024);
+    if (adj_splitsize <= (off_t)0) {
+      error("Split size must be > " OFF_T_FMT "k",
+       (OFF_T_FMT_TYPE)(DISK_BLOCK_BYTES/1024));
+      /*NOTREACHED*/
     }
 
     /* should only calculuate this once, not on retries etc */
-    if(expected_splits != 0) return(expected_splits);
+    if (expected_splits != 0)
+       return(expected_splits);
 
     total_kb = size_holding_files(filename, 1);
     
-    if(total_kb <= 0){
-      fprintf(stderr, "taper: r: %ld kb holding file makes no sense, not precalculating splits\n", total_kb);
+    if (total_kb <= (off_t)0) {
+      fprintf(stderr, "taper: r: " OFF_T_FMT
+               " kb holding file makes no sense, not precalculating splits\n",
+               (OFF_T_FMT_TYPE)total_kb);
       fflush(stderr);
       return(0);
     }
 
-    fprintf(stderr, "taper: r: Total dump size should be %ldkb, chunk size is %ldkb\n", total_kb, splitsize);
+    fprintf(stderr, "taper: r: Total dump size should be " OFF_T_FMT
+               "kb, chunk size is " OFF_T_FMT "kb\n",
+               (OFF_T_FMT_TYPE)total_kb,
+               (OFF_T_FMT_TYPE)splitsize);
     fflush(stderr);
 
-    splits = total_kb/adj_splitsize;
-    if(total_kb % adj_splitsize) splits++;
+    splits = (int)(total_kb / adj_splitsize);
+    if ((splits == 0) || (total_kb % adj_splitsize))
+       splits++;
 
 
     fprintf(stderr, "taper: r: Expecting to split into %d parts \n", splits);
@@ -1667,17 +2078,19 @@ char *filename;
  *
  */
 times_t idlewait, rdwait, wrwait, fmwait;
-long total_writes;
-double total_tape_used;
+unsigned long total_writes;
+off_t total_tape_used;
 int total_tape_fm;
 
-void write_file P((void));
-int write_buffer P((buffer_t *bp));
+void write_file(void);
+int write_buffer(buffer_t *bp);
 
-void tape_writer_side(getp, putp)
-int getp, putp;
+void
+tape_writer_side(
+    int getp,
+    int putp)
 {
-    char tok;
+    int tok;
     int tape_started;
     char *str;
     char *hostname;
@@ -1693,57 +2106,96 @@ int getp, putp;
 
     procname = "writer";
     syncpipe_init(getp, putp);
-
     tape_started = 0;
     idlewait = times_zero;
 
-    while(1) {
+    while (1) {
        startclock();
-       tok = syncpipe_get(&tmpint);
+       if ((tok = syncpipe_get(&tmpint)) == -1) {
+           error("writer: Syncpipe failure before start");
+           /*NOTREACHED*/
+       }
+
        idlewait = timesadd(idlewait, stopclock());
-       if(tok != 'S' && tok != 'Q' && !tape_started) {
+       if (tok != 'S' && tok != 'Q' && !tape_started) {
            error("writer: token '%c' before start", tok);
+           /*NOTREACHED*/
        }
 
        switch(tok) {
+       case 'H':               /* Reader read pipe side is down */
+           dbprintf(("writer: Communications with reader is down"));
+           error("writer: Communications with reader is down");
+           /*NOTREACHED*/
+           
        case 'S':               /* start-tape */
-           if(tape_started) {
+           if (tape_started) {
                error("writer: multiple start requests");
+               /*NOTREACHED*/
+           }
+           if ((str = syncpipe_getstr()) == NULL) {
+               error("writer: Syncpipe failure");
+               /*NOTREACHED*/
            }
-           str = syncpipe_getstr();
-           if(!first_tape(str ? str : "bad-datestamp")) {
-               if(tape_fd >= 0) {
+           if (!first_tape(str ? str : "bad-datestamp")) {
+               if (tape_fd >= 0) {
                    tapefd_close(tape_fd);
                    tape_fd = -1;
                }
-               syncpipe_put('E', 0);
-               syncpipe_putstr(errstr);
+               if (syncpipe_put('E', 0) == -1) {
+                   error("writer: Syncpipe failure passing exit code");
+                   /*NOTREACHED*/
+               }
+               if (syncpipe_putstr(errstr) == -1) {
+                   error("writer: Syncpipe failure passing exit string");
+                   /*NOTREACHED*/
+               }
                /* wait for reader to acknowledge error */
                do {
-                   tok = syncpipe_get(&tmpint);
-                   if(tok != 'e') {
+                   if ((tok = syncpipe_get(&tmpint)) == -1) {
+                       error("writer: Syncpipe failure waiting for error ack");
+                       /*NOTREACHED*/
+                   }
+                   if (tok != 'e') {
                        error("writer: got '%c' unexpectedly after error", tok);
+                       /*NOTREACHED*/
                    }
-               } while(tok != 'e');
+               } while (tok != 'e');
            } else {
-               syncpipe_put('S', 0);
+               if (syncpipe_put('S', 0) == -1) {
+                   error("writer: syncpipe failure while starting tape");
+                   /*NOTREACHED*/
+               }
                tape_started = 1;
            }
            amfree(str);
-
            break;
 
        case 'O':               /* open-output */
-           datestamp = syncpipe_getstr();
+           if ((datestamp = syncpipe_getstr()) == NULL) {
+               error("writer: Syncpipe failure during open");
+               /*NOTREACHED*/
+           }
            tapefd_setinfo_datestamp(tape_fd, datestamp);
            amfree(datestamp);
-           hostname = syncpipe_getstr();
+
+           if ((hostname = syncpipe_getstr()) == NULL) {
+               error("writer: Syncpipe failure fetching hostname");
+               /*NOTREACHED*/
+           }
            tapefd_setinfo_host(tape_fd, hostname);
            amfree(hostname);
-           diskname = syncpipe_getstr();
+
+           if ((diskname = syncpipe_getstr()) == NULL) {
+               error("writer: Syncpipe failure fetching diskname");
+               /*NOTREACHED*/
+           }
            tapefd_setinfo_disk(tape_fd, diskname);
            amfree(diskname);
-           level = syncpipe_getint();
+           if ((level = syncpipe_getint()) == -1) {
+               error("writer: Syncpipe failure fetching level");
+               /*NOTREACHED*/
+           }
            tapefd_setinfo_level(tape_fd, level);
            write_file();
            break;
@@ -1751,7 +2203,10 @@ int getp, putp;
 #ifdef HAVE_LIBVTBLC
        case 'L':               /* read vtbl label */
            vtbl_no = tmpint;
-           vol_label = syncpipe_getstr();
+           if ((vol_label = syncpipe_getstr()) == NULL) {
+               error("writer: Syncpipe failure fetching vrbl label");
+               /*NOTREACHED*/
+           }
            fprintf(stderr, "taper: read label string \"%s\" from pipe\n", 
                    vol_label);
            strncpy(vtbl_entry[vtbl_no].label, vol_label, 45);
@@ -1759,7 +2214,10 @@ int getp, putp;
 
        case 'D':               /* read vtbl date */
            vtbl_no = tmpint;
-           vol_date = syncpipe_getstr();
+           if ((vol_date = syncpipe_getstr()) == NULL) {
+               error("writer: Syncpipe failure fetching vrbl date");
+               /*NOTREACHED*/
+           }
            fprintf(stderr, "taper: read date string \"%s\" from pipe\n", 
                    vol_date);
            strncpy(vtbl_entry[vtbl_no].date, vol_date, 20);
@@ -1769,7 +2227,8 @@ int getp, putp;
        case 'Q':
            end_tape(0);        /* XXX check results of end tape ?? */
            clear_tapelist();
-           amfree(taper_datestamp);
+           free_server_config();
+           amfree(taper_timestamp);
            amfree(label);
            amfree(errstr);
            amfree(changer_resultstr);
@@ -1780,11 +2239,11 @@ int getp, putp;
 
            malloc_size_2 = malloc_inuse(&malloc_hist_2);
 
-           if(malloc_size_1 != malloc_size_2) {
+           if (malloc_size_1 != malloc_size_2) {
                malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2);
            }
-
            exit(0);
+           /*NOTREACHED*/
 
        default:
            assert(0);
@@ -1792,11 +2251,12 @@ int getp, putp;
     }
 }
 
-void write_file()
+void
+write_file(void)
 {
     buffer_t *bp;
     int full_buffers, i, bufnum;
-    char tok;
+    int tok;
     char number[NUM_STR_SIZE];
     char *rdwait_str, *wrwait_str, *fmwait_str;
     int tmpint;
@@ -1808,7 +2268,7 @@ void write_file()
     full_buffers = 0;
     tok = '?';
 
-    if(bufdebug) {
+    if (bufdebug) {
        fprintf(stderr, "taper: w: start file\n");
        fflush(stderr);
     }
@@ -1816,13 +2276,19 @@ void write_file()
     /*
      * Tell the reader that the tape is open, and give it all the buffers.
      */
-    syncpipe_put('O', 0);
-    for(i = 0; i < conf_tapebufs; i++) {
-       if(bufdebug) {
+    if (syncpipe_put('O', 0) == -1) {
+       error("writer: Syncpipe failure starting write sequence");
+       /*NOTREACHED*/
+    }
+    for (i = 0; i < conf_tapebufs; i++) {
+       if (bufdebug) {
            fprintf(stderr, "taper: w: put R%d\n", i);
            fflush(stderr);
        }
-       syncpipe_put('R', i);
+       if (syncpipe_put('R', i) == -1) {
+           error("writer: Syncpipe failure readying write buffers");
+           /*NOTREACHED*/
+       }
     }
 
     /*
@@ -1832,7 +2298,7 @@ void write_file()
      */
 
     startclock();
-    if(!write_filemark())
+    if (!write_filemark())
        goto tape_error;
     fmwait = stopclock();
 
@@ -1850,12 +2316,17 @@ void write_file()
         * of starts/stops, which in turn saves tape and time.
         */
 
-       if(interactive) fputs("[WS]", stderr);
+       if (interactive)
+           fputs("[WS]", stderr);
        startclock();
-       while(full_buffers < conf_tapebufs - THRESHOLD) {
-           tok = syncpipe_get(&bufnum);
-           if(tok != 'W') break;
-           if(bufdebug) {
+       while (full_buffers < conf_tapebufs - THRESHOLD) {
+           if ((tok = syncpipe_get(&bufnum)) == -1) {
+               error("writer: Syncpipe failure during buffer advance");
+               /*NOTREACHED*/
+           }
+           if (tok != 'W')
+               break;
+           if (bufdebug) {
                fprintf(stderr,"taper: w: got W%d\n",bufnum);
                fflush(stderr);
            }
@@ -1872,12 +2343,13 @@ void write_file()
         * in, then we will be STREAMING.
         */
 
-       while(full_buffers) {
-           if(tt_file_pad && bp->size < tt_blocksize) {
+       while (full_buffers) {
+           if (tt_file_pad && bp->size < (ssize_t)tt_blocksize) {
                memset(bp->buffer+bp->size, 0, tt_blocksize - bp->size);
-               bp->size = tt_blocksize;
+               bp->size = (ssize_t)tt_blocksize;
            }
-           if(!write_buffer(bp)) goto tape_error;
+           if (!write_buffer(bp))
+               goto tape_error;
            full_buffers--;
            bp = nextbuf(bp);
        }
@@ -1895,53 +2367,74 @@ void write_file()
         * to wait for buffers to fill, we are then STOPPED again.
         */
 
-       while(tok == 'W' && bp->status == FULL) {
-           tok = syncpipe_get(&bufnum);
-           if(tok == 'W') {
-               if(bufdebug) {
+       while (tok == 'W' && bp->status == FULL) {
+           if ((tok = syncpipe_get(&bufnum)) == -1) {
+               error("writer: Syncpipe failure advancing buffer");
+               /*NOTREACHED*/
+           }
+
+           if (tok == 'W') {
+               if (bufdebug) {
                    fprintf(stderr,"taper: w: got W%d\n",bufnum);
                    fflush(stderr);
                }
-               if(bufnum != bp-buftable) {
+               if(bufnum != (int)(bp - buftable)) {
                    fprintf(stderr,
                            "taper: tape-writer: my buf %d reader buf %d\n",
                            (int)(bp-buftable), bufnum);
                    fflush(stderr);
-                   syncpipe_put('E', 0);
-                   syncpipe_putstr("writer-side buffer mismatch");
+                   if (syncpipe_put('E', 0) == -1) { 
+                       error("writer: Syncpipe failure putting error token");
+                       /*NOTREACHED*/
+                   }
+                   if (syncpipe_putstr("writer-side buffer mismatch") == -1) {
+                       error("writer: Syncpipe failure putting error messgae");
+                       /*NOTREACHED*/
+                   }
                    goto error_ack;
                }
-               if(tt_file_pad && bp->size < tt_blocksize) {
+               if (tt_file_pad && bp->size < (ssize_t)tt_blocksize) {
                    memset(bp->buffer+bp->size, 0, tt_blocksize - bp->size);
-                   bp->size = tt_blocksize;
+                   bp->size = (ssize_t)tt_blocksize;
                }
-               if(!write_buffer(bp)) goto tape_error;
+               if (!write_buffer(bp))
+                   goto tape_error;
                bp = nextbuf(bp);
-           }
-           else if(tok == 'Q')
+           } else if (tok == 'Q') {
                return;
-           else if(tok == 'X')
+           } else if (tok == 'X') {
                goto reader_buffer_snafu;
-           else
+           } else {
                error("writer-side not expecting token: %c", tok);
+               /*NOTREACHED*/
+           }
        }
-    } while(tok == 'W');
+    } while (tok == 'W');
 
     /* got close signal from reader, acknowledge it */
 
-    if(tok == 'X')
+    if (tok == 'X')
        goto reader_buffer_snafu;
 
     assert(tok == 'C');
-    syncpipe_put('C', 0);
+    if (syncpipe_put('C', 0) == -1) {
+       error("writer: Syncpipe failure putting close");
+       /*NOTREACHED*/
+    }
 
     /* tell reader the tape and file number */
 
-    syncpipe_putstr(label);
-    snprintf(number, sizeof(number), "%d", filenum);
-    syncpipe_putstr(number);
+    if (syncpipe_putstr(label) == -1) {
+       error("writer: Syncpipe failure putting label");
+       /*NOTREACHED*/
+    }
+    snprintf(number, SIZEOF(number), "%d", filenum);
+    if (syncpipe_putstr(number) == -1) {
+       error("writer: Syncpipe failure putting filenum");
+       /*NOTREACHED*/
+    }
 
-    snprintf(number, sizeof(number), "%ld", total_writes);
+    snprintf(number, SIZEOF(number), "%lu", total_writes);
     rdwait_str = stralloc(walltime_str(rdwait));
     wrwait_str = stralloc(walltime_str(wrwait));
     fmwait_str = stralloc(walltime_str(fmwait));
@@ -1956,7 +2449,10 @@ void write_file()
     amfree(rdwait_str);
     amfree(wrwait_str);
     amfree(fmwait_str);
-    syncpipe_putstr(errstr);
+    if (syncpipe_putstr(errstr) == -1) {
+       error("writer: Syncpipe failure putting '%s'", errstr);
+       /*NOTREACHED*/
+    }
 
     /* XXX go to next tape if past tape size? */
 
@@ -1964,34 +2460,56 @@ void write_file()
 
  tape_error:
     /* got tape error */
-    if(next_tape(1)) syncpipe_put('T', 0);     /* next tape in place, try again */
-    else syncpipe_put('E', 0);         /* no more tapes, fail */
-    syncpipe_putstr(errstr);
+    if (next_tape(1)) {
+       if (syncpipe_put('T', 0) == -1) {   /* next tape in place, try again */
+           error("writer: Syncpipe failure during tape advance");
+           /*NOTREACHED*/
+       }
+    } else {
+       if (syncpipe_put('E', 0) == -1) {   /* no more tapes, fail */
+           error("writer: Syncpipe failure during tape error");
+           /*NOTREACHED*/
+       }
+    }
+    if (syncpipe_putstr(errstr) == -1) {
+       error("writer: Syncpipe failure putting '%s'", errstr);
+       /*NOTREACHED*/
+    }
 
  error_ack:
     /* wait for reader to acknowledge error */
     do {
-       tok = syncpipe_get(&tmpint);
-       if(tok != 'W' && tok != 'C' && tok != 'e')
+       if ((tok = syncpipe_get(&tmpint)) == -1) {
+           error("writer: syncpipe failure waiting for error ack");
+           /*NOTREACHED*/
+       }
+
+       if (tok != 'W' && tok != 'C' && tok != 'e') {
            error("writer: got '%c' unexpectedly after error", tok);
-    } while(tok != 'e');
+           /*NOTREACHED*/
+       }
+    } while (tok != 'e');
     return;
 
  reader_buffer_snafu:
-    syncpipe_put('x', 0);
+    if (syncpipe_put('x', 0) == -1) {
+       error("writer: syncpipe failure putting buffer snafu");
+       /*NOTREACHED*/
+    }
     return;
 }
 
-int write_buffer(bp)
-buffer_t *bp;
+int
+write_buffer(
+    buffer_t *bp)
 {
-    int rc;
+    ssize_t rc;
 
     assert(bp->status == FULL);
 
     startclock();
-    rc = tapefd_write(tape_fd, bp->buffer, bp->size);
-    if(rc == bp->size) {
+    rc = tapefd_write(tape_fd, bp->buffer, (size_t)bp->size);
+    if (rc == (ssize_t)bp->size) {
 #if defined(NEED_RESETOFS)
        static double tape_used_modulus_2gb = 0;
 
@@ -2001,23 +2519,28 @@ buffer_t *bp;
         * go silly on us.
         */
        tape_used_modulus_2gb += (double)rc;
-       if(tape_used_modulus_2gb + (double)rc > (double)0x7fffffff) {
+       if (tape_used_modulus_2gb + (double)rc > (double)0x7fffffff) {
            tape_used_modulus_2gb = 0;
            tapefd_resetofs(tape_fd);
        }
 #endif
        wrwait = timesadd(wrwait, stopclock());
        total_writes += 1;
-       total_tape_used += (double)rc;
+       total_tape_used += (off_t)rc;
        bp->status = EMPTY;
-       if(interactive || bufdebug) dumpstatus(bp);
-       if(interactive) fputs("W", stderr);
+       if (interactive || bufdebug)
+           dumpstatus(bp);
+       if (interactive)
+           fputs("W", stderr);
 
-       if(bufdebug) {
+       if (bufdebug) {
            fprintf(stderr, "taper: w: put R%d\n", (int)(bp-buftable));
            fflush(stderr);
        }
-       syncpipe_put('R', bp-buftable);
+       if (syncpipe_put('R', (int)(bp-buftable)) == -1) {
+           error("writer: Syncpipe failure during advancing write bufffer");
+           /*NOTREACHED*/
+       }
        return 1;
     } else {
        errstr = newvstralloc(errstr,
@@ -2025,7 +2548,8 @@ buffer_t *bp;
                              (rc != -1) ? "short write" : strerror(errno),
                              NULL);
        wrwait = timesadd(wrwait, stopclock());
-       if(interactive) fputs("[WE]", stderr);
+       if (interactive)
+           fputs("[WE]", stderr);
        return 0;
     }
 }
@@ -2042,7 +2566,8 @@ cleanup(void)
  * Cleanup shared memory segments 
  */
 static void 
-signal_handler(int signum)
+signal_handler(
+    int signum)
 {
     log_add(L_INFO, "Received signal %d", signum);
 
@@ -2056,7 +2581,7 @@ signal_handler(int signum)
  * segments
  */
 static void
-install_signal_handlers(void) 
+install_signal_handlers(void)
 {
     struct sigaction act;
 
@@ -2068,26 +2593,32 @@ install_signal_handlers(void)
 
     if (sigaction(SIGINT, &act, NULL) != 0) {
        error("taper: couldn't install SIGINT handler [%s]", strerror(errno));
+       /*NOTREACHED*/
     }
 
     if (sigaction(SIGHUP, &act, NULL) != 0) {
        error("taper: couldn't install SIGHUP handler [%s]", strerror(errno));
+       /*NOTREACHED*/
     }
    
     if (sigaction(SIGTERM, &act, NULL) != 0) {
        error("taper: couldn't install SIGTERM handler [%s]", strerror(errno));
+       /*NOTREACHED*/
     }
 
     if (sigaction(SIGUSR1, &act, NULL) != 0) {
        error("taper: couldn't install SIGUSR1 handler [%s]", strerror(errno));
+       /*NOTREACHED*/
     }
 
     if (sigaction(SIGUSR2, &act, NULL) != 0) {
        error("taper: couldn't install SIGUSR2 handler [%s]", strerror(errno));
+       /*NOTREACHED*/
     }
 
     if (sigaction(SIGALRM, &act, NULL) != 0) {
        error("taper: couldn't install SIGALRM handler [%s]", strerror(errno));
+       /*NOTREACHED*/
     }
 }
 
@@ -2102,44 +2633,51 @@ install_signal_handlers(void)
 
 int shmid = -1;
 
-char *attach_buffers(size)
-    unsigned int size;
+char *
+attach_buffers(
+    size_t size)
 {
     char *result;
 
     shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0700);
-    if(shmid == -1) {
+    if (shmid == -1) {
        return NULL;
     }
 
     result = (char *)shmat(shmid, (SHM_ARG_TYPE *)NULL, 0);
 
-    if(result == (char *)-1) {
+    if (result == (char *)-1) {
        int save_errno = errno;
 
        destroy_buffers();
        errno = save_errno;
        error("shmat: %s", strerror(errno));
+       /*NOTREACHED*/
     }
 
     return result;
 }
 
 
-void detach_buffers(bufp)
-    char *bufp;
+void
+detach_buffers(
+    char *bufp)
 {
     if ((bufp != NULL) &&
         (shmdt((SHM_ARG_TYPE *)bufp) == -1)) {
        error("shmdt: %s", strerror(errno));
+       /*NOTREACHED*/
     }
 }
 
-void destroy_buffers()
+void
+destroy_buffers(void)
 {
-    if(shmid == -1) return;    /* nothing to destroy */
-    if(shmctl(shmid, IPC_RMID, NULL) == -1) {
+    if (shmid == -1)
+       return; /* nothing to destroy */
+    if (shmctl(shmid, IPC_RMID, NULL) == -1) {
        error("shmctl: %s", strerror(errno));
+       /*NOTREACHED*/
     }
 }
 
@@ -2160,19 +2698,21 @@ void destroy_buffers()
 #endif
 
 int shmfd = -1;
-unsigned int saved_size;
+size_t saved_size;
 
-char *attach_buffers(size)
-    unsigned int size;
+char *
+attach_buffers(
+    size_t size)
 {
     char *shmbuf;
 
 #ifdef ZERO_FILE
     shmfd = open(ZERO_FILE, O_RDWR);
-    if(shmfd == -1) {
+    if (shmfd == -1) {
        error("attach_buffers: could not open %s: %s",
              ZERO_FILE,
              strerror(errno));
+        /*NOTREACHED*/
     }
 #endif
 
@@ -2186,19 +2726,22 @@ char *attach_buffers(size)
     return shmbuf;
 }
 
-void detach_buffers(bufp)
-char *bufp;
+void
+detach_buffers(
+    char *bufp)
 {
     if ((bufp != NULL) && 
        (munmap((void *)bufp, saved_size) == -1)) {
        error("detach_buffers: munmap: %s", strerror(errno));
+       /*NOTREACHED*/
     }
 
     if (shmfd != -1)
        aclose(shmfd);
 }
 
-void destroy_buffers()
+void
+destroy_buffers(void)
 {
 }
 
@@ -2217,140 +2760,244 @@ void destroy_buffers()
 
 int getpipe, putpipe;
 
-void syncpipe_init(rd, wr)
-int rd, wr;
+void
+syncpipe_init(
+    int rd,
+    int wr)
 {
     getpipe = rd;
     putpipe = wr;
 }
 
-char syncpipe_get(intp)
-int *intp;
+void
+syncpipe_read_error(
+    ssize_t    rc,
+    ssize_t    expected)
 {
-    int rc;
     char buf[sizeof(char) + sizeof(int)];
 
-    rc = fullread(getpipe, buf, sizeof(buf));
-    if(rc == 0)                /* EOF */
-       error("syncpipe_get: %c: unexpected EOF", *procname);
-    else if(rc < 0)
-       error("syncpipe_get: %c: %s", *procname, strerror(errno));
-    else if(rc != sizeof(buf))
-       error("syncpipe_get: %s", "short read");
+    if (rc == 0) {
+       dbprintf(("syncpipe_get %s halting: Unexpected read EOF\n", procname));
+       fprintf(stderr, "syncpipe_get %s halting: Unexpected read EOF\n", procname);
+    } else if (rc < 0) {
+       dbprintf(("syncpipe_get %s halting: Read error - %s\n",
+                       procname, strerror(errno)));
+       fprintf(stderr, "syncpipe_get %s halting: Read error - %s\n",
+                       procname, strerror(errno));
+    } else {
+       dbprintf(("syncpipe_get %s halting: Read "
+               SSIZE_T_FMT " bytes short of " SSIZE_T_FMT "\n",
+               procname, (SSIZE_T_FMT_TYPE)(rc - expected),
+               (SSIZE_T_FMT_TYPE)expected));
+       fprintf(stderr, "syncpipe_get %s halting: Read "
+               SSIZE_T_FMT " bytes short of " SSIZE_T_FMT "\n",
+               procname, (SSIZE_T_FMT_TYPE)(rc - expected),
+               (SSIZE_T_FMT_TYPE)expected);
+    }
+    /* Halt the other side if it's still alive */
+    buf[0] = 'H';
+    memset(&buf[1], 0, SIZEOF(int));
+    if (write(putpipe, buf, SIZEOF(buf)))
+       return;
+}
+
+void
+syncpipe_write_error(
+    ssize_t    rc,
+    ssize_t    expected)
+{
+    char buf[sizeof(char) + sizeof(int)];
+
+    if (rc == 0) {             /* EOF */
+       dbprintf(("syncpipe %s halting: Write EOF\n", procname));
+       fprintf(stderr, "syncpipe %s halting: Write EOF\n", procname);
+    } else if (rc < 0) {
+       dbprintf(("syncpipe %s halting: Write error - %s\n",
+                       procname, strerror(errno)));
+       fprintf(stderr, "syncpipe %s halting: Write error - %s\n",
+                       procname, strerror(errno));
+    } else {
+       dbprintf(("syncpipe %s halting: Write "
+                       SSIZE_T_FMT " bytes short of " SSIZE_T_FMT "\n",
+                       procname, (SSIZE_T_FMT_TYPE)(rc - expected),
+                       (SSIZE_T_FMT_TYPE)expected));
+       fprintf(stderr, "syncpipe %s halting: Write "
+                       SSIZE_T_FMT " bytes short of " SSIZE_T_FMT "\n",
+                       procname, (SSIZE_T_FMT_TYPE)(rc - expected),
+                       (SSIZE_T_FMT_TYPE)expected);
+    }
+    /* Halt the other side if it's still alive */
+    buf[0] = 'H';
+    memset(&buf[1], 0, SIZEOF(int));
+    if (write(putpipe, buf, SIZEOF(buf)))
+       return;
+}
+
+int
+syncpipe_get(
+    int *intp)
+{
+    ssize_t rc;
+    char buf[SIZEOF(char) + SIZEOF(int)];
 
-    if(bufdebug && *buf != 'R' && *buf != 'W') {
-       fprintf(stderr,"taper: %c: getc %c\n",*procname,*buf);
+    memset(buf, 0, sizeof(buf));
+    rc = fullread(getpipe, buf, SIZEOF(buf));
+    if (rc != (ssize_t)sizeof(buf)) {
+       syncpipe_read_error(rc, (ssize_t)sizeof(buf));
+       return (-1);
+    }
+
+    if (bufdebug && *buf != 'R' && *buf != 'W') {
+       fprintf(stderr,"taper: %c: getc %c\n", *procname, *buf);
        fflush(stderr);
     }
 
-    memcpy(intp, &buf[1], sizeof(int));
-    return buf[0];
+    memcpy(intp, &buf[1], SIZEOF(int));
+    return (int)buf[0];
 }
 
-int syncpipe_getint()
+int
+syncpipe_getint(void)
 {
-    int rc, i;
+    ssize_t rc;
+    int i = 0;
 
-    if ((rc = fullread(getpipe, &i, sizeof(i))) != sizeof(i))
-       error("syncpipe_getint: %s", rc < 0 ? strerror(errno) : "short read");
+    rc = fullread(getpipe, &i, SIZEOF(i));
+    if (rc != (ssize_t)sizeof(i)) {
+       syncpipe_read_error(rc, (ssize_t)sizeof(i));
+       return (-1);
+    }
 
     return (i);
 }
 
 
-char *syncpipe_getstr()
+char *
+syncpipe_getstr(void)
 {
-    int rc, len;
+    ssize_t rc;
+    int len;
     char *str;
 
-    if((len = syncpipe_getint()) <= 0) {
-       error("syncpipe_getstr: Protocol error - Invalid length (%d)", len);
-       /* NOTREACHED */
+    if ((len = syncpipe_getint()) <= 0) {
+       fprintf(stderr, "syncpipe %s halting: Protocol error - "
+                       "Invalid string length (%d)\n", procname, len);
+       syncpipe_put('H', 0); /* Halt the other side */
+       exit(1);
+       /*NOTREACHED*/
     }
 
-    str = alloc(len);
+    str = alloc((size_t)len);
 
-    if ((rc = fullread(getpipe, str, len)) != len) {
-       error("syncpipe_getstr: %s", rc < 0 ? strerror(errno) : "short read");
-       /* NOTREACHED */
+    rc = fullread(getpipe, str, (size_t)len);
+    if (rc != (ssize_t)len) {
+       syncpipe_read_error(rc, (ssize_t)len);
+       return (NULL);
     }
-
     return (str);
 }
 
 
-void syncpipe_put(chi, intval)
-int chi;
-int intval;
+int
+syncpipe_put(
+    int chi,
+    int intval)
 {
     char buf[sizeof(char) + sizeof(int)];
+    ssize_t    rc;
 
     buf[0] = (char)chi;
-    memcpy(&buf[1], &intval, sizeof(int));
-    if(bufdebug && buf[0] != 'R' && buf[0] != 'W') {
+    memcpy(&buf[1], &intval, SIZEOF(int));
+    if (bufdebug && buf[0] != 'R' && buf[0] != 'W') {
        fprintf(stderr,"taper: %c: putc %c\n",*procname,buf[0]);
        fflush(stderr);
     }
 
-    if (fullwrite(putpipe, buf, sizeof(buf)) < 0)
-       error("syncpipe_put: %s", strerror(errno));
+    rc = fullwrite(putpipe, buf, SIZEOF(buf));
+    if (rc != (ssize_t)sizeof(buf)) {
+       syncpipe_write_error(rc, (ssize_t)sizeof(buf));
+       return (-1);
+    }
+    return (0);
 }
 
-void syncpipe_putint(i)
-int i;
+int
+syncpipe_putint(
+    int i)
 {
+    ssize_t    rc;
 
-    if (fullwrite(putpipe, &i, sizeof(i)) < 0)
-       error("syncpipe_putint: %s", strerror(errno));
+    rc = fullwrite(putpipe, &i, SIZEOF(i));
+    if (rc != (ssize_t)sizeof(i)) {
+       syncpipe_write_error(rc, (ssize_t)sizeof(i));
+       return (-1);
+       /* NOTREACHED */
+    }
+    return (0);
 }
 
-void syncpipe_putstr(str)
-const char *str;
+int
+syncpipe_putstr(
+    const char *str)
 {
-    int n;
+    ssize_t n, rc;
 
-    n = strlen(str)+1;                         /* send '\0' as well */
-    syncpipe_putint(n);
-    if (fullwrite(putpipe, str, n) < 0)
-       error("syncpipe_putstr: %s", strerror(errno));
-}
+    if(!str)
+       str = "UNKNOWN syncpipe_putstr STRING";
 
+    n = (ssize_t)strlen(str) + 1;                      /* send '\0' as well */
+    syncpipe_putint((int)n);
+
+    rc = fullwrite(putpipe, str, (size_t)n);
+    if (rc != n) {
+       syncpipe_write_error(rc, n);
+       return (-1);
+    }
+    return (0);
+}
 \f
 /*
  * ========================================================================
  * TAPE MANIPULATION SUBSYSTEM
  *
  */
+int label_tape(void);
 
 /* local functions */
-int label_tape P((void));
 
-int label_tape()
+/* return 0 on success              */
+/* return 1 on error and set errstr */
+int
+label_tape(void)
 {  
     char *conf_tapelist_old = NULL;
     char *result;
     static int first_call = 1;
     char *timestamp;
-    char *error_msg;
+    char *error_msg = NULL;
     char *s, *r;
     int slot = -1;
 
-    if (taper_scan(NULL, &label, &timestamp, &error_msg, &tapedev) < 0) {
-        fprintf(stderr, "%s\n", error_msg);
-       errstr = newstralloc(errstr, error_msg);
-        amfree(error_msg);
-        amfree(timestamp);
+    amfree(label);
+    amfree(tapedev);
+    if (taper_scan(NULL, &label, &timestamp, &tapedev, CHAR_taperscan_output_callback, &error_msg) < 0) {
+       fprintf(stderr, "%s\n", error_msg);
+       errstr = error_msg;
+       error_msg = NULL;
+       amfree(timestamp);
        return 0;
     }
+    amfree(timestamp);
     if(error_msg) {
        s = error_msg; r = NULL;
        while((s=strstr(s,"slot "))) { s += 5; r=s; };
        if(r) {
            slot = atoi(r);
        }
+       amfree(error_msg);
     }
-    if((tape_fd = tape_open(tapedev, O_WRONLY)) == -1) {
-       if(errno == EACCES) {
+    if ((tape_fd = tape_open(tapedev, O_WRONLY)) == -1) {
+       if (errno == EACCES) {
            errstr = newstralloc(errstr,
                                 "writing label: tape is write protected");
        } else {
@@ -2360,23 +3007,23 @@ int label_tape()
        return 0;
     }
 
-    tapefd_setinfo_length(tape_fd, tt->length);
+    tapefd_setinfo_length(tape_fd, tapetype_get_length(tt));
 
-    tapefd_setinfo_datestamp(tape_fd, taper_datestamp);
+    tapefd_setinfo_datestamp(tape_fd, taper_timestamp);
     tapefd_setinfo_disk(tape_fd, label);
-    result = tapefd_wrlabel(tape_fd, taper_datestamp, label, tt_blocksize);
-    if(result != NULL) {
+    result = tapefd_wrlabel(tape_fd, taper_timestamp, label, tt_blocksize);
+    if (result != NULL) {
        errstr = newstralloc(errstr, result);
        return 0;
     }
 
     if(slot > -1) {
        fprintf(stderr, "taper: slot: %d wrote label `%s' date `%s'\n", slot,
-               label, taper_datestamp);
+               label, taper_timestamp);
     }
     else {
        fprintf(stderr, "taper: wrote label `%s' date `%s'\n", label,
-               taper_datestamp);
+               taper_timestamp);
     }
     fflush(stderr);
 
@@ -2390,67 +3037,74 @@ int label_tape()
 #endif /* HAVE_LIBVTBLC */
 
     if (strcmp(label, FAKE_LABEL) != 0) {
-
-       if(cur_tape == 0) {
+       if (cur_tape == 0) {
            conf_tapelist_old = stralloc2(conf_tapelist, ".yesterday");
        } else {
            char cur_str[NUM_STR_SIZE];
 
-           snprintf(cur_str, sizeof(cur_str), "%d", cur_tape - 1);
+           snprintf(cur_str, SIZEOF(cur_str), "%d", cur_tape - 1);
            conf_tapelist_old = vstralloc(conf_tapelist,
                                          ".today.", cur_str, NULL);
        }
-       if(write_tapelist(conf_tapelist_old)) {
+
+       if (write_tapelist(conf_tapelist_old)) {
            error("could not write tapelist: %s", strerror(errno));
+           /*NOTREACHED*/
        }
        amfree(conf_tapelist_old);
 
        remove_tapelabel(label);
-       add_tapelabel(atoi(taper_datestamp), label);
-       if(write_tapelist(conf_tapelist)) {
+       add_tapelabel(taper_timestamp, label);
+       if (write_tapelist(conf_tapelist)) {
            error("could not write tapelist: %s", strerror(errno));
+           /*NOTREACHED*/
        }
     }
 
     log_add(L_START, "datestamp %s label %s tape %d",
-           taper_datestamp, label, cur_tape);
+           taper_timestamp, label, cur_tape);
     if (first_call && strcmp(label, FAKE_LABEL) == 0) {
        first_call = 0;
        log_add(L_WARNING, "tapedev is %s, dumps will be thrown away", tapedev);
     }
 
-    total_tape_used=0.0;
+    total_tape_used=(off_t)0;
     total_tape_fm = 0;
 
     return 1;
 }
 
-int first_tape(new_datestamp)
-char *new_datestamp;
+/* return 0 on error and set errstr */
+/* return 1 on success              */
+int
+first_tape(
+    char *new_datestamp)
 {
-    if((have_changer = changer_init()) < 0) {
+    if ((have_changer = changer_init()) < 0) {
        error("changer initialization failed: %s", strerror(errno));
+       /*NOTREACHED*/
     }
     changer_debug = 1;
 
-    taper_datestamp = newstralloc(taper_datestamp, new_datestamp);
+    taper_timestamp = newstralloc(taper_timestamp, new_datestamp);
 
-    if(!label_tape())
+    if (!label_tape())
        return 0;
 
     filenum = 0;
     return 1;
 }
 
-int next_tape(writerror)
-int writerror;
+int
+next_tape(
+    int writerror)
 {
     end_tape(writerror);
 
-    if(++cur_tape >= runtapes)
+    if (++cur_tape >= runtapes)
        return 0;
 
-    if(!label_tape()) {
+    if (!label_tape()) {
        return 0;
     }
 
@@ -2459,33 +3113,34 @@ int writerror;
 }
 
 
-int end_tape(writerror)
-int writerror;
+int
+end_tape(
+    int writerror)
 {
     char *result;
     int rc = 0;
 
-    if(tape_fd >= 0) {
-       log_add(L_INFO, "tape %s kb %ld fm %d %s", 
+    if (tape_fd >= 0) {
+       log_add(L_INFO, "tape %s kb " OFF_T_FMT " fm %d %s", 
                label,
-               (long) ((total_tape_used+1023.0) / 1024.0),
+               (OFF_T_FMT_TYPE)((total_tape_used+(off_t)1023) / (off_t)1024),
                total_tape_fm,
                writerror? errstr : "[OK]");
 
-       fprintf(stderr, "taper: writing end marker. [%s %s kb %ld fm %d]\n",
-               label,
+       fprintf(stderr, "taper: writing end marker. [%s %s kb "
+               OFF_T_FMT " fm %d]\n", label,
                writerror? "ERR" : "OK",
-               (long) ((total_tape_used+1023.0) / 1024.0),
+               (OFF_T_FMT_TYPE)((total_tape_used+(off_t)1023) / (off_t)1024),
                total_tape_fm);
        fflush(stderr);
-       if(! writerror) {
-           if(! write_filemark()) {
+       if (! writerror) {
+           if (! write_filemark()) {
                rc = 1;
                goto common_exit;
            }
 
-           result = tapefd_wrendmark(tape_fd, taper_datestamp, tt_blocksize);
-           if(result != NULL) {
+           result = tapefd_wrendmark(tape_fd, taper_timestamp, tt_blocksize);
+           if (result != NULL) {
                errstr = newstralloc(errstr, result);
                rc = 1;
                goto common_exit;
@@ -2497,14 +3152,14 @@ int writerror;
     if (tape_fd >= 0 && is_zftape(tapedev) == 1) {
        /* rewind the tape */
 
-       if(tapefd_rewind(tape_fd) == -1 ) {
+       if (tapefd_rewind(tape_fd) == -1 ) {
            errstr = newstralloc2(errstr, "rewinding tape: ", strerror(errno));
            rc = 1;
            goto common_exit;
        }
        /* close the tape */
 
-       if(tapefd_close(tape_fd) == -1) {
+       if (tapefd_close(tape_fd) == -1) {
            errstr = newstralloc2(errstr, "closing tape: ", strerror(errno));
            rc = 1;
            goto common_exit;
@@ -2517,7 +3172,7 @@ int writerror;
        fflush(stderr);
     
        if ((tape_fd = raw_tape_open(rawtapedev, O_RDWR)) == -1) {
-           if(errno == EACCES) {
+           if (errno == EACCES) {
                errstr = newstralloc(errstr,
                                     "updating volume table: tape is write protected");
            } else {
@@ -2539,7 +3194,7 @@ int writerror;
        }
        /* set volume label and date for first entry */
        vtbl_no = 0;
-       if(set_label(label, volumes, num_volumes, vtbl_no)){
+       if (set_label(label, volumes, num_volumes, vtbl_no)) {
            errstr = newstralloc2(errstr,
                                  "setting label for entry 1: ",
                                  strerror(errno));
@@ -2547,7 +3202,7 @@ int writerror;
            goto common_exit;
        }
        /* date of start writing this tape */
-       if (set_date(start_datestr, volumes, num_volumes, vtbl_no)){
+       if (set_date(start_datestr, volumes, num_volumes, vtbl_no)) {
            errstr = newstralloc2(errstr,
                                  "setting date for entry 1: ", 
                                  strerror(errno));
@@ -2555,22 +3210,22 @@ int writerror;
            goto common_exit;
        }
        /* set volume labels and dates for backup files */
-       for (vtbl_no = 1; vtbl_no <= num_volumes - 2; vtbl_no++){ 
+       for (vtbl_no = 1; vtbl_no <= num_volumes - 2; vtbl_no++) 
            fprintf(stderr,"taper: label %i: %s, date %s\n", 
                    vtbl_no,
                    vtbl_entry[vtbl_no].label,
                    vtbl_entry[vtbl_no].date);
            fflush(stderr);
-           if(set_label(vtbl_entry[vtbl_no].label, 
-                        volumes, num_volumes, vtbl_no)){
+           if (set_label(vtbl_entry[vtbl_no].label, 
+                        volumes, num_volumes, vtbl_no)) {
                errstr = newstralloc2(errstr,
                                      "setting label for entry i: ", 
                                      strerror(errno));
                rc = 1;
                goto common_exit;
            }
-           if(set_date(vtbl_entry[vtbl_no].date, 
-                       volumes, num_volumes, vtbl_no)){
+           if (set_date(vtbl_entry[vtbl_no].date, 
+                       volumes, num_volumes, vtbl_no)) {
                errstr = newstralloc2(errstr,
                                      "setting date for entry i: ",
                                      strerror(errno));
@@ -2580,7 +3235,7 @@ int writerror;
        }
        /* set volume label and date for last entry */
        vtbl_no = num_volumes - 1;
-       if(set_label("AMANDA Tape End", volumes, num_volumes, vtbl_no)){
+       if (set_label("AMANDA Tape End", volumes, num_volumes, vtbl_no)) {
            errstr = newstralloc2(errstr,
                                  "setting label for last entry: ", 
                                  strerror(errno));
@@ -2588,7 +3243,7 @@ int writerror;
            goto common_exit;
        }
        datestr = NULL; /* take current time */ 
-       if (set_date(datestr, volumes, num_volumes, vtbl_no)){
+       if (set_date(datestr, volumes, num_volumes, vtbl_no)) {
            errstr = newstralloc2(errstr,
                                  "setting date for last entry 1: ", 
                                  strerror(errno));
@@ -2615,7 +3270,7 @@ int writerror;
 
 common_exit:
 
-    if(tape_fd >= 0 && tapefd_close(tape_fd) == -1 && ! writerror) {
+    if (tape_fd >= 0 && tapefd_close(tape_fd) == -1 && ! writerror) {
        errstr = newstralloc2(errstr, "closing tape: ", strerror(errno));
        rc = 1;
     }
@@ -2626,14 +3281,13 @@ common_exit:
 }
 
 
-int write_filemark()
+int
+write_filemark(void)
 {
-    if(tapefd_weof(tape_fd, 1) == -1) {
+    if (tapefd_weof(tape_fd, (off_t)1) == -1) {
        errstr = newstralloc2(errstr, "writing filemark: ", strerror(errno));
        return 0;
     }
     total_tape_fm++;
     return 1;
 }
-
-