imapext-2007
changeset 1:28a55bc1110c imapext-2007-1
[mq]: imapext
author | yuuji@gentei.org |
---|---|
date | Mon, 14 Sep 2009 19:23:11 +0900 |
parents | ada5e610ab86 |
children | fc6002700ecd |
files | APOPtools/Makefile APOPtools/apopcall.c APOPtools/apoppasswd APOPtools/deapop APOPtools/deapop.gzip APOPtools/index.html APOPtools/pop3-age APOPtools/pop3-record APOPtools/pop3-record.postfix APOPtools/pop3-update APOPtools/qmapmore.html APOPtools/with-tcpserver/0README APOPtools/with-tcpserver/Makefile APOPtools/with-tcpserver/log/run APOPtools/with-tcpserver/pop APOPtools/with-tcpserver/run Makefile README.maildir README.qmailapop src/c-client/auth_log.c src/c-client/auth_md5.c src/c-client/mail.c src/c-client/mail.h src/imapd/imapd.c src/ipopd/ipop3d.c src/osdep/unix/Makefile src/osdep/unix/env_unix.c src/osdep/unix/maildir.c src/osdep/unix/maildir.h src/osdep/unix/tcp_unix.c src/osdep/unix/unix.c |
diffstat | 31 files changed, 3585 insertions(+), 12 deletions(-) [+] |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/APOPtools/Makefile Mon Sep 14 19:23:11 2009 +0900 1.3 @@ -0,0 +1,30 @@ 1.4 +# 1.5 +# install script 1.6 +# 1.7 +PERMSMTPDIR = /usr/local/etc 1.8 +DEAPOPDIR = /usr/local/sbin 1.9 +BINDIR = /usr/local/bin 1.10 +CGIDIR = /usr/local/apache/cgi-bin 1.11 + 1.12 + 1.13 +all: apopcall 1.14 + 1.15 +LDFLAGS = -lcrypt 1.16 + 1.17 +apopcall: apopcall.c 1.18 + 1.19 + 1.20 +install: 1.21 + -@[ -d ${PERMSMTPDIR} ] || mkdir -p ${PERMSMTPDIR} 1.22 + install -c -m 700 pop3-record ${PERMSMTPDIR} 1.23 + csh -c 'ln -f ${PERMSMTPDIR}/pop3-{record,age}' 1.24 + csh -c 'ln -f ${PERMSMTPDIR}/pop3-{record,update}' 1.25 + -@[ -d ${DEAPOPDIR} ] || mkdir -p ${DEAPOPDIR} 1.26 + install -c -m 700 deapop ${DEAPOPDIR} 1.27 + install -c -m 755 apoppasswd ${BINDIR} 1.28 + 1.29 +install-cgi: apopcall 1.30 + install -cs -m 4755 -o 0 apopcall ${CGIDIR}/apopcall.cgi 1.31 + 1.32 +clean: 1.33 + rm apopcall
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/APOPtools/apopcall.c Mon Sep 14 19:23:11 2009 +0900 2.3 @@ -0,0 +1,526 @@ 2.4 +#include <stdio.h> 2.5 +#include <stdlib.h> 2.6 +#include <string.h> 2.7 +#include <unistd.h> 2.8 +#include <sys/types.h> 2.9 +#include <sys/wait.h> 2.10 +#include <sys/stat.h> 2.11 +#include <pwd.h> 2.12 +#ifdef SHADOW_PASSWD 2.13 +#include <shadow.h> 2.14 +#endif 2.15 + 2.16 +#ifndef APOPPASSWD 2.17 +#define APOPPASSWD "/usr/local/bin/apoppasswd" 2.18 +#endif 2.19 +#ifndef APOPFILEBASE 2.20 +#define APOPFILEBASE ".apop" 2.21 +#endif 2.22 +#ifndef XADDR_DELIM 2.23 +#define XADDR_DELIM ('-') 2.24 +#endif 2.25 + 2.26 +char *myname; 2.27 + 2.28 +int ishexa(int c) { 2.29 + strchr("0123456789ABCDFabcdef", c) ? 1 : 0; 2.30 +} 2.31 + 2.32 +put_form(email, pass, new, new2, suffix, hidden, auth, force) 2.33 + char *email, *pass, *new, *new2, *suffix; 2.34 + int hidden, auth, force; 2.35 + /* auth = 0: old password 2.36 + 1: base addresse's mail password 2.37 + 2: unix password */ 2.38 +{ 2.39 + char *authtype[] = {"old", "base", "unix"}; 2.40 + char *var[] = {"email", "pass", "new", "new2", "auth", ""}; 2.41 + char *val[] = {email, pass, new, new2, authtype[auth]}; 2.42 + char *prm[] = {"", /* "ユーザ名", */ 2.43 + auth ? 2.44 + ((auth==1) 2.45 + ? "基本メイルアドレス用パスワード<br>Password for Basic Mail address" 2.46 + : "UNIXログインパスワード<br>UNIX login Password") 2.47 + : "古いメイルパスワード<br>Old Mail Password", 2.48 + "新しいメイルパスワード<br>New Mail Password", 2.49 + "新パスワードをもう一回(確認)<br>New Mail Password Again", 2.50 + ""}; 2.51 + int h=0, i; 2.52 + 2.53 + printf("<form method=POST action\"./%s\">\n", myname); 2.54 + printf(" <table border=1>\n"); 2.55 + for (i=0; var[i][0]; i++) { 2.56 + h = hidden || strstr("email,suffix,auth", var[i]); 2.57 + if (prm[i][0]) { 2.58 + printf("<tr><td>%s</td><td>", prm[i]); 2.59 + } else { 2.60 + } 2.61 + printf("<input name=%s %svalue=\"%s\" length=40 maxlength=40>\n", 2.62 + var[i], 2.63 + h ? "type=hidden " 2.64 + : (strstr(prm[i], "パスワード") ? "type=password " : "<br>"), 2.65 + val[i]); 2.66 + if (!strcmp(var[i], "suffix")) { 2.67 + /* ここでは suffix を入れさせない方がいいかも */ 2.68 + /* 表向きのメイルアドレスを表示しておく */ 2.69 + printf("%s", email); 2.70 + /* if (suffix[0]) { 2.71 + printf("-%s", suffix); 2.72 + } */ 2.73 + if (auth) 2.74 + printf("<br>(新規作成:New Account)"); 2.75 + } 2.76 + if (prm[i][0]) 2.77 + printf("</td></tr>"); 2.78 + printf("\n"); 2.79 + } 2.80 + 2.81 + printf("</table>\n"); 2.82 + if (force) 2.83 + printf("<input name=force type=hidden value=ON>\n"); 2.84 + if (auth) { 2.85 + char *a[] = {"basic", "unix"}; 2.86 + printf("<input type=hidden name=auth value=\"%s\">\n", a[auth-1]); 2.87 + } 2.88 + printf("<input name=OK value=OK type=submit>\n"); 2.89 + printf("<input name=RESET value=RESET type=reset>\n"); 2.90 + printf("</form>\n"); 2.91 + fflush(stdout); 2.92 +} 2.93 + 2.94 +char *decode(char *code) { 2.95 + int l=1+strlen(code); 2.96 + int i, c, d; 2.97 + char *ret = (char*)malloc(l*sizeof(char)); 2.98 + char *p = code; 2.99 + memset(ret, 0, l); 2.100 + for (i=0; i<strlen(code); i++) { 2.101 + if (code[i] == '+') code[i] = ' '; 2.102 + } 2.103 + while (code[0] && (p=strchr(code, '%')) 2.104 + && ishexa(*(p+1)) && ishexa(*(p+2))) { 2.105 + *(p++) = '\0'; 2.106 + strncat(ret, code, l); 2.107 + c = (islower(*p) ? toupper(*p) : *p) - '0'; 2.108 + p++; 2.109 + d = (islower(*p) ? toupper(*p) : *p) - '0'; 2.110 + if (c > 9) c -= ('A'-'9'-1); 2.111 + if (d > 9) d -= ('A'-'9'-1); 2.112 + ret[strlen(ret)] = c*16+d; 2.113 + code = p+1; 2.114 + } 2.115 + if (code[0]) strncat(ret, code, l); 2.116 + return ret; 2.117 +} 2.118 + 2.119 +#define BSIZE 8192 2.120 +char **decode_post() { 2.121 + char *buf = (char*)malloc(BSIZE*sizeof(char)); 2.122 + char **post, *p = buf; 2.123 + int n=0, i; 2.124 + post = (char**)calloc(1, sizeof(char*)); 2.125 + *buf = '\0'; 2.126 + fgets(buf, BSIZE, stdin); 2.127 + if (strchr("\n\r", buf[strlen(buf)-1])) /* chop */ 2.128 + buf[strlen(buf)-1] = '\0'; 2.129 + while (buf[0] && NULL != (p=strchr(buf, '&'))) { 2.130 + *p = '\0'; 2.131 + post[n] = (char*)malloc((p-buf+1)*sizeof(char)); 2.132 + strcpy(post[n], buf); 2.133 + n++; 2.134 + post = (char**)realloc(post, (1+n)*sizeof(char*)); 2.135 + buf = 1+p; 2.136 + } 2.137 + if (buf[0]) post[n++] = buf; 2.138 + /* decode URL encoded */ 2.139 + for (i=0; i < n; i++) { 2.140 + char *p; 2.141 + p=post[i]; 2.142 + post[i] = decode(p); 2.143 + } 2.144 + post[i] = ""; /* terminator */ 2.145 + return post; 2.146 +} 2.147 + 2.148 +void footer() { 2.149 + puts("</body>\n</html>"); 2.150 + fflush(stdout); 2.151 +} 2.152 + 2.153 +void fail() { 2.154 + printf("パスワード更新に失敗しました<br>\n"); 2.155 + printf("<a href=\"./\">やり直し</a><br>\n"); 2.156 + footer(); 2.157 + exit(1); 2.158 +} 2.159 +void success(char *email) { 2.160 + printf("<hr>メイルアカウント %s 用のパスワード更新は完了しました。<br>\n", 2.161 + email); 2.162 + footer(); 2.163 + exit(0); 2.164 +} 2.165 + 2.166 +int apopfile_existp(char *home, char *suffix, uid_t uid) { 2.167 + struct stat st; 2.168 + int s; 2.169 + int len = strlen(home) + 1 2.170 + + strlen(APOPFILEBASE) + strlen(suffix) + 3; 2.171 + char *apopfile = (char*)malloc(len); 2.172 + if (suffix[0]) { 2.173 + snprintf(apopfile, len, "%s/%s%c%s%c", 2.174 + home, APOPFILEBASE, XADDR_DELIM, suffix, 0); 2.175 + } else { 2.176 + snprintf(apopfile, len, "%s/%s%c", home, APOPFILEBASE, 0); 2.177 + } 2.178 + seteuid(uid); 2.179 + s = stat(apopfile, &st); 2.180 + seteuid(0); 2.181 + memset(apopfile, '\0', strlen(apopfile)); 2.182 + free(apopfile); 2.183 + return !s; 2.184 +} 2.185 + 2.186 +#ifndef QMAILCONTROL 2.187 +# define QMAILCONTROL "/var/qmail/control" 2.188 +#endif 2.189 +#ifndef MAILTMPLEN 2.190 +# define MAILTMPLEN 1024 2.191 +#endif 2.192 + 2.193 +/* Convert virtual domain user 2.194 + */ 2.195 +char* conv_virtualdomain(char *account) { 2.196 + char *dom = strchr(account, '@'), *p; 2.197 + char vd[MAILTMPLEN+1], rewrite[MAILTMPLEN+1], previous[MAILTMPLEN+1]; 2.198 + FILE *vdfd; 2.199 + int match=0; 2.200 + char buf[MAILTMPLEN+1], *s; 2.201 + snprintf(vd, MAILTMPLEN, "%s/%s", QMAILCONTROL, "virtualdomains"); 2.202 + if (NULL == dom) return account; 2.203 + dom++; /* set position of domain part beginning */ 2.204 + if (dom && NULL != (vdfd = fopen (vd, "r"))) { 2.205 + int l = strlen(dom); 2.206 + int L = strlen(account); 2.207 + while ((s=fgets(buf, MAILTMPLEN, vdfd))) { 2.208 + if (p=strchr(s, '#')) 2.209 + *p = '\0'; /* zap comments */ 2.210 + if (!strchr(buf, ':')) 2.211 + continue; 2.212 + while (s && (strrchr(s, '\n') || strrchr(s, '\r') || strrchr(s, ' '))) 2.213 + s[strlen(s)-1] = '\0'; 2.214 + if (!strncmp(account, s, L) && s[L] == ':' && s[L+1]) { /* user matches */ 2.215 + match = 3; 2.216 + snprintf(rewrite, MAILTMPLEN, "%s-%s", s+L+1, account); 2.217 + break; 2.218 + } 2.219 + if (!strncmp(dom, s, l) && s[l] == ':' && s[l+1]) { /* domain matches */ 2.220 + match = 2; 2.221 + snprintf(rewrite, MAILTMPLEN, "%s%c%s", s+l+1, XADDR_DELIM, account); 2.222 + continue; 2.223 + } 2.224 + if (match < 2 && s[0] == '.') { /* if domain described in wildcard */ 2.225 + if (p=strchr(s, ':')) { 2.226 + *p = '\0'; 2.227 + if (!strcmp(dom+(strlen(dom)-strlen(s)), s)) { 2.228 + if (match == 0 2.229 + || strlen(previous) < strlen(s)) { 2.230 + match = 1; 2.231 + strncpy(previous, s, MAILTMPLEN); 2.232 + snprintf(rewrite, MAILTMPLEN, "%s%c%s", p+1, XADDR_DELIM, account); 2.233 + } 2.234 + } 2.235 + } 2.236 + } 2.237 + } 2.238 + fclose(vdfd); 2.239 + if (match) { 2.240 + p = strchr(rewrite, '@'); 2.241 + /* fprintf(stderr, "m=%d, rwr=[%s]\n", match, rewrite); */ 2.242 + if (p) { 2.243 + *p = '\0'; 2.244 + } 2.245 + /* fprintf(stderr, "rwr=[%s]\n", rewrite); */ 2.246 + s = malloc(strlen(rewrite)+1); 2.247 + strncpy(s, rewrite, strlen(rewrite)+1); 2.248 + memset(vd, 0, sizeof(vd)); 2.249 + memset(rewrite, 0, sizeof(rewrite)); 2.250 + memset(previous, 0, sizeof(previous)); 2.251 + return s; 2.252 + } 2.253 + } 2.254 + /* Then, compare with locals */ 2.255 + snprintf(vd, MAILTMPLEN, "%s/%s", QMAILCONTROL, "locals"); 2.256 + if (NULL != (vdfd=fopen(vd, "r"))) { 2.257 + while (s=fgets(buf, MAILTMPLEN, vdfd)) { 2.258 + if (p=strchr(s, '#')) *p = '\0'; /* zap after comment mark # */ 2.259 + while (*s && (strrchr(s, '\r')||strrchr(s, '\n') 2.260 + ||strrchr(s, ' ')||strrchr(s, '\t'))) { 2.261 + *(s+strlen(s)-1) = '\0'; 2.262 + } 2.263 + while (*s && (*s == '\t' || *s == ' ')) s++; 2.264 + if (!strncmp(s, dom, strlen(s))) { /* matches with local domain */ 2.265 + int len = dom-account-1; 2.266 + p = (char*)malloc(len+1); 2.267 + memset(p, '\0', len+1); 2.268 + strncpy(p, account, len); 2.269 + return p; 2.270 + } 2.271 + } 2.272 + } 2.273 + return NULL; /* invalid domain */ 2.274 + /* return account; return itself */ 2.275 +} 2.276 + 2.277 +void apopcall(char **args) { 2.278 + int i=0, sc=0; 2.279 + pid_t pid; 2.280 + char *email="", *suffix="", *pass="", *new="", *new2 = "", *home=""; 2.281 + char buf[BUFSIZ], auth, *user; 2.282 + FILE *child, *result; 2.283 + while (args[i][0]) { 2.284 + /* printf("[%s]<br>\n", args[i]); */ 2.285 + if (!strncmp("email=", args[i], 6)) { 2.286 + email = args[i]+6; 2.287 + } else if (!strncmp("suffix=", args[i], 7)) { 2.288 + suffix = args[i]+7; 2.289 + } else if (!strncmp("pass=", args[i], 5)) { 2.290 + pass = args[i]+5; 2.291 + } else if (!strncmp("new=", args[i], 4)) { 2.292 + new = args[i]+4; 2.293 + } else if (!strncmp("new2=", args[i], 5)) { 2.294 + new2 = args[i]+5; 2.295 + } else if (!strncmp("auth=", args[i], 5)) { 2.296 + /* "this" or "base" or "unix" */ 2.297 + auth = args[i][5]; 2.298 + } 2.299 + i++; 2.300 + } 2.301 + /* Make a backup of original e-mail address */ 2.302 + /* user = (char*)malloc(1+strlen(email)); 2.303 + strcpy(user, email); 2.304 + */ 2.305 + user = conv_virtualdomain(email); 2.306 + if (NULL == user) { 2.307 + printf("そのようなドメインは無効です(%s)<br>\n", strchr(email, '@')); 2.308 + printf("入力したメイルアドレスを確認してやり直してください.<br>\n"); 2.309 + fail(); 2.310 + } 2.311 + if (strchr(user, XADDR_DELIM)) { 2.312 + char *p = malloc(1+strlen(user)); 2.313 + char *q = NULL; 2.314 + struct passwd *pwd; 2.315 + /* printf("user=[%s]<br>\n", user); */ 2.316 + 2.317 + memset(p, '\0', 1+strlen(user)); 2.318 + strcpy(p, user); 2.319 + while (!(pwd=getpwnam(p)) && (q=strrchr(p, XADDR_DELIM))) { 2.320 + fflush(stdout); 2.321 + *q = '\0'; 2.322 + } 2.323 + if (pwd && q) { 2.324 + q = user+(q-p)+1; 2.325 + user=p; 2.326 + suffix=q; 2.327 + } 2.328 + } 2.329 + if (user[0] && new[0] && new2[0]) { 2.330 + int tochild[2], toparent[2]; 2.331 + pid_t pid; 2.332 + int argc=0; 2.333 + char **argv; 2.334 + struct passwd *pswd; 2.335 + char *pstr; 2.336 + 2.337 + if (!(pswd=getpwnam(user))) { 2.338 + printf("Unkown user %s.\n", user); 2.339 + fflush(stdout); 2.340 + fail(); 2.341 + } 2.342 + pstr = pswd->pw_passwd; 2.343 +#ifdef SHADOW_PASSWD 2.344 + { struct spwd *ss = getspnam(user); 2.345 + pstr = (char*)ss->sp_pwdp; 2.346 + } 2.347 +#endif 2.348 + home=pswd->pw_dir; 2.349 + argv = (char**)calloc(4, sizeof(char*)); 2.350 + argv[argc++] = "apoppasswd"; 2.351 + argv[argc++] = "-s"; 2.352 + argv[argc++] = "-c"; 2.353 + /* if old password does not exist, 2.354 + then check UNIX password */ 2.355 +#if 0 2.356 + if (apopfile_existp(home, suffix, pswd->pw_uid)) { /* no apop-ext exists */ 2.357 + /* そのまま */ 2.358 + } else if (apopfile_existp(home, "", pswd->pw_uid)) {/* check base mail password */ 2.359 + argv = (char**)realloc(argv, (argc+2)*sizeof(char*)); 2.360 + argv[argc++] = "-b"; 2.361 + } 2.362 +#endif 2.363 + switch (auth) { 2.364 + case 'b': case 'B': 2.365 + if (apopfile_existp(home, "", pswd->pw_uid)) { 2.366 + argv = (char**)realloc(argv, (argc+2)*sizeof(char*)); 2.367 + argv[argc++] = "-b"; 2.368 + } else { 2.369 + printf("基本アドレスのパスワードファイルがありません<br>\n"); 2.370 + fail(); 2.371 + } 2.372 + break; 2.373 + case 'u': case 'U': 2.374 + if (strcmp(pstr, (char*)crypt(pass, pstr))) { 2.375 + printf("UNIX Password not correct.<br>\n"); 2.376 + /* printf("[%s]vs.[%s]<br>\n", 2.377 + pswd->pw_passwd, crypt(pass, pswd->pw_passwd)); */ 2.378 + printf("UNIXパスワードと一致しません.<br>\n"); 2.379 + fflush(stdout); 2.380 + fail(); 2.381 + } 2.382 + } 2.383 + 2.384 + if (strlen(new) < 8 || strlen(new2) < 8) { 2.385 + printf("New mail password must be more than 7 characters.<br>\n"); 2.386 + printf("メイルパスワードは8文字以上にしてください。<br>\n"); 2.387 + fflush(stdout); 2.388 + fail(); 2.389 + } 2.390 + if (suffix[0]) { 2.391 + argv = (char**)realloc(argv, (argc+3)*sizeof(char*)); 2.392 + argv[argc++] = "-e"; 2.393 + argv[argc++] = suffix; 2.394 + 2.395 + } 2.396 + argv[argc++] = NULL; 2.397 + if (setgid(pswd->pw_gid) || 0 != setuid(pswd->pw_uid)) { 2.398 + printf("Cannot switch to %s\n", user); 2.399 + printf("uid=%d, gid=%d<br>\n", pswd->pw_gid, pswd->pw_uid); 2.400 + printf("メイルパスワード変更サーバの設定不良の可能性があるので<br>\n"); 2.401 + printf("お手数ですがこの画面のコピーを添えてシステム管理者"); 2.402 + printf("まで御連絡下さい。<br>\n"); 2.403 + fflush(stdout); 2.404 + fail(); 2.405 + } 2.406 + 2.407 + /* OK, start apopasswd */ 2.408 + if (pipe(tochild)+pipe(toparent)) { 2.409 + printf("Cannot create pipe\n"); 2.410 + fail(); 2.411 + } 2.412 + if ((pid=fork()) > 0) { 2.413 + FILE *child = fdopen(tochild[1], "w"); 2.414 + close(tochild[0]); 2.415 + close(toparent[1]); 2.416 + fprintf(child, "PASS %s\nNEW %s\nNEW2 %s\n", 2.417 + pass, new, new2); 2.418 + fflush(child); 2.419 + fclose(child); 2.420 + 2.421 + } else if (pid == -1) { 2.422 + printf("Cannot fork\n"); 2.423 + fail(); 2.424 + } else { 2.425 + char *pe = malloc(6+strlen(pswd->pw_dir)); 2.426 + close(tochild[1]); 2.427 + close(toparent[0]); 2.428 + dup2(tochild[0], 0); 2.429 + dup2(toparent[1], 1); 2.430 + 2.431 + /* setuid section */ 2.432 + 2.433 + strcpy(pe, "HOME="); 2.434 + strcat(pe, pswd->pw_dir); 2.435 + if (putenv(pe)) { 2.436 + puts("ga-n! arichan gakkari<br>"); 2.437 + } 2.438 + execv(APOPPASSWD, argv); 2.439 + 2.440 + /* setuid section ends */ 2.441 + fprintf(stderr, "Cannot exec %s\n", APOPPASSWD); 2.442 + fail(); 2.443 + } 2.444 + result = fdopen(toparent[0], "r"); 2.445 + while (fgets(buf, BUFSIZ, result)) { 2.446 + printf("%s<br>", buf); 2.447 + fflush(stdout); 2.448 + if (strstr(buf, "Success!")) { 2.449 + printf("<br>Mail Password changed successfully!<br>\n"); 2.450 + sc++; 2.451 + break; 2.452 + } else if (strstr(buf, "mismatch")) { 2.453 + printf("二個入れた新パスワードが一致しません.<br>\n"); 2.454 + break; 2.455 + } else if (strstr(buf, "Illegal")) { 2.456 + printf("照合用パスワードが違います.<br>--\n"); 2.457 + break; 2.458 + } else if (strstr(buf, "does not exist")) { 2.459 + /* try_overwrite(user, pass, new, new2, suffix); */ 2.460 + if (suffix[0]) { 2.461 + printf("%s-%s", user, suffix); 2.462 + } else { 2.463 + printf("%s", user); 2.464 + } 2.465 + /* ここは来ないことになった(のはず) */ 2.466 + printf("というメイルアカウントは未作成です<br>\n"); 2.467 + printf("新規に作る場合はOKボタンをクリック\n"); 2.468 + put_form(email, pass, new, new2, suffix, 1, 0, 1); 2.469 + fflush(stdout); 2.470 + } 2.471 + } 2.472 + fclose(result); 2.473 + while (wait(0) != pid) {sleep(1);fputc('.', stderr);} 2.474 + if (sc) success(email); else fail(); 2.475 + } else if (user[0]) { 2.476 + struct passwd *pw = getpwnam(user); 2.477 + int auth=0; 2.478 + if (!pw) { 2.479 + printf("そのようなユーザはいません %s<br>\n", user); 2.480 + fail(); 2.481 + } 2.482 + home=pw->pw_dir; 2.483 + 2.484 + printf("%s というメイルアドレスの<br>\n", email); 2.485 + printf("メイル専用パスワードを変更します.<br>\n"); 2.486 + printf("メイルパスワードとUNIXパスワードの違いに気をつけてください.<br>\n"); 2.487 + printf("新パスワードは8文字以上にしてください.<br>\n"); 2.488 + printf("New password must be more than or equal to 8 characters.<br>\n"); 2.489 + if (apopfile_existp(home, suffix, pw->pw_uid)) { 2.490 + auth = 0; /* this password file */ 2.491 + printf("「古いメイルパスワード」には、現在<br>\n"); 2.492 + printf("<tt>%s</tt><br>\n", email); 2.493 + printf("を読むために指定しているパスワードを入力します。"); 2.494 + } else if (apopfile_existp(home, "", pw->pw_uid)) { 2.495 + auth = 1; /* basic mail address password */ 2.496 + printf("今回は本人認証として基本メイルアドレスのパスワードを"); 2.497 + printf("入力しますが、新しくパスワードを設定するのは<br>\n"); 2.498 + printf("<tt>%s</tt><br>\n", email); 2.499 + printf("用のパスワードです。基本メイルアドレスのパスワードは"); 2.500 + printf("変わりませんので注意してください。"); 2.501 + } else { 2.502 + auth = 2; /* UNIX login */ 2.503 + } 2.504 + put_form(email, "", "", "", suffix, 0, auth, 0); 2.505 + footer(); 2.506 + exit(0); 2.507 + } 2.508 + printf("user=[%s]\n", user); 2.509 +} 2.510 + 2.511 +int main(int argc, char* argv[]) { 2.512 + char *method = getenv("REQUEST_METHOD"); 2.513 + char **args; 2.514 + myname = argv[0]; 2.515 + if (method && strcmp(method, "POST") != 0) { 2.516 + printf("This program should be used in method:POST.\n"); 2.517 + fail(); 2.518 + } 2.519 + printf("Content-type: text/html; charset=EUC-JP\n\n"); 2.520 + printf("<html>\n<head><title>Change Password</title></head>\n"); 2.521 + printf("<body style=\"background: #f0ffff;\">\n"); 2.522 + if (getenv("SSL_CIPHER") && getenv("SSL_PROTOCOL")) { 2.523 + args = decode_post(); 2.524 + apopcall(args); 2.525 + } else { 2.526 + printf("This program can be used only via SSL connection.<br>\n"); 2.527 + printf("このユーティリティはSSL接続時のみ有効です.<br>\n"); 2.528 + } 2.529 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/APOPtools/apoppasswd Mon Sep 14 19:23:11 2009 +0900 3.3 @@ -0,0 +1,210 @@ 3.4 +#!/usr/local/bin/perl 3.5 +# Customize these variables. 3.6 +# If you change APOPFILEBASE, change the same variable in apopcall.c too. 3.7 +# See http://www.gentei.org/~yuuji/software/imapext/ 3.8 + 3.9 +$HOME=$ENV{"HOME"}; 3.10 + 3.11 +$DEFAULTMAILDIR = "Maildir"; # Must be same as ../src/osdep/unix/Makefile 3.12 + 3.13 +$APOPFILEBASE = ".apop"; # "$HOME/$APOPFILEBASE" is the password file 3.14 +# $APOPFILEBASE = "$DEFAULTMAILDIR/apop"; 3.15 +# $APOPFILEBASE = "Mail/apop"; 3.16 + 3.17 +$ENCODER = "cat"; 3.18 +# $ENCODER = "gzip"; 3.19 +# $ENCODER = "uuencode $$|gzip"; 3.20 + 3.21 +$DECODER = "cat"; 3.22 +# $DECODER = "gzip -dc"; 3.23 +# $DECODER = "gzip -dc | uudecode"; 3.24 + 3.25 +$DOTQMAIL = ".qmail"; # qmail 3.26 +# $DOTQMAIL = ".forward"; # Postfix 3.27 + 3.28 +$XADDR_DELIM = "-"; # qmail 3.29 +# $XADDR_DELIM = "+"; # Postfix 3.30 + 3.31 +$HERE = "."; # qmail 3.32 +# $HERE = "~"; # Postfix 3.33 + 3.34 +$EXT = ""; 3.35 +$force = 0; 3.36 +$base = 0; 3.37 + 3.38 +$APOPFILE = "$HOME/$APOPFILEBASE"; 3.39 + 3.40 +sub handler { 3.41 + system "stty echo"; 3.42 + print STDERR "Abort:\n"; 3.43 + exit 1; 3.44 +} 3.45 + 3.46 +$SIG{'INT'} = $SIG{'KILL'} = $SIG{'QUIT'} = $SIG{'HUP'} = 'handler'; 3.47 + 3.48 +while ($_=$ARGV[0], /^-.+/ && shift) { 3.49 + if (/^-e/) { 3.50 + $APOPFILE .= $XADDR_DELIM . ($EXT=shift); 3.51 + } elsif (/^-b/) { 3.52 + $base++; 3.53 + } elsif (/^-c/) { 3.54 + $create++; 3.55 + } elsif (/^-s/) { 3.56 + $stream++; 3.57 + # and exit; 3.58 + } elsif (/^-h/) { 3.59 + &usage; # and exit 3.60 + } 3.61 +} 3.62 + 3.63 +sub checkmaildir { 3.64 + local($dotqmail) = ("$HOME/$DOTQMAIL"); 3.65 + local($maildir) = ($DEFAULTMAILDIR); # default 3.66 + $dotqmail .= "$XADDR_DELIM$EXT" if $EXT; 3.67 + $maildir .= "-$EXT" if $EXT; 3.68 + unless (-f "$dotqmail") { 3.69 + if ($create) { 3.70 + if (open(DQMAIL, "> $dotqmail")) { 3.71 + print DQMAIL "$HERE/$maildir/\n"; 3.72 + print "File [$dotqmail] created\n"; 3.73 + close(DQMAIL); 3.74 + } 3.75 + } else { 3.76 + print "$dotqmail file does not exist.\n"; # should go to stdout 3.77 + print "Your should create $maildir first!\n"; 3.78 + print "(-c option automatically makes it)\n"; 3.79 + exit 1; 3.80 + } 3.81 + } 3.82 + if (-s $dotqmail) { 3.83 + $maildir=''; 3.84 + if (open(DQMAIL, "< $dotqmail")) { 3.85 + while (<DQMAIL>) { 3.86 + s/[\r\n \t]*$//g; 3.87 + next if /#/; 3.88 + next unless m,\./.*/,; 3.89 + chop; # strip trailing "/" 3.90 + $maildir = $_; 3.91 + last; 3.92 + } 3.93 + close(DQMAIL); 3.94 + $maildir = $DEFAULTMAILDIR if $maildir eq ''; 3.95 + unless (-d "$HOME/$maildir" 3.96 + && -d "$HOME/$maildir/new" 3.97 + && -d "$HOME/$maildir/cur" 3.98 + && -d "$HOME/$maildir/tmp") { 3.99 + if ($create) { 3.100 + mkdir "$HOME/$maildir", 0700; 3.101 + mkdir "$HOME/$maildir/new", 0700; 3.102 + mkdir "$HOME/$maildir/cur", 0700; 3.103 + mkdir "$HOME/$maildir/tmp", 0700; 3.104 + print "Maildir [$maildir/] created\n"; 3.105 + } else { 3.106 + print "Maildir($maildir) does not exist\n"; 3.107 + print "Your should do maildirmake $maildir first!\n"; 3.108 + print "(-c option automatically makes it)\n"; 3.109 + exit 1; 3.110 + } 3.111 + } 3.112 + } 3.113 + } 3.114 +} 3.115 + 3.116 +sub usage { 3.117 + local($mydir, $myname) = ($0 =~ m,(.*)/(.*),); 3.118 + print<<_EOU_; 3.119 +$myname Change Mail password for imap-4.7+qmailapop 3.120 +Usage: $myname [options] 3.121 +Options are... 3.122 + -e EXT Set target email address to "user-EXT" 3.123 + -c If no .qmail file and Maildir, create them 3.124 + 3.125 +_EOU_ 3.126 + exit 0; 3.127 +} 3.128 + 3.129 +if ($stream) { 3.130 + &stream; 3.131 + exit; # not reached 3.132 +} 3.133 +$OK=0; 3.134 +until ($OK) { 3.135 + system "stty -echo"; 3.136 + print STDERR "Enter APOP Password: "; 3.137 + $new1 = <>; 3.138 + print STDERR "\n"; 3.139 + if (length($new1) == 1) { 3.140 + print STDERR "Canceled\n"; 3.141 + exit 1; 3.142 + } elsif (length($new1) < 9) { 3.143 + print STDERR "Password is too short! Please use more than 8 chars.\n"; 3.144 + next; 3.145 + } 3.146 + print STDERR "Again APOP Password: "; 3.147 + $new2 = <>; 3.148 + if ($new1 eq $new2) { 3.149 + $OK=1; 3.150 + } else { 3.151 + print STDERR "\nPassword mismatch! Try again.\n"; 3.152 + } 3.153 +} 3.154 +#OK 3.155 +&checkmaildir; 3.156 +system "stty echo"; 3.157 +open(NP, "| $ENCODER > $APOPFILE") || die "Cannot write on $APOPFILE\n"; 3.158 +print NP "$new1"; 3.159 +close(NP); 3.160 +chmod 0600, $APOPFILE; 3.161 +print STDERR "\nUpdated APOP password successfully.\n"; 3.162 + 3.163 +sub stream { # Must match with old password 3.164 + local($PASS, $old, $new1, $new2, $master) = (0); 3.165 + local($masterfile) = ($APOPFILE); 3.166 + $masterfile = "$HOME/$APOPFILEBASE" if $base; 3.167 + exit 1 if ($> == 0); 3.168 + while (<>) { 3.169 + chop; 3.170 + if (/^PASS (.*)$/i) { 3.171 + $old = $1; 3.172 + } elsif (/^NEW (.*)/i) { 3.173 + $new1 = $1; 3.174 + } elsif (/^NEW2 (.*)/i) { 3.175 + $new2 = $1; 3.176 + } 3.177 + last if ("$new1" ne "" && "$new2" ne ""); 3.178 + } 3.179 + if (-s $APOPFILE || ($base && -f $masterfile)) { # Already exist 3.180 + if (open(OLD, "$DECODER $masterfile |")) { 3.181 + ($master = <OLD>) =~ s/[\n\r]$//g; 3.182 + close(OLD); 3.183 + } else { 3.184 + print "Old password file corrupted.\n"; 3.185 + print "Please ask to administrator.\n"; 3.186 + exit 1; 3.187 + } 3.188 + if ($master ne $old) { 3.189 + print "Illegal password\nBye\n"; 3.190 + exit 1; 3.191 + } 3.192 + } 3.193 + if ($new1 ne $new2) { 3.194 + print "Password(new) mismatch\nBye\n"; 3.195 + exit 1; 3.196 + } 3.197 + # OK, now begin to create! 3.198 + &checkmaildir; 3.199 + if (open(P, "| $ENCODER > $APOPFILE")) { 3.200 + # open success 3.201 + print P "$new1\n"; 3.202 + close(P); 3.203 + chmod 0600, $APOPFILE; 3.204 + if (-s $APOPFILE) { 3.205 + print "Success!\n"; 3.206 + exit 0; 3.207 + } 3.208 + } else { 3.209 + print "Cannot output to $APOPFILE\nBye\n"; 3.210 + exit 1; 3.211 + } 3.212 + exit 0; 3.213 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/APOPtools/deapop Mon Sep 14 19:23:11 2009 +0900 4.3 @@ -0,0 +1,4 @@ 4.4 +#!/bin/sh 4.5 +# deapop script for plain password file 4.6 +cat "$@" 4.7 +
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/APOPtools/deapop.gzip Mon Sep 14 19:23:11 2009 +0900 5.3 @@ -0,0 +1,4 @@ 5.4 +#!/bin/sh 5.5 +# deapop script for gzipped password file 5.6 +gzcat "$@" 5.7 +
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/APOPtools/index.html Mon Sep 14 19:23:11 2009 +0900 6.3 @@ -0,0 +1,65 @@ 6.4 +<html> 6.5 +<head> 6.6 +<title> 6.7 +APOP Password 6.8 +</title> 6.9 +<style type="text/css"> 6.10 +<!-- 6.11 +.e {color: red; text-decoretion: underline;} 6.12 +--> 6.13 +</style> 6.14 +</head> 6.15 + 6.16 +<body bgcolor="azure"> 6.17 +<p>$B$"$J$?$N%a%$%k%"%I%l%9@lMQ$N%Q%9%o!<%I$r@_Dj$^$?$O99?7$7$^$9!#(B</p> 6.18 +<form method=POST action="./apopcall.cgi"> 6.19 +<table border="1"> 6.20 +<tr><td>$B%a%$%k%"%I%l%9(B:<br>User Name:</td> 6.21 + <td><input name="email" size="40" maxlength="40"></td></tr> 6.22 +</table> 6.23 +<input name="OK" type="submit" value="OK"> 6.24 +<input name="OK" type="reset" value="Clear"> 6.25 +</form> 6.26 +<ul> 6.27 + <li> $B=i$a$FMxMQ$9$k>l9g(B 6.28 + <p>$B%Q%9%o!<%I$r@_Dj$7$?$$%a%$%k%"%I%l%9$rF~NO$7$F$/$@$5$$!#(B 6.29 + $B%a%$%k@lMQ$N%Q%9%o!<%I$r2a5n$K@_Dj$7$F$$$J$$>l9g$O!"(B 6.30 + $B<!$N2hLL$GK\?MG'>Z$H$7$F(BUNIX$B%Q%9%o!<%I(B($B%5!<%P$K(B 6.31 + $B%m%0%$%s$9$k$H$-$N$b$N(B)$B$rF~NO$7$F$/$@$5$$!#(B</p> 6.32 + <li> $B3HD%%a%$%k%"%I%l%9$N;XDj(B 6.33 + <p>$B4pK\%a%$%k%"%I%l%9$N%f!<%6L>$N8e$m$K(B<span class="e">-$B3HD%;R(B 6.34 + </span> ($B%O%$%U%s(B+$B3HD%;R(B)$B$r2C$($?%"%I%l%9$,3HD%%a%$%k%"%I%l%9$K$J(B 6.35 + $B$j$^$9!#(B<br> 6.36 + $BNc(B:<br> 6.37 + $B4pK\%"%I%l%9(B : user@xxx.hogehoge.ac.jp<br> 6.38 + $B3HD%%"%I%l%9(B : user-foo@xxx.hogehoge.ac.jp<br> 6.39 + ($B$3$N>l9g$N3HD%;R$O(B foo) 6.40 + </p> 6.41 + <p>$B3HD%%a%$%k%"%I%l%9$O!"3HD%;RItJ,$rJQ$($k$3$H$G(B 6.42 + $B2?8D$G$b:n$k$3$H$,$G$-$^$9!#(B 6.43 + $B?75,$K:n@.$7$?$$$H$-$O!"3HD%%a%$%k%"%I%l%9$rF~NO$7$F(BOK$B$r(B 6.44 + $B2!$7$F$/$@$5$$!#?7$7$$%a%$%k%\%C%/%9$r<+F0E*$K:n@.(B 6.45 + $B$9$k$HF1;~$K?73HD%%a%$%k%"%I%l%9@lMQ$N%Q%9%o!<%I$b9T$J$$$^$9!#(B 6.46 + </p> 6.47 +</ul> 6.48 +<p>$B!Z(B<a href="qmapmore.html"> 6.49 +$B$3$N%5!<%P$GMxMQ$G$-$k%a%$%k%"%I%l%9$K$D$$$F(B</a>$B![(B</p> 6.50 +<hr> 6.51 +<ul> 6.52 + <li> At your first trial to set mail password 6.53 + <p>Push [OK] button with your mail address. We call your 6.54 + mail address <em>YourName</em>@xxx.yyy.jp as `basic email address'.<p> 6.55 + 6.56 + <li> To create extensional email address<br> 6.57 + 6.58 + <p>On our system, you can have more than one email addresses. You 6.59 + can create any (mail)account name "YourName-xxx"(where xxx is 6.60 + any extensional word you might give) which will be delivered to you. To 6.61 + create an extesional email address and/or change the password for 6.62 + it, put the extensional email address in the input window.</p> 6.63 +</ul> 6.64 + 6.65 +<hr> 6.66 +<!--#include virtual="/~yuuji/signature.html"--> 6.67 +</body> 6.68 +</html>
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/APOPtools/pop3-age Mon Sep 14 19:23:11 2009 +0900 7.3 @@ -0,0 +1,62 @@ 7.4 +#!/bin/sh - 7.5 +# A sample "POP before SMTP"-enabler script for tcp_wrappers 7.6 +# This script should be installed in /usr/local/etc 7.7 +# If you are thinking of using this script on heavily loaded host, 7.8 +# you had better to choose tcpserver instead of tcp_wrappers. 7.9 +# 7.10 +ALLOWTMP="/var/log/ATMP" 7.11 +if [ -f /usr/local/etc/hosts.allow ]; then 7.12 + ALLOW="/usr/local/etc/hosts.allow" 7.13 +else 7.14 + ALLOW=/etc/hosts.allow 7.15 +fi 7.16 +ALLOWSRC=${ALLOW}.src 7.17 +ALLOWNEW=${ALLOW}.new 7.18 + 7.19 +# for debug 7.20 +# (env;echo "1=$1") | Mail -s pop3access yuuji 7.21 + 7.22 +case $0 in 7.23 + *record) 7.24 + echo "tcp-env : $RELAYCLIENT : setenv = RELAYCLIENT" >> $ALLOWTMP.1 7.25 + ;; 7.26 + *age) 7.27 + rm -f $ALLOWTMP.2 7.28 + [ -f $ALLOWTMP.1 ] && mv -f $ALLOWTMP.1 $ALLOWTMP.2 7.29 + ;; 7.30 + *) 7.31 + # else generate master hosts.allow file 7.32 + ;; 7.33 +esac 7.34 +touch $ALLOWTMP.1 $ALLOWTMP.2 7.35 +echo "# 7.36 +# DO NOT EDIT THIS FILE! 7.37 +# This file is generated from $ALLOWSRC file. 7.38 +# Edit it! 7.39 +#" > $ALLOWNEW 7.40 +(cat $ALLOWTMP.[12] | sort -u; cat $ALLOWSRC) >> $ALLOWNEW 7.41 +/bin/mv -f $ALLOWNEW $ALLOW 7.42 + 7.43 +# pop3-{age,update,record} for tcp_wrappers ends here 7.44 +# The following section is the sample routine for tcpserver(ucsp-tcp) 7.45 +# If you use tcpserver, replace the above section after "case $0...esac" 7.46 +# by the following section. 7.47 +# Sample code was contributed by pirozeau(pirozeau@banana-fish.com). 7.48 + 7.49 +#TCPREMOTEIP=${TCPREMOTEIP:-undefined} 7.50 +#RELAYCLIENT=${RELAYCLIENT:-$TCPREMOTEIP} 7.51 +#ALLOW=/usr/local/etc/smtprule 7.52 +#case $0 in 7.53 +# *record) 7.54 +# echo "$RELAYCLIENT:allow,RELAYCLIENT=\"\"" >> $ALLOWTMP.1 7.55 +# ;; 7.56 +# *age) 7.57 +# rm -f $ALLOWTMP.2 7.58 +# [ -f $ALLOWTMP.1 ] && mv -f $ALLOWTMP.1 $ALLOWTMP.2 7.59 +# ;; 7.60 +# *) 7.61 +# # else generate master tcprule file 7.62 +# ;; 7.63 +#esac 7.64 +#touch $ALLOWTMP.1 $ALLOWTMP.2 7.65 +#(cat $ALLOWTMP.[12] | sort -u; cat ${ALLOW}) | /usr/local/bin/tcprules ${ALLOW}.cdb ${ALLOW}.tmp
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/APOPtools/pop3-record Mon Sep 14 19:23:11 2009 +0900 8.3 @@ -0,0 +1,62 @@ 8.4 +#!/bin/sh - 8.5 +# A sample "POP before SMTP"-enabler script for tcp_wrappers 8.6 +# This script should be installed in /usr/local/etc 8.7 +# If you are thinking of using this script on heavily loaded host, 8.8 +# you had better to choose tcpserver instead of tcp_wrappers. 8.9 +# 8.10 +ALLOWTMP="/var/log/ATMP" 8.11 +if [ -f /usr/local/etc/hosts.allow ]; then 8.12 + ALLOW="/usr/local/etc/hosts.allow" 8.13 +else 8.14 + ALLOW=/etc/hosts.allow 8.15 +fi 8.16 +ALLOWSRC=${ALLOW}.src 8.17 +ALLOWNEW=${ALLOW}.new 8.18 + 8.19 +# for debug 8.20 +# (env;echo "1=$1") | Mail -s pop3access yuuji 8.21 + 8.22 +case $0 in 8.23 + *record) 8.24 + echo "tcp-env : $RELAYCLIENT : setenv = RELAYCLIENT" >> $ALLOWTMP.1 8.25 + ;; 8.26 + *age) 8.27 + rm -f $ALLOWTMP.2 8.28 + [ -f $ALLOWTMP.1 ] && mv -f $ALLOWTMP.1 $ALLOWTMP.2 8.29 + ;; 8.30 + *) 8.31 + # else generate master hosts.allow file 8.32 + ;; 8.33 +esac 8.34 +touch $ALLOWTMP.1 $ALLOWTMP.2 8.35 +echo "# 8.36 +# DO NOT EDIT THIS FILE! 8.37 +# This file is generated from $ALLOWSRC file. 8.38 +# Edit it! 8.39 +#" > $ALLOWNEW 8.40 +(cat $ALLOWTMP.[12] | sort -u; cat $ALLOWSRC) >> $ALLOWNEW 8.41 +/bin/mv -f $ALLOWNEW $ALLOW 8.42 + 8.43 +# pop3-{age,update,record} for tcp_wrappers ends here 8.44 +# The following section is the sample routine for tcpserver(ucsp-tcp) 8.45 +# If you use tcpserver, replace the above section after "case $0...esac" 8.46 +# by the following section. 8.47 +# Sample code was contributed by pirozeau(pirozeau@banana-fish.com). 8.48 + 8.49 +#TCPREMOTEIP=${TCPREMOTEIP:-undefined} 8.50 +#RELAYCLIENT=${RELAYCLIENT:-$TCPREMOTEIP} 8.51 +#ALLOW=/usr/local/etc/smtprule 8.52 +#case $0 in 8.53 +# *record) 8.54 +# echo "$RELAYCLIENT:allow,RELAYCLIENT=\"\"" >> $ALLOWTMP.1 8.55 +# ;; 8.56 +# *age) 8.57 +# rm -f $ALLOWTMP.2 8.58 +# [ -f $ALLOWTMP.1 ] && mv -f $ALLOWTMP.1 $ALLOWTMP.2 8.59 +# ;; 8.60 +# *) 8.61 +# # else generate master tcprule file 8.62 +# ;; 8.63 +#esac 8.64 +#touch $ALLOWTMP.1 $ALLOWTMP.2 8.65 +#(cat $ALLOWTMP.[12] | sort -u; cat ${ALLOW}) | /usr/local/bin/tcprules ${ALLOW}.cdb ${ALLOW}.tmp
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/APOPtools/pop3-record.postfix Mon Sep 14 19:23:11 2009 +0900 9.3 @@ -0,0 +1,29 @@ 9.4 +#!/bin/sh - 9.5 +# A sample "POP before SMTP"-enabler script for Postfix 9.6 +# This script should be installed in /usr/local/etc. 9.7 +# This script assumes 9.8 +# 9.9 +POSTFIXDIR=/etc/postfix 9.10 +POSTFIXBIN=/usr/libexec/postfix 9.11 +PATH=$POSTFIXBIN\:$PATH 9.12 +OKDIR=/var/log 9.13 +OKCLIENT=$OKDIR/ATMP 9.14 +CLIENTACCESS=$POSTFIXDIR/client_access 9.15 + 9.16 +case $0 in 9.17 + *record) 9.18 + echo "$RELAYCLIENT OK" >> $OKCLIENT.1 9.19 + ;; 9.20 + *age) 9.21 + rm -f $OKCLIENT.2 9.22 + [ -f $OKCLIENT.1 ] && mv -f $OKCLIENT.1 $OKCLIENT.2 9.23 + echo '' > $CLIENTACCESS 9.24 + # rm -f $CLIENTACCESS.db 9.25 + postmap hash:$CLIENTACCESS 9.26 + ;; 9.27 + *) 9.28 + # else generate master client_access.db 9.29 + ;; 9.30 +esac 9.31 +touch $OKCLIENT.1 $OKCLIENT.2 9.32 +cat $OKCLIENT.1 $OKCLIENT.2 | postmap -r -i hash:$CLIENTACCESS
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/APOPtools/pop3-update Mon Sep 14 19:23:11 2009 +0900 10.3 @@ -0,0 +1,62 @@ 10.4 +#!/bin/sh - 10.5 +# A sample "POP before SMTP"-enabler script for tcp_wrappers 10.6 +# This script should be installed in /usr/local/etc 10.7 +# If you are thinking of using this script on heavily loaded host, 10.8 +# you had better to choose tcpserver instead of tcp_wrappers. 10.9 +# 10.10 +ALLOWTMP="/var/log/ATMP" 10.11 +if [ -f /usr/local/etc/hosts.allow ]; then 10.12 + ALLOW="/usr/local/etc/hosts.allow" 10.13 +else 10.14 + ALLOW=/etc/hosts.allow 10.15 +fi 10.16 +ALLOWSRC=${ALLOW}.src 10.17 +ALLOWNEW=${ALLOW}.new 10.18 + 10.19 +# for debug 10.20 +# (env;echo "1=$1") | Mail -s pop3access yuuji 10.21 + 10.22 +case $0 in 10.23 + *record) 10.24 + echo "tcp-env : $RELAYCLIENT : setenv = RELAYCLIENT" >> $ALLOWTMP.1 10.25 + ;; 10.26 + *age) 10.27 + rm -f $ALLOWTMP.2 10.28 + [ -f $ALLOWTMP.1 ] && mv -f $ALLOWTMP.1 $ALLOWTMP.2 10.29 + ;; 10.30 + *) 10.31 + # else generate master hosts.allow file 10.32 + ;; 10.33 +esac 10.34 +touch $ALLOWTMP.1 $ALLOWTMP.2 10.35 +echo "# 10.36 +# DO NOT EDIT THIS FILE! 10.37 +# This file is generated from $ALLOWSRC file. 10.38 +# Edit it! 10.39 +#" > $ALLOWNEW 10.40 +(cat $ALLOWTMP.[12] | sort -u; cat $ALLOWSRC) >> $ALLOWNEW 10.41 +/bin/mv -f $ALLOWNEW $ALLOW 10.42 + 10.43 +# pop3-{age,update,record} for tcp_wrappers ends here 10.44 +# The following section is the sample routine for tcpserver(ucsp-tcp) 10.45 +# If you use tcpserver, replace the above section after "case $0...esac" 10.46 +# by the following section. 10.47 +# Sample code was contributed by pirozeau(pirozeau@banana-fish.com). 10.48 + 10.49 +#TCPREMOTEIP=${TCPREMOTEIP:-undefined} 10.50 +#RELAYCLIENT=${RELAYCLIENT:-$TCPREMOTEIP} 10.51 +#ALLOW=/usr/local/etc/smtprule 10.52 +#case $0 in 10.53 +# *record) 10.54 +# echo "$RELAYCLIENT:allow,RELAYCLIENT=\"\"" >> $ALLOWTMP.1 10.55 +# ;; 10.56 +# *age) 10.57 +# rm -f $ALLOWTMP.2 10.58 +# [ -f $ALLOWTMP.1 ] && mv -f $ALLOWTMP.1 $ALLOWTMP.2 10.59 +# ;; 10.60 +# *) 10.61 +# # else generate master tcprule file 10.62 +# ;; 10.63 +#esac 10.64 +#touch $ALLOWTMP.1 $ALLOWTMP.2 10.65 +#(cat $ALLOWTMP.[12] | sort -u; cat ${ALLOW}) | /usr/local/bin/tcprules ${ALLOW}.cdb ${ALLOW}.tmp
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/APOPtools/qmapmore.html Mon Sep 14 19:23:11 2009 +0900 11.3 @@ -0,0 +1,187 @@ 11.4 +<html> 11.5 +<head> 11.6 +<title> 11.7 +APOP Password 11.8 +</title> 11.9 +<style type="text/css"> 11.10 +<!-- 11.11 +h1 {text-align: center; text-decoration: underline;} 11.12 +h2 {color: navy; background-color: lavender;} 11.13 +.e {color: red; text-decoretion: underline;} 11.14 +dt (background-color: yellow;} 11.15 +--> 11.16 +</style> 11.17 +</head> 11.18 + 11.19 +<body bgcolor="azure"> 11.20 +<h1> 11.21 + $BK\%a%$%k%5!<%P$K4X$9$kMxMQ<T>\:Y>pJs(B 11.22 +</h1> 11.23 +<p>$BL\<!(B</p> 11.24 +<ul> 11.25 + <li> <a href="#extaddress">$BK\%5!<%P$GMxMQ$G$-$k%a%$%k%"%I%l%9(B</a> 11.26 + <li> <a href="#APOP">$B%a%$%k<u?.;~$N%W%m%H%3%k$K$D$$$F(B</a> 11.27 + <li> <a href="#forward">$BB>$N%a%$%k%5!<%P$X$NE>Aw(B</a> 11.28 +</ul> 11.29 +<hr> 11.30 + 11.31 +<h2> 11.32 + <a name="extaddress">$BK\%5!<%P$GMxMQ$G$-$k%a%$%k%"%I%l%9(B</a> 11.33 +</h2> 11.34 +<p>$BK\%5!<%P$G$O%a%$%kG[Aw%7%9%F%`$H$7$F(Bqmail$B$rMxMQ$7$F$$$k$N$G!"(B 11.35 +$BMxMQ<T$N3'$5$s$O2?8D$G$b%a%$%k%"%I%l%9$r:n$k$3$H$,$G$-$^$9!#(B 11.36 +$B0J2<$N@bL@$G$O!"8D?M$N%a%$%k%"%I%l%9$N%"%+%&%s%HL>ItJ,$r(B 11.37 +<var>user</var>$B!"%I%a%$%sL>ItJ,$r(B <var>dokkano.ac.jp</var> $B$H(B 11.38 +$BI=$9$3$H$K$7$^$9!#$D$^$j!"Nc$G;HMQ$9$k%a%$%k%"%I%l%9$O(B 11.39 +<var>user@dokkano.ac.jp</var>$B$H$J$j$^$9!#$3$N%"%I%l%9$O8f<+?H$N$b$N$HCV(B 11.40 +$B$-49$($F@bL@$rFI$_?J$a$F$/$@$5$$!#(B</p> 11.41 + 11.42 +<dl> 11.43 + <dt> $B!Z4pK\%a%$%k%"%I%l%9![(B 11.44 + <dd> <p><var>user@dokkano.ac.jp</var>$B$r4pK\%a%$%k%"%I%l%9$H8F$S$^$9!#%"(B 11.45 + $B%+%&%s%H:n@.$HF1;~$KL5>r7o$GMxMQ$G$-$k%a%$%k%"%I%l%9$G$9!#$3$N%"%I(B 11.46 + $B%l%9$KFO$$$?%a%$%k$O%5!<%P>e$N$"$J$?@lMQ$N%a%$%k%\%C%/%9$KC_$($i$l(B 11.47 + $B$^$9!#JL$N%"%I%l%9$KE>Aw$9$k$3$H$b2DG=$G$9$,!"J}K!$O8e=R$7$^$9!#(B</p> 11.48 + 11.49 + <dt> $B!Z3HD%%a%$%k%"%I%l%9![(B 11.50 + <dd> <p><var>user<span class="e">-xxx</span>@dokkano.ac.jp</var>$B$H$$$&(B 11.51 + $B7A<0$N%"%I%l%9$r3HD%%a%$%k%"%I%l%9$H8F$S$^$9!#$"$J$?$N%"%+%&%s%HL>(B 11.52 + $B$G;O$^$j!"$=$ND>8e$K%O%$%U%s(B(<span class="e">-</span>)$B$G6h@Z$C$FG$(B 11.53 + $B0U$NJ8;zNs$,Mh$k%a%$%k%"%I%l%9$O!"A4$F$"$J$?08$KG[Aw$5$l$^$9!#(B 11.54 + <var>user<span class="e">-xxx</span></var>$B$N(B<var>xxx</var>$B$NItJ,$O(B 11.55 + <span class="e">$B3HD%;R(B</span>$B$H8F$S!"$I$s$JC18l$G$b9=$$$^$;$s!#(B 11.56 + <var>user-123@dokkano.ac.jp, user-job@dokkano.ac.jp, 11.57 + user-meeting@dokkano.ac.jp, ...</var>$B$J$I$J$I!"$I$s$J%a%$%k%"%I%l(B 11.58 + $B%9$G$b<+J,MQ$K:n@.$9$k$3$H$,$G$-$^$9!#(B 11.59 + </p> 11.60 +</dl> 11.61 + 11.62 +<p>$B3HD%%a%$%k%"%I%l%9$rMxMQ$9$k>l9g$O!":G=i$K$=$N%"%I%l%9$r<u$1<h$k%a%$(B 11.63 +$B%k%\%C%/%9$r:n$j$H$=$N%"%I%l%9<u?.MQ$N%Q%9%o!<%I$r@_Dj$9$kI,MW$,$"$j$^$9!#(B 11.64 +<a href="index.html">$B%a%$%k%Q%9%o!<%I@_Dj2hLL(B</a>$B$K$F!"$3$l$+$i<u$1<h$j(B 11.65 +$B$?$$%a%$%k%"%I%l%9$r(B<var>user<span 11.66 +class="e">-xxx</span>@dokkano.ac.jp</var> $B$N7A<0$GF~NO$7$F@h$K?J$a$P<+F0(B 11.67 +$BE*$K%a%$%k%\%C%/%9$N:n@.$^$G40N;$7$^$9!#$3$N$H$-!"$"$J$?K\?M$N3NG'$H$7$F(B 11.68 +$B4{B8$N(B<span class="e">$B4pK\%a%$%k%"%I%l%9$N%Q%9%o!<%I(B</span>$B$rF~NO$7$F$/(B 11.69 +$B$@$5$$!#(B</p> 11.70 + 11.71 +<h2> 11.72 + <a name="APOP">$B%a%$%k<u?.;~$N%W%m%H%3%k$K$D$$$F(B</a> 11.73 +</h2> 11.74 +<p>$B8=:_9-$/MxMQ$5$l$F$$$k%a%$%k<u?.%W%m%H%3%k$G$"$k(BPOP3$B$O!"(B 11.75 +$B%Q%9%o!<%I$r$=$N$^$^$N7A(B($BJ?J8(B:$B%W%l%$%s%F%-%9%H(B)$B$G%M%C%H%o!<%/$KN.$7$F$7(B 11.76 +$B$^$&$N$G!"4JC1$KK5<u$5$l$k$*$=$l$,$"$j$^$9(B($B8=6b<+F0;YJ'5!$NA0$G0E>ZHV9f(B 11.77 +$B$r@<$K=P$7$J$,$i2!$7$F$$$k;Q$rA[A|$7$F$/$@$5$$(B)$B!#(B</p> 11.78 + 11.79 +<p>$B$=$N$h$&$J4m81@-$r9MN8$7$FK\%5!<%P$G$O0J2<$N@_Dj$r9T$J$C$F$$$^$9!#(B</p> 11.80 +<ul> 11.81 + <li> POP3$B$O2f!9$NAH?%Fb%M%C%H%o!<%/$+$i$N$_MxMQ$r5v2D(B<br> 11.82 + ($BFbIt%M%C%H%o!<%/$K$OIt30<T$O4JC1$K$OF'$_9~$a$J$$$N$G4vJ,0BA4$G$9(B) 11.83 + <li> $B$=$l0J30$N>l=j$+$i$N<u?.$G$O(BAPOP$B$N$_$r5v2D(B 11.84 +</ul> 11.85 +<p>APOP$B$H$O%Q%9%o!<%I$r0E9f2=$7$F$d$j$H$j$9$k$h$&$K3HD%$7$?(BPOP3$B$G!"2>$K(B 11.86 +$BK5<u$5$l$?$H$7$F$b85$N%Q%9%o!<%I$O2rFI$G$-$^$;$s!#(BAPOP$B$rMxMQ$9$k>l9g$O$"(B 11.87 +$B$i$f$k>l=j$+$i$N%a%$%k$N<u?.$,2DG=$K$J$j$^$9!#0BA4@-$r9M$($k$H!"2>$KFbIt(B 11.88 +$B$+$i$7$+MxMQ$7$J$$>l9g$G$b(BAPOP$B$rMxMQ$5$l$k$3$H$r6/$/$*4+$a$7$^$9!#(B</p> 11.89 + 11.90 +<p>APOP$B$rMxMQ$9$k$?$a$NJ}K!$r@bL@$7$^$9!#$J$*!"0J2<$N%a%$%k%j!<%@$G$O(B 11.91 +APOP$B$,(B<span class="e">$BMxMQ$G$-$^$;$s(B</span>$B$N$G$4Cm0U$/$@$5$$!#(B</p> 11.92 +<dl> 11.93 + <dt> $B!Z(BAPOP$B$K(B<span class="e">$BBP1~$7$F$$$J$$(B</span>$B<g$J%a%$%k%j!<%@![(B 11.94 + <dd> Microsoft Outlook Express<br> 11.95 + Microsoft Outlook<br> 11.96 + Netscape Messenger 11.97 + <dt> $B!Z(BAPOP$B$KBP1~$7$F$$$k<g$J%a%$%k%j!<%@![(B 11.98 + <dd> <ul> 11.99 + <li> Windows$BMQ(B<br> 11.100 + <a href="http://www.almail.com/">AL-Mail</a> 11.101 + ($B%7%'%"%&%'%"(B/$B3X@8!&3X=Q5!4XMxMQ$N$_L5NA(B),<br> 11.102 + <a href="http://www.rimarts.co.jp/becky-j.htm">Becky!</a> 11.103 + ($B%7%'%"%&%'%"(B),<br> 11.104 + <a href="http://denshin8.esprix.net/">$BEE?.H,9f(B</a> 11.105 + ($B%U%j!<%=%U%H%&%'%"(B),<br> 11.106 + <a href="http://www.eudora.ne.jp/">Eudora</a> 11.107 + (3$B<oN`$N%i%$%;%s%97ABV(B) 11.108 + <li> UNIX$BMQ(B($B0J2<A4$F%U%j!<%=%U%H(B)<br> 11.109 + <a href="http://www.mew.org/index-j.html">Mew</a>,<br> 11.110 + <a href="http://www.gohome.org/wl/index.ja.html"> 11.111 + Wanderlust</a> 11.112 + </ul> 11.113 +</dl> 11.114 +<p>$B0J2<$K$$$/$D$+$N%a%$%k%j!<%@$N(BAPOP$B@_DjJ}K!$r<($7$^$9!#(B</p> 11.115 +<dl> 11.116 + <dt> $B!L(BAL-Mail$B!M(B 11.117 + <dd> <ol> 11.118 + <li> $B@_Dj$7$?$$%"%+%&%s%H$rA*$V(B 11.119 + <li> $B!V%D!<%k(B(T)$B!W"*!V%*%W%7%g%s(B(O)$B!W$G=P$FMh$k%"%+%&%s%H@_Dj%a(B 11.120 + $B%K%e!<$N!"!V%"%+%&%s%H!W2hLL$K$F1&2<$N!V9bEY$J@_Dj!W$r%/%j%C(B 11.121 + $B%/(B 11.122 + <li> $B!V9bEY$J@_Dj!W%&%#%s%I%&$N:82<!V(BAPOP$B$GG'>Z!W$r%A%'%C%/(B 11.123 + </ol> 11.124 + <dt> $B!L(BBecky!$B!M(B 11.125 + <dd> <ol> 11.126 + <li> $B!V%D!<%k(B(T)$B!W"*!V@_Dj!W$G=P$k%&%#%s%I%&$G(B [$B%"%+%&%s%H(B] 11.127 + $B$rA*Br(B 11.128 + <li> [$B%"%+%&%s%H(B]$B@_Dj%&%#%s%I%&$N2<$K$"$k(B [$B$=$NB>(B] $B$r(B 11.129 + $B%/%j%C%/(B 11.130 + <li> $B%&%#%s%I%&2<It$N(B [APOP$B$r;H$&(B] $B$r%A%'%C%/(B 11.131 + </ol> 11.132 + <dt> $B!L(BEudora 4$B!M(B 11.133 + <dd> <ol> 11.134 + <li> $B!V%D!<%k(B(T)$B!W"*!V%Q!<%=%J%j%F%#(B(P)$B!W$G%"%+%&%s%HA*Br2hLL$r:8(B 11.135 + $BB&%&%#%s%I%&$K=P$9(B 11.136 + <li> APOP$B@_Dj$7$?$$%"%+%&%s%H$r1&%/%j%C%/$7!VJQ99(B(P)$B!W$rA*$V(B 11.137 + <li> $B!V%a!<%k$N<u?.!W%a%K%e!<$rA*Br(B 11.138 + <li> $B%&%#%s%I%&$N0lHV2<$N(B [$BG'>ZJ}<0(B] $B$G(BAPOP$B$r%A%'%C%/(B 11.139 + </ol> 11.140 + 11.141 + <dt> $B!L(BMew$B!M(B 11.142 + <dd> <p>~/.im/Config $B$N(B Imget.Src $B9T$N@_Dj$r0J2<$N$h$&$KJQ$($^$9!#(B</p> 11.143 + <blockquote> 11.144 + <p><tt>Imget.Src=pop/<span class="e">APOP</span>:user@$B%5!<%PL>(B</tt></p> 11.145 + </blockquote> 11.146 + <dt> $B!L(BWanderlust$B!M(B 11.147 + <dd> <p>$B%U%)%k%@%P%C%U%!$G(B m a $B$7$F0J2<$N$h$&$K%U%)%k%@$rDI2C$7$^$9!#(B</p> 11.148 + <blockquote> 11.149 + <p><tt>&user<span class="e">/apop</span>@$B%5!<%PL>(B</tt></p> 11.150 + </blockquote> 11.151 + <hr> 11.152 +</dl> 11.153 +<p>$B0J>e$N$$$:$l$N>l9g$b!"3HD%%a%$%k%"%I%l%9$r<u?.$7$?$$$H$-$O%f!<%6L>$H(B 11.154 +$B$7$F(B user-xxx $B$N$h$&$J3HD%;RIU$NL>A0$r;XDj$7$^$9!#(B</p> 11.155 + 11.156 +<h2> 11.157 + <a name="forward">$BB>$N%a%$%k%5!<%P$X$NE>Aw(B</a> 11.158 +</h2> 11.159 +<p>$BK\%5!<%P$KFO$$$?$"$J$?08$N%a%$%k$r!"JL$N%5!<%P$G4IM}$7$F$$$k%a%$%k%"(B 11.160 +$B%I%l%9$KE>Aw$9$k>l9g$O!"%[!<%`%G%#%l%/%H%j$K$"$k(B .qmail $B$H$$$&%U%!%$%k$K(B 11.161 +$BE>Aw@h$r=q$-$^$9!#(B</p> 11.162 +<ol> 11.163 + <li> FTP$B%/%i%$%"%s%H%=%U%H$rMxMQ$7$F$3$N%5!<%P$K%m%0%$%s$9$k(B 11.164 + <li> $B%m%0%$%s8e:G=i$K$D$J$,$k%G%#%l%/%H%j(B($B%U%)%k%@(B)$B$K(B .qmail $B$H$$$&%U%!(B 11.165 + $B%$%k$,$"$k$N$G$3$l$r<j85$N(BPC$B$K%3%T!<$9$k(B 11.166 + <li> $B%a%bD"(B(Notepad.exe)$B$J$IE,Ev$J%F%-%9%H%(%G%#%?$rMxMQ$7$F$3$N%U%!%$(B 11.167 + $B%k$rJT=8$70J2<$N$h$&$K=q$-49$($F%;!<%V$9$k(B 11.168 + <blockquote> 11.169 + <tt>&user2@tensosaki.co.jp</tt> 11.170 + </blockquote> 11.171 + ($B>e5-$NNc$G$O(B <tt>user2@tensosaki.co.jp</tt> $B$,E>Aw@h%"%I%l%9(B) 11.172 + <li> FTP$B%/%i%$%"%s%H%=%U%H$G:FEY(B .qmail $B%U%!%$%k$r%5!<%P>e$KE>Aw$9$k(B 11.173 +</ol> 11.174 +<p>$BB>%"%I%l%9$KE>Aw$7!"$J$*$+$D$3$N%5!<%P>e$N%a%$%k%\%C%/%9$K$b%a%$%k$r(B 11.175 +$B;D$7$?$$>l9g$O(B .qmail $B%U%!%$%k$K85!9$"$C$?(B ./Maildir/ $B$H$$$&9T$r>C$5$:$K(B 11.176 +$BE>AwMQ$N9T$rDI2C$7$^$9!#(B</p> 11.177 +<blockquote> 11.178 +<pre>./Maildir/ 11.179 +&user2@tensosaki.co.jp</pre> 11.180 +</blockquote> 11.181 +<h3> 11.182 + $BCm0U(B! 11.183 +</h3> 11.184 +<p>FTP$B$b(BPOP3$B$HF1MMJ?J8%Q%9%o!<%I$r%M%C%H%o!<%/$KN.$94m81$J$b$N$J$N$G!"(B 11.185 +ftp$B@\B3$bFbIt$+$i$NMxMQ$N$_$K@)8B$7$F$$$^$9!#$I$&$7$F$b30It%M%C%H%o!<%/(B 11.186 +$B$+$i(BFTP$B$rMxMQ$9$kI,MW$,$"$k>l9g$O4IM}<T$^$G$4AjCL$/$@$5$$!#(B</p> 11.187 + 11.188 +<hr> 11.189 +</body> 11.190 +</html>
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/APOPtools/with-tcpserver/0README Mon Sep 14 19:23:11 2009 +0900 12.3 @@ -0,0 +1,13 @@ 12.4 + 12.5 +This directory contains sample files for maintaining ipop3d via daemontools. 12.6 + 12.7 + 12.8 +# make install 12.9 + 12.10 +Installation directory can be changed by setting DESTDIR. 12.11 +eg. 12.12 +# make DESTDIR=/other/dir install 12.13 + 12.14 +Then, edit copied files and change the logging user-id in log/run. 12.15 + 12.16 +# ln -s /var/qmail/ipopd /service
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/APOPtools/with-tcpserver/Makefile Mon Sep 14 19:23:11 2009 +0900 13.3 @@ -0,0 +1,18 @@ 13.4 +# 13.5 +TCPDIR=/usr/local/bin 13.6 +TR=${TCPDIR}/tcprules 13.7 +DESTDIR = /var/qmail/ipopd 13.8 +LOGMAIN = ${DESTDIR}/log/main 13.9 +LOGUSER = nobody 13.10 + 13.11 +all: pop.cdb 13.12 + 13.13 +install: 13.14 + -mkdir -p ${DESTDIR} 13.15 + tar cf - Makefile log run | (cd ${DESTDIR}; tar xpf -) 13.16 + chmod +x ${DESTDIR}/run ${DESTDIR}/log/run 13.17 + mkdir ${LOGMAIN} 13.18 + chown ${LOGUSER} ${LOGMAIN} 13.19 + 13.20 +pop.cdb: pop 13.21 + cat $> | ${TR} $@ pop.tmp
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 14.2 +++ b/APOPtools/with-tcpserver/log/run Mon Sep 14 19:23:11 2009 +0900 14.3 @@ -0,0 +1,5 @@ 14.4 +#!/bin/sh 14.5 +exec env - \ 14.6 +PATH=/bin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin \ 14.7 +setuidgid nobody \ 14.8 +multilog t ./main
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 15.2 +++ b/APOPtools/with-tcpserver/pop Mon Sep 14 19:23:11 2009 +0900 15.3 @@ -0,0 +1,3 @@ 15.4 +127.0.0.:allow,INTRANET="" 15.5 +10.0.0.0-127:allow,INTRANET="" 15.6 +all:allow
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 16.2 +++ b/APOPtools/with-tcpserver/run Mon Sep 14 19:23:11 2009 +0900 16.3 @@ -0,0 +1,5 @@ 16.4 +#!/bin/sh 16.5 +# ipoper should be located in one of the $PATH elements. 16.6 +exec env - \ 16.7 +PATH=/bin:/usr/bin:/usr/sbin:/var/qmail/ipopd:/usr/local/bin:/usr/local/etc \ 16.8 +tcpserver -HR -c40 -x/var/qmail/ipopd/pop.cdb 0 pop3 ipop3d 2>&1
17.1 --- a/Makefile Mon Sep 14 15:17:45 2009 +0900 17.2 +++ b/Makefile Mon Sep 14 19:23:11 2009 +0900 17.3 @@ -252,7 +252,9 @@ 17.4 # British. As of 2005, the Julian calendar and the Gregorian calendar 17.5 # diverge by 15 days. 17.6 17.7 -EXTRACFLAGS= 17.8 +# EXTRACFLAGS=-DQMAIL -DRESTRICT_POP -DXADDR_DELIM="+" -DDOTQMAIL=".forward" 17.9 +## EXTRACFLAGS=-DQMAIL -DRESTRICT_POP 17.10 +EXTRACFLAGS=-DQMAIL -DRESTRICT_POP -DINET6 17.11 17.12 17.13 # Extra linker flags (additional/alternative libraries, etc.) 17.14 @@ -728,6 +730,7 @@ 17.15 clean: 17.16 @echo Removing old processed sources and binaries... 17.17 $(SH) -c '$(RM) an ua OSTYPE SPECIALS c-client mtest imapd ipopd mailutil mlock dmail tmail || true' 17.18 + $(SH) -c '$(RM) ip6 || true' 17.19 $(CD) tools;$(MAKE) clean 17.20 17.21
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 18.2 +++ b/README.maildir Mon Sep 14 19:23:11 2009 +0900 18.3 @@ -0,0 +1,93 @@ 18.4 +Pine 4.0x Maildir c-client module 18.5 +--------------------------------- 18.6 + 18.7 +Written by Mattias Larsson <ml@techno.org> <mta@freeit.com> 18.8 + 18.9 +This is the second release of my Maildir driver for Pine 4. It is based 18.10 +on Eric Greens IMAP2bis Maildir driver. 18.11 + 18.12 +PLEASE NOTE that this driver has only been tested in the IMAP4rev1 daemon 18.13 +before. It was just put into Pine 4.00, and it looks like it works, but it 18.14 +has not been extensively tested. It has been running for 8 months in 18.15 +production in our IMAP4 daemon though. 18.16 + 18.17 +PLEASE NOTE: 18.18 + 18.19 +This driver needs to store the UID's of the message in the file somehow. In 18.20 +the earlier versions of this driver this was done by adding a new maildir 18.21 +flag (the ,3 flag), however, this solution was not very good since most 18.22 +other clients could not handle it. Thus I had to find another solution. In 18.23 +this driver I use a pretty radical method. Any file in the maildir with the 18.24 +execute bit set has its UID set in the mtime of the file. So you should not 18.25 +edit the files in here, or in any otherway update the mtime, because then 18.26 +the UID gets changed. Most clients should not do this, so I think this 18.27 +solution is compatible with most other clients (if you find one that isn't, 18.28 +let me know). If you for some reason have to edit a file in the Maildir, 18.29 +delete the ".uidvalidity" file in the root of the Maildir (ie, the dir where 18.30 +you find cur/ new/ and tmp/). Alternatively, edit maildir.c and define the 18.31 +NO_UID_VALIDITY option, which will cause the Maildir to get set new UID's on 18.32 +every start up. Note that if you are running IMAP and Netscape as a client, 18.33 +you can't change the UID's, because Netscape do not support the UID validity 18.34 +flag in the IMAP protocol. So use this with care. 18.35 + 18.36 +Please edit the maildir.c file in any case. There are 3 options you can 18.37 +set yourself. The default configuration is not suitable for ISPs. If you are 18.38 +an ISP, or system with many users, you might want to consider setting some 18.39 +of the options different. 18.40 + 18.41 +Ohh, if there are problems compiling it, let me know, and please let me know 18.42 +what you did to fix it. This thing was developed on Solaris (using both GCC 18.43 +and SunCC, should work with both), but I haven't tried it on any other 18.44 +platform. It is also known to compile cleanly on Linux RH5.1 18.45 + 18.46 +CONFIGURATION 18.47 +------------- 18.48 + 18.49 +There are a few configurable options. You find these at the top of the 18.50 +maildir.c file (and it can be found in imap/src/osdep/unix if I'm not all 18.51 +mistaken). Right now, two options are configurable. By default it is 18.52 +configured for ISP use, something that you might want to change if you use 18.53 +it at home. 18.54 + 18.55 +HOW TO USE 18.56 +---------- 18.57 + 18.58 +Use it as any other c-client driver. There is some option you want to change 18.59 +if you want all folders to be created as Maildirs (and I can't remember what 18.60 +the option is from the top of my head). Read the pine documentation. 18.61 + 18.62 +CHANGES 18.63 +------- 18.64 + 18.65 +Rel 4. Coredump problem fixed. In release 3 I decided to user the sparep 18.66 + in the message cache so no patching of mail.h would be necessary, 18.67 + however, PINE uses this pointer internally for other things, causing 18.68 + coredumps when used with the Rel 3. patch. 18.69 + 18.70 +Rel 3. New way of storing UID's (compatible with ,2 clients). 18.71 + Multiple inbox patches applied 18.72 + 18.73 +Rel 2. Pine 4 changes. 18.74 + 18.75 +Rel 1. Imap4rev 1 driver 18.76 + 18.77 +FINAL NOTES 18.78 +----------- 18.79 + 18.80 +I'll try to maintain and release new versions as soon as I have time over, 18.81 +which unfortunately does not happen very often in this business ;) 18.82 + 18.83 +You can (might) find newer versions of this driver at: 18.84 + 18.85 +http://www.freeit.com/mta/ 18.86 + 18.87 + 18.88 +Regards, 18.89 +Daniel Mattias Larsson 18.90 + 18.91 +e-mail: ml@techno.org 18.92 +ph: +46-707-268785 18.93 +snail-mail: 18.94 +Industrivagen 4 18.95 +SE-194 77 Upplands Vasby 18.96 +SWEDEN
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 19.2 +++ b/README.qmailapop Mon Sep 14 19:23:11 2009 +0900 19.3 @@ -0,0 +1,366 @@ 19.4 +// 19.5 +// qmail+maildir+apop+virtualdomain+POPbeforeSMTP extensions to uw-imapd 19.6 +// Japanese Document below 19.7 +// 19.8 + 19.9 +[Comentary] 19.10 +This patch kit enables uw-imapd to handle; 19.11 + * maildir 19.12 + * qmail's extended mail addresses of user (~/.qmail-ext) 19.13 + * Postfix's extended mail addresses of user (~/.forward+ext) 19.14 + * Accesses to extended mail addresses (authenticated with ~/.apop-ext) 19.15 + * Virtual domain user switching 19.16 + 19.17 +Because this package is produced those who want to avail all features above, 19.18 +we recommend you to turn on all switches for every extension. 19.19 +Please let me recommend you not to use plain POP3 with this package. 19.20 +If you want to cling onto POP3, please use qmail-pop3d which comes with 19.21 +qmail distribution. 19.22 + 19.23 +[Configuration] 19.24 +You can select these compilation switches. 19.25 + 19.26 + Where: ./Makefile 19.27 + Switch: QMAIL 19.28 + What: Support maildir and user's address extension. 19.29 + This switch is requisite. 19.30 + 19.31 + Where: ./Makefile 19.32 + Switch: INET6 19.33 + What: Support IPv6 address 19.34 + WORKS fine only via ucspi-tcp+ipv6patch 19.35 + If you are using tcpserver-ipv6, set this. 19.36 + 19.37 + Where: ./Makefile 19.38 + Switch: POSTFIX 19.39 + What: Defaults user address file to ~/.forward and 19.40 + extension delimiter to "+". 19.41 + Setting this flag on is equavalent to declare 19.42 + -DQMAIL -DDOTQMAIL=".forward" -DXADDR_DELIM="+" 19.43 + in ./Makefile. 19.44 + 19.45 + Where: ./Makefile 19.46 + Switch: RESTRICT_POP 19.47 + What: Restrict POP3 access from unsafe network. Allow 19.48 + normal pop3 access only when environment variable 19.49 + INTRANET is set. This can be controled by tcpd with 19.50 + /etc/hosts.allow. 19.51 + 19.52 + Where: ./src/osdep/unix/Makefile 19.53 + Switch: DEFAULTMAILDIR (quoted string) 19.54 + What: Default users' maildir directory when a user does not 19.55 + have ~/.qmail file. 19.56 + The default value is null. If null, the default value in 19.57 + osdep/unix/maildir.c("Maildir") will be taken. 19.58 + 19.59 + Where: ./src/osdep/unix/Makefile 19.60 + Switch: QMAILCONTROL (quoted string) 19.61 + What: Default qmail/control directory. 19.62 + The default value is "/var/qmail/control" 19.63 + 19.64 + Where: ./src/osdep/unix/Makefile 19.65 + Switch: USERAPOPFILE (string) 19.66 + What: User's APOP password file relative to their home dir. 19.67 + ".apop" is set by default. 19.68 + One of recommended values is "Mail/.apop". 19.69 + NOTE THAT USERAPOPFILE should NOT be readable by others. 19.70 + Do chmod 600 USERAPOPFILE. 19.71 + 19.72 + Where: ./src/osdep/unix/Makefile 19.73 + Switch: APOPOPEN (string) 19.74 + What: Command name to decode APOP password from USERAPOPFILE 19.75 + "/usr/local/sbin/deapop" is set by default. 19.76 + NOTE THAT you should install deapop command too. 19.77 + If you don't want to think about this, 19.78 + install the following shell script into /usr/local/sbin/deapop 19.79 + 19.80 + #!/bin/sh 19.81 + cat "$@" 19.82 + 19.83 + Where: ./src/osdep/unix/Makefile 19.84 + Switch: POPBEFORESMTP 19.85 + What: Turn on `POP before SMTP' feature. 19.86 + The next variable POP3RECORDER takes effect when 19.87 + this variable is defined. 19.88 + 19.89 + Where: ./src/osdep/unix/Makefile 19.90 + Switch: POP3RECORDER (string) 19.91 + What: Command name to achieve `POP before SMTP'. 19.92 + "/usr/local/etc/pop3-record" is set by default. 19.93 + This recorder program should take one argument of 19.94 + fully qualified hostname (or IP address) where the POP 19.95 + authentication is passed to. 19.96 + 19.97 +[NO WARRANTY] 19.98 + 19.99 + This package comes from absolutely NO WARRANTY. The author of 19.100 + this package is not responsible for any result caused by using 19.101 + this software. The copyright of the extension part is held by 19.102 + HIROSE, Yuuji [yuuji@gentei.org]. 19.103 + 19.104 +[COPYING] 19.105 + 19.106 + You can re-distribute this package without any cost except some 19.107 + practical cost(magnetical media or so). Although this package 19.108 + basically obeys the license terms in a file CPYRIGHT in this 19.109 + directory, there is one exception; when you modify the code 19.110 + against the extensional part (over uw-imapd) and that 19.111 + modification is a kind of bug-fix, modification should be telled 19.112 + to the author of extensional part if you are thinking of 19.113 + re-distribute your modification to the public. This limitation 19.114 + is to aim to make this extensional package reasonably safe 19.115 + always in any time. Please feel free to hack and distribute it! 19.116 + 19.117 + 19.118 +-- Japanese document follows... 19.119 + 19.120 +【qmail+maildir+APOP用POPサーバ】 19.121 + 19.122 + このimapパッケージは、qmailとIMAPを組み合わせて使うこと *ではな 19.123 + く* qmail+maildir+APOPを柔軟に利用しようということを目的として作 19.124 + られましたのでIMAPでのテストは十分に行なわれていません。このパッ 19.125 + ケージは以下のような方を満足させるでしょう。 19.126 + 19.127 + * qmailを利用している 19.128 + * mail spool には安全性の高い Maildir 形式を利用し(させ)ている 19.129 + * ~/.qmail-ext ファイルによるqmailの拡張アドレスをよく利用している 19.130 + * virtual domain を活用しまくっている 19.131 + 19.132 + 上記のようなことができるqmailですが、この機能を使いこなすために 19.133 + はUNIXマシンにログインしてローカルファイルを見に行くメイルリーダ 19.134 + を使うという方法しかありませんでした。これでは不便なので、上記の 19.135 + 使い分けを認識するPOPサーバを作ろうということで作成したのがこの 19.136 + パッケージです。またPOPのみのサーバ利用が多い昨今、リモートから 19.137 + の認証にログインパスワードを使わずにメイル専用パスワードを利用さ 19.138 + せる変更も行なっています。これによりPOPもAPOP(POPのパスワード認 19.139 + 証の暗号化版)も共通のパスワードを利用できるようにしました。また、 19.140 + POP の場合は既存ユーザのパスワード管理を考えて、認証時にUNIXパス 19.141 + ワードも参照するようにしています。 19.142 + 19.143 + もう一点、POPはパスワードをプレインテキストで流すため、外部ネッ 19.144 + トワークからの利用は危険です。そこでPOPの利用を一部のネットワー 19.145 + クに限定する機能もつけました(tcp_wrappersやtcpserverが必要)。 19.146 + 19.147 +【インストール】 19.148 + 19.149 + デフォルト設定では 19.150 + 19.151 + * POP3は拒否する 19.152 + * ユーザのパスワード設定ファイルは ~/.apop 19.153 + * ~/.apop のデコードプログラムは /usr/local/sbin/deapop 19.154 + 19.155 + となっています。APOP認証はサーバ側で必ず元のパスワードを知る必要 19.156 + があります。これまでのAPOPサーバは全てのユーザ毎に管理者権限でパ 19.157 + スワードを設定する必要がありました。一見安全そうですが、じつはユー 19.158 + ザがパスワードを変更する頻度を限りなくゼロに近づけているだけです。 19.159 + そもそもAPOPはサーバ側で元パスワードを取得する必要があるので必ず 19.160 + 復元可能な形で保存されなければなりません。ということはどんなに凝っ 19.161 + た方法で保存しても結局は復号できるのですから、複雑な方法で暗号化 19.162 + &格納をすることは手間を増やすだけです。いずれにしてもroot権限さ 19.163 + えあれば元のパスワードは簡単に読めるわけですから、最初からユーザ 19.164 + 自身にパスワード管理をさせてしまっても何ら問題は無く、むしろその 19.165 + 方がパスワードをこまめに変えてくれる可能性が(ちょりっと)上がりま 19.166 + す。ただし、誰にでもパスワードが読めては困るので、パスワードファ 19.167 + イルを chmod 600 しておかないとメイルの取り込みが出来ないように 19.168 + なっています。またどうしても平文でファイルに保存するのだけはいや 19.169 + だーという場合のために、APOPパスワードファイルは 19.170 + /usr/local/sbin/deapop というコマンドを経由して読み込むようになっ 19.171 + ています。これにデコードする処理を書いておきます。もし、とくにエ 19.172 + ンコードしなくてもいいという場合は 19.173 + 19.174 + #!/bin/sh 19.175 + cat "$@" 19.176 + 19.177 + というシェルスクリプトでも入れておいてください。このパスワードは 19.178 + ログインパスワードとは独立しているのでこれで大きな問題は起こらな 19.179 + いでしょう(責任は持ちませんが:-)。 19.180 + 19.181 + コンパイル時の変数は上記英文解説の場所を読んでください。 19.182 + 19.183 +【ユーザから見た使い方】 19.184 + 19.185 + まず、~/.qmail に正しくmaildirが設定されていることを確認します。 19.186 + maildirをまだ作っていない場合は、 19.187 + 19.188 + % /var/qmail/bin/maildirmake ~/maildir 19.189 + 19.190 + とし、~/.qmail に 19.191 + 19.192 + ./maildir/ 19.193 + 19.194 + と書きます。またメイル専用パスワードを ~/.apop に記録します。 19.195 + これは apoppasswd コマンドで行ないます。 19.196 + 19.197 + % apoppasswd 19.198 + 19.199 + これで完了です。apoppasswdコマンドは APOPtools/apoppasswd にある 19.200 + ので管理者がサイトの環境に手直しした上で一般ユーザのPATHの通る場 19.201 + 所にインストールして使って下さい。 19.202 + 19.203 + さて、拡張アドレスを使いましょう。ログイン名を login とします。 19.204 + login-isogi@hogehoge.co.jp のようなアドレスは ~/.qmail-isogi とい 19.205 + うファイルで作成できます。login-isogi 用のmaildirを作ります。 19.206 + 19.207 + % /var/qmail/bin/maildirmake ~/isogidir 19.208 + 19.209 + これを ~/.qmail-isogi に登録します。 19.210 + 19.211 + ./isogidir/ 19.212 + 19.213 + 最後に login-isogi 用のパスワードを設定します。 19.214 + 19.215 + % apoppasswd -e isogi -c 19.216 + Enter APOP Password: 19.217 + 19.218 + とすると、maildirの作成とパスワードの設定が同時に行えます。 19.219 + maildirとパスワードの作成が完了したら、利用してるメイルリーダの 19.220 + APOP アカウントの「アカウント名」をlogin-isogi にして接続します。 19.221 + 19.222 +【POP before SMTPについて】 19.223 + 19.224 + まず tcp_wrappers を利用している場合について説明します。 19.225 + tcpserverを利用する場合も原理は同じなので仕組みだけ理解してくだ 19.226 + さい。 19.227 + 19.228 + tcp_wrapperとtcp-envを組み合わせてSMTPサーバを中継用に使うドメイ 19.229 + ンを限定して使っていると思います。これの発展形でPOP接続して来た 19.230 + ドメインだけにSMTPサーバを使わせる手法のことを "POP before SMTP" 19.231 + と呼びます。このパッケージでも APOP 接続をしたドメインに対して 19.232 + SMTPの中継許可を与えることが出来ます。本パッケージの ./APOPtools 19.233 + ディレクトリにある pop3-* を /usr/local/etc にインストールします。 19.234 + 3つのファイルの実体は同じです。さらに以下の作業をします。 19.235 + 19.236 + * 原本となる /etc/hosts.allow を /etc/hosts.allow.src にコピー 19.237 + * crontab で10分毎に /usr/local/etc/pop3-age を起動させる 19.238 + 19.239 + 後者は、大抵のOSの場合 root の crontab に 19.240 + 19.241 + */10 * * * * root /usr/local/etc/pop3-age 19.242 + 19.243 + などと書けば設定できます。pop3-* スクリプトは自身の環境に合わせ 19.244 + て適宜修正して下さい。この段階で、tcp_wrapper の定義ファイルは 19.245 + /etc/hosts.allow.src が大元で、/etc/hosts.allow はcronによって自 19.246 + 動生成されるものとなります。hosts.allowをいじっても自動的に上書 19.247 + きされてしまうので、設定を変えるときは *必ず hosts.allow.src を 19.248 + 編集する* ことに注意して下さい。 19.249 + 19.250 + さらにipop3dを起動するときに接続してきたホストが環境変数 19.251 + RELAYCLIENT に入るようにしておきます。/etc/inetd.conf でipop3dを 19.252 + 起動するときに tcp_wrapper 経由となることを確認します。 19.253 + 19.254 + [/etc/inetd.conf] 19.255 + pop3 stream tcp nowait root /usr/libexec/tcpd /usr/libexec/ipop3d 19.256 + 19.257 + 1999年頃以降のPC-UNIXではinetdにデフォルトでtcpdが組み込まれてい 19.258 + ることが多いので、inetd.confにtcpdははさまなくて良いこともありま 19.259 + す。続いて /etc/hosts.allow.src で環境変数の設定が起きるようにし 19.260 + ます。 19.261 + 19.262 + [/etc/hosts.allow.src] 19.263 + ipop3d : all : setenv RELAYCLIENT %h 19.264 + 19.265 + これで POPサービスを利用しに来たクライアントのアドレスが環境変数 19.266 + に入ります。 19.267 + 19.268 + tcpserverの場合は、付属の pop3-record スクリプトの後半に例がある 19.269 + のでそれを利用してください。 19.270 + 19.271 + なお、tcp_wrappers 用の pop3-age スクリプトは負荷の高いマシンで 19.272 + は hosts.allow ファイルが空になる可能性があります。lockすれば多 19.273 + 少ましになるでしょうが完ぺきではありません。もし、hosts.allowの 19.274 + 書き換えに失敗するような負荷の高い環境で使う場合は tcp_wrappers 19.275 + ではなく、tcpserverでのアクセス制御をすることを強く勧めます。こ 19.276 + ちらはロックの必要もなく、安全にアクセス制御ファイルの更新ができ 19.277 + ます。 19.278 + 19.279 +【POPアクセス制御について】 19.280 + 19.281 + POP3とAPOPは同じポートを使うので「外部からはAPOPだけ許す」などの 19.282 + 制御はルータやtcp_wrappersなどだけではできません。このipop3dでは、 19.283 + 生のPOP3は環境変数INTRANETが定義されているときだけに利用を制限す 19.284 + ることができます。tcp_wrappers の例を示します。 19.285 + 19.286 + ipop3d : localhost .localnet.hoge.jp \ 19.287 + : setenv INTRANET : setenv RELAYCLIENT %h 19.288 + ipop3d : all : setenv RELAYCLIENT %h 19.289 + 19.290 + としておけば、ローカルネットワーク内だけで生POP3を使うことができ 19.291 + ます。 19.292 + 19.293 +【virtualdomain機能について】 19.294 + 19.295 + qmailでは /var/qmail/control/virtualdomains を使うことで、ユーザ 19.296 + が任意のメイルドメインを持つことができます。これを解釈するように 19.297 + しました。/var/qmail/control/virtualdomain ファイルで 19.298 + 19.299 + virtual.hoge.co.jp:user1 19.300 + dokan.hoge.co.jp:user2-dokan 19.301 + 19.302 + としておくと、XX@virtual.hoge.co.jp は ~user1/.qmail-XX に配送さ 19.303 + れ、YY@dokan.hoge.co.jp は ~user2/.qmail-dokan-YY に配送されます。 19.304 + それがMaildirスプールを含む場合、本パッケージのIMAP/POPで取り込 19.305 + むことができます。デフォルトではこのためのパスワードはそれぞれ 19.306 + 19.307 + ~user1/.apop-XX 19.308 + ~user2/.apop-dokan-YY 19.309 + 19.310 + ファイルに保存しておかなければなりません。 19.311 + 19.312 +【Postfixの拡張アドレス対応について】 19.313 + 19.314 + Postfixによる ~/.forward+ext で発生する拡張アドレスは、その配送 19.315 + 先がMaildirであれば本パッケージでも利用できます。Postfix のデフォ 19.316 + ルト設定の 19.317 + forward_path = $home/.forward$recipient_delimiter$extension, 19.318 + $home/.forward 19.319 + recipient_delimiter = + 19.320 + 19.321 + のまま Postfix を動かしている場合はトップレベルのMakefileの 19.322 + EXTRACFLAGS に -DPOSTFIX を追加して下さい(-DQMAILも必要です)。こ 19.323 + れにより、拡張アドレスを決めるファイルが ".forward" に、拡張部分 19.324 + を区切る文字列が "+" になります。いずれかを変更している場合はた 19.325 + とえば、 19.326 + 19.327 + -DDOTQMAIL=".postfix" -DXADDR_DELIM="-" 19.328 + 19.329 + のように変更できます。もし、Postfix の .forward+ext を利用する場 19.330 + 合は周辺ツールの APOPtools/apoppasswd, APOPtools/apopcall.c の対 19.331 + 応する変数も変更する必要があることに注意して下さい。また、パスワー 19.332 + ドファイルも ~/.apop-ext ではなく~ /.apop+ext となることに注意が 19.333 + 必要です。これらが面倒な場合は、Postfix の設定の方で .qmail-ext 19.334 + を見るようにしてしまうのも手です。この場合は 19.335 + 19.336 + recipient_delimiter = - 19.337 + forward_path = $home/.forward$recipient_delimiter$extension, 19.338 + $home/.qmail$recipient_delimiter$extension, 19.339 + $home/.forward 19.340 + 19.341 + とすると ~/.qmail-ext も参照するようになり、デフォルト状態の本パッ 19.342 + ケージのまま利用することができるでしょう。 19.343 + 19.344 +【Postfixの POP before SMTPについて】 19.345 + 19.346 + main.cf で たとえば次のようにします。 19.347 + 19.348 + smtpd_recipient_restrictions = 19.349 + permit_mynetworks 19.350 + check_client_access hash:/etc/postfix/client_access 19.351 + 19.352 + ここで /etc/postfix/client_access は POP before SMTP の許可ホス 19.353 + トリストを保持するためのファイル名で、既に使われてはいないものに 19.354 + します。配布ディレクトリの APOPtools/pop3-record.postfix は 19.355 + /etc/postfix/client_access ファイルをリレー許可判定に使うことを 19.356 + 前提とした Postfix 用のスクリプトです。 19.357 + 19.358 +【謝辞】 19.359 + 19.360 + 安井卓さん(tach@debian.or.jp)にはsyslog関係のパッチを頂きました。 19.361 + ここに感謝の意を表します。 19.362 + 19.363 +【免責】 19.364 + 19.365 + IMAPパッケージに本ドキュメントで説明した拡張機能を追加する部分の 19.366 + 著作権は広瀬雄二[yuuji@gentei.org]が保持します。このプログラムを 19.367 + 用いて生じた如何なる結果に対しても著作権者は責任を負いません。 19.368 + 19.369 + 2009/9/14 yuuji@gentei.org
20.1 --- a/src/c-client/auth_log.c Mon Sep 14 15:17:45 2009 +0900 20.2 +++ b/src/c-client/auth_log.c Mon Sep 14 19:23:11 2009 +0900 20.3 @@ -105,6 +105,10 @@ 20.4 char *ret = NIL; 20.5 char *user,*pass,*authuser; 20.6 if (user = (*responder) (PWD_USER,sizeof (PWD_USER),NIL)) { 20.7 +#ifdef QMAIL 20.8 + extern char* conv_virtualdomain(char*); 20.9 + user = conv_virtualdomain(user); 20.10 +#endif 20.11 if (pass = (*responder) (PWD_PWD,sizeof (PWD_PWD),NIL)) { 20.12 /* delimit user from possible admin */ 20.13 if (authuser = strchr (user,'*')) *authuser++ = '\0';
21.1 --- a/src/c-client/auth_md5.c Mon Sep 14 15:17:45 2009 +0900 21.2 +++ b/src/c-client/auth_md5.c Mon Sep 14 19:23:11 2009 +0900 21.3 @@ -75,9 +75,11 @@ 21.4 21.5 long auth_md5_valid (void) 21.6 { 21.7 +#ifndef QMAIL /* qmail extension can always handle MD5 */ 21.8 struct stat sbuf; 21.9 /* server forbids MD5 if no MD5 enable file */ 21.10 if (stat (MD5ENABLE,&sbuf)) auth_md5.server = NIL; 21.11 +#endif 21.12 return T; /* MD5 is otherwise valid */ 21.13 } 21.14 21.15 @@ -186,6 +188,7 @@ 21.16 char *auth_md5_pwd (char *user) 21.17 { 21.18 struct stat sbuf; 21.19 +#ifndef QMAIL 21.20 int fd = open (MD5ENABLE,O_RDONLY,NIL); 21.21 unsigned char *s,*t,*buf,*lusr,*lret; 21.22 char *r; 21.23 @@ -214,6 +217,77 @@ 21.24 fs_give ((void **) &buf); /* flush the buffer */ 21.25 close (fd); /* don't need file any longer */ 21.26 } 21.27 +#else 21.28 +# ifndef USERAPOPFILE 21.29 +# define USERAPOPFILE ".apop" 21.30 +# endif 21.31 +# ifndef XADDR_DELIM 21.32 +# ifdef POSTFIX /* Same if-condition is in maildir.c.. sorry */ 21.33 +# define XADDR_DELIM "+" 21.34 +# else 21.35 +# define XADDR_DELIM "-" 21.36 +# endif 21.37 +# endif 21.38 + extern char *myMailSuffix; 21.39 + char mycrypt[BUFSIZ+1]; 21.40 + char *ret = NIL, *tmp=NIL; 21.41 + FILE *apopfile = NIL; 21.42 + struct passwd *pw = getpwnam(user); 21.43 + if (!pw) pw = getpwnam(lcase(tmp=cpystr(user))); 21.44 + if (!pw && strstr(user, XADDR_DELIM)) { /* Check qmail alias */ 21.45 + char tmp[BUFSIZ]; 21.46 + char *s = user; 21.47 + memset(tmp, 0, BUFSIZ); 21.48 + while (*s && s && !pw) { 21.49 + s = strstr(s, XADDR_DELIM); 21.50 + if (!s) break; 21.51 + strncpy(tmp, user, s-user); 21.52 + s++; 21.53 + pw = getpwnam(tmp); 21.54 + } 21.55 + if (pw) { 21.56 + myMailSuffix = lcase(cpystr(s-1)); 21.57 + user[strlen(tmp)] = '\0'; /* zap suffix */ 21.58 + } 21.59 + } 21.60 + if (pw) { 21.61 + snprintf(mycrypt, BUFSIZ, "%s/%s", pw->pw_dir, USERAPOPFILE); 21.62 + if (NIL != myMailSuffix) strcat(mycrypt, myMailSuffix); 21.63 + if (stat(mycrypt, &sbuf) < 0) { 21.64 + /* printf("Cannot stat [%s]\015\n", mycrypt); */ 21.65 + return ret; 21.66 + } 21.67 + if (sbuf.st_mode & ~(S_IFREG | S_IREAD | S_IWRITE)) { 21.68 + /* printf("Your apoppassword file is readable by others. Do chmod 600 %s%c\n", mycrypt, 015); */ 21.69 + return ret; 21.70 + } 21.71 +#ifdef APOPOPEN 21.72 + if (stat(APOPOPEN, &sbuf) >= 0) { /* if APPOPEN exists */ 21.73 + /* read apop password via APOPOPEN program */ 21.74 + int bytes = 3+strlen(APOPOPEN)+strlen(mycrypt); 21.75 + char *aproc = (char*) fs_get(bytes); 21.76 + snprintf(aproc, bytes, "%s %s%c", APOPOPEN, mycrypt, '\0'); 21.77 + apopfile = popen(aproc, "r"); 21.78 + memset(aproc, 0, bytes); 21.79 + fs_give((void**)&aproc); 21.80 + } 21.81 +#endif /* APOPOPEN */ 21.82 + if ((NIL!=apopfile) || (apopfile = fopen( mycrypt, "r" ))) { 21.83 + fgets(mycrypt, sizeof(mycrypt) - 1, apopfile); 21.84 + fclose(apopfile); 21.85 + if (mycrypt[0]) { 21.86 + char p = strlen(mycrypt); 21.87 + while (p > 0 && (mycrypt[p-1] == '\n' || mycrypt[p-1] == '\r')) { 21.88 + mycrypt[--p] = '\0'; /* zap trailing newlines */ 21.89 + } 21.90 + } 21.91 + } else { 21.92 + return ret; 21.93 + } 21.94 + ret = cpystr(mycrypt); 21.95 + memset(mycrypt, 0, sizeof(mycrypt)); 21.96 + } 21.97 +#endif /* if QMAIL */ 21.98 return ret; /* return password */ 21.99 } 21.100 21.101 @@ -231,6 +305,9 @@ 21.102 int i,j; 21.103 char *ret = NIL; 21.104 char *s,*authuser,tmp[MAILTMPLEN]; 21.105 +#ifdef QMAIL 21.106 + char *userback = cpystr(user); 21.107 +#endif 21.108 unsigned char digest[MD5DIGLEN]; 21.109 MD5CONTEXT ctx; 21.110 char *hex = "0123456789abcdef"; 21.111 @@ -260,7 +337,15 @@ 21.112 memset (tmp,0,MAILTMPLEN); /* erase sensitive information */ 21.113 } 21.114 if (!ret) sleep (3); /* slow down possible cracker */ 21.115 + else { 21.116 + extern void permitsmtp(); 21.117 + /* permitsmtp();*/ 21.118 + } 21.119 +#ifdef QMAIL 21.120 + return (ret) ? userback : ret; 21.121 +#else 21.122 return ret; 21.123 +#endif 21.124 } 21.125 21.126 /*
22.1 --- a/src/c-client/mail.c Mon Sep 14 15:17:45 2009 +0900 22.2 +++ b/src/c-client/mail.c Mon Sep 14 19:23:11 2009 +0900 22.3 @@ -6081,6 +6081,9 @@ 22.4 if (auth->server && !compare_cstring (auth->name,mechanism)) 22.5 return (!(auth->flags & AU_DISABLE) && 22.6 ((auth->flags & AU_SECURE) || 22.7 +#ifdef QMAIL 22.8 + getenv("INTRANET") || 22.9 +#endif 22.10 !mail_parameters (NIL,GET_DISABLEPLAINTEXT,NIL))) ? 22.11 (*auth->server) (resp,argc,argv) : NIL; 22.12 return NIL; /* no authenticator found */
23.1 --- a/src/c-client/mail.h Mon Sep 14 15:17:45 2009 +0900 23.2 +++ b/src/c-client/mail.h Mon Sep 14 19:23:11 2009 +0900 23.3 @@ -858,6 +858,7 @@ 23.4 unsigned int spare7 : 1; /* seventh spare bit */ 23.5 unsigned int spare8 : 1; /* eighth spare bit */ 23.6 void *sparep; /* spare pointer */ 23.7 + void *maildirp; /* for the Maildir driver */ 23.8 unsigned long user_flags; /* user-assignable flags */ 23.9 } MESSAGECACHE; 23.10
24.1 --- a/src/imapd/imapd.c Mon Sep 14 15:17:45 2009 +0900 24.2 +++ b/src/imapd/imapd.c Mon Sep 14 19:23:11 2009 +0900 24.3 @@ -553,6 +553,9 @@ 24.4 24.5 /* plaintext login with password */ 24.6 else if (!strcmp (cmd,"LOGIN")) { 24.7 + #ifdef QMAIL 24.8 + extern char* conv_virtualdomain(char*); 24.9 + #endif 24.10 if (user) fs_give ((void **) &user); 24.11 if (pass) fs_give ((void **) &pass); 24.12 /* two arguments */ 24.13 @@ -573,7 +576,11 @@ 24.14 else { /* delimit user from possible admin */ 24.15 if (s = strchr (user,'*')) *s++ ='\0'; 24.16 /* see if username and password are OK */ 24.17 +#ifdef QMAIL 24.18 + if (server_login (conv_virtualdomain(user),pass,s,argc,argv)) { 24.19 +#else 24.20 if (server_login (user,pass,s,argc,argv)) { 24.21 +#endif 24.22 state = SELECT; /* make select */ 24.23 alerttime = 0; /* force alert */ 24.24 response = logwin;/* return logged-in capabilities */
25.1 --- a/src/ipopd/ipop3d.c Mon Sep 14 15:17:45 2009 +0900 25.2 +++ b/src/ipopd/ipop3d.c Mon Sep 14 19:23:11 2009 +0900 25.3 @@ -96,6 +96,9 @@ 25.4 void trmint (); 25.5 int pass_login (char *t,int argc,char *argv[]); 25.6 char *apop_login (char *chal,char *user,char *md5,int argc,char *argv[]); 25.7 +#ifdef QMAIL 25.8 +char* conv_virtualdomain(char *account); 25.9 +#endif 25.10 char *responder (void *challenge,unsigned long clen,unsigned long *rlen); 25.11 int mbxopen (char *mailbox); 25.12 long blat (char *text,long lines,unsigned long size,STRING *st); 25.13 @@ -128,7 +131,11 @@ 25.14 AUTHENTICATOR *auth = mail_lookup_auth (1); 25.15 while (auth && compare_cstring (auth->name,"CRAM-MD5")) auth = auth->next; 25.16 /* build challenge -- less than 128 chars */ 25.17 +#ifndef QMAIL 25.18 + if (!(auth->flags & AU_DISABLE)) 25.19 +#else 25.20 if (auth && auth->server && !(auth->flags & AU_DISABLE)) 25.21 +#endif 25.22 sprintf (challenge,"<%lx.%lx@%.64s>",(unsigned long) getpid (), 25.23 (unsigned long) time (0),tcp_serverhost ()); 25.24 else challenge[0] = '\0'; /* no MD5 authentication */ 25.25 @@ -258,10 +265,17 @@ 25.26 /* get user name */ 25.27 if (!(t && *t && (s = strtok (t," ")) && (t = strtok(NIL,"\012")))) 25.28 PSOUT ("-ERR Missing APOP argument\015\012"); 25.29 - else if (!(user = apop_login (challenge,s,t,argc,argv))) 25.30 - PSOUT ("-ERR Bad APOP\015\012"); 25.31 - else if ((state = mbxopen ("INBOX")) == TRANSACTION) 25.32 - syslog (LOG_INFO,"APOP user=%.80s host=%.80s nmsgs=%lu/%lu", 25.33 + #ifdef QMAIL 25.34 + else if (!(user = apop_login (challenge,conv_virtualdomain(s),t,argc,argv))) { 25.35 + #else /* !QMAIL */ 25.36 + else if (!(user = apop_login (challenge,s,t,argc,argv))) { 25.37 + #endif /* QMAIL */ 25.38 + PSOUT ("-ERR Bad APOP (Maybe your password is expired)\015\012"); 25.39 + user = cpystr (s); 25.40 + syslog (LOG_INFO,"APOP login failure user=%.80s host=%.80s", 25.41 + user,tcp_clienthost ()); 25.42 + } else if ((state = mbxopen ("INBOX")) == TRANSACTION) 25.43 + syslog (LOG_INFO,"APOP user=%.80s host=%.80s nmsgs=%ld/%ld", 25.44 user,tcp_clienthost (),nmsgs,stream->nmsgs); 25.45 else syslog (LOG_INFO,"APOP user=%.80s host=%.80s no mailbox", 25.46 user,tcp_clienthost ()); 25.47 @@ -279,8 +293,20 @@ 25.48 } 25.49 else PSOUT ("+OK STLS completed\015\012"); 25.50 } 25.51 +#ifndef RESTRICT_POP 25.52 else if (!mail_parameters (NIL,GET_DISABLEPLAINTEXT,NIL) && 25.53 !strcmp (s,"USER")) { 25.54 +#else /* !RESTRICT_POP */ 25.55 + else if (!strcmp (s,"USER")) { 25.56 + if (getenv("INTRANET") == NIL) { 25.57 + PSOUT("-ERR Sorry, we don't allow POP3 from your network. Use APOP instead.\015\012"); 25.58 + user = cpystr(t); 25.59 + syslog (LOG_INFO,"Plain POP3 is restricted user=%.80s host=%.80s", 25.60 + user,tcp_clienthost ()); 25.61 + memset(user, '\0', strlen(user)); 25.62 + break; 25.63 + } 25.64 +#endif 25.65 if (host) fs_give ((void **) &host); 25.66 if (user) fs_give ((void **) &user); 25.67 if (pass) fs_give ((void **) &pass); 25.68 @@ -294,7 +320,11 @@ 25.69 user = cpystr (s);/* copy user name */ 25.70 } 25.71 /* local user name */ 25.72 +#ifdef QMAIL 25.73 + else user = conv_virtualdomain(cpystr (t)); 25.74 +#else 25.75 else user = cpystr (t); 25.76 +#endif 25.77 PSOUT ("+OK User name accepted, password please\015\012"); 25.78 } 25.79 else PSOUT ("-ERR Missing username argument\015\012");
26.1 --- a/src/osdep/unix/Makefile Mon Sep 14 15:17:45 2009 +0900 26.2 +++ b/src/osdep/unix/Makefile Mon Sep 14 19:23:11 2009 +0900 26.3 @@ -27,7 +27,7 @@ 26.4 # Command line build parameters 26.5 26.6 EXTRAAUTHENTICATORS= 26.7 -EXTRADRIVERS=mbox 26.8 +EXTRADRIVERS=maildir mbox 26.9 PASSWDTYPE=std 26.10 SSLTYPE=nopwd 26.11 IP=4 26.12 @@ -102,6 +102,7 @@ 26.13 NEWSSPOOL=$(SPOOLDIR)/news 26.14 RSHPATH=/usr/ucb/rsh 26.15 MD5PWD=/etc/cram-md5.pwd 26.16 +MD5CFLAGS= -DAPOPOPEN=\"/usr/local/sbin/deapop\" -DUSERAPOPFILE=\".apop\" -DPOPBEFORESMTP -DPOP3RECORDER=\"/usr/local/etc/pop3-record\" 26.17 # Tries one of the test alternatives below if not specified. 26.18 LOCKPGM= 26.19 # Test alternatives if LOCKPGM not specified 26.20 @@ -144,17 +145,21 @@ 26.21 # However, mh needs to be before any sysinbox formats (such as mmdf or unix) 26.22 # since otherwise INBOX won't work correctly when mh_allow_inbox is set. 26.23 # 26.24 -DEFAULTDRIVERS=imap nntp pop3 mix mx mbx tenex mtx mh mmdf unix news phile 26.25 +DEFAULTDRIVERS=maildir imap nntp pop3 mix mx mbx tenex mtx mh mmdf unix news phile 26.26 CHUNKSIZE=65536 26.27 26.28 # Normally no need to change any of these 26.29 +EXTRACFLAGS=-DQMAIL 26.30 +# Next variable controls default maildir when user has no ~/.qmail 26.31 +#MAILDIRCFLAGS=-DDEFAULTMAILDIR="maildir" -DQMAILCONTROL="/var/qmail/control" 26.32 +MAILDIRCFLAGS=-DQMAILCONTROL="/var/qmail/control" 26.33 26.34 ARCHIVE=c-client.a 26.35 BINARIES=osdep.o mail.o misc.o newsrc.o smanager.o utf8.o utf8aux.o siglocal.o \ 26.36 dummy.o pseudo.o netmsg.o flstring.o fdstring.o \ 26.37 rfc822.o nntp.o smtp.o imap4r1.o pop3.o \ 26.38 - unix.o mbx.o mmdf.o tenex.o mtx.o news.o phile.o mh.o mx.o mix.o 26.39 -CFLAGS=-g 26.40 + unix.o mbx.o mmdf.o tenex.o mtx.o news.o phile.o mh.o mx.o mix.o maildir.o 26.41 +CFLAGS=-g $(EXTRACFLAGS) 26.42 26.43 CAT=cat 26.44 MAKE=make 26.45 @@ -892,6 +897,7 @@ 26.46 unix.o: mail.h misc.h osdep.h unix.h pseudo.h dummy.h 26.47 utf8.o: mail.h misc.h osdep.h utf8.h tmap.c widths.c 26.48 utf8aux.o: mail.h misc.h osdep.h utf8.h 26.49 +maildir.o: mail.h misc.h osdep.h maildir.h dummy.h 26.50 26.51 26.52 # OS-dependent 26.53 @@ -960,6 +966,7 @@ 26.54 @echo Once-only environment setup... 26.55 echo $(CC) > CCTYPE 26.56 echo $(BASECFLAGS) '$(EXTRACFLAGS)' -DCHUNKSIZE=$(CHUNKSIZE) > CFLAGS 26.57 + echo '$(MAILDIRCFLAGS)' >> CFLAGS 26.58 echo -DCREATEPROTO=$(CREATEPROTO) -DEMPTYPROTO=$(EMPTYPROTO) \ 26.59 -DMD5ENABLE=\"$(MD5PWD)\" -DMAILSPOOL=\"$(MAILSPOOL)\" \ 26.60 -DANONYMOUSHOME=\"$(MAILSPOOL)/anonymous\" \ 26.61 @@ -967,6 +974,7 @@ 26.62 -DRSHPATH=\"$(RSHPATH)\" -DLOCKPGM=\"$(LOCKPGM)\" \ 26.63 -DLOCKPGM1=\"$(LOCKPGM1)\" -DLOCKPGM2=\"$(LOCKPGM2)\" \ 26.64 -DLOCKPGM3=\"$(LOCKPGM3)\" > OSCFLAGS 26.65 + echo $(MD5CFLAGS) >> OSCFLAGS 26.66 echo $(BASELDFLAGS) $(EXTRALDFLAGS) > LDFLAGS 26.67 echo "$(ARRC) $(ARCHIVE) $(BINARIES);$(RANLIB) $(ARCHIVE)" > ARCHIVE 26.68 echo $(OS) > OSTYPE
27.1 --- a/src/osdep/unix/env_unix.c Mon Sep 14 15:17:45 2009 +0900 27.2 +++ b/src/osdep/unix/env_unix.c Mon Sep 14 19:23:11 2009 +0900 27.3 @@ -422,6 +422,10 @@ 27.4 case SET_DISABLEPLAINTEXT: 27.5 disablePlaintext = (long) value; 27.6 case GET_DISABLEPLAINTEXT: 27.7 +#ifdef RESTRICT_POP 27.8 + if (getenv("INTRANET") == NIL) disablePlaintext = 1; 27.9 + else disablePlaintext = NIL; 27.10 +#endif 27.11 ret = (void *) disablePlaintext; 27.12 break; 27.13 case SET_CHROOTSERVER: 27.14 @@ -665,6 +669,7 @@ 27.15 char *s; 27.16 struct passwd *pw; 27.17 struct passwd *ret = NIL; 27.18 +#ifndef QMAIL /* imapext md5 checker run previously. no need to do here */ 27.19 if (auth_md5.server) { /* using CRAM-MD5 authentication? */ 27.20 if (s = auth_md5_pwd (user)) { 27.21 if (!strcmp (s,pwd) || ((*pwd == ' ') && pwd[1] && !strcmp (s,pwd+1))) 27.22 @@ -673,7 +678,9 @@ 27.23 fs_give ((void **) &s); 27.24 } 27.25 } 27.26 - else if (pw = pwuser (user)) {/* can get user? */ 27.27 + else 27.28 +#endif 27.29 + if (pw = pwuser (user)) {/* can get user? */ 27.30 s = cpystr (pw->pw_name); /* copy returned name in case we need it */ 27.31 if (*pwd && !(ret = checkpw (pw,pwd,argc,argv)) && 27.32 (*pwd == ' ') && pwd[1] && (ret = pwuser (s))) 27.33 @@ -697,6 +704,10 @@ 27.34 struct passwd *pw = NIL; 27.35 int level = LOG_NOTICE; 27.36 char *err = "failed"; 27.37 +#ifdef QMAIL 27.38 + char usr[MAILTMPLEN], *apoppswd; 27.39 + strncpy(usr, user, MAILTMPLEN-1); 27.40 +#endif 27.41 /* cretins still haven't given up */ 27.42 if ((strlen (user) >= NETMAXUSER) || 27.43 (authuser && (strlen (authuser) >= NETMAXUSER))) { 27.44 @@ -706,6 +717,16 @@ 27.45 } 27.46 else if (logtry-- <= 0) err = "excessive login failures"; 27.47 else if (disablePlaintext) err = "disabled"; 27.48 +#ifdef QMAIL 27.49 + else if ((logtry > 0) && 27.50 + (apoppswd = auth_md5_pwd(usr)) 27.51 + && !strcmp(apoppswd, pwd) 27.52 + && (pw = getpwnam(usr))) { 27.53 + memset(apoppswd, 0, strlen(apoppswd)); 27.54 + fs_give((void**) &apoppswd); 27.55 + return pw_login(pw, usr, pw->pw_name, pw->pw_dir, argc, argv); 27.56 + } 27.57 +#endif 27.58 else if (!(authuser && *authuser)) pw = valpwd (user,pwd,argc,argv); 27.59 else if (valpwd (authuser,pwd,argc,argv)) pw = pwuser (user); 27.60 if (pw && pw_login (pw,authuser,pw->pw_name,NIL,argc,argv)) return T; 27.61 @@ -728,6 +749,34 @@ 27.62 return pw_login (pwuser (user),authuser,user,NIL,argc,argv); 27.63 } 27.64 27.65 +void permitsmtp() /* to update tcp permission */ 27.66 +{ 27.67 +#ifdef POPBEFORESMTP 27.68 + #include <sys/types.h> 27.69 + #include <sys/wait.h> 27.70 + #ifndef POP3RECORDER 27.71 + # define POP3RECORDER "/usr/local/etc/pop3-record" 27.72 + #endif 27.73 + int child; 27.74 + int wstat; 27.75 + char *permsmtp = POP3RECORDER; 27.76 + 27.77 + switch(child = fork()) 27.78 + { 27.79 + case -1: 27.80 + syslog (LOG_INFO,"Cannot exec %s", permsmtp); 27.81 + _exit(111); 27.82 + break; 27.83 + case 0: 27.84 + execl(permsmtp, permsmtp, 0); 27.85 + syslog (LOG_INFO,"Cannot exec %s", permsmtp); 27.86 + _exit(111); break; 27.87 + } 27.88 + waitpid(child, &wstat, 0); 27.89 +#endif 27.90 +} 27.91 + 27.92 + 27.93 27.94 /* Log in as anonymous daemon 27.95 * Accepts: argument count 27.96 @@ -781,8 +830,14 @@ 27.97 else fatal ("Login failed after chroot"); 27.98 } 27.99 /* normal login */ 27.100 +#ifdef QMAIL 27.101 + else if (((pw->pw_uid == geteuid ()) || (permitsmtp(), loginpw (pw,argc,argv 27.102 +))) && 27.103 + (ret = env_init (user,home))) chdir (myhomedir ()); 27.104 +#else 27.105 else if (((pw->pw_uid == geteuid ()) || loginpw (pw,argc,argv)) && 27.106 - (ret = env_init (user,home))) chdir (myhomedir ()); 27.107 + (ret = env_init (user,home))) chdir (myhomedir ()); 27.108 +#endif 27.109 fs_give ((void **) &home); /* clean up */ 27.110 if (user) fs_give ((void **) &user); 27.111 }
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 28.2 +++ b/src/osdep/unix/maildir.c Mon Sep 14 19:23:11 2009 +0900 28.3 @@ -0,0 +1,1541 @@ 28.4 +/* 28.5 + * Maildir Module for PINE 4.0x - fourth release, use with CARE! 28.6 + * 28.7 + * Author: Mattias Larsson <ml@techno.org> 28.8 + * 28.9 + * Version: 21.07.98 28.10 + * 28.11 + * Please read the README.maildir file before using this module! 28.12 + * 28.13 + * If you have any questions, please e-mail ml@techno.org 28.14 + * 28.15 + * Multiple inboxes patch by Dean Gaudet <dgaudet@arctic.org> 28.16 + * 28.17 + * ================================================= 28.18 + * 28.19 + * Based on the IMAP2 maildir routines by: 28.20 + * 28.21 + * Author: Eric Green 28.22 + * Bloodhounds International Inc. 28.23 + * thrytis@imaxx.net 28.24 + * 28.25 + * Additional contributions from: 28.26 + * Aidas Kasparas (kaspar@soften.ktu.lt) 28.27 + * 28.28 + * Date: 27 April 1997 28.29 + * Last Edited: 13 June 1997 28.30 + * 28.31 + * Based (heavily) on mh.c and other c-client library files by Mark Crispin: 28.32 + * 28.33 + * Mark Crispin 28.34 + * Networks and Distributed Computing 28.35 + * Computing & Communications 28.36 + * University of Washington 28.37 + * Administration Building, AG-44 28.38 + * Seattle, WA 98195 28.39 + * Internet: MRC@CAC.Washington.EDU 28.40 + * 28.41 + * Copyright 1995 by the University of Washington 28.42 + * 28.43 + * Permission to use, copy, modify, and distribute this software and its 28.44 + * documentation for any purpose and without fee is hereby granted, provided 28.45 + * that the above copyright notice appears in all copies and that both the 28.46 + * above copyright notice and this permission notice appear in supporting 28.47 + * documentation, and that the name of the University of Washington not be 28.48 + * used in advertising or publicity pertaining to distribution of the software 28.49 + * without specific, written prior permission. This software is made 28.50 + * available "as is", and 28.51 + * THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, 28.52 + * WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED 28.53 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN 28.54 + * NO EVENT SHALL THE UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY SPECIAL, 28.55 + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 28.56 + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT 28.57 + * (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION 28.58 + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 28.59 + * 28.60 + */ 28.61 + 28.62 +/* CONFIGURABLE OPTIONS - PLEASE CHECK THESE OUT */ 28.63 + 28.64 +#define NO_MAILDIR_FIDDLE /* disallow Maildir with Maildir in the 28.65 + name. This is useful in an ISP setup 28.66 + using the IMAP daemon. #undef it if you 28.67 + are running a normal pine and know what 28.68 + you are doing */ 28.69 + 28.70 +/* #define NO_ABSOLUTE_PATHS /* if you define this, all paths 28.71 + use your HOMEDIR is the root instead 28.72 + of the actual root of the machine. This 28.73 + is also useful in an ISP setup with 28.74 + IMAP */ 28.75 + 28.76 +#undef NO_UID_VALIDITIY /* define this if you want the UID's not 28.77 + to be persistent over sessions. Use this 28.78 + if you use another client to read the 28.79 + maildir that screws up the special way 28.80 + in which we store UIDs. Do not enable 28.81 + unless you are sure you need it. */ 28.82 + 28.83 +/* END CONFIGURATION */ 28.84 + 28.85 +#define MTA_DEBUG /* debugging sent to stdout */ 28.86 +#undef MTA_DEBUG 28.87 + 28.88 +#include <stdio.h> 28.89 +#include <ctype.h> 28.90 +#include <errno.h> 28.91 +extern int errno; /* just in case */ 28.92 +#include "mail.h" 28.93 +#include "osdep.h" 28.94 +#include <pwd.h> 28.95 +#include <sys/stat.h> 28.96 +#include <sys/time.h> 28.97 +#include <sys/types.h> 28.98 +#include <dirent.h> 28.99 +#include <utime.h> 28.100 +#include "maildir.h" 28.101 +#include "misc.h" 28.102 +#include "dummy.h" 28.103 + 28.104 +/* Driver dispatch used by MAIL */ 28.105 + 28.106 +DRIVER maildirdriver = { 28.107 + "maildir", /* driver name */ 28.108 + /* driver flags */ 28.109 + DR_MAIL|DR_LOCAL|DR_NOFAST|DR_NAMESPACE, 28.110 + (DRIVER *) NIL, /* next driver */ 28.111 + maildir_valid, /* mailbox is valid for us */ 28.112 + maildir_parameters, /* manipulate parameters */ 28.113 + NIL, /* scan mailboxes */ 28.114 + maildir_list, /* find mailboxes */ 28.115 + maildir_lsub, /* find subscribed mailboxes */ 28.116 + maildir_sub, /* subscribe to mailbox */ 28.117 + maildir_unsub, /* unsubscribe from mailbox */ 28.118 + maildir_create, /* create mailbox */ 28.119 + maildir_delete, /* delete mailbox */ 28.120 + maildir_rename, /* rename mailbox */ 28.121 + NIL, /* status of mailbox */ 28.122 + maildir_open, /* open mailbox */ 28.123 + maildir_close, /* close mailbox */ 28.124 + maildir_fast, /* fetch message "fast" attributes */ 28.125 + NIL, /* fetch message flags */ 28.126 + NIL, /* fetch overview */ 28.127 + NIL, /* fetch message envelopes */ 28.128 + maildir_fetchheader, /* fetch message header */ 28.129 + maildir_fetchtext, /* fetch message body */ 28.130 + NIL, /* fetch partial message text */ 28.131 + NIL, /* unique identifier */ 28.132 + NIL, /* message number */ 28.133 + NIL, /* modify flags */ 28.134 + maildir_flagmsg, /* per-message modify flags */ 28.135 + NIL, /* search for message based on criteria */ 28.136 + NIL, /* sort messages */ 28.137 + NIL, /* thread messages */ 28.138 + maildir_ping, /* ping mailbox to see if still alive */ 28.139 + maildir_check, /* check for new messages */ 28.140 + maildir_expunge, /* expunge deleted messages */ 28.141 + maildir_copy, /* copy messages to another mailbox */ 28.142 + maildir_append, /* append string message to mailbox */ 28.143 + maildir_gc /* garbage collect stream */ 28.144 +}; 28.145 + 28.146 + /* prototype stream */ 28.147 +MAILSTREAM maildirproto = {&maildirdriver}; 28.148 + 28.149 +/* Check validity of mailbox 28.150 + */ 28.151 + 28.152 +DRIVER *maildir_valid (char *name) 28.153 +{ 28.154 + return maildir_isvalid(name,T) ? &maildirdriver : NIL; 28.155 +} 28.156 + 28.157 +int maildir_isvalid (char *name,long justname) 28.158 +{ 28.159 + char tmp[MAILTMPLEN]; 28.160 + struct stat sbuf; 28.161 + 28.162 + if (!name || (!*name) || 28.163 + ((*name == '#') && 28.164 + (*(name+1) == 0 || 28.165 + (*(name+1) != 'm' && *(name+1) != 'M') || 28.166 + (*(name+2) != 'd' && *(name+1) != 'D') || 28.167 + *(name+3) != '/')) || (*name == '.')) 28.168 + return NIL; 28.169 + 28.170 + /* okay, anything containing the name Maildir will be ignored 28.171 + this is to prevent anyone from fiddling with their incoming Maildir 28.172 + directly, it should be accessed via the INBOX alias */ 28.173 + 28.174 + #ifdef NO_MAILDIR_FIDDLE 28.175 + if (strstr(name, "Maildir")) { 28.176 + return NIL; 28.177 + } 28.178 + #endif 28.179 + /* If we are requested only to check 28.180 + if the name is appropriate then we 28.181 + have done! */ 28.182 + if (justname && *name == '#') return T; 28.183 + 28.184 + 28.185 + /* must be valid local mailbox */ 28.186 + if ((*name != '*') && (*name != '{') && 28.187 + maildir_file (tmp,name) && 28.188 + /* assume its maildir if its a dir */ 28.189 + stat (tmp,&sbuf) == 0 && S_ISDIR (sbuf.st_mode)) 28.190 + return T; 28.191 + 28.192 + /* INBOX is for default Maildir */ 28.193 + if (!strcmp (ucase (strncpy (tmp,name,MAILTMPLEN)), "INBOX") && 28.194 + (stat (maildir_file (tmp,name),&sbuf) == 0) && 28.195 + S_ISDIR (sbuf.st_mode)) 28.196 + return T; 28.197 + 28.198 + return NIL; 28.199 +} 28.200 +#ifdef QMAIL 28.201 +#ifndef QMAILCONTROL 28.202 +# define QMAILCONTROL "/var/qmail/control" 28.203 +#endif 28.204 +#ifndef DOTQMAIL 28.205 +# ifdef POSTFIX 28.206 +# define DOTQMAIL ".forward" 28.207 +# else 28.208 +# define DOTQMAIL ".qmail" 28.209 +# endif 28.210 +#endif 28.211 +#ifndef XADDR_DELIM 28.212 +# ifdef POSTFIX 28.213 +# define XADDR_DELIM "+" 28.214 +# else 28.215 +# define XADDR_DELIM "-" 28.216 +# endif 28.217 +#endif 28.218 + 28.219 +/* Convert virtual domain user 28.220 + */ 28.221 +char* conv_virtualdomain(char *account) { 28.222 + char *dom = strchr(account, '@'), *p; 28.223 + char vd[MAILTMPLEN+1], rewrite[MAILTMPLEN+1], previous[MAILTMPLEN+1]; 28.224 + FILE *vdfd; 28.225 + int match=0; 28.226 + snprintf(vd, MAILTMPLEN, "%s/%s", QMAILCONTROL, "virtualdomains"); 28.227 + if (NIL == dom) return account; 28.228 + dom++; /* set position of domain part beginning */ 28.229 + if (dom && NIL != (vdfd = fopen (vd, "r"))) { 28.230 + char buf[MAILTMPLEN+1], *s; 28.231 + int l = strlen(dom); 28.232 + int L = strlen(account); 28.233 + while ((s=fgets(buf, MAILTMPLEN, vdfd))) { 28.234 + if (p=strchr(s, '#')) 28.235 + *p = '\0'; /* zap comments */ 28.236 + if (!strchr(buf, ':')) 28.237 + continue; 28.238 + while (s && (strrchr(s, '\n') || strrchr(s, '\r') || strrchr(s, ' '))) 28.239 + s[strlen(s)-1] = '\0'; 28.240 + if (!strncmp(account, s, L) && s[L] == ':' && s[L+1]) { /* user matches */ 28.241 + match = 3; 28.242 + snprintf(rewrite, MAILTMPLEN, "%s%s%s", s+L+1, XADDR_DELIM, account); 28.243 + break; 28.244 + } 28.245 + if (!strncmp(dom, s, l) && s[l] == ':' && s[l+1]) { /* domain matches */ 28.246 + match = 2; 28.247 + snprintf(rewrite, MAILTMPLEN, "%s%s%s", s+l+1, XADDR_DELIM, account); 28.248 + continue; 28.249 + } 28.250 + if (match < 2 && s[0] == '.') { /* if domain described in wildcard */ 28.251 + if (p=strchr(s, ':')) { 28.252 + *p = '\0'; 28.253 + if (!strcmp(dom+(strlen(dom)-strlen(s)), s)) { 28.254 + if (match == 0 28.255 + || strlen(previous) < strlen(s)) { 28.256 + match = 1; 28.257 + strncpy(previous, s, MAILTMPLEN); 28.258 + snprintf(rewrite, MAILTMPLEN, "%s%s%s", p+1, XADDR_DELIM, account); 28.259 + } 28.260 + } 28.261 + } 28.262 + } 28.263 + } 28.264 + fclose(vdfd); 28.265 + if (match) { 28.266 + p = strchr(rewrite, '@'); 28.267 + /* fprintf(stderr, "m=%d, rwr=[%s]\n", match, rewrite); */ 28.268 + if (p) { 28.269 + *p = '\0'; 28.270 + } 28.271 + /* fprintf(stderr, "rwr=[%s]\n", rewrite); */ 28.272 + s = cpystr(rewrite); 28.273 + memset(vd, 0, sizeof(vd)); 28.274 + memset(rewrite, 0, sizeof(rewrite)); 28.275 + memset(previous, 0, sizeof(previous)); 28.276 + return s; 28.277 + } 28.278 + } 28.279 + return account; /* return itself */ 28.280 +} 28.281 +/* ------------------------------------------------- 28.282 + Qmail virtual domain hack ends 28.283 + ------------------------------------------------- */ 28.284 +#endif 28.285 + 28.286 +char *maildir_getmaildir() { 28.287 + static char dir[MAILTMPLEN]; 28.288 + extern char *mymailsuffix(); 28.289 + static char qfile[MAILTMPLEN]; 28.290 + FILE *qmail; 28.291 + dir[0] = '\0'; 28.292 + snprintf(qfile, MAILTMPLEN, "%s/%s", myhomedir(), DOTQMAIL); 28.293 + strncat(qfile, mymailsuffix(), MAILTMPLEN); 28.294 + qmail = fopen(qfile, "r"); 28.295 + if (NULL != qmail) { /* if ~/.qmail file exists */ 28.296 + char buf[MAILTMPLEN], *s; 28.297 + while ((s=fgets(buf, MAILTMPLEN, qmail))) { 28.298 + /* Skip preceding spaces and trailing newlines */ 28.299 + while (*s && (*s == ' ' || *s == '\t')) {s++;} 28.300 + while (*s && (s[strlen(s)-1] == '\r' || s[strlen(s)-1] == '\n')) { 28.301 + s[strlen(s)-1] = '\0'; 28.302 + } 28.303 + if (*s == '#') continue; 28.304 + if (s[strlen(s)-1] != '/') continue; /* Skip non maildir format */ 28.305 + if (*s == '~' && *(s+1) == '/') 28.306 + *s = '.'; /* Convert `~/' to `./' (for Postfix) */ 28.307 + strncpy(dir, s, MAILTMPLEN); 28.308 + break; 28.309 + } 28.310 + fclose(qmail); 28.311 + } 28.312 +#ifdef DEFAULTMAILDIR 28.313 + else { 28.314 + strncpy(dir, DEFAULTMAILDIR, MAILTMPLEN); 28.315 + } 28.316 +#endif 28.317 + if (dir[0]) { 28.318 + return dir; 28.319 + } else { 28.320 +#ifdef DEFAULTMAILDIR 28.321 + snprintf(dir, MAILTMPLEN, "%s/%s/", myhomedir(), DEFAULTMAILDIR); 28.322 +#else 28.323 + snprintf(dir, MAILTMPLEN, "%s/%s/", myhomedir(), MAILDIRPATH); 28.324 +#endif 28.325 + return dir; 28.326 + } 28.327 +} 28.328 + 28.329 +/* Maildir mail generate file string 28.330 + */ 28.331 + 28.332 +char *maildir_file (char *dst,char *name) 28.333 +{ 28.334 + char tmp[MAILTMPLEN]; 28.335 + 28.336 + if (strlen (name) > 3 && /* safe do other comparisons */ 28.337 + (*name == '#') && 28.338 + (name[1] == 'm' || name[1] == 'M') && 28.339 + (name[2] == 'd' || name[2] == 'D') && 28.340 + (name[3] == '/')) 28.341 + name += 4; 28.342 + 28.343 +#ifdef NO_ABSOLUTE_PATHS 28.344 + if (*name == '/') { 28.345 + /* we do not want to accept / absolute paths, so lets strip the first 28.346 + / ... */ 28.347 + snprintf(dst, MAILTMPLEN, "%s/%s/cur", myhomedir(), name+1); 28.348 + 28.349 +/* strncpy (dst, name, MAILTMPLEN - 2); 28.350 + strncat (dst, "/cur", MAILTMPLEN - 2); 28.351 + dst[MAILTMPLEN - 1] = '\0'; */ 28.352 + } 28.353 + else 28.354 + snprintf (dst, MAILTMPLEN, "%s/%s/cur",myhomedir (), 28.355 + strcmp (ucase (strcnpy (tmp, name, MAILTMPLEN)), "INBOX") ? name : maildir_getmaildir()); 28.356 +#else 28.357 + if (*name == '/') { 28.358 + strncpy (dst, name, MAILTMPLEN - 2); 28.359 + strncat (dst, "/cur", MAILTMPLEN - 2); 28.360 + dst[MAILTMPLEN - 1] = '\0'; 28.361 + } 28.362 + else { 28.363 + char *maildir = maildir_getmaildir(); 28.364 + if (*maildir == '/') { 28.365 + snprintf (dst,MAILTMPLEN,"%scur",maildir); 28.366 + } else { 28.367 + snprintf (dst,MAILTMPLEN,"%s/%s/cur",myhomedir (), 28.368 + strcmp (ucase (strncpy (tmp, name, MAILTMPLEN)), "INBOX") ? name : maildir); 28.369 + } 28.370 + } 28.371 + 28.372 +#endif 28.373 + 28.374 + #ifdef MTA_DEBUG 28.375 + printf("maildir_file '%s'\n", dst); 28.376 + #endif 28.377 + return dst; 28.378 +} 28.379 + 28.380 +/* Maildir open 28.381 + */ 28.382 + 28.383 +MAILSTREAM *maildir_open (MAILSTREAM *stream) 28.384 +{ 28.385 + char tmp[MAILTMPLEN],tmp2[MAILTMPLEN]; 28.386 + 28.387 + if (!stream) return &maildirproto; 28.388 + if (LOCAL) { /* recycle stream */ 28.389 + maildir_close (stream, 0); 28.390 + stream->dtb = &maildirdriver; 28.391 + mail_free_cache (stream); 28.392 + stream->uid_last = 0; /* default UID validity */ 28.393 + stream->uid_validity = time (0); 28.394 + } 28.395 + 28.396 + stream->uid_validity = 0; /* was time(0) */ 28.397 + 28.398 + if (stream->uid_last < time(0)) 28.399 + stream->uid_last = time (0); 28.400 + 28.401 + stream->local = fs_get (sizeof (MAILDIRLOCAL)); 28.402 + LOCAL->inbox = !strcmp (ucase (strncpy (tmp,stream->mailbox,MAILTMPLEN)),"INBOX") || 28.403 + !strcmp (stream->mailbox,maildir_file (tmp2,"INBOX")); 28.404 + LOCAL->dir = cpystr (maildir_file (tmp,stream->mailbox)); /* copy dir name */ 28.405 + /* make temporary buffer */ 28.406 + LOCAL->buf = (char *) fs_get ((LOCAL->buflen = CHUNKSIZE-1) + 1); 28.407 + LOCAL->scantime = 0; /* not scanned yet */ 28.408 + stream->sequence++; 28.409 + stream->nmsgs = stream->recent = 0; 28.410 + 28.411 + maildir_ping_core (stream); 28.412 + maildir_ping (stream); 28.413 +/* if (maildir_ping (stream) && !(stream->nmsgs || stream->silent)) 28.414 + printf("Mailbox is empty\n"); 28.415 +*/ 28.416 + return stream; 28.417 + 28.418 +} 28.419 + 28.420 +/* Maildir ping mailbox 28.421 + */ 28.422 + 28.423 +long maildir_ping_core (MAILSTREAM *stream) 28.424 +{ 28.425 + char tmp[MAILTMPLEN]; 28.426 + MESSAGECACHE *elt; 28.427 + struct stat sbuf, sbuf2; 28.428 + DIR *dir; 28.429 + struct direct *d; 28.430 + int reloadall = NIL; 28.431 + int uidinvalid = NIL; 28.432 + unsigned long old; 28.433 + long i; 28.434 + long nmsgs = stream->nmsgs; 28.435 + long recent = stream->recent; 28.436 + long nfiles = stream->nmsgs; 28.437 + int silent = stream->silent; 28.438 + char *s, *s2; 28.439 + mailcache_t mc = (mailcache_t) mail_parameters (NIL,GET_CACHE,NIL); 28.440 + 28.441 +/* maildir_copynew (LOCAL->dir); 28.442 + */ 28.443 + 28.444 + if (stat (LOCAL->dir,&sbuf) < 0) { 28.445 + snprintf (tmp,MAILTMPLEN,"Unable to open maildir: %s",strerror (errno)); 28.446 + mm_log (tmp,ERROR); 28.447 + return NIL; 28.448 + } 28.449 + 28.450 + /* okay, lets try to figure out the Maildir UID validity. This is done 28.451 + by checking the last modification time of the file .uidvalidity 28.452 + in the rootdir of the Maildir. Any program reordering the files 28.453 + in the directory have to touch this file */ 28.454 + 28.455 + snprintf(tmp, MAILTMPLEN, "%s/../.uidvalidity", LOCAL->dir); 28.456 + 28.457 + if (stat (tmp,&sbuf2) < 0) { 28.458 + /* no uid validity file found, if uid_validity == 0, we have 28.459 + to set it to something other than 0, and then create the 28.460 + .uidvalidity file for future accesses */ 28.461 + 28.462 + if (stream->uid_validity == 0) { 28.463 + FILE *fl; 28.464 + struct utimbuf tbuf; 28.465 + 28.466 + stream->uid_validity = time(0); 28.467 + tbuf.actime = stream->uid_validity; 28.468 + tbuf.modtime = stream->uid_validity; 28.469 + 28.470 + if ((fl = fopen(tmp, "w"))) { 28.471 + fclose(fl); 28.472 + chmod (tmp, S_IRUSR|S_IWUSR); 28.473 + utime(tmp, &tbuf); 28.474 + } 28.475 + } 28.476 + uidinvalid = T; /* UID's are invalid, update them */ 28.477 + } else { 28.478 + /* valid file, lets set UID if uid_validity = 0 */ 28.479 + if (stream->uid_validity == 0) { 28.480 + stream->uid_validity = sbuf2.st_mtime; 28.481 + } 28.482 + } 28.483 + 28.484 + #ifdef NO_UID_VALIDITY 28.485 + uidinvalid = T; /* force the UIDs to be invalid and reset every time, 28.486 + useful in an environment without imap servers and 28.487 + clients that screw up the UIDs.. i'd leave it to 28.488 + OFF until I really need it though... */ 28.489 + #endif 28.490 + 28.491 + stream->silent = T; 28.492 + if (sbuf.st_ctime != LOCAL->scantime) { 28.493 + /* update the message list */ 28.494 + /* int maildir_namesort(const void *,const void *); 28.495 + int (*mn)(struct direct **, struct direct **) = maildir_namesort; */ 28.496 + struct direct **names = NIL; 28.497 + nfiles = scandir (LOCAL->dir,&names,maildir_select,maildir_namesort); 28.498 + 28.499 + for (i = 0; i < nfiles; i++) { 28.500 + 28.501 + /* check if file has executable bit set */ 28.502 + snprintf(tmp, MAILTMPLEN, "%s/%s", LOCAL->dir, names[i]->d_name); 28.503 + stat (tmp,&sbuf2); 28.504 + if (sbuf2.st_mode & S_IXUSR) { 28.505 + /* executable bit set, modtime is uid */ 28.506 + if (sbuf2.st_mtime > stream->uid_last) 28.507 + stream->uid_last = sbuf2.st_mtime+1; 28.508 + } 28.509 + /* this is kept for backwards compatibility */ 28.510 + if ((s = strstr (names[i]->d_name,":3,"))) 28.511 + s += 3; 28.512 + if (s && (s2 = strstr (s, ",U"))) { 28.513 + s2 += 2; 28.514 + sscanf(s2, "%d", &old); 28.515 + if (old > stream->uid_last) { 28.516 + stream->uid_last = old+1; 28.517 + } 28.518 + } 28.519 + 28.520 + } 28.521 + 28.522 + mm_critical (stream); /* go critical */ 28.523 + old = stream->uid_last; 28.524 + LOCAL->scantime = sbuf.st_ctime; 28.525 + 28.526 + /* check if old files same */ 28.527 + for (i = 0; i < stream->nmsgs; i++) { 28.528 + 28.529 + if (strcmp ((char *) mail_elt (stream, i + 1)->maildirp, 28.530 + names[i]->d_name)) { 28.531 + reloadall = T; 28.532 + break; 28.533 + } 28.534 + } 28.535 + 28.536 + if (reloadall) { /* files are out of order, rebuild cache */ 28.537 + 28.538 + i = 1; 28.539 + while (i <= stream->nmsgs) 28.540 + /* clean out cache */ 28.541 + if ((elt = (MESSAGECACHE *) (*mc) (stream,i,CH_ELT))) { 28.542 + fs_give ((void **) &elt->maildirp); 28.543 + mail_expunged (stream,i); 28.544 + } 28.545 + else 28.546 + i++; 28.547 + 28.548 + mm_log ("Warning: Mailbox has changed in an unexpected way. Reloading.", 28.549 + WARN); 28.550 + stream->nmsgs = 0; 28.551 + } 28.552 + nmsgs = stream->nmsgs; 28.553 + 28.554 + stream->nmsgs = nfiles; /* hm? */ 28.555 + 28.556 + for (i = nmsgs; i < nfiles; i++) { 28.557 + 28.558 + mail_exists(stream, i+1); 28.559 + /* if newly seen, add to list */ 28.560 + (elt = mail_elt (stream, i + 1))->maildirp = (long) cpystr (names[i]->d_name); 28.561 + elt->valid = T; 28.562 + 28.563 + /* grab the flags */ 28.564 + if ((s = strstr (names[i]->d_name,":3,"))) { 28.565 + s += 3; 28.566 + if (strchr (s,'F')) 28.567 + elt->flagged = T; 28.568 + if (strchr (s,'R')) 28.569 + elt->answered = T; 28.570 + if (strchr (s,'S')) 28.571 + elt->seen = T; 28.572 + if (strchr (s,'T')) 28.573 + elt->deleted = T; 28.574 + } else if ((s = strstr (names[i]->d_name,":2,"))) { 28.575 + /* this is the :2, id where all files go nowadays */ 28.576 + s += 3; 28.577 + if (strchr (s,'F')) 28.578 + elt->flagged = T; 28.579 + if (strchr (s,'R')) 28.580 + elt->answered = T; 28.581 + if (strchr (s,'S')) 28.582 + elt->seen = T; 28.583 + if (strchr (s,'T')) 28.584 + elt->deleted = T; 28.585 + snprintf(tmp, MAILTMPLEN, "%s/%s", LOCAL->dir, names[i]->d_name); 28.586 + stat (tmp,&sbuf2); 28.587 + if (sbuf2.st_mode & S_IXUSR) { 28.588 + /* executable bit set, modtime is uid */ 28.589 + elt->private.uid = sbuf2.st_mtime; 28.590 + } 28.591 + /* and if we could not retrieve UID from modtime, or if 28.592 + UIDs are invalid, go here */ 28.593 + if (elt->private.uid == 0 || uidinvalid) { 28.594 + stream->uid_last = (elt = mail_elt (stream,i+1))->private.uid = stream->uid_last+1; 28.595 + maildir_flagmsg(stream, elt); 28.596 + } 28.597 + s = 0; /* make sure next if statement does not trigger */ 28.598 + } 28.599 + 28.600 + if (s) 28.601 + if ((s2 = strstr (s, ",U"))) { 28.602 + s2 += 2; 28.603 + sscanf(s2, "%d", &elt->private.uid); 28.604 + if (elt->private.uid == 0 || uidinvalid) { 28.605 + stream->uid_last = (elt = mail_elt (stream,i+1))->private.uid = stream->uid_last+1; 28.606 + maildir_flagmsg(stream, elt); 28.607 + } 28.608 + 28.609 + } else { /* assign new UID */ 28.610 + stream->uid_last = (elt = mail_elt (stream,i+1))->private.uid = stream->uid_last+1; 28.611 + elt->recent = T; 28.612 + recent++; 28.613 + maildir_flagmsg(stream, elt); /* store the UID that we assigned to it */ 28.614 + } 28.615 + 28.616 + 28.617 + 28.618 + } 28.619 + 28.620 + mm_nocritical (stream); /* release critical */ 28.621 + /* free the names stuff */ 28.622 + for (i = 0; i < nfiles; i++) 28.623 + fs_give ((void **) &names[i]); 28.624 + if (names) 28.625 + fs_give ((void **) &names); 28.626 + } 28.627 + stream->silent = silent; 28.628 + mail_exists(stream,nfiles); 28.629 +/* if (!reloadall) */ 28.630 + mail_recent (stream,recent); 28.631 + 28.632 + return T; /* return that we are alive */ 28.633 +} 28.634 + 28.635 +long maildir_ping (MAILSTREAM *stream) 28.636 +{ 28.637 + maildir_copynew (LOCAL->dir); 28.638 + return maildir_ping_core (stream); 28.639 +} 28.640 + 28.641 +void maildir_copynew (const char *mailbox) 28.642 +{ 28.643 + char tmp[MAILTMPLEN],file[MAILTMPLEN],newfile[MAILTMPLEN]; 28.644 + DIR *dir; 28.645 + struct dirent *d; 28.646 + struct stat sbuf; 28.647 + 28.648 + snprintf (tmp,MAILTMPLEN,"%s/../new",mailbox); 28.649 + if (!(dir = opendir (tmp))) 28.650 + return; 28.651 + 28.652 + while (d = readdir (dir)) { 28.653 + if (d->d_name[0] == '.') 28.654 + continue; /* skip .files */ 28.655 + 28.656 + snprintf (file,MAILTMPLEN,"%s/%s",tmp,d->d_name); 28.657 + /* make sure this is a normal file */ 28.658 + if (stat (file,&sbuf) == 0 && S_ISREG (sbuf.st_mode)) { 28.659 + 28.660 + if (strstr (d->d_name,":3,")) /* this message already has flags */ 28.661 + snprintf (newfile,MAILTMPLEN,"%s/%s",mailbox,d->d_name); 28.662 + else 28.663 + snprintf (newfile,MAILTMPLEN,"%s/%s:3,",mailbox,d->d_name); 28.664 + 28.665 + /* move the new mail to the cur dir */ 28.666 + if (link (file,newfile) == -1) 28.667 + mm_log("Unable to read new mail!",WARN); 28.668 + else 28.669 + unlink (file); 28.670 + } 28.671 + } 28.672 + closedir (dir); 28.673 +} 28.674 + 28.675 +int maildir_select (struct direct *name) 28.676 +{ 28.677 + if (name->d_name[0] != '.') 28.678 + return T; 28.679 + 28.680 + return NIL; 28.681 +} 28.682 + 28.683 +/* int maildir_namesort (struct direct **d1,struct direct **d2) */ 28.684 +int maildir_namesort (const void *d1, const void *d2) 28.685 +{ 28.686 + return strcmp ((*(struct direct **)d1)->d_name, 28.687 + (*(struct direct **)d2)->d_name); 28.688 +} 28.689 + 28.690 + 28.691 +/* Maildir garbage collect stream 28.692 + */ 28.693 + 28.694 +void maildir_gc (MAILSTREAM *stream,long gcflags) 28.695 +{ 28.696 + unsigned long i; 28.697 + 28.698 + if (gcflags & GC_TEXTS) { /* garbage collect texts? */ 28.699 + /* flush texts from cache */ 28.700 +/* if (LOCAL->hdr) fs_give ((void **) &LOCAL->hdr); 28.701 +// if (stream->text) fs_give ((void **) &stream->text); 28.702 +// stream->msgno = 0; invalidate stream text 28.703 +*/ 28.704 + } 28.705 +} 28.706 + 28.707 +/* Maildir close 28.708 + */ 28.709 + 28.710 +void maildir_close (MAILSTREAM *stream, long options) 28.711 +{ 28.712 + MESSAGECACHE *elt; 28.713 + int i; 28.714 + mailcache_t mc = (mailcache_t) mail_parameters (NIL,GET_CACHE,NIL); 28.715 + 28.716 +/* CL_EXPUNGE OPTION SUPPORT HERE SOMEWHERE! */ 28.717 + /* clean out the cached paths */ 28.718 + for (i = 1; i <= stream->nmsgs; i++) 28.719 + if ((elt = (MESSAGECACHE *) (*mc) (stream,i,CH_ELT)) && elt->maildirp) { 28.720 + fs_give ((void **) &elt->maildirp); 28.721 + elt->maildirp = 0; /* otherwise pine coredumps */ 28.722 + } 28.723 + 28.724 + if (LOCAL) { /* only if a stream is open */ 28.725 + if (LOCAL->dir) fs_give ((void **) &LOCAL->dir); 28.726 + maildir_gc (stream,GC_TEXTS); /* free local cache */ 28.727 + /* free local scratch buffer */ 28.728 + if (LOCAL->buf) fs_give ((void **) &LOCAL->buf); 28.729 + /* nuke the local data */ 28.730 + fs_give ((void **) &stream->local); 28.731 + stream->dtb = NIL; /* log out the DTB */ 28.732 + } 28.733 +} 28.734 + 28.735 +void maildir_check (MAILSTREAM *stream) 28.736 +{ 28.737 + /* Perhaps in the future this will preserve flags */ 28.738 + if (maildir_ping (stream)) mm_log ("Check completed",(long) NIL); 28.739 +} 28.740 + 28.741 +long maildir_fetchtext (MAILSTREAM *stream,unsigned long msgno,STRING *bs, long flags) 28.742 +{ 28.743 + unsigned long i; 28.744 + MESSAGECACHE *elt; 28.745 + /* UID call "impossible" */ 28.746 + if (flags & FT_UID) return NIL; 28.747 + elt = mail_elt (stream,msgno);/* get elt */ 28.748 + /* snarf message if don't have it yet */ 28.749 + if (!elt->private.msg.text.text.data) { 28.750 + maildir_fetchheader (stream,msgno,&i,flags); 28.751 + if (!elt->private.msg.text.text.data) return NIL; 28.752 + } 28.753 + if (!(flags & FT_PEEK)) { /* mark as seen */ 28.754 + mail_elt (stream,msgno)->seen = T; 28.755 + maildir_flagmsg (stream, mail_elt(stream,msgno)); 28.756 + mm_flags (stream,msgno); 28.757 + } 28.758 + if (!elt->private.msg.text.text.data) return NIL; 28.759 + INIT (bs,mail_string,elt->private.msg.text.text.data, 28.760 + elt->private.msg.text.text.size); 28.761 + return T; 28.762 +} 28.763 + 28.764 + 28.765 +/* Maildir fetch message header 28.766 + */ 28.767 + 28.768 +char *maildir_fetchheader (MAILSTREAM *stream,unsigned long msgno, 28.769 + unsigned long *length, long flags) 28.770 +{ 28.771 + unsigned long i,hdrsize; 28.772 + int fd; 28.773 + char *t; 28.774 + char tmp[MAILTMPLEN]; 28.775 + char *s,*b; 28.776 + struct stat sbuf; 28.777 + struct tm *tm; 28.778 + MESSAGECACHE *elt; 28.779 + *length = 0; /* default to empty */ 28.780 + if (flags & FT_UID) return "";/* UID call "impossible" */ 28.781 + elt = mail_elt (stream,msgno);/* get elt */ 28.782 + if (!elt->private.msg.header.text.data) { 28.783 + 28.784 +/* maildir_gc (stream,GC_TEXTS); invalidate current cache */ 28.785 + /* build message file name */ 28.786 + snprintf (tmp,MAILTMPLEN,"%s/%s",LOCAL->dir,(char *) elt->maildirp); 28.787 + if ((fd = open (tmp,O_RDONLY,NIL)) >= 0) { 28.788 + fstat (fd,&sbuf); /* get size of message */ 28.789 + /* make plausible IMAPish date string */ 28.790 + tm = gmtime (&sbuf.st_mtime); 28.791 + elt->day = tm->tm_mday; elt->month = tm->tm_mon + 1; 28.792 + elt->year = tm->tm_year + 1900 - BASEYEAR; 28.793 + elt->hours = tm->tm_hour; elt->minutes = tm->tm_min; 28.794 + elt->seconds = tm->tm_sec; 28.795 + elt->zhours = 0; elt->zminutes = 0; 28.796 + /* slurp message */ 28.797 + read (fd,s = (char *) fs_get (sbuf.st_size + 1),sbuf.st_size); 28.798 + s[sbuf.st_size] = '\0'; /* tie off file */ 28.799 + close (fd); /* close file */ 28.800 + 28.801 + for (i = 0,b = s; *b && !(i && (*b == '\n')); i = (*b++ == '\n')); 28.802 + hdrsize = (*b ? ++b:b)-s; /* number of header bytes */ 28.803 + 28.804 + elt->rfc822_size = /* size of entire message in CRLF form */ 28.805 + (elt->private.msg.header.text.size = 28.806 + strcrlfcpy ((char **) &elt->private.msg.header.text.data,&i,s, 28.807 + hdrsize)) + 28.808 + (elt->private.msg.text.text.size = 28.809 + strcrlfcpy ((char **) &elt->private.msg.text.text.data,&i,b, 28.810 + sbuf.st_size - hdrsize)); 28.811 + fs_give ((void **) &s); 28.812 + } else return ""; 28.813 + 28.814 + } 28.815 + 28.816 + *length = elt->private.msg.header.text.size; 28.817 + return (char *) elt->private.msg.header.text.data; 28.818 +} 28.819 + 28.820 +void maildir_fast (MAILSTREAM *stream,char *sequence,long flags) 28.821 +{ 28.822 + unsigned long i,j; 28.823 + /* ugly and slow */ 28.824 + if (stream && LOCAL && ((flags & FT_UID) ? 28.825 + mail_uid_sequence (stream,sequence) : 28.826 + mail_sequence (stream,sequence))) 28.827 + for (i = 1; i <= stream->nmsgs; i++) 28.828 + if (mail_elt (stream,i)->sequence) maildir_fetchheader (stream,i,&j,NIL); 28.829 +} 28.830 + 28.831 +/* Maildir find list of subscribed mailboxes 28.832 + * Accepts: mail stream 28.833 + * pattern to search 28.834 + */ 28.835 + 28.836 +void maildir_list (MAILSTREAM *stream,char *ref, char *pat) 28.837 +{ 28.838 + DIR *dp; 28.839 + struct direct *d; 28.840 + struct stat sbuf; 28.841 + char *s,*s2,*cp,*np,curdir[MAILTMPLEN],name[MAILTMPLEN],subdir[MAILTMPLEN],rname[MAILTMPLEN]; 28.842 + 28.843 + strncpy(subdir, pat, MAILTMPLEN); 28.844 + 28.845 + s = subdir; 28.846 + s2 = 0; 28.847 + while ((s = strstr(s, "/"))) { 28.848 + s2 = s; 28.849 + s++; 28.850 + } 28.851 + 28.852 + if (s2) { /* pointer to last / */ 28.853 + *s2 = '\0'; /* snip off string */ 28.854 + s2++; 28.855 + /*syslog(LOG_INFO, "dir: '%s' pat: '%s'", subdir, s2);*/ 28.856 + snprintf(name, MAILTMPLEN, "%s/%s", myhomedir(), subdir); 28.857 + } else { 28.858 + s2 = pat; 28.859 + snprintf(name, MAILTMPLEN, "%s", myhomedir()); 28.860 + strcpy(subdir, ""); 28.861 + } 28.862 + 28.863 + maildir_listwork(name, stream, s2, subdir, 1); 28.864 + 28.865 + if (pmatch ("INBOX", pat)) 28.866 + mm_list (stream,NIL,"INBOX",LATT_NOINFERIORS); 28.867 + 28.868 +} 28.869 + 28.870 +void maildir_listwork(char *name1, MAILSTREAM *stream, char *s2, char *subdir, int flag) 28.871 +{ 28.872 + DIR *dp; 28.873 + struct direct *d; 28.874 + struct stat sbuf; 28.875 + char *s,*cp,*np,curdir[MAILTMPLEN],rname[MAILTMPLEN],name[MAILTMPLEN]; 28.876 + char tmpdir[MAILTMPLEN]; 28.877 + 28.878 + strncpy(name, name1, MAILTMPLEN); 28.879 + 28.880 + /*syslog(LOG_INFO, "opendir: '%s'", name); 28.881 + //syslog(LOG_INFO, "subdir: '%s'", subdir); 28.882 + */ 28.883 + if (dp = opendir (name)) { /* open directory */ 28.884 + while (d = readdir (dp)) /* scan directory, ignore all . names */ 28.885 + if (d->d_name[0] != '.' && 28.886 + strcmp(d->d_name, "Maildir")) {/* build file name */ 28.887 + /* we do not want to list Maildir to customers, because 28.888 + that might give them weird ideas :) */ 28.889 + 28.890 + if (subdir[0] != '\0' && subdir[0] != '%' && subdir[0] != '*') 28.891 + snprintf(name, MAILTMPLEN, "%s/%s", subdir, d->d_name); 28.892 + else 28.893 + snprintf(name, MAILTMPLEN, "%s", d->d_name); 28.894 + /*syslog(LOG_INFO, "ls: '%s'", name);*/ 28.895 + 28.896 + /* this matching might not be correctly implemented */ 28.897 + if (maildir_file(curdir, name) && 28.898 + stat (curdir,&sbuf) == 0 && S_ISDIR (sbuf.st_mode)) { 28.899 + /*syslog(LOG_INFO, "here for some stange reason");*/ 28.900 + if (pmatch(d->d_name, s2)) { 28.901 + mm_list (stream,'/',name,NIL); 28.902 + /* call function recursive if last char % */ 28.903 + /*syslog(LOG_INFO, "s2: '%s'",s2);*/ 28.904 + if (s2[strlen(s2)-1] == '%' 28.905 + || s2[strlen(s2)-1] == '*') { 28.906 + snprintf(rname, MAILTMPLEN, "%s/%s", name1, name); 28.907 + /*syslog(LOG_INFO, "rname: '%s'", rname);*/ 28.908 + maildir_listwork(rname, stream, "%", name, 1); 28.909 + } 28.910 + } 28.911 + } else 28.912 + if (strlen(curdir) > 4 && pmatch(d->d_name, s2)) { 28.913 + int fnlen = strlen (curdir); 28.914 + curdir[fnlen - 4] = '\0'; 28.915 + /*syslog(LOG_INFO, "fname: '%s'", curdir);*/ 28.916 + if (stat (curdir,&sbuf) == 0 && S_ISDIR (sbuf.st_mode)) { 28.917 + /* okay, do not list with NoSelect, since Netscape 28.918 + does not f*cking honor this flag.. stupid netscape */ 28.919 + /*mm_list (stream,'/',name,LATT_NOSELECT);*/ 28.920 + 28.921 + /* call function recursive if last char % */ 28.922 + /*syslog(LOG_INFO, "s2: '%s'",s2);*/ 28.923 + if (s2[strlen(s2)-1] == '%' 28.924 + || s2[strlen(s2)-1] == '*') { 28.925 + snprintf(rname, MAILTMPLEN, "%s/%s", name1, name); 28.926 + /*syslog(LOG_INFO, "rname: '%s'", rname);*/ 28.927 + maildir_listwork(rname, stream, "%", name, 1); 28.928 + } 28.929 + 28.930 + } 28.931 + } 28.932 + 28.933 + } 28.934 + closedir (dp); /* all done, flush directory */ 28.935 + } 28.936 + 28.937 +} 28.938 + 28.939 + 28.940 + 28.941 + 28.942 + 28.943 +void *maildir_parameters (long function,void *value) 28.944 +{ 28.945 + return NIL; 28.946 +} 28.947 + 28.948 +long maildir_create (MAILSTREAM *stream,char *mailbox) 28.949 +{ 28.950 + char tmp[MAILTMPLEN]; 28.951 + char err[MAILTMPLEN]; 28.952 + char *s, *s2; 28.953 + int fnlen, i; 28.954 + char *subdir_names[] = {"/cur","/new","/tmp",NULL}; 28.955 + 28.956 + /* must not already exist */ 28.957 + if (access (maildir_file (tmp,mailbox),F_OK) == 0) { 28.958 + snprintf (err,MAILTMPLEN,"Can't create mailbox %s: mailbox already exists",mailbox); 28.959 + mm_log (err,ERROR); 28.960 + return NIL; 28.961 + } 28.962 + 28.963 + maildir_file (tmp,mailbox); /* get file name */ 28.964 + fnlen = strlen (tmp); 28.965 + /*syslog(LOG_INFO, "fname: '%s'", tmp);*/ 28.966 + tmp[fnlen - 4] = '\0'; /* making main directory's name */ 28.967 + fnlen -= 4; 28.968 + 28.969 + /* okay, try to add support for adding hiearchys of directories, this 28.970 + is done by scanning for /'s.... */ 28.971 + 28.972 + /*syslog(LOG_INFO, "tmp '%s'", tmp);*/ 28.973 + s = tmp; 28.974 + 28.975 + while ((s = strstr(s, "/")) != 0) { 28.976 + /*syslog(LOG_INFO, "Before make: '%s'", s);*/ 28.977 + *s = '\0'; 28.978 + /*syslog(LOG_INFO, "Trying to make: '%s'", tmp);*/ 28.979 + if (mkdir (tmp,0700) && *s != '\0') /* trying to make the dir */ 28.980 + if (errno != EEXIST) { 28.981 + snprintf (err,MAILTMPLEN,"Can't create mailbox %s: %s %s", 28.982 + mailbox,tmp,strerror (errno)); 28.983 + mm_log (err,ERROR); 28.984 + return NIL; 28.985 + } 28.986 + *s = '/'; 28.987 + s++; 28.988 + } 28.989 + 28.990 + if (mkdir (tmp,0700)) { /* try to make new dir */ 28.991 + snprintf (err,MAILTMPLEN,"Can't create mailbox %s: %s %s", 28.992 + mailbox,tmp,strerror (errno)); 28.993 + mm_log (err,ERROR); 28.994 + return NIL; 28.995 + } 28.996 + 28.997 + /*syslog(LOG_INFO, "create maildir");*/ 28.998 + for (i = 0; subdir_names[i]; i++) { 28.999 + strncpy (tmp + fnlen,subdir_names[i],MAILTMPLEN); 28.1000 + 28.1001 + if (mkdir (tmp,0700)) { /* try to make new dir */ 28.1002 + snprintf (err,MAILTMPLEN,"Can't create mailbox %s: %s %s", 28.1003 + mailbox,tmp,strerror (errno)); 28.1004 + mm_log (err,ERROR); 28.1005 + return NIL; 28.1006 + } 28.1007 + } 28.1008 + 28.1009 + return T; /* return success */ 28.1010 +} 28.1011 + 28.1012 +void maildir_flagmsg (MAILSTREAM *stream,MESSAGECACHE *elt) 28.1013 +{ 28.1014 + char oldfile[MAILTMPLEN],newfile[MAILTMPLEN],fn[MAILTMPLEN]; 28.1015 + struct utimbuf tbuf; 28.1016 + char *s; 28.1017 + 28.1018 + /* build the new filename */ 28.1019 + snprintf (oldfile,MAILTMPLEN,"%s/%s",LOCAL->dir,(char *) elt->maildirp); 28.1020 + if ((s = strchr ((char *) elt->maildirp,':'))) *s = '\0'; 28.1021 + snprintf (fn,MAILTMPLEN,"%s:2,%s%s%s%s",(char *) elt->maildirp,elt->flagged ? "F" : "", 28.1022 + elt->answered ? "R" : "",elt->seen ? "S" : "", 28.1023 + elt->deleted ? "T" : ""); 28.1024 + snprintf (newfile,MAILTMPLEN,"%s/%s",LOCAL->dir,fn); 28.1025 + /* rename the file with new flags */ 28.1026 + if (rename (oldfile,newfile) < 0) { 28.1027 + snprintf(oldfile,MAILTMPLEN,"Unable to write flags to disk: %s",strerror (errno)); 28.1028 + mm_log(oldfile,ERROR); 28.1029 + return; 28.1030 + } 28.1031 + /* update the file name in cache */ 28.1032 + fs_give ((void **) &elt->maildirp); 28.1033 + elt->maildirp = (long) cpystr (fn); 28.1034 + 28.1035 + /* fix the UID on the file */ 28.1036 + tbuf.actime = elt->private.uid; 28.1037 + tbuf.modtime = elt->private.uid; 28.1038 + chmod (newfile, S_IRUSR|S_IWUSR|S_IXUSR); 28.1039 + utime (newfile, &tbuf); 28.1040 + 28.1041 +} 28.1042 + 28.1043 +void maildir_expunge (MAILSTREAM *stream) 28.1044 +{ 28.1045 + MESSAGECACHE *elt; 28.1046 + unsigned long i = 1; 28.1047 + unsigned long n = 0; 28.1048 + unsigned long recent = stream->recent; 28.1049 + 28.1050 + maildir_gc (stream,GC_TEXTS); /* invalidate texts */ 28.1051 + mm_critical (stream); /* go critical */ 28.1052 + while (i <= stream->nmsgs) { /* for each message */ 28.1053 + /* if deleted, need to trash it */ 28.1054 + if ((elt = mail_elt (stream,i))->deleted) { 28.1055 + snprintf (LOCAL->buf,MAILTMPLEN,"%s/%s",LOCAL->dir,(char *) elt->maildirp); 28.1056 + if (unlink (LOCAL->buf)) {/* try to delete the message */ 28.1057 + snprintf (LOCAL->buf,MAILTMPLEN,"Expunge of message %ld failed, aborted: %s",i, 28.1058 + strerror (errno)); 28.1059 + mm_log (LOCAL->buf,WARN); 28.1060 + break; 28.1061 + } 28.1062 + /* free the cached filename */ 28.1063 + if (elt->maildirp) { 28.1064 + fs_give ((void **) &elt->maildirp); 28.1065 + elt->maildirp = 0; /* otherwise pine coredumps */ 28.1066 + } 28.1067 + if (elt->recent) --recent;/* if recent, note one less recent message */ 28.1068 + mail_expunged (stream,i); /* notify upper levels */ 28.1069 + n++; /* count up one more expunged message */ 28.1070 + } 28.1071 + else i++; /* otherwise try next message */ 28.1072 + } 28.1073 + if (n) { /* output the news if any expunged */ 28.1074 + snprintf (LOCAL->buf,MAILTMPLEN,"Expunged %ld messages",n); 28.1075 + mm_log (LOCAL->buf,(long) NIL); 28.1076 + } 28.1077 + else mm_log ("No messages deleted, so no update needed",(long) NIL); 28.1078 + mm_nocritical (stream); /* release critical */ 28.1079 + /* notify upper level of new mailbox size */ 28.1080 + mail_exists (stream,stream->nmsgs); 28.1081 + mail_recent (stream,recent); 28.1082 +} 28.1083 + 28.1084 +/* dont forget to process options in here */ 28.1085 + 28.1086 +/* modified by sakira@sundent.mine.nu (03.01.13) */ 28.1087 +long maildir_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long options) 28.1088 +{ 28.1089 + STRING st; 28.1090 + MESSAGECACHE *elt; 28.1091 + struct stat sbuf; 28.1092 + int fd; 28.1093 + unsigned long i; 28.1094 + char flags[MAILTMPLEN], date[MAILTMPLEN]; 28.1095 + 28.1096 + /* copy the messages */ 28.1097 + if ((options & CP_UID) ? mail_uid_sequence (stream, sequence) : 28.1098 + mail_sequence (stream,sequence)) 28.1099 + for (i = 1; i <= stream->nmsgs; i++) 28.1100 + if ((elt = mail_elt (stream,i))->sequence) { 28.1101 + sprintf (LOCAL->buf, "%s/%s", LOCAL->dir, (char *) elt->maildirp); 28.1102 + /* snprintf (LOCAL->buf,MAILTMPLEN,"%s/%s",LOCAL->dir,(char *) elt->maildirp); */ 28.1103 + if ((fd = open (LOCAL->buf,O_RDONLY,NIL)) < 0) return NIL; 28.1104 + fstat (fd,&sbuf); /* get size of message */ 28.1105 + 28.1106 + if (!elt->day) { 28.1107 + struct tm *tm = gmtime (&sbuf.st_mtime); 28.1108 + elt->day = tm->tm_mday; elt->month = tm->tm_mon + 1; 28.1109 + elt->year = tm->tm_year + 1900 - BASEYEAR; 28.1110 + elt->hours = tm->tm_hour; elt->minutes = tm->tm_min; 28.1111 + elt->seconds = tm->tm_sec; 28.1112 + elt->zhours = 0; elt->zminutes = 0; 28.1113 + } 28.1114 + 28.1115 + if (sbuf.st_size > LOCAL->buflen) { 28.1116 + fs_give((void **) &LOCAL->buf); 28.1117 + LOCAL->buf = (char *) fs_get ((LOCAL->buflen = sbuf.st_size) + 1); 28.1118 + } 28.1119 + 28.1120 + /* slurp message */ 28.1121 + read(fd, LOCAL->buf, sbuf.st_size); 28.1122 + LOCAL->buf[sbuf.st_size] = '\0'; 28.1123 + close(fd); 28.1124 + /* read (fd, s = (char *) fs_get (sbuf.st_size +1),sbuf.st_size); 28.1125 + s[sbuf.st_size] = '\0'; 28.1126 + close (fd); */ 28.1127 + 28.1128 + INIT (&st,mail_string,(void *) LOCAL->buf,sbuf.st_size); 28.1129 + flags[0] = flags[1] = '\0'; 28.1130 + if (elt->seen) strcat(flags, " \\Seen"); 28.1131 + if (elt->deleted) strcat(flags, " \\Deleted"); 28.1132 + if (elt->answered) strcat(flags, " \\Answered"); 28.1133 + if (elt->draft) strcat(flags, " \\Draft"); 28.1134 + flags[0] = '('; 28.1135 + strcat(flags, ")"); 28.1136 + mail_date(date, elt); 28.1137 + /* snprintf (LOCAL->buf,MAILTMPLEN,"%s%s%s%s%s)", 28.1138 + elt->seen ? " \\Seen" : "", 28.1139 + elt->deleted ? " \\Deleted" : "", 28.1140 + elt->flagged ? " \\Flagged" : "", 28.1141 + elt->answered ? " \\Answered" : "", 28.1142 + (elt->seen || elt->deleted || elt->flagged || elt->answered) ? 28.1143 + "" : " "); 28.1144 + LOCAL->buf[0] = '('; 28.1145 + mail_date (tmp,elt); */ 28.1146 + 28.1147 + if (!mail_append_full (NIL, mailbox, flags, date, &st)) return NIL; 28.1148 + if (options & CP_MOVE) elt->deleted = T; 28.1149 + 28.1150 + /* if (!maildir_append (stream,mailbox,LOCAL->buf,tmp,&st)) { 28.1151 + fs_give ((void **) &s); 28.1152 + return NIL; 28.1153 + } */ 28.1154 + /* fs_give ((void **) &s); */ /* give back temporary space */ 28.1155 + } 28.1156 + return T; /* return success */ 28.1157 +} 28.1158 + 28.1159 +#if 0 28.1160 +long maildir_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long options) 28.1161 +{ 28.1162 + STRING st; 28.1163 + MESSAGECACHE *elt; 28.1164 + struct stat sbuf; 28.1165 + int fd; 28.1166 + long i; 28.1167 + char *s,tmp[MAILTMPLEN]; 28.1168 + /* copy the messages */ 28.1169 + if ((options & CP_UID) ? mail_uid_sequence (stream, sequence) : 28.1170 + mail_sequence (stream,sequence)) 28.1171 + for (i = 1; i <= stream->nmsgs; i++) 28.1172 + if ((elt = mail_elt (stream,i))->sequence) { 28.1173 + snprintf (LOCAL->buf,MAILTMPLEN,"%s/%s",LOCAL->dir,(char *) elt->maildirp); 28.1174 + if ((fd = open (LOCAL->buf,O_RDONLY,NIL)) < 0) return NIL; 28.1175 + fstat (fd,&sbuf); /* get size of message */ 28.1176 + /* slurp message */ 28.1177 + read (fd,s = (char *) fs_get (sbuf.st_size +1),sbuf.st_size); 28.1178 + s[sbuf.st_size] = '\0'; /* tie off file */ 28.1179 + close (fd); /* flush message file */ 28.1180 + INIT (&st,mail_string,(void *) s,sbuf.st_size); 28.1181 + snprintf (LOCAL->buf,MAILTMPLEN,"%s%s%s%s%s)", 28.1182 + elt->seen ? " \\Seen" : "", 28.1183 + elt->deleted ? " \\Deleted" : "", 28.1184 + elt->flagged ? " \\Flagged" : "", 28.1185 + elt->answered ? " \\Answered" : "", 28.1186 + (elt->seen || elt->deleted || elt->flagged || elt->answered) ? 28.1187 + "" : " "); 28.1188 + LOCAL->buf[0] = '('; /* open list */ 28.1189 + mail_date (tmp,elt); /* generate internal date */ 28.1190 + if (!maildir_append (stream,mailbox,LOCAL->buf,tmp,&st)) { 28.1191 + fs_give ((void **) &s); /* give back temporary space */ 28.1192 + return NIL; 28.1193 + } 28.1194 + fs_give ((void **) &s); /* give back temporary space */ 28.1195 + } 28.1196 + return T; /* return success */ 28.1197 +} 28.1198 +#endif 28.1199 + 28.1200 +long maildir_append (MAILSTREAM *stream, char *mailbox, append_t af, void *data) 28.1201 +{ 28.1202 + int fd; 28.1203 + char c, *s; 28.1204 + char *flags, *date; 28.1205 + char tmp[MAILTMPLEN],file[MAILTMPLEN],path1[MAILTMPLEN],path2[MAILTMPLEN]; 28.1206 + MESSAGECACHE elt; 28.1207 + STRING *message; 28.1208 + long i; 28.1209 + long size = 0; 28.1210 + long ret = LONGT; 28.1211 + short uf = 0; 28.1212 + 28.1213 + /* 28.1214 + This is intentionaly made static. Users can ask to save a LOT of messages 28.1215 + at once and this program can do that within one second. Dan's assumption 28.1216 + that time+pid+hostname always will be unique stops being true in this 28.1217 + case. So we will add yet another number to host part of message file's 28.1218 + name. Hostname is used only to make filename unique and Dan explicitly 28.1219 + says that "<...> Other than this [skipping filenames starting at dot] , 28.1220 + readers should not attempt to parse filenames. <...>". Therefore this 28.1221 + addition should be no problem. Am I right, Dan? --AK 28.1222 + */ 28.1223 + 28.1224 + static unsigned int transact = 0; 28.1225 + 28.1226 + if (!stream) stream = &maildirproto; 28.1227 + 28.1228 + if (flags) /* get flags if given */ 28.1229 + uf = maildir_getflags (user_flags (&maildirproto),flags); 28.1230 + 28.1231 + /* N.B.: can't use LOCAL->buf for tmp */ 28.1232 + /* make sure valid mailbox */ 28.1233 + if (!maildir_isvalid (mailbox, NIL)) { 28.1234 + snprintf (tmp,MAILTMPLEN,"Not a valid Maildir mailbox: %s",mailbox); 28.1235 + mm_log (tmp,ERROR); 28.1236 + return NIL; 28.1237 + } 28.1238 + 28.1239 + if (!(*af)(stream, data, &flags, &date, &message)) return NIL; 28.1240 + 28.1241 + mm_critical(stream); /* go critical */ 28.1242 + do { 28.1243 + if (!SIZE(message)) { /* guard againt zero-length */ 28.1244 + mm_log("Append of zero-length message", ERROR); 28.1245 + ret = NIL; 28.1246 + break; 28.1247 + } 28.1248 + 28.1249 + /* build file name we will use */ 28.1250 + snprintf (file,MAILTMPLEN,"%u.%d.%09u.%s:3,%s%s%s%s", 28.1251 + time (0),getpid (),transact++,mylocalhost (), 28.1252 + uf&fFLAGGED ? "F" : "",uf&fANSWERED ? "R" : "", 28.1253 + uf&fSEEN ? "S" : "",uf&fDELETED ? "T" : ""); 28.1254 + /* build tmp file name */ 28.1255 + snprintf (path1,MAILTMPLEN,"%s/../tmp/%s",maildir_file (tmp,mailbox),file); 28.1256 + 28.1257 + if ((fd = open (path1,O_WRONLY|O_CREAT|O_EXCL,S_IREAD|S_IWRITE)) < 0) { 28.1258 + snprintf (tmp,MAILTMPLEN,"Can't open append mailbox: %s",strerror (errno)); 28.1259 + mm_log (tmp,ERROR); 28.1260 + return NIL; 28.1261 + } 28.1262 + 28.1263 + i = SIZE (message); /* get size of message */ 28.1264 + s = (char *) fs_get (i + 1); /* get space for the data */ 28.1265 + /* copy the data w/o CR's */ 28.1266 + while (i--) if ((c = SNX (message)) != '\015') s[size++] = c; 28.1267 + /* write the data */ 28.1268 + if ((write (fd,s,size) < 0) || fsync (fd)) { 28.1269 + unlink (path1); /* delete message */ 28.1270 + snprintf (tmp,MAILTMPLEN,"Message append failed: %s",strerror (errno)); 28.1271 + mm_log (tmp,ERROR); 28.1272 + ret = NIL; 28.1273 + } 28.1274 + /* build final filename to use */ 28.1275 + snprintf (path2,MAILTMPLEN,"%s/../new/%s",maildir_file (tmp,mailbox),file); 28.1276 + if (link (path1,path2) < 0) { 28.1277 + snprintf (tmp,MAILTMPLEN,"Message append failed: %s",strerror (errno)); 28.1278 + mm_log (tmp,ERROR); 28.1279 + ret = NIL; 28.1280 + } 28.1281 + unlink (path1); 28.1282 + fs_give ((void **) &s); /* flush the buffer */ 28.1283 + close (fd); /* close the file */ 28.1284 + 28.1285 + if (ret) { 28.1286 + if (!(*af)(stream, data, &flags, &date, &message)) ret = NIL; 28.1287 + } 28.1288 + } while(ret && message); 28.1289 + 28.1290 + mm_nocritical (stream); /* release critical */ 28.1291 + return ret; 28.1292 +} 28.1293 + 28.1294 +#if 0 28.1295 +long maildir_append (MAILSTREAM *stream,char *mailbox,char *flags,char *date, 28.1296 + STRING *message) 28.1297 +{ 28.1298 + int fd; 28.1299 + char c,*s; 28.1300 + char tmp[MAILTMPLEN],file[MAILTMPLEN],path1[MAILTMPLEN],path2[MAILTMPLEN]; 28.1301 + MESSAGECACHE elt; 28.1302 + long i; 28.1303 + long size = 0; 28.1304 + long ret = LONGT; 28.1305 + short uf = 0; 28.1306 + 28.1307 + /* 28.1308 + This is intentionaly made static. Users can ask to save a LOT of messages 28.1309 + at once and this program can do that within one second. Dan's assumption 28.1310 + that time+pid+hostname always will be unique stops being true in this 28.1311 + case. So we will add yet another number to host part of message file's 28.1312 + name. Hostname is used only to make filename unique and Dan explicitly 28.1313 + says that "<...> Other than this [skipping filenames starting at dot] , 28.1314 + readers should not attempt to parse filenames. <...>". Therefore this 28.1315 + addition should be no problem. Am I right, Dan? --AK 28.1316 + */ 28.1317 + 28.1318 + static unsigned int transact = 0; 28.1319 + 28.1320 + if (flags) /* get flags if given */ 28.1321 + uf = maildir_getflags (user_flags (&maildirproto),flags); 28.1322 + 28.1323 +/* if (date) { want to preserve date? 28.1324 + //syslog(LOG_INFO, "date: '%s'", date); 28.1325 + // yes, parse date into an elt 28.1326 + if (!mail_parse_date (&elt,date)) { 28.1327 + snprintf (tmp,MAILTMPLEN,"Bad date in append: %s",date); 28.1328 + mm_log (tmp,ERROR); 28.1329 + return NIL; 28.1330 + } 28.1331 + } */ 28.1332 + /* N.B.: can't use LOCAL->buf for tmp */ 28.1333 + /* make sure valid mailbox */ 28.1334 + if (!maildir_isvalid (mailbox, NIL)) { 28.1335 + snprintf (tmp,MAILTMPLEN,"Not a valid Maildir mailbox: %s",mailbox); 28.1336 + mm_log (tmp,ERROR); 28.1337 + return NIL; 28.1338 + } 28.1339 + /* build file name we will use */ 28.1340 + snprintf (file,MAILTMPLEN,"%u.%d.%09u.%s:3,%s%s%s%s", 28.1341 + time (0),getpid (),transact++,mylocalhost (), 28.1342 + uf&fFLAGGED ? "F" : "",uf&fANSWERED ? "R" : "", 28.1343 + uf&fSEEN ? "S" : "",uf&fDELETED ? "T" : ""); 28.1344 + /* build tmp file name */ 28.1345 + snprintf (path1,MAILTMPLEN,"%s/../tmp/%s",maildir_file (tmp,mailbox),file); 28.1346 + 28.1347 + if ((fd = open (path1,O_WRONLY|O_CREAT|O_EXCL,S_IREAD|S_IWRITE)) < 0) { 28.1348 + snprintf (tmp,MAILTMPLEN,"Can't open append mailbox: %s",strerror (errno)); 28.1349 + mm_log (tmp,ERROR); 28.1350 + return NIL; 28.1351 + } 28.1352 + i = SIZE (message); /* get size of message */ 28.1353 + s = (char *) fs_get (i + 1); /* get space for the data */ 28.1354 + /* copy the data w/o CR's */ 28.1355 + while (i--) if ((c = SNX (message)) != '\015') s[size++] = c; 28.1356 + mm_critical (stream); /* go critical */ 28.1357 + /* write the data */ 28.1358 + if ((write (fd,s,size) < 0) || fsync (fd)) { 28.1359 + unlink (path1); /* delete message */ 28.1360 + snprintf (tmp,MAILTMPLEN,"Message append failed: %s",strerror (errno)); 28.1361 + mm_log (tmp,ERROR); 28.1362 + ret = NIL; 28.1363 + } 28.1364 + /* build final filename to use */ 28.1365 + snprintf (path2,MAILTMPLEN,"%s/../new/%s",maildir_file (tmp,mailbox),file); 28.1366 + if (link (path1,path2) < 0) { 28.1367 + snprintf (tmp,MAILTMPLEN,"Message append failed: %s",strerror (errno)); 28.1368 + mm_log (tmp,ERROR); 28.1369 + ret = NIL; 28.1370 + } 28.1371 + unlink (path1); 28.1372 + 28.1373 + close (fd); /* close the file */ 28.1374 + mm_nocritical (stream); /* release critical */ 28.1375 + fs_give ((void **) &s); /* flush the buffer */ 28.1376 + return ret; 28.1377 +} 28.1378 +#endif 28.1379 + 28.1380 +short bezerk_getflags (MAILSTREAM *stream,char *flag) 28.1381 +{ 28.1382 + char *t,tmp[MAILTMPLEN],err[MAILTMPLEN]; 28.1383 + short f = 0; 28.1384 + short i,j; 28.1385 + if (flag && *flag) { /* no-op if no flag string */ 28.1386 + /* check if a list and make sure valid */ 28.1387 + if ((i = (*flag == '(')) ^ (flag[strlen (flag)-1] == ')')) { 28.1388 + mm_log ("Bad flag list",ERROR); 28.1389 + return NIL; 28.1390 + } 28.1391 + /* copy the flag string w/o list construct */ 28.1392 + strncpy (tmp,flag+i,(j = strlen (flag) - (2*i))); 28.1393 + tmp[j] = '\0'; 28.1394 + t = ucase (tmp); /* uppercase only from now on */ 28.1395 + 28.1396 + while (t && *t) { /* parse the flags */ 28.1397 + if (*t == '\\') { /* system flag? */ 28.1398 + switch (*++t) { /* dispatch based on first character */ 28.1399 + case 'S': /* possible \Seen flag */ 28.1400 + if (t[1] == 'E' && t[2] == 'E' && t[3] == 'N') i = fSEEN; 28.1401 + t += 4; /* skip past flag name */ 28.1402 + break; 28.1403 + case 'D': /* possible \Deleted flag */ 28.1404 + if (t[1] == 'E' && t[2] == 'L' && t[3] == 'E' && t[4] == 'T' && 28.1405 + t[5] == 'E' && t[6] == 'D') i = fDELETED; 28.1406 + t += 7; /* skip past flag name */ 28.1407 + break; 28.1408 + case 'F': /* possible \Flagged flag */ 28.1409 + if (t[1] == 'L' && t[2] == 'A' && t[3] == 'G' && t[4] == 'G' && 28.1410 + t[5] == 'E' && t[6] == 'D') i = fFLAGGED; 28.1411 + t += 7; /* skip past flag name */ 28.1412 + break; 28.1413 + case 'A': /* possible \Answered flag */ 28.1414 + if (t[1] == 'N' && t[2] == 'S' && t[3] == 'W' && t[4] == 'E' && 28.1415 + t[5] == 'R' && t[6] == 'E' && t[7] == 'D') i = fANSWERED; 28.1416 + t += 8; /* skip past flag name */ 28.1417 + break; 28.1418 + default: /* unknown */ 28.1419 + i = 0; 28.1420 + break; 28.1421 + } 28.1422 + /* add flag to flags list */ 28.1423 + if (i && ((*t == '\0') || (*t++ == ' '))) f |= i; 28.1424 + } 28.1425 + else { /* no user flags yet */ 28.1426 + return f; 28.1427 + t = strtok (t," "); /* isolate flag name */ 28.1428 + /* snprintf (err,MAILTMPLEN,"Unknown flag: %.80s",t); */ 28.1429 + t = strtok (NIL," "); /* get next flag */ 28.1430 + /* mm_log (err,ERROR); */ 28.1431 + } 28.1432 + } 28.1433 + } 28.1434 + return f; 28.1435 +} 28.1436 + 28.1437 +short maildir_getflags (MAILSTREAM *stream,char *flag) 28.1438 +{ 28.1439 + return bezerk_getflags (stream,flag); /* nothing exciting, reuse old code */ 28.1440 +} 28.1441 + 28.1442 +long maildir_delete (MAILSTREAM *stream,char *mailbox) 28.1443 +{ 28.1444 + DIR *dirp; 28.1445 + struct direct *d; 28.1446 + int i,j; 28.1447 + char tmp[MAILTMPLEN],err[MAILTMPLEN]; 28.1448 + char *subdir_names[] = {"cur/","new/","tmp/",NULL}; 28.1449 + 28.1450 + /* check if mailbox even exists */ 28.1451 + if (!maildir_isvalid (mailbox,NIL)) { 28.1452 +/* sprintf (tmp,"Can't delete mailbox %s: no such mailbox",mailbox); 28.1453 + mm_log (tmp,ERROR); 28.1454 + return NIL; */ 28.1455 + /*syslog(LOG_INFO, "Invalid maildir in delete()"); */ 28.1456 + return T; /* well.. a stupid hack to get by a problem in netscape .. 28.1457 + it remembers folders locally, and if a folder is deleted on 28.1458 + another machine, you have no way removing it on any other 28.1459 + netscapes... */ 28.1460 + } 28.1461 + 28.1462 + /* get name of directory */ 28.1463 + i = strlen (maildir_file (tmp,mailbox)) + 1; 28.1464 + for (j = 0; subdir_names[j]; j++) { 28.1465 + strncpy (tmp + i - 4,subdir_names[j], MAILTMPLEN); 28.1466 + if (dirp = opendir (tmp)) { /* open directory */ 28.1467 + while (d = readdir (dirp)) /* empty the directory */ 28.1468 + if (strcmp (d->d_name,".") && strcmp (d->d_name,"..")) { 28.1469 + strncpy (tmp + i,d->d_name, MAILTMPLEN); 28.1470 + /*syslog(LOG_INFO, "unlink1: '%s'");*/ 28.1471 + unlink (tmp); 28.1472 + } 28.1473 + closedir (dirp); /* flush directory */ 28.1474 + } 28.1475 + /* remove the subdir */ 28.1476 + tmp[i + 3] = '\0'; 28.1477 + /*syslog(LOG_INFO, "tmp: '%s'", tmp);*/ 28.1478 + if (rmdir (tmp)) { 28.1479 + /* sprintf (err,"Can't delete directory %s: %s",tmp,strerror (errno)); 28.1480 + mm_log (err,ERROR);*/ 28.1481 + } 28.1482 + } 28.1483 + 28.1484 + /* try to remove the directory */ 28.1485 + *(tmp + i - 5) = '\0'; 28.1486 + /*syslog(LOG_INFO, "tmp2: '%s'", tmp);*/ 28.1487 + if (rmdir (tmp)) { 28.1488 +/* sprintf (err,"Can't delete mailbox %s: %s",mailbox,strerror (errno)); 28.1489 + mm_log (err,ERROR); 28.1490 + return NIL; */ 28.1491 + } 28.1492 + return T; /* return success */ 28.1493 +} 28.1494 + 28.1495 +long maildir_rename (MAILSTREAM *stream,char *old,char *new) 28.1496 +{ 28.1497 + char tmp[MAILTMPLEN],tmpnew[MAILTMPLEN]; 28.1498 + 28.1499 + /* old mailbox name must be valid */ 28.1500 + if (!maildir_isvalid (old,NIL)) { 28.1501 + snprintf (tmp,MAILTMPLEN,"Can't rename mailbox %s: no such mailbox",old); 28.1502 + mm_log (tmp,ERROR); 28.1503 + return NIL; 28.1504 + } 28.1505 + 28.1506 + /* new mailbox name must not exist */ 28.1507 + if (access (maildir_file (tmp,new),F_OK) == 0) { 28.1508 + snprintf (tmp,MAILTMPLEN,"Can't rename to mailbox %s: destination already exists",new); 28.1509 + mm_log (tmp,ERROR); 28.1510 + return NIL; 28.1511 + } 28.1512 + 28.1513 + /* try to rename the directory */ 28.1514 + if (rename (maildir_file (tmp,old),maildir_file (tmpnew,new))) { 28.1515 + snprintf (tmp,MAILTMPLEN,"Can't rename mailbox %s to %s: %s",old,new,strerror (errno)); 28.1516 + mm_log (tmp,ERROR); 28.1517 + return NIL; 28.1518 + } 28.1519 + return T; /* return success */ 28.1520 +} 28.1521 + 28.1522 +long maildir_sub (MAILSTREAM *stream,char *mailbox) 28.1523 +{ 28.1524 + char tmp[MAILTMPLEN]; 28.1525 + return sm_subscribe (mailbox); 28.1526 +} 28.1527 + 28.1528 +long maildir_unsub (MAILSTREAM *stream,char *mailbox) 28.1529 +{ 28.1530 + char tmp[MAILTMPLEN]; 28.1531 + return sm_unsubscribe (mailbox); 28.1532 +} 28.1533 + 28.1534 +void maildir_lsub (MAILSTREAM *stream,char *ref,char *pat) 28.1535 +{ 28.1536 + void *sdb = NIL; 28.1537 + char *s; 28.1538 + /* get canonical form of name */ 28.1539 + if ((s = sm_read (&sdb))) { 28.1540 + do if (pmatch_full (s,pat,'/')) mm_lsub (stream,'/',s,NIL); 28.1541 + while (s = sm_read (&sdb)); /* until no more subscriptions */ 28.1542 + } 28.1543 + 28.1544 +}
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 29.2 +++ b/src/osdep/unix/maildir.h Mon Sep 14 19:23:11 2009 +0900 29.3 @@ -0,0 +1,58 @@ 29.4 +/* 29.5 + * Please read maildir.c for license and information 29.6 + * 29.7 + */ 29.8 + 29.9 +#define MAILDIRPATH "Maildir" 29.10 + 29.11 +typedef struct maildir_local { 29.12 + unsigned int inbox : 1; /* if it is an INBOX or not */ 29.13 + unsigned int dirty : 1; /* diskcopy needs updating */ 29.14 + char *dir; /* mail directory name */ 29.15 + char *buf; /* temporary buffer */ 29.16 + char *hdr; /* current header */ 29.17 + unsigned long buflen; /* current size of temporary buffer */ 29.18 + time_t scantime; /* last time directory scanned */ 29.19 +} MAILDIRLOCAL; 29.20 + 29.21 +/* Convenient access to local data */ 29.22 + 29.23 +#define LOCAL ((MAILDIRLOCAL *) stream->local) 29.24 + 29.25 +/* Function prototypes */ 29.26 + 29.27 +DRIVER *maildir_valid (char *name); 29.28 +int maildir_isvalid (char *name,long justname); 29.29 +MAILSTREAM *maildir_open (MAILSTREAM *stream); 29.30 +void maildir_gc (MAILSTREAM *stream,long gcflags); 29.31 +void maildir_close (MAILSTREAM *stream, long options); 29.32 +long maildir_ping (MAILSTREAM *stream); 29.33 +long maildir_ping_core (MAILSTREAM *stream); 29.34 +void maildir_check (MAILSTREAM *stream); 29.35 +long maildir_fetchtext (MAILSTREAM *stream,unsigned long msgno,STRING *bs,long flags); 29.36 +char *maildir_fetchheader (MAILSTREAM *stream,unsigned long msgno, 29.37 + unsigned long *length, long flags); 29.38 +void maildir_fast (MAILSTREAM *stream,char *sequence,long flags); 29.39 +void maildir_list (MAILSTREAM *stream,char *ref,char *pat); 29.40 +void *maildir_parameters (long function,void *value); 29.41 +long maildir_create (MAILSTREAM *stream,char *mailbox); 29.42 +void maildir_flagmsg (MAILSTREAM *stream,MESSAGECACHE *elt); 29.43 +void maildir_expunge (MAILSTREAM *stream); 29.44 +long maildir_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long options); 29.45 +long maildir_append (MAILSTREAM *stream, char *mailbox, append_t af, void *data); 29.46 +/* long maildir_append (MAILSTREAM *stream,char *mailbox,char *flags,char *date, 29.47 + STRING *message); */ 29.48 +short maildir_getflags (MAILSTREAM *stream,char *flag); 29.49 +long maildir_delete (MAILSTREAM *stream,char *mailbox); 29.50 +long maildir_rename (MAILSTREAM *stream,char *old,char *new); 29.51 +long maildir_sub (MAILSTREAM *stream,char *mailbox); 29.52 +long maildir_unsub (MAILSTREAM *stream,char *mailbox); 29.53 +void maildir_lsub (MAILSTREAM *stream,char *ref,char *pat); 29.54 + 29.55 +/* utility functions */ 29.56 +char *maildir_file (char *dst,char *name); 29.57 +void maildir_copynew (const char *mailbox); 29.58 +int maildir_select (struct direct *name); 29.59 +/* int maildir_namesort (struct direct **d1,struct direct **d2); */ 29.60 +int maildir_namesort (const void *, const void *); 29.61 +void maildir_listwork(char *name, MAILSTREAM *stream, char *s2, char *subdir, int flag);
30.1 --- a/src/osdep/unix/tcp_unix.c Mon Sep 14 15:17:45 2009 +0900 30.2 +++ b/src/osdep/unix/tcp_unix.c Mon Sep 14 19:23:11 2009 +0900 30.3 @@ -818,6 +818,20 @@ 30.4 return stream->localhost; /* return local host name */ 30.5 } 30.6 30.7 +/* Get $TCPREMOTEHOST || $TCPREMOTEHOST 30.8 + * If invoked via tcpserver or couriertcpd, consult $TCPREMOTEHOST 30.9 + * or $TCPREMOTEIP 30.10 + */ 30.11 +char* gettcpremoteip() 30.12 +{ 30.13 + if (getenv("TCPREMOTEHOST") && strcmp("0", getenv("TCPREMOTEHOST"))) { 30.14 + return getenv("TCPREMOTEHOST"); 30.15 + } else if (getenv("TCPREMOTEIP")) { 30.16 + return getenv("TCPREMOTEIP"); 30.17 + } 30.18 + return "NON-IPv4"; 30.19 +} 30.20 + 30.21 /* TCP/IP get client host address (server calls only) 30.22 * Returns: client host address 30.23 */ 30.24 @@ -848,6 +862,15 @@ 30.25 if (!myClientHost) { 30.26 size_t sadrlen; 30.27 struct sockaddr *sadr = ip_newsockaddr (&sadrlen); 30.28 +#ifdef INET6 30.29 + if (getenv("TCPREMOTEIP")) { 30.30 + myClientHost = 30.31 + cpystr((getenv("TCPREMOTEHOST") 30.32 + && strcasecmp("UNKNOWN", getenv("TCPREMOTEHOST"))) 30.33 + ? getenv("TCPREMOTEHOST") 30.34 + : getenv("TCPREMOTEIP")); 30.35 + } else 30.36 +#endif 30.37 if (getpeername (0,sadr,(void *) &sadrlen)) { 30.38 char *s,*t,*v,tmp[MAILTMPLEN]; 30.39 if ((s = getenv (t = "SSH_CLIENT")) || 30.40 @@ -911,7 +934,8 @@ 30.41 size_t sadrlen; 30.42 struct sockaddr *sadr = ip_newsockaddr (&sadrlen); 30.43 /* get stdin's name */ 30.44 - if (getsockname (0,sadr,(void *) &sadrlen)) 30.45 + if (getsockname (0,sadr,(void *) &sadrlen) || 30.46 + (myServerPort = ip_sockaddrtoport (sadr)) < 0) 30.47 myServerHost = cpystr (mylocalhost ()); 30.48 else { /* get stdin's name */ 30.49 myServerHost = tcp_name (sadr,NIL);
31.1 --- a/src/osdep/unix/unix.c Mon Sep 14 15:17:45 2009 +0900 31.2 +++ b/src/osdep/unix/unix.c Mon Sep 14 19:23:11 2009 +0900 31.3 @@ -202,6 +202,7 @@ 31.4 31.5 /* driver parameters */ 31.6 static long unix_fromwidget = T; 31.7 +char *myMailSuffix =NIL; /* home directory name */ 31.8 31.9 /* UNIX mail validate mailbox 31.10 * Accepts: mailbox name 31.11 @@ -2401,6 +2402,15 @@ 31.12 } 31.13 f->filepos += size; /* update file position */ 31.14 } 31.15 + 31.16 +/* Return my mail suffix(of qmail or Postfix) 31.17 + * Returns: my mail address extensional suffix 31.18 + */ 31.19 + 31.20 +char *mymailsuffix () 31.21 +{ 31.22 + return myMailSuffix ? myMailSuffix : ""; 31.23 +} 31.24 31.25 /* MBOX mail routines */ 31.26