#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <fcntl.h>
#include <limits.h>
#include <poll.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include "zlib.h"
#ifndef MAP_FAILED
#define MAP_FAILED (void *)(-1)
#endif
#define WAIT_SEC 5
#define arraysize(a) (sizeof a/sizeof *a)
char compress_flag[30];
void compress_one(const char *fname)
{
int fd;
char *buf;
fd = open(fname, O_RDONLY);
if (fd >= 0) {
struct stat st;
if (fstat(fd, &st) == 0) {
buf = (char *)mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
if (buf != MAP_FAILED) {
char gzname[256];
gzFile file;
sprintf(gzname, "%s.gz", fname);
unlink(gzname);
file = gzopen(gzname, compress_flag);
if (file) {
gzwrite(file, buf, st.st_size);
gzclose(file);
}
munmap(buf, st.st_size);
}
}
close(fd);
}
}
void *compress_one_once(void *fname)
{
int fd;
char chkname[256];
sprintf(chkname, "%s.once", (char *)fname);
fd = open(chkname, O_WRONLY|O_CREAT|O_EXCL, 0700);
if (fd >= 0) {
close(fd);
poll(NULL, 0, WAIT_SEC*1000);
unlink(chkname);
compress_one(fname);
}
free(fname);
return NULL;
}
void compress_file(const char *bbs, const char *fname, pthread_t *thr)
{
char *fnbuf;
if (!(fnbuf=malloc(256))) return;
sprintf(fnbuf, "%.200s/%.30s", bbs, fname);
pthread_create(thr, NULL, compress_one_once, fnbuf);
}
int main(int ac, char **av)
{
int i, mode = 6;
pthread_t thr[3];
if (!isatty(STDOUT_FILENO)) {
switch (fork()) {
case -1: return -1;
case 0: break;
default: return 0;
}
setsid();
i = open("/dev/null", O_RDWR);
if (i == -1) return -1;
dup2(i, STDIN_FILENO);
dup2(i, STDOUT_FILENO);
dup2(i, STDERR_FILENO);
close(i);
}
++av, --ac;
if (ac == 2 && isdigit(*av[1])) {
mode = atoi(av[1]);
--ac;
}
sprintf(compress_flag, "wb%d", mode);
if (ac == 1) {
compress_file(*av, "index.html", &thr[0]);
compress_file(*av, "subback.html", &thr[1]);
compress_file(*av, "subject.txt", &thr[2]);
for (i = 0; i < arraysize(thr); i++)
pthread_join(thr[i], NULL);
}
return 0;
}