--- ../checkpassword-0.90-orig/Makefile	Thu Jan 18 12:14:10 2001
+++ Makefile	Thu Jan 18 12:04:44 2001
@@ -1,9 +1,43 @@
 # Don't edit Makefile! Use conf-* for configuration.
 
+# uncomment "-lsocket -nsl" on Solaris, "-lcrypt" or "-lz" if you need them
+MYSQL_LIBS=/opt/mysql/lib/mysql/libmysqlclient.a -lm -lz -lcrypt #-lsocket -lnsl
+MYSQL_INCLUDE=-I/usr/local/include
+LOGGING=-DO_NOT_LOG_SQL #-DO_NOT_LOG #-DO_NOT_LOG_ERRORS
 SHELL=/bin/sh
 
 default: it
 
+init_mysql.o: compile init_mysql.c auto_qmail.h
+	./compile init_mysql.c $(MYSQL_INCLUDE)
+
+connect_mysql.o: compile connect_mysql.c
+	./compile connect_mysql.c $(MYSQL_INCLUDE)
+
+getpw_mysql.o: compile getpw_mysql.c mysql_queries.h
+	./compile getpw_mysql.c $(MYSQL_INCLUDE) $(LOGGING)
+
+do_query.o: compile do_query.c mysql_queries.h
+	./compile do_query.c $(MYSQL_INCLUDE) $(LOGGING)
+
+qsutil.o: compile qsutil.c
+	./compile qsutil.c
+
+_authen.o: compile _authen.c
+	./compile _authen.c
+
+_authen: load auto_qmail.o _authen.o init_mysql.o connect_mysql.o case_lowers.o \
+getpw_mysql.o fmt_uint.o fmt_uint0.o fmt_ulong.o open_read.o \
+do_query.o qsutil.o stralloc.a str.a getln.a substdio.a error.a alloc.a
+	./load _authen auto_qmail.o init_mysql.o connect_mysql.o case_lowers.o \
+	getpw_mysql.o fmt_uint.o fmt_uint0.o fmt_ulong.o open_read.o \
+	do_query.o qsutil.o getln.a substdio.a stralloc.a str.a error.a \
+	alloc.a $(MYSQL_LIBS)
+
+alloc.a: \
+makelib alloc.o alloc_re.o
+	./makelib alloc.a alloc.o alloc_re.o
+
 alloc.o: \
 compile alloc.c alloc.h error.h
 	./compile alloc.c
@@ -48,12 +82,24 @@
 compile buffer_put.c buffer.h str.h byte.h error.h
 	./compile buffer_put.c
 
+auto_qmail.c: \
+auto-str conf-qmail
+	./auto-str auto_qmail `head -1 conf-qmail` > auto_qmail.c
+
+auto_qmail.o: \
+compile auto_qmail.c
+	./compile auto_qmail.c
+
 byte.a: \
 makelib byte_copy.o byte_cr.o byte_diff.o str_chr.o str_len.o \
 str_start.o
 	./makelib byte.a byte_copy.o byte_cr.o byte_diff.o \
 	str_chr.o str_len.o str_start.o
 
+byte_chr.o: \
+compile byte_chr.c byte.h
+	./compile byte_chr.c
+
 byte_copy.o: \
 compile byte_copy.c byte.h
 	./compile byte_copy.c
@@ -71,9 +117,24 @@
 	./instcheck
 
 checkpassword: \
-load checkpassword.o prot.o unix.a byte.a shadow.lib crypt.lib s.lib
-	./load checkpassword prot.o unix.a byte.a  `cat \
-	shadow.lib` `cat crypt.lib` `cat s.lib`
+load checkpassword.o auto_qmail.o init_mysql.o connect_mysql.o case_lowers.o \
+getpw_mysql.o do_query.o fmt_uint.o fmt_uint0.o fmt_ulong.o open_read.o \
+qsutil.o prot.o shadow.lib crypt.lib s.lib stralloc.a str.a unix.a \
+getln.a substdio.a error.a alloc.a
+	./load checkpassword auto_qmail.o init_mysql.o connect_mysql.o \
+	case_lowers.o getpw_mysql.o do_query.o fmt_uint.o fmt_uint0.o \
+	fmt_ulong.o open_read.o qsutil.o prot.o  `cat shadow.lib` `cat \
+	crypt.lib` `cat s.lib` getln.a substdio.a stralloc.a str_start.o str_chr.o str.a unix.a \
+	error.a alloc.a $(MYSQL_LIBS)
+
+#checkpassword: \
+#load checkpassword.o auto_qmail.o init_mysql.o connect_mysql.o do_query.o \
+#case_lowers.o getpw_mysql.o qsutil.o prot.o unix.a byte.a substdio.a str.a \
+#getln.a shadow.lib crypt.lib s.lib
+#./load checkpassword auto_qmail.o init_mysql.o connect_mysql.o \
+#do_query.o case_lowers.o getpw_mysql.o qsutil.o prot.o unix.a byte.a \
+#getln.a str.a substdio.a \
+#`cat shadow.lib` `cat crypt.lib` `cat s.lib` $(MYSQL_LIBS)
 
 checkpassword.o: \
 compile checkpassword.c error.h pathexec.h prot.h hasspnam.h \
@@ -111,6 +172,10 @@
 compile env.c str.h env.h
 	./compile env.c
 
+error.a: \
+makelib error.o error_str.o
+	./makelib error.a error.o error_str.o
+
 error.o: \
 compile error.c error.h
 	./compile error.c
@@ -119,6 +184,30 @@
 compile error_str.c error.h
 	./compile error_str.c
 
+fmt_uint.o: \
+compile fmt_uint.c fmt.h
+	./compile fmt_uint.c
+
+fmt_uint0.o: \
+compile fmt_uint0.c fmt.h
+	./compile fmt_uint0.c
+
+fmt_ulong.o: \
+compile fmt_ulong.c fmt.h
+	./compile fmt_ulong.c
+
+getln.a: \
+makelib getln.o getln2.o
+	./makelib getln.a getln.o getln2.o
+
+getln.o: \
+compile getln.c substdio.h byte.h stralloc.h gen_alloc.h getln.h
+	./compile getln.c
+
+getln2.o: \
+compile getln2.c substdio.h stralloc.h gen_alloc.h byte.h getln.h
+	./compile getln2.c
+
 hasshsgr.h: \
 choose compile load tryshsgr.c hasshsgr.h1 hasshsgr.h2 chkshsgr \
 warn-shsgr
@@ -209,7 +298,7 @@
 	./compile pathexec_run.c
 
 prog: \
-checkpassword
+checkpassword _authen
 
 prot.o: \
 compile prot.c hasshsgr.h prot.h
@@ -233,10 +322,28 @@
 	&& echo -lshadow || exit 0 ) > shadow.lib
 	rm -f tryshadow.o tryshadow
 
+str.a: \
+makelib str_chr.o str_cpy.o str_diff.o str_len.o str_start.o byte_chr.o byte_diff.o \
+byte_copy.o byte_cr.o
+	./makelib str.a str_chr.o str_cpy.o str_diff.o str_len.o str_start.o byte_chr.o \
+	byte_diff.o byte_copy.o byte_cr.o
+
 str_chr.o: \
 compile str_chr.c str.h
 	./compile str_chr.c
 
+str_cpy.o: \
+compile str_cpy.c str.h
+	./compile str_cpy.c
+
+str_diff.o: \
+compile str_diff.c str.h
+	./compile str_diff.c
+
+str_len.o: \
+compile str_len.c str.h
+	./compile str_len.c
+
 str_len.o: \
 compile str_len.c str.h
 	./compile str_len.c
@@ -245,6 +352,19 @@
 compile str_start.c str.h
 	./compile str_start.c
 
+stralloc.a: \
+makelib stralloc_eady.o stralloc_pend.o stralloc_copy.o \
+stralloc_opys.o stralloc_opyb.o stralloc_cat.o stralloc_cats.o \
+stralloc_catb.o stralloc_arts.o
+	./makelib stralloc.a stralloc_eady.o stralloc_pend.o \
+	stralloc_copy.o stralloc_opys.o stralloc_opyb.o \
+	stralloc_cat.o stralloc_cats.o stralloc_catb.o \
+	stralloc_arts.o
+
+stralloc_arts.o: \
+compile stralloc_arts.c byte.h str.h stralloc.h gen_alloc.h
+	./compile stralloc_arts.c
+
 stralloc_cat.o: \
 compile stralloc_cat.c byte.h stralloc.h gen_alloc.h
 	./compile stralloc_cat.c
@@ -283,6 +403,27 @@
 compile strerr_sys.c error.h strerr.h
 	./compile strerr_sys.c
 
+substdi.o: \
+compile substdi.c substdio.h byte.h error.h
+	./compile substdi.c
+
+substdio.a: \
+makelib substdio.o substdi.o substdo.o subfderr.o substdio_copy.o
+	./makelib substdio.a substdio.o substdi.o substdo.o \
+	subfderr.o substdio_copy.o
+
+substdio.o: \
+compile substdio.c substdio.h
+	./compile substdio.c
+
+substdio_copy.o: \
+compile substdio_copy.c substdio.h
+	./compile substdio_copy.c
+
+substdo.o: \
+compile substdo.c substdio.h str.h byte.h error.h
+	./compile substdo.c
+
 systype: \
 find-systype.sh trycpp.c x86cpuid.c
 	sh find-systype.sh > systype
@@ -290,12 +431,12 @@
 unix.a: \
 makelib alloc.o alloc_re.o buffer.o buffer_2.o buffer_copy.o \
 buffer_get.o buffer_put.o env.o error.o error_str.o open_read.o \
-open_trunc.o pathexec_env.o pathexec_run.o prot.o stralloc_cat.o \
-stralloc_catb.o stralloc_cats.o stralloc_eady.o stralloc_opyb.o \
-stralloc_opys.o stralloc_pend.o strerr_die.o strerr_sys.o
+open_trunc.o pathexec_env.o pathexec_run.o prot.o stralloc_arts.o \
+stralloc_cat.o stralloc_catb.o stralloc_cats.o stralloc_eady.o \
+stralloc_opyb.o stralloc_opys.o stralloc_pend.o strerr_die.o strerr_sys.o
 	./makelib unix.a alloc.o alloc_re.o buffer.o buffer_2.o \
 	buffer_copy.o buffer_get.o buffer_put.o env.o error.o \
 	error_str.o open_read.o open_trunc.o pathexec_env.o \
-	pathexec_run.o prot.o stralloc_cat.o stralloc_catb.o \
+	pathexec_run.o prot.o stralloc_arts.o stralloc_cat.o stralloc_catb.o \
 	stralloc_cats.o stralloc_eady.o stralloc_opyb.o \
 	stralloc_opys.o stralloc_pend.o strerr_die.o strerr_sys.o
--- ../checkpassword-0.90-orig/_authen.c	Thu Jan 18 12:14:10 2001
+++ _authen.c	Thu Jan 18 10:37:05 2001
@@ -0,0 +1,27 @@
+#include <pwd.h>
+#include "fmt.h"
+#include "stralloc.h"
+
+extern getpw_mysql();
+stralloc message = { 0 };
+char strnum[FMT_ULONG];
+
+int main(int argc, char **argv) {
+  struct passwd *pw;
+
+  if (argc < 3) {
+    puts("usage: _authen username password");
+    return die();
+  }
+  strnum[fmt_ulong(strnum, getppid())] = 0;
+  pw = getpw_mysql(argv[1], argv[2]);
+  if ((int) pw < 3) return die();
+  printf("%s:*:%d:%d:%s:%s\n", pw->pw_name, pw->pw_uid, pw->pw_gid,
+                               pw->pw_dir, pw->pw_shell);
+  return 0;
+}
+
+int die() {
+  if (message.len) puts(message.s);
+  return 111;
+}
--- ../checkpassword-0.90-orig/alloc.c	Thu Jan 18 12:14:10 2001
+++ alloc.c	Thu Jan 18 11:15:49 2001
@@ -4,7 +4,7 @@
 extern void free();
 
 #define ALIGNMENT 16 /* XXX: assuming that this alignment is enough */
-#define SPACE 2048 /* must be multiple of ALIGNMENT */
+#define SPACE 4096 /* must be multiple of ALIGNMENT */
 
 typedef union { char irrelevant[ALIGNMENT]; double d; } aligned;
 static aligned realspace[SPACE / ALIGNMENT];
--- ../checkpassword-0.90-orig/alloc.h	Thu Jan 18 12:14:10 2001
+++ alloc.h	Thu Jan 18 10:37:05 2001
@@ -6,3 +6,11 @@
 extern int alloc_re();
 
 #endif
+#ifndef ALLOC_H
+#define ALLOC_H
+
+extern /*@null@*//*@out@*/char *alloc();
+extern void alloc_free();
+extern int alloc_re();
+
+#endif
--- ../checkpassword-0.90-orig/auto_home.c	Thu Jan 18 12:14:10 2001
+++ auto_home.c	Thu Jan 18 12:04:47 2001
@@ -0,0 +1,3 @@
+const char auto_home[] = "\
+\057\
+";
--- ../checkpassword-0.90-orig/auto_qmail.c	Thu Jan 18 12:14:11 2001
+++ auto_qmail.c	Thu Jan 18 12:05:04 2001
@@ -0,0 +1,3 @@
+const char auto_qmail[] = "\
+\057\157\160\164\057\161\155\141\151\154\
+";
--- ../checkpassword-0.90-orig/auto_qmail.h	Thu Jan 18 12:14:11 2001
+++ auto_qmail.h	Thu Jan 18 10:37:05 2001
@@ -0,0 +1,6 @@
+#ifndef AUTO_QMAIL_H
+#define AUTO_QMAIL_H
+
+extern char auto_qmail[];
+
+#endif
--- ../checkpassword-0.90-orig/byte_chr.c	Thu Jan 18 12:14:11 2001
+++ byte_chr.c	Thu Jan 18 10:37:05 2001
@@ -0,0 +1,20 @@
+#include "byte.h"
+
+unsigned int byte_chr(s,n,c)
+char *s;
+register unsigned int n;
+int c;
+{
+  register char ch;
+  register char *t;
+
+  ch = c;
+  t = s;
+  for (;;) {
+    if (!n) break; if (*t == ch) break; ++t; --n;
+    if (!n) break; if (*t == ch) break; ++t; --n;
+    if (!n) break; if (*t == ch) break; ++t; --n;
+    if (!n) break; if (*t == ch) break; ++t; --n;
+  }
+  return t - s;
+}
--- ../checkpassword-0.90-orig/case.h	Thu Jan 18 12:14:11 2001
+++ case.h	Thu Jan 18 10:37:05 2001
@@ -0,0 +1,6 @@
+#ifndef CASE_H
+#define CASE_H
+
+extern void case_lowers();
+
+#endif
--- ../checkpassword-0.90-orig/case_lowers.c	Thu Jan 18 12:14:11 2001
+++ case_lowers.c	Thu Jan 18 10:37:05 2001
@@ -0,0 +1,12 @@
+#include "case.h"
+
+void case_lowers(s)
+char *s;
+{
+  unsigned char x;
+  while (x = *s) {
+    x -= 'A';
+    if (x <= 'Z' - 'A') *s = x + 'a';
+    ++s;
+  }
+}
--- ../checkpassword-0.90-orig/checkpassword.c	Thu Jan 18 12:14:11 2001
+++ checkpassword.c	Thu Jan 18 12:11:20 2001
@@ -1,6 +1,11 @@
 #include "error.h"
 #include "pathexec.h"
 #include "prot.h"
+#include "stralloc.h"
+#ifndef O_NOT_LOG
+#include "fmt.h"
+#include "qsutil.h"
+#endif
 
 extern char *crypt();
 #include <pwd.h>
@@ -20,6 +25,8 @@
 
 static char up[513];
 static int uplen;
+stralloc message = { 0 };
+char strnum[FMT_ULONG];
 
 main(int argc,char **argv)
 {
@@ -31,6 +38,7 @@
   int i;
  
   if (!argv[1]) _exit(2);
+  strnum[fmt_ulong(strnum, getppid())] = 0;
  
   uplen = 0;
   for (;;) {
@@ -52,37 +60,94 @@
   if (i >= uplen) _exit(2);
   while (up[i++]) if (i >= uplen) _exit(2);
 
-  pw = getpwnam(login);
-  if (pw)
-    stored = pw->pw_passwd;
-  else {
-    if (errno == error_txtbsy) _exit(111);
-    _exit(1);
-  }
+  /* doit() woz 'ere */
+  pw = getpw_mysql(login, password);
+  if ((int) pw == -1) _exit(111);
+  if ((int) pw == 1) _exit(1);
+  if ((int) pw == 0) {
+    pw = getpwnam(login);
+    if (pw)
+      stored = pw->pw_passwd;
+    else {
+      if (errno == error_txtbsy) {
+#ifndef O_NOT_LOG_ERRORS
+        log3("couldn't get information for ", login, "\n");
+#endif
+        _exit(111);
+#ifndef O_NOT_LOG
+        log3("no such user", login, "\n");
+#endif
+      }
+      _exit(1);
+    }
 #ifdef HASUSERPW
-  upw = getuserpw(login);
-  if (upw)
-    stored = upw->upw_passwd;
-  else
-    if (errno == error_txtbsy) _exit(111);
+    upw = getuserpw(login);
+    if (upw)
+      stored = upw->upw_passwd;
+    else
+      if (errno == error_txtbsy) {
+#ifndef O_NOT_LOG_ERRORS
+        log3("couldn't get information for ", login, "\n");
+#endif
+        _exit(111);
+      }
 #endif
 #ifdef HASGETSPNAM
-  spw = getspnam(login);
-  if (spw)
-    stored = spw->sp_pwdp;
-  else
-    if (errno == error_txtbsy) _exit(111);
+    spw = getspnam(login);
+    if (spw)
+      stored = spw->sp_pwdp;
+    else
+      if (errno == error_txtbsy) {
+#ifndef O_NOT_LOG_ERRORS
+        log3("couldn't get information for ", login, "\n");
 #endif
-  if (!stored) _exit(1);
+        _exit(111);
+      }
+#endif
+    if (!stored) {
+#ifndef O_NOT_LOG
+      log3("no password for ", pw->pw_name, "\n");
+#endif
+      _exit(1);
+    }
  
-  encrypted = crypt(password,stored);
-  for (i = 0;i < sizeof(up);++i) up[i] = 0;
+    encrypted = crypt(password,stored);
+    for (i = 0;i < sizeof(up);++i) up[i] = 0;
  
-  if (!*stored || strcmp(encrypted,stored)) _exit(1);
+    if (!*stored) {
+#ifndef O_NOT_LOG
+      log3("no such user ", pw->pw_name, "\n");
+#endif
+      _exit(1);
+    }
+    if (str_diff(encrypted,stored)) {
+#ifndef O_NOT_LOG
+      _exit(1);
+#endif
+    }
+  }
  
-  if (prot_gid((int) pw->pw_gid) == -1) _exit(1);
-  if (prot_uid((int) pw->pw_uid) == -1) _exit(1);
-  if (chdir(pw->pw_dir) == -1) _exit(111);
+  if (prot_gid((int) pw->pw_gid) == -1) {
+#ifndef O_NOT_LOG
+     log3("evil gid for ", login, "\n");
+#endif
+     _exit(1);
+  }
+  if (prot_uid((int) pw->pw_uid) == -1) {
+#ifndef O_NOT_LOG
+     log3("evil uid for ", login, "\n");
+#endif
+     _exit(1);
+  }
+  if (chdir(pw->pw_dir) == -1) {
+#ifndef O_NOT_LOG
+     log3("can't chdir(\"", pw->pw_dir, "\")\n");
+#endif
+     _exit(111);
+  }
+#ifndef O_NOT_LOG
+  log3("login by ", pw->pw_name, "\n");
+#endif
 
   if (!pathexec_env("USER",pw->pw_name)) _exit(111);
   if (!pathexec_env("HOME",pw->pw_dir)) _exit(111);
--- ../checkpassword-0.90-orig/connect_mysql.c	Thu Jan 18 12:14:11 2001
+++ connect_mysql.c	Thu Jan 18 10:37:17 2001
@@ -0,0 +1,44 @@
+#include <mysql/mysql.h>
+#include  "stralloc.h"
+#include "qsutil.h"
+
+#define TRIES 3
+
+/* let's alloc our strallocs */
+extern stralloc DB_HOST;
+extern stralloc DB_USER;
+extern stralloc DB_PASS;
+extern stralloc DB_NAME;
+extern stralloc DB_SOCK;
+extern stralloc DB_PORT;
+
+extern MYSQL dbh, *mysql;
+
+/* connect to the database                                                    */
+int connect_mysql() {
+  char *sock;
+  int i, port;
+
+  if (mysql) return 1;
+  if (init_mysql() == -1) return -1;
+  if (DB_PORT.a > 0) port = atoi(DB_PORT.s);
+  else port = 0;
+  if (DB_SOCK.a > 0) sock = DB_SOCK.s;
+  else sock = (char) 0;
+  for (i = 0; i < TRIES; i++) {
+    mysql = mysql_real_connect(&dbh, DB_HOST.s, DB_USER.s, DB_PASS.s, DB_NAME.s,
+                               port, sock, 0);
+    if (mysql) break;
+    /* this is bad - we'll log it regardless */
+    /* of the value of -DO_NOT_LOG_SQL       */
+    log3("error: ", mysql_error(&dbh), "\n");
+    sleep(3);
+  }
+
+  if (i < TRIES) return 1;
+  else return 0;
+}
+
+void disconnect_mysql() {
+  mysql_close(&dbh);
+}
--- ../checkpassword-0.90-orig/do_query.c	Thu Jan 18 12:14:11 2001
+++ do_query.c	Thu Jan 18 10:37:17 2001
@@ -0,0 +1,48 @@
+#include <mysql/mysql.h>
+#include "stralloc.h"
+#ifndef O_NOT_LOG_SQL
+#include "qsutil.h"
+#endif
+
+extern MYSQL dbh, *mysql;
+extern MYSQL_RES *result;
+
+/* run a given query and return 1 row only */
+MYSQL_ROW do_query(stralloc *query) {
+  int num;
+#ifndef O_NOT_LOG_SQL
+  int i;
+  char *x;
+  stralloc showme = { 0 };
+#endif
+
+  if (! connect_mysql()) return -1;
+#ifndef O_NOT_LOG_SQL
+  if (! stralloc_ready(&showme, query->a)) goto carryon;
+  num = i = 0;
+  for (x = query->s; num < 2; x++) {
+    if (*x == '(' || *x == ')') num++;
+    if (! num) i++;
+  }
+  if (! stralloc_catb(&showme, query->s, i)) goto carryon;
+  if (! stralloc_cats(&showme, x)) goto carryon;
+  if (! stralloc_0(&showme)) goto carryon;
+  log3("query: ", showme.s, ";\n");
+carryon:
+#endif
+  if (mysql_real_query(mysql, query->s, query->len) < 0) {
+    log3("error: ", mysql_error(&dbh), "\n");
+    return -1;
+  }
+  if (! (result = mysql_store_result(mysql))) return -1;
+
+  num = mysql_num_rows(result);
+
+  if (num != 1) {
+    mysql_free_result(result);
+    return 0;
+  }
+
+  return mysql_fetch_row(result);
+}
+
--- ../checkpassword-0.90-orig/fmt.h	Thu Jan 18 12:14:11 2001
+++ fmt.h	Thu Jan 18 10:37:17 2001
@@ -0,0 +1,25 @@
+#ifndef FMT_H
+#define FMT_H
+
+#define FMT_ULONG 40 /* enough space to hold 2^128 - 1 in decimal, plus \0 */
+#define FMT_LEN ((char *) 0) /* convenient abbreviation */
+
+extern unsigned int fmt_uint();
+extern unsigned int fmt_uint0();
+extern unsigned int fmt_xint();
+extern unsigned int fmt_nbbint();
+extern unsigned int fmt_ushort();
+extern unsigned int fmt_xshort();
+extern unsigned int fmt_nbbshort();
+extern unsigned int fmt_ulong();
+extern unsigned int fmt_xlong();
+extern unsigned int fmt_nbblong();
+
+extern unsigned int fmt_plusminus();
+extern unsigned int fmt_minus();
+extern unsigned int fmt_0x();
+
+extern unsigned int fmt_str();
+extern unsigned int fmt_strn();
+
+#endif
--- ../checkpassword-0.90-orig/fmt_uint.c	Thu Jan 18 12:14:11 2001
+++ fmt_uint.c	Thu Jan 18 10:37:17 2001
@@ -0,0 +1,6 @@
+#include "fmt.h"
+
+unsigned int fmt_uint(s,u) register char *s; register unsigned int u;
+{
+  register unsigned long l; l = u; return fmt_ulong(s,l);
+}
--- ../checkpassword-0.90-orig/fmt_uint0.c	Thu Jan 18 12:14:11 2001
+++ fmt_uint0.c	Thu Jan 18 10:37:17 2001
@@ -0,0 +1,10 @@
+#include "fmt.h"
+
+unsigned int fmt_uint0(s,u,n) char *s; unsigned int u; unsigned int n;
+{
+  unsigned int len;
+  len = fmt_uint(FMT_LEN,u);
+  while (len < n) { if (s) *s++ = '0'; ++len; }
+  if (s) fmt_uint(s,u);
+  return len;
+}
--- ../checkpassword-0.90-orig/fmt_ulong.c	Thu Jan 18 12:14:11 2001
+++ fmt_ulong.c	Thu Jan 18 10:37:17 2001
@@ -0,0 +1,13 @@
+#include "fmt.h"
+
+unsigned int fmt_ulong(s,u) register char *s; register unsigned long u;
+{
+  register unsigned int len; register unsigned long q;
+  len = 1; q = u;
+  while (q > 9) { ++len; q /= 10; }
+  if (s) {
+    s += len;
+    do { *--s = '0' + (u % 10); u /= 10; } while(u); /* handles u == 0 */
+  }
+  return len;
+}
--- ../checkpassword-0.90-orig/gen_alloc.h	Thu Jan 18 12:14:11 2001
+++ gen_alloc.h	Thu Jan 18 10:37:17 2001
@@ -5,3 +5,10 @@
   typedef struct ta { type *field; unsigned int len; unsigned int a; } ta;
 
 #endif
+#ifndef GEN_ALLOC_H
+#define GEN_ALLOC_H
+
+#define GEN_ALLOC_typedef(ta,type,field,len,a) \
+  typedef struct ta { type *field; unsigned int len; unsigned int a; } ta;
+
+#endif
--- ../checkpassword-0.90-orig/gen_allocdefs.h	Thu Jan 18 12:14:11 2001
+++ gen_allocdefs.h	Thu Jan 18 10:37:17 2001
@@ -2,6 +2,40 @@
 #define GEN_ALLOC_DEFS_H
 
 #define GEN_ALLOC_ready(ta,type,field,len,a,i,n,x,base,ta_ready) \
+int ta_ready(x,n) register ta *x; register unsigned int n; \
+{ register unsigned int i; \
+  if (x->field) { \
+    i = x->a; \
+    if (n > i) { \
+      x->a = base + n + (n >> 3); \
+      if (alloc_re(&x->field,i * sizeof(type),x->a * sizeof(type))) return 1; \
+      x->a = i; return 0; } \
+    return 1; } \
+  x->len = 0; \
+  return !!(x->field = (type *) alloc((x->a = n) * sizeof(type))); }
+
+#define GEN_ALLOC_readyplus(ta,type,field,len,a,i,n,x,base,ta_rplus) \
+int ta_rplus(x,n) register ta *x; register unsigned int n; \
+{ register unsigned int i; \
+  if (x->field) { \
+    i = x->a; n += x->len; \
+    if (n > i) { \
+      x->a = base + n + (n >> 3); \
+      if (alloc_re(&x->field,i * sizeof(type),x->a * sizeof(type))) return 1; \
+      x->a = i; return 0; } \
+    return 1; } \
+  x->len = 0; \
+  return !!(x->field = (type *) alloc((x->a = n) * sizeof(type))); }
+
+#define GEN_ALLOC_append(ta,type,field,len,a,i,n,x,base,ta_rplus,ta_append) \
+int ta_append(x,i) register ta *x; register type *i; \
+{ if (!ta_rplus(x,1)) return 0; x->field[x->len++] = *i; return 1; }
+
+#endif
+#ifndef GEN_ALLOC_DEFS_H
+#define GEN_ALLOC_DEFS_H
+
+#define GEN_ALLOC_ready(ta,type,field,len,a,i,n,x,base,ta_ready) \
 int ta_ready(register ta *x,register unsigned int n) \
 { register unsigned int i; \
   if (x->field) { \
--- ../checkpassword-0.90-orig/getln.c	Thu Jan 18 12:14:11 2001
+++ getln.c	Thu Jan 18 10:37:17 2001
@@ -0,0 +1,20 @@
+#include "substdio.h"
+#include "byte.h"
+#include "stralloc.h"
+#include "getln.h"
+
+int getln(ss,sa,match,sep)
+register substdio *ss;
+register stralloc *sa;
+int *match;
+int sep;
+{
+  char *cont;
+  unsigned int clen;
+
+  if (getln2(ss,sa,&cont,&clen,sep) == -1) return -1;
+  if (!clen) { *match = 0; return 0; }
+  if (!stralloc_catb(sa,cont,clen)) return -1;
+  *match = 1;
+  return 0;
+}
--- ../checkpassword-0.90-orig/getln.h	Thu Jan 18 12:14:11 2001
+++ getln.h	Thu Jan 18 10:37:17 2001
@@ -0,0 +1,7 @@
+#ifndef GETLN_H
+#define GETLN_H
+
+extern int getln();
+extern int getln2();
+
+#endif
--- ../checkpassword-0.90-orig/getln2.c	Thu Jan 18 12:14:11 2001
+++ getln2.c	Thu Jan 18 10:37:17 2001
@@ -0,0 +1,31 @@
+#include "substdio.h"
+#include "stralloc.h"
+#include "byte.h"
+#include "getln.h"
+
+int getln2(ss,sa,cont,clen,sep)
+register substdio *ss;
+register stralloc *sa;
+/*@out@*/char **cont;
+/*@out@*/unsigned int *clen;
+int sep;
+{
+  register char *x;
+  register unsigned int i;
+  int n;
+ 
+  if (!stralloc_ready(sa,0)) return -1;
+  sa->len = 0;
+ 
+  for (;;) {
+    n = substdio_feed(ss);
+    if (n < 0) return -1;
+    if (n == 0) { *clen = 0; return 0; }
+    x = substdio_PEEK(ss);
+    i = byte_chr(x,n,sep);
+    if (i < n) { substdio_SEEK(ss,*clen = i + 1); *cont = x; return 0; }
+    if (!stralloc_readyplus(sa,n)) return -1;
+    i = sa->len;
+    sa->len = i + substdio_get(ss,sa->s + i,n);
+  }
+}
--- ../checkpassword-0.90-orig/getpw_mysql.c	Thu Jan 18 12:14:11 2001
+++ getpw_mysql.c	Thu Jan 18 12:09:10 2001
@@ -0,0 +1,125 @@
+#include <mysql/mysql.h>
+#include <pwd.h>
+#include "mysql_queries.h"
+#include "qsutil.h"
+#include "case.h"
+#include "str.h"
+#include "stralloc.h"
+
+stralloc user = { 0 };
+stralloc home = { 0 };
+stralloc shell = { 0 };
+
+extern MYSQL dbh, *mysql;
+extern MYSQL_RES *result;
+
+extern MYSQL_ROW do_query(stralloc *query);
+
+struct passwd mypw;
+
+/* get a pw entry from the database                                           */
+/* returns: struct passwd if the user logged in, 1 if the user got password   */
+/* wrong or 2 if the user didn't exist (-1 on error)                          */
+struct passwd *getpw_mysql(char *username, char *pass) {
+  int i, len, uid, gid;
+  MYSQL_ROW row;
+  stralloc query = { 0 };
+  stralloc passwd = { 0 };
+  char *bogus;
+
+  i = str_len(username);
+
+  if (! stralloc_ready(&user, 2 * i + 1)) return -1;
+  len = str_len(POPSEL) + mysql_escape_string(user.s, username, i) + 2;
+  if (! stralloc_ready(&query, len)) return -1;
+  if (! stralloc_cats(&query, POPSEL)) return -1;
+  if (! stralloc_cats(&query, user.s)) return -1;
+  if (! stralloc_append(&query, "'")) return -1;
+  if (! stralloc_0(&query)) return -1;
+  
+  row = do_query(&query);
+  if ((int) row == -1) return -1;
+  if ((int) row == 0) {
+#ifndef O_NOT_LOG
+    log2(username, " does not exist in database\n");
+#endif
+    /* result has already been freed by do_query() */
+    disconnect_mysql();
+    return 0;
+  }
+
+  if (str_diff(row[1], "N")) {
+#ifndef O_NOT_LOG
+    log2(username, " is suspended\n");
+    mysql_free_result(result);
+    disconnect_mysql();
+    return 1;
+  }
+#endif
+
+#define ZARKS {\
+    mysql_free_result(result); \
+    disconnect_mysql(); \
+    return 1; \
+}
+
+  case_lowers(row[0]);
+  if (! str_diff(row[0], "password")) {
+    if (str_diff(row[2], pass)) {
+#ifndef O_NOT_LOG
+      log2(username, " got password wrong\n");
+#endif
+      ZARKS
+    }
+  }
+  else if (! str_diff(row[0], "crypt-password")) {
+    if (str_diff(row[2], crypt(pass, row[2]))) {
+#ifndef O_NOT_LOG
+      log2(username, " got crypt-password wrong\n");
+#endif
+      ZARKS
+    }
+  }
+  else if (! str_diff(row[0], "mysql-password")) {
+    if (! stralloc_ready(&passwd, 17)) return -1;
+    make_scrambled_password(passwd.s, pass);
+    if (str_diff(row[2], passwd.s)) {
+#ifndef O_NOT_LOG
+      log2(username, " got mysql-password wrong\n");
+#endif
+      ZARKS
+    }
+  }
+  else {
+    log2("MySQL misconfiguration: invalid password type for ", username);
+    ZARKS
+  }
+
+  uid = strtol(row[3], &bogus, 0);
+  if ((int) *bogus) {
+    log3("MySQL misconfiguration: uid should be a number for ", username, "!\n");
+    ZARKS
+  }
+  gid = strtol(row[4], &bogus, 0);
+  if ((int) *bogus) {
+    log3("MySQL misconfiguration: gid should be a number for ", username, "!\n");
+    ZARKS
+  }
+
+  if (! stralloc_ready(&home, str_len(row[5]))) return -1;
+  if (! stralloc_copys(&home, row[5])) return -1;
+  if (! stralloc_0(&home)) return -1;
+  if (! stralloc_ready(&shell, str_len(row[6]))) return -1;
+  if (! stralloc_copys(&shell, row[6])) return -1;
+  if (! stralloc_0(&shell)) return -1;
+
+  mysql_free_result(result);
+  disconnect_mysql();
+
+  mypw.pw_name = user.s;
+  mypw.pw_uid = uid;
+  mypw.pw_gid = gid;
+  mypw.pw_dir = home.s;
+  mypw.pw_shell = shell.s;
+  return &mypw;
+}
--- ../checkpassword-0.90-orig/hasshsgr.h	Thu Jan 18 12:14:11 2001
+++ hasshsgr.h	Thu Jan 18 11:01:39 2001
@@ -0,0 +1 @@
+/* sysdep: -shortsetgroups */
--- ../checkpassword-0.90-orig/hasspnam.h	Thu Jan 18 12:14:11 2001
+++ hasspnam.h	Thu Jan 18 11:01:37 2001
@@ -0,0 +1 @@
+#define HASGETSPNAM 1
--- ../checkpassword-0.90-orig/init_mysql.c	Thu Jan 18 12:14:11 2001
+++ init_mysql.c	Thu Jan 18 10:37:17 2001
@@ -0,0 +1,113 @@
+#include <mysql/mysql.h>
+#include <stdio.h>
+#include "auto_qmail.h"
+#include "readwrite.h"
+#include "str.h"
+#include "stralloc.h"
+#include "substdio.h"
+#include "subfd.h"
+
+#define SQLSERVER "/control/sqlserver"
+
+/* let's alloc our strallocs */
+stralloc DB_HOST = { 0 };
+stralloc DB_USER = { 0 };
+stralloc DB_PASS = { 0 };
+stralloc DB_NAME = { 0 };
+stralloc DB_SOCK = { 0 };
+stralloc DB_PORT = { 0 };
+
+static char inbuf[64];
+MYSQL dbh, *mysql;
+MYSQL_RES *result;
+
+/* read the config file and decide which server the database is on, what      */
+/* username and password we need to connect to it and which database to use   */
+/* return -1 if a bad error occurred, 0 if everything was OK or 1 if not      */
+int init_mysql() {
+  int i, error, file, match;
+  substdio ss;
+  stralloc filename = { 0 };
+  stralloc buf = { 0 };
+  
+  mysql = mysql_init(&dbh);
+  if (! mysql) return -1;
+
+  /* get the filename of the sqlserver control file */
+  i = str_len(SQLSERVER) + str_len(auto_qmail) + 1;
+  if (! stralloc_ready(&filename, i)) return -1;
+  if (! stralloc_cats(&filename, auto_qmail)) return -1;
+  if (! stralloc_cats(&filename, SQLSERVER)) return -1;
+  if (! stralloc_0(&filename)) return -1;
+  
+  /* try to open the file - much code robbed from control.c*/
+  file = open_read(filename.s);
+  if (file == -1) {
+    substdio_puts(subfderr, "warning: could not open sqlserver file ");
+    substdio_puts(subfderr, filename.s);
+    substdio_putsflush(subfderr, "\n");
+    return 0;
+  }
+  substdio_fdbuf(&ss, read, file, inbuf, sizeof(inbuf));
+  
+  i = 0;
+  while (getln(&ss, &buf, &match, '\n') != -1) {
+    if (! match && ! buf.len) break;
+    buf.len--;
+    if (! stralloc_0(&buf)) break;
+    /* we consider only lines starting with the letters s,l,p or d */
+    switch (buf.s[0]) {
+      case 's':
+        if (buf.s[1] == 'e') error = getconfig(&buf, "server", &DB_HOST);
+        else error = getconfig(&buf, "socket", &DB_SOCK);
+        break;
+      case 'l': error = getconfig(&buf, "login", &DB_USER); break;
+      case 'p':
+        if (buf.s[1] == 'a') error = getconfig(&buf, "password", &DB_PASS);
+        else error = getconfig(&buf, "port", &DB_PORT);
+        break;
+      case 'd': error = getconfig(&buf, "db", &DB_NAME); break;
+      default: continue;
+    }
+    if (error == -1) {
+      i = -1;
+      continue;
+    }
+    else i += error;
+    if (! match) break;
+  }
+  close(file);
+
+  if (i == -1)
+    substdio_putsflush(subfderr, "warning: there were errors reading sqlserver file\n");
+  else if (i > 0) {
+    substdio_putsflush(subfderr, "warning: bogus lines in sqlserver file\n");
+    i = 0;
+  }
+  return i;
+}
+
+/* read lines in the config file and grok entries of the form "x=y" or "x y"  */
+/* got is the line in the file, expected is the parmeter we're checking for   */
+/* and store is a stralloc to put the result into if it was found             */
+int getconfig(stralloc *got, char *expected, stralloc *store) {
+  char *value, *x;
+
+  x = got->s + str_len(expected);
+  value = x + 1;
+  /* we got a meaningful value */
+  if (! stralloc_starts(&got, expected) && (*x == ' ' || *x == '=') && str_len(value) > 0) {
+    if (! stralloc_ready(store, str_len(value))) return -1;
+    if (! stralloc_cats(store, value)) return -1;
+    if (! stralloc_0(store)) return -1;
+    return 0;
+  }
+  /* oh dear, the line we got didn't contain what we expected it to */
+  substdio_puts(subfderr, "error reading sqlserver file: expected '");
+  substdio_puts(subfderr, expected);
+  substdio_puts(subfderr, "' but got '");
+  substdio_puts(subfderr, got);
+  substdio_putsflush(subfderr, "'\n");
+  /* of course, we might have been expecting the wrong thing... */
+  return 1;
+}
--- ../checkpassword-0.90-orig/mysql_queries.h	Thu Jan 18 12:14:11 2001
+++ mysql_queries.h	Thu Jan 18 10:37:17 2001
@@ -0,0 +1,5 @@
+/* new, easier select query gets password type and whether the user is        */
+/* suspended direct from the database - depending on the password_type we'll  */
+/* call crypt() or mysql_hash() ourselves!                                    */
+#define POPSEL "select password_type, suspended, password, uid, gid, home, \
+'/bin/false' from mailbox where username='"
--- ../checkpassword-0.90-orig/qsutil.c	Thu Jan 18 12:14:11 2001
+++ qsutil.c	Thu Jan 18 10:37:17 2001
@@ -0,0 +1,22 @@
+#include "readwrite.h"
+#include "substdio.h"
+#include "qsutil.h"
+
+extern char strnum[];
+static char errbuf[1];
+/* change from qmail's qsutil: log to file descriptor 4 */
+static struct substdio sserr = SUBSTDIO_FDBUF(write,4,errbuf,1);
+
+void log2(s1,s2) char *s1; char *s2; {
+ substdio_putsflush(&sserr,"checkpassword: pid ");
+ substdio_putsflush(&sserr,strnum);
+ substdio_putsflush(&sserr," - ");
+ substdio_putsflush(&sserr,s1);
+ substdio_putsflush(&sserr,s2); }
+void log3(s1,s2,s3) char *s1; char *s2; char *s3; {
+ substdio_putsflush(&sserr,"checkpassword: pid ");
+ substdio_putsflush(&sserr,strnum);
+ substdio_putsflush(&sserr," - ");
+ substdio_putsflush(&sserr,s1);
+ substdio_putsflush(&sserr,s2);
+ substdio_putsflush(&sserr,s3); }
--- ../checkpassword-0.90-orig/qsutil.h	Thu Jan 18 12:14:11 2001
+++ qsutil.h	Thu Jan 18 10:37:17 2001
@@ -0,0 +1,7 @@
+#ifndef QSUTIL_H
+#define QSUTIL_H
+
+extern void log2();
+extern void log3(); 
+
+#endif
--- ../checkpassword-0.90-orig/scan.h	Thu Jan 18 12:14:11 2001
+++ scan.h	Thu Jan 18 10:37:17 2001
@@ -0,0 +1,27 @@
+#ifndef SCAN_H
+#define SCAN_H
+
+extern unsigned int scan_uint();
+extern unsigned int scan_xint();
+extern unsigned int scan_nbbint();
+extern unsigned int scan_ushort();
+extern unsigned int scan_xshort();
+extern unsigned int scan_nbbshort();
+extern unsigned int scan_ulong();
+extern unsigned int scan_xlong();
+extern unsigned int scan_nbblong();
+
+extern unsigned int scan_plusminus();
+extern unsigned int scan_0x();
+
+extern unsigned int scan_whitenskip();
+extern unsigned int scan_nonwhitenskip();
+extern unsigned int scan_charsetnskip();
+extern unsigned int scan_noncharsetnskip();
+
+extern unsigned int scan_strncmp();
+extern unsigned int scan_memcmp();
+
+extern unsigned int scan_long();
+
+#endif
--- ../checkpassword-0.90-orig/str_cpy.c	Thu Jan 18 12:14:11 2001
+++ str_cpy.c	Thu Jan 18 10:37:17 2001
@@ -0,0 +1,16 @@
+#include "str.h"
+
+unsigned int str_copy(s,t)
+register char *s;
+register char *t;
+{
+  register int len;
+
+  len = 0;
+  for (;;) {
+    if (!(*s = *t)) return len; ++s; ++t; ++len;
+    if (!(*s = *t)) return len; ++s; ++t; ++len;
+    if (!(*s = *t)) return len; ++s; ++t; ++len;
+    if (!(*s = *t)) return len; ++s; ++t; ++len;
+  }
+}
--- ../checkpassword-0.90-orig/str_diff.c	Thu Jan 18 12:14:11 2001
+++ str_diff.c	Thu Jan 18 10:37:17 2001
@@ -0,0 +1,17 @@
+#include "str.h"
+
+int str_diff(s,t)
+register char *s;
+register char *t;
+{
+  register char x;
+
+  for (;;) {
+    x = *s; if (x != *t) break; if (!x) break; ++s; ++t;
+    x = *s; if (x != *t) break; if (!x) break; ++s; ++t;
+    x = *s; if (x != *t) break; if (!x) break; ++s; ++t;
+    x = *s; if (x != *t) break; if (!x) break; ++s; ++t;
+  }
+  return ((int)(unsigned int)(unsigned char) x)
+       - ((int)(unsigned int)(unsigned char) *t);
+}
--- ../checkpassword-0.90-orig/str_start.c	Thu Jan 18 12:14:11 2001
+++ str_start.c	Thu Jan 18 11:17:06 2001
@@ -1,6 +1,8 @@
 #include "str.h"
 
-int str_start(register char *s,register char *t)
+int str_start(s,t)
+register char *s;
+register char *t;
 {
   register char x;
 
--- ../checkpassword-0.90-orig/stralloc.h	Thu Jan 18 12:14:11 2001
+++ stralloc.h	Thu Jan 18 10:37:17 2001
@@ -5,6 +5,27 @@
 
 GEN_ALLOC_typedef(stralloc,char,s,len,a)
 
+extern int stralloc_ready();
+extern int stralloc_readyplus();
+extern int stralloc_copy();
+extern int stralloc_cat();
+extern int stralloc_copys();
+extern int stralloc_cats();
+extern int stralloc_copyb();
+extern int stralloc_catb();
+extern int stralloc_append(); /* beware: this takes a pointer to 1 char */
+extern int stralloc_starts();
+
+#define stralloc_0(sa) stralloc_append(sa,"")
+
+#endif
+#ifndef STRALLOC_H
+#define STRALLOC_H
+
+#include "gen_alloc.h"
+
+GEN_ALLOC_typedef(stralloc,char,s,len,a)
+
 extern int stralloc_ready(stralloc *,unsigned int);
 extern int stralloc_readyplus(stralloc *,unsigned int);
 extern int stralloc_copy(stralloc *,stralloc *);
--- ../checkpassword-0.90-orig/stralloc_arts.c	Thu Jan 18 12:14:11 2001
+++ stralloc_arts.c	Thu Jan 18 10:37:17 2001
@@ -0,0 +1,12 @@
+#include "byte.h"
+#include "str.h"
+#include "stralloc.h"
+
+int stralloc_starts(sa,s)
+stralloc *sa;
+char *s;
+{
+  int len;
+  len = str_len(s);
+  return (sa->len >= len) && byte_equal(s,len,sa->s);
+}
--- ../checkpassword-0.90-orig/stralloc_cat.c	Thu Jan 18 12:14:11 2001
+++ stralloc_cat.c	Thu Jan 18 11:16:09 2001
@@ -1,7 +1,9 @@
 #include "byte.h"
 #include "stralloc.h"
 
-int stralloc_cat(stralloc *sato,stralloc *safrom)
+int stralloc_cat(sato,safrom)
+stralloc *sato;
+stralloc *safrom;
 {
   return stralloc_catb(sato,safrom->s,safrom->len);
 }
--- ../checkpassword-0.90-orig/stralloc_catb.c	Thu Jan 18 12:14:11 2001
+++ stralloc_catb.c	Thu Jan 18 11:16:16 2001
@@ -1,7 +1,10 @@
 #include "stralloc.h"
 #include "byte.h"
 
-int stralloc_catb(stralloc *sa,char *s,unsigned int n)
+int stralloc_catb(sa,s,n)
+stralloc *sa;
+char *s;
+unsigned int n;
 {
   if (!sa->s) return stralloc_copyb(sa,s,n);
   if (!stralloc_readyplus(sa,n + 1)) return 0;
--- ../checkpassword-0.90-orig/stralloc_cats.c	Thu Jan 18 12:14:11 2001
+++ stralloc_cats.c	Thu Jan 18 11:16:27 2001
@@ -2,7 +2,9 @@
 #include "str.h"
 #include "stralloc.h"
 
-int stralloc_cats(stralloc *sa,char *s)
+int stralloc_cats(sa,s)
+stralloc *sa;
+char *s;
 {
   return stralloc_catb(sa,s,str_len(s));
 }
--- ../checkpassword-0.90-orig/stralloc_copy.c	Thu Jan 18 12:14:11 2001
+++ stralloc_copy.c	Thu Jan 18 10:37:17 2001
@@ -0,0 +1,9 @@
+#include "byte.h"
+#include "stralloc.h"
+
+int stralloc_copy(sato,safrom)
+stralloc *sato;
+stralloc *safrom;
+{
+  return stralloc_copyb(sato,safrom->s,safrom->len);
+}
--- ../checkpassword-0.90-orig/stralloc_opyb.c	Thu Jan 18 12:14:12 2001
+++ stralloc_opyb.c	Thu Jan 18 11:16:40 2001
@@ -1,7 +1,10 @@
 #include "stralloc.h"
 #include "byte.h"
 
-int stralloc_copyb(stralloc *sa,char *s,unsigned int n)
+int stralloc_copyb(sa,s,n)
+stralloc *sa;
+char *s;
+unsigned int n;
 {
   if (!stralloc_ready(sa,n + 1)) return 0;
   byte_copy(sa->s,n,s);
--- ../checkpassword-0.90-orig/stralloc_opys.c	Thu Jan 18 12:14:12 2001
+++ stralloc_opys.c	Thu Jan 18 11:16:42 2001
@@ -2,7 +2,9 @@
 #include "str.h"
 #include "stralloc.h"
 
-int stralloc_copys(stralloc *sa,char *s)
+int stralloc_copys(sa,s)
+stralloc *sa;
+char *s;
 {
   return stralloc_copyb(sa,s,str_len(s));
 }
--- ../checkpassword-0.90-orig/subfd.h	Thu Jan 18 12:14:12 2001
+++ subfd.h	Thu Jan 18 11:17:35 2001
@@ -0,0 +1,15 @@
+#ifndef SUBFD_H
+#define SUBFD_H
+
+#include "substdio.h"
+
+extern substdio *subfdin;
+extern substdio *subfdinsmall;
+extern substdio *subfdout;
+extern substdio *subfdoutsmall;
+extern substdio *subfderr;
+
+extern int subfd_read();
+extern int subfd_readsmall();
+
+#endif
--- ../checkpassword-0.90-orig/subfderr.c	Thu Jan 18 12:14:12 2001
+++ subfderr.c	Sun Nov 22 04:29:52 1998
@@ -0,0 +1,7 @@
+#include "readwrite.h"
+#include "substdio.h"
+#include "subfd.h"
+
+char subfd_errbuf[256];
+static substdio it = SUBSTDIO_FDBUF(write,2,subfd_errbuf,256);
+substdio *subfderr = &it;
--- ../checkpassword-0.90-orig/substdi.c	Thu Jan 18 12:14:12 2001
+++ substdi.c	Sun Nov 22 04:29:52 1998
@@ -0,0 +1,91 @@
+#include "substdio.h"
+#include "byte.h"
+#include "error.h"
+
+static int oneread(op,fd,buf,len)
+register int (*op)();
+register int fd;
+register char *buf;
+register int len;
+{
+  register int r;
+
+  for (;;) {
+    r = op(fd,buf,len);
+    if (r == -1) if (errno == error_intr) continue;
+    return r;
+  }
+}
+
+static int getthis(s,buf,len)
+register substdio *s;
+register char *buf;
+register int len;
+{
+  register int r;
+  register int q;
+ 
+  r = s->p;
+  q = r - len;
+  if (q > 0) { r = len; s->p = q; } else s->p = 0;
+  byte_copy(buf,r,s->x + s->n);
+  s->n += r;
+  return r;
+}
+
+int substdio_feed(s)
+register substdio *s;
+{
+  register int r;
+  register int q;
+
+  if (s->p) return s->p;
+  q = s->n;
+  r = oneread(s->op,s->fd,s->x,q);
+  if (r <= 0) return r;
+  s->p = r;
+  q -= r;
+  s->n = q;
+  if (q > 0) /* damn, gotta shift */ byte_copyr(s->x + q,r,s->x);
+  return r;
+}
+
+int substdio_bget(s,buf,len)
+register substdio *s;
+register char *buf;
+register int len;
+{
+  register int r;
+ 
+  if (s->p > 0) return getthis(s,buf,len);
+  r = s->n; if (r <= len) return oneread(s->op,s->fd,buf,r);
+  r = substdio_feed(s); if (r <= 0) return r;
+  return getthis(s,buf,len);
+}
+
+int substdio_get(s,buf,len)
+register substdio *s;
+register char *buf;
+register int len;
+{
+  register int r;
+ 
+  if (s->p > 0) return getthis(s,buf,len);
+  if (s->n <= len) return oneread(s->op,s->fd,buf,len);
+  r = substdio_feed(s); if (r <= 0) return r;
+  return getthis(s,buf,len);
+}
+
+char *substdio_peek(s)
+register substdio *s;
+{
+  return s->x + s->n;
+}
+
+void substdio_seek(s,len)
+register substdio *s;
+register int len;
+{
+  s->n += len;
+  s->p -= len;
+}
--- ../checkpassword-0.90-orig/substdio.c	Thu Jan 18 12:14:12 2001
+++ substdio.c	Sun Nov 22 04:29:52 1998
@@ -0,0 +1,15 @@
+#include "substdio.h"
+
+void substdio_fdbuf(s,op,fd,buf,len)
+register substdio *s;
+register int (*op)();
+register int fd;
+register char *buf;
+register int len;
+{
+  s->x = buf;
+  s->fd = fd;
+  s->op = op;
+  s->p = 0;
+  s->n = len;
+}
--- ../checkpassword-0.90-orig/substdio.h	Thu Jan 18 12:14:12 2001
+++ substdio.h	Thu Jan 18 11:17:28 2001
@@ -0,0 +1,47 @@
+#ifndef SUBSTDIO_H
+#define SUBSTDIO_H
+
+typedef struct substdio {
+  char *x;
+  int p;
+  int n;
+  int fd;
+  int (*op)();
+} substdio;
+
+#define SUBSTDIO_FDBUF(op,fd,buf,len) { (buf), 0, (len), (fd), (op) }
+
+extern void substdio_fdbuf();
+
+extern int substdio_flush();
+extern int substdio_put();
+extern int substdio_bput();
+extern int substdio_putflush();
+extern int substdio_puts();
+extern int substdio_bputs();
+extern int substdio_putsflush();
+
+extern int substdio_get();
+extern int substdio_bget();
+extern int substdio_feed();
+
+extern char *substdio_peek();
+extern void substdio_seek();
+
+#define substdio_fileno(s) ((s)->fd)
+
+#define SUBSTDIO_INSIZE 8192
+#define SUBSTDIO_OUTSIZE 8192
+
+#define substdio_PEEK(s) ( (s)->x + (s)->n )
+#define substdio_SEEK(s,len) ( ( (s)->p -= (len) ) , ( (s)->n += (len) ) )
+
+#define substdio_BPUTC(s,c) \
+  ( ((s)->n != (s)->p) \
+    ? ( (s)->x[(s)->p++] = (c), 0 ) \
+    : substdio_bput((s),&(c),1) \
+  )
+
+extern int substdio_copy();
+
+#endif
--- ../checkpassword-0.90-orig/substdio_copy.c	Thu Jan 18 12:14:12 2001
+++ substdio_copy.c	Sun Nov 22 04:29:52 1998
@@ -0,0 +1,18 @@
+#include "substdio.h"
+
+int substdio_copy(ssout,ssin)
+register substdio *ssout;
+register substdio *ssin;
+{
+  register int n;
+  register char *x;
+
+  for (;;) {
+    n = substdio_feed(ssin);
+    if (n < 0) return -2;
+    if (!n) return 0;
+    x = substdio_PEEK(ssin);
+    if (substdio_put(ssout,x,n) == -1) return -3;
+    substdio_SEEK(ssin,n);
+  }
+}
--- ../checkpassword-0.90-orig/substdo.c	Thu Jan 18 12:14:12 2001
+++ substdo.c	Sun Nov 22 04:29:52 1998
@@ -0,0 +1,108 @@
+#include "substdio.h"
+#include "str.h"
+#include "byte.h"
+#include "error.h"
+
+static int allwrite(op,fd,buf,len)
+register int (*op)();
+register int fd;
+register char *buf;
+register int len;
+{
+  register int w;
+
+  while (len) {
+    w = op(fd,buf,len);
+    if (w == -1) {
+      if (errno == error_intr) continue;
+      return -1; /* note that some data may have been written */
+    }
+    if (w == 0) ; /* luser's fault */
+    buf += w;
+    len -= w;
+  }
+  return 0;
+}
+
+int substdio_flush(s)
+register substdio *s;
+{
+  register int p;
+ 
+  p = s->p;
+  if (!p) return 0;
+  s->p = 0;
+  return allwrite(s->op,s->fd,s->x,p);
+}
+
+int substdio_bput(s,buf,len)
+register substdio *s;
+register char *buf;
+register int len;
+{
+  register int n;
+ 
+  while (len > (n = s->n - s->p)) {
+    byte_copy(s->x + s->p,n,buf); s->p += n; buf += n; len -= n;
+    if (substdio_flush(s) == -1) return -1;
+  }
+  /* now len <= s->n - s->p */
+  byte_copy(s->x + s->p,len,buf);
+  s->p += len;
+  return 0;
+}
+
+int substdio_put(s,buf,len)
+register substdio *s;
+register char *buf;
+register int len;
+{
+  register int n;
+ 
+  n = s->n;
+  if (len > n - s->p) {
+    if (substdio_flush(s) == -1) return -1;
+    /* now s->p == 0 */
+    if (n < SUBSTDIO_OUTSIZE) n = SUBSTDIO_OUTSIZE;
+    while (len > s->n) {
+      if (n > len) n = len;
+      if (allwrite(s->op,s->fd,buf,n) == -1) return -1;
+      buf += n;
+      len -= n;
+    }
+  }
+  /* now len <= s->n - s->p */
+  byte_copy(s->x + s->p,len,buf);
+  s->p += len;
+  return 0;
+}
+
+int substdio_putflush(s,buf,len)
+register substdio *s;
+register char *buf;
+register int len;
+{
+  if (substdio_flush(s) == -1) return -1;
+  return allwrite(s->op,s->fd,buf,len);
+}
+
+int substdio_bputs(s,buf)
+register substdio *s;
+register char *buf;
+{
+  return substdio_bput(s,buf,str_len(buf));
+}
+
+int substdio_puts(s,buf)
+register substdio *s;
+register char *buf;
+{
+  return substdio_put(s,buf,str_len(buf));
+}
+
+int substdio_putsflush(s,buf)
+register substdio *s;
+register char *buf;
+{
+  return substdio_putflush(s,buf,str_len(buf));
+}
--- ../checkpassword-0.90-orig/conf-qmail	Thu Jan 18 12:14:12 2001
+++ conf-qmail	Thu Jan 18 12:14:09 2001
@@ -0,0 +1 @@
+/var/qmail
