Mercurial > hg > mlmmj
changeset 334:0a3a4868fd3c
-d option for mlmmj-maintd to work on all listdirs below the specified one
author | mmj |
---|---|
date | Sat, 11 Sep 2004 08:48:42 +1000 |
parents | d70614c2d99e |
children | 64540601d8a8 |
files | ChangeLog VERSION man/mlmmj-maintd.1 src/mlmmj-maintd.c |
diffstat | 4 files changed, 177 insertions(+), 98 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Fri Sep 10 17:15:44 2004 +1000 +++ b/ChangeLog Sat Sep 11 08:48:42 2004 +1000 @@ -1,3 +1,5 @@ + o Implement -d option for mlmmj-maintd to be able to supply it with a directory + containing several listdirs, where mlmmj-maintd then will run maintenance o Chown option and a fix for mlmmj-make-ml.sh. Thanks Ingo Lameter 1.0.0 o Replace index() with strchr()
--- a/VERSION Fri Sep 10 17:15:44 2004 +1000 +++ b/VERSION Sat Sep 11 08:48:42 2004 +1000 @@ -1,1 +1,1 @@ -1.0.0 +1.0.1
--- a/man/mlmmj-maintd.1 Fri Sep 10 17:15:44 2004 +1000 +++ b/man/mlmmj-maintd.1 Sat Sep 11 08:48:42 2004 +1000 @@ -3,7 +3,9 @@ mlmmj-maintd \- maintenance for mlmmj maintained lists .SH SYNOPSIS .B mlmmj-maintd -\fI-L /path/to/listdir \fR[\fI-F\fR] +[\fI-F\fR] \fI[-d\fR | \fI-L\fR] /path/to/dir +.HP +\fB\-d\fR: Full path to directory with lists .HP \fB\-L\fR: Full path to list directory .HP @@ -15,6 +17,12 @@ requests for e.g. subscription, resend list mails and clean up leftover files etc. +If a directory containing several lists exists, the \fB\-d\fR can be used to +specify this, making mlmmj-maintd perform a maintenance run in every listdir +below the specified one. + +Only either \fB\-d\fR or \fB\-L\fR can be specified at the same time. + It will run as a daemon, unless the \fB\-F\fR switch is specified, in which case it just runs once. The \fB\-F\fR option should be used when one wants to avoid running another daemon, and use e.g. cron to control it instead. In case @@ -23,10 +31,6 @@ .LP 0 */2 * * * /usr/bin/mlmmj-maintd -F -L /path/to/list -.SH BUGS -It's not yet possible to tell mlmmj-maintd to perform maintenance on all -lists (directories) in a directory yet. It's a high priority TODO item, so -expect it soonish. .SH AUTHORS This manual page was written by the following persons: .HP
--- a/src/mlmmj-maintd.c Fri Sep 10 17:15:44 2004 +1000 +++ b/src/mlmmj-maintd.c Sat Sep 11 08:48:42 2004 +1000 @@ -47,8 +47,11 @@ static void print_help(const char *prg) { - printf("Usage: %s -L /path/to/listdir [-F]\n" - " -L: Full path to list directory\n" + printf("Usage: %s [-L | -d] /path/to/dir [-F]\n" + " -d: Full path to directory with listdirs\n" + " Use this to run maintenance on all list directories\n" + " in that directory.\n" + " -L: Full path to one list directory\n" " -F: Don't fork, performing one maintenance run only.\n" " This option should be used when one wants to\n" " avoid running another daemon, and use e.g." @@ -737,99 +740,50 @@ return 0; } -int main(int argc, char **argv) +void do_maintenance(const char *listdir, const char *mlmmjsend, + const char *mlmmjbounce, const char *mlmmjunsub) { - int opt, daemonize = 1; - char *bindir, *listdir = NULL, *mlmmjsend, *mlmmjbounce, *mlmmjunsub; - char *logstr, *logname, *random; + char *random, *logname, *logstr; struct stat st; - uid_t uid; - - CHECKFULLPATH(argv[0]); - - log_set_name(argv[0]); + int maintdlogfd; + uid_t uid = getuid(); - while ((opt = getopt(argc, argv, "hFVL:")) != -1) { - switch(opt) { - case 'F': - daemonize = 0; - break; - case 'L': - listdir = optarg; - break; - case 'h': - print_help(argv[0]); - break; - case 'V': - print_version(argv[0]); - exit(0); - } + if(!listdir) + return; + + if(stat(listdir, &st) < 0) { + log_error(LOG_ARGS, "Could not stat(%s) " + "No maintenance run performed.", listdir); + return; } - if(listdir == NULL) { - fprintf(stderr, "You have to specify -L\n"); - fprintf(stderr, "%s -h for help\n", argv[0]); - exit(EXIT_FAILURE); + if(uid == 0) { /* We're root. Do something about it.*/ + if(setuid(st.st_uid) < 0) { + log_error(LOG_ARGS, "Could not setuid listdir owner."); + return; + } + } else if(uid != st.st_uid) { + log_error(LOG_ARGS, + "User ID not equal to the ID of %s. No " + "maintenance run performed.", listdir); + return; } if(chdir(listdir) < 0) { - log_error(LOG_ARGS, "Could not chdir(%s), exiting. " - "No maintenance performed.", listdir); - exit(EXIT_FAILURE); + log_error(LOG_ARGS, "Could not chdir(%s). " + "No maintenance run performed.", listdir); + return; } - /* sanity check since maintd should be invoked as root so it can - * setuid or as the owner of listdir */ - - if(listdir) { - if(stat(listdir, &st) == 0) { - uid = getuid(); - if(uid && uid != st.st_uid) { - log_error(LOG_ARGS, - "Have to invoke either as root " - "or as the user owning listdir"); - writen(STDERR_FILENO, - "Have to invoke either as root " - "or as the user owning listdir\n", 60); - exit(EXIT_FAILURE); - } - } else { - log_error(LOG_ARGS, "Could not stat %s", listdir); - exit(EXIT_FAILURE); - } - } - - if(uid == 0) { /* We're root. chown the logfile and setuid */ - chown(logname, st.st_uid, st.st_gid); - - if(setuid(st.st_uid) < 0) { - log_error(LOG_ARGS, "Could not setuid listdir owner"); - exit(EXIT_FAILURE); - } - } - - bindir = mydirname(argv[0]); - mlmmjsend = concatstr(2, bindir, "/mlmmj-send"); - mlmmjbounce = concatstr(2, bindir, "/mlmmj-bounce"); - mlmmjunsub = concatstr(2, bindir, "/mlmmj-unsub"); - myfree(bindir); - - if(daemonize && (mydaemon(listdir) < 0)) { - log_error(LOG_ARGS, "Could not daemonize. Only one " - "maintenance run will be done."); - daemonize = 0; - } - - for(;;) { random = random_str(); logname = concatstr(3, listdir, "/maintdlog-", random); myfree(random); - maintdlogfd = open(logname, O_WRONLY|O_EXCL|O_CREAT, - S_IRUSR|S_IWUSR); + + maintdlogfd = open(logname, O_WRONLY|O_EXCL|O_CREAT, S_IRUSR|S_IWUSR); if(maintdlogfd < 0) { + log_error(LOG_ARGS, "Could not open %s", logname); myfree(logname); - log_error(LOG_ARGS, "Could not open maintenance logfile"); - exit(EXIT_FAILURE); + return; } WRITEMAINTLOG4(3, "clean_moderation(", listdir, ");\n"); @@ -864,15 +818,134 @@ probe_bouncers(listdir, mlmmjbounce); close(maintdlogfd); + logstr = concatstr(3, listdir, "/", MAINTD_LOGFILE); + if(rename(logname, logstr) < 0) log_error(LOG_ARGS, "Could not rename(%s,%s)", logname, logstr); myfree(logname); myfree(logstr); +} - if(daemonize == 0) +int main(int argc, char **argv) +{ + int opt, daemonize = 1, ret; + char *bindir, *listdir = NULL, *mlmmjsend, *mlmmjbounce, *mlmmjunsub; + char *dirlists = NULL, *s; + struct stat st; + struct dirent *dp; + DIR *dirp; + + CHECKFULLPATH(argv[0]); + + log_set_name(argv[0]); + + while ((opt = getopt(argc, argv, "hFVLd:")) != -1) { + switch(opt) { + case 'd': + dirlists = optarg; + break; + case 'F': + daemonize = 0; + break; + case 'L': + listdir = optarg; + break; + case 'h': + print_help(argv[0]); + break; + case 'V': + print_version(argv[0]); + exit(EXIT_SUCCESS); + } + } + + if(listdir == NULL && dirlists == NULL) { + fprintf(stderr, "You have to specify -d or -L\n"); + fprintf(stderr, "%s -h for help\n", argv[0]); + exit(EXIT_FAILURE); + } + + if(listdir && dirlists) { + fprintf(stderr, "You have to specify either -d or -L\n"); + fprintf(stderr, "%s -h for help\n", argv[0]); + exit(EXIT_FAILURE); + } + + bindir = mydirname(argv[0]); + mlmmjsend = concatstr(2, bindir, "/mlmmj-send"); + mlmmjbounce = concatstr(2, bindir, "/mlmmj-bounce"); + mlmmjunsub = concatstr(2, bindir, "/mlmmj-unsub"); + myfree(bindir); + + if(daemonize) { + if(listdir) + ret = mydaemon(listdir); + else + ret = mydaemon(dirlists); + } + + if(daemonize && ret < 0) { + log_error(LOG_ARGS, "Could not daemonize. Only one " + "maintenance run will be done."); + daemonize = 0; + } + + while(1) { + if(listdir) { + do_maintenance(listdir, mlmmjsend, mlmmjbounce, + mlmmjunsub); + continue; + } + + if((dirp = opendir(dirlists)) == NULL) { + log_error(LOG_ARGS, "Could not opendir(%s).", + dirlists); + myfree(mlmmjbounce); + myfree(mlmmjsend); + myfree(mlmmjunsub); + exit(EXIT_FAILURE); + } + + while((dp = readdir(dirp)) != NULL) { + if((strcmp(dp->d_name, "..") == 0) || + (strcmp(dp->d_name, ".") == 0)) + continue; + + listdir = concatstr(3, dirlists, "/", dp->d_name); + + if(stat(listdir, &st) < 0) { + log_error(LOG_ARGS, "Could not stat(%s)", + listdir); + myfree(listdir); + continue; + } + + if(!S_ISDIR(st.st_mode)) { + myfree(listdir); + continue; + } + + s = concatstr(2, listdir, "/control/listaddress"); + ret = stat(s, &st); + myfree(s); + + if(ret < 0) { /* If ret < 0 it's not a listdir */ + myfree(listdir); + continue; + } + + do_maintenance(listdir, mlmmjsend, mlmmjbounce, + mlmmjunsub); + + myfree(listdir); + } + + closedir(dirp); + + if(!daemonize) break; else sleep(MAINTD_SLEEP);