summaryrefslogtreecommitdiff
path: root/checkpasswd
diff options
context:
space:
mode:
Diffstat (limited to 'checkpasswd')
-rw-r--r--checkpasswd/CHANGES25
-rw-r--r--checkpasswd/FILES78
-rw-r--r--checkpasswd/Makefile301
-rw-r--r--checkpasswd/README7
-rw-r--r--checkpasswd/SYSDEPS9
-rw-r--r--checkpasswd/TARGETS60
-rw-r--r--checkpasswd/TODO1
-rw-r--r--checkpasswd/VERSION1
-rw-r--r--checkpasswd/alloc.c32
-rw-r--r--checkpasswd/alloc.h8
-rw-r--r--checkpasswd/alloc_re.c17
-rw-r--r--checkpasswd/auto-str.c41
-rw-r--r--checkpasswd/auto_home.h6
-rw-r--r--checkpasswd/buffer.c10
-rw-r--r--checkpasswd/buffer.h56
-rw-r--r--checkpasswd/buffer_2.c6
-rw-r--r--checkpasswd/buffer_copy.c16
-rw-r--r--checkpasswd/buffer_get.c67
-rw-r--r--checkpasswd/buffer_put.c88
-rw-r--r--checkpasswd/byte.h13
-rw-r--r--checkpasswd/byte_copy.c14
-rw-r--r--checkpasswd/byte_cr.c16
-rw-r--r--checkpasswd/byte_diff.c16
-rw-r--r--checkpasswd/checkpassword.c92
-rw-r--r--checkpasswd/chkshsgr.c10
-rw-r--r--checkpasswd/choose.sh18
-rw-r--r--checkpasswd/conf-cc3
-rw-r--r--checkpasswd/conf-home4
-rw-r--r--checkpasswd/conf-ld3
-rw-r--r--checkpasswd/env.c15
-rw-r--r--checkpasswd/env.h8
-rw-r--r--checkpasswd/error.c123
-rw-r--r--checkpasswd/error.h27
-rw-r--r--checkpasswd/error_str.c267
-rw-r--r--checkpasswd/exit.h6
-rw-r--r--checkpasswd/find-systype.sh143
-rw-r--r--checkpasswd/gen_alloc.h7
-rw-r--r--checkpasswd/gen_allocdefs.h34
-rw-r--r--checkpasswd/hasshsgr.h11
-rw-r--r--checkpasswd/hasshsgr.h22
-rw-r--r--checkpasswd/hier.c6
-rw-r--r--checkpasswd/install.c149
-rw-r--r--checkpasswd/instcheck.c108
-rw-r--r--checkpasswd/open.h10
-rw-r--r--checkpasswd/open_read.c6
-rw-r--r--checkpasswd/open_trunc.c6
-rw-r--r--checkpasswd/pathexec.h8
-rw-r--r--checkpasswd/pathexec_env.c68
-rw-r--r--checkpasswd/pathexec_run.c46
-rw-r--r--checkpasswd/print-cc.sh5
-rw-r--r--checkpasswd/prot.c19
-rw-r--r--checkpasswd/prot.h7
-rw-r--r--checkpasswd/readwrite.h7
-rw-r--r--checkpasswd/str.h14
-rw-r--r--checkpasswd/str_chr.c17
-rw-r--r--checkpasswd/str_len.c14
-rw-r--r--checkpasswd/str_start.c13
-rw-r--r--checkpasswd/stralloc.h29
-rw-r--r--checkpasswd/stralloc_cat.c7
-rw-r--r--checkpasswd/stralloc_catb.c12
-rw-r--r--checkpasswd/stralloc_cats.c8
-rw-r--r--checkpasswd/stralloc_eady.c6
-rw-r--r--checkpasswd/stralloc_opyb.c11
-rw-r--r--checkpasswd/stralloc_opys.c8
-rw-r--r--checkpasswd/stralloc_pend.c5
-rw-r--r--checkpasswd/strerr.h78
-rw-r--r--checkpasswd/strerr_die.c31
-rw-r--r--checkpasswd/strerr_sys.c12
-rw-r--r--checkpasswd/trycpp.c7
-rw-r--r--checkpasswd/trycrypt.c4
-rw-r--r--checkpasswd/tryshadow.c4
-rw-r--r--checkpasswd/tryshsgr.c14
-rw-r--r--checkpasswd/tryslib.c4
-rw-r--r--checkpasswd/tryspnam.c9
-rw-r--r--checkpasswd/tryuserpw.c9
-rw-r--r--checkpasswd/warn-auto.sh2
-rw-r--r--checkpasswd/warn-shsgr3
-rw-r--r--checkpasswd/x86cpuid.c38
78 files changed, 2455 insertions, 0 deletions
diff --git a/checkpasswd/CHANGES b/checkpasswd/CHANGES
new file mode 100644
index 0000000..0f5c65f
--- /dev/null
+++ b/checkpasswd/CHANGES
@@ -0,0 +1,25 @@
+19981103
+ version: checkpassword 0.80, beta.
+19981121
+ portability problem: some Linux systems _simultaneously_ support
+ shadow passwords and non-shadow passwords. impact:
+ checkpassword would see only the shadow passwords. fix:
+ in doit(), use getpwnam() password if getspnam() fails
+ (except with ETXTBSY). tnx to several people.
+ portability problem: AIX needs -ls for getuserpw(). impact:
+ couldn't compile. fix: check for -ls; also use in
+ hasuserpw.h.
+ portability problem: some systems incorrectly return EISDIR for
+ mkdir("/",...). impact: couldn't install. fix: don't
+ bother installing anything except checkpassword.
+ version: checkpassword 0.81, beta.
+20001115
+ portability problem: PAM-based systems can put 0 into pw_passwd.
+ nitwits. impact: checkpassword inspects *0 and crashes.
+ fix: check for 0 and use "*" instead. tnx Sverre.
+20001222
+ internal: switched to new install system.
+ internal: prototypes.
+ internal: incorporated doit() into main().
+ internal: switched to pathexec and friends.
+ version: checkpassword 0.90, gamma.
diff --git a/checkpasswd/FILES b/checkpasswd/FILES
new file mode 100644
index 0000000..40d266d
--- /dev/null
+++ b/checkpasswd/FILES
@@ -0,0 +1,78 @@
+README
+TODO
+CHANGES
+VERSION
+FILES
+SYSDEPS
+TARGETS
+Makefile
+alloc.c
+alloc.h
+alloc_re.c
+auto-str.c
+auto_home.h
+buffer.c
+buffer.h
+buffer_2.c
+buffer_copy.c
+buffer_get.c
+buffer_put.c
+byte.h
+byte_copy.c
+byte_cr.c
+byte_diff.c
+checkpassword.c
+chkshsgr.c
+choose.sh
+conf-cc
+conf-home
+conf-ld
+env.c
+env.h
+error.c
+error.h
+error_str.c
+exit.h
+find-systype.sh
+gen_alloc.h
+gen_allocdefs.h
+hasshsgr.h1
+hasshsgr.h2
+hier.c
+install.c
+instcheck.c
+open.h
+open_read.c
+open_trunc.c
+pathexec.h
+pathexec_env.c
+pathexec_run.c
+print-cc.sh
+prot.c
+prot.h
+readwrite.h
+str.h
+str_chr.c
+str_len.c
+str_start.c
+stralloc.h
+stralloc_cat.c
+stralloc_catb.c
+stralloc_cats.c
+stralloc_eady.c
+stralloc_opyb.c
+stralloc_opys.c
+stralloc_pend.c
+strerr.h
+strerr_die.c
+strerr_sys.c
+trycpp.c
+trycrypt.c
+tryshadow.c
+tryshsgr.c
+tryslib.c
+tryspnam.c
+tryuserpw.c
+warn-auto.sh
+warn-shsgr
+x86cpuid.c
diff --git a/checkpasswd/Makefile b/checkpasswd/Makefile
new file mode 100644
index 0000000..9a68187
--- /dev/null
+++ b/checkpasswd/Makefile
@@ -0,0 +1,301 @@
+# Don't edit Makefile! Use conf-* for configuration.
+
+SHELL=/bin/sh
+
+default: it
+
+alloc.o: \
+compile alloc.c alloc.h error.h
+ ./compile alloc.c
+
+alloc_re.o: \
+compile alloc_re.c alloc.h byte.h
+ ./compile alloc_re.c
+
+auto-str: \
+load auto-str.o unix.a byte.a
+ ./load auto-str unix.a byte.a
+
+auto-str.o: \
+compile auto-str.c buffer.h readwrite.h exit.h
+ ./compile auto-str.c
+
+auto_home.c: \
+auto-str conf-home
+ ./auto-str auto_home `head -1 conf-home` > auto_home.c
+
+auto_home.o: \
+compile auto_home.c
+ ./compile auto_home.c
+
+buffer.o: \
+compile buffer.c buffer.h
+ ./compile buffer.c
+
+buffer_2.o: \
+compile buffer_2.c readwrite.h buffer.h
+ ./compile buffer_2.c
+
+buffer_copy.o: \
+compile buffer_copy.c buffer.h
+ ./compile buffer_copy.c
+
+buffer_get.o: \
+compile buffer_get.c buffer.h byte.h error.h
+ ./compile buffer_get.c
+
+buffer_put.o: \
+compile buffer_put.c buffer.h str.h byte.h error.h
+ ./compile buffer_put.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_copy.o: \
+compile byte_copy.c byte.h
+ ./compile byte_copy.c
+
+byte_cr.o: \
+compile byte_cr.c byte.h
+ ./compile byte_cr.c
+
+byte_diff.o: \
+compile byte_diff.c byte.h
+ ./compile byte_diff.c
+
+check: \
+it instcheck
+ ./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`
+
+checkpassword.o: \
+compile checkpassword.c error.h pathexec.h prot.h hasspnam.h \
+hasuserpw.h
+ ./compile checkpassword.c
+
+chkshsgr: \
+load chkshsgr.o
+ ./load chkshsgr
+
+chkshsgr.o: \
+compile chkshsgr.c exit.h
+ ./compile chkshsgr.c
+
+choose: \
+warn-auto.sh choose.sh conf-home
+ cat warn-auto.sh choose.sh \
+ | sed s}HOME}"`head -1 conf-home`"}g \
+ > choose
+ chmod 755 choose
+
+compile: \
+warn-auto.sh conf-cc systype print-cc.sh trycpp.c
+ sh print-cc.sh > compile
+ chmod 755 compile
+
+crypt.lib: \
+trycrypt.c compile load
+ ( ( ./compile trycrypt.c && \
+ ./load trycrypt -lcrypt ) >/dev/null 2>&1 \
+ && echo -lcrypt || exit 0 ) > crypt.lib
+ rm -f trycrypt.o trycrypt
+
+env.o: \
+compile env.c str.h env.h
+ ./compile env.c
+
+error.o: \
+compile error.c error.h
+ ./compile error.c
+
+error_str.o: \
+compile error_str.c error.h
+ ./compile error_str.c
+
+hasshsgr.h: \
+choose compile load tryshsgr.c hasshsgr.h1 hasshsgr.h2 chkshsgr \
+warn-shsgr
+ ./chkshsgr || ( cat warn-shsgr; exit 1 )
+ ./choose clr tryshsgr hasshsgr.h1 hasshsgr.h2 > hasshsgr.h
+
+hasspnam.h: \
+tryspnam.c compile load
+ ( ( ./compile tryspnam.c && ./load tryspnam ) >/dev/null \
+ 2>&1 \
+ && echo \#define HASGETSPNAM 1 || exit 0 ) > hasspnam.h
+ rm -f tryspnam.o tryspnam
+
+hasuserpw.h: \
+tryuserpw.c s.lib compile load
+ ( ( ./compile tryuserpw.c \
+ && ./load tryuserpw `cat s.lib` ) >/dev/null 2>&1 \
+ && echo \#define HASGETUSERPW 1 || exit 0 ) > hasuserpw.h
+ rm -f tryuserpw.o tryuserpw
+
+hier.o: \
+compile hier.c auto_home.h
+ ./compile hier.c
+
+install: \
+load install.o hier.o auto_home.o unix.a byte.a
+ ./load install hier.o auto_home.o unix.a byte.a
+
+install.o: \
+compile install.c buffer.h strerr.h error.h open.h readwrite.h exit.h
+ ./compile install.c
+
+instcheck: \
+load instcheck.o hier.o auto_home.o unix.a byte.a
+ ./load instcheck hier.o auto_home.o unix.a byte.a
+
+instcheck.o: \
+compile instcheck.c strerr.h error.h readwrite.h exit.h
+ ./compile instcheck.c
+
+it: \
+prog install instcheck
+
+load: \
+warn-auto.sh conf-ld
+ ( cat warn-auto.sh; \
+ echo 'main="$$1"; shift'; \
+ echo exec "`head -1 conf-ld`" \
+ '-o "$$main" "$$main".o $${1+"$$@"}' \
+ ) > load
+ chmod 755 load
+
+makelib: \
+warn-auto.sh systype
+ ( cat warn-auto.sh; \
+ echo 'main="$$1"; shift'; \
+ echo 'rm -f "$$main"'; \
+ echo 'ar cr "$$main" $${1+"$$@"}'; \
+ case "`cat systype`" in \
+ sunos-5.*) ;; \
+ unix_sv*) ;; \
+ irix64-*) ;; \
+ irix-*) ;; \
+ dgux-*) ;; \
+ hp-ux-*) ;; \
+ sco*) ;; \
+ *) echo 'ranlib "$$main"' ;; \
+ esac \
+ ) > makelib
+ chmod 755 makelib
+
+open_read.o: \
+compile open_read.c open.h
+ ./compile open_read.c
+
+open_trunc.o: \
+compile open_trunc.c open.h
+ ./compile open_trunc.c
+
+pathexec_env.o: \
+compile pathexec_env.c stralloc.h gen_alloc.h alloc.h str.h byte.h \
+env.h pathexec.h
+ ./compile pathexec_env.c
+
+pathexec_run.o: \
+compile pathexec_run.c error.h stralloc.h gen_alloc.h str.h env.h \
+pathexec.h
+ ./compile pathexec_run.c
+
+prog: \
+checkpassword
+
+prot.o: \
+compile prot.c hasshsgr.h prot.h
+ ./compile prot.c
+
+s.lib: \
+tryslib.c compile load
+ ( ( ./compile tryslib.c && \
+ ./load tryslib -ls ) >/dev/null 2>&1 \
+ && echo -ls || exit 0 ) > s.lib
+ rm -f tryslib.o tryslib
+
+setup: \
+it install
+ ./install
+
+shadow.lib: \
+tryshadow.c compile load
+ ( ( ./compile tryshadow.c && \
+ ./load tryshadow -lshadow ) >/dev/null 2>&1 \
+ && echo -lshadow || exit 0 ) > shadow.lib
+ rm -f tryshadow.o tryshadow
+
+str_chr.o: \
+compile str_chr.c str.h
+ ./compile str_chr.c
+
+str_len.o: \
+compile str_len.c str.h
+ ./compile str_len.c
+
+str_start.o: \
+compile str_start.c str.h
+ ./compile str_start.c
+
+stralloc_cat.o: \
+compile stralloc_cat.c byte.h stralloc.h gen_alloc.h
+ ./compile stralloc_cat.c
+
+stralloc_catb.o: \
+compile stralloc_catb.c stralloc.h gen_alloc.h byte.h
+ ./compile stralloc_catb.c
+
+stralloc_cats.o: \
+compile stralloc_cats.c byte.h str.h stralloc.h gen_alloc.h
+ ./compile stralloc_cats.c
+
+stralloc_eady.o: \
+compile stralloc_eady.c alloc.h stralloc.h gen_alloc.h \
+gen_allocdefs.h
+ ./compile stralloc_eady.c
+
+stralloc_opyb.o: \
+compile stralloc_opyb.c stralloc.h gen_alloc.h byte.h
+ ./compile stralloc_opyb.c
+
+stralloc_opys.o: \
+compile stralloc_opys.c byte.h str.h stralloc.h gen_alloc.h
+ ./compile stralloc_opys.c
+
+stralloc_pend.o: \
+compile stralloc_pend.c alloc.h stralloc.h gen_alloc.h \
+gen_allocdefs.h
+ ./compile stralloc_pend.c
+
+strerr_die.o: \
+compile strerr_die.c buffer.h exit.h strerr.h
+ ./compile strerr_die.c
+
+strerr_sys.o: \
+compile strerr_sys.c error.h strerr.h
+ ./compile strerr_sys.c
+
+systype: \
+find-systype.sh trycpp.c x86cpuid.c
+ sh find-systype.sh > systype
+
+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
+ ./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 \
+ stralloc_cats.o stralloc_eady.o stralloc_opyb.o \
+ stralloc_opys.o stralloc_pend.o strerr_die.o strerr_sys.o
diff --git a/checkpasswd/README b/checkpasswd/README
new file mode 100644
index 0000000..142b116
--- /dev/null
+++ b/checkpasswd/README
@@ -0,0 +1,7 @@
+checkpassword 0.90, gamma.
+20001222
+Copyright 2000
+D. J. Bernstein
+
+checkpassword home page: http://cr.yp.to/checkpwd.html
+Installation instructions: http://cr.yp.to/checkpwd/install.html
diff --git a/checkpasswd/SYSDEPS b/checkpasswd/SYSDEPS
new file mode 100644
index 0000000..cfda43a
--- /dev/null
+++ b/checkpasswd/SYSDEPS
@@ -0,0 +1,9 @@
+VERSION
+systype
+crypt.lib
+shadow.lib
+s.lib
+hasspnam.h
+hasuserpw.h
+hasshsgr.h
+hasshsgr.h
diff --git a/checkpasswd/TARGETS b/checkpasswd/TARGETS
new file mode 100644
index 0000000..f14abd3
--- /dev/null
+++ b/checkpasswd/TARGETS
@@ -0,0 +1,60 @@
+load
+systype
+compile
+hasspnam.h
+s.lib
+hasuserpw.h
+checkpassword.o
+choose
+chkshsgr.o
+chkshsgr
+hasshsgr.h
+prot.o
+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
+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
+unix.a
+byte_copy.o
+byte_cr.o
+byte_diff.o
+str_chr.o
+str_len.o
+str_start.o
+byte.a
+shadow.lib
+crypt.lib
+checkpassword
+prog
+install.o
+hier.o
+auto-str.o
+auto-str
+auto_home.c
+auto_home.o
+install
+instcheck.o
+instcheck
+it
+setup
+check
diff --git a/checkpasswd/TODO b/checkpasswd/TODO
new file mode 100644
index 0000000..cd0438e
--- /dev/null
+++ b/checkpasswd/TODO
@@ -0,0 +1 @@
+check portability
diff --git a/checkpasswd/VERSION b/checkpasswd/VERSION
new file mode 100644
index 0000000..e3d6267
--- /dev/null
+++ b/checkpasswd/VERSION
@@ -0,0 +1 @@
+checkpassword 0.90
diff --git a/checkpasswd/alloc.c b/checkpasswd/alloc.c
new file mode 100644
index 0000000..0e2d4cd
--- /dev/null
+++ b/checkpasswd/alloc.c
@@ -0,0 +1,32 @@
+#include "alloc.h"
+#include "error.h"
+extern char *malloc();
+extern void free();
+
+#define ALIGNMENT 16 /* XXX: assuming that this alignment is enough */
+#define SPACE 2048 /* must be multiple of ALIGNMENT */
+
+typedef union { char irrelevant[ALIGNMENT]; double d; } aligned;
+static aligned realspace[SPACE / ALIGNMENT];
+#define space ((char *) realspace)
+static unsigned int avail = SPACE; /* multiple of ALIGNMENT; 0<=avail<=SPACE */
+
+/*@null@*//*@out@*/char *alloc(n)
+unsigned int n;
+{
+ char *x;
+ n = ALIGNMENT + n - (n & (ALIGNMENT - 1)); /* XXX: could overflow */
+ if (n <= avail) { avail -= n; return space + avail; }
+ x = malloc(n);
+ if (!x) errno = error_nomem;
+ return x;
+}
+
+void alloc_free(x)
+char *x;
+{
+ if (x >= space)
+ if (x < space + SPACE)
+ return; /* XXX: assuming that pointers are flat */
+ free(x);
+}
diff --git a/checkpasswd/alloc.h b/checkpasswd/alloc.h
new file mode 100644
index 0000000..1b1d893
--- /dev/null
+++ b/checkpasswd/alloc.h
@@ -0,0 +1,8 @@
+#ifndef ALLOC_H
+#define ALLOC_H
+
+extern /*@null@*//*@out@*/char *alloc();
+extern void alloc_free();
+extern int alloc_re();
+
+#endif
diff --git a/checkpasswd/alloc_re.c b/checkpasswd/alloc_re.c
new file mode 100644
index 0000000..feb8b49
--- /dev/null
+++ b/checkpasswd/alloc_re.c
@@ -0,0 +1,17 @@
+#include "alloc.h"
+#include "byte.h"
+
+int alloc_re(x,m,n)
+char **x;
+unsigned int m;
+unsigned int n;
+{
+ char *y;
+
+ y = alloc(n);
+ if (!y) return 0;
+ byte_copy(y,m,*x);
+ alloc_free(*x);
+ *x = y;
+ return 1;
+}
diff --git a/checkpasswd/auto-str.c b/checkpasswd/auto-str.c
new file mode 100644
index 0000000..1340591
--- /dev/null
+++ b/checkpasswd/auto-str.c
@@ -0,0 +1,41 @@
+#include "buffer.h"
+#include "readwrite.h"
+#include "exit.h"
+
+char bspace[256];
+buffer b = BUFFER_INIT(write,1,bspace,sizeof bspace);
+
+void puts(char *s)
+{
+ if (buffer_puts(&b,s) == -1) _exit(111);
+}
+
+main(int argc,char **argv)
+{
+ char *name;
+ char *value;
+ unsigned char ch;
+ char octal[4];
+
+ name = argv[1];
+ if (!name) _exit(100);
+ value = argv[2];
+ if (!value) _exit(100);
+
+ puts("const char ");
+ puts(name);
+ puts("[] = \"\\\n");
+
+ while (ch = *value++) {
+ puts("\\");
+ octal[3] = 0;
+ octal[2] = '0' + (ch & 7); ch >>= 3;
+ octal[1] = '0' + (ch & 7); ch >>= 3;
+ octal[0] = '0' + (ch & 7);
+ puts(octal);
+ }
+
+ puts("\\\n\";\n");
+ if (buffer_flush(&b) == -1) _exit(111);
+ _exit(0);
+}
diff --git a/checkpasswd/auto_home.h b/checkpasswd/auto_home.h
new file mode 100644
index 0000000..bd59284
--- /dev/null
+++ b/checkpasswd/auto_home.h
@@ -0,0 +1,6 @@
+#ifndef AUTO_HOME_H
+#define AUTO_HOME_H
+
+extern const char auto_home[];
+
+#endif
diff --git a/checkpasswd/buffer.c b/checkpasswd/buffer.c
new file mode 100644
index 0000000..f44a697
--- /dev/null
+++ b/checkpasswd/buffer.c
@@ -0,0 +1,10 @@
+#include "buffer.h"
+
+void buffer_init(buffer *s,int (*op)(),int fd,char *buf,unsigned int len)
+{
+ s->x = buf;
+ s->fd = fd;
+ s->op = op;
+ s->p = 0;
+ s->n = len;
+}
diff --git a/checkpasswd/buffer.h b/checkpasswd/buffer.h
new file mode 100644
index 0000000..12539b3
--- /dev/null
+++ b/checkpasswd/buffer.h
@@ -0,0 +1,56 @@
+#ifndef BUFFER_H
+#define BUFFER_H
+
+typedef struct buffer {
+ char *x;
+ unsigned int p;
+ unsigned int n;
+ int fd;
+ int (*op)();
+} buffer;
+
+#define BUFFER_INIT(op,fd,buf,len) { (buf), 0, (len), (fd), (op) }
+#define BUFFER_INSIZE 8192
+#define BUFFER_OUTSIZE 8192
+
+extern void buffer_init(buffer *,int (*)(),int,char *,unsigned int);
+
+extern int buffer_flush(buffer *);
+extern int buffer_put(buffer *,char *,unsigned int);
+extern int buffer_putalign(buffer *,char *,unsigned int);
+extern int buffer_putflush(buffer *,char *,unsigned int);
+extern int buffer_puts(buffer *,char *);
+extern int buffer_putsalign(buffer *,char *);
+extern int buffer_putsflush(buffer *,char *);
+
+#define buffer_PUTC(s,c) \
+ ( ((s)->n != (s)->p) \
+ ? ( (s)->x[(s)->p++] = (c), 0 ) \
+ : buffer_put((s),&(c),1) \
+ )
+
+extern int buffer_get(buffer *,char *,unsigned int);
+extern int buffer_bget(buffer *,char *,unsigned int);
+extern int buffer_feed(buffer *);
+
+extern char *buffer_peek(buffer *);
+extern void buffer_seek(buffer *,unsigned int);
+
+#define buffer_PEEK(s) ( (s)->x + (s)->n )
+#define buffer_SEEK(s,len) ( ( (s)->p -= (len) ) , ( (s)->n += (len) ) )
+
+#define buffer_GETC(s,c) \
+ ( ((s)->p > 0) \
+ ? ( *(c) = (s)->x[(s)->n], buffer_SEEK((s),1), 1 ) \
+ : buffer_get((s),(c),1) \
+ )
+
+extern int buffer_copy(buffer *,buffer *);
+
+extern buffer *buffer_0;
+extern buffer *buffer_0small;
+extern buffer *buffer_1;
+extern buffer *buffer_1small;
+extern buffer *buffer_2;
+
+#endif
diff --git a/checkpasswd/buffer_2.c b/checkpasswd/buffer_2.c
new file mode 100644
index 0000000..297825c
--- /dev/null
+++ b/checkpasswd/buffer_2.c
@@ -0,0 +1,6 @@
+#include "readwrite.h"
+#include "buffer.h"
+
+char buffer_2_space[256];
+static buffer it = BUFFER_INIT(write,2,buffer_2_space,sizeof buffer_2_space);
+buffer *buffer_2 = &it;
diff --git a/checkpasswd/buffer_copy.c b/checkpasswd/buffer_copy.c
new file mode 100644
index 0000000..dc4d4b1
--- /dev/null
+++ b/checkpasswd/buffer_copy.c
@@ -0,0 +1,16 @@
+#include "buffer.h"
+
+int buffer_copy(buffer *bout,buffer *bin)
+{
+ int n;
+ char *x;
+
+ for (;;) {
+ n = buffer_feed(bin);
+ if (n < 0) return -2;
+ if (!n) return 0;
+ x = buffer_PEEK(bin);
+ if (buffer_put(bout,x,n) == -1) return -3;
+ buffer_SEEK(bin,n);
+ }
+}
diff --git a/checkpasswd/buffer_get.c b/checkpasswd/buffer_get.c
new file mode 100644
index 0000000..937b75e
--- /dev/null
+++ b/checkpasswd/buffer_get.c
@@ -0,0 +1,67 @@
+#include "buffer.h"
+#include "byte.h"
+#include "error.h"
+
+static int oneread(int (*op)(),int fd,char *buf,unsigned int len)
+{
+ int r;
+
+ for (;;) {
+ r = op(fd,buf,len);
+ if (r == -1) if (errno == error_intr) continue;
+ return r;
+ }
+}
+
+static int getthis(buffer *s,char *buf,unsigned int len)
+{
+ if (len > s->p) len = s->p;
+ s->p -= len;
+ byte_copy(buf,len,s->x + s->n);
+ s->n += len;
+ return len;
+}
+
+int buffer_feed(buffer *s)
+{
+ int r;
+
+ if (s->p) return s->p;
+ r = oneread(s->op,s->fd,s->x,s->n);
+ if (r <= 0) return r;
+ s->p = r;
+ s->n -= r;
+ if (s->n > 0) byte_copyr(s->x + s->n,r,s->x);
+ return r;
+}
+
+int buffer_bget(buffer *s,char *buf,unsigned int len)
+{
+ int r;
+
+ if (s->p > 0) return getthis(s,buf,len);
+ if (s->n <= len) return oneread(s->op,s->fd,buf,s->n);
+ r = buffer_feed(s); if (r <= 0) return r;
+ return getthis(s,buf,len);
+}
+
+int buffer_get(buffer *s,char *buf,unsigned int len)
+{
+ int r;
+
+ if (s->p > 0) return getthis(s,buf,len);
+ if (s->n <= len) return oneread(s->op,s->fd,buf,len);
+ r = buffer_feed(s); if (r <= 0) return r;
+ return getthis(s,buf,len);
+}
+
+char *buffer_peek(buffer *s)
+{
+ return s->x + s->n;
+}
+
+void buffer_seek(buffer *s,unsigned int len)
+{
+ s->n += len;
+ s->p -= len;
+}
diff --git a/checkpasswd/buffer_put.c b/checkpasswd/buffer_put.c
new file mode 100644
index 0000000..a05e1f5
--- /dev/null
+++ b/checkpasswd/buffer_put.c
@@ -0,0 +1,88 @@
+#include "buffer.h"
+#include "str.h"
+#include "byte.h"
+#include "error.h"
+
+static int allwrite(int (*op)(),int fd,char *buf,unsigned int len)
+{
+ 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 buffer_flush(buffer *s)
+{
+ int p;
+
+ p = s->p;
+ if (!p) return 0;
+ s->p = 0;
+ return allwrite(s->op,s->fd,s->x,p);
+}
+
+int buffer_putalign(buffer *s,char *buf,unsigned int len)
+{
+ unsigned 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 (buffer_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 buffer_put(buffer *s,char *buf,unsigned int len)
+{
+ unsigned int n;
+
+ n = s->n;
+ if (len > n - s->p) {
+ if (buffer_flush(s) == -1) return -1;
+ /* now s->p == 0 */
+ if (n < BUFFER_OUTSIZE) n = BUFFER_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 buffer_putflush(buffer *s,char *buf,unsigned int len)
+{
+ if (buffer_flush(s) == -1) return -1;
+ return allwrite(s->op,s->fd,buf,len);
+}
+
+int buffer_putsalign(buffer *s,char *buf)
+{
+ return buffer_putalign(s,buf,str_len(buf));
+}
+
+int buffer_puts(buffer *s,char *buf)
+{
+ return buffer_put(s,buf,str_len(buf));
+}
+
+int buffer_putsflush(buffer *s,char *buf)
+{
+ return buffer_putflush(s,buf,str_len(buf));
+}
diff --git a/checkpasswd/byte.h b/checkpasswd/byte.h
new file mode 100644
index 0000000..de06c69
--- /dev/null
+++ b/checkpasswd/byte.h
@@ -0,0 +1,13 @@
+#ifndef BYTE_H
+#define BYTE_H
+
+extern unsigned int byte_chr();
+extern unsigned int byte_rchr();
+extern void byte_copy();
+extern void byte_copyr();
+extern int byte_diff();
+extern void byte_zero();
+
+#define byte_equal(s,n,t) (!byte_diff((s),(n),(t)))
+
+#endif
diff --git a/checkpasswd/byte_copy.c b/checkpasswd/byte_copy.c
new file mode 100644
index 0000000..eaad11b
--- /dev/null
+++ b/checkpasswd/byte_copy.c
@@ -0,0 +1,14 @@
+#include "byte.h"
+
+void byte_copy(to,n,from)
+register char *to;
+register unsigned int n;
+register char *from;
+{
+ for (;;) {
+ if (!n) return; *to++ = *from++; --n;
+ if (!n) return; *to++ = *from++; --n;
+ if (!n) return; *to++ = *from++; --n;
+ if (!n) return; *to++ = *from++; --n;
+ }
+}
diff --git a/checkpasswd/byte_cr.c b/checkpasswd/byte_cr.c
new file mode 100644
index 0000000..3e7a1d5
--- /dev/null
+++ b/checkpasswd/byte_cr.c
@@ -0,0 +1,16 @@
+#include "byte.h"
+
+void byte_copyr(to,n,from)
+register char *to;
+register unsigned int n;
+register char *from;
+{
+ to += n;
+ from += n;
+ for (;;) {
+ if (!n) return; *--to = *--from; --n;
+ if (!n) return; *--to = *--from; --n;
+ if (!n) return; *--to = *--from; --n;
+ if (!n) return; *--to = *--from; --n;
+ }
+}
diff --git a/checkpasswd/byte_diff.c b/checkpasswd/byte_diff.c
new file mode 100644
index 0000000..cdbd760
--- /dev/null
+++ b/checkpasswd/byte_diff.c
@@ -0,0 +1,16 @@
+#include "byte.h"
+
+int byte_diff(s,n,t)
+register char *s;
+register unsigned int n;
+register char *t;
+{
+ for (;;) {
+ if (!n) return 0; if (*s != *t) break; ++s; ++t; --n;
+ if (!n) return 0; if (*s != *t) break; ++s; ++t; --n;
+ if (!n) return 0; if (*s != *t) break; ++s; ++t; --n;
+ if (!n) return 0; if (*s != *t) break; ++s; ++t; --n;
+ }
+ return ((int)(unsigned int)(unsigned char) *s)
+ - ((int)(unsigned int)(unsigned char) *t);
+}
diff --git a/checkpasswd/checkpassword.c b/checkpasswd/checkpassword.c
new file mode 100644
index 0000000..afca798
--- /dev/null
+++ b/checkpasswd/checkpassword.c
@@ -0,0 +1,92 @@
+#include "error.h"
+#include "pathexec.h"
+#include "prot.h"
+
+extern char *crypt();
+#include <pwd.h>
+static struct passwd *pw;
+
+#include "hasspnam.h"
+#ifdef HASGETSPNAM
+#include <shadow.h>
+static struct spwd *spw;
+#endif
+
+#include "hasuserpw.h"
+#ifdef HASUSERPW
+#include <userpw.h>
+static struct userpw *upw;
+#endif
+
+static char up[513];
+static int uplen;
+
+main(int argc,char **argv)
+{
+ char *login;
+ char *password;
+ char *encrypted;
+ char *stored;
+ int r;
+ int i;
+
+ if (!argv[1]) _exit(2);
+
+ uplen = 0;
+ for (;;) {
+ do
+ r = read(3,up + uplen,sizeof(up) - uplen);
+ while ((r == -1) && (errno == error_intr));
+ if (r == -1) _exit(111);
+ if (r == 0) break;
+ uplen += r;
+ if (uplen >= sizeof(up)) _exit(1);
+ }
+ close(3);
+
+ i = 0;
+ if (i >= uplen) _exit(2);
+ login = up + i;
+ while (up[i++]) if (i >= uplen) _exit(2);
+ password = up + i;
+ 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);
+ }
+#ifdef HASUSERPW
+ upw = getuserpw(login);
+ if (upw)
+ stored = upw->upw_passwd;
+ else
+ if (errno == error_txtbsy) _exit(111);
+#endif
+#ifdef HASGETSPNAM
+ spw = getspnam(login);
+ if (spw)
+ stored = spw->sp_pwdp;
+ else
+ if (errno == error_txtbsy) _exit(111);
+#endif
+ if (!stored) _exit(1);
+
+ encrypted = crypt(password,stored);
+ for (i = 0;i < sizeof(up);++i) up[i] = 0;
+
+ if (!*stored || strcmp(encrypted,stored)) _exit(1);
+
+ 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 (!pathexec_env("USER",pw->pw_name)) _exit(111);
+ if (!pathexec_env("HOME",pw->pw_dir)) _exit(111);
+ if (!pathexec_env("SHELL",pw->pw_shell)) _exit(111);
+ pathexec(argv + 1);
+ _exit(111);
+}
diff --git a/checkpasswd/chkshsgr.c b/checkpasswd/chkshsgr.c
new file mode 100644
index 0000000..4c7fc83
--- /dev/null
+++ b/checkpasswd/chkshsgr.c
@@ -0,0 +1,10 @@
+#include "exit.h"
+
+main()
+{
+ short x[4];
+
+ x[0] = x[1] = 0;
+ if (getgroups(1,x) == 0) if (setgroups(1,x) == -1) _exit(1);
+ _exit(0);
+}
diff --git a/checkpasswd/choose.sh b/checkpasswd/choose.sh
new file mode 100644
index 0000000..feff2da
--- /dev/null
+++ b/checkpasswd/choose.sh
@@ -0,0 +1,18 @@
+
+result="$4"
+
+case "$1" in
+ *c*) ./compile $2.c >/dev/null 2>&1 || result="$3" ;;
+esac
+
+case "$1" in
+ *l*) ./load $2 >/dev/null 2>&1 || result="$3" ;;
+esac
+
+case "$1" in
+ *r*) ./$2 >/dev/null 2>&1 || result="$3" ;;
+esac
+
+rm -f $2.o $2
+
+exec cat "$result"
diff --git a/checkpasswd/conf-cc b/checkpasswd/conf-cc
new file mode 100644
index 0000000..7f41e18
--- /dev/null
+++ b/checkpasswd/conf-cc
@@ -0,0 +1,3 @@
+gcc -O2
+
+This will be used to compile .c files.
diff --git a/checkpasswd/conf-home b/checkpasswd/conf-home
new file mode 100644
index 0000000..b9a9e2b
--- /dev/null
+++ b/checkpasswd/conf-home
@@ -0,0 +1,4 @@
+/
+
+This is the checkpassword home directory. The checkpassword program will
+be installed in the bin subdirectory.
diff --git a/checkpasswd/conf-ld b/checkpasswd/conf-ld
new file mode 100644
index 0000000..59a0de7
--- /dev/null
+++ b/checkpasswd/conf-ld
@@ -0,0 +1,3 @@
+gcc -s
+
+This will be used to link .o files into an executable.
diff --git a/checkpasswd/env.c b/checkpasswd/env.c
new file mode 100644
index 0000000..430203e
--- /dev/null
+++ b/checkpasswd/env.c
@@ -0,0 +1,15 @@
+#include "str.h"
+#include "env.h"
+
+extern /*@null@*/char *env_get(char *s)
+{
+ int i;
+ unsigned int len;
+
+ if (!s) return 0;
+ len = str_len(s);
+ for (i = 0;environ[i];++i)
+ if (str_start(environ[i],s) && (environ[i][len] == '='))
+ return environ[i] + len + 1;
+ return 0;
+}
diff --git a/checkpasswd/env.h b/checkpasswd/env.h
new file mode 100644
index 0000000..777873a
--- /dev/null
+++ b/checkpasswd/env.h
@@ -0,0 +1,8 @@
+#ifndef ENV_H
+#define ENV_H
+
+extern char **environ;
+
+extern /*@null@*/char *env_get(char *);
+
+#endif
diff --git a/checkpasswd/error.c b/checkpasswd/error.c
new file mode 100644
index 0000000..14adef0
--- /dev/null
+++ b/checkpasswd/error.c
@@ -0,0 +1,123 @@
+#include <errno.h>
+#include "error.h"
+
+/* warning: as coverage improves here, should update error_{str,temp} */
+
+int error_intr =
+#ifdef EINTR
+EINTR;
+#else
+-1;
+#endif
+
+int error_nomem =
+#ifdef ENOMEM
+ENOMEM;
+#else
+-2;
+#endif
+
+int error_noent =
+#ifdef ENOENT
+ENOENT;
+#else
+-3;
+#endif
+
+int error_txtbsy =
+#ifdef ETXTBSY
+ETXTBSY;
+#else
+-4;
+#endif
+
+int error_io =
+#ifdef EIO
+EIO;
+#else
+-5;
+#endif
+
+int error_exist =
+#ifdef EEXIST
+EEXIST;
+#else
+-6;
+#endif
+
+int error_timeout =
+#ifdef ETIMEDOUT
+ETIMEDOUT;
+#else
+-7;
+#endif
+
+int error_inprogress =
+#ifdef EINPROGRESS
+EINPROGRESS;
+#else
+-8;
+#endif
+
+int error_wouldblock =
+#ifdef EWOULDBLOCK
+EWOULDBLOCK;
+#else
+-9;
+#endif
+
+int error_again =
+#ifdef EAGAIN
+EAGAIN;
+#else
+-10;
+#endif
+
+int error_pipe =
+#ifdef EPIPE
+EPIPE;
+#else
+-11;
+#endif
+
+int error_perm =
+#ifdef EPERM
+EPERM;
+#else
+-12;
+#endif
+
+int error_acces =
+#ifdef EACCES
+EACCES;
+#else
+-13;
+#endif
+
+int error_nodevice =
+#ifdef ENXIO
+ENXIO;
+#else
+-14;
+#endif
+
+int error_proto =
+#ifdef EPROTO
+EPROTO;
+#else
+-15;
+#endif
+
+int error_isdir =
+#ifdef EISDIR
+EISDIR;
+#else
+-16;
+#endif
+
+int error_connrefused =
+#ifdef ECONNREFUSED
+ECONNREFUSED;
+#else
+-17;
+#endif
diff --git a/checkpasswd/error.h b/checkpasswd/error.h
new file mode 100644
index 0000000..5459656
--- /dev/null
+++ b/checkpasswd/error.h
@@ -0,0 +1,27 @@
+#ifndef ERROR_H
+#define ERROR_H
+
+extern int errno;
+
+extern int error_intr;
+extern int error_nomem;
+extern int error_noent;
+extern int error_txtbsy;
+extern int error_io;
+extern int error_exist;
+extern int error_timeout;
+extern int error_inprogress;
+extern int error_wouldblock;
+extern int error_again;
+extern int error_pipe;
+extern int error_perm;
+extern int error_acces;
+extern int error_nodevice;
+extern int error_proto;
+extern int error_isdir;
+extern int error_connrefused;
+
+extern char *error_str(int);
+extern int error_temp(int);
+
+#endif
diff --git a/checkpasswd/error_str.c b/checkpasswd/error_str.c
new file mode 100644
index 0000000..eb77e5d
--- /dev/null
+++ b/checkpasswd/error_str.c
@@ -0,0 +1,267 @@
+#include <errno.h>
+#include "error.h"
+
+#define X(e,s) if (i == e) return s;
+
+char *error_str(int i)
+{
+ X(0,"no error")
+ X(error_intr,"interrupted system call")
+ X(error_nomem,"out of memory")
+ X(error_noent,"file does not exist")
+ X(error_txtbsy,"text busy")
+ X(error_io,"input/output error")
+ X(error_exist,"file already exists")
+ X(error_timeout,"timed out")
+ X(error_inprogress,"operation in progress")
+ X(error_again,"temporary failure")
+ X(error_wouldblock,"input/output would block")
+ X(error_pipe,"broken pipe")
+ X(error_perm,"permission denied")
+ X(error_acces,"access denied")
+ X(error_nodevice,"device not configured")
+ X(error_proto,"protocol error")
+ X(error_isdir,"is a directory")
+ X(error_connrefused,"connection refused")
+#ifdef ESRCH
+ X(ESRCH,"no such process")
+#endif
+#ifdef E2BIG
+ X(E2BIG,"argument list too long")
+#endif
+#ifdef ENOEXEC
+ X(ENOEXEC,"exec format error")
+#endif
+#ifdef EBADF
+ X(EBADF,"file descriptor not open")
+#endif
+#ifdef ECHILD
+ X(ECHILD,"no child processes")
+#endif
+#ifdef EDEADLK
+ X(EDEADLK,"operation would cause deadlock")
+#endif
+#ifdef EFAULT
+ X(EFAULT,"bad address")
+#endif
+#ifdef ENOTBLK
+ X(ENOTBLK,"not a block device")
+#endif
+#ifdef EBUSY
+ X(EBUSY,"device busy")
+#endif
+#ifdef EXDEV
+ X(EXDEV,"cross-device link")
+#endif
+#ifdef ENODEV
+ X(ENODEV,"device does not support operation")
+#endif
+#ifdef ENOTDIR
+ X(ENOTDIR,"not a directory")
+#endif
+#ifdef EINVAL
+ X(EINVAL,"invalid argument")
+#endif
+#ifdef ENFILE
+ X(ENFILE,"system cannot open more files")
+#endif
+#ifdef EMFILE
+ X(EMFILE,"process cannot open more files")
+#endif
+#ifdef ENOTTY
+ X(ENOTTY,"not a tty")
+#endif
+#ifdef EFBIG
+ X(EFBIG,"file too big")
+#endif
+#ifdef ENOSPC
+ X(ENOSPC,"out of disk space")
+#endif
+#ifdef ESPIPE
+ X(ESPIPE,"unseekable descriptor")
+#endif
+#ifdef EROFS
+ X(EROFS,"read-only file system")
+#endif
+#ifdef EMLINK
+ X(EMLINK,"too many links")
+#endif
+#ifdef EDOM
+ X(EDOM,"input out of range")
+#endif
+#ifdef ERANGE
+ X(ERANGE,"output out of range")
+#endif
+#ifdef EALREADY
+ X(EALREADY,"operation already in progress")
+#endif
+#ifdef ENOTSOCK
+ X(ENOTSOCK,"not a socket")
+#endif
+#ifdef EDESTADDRREQ
+ X(EDESTADDRREQ,"destination address required")
+#endif
+#ifdef EMSGSIZE
+ X(EMSGSIZE,"message too long")
+#endif
+#ifdef EPROTOTYPE
+ X(EPROTOTYPE,"incorrect protocol type")
+#endif
+#ifdef ENOPROTOOPT
+ X(ENOPROTOOPT,"protocol not available")
+#endif
+#ifdef EPROTONOSUPPORT
+ X(EPROTONOSUPPORT,"protocol not supported")
+#endif
+#ifdef ESOCKTNOSUPPORT
+ X(ESOCKTNOSUPPORT,"socket type not supported")
+#endif
+#ifdef EOPNOTSUPP
+ X(EOPNOTSUPP,"operation not supported")
+#endif
+#ifdef EPFNOSUPPORT
+ X(EPFNOSUPPORT,"protocol family not supported")
+#endif
+#ifdef EAFNOSUPPORT
+ X(EAFNOSUPPORT,"address family not supported")
+#endif
+#ifdef EADDRINUSE
+ X(EADDRINUSE,"address already used")
+#endif
+#ifdef EADDRNOTAVAIL
+ X(EADDRNOTAVAIL,"address not available")
+#endif
+#ifdef ENETDOWN
+ X(ENETDOWN,"network down")
+#endif
+#ifdef ENETUNREACH
+ X(ENETUNREACH,"network unreachable")
+#endif
+#ifdef ENETRESET
+ X(ENETRESET,"network reset")
+#endif
+#ifdef ECONNABORTED
+ X(ECONNABORTED,"connection aborted")
+#endif
+#ifdef ECONNRESET
+ X(ECONNRESET,"connection reset")
+#endif
+#ifdef ENOBUFS
+ X(ENOBUFS,"out of buffer space")
+#endif
+#ifdef EISCONN
+ X(EISCONN,"already connected")
+#endif
+#ifdef ENOTCONN
+ X(ENOTCONN,"not connected")
+#endif
+#ifdef ESHUTDOWN
+ X(ESHUTDOWN,"socket shut down")
+#endif
+#ifdef ETOOMANYREFS
+ X(ETOOMANYREFS,"too many references")
+#endif
+#ifdef ELOOP
+ X(ELOOP,"symbolic link loop")
+#endif
+#ifdef ENAMETOOLONG
+ X(ENAMETOOLONG,"file name too long")
+#endif
+#ifdef EHOSTDOWN
+ X(EHOSTDOWN,"host down")
+#endif
+#ifdef EHOSTUNREACH
+ X(EHOSTUNREACH,"host unreachable")
+#endif
+#ifdef ENOTEMPTY
+ X(ENOTEMPTY,"directory not empty")
+#endif
+#ifdef EPROCLIM
+ X(EPROCLIM,"too many processes")
+#endif
+#ifdef EUSERS
+ X(EUSERS,"too many users")
+#endif
+#ifdef EDQUOT
+ X(EDQUOT,"disk quota exceeded")
+#endif
+#ifdef ESTALE
+ X(ESTALE,"stale NFS file handle")
+#endif
+#ifdef EREMOTE
+ X(EREMOTE,"too many levels of remote in path")
+#endif
+#ifdef EBADRPC
+ X(EBADRPC,"RPC structure is bad")
+#endif
+#ifdef ERPCMISMATCH
+ X(ERPCMISMATCH,"RPC version mismatch")
+#endif
+#ifdef EPROGUNAVAIL
+ X(EPROGUNAVAIL,"RPC program unavailable")
+#endif
+#ifdef EPROGMISMATCH
+ X(EPROGMISMATCH,"program version mismatch")
+#endif
+#ifdef EPROCUNAVAIL
+ X(EPROCUNAVAIL,"bad procedure for program")
+#endif
+#ifdef ENOLCK
+ X(ENOLCK,"no locks available")
+#endif
+#ifdef ENOSYS
+ X(ENOSYS,"system call not available")
+#endif
+#ifdef EFTYPE
+ X(EFTYPE,"bad file type")
+#endif
+#ifdef EAUTH
+ X(EAUTH,"authentication error")
+#endif
+#ifdef ENEEDAUTH
+ X(ENEEDAUTH,"not authenticated")
+#endif
+#ifdef ENOSTR
+ X(ENOSTR,"not a stream device")
+#endif
+#ifdef ETIME
+ X(ETIME,"timer expired")
+#endif
+#ifdef ENOSR
+ X(ENOSR,"out of stream resources")
+#endif
+#ifdef ENOMSG
+ X(ENOMSG,"no message of desired type")
+#endif
+#ifdef EBADMSG
+ X(EBADMSG,"bad message type")
+#endif
+#ifdef EIDRM
+ X(EIDRM,"identifier removed")
+#endif
+#ifdef ENONET
+ X(ENONET,"machine not on network")
+#endif
+#ifdef ERREMOTE
+ X(ERREMOTE,"object not local")
+#endif
+#ifdef ENOLINK
+ X(ENOLINK,"link severed")
+#endif
+#ifdef EADV
+ X(EADV,"advertise error")
+#endif
+#ifdef ESRMNT
+ X(ESRMNT,"srmount error")
+#endif
+#ifdef ECOMM
+ X(ECOMM,"communication error")
+#endif
+#ifdef EMULTIHOP
+ X(EMULTIHOP,"multihop attempted")
+#endif
+#ifdef EREMCHG
+ X(EREMCHG,"remote address changed")
+#endif
+ return "unknown error";
+}
diff --git a/checkpasswd/exit.h b/checkpasswd/exit.h
new file mode 100644
index 0000000..39011c8
--- /dev/null
+++ b/checkpasswd/exit.h
@@ -0,0 +1,6 @@
+#ifndef EXIT_H
+#define EXIT_H
+
+extern void _exit();
+
+#endif
diff --git a/checkpasswd/find-systype.sh b/checkpasswd/find-systype.sh
new file mode 100644
index 0000000..9f6e565
--- /dev/null
+++ b/checkpasswd/find-systype.sh
@@ -0,0 +1,143 @@
+# oper-:arch-:syst-:chip-:kern-
+# oper = operating system type; e.g., sunos-4.1.4
+# arch = machine language; e.g., sparc
+# syst = which binaries can run; e.g., sun4
+# chip = chip model; e.g., micro-2-80
+# kern = kernel version; e.g., sun4m
+# dependence: arch --- chip
+# \ \
+# oper --- syst --- kern
+# so, for example, syst is interpreted in light of oper, but chip is not.
+# anyway, no slashes, no extra colons, no uppercase letters.
+# the point of the extra -'s is to ease parsing: can add hierarchies later.
+# e.g., *:i386-*:*:pentium-*:* would handle pentium-100 as well as pentium,
+# and i386-486 (486s do have more instructions, you know) as well as i386.
+# the idea here is to include ALL useful available information.
+
+exec 2>/dev/null
+
+sys="`uname -s | tr '/:[A-Z]' '..[a-z]'`"
+if [ x"$sys" != x ]
+then
+ unamer="`uname -r | tr /: ..`"
+ unamem="`uname -m | tr /: ..`"
+ unamev="`uname -v | tr /: ..`"
+
+ case "$sys" in
+ bsd.os|freebsd|netbsd|openbsd)
+ # in bsd 4.4, uname -v does not have useful info.
+ # in bsd 4.4, uname -m is arch, not chip.
+ oper="$sys-$unamer"
+ arch="$unamem"
+ syst=""
+ chip="`sysctl -n hw.model`" # hopefully
+ kern=""
+ ;;
+ linux)
+ # as in bsd 4.4, uname -v does not have useful info.
+ oper="$sys-$unamer"
+ syst=""
+ chip="$unamem"
+ kern=""
+ case "$chip" in
+ i386|i486|i586|i686)
+ arch="i386"
+ ;;
+ alpha)
+ arch="alpha"
+ ;;
+ esac
+ ;;
+ aix)
+ # naturally IBM has to get uname -r and uname -v backwards. dorks.
+ oper="$sys-$unamev-$unamer"
+ arch="`arch | tr /: ..`"
+ syst=""
+ chip="$unamem"
+ kern=""
+ ;;
+ sunos)
+ oper="$sys-$unamer-$unamev"
+ arch="`(uname -p || mach) | tr /: ..`"
+ syst="`arch | tr /: ..`"
+ chip="$unamem" # this is wrong; is there any way to get the real info?
+ kern="`arch -k | tr /: ..`"
+ ;;
+ unix_sv)
+ oper="$sys-$unamer-$unamev"
+ arch="`uname -m`"
+ syst=""
+ chip="$unamem"
+ kern=""
+ ;;
+ *)
+ oper="$sys-$unamer-$unamev"
+ arch="`arch | tr /: ..`"
+ syst=""
+ chip="$unamem"
+ kern=""
+ ;;
+ esac
+else
+ gcc -c trycpp.c
+ gcc -o trycpp trycpp.o
+ case `./trycpp` in
+ nextstep)
+ oper="nextstep-`hostinfo | sed -n 's/^[ ]*NeXT Mach \([^:]*\):.*$/\1/p'`"
+ arch="`hostinfo | sed -n 's/^Processor type: \(.*\) (.*)$/\1/p' | tr /: ..`"
+ syst=""
+ chip="`hostinfo | sed -n 's/^Processor type: .* (\(.*\))$/\1/p' | tr ' /:' '...'`"
+ kern=""
+ ;;
+ *)
+ oper="unknown"
+ arch=""
+ syst=""
+ chip=""
+ kern=""
+ ;;
+ esac
+ rm -f trycpp.o trycpp
+fi
+
+case "$chip" in
+80486)
+ # let's try to be consistent here. (BSD/OS)
+ chip=i486
+ ;;
+i486DX)
+ # respect the hyphen hierarchy. (FreeBSD)
+ chip=i486-dx
+ ;;
+i486.DX2)
+ # respect the hyphen hierarchy. (FreeBSD)
+ chip=i486-dx2
+ ;;
+Intel.586)
+ # no, you nitwits, there is no such chip. (NeXTStep)
+ chip=pentium
+ ;;
+i586)
+ # no, you nitwits, there is no such chip. (Linux)
+ chip=pentium
+ ;;
+i686)
+ # STOP SAYING THAT! (Linux)
+ chip=ppro
+esac
+
+if gcc -c x86cpuid.c
+then
+ if gcc -o x86cpuid x86cpuid.o
+ then
+ x86cpuid="`./x86cpuid | tr /: ..`"
+ case "$x86cpuid" in
+ ?*)
+ chip="$x86cpuid"
+ ;;
+ esac
+ fi
+fi
+rm -f x86cpuid x86cpuid.o
+
+echo "$oper-:$arch-:$syst-:$chip-:$kern-" | tr ' [A-Z]' '.[a-z]'
diff --git a/checkpasswd/gen_alloc.h b/checkpasswd/gen_alloc.h
new file mode 100644
index 0000000..b94a956
--- /dev/null
+++ b/checkpasswd/gen_alloc.h
@@ -0,0 +1,7 @@
+#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
diff --git a/checkpasswd/gen_allocdefs.h b/checkpasswd/gen_allocdefs.h
new file mode 100644
index 0000000..d025b27
--- /dev/null
+++ b/checkpasswd/gen_allocdefs.h
@@ -0,0 +1,34 @@
+#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) { \
+ 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(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(register ta *x,register type *i) \
+{ if (!ta_rplus(x,1)) return 0; x->field[x->len++] = *i; return 1; }
+
+#endif
diff --git a/checkpasswd/hasshsgr.h1 b/checkpasswd/hasshsgr.h1
new file mode 100644
index 0000000..d11c988
--- /dev/null
+++ b/checkpasswd/hasshsgr.h1
@@ -0,0 +1 @@
+/* sysdep: -shortsetgroups */
diff --git a/checkpasswd/hasshsgr.h2 b/checkpasswd/hasshsgr.h2
new file mode 100644
index 0000000..db6a830
--- /dev/null
+++ b/checkpasswd/hasshsgr.h2
@@ -0,0 +1,2 @@
+/* sysdep: +shortsetgroups */
+#define HASSHORTSETGROUPS 1
diff --git a/checkpasswd/hier.c b/checkpasswd/hier.c
new file mode 100644
index 0000000..f11d108
--- /dev/null
+++ b/checkpasswd/hier.c
@@ -0,0 +1,6 @@
+#include "auto_home.h"
+
+void hier()
+{
+ c(auto_home,"bin","checkpassword",-1,-1,0700);
+}
diff --git a/checkpasswd/install.c b/checkpasswd/install.c
new file mode 100644
index 0000000..605fed3
--- /dev/null
+++ b/checkpasswd/install.c
@@ -0,0 +1,149 @@
+#include "buffer.h"
+#include "strerr.h"
+#include "error.h"
+#include "open.h"
+#include "readwrite.h"
+#include "exit.h"
+
+extern void hier();
+
+#define FATAL "install: fatal: "
+
+int fdsourcedir = -1;
+
+void h(home,uid,gid,mode)
+char *home;
+int uid;
+int gid;
+int mode;
+{
+ if (mkdir(home,0700) == -1)
+ if (errno != error_exist)
+ strerr_die4sys(111,FATAL,"unable to mkdir ",home,": ");
+ if (chown(home,uid,gid) == -1)
+ strerr_die4sys(111,FATAL,"unable to chown ",home,": ");
+ if (chmod(home,mode) == -1)
+ strerr_die4sys(111,FATAL,"unable to chmod ",home,": ");
+}
+
+void d(home,subdir,uid,gid,mode)
+char *home;
+char *subdir;
+int uid;
+int gid;
+int mode;
+{
+ if (chdir(home) == -1)
+ strerr_die4sys(111,FATAL,"unable to switch to ",home,": ");
+ if (mkdir(subdir,0700) == -1)
+ if (errno != error_exist)
+ strerr_die6sys(111,FATAL,"unable to mkdir ",home,"/",subdir,": ");
+ if (chown(subdir,uid,gid) == -1)
+ strerr_die6sys(111,FATAL,"unable to chown ",home,"/",subdir,": ");
+ if (chmod(subdir,mode) == -1)
+ strerr_die6sys(111,FATAL,"unable to chmod ",home,"/",subdir,": ");
+}
+
+char inbuf[BUFFER_INSIZE];
+char outbuf[BUFFER_OUTSIZE];
+buffer ssin;
+buffer ssout;
+
+void c(home,subdir,file,uid,gid,mode)
+char *home;
+char *subdir;
+char *file;
+int uid;
+int gid;
+int mode;
+{
+ int fdin;
+ int fdout;
+
+ if (fchdir(fdsourcedir) == -1)
+ strerr_die2sys(111,FATAL,"unable to switch back to source directory: ");
+
+ fdin = open_read(file);
+ if (fdin == -1)
+ strerr_die4sys(111,FATAL,"unable to read ",file,": ");
+ buffer_init(&ssin,read,fdin,inbuf,sizeof inbuf);
+
+ if (chdir(home) == -1)
+ strerr_die4sys(111,FATAL,"unable to switch to ",home,": ");
+ if (chdir(subdir) == -1)
+ strerr_die6sys(111,FATAL,"unable to switch to ",home,"/",subdir,": ");
+
+ fdout = open_trunc(file);
+ if (fdout == -1)
+ strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": ");
+ buffer_init(&ssout,write,fdout,outbuf,sizeof outbuf);
+
+ switch(buffer_copy(&ssout,&ssin)) {
+ case -2:
+ strerr_die4sys(111,FATAL,"unable to read ",file,": ");
+ case -3:
+ strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": ");
+ }
+
+ close(fdin);
+ if (buffer_flush(&ssout) == -1)
+ strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": ");
+ if (fsync(fdout) == -1)
+ strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": ");
+ if (close(fdout) == -1) /* NFS silliness */
+ strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": ");
+
+ if (chown(file,uid,gid) == -1)
+ strerr_die6sys(111,FATAL,"unable to chown .../",subdir,"/",file,": ");
+ if (chmod(file,mode) == -1)
+ strerr_die6sys(111,FATAL,"unable to chmod .../",subdir,"/",file,": ");
+}
+
+void z(home,subdir,file,len,uid,gid,mode)
+char *home;
+char *subdir;
+char *file;
+int len;
+int uid;
+int gid;
+int mode;
+{
+ int fdout;
+
+ if (chdir(home) == -1)
+ strerr_die4sys(111,FATAL,"unable to switch to ",home,": ");
+ if (chdir(subdir) == -1)
+ strerr_die6sys(111,FATAL,"unable to switch to ",home,"/",subdir,": ");
+
+ fdout = open_trunc(file);
+ if (fdout == -1)
+ strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": ");
+ buffer_init(&ssout,write,fdout,outbuf,sizeof outbuf);
+
+ while (len-- > 0)
+ if (buffer_put(&ssout,"",1) == -1)
+ strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": ");
+
+ if (buffer_flush(&ssout) == -1)
+ strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": ");
+ if (fsync(fdout) == -1)
+ strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": ");
+ if (close(fdout) == -1) /* NFS silliness */
+ strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": ");
+
+ if (chown(file,uid,gid) == -1)
+ strerr_die6sys(111,FATAL,"unable to chown .../",subdir,"/",file,": ");
+ if (chmod(file,mode) == -1)
+ strerr_die6sys(111,FATAL,"unable to chmod .../",subdir,"/",file,": ");
+}
+
+main()
+{
+ fdsourcedir = open_read(".");
+ if (fdsourcedir == -1)
+ strerr_die2sys(111,FATAL,"unable to open current directory: ");
+
+ umask(077);
+ hier();
+ _exit(0);
+}
diff --git a/checkpasswd/instcheck.c b/checkpasswd/instcheck.c
new file mode 100644
index 0000000..c945e67
--- /dev/null
+++ b/checkpasswd/instcheck.c
@@ -0,0 +1,108 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "strerr.h"
+#include "error.h"
+#include "readwrite.h"
+#include "exit.h"
+
+extern void hier();
+
+#define FATAL "instcheck: fatal: "
+#define WARNING "instcheck: warning: "
+
+void perm(prefix1,prefix2,prefix3,file,type,uid,gid,mode)
+char *prefix1;
+char *prefix2;
+char *prefix3;
+char *file;
+int type;
+int uid;
+int gid;
+int mode;
+{
+ struct stat st;
+
+ if (stat(file,&st) == -1) {
+ if (errno == error_noent)
+ strerr_warn6(WARNING,prefix1,prefix2,prefix3,file," does not exist",0);
+ else
+ strerr_warn4(WARNING,"unable to stat .../",file,": ",&strerr_sys);
+ return;
+ }
+
+ if ((uid != -1) && (st.st_uid != uid))
+ strerr_warn6(WARNING,prefix1,prefix2,prefix3,file," has wrong owner",0);
+ if ((gid != -1) && (st.st_gid != gid))
+ strerr_warn6(WARNING,prefix1,prefix2,prefix3,file," has wrong group",0);
+ if ((st.st_mode & 07777) != mode)
+ strerr_warn6(WARNING,prefix1,prefix2,prefix3,file," has wrong permissions",0);
+ if ((st.st_mode & S_IFMT) != type)
+ strerr_warn6(WARNING,prefix1,prefix2,prefix3,file," has wrong type",0);
+}
+
+void h(home,uid,gid,mode)
+char *home;
+int uid;
+int gid;
+int mode;
+{
+ perm("","","",home,S_IFDIR,uid,gid,mode);
+}
+
+void d(home,subdir,uid,gid,mode)
+char *home;
+char *subdir;
+int uid;
+int gid;
+int mode;
+{
+ if (chdir(home) == -1)
+ strerr_die4sys(111,FATAL,"unable to switch to ",home,": ");
+ perm("",home,"/",subdir,S_IFDIR,uid,gid,mode);
+}
+
+void p(home,fifo,uid,gid,mode)
+char *home;
+char *fifo;
+int uid;
+int gid;
+int mode;
+{
+ if (chdir(home) == -1)
+ strerr_die4sys(111,FATAL,"unable to switch to ",home,": ");
+ perm("",home,"/",fifo,S_IFIFO,uid,gid,mode);
+}
+
+void c(home,subdir,file,uid,gid,mode)
+char *home;
+char *subdir;
+char *file;
+int uid;
+int gid;
+int mode;
+{
+ if (chdir(home) == -1)
+ strerr_die4sys(111,FATAL,"unable to switch to ",home,": ");
+ if (chdir(subdir) == -1)
+ strerr_die6sys(111,FATAL,"unable to switch to ",home,"/",subdir,": ");
+ perm(".../",subdir,"/",file,S_IFREG,uid,gid,mode);
+}
+
+void z(home,file,len,uid,gid,mode)
+char *home;
+char *file;
+int len;
+int uid;
+int gid;
+int mode;
+{
+ if (chdir(home) == -1)
+ strerr_die4sys(111,FATAL,"unable to switch to ",home,": ");
+ perm("",home,"/",file,S_IFREG,uid,gid,mode);
+}
+
+main()
+{
+ hier();
+ _exit(0);
+}
diff --git a/checkpasswd/open.h b/checkpasswd/open.h
new file mode 100644
index 0000000..2963fa7
--- /dev/null
+++ b/checkpasswd/open.h
@@ -0,0 +1,10 @@
+#ifndef OPEN_H
+#define OPEN_H
+
+extern int open_read(char *);
+extern int open_excl(char *);
+extern int open_append(char *);
+extern int open_trunc(char *);
+extern int open_write(char *);
+
+#endif
diff --git a/checkpasswd/open_read.c b/checkpasswd/open_read.c
new file mode 100644
index 0000000..7f5ec8b
--- /dev/null
+++ b/checkpasswd/open_read.c
@@ -0,0 +1,6 @@
+#include <sys/types.h>
+#include <fcntl.h>
+#include "open.h"
+
+int open_read(char *fn)
+{ return open(fn,O_RDONLY | O_NDELAY); }
diff --git a/checkpasswd/open_trunc.c b/checkpasswd/open_trunc.c
new file mode 100644
index 0000000..77b99ef
--- /dev/null
+++ b/checkpasswd/open_trunc.c
@@ -0,0 +1,6 @@
+#include <sys/types.h>
+#include <fcntl.h>
+#include "open.h"
+
+int open_trunc(char *fn)
+{ return open(fn,O_WRONLY | O_NDELAY | O_TRUNC | O_CREAT,0644); }
diff --git a/checkpasswd/pathexec.h b/checkpasswd/pathexec.h
new file mode 100644
index 0000000..6fcbb89
--- /dev/null
+++ b/checkpasswd/pathexec.h
@@ -0,0 +1,8 @@
+#ifndef PATHEXEC_H
+#define PATHEXEC_H
+
+extern void pathexec_run(char *,char **,char **);
+extern int pathexec_env(char *,char *);
+extern void pathexec(char **);
+
+#endif
diff --git a/checkpasswd/pathexec_env.c b/checkpasswd/pathexec_env.c
new file mode 100644
index 0000000..48bba7e
--- /dev/null
+++ b/checkpasswd/pathexec_env.c
@@ -0,0 +1,68 @@
+#include "stralloc.h"
+#include "alloc.h"
+#include "str.h"
+#include "byte.h"
+#include "env.h"
+#include "pathexec.h"
+
+static stralloc plus;
+static stralloc tmp;
+
+int pathexec_env(char *s,char *t)
+{
+ if (!s) return 1;
+ if (!stralloc_copys(&tmp,s)) return 0;
+ if (t) {
+ if (!stralloc_cats(&tmp,"=")) return 0;
+ if (!stralloc_cats(&tmp,t)) return 0;
+ }
+ if (!stralloc_0(&tmp)) return 0;
+ return stralloc_cat(&plus,&tmp);
+}
+
+void pathexec(char **argv)
+{
+ char *path;
+ char **e;
+ unsigned int elen;
+ unsigned int i;
+ unsigned int j;
+ unsigned int split;
+ unsigned int t;
+
+ if (!stralloc_cats(&plus,"")) return;
+
+ elen = 0;
+ for (i = 0;environ[i];++i)
+ ++elen;
+ for (i = 0;i < plus.len;++i)
+ if (!plus.s[i])
+ ++elen;
+
+ e = (char **) alloc((elen + 1) * sizeof(char *));
+ if (!e) return;
+
+ elen = 0;
+ for (i = 0;environ[i];++i)
+ e[elen++] = environ[i];
+
+ j = 0;
+ for (i = 0;i < plus.len;++i)
+ if (!plus.s[i]) {
+ split = str_chr(plus.s + j,'=');
+ for (t = 0;t < elen;++t)
+ if (byte_equal(plus.s + j,split,e[t]))
+ if (e[t][split] == '=') {
+ --elen;
+ e[t] = e[elen];
+ break;
+ }
+ if (plus.s[j + split])
+ e[elen++] = plus.s + j;
+ j = i + 1;
+ }
+ e[elen] = 0;
+
+ pathexec_run(*argv,argv,e);
+ alloc_free(e);
+}
diff --git a/checkpasswd/pathexec_run.c b/checkpasswd/pathexec_run.c
new file mode 100644
index 0000000..17837eb
--- /dev/null
+++ b/checkpasswd/pathexec_run.c
@@ -0,0 +1,46 @@
+#include "error.h"
+#include "stralloc.h"
+#include "str.h"
+#include "env.h"
+#include "pathexec.h"
+
+static stralloc tmp;
+
+void pathexec_run(char *file,char **argv,char **envp)
+{
+ char *path;
+ unsigned int split;
+ int savederrno;
+
+ if (file[str_chr(file,'/')]) {
+ execve(file,argv,envp);
+ return;
+ }
+
+ path = env_get("PATH");
+ if (!path) path = "/bin:/usr/bin";
+
+ savederrno = 0;
+ for (;;) {
+ split = str_chr(path,':');
+ if (!stralloc_copyb(&tmp,path,split)) return;
+ if (!split)
+ if (!stralloc_cats(&tmp,".")) return;
+ if (!stralloc_cats(&tmp,"/")) return;
+ if (!stralloc_cats(&tmp,file)) return;
+ if (!stralloc_0(&tmp)) return;
+
+ execve(tmp.s,argv,envp);
+ if (errno != error_noent) {
+ savederrno = errno;
+ if ((errno != error_acces) && (errno != error_perm) && (errno != error_isdir)) return;
+ }
+
+ if (!path[split]) {
+ if (savederrno) errno = savederrno;
+ return;
+ }
+ path += split;
+ path += 1;
+ }
+}
diff --git a/checkpasswd/print-cc.sh b/checkpasswd/print-cc.sh
new file mode 100644
index 0000000..bc28452
--- /dev/null
+++ b/checkpasswd/print-cc.sh
@@ -0,0 +1,5 @@
+cc="`head -1 conf-cc`"
+systype="`cat systype`"
+
+cat warn-auto.sh
+echo exec "$cc" '-c ${1+"$@"}'
diff --git a/checkpasswd/prot.c b/checkpasswd/prot.c
new file mode 100644
index 0000000..0a8a373
--- /dev/null
+++ b/checkpasswd/prot.c
@@ -0,0 +1,19 @@
+#include "hasshsgr.h"
+#include "prot.h"
+
+int prot_gid(int gid)
+{
+#ifdef HASSHORTSETGROUPS
+ short x[2];
+ x[0] = gid; x[1] = 73; /* catch errors */
+ if (setgroups(1,x) == -1) return -1;
+#else
+ if (setgroups(1,&gid) == -1) return -1;
+#endif
+ return setgid(gid); /* _should_ be redundant, but on some systems it isn't */
+}
+
+int prot_uid(int uid)
+{
+ return setuid(uid);
+}
diff --git a/checkpasswd/prot.h b/checkpasswd/prot.h
new file mode 100644
index 0000000..7dd0503
--- /dev/null
+++ b/checkpasswd/prot.h
@@ -0,0 +1,7 @@
+#ifndef PROT_H
+#define PROT_H
+
+extern int prot_gid(int);
+extern int prot_uid(int);
+
+#endif
diff --git a/checkpasswd/readwrite.h b/checkpasswd/readwrite.h
new file mode 100644
index 0000000..2a64968
--- /dev/null
+++ b/checkpasswd/readwrite.h
@@ -0,0 +1,7 @@
+#ifndef READWRITE_H
+#define READWRITE_H
+
+extern int read();
+extern int write();
+
+#endif
diff --git a/checkpasswd/str.h b/checkpasswd/str.h
new file mode 100644
index 0000000..ab4aedd
--- /dev/null
+++ b/checkpasswd/str.h
@@ -0,0 +1,14 @@
+#ifndef STR_H
+#define STR_H
+
+extern unsigned int str_copy(char *,char *);
+extern int str_diff(char *,char *);
+extern int str_diffn(char *,char *,unsigned int);
+extern unsigned int str_len(char *);
+extern unsigned int str_chr(char *,int);
+extern unsigned int str_rchr(char *,int);
+extern int str_start(char *,char *);
+
+#define str_equal(s,t) (!str_diff((s),(t)))
+
+#endif
diff --git a/checkpasswd/str_chr.c b/checkpasswd/str_chr.c
new file mode 100644
index 0000000..886d6b6
--- /dev/null
+++ b/checkpasswd/str_chr.c
@@ -0,0 +1,17 @@
+#include "str.h"
+
+unsigned int str_chr(register char *s,int c)
+{
+ register char ch;
+ register char *t;
+
+ ch = c;
+ t = s;
+ for (;;) {
+ if (!*t) break; if (*t == ch) break; ++t;
+ if (!*t) break; if (*t == ch) break; ++t;
+ if (!*t) break; if (*t == ch) break; ++t;
+ if (!*t) break; if (*t == ch) break; ++t;
+ }
+ return t - s;
+}
diff --git a/checkpasswd/str_len.c b/checkpasswd/str_len.c
new file mode 100644
index 0000000..5bd3f62
--- /dev/null
+++ b/checkpasswd/str_len.c
@@ -0,0 +1,14 @@
+#include "str.h"
+
+unsigned int str_len(char *s)
+{
+ register char *t;
+
+ t = s;
+ for (;;) {
+ if (!*t) return t - s; ++t;
+ if (!*t) return t - s; ++t;
+ if (!*t) return t - s; ++t;
+ if (!*t) return t - s; ++t;
+ }
+}
diff --git a/checkpasswd/str_start.c b/checkpasswd/str_start.c
new file mode 100644
index 0000000..43430bb
--- /dev/null
+++ b/checkpasswd/str_start.c
@@ -0,0 +1,13 @@
+#include "str.h"
+
+int str_start(register char *s,register char *t)
+{
+ register char x;
+
+ for (;;) {
+ x = *t++; if (!x) return 1; if (x != *s++) return 0;
+ x = *t++; if (!x) return 1; if (x != *s++) return 0;
+ x = *t++; if (!x) return 1; if (x != *s++) return 0;
+ x = *t++; if (!x) return 1; if (x != *s++) return 0;
+ }
+}
diff --git a/checkpasswd/stralloc.h b/checkpasswd/stralloc.h
new file mode 100644
index 0000000..7866812
--- /dev/null
+++ b/checkpasswd/stralloc.h
@@ -0,0 +1,29 @@
+#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 *);
+extern int stralloc_cat(stralloc *,stralloc *);
+extern int stralloc_copys(stralloc *,char *);
+extern int stralloc_cats(stralloc *,char *);
+extern int stralloc_copyb(stralloc *,char *,unsigned int);
+extern int stralloc_catb(stralloc *,char *,unsigned int);
+extern int stralloc_append(stralloc *,char *); /* beware: this takes a pointer to 1 char */
+extern int stralloc_starts(stralloc *,char *);
+
+#define stralloc_0(sa) stralloc_append(sa,"")
+
+extern int stralloc_catulong0(stralloc *,unsigned long,unsigned int);
+extern int stralloc_catlong0(stralloc *,long,unsigned int);
+
+#define stralloc_catlong(sa,l) (stralloc_catlong0((sa),(l),0))
+#define stralloc_catuint0(sa,i,n) (stralloc_catulong0((sa),(i),(n)))
+#define stralloc_catint0(sa,i,n) (stralloc_catlong0((sa),(i),(n)))
+#define stralloc_catint(sa,i) (stralloc_catlong0((sa),(i),0))
+
+#endif
diff --git a/checkpasswd/stralloc_cat.c b/checkpasswd/stralloc_cat.c
new file mode 100644
index 0000000..dd08548
--- /dev/null
+++ b/checkpasswd/stralloc_cat.c
@@ -0,0 +1,7 @@
+#include "byte.h"
+#include "stralloc.h"
+
+int stralloc_cat(stralloc *sato,stralloc *safrom)
+{
+ return stralloc_catb(sato,safrom->s,safrom->len);
+}
diff --git a/checkpasswd/stralloc_catb.c b/checkpasswd/stralloc_catb.c
new file mode 100644
index 0000000..b739bed
--- /dev/null
+++ b/checkpasswd/stralloc_catb.c
@@ -0,0 +1,12 @@
+#include "stralloc.h"
+#include "byte.h"
+
+int stralloc_catb(stralloc *sa,char *s,unsigned int n)
+{
+ if (!sa->s) return stralloc_copyb(sa,s,n);
+ if (!stralloc_readyplus(sa,n + 1)) return 0;
+ byte_copy(sa->s + sa->len,n,s);
+ sa->len += n;
+ sa->s[sa->len] = 'Z'; /* ``offensive programming'' */
+ return 1;
+}
diff --git a/checkpasswd/stralloc_cats.c b/checkpasswd/stralloc_cats.c
new file mode 100644
index 0000000..8b11e94
--- /dev/null
+++ b/checkpasswd/stralloc_cats.c
@@ -0,0 +1,8 @@
+#include "byte.h"
+#include "str.h"
+#include "stralloc.h"
+
+int stralloc_cats(stralloc *sa,char *s)
+{
+ return stralloc_catb(sa,s,str_len(s));
+}
diff --git a/checkpasswd/stralloc_eady.c b/checkpasswd/stralloc_eady.c
new file mode 100644
index 0000000..3a31f4b
--- /dev/null
+++ b/checkpasswd/stralloc_eady.c
@@ -0,0 +1,6 @@
+#include "alloc.h"
+#include "stralloc.h"
+#include "gen_allocdefs.h"
+
+GEN_ALLOC_ready(stralloc,char,s,len,a,i,n,x,30,stralloc_ready)
+GEN_ALLOC_readyplus(stralloc,char,s,len,a,i,n,x,30,stralloc_readyplus)
diff --git a/checkpasswd/stralloc_opyb.c b/checkpasswd/stralloc_opyb.c
new file mode 100644
index 0000000..46b99fc
--- /dev/null
+++ b/checkpasswd/stralloc_opyb.c
@@ -0,0 +1,11 @@
+#include "stralloc.h"
+#include "byte.h"
+
+int stralloc_copyb(stralloc *sa,char *s,unsigned int n)
+{
+ if (!stralloc_ready(sa,n + 1)) return 0;
+ byte_copy(sa->s,n,s);
+ sa->len = n;
+ sa->s[n] = 'Z'; /* ``offensive programming'' */
+ return 1;
+}
diff --git a/checkpasswd/stralloc_opys.c b/checkpasswd/stralloc_opys.c
new file mode 100644
index 0000000..78594b0
--- /dev/null
+++ b/checkpasswd/stralloc_opys.c
@@ -0,0 +1,8 @@
+#include "byte.h"
+#include "str.h"
+#include "stralloc.h"
+
+int stralloc_copys(stralloc *sa,char *s)
+{
+ return stralloc_copyb(sa,s,str_len(s));
+}
diff --git a/checkpasswd/stralloc_pend.c b/checkpasswd/stralloc_pend.c
new file mode 100644
index 0000000..a3443b8
--- /dev/null
+++ b/checkpasswd/stralloc_pend.c
@@ -0,0 +1,5 @@
+#include "alloc.h"
+#include "stralloc.h"
+#include "gen_allocdefs.h"
+
+GEN_ALLOC_append(stralloc,char,s,len,a,i,n,x,30,stralloc_readyplus,stralloc_append)
diff --git a/checkpasswd/strerr.h b/checkpasswd/strerr.h
new file mode 100644
index 0000000..702f588
--- /dev/null
+++ b/checkpasswd/strerr.h
@@ -0,0 +1,78 @@
+#ifndef STRERR_H
+#define STRERR_H
+
+struct strerr {
+ struct strerr *who;
+ char *x;
+ char *y;
+ char *z;
+} ;
+
+extern struct strerr strerr_sys;
+extern void strerr_sysinit(void);
+
+extern char *strerr(struct strerr *);
+extern void strerr_warn(char *,char *,char *,char *,char *,char *,struct strerr *);
+extern void strerr_die(int,char *,char *,char *,char *,char *,char *,struct strerr *);
+
+#define STRERR(r,se,a) \
+{ se.who = 0; se.x = a; se.y = 0; se.z = 0; return r; }
+
+#define STRERR_SYS(r,se,a) \
+{ se.who = &strerr_sys; se.x = a; se.y = 0; se.z = 0; return r; }
+#define STRERR_SYS3(r,se,a,b,c) \
+{ se.who = &strerr_sys; se.x = a; se.y = b; se.z = c; return r; }
+
+#define strerr_warn6(x1,x2,x3,x4,x5,x6,se) \
+strerr_warn((x1),(x2),(x3),(x4),(x5),(x6),(se))
+#define strerr_warn5(x1,x2,x3,x4,x5,se) \
+strerr_warn((x1),(x2),(x3),(x4),(x5),0,(se))
+#define strerr_warn4(x1,x2,x3,x4,se) \
+strerr_warn((x1),(x2),(x3),(x4),0,0,(se))
+#define strerr_warn3(x1,x2,x3,se) \
+strerr_warn((x1),(x2),(x3),0,0,0,(se))
+#define strerr_warn2(x1,x2,se) \
+strerr_warn((x1),(x2),0,0,0,0,(se))
+#define strerr_warn1(x1,se) \
+strerr_warn((x1),0,0,0,0,0,(se))
+
+#define strerr_die6(e,x1,x2,x3,x4,x5,x6,se) \
+strerr_die((e),(x1),(x2),(x3),(x4),(x5),(x6),(se))
+#define strerr_die5(e,x1,x2,x3,x4,x5,se) \
+strerr_die((e),(x1),(x2),(x3),(x4),(x5),0,(se))
+#define strerr_die4(e,x1,x2,x3,x4,se) \
+strerr_die((e),(x1),(x2),(x3),(x4),0,0,(se))
+#define strerr_die3(e,x1,x2,x3,se) \
+strerr_die((e),(x1),(x2),(x3),0,0,0,(se))
+#define strerr_die2(e,x1,x2,se) \
+strerr_die((e),(x1),(x2),0,0,0,0,(se))
+#define strerr_die1(e,x1,se) \
+strerr_die((e),(x1),0,0,0,0,0,(se))
+
+#define strerr_die6sys(e,x1,x2,x3,x4,x5,x6) \
+strerr_die((e),(x1),(x2),(x3),(x4),(x5),(x6),&strerr_sys)
+#define strerr_die5sys(e,x1,x2,x3,x4,x5) \
+strerr_die((e),(x1),(x2),(x3),(x4),(x5),0,&strerr_sys)
+#define strerr_die4sys(e,x1,x2,x3,x4) \
+strerr_die((e),(x1),(x2),(x3),(x4),0,0,&strerr_sys)
+#define strerr_die3sys(e,x1,x2,x3) \
+strerr_die((e),(x1),(x2),(x3),0,0,0,&strerr_sys)
+#define strerr_die2sys(e,x1,x2) \
+strerr_die((e),(x1),(x2),0,0,0,0,&strerr_sys)
+#define strerr_die1sys(e,x1) \
+strerr_die((e),(x1),0,0,0,0,0,&strerr_sys)
+
+#define strerr_die6x(e,x1,x2,x3,x4,x5,x6) \
+strerr_die((e),(x1),(x2),(x3),(x4),(x5),(x6),0)
+#define strerr_die5x(e,x1,x2,x3,x4,x5) \
+strerr_die((e),(x1),(x2),(x3),(x4),(x5),0,0)
+#define strerr_die4x(e,x1,x2,x3,x4) \
+strerr_die((e),(x1),(x2),(x3),(x4),0,0,0)
+#define strerr_die3x(e,x1,x2,x3) \
+strerr_die((e),(x1),(x2),(x3),0,0,0,0)
+#define strerr_die2x(e,x1,x2) \
+strerr_die((e),(x1),(x2),0,0,0,0,0)
+#define strerr_die1x(e,x1) \
+strerr_die((e),(x1),0,0,0,0,0,0)
+
+#endif
diff --git a/checkpasswd/strerr_die.c b/checkpasswd/strerr_die.c
new file mode 100644
index 0000000..850028b
--- /dev/null
+++ b/checkpasswd/strerr_die.c
@@ -0,0 +1,31 @@
+#include "buffer.h"
+#include "exit.h"
+#include "strerr.h"
+
+void strerr_warn(char *x1,char *x2,char *x3,char *x4,char *x5,char *x6,struct strerr *se)
+{
+ strerr_sysinit();
+
+ if (x1) buffer_puts(buffer_2,x1);
+ if (x2) buffer_puts(buffer_2,x2);
+ if (x3) buffer_puts(buffer_2,x3);
+ if (x4) buffer_puts(buffer_2,x4);
+ if (x5) buffer_puts(buffer_2,x5);
+ if (x6) buffer_puts(buffer_2,x6);
+
+ while(se) {
+ if (se->x) buffer_puts(buffer_2,se->x);
+ if (se->y) buffer_puts(buffer_2,se->y);
+ if (se->z) buffer_puts(buffer_2,se->z);
+ se = se->who;
+ }
+
+ buffer_puts(buffer_2,"\n");
+ buffer_flush(buffer_2);
+}
+
+void strerr_die(int e,char *x1,char *x2,char *x3,char *x4,char *x5,char *x6,struct strerr *se)
+{
+ strerr_warn(x1,x2,x3,x4,x5,x6,se);
+ _exit(e);
+}
diff --git a/checkpasswd/strerr_sys.c b/checkpasswd/strerr_sys.c
new file mode 100644
index 0000000..b484197
--- /dev/null
+++ b/checkpasswd/strerr_sys.c
@@ -0,0 +1,12 @@
+#include "error.h"
+#include "strerr.h"
+
+struct strerr strerr_sys;
+
+void strerr_sysinit(void)
+{
+ strerr_sys.who = 0;
+ strerr_sys.x = error_str(errno);
+ strerr_sys.y = "";
+ strerr_sys.z = "";
+}
diff --git a/checkpasswd/trycpp.c b/checkpasswd/trycpp.c
new file mode 100644
index 0000000..3ab455b
--- /dev/null
+++ b/checkpasswd/trycpp.c
@@ -0,0 +1,7 @@
+main()
+{
+#ifdef NeXT
+ printf("nextstep\n"); exit(0);
+#endif
+ printf("unknown\n"); exit(0);
+}
diff --git a/checkpasswd/trycrypt.c b/checkpasswd/trycrypt.c
new file mode 100644
index 0000000..fbce408
--- /dev/null
+++ b/checkpasswd/trycrypt.c
@@ -0,0 +1,4 @@
+main()
+{
+ ;
+}
diff --git a/checkpasswd/tryshadow.c b/checkpasswd/tryshadow.c
new file mode 100644
index 0000000..fbce408
--- /dev/null
+++ b/checkpasswd/tryshadow.c
@@ -0,0 +1,4 @@
+main()
+{
+ ;
+}
diff --git a/checkpasswd/tryshsgr.c b/checkpasswd/tryshsgr.c
new file mode 100644
index 0000000..f55ff60
--- /dev/null
+++ b/checkpasswd/tryshsgr.c
@@ -0,0 +1,14 @@
+main()
+{
+ short x[4];
+
+ x[0] = x[1] = 1;
+ if (getgroups(1,x) == 0) if (setgroups(1,x) == -1) _exit(1);
+
+ if (getgroups(1,x) == -1) _exit(1);
+ if (x[1] != 1) _exit(1);
+ x[1] = 2;
+ if (getgroups(1,x) == -1) _exit(1);
+ if (x[1] != 2) _exit(1);
+ _exit(0);
+}
diff --git a/checkpasswd/tryslib.c b/checkpasswd/tryslib.c
new file mode 100644
index 0000000..fbce408
--- /dev/null
+++ b/checkpasswd/tryslib.c
@@ -0,0 +1,4 @@
+main()
+{
+ ;
+}
diff --git a/checkpasswd/tryspnam.c b/checkpasswd/tryspnam.c
new file mode 100644
index 0000000..622ba8b
--- /dev/null
+++ b/checkpasswd/tryspnam.c
@@ -0,0 +1,9 @@
+#include <shadow.h>
+
+void main()
+{
+ struct spwd *spw;
+
+ spw = getspnam("");
+ puts(spw->sp_pwdp);
+}
diff --git a/checkpasswd/tryuserpw.c b/checkpasswd/tryuserpw.c
new file mode 100644
index 0000000..fb14623
--- /dev/null
+++ b/checkpasswd/tryuserpw.c
@@ -0,0 +1,9 @@
+#include <userpw.h>
+
+void main()
+{
+ struct userpw *upw;
+
+ upw = getuserpw("");
+ puts(upw->upw_passwd);
+}
diff --git a/checkpasswd/warn-auto.sh b/checkpasswd/warn-auto.sh
new file mode 100644
index 0000000..36d2313
--- /dev/null
+++ b/checkpasswd/warn-auto.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+# WARNING: This file was auto-generated. Do not edit!
diff --git a/checkpasswd/warn-shsgr b/checkpasswd/warn-shsgr
new file mode 100644
index 0000000..37c351e
--- /dev/null
+++ b/checkpasswd/warn-shsgr
@@ -0,0 +1,3 @@
+Oops. Your getgroups() returned 0, and setgroups() failed; this means
+that I can't reliably do my shsgr test. Please either ``make'' as root
+or ``make'' while you're in one or more supplementary groups.
diff --git a/checkpasswd/x86cpuid.c b/checkpasswd/x86cpuid.c
new file mode 100644
index 0000000..900d7d5
--- /dev/null
+++ b/checkpasswd/x86cpuid.c
@@ -0,0 +1,38 @@
+#include <signal.h>
+
+void nope()
+{
+ exit(1);
+}
+
+main()
+{
+ unsigned long x[4];
+ unsigned long y[4];
+ int i;
+ int j;
+ char c;
+
+ signal(SIGILL,nope);
+
+ x[0] = 0;
+ x[1] = 0;
+ x[2] = 0;
+ x[3] = 0;
+
+ asm volatile(".byte 15;.byte 162" : "=a"(x[0]),"=b"(x[1]),"=c"(x[3]),"=d"(x[2]) : "0"(0) );
+ if (!x[0]) return 0;
+ asm volatile(".byte 15;.byte 162" : "=a"(y[0]),"=b"(y[1]),"=c"(y[2]),"=d"(y[3]) : "0"(1) );
+
+ for (i = 1;i < 4;++i)
+ for (j = 0;j < 4;++j) {
+ c = x[i] >> (8 * j);
+ if (c < 32) c = 32;
+ if (c > 126) c = 126;
+ putchar(c);
+ }
+
+ printf("-%08x-%08x\n",y[0],y[3]);
+
+ return 0;
+}