
v20-qd-1213599553wzknjwd at riemann
Jun 9, 2008, 12:01 AM
Post #1 of 1
(268 views)
Permalink
|
--text follows this line-- Hi, I wrote next small program. It's good for hosts starting qmail with svc or [mn]init. If your queue is most of the time empty you can start qmail using it (I use it at home. Qmail delivers 20-30 messages daily). Otherwise srop reading here. Install: compile and copy qmaild in /var/qmail/bin Usage: Let assume that 'qmail-send' is a soft link to service dir and one can start qmail-send daemon with: svc -o qmail-start Then test qmaild with: 1) svc -d qmail-send 2) rm /service/qmail-send # see also bellow 3) /var/qmail/bin/qmaild /path/to/svc /path/to/qmail-send/start/script It's possible to start also: strace /var/qmail/bin/qmaild ... qmaild will start/stop qmail-send service by need. Most of the time you will have one process instead of four. I tested qmaild with ninit http://riemann.fmi.uni-sofia.bg/ninit/ It should work good also with svc from daemontools package. I'm not sure if one have to remove the link in 2) above. This is to prevent SVC system to start qmail-send automatic. If all works fine and your system has small queue you can prepare one service (qmaild) to start 3) and make a link to qmaild service in /service/ dir. Let same-one who start qmail with daemontools correct me if I made syntax errors. Russ, if you find qmaild.c usefull make a link on www.qmail.org, please! Nikola ------------------------------------------------------------ /* qmaild.c gcc -W -Wall -s -o qmaild qmaild.c diet -Os gcc -W -Wall -s -o qmaild qmaild.c -Wl,-N usage: qmaild /path/to/[mn]svc qmail_service author: Nikola Vladov http://riemann.fmi.uni-sofia.bg/programs/ */ #define QQ "/var/qmail/queue/" #define HASFLOCK #include <unistd.h> #define __USE_GNU #include <fcntl.h> #include <dirent.h> #include <sys/file.h> #include <sys/poll.h> #include <sys/wait.h> int mesg; typedef struct buffer { char *x; /* actual buffer space */ unsigned int p; /* current position */ unsigned int n; /* string postition */ unsigned int a; /* allocated buffer size */ int fd; } buffer; #ifdef __dietlibc__ #define get_de int res = getdents(d->fd, (struct dirent *)d->x, d->a) #else #define get_de off_t x; int res = getdirentries(d->fd, d->x, d->a, &x) #endif static struct dirent* read_dir(buffer *d) { struct dirent *de = (struct dirent*)(d->x + d->p); if (d->p >= d->n || (d->p += de->d_reclen) >= d->n) { get_de; if (res<=0) return 0; d->n=res; d->p=0; } return (struct dirent*)(d->x+d->p); } #ifdef HASFLOCK #define lock_exnb(fd) flock(fd,LOCK_EX | LOCK_NB) #else #define lock_exnb(fd) lockf(fd,2,0) #endif static int is_started() { int r,fd; fd = open(QQ "lock/sendmutex", O_WRONLY | O_NDELAY); if (fd<0) return -100; r = lock_exnb(fd); close(fd); return r; /* -1 running, 0 stopped */ } static void scan_dir() { struct dirent *d; char buf_space[512]; int fd = open(".", O_RDONLY | O_DIRECTORY); buffer b = { buf_space, 0, 0, sizeof(buf_space)-1, fd }; if (fd < 0) return; while (mesg==0 && (d = read_dir(&b))) { if (d->d_name[0] == '.') continue; if (chdir(d->d_name)==0) { scan_dir(); fchdir(fd); continue; } else mesg=1; } close(fd); } static void ex(char **argv, char *opt) { char *qm[4] = { argv[1], opt, argv[2], 0 }; int pid; while ((pid=fork()) == -1) sleep(1); if (pid == 0) { execve(*qm, qm, 0); _exit(127); } waitpid(pid, 0, 0); } int main (int argc, char **argv) { struct pollfd pfd[1]; int n; for (n=0; n<10; n++) close(n); if (argc < 3 || is_started() == -100) _exit(100); pfd[0].events = POLLIN; for (;;) { if (chdir(QQ "mess")) _exit(111); mesg = 0; scan_dir(); if (mesg==0) { if (is_started()) ex(argv, "-t"); pfd[0].fd = open(QQ "lock/trigger", O_RDWR); poll(pfd, 1, -1); close(pfd[0].fd); goto start; } else { start: if (is_started()==0) ex(argv, "-o"); } sleep(127); } }
|