226 #include <sys/types.h> 235 #include <sys/stat.h> 236 #include <sys/time.h> 250 int gzlog_count = -1;
251 # define BAIL(n) do { if (n == gzlog_bail && gzlog_count-- == 0) \ 252 longjmp(gzlog_jump, gzlog_bail); } while (0) 274 #define COMPRESS_OP 2 278 #define PULL2(p) ((p)[0]+((uint)((p)[1])<<8)) 279 #define PULL4(p) (PULL2(p)+((ulong)PULL2(p+2)<<16)) 280 #define PULL8(p) (PULL4(p)+((off_t)PULL4(p+4)<<32)) 283 #define PUT2(p,a) do {(p)[0]=a;(p)[1]=(a)>>8;} while(0) 284 #define PUT4(p,a) do {PUT2(p,a);PUT2(p+2,a>>16);} while(0) 285 #define PUT8(p,a) do {PUT4(p,a);PUT4(p+4,a>>32);} while(0) 288 #define LOGID "\106\035\172" 312 39, 0,
'a',
'p', 35, 0
316 #define HEAD sizeof(log_gzhead) 320 52, 0, 0, 0, 0, 0, 0, 0,
321 52, 0, 0, 0, 0, 0, 0, 0,
322 0, 0, 0, 0, 0, 0, 0, 0,
323 0, 0, 0, 0, 0, 0, 0, 0,
328 #define EXTRA sizeof(log_gzext) 337 #define BODY sizeof(log_gzbody) 353 strcpy(log->
end,
".lock");
354 while ((fd = open(log->
path, O_CREAT | O_EXCL, 0644)) < 0) {
357 if (stat(log->
path, &st) == 0 && time(NULL) - st.st_mtime >
PATIENCE) {
364 if (stat(log->
path, &st) == 0)
365 log->
lock = st.st_mtime;
376 strcpy(log->
end,
".lock");
377 utimes(log->
path, NULL);
378 if (stat(log->
path, &st) == 0)
379 log->
lock = st.st_mtime;
388 strcpy(log->
end,
".lock");
389 if (stat(log->
path, &st) || st.st_mtime != log->
lock)
400 strcpy(log->
end,
".lock");
427 log->
back = 3 + (buf[
HEAD + 34] & 7);
428 op = (buf[
HEAD + 34] >> 3) & 3;
440 unsigned char ext[
EXTRA];
449 ext[34] = log->
back - 3 + (op << 3);
465 unsigned char buf[6];
469 len = back > 8 ? 2 : 1;
470 mask = 0x80 >> ((back - 1) & 7);
476 if (back != 8 && (lseek(log->
fd, log->
last - len,
SEEK_SET) < 0 ||
477 read(log->
fd, buf, 1) != 1))
485 buf[2 - len] = (*buf & (mask - 1)) + (last ? mask : 0);
492 write(log->
fd, buf + 2 - len, len + 4) != len + 4 ||
505 unsigned char buf[8];
521 if (
write(log->
fd, data, put) != put)
552 if (
write(log->
fd, buf, 8) != 8 ||
553 (end = lseek(log->
fd, 0,
SEEK_CUR)) < 0 || ftruncate(log->
fd, end))
559 strcpy(log->
end,
".add");
577 strcpy(log->
end,
".add");
582 strcpy(log->
end,
".dict");
586 strcpy(dest, log->
path);
587 strcpy(log->
end,
".temp");
588 ret = rename(log->
path, dest);
590 if (ret && errno != ENOENT)
615 unsigned char buf[
DICT];
628 strcpy(log->
end,
".dict");
629 fd = open(log->
path, O_RDONLY, 0);
644 if (lseek(log->
fd, log->
first - (log->
back > 8 ? 2 : 1),
654 max = (((
uint)0 - 1) >> 1) + 1;
663 if (got &&
write(log->
fd, buf, got) != got) {
678 read(log->
fd, buf, 1) != 1)
683 while ((*buf & ((
uint)1 << (8 - log->
back++))) == 0)
705 (end = lseek(log->
fd, 0,
SEEK_CUR)) < 0 || ftruncate(log->
fd, end))
724 strcpy(log->
end,
".repairs");
725 rec = fopen(log->
path,
"a");
728 fprintf(rec,
"%.24s %s recovery: %s\n", ctime(&now), op ==
APPEND_OP ?
729 "append" : (op ==
COMPRESS_OP ?
"compress" :
"replace"), record);
741 unsigned char *data = NULL;
750 strcpy(log->
end,
".add");
751 if (stat(log->
path, &st) == 0 && st.st_size) {
752 len = (size_t)(st.st_size);
753 if ((off_t)len != st.st_size ||
754 (data =
malloc(st.st_size)) == NULL) {
755 log_log(log, op,
"allocation failure");
758 if ((fd = open(log->
path, O_RDONLY, 0)) < 0) {
759 log_log(log, op,
".add file read failure");
762 ret = (size_t)
read(fd, data, len) != len;
765 log_log(log, op,
".add file read failure");
768 log_log(log, op,
"loaded .add file");
771 log_log(log, op,
"missing .add file!");
787 log_log(log, op, ret ?
"failure" :
"complete");
828 strcpy(log->
end,
".gz");
829 log->
fd = open(log->
path, O_RDWR | O_CREAT, 0644);
843 strcpy(log->
end,
".dict");
871 if (path == NULL || *path == 0)
875 log =
malloc(
sizeof(
struct log));
884 if (log->
path == NULL) {
888 strcpy(log->
path, path);
913 unsigned char *data, buf[5];
917 if (log == NULL || strcmp(log->
id,
LOGID))
927 len = ((size_t)(log->
last - log->
first) & ~(((size_t)1 << 10) - 1)) +
929 if ((data =
malloc(len)) == NULL)
939 if (
read(log->
fd, buf, 5) != 5)
941 block =
PULL2(buf + 1);
942 if (next + block > len ||
943 read(log->
fd, (
char *)data + next, block) != block)
952 strcpy(log->
end,
".add");
953 fd = open(log->
path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
956 ret = (size_t)
write(fd, data, len) != len;
962 strcpy(log->
end,
".temp");
963 fd = open(log->
path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
967 ret = (size_t)
write(fd, (
char *)data + len - next, next) != next;
1001 if (log == NULL || strcmp(log->
id,
LOGID))
1003 if (data == NULL || len <= 0)
1013 strcpy(log->
end,
".add");
1014 fd = open(log->
path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
1017 ret = (size_t)
write(fd, data, len) != len;
1018 if (ret | close(fd))
1047 if (log == NULL || strcmp(log->
id,
LOGID))
1054 if (log->
path != NULL)
1056 strcpy(log->
id,
"bad");
int gzlog_close(gzlog *logd)
int deflateSetDictionary(z_streamp strm, Bytef *dictionary, uInt dictLength)
static int log_open(struct log *log)
#define deflateInit2(strm, level, method, windowBits, memLevel, strategy)
static int log_mark(struct log *log, int op)
static void log_touch(struct log *log)
int deflateEnd(z_streamp strm)
static int log_last(struct log *log, int last)
static int log_lock(struct log *log)
static void log_unlock(struct log *log)
static void log_close(struct log *log)
unsigned long crc32(unsigned long crc, unsigned char *buf, uInt len)
gzlog * gzlog_open(char *path)
static int log_append(struct log *log, unsigned char *data, size_t len)
int gzlog_write(gzlog *logd, void *data, size_t len)
int write(ozstream &zs, const T *x, Items items)
static int log_check(struct log *log)
int deflatePrime(z_streamp strm, int bits, int value)
static unsigned char log_gzhead[]
static unsigned char log_gzext[]
static int log_replace(struct log *log)
int read(izstream &zs, T *x, Items items)
static int log_recover(struct log *log, int op)
int gzlog_compress(gzlog *logd)
static void log_log(struct log *log, int op, char *record)
static unsigned char log_gzbody[]
#define Z_DEFAULT_STRATEGY
int deflate(z_streamp strm, int flush)
static int log_head(struct log *log)
#define Z_DEFAULT_COMPRESSION
static int log_compress(struct log *log, unsigned char *data, size_t len)