/* Distributed Checksum Clearinghouse * * --C-LICENSE-- * $Revision: 1.29 $ */ #include "srvr_defs.h" static int read_rcd_fd = -1; #define BUF_SIZE (64*1024) static u_char read_rcd_buf[BUF_SIZE]; static u_int read_rcd_bufsize = BUF_SIZE; static off_t read_rcd_base; static u_int read_rcd_buflen; int read_db(DCC_EMSG *emsg, void *buf, u_int buf_len, int fd, off_t pos, const char *file_nm) { int i; if (-1 == lseek(fd, pos, SEEK_SET)) { dcc_pemsg(EX_IOERR, emsg, "lseek(%s, 0): %s", DB_NM2PATH_ERR(file_nm), ERROR_STR()); return -1; } i = read(fd, buf, buf_len); if (i >= 0) return i; dcc_pemsg(EX_IOERR, emsg, "read(%s): %s", DB_NM2PATH_ERR(file_nm), ERROR_STR()); return -1; } u_char read_db_hdr(DCC_EMSG *emsg, DB_HDR *hdrp, int fd, const char *file_nm) { int i; i = read_db(emsg, hdrp, sizeof(*hdrp), fd, 0, file_nm); if (i == sizeof(*hdrp)) return 1; if (i >= 0) dcc_pemsg(EX_DATAERR, emsg, "found only %d bytes in %s", i, file_nm); return 0; } /* invalidate the read_rcd() read-ahead cache */ void read_rcd_invalidate(u_int bufsize) { read_rcd_fd = -1; /* Set the size of the buffer for the next read_rcd() * to bufsize rounded up to an even system page size * but not larger than BUF_SIZE, * and BUF_SIZE if bufsize was 0. */ if (sys_pagesize == 0) sys_pagesize = getpagesize(); bufsize += sys_pagesize-1; bufsize -= bufsize % sys_pagesize; if (bufsize == 0 || bufsize > BUF_SIZE) bufsize = BUF_SIZE; read_rcd_bufsize = bufsize; } static int read_rcd_sub(DCC_EMSG *emsg, void *buf, u_int buflen, int fd, off_t pos, const char *file_nm) { int i; if (fd != read_rcd_fd || pos < read_rcd_base || pos+buflen > read_rcd_base+read_rcd_buflen) { if (sys_pagesize == 0) sys_pagesize = getpagesize(); read_rcd_base = pos - (pos % sys_pagesize); i = read_db(emsg, read_rcd_buf, read_rcd_bufsize, read_rcd_fd = fd, read_rcd_base, file_nm); if (i <= 0) { read_rcd_fd = -1; return i; } read_rcd_buflen = i; if (buflen > read_rcd_buflen) buflen = read_rcd_buflen; } memcpy(buf, &read_rcd_buf[pos-read_rcd_base], buflen); return buflen; } int /* -1=error 0=eof >0=record length */ read_rcd(DCC_EMSG *emsg, DB_RCD *rcd, int fd, off_t pos, const char *file_nm) { int i, cks_len, num_cks; /* read a record, starting with its beginning */ i = read_rcd_sub(emsg, rcd, DB_RCD_HDR_LEN, fd, pos, file_nm); if (DB_RCD_HDR_LEN != i) { if (i == 0) return 0; if (i > 0) { dcc_pemsg(EX_DATAERR, emsg, "header of record at "OFF_HPAT" of %s" " truncated by %d bytes", lseek(fd, 0, SEEK_CUR) - i, DB_NM2PATH_ERR(file_nm), DB_RCD_HDR_LEN-i); } return -1; } num_cks = DB_NUM_CKS(rcd); if (num_cks > DIM(rcd->cks)) { dcc_pemsg(EX_DATAERR, emsg, "bogus checksum count %#x at "OFF_HPAT" of %s", rcd->fgs_num_cks, lseek(fd, 0, SEEK_CUR), DB_NM2PATH_ERR(file_nm)); return -1; } cks_len = num_cks * sizeof(rcd->cks[0]); if (cks_len != 0) { i = read_rcd_sub(emsg, rcd->cks, cks_len, fd, pos+DB_RCD_HDR_LEN, file_nm); if (i != cks_len) { if (i < 0) return -1; if (!i) dcc_pemsg(EX_DATAERR, emsg, "record at "OFF_HPAT" of %s" " truncated after header", lseek(fd, 0, SEEK_CUR), DB_NM2PATH_ERR(file_nm)); else dcc_pemsg(EX_DATAERR, emsg, "record at "OFF_HPAT" of %s" " truncated by %d bytes", lseek(fd, 0, SEEK_CUR), DB_NM2PATH_ERR(file_nm), cks_len-i); return 0; } } return DB_RCD_HDR_LEN+cks_len; }