changeset 4:d741b3ecc917 draft

imapext-2007f
author HIROSE Yuuji <yuuji@gentei.org>
date Thu, 30 Oct 2014 00:03:05 +0900
parents 2366b362676d
children 2410c62d4b4f
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/tcp_unix.c src/osdep/unix/unix.c
diffstat 29 files changed, 1851 insertions(+), 136 deletions(-) [+]
line wrap: on
line diff
--- a/APOPtools/Makefile	Thu Oct 30 00:00:57 2014 +0900
+++ b/APOPtools/Makefile	Thu Oct 30 00:03:05 2014 +0900
@@ -28,3 +28,33 @@
 
 clean:
 	rm apopcall
+#
+# install script
+#
+PERMSMTPDIR	= /usr/local/etc
+DEAPOPDIR	= /usr/local/sbin
+BINDIR		= /usr/local/bin
+CGIDIR		= /usr/local/apache/cgi-bin
+
+
+all:	apopcall
+
+LDFLAGS	= -lcrypt
+
+apopcall:	apopcall.c
+
+
+install:
+	-@[ -d ${PERMSMTPDIR} ] || mkdir -p ${PERMSMTPDIR}
+	install -c -m 700 pop3-record ${PERMSMTPDIR}
+	csh -c 'ln -f ${PERMSMTPDIR}/pop3-{record,age}'
+	csh -c 'ln -f ${PERMSMTPDIR}/pop3-{record,update}'
+	-@[ -d ${DEAPOPDIR} ] || mkdir -p ${DEAPOPDIR}
+	install -c -m 700 deapop ${DEAPOPDIR}
+	install -c -m 755 apoppasswd ${BINDIR}
+
+install-cgi:	apopcall
+	install -cs -m 4755 -o 0 apopcall ${CGIDIR}/apopcall.cgi
+
+clean:
+	rm apopcall
--- a/APOPtools/apopcall.c	Thu Oct 30 00:00:57 2014 +0900
+++ b/APOPtools/apopcall.c	Thu Oct 30 00:03:05 2014 +0900
@@ -524,3 +524,529 @@
         printf("このユーティリティはSSL接続時のみ有効です.<br>\n");
     }
 }
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <pwd.h>
+#ifdef SHADOW_PASSWD
+#include <shadow.h>
+#endif
+
+#ifndef APOPPASSWD
+#define APOPPASSWD "/usr/local/bin/apoppasswd"
+#endif
+#ifndef APOPFILEBASE
+#define APOPFILEBASE ".apop"
+#endif
+#ifndef XADDR_DELIM
+#define XADDR_DELIM ('-')
+#endif
+
+char *myname;
+
+int ishexa(int c) {
+    strchr("0123456789ABCDFabcdef", c) ? 1 : 0;
+}
+
+put_form(email, pass, new, new2, suffix, hidden, auth, force)
+     char *email, *pass, *new, *new2, *suffix;
+     int hidden, auth, force;
+     /* auth = 0: old password
+               1: base addresse's mail password
+               2: unix password */
+{
+    char *authtype[] = {"old", "base", "unix"};
+    char *var[] = {"email", "pass", "new", "new2", "auth", ""};
+    char *val[] = {email, pass, new, new2, authtype[auth]};
+    char *prm[] = {"",  /* "ユーザ名", */
+                   auth ? 
+                   ((auth==1)
+                    ? "基本メイルアドレス用パスワード<br>Password for Basic Mail address"
+                    : "UNIXログインパスワード<br>UNIX login Password")
+                   : "古いメイルパスワード<br>Old Mail Password",
+                   "新しいメイルパスワード<br>New Mail Password",
+                   "新パスワードをもう一回(確認)<br>New Mail Password Again",
+		   ""};
+    int h=0, i;
+
+    printf("<form method=POST action\"./%s\">\n", myname);
+    printf(" <table border=1>\n");
+    for (i=0; var[i][0]; i++) {
+        h = hidden || strstr("email,suffix,auth", var[i]);
+	if (prm[i][0]) {
+            printf("<tr><td>%s</td><td>", prm[i]);
+	} else {
+	}
+        printf("<input name=%s %svalue=\"%s\" length=40 maxlength=40>\n",
+               var[i],
+               h ? "type=hidden "
+               : (strstr(prm[i], "パスワード") ? "type=password " : "<br>"),
+               val[i]);
+        if (!strcmp(var[i], "suffix")) {
+            /* ここでは suffix を入れさせない方がいいかも */
+	    /* 表向きのメイルアドレスを表示しておく */
+            printf("%s", email);
+            /* if (suffix[0]) {
+                printf("-%s", suffix);
+            } */
+            if (auth)
+                printf("<br>(新規作成:New Account)");
+        }
+	if (prm[i][0])
+          printf("</td></tr>");
+	printf("\n");
+    }
+    
+    printf("</table>\n");
+    if (force)
+        printf("<input name=force type=hidden value=ON>\n");
+    if (auth) {
+        char *a[] = {"basic", "unix"};
+        printf("<input type=hidden name=auth value=\"%s\">\n", a[auth-1]);
+    }
+    printf("<input name=OK value=OK type=submit>\n");
+    printf("<input name=RESET value=RESET type=reset>\n");
+    printf("</form>\n");
+    fflush(stdout);
+}
+
+char *decode(char *code) {
+    int l=1+strlen(code);
+    int i, c, d;
+    char *ret = (char*)malloc(l*sizeof(char));
+    char *p = code;
+    memset(ret, 0, l);
+    for (i=0; i<strlen(code); i++) {
+	if (code[i] == '+') code[i] = ' ';
+    }
+    while (code[0] && (p=strchr(code, '%'))
+           && ishexa(*(p+1)) && ishexa(*(p+2))) {
+        *(p++) = '\0';
+        strncat(ret, code, l);
+        c = (islower(*p) ? toupper(*p) : *p) - '0';
+        p++;
+        d = (islower(*p) ? toupper(*p) : *p) - '0';
+        if (c > 9) c -= ('A'-'9'-1);
+        if (d > 9) d -= ('A'-'9'-1);
+        ret[strlen(ret)] = c*16+d;
+        code = p+1;
+    }
+    if (code[0]) strncat(ret, code, l);
+    return ret;
+}
+
+#define BSIZE	8192
+char **decode_post() {
+    char *buf = (char*)malloc(BSIZE*sizeof(char));
+    char **post, *p = buf;
+    int n=0, i;
+    post = (char**)calloc(1, sizeof(char*));
+    *buf = '\0';
+    fgets(buf, BSIZE, stdin);
+    if (strchr("\n\r", buf[strlen(buf)-1])) /* chop */
+        buf[strlen(buf)-1] = '\0';
+    while (buf[0] && NULL != (p=strchr(buf, '&'))) {
+        *p = '\0';
+        post[n] = (char*)malloc((p-buf+1)*sizeof(char));
+        strcpy(post[n], buf);
+        n++;
+        post = (char**)realloc(post, (1+n)*sizeof(char*));
+        buf = 1+p;
+    }
+    if (buf[0]) post[n++] = buf;
+    /* decode URL encoded */
+    for (i=0; i < n; i++) {
+        char *p;
+        p=post[i];
+        post[i] = decode(p);
+    }
+    post[i] = "";               /* terminator */
+    return post;
+}
+
+void footer() {
+    puts("</body>\n</html>");
+    fflush(stdout);
+}
+
+void fail() {
+    printf("パスワード更新に失敗しました<br>\n");
+    printf("<a href=\"./\">やり直し</a><br>\n");
+    footer();
+    exit(1);
+}
+void success(char *email) {
+    printf("<hr>メイルアカウント %s 用のパスワード更新は完了しました。<br>\n",
+           email);
+    footer();
+    exit(0);
+}
+
+int apopfile_existp(char *home, char *suffix, uid_t uid) {
+    struct stat st;
+    int s;
+    int len = strlen(home) + 1
+        + strlen(APOPFILEBASE) + strlen(suffix) + 3;
+    char *apopfile = (char*)malloc(len);
+    if (suffix[0]) {
+        snprintf(apopfile, len, "%s/%s%c%s%c",
+                 home, APOPFILEBASE, XADDR_DELIM, suffix, 0);
+    } else {
+        snprintf(apopfile, len, "%s/%s%c", home, APOPFILEBASE, 0);
+    }
+    seteuid(uid);
+    s = stat(apopfile, &st);
+    seteuid(0);
+    memset(apopfile, '\0', strlen(apopfile));
+    free(apopfile);
+    return !s;
+}
+
+#ifndef QMAILCONTROL
+# define QMAILCONTROL "/var/qmail/control"
+#endif
+#ifndef MAILTMPLEN
+# define MAILTMPLEN 1024
+#endif
+
+/* Convert virtual domain user
+ */
+char* conv_virtualdomain(char *account) {
+  char *dom = strchr(account, '@'), *p;
+  char vd[MAILTMPLEN+1], rewrite[MAILTMPLEN+1], previous[MAILTMPLEN+1];
+  FILE *vdfd;
+  int match=0;
+  char buf[MAILTMPLEN+1], *s;
+  snprintf(vd, MAILTMPLEN, "%s/%s", QMAILCONTROL, "virtualdomains");
+  if (NULL == dom) return account;
+  dom++;		/* set position of domain part beginning */
+  if (dom && NULL != (vdfd = fopen (vd, "r"))) {
+    int l = strlen(dom);
+    int L = strlen(account);
+    while ((s=fgets(buf, MAILTMPLEN, vdfd))) {
+      if (p=strchr(s, '#'))
+        *p = '\0';			/* zap comments */
+      if (!strchr(buf, ':'))
+        continue;
+      while (s && (strrchr(s, '\n') || strrchr(s, '\r') || strrchr(s, ' ')))
+        s[strlen(s)-1] = '\0';
+      if (!strncmp(account, s, L) && s[L] == ':' && s[L+1]) { /* user matches */
+	match = 3;
+        snprintf(rewrite, MAILTMPLEN, "%s-%s", s+L+1, account);
+	break;
+      }
+      if (!strncmp(dom, s, l) && s[l] == ':' && s[l+1]) { /* domain matches */
+        match = 2;
+	snprintf(rewrite, MAILTMPLEN, "%s%c%s", s+l+1, XADDR_DELIM, account);
+	continue;
+      }
+      if (match < 2 && s[0] == '.') { /* if domain described in wildcard */
+        if (p=strchr(s, ':')) {
+	  *p = '\0';
+	  if (!strcmp(dom+(strlen(dom)-strlen(s)), s)) {
+	    if (match == 0
+	        || strlen(previous) < strlen(s)) {
+	      match = 1;
+	      strncpy(previous, s, MAILTMPLEN);
+	      snprintf(rewrite, MAILTMPLEN, "%s%c%s", p+1, XADDR_DELIM, account);
+	    }
+	  }
+	}
+      }
+    }
+    fclose(vdfd);
+    if (match) {
+      p = strchr(rewrite, '@');
+      /* fprintf(stderr, "m=%d, rwr=[%s]\n", match, rewrite); */
+      if (p) {
+        *p = '\0';
+      }
+      /* fprintf(stderr, "rwr=[%s]\n", rewrite); */
+      s = malloc(strlen(rewrite)+1);
+      strncpy(s, rewrite, strlen(rewrite)+1);
+      memset(vd, 0, sizeof(vd));
+      memset(rewrite, 0, sizeof(rewrite));
+      memset(previous, 0, sizeof(previous));
+      return s;
+    }
+  }
+  /* Then, compare with locals */
+  snprintf(vd, MAILTMPLEN, "%s/%s", QMAILCONTROL, "locals");
+  if (NULL != (vdfd=fopen(vd, "r"))) {
+    while (s=fgets(buf, MAILTMPLEN, vdfd)) {
+      if (p=strchr(s, '#')) *p = '\0'; /* zap after comment mark # */
+	while (*s && (strrchr(s, '\r')||strrchr(s, '\n')
+			||strrchr(s, ' ')||strrchr(s, '\t'))) {
+	  *(s+strlen(s)-1) = '\0';
+	}
+	while (*s && (*s == '\t' || *s == ' ')) s++;
+	if (!strncmp(s, dom, strlen(s))) {	/* matches with local domain */
+	  int len = dom-account-1;
+	  p = (char*)malloc(len+1);
+	  memset(p, '\0', len+1);
+	  strncpy(p, account, len);
+	  return p;
+	}
+      }
+  }
+  return NULL; /* invalid domain */
+  /* return account; return itself */
+}
+
+void apopcall(char **args) {
+    int i=0, sc=0;
+    pid_t pid;
+    char *email="", *suffix="", *pass="", *new="", *new2 = "", *home="";
+    char buf[BUFSIZ], auth, *user;
+    FILE *child, *result;
+    while (args[i][0]) {
+        /* printf("[%s]<br>\n", args[i]); */
+        if (!strncmp("email=", args[i], 6)) {
+            email = args[i]+6;
+        } else if (!strncmp("suffix=", args[i], 7)) {
+            suffix = args[i]+7;
+        } else if (!strncmp("pass=", args[i], 5)) {
+            pass = args[i]+5;
+        } else if (!strncmp("new=", args[i], 4)) {
+            new = args[i]+4;
+        } else if (!strncmp("new2=", args[i], 5)) {
+            new2 = args[i]+5;
+        } else if (!strncmp("auth=", args[i], 5)) {
+            /* "this" or "base" or "unix" */
+            auth = args[i][5];
+        }
+        i++;
+    }
+    /* Make a backup of original e-mail address */
+    /* user = (char*)malloc(1+strlen(email));
+       strcpy(user, email);
+     */
+    user = conv_virtualdomain(email);
+    if (NULL == user) {
+      printf("そのようなドメインは無効です(%s)<br>\n", strchr(email, '@'));
+      printf("入力したメイルアドレスを確認してやり直してください.<br>\n");
+      fail();
+    }
+    if (strchr(user, XADDR_DELIM)) {
+	char *p = malloc(1+strlen(user));
+	char *q = NULL;
+	struct passwd *pwd;
+	    /* printf("user=[%s]<br>\n", user); */
+
+	memset(p, '\0', 1+strlen(user));
+	strcpy(p, user);
+	while (!(pwd=getpwnam(p)) && (q=strrchr(p, XADDR_DELIM))) {
+	    fflush(stdout);
+	    *q = '\0';
+	}
+	if (pwd && q) {
+	    q = user+(q-p)+1;
+	    user=p;
+	    suffix=q;
+	}
+    }
+    if (user[0] && new[0] && new2[0]) {
+        int tochild[2], toparent[2];
+        pid_t pid;
+        int argc=0;
+        char **argv;
+        struct passwd *pswd;
+	char *pstr;
+
+        if (!(pswd=getpwnam(user))) {
+            printf("Unkown user %s.\n", user);
+            fflush(stdout);
+            fail();
+        }
+	pstr = pswd->pw_passwd;
+#ifdef SHADOW_PASSWD
+	{  struct spwd *ss = getspnam(user);
+	   pstr = (char*)ss->sp_pwdp;
+	}
+#endif
+        home=pswd->pw_dir;
+        argv = (char**)calloc(4, sizeof(char*));
+        argv[argc++] = "apoppasswd";
+        argv[argc++] = "-s";
+        argv[argc++] = "-c";
+        /* if old password does not exist,
+           then check UNIX password */
+#if 0
+        if (apopfile_existp(home, suffix, pswd->pw_uid)) { /* no apop-ext exists */
+            /* そのまま */
+        } else if (apopfile_existp(home, "", pswd->pw_uid)) {/* check base mail password */
+            argv = (char**)realloc(argv, (argc+2)*sizeof(char*));
+            argv[argc++] = "-b";
+        }
+#endif
+        switch (auth) {
+        case 'b': case 'B':
+            if (apopfile_existp(home, "", pswd->pw_uid)) {
+                argv = (char**)realloc(argv, (argc+2)*sizeof(char*));
+                argv[argc++] = "-b";
+            } else {
+                printf("基本アドレスのパスワードファイルがありません<br>\n");
+                fail();
+            }
+            break;
+        case 'u': case 'U':
+            if (strcmp(pstr, (char*)crypt(pass, pstr))) {
+                printf("UNIX Password not correct.<br>\n");
+                /* printf("[%s]vs.[%s]<br>\n",
+                   pswd->pw_passwd, crypt(pass, pswd->pw_passwd)); */
+                printf("UNIXパスワードと一致しません.<br>\n");
+                fflush(stdout);
+                fail();
+            }
+        }
+
+        if (strlen(new) < 8 || strlen(new2) < 8) {
+            printf("New mail password must be more than 7 characters.<br>\n");
+            printf("メイルパスワードは8文字以上にしてください。<br>\n");
+            fflush(stdout);
+            fail();
+        }
+        if (suffix[0]) {
+            argv = (char**)realloc(argv, (argc+3)*sizeof(char*));
+            argv[argc++] = "-e";
+            argv[argc++] = suffix;
+                
+        }
+        argv[argc++] = NULL;
+        if (setgid(pswd->pw_gid) || 0 != setuid(pswd->pw_uid)) {
+            printf("Cannot switch to %s\n", user);
+	    printf("uid=%d, gid=%d<br>\n", pswd->pw_gid, pswd->pw_uid);
+	    printf("メイルパスワード変更サーバの設定不良の可能性があるので<br>\n");
+	    printf("お手数ですがこの画面のコピーを添えてシステム管理者");
+	    printf("まで御連絡下さい。<br>\n");
+            fflush(stdout);
+            fail();
+        }
+
+        /* OK, start apopasswd */
+        if (pipe(tochild)+pipe(toparent)) {
+            printf("Cannot create pipe\n");
+            fail();
+        }
+        if ((pid=fork()) > 0) {
+            FILE *child = fdopen(tochild[1], "w");
+            close(tochild[0]);
+            close(toparent[1]);
+            fprintf(child, "PASS %s\nNEW %s\nNEW2 %s\n",
+                    pass, new, new2);
+            fflush(child);
+            fclose(child);
+            
+        } else if (pid == -1) {
+            printf("Cannot fork\n");
+            fail();
+        } else {
+            char *pe = malloc(6+strlen(pswd->pw_dir));
+            close(tochild[1]);
+            close(toparent[0]);
+            dup2(tochild[0], 0);
+            dup2(toparent[1], 1);
+
+            /* setuid section */
+
+			strcpy(pe, "HOME=");
+			strcat(pe, pswd->pw_dir);
+            if (putenv(pe)) {
+				puts("ga-n! arichan gakkari<br>");
+			}
+            execv(APOPPASSWD, argv);
+
+            /* setuid section ends */
+            fprintf(stderr, "Cannot exec %s\n", APOPPASSWD);
+            fail();
+        }
+        result = fdopen(toparent[0], "r");
+        while (fgets(buf, BUFSIZ, result)) {
+            printf("%s<br>", buf);
+            fflush(stdout);
+            if (strstr(buf, "Success!")) {
+                printf("<br>Mail Password changed successfully!<br>\n");
+                sc++;
+                break;
+            } else if (strstr(buf, "mismatch")) {
+                printf("二個入れた新パスワードが一致しません.<br>\n");
+                break;
+            } else if (strstr(buf, "Illegal")) {
+                printf("照合用パスワードが違います.<br>--\n");
+                break;
+            } else if (strstr(buf, "does not exist")) {
+                /* try_overwrite(user, pass, new, new2, suffix); */
+                if (suffix[0]) {
+                    printf("%s-%s", user, suffix);
+                } else {
+                    printf("%s", user);
+                }
+                /* ここは来ないことになった(のはず) */
+                printf("というメイルアカウントは未作成です<br>\n");
+                printf("新規に作る場合はOKボタンをクリック\n");
+                put_form(email, pass, new, new2, suffix, 1, 0, 1);
+                fflush(stdout);
+            }
+        }
+        fclose(result);
+        while (wait(0) != pid) {sleep(1);fputc('.', stderr);}
+        if (sc) success(email); else fail();
+    } else if (user[0]) {
+        struct passwd *pw = getpwnam(user);
+        int auth=0;
+        if (!pw) {
+            printf("そのようなユーザはいません %s<br>\n", user);
+            fail();
+        }
+	home=pw->pw_dir;
+        
+	printf("%s というメイルアドレスの<br>\n", email);
+        printf("メイル専用パスワードを変更します.<br>\n");
+        printf("メイルパスワードとUNIXパスワードの違いに気をつけてください.<br>\n");
+        printf("新パスワードは8文字以上にしてください.<br>\n");
+        printf("New password must be more than or equal to 8 characters.<br>\n");
+        if (apopfile_existp(home, suffix, pw->pw_uid)) {
+            auth = 0;           /* this password file */
+	    printf("「古いメイルパスワード」には、現在<br>\n");
+	    printf("<tt>%s</tt><br>\n", email);
+	    printf("を読むために指定しているパスワードを入力します。");
+        } else if (apopfile_existp(home, "", pw->pw_uid)) {
+            auth = 1;           /* basic mail address password */
+	    printf("今回は本人認証として基本メイルアドレスのパスワードを");
+	    printf("入力しますが、新しくパスワードを設定するのは<br>\n");
+	    printf("<tt>%s</tt><br>\n", email);
+	    printf("用のパスワードです。基本メイルアドレスのパスワードは");
+	    printf("変わりませんので注意してください。");
+        } else {
+            auth = 2;           /* UNIX login */
+        }
+        put_form(email, "", "", "", suffix, 0, auth, 0);
+        footer();
+        exit(0);
+    }
+    printf("user=[%s]\n", user);
+}
+
+int main(int argc, char* argv[]) {
+    char *method = getenv("REQUEST_METHOD");
+    char **args;
+    myname = argv[0];
+    if (method && strcmp(method, "POST") != 0) {
+        printf("This program should be used in method:POST.\n");
+        fail();
+    }
+    printf("Content-type: text/html; charset=EUC-JP\n\n");
+    printf("<html>\n<head><title>Change Password</title></head>\n");
+    printf("<body style=\"background: #f0ffff;\">\n");
+    if (getenv("SSL_CIPHER") && getenv("SSL_PROTOCOL")) {
+        args = decode_post();
+        apopcall(args);
+    } else {
+        printf("This program can be used only via SSL connection.<br>\n");
+        printf("このユーティリティはSSL接続時のみ有効です.<br>\n");
+    }
+}
--- a/APOPtools/apoppasswd	Thu Oct 30 00:00:57 2014 +0900
+++ b/APOPtools/apoppasswd	Thu Oct 30 00:03:05 2014 +0900
@@ -208,3 +208,213 @@
     }
     exit 0;
 }
+#!/usr/local/bin/perl
+# Customize these variables.
+# If you change APOPFILEBASE, change the same variable in apopcall.c too.
+# See http://www.gentei.org/~yuuji/software/imapext/
+
+$HOME=$ENV{"HOME"};
+
+$DEFAULTMAILDIR = "Maildir";	# Must be same as ../src/osdep/unix/Makefile
+
+$APOPFILEBASE = ".apop";	# "$HOME/$APOPFILEBASE" is the password file
+# $APOPFILEBASE = "$DEFAULTMAILDIR/apop";
+# $APOPFILEBASE = "Mail/apop";
+
+$ENCODER = "cat";
+# $ENCODER = "gzip";
+# $ENCODER = "uuencode $$|gzip";
+
+$DECODER = "cat";
+# $DECODER = "gzip -dc";
+# $DECODER = "gzip -dc | uudecode";
+
+$DOTQMAIL = ".qmail";		# qmail
+# $DOTQMAIL = ".forward";	# Postfix
+
+$XADDR_DELIM = "-";		# qmail
+# $XADDR_DELIM = "+";		# Postfix
+
+$HERE = ".";			# qmail
+# $HERE = "~";			# Postfix
+
+$EXT = "";
+$force = 0;
+$base = 0;
+
+$APOPFILE = "$HOME/$APOPFILEBASE";
+
+sub handler {
+	system "stty echo";
+	print STDERR "Abort:\n";
+	exit 1;
+}
+
+$SIG{'INT'} = $SIG{'KILL'} = $SIG{'QUIT'} = $SIG{'HUP'} = 'handler';
+
+while ($_=$ARGV[0], /^-.+/ && shift) {
+    if (/^-e/) {
+	$APOPFILE .= $XADDR_DELIM . ($EXT=shift);
+    } elsif (/^-b/) {
+	$base++;
+    } elsif (/^-c/) {
+	$create++;
+    } elsif (/^-s/) {
+	$stream++;
+	# and exit;
+    } elsif (/^-h/) {
+	&usage; # and exit
+    }
+}
+
+sub checkmaildir {
+    local($dotqmail) = ("$HOME/$DOTQMAIL");
+    local($maildir) = ($DEFAULTMAILDIR);	  # default
+    $dotqmail .= "$XADDR_DELIM$EXT" if $EXT;
+    $maildir .= "-$EXT" if $EXT;
+    unless (-f "$dotqmail") {
+	if ($create) {
+	    if (open(DQMAIL, "> $dotqmail")) {
+		print DQMAIL "$HERE/$maildir/\n";
+		print "File [$dotqmail] created\n";
+		close(DQMAIL);
+	    }
+	} else {
+	    print "$dotqmail file does not exist.\n";	# should go to stdout
+	    print "Your should create $maildir first!\n";
+	    print "(-c option automatically makes it)\n";
+	    exit 1;
+	}
+    }
+    if (-s $dotqmail) {
+	$maildir='';
+	if (open(DQMAIL, "< $dotqmail")) {
+	    while (<DQMAIL>) {
+		s/[\r\n \t]*$//g;
+		next if /#/;
+		next unless m,\./.*/,;
+		chop;			  # strip trailing "/"
+		$maildir = $_;
+		last;
+	    }
+	    close(DQMAIL);
+	    $maildir = $DEFAULTMAILDIR if $maildir eq '';
+	    unless (-d "$HOME/$maildir"
+		    && -d "$HOME/$maildir/new"
+		    && -d "$HOME/$maildir/cur"
+		    && -d "$HOME/$maildir/tmp") {
+		if ($create) {
+		    mkdir "$HOME/$maildir", 0700;
+		    mkdir "$HOME/$maildir/new", 0700;
+		    mkdir "$HOME/$maildir/cur", 0700;
+		    mkdir "$HOME/$maildir/tmp", 0700;
+		    print "Maildir [$maildir/] created\n";
+		} else {
+		    print "Maildir($maildir) does not exist\n";
+		    print "Your should do maildirmake $maildir first!\n";
+		    print "(-c option automatically makes it)\n";
+		    exit 1;
+		}
+	    }
+	}
+    }
+}
+
+sub usage {
+    local($mydir, $myname) = ($0 =~ m,(.*)/(.*),);
+    print<<_EOU_;
+$myname	Change Mail password for imap-4.7+qmailapop
+Usage:	$myname [options]
+Options are...
+	-e EXT		Set target email address to "user-EXT"
+	-c		If no .qmail file and Maildir, create them
+
+_EOU_
+    exit 0;
+}
+
+if ($stream) {
+    &stream;
+    exit; # not reached
+}
+$OK=0;
+until ($OK) {
+    system "stty -echo";
+    print STDERR "Enter APOP Password: ";
+    $new1 = <>;
+    print STDERR "\n";
+    if (length($new1) == 1) {
+	print STDERR "Canceled\n";
+	exit 1;
+    } elsif (length($new1) < 9) {
+	print STDERR "Password is too short!  Please use more than 8 chars.\n";
+	next;
+    }
+    print STDERR "Again APOP Password: ";
+    $new2 = <>;
+    if ($new1 eq $new2) {
+	$OK=1;
+    } else {
+	print STDERR "\nPassword mismatch! Try again.\n";
+    }
+}
+#OK
+&checkmaildir;
+system "stty echo";
+open(NP, "| $ENCODER > $APOPFILE") || die "Cannot write on $APOPFILE\n";
+print NP "$new1";
+close(NP);
+chmod 0600, $APOPFILE;
+print STDERR "\nUpdated APOP password successfully.\n";
+
+sub stream {				  # Must match with old password
+    local($PASS, $old, $new1, $new2, $master) = (0);
+    local($masterfile) = ($APOPFILE);
+    $masterfile = "$HOME/$APOPFILEBASE" if $base;
+    exit 1 if ($> == 0);
+    while (<>) {
+	chop;
+	if (/^PASS (.*)$/i) {
+	    $old = $1;
+	} elsif (/^NEW (.*)/i) {
+	    $new1 = $1;
+	} elsif (/^NEW2 (.*)/i) {
+	    $new2 = $1;
+	}
+	last if ("$new1" ne "" && "$new2" ne "");
+    }
+    if (-s $APOPFILE || ($base && -f $masterfile)) { # Already exist
+	if (open(OLD, "$DECODER $masterfile |")) {
+	    ($master = <OLD>) =~ s/[\n\r]$//g;
+	    close(OLD);
+	} else {
+	    print "Old password file corrupted.\n";
+	    print "Please ask to administrator.\n";
+	    exit 1;
+	}
+	if ($master ne $old) {
+	    print "Illegal password\nBye\n";
+	    exit 1;
+	}
+    } 
+    if ($new1 ne $new2) {
+	print "Password(new) mismatch\nBye\n";
+	exit 1;
+    }
+    # OK, now begin to create!
+    &checkmaildir;
+    if (open(P, "| $ENCODER > $APOPFILE")) {
+	# open success
+	print P "$new1\n";
+	close(P);
+	chmod 0600, $APOPFILE;
+	if (-s $APOPFILE) {
+	    print "Success!\n";
+	    exit 0;
+	}
+    } else {
+	print "Cannot output to $APOPFILE\nBye\n";
+	exit 1;
+    }
+    exit 0;
+}
--- a/APOPtools/deapop	Thu Oct 30 00:00:57 2014 +0900
+++ b/APOPtools/deapop	Thu Oct 30 00:03:05 2014 +0900
@@ -2,3 +2,7 @@
 # deapop script for plain password file
 cat "$@"
 
+#!/bin/sh
+# deapop script for plain password file
+cat "$@"
+
--- a/APOPtools/deapop.gzip	Thu Oct 30 00:00:57 2014 +0900
+++ b/APOPtools/deapop.gzip	Thu Oct 30 00:03:05 2014 +0900
@@ -2,3 +2,7 @@
 # deapop script for gzipped password file
 gzcat "$@"
 
+#!/bin/sh
+# deapop script for gzipped password file
+gzcat "$@"
+
--- a/APOPtools/index.html	Thu Oct 30 00:00:57 2014 +0900
+++ b/APOPtools/index.html	Thu Oct 30 00:03:05 2014 +0900
@@ -63,3 +63,68 @@
 <!--#include virtual="/~yuuji/signature.html"-->
 </body>
 </html>
+<html>
+<head>
+<title>
+APOP Password
+</title>
+<style type="text/css">
+<!--
+.e {color: red; text-decoretion: underline;}
+-->
+</style>
+</head>
+
+<body bgcolor="azure">
+<p>$B$"$J$?$N%a%$%k%"%I%l%9@lMQ$N%Q%9%o!<%I$r@_Dj$^$?$O99?7$7$^$9!#(B</p>
+<form method=POST action="./apopcall.cgi">
+<table border="1">
+<tr><td>$B%a%$%k%"%I%l%9(B:<br>User Name:</td>
+ <td><input name="email" size="40" maxlength="40"></td></tr>
+</table>
+<input name="OK" type="submit" value="OK">
+<input name="OK" type="reset" value="Clear">
+</form>
+<ul>
+ <li> $B=i$a$FMxMQ$9$k>l9g(B
+      <p>$B%Q%9%o!<%I$r@_Dj$7$?$$%a%$%k%"%I%l%9$rF~NO$7$F$/$@$5$$!#(B
+      $B%a%$%k@lMQ$N%Q%9%o!<%I$r2a5n$K@_Dj$7$F$$$J$$>l9g$O!"(B
+      $B<!$N2hLL$GK\?MG'>Z$H$7$F(BUNIX$B%Q%9%o!<%I(B($B%5!<%P$K(B
+      $B%m%0%$%s$9$k$H$-$N$b$N(B)$B$rF~NO$7$F$/$@$5$$!#(B</p>
+ <li> $B3HD%%a%$%k%"%I%l%9$N;XDj(B
+      <p>$B4pK\%a%$%k%"%I%l%9$N%f!<%6L>$N8e$m$K(B<span class="e">-$B3HD%;R(B
+      </span> ($B%O%$%U%s(B+$B3HD%;R(B)$B$r2C$($?%"%I%l%9$,3HD%%a%$%k%"%I%l%9$K$J(B
+      $B$j$^$9!#(B<br>
+      $BNc(B:<br>
+      $B4pK\%"%I%l%9(B : user@xxx.hogehoge.ac.jp<br>
+      $B3HD%%"%I%l%9(B : user-foo@xxx.hogehoge.ac.jp<br>
+      ($B$3$N>l9g$N3HD%;R$O(B foo)
+      </p>
+      <p>$B3HD%%a%$%k%"%I%l%9$O!"3HD%;RItJ,$rJQ$($k$3$H$G(B
+      $B2?8D$G$b:n$k$3$H$,$G$-$^$9!#(B
+      $B?75,$K:n@.$7$?$$$H$-$O!"3HD%%a%$%k%"%I%l%9$rF~NO$7$F(BOK$B$r(B
+      $B2!$7$F$/$@$5$$!#?7$7$$%a%$%k%\%C%/%9$r<+F0E*$K:n@.(B
+      $B$9$k$HF1;~$K?73HD%%a%$%k%"%I%l%9@lMQ$N%Q%9%o!<%I$b9T$J$$$^$9!#(B
+      </p>
+</ul>
+<p>$B!Z(B<a href="qmapmore.html">
+$B$3$N%5!<%P$GMxMQ$G$-$k%a%$%k%"%I%l%9$K$D$$$F(B</a>$B![(B</p>
+<hr>
+<ul>
+ <li> At your first trial to set mail password
+      <p>Push [OK] button with your mail address.  We call your
+      mail address <em>YourName</em>@xxx.yyy.jp as `basic email address'.<p>
+
+ <li> To create extensional email address<br>
+
+      <p>On our system, you can have more than one email addresses.  You
+      can create any (mail)account name "YourName-xxx"(where xxx is
+      any extensional word you might give) which will be delivered to you.  To
+      create an extesional email address and/or change the password for
+      it, put the extensional email address in the input window.</p>
+</ul>
+
+<hr>
+<!--#include virtual="/~yuuji/signature.html"-->
+</body>
+</html>
--- a/APOPtools/pop3-age	Thu Oct 30 00:00:57 2014 +0900
+++ b/APOPtools/pop3-age	Thu Oct 30 00:03:05 2014 +0900
@@ -1,62 +1,1 @@
-#!/bin/sh -
-# A sample "POP before SMTP"-enabler script for tcp_wrappers
-# This script should be installed in /usr/local/etc
-# If you are thinking of using this script on heavily loaded host,
-# you had better to choose tcpserver instead of tcp_wrappers.
-# 
-ALLOWTMP="/var/log/ATMP"
-if [ -f /usr/local/etc/hosts.allow ]; then
- ALLOW="/usr/local/etc/hosts.allow"
-else
- ALLOW=/etc/hosts.allow
-fi
-ALLOWSRC=${ALLOW}.src
-ALLOWNEW=${ALLOW}.new
-
-# for debug
-# (env;echo "1=$1") | Mail -s pop3access yuuji
-
-case $0 in
-  *record)
-	echo "tcp-env : $RELAYCLIENT : setenv = RELAYCLIENT" >> $ALLOWTMP.1
-	;;
-  *age)
-	rm -f $ALLOWTMP.2
-	[ -f $ALLOWTMP.1 ] && mv -f $ALLOWTMP.1 $ALLOWTMP.2
-	;;
-  *)
-	# else generate master hosts.allow file
-	;;
-esac
-touch $ALLOWTMP.1 $ALLOWTMP.2
-echo "#
-# DO NOT EDIT THIS FILE!
-# This file is generated from $ALLOWSRC file.
-# Edit it!
-#" > $ALLOWNEW
-(cat $ALLOWTMP.[12] | sort -u; cat $ALLOWSRC) >> $ALLOWNEW
-/bin/mv -f $ALLOWNEW $ALLOW
-
-# pop3-{age,update,record} for tcp_wrappers ends here
-# The following section is the sample routine for tcpserver(ucsp-tcp)
-# If you use tcpserver, replace the above section after "case $0...esac"
-# by the following section.
-# Sample code was contributed by pirozeau(pirozeau@banana-fish.com).
-
-#TCPREMOTEIP=${TCPREMOTEIP:-undefined}
-#RELAYCLIENT=${RELAYCLIENT:-$TCPREMOTEIP}
-#ALLOW=/usr/local/etc/smtprule
-#case $0 in
-#  *record)
-#	echo "$RELAYCLIENT:allow,RELAYCLIENT=\"\"" >> $ALLOWTMP.1
-#	;;
-#  *age)
-#	rm -f $ALLOWTMP.2
-#	[ -f $ALLOWTMP.1 ] && mv -f $ALLOWTMP.1 $ALLOWTMP.2
-#	;;
-#  *)
-#	# else generate master tcprule file
-#	;;
-#esac
-#touch $ALLOWTMP.1 $ALLOWTMP.2
-#(cat $ALLOWTMP.[12] | sort -u; cat ${ALLOW}) | /usr/local/bin/tcprules ${ALLOW}.cdb ${ALLOW}.tmp
+pop3-record
\ No newline at end of file
--- a/APOPtools/pop3-record	Thu Oct 30 00:00:57 2014 +0900
+++ b/APOPtools/pop3-record	Thu Oct 30 00:03:05 2014 +0900
@@ -60,3 +60,65 @@
 #esac
 #touch $ALLOWTMP.1 $ALLOWTMP.2
 #(cat $ALLOWTMP.[12] | sort -u; cat ${ALLOW}) | /usr/local/bin/tcprules ${ALLOW}.cdb ${ALLOW}.tmp
+#!/bin/sh -
+# A sample "POP before SMTP"-enabler script for tcp_wrappers
+# This script should be installed in /usr/local/etc
+# If you are thinking of using this script on heavily loaded host,
+# you had better to choose tcpserver instead of tcp_wrappers.
+# 
+ALLOWTMP="/var/log/ATMP"
+if [ -f /usr/local/etc/hosts.allow ]; then
+ ALLOW="/usr/local/etc/hosts.allow"
+else
+ ALLOW=/etc/hosts.allow
+fi
+ALLOWSRC=${ALLOW}.src
+ALLOWNEW=${ALLOW}.new
+
+# for debug
+# (env;echo "1=$1") | Mail -s pop3access yuuji
+
+case $0 in
+  *record)
+	echo "tcp-env : $RELAYCLIENT : setenv = RELAYCLIENT" >> $ALLOWTMP.1
+	;;
+  *age)
+	rm -f $ALLOWTMP.2
+	[ -f $ALLOWTMP.1 ] && mv -f $ALLOWTMP.1 $ALLOWTMP.2
+	;;
+  *)
+	# else generate master hosts.allow file
+	;;
+esac
+touch $ALLOWTMP.1 $ALLOWTMP.2
+echo "#
+# DO NOT EDIT THIS FILE!
+# This file is generated from $ALLOWSRC file.
+# Edit it!
+#" > $ALLOWNEW
+(cat $ALLOWTMP.[12] | sort -u; cat $ALLOWSRC) >> $ALLOWNEW
+/bin/mv -f $ALLOWNEW $ALLOW
+
+# pop3-{age,update,record} for tcp_wrappers ends here
+# The following section is the sample routine for tcpserver(ucsp-tcp)
+# If you use tcpserver, replace the above section after "case $0...esac"
+# by the following section.
+# Sample code was contributed by pirozeau(pirozeau@banana-fish.com).
+
+#TCPREMOTEIP=${TCPREMOTEIP:-undefined}
+#RELAYCLIENT=${RELAYCLIENT:-$TCPREMOTEIP}
+#ALLOW=/usr/local/etc/smtprule
+#case $0 in
+#  *record)
+#	echo "$RELAYCLIENT:allow,RELAYCLIENT=\"\"" >> $ALLOWTMP.1
+#	;;
+#  *age)
+#	rm -f $ALLOWTMP.2
+#	[ -f $ALLOWTMP.1 ] && mv -f $ALLOWTMP.1 $ALLOWTMP.2
+#	;;
+#  *)
+#	# else generate master tcprule file
+#	;;
+#esac
+#touch $ALLOWTMP.1 $ALLOWTMP.2
+#(cat $ALLOWTMP.[12] | sort -u; cat ${ALLOW}) | /usr/local/bin/tcprules ${ALLOW}.cdb ${ALLOW}.tmp
--- a/APOPtools/pop3-record.postfix	Thu Oct 30 00:00:57 2014 +0900
+++ b/APOPtools/pop3-record.postfix	Thu Oct 30 00:03:05 2014 +0900
@@ -27,3 +27,32 @@
 esac
 touch $OKCLIENT.1 $OKCLIENT.2
 cat $OKCLIENT.1 $OKCLIENT.2 | postmap -r -i hash:$CLIENTACCESS
+#!/bin/sh -
+# A sample "POP before SMTP"-enabler script for Postfix
+# This script should be installed in /usr/local/etc.
+# This script assumes 
+# 
+POSTFIXDIR=/etc/postfix
+POSTFIXBIN=/usr/libexec/postfix
+PATH=$POSTFIXBIN\:$PATH
+OKDIR=/var/log
+OKCLIENT=$OKDIR/ATMP
+CLIENTACCESS=$POSTFIXDIR/client_access
+
+case $0 in
+  *record)
+	echo "$RELAYCLIENT	OK" >> $OKCLIENT.1
+	;;
+  *age)
+	rm -f $OKCLIENT.2
+	[ -f $OKCLIENT.1 ] && mv -f $OKCLIENT.1 $OKCLIENT.2
+	echo '' > $CLIENTACCESS
+	# rm -f $CLIENTACCESS.db
+	postmap hash:$CLIENTACCESS
+	;;
+  *)
+	# else generate master client_access.db
+	;;
+esac
+touch $OKCLIENT.1 $OKCLIENT.2
+cat $OKCLIENT.1 $OKCLIENT.2 | postmap -r -i hash:$CLIENTACCESS
--- a/APOPtools/pop3-update	Thu Oct 30 00:00:57 2014 +0900
+++ b/APOPtools/pop3-update	Thu Oct 30 00:03:05 2014 +0900
@@ -1,62 +1,1 @@
-#!/bin/sh -
-# A sample "POP before SMTP"-enabler script for tcp_wrappers
-# This script should be installed in /usr/local/etc
-# If you are thinking of using this script on heavily loaded host,
-# you had better to choose tcpserver instead of tcp_wrappers.
-# 
-ALLOWTMP="/var/log/ATMP"
-if [ -f /usr/local/etc/hosts.allow ]; then
- ALLOW="/usr/local/etc/hosts.allow"
-else
- ALLOW=/etc/hosts.allow
-fi
-ALLOWSRC=${ALLOW}.src
-ALLOWNEW=${ALLOW}.new
-
-# for debug
-# (env;echo "1=$1") | Mail -s pop3access yuuji
-
-case $0 in
-  *record)
-	echo "tcp-env : $RELAYCLIENT : setenv = RELAYCLIENT" >> $ALLOWTMP.1
-	;;
-  *age)
-	rm -f $ALLOWTMP.2
-	[ -f $ALLOWTMP.1 ] && mv -f $ALLOWTMP.1 $ALLOWTMP.2
-	;;
-  *)
-	# else generate master hosts.allow file
-	;;
-esac
-touch $ALLOWTMP.1 $ALLOWTMP.2
-echo "#
-# DO NOT EDIT THIS FILE!
-# This file is generated from $ALLOWSRC file.
-# Edit it!
-#" > $ALLOWNEW
-(cat $ALLOWTMP.[12] | sort -u; cat $ALLOWSRC) >> $ALLOWNEW
-/bin/mv -f $ALLOWNEW $ALLOW
-
-# pop3-{age,update,record} for tcp_wrappers ends here
-# The following section is the sample routine for tcpserver(ucsp-tcp)
-# If you use tcpserver, replace the above section after "case $0...esac"
-# by the following section.
-# Sample code was contributed by pirozeau(pirozeau@banana-fish.com).
-
-#TCPREMOTEIP=${TCPREMOTEIP:-undefined}
-#RELAYCLIENT=${RELAYCLIENT:-$TCPREMOTEIP}
-#ALLOW=/usr/local/etc/smtprule
-#case $0 in
-#  *record)
-#	echo "$RELAYCLIENT:allow,RELAYCLIENT=\"\"" >> $ALLOWTMP.1
-#	;;
-#  *age)
-#	rm -f $ALLOWTMP.2
-#	[ -f $ALLOWTMP.1 ] && mv -f $ALLOWTMP.1 $ALLOWTMP.2
-#	;;
-#  *)
-#	# else generate master tcprule file
-#	;;
-#esac
-#touch $ALLOWTMP.1 $ALLOWTMP.2
-#(cat $ALLOWTMP.[12] | sort -u; cat ${ALLOW}) | /usr/local/bin/tcprules ${ALLOW}.cdb ${ALLOW}.tmp
+pop3-record
\ No newline at end of file
--- a/APOPtools/qmapmore.html	Thu Oct 30 00:00:57 2014 +0900
+++ b/APOPtools/qmapmore.html	Thu Oct 30 00:03:05 2014 +0900
@@ -185,3 +185,190 @@
 <hr>
 </body>
 </html>
+<html>
+<head>
+<title>
+APOP Password
+</title>
+<style type="text/css">
+<!--
+h1 {text-align: center; text-decoration: underline;}
+h2 {color: navy; background-color: lavender;}
+.e {color: red; text-decoretion: underline;}
+dt (background-color: yellow;}
+-->
+</style>
+</head>
+
+<body bgcolor="azure">
+<h1>
+ $BK\%a%$%k%5!<%P$K4X$9$kMxMQ<T>\:Y>pJs(B
+</h1>
+<p>$BL\<!(B</p>
+<ul>
+ <li> <a href="#extaddress">$BK\%5!<%P$GMxMQ$G$-$k%a%$%k%"%I%l%9(B</a>
+ <li> <a href="#APOP">$B%a%$%k<u?.;~$N%W%m%H%3%k$K$D$$$F(B</a>
+ <li> <a href="#forward">$BB>$N%a%$%k%5!<%P$X$NE>Aw(B</a>
+</ul>
+<hr>
+
+<h2>
+ <a name="extaddress">$BK\%5!<%P$GMxMQ$G$-$k%a%$%k%"%I%l%9(B</a>
+</h2>
+<p>$BK\%5!<%P$G$O%a%$%kG[Aw%7%9%F%`$H$7$F(Bqmail$B$rMxMQ$7$F$$$k$N$G!"(B
+$BMxMQ<T$N3'$5$s$O2?8D$G$b%a%$%k%"%I%l%9$r:n$k$3$H$,$G$-$^$9!#(B
+$B0J2<$N@bL@$G$O!"8D?M$N%a%$%k%"%I%l%9$N%"%+%&%s%HL>ItJ,$r(B
+<var>user</var>$B!"%I%a%$%sL>ItJ,$r(B <var>dokkano.ac.jp</var> $B$H(B
+$BI=$9$3$H$K$7$^$9!#$D$^$j!"Nc$G;HMQ$9$k%a%$%k%"%I%l%9$O(B
+<var>user@dokkano.ac.jp</var>$B$H$J$j$^$9!#$3$N%"%I%l%9$O8f<+?H$N$b$N$HCV(B
+$B$-49$($F@bL@$rFI$_?J$a$F$/$@$5$$!#(B</p>
+
+<dl>
+ <dt> $B!Z4pK\%a%$%k%"%I%l%9![(B
+ <dd> <p><var>user@dokkano.ac.jp</var>$B$r4pK\%a%$%k%"%I%l%9$H8F$S$^$9!#%"(B
+      $B%+%&%s%H:n@.$HF1;~$KL5>r7o$GMxMQ$G$-$k%a%$%k%"%I%l%9$G$9!#$3$N%"%I(B
+      $B%l%9$KFO$$$?%a%$%k$O%5!<%P>e$N$"$J$?@lMQ$N%a%$%k%\%C%/%9$KC_$($i$l(B
+      $B$^$9!#JL$N%"%I%l%9$KE>Aw$9$k$3$H$b2DG=$G$9$,!"J}K!$O8e=R$7$^$9!#(B</p>
+
+ <dt> $B!Z3HD%%a%$%k%"%I%l%9![(B
+ <dd> <p><var>user<span class="e">-xxx</span>@dokkano.ac.jp</var>$B$H$$$&(B
+      $B7A<0$N%"%I%l%9$r3HD%%a%$%k%"%I%l%9$H8F$S$^$9!#$"$J$?$N%"%+%&%s%HL>(B
+      $B$G;O$^$j!"$=$ND>8e$K%O%$%U%s(B(<span class="e">-</span>)$B$G6h@Z$C$FG$(B
+      $B0U$NJ8;zNs$,Mh$k%a%$%k%"%I%l%9$O!"A4$F$"$J$?08$KG[Aw$5$l$^$9!#(B
+      <var>user<span class="e">-xxx</span></var>$B$N(B<var>xxx</var>$B$NItJ,$O(B
+      <span class="e">$B3HD%;R(B</span>$B$H8F$S!"$I$s$JC18l$G$b9=$$$^$;$s!#(B
+      <var>user-123@dokkano.ac.jp, user-job@dokkano.ac.jp,
+      user-meeting@dokkano.ac.jp, ...</var>$B$J$I$J$I!"$I$s$J%a%$%k%"%I%l(B
+      $B%9$G$b<+J,MQ$K:n@.$9$k$3$H$,$G$-$^$9!#(B
+      </p>
+</dl>
+
+<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
+$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
+<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
+$B$?$$%a%$%k%"%I%l%9$r(B<var>user<span
+class="e">-xxx</span>@dokkano.ac.jp</var> $B$N7A<0$GF~NO$7$F@h$K?J$a$P<+F0(B
+$BE*$K%a%$%k%\%C%/%9$N:n@.$^$G40N;$7$^$9!#$3$N$H$-!"$"$J$?K\?M$N3NG'$H$7$F(B
+$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
+$B$@$5$$!#(B</p>
+
+<h2>
+ <a name="APOP">$B%a%$%k<u?.;~$N%W%m%H%3%k$K$D$$$F(B</a>
+</h2>
+<p>$B8=:_9-$/MxMQ$5$l$F$$$k%a%$%k<u?.%W%m%H%3%k$G$"$k(BPOP3$B$O!"(B
+$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
+$B$^$&$N$G!"4JC1$KK5<u$5$l$k$*$=$l$,$"$j$^$9(B($B8=6b<+F0;YJ'5!$NA0$G0E>ZHV9f(B
+$B$r@<$K=P$7$J$,$i2!$7$F$$$k;Q$rA[A|$7$F$/$@$5$$(B)$B!#(B</p>
+
+<p>$B$=$N$h$&$J4m81@-$r9MN8$7$FK\%5!<%P$G$O0J2<$N@_Dj$r9T$J$C$F$$$^$9!#(B</p>
+<ul>
+ <li> POP3$B$O2f!9$NAH?%Fb%M%C%H%o!<%/$+$i$N$_MxMQ$r5v2D(B<br>
+      ($BFbIt%M%C%H%o!<%/$K$OIt30<T$O4JC1$K$OF'$_9~$a$J$$$N$G4vJ,0BA4$G$9(B)
+ <li> $B$=$l0J30$N>l=j$+$i$N<u?.$G$O(BAPOP$B$N$_$r5v2D(B
+</ul>
+<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
+$BK5<u$5$l$?$H$7$F$b85$N%Q%9%o!<%I$O2rFI$G$-$^$;$s!#(BAPOP$B$rMxMQ$9$k>l9g$O$"(B
+$B$i$f$k>l=j$+$i$N%a%$%k$N<u?.$,2DG=$K$J$j$^$9!#0BA4@-$r9M$($k$H!"2>$KFbIt(B
+$B$+$i$7$+MxMQ$7$J$$>l9g$G$b(BAPOP$B$rMxMQ$5$l$k$3$H$r6/$/$*4+$a$7$^$9!#(B</p>
+
+<p>APOP$B$rMxMQ$9$k$?$a$NJ}K!$r@bL@$7$^$9!#$J$*!"0J2<$N%a%$%k%j!<%@$G$O(B
+APOP$B$,(B<span class="e">$BMxMQ$G$-$^$;$s(B</span>$B$N$G$4Cm0U$/$@$5$$!#(B</p>
+<dl>
+ <dt> $B!Z(BAPOP$B$K(B<span class="e">$BBP1~$7$F$$$J$$(B</span>$B<g$J%a%$%k%j!<%@![(B
+ <dd> Microsoft Outlook Express<br>
+      Microsoft Outlook<br>
+      Netscape Messenger
+ <dt> $B!Z(BAPOP$B$KBP1~$7$F$$$k<g$J%a%$%k%j!<%@![(B
+ <dd> <ul>
+       <li> Windows$BMQ(B<br>
+	    <a href="http://www.almail.com/">AL-Mail</a>
+	    ($B%7%'%"%&%'%"(B/$B3X@8!&3X=Q5!4XMxMQ$N$_L5NA(B),<br>
+	    <a href="http://www.rimarts.co.jp/becky-j.htm">Becky!</a>
+	    ($B%7%'%"%&%'%"(B),<br>
+	    <a href="http://denshin8.esprix.net/">$BEE?.H,9f(B</a>
+	    ($B%U%j!<%=%U%H%&%'%"(B),<br>
+	    <a href="http://www.eudora.ne.jp/">Eudora</a>
+	    (3$B<oN`$N%i%$%;%s%97ABV(B)
+       <li> UNIX$BMQ(B($B0J2<A4$F%U%j!<%=%U%H(B)<br>
+	    <a href="http://www.mew.org/index-j.html">Mew</a>,<br>
+	    <a href="http://www.gohome.org/wl/index.ja.html">
+	    Wanderlust</a>
+      </ul>
+</dl>
+<p>$B0J2<$K$$$/$D$+$N%a%$%k%j!<%@$N(BAPOP$B@_DjJ}K!$r<($7$^$9!#(B</p>
+<dl>
+ <dt> $B!L(BAL-Mail$B!M(B
+ <dd> <ol>
+       <li> $B@_Dj$7$?$$%"%+%&%s%H$rA*$V(B
+       <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
+	    $B%K%e!<$N!"!V%"%+%&%s%H!W2hLL$K$F1&2<$N!V9bEY$J@_Dj!W$r%/%j%C(B
+	    $B%/(B
+       <li> $B!V9bEY$J@_Dj!W%&%#%s%I%&$N:82<!V(BAPOP$B$GG'>Z!W$r%A%'%C%/(B
+      </ol>
+ <dt> $B!L(BBecky!$B!M(B
+ <dd> <ol>
+       <li> $B!V%D!<%k(B(T)$B!W"*!V@_Dj!W$G=P$k%&%#%s%I%&$G(B [$B%"%+%&%s%H(B]
+	    $B$rA*Br(B
+       <li> [$B%"%+%&%s%H(B]$B@_Dj%&%#%s%I%&$N2<$K$"$k(B [$B$=$NB>(B] $B$r(B
+	    $B%/%j%C%/(B
+       <li> $B%&%#%s%I%&2<It$N(B [APOP$B$r;H$&(B] $B$r%A%'%C%/(B
+      </ol>
+ <dt> $B!L(BEudora 4$B!M(B
+ <dd> <ol>
+       <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
+	    $BB&%&%#%s%I%&$K=P$9(B
+       <li> APOP$B@_Dj$7$?$$%"%+%&%s%H$r1&%/%j%C%/$7!VJQ99(B(P)$B!W$rA*$V(B
+       <li> $B!V%a!<%k$N<u?.!W%a%K%e!<$rA*Br(B
+       <li> $B%&%#%s%I%&$N0lHV2<$N(B [$BG'>ZJ}<0(B] $B$G(BAPOP$B$r%A%'%C%/(B
+      </ol>
+
+ <dt> $B!L(BMew$B!M(B
+ <dd> <p>~/.im/Config $B$N(B Imget.Src $B9T$N@_Dj$r0J2<$N$h$&$KJQ$($^$9!#(B</p>
+      <blockquote>
+       <p><tt>Imget.Src=pop/<span class="e">APOP</span>:user@$B%5!<%PL>(B</tt></p>
+      </blockquote>
+ <dt> $B!L(BWanderlust$B!M(B
+ <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>
+      <blockquote>
+       <p><tt>&amp;user<span class="e">/apop</span>@$B%5!<%PL>(B</tt></p>
+      </blockquote>
+  <hr>
+</dl>
+<p>$B0J>e$N$$$:$l$N>l9g$b!"3HD%%a%$%k%"%I%l%9$r<u?.$7$?$$$H$-$O%f!<%6L>$H(B
+$B$7$F(B user-xxx $B$N$h$&$J3HD%;RIU$NL>A0$r;XDj$7$^$9!#(B</p>
+
+<h2>
+ <a name="forward">$BB>$N%a%$%k%5!<%P$X$NE>Aw(B</a>
+</h2>
+<p>$BK\%5!<%P$KFO$$$?$"$J$?08$N%a%$%k$r!"JL$N%5!<%P$G4IM}$7$F$$$k%a%$%k%"(B
+$B%I%l%9$KE>Aw$9$k>l9g$O!"%[!<%`%G%#%l%/%H%j$K$"$k(B .qmail $B$H$$$&%U%!%$%k$K(B
+$BE>Aw@h$r=q$-$^$9!#(B</p>
+<ol>
+ <li> FTP$B%/%i%$%"%s%H%=%U%H$rMxMQ$7$F$3$N%5!<%P$K%m%0%$%s$9$k(B
+ <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
+      $B%$%k$,$"$k$N$G$3$l$r<j85$N(BPC$B$K%3%T!<$9$k(B
+ <li> $B%a%bD"(B(Notepad.exe)$B$J$IE,Ev$J%F%-%9%H%(%G%#%?$rMxMQ$7$F$3$N%U%!%$(B
+      $B%k$rJT=8$70J2<$N$h$&$K=q$-49$($F%;!<%V$9$k(B
+      <blockquote>
+       <tt>&amp;user2@tensosaki.co.jp</tt>
+      </blockquote>
+      ($B>e5-$NNc$G$O(B <tt>user2@tensosaki.co.jp</tt> $B$,E>Aw@h%"%I%l%9(B)
+ <li> FTP$B%/%i%$%"%s%H%=%U%H$G:FEY(B .qmail $B%U%!%$%k$r%5!<%P>e$KE>Aw$9$k(B
+</ol>
+<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
+$B;D$7$?$$>l9g$O(B .qmail $B%U%!%$%k$K85!9$"$C$?(B ./Maildir/ $B$H$$$&9T$r>C$5$:$K(B
+$BE>AwMQ$N9T$rDI2C$7$^$9!#(B</p>
+<blockquote>
+<pre>./Maildir/
+&amp;user2@tensosaki.co.jp</pre>
+</blockquote>
+<h3>
+ $BCm0U(B!
+</h3>
+<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
+ftp$B@\B3$bFbIt$+$i$NMxMQ$N$_$K@)8B$7$F$$$^$9!#$I$&$7$F$b30It%M%C%H%o!<%/(B
+$B$+$i(BFTP$B$rMxMQ$9$kI,MW$,$"$k>l9g$O4IM}<T$^$G$4AjCL$/$@$5$$!#(B</p>
+
+<hr>
+</body>
+</html>
--- a/APOPtools/with-tcpserver/0README	Thu Oct 30 00:00:57 2014 +0900
+++ b/APOPtools/with-tcpserver/0README	Thu Oct 30 00:03:05 2014 +0900
@@ -1,3 +1,13 @@
+
+This directory contains sample files for maintaining ipop3d via daemontools.
+
+
+# mkdir /var/qmail/ipopd
+# cp -r * /var/qmail-ipopd
+
+Edit copied files and change the loggin user-id in log/run.
+
+# ln -s /var/qmail/ipopd /service
 
 This directory contains sample files for maintaining ipop3d via daemontools.
 
--- a/APOPtools/with-tcpserver/Makefile	Thu Oct 30 00:00:57 2014 +0900
+++ b/APOPtools/with-tcpserver/Makefile	Thu Oct 30 00:03:05 2014 +0900
@@ -1,3 +1,11 @@
+#
+TCPDIR=/usr/local/bin
+TR=${TCPDIR}/tcprules
+
+all: pop.cdb
+
+pop.cdb:	pop
+	cat $> | ${TR} $@ pop.tmp
 #
 TCPDIR=/usr/local/bin
 TR=${TCPDIR}/tcprules
--- a/APOPtools/with-tcpserver/log/run	Thu Oct 30 00:00:57 2014 +0900
+++ b/APOPtools/with-tcpserver/log/run	Thu Oct 30 00:03:05 2014 +0900
@@ -3,3 +3,8 @@
 PATH=/bin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin \
 setuidgid nobody \
 multilog t ./main
+#!/bin/sh
+exec env - \
+PATH=/bin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin \
+setuidgid nobody \
+multilog t ./main
--- a/APOPtools/with-tcpserver/pop	Thu Oct 30 00:00:57 2014 +0900
+++ b/APOPtools/with-tcpserver/pop	Thu Oct 30 00:03:05 2014 +0900
@@ -1,3 +1,6 @@
 127.0.0.:allow,INTRANET=""
 10.0.0.0-127:allow,INTRANET=""
 all:allow
+127.0.0.:allow,INTRANET=""
+10.0.0.0-127:allow,INTRANET=""
+all:allow
--- a/APOPtools/with-tcpserver/run	Thu Oct 30 00:00:57 2014 +0900
+++ b/APOPtools/with-tcpserver/run	Thu Oct 30 00:03:05 2014 +0900
@@ -3,3 +3,8 @@
 exec env - \
 PATH=/bin:/usr/bin:/usr/sbin:/var/qmail/ipopd:/usr/local/bin:/usr/local/etc \
 tcpserver -HR -c40 -x/var/qmail/ipopd/pop.cdb 0 pop3 ipop3d 2>&1
+#!/bin/sh
+# ipoper should be located in one of the $PATH elements.
+exec env - \
+PATH=/bin:/usr/bin:/usr/sbin:/var/qmail/ipopd:/usr/local/bin:/usr/local/etc \
+tcpserver -HR -c40 -x/var/qmail/ipopd/pop.cdb 0 pop3 ipop3d 2>&1
--- a/Makefile	Thu Oct 30 00:00:57 2014 +0900
+++ b/Makefile	Thu Oct 30 00:03:05 2014 +0900
@@ -253,7 +253,9 @@
 #	British.  As of 2005, the Julian calendar and the Gregorian calendar
 #	diverge by 15 days.
 
-EXTRACFLAGS=
+# EXTRACFLAGS=-DQMAIL -DRESTRICT_POP -DXADDR_DELIM="+" -DDOTQMAIL=".forward"
+## EXTRACFLAGS=-DQMAIL -DRESTRICT_POP
+EXTRACFLAGS=-DQMAIL -DRESTRICT_POP -DINET6
 
 
 # Extra linker flags (additional/alternative libraries, etc.)
@@ -729,6 +731,7 @@
 clean:
 	@echo Removing old processed sources and binaries...
 	$(SH) -c '$(RM) an ua OSTYPE SPECIALS c-client mtest imapd ipopd mailutil mlock dmail tmail || true'
+	$(SH) -c '$(RM) ip6 || true'
 	$(CD) tools;$(MAKE) clean
 
 
--- a/README.maildir	Thu Oct 30 00:00:57 2014 +0900
+++ b/README.maildir	Thu Oct 30 00:03:05 2014 +0900
@@ -91,3 +91,96 @@
 Industrivagen 4
 SE-194 77 Upplands Vasby
 SWEDEN
+Pine 4.0x Maildir c-client module
+---------------------------------
+
+Written by Mattias Larsson <ml@techno.org> <mta@freeit.com>
+
+This is the second release of my Maildir driver for Pine 4. It is based
+on Eric Greens IMAP2bis Maildir driver.
+
+PLEASE NOTE that this driver has only been tested in the IMAP4rev1 daemon
+before. It was just put into Pine 4.00, and it looks like it works, but it
+has not been extensively tested. It has been running for 8 months in
+production in our IMAP4 daemon though.
+
+PLEASE NOTE:
+
+This driver needs to store the UID's of the message in the file somehow. In
+the earlier versions of this driver this was done by adding a new maildir
+flag (the ,3 flag), however, this solution was not very good since most
+other clients could not handle it. Thus I had to find another solution. In
+this driver I use a pretty radical method. Any file in the maildir with the
+execute bit set has its UID set in the mtime of the file. So you should not
+edit the files in here, or in any otherway update the mtime, because then
+the UID gets changed. Most clients should not do this, so I think this
+solution is compatible with most other clients (if you find one that isn't,
+let me know). If you for some reason have to edit a file in the Maildir,
+delete the ".uidvalidity" file in the root of the Maildir (ie, the dir where
+you find cur/ new/ and tmp/). Alternatively, edit maildir.c and define the
+NO_UID_VALIDITY option, which will cause the Maildir to get set new UID's on
+every start up. Note that if you are running IMAP and Netscape as a client,
+you can't change the UID's, because Netscape do not support the UID validity
+flag in the IMAP protocol. So use this with care. 
+
+Please edit the maildir.c file in any case. There are 3 options you can
+set yourself. The default configuration is not suitable for ISPs. If you are
+an ISP, or system with many users, you might want to consider setting some
+of the options different.
+
+Ohh, if there are problems compiling it, let me know, and please let me know
+what you did to fix it. This thing was developed on Solaris (using both GCC
+and SunCC, should work with both), but I haven't tried it on any other
+platform. It is also known to compile cleanly on Linux RH5.1
+
+CONFIGURATION
+-------------
+
+There are a few configurable options. You find these at the top of the
+maildir.c file (and it can be found in imap/src/osdep/unix if I'm not all
+mistaken). Right now, two options are configurable. By default it is
+configured for ISP use, something that you might want to change if you use
+it at home.
+
+HOW TO USE
+----------
+
+Use it as any other c-client driver. There is some option you want to change
+if you want all folders to be created as Maildirs (and I can't remember what
+the option is from the top of my head). Read the pine documentation.
+
+CHANGES
+-------
+
+Rel 4.  Coredump problem fixed. In release 3 I decided to user the sparep
+	in the message cache so no patching of mail.h would be necessary,
+	however, PINE uses this pointer internally for other things, causing
+	coredumps when used with the Rel 3. patch.
+
+Rel 3.	New way of storing UID's (compatible with ,2 clients).
+	Multiple inbox patches applied
+
+Rel 2.  Pine 4 changes.
+
+Rel 1.  Imap4rev 1 driver
+
+FINAL NOTES
+-----------
+
+I'll try to maintain and release new versions as soon as I have time over,
+which unfortunately does not happen very often in this business ;)
+
+You can (might) find newer versions of this driver at:
+
+http://www.freeit.com/mta/
+
+
+Regards,
+Daniel Mattias Larsson
+
+e-mail: ml@techno.org
+ph: +46-707-268785
+snail-mail:
+Industrivagen 4
+SE-194 77 Upplands Vasby
+SWEDEN
--- a/README.qmailapop	Thu Oct 30 00:00:57 2014 +0900
+++ b/README.qmailapop	Thu Oct 30 00:03:05 2014 +0900
@@ -364,3 +364,369 @@
 	用いて生じた如何なる結果に対しても著作権者は責任を負いません。
 
 						2009/9/14 yuuji@gentei.org
+//
+// qmail+maildir+apop+virtualdomain+POPbeforeSMTP extensions to uw-imapd
+// Japanese Document below
+//
+
+[Comentary]
+This patch kit enables uw-imapd to handle;
+  * maildir
+  * qmail's extended mail addresses of user (~/.qmail-ext)
+  * Postfix's extended mail addresses of user (~/.forward+ext)
+  * Accesses to extended mail addresses (authenticated with ~/.apop-ext)
+  * Virtual domain user switching
+
+Because this package is produced those who want to avail all features above,
+we recommend you to turn on all switches for every extension.
+Please let me recommend you not to use plain POP3 with this package.
+If you want to cling onto POP3, please use qmail-pop3d which comes with
+qmail distribution.
+
+[Configuration]
+You can select these compilation switches.
+
+  Where:	./Makefile
+  Switch:	QMAIL
+  What:		Support maildir and user's address extension.
+  		This switch is requisite.
+  
+  Where:	./Makefile
+  Switch:	INET6
+  What:		Support IPv6 address
+  		WORKS fine only via ucspi-tcp+ipv6patch
+  		If you are using tcpserver-ipv6, set this.
+  
+  Where:	./Makefile
+  Switch:	POSTFIX
+  What:		Defaults user address file to ~/.forward and
+		extension delimiter to "+".
+		Setting this flag on is equavalent to declare
+		-DQMAIL -DDOTQMAIL=".forward" -DXADDR_DELIM="+"
+		in ./Makefile.
+  
+  Where:	./Makefile
+  Switch:	RESTRICT_POP
+  What:		Restrict POP3 access from unsafe network.  Allow
+		normal pop3 access only when environment variable
+		INTRANET is set.  This can be controled by tcpd with
+		/etc/hosts.allow.
+  
+  Where:	./src/osdep/unix/Makefile
+  Switch:	DEFAULTMAILDIR (quoted string)
+  What:		Default users' maildir directory when a user does not
+		have ~/.qmail file.
+		The default value is null.  If null, the default value in
+		osdep/unix/maildir.c("Maildir") will be taken.
+  
+  Where:	./src/osdep/unix/Makefile
+  Switch:	QMAILCONTROL (quoted string)
+  What:		Default qmail/control directory.
+		The default value is "/var/qmail/control"
+  
+  Where:	./src/osdep/unix/Makefile
+  Switch:	USERAPOPFILE (string)
+  What:		User's APOP password file relative to their home dir.
+		".apop" is set by default.
+  		One of recommended values is "Mail/.apop".
+		NOTE THAT USERAPOPFILE should NOT be readable by others.
+		Do chmod 600 USERAPOPFILE.
+  
+  Where:	./src/osdep/unix/Makefile
+  Switch:	APOPOPEN (string)
+  What:		Command name to decode APOP password from USERAPOPFILE
+		"/usr/local/sbin/deapop" is set by default.
+  		NOTE THAT you should install deapop command too.
+		If you don't want to think about this,
+		install the following shell script into /usr/local/sbin/deapop
+
+		  #!/bin/sh
+		  cat "$@"
+
+  Where:	./src/osdep/unix/Makefile
+  Switch:	POPBEFORESMTP
+  What:		Turn on `POP before SMTP' feature.
+  		The next variable POP3RECORDER takes effect when
+		this variable is defined.
+
+  Where:	./src/osdep/unix/Makefile
+  Switch:	POP3RECORDER (string)
+  What:		Command name to achieve `POP before SMTP'.
+		"/usr/local/etc/pop3-record" is set by default.
+  		This recorder program should take one argument of
+		fully qualified hostname (or IP address) where the POP
+		authentication is passed to.
+
+[NO WARRANTY]
+
+	This package  comes from absolutely NO WARRANTY.   The author of
+	this package is  not responsible for any result  caused by using
+	this software.  The  copyright of the extension part  is held by
+	HIROSE, Yuuji [yuuji@gentei.org].
+
+[COPYING]
+
+	You can re-distribute this  package without any cost except some
+	practical cost(magnetical  media or so).   Although this package
+	basically obeys  the license  terms in a  file CPYRIGHT  in this
+	directory,  there is  one exception;  when you  modify  the code
+	against   the  extensional   part  (over   uw-imapd)   and  that
+	modification is a kind of bug-fix, modification should be telled
+	to  the  author of  extensional  part  if  you are  thinking  of
+	re-distribute your modification  to the public.  This limitation
+	is  to aim  to  make this  extensional  package reasonably  safe
+	always in any time.  Please feel free to hack and distribute it!
+
+
+-- Japanese document follows...
+
+【qmail+maildir+APOP用POPサーバ】
+
+	このimapパッケージは、qmailとIMAPを組み合わせて使うこと *ではな
+	く* qmail+maildir+APOPを柔軟に利用しようということを目的として作
+	られましたのでIMAPでのテストは十分に行なわれていません。このパッ
+	ケージは以下のような方を満足させるでしょう。
+
+	* qmailを利用している
+	* mail spool には安全性の高い Maildir 形式を利用し(させ)ている
+	* ~/.qmail-ext ファイルによるqmailの拡張アドレスをよく利用している
+	* virtual domain を活用しまくっている
+
+	上記のようなことができるqmailですが、この機能を使いこなすために
+	はUNIXマシンにログインしてローカルファイルを見に行くメイルリーダ
+	を使うという方法しかありませんでした。これでは不便なので、上記の
+	使い分けを認識するPOPサーバを作ろうということで作成したのがこの
+	パッケージです。またPOPのみのサーバ利用が多い昨今、リモートから
+	の認証にログインパスワードを使わずにメイル専用パスワードを利用さ
+	せる変更も行なっています。これによりPOPもAPOP(POPのパスワード認
+	証の暗号化版)も共通のパスワードを利用できるようにしました。また、
+	POP の場合は既存ユーザのパスワード管理を考えて、認証時にUNIXパス
+	ワードも参照するようにしています。
+
+	もう一点、POPはパスワードをプレインテキストで流すため、外部ネッ
+	トワークからの利用は危険です。そこでPOPの利用を一部のネットワー
+	クに限定する機能もつけました(tcp_wrappersやtcpserverが必要)。
+
+【インストール】
+
+	デフォルト設定では
+
+	* POP3は拒否する
+	* ユーザのパスワード設定ファイルは ~/.apop
+	* ~/.apop のデコードプログラムは /usr/local/sbin/deapop
+
+	となっています。APOP認証はサーバ側で必ず元のパスワードを知る必要
+	があります。これまでのAPOPサーバは全てのユーザ毎に管理者権限でパ
+	スワードを設定する必要がありました。一見安全そうですが、じつはユー
+	ザがパスワードを変更する頻度を限りなくゼロに近づけているだけです。
+	そもそもAPOPはサーバ側で元パスワードを取得する必要があるので必ず
+	復元可能な形で保存されなければなりません。ということはどんなに凝っ
+	た方法で保存しても結局は復号できるのですから、複雑な方法で暗号化
+	&格納をすることは手間を増やすだけです。いずれにしてもroot権限さ
+	えあれば元のパスワードは簡単に読めるわけですから、最初からユーザ
+	自身にパスワード管理をさせてしまっても何ら問題は無く、むしろその
+	方がパスワードをこまめに変えてくれる可能性が(ちょりっと)上がりま
+	す。ただし、誰にでもパスワードが読めては困るので、パスワードファ
+	イルを chmod 600 しておかないとメイルの取り込みが出来ないように
+	なっています。またどうしても平文でファイルに保存するのだけはいや
+	だーという場合のために、APOPパスワードファイルは 
+	/usr/local/sbin/deapop というコマンドを経由して読み込むようになっ
+	ています。これにデコードする処理を書いておきます。もし、とくにエ
+	ンコードしなくてもいいという場合は
+
+	  #!/bin/sh
+	  cat "$@"
+
+	というシェルスクリプトでも入れておいてください。このパスワードは
+	ログインパスワードとは独立しているのでこれで大きな問題は起こらな
+	いでしょう(責任は持ちませんが:-)。
+
+	コンパイル時の変数は上記英文解説の場所を読んでください。
+
+【ユーザから見た使い方】
+
+	まず、~/.qmail に正しくmaildirが設定されていることを確認します。
+	maildirをまだ作っていない場合は、
+	
+	% /var/qmail/bin/maildirmake ~/maildir
+
+	とし、~/.qmail に
+
+	./maildir/
+
+	と書きます。またメイル専用パスワードを ~/.apop に記録します。
+	これは apoppasswd コマンドで行ないます。
+
+	% apoppasswd
+
+	これで完了です。apoppasswdコマンドは APOPtools/apoppasswd にある
+	ので管理者がサイトの環境に手直しした上で一般ユーザのPATHの通る場
+	所にインストールして使って下さい。
+
+	さて、拡張アドレスを使いましょう。ログイン名を login とします。
+	login-isogi@hogehoge.co.jp のようなアドレスは ~/.qmail-isogi とい
+	うファイルで作成できます。login-isogi 用のmaildirを作ります。
+
+	% /var/qmail/bin/maildirmake ~/isogidir
+
+	これを ~/.qmail-isogi に登録します。
+
+	./isogidir/
+
+	最後に login-isogi 用のパスワードを設定します。
+
+	% apoppasswd -e isogi -c
+	Enter APOP Password:
+
+	とすると、maildirの作成とパスワードの設定が同時に行えます。
+	maildirとパスワードの作成が完了したら、利用してるメイルリーダの
+	APOP アカウントの「アカウント名」をlogin-isogi にして接続します。
+
+【POP before SMTPについて】
+
+	まず tcp_wrappers を利用している場合について説明します。
+	tcpserverを利用する場合も原理は同じなので仕組みだけ理解してくだ
+	さい。
+
+	tcp_wrapperとtcp-envを組み合わせてSMTPサーバを中継用に使うドメイ
+	ンを限定して使っていると思います。これの発展形でPOP接続して来た
+	ドメインだけにSMTPサーバを使わせる手法のことを "POP before SMTP" 
+	と呼びます。このパッケージでも APOP 接続をしたドメインに対して
+	SMTPの中継許可を与えることが出来ます。本パッケージの ./APOPtools 
+	ディレクトリにある pop3-* を /usr/local/etc にインストールします。
+	3つのファイルの実体は同じです。さらに以下の作業をします。
+
+	* 原本となる /etc/hosts.allow を /etc/hosts.allow.src にコピー
+	* crontab で10分毎に /usr/local/etc/pop3-age を起動させる
+
+	後者は、大抵のOSの場合 root の crontab に
+
+	     */10  *  *  *  *   root    /usr/local/etc/pop3-age
+
+	などと書けば設定できます。pop3-* スクリプトは自身の環境に合わせ
+	て適宜修正して下さい。この段階で、tcp_wrapper の定義ファイルは 
+	/etc/hosts.allow.src が大元で、/etc/hosts.allow はcronによって自
+	動生成されるものとなります。hosts.allowをいじっても自動的に上書
+	きされてしまうので、設定を変えるときは *必ず hosts.allow.src を
+	編集する* ことに注意して下さい。
+
+	さらにipop3dを起動するときに接続してきたホストが環境変数
+	RELAYCLIENT に入るようにしておきます。/etc/inetd.conf でipop3dを
+	起動するときに tcp_wrapper 経由となることを確認します。
+
+	[/etc/inetd.conf]
+	  pop3 stream tcp nowait root /usr/libexec/tcpd /usr/libexec/ipop3d
+
+	1999年頃以降のPC-UNIXではinetdにデフォルトでtcpdが組み込まれてい
+	ることが多いので、inetd.confにtcpdははさまなくて良いこともありま
+	す。続いて /etc/hosts.allow.src で環境変数の設定が起きるようにし
+	ます。
+
+	[/etc/hosts.allow.src]
+		ipop3d : all : setenv RELAYCLIENT %h
+
+	これで POPサービスを利用しに来たクライアントのアドレスが環境変数
+	に入ります。
+
+	tcpserverの場合は、付属の pop3-record スクリプトの後半に例がある
+	のでそれを利用してください。
+
+	なお、tcp_wrappers 用の pop3-age スクリプトは負荷の高いマシンで
+	は hosts.allow ファイルが空になる可能性があります。lockすれば多
+	少ましになるでしょうが完ぺきではありません。もし、hosts.allowの
+	書き換えに失敗するような負荷の高い環境で使う場合は tcp_wrappers 
+	ではなく、tcpserverでのアクセス制御をすることを強く勧めます。こ
+	ちらはロックの必要もなく、安全にアクセス制御ファイルの更新ができ
+	ます。
+
+【POPアクセス制御について】
+
+	POP3とAPOPは同じポートを使うので「外部からはAPOPだけ許す」などの
+	制御はルータやtcp_wrappersなどだけではできません。このipop3dでは、
+	生のPOP3は環境変数INTRANETが定義されているときだけに利用を制限す
+	ることができます。tcp_wrappers の例を示します。
+
+		ipop3d : localhost .localnet.hoge.jp \
+			: setenv INTRANET : setenv RELAYCLIENT %h
+		ipop3d : all : setenv RELAYCLIENT %h
+
+	としておけば、ローカルネットワーク内だけで生POP3を使うことができ
+	ます。
+
+【virtualdomain機能について】
+
+	qmailでは /var/qmail/control/virtualdomains を使うことで、ユーザ
+	が任意のメイルドメインを持つことができます。これを解釈するように
+	しました。/var/qmail/control/virtualdomain ファイルで
+
+		virtual.hoge.co.jp:user1
+		dokan.hoge.co.jp:user2-dokan
+
+	としておくと、XX@virtual.hoge.co.jp は ~user1/.qmail-XX に配送さ
+	れ、YY@dokan.hoge.co.jp は ~user2/.qmail-dokan-YY に配送されます。
+	それがMaildirスプールを含む場合、本パッケージのIMAP/POPで取り込
+	むことができます。デフォルトではこのためのパスワードはそれぞれ
+
+		~user1/.apop-XX
+		~user2/.apop-dokan-YY
+
+	ファイルに保存しておかなければなりません。
+
+【Postfixの拡張アドレス対応について】
+
+	Postfixによる ~/.forward+ext で発生する拡張アドレスは、その配送
+	先がMaildirであれば本パッケージでも利用できます。Postfix のデフォ
+	ルト設定の
+		forward_path = $home/.forward$recipient_delimiter$extension,
+			     $home/.forward
+		recipient_delimiter = +
+
+	のまま Postfix を動かしている場合はトップレベルのMakefileの
+	EXTRACFLAGS に -DPOSTFIX を追加して下さい(-DQMAILも必要です)。こ
+	れにより、拡張アドレスを決めるファイルが ".forward" に、拡張部分
+	を区切る文字列が "+" になります。いずれかを変更している場合はた
+	とえば、
+
+		-DDOTQMAIL=".postfix" -DXADDR_DELIM="-"
+
+	のように変更できます。もし、Postfix の .forward+ext を利用する場
+	合は周辺ツールの APOPtools/apoppasswd, APOPtools/apopcall.c の対
+	応する変数も変更する必要があることに注意して下さい。また、パスワー
+	ドファイルも ~/.apop-ext ではなく~ /.apop+ext となることに注意が
+	必要です。これらが面倒な場合は、Postfix の設定の方で .qmail-ext 
+	を見るようにしてしまうのも手です。この場合は
+
+		recipient_delimiter = -
+		forward_path = $home/.forward$recipient_delimiter$extension,
+				$home/.qmail$recipient_delimiter$extension,
+				$home/.forward
+
+	とすると ~/.qmail-ext も参照するようになり、デフォルト状態の本パッ
+	ケージのまま利用することができるでしょう。
+
+【Postfixの POP before SMTPについて】
+
+	main.cf で たとえば次のようにします。
+
+		smtpd_recipient_restrictions = 
+			permit_mynetworks
+			check_client_access hash:/etc/postfix/client_access
+
+	ここで /etc/postfix/client_access は POP before SMTP の許可ホス
+	トリストを保持するためのファイル名で、既に使われてはいないものに
+	します。配布ディレクトリの APOPtools/pop3-record.postfix は
+	/etc/postfix/client_access ファイルをリレー許可判定に使うことを
+	前提とした Postfix 用のスクリプトです。
+
+【謝辞】
+
+	安井卓さん(tach@debian.or.jp)にはsyslog関係のパッチを頂きました。
+	ここに感謝の意を表します。
+
+【免責】
+
+	IMAPパッケージに本ドキュメントで説明した拡張機能を追加する部分の
+	著作権は広瀬雄二[yuuji@gentei.org]が保持します。このプログラムを
+	用いて生じた如何なる結果に対しても著作権者は責任を負いません。
+
+						2009/9/14 yuuji@gentei.org
--- a/src/c-client/auth_log.c	Thu Oct 30 00:00:57 2014 +0900
+++ b/src/c-client/auth_log.c	Thu Oct 30 00:03:05 2014 +0900
@@ -105,6 +105,10 @@
   char *ret = NIL;
   char *user,*pass,*authuser;
   if (user = (*responder) (PWD_USER,sizeof (PWD_USER),NIL)) {
+#ifdef QMAIL
+    extern char* conv_virtualdomain(char*);
+    user = conv_virtualdomain(user);
+#endif
     if (pass = (*responder) (PWD_PWD,sizeof (PWD_PWD),NIL)) {
 				/* delimit user from possible admin */
       if (authuser = strchr (user,'*')) *authuser++ = '\0';
--- a/src/c-client/auth_md5.c	Thu Oct 30 00:00:57 2014 +0900
+++ b/src/c-client/auth_md5.c	Thu Oct 30 00:03:05 2014 +0900
@@ -75,9 +75,11 @@
 
 long auth_md5_valid (void)
 {
+#ifndef QMAIL			/* qmail extension can always handle MD5 */
   struct stat sbuf;
 				/* server forbids MD5 if no MD5 enable file */
   if (stat (MD5ENABLE,&sbuf)) auth_md5.server = NIL;
+#endif
   return T;			/* MD5 is otherwise valid */
 }
 
@@ -186,6 +188,7 @@
 char *auth_md5_pwd (char *user)
 {
   struct stat sbuf;
+#ifndef QMAIL
   int fd = open (MD5ENABLE,O_RDONLY,NIL);
   unsigned char *s,*t,*buf,*lusr,*lret;
   char *r;
@@ -214,6 +217,77 @@
     fs_give ((void **) &buf);	/* flush the buffer */
     close (fd);			/* don't need file any longer */
   }
+#else
+# ifndef USERAPOPFILE
+#  define USERAPOPFILE ".apop" 
+# endif
+# ifndef XADDR_DELIM
+#  ifdef POSTFIX		/* Same if-condition is in maildir.c.. sorry */
+#   define XADDR_DELIM "+"
+#  else
+#   define XADDR_DELIM "-"
+#  endif
+# endif
+  extern char *myMailSuffix;
+  char mycrypt[BUFSIZ+1];
+  char *ret = NIL, *tmp=NIL;
+  FILE *apopfile = NIL;
+  struct passwd *pw = getpwnam(user);
+  if (!pw) pw = getpwnam(lcase(tmp=cpystr(user)));
+  if (!pw && strstr(user, XADDR_DELIM)) { /* Check qmail alias */
+    char tmp[BUFSIZ];
+    char *s = user;
+    memset(tmp, 0, BUFSIZ);
+    while (*s && s && !pw) {
+      s = strstr(s, XADDR_DELIM);
+      if (!s) break;
+      strncpy(tmp, user, s-user);
+      s++;
+      pw = getpwnam(tmp);
+    }
+    if (pw) {
+      myMailSuffix = lcase(cpystr(s-1));
+      user[strlen(tmp)] = '\0'; /* zap suffix */
+    }
+  }
+  if (pw) {
+    snprintf(mycrypt, BUFSIZ, "%s/%s", pw->pw_dir, USERAPOPFILE);
+    if (NIL != myMailSuffix) strcat(mycrypt, myMailSuffix);
+    if (stat(mycrypt, &sbuf) < 0) {
+      /* printf("Cannot stat [%s]\015\n", mycrypt); */
+      return ret;
+    }
+    if (sbuf.st_mode & ~(S_IFREG | S_IREAD | S_IWRITE)) {
+      /* printf("Your apoppassword file is readable by others. Do chmod 600 %s%c\n", mycrypt, 015); */
+      return ret;
+    }
+#ifdef APOPOPEN
+    if (stat(APOPOPEN, &sbuf) >= 0) {	/* if APPOPEN exists */
+      /* read apop password via APOPOPEN program */
+      int bytes = 3+strlen(APOPOPEN)+strlen(mycrypt);
+      char *aproc = (char*) fs_get(bytes);
+      snprintf(aproc, bytes, "%s %s%c", APOPOPEN, mycrypt, '\0');
+      apopfile = popen(aproc, "r");
+      memset(aproc, 0, bytes);
+      fs_give((void**)&aproc);
+    }
+#endif /* APOPOPEN */
+    if ((NIL!=apopfile) || (apopfile = fopen( mycrypt, "r" ))) {
+      fgets(mycrypt, sizeof(mycrypt) - 1, apopfile);
+      fclose(apopfile);
+      if (mycrypt[0]) {
+	char p = strlen(mycrypt);
+	while (p > 0 && (mycrypt[p-1] == '\n' || mycrypt[p-1] == '\r')) {
+	   mycrypt[--p] = '\0'; /* zap trailing newlines */
+	}
+      }
+    } else {
+      return ret;
+    }
+    ret = cpystr(mycrypt);
+    memset(mycrypt, 0, sizeof(mycrypt));
+  }
+#endif				/* if QMAIL */
   return ret;			/* return password */
 }
 
@@ -231,6 +305,9 @@
   int i,j;
   char *ret = NIL;
   char *s,*authuser,tmp[MAILTMPLEN];
+#ifdef QMAIL
+  char *userback = cpystr(user);
+#endif
   unsigned char digest[MD5DIGLEN];
   MD5CONTEXT ctx;
   char *hex = "0123456789abcdef";
@@ -260,7 +337,15 @@
     memset (tmp,0,MAILTMPLEN);	/* erase sensitive information */
   }
   if (!ret) sleep (3);		/* slow down possible cracker */
+  else {
+    extern void permitsmtp();
+    /* permitsmtp();*/
+  }
+#ifdef QMAIL
+  return (ret) ? userback : ret;
+#else
   return ret;
+#endif
 }
 
 /*
--- a/src/c-client/mail.c	Thu Oct 30 00:00:57 2014 +0900
+++ b/src/c-client/mail.c	Thu Oct 30 00:03:05 2014 +0900
@@ -6081,6 +6081,9 @@
     if (auth->server && !compare_cstring (auth->name,mechanism))
       return (!(auth->flags & AU_DISABLE) &&
 	      ((auth->flags & AU_SECURE) ||
+#ifdef QMAIL
+	       getenv("INTRANET") ||
+#endif
 	       !mail_parameters (NIL,GET_DISABLEPLAINTEXT,NIL))) ?
 	(*auth->server) (resp,argc,argv) : NIL;
   return NIL;			/* no authenticator found */
--- a/src/c-client/mail.h	Thu Oct 30 00:00:57 2014 +0900
+++ b/src/c-client/mail.h	Thu Oct 30 00:03:05 2014 +0900
@@ -858,6 +858,7 @@
   unsigned int spare7 : 1;	/* seventh spare bit */
   unsigned int spare8 : 1;	/* eighth spare bit */
   void *sparep;			/* spare pointer */
+  void *maildirp;		/* for the Maildir driver */
   unsigned long user_flags;	/* user-assignable flags */
 } MESSAGECACHE;
 
--- a/src/imapd/imapd.c	Thu Oct 30 00:00:57 2014 +0900
+++ b/src/imapd/imapd.c	Thu Oct 30 00:03:05 2014 +0900
@@ -553,6 +553,9 @@
 
 				/* plaintext login with password */
 	else if (!strcmp (cmd,"LOGIN")) {
+          #ifdef QMAIL
+          extern char* conv_virtualdomain(char*);
+          #endif
 	  if (user) fs_give ((void **) &user);
 	  if (pass) fs_give ((void **) &pass);
 				/* two arguments */
@@ -573,7 +576,11 @@
 	  else {		/* delimit user from possible admin */
 	    if (s = strchr (user,'*')) *s++ ='\0';
 				/* see if username and password are OK */
+#ifdef QMAIL
+	    if (server_login (conv_virtualdomain(user),pass,s,argc,argv)) {
+#else
 	    if (server_login (user,pass,s,argc,argv)) {
+#endif
 	      state = SELECT;	/* make select */
 	      alerttime = 0;	/* force alert */
 	      response = logwin;/* return logged-in capabilities */
--- a/src/ipopd/ipop3d.c	Thu Oct 30 00:00:57 2014 +0900
+++ b/src/ipopd/ipop3d.c	Thu Oct 30 00:03:05 2014 +0900
@@ -96,6 +96,9 @@
 void trmint ();
 int pass_login (char *t,int argc,char *argv[]);
 char *apop_login (char *chal,char *user,char *md5,int argc,char *argv[]);
+#ifdef QMAIL
+char* conv_virtualdomain(char *account);
+#endif
 char *responder (void *challenge,unsigned long clen,unsigned long *rlen);
 int mbxopen (char *mailbox);
 long blat (char *text,long lines,unsigned long size,STRING *st);
@@ -128,7 +131,11 @@
     AUTHENTICATOR *auth = mail_lookup_auth (1);
     while (auth && compare_cstring (auth->name,"CRAM-MD5")) auth = auth->next;
 				/* build challenge -- less than 128 chars */
+#ifndef QMAIL
+    if (!(auth->flags & AU_DISABLE))
+#else
     if (auth && auth->server && !(auth->flags & AU_DISABLE))
+#endif
       sprintf (challenge,"<%lx.%lx@%.64s>",(unsigned long) getpid (),
 	       (unsigned long) time (0),tcp_serverhost ());
     else challenge[0] = '\0';	/* no MD5 authentication */
@@ -258,10 +265,17 @@
 				/* get user name */
 	    if (!(t && *t && (s = strtok (t," ")) && (t = strtok(NIL,"\012"))))
 	      PSOUT ("-ERR Missing APOP argument\015\012");
-	    else if (!(user = apop_login (challenge,s,t,argc,argv)))
-	      PSOUT ("-ERR Bad APOP\015\012");
-	    else if ((state = mbxopen ("INBOX")) == TRANSACTION)
-	      syslog (LOG_INFO,"APOP user=%.80s host=%.80s nmsgs=%lu/%lu",
+ #ifdef QMAIL
+	    else if (!(user = apop_login (challenge,conv_virtualdomain(s),t,argc,argv))) {
+ #else /* !QMAIL */
+	      else if (!(user = apop_login (challenge,s,t,argc,argv))) {
+ #endif /* QMAIL */
+	      PSOUT ("-ERR Bad APOP (Maybe your password is expired)\015\012");
+	      user = cpystr (s);
+              syslog (LOG_INFO,"APOP login failure user=%.80s host=%.80s",
+                    user,tcp_clienthost ());
+	    } else if ((state = mbxopen ("INBOX")) == TRANSACTION)
+	      syslog (LOG_INFO,"APOP user=%.80s host=%.80s nmsgs=%ld/%ld",
 		      user,tcp_clienthost (),nmsgs,stream->nmsgs);
 	    else syslog (LOG_INFO,"APOP user=%.80s host=%.80s no mailbox",
 			 user,tcp_clienthost ());
@@ -279,8 +293,20 @@
 	  }
 	  else PSOUT ("+OK STLS completed\015\012");
 	}
+#ifndef RESTRICT_POP
 	else if (!mail_parameters (NIL,GET_DISABLEPLAINTEXT,NIL) &&
 		 !strcmp (s,"USER")) {
+#else	/* !RESTRICT_POP */
+	else if (!strcmp (s,"USER")) {
+	  if (getenv("INTRANET") == NIL) {
+	    PSOUT("-ERR Sorry, we don't allow POP3 from your network.  Use APOP instead.\015\012");
+	    user = cpystr(t);
+	    syslog (LOG_INFO,"Plain POP3 is restricted user=%.80s host=%.80s",
+		    user,tcp_clienthost ());
+	    memset(user, '\0', strlen(user));
+	    break;
+	  }
+#endif
 	  if (host) fs_give ((void **) &host);
 	  if (user) fs_give ((void **) &user);
 	  if (pass) fs_give ((void **) &pass);
@@ -294,7 +320,11 @@
 	      user = cpystr (s);/* copy user name */
 	    }
 				/* local user name */
+#ifdef QMAIL
+	    else user = conv_virtualdomain(cpystr (t));
+#else
 	    else user = cpystr (t);
+#endif
 	    PSOUT ("+OK User name accepted, password please\015\012");
 	  }
 	  else PSOUT ("-ERR Missing username argument\015\012");
--- a/src/osdep/unix/Makefile	Thu Oct 30 00:00:57 2014 +0900
+++ b/src/osdep/unix/Makefile	Thu Oct 30 00:03:05 2014 +0900
@@ -27,7 +27,7 @@
 # Command line build parameters
 
 EXTRAAUTHENTICATORS=
-EXTRADRIVERS=mbox
+EXTRADRIVERS=maildir mbox
 PASSWDTYPE=std
 SSLTYPE=nopwd
 IP=4
@@ -102,6 +102,7 @@
 NEWSSPOOL=$(SPOOLDIR)/news
 RSHPATH=/usr/ucb/rsh
 MD5PWD=/etc/cram-md5.pwd
+MD5CFLAGS= -DAPOPOPEN=\"/usr/local/sbin/deapop\" -DUSERAPOPFILE=\".apop\" -DPOPBEFORESMTP -DPOP3RECORDER=\"/usr/local/etc/pop3-record\"
 # Tries one of the test alternatives below if not specified.
 LOCKPGM=
 # Test alternatives if LOCKPGM not specified
@@ -144,17 +145,21 @@
 # However, mh needs to be before any sysinbox formats (such as mmdf or unix)
 # since otherwise INBOX won't work correctly when mh_allow_inbox is set.
 #
-DEFAULTDRIVERS=imap nntp pop3 mix mx mbx tenex mtx mh mmdf unix news phile
+DEFAULTDRIVERS=maildir imap nntp pop3 mix mx mbx tenex mtx mh mmdf unix news phile
 CHUNKSIZE=65536
 
 # Normally no need to change any of these
+EXTRACFLAGS=-DQMAIL
+# Next variable controls default maildir when user has no ~/.qmail
+#MAILDIRCFLAGS=-DDEFAULTMAILDIR="maildir" -DQMAILCONTROL="/var/qmail/control"
+MAILDIRCFLAGS=-DQMAILCONTROL="/var/qmail/control"
 
 ARCHIVE=c-client.a
 BINARIES=osdep.o mail.o misc.o newsrc.o smanager.o utf8.o utf8aux.o siglocal.o \
  dummy.o pseudo.o netmsg.o flstring.o fdstring.o \
  rfc822.o nntp.o smtp.o imap4r1.o pop3.o \
- unix.o mbx.o mmdf.o tenex.o mtx.o news.o phile.o mh.o mx.o mix.o
-CFLAGS=-g
+ unix.o mbx.o mmdf.o tenex.o mtx.o news.o phile.o mh.o mx.o mix.o maildir.o
+CFLAGS=-g $(EXTRACFLAGS)
 
 CAT=cat
 MAKE=make
@@ -900,6 +905,7 @@
 unix.o: mail.h misc.h osdep.h unix.h pseudo.h dummy.h
 utf8.o: mail.h misc.h osdep.h utf8.h tmap.c widths.c
 utf8aux.o: mail.h misc.h osdep.h utf8.h
+maildir.o: mail.h misc.h osdep.h maildir.h dummy.h
 
 
 # OS-dependent
@@ -968,6 +974,7 @@
 	@echo Once-only environment setup...
 	echo $(CC) > CCTYPE
 	echo $(BASECFLAGS) '$(EXTRACFLAGS)' -DCHUNKSIZE=$(CHUNKSIZE) > CFLAGS
+	echo '$(MAILDIRCFLAGS)' >> CFLAGS
 	echo -DCREATEPROTO=$(CREATEPROTO) -DEMPTYPROTO=$(EMPTYPROTO) \
 	 -DMD5ENABLE=\"$(MD5PWD)\" -DMAILSPOOL=\"$(MAILSPOOL)\" \
 	 -DANONYMOUSHOME=\"$(MAILSPOOL)/anonymous\" \
@@ -975,6 +982,7 @@
 	 -DRSHPATH=\"$(RSHPATH)\" -DLOCKPGM=\"$(LOCKPGM)\" \
 	 -DLOCKPGM1=\"$(LOCKPGM1)\" -DLOCKPGM2=\"$(LOCKPGM2)\" \
 	 -DLOCKPGM3=\"$(LOCKPGM3)\" > OSCFLAGS
+	echo $(MD5CFLAGS) >> OSCFLAGS
 	echo $(BASELDFLAGS) $(EXTRALDFLAGS) > LDFLAGS
 	echo "$(ARRC) $(ARCHIVE) $(BINARIES);$(RANLIB) $(ARCHIVE)" > ARCHIVE
 	echo $(OS) > OSTYPE
--- a/src/osdep/unix/env_unix.c	Thu Oct 30 00:00:57 2014 +0900
+++ b/src/osdep/unix/env_unix.c	Thu Oct 30 00:03:05 2014 +0900
@@ -422,6 +422,10 @@
   case SET_DISABLEPLAINTEXT:
     disablePlaintext = (long) value;
   case GET_DISABLEPLAINTEXT:
+#ifdef RESTRICT_POP
+    if (getenv("INTRANET") == NIL) disablePlaintext = 1;
+    else disablePlaintext = NIL;
+#endif
     ret = (void *) disablePlaintext;
     break;
   case SET_CHROOTSERVER:
@@ -665,6 +669,7 @@
   char *s;
   struct passwd *pw;
   struct passwd *ret = NIL;
+#ifndef QMAIL	/* imapext md5 checker run previously. no need to do here */
   if (auth_md5.server) {	/* using CRAM-MD5 authentication? */
     if (s = auth_md5_pwd (user)) {
       if (!strcmp (s,pwd) || ((*pwd == ' ') && pwd[1] && !strcmp (s,pwd+1)))
@@ -673,7 +678,9 @@
       fs_give ((void **) &s);
     }
   }
-  else if (pw = pwuser (user)) {/* can get user? */
+  else
+#endif
+  if (pw = pwuser (user)) {/* can get user? */
     s = cpystr (pw->pw_name);	/* copy returned name in case we need it */
     if (*pwd && !(ret = checkpw (pw,pwd,argc,argv)) &&
 	(*pwd == ' ') && pwd[1] && (ret = pwuser (s)))
@@ -697,6 +704,10 @@
   struct passwd *pw = NIL;
   int level = LOG_NOTICE;
   char *err = "failed";
+#ifdef QMAIL
+  char usr[MAILTMPLEN], *apoppswd;
+  strncpy(usr, user, MAILTMPLEN-1);
+#endif
 				/* cretins still haven't given up */
   if ((strlen (user) >= NETMAXUSER) ||
       (authuser && (strlen (authuser) >= NETMAXUSER))) {
@@ -706,6 +717,16 @@
   }
   else if (logtry-- <= 0) err = "excessive login failures";
   else if (disablePlaintext) err = "disabled";
+#ifdef QMAIL
+  else if ((logtry > 0) &&
+            (apoppswd = auth_md5_pwd(usr))
+           && !strcmp(apoppswd, pwd)
+           && (pw = getpwnam(usr))) {
+    memset(apoppswd, 0, strlen(apoppswd));
+    fs_give((void**) &apoppswd);
+    return pw_login(pw, usr, pw->pw_name, pw->pw_dir, argc, argv);
+  }
+#endif
   else if (!(authuser && *authuser)) pw = valpwd (user,pwd,argc,argv);
   else if (valpwd (authuser,pwd,argc,argv)) pw = pwuser (user);
   if (pw && pw_login (pw,authuser,pw->pw_name,NIL,argc,argv)) return T;
@@ -728,6 +749,34 @@
   return pw_login (pwuser (user),authuser,user,NIL,argc,argv);
 }
 
+void permitsmtp()	/* to update tcp permission */
+{
+#ifdef POPBEFORESMTP
+  #include <sys/types.h>
+  #include <sys/wait.h>
+  #ifndef POP3RECORDER
+  # define POP3RECORDER "/usr/local/etc/pop3-record"
+  #endif
+  int child;
+  int wstat;
+  char *permsmtp = POP3RECORDER;
+
+  switch(child = fork())
+   {
+    case -1:
+	syslog (LOG_INFO,"Cannot exec %s", permsmtp);
+	_exit(111);
+	break;
+    case 0:
+	execl(permsmtp, permsmtp, 0);
+	syslog (LOG_INFO,"Cannot exec %s", permsmtp);
+	_exit(111); break;
+   }
+  waitpid(child, &wstat, 0);
+#endif
+}
+
+
 
 /* Log in as anonymous daemon
  * Accepts: argument count
@@ -781,8 +830,14 @@
       else fatal ("Login failed after chroot");
     }
 				/* normal login */
+#ifdef QMAIL
+    else if (((pw->pw_uid == geteuid ()) || (permitsmtp(), loginpw (pw,argc,argv
+))) &&
+             (ret = env_init (user,home))) chdir (myhomedir ());
+#else
     else if (((pw->pw_uid == geteuid ()) || loginpw (pw,argc,argv)) &&
-	     (ret = env_init (user,home))) chdir (myhomedir ());
+             (ret = env_init (user,home))) chdir (myhomedir ());
+#endif
     fs_give ((void **) &home);	/* clean up */
     if (user) fs_give ((void **) &user);
   }
--- a/src/osdep/unix/tcp_unix.c	Thu Oct 30 00:00:57 2014 +0900
+++ b/src/osdep/unix/tcp_unix.c	Thu Oct 30 00:03:05 2014 +0900
@@ -820,6 +820,20 @@
   return stream->localhost;	/* return local host name */
 }
 
+/* Get $TCPREMOTEHOST || $TCPREMOTEHOST
+ * If invoked via tcpserver or couriertcpd, consult $TCPREMOTEHOST
+ * or $TCPREMOTEIP
+ */
+char* gettcpremoteip()
+{
+  if (getenv("TCPREMOTEHOST") && strcmp("0", getenv("TCPREMOTEHOST"))) {
+    return getenv("TCPREMOTEHOST");
+  } else if (getenv("TCPREMOTEIP")) {
+    return getenv("TCPREMOTEIP");
+  }
+  return "NON-IPv4";
+}
+
 /* TCP/IP get client host address (server calls only)
  * Returns: client host address
  */
@@ -850,6 +864,15 @@
   if (!myClientHost) {
     size_t sadrlen;
     struct sockaddr *sadr = ip_newsockaddr (&sadrlen);
+#ifdef INET6
+    if (getenv("TCPREMOTEIP")) {
+      myClientHost =
+         cpystr((getenv("TCPREMOTEHOST")
+ 		&& strcasecmp("UNKNOWN", getenv("TCPREMOTEHOST")))
+ 		? getenv("TCPREMOTEHOST")
+ 		: getenv("TCPREMOTEIP"));
+    } else
+#endif
     if (getpeername (0,sadr,(void *) &sadrlen)) {
       char *s,*t,*v,tmp[MAILTMPLEN];
       if ((s = getenv (t = "SSH_CLIENT")) ||
@@ -913,7 +936,8 @@
     size_t sadrlen;
     struct sockaddr *sadr = ip_newsockaddr (&sadrlen);
 				/* get stdin's name */
-    if (getsockname (0,sadr,(void *) &sadrlen))
+    if (getsockname (0,sadr,(void *) &sadrlen) ||
+        (myServerPort = ip_sockaddrtoport (sadr)) < 0)
       myServerHost = cpystr (mylocalhost ());
     else {			/* get stdin's name */
       myServerHost = tcp_name (sadr,NIL);
--- a/src/osdep/unix/unix.c	Thu Oct 30 00:00:57 2014 +0900
+++ b/src/osdep/unix/unix.c	Thu Oct 30 00:03:05 2014 +0900
@@ -202,6 +202,7 @@
 
 				/* driver parameters */
 static long unix_fromwidget = T;
+char *myMailSuffix =NIL;	/* home directory name */
 
 /* UNIX mail validate mailbox
  * Accepts: mailbox name
@@ -2401,6 +2402,15 @@
   }
   f->filepos += size;		/* update file position */
 }
+
+/* Return my mail suffix(of qmail or Postfix)
+ * Returns: my mail address extensional suffix
+ */
+
+char *mymailsuffix ()
+{
+  return myMailSuffix ? myMailSuffix : "";
+}
 
 /* MBOX mail routines */
 

yatex.org